#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,
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 );
* 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 ) */
/*
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;
}
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 */
-
#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
#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,
#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 )
{
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 */
+}
+
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 );
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 );
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;