From ebb9e029a79638915ada85f8892609e6369380ed Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sun, 23 Sep 2007 04:40:51 +0000 Subject: [PATCH] Make slap_passwd_parse non-destructive --- servers/slapd/back-ldap/extended.c | 13 +++++++------ servers/slapd/overlays/rwm.c | 24 +++--------------------- servers/slapd/passwd.c | 23 +++++++++++++++++------ 3 files changed, 27 insertions(+), 33 deletions(-) diff --git a/servers/slapd/back-ldap/extended.c b/servers/slapd/back-ldap/extended.c index cf3aacbb71..57379b8dfa 100644 --- a/servers/slapd/back-ldap/extended.c +++ b/servers/slapd/back-ldap/extended.c @@ -125,11 +125,9 @@ ldap_back_exop_passwd( assert( rs->sr_ctrls == NULL ); if ( BER_BVISNULL( &ndn ) && op->ore_reqdata != NULL ) { - /* NOTE: most of this code is mutuated - * from slap_passwd_parse(); we can't call - * that function since now the request data - * has been destroyed by NULL-terminating - * the bervals. Luckily enough, we only need + /* NOTE: most of this code is mutated + * from slap_passwd_parse(); + * But here we only need * the first berval... */ ber_tag_t tag; @@ -154,7 +152,7 @@ ldap_back_exop_passwd( tag = ber_peek_tag( ber, &len ); if ( tag == LDAP_TAG_EXOP_MODIFY_PASSWD_ID ) { - tag = ber_scanf( ber, "m", &tmpid ); + tag = ber_get_stringbv( ber, &tmpid, LBER_BV_NOTERM ); if ( tag == LBER_ERROR ) { return LDAP_PROTOCOL_ERROR; @@ -162,8 +160,11 @@ ldap_back_exop_passwd( } if ( !BER_BVISEMPTY( &tmpid ) ) { + char idNull = tmpid.bv_val[tmpid.bv_len]; + tmpid.bv_val[tmpid.bv_len] = '\0'; rs->sr_err = dnPrettyNormal( NULL, &tmpid, &dn, &ndn, op->o_tmpmemctx ); + tmpid.bv_val[tmpid.bv_len] = idNull; if ( rs->sr_err != LDAP_SUCCESS ) { /* should have been successfully parsed earlier! */ return rs->sr_err; diff --git a/servers/slapd/overlays/rwm.c b/servers/slapd/overlays/rwm.c index 1afb4654f3..ac430f20e8 100644 --- a/servers/slapd/overlays/rwm.c +++ b/servers/slapd/overlays/rwm.c @@ -844,8 +844,11 @@ rwm_exop_passwd( Operation *op, SlapReply *rs ) } if ( !BER_BVISNULL( &id ) ) { + char idNul = id.bv_val[id.bv_len]; + id.bv_val[id.bv_len] = '\0'; rs->sr_err = dnPrettyNormal( NULL, &id, &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx ); + id.bv_val[id.bv_len] = idNul; if ( rs->sr_err != LDAP_SUCCESS ) { rs->sr_text = "Invalid DN"; return rs->sr_err; @@ -865,27 +868,6 @@ rwm_exop_passwd( Operation *op, SlapReply *rs ) return -1; } - ber = ber_alloc_t( LBER_USE_DER ); - if ( !ber ) { - rs->sr_err = LDAP_OTHER; - rs->sr_text = "No memory"; - return rs->sr_err; - } - ber_printf( ber, "{" ); - if ( !BER_BVISNULL( &id )) { - ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, - &op->o_req_dn ); - } - if ( !BER_BVISNULL( &pwold )) { - ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, &pwold ); - } - if ( !BER_BVISNULL( &pwnew )) { - ber_printf( ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, &pwnew ); - } - ber_printf( ber, "N}" ); - ber_flatten( ber, &op->ore_reqdata ); - ber_free( ber, 1 ); - op->o_callback = &roc->cb; return SLAP_CB_CONTINUE; diff --git a/servers/slapd/passwd.c b/servers/slapd/passwd.c index 9057f969cc..7444b179c2 100644 --- a/servers/slapd/passwd.c +++ b/servers/slapd/passwd.c @@ -53,7 +53,7 @@ int passwd_extop( Modifications *ml; slap_callback cb = { NULL, slap_null_cb, NULL, NULL }; int i, nhash; - char **hashes; + char **hashes, idNul; int rc; BackendDB *op_be; int freenewpw = 0; @@ -77,6 +77,10 @@ int passwd_extop( rs->sr_err = slap_passwd_parse( op->ore_reqdata, &id, &qpw->rs_old, &qpw->rs_new, &rs->sr_text ); + if ( !BER_BVISNULL( &id )) { + idNul = id.bv_val[id.bv_len]; + id.bv_val[id.bv_len] = '\0'; + } if ( rs->sr_err == LDAP_SUCCESS && !BER_BVISEMPTY( &id ) ) { Statslog( LDAP_DEBUG_STATS, "%s PASSMOD id=\"%s\"%s%s\n", op->o_log_prefix, id.bv_val, @@ -90,12 +94,15 @@ int passwd_extop( } if ( rs->sr_err != LDAP_SUCCESS ) { + if ( !BER_BVISNULL( &id )) + id.bv_val[id.bv_len] = idNul; return rs->sr_err; } if ( !BER_BVISEMPTY( &id ) ) { rs->sr_err = dnPrettyNormal( NULL, &id, &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx ); + id.bv_val[id.bv_len] = idNul; if ( rs->sr_err != LDAP_SUCCESS ) { rs->sr_text = "Invalid DN"; rc = rs->sr_err; @@ -318,6 +325,10 @@ error_return:; return rc; } +/* NOTE: The DN in *id is NOT NUL-terminated here. dnNormalize will + * reject it in this condition, the caller must NUL-terminate it. + * FIXME: should dnNormalize still be complaining about that? + */ int slap_passwd_parse( struct berval *reqdata, struct berval *id, struct berval *oldpass, @@ -342,9 +353,9 @@ int slap_passwd_parse( struct berval *reqdata, /* ber_init2 uses reqdata directly, doesn't allocate new buffers */ ber_init2( ber, reqdata, 0 ); - tag = ber_scanf( ber, "{" /*}*/ ); + tag = ber_skip_tag( ber, &len ); - if( tag == LBER_ERROR ) { + if( tag != LBER_SEQUENCE ) { Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: decoding error\n", 0, 0, 0 ); rc = LDAP_PROTOCOL_ERROR; @@ -362,7 +373,7 @@ int slap_passwd_parse( struct berval *reqdata, goto done; } - tag = ber_scanf( ber, "m", id ); + tag = ber_get_stringbv( ber, id, LBER_BV_NOTERM ); if( tag == LBER_ERROR ) { Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ID parse failed.\n", @@ -384,7 +395,7 @@ int slap_passwd_parse( struct berval *reqdata, goto done; } - tag = ber_scanf( ber, "m", oldpass ); + tag = ber_get_stringbv( ber, oldpass, LBER_BV_NOTERM ); if( tag == LBER_ERROR ) { Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: OLD parse failed.\n", @@ -415,7 +426,7 @@ int slap_passwd_parse( struct berval *reqdata, goto done; } - tag = ber_scanf( ber, "m", newpass ); + tag = ber_get_stringbv( ber, newpass, LBER_BV_NOTERM ); if( tag == LBER_ERROR ) { Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: NEW parse failed.\n", -- 2.39.5