diff options
-rw-r--r-- | compat/pam_compat.h | 13 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | debian/libpam-ldapd.pam-auth-update | 12 | ||||
-rw-r--r-- | man/pam_ldap.8.xml | 13 | ||||
-rw-r--r-- | pam/pam.c | 60 |
5 files changed, 84 insertions, 16 deletions
diff --git a/compat/pam_compat.h b/compat/pam_compat.h index 5967638..c453061 100644 --- a/compat/pam_compat.h +++ b/compat/pam_compat.h @@ -1,7 +1,7 @@ /* pam_compat.h - provide a replacement definitions for some pam functions - Copyright (C) 2009 Arthur de Jong + Copyright (C) 2009, 2010 Arthur de Jong This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -33,9 +33,20 @@ #else /* not HAVE_PAM_PAM_MODULES_H */ #include <pam/pam_modules.h> #endif /* not HAVE_PAM_PAM_MODULES_H */ +#ifdef HAVE_SECURITY_PAM_MODUTIL_H +#include <security/pam_modutil.h> +#endif /* HAVE_SECURITY_PAM_MODUTIL_H */ +/* define our own replacement pam_get_authtok() if it wasn't found */ #ifndef HAVE_PAM_GET_AUTHTOK int pam_get_authtok(pam_handle_t *pamh,int item,const char **authtok,const char *prompt); #endif /* HAVE_PAM_GET_AUTHTOK */ +/* fall back to using getpwnam() if pam_modutil_getpwnam() isn't defined */ +#ifndef HAVE_PAM_MODUTIL_GETGWNAM +#include <sys/types.h> +#include <pwd.h> +#define pam_modutil_getpwnam(pamh,user) getpwnam(user) +#endif /* not HAVE_PAM_MODUTIL_GETGWNAM */ + #endif /* _COMPAT_LDAP_COMPAT_H */ diff --git a/configure.ac b/configure.ac index 496b71f..cf8e8f6 100644 --- a/configure.ac +++ b/configure.ac @@ -225,6 +225,7 @@ then ]) AC_CHECK_HEADERS(pam/pam_modules.h) AC_CHECK_HEADERS(security/pam_ext.h) + AC_CHECK_HEADERS(security/pam_modutil.h) # at least one of security/pam_modules.h or pam/pam_modules.h is required if test "x$ac_cv_header_security_pam_modules_h" != "xyes" && \ test "x$ac_cv_header_pam_pam_modules_h" != "xyes" @@ -309,6 +310,7 @@ then AC_SEARCH_LIBS(pam_get_data,pam,,AC_MSG_ERROR(no PAM library available)) # replace the pam_get_authtok() function if it's unavailable AC_REPLACE_FUNCS(pam_get_authtok) + AC_CHECK_FUNCS(pam_modutil_getpwnam) # restore CFLAGS and LIBS CFLAGS="$save_CFLAGS" LIBS="$save_LIBS" diff --git a/debian/libpam-ldapd.pam-auth-update b/debian/libpam-ldapd.pam-auth-update index 8e79226..d893688 100644 --- a/debian/libpam-ldapd.pam-auth-update +++ b/debian/libpam-ldapd.pam-auth-update @@ -3,17 +3,17 @@ Default: yes Priority: 128 Auth-Type: Primary Auth-Initial: - [success=end default=ignore] pam_ldap.so + [success=end default=ignore] pam_ldap.so minimum_uid=1000 Auth: - [success=end default=ignore] pam_ldap.so use_first_pass + [success=end default=ignore] pam_ldap.so minimum_uid=1000 use_first_pass Account-Type: Primary Account: - [success=end default=ignore] pam_ldap.so + [success=end default=ignore] pam_ldap.so minimum_uid=1000 Password-Type: Primary Password-Initial: - [success=end default=ignore] pam_ldap.so + [success=end default=ignore] pam_ldap.so minimum_uid=1000 Password: - [success=end default=ignore] pam_ldap.so try_first_pass + [success=end default=ignore] pam_ldap.so minimum_uid=1000 try_first_pass Session-Type: Additional Session: - optional pam_ldap.so + optional pam_ldap.so minimum_uid=1000 diff --git a/man/pam_ldap.8.xml b/man/pam_ldap.8.xml index 2673284..1fe075c 100644 --- a/man/pam_ldap.8.xml +++ b/man/pam_ldap.8.xml @@ -147,6 +147,19 @@ </para> </listitem> </varlistentry> + <varlistentry> + <term> + <option>minimum_uid=<emphasis remap="I">UID</emphasis></option> + </term> + <listitem> + <para> + This option causes the <acronym>PAM</acronym> module to ignore the user + if the user id is lower than the specified value. This can be used to + only authenticate normal users (non-system users) using + <acronym>LDAP</acronym> (e.g. by setting it to 1000). + </para> + </listitem> + </varlistentry> </variablelist> </refsect1> @@ -254,6 +254,8 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,const char **argv) int first_pass=0,ignore_flags=0; int i; pld_ctx *ctx; + uid_t minimum_uid=0; + struct passwd *pwd; /* go over arguments */ for (i=0;i<argc;i++) { @@ -269,6 +271,8 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,const char **argv) /* ignore */; else if (strcmp(argv[i],"debug")==0) /* ignore */; + else if (strncmp(argv[i], "minimum_uid=", 12) == 0) + minimum_uid=(uid_t)atoi(argv[i]+12); else syslog(LOG_AUTHPRIV|LOG_ERR,"unknown option: %s",argv[i]); } @@ -276,6 +280,15 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,const char **argv) rc=pam_get_user(pamh,(const char **)&username,NULL); if (rc!=PAM_SUCCESS) return rc; + if ((username==NULL)||(username[0]=='\0')) + return PAM_USER_UNKNOWN; + /* check uid */ + if (minimum_uid>0) + { + pwd=pam_modutil_getpwnam(args->pamh,username); + if ((pwd!=NULL)&&(pwd->pw_uid<minimum_uid)) + return ignore_flags&IGNORE_UNKNOWN?PAM_IGNORE:PAM_USER_UNKNOWN; + } /* get our context */ rc=ctx_get(pamh,username,&ctx); if (rc!=PAM_SUCCESS) @@ -386,7 +399,9 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc,const char **argv) int i; struct pam_conv *appconv; pld_ctx *ctx=NULL, ctx2; - + uid_t minimum_uid=0; + struct passwd *pwent; + /* go over arguments */ for (i=0;i<argc;i++) { if (strcmp(argv[i],"use_first_pass")==0) @@ -401,6 +416,8 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc,const char **argv) ignore_flags|=IGNORE_UNAVAIL; else if (strcmp(argv[i],"debug")==0) ; + else if (strncmp(argv[i], "minimum_uid=", 12) == 0) + minimum_uid=(uid_t)atoi(argv[i]+12); else syslog(LOG_AUTHPRIV|LOG_ERR,"unknown option: %s",argv[i]); } @@ -411,13 +428,19 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc,const char **argv) rc=pam_get_item(pamh,PAM_CONV,(const void **)&appconv); if (rc!=PAM_SUCCESS) return rc; - + /* get user name */ rc=pam_get_user(pamh,(const char **)&username,NULL); if (rc!=PAM_SUCCESS) return rc; - if ((username==NULL)||(username[0]=='\0')) return PAM_USER_UNKNOWN; + /* check uid */ + if (minimum_uid>0) + { + pwent=pam_modutil_getpwnam(args->pamh,username); + if ((pwent!=NULL)&&(pwent->pw_uid<minimum_uid)) + return ignore_flags&IGNORE_UNKNOWN?PAM_IGNORE:PAM_USER_UNKNOWN; + } rc=ctx_get(pamh,username,&ctx); if (rc!=PAM_SUCCESS) @@ -500,7 +523,9 @@ static int pam_sm_session( int i; pld_ctx *ctx=NULL; const char *service=NULL,*tty=NULL,*rhost=NULL,*ruser=NULL; - + uid_t minimum_uid=0; + struct passwd *pwent; + /* go over arguments */ for (i=0;i<argc;i++) { if (strcmp(argv[i],"use_first_pass")==0) @@ -515,19 +540,27 @@ static int pam_sm_session( ignore_flags|=IGNORE_UNAVAIL; else if (strcmp(argv[i],"debug")==0) ; + else if (strncmp(argv[i], "minimum_uid=", 12) == 0) + minimum_uid=(uid_t)atoi(argv[i]+12); else syslog(LOG_AUTHPRIV|LOG_ERR,"unknown option: %s",argv[i]); } if (flags & PAM_SILENT) *no_warn=1; - + /* get user name */ rc=pam_get_user(pamh,(const char **)&username,NULL); if (rc!=PAM_SUCCESS) return rc; - if ((username==NULL)||(username[0]=='\0')) return PAM_USER_UNKNOWN; + /* check uid */ + if (minimum_uid>0) + { + pwent=pam_modutil_getpwnam(args->pamh,username); + if ((pwent!=NULL)&&(pwent->pw_uid<minimum_uid)) + return ignore_flags&IGNORE_UNKNOWN?PAM_IGNORE:PAM_USER_UNKNOWN; + } rc=ctx_get(pamh,username,&ctx); if (rc!=PAM_SUCCESS) @@ -638,6 +671,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv) int i; struct pam_conv *appconv; pld_ctx *ctx=NULL; + uid_t minimum_uid=0; struct passwd *pwent; /* parse module options */ for (i=0;i<argc;i++) @@ -656,6 +690,8 @@ int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv) ignore_flags|=IGNORE_UNAVAIL; else if (strcmp(argv[i],"debug")==0) ; + else if (strncmp(argv[i], "minimum_uid=", 12) == 0) + minimum_uid=(uid_t)atoi(argv[i]+12); else syslog(LOG_AUTHPRIV|LOG_ERR,"unknown option: %s",argv[i]); } @@ -666,13 +702,19 @@ int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv) rc=pam_get_item(pamh,PAM_CONV,(const void **)&appconv); if (rc!=PAM_SUCCESS) return rc; - + /* get user name */ rc=pam_get_user(pamh,(const char **)&username,NULL); if (rc!=PAM_SUCCESS) return rc; - - if (username==NULL) + if ((username==NULL)||(username[0]=='\0')) return PAM_USER_UNKNOWN; + /* check uid */ + if (minimum_uid>0) + { + pwent=pam_modutil_getpwnam(args->pamh,username); + if ((pwent!=NULL)&&(pwent->pw_uid<minimum_uid)) + return ignore_flags&IGNORE_UNKNOWN?PAM_IGNORE:PAM_USER_UNKNOWN; + } rc=ctx_get(pamh,username,&ctx); if (rc!=PAM_SUCCESS) |