Annotation of embedaddon/sudo/plugins/sudoers/parse.c, revision 1.1.1.2
1.1 misho 1: /*
1.1.1.2 ! misho 2: * Copyright (c) 2004-2005, 2007-2012 Todd C. Miller <Todd.Miller@courtesan.com>
1.1 misho 3: *
4: * Permission to use, copy, modify, and distribute this software for any
5: * purpose with or without fee is hereby granted, provided that the above
6: * copyright notice and this permission notice appear in all copies.
7: *
8: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
16: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17: */
18:
19: #include <config.h>
20:
21: #include <sys/types.h>
22: #include <sys/param.h>
23: #include <stdio.h>
24: #ifdef STDC_HEADERS
25: # include <stdlib.h>
26: # include <stddef.h>
27: #else
28: # ifdef HAVE_STDLIB_H
29: # include <stdlib.h>
30: # endif
31: #endif /* STDC_HEADERS */
32: #ifdef HAVE_STRING_H
33: # include <string.h>
34: #endif /* HAVE_STRING_H */
35: #ifdef HAVE_STRINGS_H
36: # include <strings.h>
37: #endif /* HAVE_STRINGS_H */
38: #ifdef HAVE_UNISTD_H
39: # include <unistd.h>
40: #endif /* HAVE_UNISTD_H */
41: #include <ctype.h>
42: #include <pwd.h>
43: #include <grp.h>
44:
45: #include "sudoers.h"
46: #include "parse.h"
47: #include "lbuf.h"
48: #include <gram.h>
49:
50: /* Characters that must be quoted in sudoers */
51: #define SUDOERS_QUOTED ":\\,=#\""
52:
53: /* sudoers nsswitch routines */
54: struct sudo_nss sudo_nss_file = {
55: &sudo_nss_file,
56: NULL,
57: sudo_file_open,
58: sudo_file_close,
59: sudo_file_parse,
60: sudo_file_setdefs,
61: sudo_file_lookup,
62: sudo_file_display_cmnd,
63: sudo_file_display_defaults,
64: sudo_file_display_bound_defaults,
65: sudo_file_display_privs
66: };
67:
68: /*
69: * Parser externs.
70: */
71: extern FILE *yyin;
72: extern char *errorfile;
1.1.1.2 ! misho 73: extern int errorlineno;
! 74: extern bool parse_error;
1.1 misho 75:
76: /*
77: * Local prototypes.
78: */
79: static void print_member(struct lbuf *, char *, int, int, int);
80: static int display_bound_defaults(int, struct lbuf *);
81:
82: int
83: sudo_file_open(struct sudo_nss *nss)
84: {
1.1.1.2 ! misho 85: debug_decl(sudo_file_open, SUDO_DEBUG_NSS)
! 86:
1.1 misho 87: if (def_ignore_local_sudoers)
1.1.1.2 ! misho 88: debug_return_int(-1);
! 89: nss->handle = open_sudoers(sudoers_file, false, NULL);
! 90: debug_return_int(nss->handle ? 0 : -1);
1.1 misho 91: }
92:
93: int
94: sudo_file_close(struct sudo_nss *nss)
95: {
1.1.1.2 ! misho 96: debug_decl(sudo_file_close, SUDO_DEBUG_NSS)
! 97:
1.1 misho 98: /* Free parser data structures and close sudoers file. */
99: init_parser(NULL, 0);
100: if (nss->handle != NULL) {
101: fclose(nss->handle);
102: nss->handle = NULL;
103: yyin = NULL;
104: }
1.1.1.2 ! misho 105: debug_return_int(0);
1.1 misho 106: }
107:
108: /*
109: * Parse the specified sudoers file.
110: */
111: int
112: sudo_file_parse(struct sudo_nss *nss)
113: {
1.1.1.2 ! misho 114: debug_decl(sudo_file_close, SUDO_DEBUG_NSS)
! 115:
1.1 misho 116: if (nss->handle == NULL)
1.1.1.2 ! misho 117: debug_return_int(-1);
1.1 misho 118:
119: init_parser(sudoers_file, 0);
120: yyin = nss->handle;
121: if (yyparse() != 0 || parse_error) {
1.1.1.2 ! misho 122: if (errorlineno != -1) {
! 123: log_error(0, _("parse error in %s near line %d"),
! 124: errorfile, errorlineno);
! 125: } else {
! 126: log_error(0, _("parse error in %s"), errorfile);
! 127: }
! 128: debug_return_int(-1);
1.1 misho 129: }
1.1.1.2 ! misho 130: debug_return_int(0);
1.1 misho 131: }
132:
133: /*
134: * Wrapper around update_defaults() for nsswitch code.
135: */
136: int
137: sudo_file_setdefs(struct sudo_nss *nss)
138: {
1.1.1.2 ! misho 139: debug_decl(sudo_file_setdefs, SUDO_DEBUG_NSS)
! 140:
1.1 misho 141: if (nss->handle == NULL)
1.1.1.2 ! misho 142: debug_return_int(-1);
1.1 misho 143:
144: if (!update_defaults(SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER))
1.1.1.2 ! misho 145: debug_return_int(-1);
! 146: debug_return_int(0);
1.1 misho 147: }
148:
149: /*
150: * Look up the user in the parsed sudoers file and check to see if they are
151: * allowed to run the specified command on this host as the target user.
152: */
153: int
154: sudo_file_lookup(struct sudo_nss *nss, int validated, int pwflag)
155: {
156: int match, host_match, runas_match, cmnd_match;
157: struct cmndspec *cs;
158: struct cmndtag *tags = NULL;
159: struct privilege *priv;
160: struct userspec *us;
1.1.1.2 ! misho 161: debug_decl(sudo_file_lookup, SUDO_DEBUG_NSS)
1.1 misho 162:
163: if (nss->handle == NULL)
1.1.1.2 ! misho 164: debug_return_int(validated);
1.1 misho 165:
166: /*
167: * Only check the actual command if pwflag is not set.
168: * It is set for the "validate", "list" and "kill" pseudo-commands.
169: * Always check the host and user.
170: */
171: if (pwflag) {
172: int nopass;
173: enum def_tuple pwcheck;
174:
175: pwcheck = (pwflag == -1) ? never : sudo_defs_table[pwflag].sd_un.tuple;
1.1.1.2 ! misho 176: nopass = (pwcheck == all) ? true : false;
1.1 misho 177:
178: if (list_pw == NULL)
179: SET(validated, FLAG_NO_CHECK);
180: CLR(validated, FLAG_NO_USER);
181: CLR(validated, FLAG_NO_HOST);
182: match = DENY;
183: tq_foreach_fwd(&userspecs, us) {
184: if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)
185: continue;
186: tq_foreach_fwd(&us->privileges, priv) {
187: if (hostlist_matches(&priv->hostlist) != ALLOW)
188: continue;
189: tq_foreach_fwd(&priv->cmndlist, cs) {
190: /* Only check the command when listing another user. */
191: if (user_uid == 0 || list_pw == NULL ||
192: user_uid == list_pw->pw_uid ||
193: cmnd_matches(cs->cmnd) == ALLOW)
194: match = ALLOW;
1.1.1.2 ! misho 195: if ((pwcheck == any && cs->tags.nopasswd == true) ||
! 196: (pwcheck == all && cs->tags.nopasswd != true))
1.1 misho 197: nopass = cs->tags.nopasswd;
198: }
199: }
200: }
201: if (match == ALLOW || user_uid == 0) {
202: /* User has an entry for this host. */
203: SET(validated, VALIDATE_OK);
204: } else if (match == DENY)
205: SET(validated, VALIDATE_NOT_OK);
206: if (pwcheck == always && def_authenticate)
207: SET(validated, FLAG_CHECK_USER);
1.1.1.2 ! misho 208: else if (pwcheck == never || nopass == true)
! 209: def_authenticate = false;
! 210: debug_return_int(validated);
1.1 misho 211: }
212:
213: /* Need to be runas user while stat'ing things. */
214: set_perms(PERM_RUNAS);
215:
216: match = UNSPEC;
217: tq_foreach_rev(&userspecs, us) {
218: if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)
219: continue;
220: CLR(validated, FLAG_NO_USER);
221: tq_foreach_rev(&us->privileges, priv) {
222: host_match = hostlist_matches(&priv->hostlist);
223: if (host_match == ALLOW)
224: CLR(validated, FLAG_NO_HOST);
225: else
226: continue;
227: tq_foreach_rev(&priv->cmndlist, cs) {
228: runas_match = runaslist_matches(&cs->runasuserlist,
229: &cs->runasgrouplist);
230: if (runas_match == ALLOW) {
231: cmnd_match = cmnd_matches(cs->cmnd);
232: if (cmnd_match != UNSPEC) {
233: match = cmnd_match;
234: tags = &cs->tags;
235: #ifdef HAVE_SELINUX
236: /* Set role and type if not specified on command line. */
237: if (user_role == NULL)
238: user_role = cs->role ? estrdup(cs->role) : def_role;
239: if (user_type == NULL)
240: user_type = cs->type ? estrdup(cs->type) : def_type;
241: #endif /* HAVE_SELINUX */
242: goto matched2;
243: }
244: }
245: }
246: }
247: }
248: matched2:
249: if (match == ALLOW) {
250: SET(validated, VALIDATE_OK);
251: CLR(validated, VALIDATE_NOT_OK);
252: if (tags != NULL) {
253: if (tags->nopasswd != UNSPEC)
254: def_authenticate = !tags->nopasswd;
255: if (tags->noexec != UNSPEC)
256: def_noexec = tags->noexec;
257: if (tags->setenv != UNSPEC)
258: def_setenv = tags->setenv;
259: if (tags->log_input != UNSPEC)
260: def_log_input = tags->log_input;
261: if (tags->log_output != UNSPEC)
262: def_log_output = tags->log_output;
263: }
264: } else if (match == DENY) {
265: SET(validated, VALIDATE_NOT_OK);
266: CLR(validated, VALIDATE_OK);
267: if (tags != NULL && tags->nopasswd != UNSPEC)
268: def_authenticate = !tags->nopasswd;
269: }
270: restore_perms();
1.1.1.2 ! misho 271: debug_return_int(validated);
1.1 misho 272: }
273:
274: #define TAG_CHANGED(t) \
275: (cs->tags.t != UNSPEC && cs->tags.t != IMPLIED && cs->tags.t != tags->t)
276:
277: static void
278: sudo_file_append_cmnd(struct cmndspec *cs, struct cmndtag *tags,
279: struct lbuf *lbuf)
280: {
281: struct member *m;
1.1.1.2 ! misho 282: debug_decl(sudo_file_append_cmnd, SUDO_DEBUG_NSS)
1.1 misho 283:
284: #ifdef HAVE_SELINUX
285: if (cs->role)
286: lbuf_append(lbuf, "ROLE=%s ", cs->role);
287: if (cs->type)
288: lbuf_append(lbuf, "TYPE=%s ", cs->type);
289: #endif /* HAVE_SELINUX */
290: if (TAG_CHANGED(setenv)) {
291: lbuf_append(lbuf, cs->tags.setenv ? "SETENV: " : "NOSETENV: ");
292: tags->setenv = cs->tags.setenv;
293: }
294: if (TAG_CHANGED(noexec)) {
295: lbuf_append(lbuf, cs->tags.noexec ? "NOEXEC: " : "EXEC: ");
296: tags->noexec = cs->tags.noexec;
297: }
298: if (TAG_CHANGED(nopasswd)) {
299: lbuf_append(lbuf, cs->tags.nopasswd ? "NOPASSWD: " : "PASSWD: ");
300: tags->nopasswd = cs->tags.nopasswd;
301: }
302: if (TAG_CHANGED(log_input)) {
303: lbuf_append(lbuf, cs->tags.log_input ? "LOG_INPUT: " : "NOLOG_INPUT: ");
304: tags->log_input = cs->tags.log_input;
305: }
306: if (TAG_CHANGED(log_output)) {
307: lbuf_append(lbuf, cs->tags.log_output ? "LOG_OUTPUT: " : "NOLOG_OUTPUT: ");
308: tags->log_output = cs->tags.log_output;
309: }
310: m = cs->cmnd;
311: print_member(lbuf, m->name, m->type, m->negated,
312: CMNDALIAS);
1.1.1.2 ! misho 313: debug_return;
1.1 misho 314: }
315:
316: static int
317: sudo_file_display_priv_short(struct passwd *pw, struct userspec *us,
318: struct lbuf *lbuf)
319: {
320: struct cmndspec *cs;
321: struct member *m;
322: struct privilege *priv;
323: struct cmndtag tags;
324: int nfound = 0;
1.1.1.2 ! misho 325: debug_decl(sudo_file_display_priv_short, SUDO_DEBUG_NSS)
1.1 misho 326:
327: tq_foreach_fwd(&us->privileges, priv) {
328: if (hostlist_matches(&priv->hostlist) != ALLOW)
329: continue;
330: tags.noexec = UNSPEC;
331: tags.setenv = UNSPEC;
332: tags.nopasswd = UNSPEC;
333: tags.log_input = UNSPEC;
334: tags.log_output = UNSPEC;
335: lbuf_append(lbuf, " ");
336: tq_foreach_fwd(&priv->cmndlist, cs) {
337: if (cs != tq_first(&priv->cmndlist))
338: lbuf_append(lbuf, ", ");
339: lbuf_append(lbuf, "(");
340: if (!tq_empty(&cs->runasuserlist)) {
341: tq_foreach_fwd(&cs->runasuserlist, m) {
342: if (m != tq_first(&cs->runasuserlist))
343: lbuf_append(lbuf, ", ");
344: print_member(lbuf, m->name, m->type, m->negated,
345: RUNASALIAS);
346: }
347: } else if (tq_empty(&cs->runasgrouplist)) {
348: lbuf_append(lbuf, "%s", def_runas_default);
349: } else {
350: lbuf_append(lbuf, "%s", pw->pw_name);
351: }
352: if (!tq_empty(&cs->runasgrouplist)) {
353: lbuf_append(lbuf, " : ");
354: tq_foreach_fwd(&cs->runasgrouplist, m) {
355: if (m != tq_first(&cs->runasgrouplist))
356: lbuf_append(lbuf, ", ");
357: print_member(lbuf, m->name, m->type, m->negated,
358: RUNASALIAS);
359: }
360: }
361: lbuf_append(lbuf, ") ");
362: sudo_file_append_cmnd(cs, &tags, lbuf);
363: nfound++;
364: }
365: lbuf_append(lbuf, "\n");
366: }
1.1.1.2 ! misho 367: debug_return_int(nfound);
1.1 misho 368: }
369:
370: static int
371: sudo_file_display_priv_long(struct passwd *pw, struct userspec *us,
372: struct lbuf *lbuf)
373: {
374: struct cmndspec *cs;
375: struct member *m;
376: struct privilege *priv;
377: struct cmndtag tags;
378: int nfound = 0;
1.1.1.2 ! misho 379: debug_decl(sudo_file_display_priv_long, SUDO_DEBUG_NSS)
1.1 misho 380:
381: tq_foreach_fwd(&us->privileges, priv) {
382: if (hostlist_matches(&priv->hostlist) != ALLOW)
383: continue;
384: tags.noexec = UNSPEC;
385: tags.setenv = UNSPEC;
386: tags.nopasswd = UNSPEC;
387: tags.log_input = UNSPEC;
388: tags.log_output = UNSPEC;
389: lbuf_append(lbuf, _("\nSudoers entry:\n"));
390: tq_foreach_fwd(&priv->cmndlist, cs) {
391: lbuf_append(lbuf, _(" RunAsUsers: "));
392: if (!tq_empty(&cs->runasuserlist)) {
393: tq_foreach_fwd(&cs->runasuserlist, m) {
394: if (m != tq_first(&cs->runasuserlist))
395: lbuf_append(lbuf, ", ");
396: print_member(lbuf, m->name, m->type, m->negated,
397: RUNASALIAS);
398: }
399: } else if (tq_empty(&cs->runasgrouplist)) {
400: lbuf_append(lbuf, "%s", def_runas_default);
401: } else {
402: lbuf_append(lbuf, "%s", pw->pw_name);
403: }
404: lbuf_append(lbuf, "\n");
405: if (!tq_empty(&cs->runasgrouplist)) {
406: lbuf_append(lbuf, _(" RunAsGroups: "));
407: tq_foreach_fwd(&cs->runasgrouplist, m) {
408: if (m != tq_first(&cs->runasgrouplist))
409: lbuf_append(lbuf, ", ");
410: print_member(lbuf, m->name, m->type, m->negated,
411: RUNASALIAS);
412: }
413: lbuf_append(lbuf, "\n");
414: }
415: lbuf_append(lbuf, _(" Commands:\n\t"));
416: sudo_file_append_cmnd(cs, &tags, lbuf);
417: lbuf_append(lbuf, "\n");
418: nfound++;
419: }
420: }
1.1.1.2 ! misho 421: debug_return_int(nfound);
1.1 misho 422: }
423:
424: int
425: sudo_file_display_privs(struct sudo_nss *nss, struct passwd *pw,
426: struct lbuf *lbuf)
427: {
428: struct userspec *us;
429: int nfound = 0;
1.1.1.2 ! misho 430: debug_decl(sudo_file_display_priv, SUDO_DEBUG_NSS)
1.1 misho 431:
432: if (nss->handle == NULL)
433: goto done;
434:
435: tq_foreach_fwd(&userspecs, us) {
436: if (userlist_matches(pw, &us->users) != ALLOW)
437: continue;
438:
439: if (long_list)
440: nfound += sudo_file_display_priv_long(pw, us, lbuf);
441: else
442: nfound += sudo_file_display_priv_short(pw, us, lbuf);
443: }
444: done:
1.1.1.2 ! misho 445: debug_return_int(nfound);
1.1 misho 446: }
447:
448: /*
449: * Display matching Defaults entries for the given user on this host.
450: */
451: int
452: sudo_file_display_defaults(struct sudo_nss *nss, struct passwd *pw,
453: struct lbuf *lbuf)
454: {
455: struct defaults *d;
456: char *prefix;
457: int nfound = 0;
1.1.1.2 ! misho 458: debug_decl(sudo_file_display_defaults, SUDO_DEBUG_NSS)
1.1 misho 459:
460: if (nss->handle == NULL)
461: goto done;
462:
463: if (lbuf->len == 0 || isspace((unsigned char)lbuf->buf[lbuf->len - 1]))
464: prefix = " ";
465: else
466: prefix = ", ";
467:
468: tq_foreach_fwd(&defaults, d) {
469: switch (d->type) {
470: case DEFAULTS_HOST:
471: if (hostlist_matches(&d->binding) != ALLOW)
472: continue;
473: break;
474: case DEFAULTS_USER:
475: if (userlist_matches(pw, &d->binding) != ALLOW)
476: continue;
477: break;
478: case DEFAULTS_RUNAS:
479: case DEFAULTS_CMND:
480: continue;
481: }
482: if (d->val != NULL) {
483: lbuf_append(lbuf, "%s%s%s", prefix, d->var,
484: d->op == '+' ? "+=" : d->op == '-' ? "-=" : "=");
485: if (strpbrk(d->val, " \t") != NULL) {
486: lbuf_append(lbuf, "\"");
487: lbuf_append_quoted(lbuf, "\"", "%s", d->val);
488: lbuf_append(lbuf, "\"");
489: } else
490: lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", d->val);
491: } else
492: lbuf_append(lbuf, "%s%s%s", prefix,
1.1.1.2 ! misho 493: d->op == false ? "!" : "", d->var);
1.1 misho 494: prefix = ", ";
495: nfound++;
496: }
497: done:
1.1.1.2 ! misho 498: debug_return_int(nfound);
1.1 misho 499: }
500:
501: /*
502: * Display Defaults entries that are per-runas or per-command
503: */
504: int
505: sudo_file_display_bound_defaults(struct sudo_nss *nss, struct passwd *pw,
506: struct lbuf *lbuf)
507: {
508: int nfound = 0;
1.1.1.2 ! misho 509: debug_decl(sudo_file_display_bound_defaults, SUDO_DEBUG_NSS)
1.1 misho 510:
511: /* XXX - should only print ones that match what the user can do. */
512: nfound += display_bound_defaults(DEFAULTS_RUNAS, lbuf);
513: nfound += display_bound_defaults(DEFAULTS_CMND, lbuf);
514:
1.1.1.2 ! misho 515: debug_return_int(nfound);
1.1 misho 516: }
517:
518: /*
519: * Display Defaults entries of the given type.
520: */
521: static int
522: display_bound_defaults(int dtype, struct lbuf *lbuf)
523: {
524: struct defaults *d;
525: struct member *m, *binding = NULL;
526: char *dsep;
527: int atype, nfound = 0;
1.1.1.2 ! misho 528: debug_decl(display_bound_defaults, SUDO_DEBUG_NSS)
1.1 misho 529:
530: switch (dtype) {
531: case DEFAULTS_HOST:
532: atype = HOSTALIAS;
533: dsep = "@";
534: break;
535: case DEFAULTS_USER:
536: atype = USERALIAS;
537: dsep = ":";
538: break;
539: case DEFAULTS_RUNAS:
540: atype = RUNASALIAS;
541: dsep = ">";
542: break;
543: case DEFAULTS_CMND:
544: atype = CMNDALIAS;
545: dsep = "!";
546: break;
547: default:
1.1.1.2 ! misho 548: debug_return_int(-1);
1.1 misho 549: }
550: tq_foreach_fwd(&defaults, d) {
551: if (d->type != dtype)
552: continue;
553:
554: nfound++;
555: if (binding != tq_first(&d->binding)) {
556: binding = tq_first(&d->binding);
557: if (nfound != 1)
558: lbuf_append(lbuf, "\n");
559: lbuf_append(lbuf, " Defaults%s", dsep);
560: for (m = binding; m != NULL; m = m->next) {
561: if (m != binding)
562: lbuf_append(lbuf, ",");
563: print_member(lbuf, m->name, m->type, m->negated, atype);
564: lbuf_append(lbuf, " ");
565: }
566: } else
567: lbuf_append(lbuf, ", ");
568: if (d->val != NULL) {
569: lbuf_append(lbuf, "%s%s%s", d->var, d->op == '+' ? "+=" :
570: d->op == '-' ? "-=" : "=", d->val);
571: } else
1.1.1.2 ! misho 572: lbuf_append(lbuf, "%s%s", d->op == false ? "!" : "", d->var);
1.1 misho 573: }
574:
1.1.1.2 ! misho 575: debug_return_int(nfound);
1.1 misho 576: }
577:
578: int
579: sudo_file_display_cmnd(struct sudo_nss *nss, struct passwd *pw)
580: {
581: struct cmndspec *cs;
582: struct member *match;
583: struct privilege *priv;
584: struct userspec *us;
585: int rval = 1;
586: int host_match, runas_match, cmnd_match;
1.1.1.2 ! misho 587: debug_decl(sudo_file_display_cmnd, SUDO_DEBUG_NSS)
1.1 misho 588:
589: if (nss->handle == NULL)
590: goto done;
591:
592: match = NULL;
593: tq_foreach_rev(&userspecs, us) {
594: if (userlist_matches(pw, &us->users) != ALLOW)
595: continue;
596:
597: tq_foreach_rev(&us->privileges, priv) {
598: host_match = hostlist_matches(&priv->hostlist);
599: if (host_match != ALLOW)
600: continue;
601: tq_foreach_rev(&priv->cmndlist, cs) {
602: runas_match = runaslist_matches(&cs->runasuserlist,
603: &cs->runasgrouplist);
604: if (runas_match == ALLOW) {
605: cmnd_match = cmnd_matches(cs->cmnd);
606: if (cmnd_match != UNSPEC) {
607: match = host_match && runas_match ? cs->cmnd : NULL;
608: goto matched;
609: }
610: }
611: }
612: }
613: }
614: matched:
615: if (match != NULL && !match->negated) {
616: sudo_printf(SUDO_CONV_INFO_MSG, "%s%s%s\n",
617: safe_cmnd, user_args ? " " : "", user_args ? user_args : "");
618: rval = 0;
619: }
620: done:
1.1.1.2 ! misho 621: debug_return_int(rval);
1.1 misho 622: }
623:
624: /*
625: * Print the contents of a struct member to stdout
626: */
627: static void
628: _print_member(struct lbuf *lbuf, char *name, int type, int negated,
629: int alias_type)
630: {
631: struct alias *a;
632: struct member *m;
633: struct sudo_command *c;
1.1.1.2 ! misho 634: debug_decl(_print_member, SUDO_DEBUG_NSS)
1.1 misho 635:
636: switch (type) {
637: case ALL:
638: lbuf_append(lbuf, "%sALL", negated ? "!" : "");
639: break;
640: case COMMAND:
641: c = (struct sudo_command *) name;
642: if (negated)
643: lbuf_append(lbuf, "!");
644: lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", c->cmnd);
645: if (c->args) {
646: lbuf_append(lbuf, " ");
647: lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", c->args);
648: }
649: break;
650: case ALIAS:
651: if ((a = alias_find(name, alias_type)) != NULL) {
652: tq_foreach_fwd(&a->members, m) {
653: if (m != tq_first(&a->members))
654: lbuf_append(lbuf, ", ");
655: _print_member(lbuf, m->name, m->type,
656: negated ? !m->negated : m->negated, alias_type);
657: }
658: break;
659: }
660: /* FALLTHROUGH */
661: default:
662: lbuf_append(lbuf, "%s%s", negated ? "!" : "", name);
663: break;
664: }
1.1.1.2 ! misho 665: debug_return;
1.1 misho 666: }
667:
668: static void
669: print_member(struct lbuf *lbuf, char *name, int type, int negated,
670: int alias_type)
671: {
672: alias_seqno++;
673: _print_member(lbuf, name, type, negated, alias_type);
674: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>