]> git.sur5r.net Git - openldap/commitdiff
Rough in passwd and referral routines
authorKurt Zeilenga <kurt@openldap.org>
Tue, 26 Sep 2000 03:47:56 +0000 (03:47 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Tue, 26 Sep 2000 03:47:56 +0000 (03:47 +0000)
add diag and fix a few idl bugs

servers/slapd/back-bdb/dn2id.c
servers/slapd/back-bdb/external.h
servers/slapd/back-bdb/idl.c
servers/slapd/back-bdb/init.c
servers/slapd/back-bdb/passwd.c [new file with mode: 0644]
servers/slapd/back-bdb/referral.c [new file with mode: 0644]

index 918f556f109588ca35e03d2276e3026009175158..fa4fe3fc0598041c0365f3b3782f8f70c13bfa77 100644 (file)
@@ -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;
 }
 
index 6b721685de1e6ebfbe08972fb8c6677157bfeb57..db1ccac2c713e066c0cda9fcbcc5303b1c716b3c 100644 (file)
@@ -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 */
index 3206e2f216ab0f24bde693239116c89eaef67c0b..fd8c7b88046e424c3748be04e4bbee51fd22268f 100644 (file)
@@ -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 ) {
index 6f63d36e206c7c990fbd247e5b1cfb1f150edc3d..632d601aa871ae204887277eb3c33f4d9d19ead4 100644 (file)
@@ -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 (file)
index 0000000..ba8e80e
--- /dev/null
@@ -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 <stdio.h>
+#include <ac/string.h>
+
+#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 (file)
index 0000000..6629f9e
--- /dev/null
@@ -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 <stdio.h>
+#include <ac/string.h>
+
+#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;
+}