summaryrefslogtreecommitdiff
path: root/nslcd
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2009-10-07 19:12:50 +0000
committerArthur de Jong <arthur@arthurdejong.org>2009-10-07 19:12:50 +0000
commita78a6872b80622a4f77c82f99119abb04bc5fe9b (patch)
tree0b62ab1a944e2da9032238d992b6217b06243226 /nslcd
parent801b9dc12300f1860def5a9cd3c7ca987a2c8104 (diff)
implement password changing in the PAM module by performing an LDAP password modify EXOP request
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-pam-ldapd@1000 ef36b2f9-881f-0410-afb5-c4e39611909c
Diffstat (limited to 'nslcd')
-rw-r--r--nslcd/myldap.c37
-rw-r--r--nslcd/myldap.h5
-rw-r--r--nslcd/nslcd.c1
-rw-r--r--nslcd/pam.c90
4 files changed, 106 insertions, 27 deletions
diff --git a/nslcd/myldap.c b/nslcd/myldap.c
index c5cd1e0..7da3446 100644
--- a/nslcd/myldap.c
+++ b/nslcd/myldap.c
@@ -1647,3 +1647,40 @@ int myldap_set_debuglevel(int level)
}
return LDAP_SUCCESS;
}
+
+int myldap_passwd(
+ MYLDAP_SESSION *session,
+ const char *userdn,const char *oldpassword,const char *newpasswd)
+{
+ int rc;
+ struct berval ber_userdn, ber_oldpassword, ber_newpassword, ber_retpassword;
+ /* check parameters */
+ if (!is_valid_session(session)||(userdn==NULL)||(oldpassword==NULL)||(newpasswd==NULL))
+ {
+ log_log(LOG_ERR,"myldap_exop_passwd(): invalid parameter passed");
+ errno=EINVAL;
+ return NULL;
+ }
+ /* log the call */
+ log_log(LOG_DEBUG,"myldap_exop_passwd(userdn=\"%s\")",userdn);
+ /* translate to ber stuff */
+ ber_userdn.bv_val=userdn;
+ ber_userdn.bv_len=strlen(userdn);
+ ber_oldpassword.bv_val=oldpassword;
+ ber_oldpassword.bv_len=strlen(oldpassword);
+ ber_newpassword.bv_val=newpasswd;
+ ber_newpassword.bv_len=strlen(newpasswd);
+ ber_retpassword.bv_val=NULL;
+ ber_retpassword.bv_len=0;
+ /* perform request */
+ rc=ldap_passwd_s(session->ld,&ber_userdn,&ber_oldpassword,&ber_newpassword,
+ &ber_retpassword,NULL,NULL);
+ if (rc!=LDAP_SUCCESS)
+ log_log(LOG_ERR,"ldap_passwd_s() failed: %s",ldap_err2string(rc));
+
+
+ /* FIXME: free ber_retpassword data if bv_val!=NULL */
+
+ return rc;
+
+}
diff --git a/nslcd/myldap.h b/nslcd/myldap.h
index 55cf1da..b9d1058 100644
--- a/nslcd/myldap.h
+++ b/nslcd/myldap.h
@@ -133,4 +133,9 @@ MUST_USE int myldap_escape(const char *src,char *buffer,size_t buflen);
/* Set the debug level globally. Returns an LDAP status code. */
int myldap_set_debuglevel(int i);
+/* Perform an EXOP password modification call. */
+int myldap_passwd(
+ MYLDAP_SESSION *session,
+ const char *userdn,const char *oldpassword,const char *newpasswd);
+
#endif /* not _MYLDAP_H */
diff --git a/nslcd/nslcd.c b/nslcd/nslcd.c
index 5ed9608..d5fe923 100644
--- a/nslcd/nslcd.c
+++ b/nslcd/nslcd.c
@@ -417,6 +417,7 @@ static void handleconnection(int sock,MYLDAP_SESSION *session)
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 */
default:
log_log(LOG_WARNING,"invalid request id: %d",(int)action);
break;
diff --git a/nslcd/pam.c b/nslcd/pam.c
index 82a2a0c..d30e703 100644
--- a/nslcd/pam.c
+++ b/nslcd/pam.c
@@ -140,7 +140,8 @@ int nslcd_pam_authc(TFILE *fp,MYLDAP_SESSION *session)
READ_STRING(fp,servicename);
READ_STRING(fp,password);
/* log call */
- log_log(LOG_DEBUG,"nslcd_pam_authc(\"%s\",\"%s\",\"%s\")",username,userdn,servicename);
+ log_log(LOG_DEBUG,"nslcd_pam_authc(\"%s\",\"%s\",\"%s\",\"%s\")",
+ username,userdn,servicename,*password?"***":"");
/* write the response header */
WRITE_INT32(fp,NSLCD_VERSION);
WRITE_INT32(fp,NSLCD_ACTION_PAM_AUTHC);
@@ -261,37 +262,72 @@ int nslcd_pam_sess_c(TFILE *fp,MYLDAP_SESSION *session)
return 0;
}
+static int try_pwmod(const char *userdn,const char *oldpassword,
+ const char *newpassword)
+{
+ MYLDAP_SESSION *session;
+ int rc;
+ /* set up a new connection */
+ session=myldap_create_session();
+ if (session==NULL)
+ return NSLCD_PAM_AUTH_ERR;
+ /* set up credentials for the session */
+ rc=myldap_set_credentials(session,userdn,oldpassword);
+ if (rc==LDAP_SUCCESS)
+ {
+ /* perform password modification */
+ rc=myldap_passwd(session,userdn,oldpassword,newpassword);
+ }
+ /* close the session */
+ myldap_session_close(session);
+ /* return */
+ return rc;
+}
+
int nslcd_pam_pwmod(TFILE *fp,MYLDAP_SESSION *session)
{
-/*
- struct berval dn, uid, opw, npw;
int32_t tmpint32;
- char dnc[1024];
- char uidc[256];
- char opwc[256];
- char npwc[256];
-
- READ_STRING(fp,dnc);
- dn.bv_val = dnc;
- dn.bv_len = tmpint32;
- READ_STRING(fp,uidc);
- uid.bv_val = uidc;
- uid.bv_len = tmpint32;
- READ_STRING(fp,opwc);
- opw.bv_val = opwc;
- opw.bv_len = tmpint32;
- READ_STRING(fp,npwc);
- npw.bv_val = npwc;
- npw.bv_len = tmpint32;
-
- Debug(LDAP_DEBUG_TRACE,"nssov_pam_pwmod(%s), %s\n",dn.bv_val,uid.bv_val,0);
-
- BER_BVZERO(&npw);
+ char username[256];
+ char userdn[256];
+ char servicename[64];
+ char oldpassword[64];
+ char newpassword[64];
+ int rc;
+ /* read request parameters */
+ READ_STRING(fp,username);
+ READ_STRING(fp,userdn);
+ READ_STRING(fp,servicename);
+ READ_STRING(fp,oldpassword);
+ READ_STRING(fp,newpassword);
+ /* log call */
+ log_log(LOG_DEBUG,"nslcd_pam_pwmod(\"%s\",\"%s\",\"%s\",\"%s\",\"%s\")",
+ username,userdn,servicename,*oldpassword?"***":"",
+ *newpassword?"***":"");
+ /* write the response header */
WRITE_INT32(fp,NSLCD_VERSION);
WRITE_INT32(fp,NSLCD_ACTION_PAM_PWMOD);
+ /* validate request and fill in the blanks */
+ if (validate_user(session,userdn,sizeof(userdn),username,sizeof(username)))
+ {
+ WRITE_INT32(fp,NSLCD_RESULT_END);
+ return -1;
+ }
+ /* perform password modification */
+ rc=try_pwmod(userdn,oldpassword,newpassword);
+ /* write response */
WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
- WRITE_INT32(fp,PAM_SUCCESS);
- WRITE_BERVAL(fp,&npw);
-*/
+ WRITE_STRING(fp,username);
+ WRITE_STRING(fp,userdn);
+ if (rc==LDAP_SUCCESS)
+ {
+ WRITE_INT32(fp,NSLCD_PAM_SUCCESS);
+ WRITE_STRING(fp,"");
+ }
+ else
+ {
+ WRITE_INT32(fp,NSLCD_PAM_PERM_DENIED);
+ WRITE_STRING(fp,ldap_err2string(rc));
+ }
+ WRITE_INT32(fp,NSLCD_RESULT_END);
return 0;
}