From: Kurt Zeilenga Date: Tue, 26 Sep 2000 03:47:56 +0000 (+0000) Subject: Rough in passwd and referral routines X-Git-Tag: LDBM_PRE_GIANT_RWLOCK~1888 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=ebae2e5c621ca1ff088cc5a1c723fa1f547b9761;p=openldap Rough in passwd and referral routines add diag and fix a few idl bugs --- diff --git a/servers/slapd/back-bdb/dn2id.c b/servers/slapd/back-bdb/dn2id.c index 918f556f10..fa4fe3fc05 100644 --- a/servers/slapd/back-bdb/dn2id.c +++ b/servers/slapd/back-bdb/dn2id.c @@ -85,8 +85,7 @@ bdb_dn2id_add( Debug( LDAP_DEBUG_ANY, "=> bdb_dn2id_add: subtree (%s) insert failed: %d\n", subtree[i], rc, 0 ); - charray_free( subtree ); - goto done; + break; } } @@ -96,7 +95,7 @@ bdb_dn2id_add( done: ch_free( key.data ); - Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_add %d\n", rc, 0, 0 ); + Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_add: %d\n", rc, 0, 0 ); return rc; } diff --git a/servers/slapd/back-bdb/external.h b/servers/slapd/back-bdb/external.h index 6b721685de..db1ccac2c7 100644 --- a/servers/slapd/back-bdb/external.h +++ b/servers/slapd/back-bdb/external.h @@ -55,6 +55,14 @@ extern int bdb_search LDAP_P(( BackendDB *bd, extern int bdb_unbind LDAP_P(( BackendDB *bd, Connection *conn, Operation *op )); +extern int bdb_referrals( + BackendDB *be, + Connection *conn, + Operation *op, + const char *dn, + const char *ndn, + const char **text ); + LDAP_END_DECL #endif /* _BDB_EXTERNAL_H */ diff --git a/servers/slapd/back-bdb/idl.c b/servers/slapd/back-bdb/idl.c index 3206e2f216..fd8c7b8804 100644 --- a/servers/slapd/back-bdb/idl.c +++ b/servers/slapd/back-bdb/idl.c @@ -49,15 +49,16 @@ int bdb_idl_search( ID *ids, ID id ) } else { return cursor + 1; } + #else - /* linear search */ + /* (reverse) linear search */ int i; - for( i=1; i<=ids[0]; i++ ) { - if( id <= ids[i] ) { - return i; + for( i=ids[0]; i; i-- ) { + if( id > ids[i] ) { + break; } } - return i; + return i+1; #endif } @@ -65,17 +66,19 @@ static int idl_insert( ID *ids, ID id ) { int x = bdb_idl_search( ids, id ); - if( ids[x] == id ) { - /* duplicate */ + assert( x > 0 ); + + if( x <= 0 ) { + /* internal error */ return -1; } - if( x == 0 ) { - /* append the id */ - ids[0]++; - ids[ids[0]] = id; + if ( ids[x] == id ) { + /* duplicate */ + return -1; + } - } else if ( ++ids[0] >= BDB_IDL_DB_MAX ) { + if ( ++ids[0] >= BDB_IDL_DB_MAX ) { ids[0] = NOID; } else { @@ -92,12 +95,21 @@ static int idl_delete( ID *ids, ID id ) { int x = bdb_idl_search( ids, id ); - if( x == 0 || ids[x] != id ) { + assert( x > 0 ); + + if( x <= 0 ) { + /* internal error */ + return -1; + } + + if( x > ids[0] || ids[x] != id ) { /* not found */ return -1; } else if ( --ids[0] == 0 ) { - if( x != 1 ) return -1; + if( x != 1 ) { + return -1; + } } else { AC_MEMCPY( &ids[x], &ids[x+1], (1+ids[0]-x) * sizeof(ID) ); @@ -165,7 +177,11 @@ bdb_idl_insert_key( return rc; } - data.size = (ids[0]+1) * sizeof( ID ); + if( BDB_IS_ALLIDS( ids ) ) { + data.size = sizeof( ID ); + } else { + data.size = (ids[0]+1) * sizeof( ID ); + } } /* store the key */ @@ -233,7 +249,7 @@ bdb_idl_delete_key( return rc; } - if( BDB_IS_ALLIDS(ids) ) { + if( ids[0] == 0 ) { /* delete the key */ rc = db->del( db, tid, key, 0 ); if( rc != 0 ) { diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c index 6f63d36e20..632d601aa8 100644 --- a/servers/slapd/back-bdb/init.c +++ b/servers/slapd/back-bdb/init.c @@ -317,6 +317,7 @@ bdb_initialize( bi->bi_acl_group = bdb_group; bi->bi_acl_attribute = bdb_attribute; + bi->bi_chk_referrals = bdb_referrals; #endif diff --git a/servers/slapd/back-bdb/passwd.c b/servers/slapd/back-bdb/passwd.c new file mode 100644 index 0000000000..ba8e80ed96 --- /dev/null +++ b/servers/slapd/back-bdb/passwd.c @@ -0,0 +1,161 @@ +/* passwd.c - bdb backend password routines */ +/* $OpenLDAP$ */ +/* + * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. + * COPYING RESTRICTIONS APPLY, see COPYRIGHT file + */ + +#include "portable.h" + +#include +#include + +#include "back-bdb.h" + +int +bdb_exop_passwd( + Backend *be, + Connection *conn, + Operation *op, + const char *reqoid, + struct berval *reqdata, + char **rspoid, + struct berval **rspdata, + LDAPControl *** rspctrls, + const char **text, + struct berval *** refs +) +{ + struct bdb_info *bdb = (struct bdb_info *) be->be_private; + int rc; + Entry *e = NULL; + struct berval *hash = NULL; + DB_TXN *ltid; + + struct berval *id = NULL; + struct berval *new = NULL; + + char *dn; + + assert( reqoid != NULL ); + assert( strcmp( LDAP_EXOP_X_MODIFY_PASSWD, reqoid ) == 0 ); + + rc = slap_passwd_parse( reqdata, + &id, NULL, &new, text ); + + Debug( LDAP_DEBUG_ARGS, "==> bdb_exop_passwd: \"%s\"\n", + id ? id->bv_val : "", 0, 0 ); + + if( rc != LDAP_SUCCESS ) { + goto done; + } + + if( new == NULL || new->bv_len == 0 ) { + new = slap_passwd_generate(); + + if( new == NULL || new->bv_len == 0 ) { + *text = "password generation failed."; + rc = LDAP_OTHER; + goto done; + } + + *rspdata = slap_passwd_return( new ); + } + + hash = slap_passwd_hash( new ); + + if( hash == NULL || hash->bv_len == 0 ) { + *text = "password hash failed"; + rc = LDAP_OTHER; + goto done; + } + + dn = id ? id->bv_val : op->o_dn; + + Debug( LDAP_DEBUG_TRACE, "passwd: \"%s\"%s\n", + dn, id ? " (proxy)" : "", 0 ); + + if( dn == NULL || dn[0] == '\0' ) { + *text = "No password is associated with the Root DSE"; + rc = LDAP_OPERATIONS_ERROR; + goto done; + } + + /* fetch entry */ + rc = dn2entry_w( be, NULL, dn, &e, NULL ); + + switch(rc) { + case DB_NOTFOUND: + case 0: + break; + default: + send_ldap_result( conn, op, rc=LDAP_OTHER, + NULL, "internal error", NULL, NULL ); + return rc; + } + + if( e == NULL ) { + *text = "could not locate authorization entry"; + rc = LDAP_OPERATIONS_ERROR; + goto done; + } + + if( is_entry_alias( e ) ) { + /* entry is an alias, don't allow operation */ + *text = "authorization entry is alias"; + rc = LDAP_ALIAS_PROBLEM; + goto done; + } + + rc = LDAP_OPERATIONS_ERROR; + + if( is_entry_referral( e ) ) { + /* entry is an referral, don't allow operation */ + *text = "authorization entry is referral"; + goto done; + } + + { + Modifications ml; + struct berval *vals[2]; + + vals[0] = hash; + vals[1] = NULL; + + ml.sml_desc = slap_schema.si_ad_userPassword; + ml.sml_bvalues = vals; + ml.sml_op = LDAP_MOD_REPLACE; + ml.sml_next = NULL; + + rc = bdb_modify_internal( be, + conn, op, op->o_ndn, &ml, e, text ); + + } + + if( rc == LDAP_SUCCESS ) { + /* change the entry itself */ + if( bdb_id2entry_add( be, ltid, e ) != 0 ) { + *text = "entry update failed"; + rc = LDAP_OTHER; + } + } + +done: + if( e != NULL ) { + bdb_entry_return( be, e ); + } + + if( id != NULL ) { + ber_bvfree( id ); + } + + if( new != NULL ) { + ber_bvfree( new ); + } + + if( hash != NULL ) { + ber_bvfree( hash ); + } + + return rc; +} diff --git a/servers/slapd/back-bdb/referral.c b/servers/slapd/back-bdb/referral.c new file mode 100644 index 0000000000..6629f9e037 --- /dev/null +++ b/servers/slapd/back-bdb/referral.c @@ -0,0 +1,101 @@ +/* referral.c - LDBM backend referral handler */ +/* $OpenLDAP$ */ +/* + * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved. + * COPYING RESTRICTIONS APPLY, see COPYRIGHT file + */ + +#include "portable.h" +#include +#include + +#include "back-bdb.h" + +int +bdb_referrals( + BackendDB *be, + Connection *conn, + Operation *op, + const char *dn, + const char *ndn, + const char **text ) +{ + struct bdb_info *bdb = (struct bdb_info *) be->be_private; + int rc = LDAP_SUCCESS; + Entry *e, *matched; + + if( op->o_tag == LDAP_REQ_SEARCH ) { + /* let search take care of itself */ + return rc; + } + + if( get_manageDSAit( op ) ) { + /* let op take care of DSA management */ + return rc; + } + + /* fetch entry */ + rc = dn2entry_r( be, NULL, ndn, &e, &matched ); + + switch(rc) { + case DB_NOTFOUND: + case 0: + break; + default: + send_ldap_result( conn, op, rc=LDAP_OTHER, + NULL, "internal error", NULL, NULL ); + return rc; + } + + if ( e == NULL ) { + char *matched_dn = NULL; + struct berval **refs = default_referral; + + if ( matched != NULL ) { + matched_dn = ch_strdup( matched->e_dn ); + + Debug( LDAP_DEBUG_TRACE, + "ldbm_referrals: op=%ld target=\"%s\" matched=\"%s\"\n", + op->o_tag, dn, matched_dn ); + + refs = is_entry_referral( matched ) + ? get_entry_referrals( be, conn, op, matched ) + : NULL; + + bdb_entry_return( be, matched ); + } + + if( refs != NULL ) { + /* send referrals */ + send_ldap_result( conn, op, rc = LDAP_REFERRAL, + matched_dn, NULL, refs, NULL ); + } + + if( matched != NULL ) { + ber_bvecfree( refs ); + free( matched_dn ); + } + + return rc; + } + + if ( is_entry_referral( e ) ) { + /* entry is a referral */ + struct berval **refs = get_entry_referrals( be, + conn, op, e ); + + Debug( LDAP_DEBUG_TRACE, + "ldbm_referrals: op=%ld target=\"%s\" matched=\"%s\"\n", + op->o_tag, dn, e->e_dn ); + + if( refs != NULL ) { + send_ldap_result( conn, op, rc = LDAP_REFERRAL, + e->e_dn, NULL, refs, NULL ); + } + + ber_bvecfree( refs ); + } + + bdb_entry_return( be, e ); + return rc; +}