bin/105341: [PATCH] pam_krb5: Add minimum_uid/minimum_gid options
Shaun Amott
shaun at FreeBSD.org
Thu Nov 9 17:38:19 UTC 2006
>Number: 105341
>Category: bin
>Synopsis: [PATCH] pam_krb5: Add minimum_uid/minimum_gid options
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Thu Nov 09 17:38:13 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator: Shaun Amott
>Release: FreeBSD 6.2-PRERELEASE i386
>Organization:
>Environment:
>Description:
The following patch adds functionality which is apparently present in
the pam_krb5 module of other PAM implementations. Two new options make
it possible to skip over Kerberos authentication for local system
accounts, like so:
auth required pam_krb5.so no_warn minimum_uid=1000
auth required pam_unix.so no_warn try_first_pass
Patch reviewed by ru at .
>How-To-Repeat:
>Fix:
--- pam_krb5.diff begins here ---
Index: pam_krb5.8
===================================================================
RCS file: /home/ncvs/src/lib/libpam/modules/pam_krb5/pam_krb5.8,v
retrieving revision 1.6
diff -u -r1.6 pam_krb5.8
--- pam_krb5.8 24 Nov 2001 23:41:32 -0000 1.6
+++ pam_krb5.8 9 Nov 2006 15:32:28 -0000
@@ -1,7 +1,7 @@
.\"
.\" $Id: pam_krb5.5,v 1.5 2000/01/05 00:59:56 fcusack Exp $
.\" $FreeBSD: src/lib/libpam/modules/pam_krb5/pam_krb5.8,v 1.6 2001/11/24 23:41:32 dd Exp $
-.Dd January 15, 1999
+.Dd November 09, 2006
.Dt PAM_KRB5 8
.Os
.Sh NAME
@@ -108,6 +108,13 @@
.Ql %p ,
to designate the current process ID; can be used in
.Ar name .
+.It Cm minimum_uid Ns = Ns Ar id
+Do not attempt to authenticate users with a UID below
+.Ar id .
+Instead, simply return; thus allowing a later module to authenticate
+the user.
+.It Cm minimum_gid Ns = Ns Ar id
+As above, but specifies a minimum primary GID.
.El
.Ss Kerberos 5 Account Management Module
The Kerberos 5 account management component
Index: pam_krb5.c
===================================================================
RCS file: /home/ncvs/src/lib/libpam/modules/pam_krb5/pam_krb5.c,v
retrieving revision 1.23
diff -u -r1.23 pam_krb5.c
--- pam_krb5.c 7 Jul 2005 14:16:38 -0000 1.23
+++ pam_krb5.c 9 Nov 2006 15:32:29 -0000
@@ -88,6 +88,8 @@
#define PAM_OPT_CCACHE "ccache"
#define PAM_OPT_DEBUG "debug"
#define PAM_OPT_FORWARDABLE "forwardable"
+#define PAM_OPT_MINIMUM_GID "minimum_gid"
+#define PAM_OPT_MINIMUM_UID "minimum_uid"
#define PAM_OPT_NO_CCACHE "no_ccache"
#define PAM_OPT_REUSE_CCACHE "reuse_ccache"
@@ -110,6 +112,9 @@
const char *user, *pass;
const void *sourceuser, *service;
char *principal, *princ_name, *ccache_name, luser[32], *srvdup;
+ const char *retstr;
+ uid_t minuid;
+ gid_t mingid;
retval = pam_get_user(pamh, &user, USER_PROMPT);
if (retval != PAM_SUCCESS)
@@ -222,6 +227,47 @@
PAM_LOG("Done getpwnam()");
+ retstr = openpam_get_option(pamh, PAM_OPT_MINIMUM_UID);
+ if (retstr != NULL) {
+ unsigned long val;
+ val = strtoul(retstr, NULL, 10);
+ if ((val == ULONG_MAX && errno == ERANGE) ||
+ (val == 0 && errno == EINVAL)) {
+ PAM_LOG("Error in minimum_uid: %s",
+ strerror(errno));
+ return (PAM_SERVICE_ERR);
+ } else if (val > UID_MAX) {
+ PAM_LOG("Error in minimum_uid: invalid UID");
+ return (PAM_SERVICE_ERR);
+ } else {
+ minuid = (uid_t)val;
+ }
+ } else
+ minuid = 0;
+
+ retstr = openpam_get_option(pamh, PAM_OPT_MINIMUM_GID);
+ if (retstr != NULL) {
+ unsigned long val;
+ val = strtoul(retstr, NULL, 10);
+ if ((val == ULONG_MAX && errno == ERANGE) ||
+ (val == 0 && errno == EINVAL)) {
+ PAM_LOG("Error in minimum_gid: %s",
+ strerror(errno));
+ return (PAM_SERVICE_ERR);
+ } else if (val > GID_MAX) {
+ PAM_LOG("Error in minimum_gid: invalid GID");
+ return (PAM_SERVICE_ERR);
+ } else {
+ mingid = (gid_t)val;
+ }
+ } else
+ mingid = 0;
+
+ if (pwd->pw_uid < minuid || pwd->pw_gid < mingid)
+ return (PAM_IGNORE);
+
+ PAM_LOG("Checked uid and gid bounds");
+
/* Get a TGT */
memset(&creds, 0, sizeof(krb5_creds));
krbret = krb5_get_init_creds_password(pam_context, &creds, princ,
@@ -349,6 +395,9 @@
const void *user;
void *cache_data;
char *cache_name_buf = NULL, *p;
+ const char *retstr;
+ uid_t minuid;
+ gid_t mingid;
uid_t euid;
gid_t egid;
@@ -391,6 +440,56 @@
PAM_LOG("Got euid, egid: %d %d", euid, egid);
+ /* Get the uid. This should exist. */
+ pwd = getpwnam(user);
+ if (pwd == NULL) {
+ retval = PAM_USER_UNKNOWN;
+ goto cleanup3;
+ }
+
+ PAM_LOG("Done getpwnam()");
+
+ retstr = openpam_get_option(pamh, PAM_OPT_MINIMUM_UID);
+ if (retstr != NULL) {
+ unsigned long val;
+ val = strtoul(retstr, NULL, 10);
+ if ((val == ULONG_MAX && errno == ERANGE) ||
+ (val == 0 && errno == EINVAL)) {
+ PAM_LOG("Error in minimum_uid: %s",
+ strerror(errno));
+ return (PAM_SERVICE_ERR);
+ } else if (val > UID_MAX) {
+ PAM_LOG("Error in minimum_uid: invalid UID");
+ return (PAM_SERVICE_ERR);
+ } else {
+ minuid = (uid_t)val;
+ }
+ } else
+ minuid = 0;
+
+ retstr = openpam_get_option(pamh, PAM_OPT_MINIMUM_GID);
+ if (retstr != NULL) {
+ unsigned long val;
+ val = strtoul(retstr, NULL, 10);
+ if ((val == ULONG_MAX && errno == ERANGE) ||
+ (val == 0 && errno == EINVAL)) {
+ PAM_LOG("Error in minimum_gid: %s",
+ strerror(errno));
+ return (PAM_SERVICE_ERR);
+ } else if (val > GID_MAX) {
+ PAM_LOG("Error in minimum_gid: invalid GID");
+ return (PAM_SERVICE_ERR);
+ } else {
+ mingid = (gid_t)val;
+ }
+ } else
+ mingid = 0;
+
+ if (pwd->pw_uid < minuid || pwd->pw_gid < mingid)
+ return (PAM_IGNORE);
+
+ PAM_LOG("Checked uid and gid bounds");
+
/* Retrieve the temporary cache */
retval = pam_get_data(pamh, "ccache", &cache_data);
if (retval != PAM_SUCCESS) {
@@ -405,15 +504,6 @@
goto cleanup3;
}
- /* Get the uid. This should exist. */
- pwd = getpwnam(user);
- if (pwd == NULL) {
- retval = PAM_USER_UNKNOWN;
- goto cleanup3;
- }
-
- PAM_LOG("Done getpwnam()");
-
/* Avoid following a symlink as root */
if (setegid(pwd->pw_gid)) {
retval = PAM_SERVICE_ERR;
--- pam_krb5.diff ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list