Diff for /embedaddon/sudo/plugins/sudoers/visudo.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2012/10/09 09:29:52 version 1.1.1.4, 2013/07/22 10:46:12
Line 1 Line 1
 /*  /*
 * Copyright (c) 1996, 1998-2005, 2007-2012 * Copyright (c) 1996, 1998-2005, 2007-2013
  *      Todd C. Miller <Todd.Miller@courtesan.com>   *      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
Line 32 Line 32
 #include <config.h>  #include <config.h>
   
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/param.h>  
 #include <sys/stat.h>  #include <sys/stat.h>
 #include <sys/socket.h>  #include <sys/socket.h>
 #include <sys/time.h>  #include <sys/time.h>
   #include <sys/uio.h>
 #ifndef __TANDEM  #ifndef __TANDEM
 # include <sys/file.h>  # include <sys/file.h>
 #endif  #endif
Line 67 Line 67
 #include <fcntl.h>  #include <fcntl.h>
 #include <netinet/in.h>  #include <netinet/in.h>
 #include <arpa/inet.h>  #include <arpa/inet.h>
 #include <netdb.h>  
 #if TIME_WITH_SYS_TIME  #if TIME_WITH_SYS_TIME
 # include <time.h>  # include <time.h>
 #endif  #endif
 #ifdef HAVE_SETLOCALE  
 # include <locale.h>  
 #endif  
   
 #include "sudoers.h"  #include "sudoers.h"
 #include "interfaces.h"  
 #include "parse.h"  #include "parse.h"
 #include "redblack.h"  #include "redblack.h"
 #include "gettext.h"  #include "gettext.h"
Line 94  struct sudoersfile { Line 89  struct sudoersfile {
 };  };
 TQ_DECLARE(sudoersfile)  TQ_DECLARE(sudoersfile)
   
 sudo_conv_t sudo_conv;  /* NULL in non-plugin */  
   
 /*  /*
  * Function prototypes   * Function prototypes
  */   */
Line 109  static bool check_syntax(char *, bool, bool, bool); Line 102  static bool check_syntax(char *, bool, bool, bool);
 static bool edit_sudoers(struct sudoersfile *, char *, char *, int);  static bool edit_sudoers(struct sudoersfile *, char *, char *, int);
 static bool install_sudoers(struct sudoersfile *, bool);  static bool install_sudoers(struct sudoersfile *, bool);
 static int print_unused(void *, void *);  static int print_unused(void *, void *);
static void reparse_sudoers(char *, char *, bool, bool);static bool reparse_sudoers(char *, char *, bool, bool);
 static int run_command(char *, char **);  static int run_command(char *, char **);
 static int visudo_printf(int msg_type, const char *fmt, ...);  
 static void setup_signals(void);  static void setup_signals(void);
 static void help(void) __attribute__((__noreturn__));  static void help(void) __attribute__((__noreturn__));
 static void usage(int);  static void usage(int);
   static void visudo_cleanup(void);
   
void cleanup(int);extern void sudoerserror(const char *);
 extern void sudoersrestart(FILE *);
   
 extern void yyerror(const char *);  
 extern void yyrestart(FILE *);  
   
 /*  /*
  * External globals exported by the parser   * External globals exported by the parser
  */   */
 extern struct rbtree *aliases;  extern struct rbtree *aliases;
extern FILE *yyin;extern FILE *sudoersin;
 extern char *sudoers, *errorfile;  extern char *sudoers, *errorfile;
 extern int errorlineno;  extern int errorlineno;
 extern bool parse_error;  extern bool parse_error;
Line 136  extern int optind; Line 127  extern int optind;
 /*  /*
  * Globals   * Globals
  */   */
 struct interface *interfaces;  
 struct sudo_user sudo_user;  struct sudo_user sudo_user;
 struct passwd *list_pw;  struct passwd *list_pw;
 sudo_printf_t sudo_printf = visudo_printf;  
 static struct sudoersfile_list sudoerslist;  static struct sudoersfile_list sudoerslist;
 static struct rbtree *alias_freelist;  static struct rbtree *alias_freelist;
 static bool checkonly;  static bool checkonly;
   
   __dso_public int main(int argc, char *argv[]);
   
 int  int
 main(int argc, char *argv[])  main(int argc, char *argv[])
 {  {
Line 164  main(int argc, char *argv[]) Line 155  main(int argc, char *argv[])
     setprogname(argc > 0 ? argv[0] : "visudo");      setprogname(argc > 0 ? argv[0] : "visudo");
 #endif  #endif
   
#ifdef HAVE_SETLOCALE     sudoers_setlocale(SUDOERS_LOCALE_USER, NULL);
    setlocale(LC_ALL, ""); 
#endif 
     bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have visudo domain */      bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have visudo domain */
     textdomain("sudoers");      textdomain("sudoers");
   
     if (argc < 1)      if (argc < 1)
         usage(1);          usage(1);
   
       /* Register fatal/fatalx callback. */
       fatal_callback_register(visudo_cleanup);
   
     /* Read sudo.conf. */      /* Read sudo.conf. */
    sudo_conf_read();    sudo_conf_read(NULL);
   
     /*      /*
      * Arg handling.       * Arg handling.
Line 217  main(int argc, char *argv[]) Line 209  main(int argc, char *argv[])
     /* Mock up a fake sudo_user struct. */      /* Mock up a fake sudo_user struct. */
     user_cmnd = "";      user_cmnd = "";
     if ((sudo_user.pw = sudo_getpwuid(getuid())) == NULL)      if ((sudo_user.pw = sudo_getpwuid(getuid())) == NULL)
        errorx(1, _("you do not exist in the %s database"), "passwd");        fatalx(_("you do not exist in the %s database"), "passwd");
     get_hostname();      get_hostname();
   
     /* Setup defaults data structures. */      /* Setup defaults data structures. */
Line 229  main(int argc, char *argv[]) Line 221  main(int argc, char *argv[])
     }      }
   
     /*      /*
     * Parse the existing sudoers file(s) in quiet mode to highlight any     * Parse the existing sudoers file(s) to highlight any existing
     * existing errors and to pull in editor and env_editor conf values.     * errors and to pull in editor and env_editor conf values.
      */       */
    if ((yyin = open_sudoers(sudoers_path, true, NULL)) == NULL) {    if ((sudoersin = open_sudoers(sudoers_path, true, NULL)) == NULL)
        error(1, "%s", sudoers_path);        exit(1);
    } 
     init_parser(sudoers_path, false);      init_parser(sudoers_path, false);
    yyparse();    sudoersparse();
     (void) update_defaults(SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER);      (void) update_defaults(SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER);
   
     editor = get_editor(&args);      editor = get_editor(&args);
Line 256  main(int argc, char *argv[]) Line 247  main(int argc, char *argv[])
         edit_sudoers(sp, editor, args, -1);          edit_sudoers(sp, editor, args, -1);
     }      }
   
    /* Check edited files for a parse error and re-edit any that fail. */    /*
    reparse_sudoers(editor, args, strict, quiet);     * Check edited files for a parse error, re-edit any that fail
     * and install the edited files as needed.
    /* Install the sudoers temp files as needed. */     */
    tq_foreach_fwd(&sudoerslist, sp) {    if (reparse_sudoers(editor, args, strict, quiet)) {
        (void) install_sudoers(sp, oldperms);        tq_foreach_fwd(&sudoerslist, sp) {
             (void) install_sudoers(sp, oldperms);
         }
     }      }
   
 done:  done:
Line 316  edit_sudoers(struct sudoersfile *sp, char *editor, cha Line 309  edit_sudoers(struct sudoersfile *sp, char *editor, cha
     debug_decl(edit_sudoers, SUDO_DEBUG_UTIL)      debug_decl(edit_sudoers, SUDO_DEBUG_UTIL)
   
     if (fstat(sp->fd, &sb) == -1)      if (fstat(sp->fd, &sb) == -1)
        error(1, _("unable to stat %s"), sp->path);        fatal(_("unable to stat %s"), sp->path);
     orig_size = sb.st_size;      orig_size = sb.st_size;
     mtim_get(&sb, &orig_mtim);      mtim_get(&sb, &orig_mtim);
   
Line 325  edit_sudoers(struct sudoersfile *sp, char *editor, cha Line 318  edit_sudoers(struct sudoersfile *sp, char *editor, cha
         easprintf(&sp->tpath, "%s.tmp", sp->path);          easprintf(&sp->tpath, "%s.tmp", sp->path);
         tfd = open(sp->tpath, O_WRONLY | O_CREAT | O_TRUNC, 0600);          tfd = open(sp->tpath, O_WRONLY | O_CREAT | O_TRUNC, 0600);
         if (tfd < 0)          if (tfd < 0)
            error(1, "%s", sp->tpath);            fatal("%s", sp->tpath);
   
         /* Copy sp->path -> sp->tpath and reset the mtime. */          /* Copy sp->path -> sp->tpath and reset the mtime. */
         if (orig_size != 0) {          if (orig_size != 0) {
             (void) lseek(sp->fd, (off_t)0, SEEK_SET);              (void) lseek(sp->fd, (off_t)0, SEEK_SET);
             while ((nread = read(sp->fd, buf, sizeof(buf))) > 0)              while ((nread = read(sp->fd, buf, sizeof(buf))) > 0)
                 if (write(tfd, buf, nread) != nread)                  if (write(tfd, buf, nread) != nread)
                    error(1, _("write error"));                    fatal(_("write error"));
   
             /* Add missing newline at EOF if needed. */              /* Add missing newline at EOF if needed. */
             if (nread > 0 && buf[nread - 1] != '\n') {              if (nread > 0 && buf[nread - 1] != '\n') {
                 buf[0] = '\n';                  buf[0] = '\n';
                 if (write(tfd, buf, 1) != 1)                  if (write(tfd, buf, 1) != 1)
                    error(1, _("write error"));                    fatal(_("write error"));
             }              }
         }          }
         (void) close(tfd);          (void) close(tfd);
Line 464  done: Line 457  done:
 /*  /*
  * Parse sudoers after editing and re-edit any ones that caused a parse error.   * Parse sudoers after editing and re-edit any ones that caused a parse error.
  */   */
static voidstatic bool
 reparse_sudoers(char *editor, char *args, bool strict, bool quiet)  reparse_sudoers(char *editor, char *args, bool strict, bool quiet)
 {  {
     struct sudoersfile *sp, *last;      struct sudoersfile *sp, *last;
Line 472  reparse_sudoers(char *editor, char *args, bool strict, Line 465  reparse_sudoers(char *editor, char *args, bool strict,
     int ch;      int ch;
     debug_decl(reparse_sudoers, SUDO_DEBUG_UTIL)      debug_decl(reparse_sudoers, SUDO_DEBUG_UTIL)
   
     if (tq_empty(&sudoerslist))  
         debug_return;  
   
     /*      /*
      * Parse the edited sudoers files and do sanity checking       * Parse the edited sudoers files and do sanity checking
      */       */
    do {    while ((sp = tq_first(&sudoerslist)) != NULL) {
        sp = tq_first(&sudoerslist); 
         last = tq_last(&sudoerslist);          last = tq_last(&sudoerslist);
         fp = fopen(sp->tpath, "r+");          fp = fopen(sp->tpath, "r+");
         if (fp == NULL)          if (fp == NULL)
            errorx(1, _("unable to re-open temporary file (%s), %s unchanged."),            fatalx(_("unable to re-open temporary file (%s), %s unchanged."),
                 sp->tpath, sp->path);                  sp->tpath, sp->path);
   
         /* Clean slate for each parse */          /* Clean slate for each parse */
         init_defaults();          init_defaults();
         init_parser(sp->path, quiet);          init_parser(sp->path, quiet);
   
        /* Parse the sudoers temp file */        /* Parse the sudoers temp file(s) */
        yyrestart(fp);        sudoersrestart(fp);
        if (yyparse() && !parse_error) {        if (sudoersparse() && !parse_error) {
             warningx(_("unabled to parse temporary file (%s), unknown error"),              warningx(_("unabled to parse temporary file (%s), unknown error"),
                 sp->tpath);                  sp->tpath);
             parse_error = true;              parse_error = true;
             errorfile = sp->path;              errorfile = sp->path;
         }          }
        fclose(yyin);        fclose(sudoersin);
         if (!parse_error) {          if (!parse_error) {
             if (!check_defaults(SETDEF_ALL, quiet) ||              if (!check_defaults(SETDEF_ALL, quiet) ||
                 check_aliases(strict, quiet) != 0) {                  check_aliases(strict, quiet) != 0) {
Line 508  reparse_sudoers(char *editor, char *args, bool strict, Line 497  reparse_sudoers(char *editor, char *args, bool strict,
         }          }
   
         /*          /*
         * Got an error, prompt the user for what to do now         * Got an error, prompt the user for what to do now.
          */           */
         if (parse_error) {          if (parse_error) {
             switch (whatnow()) {              switch (whatnow()) {
                case 'Q' :        parse_error = false;    /* ignore parse error */            case 'Q':
                                break;                parse_error = false;    /* ignore parse error */
                case 'x' :       /* XXX - should return instead of exiting */                break;
                                cleanup(0);            case 'x':
                                sudo_debug_exit_int(__func__, __FILE__,                visudo_cleanup();      /* discard changes */
                                    __LINE__, sudo_debug_subsys, 0);                debug_return_bool(false);
                                exit(0);            case 'e':
                                break;            default:
            }                /* Edit file with the parse error */
        }                tq_foreach_fwd(&sudoerslist, sp) {
        if (parse_error) {                    if (errorfile == NULL || strcmp(sp->path, errorfile) == 0) {
            /* Edit file with the parse error */                        edit_sudoers(sp, editor, args, errorlineno);
            tq_foreach_fwd(&sudoerslist, sp) {                        if (errorfile != NULL)
                if (errorfile == NULL || strcmp(sp->path, errorfile) == 0) {                            break;
                    edit_sudoers(sp, editor, args, errorlineno);                    }
                    if (errorfile != NULL) 
                        break; 
                 }                  }
                   if (errorfile != NULL && sp == NULL) {
                       fatalx(_("internal error, unable to find %s in list!"),
                           sudoers);
                   }
                   break;
             }              }
             if (errorfile != NULL && sp == NULL) {  
                 errorx(1, _("internal error, unable to find %s in list!"),  
                     sudoers);  
             }  
         }          }
   
         /* If any new #include directives were added, edit them too. */          /* If any new #include directives were added, edit them too. */
Line 544  reparse_sudoers(char *editor, char *args, bool strict, Line 532  reparse_sudoers(char *editor, char *args, bool strict,
                     continue;                      continue;
             edit_sudoers(sp, editor, args, errorlineno);              edit_sudoers(sp, editor, args, errorlineno);
         }          }
     } while (parse_error);  
   
    debug_return;        /* If all sudoers files parsed OK we are done. */
         if (!parse_error)
             break;
     }
 
     debug_return_bool(true);
 }  }
   
 /*  /*
Line 582  install_sudoers(struct sudoersfile *sp, bool oldperms) Line 574  install_sudoers(struct sudoersfile *sp, bool oldperms)
     if (oldperms) {      if (oldperms) {
         /* Use perms of the existing file.  */          /* Use perms of the existing file.  */
         if (fstat(sp->fd, &sb) == -1)          if (fstat(sp->fd, &sb) == -1)
            error(1, _("unable to stat %s"), sp->path);            fatal(_("unable to stat %s"), sp->path);
         if (chown(sp->tpath, sb.st_uid, sb.st_gid) != 0) {          if (chown(sp->tpath, sb.st_uid, sb.st_gid) != 0) {
             warning(_("unable to set (uid, gid) of %s to (%u, %u)"),              warning(_("unable to set (uid, gid) of %s to (%u, %u)"),
                 sp->tpath, (unsigned int)sb.st_uid, (unsigned int)sb.st_gid);                  sp->tpath, (unsigned int)sb.st_uid, (unsigned int)sb.st_gid);
Line 651  done: Line 643  done:
   
 /* STUB */  /* STUB */
 void  void
 set_fqdn(void)  
 {  
     return;  
 }  
   
 /* STUB */  
 void  
 init_envtables(void)  init_envtables(void)
 {  {
     return;      return;
Line 691  group_plugin_query(const char *user, const char *group Line 676  group_plugin_query(const char *user, const char *group
     return false;      return false;
 }  }
   
   /* STUB */
   struct interface *get_interfaces(void)
   {
       return NULL;
   }
   
 /*  /*
  * Assuming a parse error occurred, prompt the user for what they want   * Assuming a parse error occurred, prompt the user for what they want
  * to do now.  Returns the first letter of their choice.   * to do now.  Returns the first letter of their choice.
Line 757  run_command(char *path, char **argv) Line 748  run_command(char *path, char **argv)
   
     switch (pid = sudo_debug_fork()) {      switch (pid = sudo_debug_fork()) {
         case -1:          case -1:
            error(1, _("unable to execute %s"), path);            fatal(_("unable to execute %s"), path);
             break;      /* NOTREACHED */              break;      /* NOTREACHED */
         case 0:          case 0:
             sudo_endpwent();              sudo_endpwent();
Line 812  check_syntax(char *sudoers_path, bool quiet, bool stri Line 803  check_syntax(char *sudoers_path, bool quiet, bool stri
     debug_decl(check_syntax, SUDO_DEBUG_UTIL)      debug_decl(check_syntax, SUDO_DEBUG_UTIL)
   
     if (strcmp(sudoers_path, "-") == 0) {      if (strcmp(sudoers_path, "-") == 0) {
        yyin = stdin;        sudoersin = stdin;
         sudoers_path = "stdin";          sudoers_path = "stdin";
    } else if ((yyin = fopen(sudoers_path, "r")) == NULL) {    } else if ((sudoersin = fopen(sudoers_path, "r")) == NULL) {
         if (!quiet)          if (!quiet)
             warning(_("unable to open %s"), sudoers_path);              warning(_("unable to open %s"), sudoers_path);
         goto done;          goto done;
     }      }
     init_parser(sudoers_path, quiet);      init_parser(sudoers_path, quiet);
    if (yyparse() && !parse_error) {    if (sudoersparse() && !parse_error) {
         if (!quiet)          if (!quiet)
             warningx(_("failed to parse %s file, unknown error"), sudoers_path);              warningx(_("failed to parse %s file, unknown error"), sudoers_path);
         parse_error = true;          parse_error = true;
Line 840  check_syntax(char *sudoers_path, bool quiet, bool stri Line 831  check_syntax(char *sudoers_path, bool quiet, bool stri
             if (errorlineno != -1)              if (errorlineno != -1)
                 (void) printf(_("parse error in %s near line %d\n"),                  (void) printf(_("parse error in %s near line %d\n"),
                     errorfile, errorlineno);                      errorfile, errorlineno);
            else            else if (errorfile != NULL)
                 (void) printf(_("parse error in %s\n"), errorfile);                  (void) printf(_("parse error in %s\n"), errorfile);
         }          }
     } else {      } else {
Line 900  open_sudoers(const char *path, bool doedit, bool *keep Line 891  open_sudoers(const char *path, bool doedit, bool *keep
             debug_return_ptr(NULL);              debug_return_ptr(NULL);
         }          }
         if (!checkonly && !lock_file(entry->fd, SUDO_TLOCK))          if (!checkonly && !lock_file(entry->fd, SUDO_TLOCK))
            errorx(1, _("%s busy, try again later"), entry->path);            fatalx(_("%s busy, try again later"), entry->path);
         if ((fp = fdopen(entry->fd, "r")) == NULL)          if ((fp = fdopen(entry->fd, "r")) == NULL)
            error(1, "%s", entry->path);            fatal("%s", entry->path);
         tq_append(&sudoerslist, entry);          tq_append(&sudoerslist, entry);
     } else {      } else {
         /* Already exists, open .tmp version if there is one. */          /* Already exists, open .tmp version if there is one. */
         if (entry->tpath != NULL) {          if (entry->tpath != NULL) {
             if ((fp = fopen(entry->tpath, "r")) == NULL)              if ((fp = fopen(entry->tpath, "r")) == NULL)
                error(1, "%s", entry->tpath);                fatal("%s", entry->tpath);
         } else {          } else {
             if ((fp = fdopen(entry->fd, "r")) == NULL)              if ((fp = fdopen(entry->fd, "r")) == NULL)
                error(1, "%s", entry->path);                fatal("%s", entry->path);
             rewind(fp);              rewind(fp);
         }          }
     }      }
Line 944  get_editor(char **args) Line 935  get_editor(char **args)
         } else {          } else {
             if (def_env_editor) {              if (def_env_editor) {
                 /* If we are honoring $EDITOR this is a fatal error. */                  /* If we are honoring $EDITOR this is a fatal error. */
                errorx(1, _("specified editor (%s) doesn't exist"), UserEditor);                fatalx(_("specified editor (%s) doesn't exist"), UserEditor);
             } else {              } else {
                 /* Otherwise, just ignore $EDITOR. */                  /* Otherwise, just ignore $EDITOR. */
                 UserEditor = NULL;                  UserEditor = NULL;
Line 967  get_editor(char **args) Line 958  get_editor(char **args)
   
         if (stat(UserEditor, &user_editor_sb) != 0) {          if (stat(UserEditor, &user_editor_sb) != 0) {
             /* Should never happen since we already checked above. */              /* Should never happen since we already checked above. */
            error(1, _("unable to stat editor (%s)"), UserEditor);            fatal(_("unable to stat editor (%s)"), UserEditor);
         }          }
         EditorPath = estrdup(def_editor);          EditorPath = estrdup(def_editor);
         Editor = strtok(EditorPath, ":");          Editor = strtok(EditorPath, ":");
Line 1015  get_editor(char **args) Line 1006  get_editor(char **args)
   
         /* Bleah, none of the editors existed! */          /* Bleah, none of the editors existed! */
         if (Editor == NULL || *Editor == '\0')          if (Editor == NULL || *Editor == '\0')
            errorx(1, _("no editor found (editor path = %s)"), def_editor);            fatalx(_("no editor found (editor path = %s)"), def_editor);
     }      }
     *args = EditorArgs;      *args = EditorArgs;
     debug_return_str(Editor);      debug_return_str(Editor);
Line 1047  get_args(char *cmnd) Line 1038  get_args(char *cmnd)
 static void  static void
 get_hostname(void)  get_hostname(void)
 {  {
    char *p, thost[MAXHOSTNAMELEN + 1];    char *p, thost[HOST_NAME_MAX + 1];
     debug_decl(get_hostname, SUDO_DEBUG_UTIL)      debug_decl(get_hostname, SUDO_DEBUG_UTIL)
   
     if (gethostname(thost, sizeof(thost)) != -1) {      if (gethostname(thost, sizeof(thost)) != -1) {
Line 1075  alias_remove_recursive(char *name, int type) Line 1066  alias_remove_recursive(char *name, int type)
     bool rval = true;      bool rval = true;
     debug_decl(alias_remove_recursive, SUDO_DEBUG_ALIAS)      debug_decl(alias_remove_recursive, SUDO_DEBUG_ALIAS)
   
    if ((a = alias_find(name, type)) != NULL) {    if ((a = alias_remove(name, type)) != NULL) {
         tq_foreach_fwd(&a->members, m) {          tq_foreach_fwd(&a->members, m) {
             if (m->type == ALIAS) {              if (m->type == ALIAS) {
                 if (!alias_remove_recursive(m->name, type))                  if (!alias_remove_recursive(m->name, type))
                     rval = false;                      rval = false;
             }              }
         }          }
     }  
     alias_seqno++;  
     a = alias_remove(name, type);  
     if (a)  
         rbinsert(alias_freelist, a);          rbinsert(alias_freelist, a);
       }
     debug_return_bool(rval);      debug_return_bool(rval);
 }  }
   
Line 1098  check_alias(char *name, int type, int strict, int quie Line 1086  check_alias(char *name, int type, int strict, int quie
     int errors = 0;      int errors = 0;
     debug_decl(check_alias, SUDO_DEBUG_ALIAS)      debug_decl(check_alias, SUDO_DEBUG_ALIAS)
   
    if ((a = alias_find(name, type)) != NULL) {    if ((a = alias_get(name, type)) != NULL) {
         /* check alias contents */          /* check alias contents */
         tq_foreach_fwd(&a->members, m) {          tq_foreach_fwd(&a->members, m) {
             if (m->type == ALIAS)              if (m->type == ALIAS)
                 errors += check_alias(m->name, type, strict, quiet);                  errors += check_alias(m->name, type, strict, quiet);
         }          }
           alias_put(a);
     } else {      } else {
         if (!quiet) {          if (!quiet) {
             char *fmt;              char *fmt;
Line 1148  check_aliases(bool strict, bool quiet) Line 1137  check_aliases(bool strict, bool quiet)
     tq_foreach_fwd(&userspecs, us) {      tq_foreach_fwd(&userspecs, us) {
         tq_foreach_fwd(&us->users, m) {          tq_foreach_fwd(&us->users, m) {
             if (m->type == ALIAS) {              if (m->type == ALIAS) {
                 alias_seqno++;  
                 errors += check_alias(m->name, USERALIAS, strict, quiet);                  errors += check_alias(m->name, USERALIAS, strict, quiet);
             }              }
         }          }
         tq_foreach_fwd(&us->privileges, priv) {          tq_foreach_fwd(&us->privileges, priv) {
             tq_foreach_fwd(&priv->hostlist, m) {              tq_foreach_fwd(&priv->hostlist, m) {
                 if (m->type == ALIAS) {                  if (m->type == ALIAS) {
                     alias_seqno++;  
                     errors += check_alias(m->name, HOSTALIAS, strict, quiet);                      errors += check_alias(m->name, HOSTALIAS, strict, quiet);
                 }                  }
             }              }
             tq_foreach_fwd(&priv->cmndlist, cs) {              tq_foreach_fwd(&priv->cmndlist, cs) {
                 tq_foreach_fwd(&cs->runasuserlist, m) {                  tq_foreach_fwd(&cs->runasuserlist, m) {
                     if (m->type == ALIAS) {                      if (m->type == ALIAS) {
                         alias_seqno++;  
                         errors += check_alias(m->name, RUNASALIAS, strict, quiet);                          errors += check_alias(m->name, RUNASALIAS, strict, quiet);
                     }                      }
                 }                  }
                 if ((m = cs->cmnd)->type == ALIAS) {                  if ((m = cs->cmnd)->type == ALIAS) {
                     alias_seqno++;  
                     errors += check_alias(m->name, CMNDALIAS, strict, quiet);                      errors += check_alias(m->name, CMNDALIAS, strict, quiet);
                 }                  }
             }              }
Line 1178  check_aliases(bool strict, bool quiet) Line 1163  check_aliases(bool strict, bool quiet)
     tq_foreach_fwd(&userspecs, us) {      tq_foreach_fwd(&userspecs, us) {
         tq_foreach_fwd(&us->users, m) {          tq_foreach_fwd(&us->users, m) {
             if (m->type == ALIAS) {              if (m->type == ALIAS) {
                 alias_seqno++;  
                 if (!alias_remove_recursive(m->name, USERALIAS))                  if (!alias_remove_recursive(m->name, USERALIAS))
                     errors++;                      errors++;
             }              }
Line 1186  check_aliases(bool strict, bool quiet) Line 1170  check_aliases(bool strict, bool quiet)
         tq_foreach_fwd(&us->privileges, priv) {          tq_foreach_fwd(&us->privileges, priv) {
             tq_foreach_fwd(&priv->hostlist, m) {              tq_foreach_fwd(&priv->hostlist, m) {
                 if (m->type == ALIAS) {                  if (m->type == ALIAS) {
                     alias_seqno++;  
                     if (!alias_remove_recursive(m->name, HOSTALIAS))                      if (!alias_remove_recursive(m->name, HOSTALIAS))
                         errors++;                          errors++;
                 }                  }
Line 1194  check_aliases(bool strict, bool quiet) Line 1177  check_aliases(bool strict, bool quiet)
             tq_foreach_fwd(&priv->cmndlist, cs) {              tq_foreach_fwd(&priv->cmndlist, cs) {
                 tq_foreach_fwd(&cs->runasuserlist, m) {                  tq_foreach_fwd(&cs->runasuserlist, m) {
                     if (m->type == ALIAS) {                      if (m->type == ALIAS) {
                         alias_seqno++;  
                         if (!alias_remove_recursive(m->name, RUNASALIAS))                          if (!alias_remove_recursive(m->name, RUNASALIAS))
                             errors++;                              errors++;
                     }                      }
                 }                  }
                 if ((m = cs->cmnd)->type == ALIAS) {                  if ((m = cs->cmnd)->type == ALIAS) {
                     alias_seqno++;  
                     if (!alias_remove_recursive(m->name, CMNDALIAS))                      if (!alias_remove_recursive(m->name, CMNDALIAS))
                         errors++;                          errors++;
                 }                  }
Line 1227  check_aliases(bool strict, bool quiet) Line 1208  check_aliases(bool strict, bool quiet)
         tq_foreach_fwd(&d->binding, binding) {          tq_foreach_fwd(&d->binding, binding) {
             for (m = binding; m != NULL; m = m->next) {              for (m = binding; m != NULL; m = m->next) {
                 if (m->type == ALIAS) {                  if (m->type == ALIAS) {
                     alias_seqno++;  
                     if (!alias_remove_recursive(m->name, atype))                      if (!alias_remove_recursive(m->name, atype))
                         errors++;                          errors++;
                 }                  }
Line 1249  print_unused(void *v1, void *v2) Line 1229  print_unused(void *v1, void *v2)
     struct alias *a = (struct alias *)v1;      struct alias *a = (struct alias *)v1;
     char *prefix = (char *)v2;      char *prefix = (char *)v2;
   
    warningx2(_("%s: unused %s_Alias %s"), prefix,    warningx_nodebug(_("%s: unused %s_Alias %s"), prefix,
         a->type == HOSTALIAS ? "Host" : a->type == CMNDALIAS ? "Cmnd" :          a->type == HOSTALIAS ? "Host" : a->type == CMNDALIAS ? "Cmnd" :
         a->type == USERALIAS ? "User" : a->type == RUNASALIAS ? "Runas" :          a->type == USERALIAS ? "User" : a->type == RUNASALIAS ? "Runas" :
         "Unknown", a->name);          "Unknown", a->name);
Line 1259  print_unused(void *v1, void *v2) Line 1239  print_unused(void *v1, void *v2)
 /*  /*
  * Unlink any sudoers temp files that remain.   * Unlink any sudoers temp files that remain.
  */   */
voidstatic void
cleanup(int gotsignal)visudo_cleanup(void)
 {  {
     struct sudoersfile *sp;      struct sudoersfile *sp;
   
Line 1268  cleanup(int gotsignal) Line 1248  cleanup(int gotsignal)
         if (sp->tpath != NULL)          if (sp->tpath != NULL)
             (void) unlink(sp->tpath);              (void) unlink(sp->tpath);
     }      }
    if (!gotsignal) {    sudo_endpwent();
        sudo_endpwent();    sudo_endgrent();
        sudo_endgrent(); 
    } 
 }  }
   
 /*  /*
Line 1280  cleanup(int gotsignal) Line 1258  cleanup(int gotsignal)
 static void  static void
 quit(int signo)  quit(int signo)
 {  {
    const char *signame, *myname;    struct sudoersfile *sp;
     struct iovec iov[4];
   
    cleanup(signo);    tq_foreach_fwd(&sudoerslist, sp) {
         if (sp->tpath != NULL)
             (void) unlink(sp->tpath);
     }
 
 #define emsg     " exiting due to signal: "  #define emsg     " exiting due to signal: "
    myname = getprogname();    iov[0].iov_base = (char *)getprogname();
    signame = strsignal(signo);    iov[0].iov_len = strlen(iov[0].iov_base);
    ignore_result(write(STDERR_FILENO, myname, strlen(myname)));    iov[1].iov_base = emsg;
    ignore_result(write(STDERR_FILENO, emsg, sizeof(emsg) - 1));    iov[1].iov_len = sizeof(emsg) - 1;
    ignore_result(write(STDERR_FILENO, signame, strlen(signame)));    iov[2].iov_base = strsignal(signo);
    ignore_result(write(STDERR_FILENO, "\n", 1));    iov[2].iov_len = strlen(iov[2].iov_base);
     iov[3].iov_base = "\n";
     iov[3].iov_len = 1;
     ignore_result(writev(STDERR_FILENO, iov, 4));
     _exit(signo);      _exit(signo);
 }  }
   
Line 1315  help(void) Line 1301  help(void)
         "  -s          strict syntax checking\n"          "  -s          strict syntax checking\n"
         "  -V          display version information and exit"));          "  -V          display version information and exit"));
     exit(0);      exit(0);
 }  
   
 static int  
 visudo_printf(int msg_type, const char *fmt, ...)  
 {  
     va_list ap;  
     FILE *fp;  
               
     switch (msg_type) {  
     case SUDO_CONV_INFO_MSG:  
         fp = stdout;  
         break;  
     case SUDO_CONV_ERROR_MSG:  
         fp = stderr;  
         break;  
     default:  
         errno = EINVAL;  
         return -1;  
     }  
      
     va_start(ap, fmt);  
     vfprintf(fp, fmt, ap);  
     va_end(ap);  
      
     return 0;  
 }  }

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.4


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