Annotation of embedaddon/sudo/plugins/sudoers/sssd.c, revision 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>