From: Howard Chu Date: Mon, 20 Apr 2009 10:25:24 +0000 (+0000) Subject: Reformat requests, rough pwmod support X-Git-Tag: ACLCHECK_0~605 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=42a7e05809dfd0773f7063ac81aebbc3b7d729cf;p=openldap Reformat requests, rough pwmod support --- diff --git a/contrib/slapd-modules/nssov/nss-ldapd/nss/pam.c b/contrib/slapd-modules/nssov/nss-ldapd/nss/pam.c index 281f66ff2a..40b1e4cd6e 100644 --- a/contrib/slapd-modules/nssov/nss-ldapd/nss/pam.c +++ b/contrib/slapd-modules/nssov/nss-ldapd/nss/pam.c @@ -62,6 +62,7 @@ typedef struct pld_ctx { char *dn; char *tmpluser; char *authzmsg; + char *oldpw; int authok; int authz; char buf[1024]; @@ -74,6 +75,11 @@ static void pam_clr_ctx( free(ctx->user); ctx->user = NULL; } + if (ctx->oldpw) { + memset(ctx->oldpw,0,strlen(ctx->oldpw)); + free(ctx->oldpw); + ctx->oldpw = NULL; + } ctx->dn = NULL; ctx->tmpluser = NULL; ctx->authzmsg = NULL; @@ -184,23 +190,25 @@ static int pam_get_authtok( static enum nss_status pam_read_authc( TFILE *fp,pld_ctx *ctx,int *errnop) { - char *buffer = ctx->buf; + char *buffer = ctx->buf, *user; size_t buflen = sizeof(ctx->buf); size_t bufptr = 0; int32_t tmpint32; + READ_STRING_BUF(fp,user); + READ_STRING_BUF(fp,ctx->dn); READ_INT32(fp,ctx->authok); READ_INT32(fp,ctx->authz); - READ_STRING_BUF(fp,ctx->dn); READ_STRING_BUF(fp,ctx->authzmsg); return NSS_STATUS_SUCCESS; } static enum nss_status pam_do_authc( - pld_ctx *ctx, const char *name, const char *svc,const char *pwd,int *errnop) + pld_ctx *ctx, const char *user, const char *svc,const char *pwd,int *errnop) { NSS_BYGEN(NSLCD_ACTION_PAM_AUTHC, - WRITE_STRING(fp,name); + WRITE_STRING(fp,user); + WRITE_STRING(fp,"" /* DN */); WRITE_STRING(fp,svc); WRITE_STRING(fp,pwd), pam_read_authc(fp,ctx,errnop)); @@ -273,8 +281,11 @@ int pam_sm_authenticate( first_pass = 0; } - if (rc == PAM_SUCCESS) + if (rc == PAM_SUCCESS) { ctx->user = strdup(username); + if (ctx->authz == PAM_NEW_AUTHTOK_REQD) + ctx->oldpw = strdup(p); + } return rc; } @@ -314,9 +325,10 @@ static enum nss_status pam_read_authz( size_t bufptr = 0; int32_t tmpint32; + READ_STRING_BUF(fp,ctx->tmpluser); + READ_STRING_BUF(fp,ctx->dn); READ_INT32(fp,ctx->authz); READ_STRING_BUF(fp,ctx->authzmsg); - READ_STRING_BUF(fp,ctx->tmpluser); return NSS_STATUS_SUCCESS; } @@ -324,6 +336,7 @@ static enum nss_status pam_do_authz( pld_ctx *ctx, const char *svc,int *errnop) { NSS_BYGEN(NSLCD_ACTION_PAM_AUTHZ, + WRITE_STRING(fp,ctx->user); WRITE_STRING(fp,ctx->dn); WRITE_STRING(fp,svc), pam_read_authz(fp,ctx,errnop)); @@ -380,6 +393,7 @@ int pam_sm_acct_mgmt( return rc; ctx2.dn = ctx->dn; + ctx2.user = ctx->user; rc = pam_do_authz(&ctx2, svc, &err); NSS2PAM_RC(rc, ignore_flags, PAM_SUCCESS); if (rc != PAM_SUCCESS) { @@ -404,6 +418,7 @@ static enum nss_status pam_do_sess_o( pld_ctx *ctx, const char *svc,int *errnop) { NSS_BYGEN(NSLCD_ACTION_PAM_SESS_O, + WRITE_STRING(fp,ctx->user); WRITE_STRING(fp,ctx->dn); WRITE_STRING(fp,svc), NSS_STATUS_SUCCESS); @@ -470,6 +485,7 @@ static enum nss_status pam_do_sess_c( pld_ctx *ctx, const char *svc,int *errnop) { NSS_BYGEN(NSLCD_ACTION_PAM_SESS_C, + WRITE_STRING(fp,ctx->user); WRITE_STRING(fp,ctx->dn); WRITE_STRING(fp,svc), NSS_STATUS_SUCCESS); @@ -535,22 +551,26 @@ int pam_sm_close_session( static enum nss_status pam_read_pwmod( TFILE *fp,pld_ctx *ctx,int *errnop) { - char *buffer = ctx->buf; + char *buffer = ctx->buf, *user; size_t buflen = sizeof(ctx->buf); size_t bufptr = 0; int32_t tmpint32; + READ_STRING_BUF(fp,user); + READ_STRING_BUF(fp,ctx->dn); READ_INT32(fp,ctx->authz); READ_STRING_BUF(fp,ctx->authzmsg); return NSS_STATUS_SUCCESS; } static enum nss_status pam_do_pwmod( - pld_ctx *ctx, const char *user, const char *oldpw, const char *newpw, int *errnop) + pld_ctx *ctx, const char *user, const char *svc, + const char *oldpw, const char *newpw, int *errnop) { NSS_BYGEN(NSLCD_ACTION_PAM_PWMOD, - WRITE_STRING(fp,ctx->dn); WRITE_STRING(fp,user); + WRITE_STRING(fp,ctx->dn); + WRITE_STRING(fp,svc); WRITE_STRING(fp,oldpw); WRITE_STRING(fp,newpw), pam_read_pwmod(fp,ctx,errnop)); @@ -560,7 +580,7 @@ int pam_sm_chauthtok( pam_handle_t *pamh, int flags, int argc, const char **argv) { int rc, err; - const char *username, *p = NULL, *q = NULL; + const char *username, *p = NULL, *q = NULL, *svc; int first_pass = 0, no_warn = 0, ignore_flags = 0; int i, success = PAM_SUCCESS; struct pam_conv *appconv; @@ -604,6 +624,10 @@ int pam_sm_chauthtok( if (rc != PAM_SUCCESS) return rc; + rc = pam_get_item (pamh, PAM_SERVICE, (CONST_ARG void **) &svc); + if (rc != PAM_SUCCESS) + return rc; + if (flags & PAM_PRELIM_CHECK) { if (getuid()) { if (!first_pass) { @@ -615,16 +639,23 @@ int pam_sm_chauthtok( free(p); } } + rc = pam_get_item(pamh, PAM_OLDAUTHTOK, &p); + if (rc) return rc; } else { rc = PAM_SUCCESS; } + if (!ctx->dn) { + rc = pam_do_pwmod(ctx, username, svc, p, NULL, &err); + NSS2PAM_RC(rc, ignore_flags, PAM_SUCCESS); + } return rc; } - if (getuid()) { - rc = pam_get_item(pamh, PAM_OLDAUTHTOK, &p); - if (rc) return rc; - } + rc = pam_get_item(pamh, PAM_OLDAUTHTOK, &p); + if (rc) return rc; + + if (!p) + p = ctx->oldpw; if (first_pass) { rc = pam_get_item(pamh, PAM_AUTHTOK, &q); @@ -646,7 +677,7 @@ int pam_sm_chauthtok( if (rc != PAM_SUCCESS) return rc; } - rc = pam_do_pwmod(ctx, username, p, q, &err); + rc = pam_do_pwmod(ctx, username, svc, p, q, &err); p = NULL; q = NULL; NSS2PAM_RC(rc, ignore_flags, PAM_SUCCESS); if (rc == PAM_SUCCESS) { diff --git a/contrib/slapd-modules/nssov/pam.c b/contrib/slapd-modules/nssov/pam.c index b735465e7c..a960547fe0 100644 --- a/contrib/slapd-modules/nssov/pam.c +++ b/contrib/slapd-modules/nssov/pam.c @@ -19,7 +19,11 @@ static int ppolicy_cid; -struct bindinfo { +struct paminfo { + struct berval uid; + struct berval dn; + struct berval svc; + struct berval pwd; int authz; struct berval msg; }; @@ -27,7 +31,7 @@ struct bindinfo { static int pam_bindcb( Operation *op, SlapReply *rs) { - struct bindinfo *bi = op->o_callback->sc_private; + struct paminfo *pi = op->o_callback->sc_private; LDAPControl *ctrl = ldap_control_find(LDAP_CONTROL_PASSWORDPOLICYRESPONSE, rs->sr_ctrls, NULL); if (ctrl) { @@ -68,23 +72,23 @@ static int pam_bindcb( unit = "years"; } #endif - bi->msg.bv_len = sprintf(bi->msg.bv_val, + pi->msg.bv_len = sprintf(pi->msg.bv_val, "\nWARNING: Password expires in %d %s\n", expire, unit); } else if (grace > 0) { - bi->msg.bv_len = sprintf(bi->msg.bv_val, + pi->msg.bv_len = sprintf(pi->msg.bv_val, "Password expired; %d grace logins remaining", grace); - bi->authz = PAM_NEW_AUTHTOK_REQD; + pi->authz = PAM_NEW_AUTHTOK_REQD; } else if (error != PP_noError) { ber_str2bv(ldap_passwordpolicy_err2txt(error), 0, 0, - &bi->msg); + &pi->msg); switch (error) { case PP_passwordExpired: /* report this during authz */ rs->sr_err = LDAP_SUCCESS; /* fallthru */ case PP_changeAfterReset: - bi->authz = PAM_NEW_AUTHTOK_REQD; + pi->authz = PAM_NEW_AUTHTOK_REQD; } } } @@ -94,69 +98,58 @@ static int pam_bindcb( return LDAP_SUCCESS; } -int pam_authc(nssov_info *ni,TFILE *fp,Operation *op) +int pam_do_bind(nssov_info *ni,TFILE *fp,Operation *op, + struct paminfo *pi) { - int32_t tmpint32; int rc; slap_callback cb = {0}; SlapReply rs = {REP_RESULT}; - char uidc[32]; - char svcc[256]; - char pwdc[256]; - struct berval uid, svc, pwd, sdn, dn; - struct bindinfo bi; - - bi.authz = PAM_SUCCESS; - bi.msg.bv_val = pwdc; - bi.msg.bv_len = 0; - - READ_STRING_BUF2(fp,uidc,sizeof(uidc)); - uid.bv_val = uidc; - uid.bv_len = tmpint32; - READ_STRING_BUF2(fp,svcc,sizeof(svcc)); - svc.bv_val = svcc; - svc.bv_len = tmpint32; - READ_STRING_BUF2(fp,pwdc,sizeof(pwdc)); - pwd.bv_val = pwdc; - pwd.bv_len = tmpint32; + struct berval sdn; - Debug(LDAP_DEBUG_TRACE,"nssov_pam_authc(%s)\n",uid.bv_val,0,0); + pi->msg.bv_val = pi->pwd.bv_val; + pi->msg.bv_len = 0; + pi->authz = PAM_SUCCESS; + BER_BVZERO(&pi->dn); - if (!isvalidusername(&uid)) { - Debug(LDAP_DEBUG_ANY,"nssov_pam_authc(%s): invalid user name\n",uid.bv_val,0,0); + if (!isvalidusername(&pi->uid)) { + Debug(LDAP_DEBUG_ANY,"nssov_pam_do_bind(%s): invalid user name\n", + pi->uid.bv_val,0,0); rc = PAM_USER_UNKNOWN; goto finish; } - BER_BVZERO(&dn); - if (ni->ni_pam_opts & NI_PAM_SASL2DN) { int hlen = global_host_bv.bv_len; /* cn=+uid=,cn=,cn=pam,cn=auth */ - sdn.bv_len = uid.bv_len + svc.bv_len + hlen + + sdn.bv_len = pi->uid.bv_len + pi->svc.bv_len + hlen + STRLENOF( "cn=+uid=,cn=,cn=pam,cn=auth" ); sdn.bv_val = op->o_tmpalloc( sdn.bv_len + 1, op->o_tmpmemctx ); sprintf(sdn.bv_val, "cn=%s+uid=%s,cn=%s,cn=pam,cn=auth", - svcc, uidc, global_host_bv.bv_val); - slap_sasl2dn(op, &sdn, &dn, 0); + pi->svc.bv_val, pi->uid.bv_val, global_host_bv.bv_val); + slap_sasl2dn(op, &sdn, &pi->dn, 0); op->o_tmpfree( sdn.bv_val, op->o_tmpmemctx ); } /* If no luck, do a basic uid search */ - if (BER_BVISEMPTY(&dn) && (ni->ni_pam_opts & NI_PAM_UID2DN)) { - nssov_uid2dn(op, ni, &uid, &dn); - if (!BER_BVISEMPTY(&dn)) { - sdn = dn; - dnNormalize( 0, NULL, NULL, &sdn, &dn, op->o_tmpmemctx ); + if (BER_BVISEMPTY(&pi->dn) && (ni->ni_pam_opts & NI_PAM_UID2DN)) { + nssov_uid2dn(op, ni, &pi->uid, &pi->dn); + if (!BER_BVISEMPTY(&pi->dn)) { + sdn = pi->dn; + dnNormalize( 0, NULL, NULL, &sdn, &pi->dn, op->o_tmpmemctx ); } } BER_BVZERO(&sdn); - if (BER_BVISEMPTY(&dn)) { + if (BER_BVISEMPTY(&pi->dn)) { rc = PAM_USER_UNKNOWN; goto finish; } + if (BER_BVISEMPTY(&pi->pwd)) { + rc = PAM_IGNORE; + goto finish; + } + /* Should only need to do this once at open time, but there's always * the possibility that ppolicy will get loaded later. */ @@ -169,7 +162,7 @@ int pam_authc(nssov_info *ni,TFILE *fp,Operation *op) op->o_ctrlflag[ppolicy_cid] = SLAP_CONTROL_NONCRITICAL; } cb.sc_response = pam_bindcb; - cb.sc_private = &bi; + cb.sc_private = pi; op->o_callback = &cb; op->o_dn.bv_val[0] = 0; op->o_dn.bv_len = 0; @@ -178,12 +171,12 @@ int pam_authc(nssov_info *ni,TFILE *fp,Operation *op) op->o_tag = LDAP_REQ_BIND; op->o_protocol = LDAP_VERSION3; op->orb_method = LDAP_AUTH_SIMPLE; - op->orb_cred = pwd; - op->o_req_dn = dn; - op->o_req_ndn = dn; + op->orb_cred = pi->pwd; + op->o_req_dn = pi->dn; + op->o_req_ndn = pi->dn; slap_op_time( &op->o_time, &op->o_tincr ); rc = op->o_bd->be_bind( op, &rs ); - memset(pwd.bv_val,0,pwd.bv_len); + memset(pi->pwd.bv_val,0,pi->pwd.bv_len); /* quirk: on successful bind, caller has to send result. we need * to make sure callbacks run. */ @@ -194,15 +187,50 @@ int pam_authc(nssov_info *ni,TFILE *fp,Operation *op) case LDAP_INVALID_CREDENTIALS: rc = PAM_AUTH_ERR; break; default: rc = PAM_AUTH_ERR; break; } +finish: + return rc; +} + +int pam_authc(nssov_info *ni,TFILE *fp,Operation *op) +{ + int32_t tmpint32; + int rc; + slap_callback cb = {0}; + SlapReply rs = {REP_RESULT}; + char dnc[1024]; + char uidc[32]; + char svcc[256]; + char pwdc[256]; + struct berval sdn, dn; + struct paminfo pi; + + + READ_STRING_BUF2(fp,uidc,sizeof(uidc)); + pi.uid.bv_val = uidc; + pi.uid.bv_len = tmpint32; + READ_STRING_BUF2(fp,dnc,sizeof(dnc)); + pi.dn.bv_val = dnc; + pi.dn.bv_len = tmpint32; + READ_STRING_BUF2(fp,svcc,sizeof(svcc)); + pi.svc.bv_val = svcc; + pi.svc.bv_len = tmpint32; + READ_STRING_BUF2(fp,pwdc,sizeof(pwdc)); + 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); + + rc = pam_do_bind(ni, fp, op, &pi); finish: WRITE_INT32(fp,NSLCD_VERSION); WRITE_INT32(fp,NSLCD_ACTION_PAM_AUTHC); WRITE_INT32(fp,NSLCD_RESULT_SUCCESS); + WRITE_BERVAL(fp,&pi.uid); + WRITE_BERVAL(fp,&pi.dn); WRITE_INT32(fp,rc); - WRITE_INT32(fp,bi.authz); /* authz */ - WRITE_BERVAL(fp,&dn); - WRITE_BERVAL(fp,&bi.msg); /* authzmsg */ + WRITE_INT32(fp,pi.authz); /* authz */ + WRITE_BERVAL(fp,&pi.msg); /* authzmsg */ return 0; } @@ -222,11 +250,11 @@ static struct berval uidmsg = int pam_authz(nssov_info *ni,TFILE *fp,Operation *op) { - struct berval dn, svc; + struct berval dn, uid, svc; struct berval authzmsg = BER_BVNULL; - struct berval tmpluser = BER_BVNULL; int32_t tmpint32; char dnc[1024]; + char uidc[32]; char svcc[256]; int rc = PAM_SUCCESS; Entry *e = NULL; @@ -234,6 +262,9 @@ int pam_authz(nssov_info *ni,TFILE *fp,Operation *op) SlapReply rs = {REP_RESULT}; slap_callback cb = {0}; + READ_STRING_BUF2(fp,uidc,sizeof(uidc)); + uid.bv_val = uidc; + uid.bv_len = tmpint32; READ_STRING_BUF2(fp,dnc,sizeof(dnc)); dn.bv_val = dnc; dn.bv_len = tmpint32; @@ -399,18 +430,19 @@ int pam_authz(nssov_info *ni,TFILE *fp,Operation *op) if (ni->ni_pam_template_ad) { a = attr_find(e->e_attrs, ni->ni_pam_template_ad); if (a) - tmpluser = a->a_vals[0]; + uid = a->a_vals[0]; else if (!BER_BVISEMPTY(&ni->ni_pam_template)) - tmpluser = ni->ni_pam_template; + uid = ni->ni_pam_template; } finish: WRITE_INT32(fp,NSLCD_VERSION); WRITE_INT32(fp,NSLCD_ACTION_PAM_AUTHZ); WRITE_INT32(fp,NSLCD_RESULT_SUCCESS); + WRITE_BERVAL(fp,&uid); + WRITE_BERVAL(fp,&dn); WRITE_INT32(fp,rc); WRITE_BERVAL(fp,&authzmsg); - WRITE_BERVAL(fp,&tmpluser); if (e) { be_entry_release_r(op, e); } @@ -419,11 +451,15 @@ finish: int pam_sess_o(nssov_info *ni,TFILE *fp,Operation *op) { - struct berval dn, svc; + struct berval dn, uid, svc; int32_t tmpint32; char dnc[1024]; char svcc[256]; + char uidc[32]; + READ_STRING_BUF2(fp,uidc,sizeof(uidc)); + uid.bv_val = uidc; + uid.bv_len = tmpint32; READ_STRING_BUF2(fp,dnc,sizeof(dnc)); dn.bv_val = dnc; dn.bv_len = tmpint32; @@ -441,11 +477,15 @@ int pam_sess_o(nssov_info *ni,TFILE *fp,Operation *op) int pam_sess_c(nssov_info *ni,TFILE *fp,Operation *op) { - struct berval dn, svc; + struct berval dn, uid, svc; int32_t tmpint32; char dnc[1024]; char svcc[256]; + char uidc[32]; + READ_STRING_BUF2(fp,uidc,sizeof(uidc)); + uid.bv_val = uidc; + uid.bv_len = tmpint32; READ_STRING_BUF2(fp,dnc,sizeof(dnc)); dn.bv_val = dnc; dn.bv_len = tmpint32; @@ -463,33 +503,82 @@ int pam_sess_c(nssov_info *ni,TFILE *fp,Operation *op) int pam_pwmod(nssov_info *ni,TFILE *fp,Operation *op) { - struct berval dn, uid, opw, npw; + struct berval npw; int32_t tmpint32; char dnc[1024]; - char uidc[256]; + char uidc[32]; char opwc[256]; char npwc[256]; + char svcc[256]; + struct paminfo pi; + int rc; - READ_STRING_BUF2(fp,dnc,sizeof(dnc)); - dn.bv_val = dnc; - dn.bv_len = tmpint32; READ_STRING_BUF2(fp,uidc,sizeof(uidc)); - uid.bv_val = uidc; - uid.bv_len = tmpint32; + pi.uid.bv_val = uidc; + pi.uid.bv_len = tmpint32; + READ_STRING_BUF2(fp,dnc,sizeof(dnc)); + pi.dn.bv_val = dnc; + pi.dn.bv_len = tmpint32; + READ_STRING_BUF2(fp,svcc,sizeof(svcc)); + pi.svc.bv_val = svcc; + pi.svc.bv_len = tmpint32; READ_STRING_BUF2(fp,opwc,sizeof(opwc)); - opw.bv_val = opwc; - opw.bv_len = tmpint32; + pi.pwd.bv_val = opwc; + pi.pwd.bv_len = tmpint32; READ_STRING_BUF2(fp,npwc,sizeof(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); + Debug(LDAP_DEBUG_TRACE,"nssov_pam_pwmod(%s), %s\n", + pi.dn.bv_val,pi.uid.bv_val,0); + + BER_BVZERO(&pi.msg); + + /* This is a prelim check */ + if (BER_BVISEMPTY(&pi.dn)) { + rc = pam_do_bind(ni,fp,op,&pi); + if (rc == PAM_IGNORE) + rc = PAM_SUCCESS; + } 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; + 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 = pam_nullcb; + 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 = PAM_SUCCESS; + else + rc = PAM_PERM_DENIED; + } WRITE_INT32(fp,NSLCD_VERSION); WRITE_INT32(fp,NSLCD_ACTION_PAM_PWMOD); WRITE_INT32(fp,NSLCD_RESULT_SUCCESS); - WRITE_INT32(fp,PAM_SUCCESS); - WRITE_BERVAL(fp,&npw); + WRITE_BERVAL(fp,&pi.uid); + WRITE_BERVAL(fp,&pi.dn); + WRITE_INT32(fp,rc); + WRITE_BERVAL(fp,&pi.msg); return 0; }