]> git.sur5r.net Git - openldap/commitdiff
ITS#7518 1. Sync'ed up with nss-pam-ldapd 0.8.11 * added nssov_config support * added...
authorTed C. Cheng <tedcheng@symas.com>
Tue, 5 Feb 2013 00:39:50 +0000 (16:39 -0800)
committerQuanah Gibson-Mount <quanah@openldap.org>
Tue, 5 Feb 2013 23:55:54 +0000 (15:55 -0800)
contrib/slapd-modules/nssov/nssov.c
contrib/slapd-modules/nssov/nssov.h
contrib/slapd-modules/nssov/pam.c
contrib/slapd-modules/nssov/service.c
contrib/slapd-modules/nssov/slapo-nssov.5

index 6da718da6a43c1d81e4615475f0dcf0094d7515e..e734e3b2b223b6dc6356cf6dc88659c1e4e1c39a 100644 (file)
@@ -4,6 +4,7 @@
  *
  * Copyright 2008-2013 The OpenLDAP Foundation.
  * Portions Copyright 2008 by Howard Chu, Symas Corp.
+ * Portions Copyright 2013 by Ted C. Cheng, Symas Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -250,13 +251,50 @@ static int read_header(TFILE *fp,int32_t *action)
   return 0;
 }
 
+int nssov_config(nssov_info *ni,TFILE *fp,Operation *op)
+{
+       int opt;
+       int32_t tmpint32;
+       struct berval *msg = BER_BVC("");
+       int rc = NSLCD_PAM_SUCCESS;
+
+       READ_INT32(fp,opt);
+
+       Debug(LDAP_DEBUG_TRACE, "nssov_config (%d)\n",opt,0,0);
+
+       switch (opt) {
+       case NSLCD_CONFIG_PAM_PASSWORD_PROHIBIT_MESSAGE:
+               /* request for pam password_prothibit_message */
+               /* nssov_pam prohibits password  */
+               if (!BER_BVISEMPTY(&ni->ni_pam_password_prohibit_message)) {
+                       Debug(LDAP_DEBUG_TRACE,"nssov_config(): %s (%s)\n",
+                               "password_prohibit_message",
+                               ni->ni_pam_password_prohibit_message.bv_val,0);
+                       msg = &ni->ni_pam_password_prohibit_message;
+                       rc = NSLCD_PAM_PERM_DENIED;
+               }
+               /* fall through */
+       default:
+               break;
+       }
+
+done:;
+       WRITE_INT32(fp,NSLCD_VERSION);
+       WRITE_INT32(fp,NSLCD_ACTION_CONFIG_GET);
+       WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
+       WRITE_BERVAL(fp,msg);
+       WRITE_INT32(fp,NSLCD_RESULT_END);
+       return 0;
+}
+
+
 /* read a request message, returns <0 in case of errors,
    this function closes the socket */
 static void handleconnection(nssov_info *ni,int sock,Operation *op)
 {
   TFILE *fp;
   int32_t action;
-  struct timeval readtimeout,writetimeout;
+  int readtimeout,writetimeout;
   uid_t uid;
   gid_t gid;
   char authid[sizeof("gidNumber=4294967295+uidNumber=424967295,cn=peercred,cn=external,cn=auth")];
@@ -272,17 +310,19 @@ static void handleconnection(nssov_info *ni,int sock,Operation *op)
 
   /* Should do authid mapping too */
   op->o_dn.bv_len = sprintf(authid,"gidNumber=%d+uidNumber=%d,cn=peercred,cn=external,cn=auth",
-       (int)uid, (int)gid );
+       (int)gid, (int)uid );
   op->o_dn.bv_val = authid;
   op->o_ndn = op->o_dn;
 
-  /* set the timeouts */
-  readtimeout.tv_sec=0; /* clients should send their request quickly */
-  readtimeout.tv_usec=500000;
-  writetimeout.tv_sec=5; /* clients could be taking some time to process the results */
-  writetimeout.tv_usec=0;
+  /* set the timeouts:
+   * read timeout is half a second because clients should send their request
+   * quickly, write timeout is 60 seconds because clients could be taking some
+   * time to process the results
+   */
+  readtimeout = 500;
+  writetimeout = 60000;
   /* create a stream object */
-  if ((fp=tio_fdopen(sock,&readtimeout,&writetimeout,
+  if ((fp=tio_fdopen(sock,readtimeout,writetimeout,
                      READBUFFER_MINSIZE,READBUFFER_MAXSIZE,
                      WRITEBUFFER_MINSIZE,WRITEBUFFER_MAXSIZE))==NULL)
   {
@@ -334,6 +374,7 @@ static void handleconnection(nssov_info *ni,int sock,Operation *op)
        case NSLCD_ACTION_PAM_SESS_O:           if (uid==0) (void)pam_sess_o(ni,fp,op); break;
        case NSLCD_ACTION_PAM_SESS_C:           if (uid==0) (void)pam_sess_c(ni,fp,op); break;
        case NSLCD_ACTION_PAM_PWMOD:            (void)pam_pwmod(ni,fp,op); break;
+       case NSLCD_ACTION_CONFIG_GET:                   (void)nssov_config(ni,fp,op); break;
     default:
       Debug( LDAP_DEBUG_ANY,"nssov: invalid request id: %d",(int)action,0,0);
       break;
@@ -497,6 +538,30 @@ static ConfigTable nsscfg[] = {
                        "DESC 'Services for which sessions will be recorded' "
                        "EQUALITY caseIgnoreMatch "
                        "SYNTAX OMsDirectoryString )", NULL, NULL },
+       { "nssov-pam-password-prohibit-message",
+               "password_prohibit_message", 2, 2, 0,
+               ARG_OFFSET|ARG_BERVAL,
+               (void *)offsetof(struct nssov_info, ni_pam_password_prohibit_message),
+               "(OLcfgCtAt:3.12 NAME 'olcNssPamPwdProhibitMsg' "
+                       "DESC 'Prohibit password modification message' "
+                       "EQUALITY caseIgnoreMatch "
+                       "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+       { "nssov-pam-pwdmgr-dn",
+               "pwdmgr_dn", 2, 2, 0,
+               ARG_OFFSET|ARG_BERVAL,
+               (void *)offsetof(struct nssov_info, ni_pam_pwdmgr_dn),
+               "(OLcfgCtAt:3.13 NAME 'olcPamPwdmgrDn' "
+                       "DESC 'Password Manager DN' "
+                       "EQUALITY distinguishedNameMatch "
+                       "SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL },
+       { "nssov-pam-pwdmgr-pwd",
+               "pwdmgr_pwd", 2, 2, 0,
+               ARG_OFFSET|ARG_BERVAL,
+               (void *)offsetof(struct nssov_info, ni_pam_pwdmgr_pwd),
+               "(OLcfgCtAt:3.14 NAME 'olcPamPwdmgrPwd' "
+                       "DESC 'Password Manager Pwd' "
+                       "EQUALITY octetStringMatch "
+                       "SYNTAX OMsOctetString SINGLE-VALUE )", NULL, NULL },
        { NULL, NULL, 0,0,0, ARG_IGNORED }
 };
 
index fd55ee683e36d79d3e3873d7764161a172b51aa1..684ade24356aecf66658b00a2f25efa7dc2fa6ee 100644 (file)
@@ -4,6 +4,7 @@
  *
  * Copyright 2008-2013 The OpenLDAP Foundation.
  * Portions Copyright 2008 Howard Chu.
+ * Portions Copyright 2013 Ted C. Cheng, Symas Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -88,6 +89,9 @@ typedef struct nssov_info
        struct berval ni_pam_template;
        struct berval ni_pam_defhost;
        struct berval *ni_pam_sessions;
+       struct berval ni_pam_password_prohibit_message;
+       struct berval ni_pam_pwdmgr_dn;
+       struct berval ni_pam_pwdmgr_pwd;
 } nssov_info;
 
 #define NI_PAM_USERHOST                1       /* old style host checking */
index 31f5e37f7a9c4a75de8409d2568f25a8fa57d05e..2558bf7cc32687febbc137a0a1efe1e37eed0ac3 100644 (file)
@@ -4,6 +4,7 @@
  *
  * Copyright 2008-2013 The OpenLDAP Foundation.
  * Portions Copyright 2008 by Howard Chu, Symas Corp.
+ * Portions Copyright 2013 by Ted C. Cheng, Symas Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,6 +29,7 @@ struct paminfo {
        struct berval pwd;
        int authz;
        struct berval msg;
+       int ispwdmgr;
 };
 
 static int pam_bindcb(
@@ -109,7 +111,7 @@ static int pam_uid2dn(nssov_info *ni, Operation *op,
 
        if (!isvalidusername(&pi->uid)) {
                Debug(LDAP_DEBUG_ANY,"nssov_pam_uid2dn(%s): invalid user name\n",
-                       pi->uid.bv_val,0,0);
+                       pi->uid.bv_val ? pi->uid.bv_val : "NULL",0,0);
                return NSLCD_PAM_USER_UNKNOWN;
        }
 
@@ -150,27 +152,31 @@ int pam_do_bind(nssov_info *ni,TFILE *fp,Operation *op,
        pi->msg.bv_val = pi->pwd.bv_val;
        pi->msg.bv_len = 0;
        pi->authz = NSLCD_PAM_SUCCESS;
-       BER_BVZERO(&pi->dn);
 
-       rc = pam_uid2dn(ni, op, pi);
-       if (rc) goto finish;
+       if (!pi->ispwdmgr) {
 
-       if (BER_BVISEMPTY(&pi->pwd)) {
-               rc = NSLCD_PAM_IGNORE;
-               goto finish;
-       }
+               BER_BVZERO(&pi->dn);
+               rc = pam_uid2dn(ni, op, pi);
+               if (rc) goto finish;
 
-       /* Should only need to do this once at open time, but there's always
-        * the possibility that ppolicy will get loaded later.
-        */
-       if (!ppolicy_cid) {
-               rc = slap_find_control_id(LDAP_CONTROL_PASSWORDPOLICYREQUEST,
-                       &ppolicy_cid);
-       }
-       /* of course, 0 is a valid cid, but it won't be ppolicy... */
-       if (ppolicy_cid) {
-               op->o_ctrlflag[ppolicy_cid] = SLAP_CONTROL_NONCRITICAL;
+               if (BER_BVISEMPTY(&pi->pwd)) {
+                       rc = NSLCD_PAM_PERM_DENIED;
+                       goto finish;
+               }
+
+               /* Should only need to do this once at open time, but there's always
+                * the possibility that ppolicy will get loaded later.
+                */
+               if (!ppolicy_cid) {
+                       rc = slap_find_control_id(LDAP_CONTROL_PASSWORDPOLICYREQUEST,
+                               &ppolicy_cid);
+               }
+               /* of course, 0 is a valid cid, but it won't be ppolicy... */
+               if (ppolicy_cid) {
+                       op->o_ctrlflag[ppolicy_cid] = SLAP_CONTROL_NONCRITICAL;
+               }
        }
+
        cb.sc_response = pam_bindcb;
        cb.sc_private = pi;
        op->o_callback = &cb;
@@ -198,6 +204,8 @@ int pam_do_bind(nssov_info *ni,TFILE *fp,Operation *op,
        default: rc = NSLCD_PAM_AUTH_ERR; break;
        }
 finish:
+       Debug(LDAP_DEBUG_ANY,"pam_do_bind (%s): rc (%d)\n",
+               pi->dn.bv_val ? pi->dn.bv_val : "NULL", rc, 0);
        return rc;
 }
 
@@ -227,11 +235,64 @@ int pam_authc(nssov_info *ni,TFILE *fp,Operation *op)
        pi.pwd.bv_val = pwdc;
        pi.pwd.bv_len = tmpint32;
 
-       Debug(LDAP_DEBUG_TRACE,"nssov_pam_authc(%s)\n",pi.uid.bv_val,0,0);
+       Debug(LDAP_DEBUG_TRACE,"nssov_pam_authc(%s)\n",
+                       pi.uid.bv_val ? pi.uid.bv_val : "NULL",0,0);
+
+       pi.ispwdmgr = 0;
+
+       /* if service is "passwd" and "nssov-pam-password-prohibit-message */
+       /* is set, deny the auth request */
+       if (!strcmp(svcc, "passwd") &&
+               !BER_BVISEMPTY(&ni->ni_pam_password_prohibit_message)) {
+               Debug(LDAP_DEBUG_TRACE,"nssov_pam_authc(): %s (%s)\n",
+                       "password_prohibit_message for passwd",
+                       ni->ni_pam_password_prohibit_message.bv_val,0);
+               ber_str2bv(ni->ni_pam_password_prohibit_message.bv_val, 0, 0, &pi.msg);
+               pi.authz = NSLCD_PAM_PERM_DENIED;
+               rc = NSLCD_PAM_PERM_DENIED;
+               goto finish;
+       }
+
+       /* if username is null, pwdmgr password preliminary check */
+       if (BER_BVISEMPTY(&pi.uid)) {
+               if (BER_BVISEMPTY(&ni->ni_pam_pwdmgr_dn)) {
+                       /* pwdmgr dn not configured */
+                       Debug(LDAP_DEBUG_TRACE,"nssov_pam_authc(prelim check): %s\n",
+                               "pwdmgr dn not configured", 0, 0);
+                       ber_str2bv("pwdmgr dn not configured", 0, 0, &pi.msg);
+                       pi.authz = NSLCD_PAM_PERM_DENIED;
+                       rc = NSLCD_PAM_PERM_DENIED;
+                       goto finish;
+               } else {
+                       /* use pwdmgr dn */
+                       ber_str2bv(ni->ni_pam_pwdmgr_dn.bv_val, 0, 0, &pi.dn);
+               }
+
+               /* use pwdmgr pwd if configured */
+               if (BER_BVISEMPTY(&pi.pwd)) {
+                       if (BER_BVISEMPTY(&ni->ni_pam_pwdmgr_pwd)) {
+                               Debug(LDAP_DEBUG_TRACE,"nssov_pam_authc(prelim check): %s\n",
+                                       "no pwdmgr pwd", 0, 0);
+                               ber_str2bv("pwdmgr pwd not configured", 0, 0, &pi.msg);
+                               pi.authz = NSLCD_PAM_PERM_DENIED;
+                               rc = NSLCD_PAM_PERM_DENIED;
+                               goto finish;
+                       }
+                       /* use configured pwdmgr pwd */
+                       memset((void *) pwdc, 0, 256);
+                       strncpy(pi.pwd.bv_val, ni->ni_pam_pwdmgr_pwd.bv_val,
+                                       ni->ni_pam_pwdmgr_pwd.bv_len);
+                       pi.pwd.bv_len = ni->ni_pam_pwdmgr_pwd.bv_len;
+               }
+               pi.ispwdmgr = 1;
+       }
+
 
        rc = pam_do_bind(ni, fp, op, &pi);
 
 finish:
+       Debug(LDAP_DEBUG_TRACE,"nssov_pam_authc(%s): rc (%d)\n",
+               pi.dn.bv_val ? pi.dn.bv_val : "NULL",rc,0);
        WRITE_INT32(fp,NSLCD_VERSION);
        WRITE_INT32(fp,NSLCD_ACTION_PAM_AUTHC);
        WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
@@ -294,7 +355,8 @@ int pam_authz(nssov_info *ni,TFILE *fp,Operation *op)
        tty.bv_val = ttyc;
        tty.bv_len = tmpint32;
 
-       Debug(LDAP_DEBUG_TRACE,"nssov_pam_authz(%s)\n",dn.bv_val,0,0);
+       Debug(LDAP_DEBUG_TRACE,"nssov_pam_authz(%s)\n",
+                       dn.bv_val ? dn.bv_val : "NULL",0,0);
 
        /* If we didn't do authc, we don't have a DN yet */
        if (BER_BVISEMPTY(&dn)) {
@@ -477,6 +539,19 @@ finish:
        if (e) {
                be_entry_release_r(op, e);
        }
+       switch (rc) {
+       case NSLCD_PAM_SUCCESS:
+               Debug(LDAP_DEBUG_TRACE,"nssov_pam_authz(): success\n", 0,0,0);
+               break;
+       case NSLCD_PAM_PERM_DENIED:
+               Debug(LDAP_DEBUG_TRACE,"nssov_pam_authz(): %s\n",
+                       authzmsg.bv_val ? authzmsg.bv_val : "NULL",0,0);
+               break;
+       default:
+               Debug(LDAP_DEBUG_TRACE,
+                       "nssov_pam_authz(): permission denied, rc (%d)\n",
+                       rc, 0, 0);
+       }
        return 0;
 }
 
@@ -496,6 +571,8 @@ static int pam_sess(nssov_info *ni,TFILE *fp,Operation *op,int action)
        struct berval timestamp, bv[2], *nbv;
        time_t stamp;
        Modifications mod;
+       int rc = 0;
+       int sessionID = -1;
 
        READ_STRING(fp,uidc);
        uid.bv_val = uidc;
@@ -520,7 +597,20 @@ static int pam_sess(nssov_info *ni,TFILE *fp,Operation *op,int action)
        Debug(LDAP_DEBUG_TRACE,"nssov_pam_sess_%c(%s)\n",
                action==NSLCD_ACTION_PAM_SESS_O ? 'o' : 'c', dn.bv_val,0);
 
-       if (!dn.bv_len || !ni->ni_pam_sessions) return 0;
+       if (!dn.bv_len) {
+               Debug(LDAP_DEBUG_TRACE,"nssov_pam_sess_%c(): %s\n",
+                       action==NSLCD_ACTION_PAM_SESS_O ? 'o' : 'c', "null DN",0);
+               rc = -1;
+               goto done;
+       }
+
+       if (!ni->ni_pam_sessions) {
+               Debug(LDAP_DEBUG_TRACE,"nssov_pam_sess_%c(): %s\n",
+                       action==NSLCD_ACTION_PAM_SESS_O ? 'o' : 'c',
+                       "pam session(s) not configured, ignored",0);
+               rc = -1;
+               goto done;
+       }
 
        {
                int i, found=0;
@@ -532,7 +622,14 @@ static int pam_sess(nssov_info *ni,TFILE *fp,Operation *op,int action)
                                break;
                        }
                }
-               if (!found) return 0;
+               if (!found) {
+                       Debug(LDAP_DEBUG_TRACE,
+                               "nssov_pam_sess_%c(): service(%s) not configured, ignored\n",
+                               action==NSLCD_ACTION_PAM_SESS_O ? 'o' : 'c',
+                               svc.bv_val,0);
+                       rc = -1;
+                       goto done;
+               }
        }
 
        slap_op_time( &op->o_time, &op->o_tincr );
@@ -547,6 +644,9 @@ static int pam_sess(nssov_info *ni,TFILE *fp,Operation *op,int action)
        sprintf(bv[0].bv_val, "%s %s %s %s (%s@%s)",
                timestamp.bv_val, global_host_bv.bv_val, svc.bv_val, tty.bv_val,
                ruser.bv_val, rhost.bv_val);
+
+       Debug(LDAP_DEBUG_TRACE, "nssov_pam_sess_%c(): loginStatus (%s) \n",
+                       action==NSLCD_ACTION_PAM_SESS_O ? 'o' : 'c', bv[0].bv_val,0);
        
        mod.sml_numvals = 1;
        mod.sml_values = bv;
@@ -568,16 +668,32 @@ static int pam_sess(nssov_info *ni,TFILE *fp,Operation *op,int action)
        op->orm_no_opattrs = 1;
        op->o_req_dn = dn;
        op->o_req_ndn = dn;
-       op->o_bd->be_modify( op, &rs );
+       if (op->o_bd->be_modify( op, &rs ) != LDAP_SUCCESS) {
+               Debug(LDAP_DEBUG_TRACE,
+                       "nssov_pam_sess_%c(): modify op failed\n",
+                       action==NSLCD_ACTION_PAM_SESS_O ? 'o' : 'c',
+                       0,0);
+               rc = -1;
+       }
+
        if ( mod.sml_next ) {
                slap_mods_free( mod.sml_next, 1 );
        }
        ber_bvarray_free_x( nbv, op->o_tmpmemctx );
 
+done:;
+
+       if (rc == 0) {
+               Debug(LDAP_DEBUG_TRACE,
+                       "nssov_pam_sess_%c(): success\n",
+                       action==NSLCD_ACTION_PAM_SESS_O ? 'o' : 'c',
+                       0,0);
+               sessionID = op->o_time;
+       }
        WRITE_INT32(fp,NSLCD_VERSION);
        WRITE_INT32(fp,action);
        WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
-       WRITE_INT32(fp,op->o_time);
+       WRITE_INT32(fp,sessionID);
        return 0;
 }
 
@@ -620,49 +736,96 @@ int pam_pwmod(nssov_info *ni,TFILE *fp,Operation *op)
        npw.bv_len = tmpint32;
 
        Debug(LDAP_DEBUG_TRACE,"nssov_pam_pwmod(%s), %s\n",
-               pi.dn.bv_val,pi.uid.bv_val,0);
+               pi.dn.bv_val ? pi.dn.bv_val : "NULL",
+               pi.uid.bv_val ? pi.uid.bv_val : "NULL" ,0);
 
        BER_BVZERO(&pi.msg);
+       pi.ispwdmgr = 0;
+
+       /* nssov_pam prohibits password mod */
+       if (!BER_BVISEMPTY(&ni->ni_pam_password_prohibit_message)) {
+               Debug(LDAP_DEBUG_TRACE,"nssov_pam_pwmod(): %s (%s)\n",
+                       "password_prohibit_message",
+                       ni->ni_pam_password_prohibit_message.bv_val,0);
+               ber_str2bv(ni->ni_pam_password_prohibit_message.bv_val, 0, 0, &pi.msg);
+               rc = NSLCD_PAM_PERM_DENIED;
+               goto done;
+       }
 
-       /* This is a prelim check */
        if (BER_BVISEMPTY(&pi.dn)) {
-               rc = pam_do_bind(ni,fp,op,&pi);
-               if (rc == NSLCD_PAM_IGNORE)
-                       rc = NSLCD_PAM_SUCCESS;
+               /* should not be here at all, pam_authc() should have returned */
+               /* error */
+               Debug(LDAP_DEBUG_TRACE,"nssov_pam_pwmod(), %s\n",
+                       "prelim checking failed", 0, 0);
+               ber_str2bv("no pwmod requesting dn", 0, 0, &pi.msg);
+               rc = NSLCD_PAM_PERM_DENIED;
+               goto done;
+       }
+
+       if (BER_BVISEMPTY(&ni->ni_pam_pwdmgr_dn)) {
+               Debug(LDAP_DEBUG_TRACE,"nssov_pam_pwmod(), %s\n",
+                       "pwdmgr not configured", 0, 0);
+               ber_str2bv("pwdmgr not configured", 0, 0, &pi.msg);
+               rc = NSLCD_PAM_PERM_DENIED;
+               goto done;
+       } else if (!ber_bvcmp(&pi.dn, &ni->ni_pam_pwdmgr_dn)) {
+               /* root user requesting pwmod, convert uid to dn */
+               pi.ispwdmgr = 1;
+               rc = pam_uid2dn(ni, op, &pi);
+               if (rc) {
+                       ber_str2bv("unable to convert uid to dn", 0, 0, &pi.msg);
+                       rc = NSLCD_PAM_PERM_DENIED;
+                       goto done;
+               }
+       }
+
+       BerElementBuffer berbuf;
+       BerElement *ber = (BerElement *)&berbuf;
+       struct berval bv;
+       SlapReply rs = {REP_RESULT};
+       slap_callback cb = {0};
+
+       ber_init_w_nullc(ber, LBER_USE_DER);
+       ber_printf(ber, "{");
+       if (!BER_BVISEMPTY(&pi.dn))
+               ber_printf(ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_ID,
+                       &pi.dn);
+       /* supply old pwd only when end-user changing pwd */
+       if (!BER_BVISEMPTY(&pi.pwd) && pi.ispwdmgr == 0)
+               ber_printf(ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_OLD,
+                       &pi.pwd);
+       if (!BER_BVISEMPTY(&npw))
+               ber_printf(ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW,
+                       &npw);
+       ber_printf(ber, "N}");
+       ber_flatten2(ber, &bv, 0);
+       op->o_tag = LDAP_REQ_EXTENDED;
+       op->ore_reqoid = slap_EXOP_MODIFY_PASSWD;
+       op->ore_reqdata = &bv;
+
+       if (pi.ispwdmgr) {
+               /* root user changing end-user passwords */
+               op->o_dn = ni->ni_pam_pwdmgr_dn;
+               op->o_ndn = ni->ni_pam_pwdmgr_dn;
        } else {
-               BerElementBuffer berbuf;
-               BerElement *ber = (BerElement *)&berbuf;
-               struct berval bv;
-               SlapReply rs = {REP_RESULT};
-               slap_callback cb = {0};
-
-               ber_init_w_nullc(ber, LBER_USE_DER);
-               ber_printf(ber, "{");
-               if (!BER_BVISEMPTY(&pi.pwd))
-                       ber_printf(ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_OLD,
-                               &pi.pwd);
-               if (!BER_BVISEMPTY(&npw))
-                       ber_printf(ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW,
-                               &npw);
-               ber_printf(ber, "N}");
-               ber_flatten2(ber, &bv, 0);
-               op->o_tag = LDAP_REQ_EXTENDED;
-               op->ore_reqoid = slap_EXOP_MODIFY_PASSWD;
-               op->ore_reqdata = &bv;
+               /* end-user self-pwd-mod */
                op->o_dn = pi.dn;
                op->o_ndn = pi.dn;
-               op->o_callback = &cb;
-               op->o_conn->c_authz_backend = op->o_bd;
-               cb.sc_response = slap_null_cb;
-               op->o_bd = frontendDB;
-               rc = op->o_bd->be_extended(op, &rs);
-               if (rs.sr_text)
-                       ber_str2bv(rs.sr_text, 0, 0, &pi.msg);
-               if (rc == LDAP_SUCCESS)
-                       rc = NSLCD_PAM_SUCCESS;
-               else
-                       rc = NSLCD_PAM_PERM_DENIED;
        }
+       op->o_callback = &cb;
+       op->o_conn->c_authz_backend = op->o_bd;
+       cb.sc_response = slap_null_cb;
+       op->o_bd = frontendDB;
+       rc = op->o_bd->be_extended(op, &rs);
+       if (rs.sr_text)
+               ber_str2bv(rs.sr_text, 0, 0, &pi.msg);
+       if (rc == LDAP_SUCCESS)
+               rc = NSLCD_PAM_SUCCESS;
+       else
+               rc = NSLCD_PAM_PERM_DENIED;
+
+done:;
+       Debug(LDAP_DEBUG_TRACE,"nssov_pam_pwmod(), rc (%d)\n", rc, 0, 0);
        WRITE_INT32(fp,NSLCD_VERSION);
        WRITE_INT32(fp,NSLCD_ACTION_PAM_PWMOD);
        WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
index d2e8c978fea3019753d6b6c31c336f0e90505c43..94aba4044d954a3dc886dd5fc3e6391a606230ff 100644 (file)
@@ -217,7 +217,7 @@ NSSOV_HANDLE(
        READ_STRING(fp,cbp.pbuf);
        cbp.prot.bv_len = tmpint32;
        cbp.prot.bv_val = tmpint32 ? cbp.pbuf : NULL;,
-       Debug(LDAP_DEBUG_TRACE,"nssov_service_byname(%s,%s)\n",cbp.name.bv_val,cbp.prot.bv_val,0);,
+       Debug(LDAP_DEBUG_TRACE,"nssov_service_byname(%s,%s)\n",cbp.name.bv_val,cbp.prot.bv_val ? cbp.prot.bv_val : "",0);,
        NSLCD_ACTION_SERVICE_BYNAME,
        mkfilter_service_byname(cbp.mi,&cbp.name,&cbp.prot,&filter)
 )
index 805133750907b8bbb15a9ca99cddd901b10a8e57..358bcd71ea4b768d25a446f668e55ba2a449efe8 100644 (file)
@@ -39,7 +39,7 @@ Another major benefit of nssov is that it allows all security policy to be
 administered centrally via LDAP, instead of having fragile rules scattered 
 across multiple flat files. As such, there is no client-side configuration at 
 all for the NSS/PAM stub libraries. (The stubs talk to the server via a Unix
-domain socket whose path is hardcoded to /var/run/nslcd/). As a side benefit,
+domain socket whose path is hardcoded to NSLCDPATH). As a side benefit,
 this can finally eliminate the perpetual confusion between OpenLDAP's
 ldap.conf file in ETCDIR/ldap.conf and the similarly named files typically
 used by pam_ldap and nss_ldap.
@@ -48,17 +48,7 @@ User authentication is performed by internal simple Binds. User authorization
 leverages the slapd ACL engine, which offers much more power and flexibility 
 than the simple group/hostname checks in the old pam_ldap code.
 .LP
-To use this code, you will need the client-side stuf library from
-nss-pam-ldapd.  You can get it from:
-http://arthurdejong.org/nss-pam-ldapd
-You will not need the nslcd daemon; this overlay replaces that part.
-To disable building of the nslcd daemon in nss-pam-ldapd, add the
---disable-nslcd option to the nss-pam-ldapd configure script. You
-should already be familiar with the RFC2307 and RFC2307bis schema
-to use this overlay.  See the nss-pam-ldapd README for more information
-on the schema and which features are supported.
-.LP
-You will also need to include the nis.schema in your slapd configuration
+You will need to include the nis.schema in your slapd configuration
 for RFC2307 support. If you wish to use RFC2307bis you will need a slightly
 different schema. You will also need the ldapns.schema for PAM authorization
 management.
@@ -239,6 +229,17 @@ directive must be configured for this setting to have any effect.
 .B nssov-pam-session <service>
 Specify a PAM service name whose sessions will be recorded. For the
 configured services, logins will be recorded in the
+.TP
+.B nssov-pam-password-prohibit-message <message>
+Diable password change service and return the specified message to
+users.
+.TP
+.B nssov-pam-pwdmgr-dn <dn>
+Specify the dn of the password manager.
+.TP
+.B nssov-pam-pwdmgr-pwd <pwd>
+Specify the pwd of the password manager.
+.TP
 .B loginStatus
 operational attribute of the user's entry. The attribute's values are
 of the form
@@ -301,3 +302,4 @@ default slapd configuration file
 .BR slapd (8).
 .SH AUTHOR
 Howard Chu, inspired by nss-ldapd by Arthur de Jong and pam_ldap by Luke Howard
+Enhancements by Ted C. Cheng, Symas Corp.