Exemplo n.º 1
0
/* Generate a remote message with a mapped objectClass. */
static void map_objectclass_generate_remote(struct ldb_module *module, const char *local_attr, const struct ldb_message *old, struct ldb_message *remote, struct ldb_message *local)
{
	const struct ldb_map_context *data = map_get_context(module);
	struct ldb_context *ldb;
	struct ldb_message_element *el, *oc;
	struct ldb_val val;
	bool found_extensibleObject = false;
	unsigned int i;

	ldb = ldb_module_get_ctx(module);

	/* Find old local objectClass */
	oc = ldb_msg_find_element(old, "objectClass");
	if (oc == NULL) {
		return;
	}

	/* Prepare new element */
	el = talloc_zero(remote, struct ldb_message_element);
	if (el == NULL) {
		ldb_oom(ldb);
		return;			/* TODO: fail? */
	}

	/* Copy local objectClass element, reverse space for an extra value */
	el->num_values = oc->num_values + 1;
	el->values = talloc_array(el, struct ldb_val, el->num_values);
	if (el->values == NULL) {
		talloc_free(el);
		ldb_oom(ldb);
		return;			/* TODO: fail? */
	}

	/* Copy local element name "objectClass" */
	el->name = talloc_strdup(el, local_attr);

	/* Convert all local objectClasses */
	for (i = 0; i < el->num_values - 1; i++) {
		el->values[i] = map_objectclass_convert_local(module, el->values, &oc->values[i]);
		if (ldb_attr_cmp((char *)el->values[i].data, data->add_objectclass) == 0) {
			found_extensibleObject = true;
		}
	}

	if (!found_extensibleObject) {
		val.data = (uint8_t *)talloc_strdup(el->values, data->add_objectclass);
		val.length = strlen((char *)val.data);

		/* Append additional objectClass data->add_objectclass */
		el->values[i] = val;
	} else {
		el->num_values--;
	}

	/* Add new objectClass to remote message */
	ldb_msg_add(remote, el, 0);
}
Exemplo n.º 2
0
/* Check whether a DN is below the local baseDN. */
BOOL ldb_dn_check_local(struct ldb_module *module, const struct ldb_dn *dn)
{
	const struct ldb_map_context *data = map_get_context(module);

	if (!data->local_base_dn) {
		return True;
	}

	return ldb_dn_compare_base(module->ldb, data->local_base_dn, dn) == 0;
}
Exemplo n.º 3
0
/* Check whether any data should be stored in the local partition. */
BOOL map_check_local_db(struct ldb_module *module)
{
	const struct ldb_map_context *data = map_get_context(module);

	if (!data->remote_base_dn || !data->local_base_dn) {
		return False;
	}

	return True;
}
Exemplo n.º 4
0
/* TODO: This should not be required with GUIDs. */
struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_dn *dn)
{
	const struct ldb_map_context *data = map_get_context(module);
	struct ldb_dn *dn1, *dn2;

	dn1 = ldb_dn_rebase_local(mem_ctx, data, dn);
	dn2 = ldb_dn_map_remote(module, mem_ctx, dn1);

	talloc_free(dn1);
	return dn2;
}
Exemplo n.º 5
0
/* Generate a local message with a mapped objectClass. */
static struct ldb_message_element *map_objectclass_generate_local(struct ldb_module *module, void *mem_ctx, const char *local_attr, const struct ldb_message *remote)
{
	const struct ldb_map_context *data = map_get_context(module);
	struct ldb_context *ldb;
	struct ldb_message_element *el, *oc;
	struct ldb_val val;
	unsigned int i;

	ldb = ldb_module_get_ctx(module);

	/* Find old remote objectClass */
	oc = ldb_msg_find_element(remote, "objectClass");
	if (oc == NULL) {
		return NULL;
	}

	/* Prepare new element */
	el = talloc_zero(mem_ctx, struct ldb_message_element);
	if (el == NULL) {
		ldb_oom(ldb);
		return NULL;
	}

	/* Copy remote objectClass element */
	el->num_values = oc->num_values;
	el->values = talloc_array(el, struct ldb_val, el->num_values);
	if (el->values == NULL) {
		talloc_free(el);
		ldb_oom(ldb);
		return NULL;
	}

	/* Copy remote element name "objectClass" */
	el->name = talloc_strdup(el, local_attr);

	/* Convert all remote objectClasses */
	for (i = 0; i < el->num_values; i++) {
		el->values[i] = map_objectclass_convert_remote(module, el->values, &oc->values[i]);
	}

	val.data = (uint8_t *)talloc_strdup(el->values, data->add_objectclass);
	val.length = strlen((char *)val.data);

	/* Remove last value if it was the string in data->add_objectclass (eg samba4top, extensibleObject) */
	if (ldb_val_equal_exact(&val, &el->values[i-1])) {
		el->num_values--;
		el->values = talloc_realloc(el, el->values, struct ldb_val, el->num_values);
		if (el->values == NULL) {
			talloc_free(el);
			ldb_oom(ldb);
			return NULL;
		}
	}
Exemplo n.º 6
0
/* TODO: free old DNs and messages? */
int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *request)
{
	const struct ldb_map_context *data = map_get_context(module);
	struct ldb_context *ldb;
	struct ldb_message *msg;

	ldb = ldb_module_get_ctx(module);

	switch (request->operation) {
	case LDB_SEARCH:
		if (request->op.search.base) {
			request->op.search.base = ldb_dn_rebase_remote(request, data, request->op.search.base);
		} else {
			request->op.search.base = data->remote_base_dn;
			/* TODO: adjust scope? */
		}
		break;

	case LDB_ADD:
		msg = ldb_msg_copy_shallow(request, request->op.add.message);
		if (msg == NULL) {
			return LDB_ERR_OPERATIONS_ERROR;
		}
		msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn);
		request->op.add.message = msg;
		break;

	case LDB_MODIFY:
		msg = ldb_msg_copy_shallow(request, request->op.mod.message);
		if (msg == NULL) {
			return LDB_ERR_OPERATIONS_ERROR;
		}
		msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn);
		request->op.mod.message = msg;
		break;

	case LDB_DELETE:
		request->op.del.dn = ldb_dn_rebase_remote(request, data, request->op.del.dn);
		break;

	case LDB_RENAME:
		request->op.rename.olddn = ldb_dn_rebase_remote(request, data, request->op.rename.olddn);
		request->op.rename.newdn = ldb_dn_rebase_remote(request, data, request->op.rename.newdn);
		break;

	default:
		ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
			  "Invalid remote request!");
		return LDB_ERR_OPERATIONS_ERROR;
	}

	return ldb_next_request(module, request);
}
Exemplo n.º 7
0
/* Check whether a message will be (partially) mapped into the remote partition. */
static BOOL ldb_msg_check_remote(struct ldb_module *module, const struct ldb_message *msg)
{
	const struct ldb_map_context *data = map_get_context(module);
	BOOL ret;
	int i;

	for (i = 0; i < msg->num_elements; i++) {
		ret = map_attr_check_remote(data, msg->elements[i].name);
		if (ret) {
			return ret;
		}
	}

	return False;
}
Exemplo n.º 8
0
/* Map an objectClass into the local partition. */
static struct ldb_val map_objectclass_convert_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val)
{
	const struct ldb_map_context *data = map_get_context(module);
	const char *name = (char *)val->data;
	const struct ldb_map_objectclass *map = map_objectclass_find_remote(data, name);
	struct ldb_val newval;

	if (map) {
		newval.data = (uint8_t*)talloc_strdup(mem_ctx, map->local_name);
		newval.length = strlen((char *)newval.data);
		return newval;
	}

	return ldb_val_dup(mem_ctx, val);
}
Exemplo n.º 9
0
/* Add a message element either to a local or to a remote message,
 * depending on whether it goes into the local or remote partition. */
static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg, const char *attr_name, /* const char * const names[], */ const struct ldb_message_element *old)
{
	const struct ldb_map_context *data = map_get_context(module);
	const struct ldb_map_attribute *map = map_attr_find_local(data, attr_name);
	struct ldb_message_element *el=NULL;

	/* Unknown attribute: ignore */
	if (map == NULL) {
		ldb_debug(module->ldb, LDB_DEBUG_WARNING, "ldb_map: "
			  "Not mapping attribute '%s': no mapping found\n",
			  old->name);
		goto local;
	}

	switch (map->type) {
	case MAP_IGNORE:
		goto local;

	case MAP_CONVERT:
		if (map->u.convert.convert_local == NULL) {
			ldb_debug(module->ldb, LDB_DEBUG_WARNING, "ldb_map: "
				  "Not mapping attribute '%s': "
				  "'convert_local' not set\n",
				  map->local_name);
			goto local;
		}
		/* fall through */
	case MAP_KEEP:
	case MAP_RENAME:
		el = ldb_msg_el_map_local(module, remote, map, old);
		break;

	case MAP_GENERATE:
		if (map->u.generate.generate_remote == NULL) {
			ldb_debug(module->ldb, LDB_DEBUG_WARNING, "ldb_map: "
				  "Not mapping attribute '%s': "
				  "'generate_remote' not set\n",
				  map->local_name);
			goto local;
		}

		/* TODO: if this attr requires context:
		 *	 make sure all context attrs are mappable (in 'names')
		 *	 make sure all context attrs have already been mapped?
		 *	 maybe postpone generation until they have been mapped?
		 */

		map->u.generate.generate_remote(module, map->local_name, msg, remote, local);
		return 0;
	}

	if (el == NULL) {
		return -1;
	}

	return ldb_msg_add(remote, el, old->flags);

local:
	el = talloc(local, struct ldb_message_element);
	if (el == NULL) {
		map_oom(module);
		return -1;
	}

	*el = *old;			/* copy the old element */

	return ldb_msg_add(local, el, old->flags);
}
Exemplo n.º 10
0
/* Map a DN into the local partition. */
struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_dn *dn)
{
	const struct ldb_map_context *data = map_get_context(module);
	struct ldb_dn *newdn;
	const struct ldb_map_attribute *map;
	enum ldb_map_attr_type map_type;
	const char *name;
	struct ldb_val value;
	int i, ret;

	if (dn == NULL) {
		return NULL;
	}

	newdn = ldb_dn_copy(mem_ctx, dn);
	if (newdn == NULL) {
		map_oom(module);
		return NULL;
	}

	/* For each RDN, map the component name and possibly the value */
	for (i = 0; i < ldb_dn_get_comp_num(newdn); i++) {
		map = map_attr_find_remote(data, ldb_dn_get_component_name(dn, i));

		/* Unknown attribute - leave this RDN as is and hope the best... */
		if (map == NULL) {
			map_type = MAP_KEEP;
		} else {
			map_type = map->type;
		}

		switch (map_type) {
		case MAP_IGNORE:
		case MAP_GENERATE:
			ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: "
				  "MAP_IGNORE/MAP_GENERATE attribute '%s' "
				  "used in DN!\n", ldb_dn_get_component_name(dn, i));
			goto failed;

		case MAP_CONVERT:
			if (map->u.convert.convert_remote == NULL) {
				ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: "
					  "'convert_remote' not set for attribute '%s' "
					  "used in DN!\n", ldb_dn_get_component_name(dn, i));
				goto failed;
			}
			/* fall through */
		case MAP_KEEP:
		case MAP_RENAME:
			name = map_attr_map_remote(newdn, map, ldb_dn_get_component_name(dn, i));
			if (name == NULL) goto failed;

			value = ldb_val_map_remote(module, newdn, map, ldb_dn_get_component_val(dn, i));
			if (value.data == NULL) goto failed;

			ret = ldb_dn_set_component(newdn, i, name, value);
			if (ret != LDB_SUCCESS) {
				goto failed;
			}

			break;
		}
	}

	return newdn;

failed:
	talloc_free(newdn);
	return NULL;
}