📄 ldb_map.c
字号:
return 0;}/* Mapping ldb values * ================== *//* Map an ldb value into the remote partition. */struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val){ if (map && (map->type == MAP_CONVERT) && (map->u.convert.convert_local)) { return map->u.convert.convert_local(module, mem_ctx, val); } return ldb_val_dup(mem_ctx, val);}/* Map an ldb value back into the local partition. */struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val){ if (map && (map->type == MAP_CONVERT) && (map->u.convert.convert_remote)) { return map->u.convert.convert_remote(module, mem_ctx, val); } return ldb_val_dup(mem_ctx, val);}/* Mapping DNs * =========== *//* Check whether a DN is below the local baseDN. */bool ldb_dn_check_local(struct ldb_module *module, 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(data->local_base_dn, dn) == 0;}/* Map a DN into the remote partition. */struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, 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_local(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_local == NULL) { ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: " "'convert_local' 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_local(newdn, map, ldb_dn_get_component_name(dn, i)); if (name == NULL) goto failed; value = ldb_val_map_local(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;}/* Map a DN into the local partition. */struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, 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;}/* Map a DN and its base into the local partition. *//* TODO: This should not be required with GUIDs. */struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx, 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;}/* Converting DNs and objectClasses (as ldb values) * ================================================ *//* Map a DN contained in an ldb value into the remote partition. */static struct ldb_val ldb_dn_convert_local(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val){ struct ldb_dn *dn, *newdn; struct ldb_val newval; dn = ldb_dn_new(mem_ctx, module->ldb, (char *)val->data); if (! ldb_dn_validate(dn)) { newval.length = 0; newval.data = NULL; talloc_free(dn); return newval; } newdn = ldb_dn_map_local(module, mem_ctx, dn); talloc_free(dn); newval.length = 0; newval.data = (uint8_t *)ldb_dn_alloc_linearized(mem_ctx, newdn); if (newval.data) { newval.length = strlen((char *)newval.data); } talloc_free(newdn); return newval;}/* Map a DN contained in an ldb value into the local partition. */static struct ldb_val ldb_dn_convert_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val){ struct ldb_dn *dn, *newdn; struct ldb_val newval; dn = ldb_dn_new(mem_ctx, module->ldb, (char *)val->data); if (! ldb_dn_validate(dn)) { newval.length = 0; newval.data = NULL; talloc_free(dn); return newval; } newdn = ldb_dn_map_remote(module, mem_ctx, dn); talloc_free(dn); newval.length = 0; newval.data = (uint8_t *)ldb_dn_alloc_linearized(mem_ctx, newdn); if (newval.data) { newval.length = strlen((char *)newval.data); } talloc_free(newdn); return newval;}/* Map an objectClass into the remote partition. */static struct ldb_val map_objectclass_convert_local(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_local(data, name); struct ldb_val newval; if (map) { newval.data = (uint8_t*)talloc_strdup(mem_ctx, map->remote_name); newval.length = strlen((char *)newval.data); return newval; } return ldb_val_dup(mem_ctx, val);}/* 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_message_element *el, *oc; struct ldb_val val; bool found_extensibleObject = false; int i; /* 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(module->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(module->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);}/* 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);}/* 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){ struct ldb_message_element *el, *oc; struct ldb_val val; int i; /* 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(module->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(module->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, "extensibleObject"); val.length = strlen((char *)val.data); /* Remove last value if it was "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(module->ldb); return NULL; } } return el;}static const struct ldb_map_attribute objectclass_convert_map = { .local_name = "objectClass", .type = MAP_CONVERT, .u = { .convert = { .remote_name = "objectClass", .convert_local = map_objectclass_convert_local, .convert_remote = map_objectclass_convert_remote, }, },};/* Mappings for searches on objectClass= assuming a one-to-one * mapping. Needed because this is a generate operator for the * add/modify code */static int map_objectclass_convert_operator(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) { return map_subtree_collect_remote_simple(module, mem_ctx, new, tree, &objectclass_convert_map);}/* Auxiliary request construction * ============================== *//* Store the DN of a single search result in context. */static int map_search_self_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares){ struct map_context *ac; if (context == NULL || ares == NULL) { ldb_set_errstring(ldb, talloc_asprintf(ldb, "NULL Context or Result in callback")); return LDB_ERR_OPERATIONS_ERROR; } ac = talloc_get_type(context, struct map_context); /* We are interested only in the single reply */ if (ares->type != LDB_REPLY_ENTRY) { talloc_free(ares); return LDB_SUCCESS; } /* We have already found a remote DN */ if (ac->local_dn) { ldb_set_errstring(ldb, talloc_asprintf(ldb, "Too many results to base search")); talloc_free(ares); return LDB_ERR_OPERATIONS_ERROR; } /* Store local DN */ ac->local_dn = ares->message->dn; return LDB_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -