/* add a record */ static int lldb_add(struct lldb_context *lldb_ac) { struct ldb_context *ldb; struct lldb_private *lldb = lldb_ac->lldb; struct ldb_module *module = lldb_ac->module; struct ldb_request *req = lldb_ac->req; LDAPMod **mods; char *dn; int ret; ldb = ldb_module_get_ctx(module); ldb_request_set_state(req, LDB_ASYNC_PENDING); mods = lldb_msg_to_mods(lldb_ac, req->op.add.message, 0); if (mods == NULL) { return LDB_ERR_OPERATIONS_ERROR; } dn = ldb_dn_alloc_linearized(lldb_ac, req->op.add.message->dn); if (dn == NULL) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldap_add_ext(lldb->ldap, dn, mods, NULL, NULL, &lldb_ac->msgid); if (ret != LDAP_SUCCESS) { ldb_set_errstring(ldb, ldap_err2string(ret)); } return lldb_ldap_to_ldb(ret); }
static void import_send_key (SeahorseLDAPSource *self, GSimpleAsyncResult *res) { source_import_closure *closure = g_simple_async_result_get_op_res_gpointer (res); LDAPServerInfo *sinfo; gchar *base; LDAPMod mod; LDAPMod *attrs[2]; char *values[2]; GSource *gsource; GError *error = NULL; gchar *keydata; int ldap_op; int rc; if (closure->current_index >= 0) { keydata = closure->keydata->pdata[closure->current_index]; seahorse_progress_end (closure->cancellable, keydata); } closure->current_index++; /* All done, complete operation */ if (closure->current_index == (gint)closure->keydata->len) { g_simple_async_result_complete (res); return; } keydata = closure->keydata->pdata[closure->current_index]; seahorse_progress_begin (closure->cancellable, keydata); values[0] = keydata; values[1] = NULL; sinfo = get_ldap_server_info (self, TRUE); memset (&mod, 0, sizeof (mod)); mod.mod_op = LDAP_MOD_ADD; mod.mod_type = sinfo->key_attr; mod.mod_values = values; attrs[0] = &mod; attrs[1] = NULL; base = g_strdup_printf ("pgpCertid=virtual,%s", sinfo->base_dn); rc = ldap_add_ext (closure->ldap, base, attrs, NULL, NULL, &ldap_op); g_free (base); if (seahorse_ldap_source_propagate_error (self, rc, &error)) { g_simple_async_result_complete (res); return; } gsource = seahorse_ldap_gsource_new (closure->ldap, ldap_op, closure->cancellable); g_source_set_callback (gsource, (GSourceFunc)on_import_add_completed, g_object_ref (res), g_object_unref); g_source_attach (gsource, g_main_context_default ()); g_source_unref (gsource); }
/* ARGSUSED */ int _ns_ldap_add_ext(char *service, int flags, char *dn, LDAPMod **attrs, LDAPControl ** serverctrls, LDAPControl **clientctrls, int *msgidp) { LDAP *ld = __s_api_getLDAPconn(flags); return (ldap_add_ext(ld, dn, attrs, serverctrls, clientctrls, msgidp)); }
/* ** Add a new entry to the directory. ** @param #1 LDAP connection. ** @param #2 String with new entry's DN. ** @param #3 Table with new entry's attributes and values. ** @return Function to process the LDAP result. */ static int lualdap_add (lua_State *L) { conn_data *conn = getconnection (L); ldap_pchar_t dn = (ldap_pchar_t) luaL_checkstring (L, 2); attrs_data attrs; ldap_int_t rc, msgid; A_init (&attrs); if (lua_istable (L, 3)) A_tab2mod (L, &attrs, 3, LUALDAP_MOD_ADD); A_lastattr (L, &attrs); rc = ldap_add_ext (conn->ld, dn, attrs.attrs, NULL, NULL, &msgid); return create_future (L, rc, 1, msgid, LDAP_RES_ADD); }
/* * ldap_add - initiate an ldap add operation. Parameters: * * ld LDAP descriptor * dn DN of the entry to add * mods List of attributes for the entry. This is a null- * terminated array of pointers to LDAPMod structures. * only the type and values in the structures need be * filled in. * * Example: * LDAPMod *attrs[] = { * { 0, "cn", { "babs jensen", "babs", 0 } }, * { 0, "sn", { "jensen", 0 } }, * { 0, "objectClass", { "person", 0 } }, * 0 * } * msgid = ldap_add( ld, dn, attrs ); */ int ldap_add( LDAP *ld, LDAP_CONST char *dn, LDAPMod **attrs ) { int rc; int msgid; rc = ldap_add_ext( ld, dn, attrs, NULL, NULL, &msgid ); if ( rc != LDAP_SUCCESS ) return -1; return msgid; }
/*********************************************************************** * ldap_add_extW (WLDAP32.@) * * Add an entry to a directory tree (asynchronous operation). * * PARAMS * ld [I] Pointer to an LDAP context. * dn [I] DN of the entry to add. * attrs [I] Pointer to an array of LDAPModW structures, each * specifying an attribute and its values to add. * serverctrls [I] Array of LDAP server controls. * clientctrls [I] Array of LDAP client controls. * message [O] Message ID of the add operation. * * RETURNS * Success: LDAP_SUCCESS * Failure: An LDAP error code. * * NOTES * Call ldap_result with the message ID to get the result of * the operation. The serverctrls and clientctrls parameters are * optional and should be set to NULL if not used. */ ULONG CDECL ldap_add_extW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *attrs[], PLDAPControlW *serverctrls, PLDAPControlW *clientctrls, ULONG *message ) { ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; #ifdef HAVE_LDAP char *dnU = NULL; LDAPMod **attrsU = NULL; LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL; int dummy; ret = WLDAP32_LDAP_NO_MEMORY; TRACE( "(%p, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn), attrs, serverctrls, clientctrls, message ); if (!ld) return WLDAP32_LDAP_PARAM_ERROR; if (dn) { dnU = strWtoU( dn ); if (!dnU) goto exit; } if (attrs) { attrsU = modarrayWtoU( attrs ); if (!attrsU) goto exit; } if (serverctrls) { serverctrlsU = controlarrayWtoU( serverctrls ); if (!serverctrlsU) goto exit; } if (clientctrls) { clientctrlsU = controlarrayWtoU( clientctrls ); if (!clientctrlsU) goto exit; } ret = map_error( ldap_add_ext( ld, dn ? dnU : "", attrs ? attrsU : nullattrs, serverctrlsU, clientctrlsU, message ? (int *)message : &dummy )); exit: strfreeU( dnU ); modarrayfreeU( attrsU ); controlarrayfreeU( serverctrlsU ); controlarrayfreeU( clientctrlsU ); #endif return ret; }
static int lua_apr_ldap_add(lua_State *L) { lua_apr_ldap_object *object; ldap_pchar_t dn; attrs_data attrs; ldap_int_t rc, msgid; object = check_ldap_connection(L, 1); dn = (ldap_pchar_t) luaL_checkstring(L, 2); A_init(&attrs); if (lua_istable(L, 3)) A_tab2mod(L, &attrs, 3, LUA_APR_LDAP_MOD_ADD); A_lastattr(L, &attrs); rc = ldap_add_ext(object->ldap, dn, attrs.attrs, NULL, NULL, &msgid); return create_future(L, rc, 1, msgid, LDAP_RES_ADD); }
int ldap_add_ext_s( LDAP *ld, LDAP_CONST char *dn, LDAPMod **attrs, LDAPControl **sctrls, LDAPControl **cctrls ) { int msgid, rc; LDAPMessage *res; rc = ldap_add_ext( ld, dn, attrs, sctrls, cctrls, &msgid ); if ( rc != LDAP_SUCCESS ) return( rc ); if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res ) return( ld->ld_errno ); return( ldap_result2error( ld, res, 1 ) ); }
/*********************************************************************** * ldap_addW (WLDAP32.@) * * Add an entry to a directory tree (asynchronous operation). * * PARAMS * ld [I] Pointer to an LDAP context. * dn [I] DN of the entry to add. * attrs [I] Pointer to an array of LDAPModW structures, each * specifying an attribute and its values to add. * * RETURNS * Success: Message ID of the add operation. * Failure: An LDAP error code. * * NOTES * Call ldap_result with the message ID to get the result of * the operation. Cancel the operation by calling ldap_abandon * with the message ID. */ ULONG CDECL ldap_addW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *attrs[] ) { ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; #ifdef HAVE_LDAP char *dnU = NULL; LDAPMod **attrsU = NULL; int msg; ret = WLDAP32_LDAP_NO_MEMORY; TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), attrs ); if (!ld) return WLDAP32_LDAP_PARAM_ERROR; if (dn) { dnU = strWtoU( dn ); if (!dnU) goto exit; } if (attrs) { attrsU = modarrayWtoU( attrs ); if (!attrsU) goto exit; } ret = ldap_add_ext( ld, dn ? dnU : "", attrs ? attrsU : nullattrs, NULL, NULL, &msg ); if (ret == LDAP_SUCCESS) ret = msg; else ret = ~0u; exit: strfreeU( dnU ); modarrayfreeU( attrsU ); #endif return ret; }
int ldap_add_ext_s(LDAP *ld, char *dn, LDAPMod **attrs, LDAPControl ** serverctrls, LDAPControl **clientctrls) { int msgid; int retcode = LDAP_SUCCESS; LDAPMessage *res; if ((retcode = ldap_add_ext(ld, dn, attrs, serverctrls, clientctrls, &msgid)) != LDAP_SUCCESS) return (retcode); if (ldap_result(ld, msgid, 1, (struct timeval *)NULL, &res ) == -1) return (ld->ld_errno ); #ifdef _REENTRANT LOCK_LDAP(ld); #endif retcode = ldap_parse_result(ld, res, &ld->ld_errno, &ld->ld_matched, &ld->ld_error, &ld->ld_referrals, &ld->ld_ret_ctrls, 1); if (retcode == LDAP_SUCCESS) retcode = ld->ld_errno; #ifdef _REENTRANT UNLOCK_LDAP(ld); #endif return (retcode); }
static int domodify( const char *dn, LDAPMod **pmods, LDAPControl **pctrls, int newentry ) { int rc, i, j, k, notascii, op; struct berval *bvp; if ( dn == NULL ) { fprintf( stderr, _("%s: no DN specified\n"), prog ); return( LDAP_PARAM_ERROR ); } if ( pmods == NULL ) { /* implement "touch" (empty sequence) * modify operation (note that there * is no symmetry with the UNIX command, * since \"touch\" on a non-existent entry * will fail)*/ printf( "warning: no attributes to %sadd (entry=\"%s\")\n", newentry ? "" : "change or ", dn ); } else { for ( i = 0; pmods[ i ] != NULL; ++i ) { op = pmods[ i ]->mod_op & ~LDAP_MOD_BVALUES; if( op == LDAP_MOD_ADD && ( pmods[i]->mod_bvalues == NULL )) { fprintf( stderr, _("%s: attribute \"%s\" has no values (entry=\"%s\")\n"), prog, pmods[i]->mod_type, dn ); return LDAP_PARAM_ERROR; } } if ( verbose ) { for ( i = 0; pmods[ i ] != NULL; ++i ) { op = pmods[ i ]->mod_op & ~LDAP_MOD_BVALUES; printf( "%s %s:\n", op == LDAP_MOD_REPLACE ? _("replace") : op == LDAP_MOD_ADD ? _("add") : op == LDAP_MOD_INCREMENT ? _("increment") : op == LDAP_MOD_DELETE ? _("delete") : _("unknown"), pmods[ i ]->mod_type ); if ( pmods[ i ]->mod_bvalues != NULL ) { for ( j = 0; pmods[ i ]->mod_bvalues[ j ] != NULL; ++j ) { bvp = pmods[ i ]->mod_bvalues[ j ]; notascii = 0; for ( k = 0; (unsigned long) k < bvp->bv_len; ++k ) { if ( !isascii( bvp->bv_val[ k ] )) { notascii = 1; break; } } if ( notascii ) { printf( _("\tNOT ASCII (%ld bytes)\n"), bvp->bv_len ); } else { printf( "\t%s\n", bvp->bv_val ); } } } } } } if ( newentry ) { printf( "%sadding new entry \"%s\"\n", dont ? "!" : "", dn ); } else { printf( "%smodifying entry \"%s\"\n", dont ? "!" : "", dn ); } if ( !dont ) { int msgid; if ( newentry ) { rc = ldap_add_ext( ld, dn, pmods, pctrls, NULL, &msgid ); } else { rc = ldap_modify_ext( ld, dn, pmods, pctrls, NULL, &msgid ); } if ( rc != LDAP_SUCCESS ) { /* print error message about failed update including DN */ fprintf( stderr, _("%s: update failed: %s\n"), prog, dn ); tool_perror( newentry ? "ldap_add" : "ldap_modify", rc, NULL, NULL, NULL, NULL ); goto done; } rc = process_response( ld, msgid, newentry ? LDAP_RES_ADD : LDAP_RES_MODIFY, dn ); if ( verbose && rc == LDAP_SUCCESS ) { printf( _("modify complete\n") ); } } else { rc = LDAP_SUCCESS; } done: putchar( '\n' ); return rc; }
// wrappers for ldap_add_ext // nsresult nsLDAPOperation::AddExt(const char *base, nsIArray *mods, LDAPControl **serverctrls, LDAPControl **clientctrls) { if (mMessageListener == 0) { NS_ERROR("nsLDAPOperation::AddExt(): mMessageListener not set"); return NS_ERROR_NOT_INITIALIZED; } LDAPMod **attrs = 0; int retVal = LDAP_SUCCESS; PRUint32 modCount = 0; nsresult rv = mods->GetLength(&modCount); NS_ENSURE_SUCCESS(rv, rv); if (mods && modCount) { attrs = static_cast<LDAPMod **>(nsMemory::Alloc((modCount + 1) * sizeof(LDAPMod *))); if (!attrs) { NS_ERROR("nsLDAPOperation::AddExt: out of memory "); return NS_ERROR_OUT_OF_MEMORY; } nsCAutoString type; PRUint32 index; for (index = 0; index < modCount && NS_SUCCEEDED(rv); ++index) { attrs[index] = new LDAPMod(); if (!attrs[index]) return NS_ERROR_OUT_OF_MEMORY; nsCOMPtr<nsILDAPModification> modif(do_QueryElementAt(mods, index, &rv)); if (NS_FAILED(rv)) break; #ifdef NS_DEBUG PRInt32 operation; NS_ASSERTION(NS_SUCCEEDED(modif->GetOperation(&operation)) && ((operation & ~LDAP_MOD_BVALUES) == LDAP_MOD_ADD), "AddExt can only add."); #endif attrs[index]->mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES; nsresult rv = modif->GetType(type); if (NS_FAILED(rv)) break; attrs[index]->mod_type = ToNewCString(type); rv = CopyValues(modif, &attrs[index]->mod_bvalues); if (NS_FAILED(rv)) break; } if (NS_SUCCEEDED(rv)) { attrs[modCount] = 0; retVal = ldap_add_ext(mConnectionHandle, base, attrs, serverctrls, clientctrls, &mMsgID); } else // reset the modCount so we correctly free the array. modCount = index; } for (PRUint32 counter = 0; counter < modCount; ++counter) delete attrs[counter]; nsMemory::Free(attrs); return NS_FAILED(rv) ? rv : TranslateLDAPErrorToNSError(retVal); }
int meta_back_add( Operation *op, SlapReply *rs ) { metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; metatarget_t *mt; metaconn_t *mc; int i, candidate = -1; int isupdate; Attribute *a; LDAPMod **attrs; struct berval mdn = BER_BVNULL, mapped; dncookie dc; int msgid; ldap_back_send_t retrying = LDAP_BACK_RETRYING; LDAPControl **ctrls = NULL; Debug(LDAP_DEBUG_ARGS, "==> meta_back_add: %s\n", op->o_req_dn.bv_val ); /* * get the current connection */ mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR ); if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) { return rs->sr_err; } assert( mc->mc_conns[ candidate ].msc_ld != NULL ); /* * Rewrite the add dn, if needed */ mt = mi->mi_targets[ candidate ]; dc.target = mt; dc.conn = op->o_conn; dc.rs = rs; dc.ctx = "addDN"; if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) { send_ldap_result( op, rs ); goto done; } /* Count number of attributes in entry ( +1 ) */ for ( i = 1, a = op->ora_e->e_attrs; a; i++, a = a->a_next ); /* Create array of LDAPMods for ldap_add() */ attrs = ch_malloc( sizeof( LDAPMod * )*i ); dc.ctx = "addAttrDN"; isupdate = be_shadow_update( op ); for ( i = 0, a = op->ora_e->e_attrs; a; a = a->a_next ) { int j, is_oc = 0; if ( !isupdate && !get_relax( op ) && a->a_desc->ad_type->sat_no_user_mod ) { continue; } if ( a->a_desc == slap_schema.si_ad_objectClass || a->a_desc == slap_schema.si_ad_structuralObjectClass ) { is_oc = 1; mapped = a->a_desc->ad_cname; } else { ldap_back_map( &mt->mt_rwmap.rwm_at, &a->a_desc->ad_cname, &mapped, BACKLDAP_MAP ); if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) { continue; } } attrs[ i ] = ch_malloc( sizeof( LDAPMod ) ); if ( attrs[ i ] == NULL ) { continue; } attrs[ i ]->mod_op = LDAP_MOD_BVALUES; attrs[ i ]->mod_type = mapped.bv_val; if ( is_oc ) { for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ ) ; attrs[ i ]->mod_bvalues = (struct berval **)ch_malloc( ( j + 1 ) * sizeof( struct berval * ) ); for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); ) { struct ldapmapping *mapping; ldap_back_mapping( &mt->mt_rwmap.rwm_oc, &a->a_vals[ j ], &mapping, BACKLDAP_MAP ); if ( mapping == NULL ) { if ( mt->mt_rwmap.rwm_oc.drop_missing ) { continue; } attrs[ i ]->mod_bvalues[ j ] = &a->a_vals[ j ]; } else { attrs[ i ]->mod_bvalues[ j ] = &mapping->dst; } j++; } attrs[ i ]->mod_bvalues[ j ] = NULL; } else { /* * FIXME: dn-valued attrs should be rewritten * to allow their use in ACLs at the back-ldap * level. */ if ( a->a_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) { (void)ldap_dnattr_rewrite( &dc, a->a_vals ); if ( a->a_vals == NULL ) { continue; } } for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ ) ; attrs[ i ]->mod_bvalues = ch_malloc( ( j + 1 ) * sizeof( struct berval * ) ); for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ ) { attrs[ i ]->mod_bvalues[ j ] = &a->a_vals[ j ]; } attrs[ i ]->mod_bvalues[ j ] = NULL; } i++; } attrs[ i ] = NULL; retry:; ctrls = op->o_ctrls; if ( meta_back_controls_add( op, rs, mc, candidate, &ctrls ) != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto cleanup; } rs->sr_err = ldap_add_ext( mc->mc_conns[ candidate ].msc_ld, mdn.bv_val, attrs, ctrls, NULL, &msgid ); rs->sr_err = meta_back_op_result( mc, op, rs, candidate, msgid, mt->mt_timeout[ SLAP_OP_ADD ], ( LDAP_BACK_SENDRESULT | retrying ) ); if ( rs->sr_err == LDAP_UNAVAILABLE && retrying ) { retrying &= ~LDAP_BACK_RETRYING; if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) { /* if the identity changed, there might be need to re-authz */ (void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls ); goto retry; } } cleanup:; (void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls ); for ( --i; i >= 0; --i ) { free( attrs[ i ]->mod_bvalues ); free( attrs[ i ] ); } free( attrs ); if ( mdn.bv_val != op->ora_e->e_dn ) { free( mdn.bv_val ); BER_BVZERO( &mdn ); } done:; if ( mc ) { meta_back_release_conn( mi, mc ); } return rs->sr_err; }
int ldap_back_add( Operation *op, SlapReply *rs ) { ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; ldapconn_t *lc = NULL; int i = 0, j = 0; Attribute *a; LDAPMod **attrs = NULL, *attrs2 = NULL; ber_int_t msgid; int isupdate; ldap_back_send_t retrying = LDAP_BACK_RETRYING; LDAPControl **ctrls = NULL; rs->sr_err = LDAP_SUCCESS; Debug( LDAP_DEBUG_ARGS, "==> ldap_back_add(\"%s\")\n", op->o_req_dn.bv_val, 0, 0 ); if ( !ldap_back_dobind( &lc, op, rs, LDAP_BACK_SENDERR ) ) { lc = NULL; goto cleanup; } /* Count number of attributes in entry */ for ( i = 1, a = op->oq_add.rs_e->e_attrs; a; i++, a = a->a_next ) /* just count attrs */ ; /* Create array of LDAPMods for ldap_add() */ attrs = (LDAPMod **)ch_malloc( sizeof( LDAPMod * )*i + sizeof( LDAPMod )*( i - 1 ) ); attrs2 = ( LDAPMod * )&attrs[ i ]; isupdate = be_shadow_update( op ); for ( i = 0, a = op->oq_add.rs_e->e_attrs; a; a = a->a_next ) { if ( !isupdate && !get_relax( op ) && a->a_desc->ad_type->sat_no_user_mod ) { continue; } attrs[ i ] = &attrs2[ i ]; attrs[ i ]->mod_op = LDAP_MOD_BVALUES; attrs[ i ]->mod_type = a->a_desc->ad_cname.bv_val; for ( j = 0; a->a_vals[ j ].bv_val; j++ ) /* just count vals */ ; attrs[i]->mod_vals.modv_bvals = ch_malloc( ( j + 1 )*sizeof( struct berval * ) ); for ( j = 0; a->a_vals[ j ].bv_val; j++ ) { attrs[ i ]->mod_vals.modv_bvals[ j ] = &a->a_vals[ j ]; } attrs[ i ]->mod_vals.modv_bvals[ j ] = NULL; i++; } attrs[ i ] = NULL; retry: ctrls = op->o_ctrls; rs->sr_err = ldap_back_controls_add( op, rs, lc, &ctrls ); if ( rs->sr_err != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto cleanup; } rs->sr_err = ldap_add_ext( lc->lc_ld, op->o_req_dn.bv_val, attrs, ctrls, NULL, &msgid ); rs->sr_err = ldap_back_op_result( lc, op, rs, msgid, li->li_timeout[ SLAP_OP_ADD ], ( LDAP_BACK_SENDRESULT | retrying ) ); if ( rs->sr_err == LDAP_UNAVAILABLE && retrying ) { retrying &= ~LDAP_BACK_RETRYING; if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) { /* if the identity changed, there might be need to re-authz */ (void)ldap_back_controls_free( op, rs, &ctrls ); goto retry; } } ldap_pvt_thread_mutex_lock( &li->li_counter_mutex ); ldap_pvt_mp_add( li->li_ops_completed[ SLAP_OP_ADD ], 1 ); ldap_pvt_thread_mutex_unlock( &li->li_counter_mutex ); cleanup: (void)ldap_back_controls_free( op, rs, &ctrls ); if ( attrs ) { for ( --i; i >= 0; --i ) { ch_free( attrs[ i ]->mod_vals.modv_bvals ); } ch_free( attrs ); } if ( lc ) { ldap_back_release_conn( li, lc ); } Debug( LDAP_DEBUG_ARGS, "<== ldap_back_add(\"%s\"): %d\n", op->o_req_dn.bv_val, rs->sr_err, 0 ); return rs->sr_err; }