Author: idra Date: 2005-12-10 13:37:22 +0000 (Sat, 10 Dec 2005) New Revision: 12164
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=12164 Log: Client side support for exploded dn control I hate the way Microsoft did this, there was no need to change the dn given they have a distinguishedName entry :-( To support this control I had to add a new ldb_dn funciotn: ldb_dn_explode_or_special() This function should gather any present or future "special" dn like the one produced by this control. Simo. Modified: branches/tmp/samba4_ldap_controls/source/lib/ldb/common/ldb_dn.c branches/tmp/samba4_ldap_controls/source/lib/ldb/include/ldb.h branches/tmp/samba4_ldap_controls/source/lib/ldb/ldb_ildap/ldb_ildap.c branches/tmp/samba4_ldap_controls/source/lib/ldb/ldb_ldap/ldb_ldap.c branches/tmp/samba4_ldap_controls/source/lib/ldb/tools/ldbtest_controls.c Changeset: Modified: branches/tmp/samba4_ldap_controls/source/lib/ldb/common/ldb_dn.c =================================================================== --- branches/tmp/samba4_ldap_controls/source/lib/ldb/common/ldb_dn.c 2005-12-10 11:22:01 UTC (rev 12163) +++ branches/tmp/samba4_ldap_controls/source/lib/ldb/common/ldb_dn.c 2005-12-10 13:37:22 UTC (rev 12164) @@ -417,6 +417,39 @@ return NULL; } +struct ldb_dn *ldb_dn_explode_or_special(void *mem_ctx, const char *dn) +{ + struct ldb_dn *edn; /* the exploded dn */ + + if (dn == NULL) return NULL; + + if (strncasecmp(dn, "<GUID=", 6) == 0) { + /* this is special DN returned when the + * exploded_dn control is used + */ + + /* Allocate a structure to hold the exploded DN */ + edn = ldb_dn_new(mem_ctx); + + edn->comp_num = 1; + edn->components = talloc(edn, struct ldb_dn_component); + if (edn->components == NULL) goto failed; + edn->components[0].name = talloc_strdup(edn->components, LDB_SPECIAL); + if (edn->components[0].name == NULL) goto failed; + edn->components[0].value.data = (uint8_t *)talloc_strdup(edn->components, dn); + if (edn->components[0].value.data== NULL) goto failed; + edn->components[0].value.length = strlen(dn); + return edn; + + } + + return ldb_dn_explode(mem_ctx, dn); + +failed: + talloc_free(edn); + return NULL; +} + char *ldb_dn_linearize(void *mem_ctx, const struct ldb_dn *edn) { char *dn, *value; Modified: branches/tmp/samba4_ldap_controls/source/lib/ldb/include/ldb.h =================================================================== --- branches/tmp/samba4_ldap_controls/source/lib/ldb/include/ldb.h 2005-12-10 11:22:01 UTC (rev 12163) +++ branches/tmp/samba4_ldap_controls/source/lib/ldb/include/ldb.h 2005-12-10 13:37:22 UTC (rev 12164) @@ -246,12 +246,21 @@ #define LDB_SYNTAX_UTC_TIME "1.3.6.1.4.1.1466.115.121.1.53" #define LDB_SYNTAX_OBJECTCLASS "LDB_SYNTAX_OBJECTCLASS" + + +#define LDB_CONTROL_PAGED_REQUESTS_OID "1.2.840.113556.1.4.319" +#define LDB_CONTROL_EXTENDED_DN_OID "1.2.840.113556.1.4.529" + struct ldb_paged_control { int size; int cookie_len; char *cookie; }; +struct ldb_extended_dn_control { + int type; +}; + struct ldb_control { const char *oid; BOOL critical; @@ -438,6 +447,7 @@ char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value); struct ldb_dn *ldb_dn_new(void *mem_ctx); struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn); +struct ldb_dn *ldb_dn_explode_or_special(void *mem_ctx, const char *dn); char *ldb_dn_linearize(void *mem_ctx, const struct ldb_dn *edn); char *ldb_dn_linearize_casefold(struct ldb_context *ldb, const struct ldb_dn *edn); int ldb_dn_compare_base(struct ldb_context *ldb, const struct ldb_dn *base, const struct ldb_dn *dn); Modified: branches/tmp/samba4_ldap_controls/source/lib/ldb/ldb_ildap/ldb_ildap.c =================================================================== --- branches/tmp/samba4_ldap_controls/source/lib/ldb/ldb_ildap/ldb_ildap.c 2005-12-10 11:22:01 UTC (rev 12163) +++ branches/tmp/samba4_ldap_controls/source/lib/ldb/ldb_ildap/ldb_ildap.c 2005-12-10 13:37:22 UTC (rev 12164) @@ -236,7 +236,7 @@ } (*res)->msgs[i+1] = NULL; - (*res)->msgs[i]->dn = ldb_dn_explode((*res)->msgs[i], search->dn); + (*res)->msgs[i]->dn = ldb_dn_explode_or_special((*res)->msgs[i], search->dn); if ((*res)->msgs[i]->dn == NULL) { goto failed; } Modified: branches/tmp/samba4_ldap_controls/source/lib/ldb/ldb_ldap/ldb_ldap.c =================================================================== --- branches/tmp/samba4_ldap_controls/source/lib/ldb/ldb_ldap/ldb_ldap.c 2005-12-10 11:22:01 UTC (rev 12163) +++ branches/tmp/samba4_ldap_controls/source/lib/ldb/ldb_ldap/ldb_ldap.c 2005-12-10 13:37:22 UTC (rev 12164) @@ -273,7 +273,7 @@ goto failed; } - (*res)->msgs[msg_count]->dn = ldb_dn_explode((*res)->msgs[msg_count], dn); + (*res)->msgs[msg_count]->dn = ldb_dn_explode_or_special((*res)->msgs[msg_count], dn); ldap_memfree(dn); if (!(*res)->msgs[msg_count]->dn) { goto failed; Modified: branches/tmp/samba4_ldap_controls/source/lib/ldb/tools/ldbtest_controls.c =================================================================== --- branches/tmp/samba4_ldap_controls/source/lib/ldb/tools/ldbtest_controls.c 2005-12-10 11:22:01 UTC (rev 12163) +++ branches/tmp/samba4_ldap_controls/source/lib/ldb/tools/ldbtest_controls.c 2005-12-10 13:37:22 UTC (rev 12164) @@ -56,12 +56,12 @@ exit(1); } -static int do_search(struct ldb_context *ldb, - const struct ldb_dn *basedn, - int scope, - int sort_attribs, - const char *expression, - const char * const *attrs) +static int search_paged(struct ldb_context *ldb, + const struct ldb_dn *basedn, + int scope, + int sort_attribs, + const char *expression, + const char * const *attrs) { int ret, i, total; struct ldb_request req; @@ -74,7 +74,7 @@ ctrl = talloc_array(ldb, struct ldb_control *, 2); ctrl[0] = talloc(ldb, struct ldb_control); ctrl[1] = NULL; - ctrl[0]->oid = "1.2.840.113556.1.4.319"; + ctrl[0]->oid = LDB_CONTROL_PAGED_REQUESTS_OID; ctrl[0]->critical = True; paged_control = talloc(ctrl[0], struct ldb_paged_control); paged_control->size = 10; @@ -121,6 +121,10 @@ ldb_ldif_write_file(ldb, stdout, &ldif); } + if (result->controls == NULL) { + fprintf(stderr, "ERROR: No control reply even if control was marked as critical\n"); + return 1; + } /* paged_result = talloc_get_type(result->controls[0]->data, struct ldb_paged_control); */ paged_result = (struct ldb_paged_control *)result->controls[0]->data; if (paged_result->cookie_len == 0) break; @@ -136,6 +140,67 @@ return 0; } +static int search_extended_dn(struct ldb_context *ldb, + const struct ldb_dn *basedn, + int scope, + int sort_attribs, + const char *expression, + const char * const *attrs) +{ + int ret, i; + struct ldb_request req; + struct ldb_result *result = NULL; + struct ldb_control **ctrl; + struct ldb_extended_dn_control *extended_control; + + ctrl = talloc_array(ldb, struct ldb_control *, 2); + ctrl[0] = talloc(ldb, struct ldb_control); + ctrl[1] = NULL; + ctrl[0]->oid = LDB_CONTROL_EXTENDED_DN_OID; + ctrl[0]->critical = True; + extended_control = talloc(ctrl[0], struct ldb_extended_dn_control); + extended_control->type = 0; + ctrl[0]->data = extended_control; + + req.operation = LDB_REQ_SEARCH; + req.op.search.base = basedn; + req.op.search.scope = scope; + req.op.search.tree = ldb_parse_tree(ldb, expression); + req.op.search.attrs = attrs; + req.op.search.res = NULL; + req.controls = ctrl; + req.creds = NULL; + + ret = ldb_request(ldb, &req); + if (ret != LDB_SUCCESS) { + printf("search failed - %s\n", ldb_errstring(ldb)); + return -1; + } + + result = req.op.search.res; + printf("# returned %d records\n", result->count); + + for (i = 0; i < result->count; i++) { + struct ldb_ldif ldif; + printf("# record %d\n", i+1); + + ldif.changetype = LDB_CHANGETYPE_NONE; + ldif.msg = result->msgs[i]; + + ldb_ldif_write_file(ldb, stdout, &ldif); + } + + if (result) { + ret = talloc_free(result); + if (ret == -1) { + fprintf(stderr, "talloc_free failed\n"); + exit(1); + } + } + + return 0; +} + int main(int argc, const char **argv) { struct ldb_context *ldb; @@ -170,18 +235,13 @@ } } - if (options->interactive) { - char line[1024]; - while (fgets(line, sizeof(line), stdin)) { - if (do_search(ldb, basedn, - options->scope, options->sorted, line, attrs) == -1) { - ret = -1; - } - } - } else { - ret = do_search(ldb, basedn, options->scope, options->sorted, - expression, attrs); - } + fprintf(stdout, "Searching with paged results control turned on\n"); + sleep(2); + ret = search_paged(ldb, basedn, options->scope, options->sorted, expression, attrs); + + fprintf(stdout, "Searching with extended dn control turned on\n"); + sleep(2); + ret = search_extended_dn(ldb, basedn, options->scope, options->sorted, expression, attrs); talloc_free(ldb); return ret;