]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/slapacl.c
Partially revert prev commit, leave rs->sr_err == SLAPD_ABANDON
[openldap] / servers / slapd / slapacl.c
index 2b325f661ad6208ff6d4459b560416a70773faf3..cc49b215256d48a07534dbd634c5deedd2d89da9 100644 (file)
@@ -1,6 +1,7 @@
+/* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2004-2005 The OpenLDAP Foundation.
+ * Copyright 2004-2009 The OpenLDAP Foundation.
  * Portions Copyright 2004 Pierangelo Masarati.
  * All rights reserved.
  *
@@ -45,7 +46,6 @@ print_access(
        int                     rc;
        slap_mask_t             mask;
        char                    accessmaskbuf[ACCESSMASK_MAXLEN];
-       slap_access_t           access = ACL_AUTH;
 
        rc = access_allowed_mask( op, e, desc, nval, ACL_AUTH, NULL, &mask );
 
@@ -53,7 +53,8 @@ print_access(
                        desc->ad_cname.bv_val,
                        ( val && !BER_BVISNULL( val ) ) ? "=" : "",
                        ( val && !BER_BVISNULL( val ) ) ?
-                               ( desc == slap_schema.si_ad_userPassword ? "****" : val->bv_val ) : "",
+                               ( desc == slap_schema.si_ad_userPassword ?
+                                       "****" : val->bv_val ) : "",
                        accessmask2str( mask, accessmaskbuf, 1 ) );
 
        return rc;
@@ -66,18 +67,38 @@ slapacl( int argc, char **argv )
        const char              *progname = "slapacl";
        Connection              conn = { 0 };
        Listener                listener;
-       char                    opbuf[OPERATION_BUFFER_SIZE];
-       Operation               *op;
+       OperationBuffer opbuf;
+       Operation               *op = NULL;
        Entry                   e = { 0 }, *ep = &e;
        char                    *attr = NULL;
+       int                     doclose = 0;
+       BackendDB               *bd;
 
        slap_tool_init( progname, SLAPACL, argc, argv );
 
+       if ( !dryrun ) {
+               int     i = 0;
+
+               LDAP_STAILQ_FOREACH( bd, &backendDB, be_next ) {
+                       if ( bd != be && backend_startup( bd ) ) {
+                               fprintf( stderr, "backend_startup(#%d%s%s) failed\n",
+                                               i,
+                                               bd->be_suffix ? ": " : "",
+                                               bd->be_suffix ? bd->be_suffix[0].bv_val : "" );
+                               rc = 1;
+                               goto destroy;
+                       }
+
+                       i++;
+               }
+       }
+
        argv = &argv[ optind ];
        argc -= optind;
 
-       op = (Operation *)opbuf;
-       connection_fake_init( &conn, op, &conn );
+       connection_fake_init( &conn, &opbuf, &conn );
+       op = &opbuf.ob_op;
+       op->o_tmpmemctx = NULL;
 
        conn.c_listener = &listener;
        conn.c_listener_url = listener_url;
@@ -166,6 +187,26 @@ slapacl( int argc, char **argv )
                fprintf( stderr, "authzDN: \"%s\"\n", authzDN.bv_val );
        }
 
+       if ( !BER_BVISNULL( &authzDN ) ) {
+               op->o_dn = authzDN;
+               op->o_ndn = authzDN;
+               
+               if ( !BER_BVISNULL( &authcDN ) ) {
+                       op->o_conn->c_dn = authcDN;
+                       op->o_conn->c_ndn = authcDN;
+
+               } else {
+                       op->o_conn->c_dn = authzDN;
+                       op->o_conn->c_ndn = authzDN;
+               }
+
+       } else if ( !BER_BVISNULL( &authcDN ) ) {
+               op->o_conn->c_dn = authcDN;
+               op->o_conn->c_ndn = authcDN;
+               op->o_dn = authcDN;
+               op->o_ndn = authcDN;
+       }
+
        assert( !BER_BVISNULL( &baseDN ) );
        rc = dnPrettyNormal( NULL, &baseDN, &e.e_name, &e.e_nname, NULL );
        if ( rc != LDAP_SUCCESS ) {
@@ -177,18 +218,25 @@ slapacl( int argc, char **argv )
        }
 
        op->o_bd = be;
-       if ( !BER_BVISNULL( &authzDN ) ) {
-               op->o_dn = authzDN;
-               op->o_ndn = authzDN;
-       }
-       if ( !BER_BVISNULL( &authcDN ) ) {
-               op->o_conn->c_dn = authcDN;
-               op->o_conn->c_ndn = authcDN;
+       if ( op->o_bd == NULL ) {
+               /* NOTE: if no database could be found (e.g. because
+                * accessing the rootDSE or so), use the frontendDB
+                * rules; might need work */
+               op->o_bd = frontendDB;
        }
 
-       if ( !dryrun && be ) {
+       if ( !dryrun ) {
                ID      id;
 
+               if ( be == NULL ) {
+                       fprintf( stderr, "%s: no target database "
+                               "has been found for baseDN=\"%s\"; "
+                               "you may try with \"-u\" (dry run).\n",
+                               baseDN.bv_val, progname );
+                       rc = 1;
+                       goto destroy;
+               }
+
                if ( !be->be_entry_open ||
                        !be->be_entry_close ||
                        !be->be_dn2id_get ||
@@ -209,6 +257,8 @@ slapacl( int argc, char **argv )
                        goto destroy;
                }
 
+               doclose = 1;
+
                id = be->be_dn2id_get( be, &e.e_nname );
                if ( id == NOID ) {
                        fprintf( stderr, "%s: unable to fetch ID of DN \"%s\"\n",
@@ -216,7 +266,8 @@ slapacl( int argc, char **argv )
                        rc = 1;
                        goto destroy;
                }
-               if ( be->be_id2entry_get( be, id, &ep ) != 0 ) {
+               ep = be->be_entry_get( be, id );
+               if ( ep == NULL ) {
                        fprintf( stderr, "%s: unable to fetch entry \"%s\" (%lu)\n",
                                progname, e.e_nname.bv_val, id );
                        rc = 1;
@@ -266,12 +317,29 @@ slapacl( int argc, char **argv )
 
                accessstr = strchr( attr, '/' );
                if ( accessstr != NULL ) {
+                       int     invalid = 0;
+
                        accessstr[0] = '\0';
                        accessstr++;
                        access = str2access( accessstr );
-                       if ( access == ACL_INVALID_ACCESS ) {
+                       switch ( access ) {
+                       case ACL_INVALID_ACCESS:
                                fprintf( stderr, "unknown access \"%s\" for attribute \"%s\"\n",
                                                accessstr, attr );
+                               invalid = 1;
+                               break;
+
+                       case ACL_NONE:
+                               fprintf( stderr, "\"none\" not allowed for attribute \"%s\"\n",
+                                               attr );
+                               invalid = 1;
+                               break;
+
+                       default:
+                               break;
+                       }
+
+                       if ( invalid ) {
                                if ( continuemode ) {
                                        continue;
                                }
@@ -312,16 +380,29 @@ slapacl( int argc, char **argv )
        }
 
 destroy:;
-       ber_memfree( e.e_name.bv_val );
-       ber_memfree( e.e_nname.bv_val );
+       if ( !BER_BVISNULL( &e.e_name ) ) {
+               ber_memfree( e.e_name.bv_val );
+       }
+       if ( !BER_BVISNULL( &e.e_nname ) ) {
+               ber_memfree( e.e_nname.bv_val );
+       }
        if ( !dryrun && be ) {
-               if ( ep != &e ) {
+               if ( ep && ep != &e ) {
                        be_entry_release_r( op, ep );
                }
-               be->be_entry_close( be );
+               if ( doclose ) {
+                       be->be_entry_close( be );
+               }
+
+               LDAP_STAILQ_FOREACH( bd, &backendDB, be_next ) {
+                       if ( bd != be ) {
+                               backend_shutdown( bd );
+                       }
+               }
        }
 
-       slap_tool_destroy();
+       if ( slap_tool_destroy())
+               rc = EXIT_FAILURE;
 
        return rc;
 }