nss-pam-ldapd commit: r1206 - in nss-pam-ldapd: man nslcd pam
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
nss-pam-ldapd commit: r1206 - in nss-pam-ldapd: man nslcd pam
- From: Commits of the nss-pam-ldapd project <nss-pam-ldapd-commits [at] lists.arthurdejong.org>
- To: nss-pam-ldapd-commits [at] lists.arthurdejong.org
- Reply-to: nss-pam-ldapd-users [at] lists.arthurdejong.org
- Subject: nss-pam-ldapd commit: r1206 - in nss-pam-ldapd: man nslcd pam
- Date: Sun, 5 Sep 2010 11:30:45 +0200 (CEST)
Author: arthur
Date: Sun Sep 5 11:30:44 2010
New Revision: 1206
URL: http://arthurdejong.org/viewvc/nss-pam-ldapd?view=rev&revision=1206
Log:
implement a rootpwmodpw option that allows root users to change user passwords
without a password prompt
Modified:
nss-pam-ldapd/man/nslcd.conf.5.xml
nss-pam-ldapd/nslcd/cfg.c
nss-pam-ldapd/nslcd/cfg.h
nss-pam-ldapd/nslcd/common.h
nss-pam-ldapd/nslcd/nslcd.c
nss-pam-ldapd/nslcd/pam.c
nss-pam-ldapd/pam/pam.c
Modified: nss-pam-ldapd/man/nslcd.conf.5.xml
==============================================================================
--- nss-pam-ldapd/man/nslcd.conf.5.xml Sat Aug 28 21:46:37 2010 (r1205)
+++ nss-pam-ldapd/man/nslcd.conf.5.xml Sun Sep 5 11:30:44 2010 (r1206)
@@ -192,8 +192,24 @@
<listitem>
<para>
Specifies the distinguished name to use when the root user tries to
- modify a user's password using the PAM module. The PAM module prompts
- the user for the admin password instead of the user's password.
+ modify a user's password using the PAM module.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>rootpwmodpw</option>
<replaceable>PASSWORD</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the clear text credentials with which to bind if the root
+ user tries to change a user's password.
+ This option is only applicable when used with
+ <option>rootpwmoddn</option> above.
+ If this option is not specified the PAM module prompts the user for
+ this password.
+ If you set this option you should consider changing the permissions
+ of the <filename>nslcd.conf</filename> file to only grant access to
+ the root user.
</para>
</listitem>
</varlistentry>
Modified: nss-pam-ldapd/nslcd/cfg.c
==============================================================================
--- nss-pam-ldapd/nslcd/cfg.c Sat Aug 28 21:46:37 2010 (r1205)
+++ nss-pam-ldapd/nslcd/cfg.c Sun Sep 5 11:30:44 2010 (r1206)
@@ -97,6 +97,7 @@
cfg->ldc_binddn=NULL;
cfg->ldc_bindpw=NULL;
cfg->ldc_rootpwmoddn=NULL;
+ cfg->ldc_rootpwmodpw=NULL;
cfg->ldc_sasl_mech=NULL;
cfg->ldc_sasl_realm=NULL;
cfg->ldc_sasl_authcid=NULL;
@@ -377,6 +378,28 @@
}
}
+/* check that the file is not world readable */
+static void check_permissions(const char *filename,const char *keyword)
+{
+ struct stat sb;
+ /* get file status */
+ if (stat(filename,&sb))
+ {
+ log_log(LOG_ERR,"cannot stat() %s: %s",filename,strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ /* check permissions */
+ if ((sb.st_mode&0007)!=0)
+ {
+ if (keyword!=NULL)
+ log_log(LOG_ERR,"%s: file should not be world readable if %s is set",
+ filename, keyword);
+ else
+ log_log(LOG_ERR,"%s: file should not be world readable",filename);
+ exit(EXIT_FAILURE);
+ }
+}
+
static void get_int(const char *filename,int lnr,
const char *keyword,char **line,
int *var)
@@ -811,12 +834,18 @@
}
else if (strcasecmp(keyword,"bindpw")==0)
{
+ check_permissions(filename,keyword);
get_restdup(filename,lnr,keyword,&line,&cfg->ldc_bindpw);
}
else if (strcasecmp(keyword,"rootpwmoddn")==0)
{
get_restdup(filename,lnr,keyword,&line,&cfg->ldc_rootpwmoddn);
}
+ else if (strcasecmp(keyword,"rootpwmodpw")==0)
+ {
+ check_permissions(filename,keyword);
+ get_restdup(filename,lnr,keyword,&line,&cfg->ldc_rootpwmodpw);
+ }
/* SASL authentication options */
else if (strcasecmp(keyword,"use_sasl")==0)
{
@@ -1055,6 +1084,8 @@
exit(EXIT_FAILURE);
}
}
+ /* check permissions */
+ check_permissions(filename,NULL);
/* read the first line */
if (fgets(linebuf,sizeof(linebuf),fp)==NULL)
{
@@ -1062,8 +1093,6 @@
exit(EXIT_FAILURE);
}
/* chop the last char off and save the rest as bindpw */
- i=strlen(linebuf);
-
i=(int)strlen(linebuf);
if ((i<=0)||(linebuf[i-1]!='\n'))
{
Modified: nss-pam-ldapd/nslcd/cfg.h
==============================================================================
--- nss-pam-ldapd/nslcd/cfg.h Sat Aug 28 21:46:37 2010 (r1205)
+++ nss-pam-ldapd/nslcd/cfg.h Sun Sep 5 11:30:44 2010 (r1206)
@@ -95,6 +95,8 @@
char *ldc_bindpw;
/* bind DN for password modification by administrator */
char *ldc_rootpwmoddn;
+ /* bind password for password modification by root */
+ char *ldc_rootpwmodpw;
/* sasl mech */
char *ldc_sasl_mech;
/* sasl realm */
Modified: nss-pam-ldapd/nslcd/common.h
==============================================================================
--- nss-pam-ldapd/nslcd/common.h Sat Aug 28 21:46:37 2010 (r1205)
+++ nss-pam-ldapd/nslcd/common.h Sun Sep 5 11:30:44 2010 (r1206)
@@ -140,11 +140,11 @@
int nslcd_service_all(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_shadow_byname(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_shadow_all(TFILE *fp,MYLDAP_SESSION *session);
-int nslcd_pam_authc(TFILE *fp,MYLDAP_SESSION *session);
+int nslcd_pam_authc(TFILE *fp,MYLDAP_SESSION *session,uid_t calleruid);
int nslcd_pam_authz(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_pam_sess_o(TFILE *fp,MYLDAP_SESSION *session);
int nslcd_pam_sess_c(TFILE *fp,MYLDAP_SESSION *session);
-int nslcd_pam_pwmod(TFILE *fp,MYLDAP_SESSION *session);
+int nslcd_pam_pwmod(TFILE *fp,MYLDAP_SESSION *session,uid_t calleruid);
/* macros for generating service handling code */
#define NSLCD_HANDLE(db,fn,readfn,logcall,action,mkfilter,writefn) \
Modified: nss-pam-ldapd/nslcd/nslcd.c
==============================================================================
--- nss-pam-ldapd/nslcd/nslcd.c Sat Aug 28 21:46:37 2010 (r1205)
+++ nss-pam-ldapd/nslcd/nslcd.c Sun Sep 5 11:30:44 2010 (r1206)
@@ -421,12 +421,11 @@
case NSLCD_ACTION_SERVICE_ALL: (void)nslcd_service_all(fp,session);
break;
case NSLCD_ACTION_SHADOW_BYNAME: if (uid==0)
(void)nslcd_shadow_byname(fp,session); break;
case NSLCD_ACTION_SHADOW_ALL: if (uid==0)
(void)nslcd_shadow_all(fp,session); break;
- case NSLCD_ACTION_PAM_AUTHC: (void)nslcd_pam_authc(fp,session);
break;
+ case NSLCD_ACTION_PAM_AUTHC: (void)nslcd_pam_authc(fp,session,uid);
break;
case NSLCD_ACTION_PAM_AUTHZ: (void)nslcd_pam_authz(fp,session);
break;
case NSLCD_ACTION_PAM_SESS_O: (void)nslcd_pam_sess_o(fp,session);
break;
case NSLCD_ACTION_PAM_SESS_C: (void)nslcd_pam_sess_c(fp,session);
break;
- case NSLCD_ACTION_PAM_PWMOD: (void)nslcd_pam_pwmod(fp,session);
break;
- /* TODO: maybe only do pwmod for (suid) root users */
+ case NSLCD_ACTION_PAM_PWMOD: (void)nslcd_pam_pwmod(fp,session,uid);
break;
default:
log_log(LOG_WARNING,"invalid request id: %d",(int)action);
break;
Modified: nss-pam-ldapd/nslcd/pam.c
==============================================================================
--- nss-pam-ldapd/nslcd/pam.c Sat Aug 28 21:46:37 2010 (r1205)
+++ nss-pam-ldapd/nslcd/pam.c Sun Sep 5 11:30:44 2010 (r1206)
@@ -129,7 +129,7 @@
}
/* check authentication credentials of the user */
-int nslcd_pam_authc(TFILE *fp,MYLDAP_SESSION *session)
+int nslcd_pam_authc(TFILE *fp,MYLDAP_SESSION *session,uid_t calleruid)
{
int32_t tmpint32;
int rc;
@@ -158,6 +158,16 @@
return -1;
}
strcpy(userdn,nslcd_cfg->ldc_rootpwmoddn);
+ /* if the caller is root we will allow the use of the rootpwmodpw option */
+ if ((*password=='\0')&&(calleruid==0)&&(nslcd_cfg->ldc_rootpwmodpw!=NULL))
+ {
+ if (strlen(nslcd_cfg->ldc_rootpwmodpw)>=sizeof(password))
+ {
+ log_log(LOG_ERR,"nslcd_pam_authc(): rootpwmodpw will not fit in
password");
+ return -1;
+ }
+ strcpy(password,nslcd_cfg->ldc_rootpwmodpw);
+ }
}
else if
(validate_user(session,userdn,sizeof(userdn),username,sizeof(username)))
{
@@ -423,7 +433,7 @@
return rc;
}
-int nslcd_pam_pwmod(TFILE *fp,MYLDAP_SESSION *session)
+int nslcd_pam_pwmod(TFILE *fp,MYLDAP_SESSION *session,uid_t calleruid)
{
int32_t tmpint32;
char username[256];
@@ -451,6 +461,16 @@
{
binddn=nslcd_cfg->ldc_rootpwmoddn;
userdn[0]='\0'; /* cause validate_user() to get the user DN */
+ /* check if rootpwmodpw should be used */
+ if
((*oldpassword=='\0')&&(calleruid==0)&&(nslcd_cfg->ldc_rootpwmodpw!=NULL))
+ {
+ if (strlen(nslcd_cfg->ldc_rootpwmodpw)>=sizeof(oldpassword))
+ {
+ log_log(LOG_ERR,"nslcd_pam_pwmod(): rootpwmodpw will not fit in
oldpassword");
+ return -1;
+ }
+ strcpy(oldpassword,nslcd_cfg->ldc_rootpwmodpw);
+ }
}
/* validate request and fill in the blanks */
if (validate_user(session,userdn,sizeof(userdn),username,sizeof(username)))
Modified: nss-pam-ldapd/pam/pam.c
==============================================================================
--- nss-pam-ldapd/pam/pam.c Sat Aug 28 21:46:37 2010 (r1205)
+++ nss-pam-ldapd/pam/pam.c Sun Sep 5 11:30:44 2010 (r1206)
@@ -513,6 +513,7 @@
const char *username,*service;
const char *oldpassword=NULL,*newpassword=NULL;
struct passwd *pwent;
+ uid_t myuid;
/* set up configuration */
rc=init(pamh,flags,argc,argv,&cfg,&ctx,&username,&service);
if (rc!=PAM_SUCCESS)
@@ -523,8 +524,17 @@
{
/* see if the user is trying to modify another user's password */
pwent=getpwnam(username);
- if ((pwent!=NULL)&&(pwent->pw_uid!=getuid()))
+ myuid=getuid();
+ if ((pwent!=NULL)&&(pwent->pw_uid!=myuid))
{
+ /* we are root so we can test if nslcd will allow us to change the
+ user's password without the admin password */
+ if (myuid==0)
+ {
+ rc=nslcd_request_authc(pamh,ctx,&cfg,"",service,"");
+ if ((rc==PAM_SUCCESS)&&(ctx->authok==PAM_SUCCESS))
+ return pam_set_item(pamh,PAM_OLDAUTHTOK,"");
+ }
/* try to authenticate with the LDAP administrator password by passing
an empty username to the authc request */
rc=pam_get_authtok(pamh,PAM_OLDAUTHTOK,&oldpassword,"LDAP administrator
password: ");
@@ -558,6 +568,9 @@
pam_syslog(pamh,LOG_NOTICE,"%s;
user=%s",pam_strerror(pamh,ctx->authok),username);
else if (cfg.debug)
pam_syslog(pamh,LOG_DEBUG,"authentication succeeded");
+ /* store password (needed if oldpassword was retreived from context) */
+ if (rc==PAM_SUCCESS)
+ return pam_set_item(pamh,PAM_OLDAUTHTOK,oldpassword);
/* remap error code */
return remap_pam_rc(ctx->authok,&cfg);
}
--
To unsubscribe send an email to
nss-pam-ldapd-commits-unsubscribe@lists.arthurdejong.org or see
http://lists.arthurdejong.org/nss-pam-ldapd-commits
- nss-pam-ldapd commit: r1206 - in nss-pam-ldapd: man nslcd pam,
Commits of the nss-pam-ldapd project