pam_group.c revision 219564
1110453Sdes/*- 2110453Sdes * Copyright (c) 2003 Networks Associates Technology, Inc. 3219563Sdes * Copyright (c) 2004-2011 Dag-Erling Sm��rgrav 4110453Sdes * All rights reserved. 5110453Sdes * 6110453Sdes * Portions of this software were developed for the FreeBSD Project by 7110453Sdes * ThinkSec AS and NAI Labs, the Security Research Division of Network 8110453Sdes * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 9110453Sdes * ("CBOSS"), as part of the DARPA CHATS research program. 10110453Sdes * 11110453Sdes * Redistribution and use in source and binary forms, with or without 12110453Sdes * modification, are permitted provided that the following conditions 13110453Sdes * are met: 14110453Sdes * 1. Redistributions of source code must retain the above copyright 15110453Sdes * notice, this list of conditions and the following disclaimer. 16110453Sdes * 2. Redistributions in binary form must reproduce the above copyright 17110453Sdes * notice, this list of conditions and the following disclaimer in the 18110453Sdes * documentation and/or other materials provided with the distribution. 19110453Sdes * 3. The name of the author may not be used to endorse or promote 20110453Sdes * products derived from this software without specific prior written 21110453Sdes * permission. 22110453Sdes * 23110453Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 24110453Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25110453Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26110453Sdes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 27110453Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28110453Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29110453Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30110453Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31110453Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32110453Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33110453Sdes * SUCH DAMAGE. 34110453Sdes */ 35110453Sdes 36110453Sdes#include <sys/cdefs.h> 37110453Sdes__FBSDID("$FreeBSD: head/lib/libpam/modules/pam_group/pam_group.c 219564 2011-03-12 11:26:37Z des $"); 38110453Sdes 39110453Sdes#include <sys/types.h> 40110453Sdes 41110453Sdes#include <grp.h> 42110453Sdes#include <pwd.h> 43110453Sdes#include <stdarg.h> 44110453Sdes#include <stdio.h> 45110453Sdes#include <string.h> 46110453Sdes#include <syslog.h> 47110453Sdes#include <unistd.h> 48110453Sdes 49110453Sdes#define PAM_SM_AUTH 50110453Sdes 51110453Sdes#include <security/pam_appl.h> 52110453Sdes#include <security/pam_modules.h> 53110453Sdes#include <security/openpam.h> 54110453Sdes 55110453Sdes 56110453SdesPAM_EXTERN int 57110453Sdespam_sm_authenticate(pam_handle_t *pamh, int flags __unused, 58110453Sdes int argc __unused, const char *argv[] __unused) 59110453Sdes{ 60219563Sdes int local, remote; 61123448Sdes const char *group, *user; 62123448Sdes const void *ruser; 63110453Sdes char *const *list; 64110453Sdes struct passwd *pwd; 65110453Sdes struct group *grp; 66110453Sdes 67110453Sdes /* get target account */ 68110653Sdes if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || 69110653Sdes user == NULL || (pwd = getpwnam(user)) == NULL) 70110453Sdes return (PAM_AUTH_ERR); 71110453Sdes if (pwd->pw_uid != 0 && openpam_get_option(pamh, "root_only")) 72110453Sdes return (PAM_IGNORE); 73110453Sdes 74219563Sdes /* check local / remote */ 75219563Sdes local = openpam_get_option(pamh, "luser") ? 1 : 0; 76219563Sdes remote = openpam_get_option(pamh, "ruser") ? 1 : 0; 77219563Sdes if (local && remote) { 78219564Sdes openpam_log(PAM_LOG_ERROR, "(pam_group) " 79219563Sdes "the luser and ruser options are mutually exclusive"); 80219563Sdes return (PAM_SERVICE_ERR); 81219563Sdes } else if (local) { 82219563Sdes /* we already have the correct struct passwd */ 83219563Sdes } else { 84219563Sdes if (!remote) 85219564Sdes openpam_log(PAM_LOG_NOTICE, "(pam_group) " 86219563Sdes "neither luser nor ruser specified, assuming ruser"); 87219563Sdes /* default / historical behavior */ 88219563Sdes if (pam_get_item(pamh, PAM_RUSER, &ruser) != PAM_SUCCESS || 89219563Sdes ruser == NULL || (pwd = getpwnam(ruser)) == NULL) 90219563Sdes return (PAM_AUTH_ERR); 91219563Sdes } 92110453Sdes 93110453Sdes /* get regulating group */ 94110453Sdes if ((group = openpam_get_option(pamh, "group")) == NULL) 95110453Sdes group = "wheel"; 96110453Sdes if ((grp = getgrnam(group)) == NULL || grp->gr_mem == NULL) 97110453Sdes goto failed; 98110453Sdes 99110453Sdes /* check if the group is empty */ 100110453Sdes if (*grp->gr_mem == NULL) 101110453Sdes goto failed; 102110453Sdes 103110453Sdes /* check membership */ 104110453Sdes if (pwd->pw_gid == grp->gr_gid) 105110453Sdes goto found; 106110453Sdes for (list = grp->gr_mem; *list != NULL; ++list) 107110453Sdes if (strcmp(*list, pwd->pw_name) == 0) 108110453Sdes goto found; 109110453Sdes 110110453Sdes not_found: 111110453Sdes if (openpam_get_option(pamh, "deny")) 112110453Sdes return (PAM_SUCCESS); 113110453Sdes return (PAM_AUTH_ERR); 114110453Sdes found: 115110453Sdes if (openpam_get_option(pamh, "deny")) 116110453Sdes return (PAM_AUTH_ERR); 117110453Sdes return (PAM_SUCCESS); 118110453Sdes failed: 119110453Sdes if (openpam_get_option(pamh, "fail_safe")) 120110453Sdes goto found; 121110453Sdes else 122110453Sdes goto not_found; 123110453Sdes} 124110453Sdes 125110453SdesPAM_EXTERN int 126110453Sdespam_sm_setcred(pam_handle_t * pamh __unused, int flags __unused, 127110453Sdes int argc __unused, const char *argv[] __unused) 128110453Sdes{ 129110453Sdes 130110453Sdes return (PAM_SUCCESS); 131110453Sdes} 132110453Sdes 133110453SdesPAM_MODULE_ENTRY("pam_group"); 134