--- embedaddon/sudo/plugins/sudoers/testsudoers.c 2012/10/09 09:29:52 1.1.1.3 +++ embedaddon/sudo/plugins/sudoers/testsudoers.c 2014/06/15 16:12:54 1.1.1.6 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 1998-2005, 2007-2012 + * Copyright (c) 1996, 1998-2005, 2007-2013 * Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any @@ -25,7 +25,6 @@ #include -#include #include #include #include @@ -59,10 +58,6 @@ #include #include #include -#include -#ifdef HAVE_SETLOCALE -# include -#endif #include "tsgetgrpw.h" #include "sudoers.h" @@ -81,11 +76,9 @@ void print_defaults(void); void print_privilege(struct privilege *); void print_userspecs(void); void usage(void) __attribute__((__noreturn__)); -void cleanup(int); static void set_runaspw(const char *); static void set_runasgr(const char *); static int cb_runas_default(const char *); -static int testsudoers_printf(int msg_type, const char *fmt, ...); static int testsudoers_print(const char *msg); extern void setgrfile(const char *); @@ -106,27 +99,19 @@ extern int (*trace_print)(const char *msg); /* * Globals */ -struct interface *interfaces; struct sudo_user sudo_user; struct passwd *list_pw; static char *runas_group, *runas_user; -extern int errorlineno; -extern bool parse_error; -extern char *errorfile; -sudo_printf_t sudo_printf = testsudoers_printf; -sudo_conv_t sudo_conv; /* NULL in non-plugin */ -/* For getopt(3) */ -extern char *optarg; -extern int optind; - #if defined(SUDO_DEVEL) && defined(__OpenBSD__) extern char *malloc_options; #endif #ifdef YYDEBUG -extern int yydebug; +extern int sudoersdebug; #endif +__dso_public int main(int argc, char *argv[]); + int main(int argc, char *argv[]) { @@ -134,7 +119,8 @@ main(int argc, char *argv[]) struct privilege *priv; struct userspec *us; char *p, *grfile, *pwfile; - char hbuf[MAXHOSTNAMELEN + 1]; + char hbuf[HOST_NAME_MAX + 1]; + const char *errstr; int match, host_match, runas_match, cmnd_match; int ch, dflag, exitcode = 0; debug_decl(main, SUDO_DEBUG_MAIN) @@ -143,21 +129,17 @@ main(int argc, char *argv[]) malloc_options = "AFGJPR"; #endif #ifdef YYDEBUG - yydebug = 1; + sudoersdebug = 1; #endif -#if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME) - setprogname(argc > 0 ? argv[0] : "testsudoers"); -#endif + initprogname(argc > 0 ? argv[0] : "testsudoers"); -#ifdef HAVE_SETLOCALE - setlocale(LC_ALL, ""); -#endif + sudoers_initlocale(setlocale(LC_ALL, ""), def_sudoers_locale); bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have own domain */ textdomain("sudoers"); /* Read sudo.conf. */ - sudo_conf_read(); + sudo_conf_read(NULL); dflag = 0; grfile = pwfile = NULL; @@ -170,7 +152,9 @@ main(int argc, char *argv[]) user_host = optarg; break; case 'G': - sudoers_gid = (gid_t)atoi(optarg); + sudoers_gid = (gid_t)atoid(optarg, NULL, NULL, &errstr); + if (errstr != NULL) + fatalx("group ID %s: %s", optarg, errstr); break; case 'g': runas_group = optarg; @@ -185,7 +169,9 @@ main(int argc, char *argv[]) trace_print = testsudoers_print; break; case 'U': - sudoers_uid = (uid_t)atoi(optarg); + sudoers_uid = (uid_t)atoid(optarg, NULL, NULL, &errstr); + if (errstr != NULL) + fatalx("user ID %s: %s", optarg, errstr); break; case 'u': runas_user = optarg; @@ -222,11 +208,11 @@ main(int argc, char *argv[]) argc -= 2; } if ((sudo_user.pw = sudo_getpwnam(user_name)) == NULL) - errorx(1, _("unknown user: %s"), user_name); + fatalx(U_("unknown user: %s"), user_name); if (user_host == NULL) { if (gethostname(hbuf, sizeof(hbuf)) != 0) - error(1, "gethostname"); + fatal("gethostname"); hbuf[sizeof(hbuf) - 1] = '\0'; user_host = hbuf; } @@ -237,6 +223,8 @@ main(int argc, char *argv[]) } else { user_shost = user_host; } + user_runhost = user_host; + user_srunhost = user_shost; /* Fill in user_args from argv. */ if (argc > 0) { @@ -250,7 +238,7 @@ main(int argc, char *argv[]) for (to = user_args, from = argv; *from; from++) { n = strlcpy(to, *from, size - (to - user_args)); if (n >= size - (to - user_args)) - errorx(1, _("internal error, %s overflow"), "init_vars()"); + fatalx(U_("internal error, %s overflow"), "init_vars()"); to += n; *to++ = ' '; } @@ -270,7 +258,7 @@ main(int argc, char *argv[]) /* Allocate space for data structures in the parser. */ init_parser("sudoers", false); - if (yyparse() != 0 || parse_error) { + if (sudoersparse() != 0 || parse_error) { parse_error = true; if (errorlineno != -1) (void) printf("Parse error in %s near line %d", @@ -312,19 +300,19 @@ main(int argc, char *argv[]) /* This loop must match the one in sudo_file_lookup() */ printf("\nEntries for user %s:\n", user_name); match = UNSPEC; - tq_foreach_rev(&userspecs, us) { + TAILQ_FOREACH_REVERSE(us, &userspecs, userspec_list, entries) { if (userlist_matches(sudo_user.pw, &us->users) != ALLOW) continue; - tq_foreach_rev(&us->privileges, priv) { + TAILQ_FOREACH_REVERSE(priv, &us->privileges, privilege_list, entries) { putchar('\n'); - print_privilege(priv); /* XXX */ + print_privilege(priv); putchar('\n'); host_match = hostlist_matches(&priv->hostlist); if (host_match == ALLOW) { puts("\thost matched"); - tq_foreach_rev(&priv->cmndlist, cs) { - runas_match = runaslist_matches(&cs->runasuserlist, - &cs->runasgrouplist, NULL, NULL); + TAILQ_FOREACH_REVERSE(cs, &priv->cmndlist, cmndspec_list, entries) { + runas_match = runaslist_matches(cs->runasuserlist, + cs->runasgrouplist, NULL, NULL); if (runas_match == ALLOW) { puts("\trunas matched"); cmnd_match = cmnd_matches(cs->cmnd); @@ -350,6 +338,8 @@ main(int argc, char *argv[]) */ exitcode = parse_error ? 1 : (match == ALLOW ? 0 : match + 3); done: + sudo_endpwent(); + sudo_endgrent(); sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode); exit(exitcode); } @@ -357,36 +347,48 @@ done: static void set_runaspw(const char *user) { - debug_decl(main, SUDO_DEBUG_UTIL) + struct passwd *pw = NULL; + debug_decl(set_runaspw, SUDO_DEBUG_UTIL) - if (runas_pw != NULL) - sudo_pw_delref(runas_pw); if (*user == '#') { - if ((runas_pw = sudo_getpwuid(atoi(user + 1))) == NULL) - runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0); - } else { - if ((runas_pw = sudo_getpwnam(user)) == NULL) - errorx(1, _("unknown user: %s"), user); + const char *errstr; + uid_t uid = atoid(user + 1, NULL, NULL, &errstr); + if (errstr == NULL) { + if ((pw = sudo_getpwuid(uid)) == NULL) + pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0); + } } - + if (pw == NULL) { + if ((pw = sudo_getpwnam(user)) == NULL) + fatalx(U_("unknown user: %s"), user); + } + if (runas_pw != NULL) + sudo_pw_delref(runas_pw); + runas_pw = pw; debug_return; } static void set_runasgr(const char *group) { - debug_decl(main, SUDO_DEBUG_UTIL) + struct group *gr = NULL; + debug_decl(set_runasgr, SUDO_DEBUG_UTIL) - if (runas_gr != NULL) - sudo_gr_delref(runas_gr); if (*group == '#') { - if ((runas_gr = sudo_getgrgid(atoi(group + 1))) == NULL) - runas_gr = sudo_fakegrnam(group); - } else { - if ((runas_gr = sudo_getgrnam(group)) == NULL) - errorx(1, _("unknown group: %s"), group); + const char *errstr; + gid_t gid = atoid(group + 1, NULL, NULL, &errstr); + if (errstr == NULL) { + if ((gr = sudo_getgrgid(gid)) == NULL) + gr = sudo_fakegrnam(group); + } } - + if (gr == NULL) { + if ((gr = sudo_getgrnam(group)) == NULL) + fatalx(U_("unknown group: %s"), group); + } + if (runas_gr != NULL) + sudo_gr_delref(runas_gr); + runas_gr = gr; debug_return; } @@ -414,12 +416,6 @@ sudo_endspent(void) return; } -void -set_fqdn(void) -{ - return; -} - FILE * open_sudoers(const char *sudoers, bool doedit, bool *keepopen) { @@ -479,15 +475,6 @@ restore_perms(void) } void -cleanup(int gotsignal) -{ - if (!gotsignal) { - sudo_endpwent(); - sudo_endgrent(); - } -} - -void print_member(struct member *m) { struct sudo_command *c; @@ -513,9 +500,9 @@ print_defaults(void) { struct defaults *d; struct member *m; - debug_decl(print_member, SUDO_DEBUG_UTIL) + debug_decl(print_defaults, SUDO_DEBUG_UTIL) - tq_foreach_fwd(&defaults, d) { + TAILQ_FOREACH(d, &defaults, entries) { (void) fputs("Defaults", stdout); switch (d->type) { case DEFAULTS_HOST: @@ -531,8 +518,8 @@ print_defaults(void) putchar('!'); break; } - tq_foreach_fwd(&d->binding, m) { - if (m != tq_first(&d->binding)) + TAILQ_FOREACH(m, d->binding, entries) { + if (m != TAILQ_FIRST(d->binding)) putchar(','); print_member(m); } @@ -568,8 +555,8 @@ print_alias(void *v1, void *v2) (void) printf("Runas_Alias\t%s = ", a->name); break; } - tq_foreach_fwd(&a->members, m) { - if (m != tq_first(&a->members)) + TAILQ_FOREACH(m, &a->members, entries) { + if (m != TAILQ_FIRST(&a->members)) fputs(", ", stdout); if (m->type == COMMAND) { c = (struct sudo_command *) m->name; @@ -590,65 +577,61 @@ print_privilege(struct privilege *priv) { struct cmndspec *cs; struct member *m; - struct privilege *p; struct cmndtag tags; debug_decl(print_privilege, SUDO_DEBUG_UTIL) - for (p = priv; p != NULL; p = p->next) { - if (p != priv) - fputs(" : ", stdout); - tq_foreach_fwd(&p->hostlist, m) { - if (m != tq_first(&p->hostlist)) - fputs(", ", stdout); - print_member(m); - } - fputs(" = ", stdout); - tags.nopasswd = tags.noexec = UNSPEC; - tq_foreach_fwd(&p->cmndlist, cs) { - if (cs != tq_first(&p->cmndlist)) - fputs(", ", stdout); - if (!tq_empty(&cs->runasuserlist) || !tq_empty(&cs->runasgrouplist)) { - fputs("(", stdout); - if (!tq_empty(&cs->runasuserlist)) { - tq_foreach_fwd(&cs->runasuserlist, m) { - if (m != tq_first(&cs->runasuserlist)) - fputs(", ", stdout); - print_member(m); - } - } else if (tq_empty(&cs->runasgrouplist)) { - fputs(def_runas_default, stdout); - } else { - fputs(sudo_user.pw->pw_name, stdout); + TAILQ_FOREACH(m, &priv->hostlist, entries) { + if (m != TAILQ_FIRST(&priv->hostlist)) + fputs(", ", stdout); + print_member(m); + } + fputs(" = ", stdout); + tags.nopasswd = UNSPEC; + tags.noexec = UNSPEC; + TAILQ_FOREACH(cs, &priv->cmndlist, entries) { + if (cs != TAILQ_FIRST(&priv->cmndlist)) + fputs(", ", stdout); + if (cs->runasuserlist != NULL || cs->runasgrouplist != NULL) { + fputs("(", stdout); + if (cs->runasuserlist != NULL) { + TAILQ_FOREACH(m, cs->runasuserlist, entries) { + if (m != TAILQ_FIRST(cs->runasuserlist)) + fputs(", ", stdout); + print_member(m); + } + } else if (cs->runasgrouplist == NULL) { + fputs(def_runas_default, stdout); + } else { + fputs(sudo_user.pw->pw_name, stdout); + } + if (cs->runasgrouplist != NULL) { + fputs(" : ", stdout); + TAILQ_FOREACH(m, cs->runasgrouplist, entries) { + if (m != TAILQ_FIRST(cs->runasgrouplist)) + fputs(", ", stdout); + print_member(m); } - if (!tq_empty(&cs->runasgrouplist)) { - fputs(" : ", stdout); - tq_foreach_fwd(&cs->runasgrouplist, m) { - if (m != tq_first(&cs->runasgrouplist)) - fputs(", ", stdout); - print_member(m); - } - } - fputs(") ", stdout); } + fputs(") ", stdout); + } #ifdef HAVE_SELINUX - if (cs->role) - printf("ROLE=%s ", cs->role); - if (cs->type) - printf("TYPE=%s ", cs->type); + if (cs->role) + printf("ROLE=%s ", cs->role); + if (cs->type) + printf("TYPE=%s ", cs->type); #endif /* HAVE_SELINUX */ #ifdef HAVE_PRIV_SET - if (cs->privs) - printf("PRIVS=%s ", cs->privs); - if (cs->limitprivs) - printf("LIMITPRIVS=%s ", cs->limitprivs); + if (cs->privs) + printf("PRIVS=%s ", cs->privs); + if (cs->limitprivs) + printf("LIMITPRIVS=%s ", cs->limitprivs); #endif /* HAVE_PRIV_SET */ - if (cs->tags.nopasswd != UNSPEC && cs->tags.nopasswd != tags.nopasswd) - printf("%sPASSWD: ", cs->tags.nopasswd ? "NO" : ""); - if (cs->tags.noexec != UNSPEC && cs->tags.noexec != tags.noexec) - printf("%sEXEC: ", cs->tags.noexec ? "NO" : ""); - print_member(cs->cmnd); - memcpy(&tags, &cs->tags, sizeof(tags)); - } + if (cs->tags.nopasswd != UNSPEC && cs->tags.nopasswd != tags.nopasswd) + printf("%sPASSWD: ", cs->tags.nopasswd ? "NO" : ""); + if (cs->tags.noexec != UNSPEC && cs->tags.noexec != tags.noexec) + printf("%sEXEC: ", cs->tags.noexec ? "NO" : ""); + print_member(cs->cmnd); + memcpy(&tags, &cs->tags, sizeof(tags)); } debug_return; } @@ -658,47 +641,26 @@ print_userspecs(void) { struct member *m; struct userspec *us; + struct privilege *priv; debug_decl(print_userspecs, SUDO_DEBUG_UTIL) - tq_foreach_fwd(&userspecs, us) { - tq_foreach_fwd(&us->users, m) { - if (m != tq_first(&us->users)) + TAILQ_FOREACH(us, &userspecs, entries) { + TAILQ_FOREACH(m, &us->users, entries) { + if (m != TAILQ_FIRST(&us->users)) fputs(", ", stdout); print_member(m); } putchar('\t'); - print_privilege(us->privileges.first); /* XXX */ + TAILQ_FOREACH(priv, &us->privileges, entries) { + if (priv != TAILQ_FIRST(&us->privileges)) + fputs(" : ", stdout); + print_privilege(priv); + } putchar('\n'); } debug_return; } -static int -testsudoers_printf(int msg_type, const char *fmt, ...) -{ - va_list ap; - FILE *fp; - debug_decl(testsudoers_printf, SUDO_DEBUG_UTIL) - - switch (msg_type) { - case SUDO_CONV_INFO_MSG: - fp = stdout; - break; - case SUDO_CONV_ERROR_MSG: - fp = stderr; - break; - default: - errno = EINVAL; - debug_return_int(-1); - } - - va_start(ap, fmt); - vfprintf(fp, fmt, ap); - va_end(ap); - - debug_return_int(0); -} - void dump_sudoers(void) { @@ -723,6 +685,6 @@ static int testsudoers_print(const char *msg) void usage(void) { - (void) fprintf(stderr, "usage: %s [-dt] [-G sudoers_gid] [-g group] [-h host] [-p grfile] [-p pwfile] [-U sudoers_uid] [-u user] [args]\n", getprogname()); + (void) fprintf(stderr, "usage: %s [-dt] [-G sudoers_gid] [-g group] [-h host] [-P grfile] [-p pwfile] [-U sudoers_uid] [-u user] [args]\n", getprogname()); exit(1); }