summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compat/pam_compat.h13
-rw-r--r--configure.ac2
-rw-r--r--debian/libpam-ldapd.pam-auth-update12
-rw-r--r--man/pam_ldap.8.xml13
-rw-r--r--pam/pam.c60
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>
diff --git a/pam/pam.c b/pam/pam.c
index 855f9ef..b09eb24 100644
--- a/pam/pam.c
+++ b/pam/pam.c
@@ -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)