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