RFC: pam_krb5: minimum_[ug]id options

Ruslan Ermilov ru at FreeBSD.org
Wed Nov 8 22:11:21 UTC 2006


On Wed, Nov 08, 2006 at 09:28:30PM +0000, Shaun Amott wrote:
> While fiddling with PAM, it came to my attention that the pam_krb5
> module in some other (Linux?) PAM implementations supports, amongst
> other things, a minimum_uid option. This makes 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
> 
> I think it'd a nice addition to our pam_krb5 at least.
> 
> I've attached an initial patch. Comments/review welcome.
> 
OK.

> 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	8 Nov 2006 20:50:35 -0000
> @@ -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
                                               ^^^ UID
> +.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 group.
                                     ^^^^^ "group ID" or GID

Also, it could be explicit about this being a primary GID.

>  .El
>  .Ss Kerberos 5 Account Management Module
>  The Kerberos 5 account management component
> 
Document date should be bumped (the .Dd macro).

> 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	8 Nov 2006 20:50:36 -0000
> @@ -90,6 +90,8 @@
>  #define PAM_OPT_FORWARDABLE	"forwardable"
>  #define PAM_OPT_NO_CCACHE	"no_ccache"
>  #define PAM_OPT_REUSE_CCACHE	"reuse_ccache"
> +#define PAM_OPT_MINIMUM_UID	"minimum_uid"
> +#define PAM_OPT_MINIMUM_GID	"minimum_gid"
>  
Defines were sorted alphabetically by a defined name.

>  /*
>   * authentication management
> @@ -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 = 0;
> +	gid_t mingid = 0;
>  
>  	retval = pam_get_user(pamh, &user, USER_PROMPT);
>  	if (retval != PAM_SUCCESS)
> @@ -222,6 +227,21 @@
>  
>  	PAM_LOG("Done getpwnam()");
>  
> +	retstr = openpam_get_option(pamh, PAM_OPT_MINIMUM_UID);
> +
Extraneous empty line.

> +	if (retstr)
                  ^ missing "!= NULL"

> +		minuid = (uid_t)strtoul(retstr, NULL, 10);
> 
Errors are silently ignored; limit (UID_MAX) isn't checked.

> +
> +	retstr = openpam_get_option(pamh, PAM_OPT_MINIMUM_GID);
> +
> +	if (retstr)
> +		mingid = (gid_t)strtoul(retstr, NULL, 10);
> +
> 
Ditto but s/UID_MAX/GID_MAX/.

> +	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 +369,9 @@
>  	const void *user;
>  	void *cache_data;
>  	char *cache_name_buf = NULL, *p;
> +	const char *retstr;
> +	uid_t minuid = 0;
> +	gid_t mingid = 0;
>  
>  	uid_t euid;
>  	gid_t egid;
> @@ -391,6 +414,30 @@
>  
>  	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)
> +		minuid = (uid_t)strtoul(retstr, NULL, 10);
> +
> +	retstr = openpam_get_option(pamh, PAM_OPT_MINIMUM_GID);
> +
> +	if (retstr)
> +		mingid = (gid_t)strtoul(retstr, NULL, 10);
> +
> +	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 +452,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;


Cheers,
-- 
Ruslan Ermilov
ru at FreeBSD.org
FreeBSD committer
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20061108/7a15b99a/attachment.pgp


More information about the freebsd-hackers mailing list