Annotation of embedaddon/sudo/plugins/system_group/system_group.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (c) 2010, 2012 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 <sys/stat.h>
        !            22: 
        !            23: #include <stdio.h>
        !            24: #ifdef STDC_HEADERS
        !            25: # include <stdlib.h>
        !            26: # include <stddef.h>
        !            27: #else
        !            28: # ifdef HAVE_STDLIB_H
        !            29: #  include <stdlib.h>
        !            30: # endif
        !            31: #endif /* STDC_HEADERS */
        !            32: #ifdef HAVE_STDBOOL_H
        !            33: # include <stdbool.h>
        !            34: #else
        !            35: # include "compat/stdbool.h"
        !            36: #endif /* HAVE_STDBOOL_H */
        !            37: #ifdef HAVE_STRING_H
        !            38: # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
        !            39: #  include <memory.h>
        !            40: # endif
        !            41: # include <string.h>
        !            42: #endif /* HAVE_STRING_H */
        !            43: #ifdef HAVE_STRINGS_H
        !            44: # include <strings.h>
        !            45: #endif /* HAVE_STRINGS_H */
        !            46: #ifdef HAVE_UNISTD_H
        !            47: # include <unistd.h>
        !            48: #endif /* HAVE_UNISTD_H */
        !            49: #ifdef HAVE_DLOPEN
        !            50: # include <dlfcn.h>
        !            51: #else
        !            52: # include "compat/dlfcn.h"
        !            53: #endif
        !            54: #include <ctype.h>
        !            55: #include <errno.h>
        !            56: #include <fcntl.h>
        !            57: #include <limits.h>
        !            58: #include <grp.h>
        !            59: #include <pwd.h>
        !            60: 
        !            61: #include "sudo_plugin.h"
        !            62: #include "missing.h"
        !            63: 
        !            64: #ifndef RTLD_DEFAULT
        !            65: # define RTLD_DEFAULT  NULL
        !            66: #endif
        !            67: 
        !            68: /*
        !            69:  * Sudoers group plugin that does group name-based lookups using the system
        !            70:  * group database functions, similar to how sudo behaved prior to 1.7.3.
        !            71:  * This can be used on systems where lookups by group ID are problematic.
        !            72:  */
        !            73: 
        !            74: static sudo_printf_t sudo_log;
        !            75: 
        !            76: typedef struct group * (*sysgroup_getgrnam_t)(const char *);
        !            77: typedef struct group * (*sysgroup_getgrgid_t)(gid_t);
        !            78: typedef void (*sysgroup_gr_delref_t)(struct group *);
        !            79: 
        !            80: static sysgroup_getgrnam_t sysgroup_getgrnam;
        !            81: static sysgroup_getgrgid_t sysgroup_getgrgid;
        !            82: static sysgroup_gr_delref_t sysgroup_gr_delref;
        !            83: static bool need_setent;
        !            84: 
        !            85: static int
        !            86: sysgroup_init(int version, sudo_printf_t sudo_printf, char *const argv[])
        !            87: {
        !            88:     void *handle;
        !            89: 
        !            90:     sudo_log = sudo_printf;
        !            91: 
        !            92:     if (GROUP_API_VERSION_GET_MAJOR(version) != GROUP_API_VERSION_MAJOR) {
        !            93:        sudo_log(SUDO_CONV_ERROR_MSG,
        !            94:            "sysgroup_group: incompatible major version %d, expected %d\n",
        !            95:            GROUP_API_VERSION_GET_MAJOR(version),
        !            96:            GROUP_API_VERSION_MAJOR);
        !            97:        return -1;
        !            98:     }
        !            99: 
        !           100:     /* Share group cache with sudo if possible. */
        !           101:     handle = dlsym(RTLD_DEFAULT, "sudo_getgrnam");
        !           102:     if (handle != NULL) {
        !           103:        sysgroup_getgrnam = (sysgroup_getgrnam_t)handle;
        !           104:     } else {
        !           105:        sysgroup_getgrnam = (sysgroup_getgrnam_t)getgrnam;
        !           106:        need_setent = true;
        !           107:     }
        !           108: 
        !           109:     handle = dlsym(RTLD_DEFAULT, "sudo_getgrgid");
        !           110:     if (handle != NULL) {
        !           111:        sysgroup_getgrgid = (sysgroup_getgrgid_t)handle;
        !           112:     } else {
        !           113:        sysgroup_getgrgid = (sysgroup_getgrgid_t)getgrgid;
        !           114:        need_setent = true;
        !           115:     }
        !           116: 
        !           117:     handle = dlsym(RTLD_DEFAULT, "gr_delref");
        !           118:     if (handle != NULL)
        !           119:        sysgroup_gr_delref = (sysgroup_gr_delref_t)handle;
        !           120: 
        !           121:     if (need_setent)
        !           122:        setgrent();
        !           123: 
        !           124:     return true;
        !           125: }
        !           126: 
        !           127: static void
        !           128: sysgroup_cleanup(void)
        !           129: {
        !           130:     if (need_setent)
        !           131:        endgrent();
        !           132: }
        !           133: 
        !           134: /*
        !           135:  * Returns true if "user" is a member of "group", else false.
        !           136:  */
        !           137: static int
        !           138: sysgroup_query(const char *user, const char *group, const struct passwd *pwd)
        !           139: {
        !           140:     char **member, *ep = '\0';
        !           141:     struct group *grp;
        !           142: 
        !           143:     grp = sysgroup_getgrnam(group);
        !           144:     if (grp == NULL && group[0] == '#' && group[1] != '\0') {
        !           145:        long lval = strtol(group + 1, &ep, 10);
        !           146:        if (*ep == '\0') {
        !           147:            if ((lval != LONG_MAX && lval != LONG_MIN) || errno != ERANGE)
        !           148:                grp = sysgroup_getgrgid((gid_t)lval);
        !           149:        }
        !           150:     }
        !           151:     if (grp != NULL) {
        !           152:        for (member = grp->gr_mem; *member != NULL; member++) {
        !           153:            if (strcasecmp(user, *member) == 0) {
        !           154:                if (sysgroup_gr_delref)
        !           155:                    sysgroup_gr_delref(grp);
        !           156:                return true;
        !           157:            }
        !           158:        }
        !           159:        if (sysgroup_gr_delref)
        !           160:            sysgroup_gr_delref(grp);
        !           161:     }
        !           162: 
        !           163:     return false;
        !           164: }
        !           165: 
        !           166: struct sudoers_group_plugin group_plugin = {
        !           167:     GROUP_API_VERSION,
        !           168:     sysgroup_init,
        !           169:     sysgroup_cleanup,
        !           170:     sysgroup_query
        !           171: };

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