1761efaa7SDag-Erling Smørgrav /* $OpenBSD: groupaccess.c,v 1.12 2006/08/03 03:34:42 deraadt Exp $ */ 21e8db6e2SBrian Feldman /* 31e8db6e2SBrian Feldman * Copyright (c) 2001 Kevin Steves. All rights reserved. 41e8db6e2SBrian Feldman * 51e8db6e2SBrian Feldman * Redistribution and use in source and binary forms, with or without 61e8db6e2SBrian Feldman * modification, are permitted provided that the following conditions 71e8db6e2SBrian Feldman * are met: 81e8db6e2SBrian Feldman * 1. Redistributions of source code must retain the above copyright 91e8db6e2SBrian Feldman * notice, this list of conditions and the following disclaimer. 101e8db6e2SBrian Feldman * 2. Redistributions in binary form must reproduce the above copyright 111e8db6e2SBrian Feldman * notice, this list of conditions and the following disclaimer in the 121e8db6e2SBrian Feldman * documentation and/or other materials provided with the distribution. 131e8db6e2SBrian Feldman * 141e8db6e2SBrian Feldman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 151e8db6e2SBrian Feldman * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 161e8db6e2SBrian Feldman * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 171e8db6e2SBrian Feldman * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 181e8db6e2SBrian Feldman * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 191e8db6e2SBrian Feldman * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 201e8db6e2SBrian Feldman * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 211e8db6e2SBrian Feldman * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 221e8db6e2SBrian Feldman * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 231e8db6e2SBrian Feldman * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 241e8db6e2SBrian Feldman */ 251e8db6e2SBrian Feldman 261e8db6e2SBrian Feldman #include "includes.h" 271e8db6e2SBrian Feldman 28761efaa7SDag-Erling Smørgrav #include <sys/types.h> 29761efaa7SDag-Erling Smørgrav #include <sys/param.h> 30761efaa7SDag-Erling Smørgrav 31761efaa7SDag-Erling Smørgrav #include <grp.h> 32761efaa7SDag-Erling Smørgrav #include <unistd.h> 33761efaa7SDag-Erling Smørgrav #include <stdarg.h> 34761efaa7SDag-Erling Smørgrav 351e8db6e2SBrian Feldman #include "xmalloc.h" 36761efaa7SDag-Erling Smørgrav #include "groupaccess.h" 371e8db6e2SBrian Feldman #include "match.h" 381e8db6e2SBrian Feldman #include "log.h" 391e8db6e2SBrian Feldman 401e8db6e2SBrian Feldman static int ngroups; 41efcad6b7SDag-Erling Smørgrav static char **groups_byname; 421e8db6e2SBrian Feldman 43ae1f160dSDag-Erling Smørgrav /* 44ae1f160dSDag-Erling Smørgrav * Initialize group access list for user with primary (base) and 45ae1f160dSDag-Erling Smørgrav * supplementary groups. Return the number of groups in the list. 46ae1f160dSDag-Erling Smørgrav */ 471e8db6e2SBrian Feldman int 481e8db6e2SBrian Feldman ga_init(const char *user, gid_t base) 491e8db6e2SBrian Feldman { 50efcad6b7SDag-Erling Smørgrav gid_t *groups_bygid; 511e8db6e2SBrian Feldman int i, j; 521e8db6e2SBrian Feldman struct group *gr; 531e8db6e2SBrian Feldman 541e8db6e2SBrian Feldman if (ngroups > 0) 551e8db6e2SBrian Feldman ga_free(); 561e8db6e2SBrian Feldman 57efcad6b7SDag-Erling Smørgrav ngroups = NGROUPS_MAX; 58efcad6b7SDag-Erling Smørgrav #if defined(HAVE_SYSCONF) && defined(_SC_NGROUPS_MAX) 59efcad6b7SDag-Erling Smørgrav ngroups = MAX(NGROUPS_MAX, sysconf(_SC_NGROUPS_MAX)); 60efcad6b7SDag-Erling Smørgrav #endif 61efcad6b7SDag-Erling Smørgrav 62761efaa7SDag-Erling Smørgrav groups_bygid = xcalloc(ngroups, sizeof(*groups_bygid)); 63761efaa7SDag-Erling Smørgrav groups_byname = xcalloc(ngroups, sizeof(*groups_byname)); 64efcad6b7SDag-Erling Smørgrav 651e8db6e2SBrian Feldman if (getgrouplist(user, base, groups_bygid, &ngroups) == -1) 66d95e11bfSDag-Erling Smørgrav logit("getgrouplist: groups list too small"); 671e8db6e2SBrian Feldman for (i = 0, j = 0; i < ngroups; i++) 681e8db6e2SBrian Feldman if ((gr = getgrgid(groups_bygid[i])) != NULL) 691e8db6e2SBrian Feldman groups_byname[j++] = xstrdup(gr->gr_name); 70efcad6b7SDag-Erling Smørgrav xfree(groups_bygid); 711e8db6e2SBrian Feldman return (ngroups = j); 721e8db6e2SBrian Feldman } 731e8db6e2SBrian Feldman 74ae1f160dSDag-Erling Smørgrav /* 75ae1f160dSDag-Erling Smørgrav * Return 1 if one of user's groups is contained in groups. 76ae1f160dSDag-Erling Smørgrav * Return 0 otherwise. Use match_pattern() for string comparison. 77ae1f160dSDag-Erling Smørgrav */ 781e8db6e2SBrian Feldman int 791e8db6e2SBrian Feldman ga_match(char * const *groups, int n) 801e8db6e2SBrian Feldman { 811e8db6e2SBrian Feldman int i, j; 821e8db6e2SBrian Feldman 831e8db6e2SBrian Feldman for (i = 0; i < ngroups; i++) 841e8db6e2SBrian Feldman for (j = 0; j < n; j++) 851e8db6e2SBrian Feldman if (match_pattern(groups_byname[i], groups[j])) 861e8db6e2SBrian Feldman return 1; 871e8db6e2SBrian Feldman return 0; 881e8db6e2SBrian Feldman } 891e8db6e2SBrian Feldman 90ae1f160dSDag-Erling Smørgrav /* 91ae1f160dSDag-Erling Smørgrav * Free memory allocated for group access list. 92ae1f160dSDag-Erling Smørgrav */ 931e8db6e2SBrian Feldman void 941e8db6e2SBrian Feldman ga_free(void) 951e8db6e2SBrian Feldman { 961e8db6e2SBrian Feldman int i; 971e8db6e2SBrian Feldman 981e8db6e2SBrian Feldman if (ngroups > 0) { 991e8db6e2SBrian Feldman for (i = 0; i < ngroups; i++) 1001e8db6e2SBrian Feldman xfree(groups_byname[i]); 1011e8db6e2SBrian Feldman ngroups = 0; 102efcad6b7SDag-Erling Smørgrav xfree(groups_byname); 1031e8db6e2SBrian Feldman } 1041e8db6e2SBrian Feldman } 105