]> granicus.if.org Git - sudo/commitdiff
Adapt plugins to version I/O logging ABI 1.1
authorTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 20 Dec 2010 21:28:20 +0000 (16:28 -0500)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 20 Dec 2010 21:28:20 +0000 (16:28 -0500)
plugins/sample/sample_plugin.c
plugins/sudoers/iolog.c
plugins/sudoers/sudoers.c

index a7f13a50fccb6b88e8e9307a6e2a650bcff3ba57..c337637d438a6d40c81e00146af6b6e8ea5596f0 100644 (file)
@@ -423,8 +423,8 @@ policy_close(int exit_status, int error)
 static int
 io_open(unsigned int version, sudo_conv_t conversation,
     sudo_printf_t sudo_printf, char * const settings[],
-    char * const user_info[], int argc, char * const argv[],
-    char * const user_env[])
+    char * const user_info[], char * const command_info[],
+    int argc, char * const argv[], char * const user_env[])
 {
     int fd;
     char path[PATH_MAX];
index 3c9a98e071a8b07fbada5bf7c356473e89477c1b..955e88087b88fe68c2a88237275e07f8c4c96690 100644 (file)
@@ -148,37 +148,71 @@ io_nextid(void)
 }
 
 static int
-build_idpath(char *pathbuf, size_t pathsize)
+build_idpath(const char *iolog_dir, const char *sessid, char *pathbuf, size_t pathsize)
 {
     struct stat sb;
+    char *cp;
     int i, len;
 
-    if (sudo_user.sessid[0] == '\0')
+    if (sessid[0] == '\0')
        log_error(0, "tried to build a session id path without a session id");
 
-    /*
-     * Path is of the form /var/log/sudo-io/00/00/01.
-     */
-    len = snprintf(pathbuf, pathsize, "%s/%c%c/%c%c/%c%c", def_iolog_dir,
-       sudo_user.sessid[0], sudo_user.sessid[1], sudo_user.sessid[2],
-       sudo_user.sessid[3], sudo_user.sessid[4], sudo_user.sessid[5]);
-    if (len <= 0 && len >= pathsize) {
-       errno = ENAMETOOLONG;
-       log_error(USE_ERRNO, "%s/%s", def_iolog_dir, sudo_user.sessid);
+    /* Check whether or not we have a real session ID. */
+    for (i = 0; i < 6; i++) {
+       switch (sessid[i]) {
+           case '0': case '1': case '2': case '3': case '4': case '5':
+           case '6': case '7': case '8': case '9': case 'A': case 'B':
+           case 'C': case 'D': case 'E': case 'F': case 'G': case 'H':
+           case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
+           case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T':
+           case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
+               break;
+           default:
+               goto checked;
+       }
     }
+checked:
+    if (i == 6 && sessid[6] == '\0') {
+       /* Path is of the form /var/log/sudo-io/00/00/01. */
+       len = snprintf(pathbuf, pathsize, "%s/%c%c/%c%c/%c%c", iolog_dir,
+           sessid[0], sessid[1], sessid[2], sessid[3], sessid[4], sessid[5]);
+       if (len <= 0 && len >= pathsize) {
+           errno = ENAMETOOLONG;
+           log_error(USE_ERRNO, "%s/%s", iolog_dir, sessid);
+       }
 
-    /*
-     * Create the intermediate subdirs as needed.
-     */
-    for (i = 6; i > 0; i -= 3) {
-       pathbuf[len - i] = '\0';
-       if (stat(pathbuf, &sb) != 0) {
-           if (mkdir(pathbuf, S_IRWXU) != 0)
-               log_error(USE_ERRNO, "Can't mkdir %s", pathbuf);
-       } else if (!S_ISDIR(sb.st_mode)) {
-           log_error(0, "%s: %s", pathbuf, strerror(ENOTDIR));
+       /* Create the intermediate subdirs as needed. */
+       for (i = 6; i > 0; i -= 3) {
+           pathbuf[len - i] = '\0';
+           if (stat(pathbuf, &sb) != 0) {
+               if (mkdir(pathbuf, S_IRWXU) != 0)
+                   log_error(USE_ERRNO, "Can't mkdir %s", pathbuf);
+           } else if (!S_ISDIR(sb.st_mode)) {
+               log_error(0, "%s: %s", pathbuf, strerror(ENOTDIR));
+           }
+           pathbuf[len - i] = '/';
+       }
+    } else {
+       /* Not a session ID, just append dir + file. */
+       len = snprintf(pathbuf, pathsize, "%s/%s", iolog_dir, sessid);
+       if (len <= 0 && len >= pathsize) {
+           errno = ENAMETOOLONG;
+           log_error(USE_ERRNO, "%s/%s", iolog_dir, sessid);
        }
-       pathbuf[len - i] = '/';
+
+       /* Create the intermediate subdirs as needed. */
+       cp = &pathbuf[strlen(iolog_dir)];
+       do {
+           *cp = '\0';
+           if (stat(pathbuf, &sb) != 0) {
+               if (mkdir(pathbuf, S_IRWXU) != 0)
+                   log_error(USE_ERRNO, "Can't mkdir %s", pathbuf);
+           } else if (!S_ISDIR(sb.st_mode)) {
+               log_error(0, "%s: %s", pathbuf, strerror(ENOTDIR));
+           }
+           *cp++ = '/';
+           cp = strchr(cp, '/');
+       } while (cp != NULL);
     }
 
     return(len);
@@ -208,10 +242,12 @@ open_io_fd(char *pathbuf, int len, const char *suffix, int docompress)
 static int
 sudoers_io_open(unsigned int version, sudo_conv_t conversation,
     sudo_printf_t plugin_printf, char * const settings[],
-    char * const user_info[], int argc, char * const argv[],
-    char * const user_env[])
+    char * const user_info[], char * const command_info[],
+    int argc, char * const argv[], char * const user_env[])
 {
     char pathbuf[PATH_MAX];
+    const char *iolog_dir, *iolog_file = NULL;
+    char * const *cur;
     FILE *io_logfile;
     int len;
 
@@ -224,14 +260,30 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
     if (argc == 0)
        return TRUE;
 
-    if (!def_log_input && !def_log_output && !def_use_pty)
+    /*
+     * Pull iolog_dir and iolog_file out of command_info, if present,
+     * falling back to policy module info if not.
+     */
+    iolog_dir = def_iolog_dir;
+    for (cur = command_info; *cur != NULL; cur++) {
+       if (**cur != 'i')
+           continue;
+       if (strncmp(*cur, "iolog_file=", sizeof("iolog_file=") - 1) == 0) {
+           iolog_file = *cur + sizeof("iolog_file=") - 1;
+       } else if (strncmp(*cur, "iolog_dir=", sizeof("iolog_dir=") - 1) == 0) {
+           iolog_dir = *cur + sizeof("iolog_dir=") - 1;
+       }
+    }
+
+    /* If no I/O log file defined there is nothing to do. */
+    if (iolog_file == NULL)
        return FALSE;
 
     /*
      * Build a path containing the session id split into two-digit subdirs,
      * so ID 000001 becomes /var/log/sudo-io/00/00/01.
      */
-    len = build_idpath(pathbuf, sizeof(pathbuf));
+    len = build_idpath(iolog_dir, iolog_file, pathbuf, sizeof(pathbuf));
     if (len == -1)
        return -1;
 
index 0156d893d5ae1ba99474872064072022d7614190..bdc32296abd368c53d7664ee854eeddee0c3bcc2 100644 (file)
@@ -499,8 +499,12 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
            validate_env_vars(sudo_user.env_vars);
     }
 
-    if (ISSET(sudo_mode, (MODE_RUN| MODE_EDIT)) && (def_log_input || def_log_output))
+    if (ISSET(sudo_mode, (MODE_RUN| MODE_EDIT)) && (def_log_input || def_log_output)) {
        io_nextid();
+       command_info[info_len++] = fmt_string("iolog_dir", def_iolog_dir);
+       command_info[info_len++] = fmt_string("iolog_file", sudo_user.sessid);
+    }
+
     log_allowed(validated);
     if (ISSET(sudo_mode, MODE_CHECK))
        rval = display_cmnd(snl, list_pw ? list_pw : sudo_user.pw);