]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/result.c
Preliminary checkin for new access_allowed() signature. Still need
[openldap] / servers / slapd / result.c
index 33a5ee1c5f844e415a6e9cb125063f20c9e1b13f..2014864e856dc945a2439af5667095bc7d568d21 100644 (file)
@@ -132,6 +132,50 @@ slap_req2res( ber_tag_t tag )
        return tag;
 }
 
+#ifdef RS_ASSERT
+#elif 0 && defined LDAP_DEVEL /* FIXME: this should not crash. ITS#5340. */
+#define RS_ASSERT assert
+#else
+#define RS_ASSERT(cond) ((void) 0)
+#endif
+
+/* Set rs->sr_entry after obyeing and clearing sr_flags & REP_ENTRY_MASK. */
+void
+rs_replace_entry( Operation *op, SlapReply *rs, slap_overinst *on, Entry *e )
+{
+       slap_mask_t e_flags = rs->sr_flags & REP_ENTRY_MUSTFLUSH;
+
+       if ( e_flags && rs->sr_entry != NULL ) {
+               RS_ASSERT( e_flags != REP_ENTRY_MUSTFLUSH );
+               if ( !(e_flags & REP_ENTRY_MUSTRELEASE) ) {
+                       entry_free( rs->sr_entry );
+               } else if ( on != NULL ) {
+                       overlay_entry_release_ov( op, rs->sr_entry, 0, on );
+               } else {
+                       be_entry_release_rw( op, rs->sr_entry, 0 );
+               }
+       }
+       rs->sr_flags &= ~REP_ENTRY_MASK;
+       rs->sr_entry = e;
+}
+
+/*
+ * Ensure rs->sr_entry is modifiable, by duplicating it if necessary.
+ * Obey sr_flags.  Set REP_ENTRY_<MODIFIABLE, and MUSTBEFREED if duplicated>.
+ * Return nonzero if rs->sr_entry was replaced.
+ */
+int
+rs_ensure_entry_modifiable( Operation *op, SlapReply *rs, slap_overinst *on )
+{
+       if ( rs->sr_flags & REP_ENTRY_MODIFIABLE ) {
+               RS_ASSERT((rs->sr_flags & REP_ENTRY_MUSTFLUSH)==REP_ENTRY_MUSTBEFREED);
+               return 0;
+       }
+       rs_replace_entry( op, rs, on, entry_dup( rs->sr_entry ));
+       rs->sr_flags |= REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED;
+       return 1;
+}
+
 static long send_ldap_ber(
        Operation *op,
        BerElement *ber )
@@ -803,6 +847,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
        AccessControlState acl_state = ACL_STATE_INIT;
        int                      attrsonly;
        AttributeDescription *ad_entry = slap_schema.si_ad_entry;
+       AclCheck        ak;
 
        /* a_flags: array of flags telling if the i-th element will be
         *          returned or filtered out
@@ -852,7 +897,12 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 
        attrsonly = op->ors_attrsonly;
 
-       if ( !access_allowed( op, rs->sr_entry, ad_entry, NULL, ACL_READ, NULL )) {
+       ak.ak_e = rs->sr_entry;
+       ak.ak_desc = ad_entry;
+       ak.ak_val = NULL;
+       ak.ak_access = ACL_READ;
+       ak.ak_state = NULL;
+       if ( !access_allowed( op, &ak )) {
                Debug( LDAP_DEBUG_ACL,
                        "send_search_entry: conn %lu access to entry (%s) not allowed\n", 
                        op->o_connid, rs->sr_entry->e_name.bv_val, 0 );
@@ -955,6 +1005,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                }
        }
 
+       ak.ak_state = &acl_state;
        for ( a = rs->sr_entry->e_attrs, j = 0; a != NULL; a = a->a_next, j++ ) {
                AttributeDescription *desc = a->a_desc;
                int finish = 0;
@@ -985,9 +1036,9 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                        }
                }
 
+               ak.ak_desc = desc;
                if ( attrsonly ) {
-                       if ( ! access_allowed( op, rs->sr_entry, desc, NULL,
-                               ACL_READ, &acl_state ) )
+                       if ( ! access_allowed( op, &ak ))
                        {
                                Debug( LDAP_DEBUG_ACL, "send_search_entry: "
                                        "conn %lu access to attribute %s not allowed\n",
@@ -1011,8 +1062,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                } else {
                        int first = 1;
                        for ( i = 0; a->a_nvals[i].bv_val != NULL; i++ ) {
-                               if ( ! access_allowed( op, rs->sr_entry,
-                                       desc, &a->a_nvals[i], ACL_READ, &acl_state ) )
+                               ak.ak_val = &a->a_nvals[i];
+                               if ( ! access_allowed( op, &ak ))
                                {
                                        Debug( LDAP_DEBUG_ACL,
                                                "send_search_entry: conn %lu "
@@ -1146,8 +1197,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                        }
                }
 
-               if ( ! access_allowed( op, rs->sr_entry, desc, NULL,
-                       ACL_READ, &acl_state ) )
+               ak.ak_desc = desc;
+               if ( ! access_allowed( op, &ak ))
                {
                        Debug( LDAP_DEBUG_ACL,
                                "send_search_entry: conn %lu "
@@ -1172,8 +1223,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 
                if ( ! attrsonly ) {
                        for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
-                               if ( ! access_allowed( op, rs->sr_entry,
-                                       desc, &a->a_vals[i], ACL_READ, &acl_state ) )
+                               ak.ak_val = &a->a_vals[i];
+                               if ( ! access_allowed( op, &ak ))
                                {
                                        Debug( LDAP_DEBUG_ACL,
                                                "send_search_entry: conn %lu "
@@ -1339,25 +1390,29 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
                "=> send_search_reference: dn=\"%s\"\n",
                edn, 0, 0 );
 
-       if (  rs->sr_entry && ! access_allowed( op, rs->sr_entry,
-               ad_entry, NULL, ACL_READ, NULL ) )
+       if ( rs->sr_entry )
        {
-               Debug( LDAP_DEBUG_ACL,
-                       "send_search_reference: access to entry not allowed\n",
-                   0, 0, 0 );
-               rc = 1;
-               goto rel;
-       }
+               AclCheck ak = { rs->sr_entry, ad_entry, NULL, ACL_READ, NULL };
 
-       if ( rs->sr_entry && ! access_allowed( op, rs->sr_entry,
-               ad_ref, NULL, ACL_READ, NULL ) )
-       {
-               Debug( LDAP_DEBUG_ACL,
-                       "send_search_reference: access "
-                       "to reference not allowed\n",
-                   0, 0, 0 );
-               rc = 1;
-               goto rel;
+               if ( !access_allowed( op, &ak ))
+               {
+                       Debug( LDAP_DEBUG_ACL,
+                               "send_search_reference: access to entry not allowed\n",
+                               0, 0, 0 );
+                       rc = 1;
+                       goto rel;
+               }
+
+               ak.ak_desc = ad_ref;
+               if ( !access_allowed( op, &ak ))
+               {
+                       Debug( LDAP_DEBUG_ACL,
+                               "send_search_reference: access "
+                               "to reference not allowed\n",
+                               0, 0, 0 );
+                       rc = 1;
+                       goto rel;
+               }
        }
 
        if( op->o_domain_scope ) {