Annotation of embedaddon/sudo/plugins/sudoers/policy.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (c) 2010-2013 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/stat.h>
        !            21: #include <netinet/in.h>
        !            22: #include <stdio.h>
        !            23: #ifdef STDC_HEADERS
        !            24: # include <stdlib.h>
        !            25: # include <stddef.h>
        !            26: #else
        !            27: # ifdef HAVE_STDLIB_H
        !            28: #  include <stdlib.h>
        !            29: # endif
        !            30: #endif /* STDC_HEADERS */
        !            31: #ifdef HAVE_STRING_H
        !            32: # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
        !            33: #  include <memory.h>
        !            34: # endif
        !            35: # include <string.h>
        !            36: #endif /* HAVE_STRING_H */
        !            37: #ifdef HAVE_STRINGS_H
        !            38: # include <strings.h>
        !            39: #endif /* HAVE_STRINGS_H */
        !            40: #ifdef HAVE_UNISTD_H
        !            41: # include <unistd.h>
        !            42: #endif /* HAVE_UNISTD_H */
        !            43: #include <errno.h>
        !            44: #include <grp.h>
        !            45: #include <pwd.h>
        !            46: 
        !            47: #include "sudoers.h"
        !            48: #include "sudoers_version.h"
        !            49: #include "interfaces.h"
        !            50: 
        !            51: /*
        !            52:  * Info passed in from the sudo front-end.
        !            53:  */
        !            54: struct sudoers_policy_open_info {
        !            55:     char * const *settings;
        !            56:     char * const *user_info;
        !            57:     char * const *plugin_args;
        !            58: };
        !            59: 
        !            60: /*
        !            61:  * Command execution args to be filled in: argv, envp and command info.
        !            62:  */
        !            63: struct sudoers_exec_args {
        !            64:     char ***argv;
        !            65:     char ***envp;
        !            66:     char ***info;
        !            67: };
        !            68: 
        !            69: static int sudo_version;
        !            70: static const char *interfaces_string;
        !            71: sudo_conv_t sudo_conv;
        !            72: const char *path_ldap_conf = _PATH_LDAP_CONF;
        !            73: const char *path_ldap_secret = _PATH_LDAP_SECRET;
        !            74: 
        !            75: extern __dso_public struct policy_plugin sudoers_policy;
        !            76: 
        !            77: #ifdef HAVE_BSD_AUTH_H
        !            78: extern char *login_style;
        !            79: #endif /* HAVE_BSD_AUTH_H */
        !            80: 
        !            81: /*
        !            82:  * Deserialize args, settings and user_info arrays.
        !            83:  * Fills in struct sudo_user and other common sudoers state.
        !            84:  */
        !            85: int
        !            86: sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
        !            87: {
        !            88:     struct sudoers_policy_open_info *info = v;
        !            89:     char * const *cur;
        !            90:     const char *p, *groups = NULL;
        !            91:     const char *debug_flags = NULL;
        !            92:     int flags = 0;
        !            93:     debug_decl(sudoers_policy_deserialize_info, SUDO_DEBUG_PLUGIN)
        !            94: 
        !            95: #define MATCHES(s, v) (strncmp(s, v, sizeof(v) - 1) == 0)
        !            96: 
        !            97:     /* Parse sudo.conf plugin args. */
        !            98:     if (info->plugin_args != NULL) {
        !            99:        for (cur = info->plugin_args; *cur != NULL; cur++) {
        !           100:            if (MATCHES(*cur, "sudoers_file=")) {
        !           101:                sudoers_file = *cur + sizeof("sudoers_file=") - 1;
        !           102:                continue;
        !           103:            }
        !           104:            if (MATCHES(*cur, "sudoers_uid=")) {
        !           105:                sudoers_uid = (uid_t) atoi(*cur + sizeof("sudoers_uid=") - 1);
        !           106:                continue;
        !           107:            }
        !           108:            if (MATCHES(*cur, "sudoers_gid=")) {
        !           109:                sudoers_gid = (gid_t) atoi(*cur + sizeof("sudoers_gid=") - 1);
        !           110:                continue;
        !           111:            }
        !           112:            if (MATCHES(*cur, "sudoers_mode=")) {
        !           113:                sudoers_mode = (mode_t) strtol(*cur + sizeof("sudoers_mode=") - 1,
        !           114:                    NULL, 8);
        !           115:                continue;
        !           116:            }
        !           117:            if (MATCHES(*cur, "ldap_conf=")) {
        !           118:                path_ldap_conf = *cur + sizeof("ldap_conf=") - 1;
        !           119:                continue;
        !           120:            }
        !           121:            if (MATCHES(*cur, "ldap_secret=")) {
        !           122:                path_ldap_secret = *cur + sizeof("ldap_secret=") - 1;
        !           123:                continue;
        !           124:            }
        !           125:        }
        !           126:     }
        !           127: 
        !           128:     /* Parse command line settings. */
        !           129:     user_closefrom = -1;
        !           130:     sudo_user.max_groups = -1;
        !           131:     for (cur = info->settings; *cur != NULL; cur++) {
        !           132:        if (MATCHES(*cur, "closefrom=")) {
        !           133:            user_closefrom = atoi(*cur + sizeof("closefrom=") - 1);
        !           134:            continue;
        !           135:        }
        !           136:        if (MATCHES(*cur, "debug_flags=")) {
        !           137:            debug_flags = *cur + sizeof("debug_flags=") - 1;
        !           138:            continue;
        !           139:        }
        !           140:        if (MATCHES(*cur, "runas_user=")) {
        !           141:            *runas_user = *cur + sizeof("runas_user=") - 1;
        !           142:            sudo_user.flags |= RUNAS_USER_SPECIFIED;
        !           143:            continue;
        !           144:        }
        !           145:        if (MATCHES(*cur, "runas_group=")) {
        !           146:            *runas_group = *cur + sizeof("runas_group=") - 1;
        !           147:            sudo_user.flags |= RUNAS_GROUP_SPECIFIED;
        !           148:            continue;
        !           149:        }
        !           150:        if (MATCHES(*cur, "prompt=")) {
        !           151:            user_prompt = *cur + sizeof("prompt=") - 1;
        !           152:            def_passprompt_override = true;
        !           153:            continue;
        !           154:        }
        !           155:        if (MATCHES(*cur, "set_home=")) {
        !           156:            if (atobool(*cur + sizeof("set_home=") - 1) == true)
        !           157:                SET(flags, MODE_RESET_HOME);
        !           158:            continue;
        !           159:        }
        !           160:        if (MATCHES(*cur, "preserve_environment=")) {
        !           161:            if (atobool(*cur + sizeof("preserve_environment=") - 1) == true)
        !           162:                SET(flags, MODE_PRESERVE_ENV);
        !           163:            continue;
        !           164:        }
        !           165:        if (MATCHES(*cur, "run_shell=")) {
        !           166:            if (atobool(*cur + sizeof("run_shell=") - 1) == true)
        !           167:                SET(flags, MODE_SHELL);
        !           168:            continue;
        !           169:        }
        !           170:        if (MATCHES(*cur, "login_shell=")) {
        !           171:            if (atobool(*cur + sizeof("login_shell=") - 1) == true) {
        !           172:                SET(flags, MODE_LOGIN_SHELL);
        !           173:                def_env_reset = true;
        !           174:            }
        !           175:            continue;
        !           176:        }
        !           177:        if (MATCHES(*cur, "implied_shell=")) {
        !           178:            if (atobool(*cur + sizeof("implied_shell=") - 1) == true)
        !           179:                SET(flags, MODE_IMPLIED_SHELL);
        !           180:            continue;
        !           181:        }
        !           182:        if (MATCHES(*cur, "preserve_groups=")) {
        !           183:            if (atobool(*cur + sizeof("preserve_groups=") - 1) == true)
        !           184:                SET(flags, MODE_PRESERVE_GROUPS);
        !           185:            continue;
        !           186:        }
        !           187:        if (MATCHES(*cur, "ignore_ticket=")) {
        !           188:            if (atobool(*cur + sizeof("ignore_ticket=") - 1) == true)
        !           189:                SET(flags, MODE_IGNORE_TICKET);
        !           190:            continue;
        !           191:        }
        !           192:        if (MATCHES(*cur, "noninteractive=")) {
        !           193:            if (atobool(*cur + sizeof("noninteractive=") - 1) == true)
        !           194:                SET(flags, MODE_NONINTERACTIVE);
        !           195:            continue;
        !           196:        }
        !           197:        if (MATCHES(*cur, "sudoedit=")) {
        !           198:            if (atobool(*cur + sizeof("sudoedit=") - 1) == true)
        !           199:                SET(flags, MODE_EDIT);
        !           200:            continue;
        !           201:        }
        !           202:        if (MATCHES(*cur, "login_class=")) {
        !           203:            login_class = *cur + sizeof("login_class=") - 1;
        !           204:            def_use_loginclass = true;
        !           205:            continue;
        !           206:        }
        !           207: #ifdef HAVE_PRIV_SET
        !           208:        if (MATCHES(*cur, "runas_privs=")) {
        !           209:            def_privs = *cur + sizeof("runas_privs=") - 1;
        !           210:            continue;
        !           211:        }
        !           212:        if (MATCHES(*cur, "runas_limitprivs=")) {
        !           213:            def_limitprivs = *cur + sizeof("runas_limitprivs=") - 1;
        !           214:            continue;
        !           215:        }
        !           216: #endif /* HAVE_PRIV_SET */
        !           217: #ifdef HAVE_SELINUX
        !           218:        if (MATCHES(*cur, "selinux_role=")) {
        !           219:            user_role = *cur + sizeof("selinux_role=") - 1;
        !           220:            continue;
        !           221:        }
        !           222:        if (MATCHES(*cur, "selinux_type=")) {
        !           223:            user_type = *cur + sizeof("selinux_type=") - 1;
        !           224:            continue;
        !           225:        }
        !           226: #endif /* HAVE_SELINUX */
        !           227: #ifdef HAVE_BSD_AUTH_H
        !           228:        if (MATCHES(*cur, "bsdauth_type=")) {
        !           229:            login_style = *cur + sizeof("bsdauth_type=") - 1;
        !           230:            continue;
        !           231:        }
        !           232: #endif /* HAVE_BSD_AUTH_H */
        !           233: #if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
        !           234:        if (MATCHES(*cur, "progname=")) {
        !           235:            setprogname(*cur + sizeof("progname=") - 1);
        !           236:            continue;
        !           237:        }
        !           238: #endif
        !           239:        if (MATCHES(*cur, "network_addrs=")) {
        !           240:            interfaces_string = *cur + sizeof("network_addrs=") - 1;
        !           241:            set_interfaces(interfaces_string);
        !           242:            continue;
        !           243:        }
        !           244:        if (MATCHES(*cur, "max_groups=")) {
        !           245:            sudo_user.max_groups = atoi(*cur + sizeof("max_groups=") - 1);
        !           246:            continue;
        !           247:        }
        !           248:     }
        !           249: 
        !           250:     for (cur = info->user_info; *cur != NULL; cur++) {
        !           251:        if (MATCHES(*cur, "user=")) {
        !           252:            user_name = estrdup(*cur + sizeof("user=") - 1);
        !           253:            continue;
        !           254:        }
        !           255:        if (MATCHES(*cur, "uid=")) {
        !           256:            user_uid = (uid_t) atoi(*cur + sizeof("uid=") - 1);
        !           257:            continue;
        !           258:        }
        !           259:        if (MATCHES(*cur, "gid=")) {
        !           260:            p = *cur + sizeof("gid=") - 1;
        !           261:            user_gid = (gid_t) atoi(p);
        !           262:            continue;
        !           263:        }
        !           264:        if (MATCHES(*cur, "groups=")) {
        !           265:            groups = *cur + sizeof("groups=") - 1;
        !           266:            continue;
        !           267:        }
        !           268:        if (MATCHES(*cur, "cwd=")) {
        !           269:            user_cwd = estrdup(*cur + sizeof("cwd=") - 1);
        !           270:            continue;
        !           271:        }
        !           272:        if (MATCHES(*cur, "tty=")) {
        !           273:            user_tty = user_ttypath = estrdup(*cur + sizeof("tty=") - 1);
        !           274:            if (strncmp(user_tty, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
        !           275:                user_tty += sizeof(_PATH_DEV) - 1;
        !           276:            continue;
        !           277:        }
        !           278:        if (MATCHES(*cur, "host=")) {
        !           279:            user_host = user_shost = estrdup(*cur + sizeof("host=") - 1);
        !           280:            if ((p = strchr(user_host, '.')))
        !           281:                user_shost = estrndup(user_host, (size_t)(p - user_host));
        !           282:            continue;
        !           283:        }
        !           284:        if (MATCHES(*cur, "lines=")) {
        !           285:            sudo_user.lines = atoi(*cur + sizeof("lines=") - 1);
        !           286:            continue;
        !           287:        }
        !           288:        if (MATCHES(*cur, "cols=")) {
        !           289:            sudo_user.cols = atoi(*cur + sizeof("cols=") - 1);
        !           290:            continue;
        !           291:        }
        !           292:        if (MATCHES(*cur, "sid=")) {
        !           293:            sudo_user.sid = atoi(*cur + sizeof("sid=") - 1);
        !           294:            continue;
        !           295:        }
        !           296:     }
        !           297:     if (user_cwd == NULL)
        !           298:        user_cwd = "unknown";
        !           299:     if (user_tty == NULL)
        !           300:        user_tty = "unknown"; /* user_ttypath remains NULL */
        !           301: 
        !           302:     if (groups != NULL && groups[0] != '\0') {
        !           303:        const char *cp;
        !           304:        GETGROUPS_T *gids;
        !           305:        int ngids;
        !           306: 
        !           307:        /* Count number of groups, including passwd gid. */
        !           308:        ngids = 2;
        !           309:        for (cp = groups; *cp != '\0'; cp++) {
        !           310:            if (*cp == ',')
        !           311:                ngids++;
        !           312:        }
        !           313: 
        !           314:        /* The first gid in the list is the passwd group gid. */
        !           315:        gids = emalloc2(ngids, sizeof(GETGROUPS_T));
        !           316:        gids[0] = user_gid;
        !           317:        ngids = 1;
        !           318:        cp = groups;
        !           319:        for (;;) {
        !           320:            gids[ngids] = atoi(cp);
        !           321:            if (gids[0] != gids[ngids])
        !           322:                ngids++;
        !           323:            cp = strchr(cp, ',');
        !           324:            if (cp == NULL)
        !           325:                break;
        !           326:            cp++; /* skip over comma */
        !           327:        }
        !           328:        user_gids = gids;
        !           329:        user_ngids = ngids;
        !           330:     }
        !           331: 
        !           332:     /* Stash initial umask for later use. */
        !           333:     user_umask = umask(SUDO_UMASK);
        !           334:     umask(user_umask);
        !           335: 
        !           336:     /* Setup debugging if indicated. */
        !           337:     if (debug_flags != NULL) {
        !           338:        sudo_debug_init(NULL, debug_flags);
        !           339:        for (cur = info->settings; *cur != NULL; cur++)
        !           340:            sudo_debug_printf(SUDO_DEBUG_INFO, "settings: %s", *cur);
        !           341:        for (cur = info->user_info; *cur != NULL; cur++)
        !           342:            sudo_debug_printf(SUDO_DEBUG_INFO, "user_info: %s", *cur);
        !           343:     }
        !           344: 
        !           345: #undef MATCHES
        !           346:     debug_return_int(flags);
        !           347: }
        !           348: 
        !           349: /*
        !           350:  * Setup the execution environment.
        !           351:  * Builds up the command_info list and sets argv and envp.
        !           352:  * Returns 1 on success and -1 on error.
        !           353:  */
        !           354: int
        !           355: sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
        !           356:     char *iolog_path, void *v)
        !           357: {
        !           358:     struct sudoers_exec_args *exec_args = v;
        !           359:     char **command_info;
        !           360:     int info_len = 0;
        !           361:     debug_decl(sudoers_policy_exec_setup, SUDO_DEBUG_PLUGIN)
        !           362: 
        !           363:     /* Increase the length of command_info as needed, it is *not* checked. */
        !           364:     command_info = ecalloc(32, sizeof(char **));
        !           365: 
        !           366:     command_info[info_len++] = fmt_string("command", safe_cmnd);
        !           367:     if (def_log_input || def_log_output) {
        !           368:        if (iolog_path)
        !           369:            command_info[info_len++] = iolog_path;
        !           370:        if (def_log_input) {
        !           371:            command_info[info_len++] = estrdup("iolog_stdin=true");
        !           372:            command_info[info_len++] = estrdup("iolog_ttyin=true");
        !           373:        }
        !           374:        if (def_log_output) {
        !           375:            command_info[info_len++] = estrdup("iolog_stdout=true");
        !           376:            command_info[info_len++] = estrdup("iolog_stderr=true");
        !           377:            command_info[info_len++] = estrdup("iolog_ttyout=true");
        !           378:        }
        !           379:        if (def_compress_io) {
        !           380:            command_info[info_len++] = estrdup("iolog_compress=true");
        !           381:        }
        !           382:        if (def_maxseq) {
        !           383:            easprintf(&command_info[info_len++], "maxseq=%u", def_maxseq);
        !           384:        }
        !           385:     }
        !           386:     if (ISSET(sudo_mode, MODE_EDIT))
        !           387:        command_info[info_len++] = estrdup("sudoedit=true");
        !           388:     if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
        !           389:        /* Set cwd to run user's homedir. */
        !           390:        command_info[info_len++] = fmt_string("cwd", runas_pw->pw_dir);
        !           391:     }
        !           392:     if (def_stay_setuid) {
        !           393:        easprintf(&command_info[info_len++], "runas_uid=%u",
        !           394:            (unsigned int)user_uid);
        !           395:        easprintf(&command_info[info_len++], "runas_gid=%u",
        !           396:            (unsigned int)user_gid);
        !           397:        easprintf(&command_info[info_len++], "runas_euid=%u",
        !           398:            (unsigned int)runas_pw->pw_uid);
        !           399:        easprintf(&command_info[info_len++], "runas_egid=%u",
        !           400:            runas_gr ? (unsigned int)runas_gr->gr_gid :
        !           401:            (unsigned int)runas_pw->pw_gid);
        !           402:     } else {
        !           403:        easprintf(&command_info[info_len++], "runas_uid=%u",
        !           404:            (unsigned int)runas_pw->pw_uid);
        !           405:        easprintf(&command_info[info_len++], "runas_gid=%u",
        !           406:            runas_gr ? (unsigned int)runas_gr->gr_gid :
        !           407:            (unsigned int)runas_pw->pw_gid);
        !           408:     }
        !           409:     if (def_preserve_groups) {
        !           410:        command_info[info_len++] = "preserve_groups=true";
        !           411:     } else {
        !           412:        int i, len;
        !           413:        gid_t egid;
        !           414:        size_t glsize;
        !           415:        char *cp, *gid_list;
        !           416:        struct group_list *grlist = sudo_get_grlist(runas_pw);
        !           417: 
        !           418:        /* We reserve an extra spot in the list for the effective gid. */
        !           419:        glsize = sizeof("runas_groups=") - 1 +
        !           420:            ((grlist->ngids + 1) * (MAX_UID_T_LEN + 1));
        !           421:        gid_list = emalloc(glsize);
        !           422:        memcpy(gid_list, "runas_groups=", sizeof("runas_groups=") - 1);
        !           423:        cp = gid_list + sizeof("runas_groups=") - 1;
        !           424: 
        !           425:        /* On BSD systems the effective gid is the first group in the list. */
        !           426:        egid = runas_gr ? (unsigned int)runas_gr->gr_gid :
        !           427:            (unsigned int)runas_pw->pw_gid;
        !           428:        len = snprintf(cp, glsize - (cp - gid_list), "%u", egid);
        !           429:        if (len < 0 || len >= glsize - (cp - gid_list))
        !           430:            fatalx(_("internal error, %s overflow"), "runas_groups");
        !           431:        cp += len;
        !           432:        for (i = 0; i < grlist->ngids; i++) {
        !           433:            if (grlist->gids[i] != egid) {
        !           434:                len = snprintf(cp, glsize - (cp - gid_list), ",%u",
        !           435:                     (unsigned int) grlist->gids[i]);
        !           436:                if (len < 0 || len >= glsize - (cp - gid_list))
        !           437:                    fatalx(_("internal error, %s overflow"), "runas_groups");
        !           438:                cp += len;
        !           439:            }
        !           440:        }
        !           441:        command_info[info_len++] = gid_list;
        !           442:        sudo_grlist_delref(grlist);
        !           443:     }
        !           444:     if (def_closefrom >= 0)
        !           445:        easprintf(&command_info[info_len++], "closefrom=%d", def_closefrom);
        !           446:     if (def_noexec)
        !           447:        command_info[info_len++] = estrdup("noexec=true");
        !           448:     if (def_exec_background)
        !           449:        command_info[info_len++] = estrdup("exec_background=true");
        !           450:     if (def_set_utmp)
        !           451:        command_info[info_len++] = estrdup("set_utmp=true");
        !           452:     if (def_use_pty)
        !           453:        command_info[info_len++] = estrdup("use_pty=true");
        !           454:     if (def_utmp_runas)
        !           455:        command_info[info_len++] = fmt_string("utmp_user", runas_pw->pw_name);
        !           456:     if (cmnd_umask != 0777)
        !           457:        easprintf(&command_info[info_len++], "umask=0%o", (unsigned int)cmnd_umask);
        !           458: #ifdef HAVE_LOGIN_CAP_H
        !           459:     if (def_use_loginclass)
        !           460:        command_info[info_len++] = fmt_string("login_class", login_class);
        !           461: #endif /* HAVE_LOGIN_CAP_H */
        !           462: #ifdef HAVE_SELINUX
        !           463:     if (user_role != NULL)
        !           464:        command_info[info_len++] = fmt_string("selinux_role", user_role);
        !           465:     if (user_type != NULL)
        !           466:        command_info[info_len++] = fmt_string("selinux_type", user_type);
        !           467: #endif /* HAVE_SELINUX */
        !           468: #ifdef HAVE_PRIV_SET
        !           469:     if (runas_privs != NULL)
        !           470:        command_info[info_len++] = fmt_string("runas_privs", runas_privs);
        !           471:     if (runas_limitprivs != NULL)
        !           472:        command_info[info_len++] = fmt_string("runas_limitprivs", runas_limitprivs);
        !           473: #endif /* HAVE_SELINUX */
        !           474: 
        !           475:     /* Fill in exec environment info */
        !           476:     *(exec_args->argv) = argv;
        !           477:     *(exec_args->envp) = envp;
        !           478:     *(exec_args->info) = command_info;
        !           479: 
        !           480:     debug_return_bool(true);
        !           481: }
        !           482: 
        !           483: static int
        !           484: sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
        !           485:     sudo_printf_t plugin_printf, char * const settings[],
        !           486:     char * const user_info[], char * const envp[], char * const args[])
        !           487: {
        !           488:     struct sudoers_policy_open_info info;
        !           489:     debug_decl(sudoers_policy_open, SUDO_DEBUG_PLUGIN)
        !           490: 
        !           491:     sudo_version = version;
        !           492:     sudo_conv = conversation;
        !           493:     sudo_printf = plugin_printf;
        !           494: 
        !           495:     /* Plugin args are only specified for API version 1.2 and higher. */
        !           496:     if (sudo_version < SUDO_API_MKVERSION(1, 2))
        !           497:        args = NULL;
        !           498: 
        !           499:     if (fatal_setjmp() != 0) {
        !           500:        /* called via fatal(), fatalx() or log_fatal() */
        !           501:        rewind_perms();
        !           502:        fatal_disable_setjmp();
        !           503:        debug_return_bool(-1);
        !           504:     }
        !           505: 
        !           506:     /* Call the sudoers init function. */
        !           507:     info.settings = settings;
        !           508:     info.user_info = user_info;
        !           509:     info.plugin_args = args;
        !           510:     debug_return_bool(sudoers_policy_init(&info, envp));
        !           511: }
        !           512: 
        !           513: static void
        !           514: sudoers_policy_close(int exit_status, int error_code)
        !           515: {
        !           516:     debug_decl(sudoers_policy_close, SUDO_DEBUG_PLUGIN)
        !           517: 
        !           518:     if (fatal_setjmp() != 0) {
        !           519:        /* called via fatal(), fatalx() or log_fatal() */
        !           520:        fatal_disable_setjmp();
        !           521:        debug_return;
        !           522:     }
        !           523: 
        !           524:     /* We do not currently log the exit status. */
        !           525:     if (error_code) {
        !           526:        errno = error_code;
        !           527:        warning(_("unable to execute %s"), safe_cmnd);
        !           528:     }
        !           529: 
        !           530:     /* Close the session we opened in sudoers_policy_init_session(). */
        !           531:     if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT))
        !           532:        (void)sudo_auth_end_session(runas_pw);
        !           533: 
        !           534:     /* Free remaining references to password and group entries. */
        !           535:     /* XXX - move cleanup to function in sudoers.c */
        !           536:     sudo_pw_delref(sudo_user.pw);
        !           537:     sudo_user.pw = NULL;
        !           538:     sudo_pw_delref(runas_pw);
        !           539:     runas_pw = NULL;
        !           540:     if (runas_gr != NULL) {
        !           541:        sudo_gr_delref(runas_gr);
        !           542:        runas_gr = NULL;
        !           543:     }
        !           544:     if (user_group_list != NULL) {
        !           545:        sudo_grlist_delref(user_group_list);
        !           546:        user_group_list = NULL;
        !           547:     }
        !           548:     efree(user_gids);
        !           549:     user_gids = NULL;
        !           550: 
        !           551:     debug_return;
        !           552: }
        !           553: 
        !           554: /*
        !           555:  * The init_session function is called before executing the command
        !           556:  * and before uid/gid changes occur.
        !           557:  * Returns 1 on success, 0 on failure and -1 on error.
        !           558:  */
        !           559: static int
        !           560: sudoers_policy_init_session(struct passwd *pwd, char **user_env[])
        !           561: {
        !           562:     debug_decl(sudoers_policy_init_session, SUDO_DEBUG_PLUGIN)
        !           563: 
        !           564:     /* user_env is only specified for API version 1.2 and higher. */
        !           565:     if (sudo_version < SUDO_API_MKVERSION(1, 2))
        !           566:        user_env = NULL;
        !           567: 
        !           568:     if (fatal_setjmp() != 0) {
        !           569:        /* called via fatal(), fatalx() or log_fatal() */
        !           570:        fatal_disable_setjmp();
        !           571:        debug_return_bool(-1);
        !           572:     }
        !           573: 
        !           574:     debug_return_bool(sudo_auth_begin_session(pwd, user_env));
        !           575: }
        !           576: 
        !           577: static int
        !           578: sudoers_policy_check(int argc, char * const argv[], char *env_add[],
        !           579:     char **command_infop[], char **argv_out[], char **user_env_out[])
        !           580: {
        !           581:     struct sudoers_exec_args exec_args;
        !           582:     int rval;
        !           583:     debug_decl(sudoers_policy_check, SUDO_DEBUG_PLUGIN)
        !           584: 
        !           585:     if (!ISSET(sudo_mode, MODE_EDIT))
        !           586:        SET(sudo_mode, MODE_RUN);
        !           587: 
        !           588:     exec_args.argv = argv_out;
        !           589:     exec_args.envp = user_env_out;
        !           590:     exec_args.info = command_infop;
        !           591: 
        !           592:     rval = sudoers_policy_main(argc, argv, 0, env_add, &exec_args);
        !           593:     if (rval == true && sudo_version >= SUDO_API_MKVERSION(1, 3)) {
        !           594:        /* Unset close function if we don't need it to avoid extra process. */
        !           595:        if (!def_log_input && !def_log_output && !def_use_pty &&
        !           596:            !sudo_auth_needs_end_session())
        !           597:            sudoers_policy.close = NULL;
        !           598:     }
        !           599:     debug_return_bool(rval);
        !           600: }
        !           601: 
        !           602: static int
        !           603: sudoers_policy_validate(void)
        !           604: {
        !           605:     debug_decl(sudoers_policy_validate, SUDO_DEBUG_PLUGIN)
        !           606: 
        !           607:     user_cmnd = "validate";
        !           608:     SET(sudo_mode, MODE_VALIDATE);
        !           609: 
        !           610:     debug_return_bool(sudoers_policy_main(0, NULL, I_VERIFYPW, NULL, NULL));
        !           611: }
        !           612: 
        !           613: static void
        !           614: sudoers_policy_invalidate(int remove)
        !           615: {
        !           616:     debug_decl(sudoers_policy_invalidate, SUDO_DEBUG_PLUGIN)
        !           617: 
        !           618:     user_cmnd = "kill";
        !           619:     if (fatal_setjmp() == 0) {
        !           620:        remove_timestamp(remove);
        !           621:        sudoers_cleanup();
        !           622:     }
        !           623:     fatal_disable_setjmp();
        !           624: 
        !           625:     debug_return;
        !           626: }
        !           627: 
        !           628: static int
        !           629: sudoers_policy_list(int argc, char * const argv[], int verbose,
        !           630:     const char *list_user)
        !           631: {
        !           632:     int rval;
        !           633:     debug_decl(sudoers_policy_list, SUDO_DEBUG_PLUGIN)
        !           634: 
        !           635:     user_cmnd = "list";
        !           636:     if (argc)
        !           637:        SET(sudo_mode, MODE_CHECK);
        !           638:     else
        !           639:        SET(sudo_mode, MODE_LIST);
        !           640:     if (verbose)
        !           641:        long_list = 1;
        !           642:     if (list_user) {
        !           643:        list_pw = sudo_getpwnam(list_user);
        !           644:        if (list_pw == NULL) {
        !           645:            warningx(_("unknown user: %s"), list_user);
        !           646:            debug_return_bool(-1);
        !           647:        }
        !           648:     }
        !           649:     rval = sudoers_policy_main(argc, argv, I_LISTPW, NULL, NULL);
        !           650:     if (list_user) {
        !           651:        sudo_pw_delref(list_pw);
        !           652:        list_pw = NULL;
        !           653:     }
        !           654: 
        !           655:     debug_return_bool(rval);
        !           656: }
        !           657: 
        !           658: static int
        !           659: sudoers_policy_version(int verbose)
        !           660: {
        !           661:     debug_decl(sudoers_policy_version, SUDO_DEBUG_PLUGIN)
        !           662: 
        !           663:     if (fatal_setjmp() != 0) {
        !           664:        /* error recovery via fatal(), fatalx() or log_fatal() */
        !           665:        fatal_disable_setjmp();
        !           666:        debug_return_bool(-1);
        !           667:     }
        !           668: 
        !           669:     sudo_printf(SUDO_CONV_INFO_MSG, _("Sudoers policy plugin version %s\n"),
        !           670:        PACKAGE_VERSION);
        !           671:     sudo_printf(SUDO_CONV_INFO_MSG, _("Sudoers file grammar version %d\n"),
        !           672:        SUDOERS_GRAMMAR_VERSION);
        !           673: 
        !           674:     if (verbose) {
        !           675:        sudo_printf(SUDO_CONV_INFO_MSG, _("\nSudoers path: %s\n"), sudoers_file);
        !           676: #ifdef HAVE_LDAP
        !           677: # ifdef _PATH_NSSWITCH_CONF
        !           678:        sudo_printf(SUDO_CONV_INFO_MSG, _("nsswitch path: %s\n"), _PATH_NSSWITCH_CONF);
        !           679: # endif
        !           680:        sudo_printf(SUDO_CONV_INFO_MSG, _("ldap.conf path: %s\n"), path_ldap_conf);
        !           681:        sudo_printf(SUDO_CONV_INFO_MSG, _("ldap.secret path: %s\n"), path_ldap_secret);
        !           682: #endif
        !           683:        dump_auth_methods();
        !           684:        dump_defaults();
        !           685:        sudo_printf(SUDO_CONV_INFO_MSG, "\n");
        !           686:        if (interfaces_string != NULL) {
        !           687:            dump_interfaces(interfaces_string);
        !           688:            sudo_printf(SUDO_CONV_INFO_MSG, "\n");
        !           689:        }
        !           690:     }
        !           691:     debug_return_bool(true);
        !           692: }
        !           693: 
        !           694: static void
        !           695: sudoers_policy_register_hooks(int version, int (*register_hook)(struct sudo_hook *hook))
        !           696: {
        !           697:     struct sudo_hook hook;
        !           698: 
        !           699:     memset(&hook, 0, sizeof(hook));
        !           700:     hook.hook_version = SUDO_HOOK_VERSION;
        !           701: 
        !           702:     hook.hook_type = SUDO_HOOK_SETENV;
        !           703:     hook.hook_fn = sudoers_hook_setenv;
        !           704:     register_hook(&hook);
        !           705: 
        !           706:     hook.hook_type = SUDO_HOOK_UNSETENV;
        !           707:     hook.hook_fn = sudoers_hook_unsetenv;
        !           708:     register_hook(&hook);
        !           709: 
        !           710:     hook.hook_type = SUDO_HOOK_GETENV;
        !           711:     hook.hook_fn = sudoers_hook_getenv;
        !           712:     register_hook(&hook);
        !           713: 
        !           714:     hook.hook_type = SUDO_HOOK_PUTENV;
        !           715:     hook.hook_fn = sudoers_hook_putenv;
        !           716:     register_hook(&hook);
        !           717: }
        !           718: 
        !           719: __dso_public struct policy_plugin sudoers_policy = {
        !           720:     SUDO_POLICY_PLUGIN,
        !           721:     SUDO_API_VERSION,
        !           722:     sudoers_policy_open,
        !           723:     sudoers_policy_close,
        !           724:     sudoers_policy_version,
        !           725:     sudoers_policy_check,
        !           726:     sudoers_policy_list,
        !           727:     sudoers_policy_validate,
        !           728:     sudoers_policy_invalidate,
        !           729:     sudoers_policy_init_session,
        !           730:     sudoers_policy_register_hooks
        !           731: };

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>