Author: mkhl Date: 2006-06-25 20:02:11 +0000 (Sun, 25 Jun 2006) New Revision: 16512
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=16512 Log: Add separation of search attrs into local and remote "parts". Martin Modified: branches/SOC/mkhl/ldb-map/modules/ldb_map.c Changeset: Modified: branches/SOC/mkhl/ldb-map/modules/ldb_map.c =================================================================== --- branches/SOC/mkhl/ldb-map/modules/ldb_map.c 2006-06-25 16:08:19 UTC (rev 16511) +++ branches/SOC/mkhl/ldb-map/modules/ldb_map.c 2006-06-25 20:02:11 UTC (rev 16512) @@ -291,7 +291,8 @@ int i; for (i = 0; data->attribute_maps[i].local_name; i++) - if (ldb_attr_cmp(data->attribute_maps[i].local_name, name) == 0) + if (ldb_attr_cmp(data->attribute_maps[i] + .local_name, name) == 0) return &data->attribute_maps[i]; return NULL; @@ -308,12 +309,13 @@ for (i = 0; data->attribute_maps[i].local_name; i++) { switch (data->attribute_maps[i].type) { case MAP_KEEP: - if (ldb_attr_cmp(data->attribute_maps[i].local_name, - name) == 0) + if (ldb_attr_cmp(data->attribute_maps[i] + .local_name, name) == 0) return &data->attribute_maps[i]; case MAP_RENAME: case MAP_CONVERT: - if (ldb_attr_cmp(data->attribute_maps[i].u.rename.remote_name, name) == 0) + if (ldb_attr_cmp(data->attribute_maps[i] + .u.rename.remote_name, name) == 0) return &data->attribute_maps[i]; default: break; @@ -391,6 +393,119 @@ return False; } +/* select only attrs that are not mapped */ +static +const char ** +select_unmapped_attrs(struct ldb_module *module, + void *mem_ctx, + const char * const *attrs) +{ + struct ldb_map_context *data = map_get_privdat(module); + const char **result; + int i, last; + + if (attrs == NULL) + return NULL; + + last = 0; + result = NULL; + + for (i = 0; attrs[i]; i++) { + /* keep "*" and ignored attrs */ + if ((ldb_attr_cmp(attrs[i], "*") == 0) + || (!check_attr_mapped(data, attrs[i]))) { + result = talloc_realloc(mem_ctx, result, + const char *, last+2); + if (result == NULL) + goto failed; + + result[last] = talloc_strdup(mem_ctx, attrs[i]); + result[last+1] = NULL; + last++; + } + } + + return result; + +failed: + map_oom(module); + return NULL; +} + +/* select only attrs that are mapped */ +static +const char ** +select_mapped_attrs(struct ldb_module *module, + void *mem_ctx, + const char * const *attrs) +{ + struct ldb_map_context *data = map_get_privdat(module); + struct ldb_map_attribute *map; + const char *name; + const char **result; + int i, j, last; + + if (attrs == NULL) + return NULL; + + last = 0; + result = NULL; + + for (i = 0; attrs[i]; i++) { + /* keep "*" as is */ + if (ldb_attr_cmp(attrs[i], "*") == 0) { + name = talloc_strdup(mem_ctx, attrs[i]); + goto named; + } + + /* add remote names of mapped attrs */ + map = find_attr_local(data, attrs[i]); + if (map == NULL) + continue; + + switch (map->type) { + case MAP_IGNORE: + continue; + + case MAP_KEEP: + name = map->local_name; + goto named; + + case MAP_RENAME: + case MAP_CONVERT: + name = map->u.rename.remote_name; + goto named; + + case MAP_GENERATE: + /* add all remote names of "generate" attrs */ + for (j = 0; map->u.generate.remote_names[j]; j++) { + result = talloc_realloc(mem_ctx, result, + const char *, last+2); + result[last] = talloc_strdup(mem_ctx, map->u .generate.remote_names[j]); + result[last+1] = NULL; + last++; + } + continue; + } + + named: + result = talloc_realloc(mem_ctx, result, + const char *, last+2); + if (result == NULL) + goto failed; + + result[last] = name; + result[last+1] = NULL; + last++; + } + + return result; + +failed: + map_oom(module); + return NULL; +} + /* Check whether the given objectClass is contained in the specified * message */ /* @@ -779,68 +894,6 @@ return ldb_val_dup(ctx, val); } -/* Local attribute names -> Remote attribute names */ -/* -static const char **map_local_attrs(struct ldb_module *module, - const char *const attrs[]) -{ - struct ldb_map_context *map = map_get_privdat(module); - const char **names; - const struct ldb_map_attribute *attr; - int count = 0; - int i, j; - - if (attrs == NULL) - return NULL; - - names = talloc_array(module, const char *, 1); - if (names == NULL) - return NULL; - - names[0] = NULL; - - for (i = 0; attrs[i]; i++) { - attr = find_attr_local(map, attrs[i]); - if (attr == NULL) { - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_map: " - "Unknown local attribute '%s'\n", attrs[i]); - continue; - } - - switch (attr->type) { - case MAP_IGNORE: - break; - - case MAP_KEEP: - names = talloc_realloc(module, names, const char *, count+2); - names[count] = attr->local_name; - names[count+1] = NULL; - count++; - break; - - case MAP_RENAME: - case MAP_CONVERT: - names = talloc_realloc(module, names, const char *, count+2); - names[count] = attr->u.rename.remote_name; - names[count+1] = NULL; - count++; - break; - - case MAP_GENERATE: - for (j = 0; attr->u.generate.remote_names[j]; j++) { - names = talloc_realloc(module, names, const char *, count+2); - names[count] = attr->u.generate.remote_names[j]; - names[count+1] = NULL; - count++; - } - break; - } - } - - return names; -} -*/ - /* Remote message -> List of local attribute names of which all remote * attributes are present in the message */ static const char **map_msg_available_local_attrs(struct ldb_module *module, @@ -1272,7 +1325,8 @@ if (map == NULL) el->values[i] = ldb_val_dup(el, &old->values[i]); else - el->values[i] = map->u.convert.convert_local(ac->module, el, &old->values[i]); + el->values[i] = map->u.convert + .convert_local(ac->module, el, &old->values[i]); } return el; @@ -1512,7 +1566,7 @@ case LDB_REPLY_ENTRY: /* we have already found a remote record */ if (sc->remote_res) { - ldb_set_errstring(ldb, talloc_asprintf(ldb, "Too many results to base search")); + ldb_set_errstring(ldb, talloc_asprintf(ldb, "Too many results to base search for mapped entry")); talloc_free(ares); return LDB_ERR_OPERATIONS_ERROR; } @@ -1529,8 +1583,12 @@ case LDB_REPLY_DONE: /* no mapped record found, continue with local record */ - if (sc->remote_res == NULL) - return sc->ac->orig_req->async.callback(ldb, sc->ac->orig_req->async.context, sc->local_res); + if (sc->remote_res == NULL) { + const struct ldb_request *req; + req = sc->ac->orig_req; + return req->async.callback(ldb, req->async.context, + sc->local_res); + } break; default: @@ -1553,6 +1611,7 @@ struct map_async_search_context *sc; struct ldb_request *req; struct ldb_dn *dn; + const char * const *remote_attrs; if (context == NULL || ares == NULL) { ldb_set_errstring(ldb, talloc_asprintf(ldb, "NULL Context or Result in callback")); @@ -1578,10 +1637,6 @@ ac->remote_dn = dn; /* prepare remote operation */ - req = talloc_zero(ac, struct ldb_request); - if (req == NULL) - goto error; - sc = talloc(ac, struct map_async_search_context); if (sc == NULL) goto error; @@ -1591,15 +1646,17 @@ sc->local_res = ares; sc->remote_res = NULL; - /* TODO: replace NULL with remote attrs! */ - req = search_base_req(ac, dn, NULL, remote_search_callback); + remote_attrs = select_mapped_attrs(ac->module, ac, + ac->orig_req->op.search.attrs); + req = search_base_req(ac, dn, remote_attrs, remote_search_callback); if (req == NULL) goto error; return ldb_next_remote_request(ac->module, req); callback: - return ac->orig_req->async.callback(ldb, ac->orig_req->async.context, ares); + req = ac->orig_req; + return req->async.callback(ldb, req->async.context, ares); error: talloc_free(ares); @@ -1811,7 +1868,7 @@ { struct ldb_async_handle *h; struct map_async_context *ac; - const char * const *local_attrs; + const char **local_attrs; int ret; /* do not manipulate our control entries */ @@ -1852,8 +1909,8 @@ ac->local_req->async.context = ac; ac->local_req->async.callback = local_search_callback; - /* TODO: separate local and remote attrs - maybe even store them in context */ + local_attrs = select_unmapped_attrs(module, ac->local_req, + req->op.search.attrs); ac->local_req->op.search.attrs = local_attrs;
