Annotation of embedaddon/sudo/plugins/sudoers/sssd.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (c) 2003-2012 Todd C. Miller <Todd.Miller@courtesan.com>
3: * Copyright (c) 2011 Daniel Kopecek <dkopecek@redhat.com>
4: *
5: * This code is derived from software contributed by Aaron Spangler.
6: *
7: * Permission to use, copy, modify, and distribute this software for any
8: * purpose with or without fee is hereby granted, provided that the above
9: * copyright notice and this permission notice appear in all copies.
10: *
11: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18: */
19:
20: #include <config.h>
21:
22: #include <sys/types.h>
23: #include <sys/time.h>
24: #include <sys/param.h>
25: #include <sys/stat.h>
26: #include <stdio.h>
27: #ifdef STDC_HEADERS
28: # include <stdlib.h>
29: # include <stddef.h>
30: #else
31: # ifdef HAVE_STDLIB_H
32: # include <stdlib.h>
33: # endif
34: #endif /* STDC_HEADERS */
35: #ifdef HAVE_STRING_H
36: # include <string.h>
37: #endif /* HAVE_STRING_H */
38: #ifdef HAVE_STRINGS_H
39: # include <strings.h>
40: #endif /* HAVE_STRINGS_H */
41: #ifdef HAVE_UNISTD_H
42: # include <unistd.h>
43: #endif /* HAVE_UNISTD_H */
44: #if TIME_WITH_SYS_TIME
45: # include <time.h>
46: #endif
47: #ifdef HAVE_DLOPEN
48: # include <dlfcn.h>
49: #else
50: # include "compat/dlfcn.h"
51: #endif
52: #include <ctype.h>
53: #include <pwd.h>
54: #include <grp.h>
55:
56: #include <errno.h>
57: #include <stdint.h>
58:
59: #include "sudoers.h"
60: #include "parse.h"
61: #include "lbuf.h"
62: #include "sudo_debug.h"
63:
64: /* SSSD <--> SUDO interface - do not change */
65: struct sss_sudo_attr {
66: char *name;
67: char **values;
68: unsigned int num_values;
69: };
70:
71: struct sss_sudo_rule {
72: unsigned int num_attrs;
73: struct sss_sudo_attr *attrs;
74: };
75:
76: struct sss_sudo_result {
77: unsigned int num_rules;
78: struct sss_sudo_rule *rules;
79: };
80:
81: typedef int (*sss_sudo_send_recv_t)(uid_t, const char*, const char*,
82: uint32_t*, struct sss_sudo_result**);
83:
84: typedef int (*sss_sudo_send_recv_defaults_t)(uid_t, const char*, uint32_t*,
85: char**, struct sss_sudo_result**);
86:
87: typedef void (*sss_sudo_free_result_t)(struct sss_sudo_result*);
88:
89: typedef int (*sss_sudo_get_values_t)(struct sss_sudo_rule*, const char*,
90: char***);
91:
92: typedef void (*sss_sudo_free_values_t)(char**);
93:
94: /* sudo_nss implementation */
95:
96: struct sudo_sss_handle {
97: char *domainname;
98: struct passwd *pw;
99: void *ssslib;
100: sss_sudo_send_recv_t fn_send_recv;
101: sss_sudo_send_recv_defaults_t fn_send_recv_defaults;
102: sss_sudo_free_result_t fn_free_result;
103: sss_sudo_get_values_t fn_get_values;
104: sss_sudo_free_values_t fn_free_values;
105: };
106:
107: static int sudo_sss_open(struct sudo_nss *nss);
108: static int sudo_sss_close(struct sudo_nss *nss);
109: static int sudo_sss_parse(struct sudo_nss *nss);
110: static void sudo_sss_parse_options(struct sudo_sss_handle *handle,
111: struct sss_sudo_rule *rule);
112: static int sudo_sss_setdefs(struct sudo_nss *nss);
113: static int sudo_sss_lookup(struct sudo_nss *nss, int ret, int pwflag);
114: static int sudo_sss_display_cmnd(struct sudo_nss *nss, struct passwd *pw);
115: static int sudo_sss_display_defaults(struct sudo_nss *nss, struct passwd *pw,
116: struct lbuf *lbuf);
117:
118: static int sudo_sss_display_bound_defaults(struct sudo_nss *nss,
119: struct passwd *pw, struct lbuf *lbuf);
120:
121: static int sudo_sss_display_privs(struct sudo_nss *nss, struct passwd *pw,
122: struct lbuf *lbuf);
123:
124:
125: static struct sss_sudo_result *sudo_sss_result_get(struct sudo_nss *nss,
126: struct passwd *pw,
127: uint32_t *state);
128:
129: static void
130: sudo_sss_attrcpy(struct sss_sudo_attr *dst, const struct sss_sudo_attr *src)
131: {
132: int i;
133: debug_decl(sudo_sss_attrcpy, SUDO_DEBUG_SSSD)
134:
135: sudo_debug_printf(SUDO_DEBUG_DEBUG, "dst=%p, src=%p", dst, src);
136: sudo_debug_printf(SUDO_DEBUG_INFO, "emalloc: cnt=%d", src->num_values);
137:
138: dst->name = estrdup(src->name);
139: dst->num_values = src->num_values;
140: dst->values = emalloc2(dst->num_values, sizeof(char *));
141:
142: for (i = 0; i < dst->num_values; ++i)
143: dst->values[i] = estrdup(src->values[i]);
144:
145: debug_return;
146: }
147:
148: static void
149: sudo_sss_rulecpy(struct sss_sudo_rule *dst, const struct sss_sudo_rule *src)
150: {
151: int i;
152: debug_decl(sudo_sss_rulecpy, SUDO_DEBUG_SSSD)
153:
154: sudo_debug_printf(SUDO_DEBUG_DEBUG, "dst=%p, src=%p", dst, src);
155: sudo_debug_printf(SUDO_DEBUG_INFO, "emalloc: cnt=%d", src->num_attrs);
156:
157: dst->num_attrs = src->num_attrs;
158: dst->attrs = emalloc2(dst->num_attrs, sizeof(struct sss_sudo_attr));
159:
160: for (i = 0; i < dst->num_attrs; ++i)
161: sudo_sss_attrcpy(dst->attrs + i, src->attrs + i);
162:
163: debug_return;
164: }
165:
166: #define _SUDO_SSS_FILTER_INCLUDE 0
167: #define _SUDO_SSS_FILTER_EXCLUDE 1
168:
169: #define _SUDO_SSS_STATE_HOSTMATCH 0x01
170: #define _SUDO_SSS_STATE_USERMATCH 0x02
171:
172: static struct sss_sudo_result *
173: sudo_sss_filter_result(struct sudo_sss_handle *handle,
174: struct sss_sudo_result *in_res,
175: int (*filterp)(struct sudo_sss_handle *, struct sss_sudo_rule *, void *),
176: int act, void *filterp_arg)
177: {
178: struct sss_sudo_result *out_res;
179: int i, l, r;
180: debug_decl(sudo_sss_filter_result, SUDO_DEBUG_SSSD)
181:
182: sudo_debug_printf(SUDO_DEBUG_DEBUG, "in_res=%p, count=%u, act=%s",
183: in_res, in_res->num_rules,
184: act == _SUDO_SSS_FILTER_EXCLUDE ? "EXCLUDE" : "INCLUDE");
185:
186: if (in_res == NULL)
187: debug_return_ptr(NULL);
188:
189: sudo_debug_printf(SUDO_DEBUG_DEBUG, "emalloc: cnt=%d", in_res->num_rules);
190:
191: out_res = emalloc(sizeof(struct sss_sudo_result));
192: out_res->rules = in_res->num_rules > 0 ?
193: emalloc2(in_res->num_rules, sizeof(struct sss_sudo_rule)) : NULL;
194: out_res->num_rules = 0;
195:
196: for (i = l = 0; i < in_res->num_rules; ++i) {
197: r = filterp(handle, in_res->rules + i, filterp_arg);
198:
199: if (( r && act == _SUDO_SSS_FILTER_INCLUDE) ||
200: (!r && act == _SUDO_SSS_FILTER_EXCLUDE)) {
201: sudo_debug_printf(SUDO_DEBUG_DEBUG,
202: "COPY (%s): %p[%u] => %p[%u] (= %p)",
203: act == _SUDO_SSS_FILTER_EXCLUDE ? "not excluded" : "included",
204: in_res->rules, i, out_res->rules, l, in_res->rules + i);
205:
206: sudo_sss_rulecpy(out_res->rules + l, in_res->rules + i);
207: ++l;
208: }
209: }
210:
211: if (l < in_res->num_rules) {
212: sudo_debug_printf(SUDO_DEBUG_DEBUG,
213: "reallocating result: %p (count: %u -> %u)", out_res->rules,
214: in_res->num_rules, l);
215: out_res->rules = erealloc3(out_res->rules, l, sizeof(struct sss_sudo_rule));
216: }
217:
218: out_res->num_rules = l;
219:
220: debug_return_ptr(out_res);
221: }
222:
223: struct sudo_nss sudo_nss_sss = {
224: &sudo_nss_sss,
225: NULL,
226: sudo_sss_open,
227: sudo_sss_close,
228: sudo_sss_parse,
229: sudo_sss_setdefs,
230: sudo_sss_lookup,
231: sudo_sss_display_cmnd,
232: sudo_sss_display_defaults,
233: sudo_sss_display_bound_defaults,
234: sudo_sss_display_privs
235: };
236:
237: /* sudo_nss implementation */
238: // ok
239: static int sudo_sss_open(struct sudo_nss *nss)
240: {
241: struct sudo_sss_handle *handle;
242: static const char path[] = _PATH_SSSD_LIB"/libsss_sudo.so";
243: debug_decl(sudo_sss_open, SUDO_DEBUG_SSSD);
244:
245: /* Create a handle container. */
246: handle = emalloc(sizeof(struct sudo_sss_handle));
247:
248: /* Load symbols */
249: handle->ssslib = dlopen(path, RTLD_LAZY);
250: if (handle->ssslib == NULL) {
251: warningx(_("Unable to dlopen %s: %s"), path, dlerror());
252: warningx(_("Unable to initialize SSS source. Is SSSD installed on your machine?"));
253: debug_return_int(EFAULT);
254: }
255:
256: handle->fn_send_recv = dlsym(handle->ssslib, "sss_sudo_send_recv");
257: if (handle->fn_send_recv == NULL) {
258: warningx(_("unable to find symbol \"%s\" in %s"), path,
259: "sss_sudo_send_recv");
260: debug_return_int(EFAULT);
261: }
262:
263: handle->fn_send_recv_defaults =
264: dlsym(handle->ssslib, "sss_sudo_send_recv_defaults");
265: if (handle->fn_send_recv_defaults == NULL) {
266: warningx(_("unable to find symbol \"%s\" in %s"), path,
267: "sss_sudo_send_recv_defaults");
268: debug_return_int(EFAULT);
269: }
270:
271: handle->fn_free_result = dlsym(handle->ssslib, "sss_sudo_free_result");
272: if (handle->fn_free_result == NULL) {
273: warningx(_("unable to find symbol \"%s\" in %s"), path,
274: "sss_sudo_free_result");
275: debug_return_int(EFAULT);
276: }
277:
278: handle->fn_get_values = dlsym(handle->ssslib, "sss_sudo_get_values");
279: if (handle->fn_get_values == NULL) {
280: warningx(_("unable to find symbol \"%s\" in %s"), path,
281: "sss_sudo_get_values");
282: debug_return_int(EFAULT);
283: }
284:
285: handle->fn_free_values = dlsym(handle->ssslib, "sss_sudo_free_values");
286: if (handle->fn_free_values == NULL) {
287: warningx(_("unable to find symbol \"%s\" in %s"), path,
288: "sss_sudo_free_values");
289: debug_return_int(EFAULT);
290: }
291:
292: handle->domainname = NULL;
293: handle->pw = sudo_user.pw;
294: nss->handle = handle;
295:
296: sudo_debug_printf(SUDO_DEBUG_DEBUG, "handle=%p", handle);
297:
298: debug_return_int(0);
299: }
300:
301: // ok
302: static int sudo_sss_close(struct sudo_nss *nss)
303: {
304: struct sudo_sss_handle *handle;
305: debug_decl(sudo_sss_close, SUDO_DEBUG_SSSD);
306:
307: if (nss && nss->handle) {
308: handle = nss->handle;
309: dlclose(handle->ssslib);
310: }
311:
312: efree(nss->handle);
313: debug_return_int(0);
314: }
315:
316: // ok
317: static int sudo_sss_parse(struct sudo_nss *nss)
318: {
319: debug_decl(sudo_sss_parse, SUDO_DEBUG_SSSD);
320: debug_return_int(0);
321: }
322:
323: static int sudo_sss_setdefs(struct sudo_nss *nss)
324: {
325: struct sudo_sss_handle *handle = nss->handle;
326:
327: struct sss_sudo_result *sss_result;
328: struct sss_sudo_rule *sss_rule;
329: uint32_t sss_error;
330: int i;
331: debug_decl(sudo_sss_setdefs, SUDO_DEBUG_SSSD);
332:
333: if (handle == NULL)
334: debug_return_int(-1);
335:
336: sudo_debug_printf(SUDO_DEBUG_DIAG, "Looking for cn=defaults");
337:
338: if (handle->fn_send_recv_defaults(handle->pw->pw_uid, handle->pw->pw_name,
339: &sss_error, &handle->domainname,
340: &sss_result) != 0) {
341: sudo_debug_printf(SUDO_DEBUG_INFO,
342: "handle->fn_send_recv_defaults: != 0, sss_error=%u", sss_error);
343: debug_return_int(-1);
344: }
345:
346: if (sss_error == ENOENT) {
347: sudo_debug_printf(SUDO_DEBUG_INFO, "The user was not found in SSSD.");
348: debug_return_int(-1);
349: } else if(sss_error != 0) {
350: sudo_debug_printf(SUDO_DEBUG_INFO, "sss_error=%u\n", sss_error);
351: debug_return_int(-1);
352: }
353:
354: for (i = 0; i < sss_result->num_rules; ++i) {
355: sudo_debug_printf(SUDO_DEBUG_DIAG,
356: "Parsing cn=defaults, %d/%d", i, sss_result->num_rules);
357: sss_rule = sss_result->rules + i;
358: sudo_sss_parse_options(handle, sss_rule);
359: }
360:
361: handle->fn_free_result(sss_result);
362: debug_return_int(0);
363: }
364:
365: static int sudo_sss_checkpw(struct sudo_nss *nss, struct passwd *pw)
366: {
367: struct sudo_sss_handle *handle = nss->handle;
368: debug_decl(sudo_sss_checkpw, SUDO_DEBUG_SSSD);
369:
370: if (pw->pw_name != handle->pw->pw_name ||
371: pw->pw_uid != handle->pw->pw_uid) {
372: sudo_debug_printf(SUDO_DEBUG_DIAG,
373: "Requested name or uid don't match the initial once, reinitializing...");
374: handle->pw = pw;
375:
376: if (sudo_sss_setdefs(nss) != 0)
377: debug_return_int(-1);
378: }
379:
380: debug_return_int(0);
381: }
382:
383: static int
384: sudo_sss_check_runas_user(struct sudo_sss_handle *handle, struct sss_sudo_rule *sss_rule)
385: {
386: char **val_array = NULL;
387: char *val;
388: int ret = false, i;
389: debug_decl(sudo_sss_check_runas_user, SUDO_DEBUG_SSSD);
390:
391: if (!runas_pw)
392: debug_return_int(UNSPEC);
393:
394: /* get the runas user from the entry */
395: switch (handle->fn_get_values(sss_rule, "sudoRunAsUser", &val_array)) {
396: case 0:
397: break;
398: case ENOENT:
399: sudo_debug_printf(SUDO_DEBUG_INFO, "No result. Trying old style (sudoRunAs)");
400:
401: /* try old style */
402: switch (handle->fn_get_values(sss_rule, "sudoRunAs", &val_array)) {
403: case 0:
404: break;
405: case ENOENT:
406: sudo_debug_printf(SUDO_DEBUG_INFO, "No result. Matching against runas_default");
407: /*
408: * If there are no runas entries, match runas_default against
409: * what the user specified on the command line.
410: */
411: return !strcasecmp(runas_pw->pw_name, def_runas_default);
412: default:
413: sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoRunAs): != 0");
414: debug_return_int(UNSPEC);
415: }
416: break;
417: default:
418: sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoRunAsUser): != 0");
419: debug_return_int(UNSPEC);
420: }
421:
422: /*
423: * BUG:
424: *
425: * if runas is not specified on the command line, the only information
426: * as to which user to run as is in the runas_default option. We should
427: * check to see if we have the local option present. Unfortunately we
428: * don't parse these options until after this routine says yes or no.
429: * The query has already returned, so we could peek at the attribute
430: * values here though.
431: *
432: * For now just require users to always use -u option unless its set
433: * in the global defaults. This behaviour is no different than the global
434: * /etc/sudoers.
435: *
436: * Sigh - maybe add this feature later
437: */
438:
439: /* walk through values returned, looking for a match */
440: for (i = 0; val_array[i] != NULL && !ret; ++i) {
441: val = val_array[i];
442:
443: sudo_debug_printf(SUDO_DEBUG_DEBUG, "val[%d]=%s", i, val);
444:
445: switch (val[0]) {
446: case '+':
447: sudo_debug_printf(SUDO_DEBUG_DEBUG, "netgr_");
448: if (netgr_matches(val, NULL, NULL, runas_pw->pw_name)) {
449: sudo_debug_printf(SUDO_DEBUG_DEBUG, "=> match");
450: ret = true;
451: }
452: break;
453: case '%':
454: sudo_debug_printf(SUDO_DEBUG_DEBUG, "usergr_");
455: if (usergr_matches(val, runas_pw->pw_name, runas_pw)) {
456: sudo_debug_printf(SUDO_DEBUG_DEBUG, "=> match");
457: ret = true;
458: }
459: break;
460: case 'A':
461: if (strcmp(val, "ALL") == 0) {
462: sudo_debug_printf(SUDO_DEBUG_DEBUG, "ALL => match");
463: ret = true;
464: break;
465: }
466: /* FALLTHROUGH */
467: sudo_debug_printf(SUDO_DEBUG_DEBUG, "FALLTHROUGH");
468: default:
469: if (strcasecmp(val, runas_pw->pw_name) == 0) {
470: sudo_debug_printf(SUDO_DEBUG_DEBUG,
471: "%s == %s (pw_name) => match", val, runas_pw->pw_name);
472: ret = true;
473: }
474: break;
475: }
476:
477: sudo_debug_printf(SUDO_DEBUG_INFO,
478: "sssd/ldap sudoRunAsUser '%s' ... %s", val, ret ? "MATCH!" : "not");
479: }
480:
481: handle->fn_free_values(val_array); /* cleanup */
482:
483: debug_return_int(ret);
484: }
485:
486: static int
487: sudo_sss_check_runas_group(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
488: {
489: char **val_array = NULL;
490: char *val;
491: int ret = false, i;
492: debug_decl(sudo_sss_check_runas_group, SUDO_DEBUG_SSSD);
493:
494: /* runas_gr is only set if the user specified the -g flag */
495: if (!runas_gr)
496: debug_return_int(UNSPEC);
497:
498: /* get the values from the entry */
499: switch (handle->fn_get_values(rule, "sudoRunAsGroup", &val_array)) {
500: case 0:
501: break;
502: case ENOENT:
503: sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
504: debug_return_int(false);
505: default:
506: sudo_debug_printf(SUDO_DEBUG_INFO,
507: "handle->fn_get_values(sudoRunAsGroup): != 0");
508: debug_return_int(UNSPEC);
509: }
510:
511: /* walk through values returned, looking for a match */
512: for (i = 0; val_array[i] != NULL; ++i) {
513: val = val_array[i];
514: sudo_debug_printf(SUDO_DEBUG_DEBUG, "val[%d]=%s", i, val);
515:
516: if (strcmp(val, "ALL") == 0 || group_matches(val, runas_gr))
517: ret = true;
518:
519: sudo_debug_printf(SUDO_DEBUG_INFO,
520: "sssd/ldap sudoRunAsGroup '%s' ... %s", val, ret ? "MATCH!" : "not");
521: }
522:
523: handle->fn_free_values(val_array);
524:
525: debug_return_int(ret);
526: }
527:
528: /*
529: * Walk through search results and return true if we have a runas match,
530: * else false. RunAs info is optional.
531: */
532: static int
533: sudo_sss_check_runas(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
534: {
535: int ret;
536: debug_decl(sudo_sss_check_runas, SUDO_DEBUG_SSSD);
537:
538: if (rule == NULL)
539: debug_return_int(false);
540:
541: ret = sudo_sss_check_runas_user(handle, rule) != false &&
542: sudo_sss_check_runas_group(handle, rule) != false;
543:
544: debug_return_int(ret);
545: }
546:
547: static int
548: sudo_sss_check_host(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
549: {
550: char **val_array, *val;
551: int ret = false, i;
552: debug_decl(sudo_sss_check_host, SUDO_DEBUG_SSSD);
553:
554: if (rule == NULL)
555: debug_return_int(ret);
556:
557: /* get the values from the rule */
558: switch (handle->fn_get_values(rule, "sudoHost", &val_array))
559: {
560: case 0:
561: break;
562: case ENOENT:
563: sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
564: debug_return_int(false);
565: default:
566: sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoHost): != 0");
567: debug_return_int(ret);
568: }
569:
570: /* walk through values */
571: for (i = 0; val_array[i] != NULL; ++i) {
572: val = val_array[i];
573: sudo_debug_printf(SUDO_DEBUG_DEBUG, "val[%d]=%s", i, val);
574:
575: /* match any or address or netgroup or hostname */
576: if (!strcmp(val, "ALL") || addr_matches(val) ||
577: netgr_matches(val, user_host, user_shost, NULL) ||
578: hostname_matches(user_shost, user_host, val))
579: ret = true;
580:
581: sudo_debug_printf(SUDO_DEBUG_INFO,
582: "sssd/ldap sudoHost '%s' ... %s", val, ret ? "MATCH!" : "not");
583: }
584:
585: handle->fn_free_values(val_array);
586:
587: debug_return_int(ret);
588: }
589:
590: static int
591: sudo_sss_result_filterp(struct sudo_sss_handle *handle,
592: struct sss_sudo_rule *rule, void *unused)
593: {
594: (void)unused;
595: debug_decl(sudo_sss_result_filterp, SUDO_DEBUG_SSSD);
596:
597: if (sudo_sss_check_host(handle, rule))
598: debug_return_int(1);
599: else
600: debug_return_int(0);
601: }
602:
603: static struct sss_sudo_result *
604: sudo_sss_result_get(struct sudo_nss *nss, struct passwd *pw, uint32_t *state)
605: {
606: struct sudo_sss_handle *handle = nss->handle;
607: struct sss_sudo_result *u_sss_result, *f_sss_result;
608: uint32_t sss_error = 0, ret;
609: debug_decl(sudo_sss_result_get, SUDO_DEBUG_SSSD);
610:
611: if (sudo_sss_checkpw(nss, pw) != 0)
612: debug_return_ptr(NULL);
613:
614: sudo_debug_printf(SUDO_DEBUG_DIAG, " username=%s", handle->pw->pw_name);
615: sudo_debug_printf(SUDO_DEBUG_DIAG, "domainname=%s", handle->domainname);
616:
617: u_sss_result = f_sss_result = NULL;
618:
619: ret = handle->fn_send_recv(handle->pw->pw_uid, handle->pw->pw_name,
620: handle->domainname, &sss_error, &u_sss_result);
621:
622: switch (ret) {
623: case 0:
624: switch (sss_error) {
625: case 0:
626: if (u_sss_result != NULL) {
627: if (state != NULL) {
628: sudo_debug_printf(SUDO_DEBUG_DEBUG, "state |= USERMATCH");
629: *state |= _SUDO_SSS_STATE_USERMATCH;
630: }
631: sudo_debug_printf(SUDO_DEBUG_INFO, "Received %u rule(s)",
632: u_sss_result->num_rules);
633: } else {
634: sudo_debug_printf(SUDO_DEBUG_INFO,
635: "Internal error: u_sss_result == NULL && sss_error == 0");
636: debug_return_ptr(NULL);
637: }
638: break;
639: case ENOENT:
640: sudo_debug_printf(SUDO_DEBUG_INFO, "The user was not found in SSSD.");
641: default:
642: sudo_debug_printf(SUDO_DEBUG_INFO, "sss_error=%u\n", sss_error);
643: debug_return_ptr(NULL);
644: }
645: break;
646: default:
647: sudo_debug_printf(SUDO_DEBUG_INFO,
648: "handle->fn_send_recv: != 0: ret=%d", ret);
649: debug_return_ptr(NULL);
650: }
651:
652: f_sss_result = sudo_sss_filter_result(handle, u_sss_result,
653: sudo_sss_result_filterp, _SUDO_SSS_FILTER_INCLUDE, NULL);
654:
655: if (f_sss_result != NULL) {
656: if (f_sss_result->num_rules > 0) {
657: if (state != NULL) {
658: sudo_debug_printf(SUDO_DEBUG_DEBUG, "state |= HOSTMATCH");
659: *state |= _SUDO_SSS_STATE_HOSTMATCH;
660: }
661: }
662: }
663:
664: sudo_debug_printf(SUDO_DEBUG_DEBUG,
665: "u_sss_result=(%p, %u) => f_sss_result=(%p, %u)", u_sss_result,
666: u_sss_result->num_rules, f_sss_result, f_sss_result->num_rules);
667:
668: handle->fn_free_result(u_sss_result);
669:
670: debug_return_ptr(f_sss_result);
671: }
672:
673: /*
674: * Search for boolean "option" in sudoOption.
675: * Returns true if found and allowed, false if negated, else UNSPEC.
676: */
677: static int
678: sudo_sss_check_bool(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule,
679: char *option)
680: {
681: char ch, *var, **val_array = NULL;
682: int i, ret = UNSPEC;
683: debug_decl(sudo_sss_check_bool, SUDO_DEBUG_SSSD);
684:
685: if (rule == NULL)
686: debug_return_int(ret);
687:
688: switch (handle->fn_get_values(rule, "sudoOption", &val_array)) {
689: case 0:
690: break;
691: case ENOENT:
692: sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
693: debug_return_int(ret);
694: default:
695: sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values: != 0");
696: debug_return_int(ret);
697: }
698:
699: /* walk through options */
700: for (i = 0; val_array[i] != NULL; ++i) {
701: var = val_array[i];
702: sudo_debug_printf(SUDO_DEBUG_INFO, "sssd/ldap sudoOption: '%s'", var);
703:
704: if ((ch = *var) == '!')
705: var++;
706: if (strcmp(var, option) == 0)
707: ret = (ch != '!');
708: }
709:
710: handle->fn_free_values(val_array);
711:
712: debug_return_int(ret);
713: }
714:
715: /*
716: * Walk through search results and return true if we have a command match,
717: * false if disallowed and UNSPEC if not matched.
718: */
719: static int
720: sudo_sss_check_command(struct sudo_sss_handle *handle,
721: struct sss_sudo_rule *rule, int *setenv_implied)
722: {
723: char **val_array = NULL, *val;
724: char *allowed_cmnd, *allowed_args;
725: int i, foundbang, ret = UNSPEC;
726: debug_decl(sudo_sss_check_command, SUDO_DEBUG_SSSD);
727:
728: if (rule == NULL)
729: debug_return_int(ret);
730:
731: switch (handle->fn_get_values(rule, "sudoCommand", &val_array)) {
732: case 0:
733: break;
734: case ENOENT:
735: sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
736: debug_return_int(ret);
737: default:
738: sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values: != 0");
739: debug_return_int(ret);
740: }
741:
742: for (i = 0; val_array[i] != NULL && ret != false; ++i) {
743: val = val_array[i];
744:
745: sudo_debug_printf(SUDO_DEBUG_DEBUG, "val[%d]=%s", i, val);
746:
747: /* Match against ALL ? */
748: if (!strcmp(val, "ALL")) {
749: ret = true;
750: if (setenv_implied != NULL)
751: *setenv_implied = true;
752: sudo_debug_printf(SUDO_DEBUG_INFO,
753: "sssd/ldap sudoCommand '%s' ... MATCH!", val);
754: continue;
755: }
756:
757: /* check for !command */
758: if (*val == '!') {
759: foundbang = true;
760: allowed_cmnd = estrdup(1 + val); /* !command */
761: } else {
762: foundbang = false;
763: allowed_cmnd = estrdup(val); /* command */
764: }
765:
766: /* split optional args away from command */
767: allowed_args = strchr(allowed_cmnd, ' ');
768: if (allowed_args)
769: *allowed_args++ = '\0';
770:
771: /* check the command like normal */
772: if (command_matches(allowed_cmnd, allowed_args)) {
773: /*
774: * If allowed (no bang) set ret but keep on checking.
775: * If disallowed (bang), exit loop.
776: */
777: ret = foundbang ? false : true;
778: }
779:
780: sudo_debug_printf(SUDO_DEBUG_INFO, "sssd/ldap sudoCommand '%s' ... %s",
781: val, ret == true ? "MATCH!" : "not");
782: efree(allowed_cmnd); /* cleanup */
783: }
784:
785: handle->fn_free_values(val_array); /* more cleanup */
786:
787: debug_return_int(ret);
788: }
789:
790: static void
791: sudo_sss_parse_options(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
792: {
793: int i;
794: char op, *v, *val;
795: char **val_array = NULL;
796: debug_decl(sudo_sss_parse_options, SUDO_DEBUG_SSSD);
797:
798: if (rule == NULL)
799: debug_return;
800:
801: switch (handle->fn_get_values(rule, "sudoOption", &val_array)) {
802: case 0:
803: break;
804: case ENOENT:
805: sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
806: debug_return;
807: default:
808: sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoOption): != 0");
809: debug_return;
810: }
811:
812: /* walk through options */
813: for (i = 0; val_array[i] != NULL; i++) {
814: sudo_debug_printf(SUDO_DEBUG_INFO, "sssd/ldap sudoOption: '%s'",
815: val_array[i]);
816: v = estrdup(val_array[i]);
817:
818: /* check for equals sign past first char */
819: val = strchr(v, '=');
820: if (val > v) {
821: *val++ = '\0'; /* split on = and truncate var */
822: op = *(val - 2); /* peek for += or -= cases */
823: if (op == '+' || op == '-') {
824: *(val - 2) = '\0'; /* found, remove extra char */
825: /* case var+=val or var-=val */
826: set_default(v, val, (int) op);
827: } else {
828: /* case var=val */
829: set_default(v, val, true);
830: }
831: } else if (*v == '!') {
832: /* case !var Boolean False */
833: set_default(v + 1, NULL, false);
834: } else {
835: /* case var Boolean True */
836: set_default(v, NULL, true);
837: }
838: efree(v);
839: }
840:
841: handle->fn_free_values(val_array);
842: debug_return;
843: }
844:
845: static int
846: sudo_sss_lookup(struct sudo_nss *nss, int ret, int pwflag)
847: {
848: int rc, setenv_implied;
849:
850: struct sudo_sss_handle *handle = nss->handle;
851: struct sss_sudo_result *sss_result = NULL;
852: struct sss_sudo_rule *rule;
853: uint32_t i, state = 0;
854: debug_decl(sudo_sss_lookup, SUDO_DEBUG_SSSD);
855:
856: /* Fetch list of sudoRole entries that match user and host. */
857: sss_result = sudo_sss_result_get(nss, sudo_user.pw, &state);
858:
859: /*
860: * The following queries are only determine whether or not a
861: * password is required, so the order of the entries doesn't matter.
862: */
863: if (pwflag) {
864: int doauth = UNSPEC;
865: int matched = UNSPEC;
866: enum def_tuple pwcheck =
867: (pwflag == -1) ? never : sudo_defs_table[pwflag].sd_un.tuple;
868:
869: sudo_debug_printf(SUDO_DEBUG_INFO, "perform search for pwflag %d", pwflag);
870: if (sss_result != NULL) {
871: for (i = 0; i < sss_result->num_rules; i++) {
872: rule = sss_result->rules + i;
873: if ((pwcheck == any && doauth != false) ||
874: (pwcheck == all && doauth == false)) {
875: doauth = sudo_sss_check_bool(handle, rule, "authenticate");
876: }
877: /* Only check the command when listing another user. */
878: if (user_uid == 0 || list_pw == NULL ||
879: user_uid == list_pw->pw_uid ||
880: sudo_sss_check_command(handle, rule, NULL)) {
881: matched = true;
882: break;
883: }
884: }
885: }
886: if (matched || user_uid == 0) {
887: SET(ret, VALIDATE_OK);
888: CLR(ret, VALIDATE_NOT_OK);
889: if (def_authenticate) {
890: switch (pwcheck) {
891: case always:
892: SET(ret, FLAG_CHECK_USER);
893: break;
894: case all:
895: case any:
896: if (doauth == false)
897: def_authenticate = false;
898: break;
899: case never:
900: def_authenticate = false;
901: break;
902: default:
903: break;
904: }
905: }
906: }
907: goto done;
908: }
909:
910: sudo_debug_printf(SUDO_DEBUG_DIAG,
911: "searching SSSD/LDAP for sudoers entries");
912:
913: setenv_implied = false;
914: if (sss_result != NULL) {
915: for (i = 0; i < sss_result->num_rules; i++) {
916: rule = sss_result->rules + i;
917: if (!sudo_sss_check_runas(handle, rule))
918: continue;
919: rc = sudo_sss_check_command(handle, rule, &setenv_implied);
920: if (rc != UNSPEC) {
921: /* We have a match. */
922: sudo_debug_printf(SUDO_DEBUG_DIAG, "Command %sallowed",
923: rc == true ? "" : "NOT ");
924: if (rc == true) {
925: sudo_debug_printf(SUDO_DEBUG_DEBUG, "SSSD rule: %p", rule);
926: /* Apply entry-specific options. */
927: if (setenv_implied)
928: def_setenv = true;
929: sudo_sss_parse_options(handle, rule);
930: #ifdef HAVE_SELINUX
931: /* Set role and type if not specified on command line. */
932: if (user_role == NULL)
933: user_role = def_role;
934: if (user_type == NULL)
935: user_type = def_type;
936: #endif /* HAVE_SELINUX */
937: SET(ret, VALIDATE_OK);
938: CLR(ret, VALIDATE_NOT_OK);
939: } else {
940: SET(ret, VALIDATE_NOT_OK);
941: CLR(ret, VALIDATE_OK);
942: }
943: break;
944: }
945: }
946: }
947: done:
948: sudo_debug_printf(SUDO_DEBUG_DIAG, "Done with LDAP searches");
949:
950: if (!ISSET(ret, VALIDATE_OK)) {
951: /* No matching entries. */
952: if (pwflag && list_pw == NULL)
953: SET(ret, FLAG_NO_CHECK);
954: }
955:
956: if (state & _SUDO_SSS_STATE_USERMATCH)
957: CLR(ret, FLAG_NO_USER);
958: if (state & _SUDO_SSS_STATE_HOSTMATCH)
959: CLR(ret, FLAG_NO_HOST);
960:
961: sudo_debug_printf(SUDO_DEBUG_DEBUG, "sudo_sss_lookup(%d)=0x%02x",
962: pwflag, ret);
963:
964: debug_return_int(ret);
965: }
966:
967: static int
968: sudo_sss_display_cmnd(struct sudo_nss *nss, struct passwd *pw)
969: {
970: struct sudo_sss_handle *handle = nss->handle;
971: struct sss_sudo_result *sss_result = NULL;
972: struct sss_sudo_rule *rule;
973: int i, found = false;
974: debug_decl(sudo_sss_display_cmnd, SUDO_DEBUG_SSSD);
975:
976: if (handle == NULL)
977: goto done;
978:
979: if (sudo_sss_checkpw(nss, pw) != 0)
980: debug_return_int(-1);
981:
982: /*
983: * The sudo_sss_result_get() function returns all nodes that match
984: * the user and the host.
985: */
986: sudo_debug_printf(SUDO_DEBUG_DIAG, "sssd/ldap search for command list");
987: sss_result = sudo_sss_result_get(nss, pw, NULL);
988:
989: if (sss_result == NULL)
990: goto done;
991:
992: for (i = 0; i < sss_result->num_rules; i++) {
993: rule = sss_result->rules + i;
994: if (sudo_sss_check_command(handle, rule, NULL) &&
995: sudo_sss_check_runas(handle, rule)) {
996: found = true;
997: goto done;
998: }
999: }
1000:
1001: done:
1002: if (found)
1003: printf("%s%s%s\n", safe_cmnd ? safe_cmnd : user_cmnd,
1004: user_args ? " " : "", user_args ? user_args : "");
1005:
1006: if (sss_result != NULL)
1007: handle->fn_free_result(sss_result);
1008:
1009: debug_return_int(!found);
1010: }
1011:
1012: static int
1013: sudo_sss_display_defaults(struct sudo_nss *nss, struct passwd *pw,
1014: struct lbuf *lbuf)
1015: {
1016: struct sudo_sss_handle *handle = nss->handle;
1017:
1018: struct sss_sudo_rule *rule;
1019: struct sss_sudo_result *sss_result = NULL;
1020:
1021: uint32_t sss_error = 0;
1022:
1023: char *prefix, *val, **val_array = NULL;
1024: int count = 0, i, j;
1025:
1026: debug_decl(sudo_sss_display_defaults, SUDO_DEBUG_SSSD);
1027:
1028: if (handle == NULL)
1029: goto done;
1030:
1031: if (handle->fn_send_recv_defaults(pw->pw_uid, pw->pw_name,
1032: &sss_error, &handle->domainname,
1033: &sss_result) != 0) {
1034: sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_send_recv_defaults: !=0, sss_error=%u", sss_error);
1035: goto done;
1036: }
1037:
1038: if (sss_error == ENOENT) {
1039: sudo_debug_printf(SUDO_DEBUG_INFO, "The user was not found in SSSD.");
1040: goto done;
1041: } else if(sss_error != 0) {
1042: sudo_debug_printf(SUDO_DEBUG_INFO, "sss_error=%u\n", sss_error);
1043: goto done;
1044: }
1045:
1046: handle->pw = pw;
1047:
1048: for (i = 0; i < sss_result->num_rules; ++i) {
1049: rule = sss_result->rules + i;
1050:
1051: switch (handle->fn_get_values(rule, "sudoOption", &val_array)) {
1052: case 0:
1053: break;
1054: case ENOENT:
1055: sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
1056: continue;
1057: default:
1058: sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values: != 0");
1059: continue;
1060: }
1061:
1062: if (lbuf->len == 0 || isspace((unsigned char)lbuf->buf[lbuf->len - 1]))
1063: prefix = " ";
1064: else
1065: prefix = ", ";
1066:
1067: for (j = 0; val_array[j] != NULL; ++j) {
1068: val = val_array[j];
1069: lbuf_append(lbuf, "%s%s", prefix, val);
1070: prefix = ", ";
1071: count++;
1072: }
1073:
1074: handle->fn_free_values(val_array);
1075: val_array = NULL;
1076: }
1077:
1078: handle->fn_free_result(sss_result);
1079: done:
1080: debug_return_int(count);
1081: }
1082:
1083: // ok
1084: static int
1085: sudo_sss_display_bound_defaults(struct sudo_nss *nss,
1086: struct passwd *pw, struct lbuf *lbuf)
1087: {
1088: debug_decl(sudo_sss_display_bound_defaults, SUDO_DEBUG_SSSD);
1089: debug_return_int(0);
1090: }
1091:
1092: static int
1093: sudo_sss_display_entry_long(struct sudo_sss_handle *handle,
1094: struct sss_sudo_rule *rule, struct lbuf *lbuf)
1095: {
1096: char **val_array = NULL;
1097: int count = 0, i;
1098: debug_decl(sudo_sss_display_entry_long, SUDO_DEBUG_SSSD);
1099:
1100: /* get the RunAsUser Values from the entry */
1101: lbuf_append(lbuf, " RunAsUsers: ");
1102: switch (handle->fn_get_values(rule, "sudoRunAsUser", &val_array)) {
1103: case 0:
1104: for (i = 0; val_array[i] != NULL; ++i)
1105: lbuf_append(lbuf, "%s%s", i != 0 ? ", " : "", val_array[i]);
1106: handle->fn_free_values(val_array);
1107: break;
1108: case ENOENT:
1109: switch (handle->fn_get_values(rule, "sudoRunAs", &val_array)) {
1110: case 0:
1111: for (i = 0; val_array[i] != NULL; ++i)
1112: lbuf_append(lbuf, "%s%s", i != 0 ? ", " : "", val_array[i]);
1113: handle->fn_free_values(val_array);
1114: break;
1115: case ENOENT:
1116: sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
1117: lbuf_append(lbuf, "%s", def_runas_default);
1118: break;
1119: default:
1120: sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoRunAs): != 0");
1121: debug_return_int(count);
1122: }
1123: break;
1124: default:
1125: sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoRunAsUser): != 0");
1126: debug_return_int(count);
1127: }
1128: lbuf_append(lbuf, "\n");
1129:
1130: /* get the RunAsGroup Values from the entry */
1131: switch (handle->fn_get_values(rule, "sudoRunAsGroup", &val_array)) {
1132: case 0:
1133: lbuf_append(lbuf, " RunAsGroups: ");
1134: for (i = 0; val_array[i] != NULL; ++i)
1135: lbuf_append(lbuf, "%s%s", i != 0 ? ", " : "", val_array[i]);
1136: handle->fn_free_values(val_array);
1137: lbuf_append(lbuf, "\n");
1138: break;
1139: case ENOENT:
1140: sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
1141: break;
1142: default:
1143: sudo_debug_printf(SUDO_DEBUG_INFO,
1144: "handle->fn_get_values(sudoRunAsGroup): != 0");
1145: debug_return_int(count);
1146: }
1147:
1148: /* get the Option Values from the entry */
1149: switch (handle->fn_get_values(rule, "sudoOption", &val_array)) {
1150: case 0:
1151: lbuf_append(lbuf, " Options: ");
1152: for (i = 0; val_array[i] != NULL; ++i)
1153: lbuf_append(lbuf, "%s%s", i != 0 ? ", " : "", val_array[i]);
1154: handle->fn_free_values(val_array);
1155: lbuf_append(lbuf, "\n");
1156: break;
1157: case ENOENT:
1158: sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
1159: break;
1160: default:
1161: sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoOption): != 0");
1162: debug_return_int(count);
1163: }
1164:
1165: /* Get the command values from the entry. */
1166: switch (handle->fn_get_values(rule, "sudoCommand", &val_array)) {
1167: case 0:
1168: lbuf_append(lbuf, _(" Commands:\n"));
1169: for (i = 0; val_array[i] != NULL; ++i) {
1170: lbuf_append(lbuf, "\t%s\n", val_array[i]);
1171: count++;
1172: }
1173: handle->fn_free_values(val_array);
1174: break;
1175: case ENOENT:
1176: sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
1177: break;
1178: default:
1179: sudo_debug_printf(SUDO_DEBUG_INFO,
1180: "handle->fn_get_values(sudoCommand): != 0");
1181: debug_return_int(count);
1182: }
1183:
1184: debug_return_int(count);
1185: }
1186:
1187: static int
1188: sudo_sss_display_entry_short(struct sudo_sss_handle *handle,
1189: struct sss_sudo_rule *rule, struct lbuf *lbuf)
1190: {
1191: char **val_array = NULL;
1192: int count = 0, i;
1193: debug_decl(sudo_sss_display_entry_short, SUDO_DEBUG_SSSD);
1194:
1195: lbuf_append(lbuf, " (");
1196:
1197: /* get the RunAsUser Values from the entry */
1198: switch (handle->fn_get_values(rule, "sudoRunAsUser", &val_array)) {
1199: case 0:
1200: for (i = 0; val_array[i] != NULL; ++i)
1201: lbuf_append(lbuf, "%s%s", i != 0 ? ", " : "", val_array[i]);
1202: handle->fn_free_values(val_array);
1203: break;
1204: case ENOENT:
1205: sudo_debug_printf(SUDO_DEBUG_INFO, "No result. Trying old style (sudoRunAs).");
1206: /* try old style */
1207: switch (handle->fn_get_values(rule, "sudoRunAs", &val_array)) {
1208: case 0:
1209: for (i = 0; val_array[i] != NULL; ++i)
1210: lbuf_append(lbuf, "%s%s", i != 0 ? ", " : "", val_array[i]);
1211: handle->fn_free_values(val_array);
1212: break;
1213: case ENOENT:
1214: sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
1215: lbuf_append(lbuf, "%s", def_runas_default);
1216: break;
1217: default:
1218: sudo_debug_printf(SUDO_DEBUG_INFO,
1219: "handle->fn_get_values(sudoRunAs): != 0");
1220: debug_return_int(count);
1221: }
1222: break;
1223: default:
1224: sudo_debug_printf(SUDO_DEBUG_INFO,
1225: "handle->fn_get_values(sudoRunAsUser): != 0");
1226: debug_return_int(count);
1227: }
1228:
1229: /* get the RunAsGroup Values from the entry */
1230: switch (handle->fn_get_values(rule, "sudoRunAsGroup", &val_array)) {
1231: case 0:
1232: lbuf_append(lbuf, " : ");
1233: for (i = 0; val_array[i] != NULL; ++i)
1234: lbuf_append(lbuf, "%s%s", i != 0 ? ", " : "", val_array[i]);
1235: handle->fn_free_values(val_array);
1236: break;
1237: case ENOENT:
1238: sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
1239: break;
1240: default:
1241: sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoRunAsGroup): != 0");
1242: debug_return_int(count);
1243: }
1244:
1245: lbuf_append(lbuf, ") ");
1246:
1247: /* get the Option Values from the entry */
1248: switch (handle->fn_get_values(rule, "sudoOption", &val_array)) {
1249: case 0:
1250: for (i = 0; val_array[i] != NULL; ++i) {
1251: char *cp = val_array[i];
1252: if (*cp == '!')
1253: cp++;
1254: if (strcmp(cp, "authenticate") == 0)
1255: lbuf_append(lbuf, val_array[i][0] == '!' ?
1256: "NOPASSWD: " : "PASSWD: ");
1257: else if (strcmp(cp, "noexec") == 0)
1258: lbuf_append(lbuf, val_array[i][0] == '!' ?
1259: "EXEC: " : "NOEXEC: ");
1260: else if (strcmp(cp, "setenv") == 0)
1261: lbuf_append(lbuf, val_array[i][0] == '!' ?
1262: "NOSETENV: " : "SETENV: ");
1263: }
1264: handle->fn_free_values(val_array);
1265: break;
1266: case ENOENT:
1267: sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
1268: break;
1269: default:
1270: sudo_debug_printf(SUDO_DEBUG_INFO,
1271: "handle->fn_get_values(sudoOption): != 0");
1272: debug_return_int(count);
1273: }
1274:
1275: /* get the Command Values from the entry */
1276: switch (handle->fn_get_values(rule, "sudoCommand", &val_array)) {
1277: case 0:
1278: for (i = 0; val_array[i] != NULL; ++i) {
1279: lbuf_append(lbuf, "%s%s", i != 0 ? ", " : "", val_array[i]);
1280: count++;
1281: }
1282: handle->fn_free_values(val_array);
1283: break;
1284: case ENOENT:
1285: sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
1286: break;
1287: default:
1288: sudo_debug_printf(SUDO_DEBUG_INFO,
1289: "handle->fn_get_values(sudoCommand): != 0");
1290: debug_return_int(count);
1291: }
1292: lbuf_append(lbuf, "\n");
1293:
1294: debug_return_int(count);
1295: }
1296:
1297: static int
1298: sudo_sss_display_privs(struct sudo_nss *nss, struct passwd *pw,
1299: struct lbuf *lbuf)
1300: {
1301: struct sudo_sss_handle *handle = nss->handle;
1302:
1303: struct sss_sudo_result *sss_result = NULL;
1304: struct sss_sudo_rule *rule;
1305: unsigned int i, count = 0;
1306: debug_decl(sudo_sss_display_privs, SUDO_DEBUG_SSSD);
1307:
1308: if (handle == NULL)
1309: debug_return_int(-1);
1310: if (sudo_sss_checkpw(nss, pw) != 0)
1311: debug_return_int(-1);
1312:
1313: sudo_debug_printf(SUDO_DEBUG_INFO, "sssd/ldap search for command list");
1314:
1315: sss_result = sudo_sss_result_get(nss, pw, NULL);
1316:
1317: if (sss_result == NULL)
1318: debug_return_int(count);
1319:
1320: /* Display all matching entries. */
1321: for (i = 0; i < sss_result->num_rules; ++i) {
1322: rule = sss_result->rules + i;
1323: if (long_list)
1324: count += sudo_sss_display_entry_long(handle, rule, lbuf);
1325: else
1326: count += sudo_sss_display_entry_short(handle, rule, lbuf);
1327: }
1328:
1329: if (sss_result != NULL)
1330: handle->fn_free_result(sss_result);
1331:
1332: debug_return_int(count);
1333: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>