Пример #1
0
/*
  modify a record
*/
static int lldb_modify(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.mod.message, 1);
	if (mods == NULL) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	dn = ldb_dn_alloc_linearized(lldb_ac, req->op.mod.message->dn);
	if (dn == NULL) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	ret = ldap_modify_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 int lua_apr_ldap_modify(lua_State *L)
{
  lua_apr_ldap_object *object;
  ldap_pchar_t dn;
  attrs_data attrs;
  ldap_int_t rc, msgid;
  int param = 3;

  object = check_ldap_connection(L, 1);
  dn = (ldap_pchar_t) luaL_checkstring(L, 2);
  A_init (&attrs);

  while (lua_istable(L, param)) {
    int op;
    /* get operation ('+','-','=' operations allowed) */
    lua_rawgeti(L, param, 1);
    op = op2code(lua_tostring(L, -1));
    if (op == LUA_APR_LDAP_NOOP)
      return luaL_error(L, "Forgotten operation on argument #%d!", param);
    /* get array of attributes and values */
    A_tab2mod(L, &attrs, param, op);
    param++;
  }
  A_lastattr(L, &attrs);
  rc = ldap_modify_ext(object->ldap, dn, attrs.attrs, NULL, NULL, &msgid);
  return create_future(L, rc, 1, msgid, LDAP_RES_MODIFY);
}
Пример #3
0
/** Modify something in the LDAP directory
 *
 * Binds as the administrative user and attempts to modify an LDAP object.
 *
 * @param[in] request		Current request.
 * @param[in,out] pconn		to use. May change as this function calls functions which auto re-connect.
 * @param[in] dn		of the object to modify.
 * @param[in] mods		to make, see 'man ldap_modify' for more information.
 * @param[in] serverctrls	Search controls to pass to the server.  May be NULL.
 * @param[in] clientctrls	Search controls for ldap_modify.  May be NULL.
 * @return One of the LDAP_PROC_* (#fr_ldap_rcode_t) values.
 */
fr_ldap_rcode_t fr_ldap_modify(REQUEST *request, fr_ldap_connection_t **pconn,
			       char const *dn, LDAPMod *mods[],
			       LDAPControl **serverctrls, LDAPControl **clientctrls)
{
	fr_ldap_rcode_t	status = LDAP_PROC_ERROR;

	int		msgid;		// Message id returned by ldap_search_ext.

	LDAPControl	*our_serverctrls[LDAP_MAX_CONTROLS];
	LDAPControl	*our_clientctrls[LDAP_MAX_CONTROLS];

	fr_ldap_control_merge(our_serverctrls, our_clientctrls,
			      sizeof(our_serverctrls) / sizeof(*our_serverctrls),
			      sizeof(our_clientctrls) / sizeof(*our_clientctrls),
			      *pconn, serverctrls, clientctrls);

	rad_assert(*pconn && (*pconn)->handle);

	if (RDEBUG_ENABLED4) fr_ldap_timeout_debug(request, *pconn, NULL, __FUNCTION__);

	/*
	 *	Perform all modifications as the admin user.
	 */
	if ((*pconn)->rebound) {
		status = fr_ldap_bind(request, pconn,
				      (*pconn)->config->admin_identity, (*pconn)->config->admin_password,
				      &(*pconn)->config->admin_sasl,
				      NULL, NULL, NULL);
		if (status != LDAP_PROC_SUCCESS) {
			return LDAP_PROC_ERROR;
		}

		rad_assert(*pconn);

		(*pconn)->rebound = false;
	}

	RDEBUG2("Modifying object with DN \"%s\"", dn);
	(void) ldap_modify_ext((*pconn)->handle, dn, mods, our_serverctrls, our_clientctrls, &msgid);

	RDEBUG2("Waiting for modify result...");
	status = fr_ldap_result(NULL, NULL, *pconn, msgid, 0, dn, NULL);
	switch (status) {
	case LDAP_PROC_SUCCESS:
		break;

	case LDAP_PROC_BAD_CONN:
		break;

		/* FALL-THROUGH */
	default:
		ROPTIONAL(RPEDEBUG, RPERROR, "Failed modifying object");

		goto finish;
	}

finish:
	return status;
}
Пример #4
0
/* ARGSUSED */
int _ns_ldap_modify_ext(char *service, int flags,
	char *dn, LDAPMod **mods,
	LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp)
{
	LDAP *ld = __s_api_getLDAPconn(flags);

	return (ldap_modify_ext(ld, dn, mods, serverctrls,
		clientctrls, msgidp));
}
Пример #5
0
/*
 * ldap_modify - initiate an ldap modify operation.
 *
 * Parameters:
 *
 *	ld		LDAP descriptor
 *	dn		DN of the object to modify
 *	mods		List of modifications to make.  This is null-terminated
 *			array of struct ldapmod's, specifying the modifications
 *			to perform.
 *
 * Example:
 *	LDAPMod	*mods[] = { 
 *			{ LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } },
 *			{ LDAP_MOD_REPLACE, "sn", { "babs jensen", "babs", 0 } },
 *			{ LDAP_MOD_DELETE, "ou", 0 },
 *			{ LDAP_MOD_INCREMENT, "uidNumber, { "1", 0 } }
 *			0
 *		}
 *	msgid = ldap_modify( ld, dn, mods );
 */
int
ldap_modify( LDAP *ld, LDAP_CONST char *dn, LDAPMod **mods )
{
	int rc, msgid;

	Debug( LDAP_DEBUG_TRACE, "ldap_modify\n", 0, 0, 0 );

	rc = ldap_modify_ext( ld, dn, mods, NULL, NULL, &msgid );

	if ( rc != LDAP_SUCCESS )
		return -1;

	return msgid;
}
Пример #6
0
/*
 * ldap_modify - initiate an ldap modify operation.  Parameters:
 *
 *	ld		LDAP descriptor
 *	dn		DN of the object to modify
 *	mods		List of modifications to make.  This is null-terminated
 *			array of struct ldapmod's, specifying the modifications
 *			to perform.
 *
 * Example:
 *	LDAPMod	*mods[] = { 
 *			{ LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } },
 *			{ LDAP_MOD_REPLACE, "sn", { "jensen", 0 } },
 *			0
 *		}
 *	msgid = ldap_modify( ld, dn, mods );
 */
int
LDAP_CALL
ldap_modify( LDAP *ld, const char *dn, LDAPMod **mods )
{
	int		msgid;

	LDAPDebug( LDAP_DEBUG_TRACE, "ldap_modify\n", 0, 0, 0 );

	if ( ldap_modify_ext( ld, dn, mods, NULL, NULL, &msgid )
	    == LDAP_SUCCESS ) {
		return( msgid );
	} else {
		return( -1 );	/* error is in ld handle */
	}
}
Пример #7
0
/***********************************************************************
 *      ldap_modify_extW     (WLDAP32.@)
 *
 * Change an entry in a directory tree (asynchronous operation).
 *
 * PARAMS
 *  ld          [I] Pointer to an LDAP context.
 *  dn          [I] DN of the entry to change.
 *  mods        [I] Pointer to an array of LDAPModW structures, each
 *                  specifying an attribute and its values to change.
 *  serverctrls [I] Array of LDAP server controls.
 *  clientctrls [I] Array of LDAP client controls.
 *  message     [O] Message ID of the modify 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_modify_extW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *mods[],
    PLDAPControlW *serverctrls, PLDAPControlW *clientctrls, ULONG *message )
{
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
#ifdef HAVE_LDAP
    char *dnU = NULL;
    LDAPMod **modsU = 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), mods,
           serverctrls, clientctrls, message );

    if (!ld) return ~0u;

    if (dn) {
        dnU = strWtoU( dn );
        if (!dnU) goto exit;
    }
    if (mods) {
        modsU = modarrayWtoU( mods );
        if (!modsU) goto exit;
    }
    if (serverctrls) {
        serverctrlsU = controlarrayWtoU( serverctrls );
        if (!serverctrlsU) goto exit;
    }
    if (clientctrls) {
        clientctrlsU = controlarrayWtoU( clientctrls );
        if (!clientctrlsU) goto exit;
    }

    ret = map_error( ldap_modify_ext( ld, dn ? dnU : "", mods ? modsU : nullmods, serverctrlsU,
                                      clientctrlsU, message ? (int *)message : &dummy ));

exit:
    strfreeU( dnU );
    modarrayfreeU( modsU );
    controlarrayfreeU( serverctrlsU );
    controlarrayfreeU( clientctrlsU );

#endif
    return ret;
}
Пример #8
0
int
ldap_modify_ext_s( LDAP *ld, LDAP_CONST char *dn,
	LDAPMod **mods, LDAPControl **sctrl, LDAPControl **cctrl )
{
	int		rc;
	int		msgid;
	LDAPMessage	*res;

	rc = ldap_modify_ext( ld, dn, mods, sctrl, cctrl, &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
/*
 * ldap_modify - initiate an ldap modify operation.
 *
 * Parameters:
 *
 *	ld		LDAP descriptor
 *	dn		DN of the object to modify
 *	mods		List of modifications to make.  This is null-terminated
 *			array of struct ldapmod's, specifying the modifications
 *			to perform.
 *
 * Example:
 *	LDAPMod	*mods[] = { 
 *			{ LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } },
 *			{ LDAP_MOD_REPLACE, "sn", { "jensen", 0 } },
 *			0
 *		}
 *	msgid = ldap_modify( ld, dn, mods );
 */
int
ldap_modify( LDAP *ld, LDAP_CONST char *dn, LDAPMod **mods )
{
	int rc, msgid;

#ifdef NEW_LOGGING
	LDAP_LOG ( OPERATION, ENTRY, "ldap_modify\n", 0, 0, 0 );
#else
	Debug( LDAP_DEBUG_TRACE, "ldap_modify\n", 0, 0, 0 );
#endif

	rc = ldap_modify_ext( ld, dn, mods, NULL, NULL, &msgid );

	if ( rc != LDAP_SUCCESS )
		return -1;

	return msgid;
}
Пример #10
0
int
LDAP_CALL
ldap_modify_ext_s( LDAP *ld, const char *dn, LDAPMod **mods,
    LDAPControl **serverctrls, LDAPControl **clientctrls )
{
	int		msgid, err;
	LDAPMessage	*res;

	if (( err = ldap_modify_ext( ld, dn, mods, serverctrls, clientctrls,
	    &msgid )) != LDAP_SUCCESS ) {
		return( err );
	}

	if ( ldap_result( ld, msgid, 1, (struct timeval *)NULL, &res ) == -1 ) {
		return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
	}

	return( ldap_result2error( ld, res, 1 ) );
}
Пример #11
0
/*
** Modify an entry.
** @param #1 LDAP connection.
** @param #2 String with entry's DN.
** @param #3, #4... Tables with modifications to apply.
** @return True on success or nil, error message otherwise.
*/
static int lualdap_modify (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;
	int param = 3;
	A_init (&attrs);
	while (lua_istable (L, param)) {
		int op;
		/* get operation ('+','-','=' operations allowed) */
		lua_rawgeti (L, param, 1);
		op = op2code (lua_tostring (L, -1));
		if (op == LUALDAP_NO_OP)
			return luaL_error (L, LUALDAP_PREFIX"forgotten operation on argument #%d", param);
		/* get array of attributes and values */
		A_tab2mod (L, &attrs, param, op);
		param++;
	}
	A_lastattr (L, &attrs);
	rc = ldap_modify_ext (conn->ld, dn, attrs.attrs, NULL, NULL, &msgid);
	return create_future (L, rc, 1, msgid, LDAP_RES_MODIFY);
}
Пример #12
0
/***********************************************************************
 *      ldap_modifyW     (WLDAP32.@)
 *
 * Change an entry in a directory tree (asynchronous operation).
 *
 * PARAMS
 *  ld     [I] Pointer to an LDAP context.
 *  dn     [I] DN of the entry to change.
 *  mods   [I] Pointer to an array of LDAPModW structures, each
 *             specifying an attribute and its values to change.
 *
 * RETURNS
 *  Success: Message ID of the modify 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_modifyW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *mods[] )
{
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
#ifdef HAVE_LDAP
    char *dnU = NULL;
    LDAPMod **modsU = NULL;
    int msg;

    ret = WLDAP32_LDAP_NO_MEMORY;

    TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), mods );

    if (!ld) return WLDAP32_LDAP_PARAM_ERROR;

    if (dn) {
        dnU = strWtoU( dn );
        if (!dnU) goto exit;
    }
    if (mods) {
        modsU = modarrayWtoU( mods );
        if (!modsU) goto exit;
    }

    ret = ldap_modify_ext( ld, dn ? dnU : "", mods ? modsU : nullmods,
                           NULL, NULL, &msg );

    if (ret == LDAP_SUCCESS)
        ret = msg;
    else
        ret = ~0u;

exit:
    strfreeU( dnU );
    modarrayfreeU( modsU );

#endif
    return ret;
}
Пример #13
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;
}
Пример #14
0
int
meta_back_modify( Operation *op, SlapReply *rs )
{
	metainfo_t	*mi = ( metainfo_t * )op->o_bd->be_private;
	metatarget_t	*mt;
	metaconn_t	*mc;
	int		rc = 0;
	LDAPMod		**modv = NULL;
	LDAPMod		*mods = NULL;
	Modifications	*ml;
	int		candidate = -1, i;
	int		isupdate;
	struct berval	mdn = BER_BVNULL;
	struct berval	mapped;
	dncookie	dc;
	int		msgid;
	ldap_back_send_t	retrying = LDAP_BACK_RETRYING;
	LDAPControl	**ctrls = NULL;

	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 modify dn, if needed
	 */
	mt = mi->mi_targets[ candidate ];
	dc.target = mt;
	dc.conn = op->o_conn;
	dc.rs = rs;
	dc.ctx = "modifyDN";

	if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
		send_ldap_result( op, rs );
		goto cleanup;
	}

	for ( i = 0, ml = op->orm_modlist; ml; i++ ,ml = ml->sml_next )
		;

	mods = ch_malloc( sizeof( LDAPMod )*i );
	if ( mods == NULL ) {
		rs->sr_err = LDAP_OTHER;
		send_ldap_result( op, rs );
		goto cleanup;
	}
	modv = ( LDAPMod ** )ch_malloc( ( i + 1 )*sizeof( LDAPMod * ) );
	if ( modv == NULL ) {
		rs->sr_err = LDAP_OTHER;
		send_ldap_result( op, rs );
		goto cleanup;
	}

	dc.ctx = "modifyAttrDN";
	isupdate = be_shadow_update( op );
	for ( i = 0, ml = op->orm_modlist; ml; ml = ml->sml_next ) {
		int	j, is_oc = 0;

		if ( !isupdate && !get_relax( op ) && ml->sml_desc->ad_type->sat_no_user_mod  )
		{
			continue;
		}

		if ( ml->sml_desc == slap_schema.si_ad_objectClass 
				|| ml->sml_desc == slap_schema.si_ad_structuralObjectClass )
		{
			is_oc = 1;
			mapped = ml->sml_desc->ad_cname;

		} else {
			ldap_back_map( &mt->mt_rwmap.rwm_at,
					&ml->sml_desc->ad_cname, &mapped,
					BACKLDAP_MAP );
			if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
				continue;
			}
		}

		modv[ i ] = &mods[ i ];
		mods[ i ].mod_op = ml->sml_op | LDAP_MOD_BVALUES;
		mods[ i ].mod_type = mapped.bv_val;

		/*
		 * FIXME: dn-valued attrs should be rewritten
		 * to allow their use in ACLs at the back-ldap
		 * level.
		 */
		if ( ml->sml_values != NULL ) {
			if ( is_oc ) {
				for ( j = 0; !BER_BVISNULL( &ml->sml_values[ j ] ); j++ )
					;
				mods[ i ].mod_bvalues =
					(struct berval **)ch_malloc( ( j + 1 ) *
					sizeof( struct berval * ) );
				for ( j = 0; !BER_BVISNULL( &ml->sml_values[ j ] ); ) {
					struct ldapmapping	*mapping;

					ldap_back_mapping( &mt->mt_rwmap.rwm_oc,
							&ml->sml_values[ j ], &mapping, BACKLDAP_MAP );

					if ( mapping == NULL ) {
						if ( mt->mt_rwmap.rwm_oc.drop_missing ) {
							continue;
						}
						mods[ i ].mod_bvalues[ j ] = &ml->sml_values[ j ];

					} else {
						mods[ i ].mod_bvalues[ j ] = &mapping->dst;
					}
					j++;
				}
				mods[ i ].mod_bvalues[ j ] = NULL;

			} else {
				if ( ml->sml_desc->ad_type->sat_syntax ==
						slap_schema.si_syn_distinguishedName )
				{
					( void )ldap_dnattr_rewrite( &dc, ml->sml_values );
					if ( ml->sml_values == NULL ) {
						continue;
					}
				}

				for ( j = 0; !BER_BVISNULL( &ml->sml_values[ j ] ); j++ )
					;
				mods[ i ].mod_bvalues =
					(struct berval **)ch_malloc( ( j + 1 ) *
					sizeof( struct berval * ) );
				for ( j = 0; !BER_BVISNULL( &ml->sml_values[ j ] ); j++ ) {
					mods[ i ].mod_bvalues[ j ] = &ml->sml_values[ j ];
				}
				mods[ i ].mod_bvalues[ j ] = NULL;
			}

		} else {
			mods[ i ].mod_bvalues = NULL;
		}

		i++;
	}
	modv[ i ] = 0;

retry:;
	ctrls = op->o_ctrls;
	rc = meta_back_controls_add( op, rs, mc, candidate, &ctrls );
	if ( rc != LDAP_SUCCESS ) {
		send_ldap_result( op, rs );
		goto cleanup;
	}

	rs->sr_err = ldap_modify_ext( mc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
			modv, ctrls, NULL, &msgid );
	rs->sr_err = meta_back_op_result( mc, op, rs, candidate, msgid,
		mt->mt_timeout[ SLAP_OP_MODIFY ], ( 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 );

	if ( mdn.bv_val != op->o_req_dn.bv_val ) {
		free( mdn.bv_val );
		BER_BVZERO( &mdn );
	}
	if ( modv != NULL ) {
		for ( i = 0; modv[ i ]; i++ ) {
			free( modv[ i ]->mod_bvalues );
		}
	}
	free( mods );
	free( modv );

	if ( mc ) {
		meta_back_release_conn( mi, mc );
	}

	return rs->sr_err;
}
Пример #15
0
// wrappers for ldap_modify_ext
//
nsresult
nsLDAPOperation::ModifyExt(const char *base,
                           nsIArray *mods,
                           LDAPControl **serverctrls,
                           LDAPControl **clientctrls)
{
  if (mMessageListener == 0) {
    NS_ERROR("nsLDAPOperation::ModifyExt(): mMessageListener not set");
    return NS_ERROR_NOT_INITIALIZED;
  }

  LDAPMod **attrs = 0;
  int retVal = 0;
  PRUint32 modCount = 0;
  nsresult rv = mods->GetLength(&modCount);
  NS_ENSURE_SUCCESS(rv, rv);
  if (modCount && mods) {
    attrs = static_cast<LDAPMod **>(nsMemory::Alloc((modCount + 1) *
                                                       sizeof(LDAPMod *)));
    if (!attrs) {
      NS_ERROR("nsLDAPOperation::ModifyExt: 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;

      PRInt32 operation;
      nsresult rv = modif->GetOperation(&operation);
      if (NS_FAILED(rv))
        break;

      attrs[index]->mod_op = operation | LDAP_MOD_BVALUES;

      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_modify_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);
}
Пример #16
0
int
ldap_back_modify(
		Operation	*op,
		SlapReply	*rs )
{
	ldapinfo_t		*li = (ldapinfo_t *)op->o_bd->be_private;

	ldapconn_t		*lc = NULL;
	LDAPMod			**modv = NULL,
				*mods = NULL;
	Modifications		*ml;
	int			i, j, rc;
	ber_int_t		msgid;
	int			isupdate;
	ldap_back_send_t	retrying = LDAP_BACK_RETRYING;
	LDAPControl		**ctrls = NULL;

	if ( !ldap_back_dobind( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
		return rs->sr_err;
	}

	for ( i = 0, ml = op->orm_modlist; ml; i++, ml = ml->sml_next )
		/* just count mods */ ;

	modv = (LDAPMod **)ch_malloc( ( i + 1 )*sizeof( LDAPMod * )
			+ i*sizeof( LDAPMod ) );
	if ( modv == NULL ) {
		rc = LDAP_NO_MEMORY;
		goto cleanup;
	}
	mods = (LDAPMod *)&modv[ i + 1 ];

	isupdate = be_shadow_update( op );
	for ( i = 0, ml = op->orm_modlist; ml; ml = ml->sml_next ) {
		if ( !isupdate && !get_relax( op ) && ml->sml_desc->ad_type->sat_no_user_mod  )
		{
			continue;
		}

		modv[ i ] = &mods[ i ];
		mods[ i ].mod_op = ( ml->sml_op | LDAP_MOD_BVALUES );
		mods[ i ].mod_type = ml->sml_desc->ad_cname.bv_val;

		if ( ml->sml_values != NULL ) {
			if ( ml->sml_values == NULL ) {	
				continue;
			}

			for ( j = 0; !BER_BVISNULL( &ml->sml_values[ j ] ); j++ )
				/* just count mods */ ;
			mods[ i ].mod_bvalues =
				(struct berval **)ch_malloc( ( j + 1 )*sizeof( struct berval * ) );
			for ( j = 0; !BER_BVISNULL( &ml->sml_values[ j ] ); j++ )
			{
				mods[ i ].mod_bvalues[ j ] = &ml->sml_values[ j ];
			}
			mods[ i ].mod_bvalues[ j ] = NULL;

		} else {
			mods[ i ].mod_bvalues = NULL;
		}

		i++;
	}
	modv[ i ] = 0;

retry:;
	ctrls = op->o_ctrls;
	rc = ldap_back_controls_add( op, rs, lc, &ctrls );
	if ( rc != LDAP_SUCCESS ) {
		send_ldap_result( op, rs );
		rc = -1;
		goto cleanup;
	}

	rs->sr_err = ldap_modify_ext( lc->lc_ld, op->o_req_dn.bv_val, modv,
			ctrls, NULL, &msgid );
	rc = ldap_back_op_result( lc, op, rs, msgid,
		li->li_timeout[ SLAP_OP_MODIFY ],
		( 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;
		}
	}

cleanup:;
	(void)ldap_back_controls_free( op, rs, &ctrls );

	for ( i = 0; modv[ i ]; i++ ) {
		ch_free( modv[ i ]->mod_bvalues );
	}
	ch_free( modv );

	if ( lc != NULL ) {
		ldap_back_release_conn( li, lc );
	}

	return rc;
}