X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fslapi%2Fslapi_utils.c;h=91c84fae44d6cb4ae35f42e62ceeb6838d17da41;hb=b0b3eff457f0e431c4fd094d3d9cfeb6383df91d;hp=368dc6234e28259014d07264a571e4fa8f79340f;hpb=4b3545cd2ed5165bc6717d8638daa5bb15925066;p=openldap diff --git a/servers/slapd/slapi/slapi_utils.c b/servers/slapd/slapi/slapi_utils.c index 368dc6234e..91c84fae44 100644 --- a/servers/slapd/slapi/slapi_utils.c +++ b/servers/slapd/slapi/slapi_utils.c @@ -1,21 +1,23 @@ -/* - * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file - */ -/* - * Copyright IBM Corp. 1997,2002 - * Use of this source code is subject to the terms of The OpenLDAP Public - * License (version 2.7 or later). - * No trademarks of the IBM Corporation are to be used to identify, endorse - * or promote any products derived from this code without the prior - * written consent of IBM +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . + * + * Copyright 2002-2003 The OpenLDAP Foundation. + * Portions Copyright 1997,2002-2003 IBM Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . */ -/* - * Portions (C) Copyright PADL Software Pty Ltd. 2003 - * Redistribution and use in source and binary forms are permitted - * provided that this notice is preserved and that due credit is - * given to PADL Software Pty Ltd. This software is provided ``as is'' - * without express or implied warranty. +/* ACKNOWLEDGEMENTS: + * This work was initially developed by IBM Corporation for use in + * IBM products and subsequently ported to OpenLDAP Software by + * Steve Omrani. Additional significant contributors include: + * Luke Howard */ #include "portable.h" @@ -29,10 +31,6 @@ #include #include -#ifdef _SPARC -#include -#endif - #include /* @@ -170,26 +168,7 @@ Slapi_Entry * slapi_entry_dup( Slapi_Entry *e ) { #ifdef LDAP_SLAPI - char *tmp = NULL; - Slapi_Entry *tmpEnt; - int len = 0; - - tmp = slapi_entry2str( e, &len ); - if ( tmp == NULL ) { - return (Slapi_Entry *)NULL; - } - - tmpEnt = (Slapi_Entry *)str2entry( tmp ); - if ( tmpEnt == NULL ) { - slapi_ch_free( (void **)&tmp ); - return (Slapi_Entry *)NULL; - } - - if (tmp != NULL) { - slapi_ch_free( (void **)&tmp ); - } - - return tmpEnt; + return entry_dup( e ); #else /* LDAP_SLAPI */ return NULL; #endif /* LDAP_SLAPI */ @@ -931,6 +910,139 @@ slapi_dn_issuffix( #endif /* LDAP_SLAPI */ } +int +slapi_dn_isparent( + const char *parentdn, + const char *childdn ) +{ +#ifdef LDAP_SLAPI + struct berval assertedParentDN, normalizedAssertedParentDN; + struct berval childDN, normalizedChildDN; + struct berval normalizedParentDN; + int match; + + assert( parentdn != NULL ); + assert( childdn != NULL ); + + assertedParentDN.bv_val = (char *)parentdn; + assertedParentDN.bv_len = strlen( parentdn ); + + if ( dnNormalize( 0, NULL, NULL, &assertedParentDN, + &normalizedAssertedParentDN, NULL ) != LDAP_SUCCESS ) + { + return 0; + } + + childDN.bv_val = (char *)childdn; + childDN.bv_len = strlen( childdn ); + + if ( dnNormalize( 0, NULL, NULL, &childDN, + &normalizedChildDN, NULL ) != LDAP_SUCCESS ) + { + slapi_ch_free( (void **)&normalizedAssertedParentDN.bv_val ); + return 0; + } + + dnParent( &normalizedChildDN, &normalizedParentDN ); + + if ( dnMatch( &match, 0, slap_schema.si_syn_distinguishedName, NULL, + &normalizedParentDN, (void *)&normalizedAssertedParentDN ) != LDAP_SUCCESS ) + { + match = -1; + } + + slapi_ch_free( (void **)&normalizedAssertedParentDN.bv_val ); + slapi_ch_free( (void **)&normalizedChildDN.bv_val ); + + return ( match == 0 ); +#else + return 0; +#endif /* LDAP_SLAPI */ +} + +/* + * Returns DN of the parent entry, or NULL if the DN is + * an empty string or NULL, or has no parent. + */ +char * +slapi_dn_parent( const char *_dn ) +{ +#ifdef LDAP_SLAPI + struct berval dn, prettyDN; + struct berval parentDN; + + if ( _dn == NULL ) { + return NULL; + } + + dn.bv_val = (char *)_dn; + dn.bv_len = strlen( _dn ); + + if ( dn.bv_len == 0 ) { + return NULL; + } + + if ( dnPretty( NULL, &dn, &prettyDN, NULL ) != LDAP_SUCCESS ) { + return NULL; + } + + dnParent( &prettyDN, &parentDN ); /* in-place */ + + slapi_ch_free( (void **)&prettyDN.bv_val ); + + if ( parentDN.bv_len == 0 ) { + return NULL; + } + + return slapi_ch_strdup( parentDN.bv_val ); +#else + return NULL; +#endif /* LDAP_SLAPI */ +} + +/* + * Returns DN of the parent entry; or NULL if the DN is + * an empty string, if the DN has no parent, or if the + * DN is the suffix of the backend database + */ +char *slapi_dn_beparent( Slapi_PBlock *pb, const char *_dn ) +{ +#ifdef LDAP_SLAPI + Backend *be; + struct berval dn, prettyDN; + struct berval normalizedDN, parentDN; + + if ( slapi_pblock_get( pb, SLAPI_BACKEND, (void **)&be ) != 0 ) + be = NULL; + + dn.bv_val = (char *)_dn; + dn.bv_len = strlen( _dn ); + + if ( dnPrettyNormal( NULL, &dn, &prettyDN, &normalizedDN, NULL ) != LDAP_SUCCESS ) { + return NULL; + } + + if ( be != NULL && be_issuffix( be, &normalizedDN ) ) { + slapi_ch_free( (void **)&prettyDN.bv_val ); + slapi_ch_free( (void **)&normalizedDN.bv_val ); + return NULL; + } + + dnParent( &prettyDN, &parentDN ); + + slapi_ch_free( (void **)&prettyDN.bv_val ); + slapi_ch_free( (void **)&normalizedDN.bv_val ); + + if ( parentDN.bv_len == 0 ) { + return NULL; + } + + return slapi_ch_strdup( parentDN.bv_val ); +#else + return NULL; +#endif /* LDAP_SLAPI */ +} + char * slapi_dn_ignore_case( char *dn ) { @@ -1282,7 +1394,7 @@ slapi_register_supported_saslmechanism( char *mechanism ) { #ifdef LDAP_SLAPI /* FIXME -- can not add saslmechanism to OpenLDAP dynamically */ - slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SASL", + slapi_log_error( SLAPI_LOG_FATAL, "slapi_register_supported_saslmechanism", "OpenLDAP does not support dynamic registration of SASL mechanisms\n" ); #endif /* LDAP_SLAPI */ } @@ -1292,7 +1404,7 @@ slapi_get_supported_saslmechanisms( void ) { #ifdef LDAP_SLAPI /* FIXME -- can not get the saslmechanism without a connection. */ - slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SASL", + slapi_log_error( SLAPI_LOG_FATAL, "slapi_get_supported_saslmechanisms", "can not get the SASL mechanism list " "without a connection\n" ); return NULL; @@ -1451,6 +1563,60 @@ slapi_send_ldap_search_entry( #endif /* LDAP_SLAPI */ } +int +slapi_send_ldap_search_reference( + Slapi_PBlock *pb, + Slapi_Entry *e, + struct berval **references, + LDAPControl **ectrls, + struct berval **v2refs + ) +{ +#ifdef LDAP_SLAPI + Operation *pOp; + SlapReply rs = { REP_SEARCHREF }; + int rc; + + rs.sr_err = LDAP_SUCCESS; + rs.sr_matched = NULL; + rs.sr_text = NULL; + + rc = bvptr2obj( references, &rs.sr_ref ); + if ( rc != LDAP_SUCCESS ) { + return rc; + } + + rs.sr_ctrls = ectrls; + rs.sr_attrs = NULL; + rs.sr_entry = e; + + if ( v2refs != NULL ) { + rc = bvptr2obj( v2refs, &rs.sr_v2ref ); + if ( rc != LDAP_SUCCESS ) { + slapi_ch_free( (void **)&rs.sr_ref ); + return rc; + } + } else { + rs.sr_v2ref = NULL; + } + + if ( slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&pOp ) != 0 ) { + return LDAP_OTHER; + } + + rc = send_search_reference( pOp, &rs ); + + if ( rs.sr_ref != NULL ) + slapi_ch_free( (void **)&rs.sr_ref ); + + if ( rs.sr_v2ref != NULL ) + slapi_ch_free( (void **)&rs.sr_v2ref ); + + return rc; +#else + return -1; +#endif /* LDAP_SLAPI */ +} Slapi_Filter * slapi_str2filter( char *str ) @@ -1939,24 +2105,6 @@ slapi_get_hostname( void ) { #ifdef LDAP_SLAPI char *hn = NULL; - - /* - * FIXME: I'd prefer a different check ... - */ -#if defined _SPARC - hn = (char *)slapi_ch_malloc( MAX_HOSTNAME ); - if ( hn == NULL) { - slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO", - "can't malloc memory for hostname\n" ); - hn = NULL; - - } else if ( sysinfo( SI_HOSTNAME, hn, MAX_HOSTNAME ) < 0 ) { - slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO", - "can't get hostname\n" ); - slapi_ch_free( (void **)&hn ); - hn = NULL; - } -#else /* !_SPARC */ static int been_here = 0; static char *static_hn = NULL; @@ -1964,8 +2112,8 @@ slapi_get_hostname( void ) if ( !been_here ) { static_hn = (char *)slapi_ch_malloc( MAX_HOSTNAME ); if ( static_hn == NULL) { - slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO", - "can't malloc memory for hostname\n" ); + slapi_log_error( SLAPI_LOG_FATAL, "slapi_get_hostname", + "Cannot allocate memory for hostname\n" ); static_hn = NULL; ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex ); @@ -1974,7 +2122,7 @@ slapi_get_hostname( void ) } else { if ( gethostname( static_hn, MAX_HOSTNAME ) != 0 ) { slapi_log_error( SLAPI_LOG_FATAL, - "SLAPI_SYSINFO", + "SLAPI", "can't get hostname\n" ); slapi_ch_free( (void **)&static_hn ); static_hn = NULL; @@ -1990,7 +2138,6 @@ slapi_get_hostname( void ) ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex ); hn = ch_strdup( static_hn ); -#endif /* !_SPARC */ return hn; #else /* LDAP_SLAPI */ @@ -2253,17 +2400,29 @@ static int initConnectionPB( Slapi_PBlock *pb, Connection *conn ) 0 ); if ( connAuthType != NULL ) { rc = slapi_pblock_set(pb, SLAPI_CONN_AUTHMETHOD, (void *)connAuthType); + /* slapi_pblock_set dups this itself */ + slapi_ch_free( (void **)&connAuthType ); if ( rc != LDAP_SUCCESS ) return rc; } if ( conn->c_authz.sai_dn.bv_val != NULL ) { - char *connDn = slapi_ch_strdup(conn->c_authz.sai_dn.bv_val); - rc = slapi_pblock_set(pb, SLAPI_CONN_DN, (void *)connDn); + /* slapi_pblock_set dups this itself */ + rc = slapi_pblock_set(pb, SLAPI_CONN_DN, (void *)conn->c_authz.sai_dn.bv_val); if ( rc != LDAP_SUCCESS ) return rc; } + rc = slapi_pblock_set(pb, SLAPI_X_CONN_SSF, (void *)conn->c_ssf); + if ( rc != LDAP_SUCCESS ) + return rc; + + rc = slapi_pblock_set(pb, SLAPI_X_CONN_SASL_CONTEXT, + ( conn->c_sasl_authctx != NULL ? conn->c_sasl_authctx : + conn->c_sasl_sockctx ) ); + if ( rc != LDAP_SUCCESS ) + return rc; + return rc; } #endif /* LDAP_SLAPI */ @@ -3083,14 +3242,14 @@ void slapi_valueset_set_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2) int slapi_access_allowed( Slapi_PBlock *pb, Slapi_Entry *e, char *attr, struct berval *val, int access ) { -#ifdef LDAPI_SLAPI +#ifdef LDAP_SLAPI Backend *be; Connection *conn; Operation *op; int ret; slap_access_t slap_access; AttributeDescription *ad = NULL; - char *text; + const char *text; ret = slap_str2ad( attr, &ad, &text ); if ( ret != LDAP_SUCCESS ) { @@ -3130,7 +3289,7 @@ int slapi_access_allowed( Slapi_PBlock *pb, Slapi_Entry *e, char *attr, return LDAP_PARAM_ERROR; } - ret = access_allowed( be, conn, op, e, desc, val, slap_access, NULL ); + ret = access_allowed( op, e, ad, val, slap_access, NULL ); return ret ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS; #else @@ -3142,9 +3301,8 @@ int slapi_acl_check_mods(Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char { #ifdef LDAP_SLAPI Operation *op; - int ret; - Modifications *ml; - Modifications *next; + int rc = LDAP_SUCCESS; + Modifications *ml, *mp; if ( slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&op ) != 0 ) { return LDAP_PARAM_ERROR; @@ -3155,18 +3313,27 @@ int slapi_acl_check_mods(Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char return LDAP_OTHER; } - ret = acl_check_modlist( op, e, ml ); + for ( mp = ml; mp != NULL; mp = mp->sml_next ) { + rc = slap_bv2ad( &mp->sml_type, &mp->sml_desc, (const char **)errbuf ); + if ( rc != LDAP_SUCCESS ) { + break; + } + } + + if ( rc == LDAP_SUCCESS ) { + rc = acl_check_modlist( op, e, ml ) ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS; + } /* Careful when freeing the modlist because it has pointers into the mods array. */ - for ( ; ml != NULL; ml = next ) { - next = ml->sml_next; + for ( ; ml != NULL; ml = mp ) { + mp = 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; + return rc; #else return LDAP_UNWILLING_TO_PERFORM; #endif @@ -3272,7 +3439,7 @@ Modifications *slapi_x_ldapmods2modifications (LDAPMod **mods) } if ( i == 0 ) { - mod->sml_bvalues = NULL; + mod->sml_bvalues = NULL; } else { mod->sml_bvalues = (BerVarray) ch_malloc( (i + 1) * sizeof(struct berval) ); @@ -3396,7 +3563,7 @@ int slapi_x_compute_output_ber(computed_attr_context *c, Slapi_Attr *a, Slapi_En } if ( !access_allowed( op, e, desc, NULL, ACL_READ, &c->cac_acl_state) ) { - slapi_log_error( SLAPI_LOG_ACL, "SLAPI_COMPUTE", + slapi_log_error( SLAPI_LOG_ACL, "slapi_x_compute_output_ber", "acl: access to attribute %s not allowed\n", desc->ad_cname.bv_val ); return 0; @@ -3404,7 +3571,7 @@ int slapi_x_compute_output_ber(computed_attr_context *c, Slapi_Attr *a, Slapi_En rc = ber_printf( ber, "{O[" /*]}*/ , &desc->ad_cname ); if (rc == -1 ) { - slapi_log_error( SLAPI_LOG_BER, "SLAPI_COMPUTE", + slapi_log_error( SLAPI_LOG_BER, "slapi_x_compute_output_ber", "ber_printf failed\n"); return 1; } @@ -3413,15 +3580,15 @@ int slapi_x_compute_output_ber(computed_attr_context *c, Slapi_Attr *a, Slapi_En for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) { if ( !access_allowed( op, e, desc, &a->a_vals[i], ACL_READ, &c->cac_acl_state)) { - slapi_log_error( SLAPI_LOG_ACL, "SLAPI_COMPUTE", - "slapi_x_compute_output_ber: conn %lu " + slapi_log_error( SLAPI_LOG_ACL, "slapi_x_compute_output_ber", + "conn %lu " "acl: access to %s, value %d not allowed\n", op->o_connid, desc->ad_cname.bv_val, i ); continue; } if (( rc = ber_printf( ber, "O", &a->a_vals[i] )) == -1 ) { - slapi_log_error( SLAPI_LOG_BER, "SLAPI_COMPUTE", + slapi_log_error( SLAPI_LOG_BER, "slapi_x_compute_output_ber", "ber_printf failed\n"); return 1; } @@ -3429,7 +3596,7 @@ int slapi_x_compute_output_ber(computed_attr_context *c, Slapi_Attr *a, Slapi_En } if (( rc = ber_printf( ber, /*{[*/ "]N}" )) == -1 ) { - slapi_log_error( SLAPI_LOG_BER, "SLAPI_COMPUTE", + slapi_log_error( SLAPI_LOG_BER, "slapi_x_compute_output_ber", "ber_printf failed\n" ); return 1; } @@ -3716,3 +3883,66 @@ int slapi_notify_condvar( Slapi_CondVar *cvar, int notify_all ) #endif } +int slapi_x_access_allowed( Operation *op, + Entry *entry, + AttributeDescription *desc, + struct berval *val, + slap_access_t access, + AccessControlState *state ) +{ +#ifdef LDAP_SLAPI + int rc, slap_access = 0; + slapi_acl_callback_t *pGetPlugin, *tmpPlugin; + + if ( op->o_pb == NULL ) { + /* internal operation */ + return 1; + } + + switch ( access ) { + case ACL_WRITE: + slap_access |= SLAPI_ACL_ADD | SLAPI_ACL_DELETE | SLAPI_ACL_WRITE; + break; + case ACL_READ: + slap_access |= SLAPI_ACL_READ; + break; + case ACL_SEARCH: + slap_access |= SLAPI_ACL_SEARCH; + break; + case ACL_COMPARE: + slap_access = ACL_COMPARE; + break; + default: + break; + } + + rc = getAllPluginFuncs( op->o_bd, SLAPI_PLUGIN_ACL_ALLOW_ACCESS, (SLAPI_FUNC **)&tmpPlugin ); + if ( rc != LDAP_SUCCESS || tmpPlugin == NULL ) { + /* nothing to do; allowed access */ + return 1; + } + + slapi_x_pblock_set_operation( op->o_pb, op ); + + rc = 1; /* default allow policy */ + + for ( pGetPlugin = tmpPlugin; *pGetPlugin != NULL; pGetPlugin++ ) { + /* + * 0 access denied + * 1 access granted + */ + rc = (*pGetPlugin)( op->o_pb, entry, desc->ad_cname.bv_val, + val, slap_access, (void *)state ); + if ( rc == 0 ) { + break; + } + } + + slapi_ch_free( (void **)&tmpPlugin ); + + return rc; +#else + return 1; +#endif /* LDAP_SLAPI */ +} +