version 1.1.1.3, 2012/10/09 09:29:52
|
version 1.1.1.5, 2014/06/15 16:12:54
|
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 25
|
Line 25
|
#include <config.h> |
#include <config.h> |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/param.h> |
|
#include <stdio.h> |
#include <stdio.h> |
#ifdef STDC_HEADERS |
#ifdef STDC_HEADERS |
# include <stdlib.h> |
# include <stdlib.h> |
Line 55
|
Line 54
|
#include "sudoers.h" /* XXX */ |
#include "sudoers.h" /* XXX */ |
#include "parse.h" |
#include "parse.h" |
#include "toke.h" |
#include "toke.h" |
#include "gram.h" |
|
|
|
/* |
/* |
* We must define SIZE_MAX for yacc's skeleton.c. |
* We must define SIZE_MAX for yacc's skeleton.c. |
Line 73
|
Line 71
|
/* |
/* |
* Globals |
* Globals |
*/ |
*/ |
extern int sudolineno; |
|
extern int last_token; |
|
extern char *sudoers; |
|
bool sudoers_warnings = true; |
bool sudoers_warnings = true; |
bool parse_error = false; |
bool parse_error = false; |
int errorlineno = -1; |
int errorlineno = -1; |
char *errorfile = NULL; | const char *errorfile = NULL; |
|
|
struct defaults_list defaults; | struct defaults_list defaults = TAILQ_HEAD_INITIALIZER(defaults); |
struct userspec_list userspecs; | struct userspec_list userspecs = TAILQ_HEAD_INITIALIZER(userspecs); |
|
|
/* |
/* |
* Local protoypes |
* Local protoypes |
Line 91 static void add_defaults(int, struct member *, struct
|
Line 86 static void add_defaults(int, struct member *, struct
|
static void add_userspec(struct member *, struct privilege *); |
static void add_userspec(struct member *, struct privilege *); |
static struct defaults *new_default(char *, char *, int); |
static struct defaults *new_default(char *, char *, int); |
static struct member *new_member(char *, int); |
static struct member *new_member(char *, int); |
void yyerror(const char *); | static struct sudo_digest *new_digest(int, const char *); |
| |
void | |
yyerror(const char *s) | |
{ | |
debug_decl(yyerror, SUDO_DEBUG_PARSER) | |
| |
/* If we last saw a newline the error is on the preceding line. */ | |
if (last_token == COMMENT) | |
sudolineno--; | |
| |
/* Save the line the first error occurred on. */ | |
if (errorlineno == -1) { | |
errorlineno = sudolineno; | |
errorfile = estrdup(sudoers); | |
} | |
if (sudoers_warnings && s != NULL) { | |
LEXTRACE("<*> "); | |
#ifndef TRACELEXER | |
if (trace_print == NULL || trace_print == sudoers_trace_print) | |
warningx(_(">>> %s: %s near line %d <<<"), sudoers, s, sudolineno); | |
#endif | |
} | |
parse_error = true; | |
debug_return; | |
} | |
%} |
%} |
|
|
%union { |
%union { |
Line 125 yyerror(const char *s)
|
Line 95 yyerror(const char *s)
|
struct member *member; |
struct member *member; |
struct runascontainer *runas; |
struct runascontainer *runas; |
struct privilege *privilege; |
struct privilege *privilege; |
|
struct sudo_digest *digest; |
struct sudo_command command; |
struct sudo_command command; |
struct cmndtag tag; |
struct cmndtag tag; |
struct selinux_info seinfo; |
struct selinux_info seinfo; |
Line 141 yyerror(const char *s)
|
Line 112 yyerror(const char *s)
|
%token <string> NETGROUP /* a netgroup (+NAME) */ |
%token <string> NETGROUP /* a netgroup (+NAME) */ |
%token <string> USERGROUP /* a usergroup (%NAME) */ |
%token <string> USERGROUP /* a usergroup (%NAME) */ |
%token <string> WORD /* a word */ |
%token <string> WORD /* a word */ |
|
%token <string> DIGEST /* a SHA-2 digest */ |
%token <tok> DEFAULTS /* Defaults entry */ |
%token <tok> DEFAULTS /* Defaults entry */ |
%token <tok> DEFAULTS_HOST /* Host-specific defaults entry */ |
%token <tok> DEFAULTS_HOST /* Host-specific defaults entry */ |
%token <tok> DEFAULTS_USER /* User-specific defaults entry */ |
%token <tok> DEFAULTS_USER /* User-specific defaults entry */ |
Line 170 yyerror(const char *s)
|
Line 142 yyerror(const char *s)
|
%token <tok> PRIVS /* Solaris privileges */ |
%token <tok> PRIVS /* Solaris privileges */ |
%token <tok> LIMITPRIVS /* Solaris limit privileges */ |
%token <tok> LIMITPRIVS /* Solaris limit privileges */ |
%token <tok> MYSELF /* run as myself, not another user */ |
%token <tok> MYSELF /* run as myself, not another user */ |
|
%token <tok> SHA224 /* sha224 digest */ |
|
%token <tok> SHA256 /* sha256 digest */ |
|
%token <tok> SHA384 /* sha384 digest */ |
|
%token <tok> SHA512 /* sha512 digest */ |
|
|
%type <cmndspec> cmndspec |
%type <cmndspec> cmndspec |
%type <cmndspec> cmndspeclist |
%type <cmndspec> cmndspeclist |
Line 177 yyerror(const char *s)
|
Line 153 yyerror(const char *s)
|
%type <defaults> defaults_list |
%type <defaults> defaults_list |
%type <member> cmnd |
%type <member> cmnd |
%type <member> opcmnd |
%type <member> opcmnd |
|
%type <member> digcmnd |
%type <member> cmndlist |
%type <member> cmndlist |
%type <member> host |
%type <member> host |
%type <member> hostlist |
%type <member> hostlist |
Line 198 yyerror(const char *s)
|
Line 175 yyerror(const char *s)
|
%type <privinfo> solarisprivs |
%type <privinfo> solarisprivs |
%type <string> privsspec |
%type <string> privsspec |
%type <string> limitprivsspec |
%type <string> limitprivsspec |
|
%type <digest> digest |
|
|
%% |
%% |
|
|
Line 249 entry : COMMENT {
|
Line 227 entry : COMMENT {
|
|
|
defaults_list : defaults_entry |
defaults_list : defaults_entry |
| defaults_list ',' defaults_entry { |
| defaults_list ',' defaults_entry { |
list_append($1, $3); | HLTQ_CONCAT($1, $3, entries); |
$$ = $1; |
$$ = $1; |
} |
} |
; |
; |
Line 273 defaults_entry : DEFVAR {
|
Line 251 defaults_entry : DEFVAR {
|
|
|
privileges : privilege |
privileges : privilege |
| privileges ':' privilege { |
| privileges ':' privilege { |
list_append($1, $3); | HLTQ_CONCAT($1, $3, entries); |
$$ = $1; |
$$ = $1; |
} |
} |
; |
; |
|
|
privilege : hostlist '=' cmndspeclist { |
privilege : hostlist '=' cmndspeclist { |
struct privilege *p = ecalloc(1, sizeof(*p)); |
struct privilege *p = ecalloc(1, sizeof(*p)); |
list2tq(&p->hostlist, $1); | HLTQ_TO_TAILQ(&p->hostlist, $1, entries); |
list2tq(&p->cmndlist, $3); | HLTQ_TO_TAILQ(&p->cmndlist, $3, entries); |
p->prev = p; | HLTQ_INIT(p, entries); |
/* p->next = NULL; */ | |
$$ = p; |
$$ = p; |
} |
} |
; |
; |
Line 317 host : ALIAS {
|
Line 294 host : ALIAS {
|
|
|
cmndspeclist : cmndspec |
cmndspeclist : cmndspec |
| cmndspeclist ',' cmndspec { |
| cmndspeclist ',' cmndspec { |
list_append($1, $3); | struct cmndspec *prev; |
| prev = HLTQ_LAST($1, cmndspec, entries); |
| HLTQ_CONCAT($1, $3, entries); |
#ifdef HAVE_SELINUX |
#ifdef HAVE_SELINUX |
/* propagate role and type */ |
/* propagate role and type */ |
if ($3->role == NULL) |
if ($3->role == NULL) |
$3->role = $3->prev->role; | $3->role = prev->role; |
if ($3->type == NULL) |
if ($3->type == NULL) |
$3->type = $3->prev->type; | $3->type = prev->type; |
#endif /* HAVE_SELINUX */ |
#endif /* HAVE_SELINUX */ |
#ifdef HAVE_PRIV_SET |
#ifdef HAVE_PRIV_SET |
/* propagate privs & limitprivs */ |
/* propagate privs & limitprivs */ |
if ($3->privs == NULL) |
if ($3->privs == NULL) |
$3->privs = $3->prev->privs; | $3->privs = prev->privs; |
if ($3->limitprivs == NULL) |
if ($3->limitprivs == NULL) |
$3->limitprivs = $3->prev->limitprivs; | $3->limitprivs = prev->limitprivs; |
#endif /* HAVE_PRIV_SET */ |
#endif /* HAVE_PRIV_SET */ |
/* propagate tags and runas list */ |
/* propagate tags and runas list */ |
if ($3->tags.nopasswd == UNSPEC) |
if ($3->tags.nopasswd == UNSPEC) |
$3->tags.nopasswd = $3->prev->tags.nopasswd; | $3->tags.nopasswd = prev->tags.nopasswd; |
if ($3->tags.noexec == UNSPEC) |
if ($3->tags.noexec == UNSPEC) |
$3->tags.noexec = $3->prev->tags.noexec; | $3->tags.noexec = prev->tags.noexec; |
if ($3->tags.setenv == UNSPEC && |
if ($3->tags.setenv == UNSPEC && |
$3->prev->tags.setenv != IMPLIED) | prev->tags.setenv != IMPLIED) |
$3->tags.setenv = $3->prev->tags.setenv; | $3->tags.setenv = prev->tags.setenv; |
if ($3->tags.log_input == UNSPEC) |
if ($3->tags.log_input == UNSPEC) |
$3->tags.log_input = $3->prev->tags.log_input; | $3->tags.log_input = prev->tags.log_input; |
if ($3->tags.log_output == UNSPEC) |
if ($3->tags.log_output == UNSPEC) |
$3->tags.log_output = $3->prev->tags.log_output; | $3->tags.log_output = prev->tags.log_output; |
if ((tq_empty(&$3->runasuserlist) && | if (($3->runasuserlist == NULL && |
tq_empty(&$3->runasgrouplist)) && | $3->runasgrouplist == NULL) && |
(!tq_empty(&$3->prev->runasuserlist) || | (prev->runasuserlist != NULL || |
!tq_empty(&$3->prev->runasgrouplist))) { | prev->runasgrouplist != NULL)) { |
$3->runasuserlist = $3->prev->runasuserlist; | $3->runasuserlist = prev->runasuserlist; |
$3->runasgrouplist = $3->prev->runasgrouplist; | $3->runasgrouplist = prev->runasgrouplist; |
} |
} |
$$ = $1; |
$$ = $1; |
} |
} |
; |
; |
|
|
cmndspec : runasspec selinux solarisprivs cmndtag opcmnd { | cmndspec : runasspec selinux solarisprivs cmndtag digcmnd { |
struct cmndspec *cs = ecalloc(1, sizeof(*cs)); |
struct cmndspec *cs = ecalloc(1, sizeof(*cs)); |
if ($1 != NULL) { |
if ($1 != NULL) { |
list2tq(&cs->runasuserlist, $1->runasusers); | if ($1->runasusers != NULL) { |
list2tq(&cs->runasgrouplist, $1->runasgroups); | cs->runasuserlist = |
| emalloc(sizeof(*cs->runasuserlist)); |
| HLTQ_TO_TAILQ(cs->runasuserlist, |
| $1->runasusers, entries); |
| } |
| if ($1->runasgroups != NULL) { |
| cs->runasgrouplist = |
| emalloc(sizeof(*cs->runasgrouplist)); |
| HLTQ_TO_TAILQ(cs->runasgrouplist, |
| $1->runasgroups, entries); |
| } |
efree($1); |
efree($1); |
} else { |
|
tq_init(&cs->runasuserlist); |
|
tq_init(&cs->runasgrouplist); |
|
} |
} |
#ifdef HAVE_SELINUX |
#ifdef HAVE_SELINUX |
cs->role = $2.role; |
cs->role = $2.role; |
Line 375 cmndspec : runasspec selinux solarisprivs cmndtag opcm
|
Line 361 cmndspec : runasspec selinux solarisprivs cmndtag opcm
|
#endif |
#endif |
cs->tags = $4; |
cs->tags = $4; |
cs->cmnd = $5; |
cs->cmnd = $5; |
cs->prev = cs; | HLTQ_INIT(cs, entries); |
cs->next = NULL; | |
/* sudo "ALL" implies the SETENV tag */ |
/* sudo "ALL" implies the SETENV tag */ |
if (cs->cmnd->type == ALL && !cs->cmnd->negated && |
if (cs->cmnd->type == ALL && !cs->cmnd->negated && |
cs->tags.setenv == UNSPEC) |
cs->tags.setenv == UNSPEC) |
Line 385 cmndspec : runasspec selinux solarisprivs cmndtag opcm
|
Line 370 cmndspec : runasspec selinux solarisprivs cmndtag opcm
|
} |
} |
; |
; |
|
|
|
digest : SHA224 ':' DIGEST { |
|
$$ = new_digest(SUDO_DIGEST_SHA224, $3); |
|
} |
|
| SHA256 ':' DIGEST { |
|
$$ = new_digest(SUDO_DIGEST_SHA256, $3); |
|
} |
|
| SHA384 ':' DIGEST { |
|
$$ = new_digest(SUDO_DIGEST_SHA384, $3); |
|
} |
|
| SHA512 ':' DIGEST { |
|
$$ = new_digest(SUDO_DIGEST_SHA512, $3); |
|
} |
|
; |
|
|
|
digcmnd : opcmnd { |
|
$$ = $1; |
|
} |
|
| digest opcmnd { |
|
/* XXX - yuck */ |
|
struct sudo_command *c = (struct sudo_command *)($2->name); |
|
c->digest = $1; |
|
$$ = $2; |
|
} |
|
; |
|
|
opcmnd : cmnd { |
opcmnd : cmnd { |
$$ = $1; |
$$ = $1; |
$$->negated = false; |
$$->negated = false; |
Line 443 solarisprivs : /* empty */ {
|
Line 453 solarisprivs : /* empty */ {
|
| privsspec { |
| privsspec { |
$$.privs = $1; |
$$.privs = $1; |
$$.limitprivs = NULL; |
$$.limitprivs = NULL; |
} | } |
| limitprivsspec { |
| limitprivsspec { |
$$.privs = NULL; |
$$.privs = NULL; |
$$.limitprivs = $1; |
$$.limitprivs = $1; |
} | } |
| privsspec limitprivsspec { |
| privsspec limitprivsspec { |
$$.privs = $1; |
$$.privs = $1; |
$$.limitprivs = $2; |
$$.limitprivs = $2; |
} | } |
| limitprivsspec privsspec { |
| limitprivsspec privsspec { |
$$.limitprivs = $1; |
$$.limitprivs = $1; |
$$.privs = $2; |
$$.privs = $2; |
} | } |
| ; |
|
|
runasspec : /* empty */ { |
runasspec : /* empty */ { |
$$ = NULL; |
$$ = NULL; |
Line 549 hostaliases : hostalias
|
Line 560 hostaliases : hostalias
|
hostalias : ALIAS '=' hostlist { |
hostalias : ALIAS '=' hostlist { |
char *s; |
char *s; |
if ((s = alias_add($1, HOSTALIAS, $3)) != NULL) { |
if ((s = alias_add($1, HOSTALIAS, $3)) != NULL) { |
yyerror(s); | sudoerserror(s); |
YYERROR; |
YYERROR; |
} |
} |
} |
} |
Line 557 hostalias : ALIAS '=' hostlist {
|
Line 568 hostalias : ALIAS '=' hostlist {
|
|
|
hostlist : ophost |
hostlist : ophost |
| hostlist ',' ophost { |
| hostlist ',' ophost { |
list_append($1, $3); | HLTQ_CONCAT($1, $3, entries); |
$$ = $1; |
$$ = $1; |
} |
} |
; |
; |
Line 569 cmndaliases : cmndalias
|
Line 580 cmndaliases : cmndalias
|
cmndalias : ALIAS '=' cmndlist { |
cmndalias : ALIAS '=' cmndlist { |
char *s; |
char *s; |
if ((s = alias_add($1, CMNDALIAS, $3)) != NULL) { |
if ((s = alias_add($1, CMNDALIAS, $3)) != NULL) { |
yyerror(s); | sudoerserror(s); |
YYERROR; |
YYERROR; |
} |
} |
} |
} |
; |
; |
|
|
cmndlist : opcmnd | cmndlist : digcmnd |
| cmndlist ',' opcmnd { | | cmndlist ',' digcmnd { |
list_append($1, $3); | HLTQ_CONCAT($1, $3, entries); |
$$ = $1; |
$$ = $1; |
} |
} |
; |
; |
Line 589 runasaliases : runasalias
|
Line 600 runasaliases : runasalias
|
runasalias : ALIAS '=' userlist { |
runasalias : ALIAS '=' userlist { |
char *s; |
char *s; |
if ((s = alias_add($1, RUNASALIAS, $3)) != NULL) { |
if ((s = alias_add($1, RUNASALIAS, $3)) != NULL) { |
yyerror(s); | sudoerserror(s); |
YYERROR; |
YYERROR; |
} |
} |
} |
} |
Line 602 useraliases : useralias
|
Line 613 useraliases : useralias
|
useralias : ALIAS '=' userlist { |
useralias : ALIAS '=' userlist { |
char *s; |
char *s; |
if ((s = alias_add($1, USERALIAS, $3)) != NULL) { |
if ((s = alias_add($1, USERALIAS, $3)) != NULL) { |
yyerror(s); | sudoerserror(s); |
YYERROR; |
YYERROR; |
} |
} |
} |
} |
Line 610 useralias : ALIAS '=' userlist {
|
Line 621 useralias : ALIAS '=' userlist {
|
|
|
userlist : opuser |
userlist : opuser |
| userlist ',' opuser { |
| userlist ',' opuser { |
list_append($1, $3); | HLTQ_CONCAT($1, $3, entries); |
$$ = $1; |
$$ = $1; |
} |
} |
; |
; |
Line 644 user : ALIAS {
|
Line 655 user : ALIAS {
|
|
|
grouplist : opgroup |
grouplist : opgroup |
| grouplist ',' opgroup { |
| grouplist ',' opgroup { |
list_append($1, $3); | HLTQ_CONCAT($1, $3, entries); |
$$ = $1; |
$$ = $1; |
} |
} |
; |
; |
Line 671 group : ALIAS {
|
Line 682 group : ALIAS {
|
; |
; |
|
|
%% |
%% |
|
void |
|
sudoerserror(const char *s) |
|
{ |
|
debug_decl(sudoerserror, SUDO_DEBUG_PARSER) |
|
|
|
/* If we last saw a newline the error is on the preceding line. */ |
|
if (last_token == COMMENT) |
|
sudolineno--; |
|
|
|
/* Save the line the first error occurred on. */ |
|
if (errorlineno == -1) { |
|
errorlineno = sudolineno; |
|
errorfile = estrdup(sudoers); |
|
} |
|
if (sudoers_warnings && s != NULL) { |
|
LEXTRACE("<*> "); |
|
#ifndef TRACELEXER |
|
if (trace_print == NULL || trace_print == sudoers_trace_print) { |
|
const char fmt[] = ">>> %s: %s near line %d <<<\n"; |
|
int oldlocale; |
|
|
|
/* Warnings are displayed in the user's locale. */ |
|
sudoers_setlocale(SUDOERS_LOCALE_USER, &oldlocale); |
|
sudo_printf(SUDO_CONV_ERROR_MSG, _(fmt), sudoers, _(s), sudolineno); |
|
sudoers_setlocale(oldlocale, NULL); |
|
} |
|
#endif |
|
} |
|
parse_error = true; |
|
debug_return; |
|
} |
|
|
static struct defaults * |
static struct defaults * |
new_default(char *var, char *val, int op) |
new_default(char *var, char *val, int op) |
{ |
{ |
Line 680 new_default(char *var, char *val, int op)
|
Line 723 new_default(char *var, char *val, int op)
|
d = ecalloc(1, sizeof(struct defaults)); |
d = ecalloc(1, sizeof(struct defaults)); |
d->var = var; |
d->var = var; |
d->val = val; |
d->val = val; |
tq_init(&d->binding); |
|
/* d->type = 0; */ |
/* d->type = 0; */ |
d->op = op; |
d->op = op; |
d->prev = d; | /* d->binding = NULL */ |
/* d->next = NULL; */ | HLTQ_INIT(d, entries); |
|
|
debug_return_ptr(d); |
debug_return_ptr(d); |
} |
} |
Line 698 new_member(char *name, int type)
|
Line 740 new_member(char *name, int type)
|
m = ecalloc(1, sizeof(struct member)); |
m = ecalloc(1, sizeof(struct member)); |
m->name = name; |
m->name = name; |
m->type = type; |
m->type = type; |
m->prev = m; | HLTQ_INIT(m, entries); |
/* m->next = NULL; */ | |
|
|
debug_return_ptr(m); |
debug_return_ptr(m); |
} |
} |
|
|
|
struct sudo_digest * |
|
new_digest(int digest_type, const char *digest_str) |
|
{ |
|
struct sudo_digest *dig; |
|
debug_decl(new_digest, SUDO_DEBUG_PARSER) |
|
|
|
dig = emalloc(sizeof(*dig)); |
|
dig->digest_type = digest_type; |
|
dig->digest_str = estrdup(digest_str); |
|
|
|
debug_return_ptr(dig); |
|
} |
|
|
/* |
/* |
* Add a list of defaults structures to the defaults list. |
* Add a list of defaults structures to the defaults list. |
* The binding, if non-NULL, specifies a list of hosts, users, or |
* The binding, if non-NULL, specifies a list of hosts, users, or |
Line 713 static void
|
Line 767 static void
|
add_defaults(int type, struct member *bmem, struct defaults *defs) |
add_defaults(int type, struct member *bmem, struct defaults *defs) |
{ |
{ |
struct defaults *d; |
struct defaults *d; |
struct member_list binding; | struct member_list *binding; |
debug_decl(add_defaults, SUDO_DEBUG_PARSER) |
debug_decl(add_defaults, SUDO_DEBUG_PARSER) |
|
|
/* | if (defs != NULL) { |
* We can only call list2tq once on bmem as it will zero | /* |
* out the prev pointer when it consumes bmem. | * We use a single binding for each entry in defs. |
*/ | */ |
list2tq(&binding, bmem); | binding = emalloc(sizeof(*binding)); |
| if (bmem != NULL) |
| HLTQ_TO_TAILQ(binding, bmem, entries); |
| else |
| TAILQ_INIT(binding); |
|
|
/* | /* |
* Set type and binding (who it applies to) for new entries. | * Set type and binding (who it applies to) for new entries. |
*/ | * Then add to the global defaults list. |
for (d = defs; d != NULL; d = d->next) { | */ |
d->type = type; | HLTQ_FOREACH(d, defs, entries) { |
d->binding = binding; | d->type = type; |
| d->binding = binding; |
| } |
| TAILQ_CONCAT_HLTQ(&defaults, defs, entries); |
} |
} |
tq_append(&defaults, defs); |
|
|
|
debug_return; |
debug_return; |
} |
} |
|
|
/* |
/* |
* Allocate a new struct userspec, populate it, and insert it at the |
* Allocate a new struct userspec, populate it, and insert it at the |
* and of the userspecs list. | * end of the userspecs list. |
*/ |
*/ |
static void |
static void |
add_userspec(struct member *members, struct privilege *privs) |
add_userspec(struct member *members, struct privilege *privs) |
Line 745 add_userspec(struct member *members, struct privilege
|
Line 805 add_userspec(struct member *members, struct privilege
|
debug_decl(add_userspec, SUDO_DEBUG_PARSER) |
debug_decl(add_userspec, SUDO_DEBUG_PARSER) |
|
|
u = ecalloc(1, sizeof(*u)); |
u = ecalloc(1, sizeof(*u)); |
list2tq(&u->users, members); | HLTQ_TO_TAILQ(&u->users, members, entries); |
list2tq(&u->privileges, privs); | HLTQ_TO_TAILQ(&u->privileges, privs, entries); |
u->prev = u; | TAILQ_INSERT_TAIL(&userspecs, u, entries); |
/* u->next = NULL; */ | |
tq_append(&userspecs, u); | |
|
|
debug_return; |
debug_return; |
} |
} |
Line 761 add_userspec(struct member *members, struct privilege
|
Line 819 add_userspec(struct member *members, struct privilege
|
void |
void |
init_parser(const char *path, bool quiet) |
init_parser(const char *path, bool quiet) |
{ |
{ |
struct defaults *d; | struct member_list *binding; |
struct member *m, *binding; | struct defaults *d, *d_next; |
struct userspec *us; | struct userspec *us, *us_next; |
struct privilege *priv; | |
struct cmndspec *cs; | |
struct sudo_command *c; | |
debug_decl(init_parser, SUDO_DEBUG_PARSER) |
debug_decl(init_parser, SUDO_DEBUG_PARSER) |
|
|
while ((us = tq_pop(&userspecs)) != NULL) { | TAILQ_FOREACH_SAFE(us, &userspecs, entries, us_next) { |
while ((m = tq_pop(&us->users)) != NULL) { | struct member *m, *m_next; |
| struct privilege *priv, *priv_next; |
| |
| TAILQ_FOREACH_SAFE(m, &us->users, entries, m_next) { |
efree(m->name); |
efree(m->name); |
efree(m); |
efree(m); |
} |
} |
while ((priv = tq_pop(&us->privileges)) != NULL) { | TAILQ_FOREACH_SAFE(priv, &us->privileges, entries, priv_next) { |
struct member *runasuser = NULL, *runasgroup = NULL; | struct member_list *runasuserlist = NULL, *runasgrouplist = NULL; |
| struct cmndspec *cs, *cs_next; |
#ifdef HAVE_SELINUX |
#ifdef HAVE_SELINUX |
char *role = NULL, *type = NULL; |
char *role = NULL, *type = NULL; |
#endif /* HAVE_SELINUX */ |
#endif /* HAVE_SELINUX */ |
Line 783 init_parser(const char *path, bool quiet)
|
Line 842 init_parser(const char *path, bool quiet)
|
char *privs = NULL, *limitprivs = NULL; |
char *privs = NULL, *limitprivs = NULL; |
#endif /* HAVE_PRIV_SET */ |
#endif /* HAVE_PRIV_SET */ |
|
|
while ((m = tq_pop(&priv->hostlist)) != NULL) { | TAILQ_FOREACH_SAFE(m, &priv->hostlist, entries, m_next) { |
efree(m->name); |
efree(m->name); |
efree(m); |
efree(m); |
} |
} |
while ((cs = tq_pop(&priv->cmndlist)) != NULL) { | TAILQ_FOREACH_SAFE(cs, &priv->cmndlist, entries, cs_next) { |
#ifdef HAVE_SELINUX |
#ifdef HAVE_SELINUX |
/* Only free the first instance of a role/type. */ |
/* Only free the first instance of a role/type. */ |
if (cs->role != role) { |
if (cs->role != role) { |
Line 810 init_parser(const char *path, bool quiet)
|
Line 869 init_parser(const char *path, bool quiet)
|
efree(cs->limitprivs); |
efree(cs->limitprivs); |
} |
} |
#endif /* HAVE_PRIV_SET */ |
#endif /* HAVE_PRIV_SET */ |
if (tq_last(&cs->runasuserlist) != runasuser) { | /* Only free the first instance of runas user/group lists. */ |
runasuser = tq_last(&cs->runasuserlist); | if (cs->runasuserlist && cs->runasuserlist != runasuserlist) { |
while ((m = tq_pop(&cs->runasuserlist)) != NULL) { | runasuserlist = cs->runasuserlist; |
| TAILQ_FOREACH_SAFE(m, runasuserlist, entries, m_next) { |
efree(m->name); |
efree(m->name); |
efree(m); |
efree(m); |
} |
} |
|
efree(runasuserlist); |
} |
} |
if (tq_last(&cs->runasgrouplist) != runasgroup) { | if (cs->runasgrouplist && cs->runasgrouplist != runasgrouplist) { |
runasgroup = tq_last(&cs->runasgrouplist); | runasgrouplist = cs->runasgrouplist; |
while ((m = tq_pop(&cs->runasgrouplist)) != NULL) { | TAILQ_FOREACH_SAFE(m, runasgrouplist, entries, m_next) { |
efree(m->name); |
efree(m->name); |
efree(m); |
efree(m); |
} |
} |
|
efree(runasgrouplist); |
} |
} |
if (cs->cmnd->type == COMMAND) { |
if (cs->cmnd->type == COMMAND) { |
c = (struct sudo_command *) cs->cmnd->name; | struct sudo_command *c = |
| (struct sudo_command *) cs->cmnd->name; |
efree(c->cmnd); |
efree(c->cmnd); |
efree(c->args); |
efree(c->args); |
} |
} |
Line 837 init_parser(const char *path, bool quiet)
|
Line 900 init_parser(const char *path, bool quiet)
|
} |
} |
efree(us); |
efree(us); |
} |
} |
tq_init(&userspecs); | TAILQ_INIT(&userspecs); |
|
|
binding = NULL; |
binding = NULL; |
while ((d = tq_pop(&defaults)) != NULL) { | TAILQ_FOREACH_SAFE(d, &defaults, entries, d_next) { |
if (tq_last(&d->binding) != binding) { | if (d->binding != binding) { |
binding = tq_last(&d->binding); | struct member *m, *m_next; |
while ((m = tq_pop(&d->binding)) != NULL) { | |
| binding = d->binding; |
| TAILQ_FOREACH_SAFE(m, d->binding, entries, m_next) { |
if (m->type == COMMAND) { |
if (m->type == COMMAND) { |
c = (struct sudo_command *) m->name; | struct sudo_command *c = |
| (struct sudo_command *) m->name; |
efree(c->cmnd); |
efree(c->cmnd); |
efree(c->args); |
efree(c->args); |
} |
} |
efree(m->name); |
efree(m->name); |
efree(m); |
efree(m); |
} |
} |
|
efree(d->binding); |
} |
} |
efree(d->var); |
efree(d->var); |
efree(d->val); |
efree(d->val); |
efree(d); |
efree(d); |
} |
} |
tq_init(&defaults); | TAILQ_INIT(&defaults); |
|
|
init_aliases(); |
init_aliases(); |
|
|