a = emalloc(sizeof(*a));
a->name = name;
a->type = type;
- a->first_member = members;
+ LIST2HEAD(a->members, members);
if (rbinsert(aliases, a)) {
efree(a);
snprintf(errbuf, sizeof(errbuf), "Alias `%s' already defined", name);
struct member *m;
VOID *next;
- for (m = a->first_member; m != NULL; m = next) {
+ for (m = a->members.first; m != NULL; m = next) {
next = m->next;
efree(m->name);
efree(m);
{ NULL, -1 }
};
-extern struct defaults *defaults;
-
/*
* Local prototypes.
*/
{
struct defaults *def;
- for (def = defaults; def != NULL; def = def->next) {
+ LH_FOREACH_FWD(defaults, def) {
if (skip_cmnd == (def->type == DEFAULTS_CMND))
continue;
switch (def->type) {
if (!set_default(def->var, def->val, def->op))
return(FALSE);
case DEFAULTS_USER:
- if (user_matches(sudo_user.pw, def->binding) &&
+ if (userlist_matches(sudo_user.pw, &def->binding) &&
!set_default(def->var, def->val, def->op))
return(FALSE);
break;
case DEFAULTS_RUNAS:
- if (runas_matches(def->binding) &&
+ if (runaslist_matches(&def->binding) &&
!set_default(def->var, def->val, def->op))
return(FALSE);
break;
case DEFAULTS_HOST:
- if (host_matches(def->binding) &&
+ if (hostlist_matches(&def->binding) &&
!set_default(def->var, def->val, def->op))
return(FALSE);
break;
case DEFAULTS_CMND:
- if (cmnd_matches(def->binding) &&
+ if (cmndlist_matches(&def->binding) &&
!set_default(def->var, def->val, def->op))
return(FALSE);
}
int errorlineno = -1;
char *errorfile = NULL;
-struct defaults *defaults;
-struct userspec *userspecs;
+struct defaults_list defaults;
+struct userspec_list userspecs;
/*
* Local protoypes
struct cmndtag tags;
struct privilege *p = emalloc(sizeof(*p));
struct cmndspec *cs;
- p->hostlist = $1;
- p->cmndlist = $3;
+ LIST2HEAD(p->hostlist, $1);
+ LIST2HEAD(p->cmndlist, $3);
tags.nopasswd = tags.noexec = tags.setenv = UNSPEC;
/* propagate tags */
for (cs = $3; cs != NULL; cs = cs->next) {
cmndspec : runasspec cmndtag opcmnd {
struct cmndspec *cs = emalloc(sizeof(*cs));
- cs->runaslist = $1;
+ LIST2HEAD(cs->runaslist, $1);
cs->tags = $2;
cs->cmnd = $3;
cs->prev = cs;
*/
for (d = defs; d != NULL; d = d->next) {
d->type = type;
- d->binding = binding;
+ LIST2HEAD(d->binding, binding);
}
- if (defaults == NULL)
- defaults = defs;
- else
- LIST_APPEND(defaults, defs);
+ HEAD_APPEND(defaults, defs);
}
/*
struct userspec *u;
u = emalloc(sizeof(*u));
- u->user = members;
- u->privileges = privs;
+ LIST2HEAD(u->users, members);
+ LIST2HEAD(u->privileges, privs);
u->prev = u;
u->next = NULL;
- if (userspecs == NULL)
- userspecs = u;
- else
- LIST_APPEND(userspecs, u);
+ HEAD_APPEND(userspecs, u);
}
/*
struct userspec *us;
struct privilege *priv;
struct cmndspec *cs;
- VOID *next;
- for (us = userspecs; us != NULL; us = next) {
- for (m = us->user; m != NULL; m = next) {
- next = m->next;
+ while ((us = LH_LAST(userspecs)) != NULL) {
+ LH_POP(userspecs);
+ while ((m = LH_LAST(us->users)) != NULL) {
+ LH_POP(us->users);
efree(m->name);
efree(m);
}
- for (priv = us->privileges; priv != NULL; priv = next) {
- for (m = priv->hostlist; m != NULL; m = next) {
- next = m->next;
+ while ((priv = LH_LAST(us->privileges)) != NULL) {
+ LH_POP(us->privileges);
+ while ((m = LH_LAST(priv->hostlist)) != NULL) {
+ LH_POP(priv->hostlist);
efree(m->name);
efree(m);
}
- for (cs = priv->cmndlist; cs != NULL; cs = next) {
- for (m = cs->runaslist; m != NULL; m = next) {
- next = m->next;
+ while ((cs = LH_LAST(priv->cmndlist)) != NULL) {
+ LH_POP(priv->cmndlist);
+ while ((m = LH_LAST(cs->runaslist)) != NULL) {
+ LH_POP(cs->runaslist);
efree(m->name);
efree(m);
}
efree(cs->cmnd->name);
efree(cs->cmnd);
- next = cs->next;
efree(cs);
}
- next = priv->next;
efree(priv);
}
- next = us->next;
- efree(us);
}
- userspecs = NULL;
+ LH_INIT(userspecs);
lastbinding = NULL;
- for (d = defaults; d != NULL; d = next) {
- if (d->binding != lastbinding) {
- for (m = d->binding; m != NULL; m = next) {
- next = m->next;
+ while ((d = LH_LAST(defaults)) != NULL) {
+ LH_POP(defaults);
+ if (LH_FIRST(d->binding) != lastbinding) {
+ lastbinding = LH_FIRST(d->binding);
+ while ((m = LH_LAST(d->binding)) != NULL) {
+ LH_POP(d->binding);
efree(m->name);
efree(m);
}
- lastbinding = d->binding;
}
- next = d->next;
efree(d->var);
efree(d->val);
efree(d);
}
- defaults = NULL;
+ LH_INIT(defaults);
init_aliases();
* Returns ALLOW, DENY or UNSPEC.
*/
int
-user_matches(pw, list)
+userlist_matches(pw, list)
struct passwd *pw;
- struct member *list;
+ struct member_list *list;
{
struct member *m;
struct alias *a;
int rval, matched = UNSPEC;
- for (m = list; m != NULL; m = m->next) {
+ for (m = list->first; m != NULL; m = m->next) {
switch (m->type) {
case ALL:
matched = !m->negated;
break;
case ALIAS:
if ((a = find_alias(m->name, USERALIAS)) != NULL) {
- rval = user_matches(pw, a->first_member);
+ rval = userlist_matches(pw, &a->members);
if (rval != UNSPEC)
matched = m->negated ? !rval : rval;
break;
* Returns ALLOW, DENY or UNSPEC.
*/
int
-runas_matches(list)
- struct member *list;
+runaslist_matches(list)
+ struct member_list *list;
{
struct member *m;
struct alias *a;
if (list == NULL)
return(userpw_matches(def_runas_default, runas_pw->pw_name, runas_pw));
- for (m = list; m != NULL; m = m->next) {
+ for (m = list->first; m != NULL; m = m->next) {
switch (m->type) {
case ALL:
matched = !m->negated;
break;
case ALIAS:
if ((a = find_alias(m->name, RUNASALIAS)) != NULL) {
- rval = runas_matches(a->first_member);
+ rval = runaslist_matches(&a->members);
if (rval != UNSPEC)
matched = m->negated ? !rval : rval;
break;
* Returns ALLOW, DENY or UNSPEC.
*/
int
-host_matches(list)
- struct member *list;
+hostlist_matches(list)
+ struct member_list *list;
{
struct member *m;
struct alias *a;
int rval, matched = UNSPEC;
- for (m = list; m != NULL; m = m->next) {
+ for (m = list->first; m != NULL; m = m->next) {
switch (m->type) {
case ALL:
matched = !m->negated;
break;
case ALIAS:
if ((a = find_alias(m->name, HOSTALIAS)) != NULL) {
- rval = host_matches(a->first_member);
+ rval = hostlist_matches(&a->members);
if (rval != UNSPEC)
matched = m->negated ? !rval : rval;
break;
}
/*
- * Check for cmnd and args in a list of members.
+ * Check cmnd and args.
* Returns ALLOW, DENY or UNSPEC.
*/
int
-cmnd_matches(list)
- struct member *list;
-{
- struct sudo_command *c;
+cmnd_matches(m)
struct member *m;
+{
struct alias *a;
+ struct sudo_command *c;
int rval, matched = UNSPEC;
- for (m = list; m != NULL; m = m->next) {
- switch (m->type) {
- case ALL:
+ switch (m->type) {
+ case ALL:
+ matched = !m->negated;
+ break;
+ case ALIAS:
+ if ((a = find_alias(m->name, CMNDALIAS)) != NULL) {
+ rval = cmndlist_matches(&a->members);
+ if (rval != UNSPEC)
+ matched = m->negated ? !rval : rval;
+ }
+ break;
+ case COMMAND:
+ c = (struct sudo_command *)m->name;
+ if (command_matches(c->cmnd, c->args))
matched = !m->negated;
- break;
- case ALIAS:
- if ((a = find_alias(m->name, CMNDALIAS)) != NULL) {
- rval = cmnd_matches(a->first_member);
- if (rval != UNSPEC)
- matched = m->negated ? !rval : rval;
- }
- break;
- case COMMAND:
- c = (struct sudo_command *)m->name;
- if (command_matches(c->cmnd, c->args))
- matched = !m->negated;
- break;
- }
+ break;
+ }
+ return(matched);
+}
+
+/*
+ * Check for cmnd and args in a list of members.
+ * Returns ALLOW, DENY or UNSPEC.
+ */
+int
+cmndlist_matches(list)
+ struct member_list *list;
+{
+ struct member *m;
+ int rval, matched = UNSPEC;
+
+ for (m = list->first; m != NULL; m = m->next) {
+ rval = cmnd_matches(m);
+ if (rval != UNSPEC)
+ matched = m->negated ? !rval : rval;
}
return(matched);
}
/* Characters that must be quoted in sudoers */
#define SUDOERS_QUOTED "*?[]!:\\,=#\""
-/*
- * Parsed sudoers info.
- */
-extern struct userspec *userspecs;
-extern struct defaults *defaults;
-
/*
* Local prototypes.
*/
int validated, match, host_match, runas_match, cmnd_match;
struct cmndspec *cs;
struct cmndtag *tags = NULL;
- struct member *runas;
+ struct member_list *runas;
struct privilege *priv;
struct userspec *us;
CLR(validated, FLAG_NO_USER);
CLR(validated, FLAG_NO_HOST);
match = DENY;
- for (us = userspecs; us != NULL; us = us->next) {
- if (user_matches(sudo_user.pw, us->user) != ALLOW)
+ /* XXX - it should be faster to start from the bottom and
+ work our way up and then just stop at the first match. */
+ LH_FOREACH_FWD(userspecs, us) {
+ if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)
continue;
- for (priv = us->privileges; priv != NULL; priv = priv->next) {
- if (host_matches(priv->hostlist) != ALLOW)
+ LH_FOREACH_FWD(us->privileges, priv) {
+ if (hostlist_matches(&priv->hostlist) != ALLOW)
continue;
- for (cs = priv->cmndlist; cs != NULL; cs = cs->next) {
+ LH_FOREACH_FWD(priv->cmndlist, cs) {
/* Only check the command when listing another user. */
if (user_uid == 0 || list_pw == NULL ||
user_uid == list_pw->pw_uid ||
/* Need to be runas user while stat'ing things. */
set_perms(PERM_RUNAS);
+ /* XXX - it should be faster to start from the bottom and
+ work our way up and then just stop at the first match. */
match = UNSPEC;
- for (us = userspecs; us != NULL; us = us->next) {
- if (user_matches(sudo_user.pw, us->user) != ALLOW)
+ LH_FOREACH_FWD(userspecs, us) {
+ if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)
continue;
CLR(validated, FLAG_NO_USER);
- for (priv = us->privileges; priv != NULL; priv = priv->next) {
- host_match = host_matches(priv->hostlist);
+ LH_FOREACH_FWD(us->privileges, priv) {
+ host_match = hostlist_matches(&priv->hostlist);
if (host_match == UNSPEC)
continue;
if (host_match == ALLOW)
CLR(validated, FLAG_NO_HOST);
runas = NULL;
- for (cs = priv->cmndlist; cs != NULL; cs = cs->next) {
- if (cs->runaslist != NULL)
- runas = cs->runaslist;
- runas_match = runas_matches(runas);
+ LH_FOREACH_FWD(priv->cmndlist, cs) {
+ if (!LH_EMPTY(cs->runaslist))
+ runas = &cs->runaslist;
+ runas_match = runaslist_matches(runas);
if (runas_match != UNSPEC) {
cmnd_match = cmnd_matches(cs->cmnd);
if (cmnd_match != UNSPEC)
printf("User %s may run the following commands on this host:\n",
pw->pw_name);
- for (us = userspecs; us != NULL; us = us->next) {
- if (user_matches(pw, us->user) != ALLOW ||
- host_matches(us->privileges->hostlist) != ALLOW)
+ LH_FOREACH_FWD(userspecs, us) {
+ /* XXX - why only check the first privilege here? */
+ if (userlist_matches(pw, &us->users) != ALLOW ||
+ hostlist_matches(&us->privileges.first->hostlist) != ALLOW)
continue;
- for (priv = us->privileges; priv != NULL; priv = priv->next) {
+ LH_FOREACH_FWD(us->privileges, priv) {
tags.noexec = def_noexec;
tags.setenv = def_setenv;
tags.nopasswd = !def_authenticate;
lbuf_append(&lbuf, " ", NULL);
- for (cs = priv->cmndlist; cs != NULL; cs = cs->next) {
- if (cs != priv->cmndlist)
+ LH_FOREACH_FWD(priv->cmndlist, cs) {
+ if (cs != LH_FIRST(priv->cmndlist))
lbuf_append(&lbuf, ", ", NULL);
lbuf_append(&lbuf, "(", NULL);
- if (cs->runaslist != NULL) {
- for (m = cs->runaslist; m != NULL; m = m->next) {
- if (m != cs->runaslist)
+ if (!LH_EMPTY(cs->runaslist)) {
+ LH_FOREACH_FWD(cs->runaslist, m) {
+ if (m != LH_FIRST(cs->runaslist))
lbuf_append(&lbuf, ", ", NULL);
print_member(&lbuf, m->name, m->type, m->negated,
RUNASALIAS);
{
struct defaults *d;
struct lbuf lbuf;
- char *prefix;
+ char *prefix = NULL;
int per_runas = 0, per_cmnd = 0;
lbuf_init(&lbuf, NULL, 4, 0);
- for (d = defaults, prefix = NULL; d != NULL; d = d->next) {
+ LH_FOREACH_FWD(defaults, d) {
switch (d->type) {
case DEFAULTS_HOST:
- if (host_matches(d->binding) != ALLOW)
+ if (hostlist_matches(&d->binding) != ALLOW)
continue;
break;
case DEFAULTS_USER:
- if (user_matches(pw, d->binding) != ALLOW)
+ if (userlist_matches(pw, &d->binding) != ALLOW)
continue;
break;
case DEFAULTS_RUNAS:
{
struct lbuf lbuf;
struct defaults *d;
- struct member *m, *binding;
+ struct member *m, *binding = NULL;
char *dname, *dsep;
int atype;
}
lbuf_init(&lbuf, NULL, 4, 0);
printf("Per-%s Defaults entries:\n", dname);
- for (d = defaults, binding = NULL; d != NULL; d = d->next) {
+ LH_FOREACH_FWD(defaults, d) {
if (d->type != dtype)
continue;
- if (d->binding != binding) {
- binding = d->binding;
+ if (binding != LH_FIRST(d->binding)) {
+ binding = LH_FIRST(d->binding);
lbuf_append(&lbuf, " Defaults", dsep, NULL);
for (m = binding; m != NULL; m = m->next) {
if (m != binding)
struct passwd *pw;
{
struct cmndspec *cs;
- struct member *match, *runas;
+ struct member *match;
+ struct member_list *runas;
struct privilege *priv;
struct userspec *us;
int rval = 1;
rval = sudo_ldap_display_cmnd(v, pw);
#endif
if (rval != 0 && !def_ignore_local_sudoers) {
- for (match = NULL, us = userspecs; us != NULL; us = us->next) {
- if (user_matches(pw, us->user) != ALLOW)
+ match = NULL;
+ LH_FOREACH_FWD(userspecs, us) {
+ if (userlist_matches(pw, &us->users) != ALLOW)
continue;
- for (priv = us->privileges; priv != NULL; priv = priv->next) {
- host_match = host_matches(priv->hostlist);
+ LH_FOREACH_FWD(us->privileges, priv) {
+ host_match = hostlist_matches(&priv->hostlist);
if (host_match == UNSPEC)
continue;
runas = NULL;
- for (cs = priv->cmndlist; cs != NULL; cs = cs->next) {
- if (cs->runaslist != NULL)
- runas = cs->runaslist;
- runas_match = runas_matches(runas);
+ LH_FOREACH_FWD(priv->cmndlist, cs) {
+ if (!LH_EMPTY(cs->runaslist) != NULL)
+ runas = &cs->runaslist;
+ runas_match = runaslist_matches(runas);
if (runas_match != UNSPEC) {
cmnd_match = cmnd_matches(cs->cmnd);
if (cmnd_match != UNSPEC)
break;
case ALIAS:
if ((a = find_alias(name, alias_type)) != NULL) {
- for (m = a->first_member; m != NULL; m = m->next) {
- if (m != a->first_member)
+ LH_FOREACH_FWD(a->members, m) {
+ if (m != LH_FIRST(a->members))
lbuf_append(lbuf, ", ", NULL);
print_member(lbuf, m->name, m->type,
negated ? !m->negated : m->negated, alias_type);
* pointer of the last entry is NULL and does not point back to the head.
*/
+/*
+ * Tail queue list head structure.
+ */
+struct defaults_list {
+ struct defaults *first;
+ struct defaults *last;
+};
+
+struct userspec_list {
+ struct userspec *first;
+ struct userspec *last;
+};
+
+struct member_list {
+ struct member *first;
+ struct member *last;
+};
+
+struct privilege_list {
+ struct privilege *first;
+ struct privilege *last;
+};
+
+struct cmndspec_list {
+ struct cmndspec *first;
+ struct cmndspec *last;
+};
+
/*
* Structure describing a user specification and list thereof.
*/
struct userspec {
- struct member *user; /* list of users */
- struct privilege *privileges; /* list of privileges */
+ struct member_list users; /* list of users */
+ struct privilege_list privileges; /* list of privileges */
struct userspec *prev, *next;
};
* Structure describing a privilege specification.
*/
struct privilege {
- struct member *hostlist; /* list of hosts */
- struct cmndspec *cmndlist; /* list of Cmnd_Specs */
+ struct member_list hostlist; /* list of hosts */
+ struct cmndspec_list cmndlist; /* list of Cmnd_Specs */
struct privilege *prev, *next;
};
* Structure describing a linked list of Cmnd_Specs.
*/
struct cmndspec {
- struct member *runaslist; /* list of runas users */
+ struct member_list runaslist; /* list of runas users */
struct member *cmnd; /* command to allow/deny */
struct cmndtag tags; /* tag specificaion */
struct cmndspec *prev, *next;
struct alias {
char *name; /* alias name */
int type; /* {USER,HOST,RUNAS,CMND}ALIAS */
- struct member *first_member; /* list of alias members */
+ struct member_list members; /* list of alias members */
};
/*
struct defaults {
char *var; /* variable name */
char *val; /* variable value */
- struct member *binding; /* user/host/runas binding */
+ struct member_list binding; /* user/host/runas binding */
int type; /* DEFAULTS{,_USER,_RUNAS,_HOST} */
int op; /* TRUE, FALSE, '+', '-' */
struct defaults *prev, *next;
/*
* Allocate space for a defaults entry and populate it.
*/
+#undef NEW_DEFAULT
#define NEW_DEFAULT(r, v1, v2, o) do { \
(r) = emalloc(sizeof(struct defaults)); \
(r)->var = (v1); \
/*
* Allocate space for a member and populate it.
*/
+#undef NEW_MEMBER
#define NEW_MEMBER(r, n, t) do { \
(r) = emalloc(sizeof(struct member)); \
(r)->name = (n); \
* Append one queue (or single entry) to another using the
* circular properties of the prev pointer to simplify the logic.
*/
+#undef LIST_APPEND
#define LIST_APPEND(h, e) do { \
void *_tail = (e)->prev; \
(h)->prev->next = (e); \
(h)->prev = _tail; \
} while (0)
+/*
+ * Append the list of entries to the head node and convert
+ * e from a semi-circle queue to normal doubly-linked list.
+ */
+#undef HEAD_APPEND
+#define HEAD_APPEND(h, e) do { \
+ void *_tail = (e)->prev; \
+ if ((h).first == NULL) \
+ (h).first = (e); \
+ else \
+ (h).last->next = (e); \
+ (e)->prev = (h).last; \
+ (h).last = _tail; \
+} while (0)
+
+/*
+ * Convert from a semi-circle queue to normal doubly-linked list
+ * with a head node.
+ */
+#undef LIST2HEAD
+#define LIST2HEAD(h, e) do { \
+ if ((e) != NULL) { \
+ (h).first = (e); \
+ (h).last = (e)->prev; \
+ (e)->prev = NULL; \
+ } else { \
+ (h).first = NULL; \
+ (h).last = NULL; \
+ } \
+} while (0)
+
+#undef LH_FOREACH_FWD
+#define LH_FOREACH_FWD(h, v) \
+ for ((v) = (h).first; (v) != NULL; (v) = (v)->next)
+
+#undef LH_FOREACH_REV
+#define LH_FOREACH_REV(h, v) \
+ for ((v) = (h).last; (v) != NULL; (v) = (v)->prev)
+
+/*
+ * Pop the last element off the end of h.
+ * XXX - really should return the popped element.
+ */
+#undef LH_POP
+#define LH_POP(h) do { \
+ if (!LH_EMPTY(h)) { \
+ if ((h).first == (h).last) \
+ (h).first = (h).last = NULL; \
+ else { \
+ (h).last = (h).last->prev; \
+ (h).last->next = NULL; \
+ } \
+ } \
+} while (0)
+
+#undef LH_INIT
+#define LH_INIT(h) do { \
+ (h).first = NULL; \
+ (h).last = NULL; \
+} while (0)
+
+#undef LH_EMPTY
+#define LH_EMPTY(h) ((h).first == NULL)
+
+#undef LH_FIRST
+#define LH_FIRST(h) ((h).first)
+
+#undef LH_LAST
+#define LH_LAST(h) ((h).last)
+
+#undef LIST_NEXT
+#define LIST_NEXT(e) ((e)->next)
+
+#undef LIST_PREV
+#define LIST_PREV(e) ((e)->prev)
+
+/*
+ * Parsed sudoers info.
+ */
+extern struct userspec_list userspecs;
+extern struct defaults_list defaults;
+
/*
* Prototypes
*/
int addr_matches __P((char *));
int alias_remove __P((char *, int));
int cmnd_matches __P((struct member *));
+int cmndlist_matches __P((struct member_list *));
int command_matches __P((char *, char *));
-int host_matches __P((struct member *));
+int hostlist_matches __P((struct member_list *));
int hostname_matches __P((char *, char *, char *));
int netgr_matches __P((char *, char *, char *, char *));
int no_aliases __P((void));
-int runas_matches __P((struct member *));
-int user_matches __P((struct passwd *, struct member *));
+int runaslist_matches __P((struct member_list *));
+int userlist_matches __P((struct passwd *, struct member_list *));
int usergr_matches __P((char *, char *, struct passwd *));
int userpw_matches __P((char *, char *, struct passwd *));
struct alias *find_alias __P((char *, int));
extern char *optarg;
extern int optind;
-extern struct defaults *defaults;
-extern struct userspec *userspecs;
-
int print_alias __P((VOID *, VOID *));
void dump_sudoers __P((void));
void print_defaults __P((void));
char **argv;
{
struct cmndspec *cs;
- struct member *runas;
+ struct member_list *runas;
struct privilege *priv;
struct userspec *us;
char *p, *grfile, *pwfile, *uflag, hbuf[MAXHOSTNAMELEN];
/* This loop must match the one in sudoers_lookup() */
printf("\nEntries for user %s:\n", user_name);
matched = UNSPEC;
- for (us = userspecs; us != NULL; us = us->next) {
- if (user_matches(sudo_user.pw, us->user) != TRUE)
+ LH_FOREACH_FWD(userspecs, us) {
+ if (userlist_matches(sudo_user.pw, &us->users) != TRUE)
continue;
- for (priv = us->privileges; priv != NULL; priv = priv->next) {
+ LH_FOREACH_FWD(us->privileges, priv) {
putchar('\n');
- print_privilege(priv);
+ print_privilege(priv); /* XXX */
putchar('\n');
- if (host_matches(priv->hostlist) == TRUE) {
+ if (hostlist_matches(&priv->hostlist) == TRUE) {
puts("\thost matched");
runas = NULL;
- for (cs = priv->cmndlist; cs != NULL; cs = cs->next) {
- if (cs->runaslist != NULL)
- runas = cs->runaslist;
- if (runas_matches(runas) == TRUE) {
+ LH_FOREACH_FWD(priv->cmndlist, cs) {
+ if (!LH_EMPTY(cs->runaslist))
+ runas = &cs->runaslist;
+ if (runaslist_matches(runas) == TRUE) {
puts("\trunas matched");
rval = cmnd_matches(cs->cmnd);
if (rval != UNSPEC)
struct defaults *d;
struct member *m;
- for (d = defaults; d != NULL; d = d->next) {
+ LH_FOREACH_FWD(defaults, d) {
(void) fputs("Defaults", stdout);
switch (d->type) {
case DEFAULTS_HOST:
putchar('!');
break;
}
- for (m = d->binding; m != NULL; m = m->next) {
- if (m != d->binding)
+ LH_FOREACH_FWD(d->binding, m) {
+ if (m != LH_FIRST(d->binding))
putchar(',');
print_member(m);
}
(void) printf("Runas_Alias\t%s = ", a->name);
break;
}
- for (m = a->first_member; m != NULL; m = m->next) {
- if (m != a->first_member)
+ LH_FOREACH_FWD(a->members, m) {
+ if (m != LH_FIRST(a->members))
fputs(", ", stdout);
if (m->type == COMMAND) {
c = (struct sudo_command *) m->name;
for (p = priv; p != NULL; p = p->next) {
if (p != priv)
fputs(" : ", stdout);
- for (m = p->hostlist; m != NULL; m = m->next) {
- if (m != p->hostlist)
+ LH_FOREACH_FWD(p->hostlist, m) {
+ if (m != LH_FIRST(p->hostlist))
fputs(", ", stdout);
print_member(m);
}
fputs(" = ", stdout);
tags.nopasswd = tags.noexec = UNSPEC;
- for (cs = p->cmndlist; cs != NULL; cs = cs->next) {
- if (cs != p->cmndlist)
+ LH_FOREACH_FWD(p->cmndlist, cs) {
+ if (cs != LH_FIRST(p->cmndlist))
fputs(", ", stdout);
- if (cs->runaslist) {
+ if (!LH_EMPTY(cs->runaslist)) {
fputs("(", stdout);
- for (m = cs->runaslist; m != NULL; m = m->next) {
- if (m != cs->runaslist)
+ LH_FOREACH_FWD(cs->runaslist, m) {
+ if (m != LH_FIRST(cs->runaslist))
fputs(", ", stdout);
print_member(m);
}
struct member *m;
struct userspec *us;
- for (us = userspecs; us != NULL; us = us->next) {
- for (m = us->user; m != NULL; m = m->next) {
- if (m != us->user)
+ LH_FOREACH_FWD(userspecs, us) {
+ LH_FOREACH_FWD(us->users, m) {
+ if (m != LH_FIRST(us->users))
fputs(", ", stdout);
print_member(m);
}
putchar('\t');
- print_privilege(us->privileges);
+ print_privilege(us->privileges.first); /* XXX */
putchar('\n');
}
}
extern char *optarg;
extern int optind;
-extern struct defaults *defaults;
-extern struct userspec *userspecs;
-
/*
* Globals
*/
setup_signals();
/* Edit the sudoers file(s) */
- for (sp = sudoerslist.first; sp != NULL; sp = sp->next) {
- if (sp != sudoerslist.first) {
+ LH_FOREACH_FWD(sudoerslist, sp) {
+ if (sp != LH_FIRST(sudoerslist)) {
printf("press return to edit %s: ", sp->path);
while ((ch = getchar()) != EOF && ch != '\n')
continue;
reparse_sudoers(editor, args, strict, quiet);
/* Install the sudoers temp files. */
- for (sp = sudoerslist.first; sp != NULL; sp = sp->next) {
+ LH_FOREACH_FWD(sudoerslist, sp) {
if (!sp->modified)
(void) unlink(sp->tpath);
else
* Parse the edited sudoers files and do sanity checking
*/
do {
- sp = sudoerslist.first;
- last = sudoerslist.last;
+ sp = LH_FIRST(sudoerslist);
+ last = LH_LAST(sudoerslist);
fp = fopen(sp->tpath, "r+");
if (fp == NULL)
errorx(1, "can't re-open temporary file (%s), %s unchanged.",
}
if (parse_error) {
/* Edit file with the parse error */
- for (sp = sudoerslist.first; sp != NULL; sp = sp->next) {
+ LH_FOREACH_FWD(sudoerslist, sp) {
if (errorfile == NULL || strcmp(sp->path, errorfile) == 0) {
edit_sudoers(sp, editor, args, errorlineno);
break;
FILE *fp;
/* Check for existing entry */
- for (entry = sudoerslist.first; entry != NULL; entry = entry->next) {
+ LH_FOREACH_FWD(sudoerslist, entry) {
if (strcmp(path, entry->path) == 0)
break;
}
errorx(1, "%s busy, try again later", entry->path);
if ((fp = fdopen(entry->fd, "r")) == NULL)
error(1, "%s", entry->path);
+ /* XXX - macro here? */
if (sudoerslist.last == NULL)
sudoerslist.first = sudoerslist.last = entry;
else {
int error = 0;
/* Forward check. */
- for (us = userspecs; us != NULL; us = us->next) {
- for (m = us->user; m != NULL; m = m->next) {
+ LH_FOREACH_FWD(userspecs, us) {
+ LH_FOREACH_FWD(us->users, m) {
if (m->type == USERALIAS) {
if (find_alias(m->name, m->type) == NULL) {
fprintf(stderr,
}
}
}
- for (priv = us->privileges; priv != NULL; priv = priv->next) {
- for (m = priv->hostlist; m != NULL; m = m->next) {
+ LH_FOREACH_FWD(us->privileges, priv) {
+ LH_FOREACH_FWD(priv->hostlist, m) {
if (m->type == HOSTALIAS) {
if (find_alias(m->name, m->type) == NULL) {
fprintf(stderr,
}
}
}
- for (cs = priv->cmndlist; cs != NULL; cs = cs->next) {
- for (m = cs->runaslist; m != NULL; m = m->next) {
+ LH_FOREACH_FWD(priv->cmndlist, cs) {
+ LH_FOREACH_FWD(cs->runaslist, m) {
if (m->type == RUNASALIAS) {
if (find_alias(m->name, m->type) == NULL) {
fprintf(stderr,
}
/* Reverse check (destructive) */
- for (us = userspecs; us != NULL; us = us->next) {
- for (m = us->user; m != NULL; m = m->next) {
+ LH_FOREACH_FWD(userspecs, us) {
+ LH_FOREACH_FWD(us->users, m) {
if (m->type == USERALIAS)
(void) alias_remove(m->name, m->type);
}
- for (priv = us->privileges; priv != NULL; priv = priv->next) {
- for (m = priv->hostlist; m != NULL; m = m->next) {
+ LH_FOREACH_FWD(us->privileges, priv) {
+ LH_FOREACH_FWD(priv->hostlist, m) {
if (m->type == HOSTALIAS)
(void) alias_remove(m->name, m->type);
}
- for (cs = priv->cmndlist; cs != NULL; cs = cs->next) {
- for (m = cs->runaslist; m != NULL; m = m->next) {
+ LH_FOREACH_FWD(priv->cmndlist, cs) {
+ LH_FOREACH_FWD(cs->runaslist, m) {
if (m->type == RUNASALIAS)
(void) alias_remove(m->name, m->type);
}
{
struct sudoersfile *sp;
- for (sp = sudoerslist.first; sp != NULL; sp = sp->next) {
+ LH_FOREACH_FWD(sudoerslist, sp) {
if (sp->tpath != NULL)
(void) unlink(sp->tpath);
}