]> git.sur5r.net Git - openldap/commitdiff
Added slapi_access_allowed() and slapi_acl_check_mods() API for Sun ONE
authorLuke Howard <lukeh@openldap.org>
Wed, 22 Jan 2003 09:00:06 +0000 (09:00 +0000)
committerLuke Howard <lukeh@openldap.org>
Wed, 22 Jan 2003 09:00:06 +0000 (09:00 +0000)
DS 5.x compat
This required exposing the mods array conversion functions so they
are now in slapi/slapi_utils.[ch]

servers/slapd/modify.c
servers/slapd/slapi/slapi.h
servers/slapd/slapi/slapi_utils.c
servers/slapd/slapi/slapi_utils.h

index 03c4c05537525b52561609dd6315a1181f603716..ae2efd33511025049968fbaff8aa8e1354577ad7 100644 (file)
 #include "slap.h"
 #include "slapi.h"
 
-#ifdef LDAP_SLAPI
-static LDAPMod **Modifications2LDAPMods (Modifications **modlist);
-static Modifications *LDAPMods2Modifications (LDAPMod **mods);
-static void FreeLDAPMods (LDAPMod **mods);
-#endif /* LDAP_SLAPI */
-
 int
 do_modify(
     Connection *conn,
@@ -345,7 +339,7 @@ do_modify(
        slapi_x_operation_set_pb( pb, op );
        slapi_pblock_set( pb, SLAPI_MODIFY_TARGET, (void *)dn.bv_val );
        slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(1) );
-       modv = Modifications2LDAPMods( &modlist );
+       modv = slapi_x_modifications2ldapmods( &modlist );
        slapi_pblock_set( pb, SLAPI_MODIFY_MODS, (void *)modv );
 
        rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_MODIFY_FN, pb );
@@ -374,11 +368,11 @@ do_modify(
         * modification array, so we need to convert it back to
         * a Modification list.
         *
-        * Calling Modifications2LDAPMods() destroyed modlist so
+        * Calling slapi_x_modifications2ldapmods() destroyed modlist so
         * we don't need to free it.
         */
        slapi_pblock_get( pb, SLAPI_MODIFY_MODS, (void **)&modv );
-       modlist = LDAPMods2Modifications( modv );
+       modlist = slapi_x_ldapmods2modifications( modv );
 #endif /* defined( LDAP_SLAPI ) */
 
        /*
@@ -475,7 +469,7 @@ cleanup:
        free( ndn.bv_val );
        if ( modlist != NULL ) slap_mods_free( modlist );
 #if defined( LDAP_SLAPI )
-       if ( modv != NULL ) FreeLDAPMods( modv );
+       if ( modv != NULL ) slapi_x_free_ldapmods( modv );
 #endif
        return rc;
 }
@@ -772,154 +766,3 @@ int slap_mods_opattrs(
        return LDAP_SUCCESS;
 }
 
-#ifdef LDAP_SLAPI
-/*
- * Synthesise an LDAPMod array from a Modifications list to pass
- * to SLAPI. This synthesis is destructive and as such the 
- * Modifications list may not be used after calling this 
- * function.
- * 
- * This function must also be called before slap_mods_check().
- */
-static LDAPMod **Modifications2LDAPMods(Modifications **pmodlist)
-{
-       Modifications *ml, *modlist;
-       LDAPMod **mods, *modp;
-       int i, j;
-
-       modlist = *pmodlist;
-
-       for( i = 0, ml = modlist; ml != NULL; i++, ml = ml->sml_next )
-               ;
-
-       mods = (LDAPMod **)ch_malloc( (i + 1) * sizeof(LDAPMod *) );
-
-       for( i = 0, ml = modlist; ml != NULL; ml = ml->sml_next ) {
-               modp = mods[i];
-               modp->mod_op = ml->sml_op | LDAP_MOD_BVALUES;
-
-               /* Take ownership of original type. */
-               modp->mod_type = ml->sml_type.bv_val;
-               ml->sml_type.bv_val = NULL;
-
-               if ( ml->sml_bvalues != NULL ) {
-                       for( j = 0; ml->sml_bvalues[j].bv_val != NULL; j++ )
-                               ;
-                       modp->mod_bvalues = (struct berval **)ch_malloc( (j + 1) *
-                               sizeof(struct berval *) );
-                       for( j = 0; ml->sml_bvalues[j].bv_val != NULL; j++ ) {
-                               /* Take ownership of original values. */
-                               modp->mod_bvalues[j] = (struct berval *)ch_malloc( sizeof(struct berval) );
-                               modp->mod_bvalues[j]->bv_len = ml->sml_bvalues[j].bv_len;
-                               modp->mod_bvalues[j]->bv_val = ml->sml_bvalues[j].bv_val;
-                               ml->sml_bvalues[j].bv_len = 0;
-                               ml->sml_bvalues[j].bv_val = NULL;
-                       }
-                       modp->mod_bvalues[j] = NULL;
-               } else {
-                       modp->mod_bvalues = NULL;
-               }
-               i++;
-       }
-
-       mods[i] = NULL;
-
-       slap_mods_free( modlist );
-       *pmodlist = NULL;
-
-       return mods;
-}
-
-/*
- * Convert a potentially modified array of LDAPMods back to a
- * Modification list. 
- * 
- * The returned Modification list contains pointers into the
- * LDAPMods array; the latter MUST be freed with FreeLDAPMods()
- * (see below).
- */
-static Modifications *LDAPMods2Modifications (LDAPMod **mods)
-{
-       Modifications *modlist, **modtail;
-       LDAPMod **modp;
-
-       modtail = &modlist;
-
-       for( modp = mods; *modp != NULL; modp++ ) {
-               Modifications *mod;
-               int i;
-               char **p;
-               struct berval **bvp;
-
-               mod = (Modifications *) ch_malloc( sizeof(Modifications) );
-               mod->sml_op = (*modp)->mod_op & (~LDAP_MOD_BVALUES);
-               mod->sml_type.bv_val = (*modp)->mod_type;
-               mod->sml_type.bv_len = strlen( mod->sml_type.bv_val );
-               mod->sml_desc = NULL;
-               mod->sml_next = NULL;
-
-               if ( (*modp)->mod_op & LDAP_MOD_BVALUES ) {
-                       for( i = 0, bvp = (*modp)->mod_bvalues; *bvp != NULL; bvp++, i++ )
-                               ;
-               } else {
-                       for( i = 0, p = (*modp)->mod_values; *p != NULL; p++, i++ )
-                               ;
-               }
-
-               mod->sml_bvalues = (BerVarray) ch_malloc( (i + 1) * sizeof(struct berval) );
-
-               /* NB: This implicitly trusts a plugin to return valid modifications. */
-               if ( (*modp)->mod_op & LDAP_MOD_BVALUES ) {
-                       for( i = 0, bvp = (*modp)->mod_bvalues; *bvp != NULL; bvp++, i++ ) {
-                               mod->sml_bvalues[i].bv_val = (*bvp)->bv_val;
-                               mod->sml_bvalues[i].bv_len = (*bvp)->bv_len;
-                       }
-               } else {
-                       for( i = 0, p = (*modp)->mod_values; *p != NULL; p++, i++ ) {
-                               mod->sml_bvalues[i].bv_val = *p;
-                               mod->sml_bvalues[i].bv_len = strlen( *p );
-                       }
-               }
-               mod->sml_bvalues[i].bv_val = NULL;
-
-               *modtail = mod;
-               modtail = &mod->sml_next;
-       }
-       
-       return modlist;
-}
-
-/*
- * This function only frees the parts of the mods array that
- * are not shared with the Modification list that was created
- * by LDAPMods2Modifications. 
- *
- */
-static void FreeLDAPMods (LDAPMod **mods)
-{
-       int i, j;
-
-       if (mods == NULL)
-               return;
-
-       for ( i = 0; mods[i] != NULL; i++ ) {
-               /*
-                * Don't free values themselves; they're owned by the
-                * Modification list. Do free the containing array.
-                */
-               if ( mods[i]->mod_op & LDAP_MOD_BVALUES ) {
-                       for ( j = 0; mods[i]->mod_bvalues[j] != NULL; j++ ) {
-                               ch_free( mods[i]->mod_bvalues[j] );
-                       }
-                       ch_free( mods[i]->mod_bvalues );
-               } else {
-                       ch_free( mods[i]->mod_values );
-               }
-               /* Don't free type, for same reasons. */
-               ch_free( mods[i] );
-       }
-       ch_free( mods );
-}
-
-#endif /* LDAP_SLAPI */
-
index aae64082fc8da309ac86f6c975f24b1a4a84bb91..d8c9e938b46d8590177dc5d920ba9494df1d1211 100644 (file)
@@ -50,6 +50,19 @@ LDAP_BEGIN_DECL
 #define SLAPI_ATTR_FLAG_COLLECTIVE     0x0080
 #define SLAPI_ATTR_FLAG_NOUSERMOD      0x0100
 
+/*
+ * ACL levels
+ */
+#define SLAPI_ACL_COMPARE      0x01
+#define SLAPI_ACL_SEARCH       0x02
+#define SLAPI_ACL_READ         0x04
+#define SLAPI_ACL_WRITE                0x08
+#define SLAPI_ACL_DELETE       0x10
+#define SLAPI_ACL_ADD          0x20
+#define SLAPI_ACL_SELF         0x40
+#define SLAPI_ACL_PROXY                0x80
+#define SLAPI_ACL_ALL          0x7f
+
 /*
  * Plugin types universally supported by SLAPI
  * implementations
index 4887da032b3255fe0b4d69e4eae0813745587db6..fe15ffd277886848858c3e4b0cdee6e12e49be42 100644 (file)
@@ -423,6 +423,14 @@ slapi_ch_free( void **ptr )
 #endif /* defined(LDAP_SLAPI) */
 }
 
+void 
+slapi_ch_free_string( char **ptr ) 
+{
+#if defined(LDAP_SLAPI)
+       slapi_ch_free( (void **)ptr );
+#endif /* defined(LDAP_SLAPI) */
+}
+
 char *
 slapi_ch_calloc(
        unsigned long nelem, 
@@ -2064,9 +2072,113 @@ void slapi_valueset_set_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2)
 #endif
 }
 
+int slapi_access_allowed( Slapi_PBlock *pb, Slapi_Entry *e, char *attr,
+       struct berval *val, int access )
+{
+#ifdef LDAPI_SLAPI
+       Backend *be;
+       Connection *conn;
+       Operation *op;
+       int ret;
+       slap_access_t slap_access;
+       AttributeDescription *ad = NULL;
+       char *text;
+
+       ret = slap_str2ad( attr, &ad, &text );
+       if ( ret != LDAP_SUCCESS ) {
+               return ret;
+       }
+
+       switch ( access & SLAPI_ACL_ALL ) {
+       case SLAPI_ACL_COMPARE:
+               slap_access = ACL_COMPARE;
+               break;
+       case SLAPI_ACL_SEARCH:
+               slap_access = ACL_SEARCH;
+               break;
+       case SLAPI_ACL_READ:
+               slap_access = ACL_READ;
+               break;
+       case SLAPI_ACL_WRITE:
+       case SLAPI_ACL_DELETE:
+       case SLAPI_ACL_ADD:
+       case SLAPI_ACL_SELF:
+               slap_access = ACL_WRITE;
+               break;
+       default:
+               return LDAP_INSUFFICIENT_ACCESS;
+               break;
+       }
+
+       if ( slapi_pblock_get( pb, SLAPI_BACKEND, (void *)&be ) != 0 ) {
+               return LDAP_PARAM_ERROR;
+       }
+
+       if ( slapi_pblock_get( pb, SLAPI_CONNECTION, (void *)&conn ) != 0 ) {
+               return LDAP_PARAM_ERROR;
+       }
+
+       if ( slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&op ) != 0 ) {
+               return LDAP_PARAM_ERROR;
+       }
+
+       ret = access_allowed( be, conn, op, e, desc, val, slap_access, NULL );
+
+       return ret ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS;
+#else
+       return LDAP_UNWILLING_TO_PERFORM;
+#endif
+}
+
+int slapi_acl_check_mods(Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char **errbuf)
+{
+#ifdef LDAP_SLAPI
+       Backend *be;
+       Connection *conn;
+       Operation *op;
+       int ret;
+       Modifications *ml;
+        Modifications *next;
+
+       if ( slapi_pblock_get( pb, SLAPI_BACKEND, (void *)&be ) != 0 ) {
+               return LDAP_PARAM_ERROR;
+       }
+
+       if ( slapi_pblock_get( pb, SLAPI_CONNECTION, (void *)&conn ) != 0 ) {
+               return LDAP_PARAM_ERROR;
+       }
+
+       if ( slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&op ) != 0 ) {
+               return LDAP_PARAM_ERROR;
+       }
+
+       ml = slapi_x_ldapmods2modifications( mods );
+       if ( ml == NULL ) {
+               return LDAP_OTHER;
+       }
+
+       ret = acl_check_modlist( be, conn, op, e, ml );
+
+       /* Careful when freeing the modlist because it has pointers into the mods array. */
+       for ( ; ml != NULL; ml = next ) {
+               next = ml->sml_next;
+
+               /* just free the containing array */
+               slapi_ch_free( (void **)&ml->sml_bvalues );
+               slapi_ch_free( (void **)&ml );
+       }
+
+       return ret ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS;
+#else
+       return LDAP_UNWILLING_TO_PERFORM;
+#endif
+}
+
 /*
  * Attribute sets are an OpenLDAP extension for the 
- * virtual operational attribute coalescing plugin 
+ * virtual operational attribute coalescing plugin  
+ *
+ * Subject to going away very soon; do not use
  */
 Slapi_AttrSet *slapi_x_attrset_new( void )
 {
@@ -2264,3 +2376,162 @@ int slapi_x_attrset_delete( Slapi_AttrSet *as, const char *type )
        return -1;
 #endif
 }
+
+/*
+ * Synthesise an LDAPMod array from a Modifications list to pass
+ * to SLAPI. This synthesis is destructive and as such the 
+ * Modifications list may not be used after calling this 
+ * function.
+ * 
+ * This function must also be called before slap_mods_check().
+ */
+LDAPMod **slapi_x_modifications2ldapmods(Modifications **pmodlist)
+{
+#ifdef LDAP_SLAPI
+       Modifications *ml, *modlist;
+       LDAPMod **mods, *modp;
+       int i, j;
+
+       modlist = *pmodlist;
+
+       for( i = 0, ml = modlist; ml != NULL; i++, ml = ml->sml_next )
+               ;
+
+       mods = (LDAPMod **)ch_malloc( (i + 1) * sizeof(LDAPMod *) );
+
+       for( i = 0, ml = modlist; ml != NULL; ml = ml->sml_next ) {
+               modp = mods[i];
+               modp->mod_op = ml->sml_op | LDAP_MOD_BVALUES;
+
+               /* Take ownership of original type. */
+               modp->mod_type = ml->sml_type.bv_val;
+               ml->sml_type.bv_val = NULL;
+
+               if ( ml->sml_bvalues != NULL ) {
+                       for( j = 0; ml->sml_bvalues[j].bv_val != NULL; j++ )
+                               ;
+                       modp->mod_bvalues = (struct berval **)ch_malloc( (j + 1) *
+                               sizeof(struct berval *) );
+                       for( j = 0; ml->sml_bvalues[j].bv_val != NULL; j++ ) {
+                               /* Take ownership of original values. */
+                               modp->mod_bvalues[j] = (struct berval *)ch_malloc( sizeof(struct berval) );
+                               modp->mod_bvalues[j]->bv_len = ml->sml_bvalues[j].bv_len;
+                               modp->mod_bvalues[j]->bv_val = ml->sml_bvalues[j].bv_val;
+                               ml->sml_bvalues[j].bv_len = 0;
+                               ml->sml_bvalues[j].bv_val = NULL;
+                       }
+                       modp->mod_bvalues[j] = NULL;
+               } else {
+                       modp->mod_bvalues = NULL;
+               }
+               i++;
+       }
+
+       mods[i] = NULL;
+
+       slap_mods_free( modlist );
+       *pmodlist = NULL;
+
+       return mods;
+#else
+       return NULL;
+#endif
+}
+
+/*
+ * Convert a potentially modified array of LDAPMods back to a
+ * Modification list. 
+ * 
+ * The returned Modification list contains pointers into the
+ * LDAPMods array; the latter MUST be freed with
+ * slapi_x_free_ldapmods() (see below).
+ */
+Modifications *slapi_x_ldapmods2modifications (LDAPMod **mods)
+{
+#ifdef LDAP_SLAPI
+       Modifications *modlist, **modtail;
+       LDAPMod **modp;
+
+       modtail = &modlist;
+
+       for( modp = mods; *modp != NULL; modp++ ) {
+               Modifications *mod;
+               int i;
+               char **p;
+               struct berval **bvp;
+
+               mod = (Modifications *) ch_malloc( sizeof(Modifications) );
+               mod->sml_op = (*modp)->mod_op & (~LDAP_MOD_BVALUES);
+               mod->sml_type.bv_val = (*modp)->mod_type;
+               mod->sml_type.bv_len = strlen( mod->sml_type.bv_val );
+               mod->sml_desc = NULL;
+               mod->sml_next = NULL;
+
+               if ( (*modp)->mod_op & LDAP_MOD_BVALUES ) {
+                       for( i = 0, bvp = (*modp)->mod_bvalues; *bvp != NULL; bvp++, i++ )
+                               ;
+               } else {
+                       for( i = 0, p = (*modp)->mod_values; *p != NULL; p++, i++ )
+                               ;
+               }
+
+               mod->sml_bvalues = (BerVarray) ch_malloc( (i + 1) * sizeof(struct berval) );
+
+               /* NB: This implicitly trusts a plugin to return valid modifications. */
+               if ( (*modp)->mod_op & LDAP_MOD_BVALUES ) {
+                       for( i = 0, bvp = (*modp)->mod_bvalues; *bvp != NULL; bvp++, i++ ) {
+                               mod->sml_bvalues[i].bv_val = (*bvp)->bv_val;
+                               mod->sml_bvalues[i].bv_len = (*bvp)->bv_len;
+                       }
+               } else {
+                       for( i = 0, p = (*modp)->mod_values; *p != NULL; p++, i++ ) {
+                               mod->sml_bvalues[i].bv_val = *p;
+                               mod->sml_bvalues[i].bv_len = strlen( *p );
+                       }
+               }
+               mod->sml_bvalues[i].bv_val = NULL;
+
+               *modtail = mod;
+               modtail = &mod->sml_next;
+       }
+       
+       return modlist;
+#else
+       return NULL;
+#endif 
+}
+
+/*
+ * This function only frees the parts of the mods array that
+ * are not shared with the Modification list that was created
+ * by slapi_x_ldapmods2modifications(). 
+ *
+ */
+void slapi_x_free_ldapmods (LDAPMod **mods)
+{
+#ifdef LDAP_SLAPI
+       int i, j;
+
+       if (mods == NULL)
+               return;
+
+       for ( i = 0; mods[i] != NULL; i++ ) {
+               /*
+                * Don't free values themselves; they're owned by the
+                * Modification list. Do free the containing array.
+                */
+               if ( mods[i]->mod_op & LDAP_MOD_BVALUES ) {
+                       for ( j = 0; mods[i]->mod_bvalues[j] != NULL; j++ ) {
+                               ch_free( mods[i]->mod_bvalues[j] );
+                       }
+                       ch_free( mods[i]->mod_bvalues );
+               } else {
+                       ch_free( mods[i]->mod_values );
+               }
+               /* Don't free type, for same reasons. */
+               ch_free( mods[i] );
+       }
+       ch_free( mods );
+#endif /* LDAP_SLAPI */
+}
+
index 0b97dfb68308f47b92797cbdefdbc08272287f26..5c70db6750fe800ef22b1bcf63ea135264211723 100644 (file)
@@ -69,6 +69,8 @@ int slapi_x_attrset_merge_bervals( Slapi_AttrSet *as, const char *type, struct b
 int slapi_x_attrset_delete( Slapi_AttrSet *as, const char *type );
 
 /* DS 5.x SLAPI */
+int slapi_access_allowed( Slapi_PBlock *pb, Slapi_Entry *e, char *attr, struct berval *val, int access );
+int slapi_acl_check_mods( Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char **errbuf );
 Slapi_Attr *slapi_attr_new( void );
 Slapi_Attr *slapi_attr_init( Slapi_Attr *a, const char *type );
 void slapi_attr_free( Slapi_Attr **a );
@@ -128,6 +130,7 @@ void slapi_valueset_set_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2)
 
 char *slapi_ch_malloc( unsigned long size );
 void slapi_ch_free( void **ptr );
+void slapi_ch_free_string( char **s );
 char *slapi_ch_calloc( unsigned long nelem, unsigned long size );
 char *slapi_ch_realloc( char *block, unsigned long size );
 char *slapi_ch_strdup( char *s );
@@ -186,6 +189,10 @@ int slapi_x_backend_set_pb( Slapi_PBlock *pb, Backend *be );
 int slapi_x_connection_set_pb( Slapi_PBlock *pb, Connection *conn );
 int slapi_x_operation_set_pb( Slapi_PBlock *pb, Operation *op );
 
+LDAPMod **slapi_x_modifications2ldapmods(Modifications **);
+Modifications *slapi_x_ldapmods2modifications(LDAPMod **);
+void slapi_x_free_ldapmods(LDAPMod **);
+
 extern ldap_pvt_thread_mutex_t slapi_hn_mutex;
 extern ldap_pvt_thread_mutex_t slapi_time_mutex;
 extern ldap_pvt_thread_mutex_t slapi_printmessage_mutex;