Return to sssd.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / plugins / sudoers |
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: }