[BACK]Return to sudo_nss.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / sudo

Annotation of src/usr.bin/sudo/sudo_nss.c, Revision 1.1

1.1     ! millert     1: /*
        !             2:  * Copyright (c) 2007-2008 Todd C. Miller <Todd.Miller@courtesan.com>
        !             3:  *
        !             4:  * Permission to use, copy, modify, and distribute this software for any
        !             5:  * purpose with or without fee is hereby granted, provided that the above
        !             6:  * copyright notice and this permission notice appear in all copies.
        !             7:  *
        !             8:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !             9:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            10:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            11:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            12:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            13:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            14:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            15:  */
        !            16:
        !            17: #include <config.h>
        !            18:
        !            19: #include <sys/types.h>
        !            20: #include <sys/param.h>
        !            21: #include <stdio.h>
        !            22: #ifdef STDC_HEADERS
        !            23: # include <stdlib.h>
        !            24: # include <stddef.h>
        !            25: #else
        !            26: # ifdef HAVE_STDLIB_H
        !            27: #  include <stdlib.h>
        !            28: # endif
        !            29: #endif /* STDC_HEADERS */
        !            30: #ifdef HAVE_STRING_H
        !            31: # include <string.h>
        !            32: #else
        !            33: # ifdef HAVE_STRINGS_H
        !            34: #  include <strings.h>
        !            35: # endif
        !            36: #endif /* HAVE_STRING_H */
        !            37: #ifdef HAVE_UNISTD_H
        !            38: # include <unistd.h>
        !            39: #endif /* HAVE_UNISTD_H */
        !            40: #include <pwd.h>
        !            41: #include <grp.h>
        !            42:
        !            43: #include "sudo.h"
        !            44: #include "lbuf.h"
        !            45:
        !            46: #ifndef lint
        !            47: __unused static const char rcsid[] = "$Sudo: sudo_nss.c,v 1.6 2008/02/08 13:18:12 millert Exp $";
        !            48: #endif /* lint */
        !            49:
        !            50: extern struct sudo_nss sudo_nss_file;
        !            51: #ifdef HAVE_LDAP
        !            52: extern struct sudo_nss sudo_nss_ldap;
        !            53: #endif
        !            54:
        !            55: #if defined(HAVE_LDAP) && defined(_PATH_NSSWITCH_CONF)
        !            56: /*
        !            57:  * Read in /etc/nsswitch.conf
        !            58:  * Returns a tail queue of matches.
        !            59:  */
        !            60: struct sudo_nss_list *
        !            61: sudo_read_nss()
        !            62: {
        !            63:     FILE *fp;
        !            64:     char *cp;
        !            65:     int saw_files = FALSE;
        !            66:     int saw_ldap = FALSE;
        !            67:     int got_match = FALSE;
        !            68:     static struct sudo_nss_list snl;
        !            69:
        !            70:     if ((fp = fopen(_PATH_NSSWITCH_CONF, "r")) == NULL)
        !            71:        goto nomatch;
        !            72:
        !            73:     while ((cp = sudo_parseln(fp)) != NULL) {
        !            74:        /* Skip blank or comment lines */
        !            75:        if (*cp == '\0')
        !            76:            continue;
        !            77:
        !            78:        /* Look for a line starting with "sudoers:" */
        !            79:        if (strncasecmp(cp, "sudoers:", 8) != 0)
        !            80:            continue;
        !            81:
        !            82:        /* Parse line */
        !            83:        for ((cp = strtok(cp + 8, " \t")); cp != NULL; (cp = strtok(NULL, " \t"))) {
        !            84:            if (strcasecmp(cp, "files") == 0 && !saw_files) {
        !            85:                tq_append(&snl, &sudo_nss_file);
        !            86:                got_match = TRUE;
        !            87:            } else if (strcasecmp(cp, "ldap") == 0 && !saw_ldap) {
        !            88:                tq_append(&snl, &sudo_nss_ldap);
        !            89:                got_match = TRUE;
        !            90:            } else if (strcasecmp(cp, "[NOTFOUND=return]") == 0 && got_match) {
        !            91:                /* NOTFOUND affects the most recent entry */
        !            92:                tq_last(&snl)->ret_notfound = TRUE;
        !            93:                got_match = FALSE;
        !            94:            } else
        !            95:                got_match = FALSE;
        !            96:        }
        !            97:        /* Only parse the first "sudoers:" line */
        !            98:        break;
        !            99:     }
        !           100:     fclose(fp);
        !           101:
        !           102: nomatch:
        !           103:     /* Default to files only if no matches */
        !           104:     if (tq_empty(&snl))
        !           105:        tq_append(&snl, &sudo_nss_file);
        !           106:
        !           107:     return(&snl);
        !           108: }
        !           109:
        !           110: #else /* HAVE_LDAP && _PATH_NSSWITCH_CONF */
        !           111:
        !           112: /*
        !           113:  * Non-nsswitch.conf version with hard-coded order.
        !           114:  */
        !           115: struct sudo_nss_list *
        !           116: sudo_read_nss()
        !           117: {
        !           118:     static struct sudo_nss_list snl;
        !           119:
        !           120: # ifdef HAVE_LDAP
        !           121:     tq_append(&snl, &sudo_nss_ldap);
        !           122: # endif
        !           123:     tq_append(&snl, &sudo_nss_file);
        !           124:
        !           125:     return(&snl);
        !           126: }
        !           127:
        !           128: #endif /* HAVE_LDAP && _PATH_NSSWITCH_CONF */
        !           129:
        !           130: /* Reset user_groups based on passwd entry. */
        !           131: static void
        !           132: reset_groups(pw)
        !           133:     struct passwd *pw;
        !           134: {
        !           135: #if defined(HAVE_INITGROUPS) && defined(HAVE_GETGROUPS)
        !           136:     if (pw != sudo_user.pw) {
        !           137:        (void) initgroups(pw->pw_name, pw->pw_gid);
        !           138:        if ((user_ngroups = getgroups(0, NULL)) > 0) {
        !           139:            user_groups = erealloc3(user_groups, user_ngroups,
        !           140:                sizeof(GETGROUPS_T));
        !           141:            if (getgroups(user_ngroups, user_groups) < 0)
        !           142:                log_error(USE_ERRNO|MSG_ONLY, "can't get group vector");
        !           143:        } else {
        !           144:            user_ngroups = 0;
        !           145:            efree(user_groups);
        !           146:        }
        !           147:     }
        !           148: #endif
        !           149: }
        !           150:
        !           151: /*
        !           152:  * Print out privileges for the specified user.
        !           153:  * We only get here if the user is allowed to run something on this host.
        !           154:  */
        !           155: void
        !           156: display_privs(snl, pw)
        !           157:     struct sudo_nss_list *snl;
        !           158:     struct passwd *pw;
        !           159: {
        !           160:     struct sudo_nss *nss;
        !           161:     struct lbuf lbuf;
        !           162:     int count;
        !           163:
        !           164:     /* Reset group vector so group matching works correctly. */
        !           165:     reset_groups(pw);
        !           166:
        !           167:     lbuf_init(&lbuf, NULL, 4, 0);
        !           168:
        !           169:     /* Display defaults from all sources. */
        !           170:     count = 0;
        !           171:     tq_foreach_fwd(snl, nss)
        !           172:        count += nss->display_defaults(nss, pw, &lbuf);
        !           173:     if (count) {
        !           174:        printf("Matching Defaults entries for %s on this host:\n", pw->pw_name);
        !           175:        lbuf_print(&lbuf);
        !           176:        putchar('\n');
        !           177:     }
        !           178:
        !           179:     /* Display Runas and Cmnd-specific defaults from all sources. */
        !           180:     count = 0;
        !           181:     tq_foreach_fwd(snl, nss)
        !           182:        count += nss->display_bound_defaults(nss, pw, &lbuf);
        !           183:     if (count) {
        !           184:        printf("Runas and Command-specific defaults for %s:\n", pw->pw_name);
        !           185:        lbuf_print(&lbuf);
        !           186:        putchar('\n');
        !           187:     }
        !           188:
        !           189:     /* Display privileges from all sources. */
        !           190:     printf("User %s may run the following commands on this host:\n",
        !           191:        pw->pw_name);
        !           192:     tq_foreach_fwd(snl, nss)
        !           193:        (void) nss->display_privs(nss, pw, &lbuf);
        !           194:     if (lbuf.len != 0)
        !           195:        lbuf_print(&lbuf);              /* print remainder, if any */
        !           196:     lbuf_destroy(&lbuf);
        !           197: }
        !           198:
        !           199: /*
        !           200:  * Check user_cmnd against sudoers and print the matching entry if the
        !           201:  * command is allowed.
        !           202:  */
        !           203: int
        !           204: display_cmnd(snl, pw)
        !           205:     struct sudo_nss_list *snl;
        !           206:     struct passwd *pw;
        !           207: {
        !           208:     struct sudo_nss *nss;
        !           209:
        !           210:     /* Reset group vector so group matching works correctly. */
        !           211:     reset_groups(pw);
        !           212:
        !           213:     tq_foreach_fwd(snl, nss) {
        !           214:        if (nss->display_cmnd(nss, pw) == 0)
        !           215:            return(0);
        !           216:     }
        !           217:     return(1);
        !           218: }