diff --git a/lib/libpam/modules/pam_group/pam_group.8 b/lib/libpam/modules/pam_group/pam_group.8 index 832841b4c699..985094b1ed24 100644 --- a/lib/libpam/modules/pam_group/pam_group.8 +++ b/lib/libpam/modules/pam_group/pam_group.8 @@ -1,4 +1,5 @@ .\" Copyright (c) 2003 Networks Associates Technology, Inc. +.\" Copyright (c) 2004-2011 Dag-Erling Smørgrav .\" All rights reserved. .\" .\" Portions of this software were developed for the FreeBSD Project by @@ -32,7 +33,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 6, 2003 +.Dd March 9, 2011 .Dt PAM_GROUP 8 .Os .Sh NAME @@ -64,10 +65,23 @@ it does exist and the applicant is a member. Specify the name of the group to check. The default is .Dq Li wheel . +.It Cm luser +Accept or reject based on the target user's group membership. .It Cm root_only Skip this module entirely if the target account is not the superuser account. +.It Cm ruser +Accept or reject based on the supplicant's group membership. +This is the default. .El +.Pp +Note that the +.Cm luser +and +.Cm ruser +options are mutually exclusive, and that +.Nm +will fail if both are specified. .Sh SEE ALSO .Xr pam.conf 5 , .Xr pam 8 diff --git a/lib/libpam/modules/pam_group/pam_group.c b/lib/libpam/modules/pam_group/pam_group.c index a9d5fc32df1c..f09d51829c92 100644 --- a/lib/libpam/modules/pam_group/pam_group.c +++ b/lib/libpam/modules/pam_group/pam_group.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2003 Networks Associates Technology, Inc. + * Copyright (c) 2004-2011 Dag-Erling Smørgrav * All rights reserved. * * Portions of this software were developed for the FreeBSD Project by @@ -56,6 +57,7 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, int argc __unused, const char *argv[] __unused) { + int local, remote; const char *group, *user; const void *ruser; char *const *list; @@ -69,10 +71,24 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags __unused, if (pwd->pw_uid != 0 && openpam_get_option(pamh, "root_only")) return (PAM_IGNORE); - /* get applicant */ - if (pam_get_item(pamh, PAM_RUSER, &ruser) != PAM_SUCCESS - || ruser == NULL || (pwd = getpwnam(ruser)) == NULL) - return (PAM_AUTH_ERR); + /* check local / remote */ + local = openpam_get_option(pamh, "luser") ? 1 : 0; + remote = openpam_get_option(pamh, "ruser") ? 1 : 0; + if (local && remote) { + openpam_log(PAM_LOG_ERROR, + "the luser and ruser options are mutually exclusive"); + return (PAM_SERVICE_ERR); + } else if (local) { + /* we already have the correct struct passwd */ + } else { + if (!remote) + openpam_log(PAM_LOG_NOTICE, + "neither luser nor ruser specified, assuming ruser"); + /* default / historical behavior */ + if (pam_get_item(pamh, PAM_RUSER, &ruser) != PAM_SUCCESS || + ruser == NULL || (pwd = getpwnam(ruser)) == NULL) + return (PAM_AUTH_ERR); + } /* get regulating group */ if ((group = openpam_get_option(pamh, "group")) == NULL)