groupaccess.c revision 162852
1162852Sdes/* $OpenBSD: groupaccess.c,v 1.12 2006/08/03 03:34:42 deraadt Exp $ */ 276259Sgreen/* 376259Sgreen * Copyright (c) 2001 Kevin Steves. All rights reserved. 476259Sgreen * 576259Sgreen * Redistribution and use in source and binary forms, with or without 676259Sgreen * modification, are permitted provided that the following conditions 776259Sgreen * are met: 876259Sgreen * 1. Redistributions of source code must retain the above copyright 976259Sgreen * notice, this list of conditions and the following disclaimer. 1076259Sgreen * 2. Redistributions in binary form must reproduce the above copyright 1176259Sgreen * notice, this list of conditions and the following disclaimer in the 1276259Sgreen * documentation and/or other materials provided with the distribution. 1376259Sgreen * 1476259Sgreen * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1576259Sgreen * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1676259Sgreen * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1776259Sgreen * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1876259Sgreen * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1976259Sgreen * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2076259Sgreen * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2176259Sgreen * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2276259Sgreen * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2376259Sgreen * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2476259Sgreen */ 2576259Sgreen 2676259Sgreen#include "includes.h" 2776259Sgreen 28162852Sdes#include <sys/types.h> 29162852Sdes#include <sys/param.h> 30162852Sdes 31162852Sdes#include <grp.h> 32162852Sdes#include <unistd.h> 33162852Sdes#include <stdarg.h> 34162852Sdes 35162852Sdes#include "xmalloc.h" 3676259Sgreen#include "groupaccess.h" 3776259Sgreen#include "match.h" 3876259Sgreen#include "log.h" 3976259Sgreen 4076259Sgreenstatic int ngroups; 41126274Sdesstatic char **groups_byname; 4276259Sgreen 4392555Sdes/* 4492555Sdes * Initialize group access list for user with primary (base) and 4592555Sdes * supplementary groups. Return the number of groups in the list. 4692555Sdes */ 4776259Sgreenint 4876259Sgreenga_init(const char *user, gid_t base) 4976259Sgreen{ 50126274Sdes gid_t *groups_bygid; 5176259Sgreen int i, j; 5276259Sgreen struct group *gr; 5376259Sgreen 5476259Sgreen if (ngroups > 0) 5576259Sgreen ga_free(); 5676259Sgreen 57126274Sdes ngroups = NGROUPS_MAX; 58126274Sdes#if defined(HAVE_SYSCONF) && defined(_SC_NGROUPS_MAX) 59126274Sdes ngroups = MAX(NGROUPS_MAX, sysconf(_SC_NGROUPS_MAX)); 60126274Sdes#endif 61126274Sdes 62162852Sdes groups_bygid = xcalloc(ngroups, sizeof(*groups_bygid)); 63162852Sdes groups_byname = xcalloc(ngroups, sizeof(*groups_byname)); 64126274Sdes 6576259Sgreen if (getgrouplist(user, base, groups_bygid, &ngroups) == -1) 66124208Sdes logit("getgrouplist: groups list too small"); 6776259Sgreen for (i = 0, j = 0; i < ngroups; i++) 6876259Sgreen if ((gr = getgrgid(groups_bygid[i])) != NULL) 6976259Sgreen groups_byname[j++] = xstrdup(gr->gr_name); 70126274Sdes xfree(groups_bygid); 7176259Sgreen return (ngroups = j); 7276259Sgreen} 7376259Sgreen 7492555Sdes/* 7592555Sdes * Return 1 if one of user's groups is contained in groups. 7692555Sdes * Return 0 otherwise. Use match_pattern() for string comparison. 7792555Sdes */ 7876259Sgreenint 7976259Sgreenga_match(char * const *groups, int n) 8076259Sgreen{ 8176259Sgreen int i, j; 8276259Sgreen 8376259Sgreen for (i = 0; i < ngroups; i++) 8476259Sgreen for (j = 0; j < n; j++) 8576259Sgreen if (match_pattern(groups_byname[i], groups[j])) 8676259Sgreen return 1; 8776259Sgreen return 0; 8876259Sgreen} 8976259Sgreen 9092555Sdes/* 9192555Sdes * Free memory allocated for group access list. 9292555Sdes */ 9376259Sgreenvoid 9476259Sgreenga_free(void) 9576259Sgreen{ 9676259Sgreen int i; 9776259Sgreen 9876259Sgreen if (ngroups > 0) { 9976259Sgreen for (i = 0; i < ngroups; i++) 10076259Sgreen xfree(groups_byname[i]); 10176259Sgreen ngroups = 0; 102126274Sdes xfree(groups_byname); 10376259Sgreen } 10476259Sgreen} 105