예제 #1
0
파일: ldb_ldap.c 프로젝트: AIdrifter/samba
/*
  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);
}
예제 #2
0
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);
}
예제 #3
0
/* 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));
}
예제 #4
0
/*
** 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);
}
예제 #5
0
파일: add.c 프로젝트: dago/openldap
/*
 * 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;
}
예제 #6
0
파일: add.c 프로젝트: RareHare/reactos
/***********************************************************************
 *      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;
}
예제 #7
0
파일: ldap.c 프로젝트: LuaDist/lua-apr
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);
}
예제 #8
0
파일: add.c 프로젝트: dago/openldap
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 ) );
}
예제 #9
0
파일: add.c 프로젝트: RareHare/reactos
/***********************************************************************
 *      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;
}
예제 #10
0
파일: add.c 프로젝트: andreiw/polaris
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);
}
예제 #11
0
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;
}
예제 #12
0
// 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);
}
예제 #13
0
파일: add.c 프로젝트: tiniesst/ReOpenLDAP
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;
}
예제 #14
0
파일: add.c 프로젝트: Distrotech/openldap
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;
}