X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fpasswd.c;h=a262a9911aa74009a485b084d9ad4139f9e2d982;hb=4a8d8eb78a610baefde7f5b3e0a371961dafff84;hp=f0e97b6b9bd5e008812bc90bb39437fe6e20458c;hpb=dbb4593d756a3a6d54739a1945da59198d5af5cc;p=openldap diff --git a/servers/slapd/passwd.c b/servers/slapd/passwd.c index f0e97b6b9b..a262a9911a 100644 --- a/servers/slapd/passwd.c +++ b/servers/slapd/passwd.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2004 The OpenLDAP Foundation. + * Copyright 1998-2005 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,6 +27,7 @@ #include #include +#include static const char *defhash[] = { #ifdef LUTIL_SHA1_BYTES @@ -43,13 +44,14 @@ int passwd_extop( { struct berval id = {0, NULL}, hash, *rsp = NULL; req_pwdexop_s *qpw = &op->oq_pwdexop; + req_extended_s qext = op->oq_extended; Modifications *ml; - Operation op2; slap_callback cb = { NULL, slap_null_cb, NULL, NULL }; slap_callback cb2 = { NULL, slap_replog_cb, NULL, NULL }; int i, nhash; char **hashes; int rc; + BackendDB *op_be; cb2.sc_next = &cb; @@ -81,7 +83,7 @@ int passwd_extop( rc = rs->sr_err; goto error_return; } - op->o_bd = select_backend( &op->o_req_ndn, 0, 0 ); + op->o_bd = select_backend( &op->o_req_ndn, 0, 1 ); } else { ber_dupbv_x( &op->o_req_dn, &op->o_dn, op->o_tmpmemctx ); @@ -107,12 +109,23 @@ int passwd_extop( goto error_return; } + /* If we've got a glued backend, check the real backend */ + op_be = op->o_bd; + if ( SLAP_GLUE_INSTANCE( op->o_bd )) { + op->o_bd = select_backend( &op->o_req_ndn, 0, 0 ); + } + if (backend_check_restrictions( op, rs, (struct berval *)&slap_EXOP_MODIFY_PASSWD ) != LDAP_SUCCESS) { rc = rs->sr_err; goto error_return; } + /* check for referrals */ + if ( backend_check_referrals( op, rs ) != LDAP_SUCCESS ) { + rc = rs->sr_err; + goto error_return; + } #ifndef SLAPD_MULTIMASTER /* This does not apply to multi-master case */ @@ -153,6 +166,8 @@ int passwd_extop( goto error_return; } + op->o_bd = op_be; + /* Give the backend a chance to handle this itself */ if ( op->o_bd->be_extended ) { rs->sr_err = op->o_bd->be_extended( op, rs ); @@ -202,27 +217,27 @@ int passwd_extop( rs->sr_err = LDAP_OTHER; } else { - op2 = *op; - op2.o_tag = LDAP_REQ_MODIFY; - op2.o_callback = &cb2; - op2.orm_modlist = qpw->rs_mods; + slap_callback *sc = op->o_callback; + + op->o_tag = LDAP_REQ_MODIFY; + op->o_callback = &cb2; + op->orm_modlist = qpw->rs_mods; cb2.sc_private = qpw; /* let Modify know this was pwdMod, * if it cares... */ - rs->sr_err = slap_mods_opattrs( &op2, ml, qpw->rs_modtail, &rs->sr_text, - NULL, 0 ); + rs->sr_err = slap_mods_opattrs( op, ml, qpw->rs_modtail, &rs->sr_text, + NULL, 0, 1 ); if ( rs->sr_err == LDAP_SUCCESS ) { - rs->sr_err = op2.o_bd->be_modify( &op2, rs ); - /* FIXME: in case it got rewritten... */ - op->o_req_dn = op2.o_req_dn; - op->o_req_ndn = op2.o_req_ndn; + rs->sr_err = op->o_bd->be_modify( op, rs ); } if ( rs->sr_err == LDAP_SUCCESS ) { rs->sr_rspdata = rsp; } else if ( rsp ) { ber_bvfree( rsp ); } + op->o_tag = LDAP_REQ_EXTENDED; + op->o_callback = sc; } slap_mods_free( qpw->rs_mods ); if ( rsp ) { @@ -230,6 +245,7 @@ int passwd_extop( } rc = rs->sr_err; + op->oq_extended = qext; error_return:; if ( !BER_BVISNULL( &op->o_req_dn ) ) { @@ -269,13 +285,8 @@ int slap_passwd_parse( struct berval *reqdata, tag = ber_scanf( ber, "{" /*}*/ ); if( tag == LBER_ERROR ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "slap_passwd_parse: decoding error\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: decoding error\n", 0, 0, 0 ); -#endif rc = LDAP_PROTOCOL_ERROR; goto done; } @@ -283,13 +294,8 @@ int slap_passwd_parse( struct berval *reqdata, tag = ber_peek_tag( ber, &len ); if( tag == LDAP_TAG_EXOP_MODIFY_PASSWD_ID ) { if( id == NULL ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "slap_passwd_parse: ID not allowed.\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ID not allowed.\n", 0, 0, 0 ); -#endif *text = "user must change own password"; rc = LDAP_UNWILLING_TO_PERFORM; @@ -299,13 +305,8 @@ int slap_passwd_parse( struct berval *reqdata, tag = ber_scanf( ber, "m", id ); if( tag == LBER_ERROR ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "slap_passwd_parse: ID parse failed.\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ID parse failed.\n", 0, 0, 0 ); -#endif goto decoding_error; } @@ -315,13 +316,8 @@ int slap_passwd_parse( struct berval *reqdata, if( tag == LDAP_TAG_EXOP_MODIFY_PASSWD_OLD ) { if( oldpass == NULL ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "slap_passwd_parse: OLD not allowed.\n" , 0, 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: OLD not allowed.\n", 0, 0, 0 ); -#endif *text = "use bind to verify old password"; rc = LDAP_UNWILLING_TO_PERFORM; @@ -331,13 +327,8 @@ int slap_passwd_parse( struct berval *reqdata, tag = ber_scanf( ber, "m", oldpass ); if( tag == LBER_ERROR ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "slap_passwd_parse: ID parse failed.\n" , 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ID parse failed.\n", + Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: OLD parse failed.\n", 0, 0, 0 ); -#endif goto decoding_error; } @@ -347,13 +338,8 @@ int slap_passwd_parse( struct berval *reqdata, if( tag == LDAP_TAG_EXOP_MODIFY_PASSWD_NEW ) { if( newpass == NULL ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "slap_passwd_parse: NEW not allowed.\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: NEW not allowed.\n", 0, 0, 0 ); -#endif *text = "user specified passwords disallowed"; rc = LDAP_UNWILLING_TO_PERFORM; @@ -363,13 +349,8 @@ int slap_passwd_parse( struct berval *reqdata, tag = ber_scanf( ber, "m", newpass ); if( tag == LBER_ERROR ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "slap_passwd_parse: OLD parse failed.\n", 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: OLD parse failed.\n", + Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: NEW parse failed.\n", 0, 0, 0 ); -#endif goto decoding_error; } @@ -379,14 +360,9 @@ int slap_passwd_parse( struct berval *reqdata, if( len != 0 ) { decoding_error: -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "slap_passwd_parse: decoding error, len=%ld\n", (long)len, 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: decoding error, len=%ld\n", (long) len, 0, 0 ); -#endif *text = "data decoding error"; rc = LDAP_PROTOCOL_ERROR; @@ -407,13 +383,8 @@ struct berval * slap_passwd_return( assert( cred != NULL ); -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ENTRY, - "slap_passwd_return: %ld\n",(long)cred->bv_len, 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "slap_passwd_return: %ld\n", (long) cred->bv_len, 0, 0 ); -#endif ber_init_w_nullc( ber, LBER_USE_DER ); @@ -429,25 +400,37 @@ struct berval * slap_passwd_return( return bv; } +/* + * if "e" is provided, access to each value of the password is checked first + */ int slap_passwd_check( - Connection *conn, - Attribute *a, - struct berval *cred, - const char **text ) + Operation *op, + Entry *e, + Attribute *a, + struct berval *cred, + const char **text ) { - int result = 1; - struct berval *bv; + int result = 1; + struct berval *bv; + AccessControlState acl_state = ACL_STATE_INIT; #if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD ) ldap_pvt_thread_mutex_lock( &passwd_mutex ); #ifdef SLAPD_SPASSWD - lutil_passwd_sasl_conn = conn->c_sasl_authctx; + lutil_passwd_sasl_conn = op->o_conn->c_sasl_authctx; #endif #endif for ( bv = a->a_vals; bv->bv_val != NULL; bv++ ) { - if( !lutil_passwd( bv, cred, NULL, text ) ) { + /* if e is provided, check access */ + if ( e && access_allowed( op, e, a->a_desc, bv, + ACL_AUTH, &acl_state ) == 0 ) + { + continue; + } + + if ( !lutil_passwd( bv, cred, NULL, text ) ) { result = 0; break; } @@ -466,11 +449,7 @@ slap_passwd_check( void slap_passwd_generate( struct berval *pass ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ENTRY, "slap_passwd_generate: begin\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "slap_passwd_generate\n", 0, 0, 0 ); -#endif pass->bv_val = NULL; pass->bv_len = 0;