Diff for /embedaddon/sudo/plugins/sudoers/iolog_path.c between versions 1.1.1.2 and 1.1.1.6

version 1.1.1.2, 2012/05/29 12:26:49 version 1.1.1.6, 2014/06/15 16:12:54
Line 1 Line 1
 /*  /*
 * Copyright (c) 2011 Todd C. Miller <Todd.Miller@courtesan.com> * Copyright (c) 2011-2013 Todd C. Miller <Todd.Miller@courtesan.com>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above   * purpose with or without fee is hereby granted, provided that the above
Line 35 Line 35
 #ifdef HAVE_STRINGS_H  #ifdef HAVE_STRINGS_H
 # include <strings.h>  # include <strings.h>
 #endif /* HAVE_STRINGS_H */  #endif /* HAVE_STRINGS_H */
 #ifdef HAVE_SETLOCALE  
 # include <locale.h>  
 #endif  
 #include <pwd.h>  #include <pwd.h>
 #include <grp.h>  #include <grp.h>
 #include <time.h>  #include <time.h>
Line 46 Line 43
   
 struct path_escape {  struct path_escape {
     const char *name;      const char *name;
    size_t (*copy_fn)(char *, size_t);    size_t (*copy_fn)(char *, size_t, char *);
 };  };
   
 static size_t fill_seq(char *, size_t);  
 static size_t fill_user(char *, size_t);  
 static size_t fill_group(char *, size_t);  
 static size_t fill_runas_user(char *, size_t);  
 static size_t fill_runas_group(char *, size_t);  
 static size_t fill_hostname(char *, size_t);  
 static size_t fill_command(char *, size_t);  
   
 static struct path_escape escapes[] = {  
     { "seq", fill_seq },  
     { "user", fill_user },  
     { "group", fill_group },  
     { "runas_user", fill_runas_user },  
     { "runas_group", fill_runas_group },  
     { "hostname", fill_hostname },  
     { "command", fill_command },  
     { NULL, NULL }  
 };  
   
 static size_t  static size_t
fill_seq(char *str, size_t strsize)fill_seq(char *str, size_t strsize, char *logdir)
 {  {
   #ifdef SUDOERS_NO_SEQ
       debug_decl(fill_seq, SUDO_DEBUG_UTIL)
       debug_return_size_t(strlcpy(str, "%{seq}", strsize));
   #else
     static char sessid[7];      static char sessid[7];
     int len;      int len;
    debug_decl(sudoers_io_version, SUDO_DEBUG_UTIL)    debug_decl(fill_seq, SUDO_DEBUG_UTIL)
   
     if (sessid[0] == '\0')      if (sessid[0] == '\0')
        io_nextid(def_iolog_dir, sessid);        io_nextid(logdir, def_iolog_dir, sessid);
   
     /* Path is of the form /var/log/sudo-io/00/00/01. */      /* Path is of the form /var/log/sudo-io/00/00/01. */
     len = snprintf(str, strsize, "%c%c/%c%c/%c%c", sessid[0],      len = snprintf(str, strsize, "%c%c/%c%c/%c%c", sessid[0],
Line 84  fill_seq(char *str, size_t strsize) Line 66  fill_seq(char *str, size_t strsize)
     if (len < 0)      if (len < 0)
         debug_return_size_t(strsize); /* handle non-standard snprintf() */          debug_return_size_t(strsize); /* handle non-standard snprintf() */
     debug_return_size_t(len);      debug_return_size_t(len);
   #endif /* SUDOERS_NO_SEQ */
 }  }
   
 static size_t  static size_t
fill_user(char *str, size_t strsize)fill_user(char *str, size_t strsize, char *unused)
 {  {
     debug_decl(fill_user, SUDO_DEBUG_UTIL)      debug_decl(fill_user, SUDO_DEBUG_UTIL)
     debug_return_size_t(strlcpy(str, user_name, strsize));      debug_return_size_t(strlcpy(str, user_name, strsize));
 }  }
   
 static size_t  static size_t
fill_group(char *str, size_t strsize)fill_group(char *str, size_t strsize, char *unused)
 {  {
     struct group *grp;      struct group *grp;
     size_t len;      size_t len;
Line 102  fill_group(char *str, size_t strsize) Line 85  fill_group(char *str, size_t strsize)
   
     if ((grp = sudo_getgrgid(user_gid)) != NULL) {      if ((grp = sudo_getgrgid(user_gid)) != NULL) {
         len = strlcpy(str, grp->gr_name, strsize);          len = strlcpy(str, grp->gr_name, strsize);
        gr_delref(grp);        sudo_gr_delref(grp);
     } else {      } else {
         len = strlen(str);          len = strlen(str);
         len = snprintf(str + len, strsize - len, "#%u",          len = snprintf(str + len, strsize - len, "#%u",
Line 112  fill_group(char *str, size_t strsize) Line 95  fill_group(char *str, size_t strsize)
 }  }
   
 static size_t  static size_t
fill_runas_user(char *str, size_t strsize)fill_runas_user(char *str, size_t strsize, char *unused)
 {  {
     debug_decl(fill_runas_user, SUDO_DEBUG_UTIL)      debug_decl(fill_runas_user, SUDO_DEBUG_UTIL)
     debug_return_size_t(strlcpy(str, runas_pw->pw_name, strsize));      debug_return_size_t(strlcpy(str, runas_pw->pw_name, strsize));
 }  }
   
 static size_t  static size_t
fill_runas_group(char *str, size_t strsize)fill_runas_group(char *str, size_t strsize, char *unused)
 {  {
     struct group *grp;      struct group *grp;
     size_t len;      size_t len;
Line 130  fill_runas_group(char *str, size_t strsize) Line 113  fill_runas_group(char *str, size_t strsize)
     } else {      } else {
         if ((grp = sudo_getgrgid(runas_pw->pw_gid)) != NULL) {          if ((grp = sudo_getgrgid(runas_pw->pw_gid)) != NULL) {
             len = strlcpy(str, grp->gr_name, strsize);              len = strlcpy(str, grp->gr_name, strsize);
            gr_delref(grp);            sudo_gr_delref(grp);
         } else {          } else {
             len = strlen(str);              len = strlen(str);
             len = snprintf(str + len, strsize - len, "#%u",              len = snprintf(str + len, strsize - len, "#%u",
Line 141  fill_runas_group(char *str, size_t strsize) Line 124  fill_runas_group(char *str, size_t strsize)
 }  }
   
 static size_t  static size_t
fill_hostname(char *str, size_t strsize)fill_hostname(char *str, size_t strsize, char *unused)
 {  {
     debug_decl(fill_hostname, SUDO_DEBUG_UTIL)      debug_decl(fill_hostname, SUDO_DEBUG_UTIL)
     debug_return_size_t(strlcpy(str, user_shost, strsize));      debug_return_size_t(strlcpy(str, user_shost, strsize));
 }  }
   
 static size_t  static size_t
fill_command(char *str, size_t strsize)fill_command(char *str, size_t strsize, char *unused)
 {  {
     debug_decl(fill_command, SUDO_DEBUG_UTIL)      debug_decl(fill_command, SUDO_DEBUG_UTIL)
     debug_return_size_t(strlcpy(str, user_base, strsize));      debug_return_size_t(strlcpy(str, user_base, strsize));
 }  }
   
   /* Note: "seq" must be first in the list. */
   static struct path_escape io_path_escapes[] = {
       { "seq", fill_seq },
       { "user", fill_user },
       { "group", fill_group },
       { "runas_user", fill_runas_user },
       { "runas_group", fill_runas_group },
       { "hostname", fill_hostname },
       { "command", fill_command },
       { NULL, NULL }
   };
   
 /*  /*
  * Concatenate dir + file, expanding any escape sequences.   * Concatenate dir + file, expanding any escape sequences.
  * Returns the concatenated path and sets slashp point to   * Returns the concatenated path and sets slashp point to
Line 165  expand_iolog_path(const char *prefix, const char *dir, Line 160  expand_iolog_path(const char *prefix, const char *dir,
 {  {
     size_t len, prelen = 0;      size_t len, prelen = 0;
     char *dst, *dst0, *path, *pathend, tmpbuf[PATH_MAX];      char *dst, *dst0, *path, *pathend, tmpbuf[PATH_MAX];
       char *slash = NULL;
     const char *endbrace, *src = dir;      const char *endbrace, *src = dir;
    int pass;    struct path_escape *escapes = NULL;
     int pass, oldlocale;
     bool strfit;      bool strfit;
     debug_decl(expand_iolog_path, SUDO_DEBUG_UTIL)      debug_decl(expand_iolog_path, SUDO_DEBUG_UTIL)
   
Line 193  expand_iolog_path(const char *prefix, const char *dir, Line 190  expand_iolog_path(const char *prefix, const char *dir,
         switch (pass) {          switch (pass) {
         case 0:          case 0:
             src = dir;              src = dir;
               escapes = io_path_escapes + 1; /* skip "%{seq}" */
             break;              break;
         case 1:          case 1:
             /* Trim trailing slashes from dir component. */              /* Trim trailing slashes from dir component. */
            while (dst - path - 1 > prelen && dst[-1] == '/')            while (dst > path + prelen + 1 && dst[-1] == '/')
                 dst--;                  dst--;
            if (slashp)            /* The NUL will be replaced with a '/' at the end. */
                *slashp = dst;            if (dst + 1 >= pathend)
            src = "/";                goto bad;
            break;            slash = dst++;
             continue;
         case 2:          case 2:
             src = file;              src = file;
               escapes = io_path_escapes;
             break;              break;
         }          }
         dst0 = dst;          dst0 = dst;
Line 220  expand_iolog_path(const char *prefix, const char *dir, Line 220  expand_iolog_path(const char *prefix, const char *dir,
                                 break;                                  break;
                         }                          }
                         if (esc->name != NULL) {                          if (esc->name != NULL) {
                            len = esc->copy_fn(dst, (size_t)(pathend - dst));                            len = esc->copy_fn(dst, (size_t)(pathend - dst),
                                 path + prelen);
                             if (len >= (size_t)(pathend - dst))                              if (len >= (size_t)(pathend - dst))
                                 goto bad;                                  goto bad;
                             dst += len;                              dst += len;
Line 249  expand_iolog_path(const char *prefix, const char *dir, Line 250  expand_iolog_path(const char *prefix, const char *dir,
             struct tm *timeptr;              struct tm *timeptr;
   
             time(&now);              time(&now);
            timeptr = localtime(&now);            if ((timeptr = localtime(&now)) == NULL)
                 goto bad;
   
#ifdef HAVE_SETLOCALE            /* Use sudoers locale for strftime() */
            if (!setlocale(LC_ALL, def_sudoers_locale)) {            sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
                warningx(_("unable to set locale to \"%s\", using \"C\""),
                    def_sudoers_locale);            /* We only call strftime() on the current part of the buffer. */
                setlocale(LC_ALL, "C"); 
            } 
#endif 
            /* We only calls strftime() on the current part of the buffer. */ 
             tmpbuf[sizeof(tmpbuf) - 1] = '\0';              tmpbuf[sizeof(tmpbuf) - 1] = '\0';
             len = strftime(tmpbuf, sizeof(tmpbuf), dst0, timeptr);              len = strftime(tmpbuf, sizeof(tmpbuf), dst0, timeptr);
   
#ifdef HAVE_SETLOCALE            /* Restore old locale. */
            setlocale(LC_ALL, "");            sudoers_setlocale(oldlocale, NULL);
#endif
             if (len == 0 || tmpbuf[sizeof(tmpbuf) - 1] != '\0')              if (len == 0 || tmpbuf[sizeof(tmpbuf) - 1] != '\0')
                 goto bad;               /* strftime() failed, buf too small? */                  goto bad;               /* strftime() failed, buf too small? */
   
Line 275  expand_iolog_path(const char *prefix, const char *dir, Line 273  expand_iolog_path(const char *prefix, const char *dir,
             *dst = '\0';              *dst = '\0';
         }          }
     }      }
       if (slashp)
           *slashp = slash;
       *slash = '/';
   
     debug_return_str(path);      debug_return_str(path);
 bad:  bad:

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.6


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>