From f6929068a19ef65fad5928982fd4ac4434e1763e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Apr 2002 04:55:37 +0000 Subject: by using a prompter function we can avoid the bug in the MIT kerberos libraries with handling blank passwords. (This used to be commit 59d755ffb57c322a104ff8f52819956cafff1bac) --- source3/libads/kerberos.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 194a71275e..85518a6769 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -24,6 +24,28 @@ #ifdef HAVE_KRB5 +/* + we use a prompter to avoid a crash bug in the kerberos libs when + dealing with empty passwords + this prompter is just a string copy ... +*/ +static krb5_error_code +kerb_prompter(krb5_context ctx, void *data, + const char *name, + const char *banner, + int num_prompts, + krb5_prompt prompts[]) +{ + if (num_prompts == 0) return 0; + + memset(prompts[0].reply->data, 0, prompts[0].reply->length); + if (prompts[0].reply->length > 0) { + strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); + prompts[0].reply->length = strlen(prompts[0].reply->data); + } + return 0; +} + /* simulate a kinit, putting the tgt in the default cache location remus@snapserver.com @@ -36,11 +58,6 @@ int kerberos_kinit_password(const char *principal, const char *password) krb5_principal me; krb5_creds my_creds; - if (! *password) { - /* kerberos dies on an empty password! */ - return KRB5_PARSE_MALFORMED; - } - if ((code = krb5_init_context(&ctx))) return code; @@ -54,8 +71,9 @@ int kerberos_kinit_password(const char *principal, const char *password) return code; } - if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, (char*)password, NULL, - NULL, 0, NULL, NULL))) { + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, NULL, + kerb_prompter, + password, 0, NULL, NULL))) { krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; -- cgit From c0a991943044e038b78f796fb35d7625eb843d85 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Apr 2002 06:56:44 +0000 Subject: fixed the fallback to a BDC for ADS connections (This used to be commit 3e58a1ee83ea0b4347ce24e566445cc6cb67bb3a) --- source3/libads/ads_struct.c | 19 ++++++++++++++++++- source3/libads/ldap.c | 24 ++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 489f301ae2..816b616097 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -90,7 +90,12 @@ static char *find_ldap_server(ADS_STRUCT *ads) } /* get desperate, find the domain controller IP */ - if (resolve_name(lp_workgroup(), &ip, 0x1B)) { + if (resolve_name(ads->workgroup, &ip, 0x1B)) { + return strdup(inet_ntoa(ip)); + } + + /* or a BDC ... */ + if (resolve_name(ads->workgroup, &ip, 0x1C)) { return strdup(inet_ntoa(ip)); } @@ -115,6 +120,7 @@ static char *find_ldap_server(ADS_STRUCT *ads) initialise a ADS_STRUCT, ready for some ads_ ops */ ADS_STRUCT *ads_init(const char *realm, + const char *workgroup, const char *ldap_server, const char *bind_path, const char *password) @@ -124,7 +130,12 @@ ADS_STRUCT *ads_init(const char *realm, ads = (ADS_STRUCT *)smb_xmalloc(sizeof(*ads)); ZERO_STRUCTP(ads); + if (!workgroup) { + workgroup = lp_workgroup(); + } + ads->realm = realm? strdup(realm) : NULL; + ads->workgroup = strdup(workgroup); ads->ldap_server = ldap_server? strdup(ldap_server) : NULL; ads->bind_path = bind_path? strdup(bind_path) : NULL; ads->ldap_port = LDAP_PORT; @@ -153,6 +164,12 @@ ADS_STRUCT *ads_init(const char *realm, return ads; } +/* a simpler ads_init() interface using all defaults */ +ADS_STRUCT *ads_init_simple(void) +{ + return ads_init(NULL, NULL, NULL, NULL, NULL); +} + /* free the memory used by the ADS structure initialized with 'ads_init(...)' */ diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e2e351bd4b..3b787c6a8f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -46,9 +46,33 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ads->last_attempt = time(NULL); ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); + + /* if that failed then try each of the BDC's in turn */ + if (!ads->ld) { + struct in_addr *ip_list; + int count; + + if (get_dc_list(False, ads->workgroup, &ip_list, &count)) { + int i; + for (i=0;ild = ldap_open(inet_ntoa(ip_list[i]), + ads->ldap_port); + if (ads->ld) break; + } + if (ads->ld) { + free(ads->ldap_server); + ads->ldap_server = strdup(inet_ntoa(ip_list[i])); + } + free(ip_list); + } + } + if (!ads->ld) { return ADS_ERROR_SYSTEM(errno); } + + DEBUG(3,("Connected to LDAP server %s\n", ads->ldap_server)); + status = ads_server_info(ads); if (!ADS_ERR_OK(status)) { DEBUG(1,("Failed to get ldap server info\n")); -- cgit From fc78c773f8216df1bbaa88d9007cf3f5df386e3d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 19 Apr 2002 03:00:29 +0000 Subject: fixed trust relationships in ADS winbindd after breaking them with my BDC changes ... (This used to be commit 8096032663690eafb6bb8b4f405d6231389d4f80) --- source3/libads/ads_struct.c | 9 ++++++--- source3/libads/ldap.c | 8 ++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 816b616097..638dc0b22e 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -81,7 +81,8 @@ static char *find_ldap_server(ADS_STRUCT *ads) char *list = NULL; struct in_addr ip; - if (ads->realm && + if (ads->realm && + strcasecmp(ads->workgroup, lp_workgroup()) == 0 && ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) { char *p; p = strchr(list, ':'); @@ -151,8 +152,10 @@ ADS_STRUCT *ads_init(const char *realm, ads->bind_path = ads_build_dn(ads->realm); } if (!ads->ldap_server) { - ads->ldap_server = strdup(lp_ads_server()); - if (!ads->ldap_server[0]) { + if (strcasecmp(ads->workgroup, lp_workgroup()) == 0) { + ads->ldap_server = strdup(lp_ads_server()); + } + if (!ads->ldap_server || !ads->ldap_server[0]) { ads->ldap_server = find_ldap_server(ads); } } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 3b787c6a8f..543e53bcf8 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -45,7 +45,11 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ads->last_attempt = time(NULL); - ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); + ads->ld = NULL; + + if (ads->ldap_server) { + ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); + } /* if that failed then try each of the BDC's in turn */ if (!ads->ld) { @@ -60,7 +64,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) if (ads->ld) break; } if (ads->ld) { - free(ads->ldap_server); + SAFE_FREE(ads->ldap_server); ads->ldap_server = strdup(inet_ntoa(ip_list[i])); } free(ip_list); -- cgit From 2503dc8eb80c35cbeef679a3d1b8d5579504cc47 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 9 May 2002 23:44:46 +0000 Subject: Add ads group account add function. (This used to be commit 180311a48cfa808ea9edc9f32558554b243b10eb) --- source3/libads/ldap_user.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index 13e68eb82e..c1a9a89e46 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -77,4 +77,37 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, talloc_destroy(ctx); return status; } + +ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, + const char *comment) +{ + TALLOC_CTX *ctx; + ADS_MODLIST mods; + ADS_STATUS status; + char *new_dn; + + if (!(ctx = talloc_init_named("ads_add_group_acct"))) + return ADS_ERROR(LDAP_NO_MEMORY); + + status = ADS_ERROR(LDAP_NO_MEMORY); + + if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", group, + ads->bind_path))) + goto done; + if (!(mods = ads_init_mods(ctx))) + goto done; + + ads_mod_add(ctx, &mods, "cn", group); + ads_mod_add_var(ctx, &mods, LDAP_MOD_ADD, "objectClass", "top", + "group", NULL); + ads_mod_add(ctx, &mods, "name", group); + if (comment) + ads_mod_add(ctx, &mods, "description", comment); + ads_mod_add(ctx, &mods, "sAMAccountName", group); + status = ads_gen_add(ads, new_dn, mods); + + done: + talloc_destroy(ctx); + return status; +} #endif -- cgit From 31cda568c05624ef5e7fd2970c5f2733e67eedc3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 17 May 2002 14:35:54 +0000 Subject: This is meant to be accessed via the helper fn, not directly. (This used to be commit b84882a628b3f2f0890322f25694c1932aa3e5ec) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 543e53bcf8..ab2828c23d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1192,7 +1192,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) #endif if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY); - ads_mod_repl_len(ctx, &mods, attrs[0], sd_size, ps_wire.data_p); + ads_mod_repl_len(ctx, &mods, attrs[0], sd_size, prs_data_p(&ps_wire)); ret = ads_gen_mod(ads, dn, mods); prs_mem_free(&ps); -- cgit From d53b9f113a5f33eb93ae3e114b71fcfe18dcf666 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Jun 2002 02:46:25 +0000 Subject: fixed a spelling mistake (This used to be commit 5a04ea1f0c41965bc735f38f4892dc37571734d6) --- source3/libads/disp_sec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index ab8ceecb0c..35a7af7b36 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -123,7 +123,7 @@ void ads_disp_ace(SEC_ACE *sec_ace) } else if (sec_ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) { access_type = "ALLOWED OBJECT"; } else if (sec_ace->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT) { - access_type = "DEINED OBJECT"; + access_type = "DENIED OBJECT"; } else if (sec_ace->type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT) { access_type = "AUDIT OBJECT"; } -- cgit From 24b67730bf7bbf4414df99129a3cc20aa93dc0da Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 24 Jun 2002 17:50:02 +0000 Subject: Support utf8 on the wire for ads ldap. DN's are converted, as well as strings, though it is up to the calling function to decide whether values are strings or not. Attributes are not converted at this point, though support for it would be simple. I have tested it with users and groups using non-ascii chars, and if the check for alphanumeric user/domain names is removed form sesssetup.c, even a user with accented chars can connect, or even login (via winbind). I have also simplified the interfaces to ads_mod_*, though we will probably want to expand this by a few functions in the near future. We just had too many ways to do the same thing... (This used to be commit f924cb53580bc081ff34e45abba57629018c68d6) --- source3/libads/ldap.c | 532 +++++++++++++++++++----------------------- source3/libads/ldap_printer.c | 73 +++--- source3/libads/ldap_user.c | 29 +-- 3 files changed, 295 insertions(+), 339 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ab2828c23d..b898eec7a9 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -30,6 +30,11 @@ * * The routines contained here should do the necessary ldap calls for * ads setups. + * + * Important note: attribute names passed into ads_ routines must + * already be in UTF-8 format. We do not convert them because in almost + * all cases, they are just ascii (which is represented with the same + * codepoints in UTF-8). This may have to change at some point **/ /** @@ -112,8 +117,8 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) * @param ads connection to ads server * @param bind_path Base dn for the search * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) - * @param exp Search expression - * @param attrs Attributes to retrieve + * @param exp Search expression - specified in local charset + * @param attrs Attributes to retrieve - specified in utf8 or ascii * @param res ** which will contain results - free res* with ads_msgfree() * @param count Number of entries retrieved on this page * @param cookie The paged results cookie to be returned on subsequent calls @@ -124,23 +129,16 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, const char **attrs, void **res, int *count, void **cookie) { - int rc; - int version; - LDAPControl PagedResults; - LDAPControl NoReferrals; + int rc, i, version; + char *utf8_exp, *utf8_path; + LDAPControl PagedResults, NoReferrals, *controls[3], **rcontrols; BerElement *cookie_be = NULL; struct berval *cookie_bv= NULL; - LDAPControl *controls[3]; - LDAPControl **rcontrols; - int i; *res = NULL; + /* Paged results only available on ldap v3 or later */ ldap_get_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); - - /* Paged results only available on ldap v3 or later, so check - version first before using, since at connect time we're - only v2. Not sure exactly why... */ if (version < LDAP_VERSION3) return ADS_ERROR(LDAP_NOT_SUPPORTED); @@ -171,20 +169,29 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, *res = NULL; /* we need to disable referrals as the openldap libs don't - seem to handle them correctly. They result in the result - record containing the server control being removed from the - result list (tridge) + handle them and paged results at the same time. Using them + together results in the result record containing the server + page control being removed from the result list (tridge/jmcd) leaving this in despite the control that says don't generate referrals, in case the server doesn't support it (jmcd) */ ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - rc = ldap_search_ext_s(ads->ld, bind_path, scope, exp, + if (!push_utf8_allocate((void **) &utf8_exp, exp)) + utf8_exp = exp; + if (!push_utf8_allocate((void **) &utf8_path, bind_path)) + utf8_path = bind_path; + + rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, (char **) attrs, 0, controls, NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); + if (utf8_exp != exp) + SAFE_FREE(utf8_exp); + if (utf8_path != bind_path) + SAFE_FREE(utf8_path); ber_free(cookie_be, 1); ber_bvfree(cookie_bv); @@ -262,7 +269,6 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, next = ads_next_entry(ads, msg); ldap_add_result_entry((LDAPMessage **)res, msg); } - /* note that we do not free res2, as the memory is now part of the main returned list */ } @@ -276,15 +282,15 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, * @param ads connection to ads server * @param bind_path Base dn for the search * @param scope Scope of search (LDAP_BASE | LDAP_ONE | LDAP_SUBTREE) - * @param exp Search expression - * @param attrs Attributes to retrieve + * @param exp Search expression - specified in local charset + * @param attrs Attributes to retrieve - specified in UTF-8 or ascii * @param fn Function which takes attr name, values list, and data_area * @param data_area Pointer which is passed to function on each call * @return status of search **/ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, const char **attrs, - void(*fn)(char *, void **, void *), + BOOL(*fn)(char *, void **, void *), void *data_area) { void *cookie = NULL; @@ -329,16 +335,25 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, { struct timeval timeout; int rc; + char *utf8_exp, *utf8_path; timeout.tv_sec = ADS_SEARCH_TIMEOUT; timeout.tv_usec = 0; *res = NULL; - rc = ldap_search_ext_s(ads->ld, - bind_path, scope, - exp, (char **) attrs, 0, NULL, NULL, + if (!push_utf8_allocate((void **) &utf8_exp, exp)) + utf8_exp = exp; + if (!push_utf8_allocate((void **) &utf8_path, bind_path)) + utf8_path = bind_path; + + rc = ldap_search_ext_s(ads->ld, utf8_path, scope, + utf8_exp, (char **) attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); + if (utf8_exp != exp) + SAFE_FREE(utf8_exp); + if (utf8_path != bind_path) + SAFE_FREE(utf8_path); if (rc == LDAP_SIZELIMIT_EXCEEDED) { DEBUG(3,("Warning! sizelimit exceeded in ldap. Truncating.\n")); rc = 0; @@ -395,8 +410,7 @@ void ads_msgfree(ADS_STRUCT *ads, void *msg) **/ void ads_memfree(ADS_STRUCT *ads, void *mem) { - if (!mem) return; - ldap_memfree(mem); + SAFE_FREE(mem); } /** @@ -407,7 +421,12 @@ void ads_memfree(ADS_STRUCT *ads, void *mem) **/ char *ads_get_dn(ADS_STRUCT *ads, void *res) { - return ldap_get_dn(ads->ld, res); + char *utf8_dn, *unix_dn; + + utf8_dn = ldap_get_dn(ads->ld, res); + pull_utf8_allocate(&unix_dn, utf8_dn); + ldap_memfree(utf8_dn); + return unix_dn; } /** @@ -431,25 +450,6 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) return status; } -/* - duplicate an already-assembled list of values so that it can be - freed as part of the standard msgfree call -*/ -static char **ads_dup_values(TALLOC_CTX *ctx, char **values) -{ - char **newvals; - int i; -#define ADS_MAX_NUM_VALUES 32 - - for (i=0; values[i] && ibv_len == 0) return value; + + value->bv_len = in_val->bv_len; + value->bv_val = talloc_memdup(ctx, in_val->bv_val, in_val->bv_len); + return value; +} + +/* + Make a values list out of an array of (struct berval *) + */ +static struct berval **ads_dup_values(TALLOC_CTX *ctx, struct berval **in_vals) +{ + void **values; + int i; + + if (!in_vals) return NULL; + for (i=0; in_vals[i]; i++); /* count values */ + values = talloc_zero(ctx, (i+1)*sizeof(struct berval *)); + if (!values) return NULL; + + for (i=0; in_vals[i]; i++) { + values[i] = dup_berval(ctx, in_vals[i]); + } + return values; +} + +/* + UTF8-encode a values list out of an array of (char *) + */ +static char **ads_push_strvals(TALLOC_CTX *ctx, char **in_vals) +{ + void **values; + int i; + + if (!in_vals) return NULL; + for (i=0; in_vals[i]; i++); /* count values */ + values = talloc_zero(ctx, (i+1)*sizeof(char *)); + if (!values) return NULL; + + for (i=0; in_vals[i]; i++) { + push_utf8_talloc(ctx, &values[i], in_vals[i]); + } + return values; +} + +/* + Pull a (char *) array out of a UTF8-encoded values list + */ +static char **ads_pull_strvals(TALLOC_CTX *ctx, char **in_vals) +{ + void **values; + int i; + + if (!in_vals) return NULL; + for (i=0; in_vals[i]; i++); /* count values */ + values = talloc_zero(ctx, (i+1)*sizeof(char *)); + if (!values) return NULL; + + for (i=0; in_vals[i]; i++) { + pull_utf8_talloc(ctx, &values[i], in_vals[i]); + } + return values; +} + /* add an attribute to the list, with values list already constructed */ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, - int mod_op, const char *name, char **values) + int mod_op, const char *name, void **invals) { int curmod; LDAPMod **modlist = (LDAPMod **) *mods; + void **values; + + if (!invals) { + values = NULL; + mod_op = LDAP_MOD_DELETE; + } else { + if (mod_op & LDAP_MOD_BVALUES) + values = ads_dup_values(ctx, invals); + else + values = ads_push_strvals(ctx, invals); + } /* find the first empty slot */ for (curmod=0; modlist[curmod] && modlist[curmod] != (LDAPMod *) -1; @@ -497,213 +582,62 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (mod_op & LDAP_MOD_BVALUES) modlist[curmod]->mod_bvalues = (struct berval **) values; else - modlist[curmod]->mod_values = values; + modlist[curmod]->mod_values = (char **) values; modlist[curmod]->mod_op = mod_op; return ADS_ERROR(LDAP_SUCCESS); } /** - * Add an already-constructed list of values to a mod list for an ADD + * Add a single string value to a mod list * @param ctx An initialized TALLOC_CTX * @param mods An initialized ADS_MODLIST * @param name The attribute name to add - * @param values Constructed values list to add + * @param val The value to add - NULL means DELETE * @return ADS STATUS indicating success of add **/ -ADS_STATUS ads_mod_add_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, char **values) -{ - char **newvals = ads_dup_values(ctx, values); - if (newvals) - return ads_modlist_add(ctx, mods, LDAP_MOD_ADD, name, newvals); - else - return ADS_ERROR(LDAP_NO_MEMORY); -} - -/** - * Add an already-constructed list of values to a mod list for a REPLACE - * @param ctx An initialized TALLOC_CTX - * @param mods An initialized ADS_MODLIST - * @param name The attribute name to add - * @param values Constructed values list to add - * @return ADS STATUS indicating success of add - **/ -ADS_STATUS ads_mod_repl_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, char **values) +ADS_STATUS ads_mod_str(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const char *name, const char *val) { - char **newvals; - if (values && *values) { - if (!(newvals = ads_dup_values(ctx, values))) - return ADS_ERROR(LDAP_NO_MEMORY); - else - return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, - name, newvals); - } - else + char *values[2] = {val, NULL}; + if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); + return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, + (void **) values); } /** - * Add any number of string values to a mod list - for ADD or REPLACE - * @param ctx An initialized TALLOC_CTX - * @param mods An initialized ADS_MODLIST - * @param mod_op Operation to perform (LDAP_MOD_ADD | LDAP_MOD_REPLACE) - * @param name The attribute name to add - * @param ... Any number of values, in (char *) form - * @return ADS STATUS indicating success of add - **/ -ADS_STATUS ads_mod_add_var(TALLOC_CTX *ctx, ADS_MODLIST *mods, - int mod_op, const char *name, ...) -{ - va_list ap; - int num_vals, i, do_op; - char *value, **values; - - /* count the number of values */ - va_start(ap, name); - for (num_vals=0; va_arg(ap, char *); num_vals++); - va_end(ap); - - if (num_vals) { - if (!(values = talloc_zero(ctx, sizeof(char *)*(num_vals+1)))) - return ADS_ERROR(LDAP_NO_MEMORY); - va_start(ap, name); - for (i=0; (value = (char *) va_arg(ap, char *)) && - i < num_vals; i++) - values[i] = value; - va_end(ap); - values[i] = NULL; - do_op = mod_op; - } else { - do_op = LDAP_MOD_DELETE; - values = NULL; - } - return ads_modlist_add(ctx, mods, do_op, name, values); -} - -/** - * Add any number of ber values to a mod list - for ADD or REPLACE + * Add an array of string values to a mod list * @param ctx An initialized TALLOC_CTX * @param mods An initialized ADS_MODLIST - * @param mod_op Operation to perform (LDAP_MOD_ADD | LDAP_MOD_REPLACE) * @param name The attribute name to add - * @param ... Any number of values, in (struct berval *) form - * @return ADS STATUS indicating success of add - **/ -ADS_STATUS ads_mod_add_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, - int mod_op, const char *name, ...) -{ - va_list ap; - int num_vals, i, do_op; - char *value, **values; - - /* count the number of values */ - va_start(ap, name); - for (num_vals=0; va_arg(ap, struct berval *); num_vals++); - va_end(ap); - - if (num_vals) { - if (!(values = talloc_zero(ctx, sizeof(struct berval) * - (num_vals + 1)))) - return ADS_ERROR(LDAP_NO_MEMORY); - va_start(ap, name); - for (i=0; (value = (char *) va_arg(ap, char *)) && - i < num_vals; i++) - values[i] = value; - va_end(ap); - values[i] = NULL; - do_op = mod_op; - } else { - do_op = LDAP_MOD_DELETE; - values = NULL; - } - do_op |= LDAP_MOD_BVALUES; - return ads_modlist_add(ctx, mods, do_op, name, values); -} - -/** - * Add a single string value to a mod list - for REPLACE - * @param ctx An initialized TALLOC_CTX - * @param mods An initialized ADS_MODLIST - * @param name The attribute name to replace - * @param val The value to add + * @param vals The array of string values to add - NULL means DELETE * @return ADS STATUS indicating success of add **/ -ADS_STATUS ads_mod_repl(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, char *val) +ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const char *name, const char **vals) { - if (val) - return ads_mod_add_var(ctx, mods, LDAP_MOD_REPLACE, - name, val, NULL); - else - return ads_mod_add_var(ctx, mods, LDAP_MOD_DELETE, name, NULL); -} - -/** - * Add a single string value to a mod list - for ADD - * @param ctx An initialized TALLOC_CTX - * @param mods An initialized ADS_MODLIST - * @param name The attribute name to add - * @param val The value to add - * @return ADS STATUS indicating success of add - **/ -ADS_STATUS ads_mod_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, - const char *name, const char *val) -{ - return ads_mod_add_var(ctx, mods, LDAP_MOD_ADD, name, val, NULL); + if (!vals) + return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); + return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, + (void **) vals); } /** - * Add a single berval value to a mod list - for ADD + * Add a single ber-encoded value to a mod list * @param ctx An initialized TALLOC_CTX * @param mods An initialized ADS_MODLIST * @param name The attribute name to add - * @param size The size of of the value - * @param val The value to add - * @return ADS STATUS indicating success of add - **/ -ADS_STATUS ads_mod_add_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, size_t size, char *val) -{ - struct berval *bval = NULL; - - if (!(bval = talloc_zero(ctx, sizeof(struct berval *)))) - return ADS_ERROR(LDAP_NO_MEMORY); - if (!(bval->bv_val = talloc_zero(ctx, sizeof(char *)))) - return ADS_ERROR(LDAP_NO_MEMORY); - - bval->bv_val = val; - bval->bv_len = size; - return ads_mod_add_ber(ctx, mods, LDAP_MOD_ADD, name, bval, NULL); -} - -/** - * Add a single berval value to a mod list - for REPLACE - * @param ctx An initialized TALLOC_CTX - * @param mods An initialized ADS_MODLIST - * @param name The attribute name to replace - * @param size The size of of the value - * @param val The value to add + * @param val The value to add - NULL means DELETE * @return ADS STATUS indicating success of add **/ -ADS_STATUS ads_mod_repl_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, - const char *name, size_t size, char *val) +ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const char *name, const struct berval *val) { - struct berval *bval = NULL; - - if (!(bval = talloc_zero(ctx, sizeof(struct berval *)))) - return ADS_ERROR(LDAP_NO_MEMORY); - + struct berval *values[2] = {val, NULL}; if (!val) - return ads_mod_add_ber(ctx, mods, LDAP_MOD_DELETE, name, NULL); - else { - if (!(bval->bv_val = talloc_zero(ctx, sizeof(char *)))) - return ADS_ERROR(LDAP_NO_MEMORY); - bval->bv_val = val; - bval->bv_len = size; - return ads_mod_add_ber(ctx, mods, LDAP_MOD_REPLACE, name, - bval, NULL); - } + return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); + return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE|LDAP_MOD_BVALUES, + name, (void **) values); } /** @@ -716,6 +650,7 @@ ADS_STATUS ads_mod_repl_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) { int ret,i; + char *utf8_dn = NULL; /* this control is needed to modify that contains a currently non-existent attribute (but allowable for the object) to run @@ -729,12 +664,15 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) controls[0] = &PermitModify; controls[1] = NULL; + push_utf8_allocate(&utf8_dn, mod_dn); + /* find the end of the list, marked by NULL or -1 */ for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_modify_ext_s(ads->ld, mod_dn, (LDAPMod **) mods, - controls, NULL); + ret = ldap_modify_ext_s(ads->ld, utf8_dn ? utf8_dn : mod_dn, + (LDAPMod **) mods, controls, NULL); + SAFE_FREE(utf8_dn); return ADS_ERROR(ret); } @@ -747,14 +685,19 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) **/ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) { - int i; + int ret, i; + char *utf8_dn = NULL; + push_utf8_allocate(&utf8_dn, new_dn); + /* find the end of the list, marked by NULL or -1 */ for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); /* make sure the end of the list is NULL */ mods[i] = NULL; - return ADS_ERROR(ldap_add_s(ads->ld, new_dn, mods)); + ret = ldap_add_s(ads->ld, utf8_dn ? utf8_dn : new_dn, mods); + SAFE_FREE(utf8_dn); + return ADS_ERROR(ret); } /** @@ -765,7 +708,11 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) **/ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) { - return ADS_ERROR(ldap_delete(ads->ld, del_dn)); + int ret; + char *utf8_dn = NULL; + push_utf8_allocate(&utf8_dn, del_dn); + ret = ldap_delete(ads->ld, utf8_dn ? utf8_dn : del_dn); + return ADS_ERROR(ret); } /** @@ -797,6 +744,8 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, char *ou_str; TALLOC_CTX *ctx; ADS_MODLIST mods; + const char *objectClass[] = {"top", "person", "organizationalPerson", + "user", "computer", NULL}; if (!(ctx = talloc_init_named("machine_account"))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -824,17 +773,15 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, if (!(mods = ads_init_mods(ctx))) goto done; - ads_mod_add(ctx, &mods, "cn", hostname); - ads_mod_add(ctx, &mods, "sAMAccountName", samAccountName); - ads_mod_add_var(ctx, &mods, LDAP_MOD_ADD, "objectClass", - "top", "person", "organizationalPerson", - "user", "computer", NULL); - ads_mod_add(ctx, &mods, "userPrincipalName", host_upn); - ads_mod_add(ctx, &mods, "servicePrincipalName", host_spn); - ads_mod_add(ctx, &mods, "dNSHostName", hostname); - ads_mod_add(ctx, &mods, "userAccountControl", controlstr); - ads_mod_add(ctx, &mods, "operatingSystem", "Samba"); - ads_mod_add(ctx, &mods, "operatingSystemVersion", VERSION); + ads_mod_str(ctx, &mods, "cn", hostname); + ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); + ads_mod_strlist(ctx, &mods, "objectClass", objectClass); + ads_mod_str(ctx, &mods, "userPrincipalName", host_upn); + ads_mod_str(ctx, &mods, "servicePrincipalName", host_spn); + ads_mod_str(ctx, &mods, "dNSHostName", hostname); + ads_mod_str(ctx, &mods, "userAccountControl", controlstr); + ads_mod_str(ctx, &mods, "operatingSystem", "Samba"); + ads_mod_str(ctx, &mods, "operatingSystemVersion", VERSION); ads_gen_add(ads, new_dn, mods); ret = ads_set_machine_sd(ads, hostname, new_dn); @@ -918,33 +865,39 @@ static void dump_string(const char *field, struct berval **values) used for debugging */ -static void ads_dump_field(char *field, void **values, void *data_area) +static BOOL ads_dump_field(char *field, void **values, void *data_area) { struct { char *name; + BOOL string; void (*handler)(const char *, struct berval **); } handlers[] = { - {"objectGUID", dump_binary}, - {"nTSecurityDescriptor", dump_sd}, - {"objectSid", dump_sid}, - {NULL, NULL} + {"objectGUID", False, dump_binary}, + {"nTSecurityDescriptor", False, dump_sd}, + {"objectSid", False, dump_sid}, + {NULL, True, NULL} }; int i; if (!field) { /* must be end of an entry */ printf("\n"); - return; + return False; } for (i=0; handlers[i].name; i++) { if (StrCaseCmp(handlers[i].name, field) == 0) { + if (!values) /* first time, indicate string or not */ + return handlers[i].string; handlers[i].handler(field, (struct berval **) values); break; } } if (!handlers[i].name) { + if (!values) /* first time, indicate string conversion */ + return True; dump_string(field, (struct berval **) values); } + return False; } /** @@ -971,62 +924,56 @@ void ads_dump(ADS_STRUCT *ads, void *res) * @param data_area user-defined area to pass to function **/ void ads_process_results(ADS_STRUCT *ads, void *res, - void(*fn)(char *, void **, void *), + BOOL(*fn)(char *, void **, void *), void *data_area) { void *msg; + TALLOC_CTX *ctx; + + if (!(ctx = talloc_init())) + return; for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { - char *field; + char *utf8_field; BerElement *b; - for (field = ldap_first_attribute(ads->ld, (LDAPMessage *)msg, &b); - field; - field = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, b)) { - struct berval **values; - - values = ldap_get_values_len(ads->ld, (LDAPMessage *)msg, field); - fn(field, (void **) values, data_area); - - ldap_value_free_len(values); - ldap_memfree(field); + for (utf8_field=ldap_first_attribute(ads->ld, + (LDAPMessage *)msg,&b); + utf8_field; + utf8_field=ldap_next_attribute(ads->ld, + (LDAPMessage *)msg,b)) { + struct berval **ber_vals; + char **str_vals, **utf8_vals; + char *field; + BOOL string; + + pull_utf8_talloc(ctx, (void **) &field, utf8_field); + string = fn(field, NULL, data_area); + + if (string) { + utf8_vals = ldap_get_values(ads->ld, + (LDAPMessage *)msg, field); + str_vals = ads_pull_strvals(ctx, utf8_vals); + fn(field, (void **) str_vals, data_area); + ldap_value_free(utf8_vals); + } else { + ber_vals = ldap_get_values_len(ads->ld, + (LDAPMessage *)msg, field); + fn(field, (void **) ber_vals, data_area); + + ldap_value_free_len(ber_vals); + } + ldap_memfree(utf8_field); } ber_free(b, 0); + talloc_destroy_pool(ctx); fn(NULL, NULL, data_area); /* completed an entry */ } + talloc_destroy(ctx); } -/** - * Walk through an entry, calling a function for each attribute found. - * The function receives a field name, a berval * array of values, - * and a data area passed through from the start. - * @param ads connection to ads server - * @param res Results to process - * @param fn Function for processing each result - * @param data_area user-defined area to pass to function - **/ -void ads_process_entry(ADS_STRUCT *ads, void *msg, - void(*fn)(ADS_STRUCT *, char *, void **, void *), - void *data_area) -{ - char *field; - BerElement *b; - - for (field = ldap_first_attribute(ads->ld, (LDAPMessage *)msg, &b); - field; - field = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, b)) { - struct berval **values; - - values = ldap_get_values_len(ads->ld, (LDAPMessage *)msg, field); - fn(ads, field, (void **) values, data_area); - - ldap_value_free_len(values); - ldap_memfree(field); - } - ber_free(b, 0); -} /** * count how many replies are in a LDAPMessage * @param ads connection to ads server @@ -1138,6 +1085,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) char *exp = 0; size_t sd_size = 0; struct berval **bvals = 0; + struct berval bval = {0, NULL}; prs_struct ps; prs_struct ps_wire; @@ -1192,7 +1140,9 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) #endif if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY); - ads_mod_repl_len(ctx, &mods, attrs[0], sd_size, prs_data_p(&ps_wire)); + bval.bv_len = sd_size; + bval.bv_val = prs_data_p(&ps_wire); + ads_mod_ber(ctx, &mods, attrs[0], &bval); ret = ads_gen_mod(ads, dn, mods); prs_mem_free(&ps); @@ -1274,12 +1224,18 @@ char *ads_pull_string(ADS_STRUCT *ads, { char **values; char *ret = NULL; + char *ux_string; + int rc; values = ldap_get_values(ads->ld, msg, field); if (!values) return NULL; if (values[0]) { - ret = talloc_strdup(mem_ctx, values[0]); + rc = pull_utf8_talloc(mem_ctx, (void **)&ux_string, + values[0]); + if (rc != -1) + ret = ux_string; + } ldap_value_free(values); return ret; diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 52771ba39a..64ae8252c8 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -31,7 +31,7 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, char *printer, char *servername) { ADS_STATUS status; - char *srv_dn, *exp; + char *srv_dn, **srv_cn, *exp; const char *attrs[] = {"*", "nTSecurityDescriptor", NULL}; status = ads_find_machine_acct(ads, res, servername); @@ -41,12 +41,14 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, return status; } srv_dn = ldap_get_dn(ads->ld, *res); + srv_cn = ldap_explode_dn(srv_dn, 1); ads_msgfree(ads, *res); - asprintf(&exp, "(printerName=%s)", printer); - status = ads_do_search(ads, srv_dn, LDAP_SCOPE_SUBTREE, - exp, attrs, res); + asprintf(&exp, "(cn=%s-%s)", srv_cn[0], printer); + status = ads_search(ads, res, exp, attrs); + ldap_memfree(srv_dn); + ldap_value_free(srv_cn); free(exp); return status; } @@ -68,33 +70,33 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, mods = ads_init_mods(ctx); /* add the attributes to the list - required ones first */ - ads_mod_repl(ctx, &mods, "printerName", prt->printerName); - ads_mod_repl(ctx, &mods, "serverName", prt->serverName); - ads_mod_repl(ctx, &mods, "shortServerName", prt->shortServerName); - ads_mod_repl(ctx, &mods, "uNCName", prt->uNCName); - ads_mod_repl(ctx, &mods, "versionNumber", prt->versionNumber); + ads_mod_str(ctx, &mods, "printerName", prt->printerName); + ads_mod_str(ctx, &mods, "serverName", prt->serverName); + ads_mod_str(ctx, &mods, "shortServerName", prt->shortServerName); + ads_mod_str(ctx, &mods, "uNCName", prt->uNCName); + ads_mod_str(ctx, &mods, "versionNumber", prt->versionNumber); /* now the optional ones */ - ads_mod_repl_list(ctx, &mods, "description", prt->description); - ads_mod_repl(ctx, &mods, "assetNumber",prt->assetNumber); - ads_mod_repl(ctx, &mods, "bytesPerMinute",prt->bytesPerMinute); - ads_mod_repl(ctx, &mods, "defaultPriority",prt->defaultPriority); - ads_mod_repl(ctx, &mods, "driverName", prt->driverName); - ads_mod_repl(ctx, &mods, "driverVersion",prt->driverVersion); - ads_mod_repl(ctx, &mods, "location", prt->location); - ads_mod_repl(ctx, &mods, "operatingSystem",prt->operatingSystem); - ads_mod_repl(ctx, &mods, "operatingSystemHotfix", + ads_mod_strlist(ctx, &mods, "description", prt->description); + ads_mod_str(ctx, &mods, "assetNumber",prt->assetNumber); + ads_mod_str(ctx, &mods, "bytesPerMinute",prt->bytesPerMinute); + ads_mod_str(ctx, &mods, "defaultPriority",prt->defaultPriority); + ads_mod_str(ctx, &mods, "driverName", prt->driverName); + ads_mod_str(ctx, &mods, "driverVersion",prt->driverVersion); + ads_mod_str(ctx, &mods, "location", prt->location); + ads_mod_str(ctx, &mods, "operatingSystem",prt->operatingSystem); + ads_mod_str(ctx, &mods, "operatingSystemHotfix", prt->operatingSystemHotfix); - ads_mod_repl(ctx, &mods, "operatingSystemServicePack", + ads_mod_str(ctx, &mods, "operatingSystemServicePack", prt->operatingSystemServicePack); - ads_mod_repl(ctx, &mods, "operatingSystemVersion", + ads_mod_str(ctx, &mods, "operatingSystemVersion", prt->operatingSystemVersion); - ads_mod_repl(ctx, &mods, "physicalLocationObject", + ads_mod_str(ctx, &mods, "physicalLocationObject", prt->physicalLocationObject); - ads_mod_repl_list(ctx, &mods, "portName", prt->portName); - ads_mod_repl(ctx, &mods, "printStartTime", prt->printStartTime); - ads_mod_repl(ctx, &mods, "printEndTime", prt->printEndTime); - ads_mod_repl_list(ctx, &mods, "printBinNames", prt->printBinNames); + ads_mod_strlist(ctx, &mods, "portName", prt->portName); + ads_mod_str(ctx, &mods, "printStartTime", prt->printStartTime); + ads_mod_str(ctx, &mods, "printEndTime", prt->printEndTime); + ads_mod_strlist(ctx, &mods, "printBinNames", prt->printBinNames); /*... and many others */ /* do the ldap modify */ @@ -124,12 +126,12 @@ static ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn, return ADS_ERROR(LDAP_NO_MEMORY); /* These are the fields a printQueue must contain */ - ads_mod_add(ctx, &mods, "uNCName", prt->uNCName); - ads_mod_add(ctx, &mods, "versionNumber", prt->versionNumber); - ads_mod_add(ctx, &mods, "serverName", prt->serverName); - ads_mod_add(ctx, &mods, "shortServerName", prt->shortServerName); - ads_mod_add(ctx, &mods, "printerName", prt->printerName); - ads_mod_add(ctx, &mods, "objectClass", "printQueue"); + ads_mod_str(ctx, &mods, "uNCName", prt->uNCName); + ads_mod_str(ctx, &mods, "versionNumber", prt->versionNumber); + ads_mod_str(ctx, &mods, "serverName", prt->serverName); + ads_mod_str(ctx, &mods, "shortServerName", prt->shortServerName); + ads_mod_str(ctx, &mods, "printerName", prt->printerName); + ads_mod_str(ctx, &mods, "objectClass", "printQueue"); status = ads_gen_add(ads, prt_dn, mods); @@ -157,14 +159,11 @@ ADS_STATUS ads_add_printer(ADS_STRUCT *ads, const ADS_PRINTER_ENTRY *prt) prt->shortServerName)); return status; } - host_dn = ldap_get_dn(ads->ld, res); + host_dn = ads_get_dn(ads, res); ads_msgfree(ads, res); - /* printer dn is cn=server-printer followed by host dn */ - asprintf(&prt_dn, "cn=%s-%s,%s", prt->shortServerName, - prt->printerName, host_dn); - - status = ads_search_dn(ads, &res, prt_dn, attrs); + ads_find_printer_on_server(ads, &res, prt->printerName, + prt->shortServerName); if (ADS_ERR_OK(status) && ads_count_replies(ads, res)) { DEBUG(1, ("ads_add_printer: printer %s already exists\n", diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index c1a9a89e46..d0b6c2ca8c 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -44,6 +44,8 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, ADS_MODLIST mods; ADS_STATUS status; char *upn, *new_dn, *name, *controlstr; + const char *objectClass[] = {"top", "person", "organizationalPerson", + "user", NULL}; if (fullname && *fullname) name = fullname; else name = user; @@ -63,14 +65,13 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, if (!(mods = ads_init_mods(ctx))) goto done; - ads_mod_add(ctx, &mods, "cn", name); - ads_mod_add_var(ctx, &mods, LDAP_MOD_ADD, "objectClass", "top", - "person", "organizationalPerson", "user", NULL); - ads_mod_add(ctx, &mods, "userPrincipalName", upn); - ads_mod_add(ctx, &mods, "name", name); - ads_mod_add(ctx, &mods, "displayName", name); - ads_mod_add(ctx, &mods, "sAMAccountName", user); - ads_mod_add(ctx, &mods, "userAccountControl", controlstr); + ads_mod_str(ctx, &mods, "cn", name); + ads_mod_strlist(ctx, &mods, "objectClass", objectClass); + ads_mod_str(ctx, &mods, "userPrincipalName", upn); + ads_mod_str(ctx, &mods, "name", name); + ads_mod_str(ctx, &mods, "displayName", name); + ads_mod_str(ctx, &mods, "sAMAccountName", user); + ads_mod_str(ctx, &mods, "userAccountControl", controlstr); status = ads_gen_add(ads, new_dn, mods); done: @@ -85,6 +86,7 @@ ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, ADS_MODLIST mods; ADS_STATUS status; char *new_dn; + const char *objectClass[] = {"top", "group", NULL}; if (!(ctx = talloc_init_named("ads_add_group_acct"))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -97,13 +99,12 @@ ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group, if (!(mods = ads_init_mods(ctx))) goto done; - ads_mod_add(ctx, &mods, "cn", group); - ads_mod_add_var(ctx, &mods, LDAP_MOD_ADD, "objectClass", "top", - "group", NULL); - ads_mod_add(ctx, &mods, "name", group); + ads_mod_str(ctx, &mods, "cn", group); + ads_mod_strlist(ctx, &mods, "objectClass",objectClass); + ads_mod_str(ctx, &mods, "name", group); if (comment) - ads_mod_add(ctx, &mods, "description", comment); - ads_mod_add(ctx, &mods, "sAMAccountName", group); + ads_mod_str(ctx, &mods, "description", comment); + ads_mod_str(ctx, &mods, "sAMAccountName", group); status = ads_gen_add(ads, new_dn, mods); done: -- cgit From 0327428f27b453e5b2c1ee2751ab87d7716144d7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 25 Jun 2002 02:29:09 +0000 Subject: Break up samba's object dependencies, and its prototype includes. Now smbclient, net, and swat use their own proto files - now the global proto.h The change to libads/kerberos.c was to break up the dependency on secrets.c - we want to be able to write an ADS client that doesn't need local secrets. I have other breakups in the works - I will remove the dependency of rpc_parse on passdb (and therefore secrets.c) shortly. (NOTE: This patch does *not* break up includes.h, or other such forbidden actions). Andrew Bartlett (This used to be commit edb41dad2df0ae3db364dbc3896cc75956262edf) --- source3/libads/kerberos.c | 123 ------------------------------- source3/libads/kerberos_verify.c | 151 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+), 123 deletions(-) create mode 100644 source3/libads/kerberos_verify.c (limited to 'source3/libads') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 85518a6769..1ba5d978e8 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -129,128 +129,5 @@ int ads_kinit_password(ADS_STRUCT *ads) return ret; } -/* - verify an incoming ticket and parse out the principal name and - authorization_data if available -*/ -NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, - char **principal, DATA_BLOB *auth_data) -{ - krb5_context context; - krb5_auth_context auth_context = NULL; - krb5_keytab keytab = NULL; - krb5_data packet; - krb5_ticket *tkt = NULL; - krb5_data salt; - krb5_encrypt_block eblock; - int ret; - krb5_keyblock * key; - krb5_principal host_princ; - char *host_princ_s; - extern pstring global_myname; - fstring myname; - char *password_s; - krb5_data password; - - if (!secrets_init()) { - DEBUG(1,("secrets_init failed\n")); - return NT_STATUS_LOGON_FAILURE; - } - - password_s = secrets_fetch_machine_password(); - if (!password_s) { - DEBUG(1,("failed to fetch machine password\n")); - return NT_STATUS_LOGON_FAILURE; - } - - password.data = password_s; - password.length = strlen(password_s); - - ret = krb5_init_context(&context); - if (ret) { - DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - ret = krb5_set_default_realm(context, ads->realm); - if (ret) { - DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); - ads_destroy(&ads); - return NT_STATUS_LOGON_FAILURE; - } - - /* this whole process is far more complex than I would - like. We have to go through all this to allow us to store - the secret internally, instead of using /etc/krb5.keytab */ - ret = krb5_auth_con_init(context, &auth_context); - if (ret) { - DEBUG(1,("krb5_auth_con_init failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - fstrcpy(myname, global_myname); - strlower(myname); - asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm()); - ret = krb5_parse_name(context, host_princ_s, &host_princ); - if (ret) { - DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - ret = krb5_principal2salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { - return NT_STATUS_NO_MEMORY; - } - - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); - - ret = krb5_string_to_key(context, &eblock, key, &password, &salt); - if (ret) { - DEBUG(1,("krb5_string_to_key failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - krb5_auth_con_setuseruserkey(context, auth_context, key); - - packet.length = ticket->length; - packet.data = (krb5_pointer)ticket->data; - -#if 0 - file_save("/tmp/ticket.dat", ticket->data, ticket->length); -#endif - - if ((ret = krb5_rd_req(context, &auth_context, &packet, - NULL, keytab, NULL, &tkt))) { - DEBUG(3,("krb5_rd_req with auth failed (%s)\n", - error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - if (tkt->enc_part2) { - *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); - } - -#if 0 - if (tkt->enc_part2) { - file_save("/tmp/authdata.dat", - tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); - } -#endif - - if ((ret = krb5_unparse_name(context, tkt->enc_part2->client, principal))) { - DEBUG(3,("krb5_unparse_name failed (%s)\n", - error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - return NT_STATUS_OK; -} #endif diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c new file mode 100644 index 0000000000..dac90908c4 --- /dev/null +++ b/source3/libads/kerberos_verify.c @@ -0,0 +1,151 @@ +/* + Unix SMB/CIFS implementation. + kerberos utility library + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Remus Koos 2001 + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#ifdef HAVE_KRB5 + +/* + verify an incoming ticket and parse out the principal name and + authorization_data if available +*/ +NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, + char **principal, DATA_BLOB *auth_data) +{ + krb5_context context; + krb5_auth_context auth_context = NULL; + krb5_keytab keytab = NULL; + krb5_data packet; + krb5_ticket *tkt = NULL; + krb5_data salt; + krb5_encrypt_block eblock; + int ret; + krb5_keyblock * key; + krb5_principal host_princ; + char *host_princ_s; + extern pstring global_myname; + fstring myname; + char *password_s; + krb5_data password; + + if (!secrets_init()) { + DEBUG(1,("secrets_init failed\n")); + return NT_STATUS_LOGON_FAILURE; + } + + password_s = secrets_fetch_machine_password(); + if (!password_s) { + DEBUG(1,("failed to fetch machine password\n")); + return NT_STATUS_LOGON_FAILURE; + } + + password.data = password_s; + password.length = strlen(password_s); + + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + ret = krb5_set_default_realm(context, ads->realm); + if (ret) { + DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); + ads_destroy(&ads); + return NT_STATUS_LOGON_FAILURE; + } + + /* this whole process is far more complex than I would + like. We have to go through all this to allow us to store + the secret internally, instead of using /etc/krb5.keytab */ + ret = krb5_auth_con_init(context, &auth_context); + if (ret) { + DEBUG(1,("krb5_auth_con_init failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + fstrcpy(myname, global_myname); + strlower(myname); + asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm()); + ret = krb5_parse_name(context, host_princ_s, &host_princ); + if (ret) { + DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + ret = krb5_principal2salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { + return NT_STATUS_NO_MEMORY; + } + + krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); + + ret = krb5_string_to_key(context, &eblock, key, &password, &salt); + if (ret) { + DEBUG(1,("krb5_string_to_key failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + krb5_auth_con_setuseruserkey(context, auth_context, key); + + packet.length = ticket->length; + packet.data = (krb5_pointer)ticket->data; + +#if 0 + file_save("/tmp/ticket.dat", ticket->data, ticket->length); +#endif + + if ((ret = krb5_rd_req(context, &auth_context, &packet, + NULL, keytab, NULL, &tkt))) { + DEBUG(3,("krb5_rd_req with auth failed (%s)\n", + error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + if (tkt->enc_part2) { + *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, + tkt->enc_part2->authorization_data[0]->length); + } + +#if 0 + if (tkt->enc_part2) { + file_save("/tmp/authdata.dat", + tkt->enc_part2->authorization_data[0]->contents, + tkt->enc_part2->authorization_data[0]->length); + } +#endif + + if ((ret = krb5_unparse_name(context, tkt->enc_part2->client, principal))) { + DEBUG(3,("krb5_unparse_name failed (%s)\n", + error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + return NT_STATUS_OK; +} + +#endif -- cgit From f0a0c6955bc4e7c587fa06599759ad9be5750573 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 26 Jun 2002 17:27:30 +0000 Subject: Reduce compiler warnings. (This used to be commit b361089360068b91e9f4d221abdc3c8351596a7f) --- source3/libads/ldap.c | 64 +++++++++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 28 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b898eec7a9..22d7ed3ebf 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -37,6 +37,12 @@ * codepoints in UTF-8). This may have to change at some point **/ +/* This is used to get reduce other const warnings to just this fn */ +static void * ads_unconst_ptr(const void *const_ptr) +{ + return const_ptr; +} + /** * Connect to the LDAP server * @param ads Pointer to an existing ADS_STRUCT @@ -179,14 +185,13 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); if (!push_utf8_allocate((void **) &utf8_exp, exp)) - utf8_exp = exp; + utf8_exp = ads_unconst_ptr(exp); if (!push_utf8_allocate((void **) &utf8_path, bind_path)) - utf8_path = bind_path; + utf8_path = ads_unconst_ptr(bind_path); rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, - (char **) attrs, 0, controls, NULL, - NULL, LDAP_NO_LIMIT, - (LDAPMessage **)res); + ads_unconst_ptr(attrs), 0, controls, + NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); if (utf8_exp != exp) SAFE_FREE(utf8_exp); @@ -342,12 +347,12 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, *res = NULL; if (!push_utf8_allocate((void **) &utf8_exp, exp)) - utf8_exp = exp; + utf8_exp = ads_unconst_ptr(exp); if (!push_utf8_allocate((void **) &utf8_path, bind_path)) - utf8_path = bind_path; + utf8_path = ads_unconst_ptr(bind_path); - rc = ldap_search_ext_s(ads->ld, utf8_path, scope, - utf8_exp, (char **) attrs, 0, NULL, NULL, + rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, + ads_unconst_ptr(attrs), 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); if (utf8_exp != exp) @@ -424,7 +429,7 @@ char *ads_get_dn(ADS_STRUCT *ads, void *res) char *utf8_dn, *unix_dn; utf8_dn = ldap_get_dn(ads->ld, res); - pull_utf8_allocate(&unix_dn, utf8_dn); + pull_utf8_allocate((void **) &unix_dn, utf8_dn); ldap_memfree(utf8_dn); return unix_dn; } @@ -491,12 +496,13 @@ static struct berval *dup_berval(TALLOC_CTX *ctx, struct berval *in_val) */ static struct berval **ads_dup_values(TALLOC_CTX *ctx, struct berval **in_vals) { - void **values; + struct berval **values; int i; if (!in_vals) return NULL; for (i=0; in_vals[i]; i++); /* count values */ - values = talloc_zero(ctx, (i+1)*sizeof(struct berval *)); + values = (struct berval **) talloc_zero(ctx, + (i+1)*sizeof(struct berval *)); if (!values) return NULL; for (i=0; in_vals[i]; i++) { @@ -510,16 +516,16 @@ static struct berval **ads_dup_values(TALLOC_CTX *ctx, struct berval **in_vals) */ static char **ads_push_strvals(TALLOC_CTX *ctx, char **in_vals) { - void **values; + char **values; int i; if (!in_vals) return NULL; for (i=0; in_vals[i]; i++); /* count values */ - values = talloc_zero(ctx, (i+1)*sizeof(char *)); + values = (char ** ) talloc_zero(ctx, (i+1)*sizeof(char *)); if (!values) return NULL; for (i=0; in_vals[i]; i++) { - push_utf8_talloc(ctx, &values[i], in_vals[i]); + push_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); } return values; } @@ -529,16 +535,16 @@ static char **ads_push_strvals(TALLOC_CTX *ctx, char **in_vals) */ static char **ads_pull_strvals(TALLOC_CTX *ctx, char **in_vals) { - void **values; + char **values; int i; if (!in_vals) return NULL; for (i=0; in_vals[i]; i++); /* count values */ - values = talloc_zero(ctx, (i+1)*sizeof(char *)); + values = (char **) talloc_zero(ctx, (i+1)*sizeof(char *)); if (!values) return NULL; for (i=0; in_vals[i]; i++) { - pull_utf8_talloc(ctx, &values[i], in_vals[i]); + pull_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); } return values; } @@ -558,9 +564,11 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, mod_op = LDAP_MOD_DELETE; } else { if (mod_op & LDAP_MOD_BVALUES) - values = ads_dup_values(ctx, invals); + values = (void **) ads_dup_values(ctx, + (struct berval **)invals); else - values = ads_push_strvals(ctx, invals); + values = (void **) ads_push_strvals(ctx, + (char **) invals); } /* find the first empty slot */ @@ -578,7 +586,7 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (!(modlist[curmod] = talloc_zero(ctx, sizeof(LDAPMod)))) return ADS_ERROR(LDAP_NO_MEMORY); - modlist[curmod]->mod_type = name; + modlist[curmod]->mod_type = ads_unconst_ptr(name); if (mod_op & LDAP_MOD_BVALUES) modlist[curmod]->mod_bvalues = (struct berval **) values; else @@ -598,7 +606,7 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, ADS_STATUS ads_mod_str(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const char *val) { - char *values[2] = {val, NULL}; + char *values[2] = {ads_unconst_ptr(val), NULL}; if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, @@ -618,8 +626,8 @@ ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, { if (!vals) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); - return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, - (void **) vals); + return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, + ads_unconst_ptr(name), ads_unconst_ptr(vals)); } /** @@ -633,7 +641,7 @@ ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const struct berval *val) { - struct berval *values[2] = {val, NULL}; + struct berval *values[2] = {ads_unconst_ptr(val), NULL}; if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE|LDAP_MOD_BVALUES, @@ -664,7 +672,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) controls[0] = &PermitModify; controls[1] = NULL; - push_utf8_allocate(&utf8_dn, mod_dn); + push_utf8_allocate((void **) &utf8_dn, mod_dn); /* find the end of the list, marked by NULL or -1 */ for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); @@ -688,7 +696,7 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) int ret, i; char *utf8_dn = NULL; - push_utf8_allocate(&utf8_dn, new_dn); + push_utf8_allocate((void **) &utf8_dn, new_dn); /* find the end of the list, marked by NULL or -1 */ for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); @@ -710,7 +718,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) { int ret; char *utf8_dn = NULL; - push_utf8_allocate(&utf8_dn, del_dn); + push_utf8_allocate((void **) &utf8_dn, del_dn); ret = ldap_delete(ads->ld, utf8_dn ? utf8_dn : del_dn); return ADS_ERROR(ret); } -- cgit From f90e74afbabf86b54cf0d0cc137bff167d23d768 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 28 Jun 2002 19:25:11 +0000 Subject: Const cleanup...should only be 2 warnings left from calling lib/util_str.c str_list_copy(). Perhaps its proto should be fixed. (This used to be commit b81bc2b34b620c24a148435d9913bd1a1528c983) --- source3/libads/ldap.c | 275 +++++++++++++++++++++++++++++--------------------- 1 file changed, 158 insertions(+), 117 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 22d7ed3ebf..c95cb4ad90 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -37,12 +37,6 @@ * codepoints in UTF-8). This may have to change at some point **/ -/* This is used to get reduce other const warnings to just this fn */ -static void * ads_unconst_ptr(const void *const_ptr) -{ - return const_ptr; -} - /** * Connect to the LDAP server * @param ads Pointer to an existing ADS_STRUCT @@ -115,6 +109,81 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) return ads_sasl_bind(ads); } +/* + Duplicate a struct berval into talloc'ed memory + */ +static struct berval *dup_berval(TALLOC_CTX *ctx, const struct berval *in_val) +{ + struct berval *value; + + if (!in_val) return NULL; + + value = talloc_zero(ctx, sizeof(struct berval)); + if (in_val->bv_len == 0) return value; + + value->bv_len = in_val->bv_len; + value->bv_val = talloc_memdup(ctx, in_val->bv_val, in_val->bv_len); + return value; +} + +/* + Make a values list out of an array of (struct berval *) + */ +static struct berval **ads_dup_values(TALLOC_CTX *ctx, + const struct berval **in_vals) +{ + struct berval **values; + int i; + + if (!in_vals) return NULL; + for (i=0; in_vals[i]; i++); /* count values */ + values = (struct berval **) talloc_zero(ctx, + (i+1)*sizeof(struct berval *)); + if (!values) return NULL; + + for (i=0; in_vals[i]; i++) { + values[i] = dup_berval(ctx, in_vals[i]); + } + return values; +} + +/* + UTF8-encode a values list out of an array of (char *) + */ +static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals) +{ + char **values; + int i; + + if (!in_vals) return NULL; + for (i=0; in_vals[i]; i++); /* count values */ + values = (char ** ) talloc_zero(ctx, (i+1)*sizeof(char *)); + if (!values) return NULL; + + for (i=0; in_vals[i]; i++) { + push_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); + } + return values; +} + +/* + Pull a (char *) array out of a UTF8-encoded values list + */ +static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) +{ + char **values; + int i; + + if (!in_vals) return NULL; + for (i=0; in_vals[i]; i++); /* count values */ + values = (char **) talloc_zero(ctx, (i+1)*sizeof(char *)); + if (!values) return NULL; + + for (i=0; in_vals[i]; i++) { + pull_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); + } + return values; +} /** * Do a search with paged results. cookie must be null on the first @@ -136,17 +205,45 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, int *count, void **cookie) { int rc, i, version; - char *utf8_exp, *utf8_path; + char *utf8_exp, *utf8_path, **search_attrs; LDAPControl PagedResults, NoReferrals, *controls[3], **rcontrols; BerElement *cookie_be = NULL; struct berval *cookie_bv= NULL; + TALLOC_CTX *ctx; *res = NULL; + if (!(ctx = talloc_init())) + return ADS_ERROR(LDAP_NO_MEMORY); + + /* 0 means the conversion worked but the result was empty + so we only fail if it's negative. In any case, it always + at least nulls out the dest */ + if ((push_utf8_talloc(ctx, (void **) &utf8_exp, exp) < 0) || + (push_utf8_talloc(ctx, (void **) &utf8_path, bind_path) < 0)) { + rc = LDAP_NO_MEMORY; + goto done; + } + + if (!attrs || !(*attrs)) + search_attrs = NULL; + else { + /* This would be the utf8-encoded version...*/ + /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ + if (!(str_list_copy(&search_attrs, (char **) attrs))) + { + rc = LDAP_NO_MEMORY; + goto done; + } + } + + /* Paged results only available on ldap v3 or later */ ldap_get_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); - if (version < LDAP_VERSION3) - return ADS_ERROR(LDAP_NOT_SUPPORTED); + if (version < LDAP_VERSION3) { + rc = LDAP_NOT_SUPPORTED; + goto done; + } cookie_be = ber_alloc_t(LBER_USE_DER); if (cookie && *cookie) { @@ -184,32 +281,23 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, */ ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - if (!push_utf8_allocate((void **) &utf8_exp, exp)) - utf8_exp = ads_unconst_ptr(exp); - if (!push_utf8_allocate((void **) &utf8_path, bind_path)) - utf8_path = ads_unconst_ptr(bind_path); - rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, - ads_unconst_ptr(attrs), 0, controls, + search_attrs, 0, controls, NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); - if (utf8_exp != exp) - SAFE_FREE(utf8_exp); - if (utf8_path != bind_path) - SAFE_FREE(utf8_path); ber_free(cookie_be, 1); ber_bvfree(cookie_bv); if (rc) { DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", exp, ldap_err2string(rc))); - return ADS_ERROR(rc); + goto done; } rc = ldap_parse_result(ads->ld, *res, NULL, NULL, NULL, NULL, &rcontrols, 0); if (!rcontrols) { - return ADS_ERROR(rc); + goto done; } for (i=0; rcontrols[i]; i++) { @@ -229,7 +317,12 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, } } ldap_controls_free(rcontrols); - + +done: + talloc_destroy(ctx); + /* if/when we decide to utf8-encode attrs, take out this next line */ + str_list_free(&search_attrs); + return ADS_ERROR(rc); } @@ -340,30 +433,50 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, { struct timeval timeout; int rc; - char *utf8_exp, *utf8_path; + char *utf8_exp, *utf8_path, **search_attrs = NULL; + TALLOC_CTX *ctx; + + if (!(ctx = talloc_init())) + return ADS_ERROR(LDAP_NO_MEMORY); + + /* 0 means the conversion worked but the result was empty + so we only fail if it's negative. In any case, it always + at least nulls out the dest */ + if ((push_utf8_talloc(ctx, (void **) &utf8_exp, exp) < 0) || + (push_utf8_talloc(ctx, (void **) &utf8_path, bind_path) < 0)) { + rc = LDAP_NO_MEMORY; + goto done; + } + + if (!attrs || !(*attrs)) + search_attrs = NULL; + else { + /* This would be the utf8-encoded version...*/ + /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ + if (!(str_list_copy(&search_attrs, (char **) attrs))) + { + rc = LDAP_NO_MEMORY; + goto done; + } + } timeout.tv_sec = ADS_SEARCH_TIMEOUT; timeout.tv_usec = 0; *res = NULL; - if (!push_utf8_allocate((void **) &utf8_exp, exp)) - utf8_exp = ads_unconst_ptr(exp); - if (!push_utf8_allocate((void **) &utf8_path, bind_path)) - utf8_path = ads_unconst_ptr(bind_path); - rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, - ads_unconst_ptr(attrs), 0, NULL, NULL, + search_attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); - if (utf8_exp != exp) - SAFE_FREE(utf8_exp); - if (utf8_path != bind_path) - SAFE_FREE(utf8_path); if (rc == LDAP_SIZELIMIT_EXCEEDED) { DEBUG(3,("Warning! sizelimit exceeded in ldap. Truncating.\n")); rc = 0; } + done: + talloc_destroy(ctx); + /* if/when we decide to utf8-encode attrs, take out this next line */ + str_list_free(&search_attrs); return ADS_ERROR(rc); } /** @@ -474,86 +587,13 @@ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx) return mods; } -/* - Duplicate a struct berval into talloc'ed memory - */ -static struct berval *dup_berval(TALLOC_CTX *ctx, struct berval *in_val) -{ - struct berval *value; - - if (!in_val) return NULL; - - value = talloc_zero(ctx, sizeof(struct berval)); - if (in_val->bv_len == 0) return value; - - value->bv_len = in_val->bv_len; - value->bv_val = talloc_memdup(ctx, in_val->bv_val, in_val->bv_len); - return value; -} - -/* - Make a values list out of an array of (struct berval *) - */ -static struct berval **ads_dup_values(TALLOC_CTX *ctx, struct berval **in_vals) -{ - struct berval **values; - int i; - - if (!in_vals) return NULL; - for (i=0; in_vals[i]; i++); /* count values */ - values = (struct berval **) talloc_zero(ctx, - (i+1)*sizeof(struct berval *)); - if (!values) return NULL; - - for (i=0; in_vals[i]; i++) { - values[i] = dup_berval(ctx, in_vals[i]); - } - return values; -} - -/* - UTF8-encode a values list out of an array of (char *) - */ -static char **ads_push_strvals(TALLOC_CTX *ctx, char **in_vals) -{ - char **values; - int i; - - if (!in_vals) return NULL; - for (i=0; in_vals[i]; i++); /* count values */ - values = (char ** ) talloc_zero(ctx, (i+1)*sizeof(char *)); - if (!values) return NULL; - - for (i=0; in_vals[i]; i++) { - push_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); - } - return values; -} - -/* - Pull a (char *) array out of a UTF8-encoded values list - */ -static char **ads_pull_strvals(TALLOC_CTX *ctx, char **in_vals) -{ - char **values; - int i; - - if (!in_vals) return NULL; - for (i=0; in_vals[i]; i++); /* count values */ - values = (char **) talloc_zero(ctx, (i+1)*sizeof(char *)); - if (!values) return NULL; - - for (i=0; in_vals[i]; i++) { - pull_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); - } - return values; -} /* add an attribute to the list, with values list already constructed */ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, - int mod_op, const char *name, void **invals) + int mod_op, const char *name, + const void **invals) { int curmod; LDAPMod **modlist = (LDAPMod **) *mods; @@ -565,10 +605,10 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, } else { if (mod_op & LDAP_MOD_BVALUES) values = (void **) ads_dup_values(ctx, - (struct berval **)invals); + (const struct berval **)invals); else values = (void **) ads_push_strvals(ctx, - (char **) invals); + (const char **) invals); } /* find the first empty slot */ @@ -586,7 +626,7 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (!(modlist[curmod] = talloc_zero(ctx, sizeof(LDAPMod)))) return ADS_ERROR(LDAP_NO_MEMORY); - modlist[curmod]->mod_type = ads_unconst_ptr(name); + modlist[curmod]->mod_type = talloc_strdup(ctx, name); if (mod_op & LDAP_MOD_BVALUES) modlist[curmod]->mod_bvalues = (struct berval **) values; else @@ -606,11 +646,11 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, ADS_STATUS ads_mod_str(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const char *val) { - char *values[2] = {ads_unconst_ptr(val), NULL}; + const char *values[2] = {val, NULL}; if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, - (void **) values); + (const void **) values); } /** @@ -627,7 +667,7 @@ ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (!vals) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, - ads_unconst_ptr(name), ads_unconst_ptr(vals)); + name, (const void **) vals); } /** @@ -641,11 +681,11 @@ ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const struct berval *val) { - struct berval *values[2] = {ads_unconst_ptr(val), NULL}; + const struct berval *values[2] = {val, NULL}; if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE|LDAP_MOD_BVALUES, - name, (void **) values); + name, (const void **) values); } /** @@ -962,7 +1002,8 @@ void ads_process_results(ADS_STRUCT *ads, void *res, if (string) { utf8_vals = ldap_get_values(ads->ld, (LDAPMessage *)msg, field); - str_vals = ads_pull_strvals(ctx, utf8_vals); + str_vals = ads_pull_strvals(ctx, + (const char **) utf8_vals); fn(field, (void **) str_vals, data_area); ldap_value_free(utf8_vals); } else { -- cgit From 859b13577309912fc5b3591971412b2cb3a42f28 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Jul 2002 07:30:40 +0000 Subject: ads_mod_ber should be static, not public this fixes the huge number of struct berval warnings on non-ads compiles (This used to be commit e7f588d8156856109623b5f5a3841c5d096b1185) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c95cb4ad90..1045b05812 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -678,8 +678,8 @@ ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, * @param val The value to add - NULL means DELETE * @return ADS STATUS indicating success of add **/ -ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, - const char *name, const struct berval *val) +static ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const char *name, const struct berval *val) { const struct berval *values[2] = {val, NULL}; if (!val) -- cgit From 9930b0b0650ae3e38c033c28672398425dd8228c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Jul 2002 09:12:41 +0000 Subject: used findstatic.pl to make some variables static and remove some dead code (This used to be commit 91ad9041e9507d36eb3f40c23c5d4df61f139ef0) --- source3/libads/disp_sec.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index 35a7af7b36..a930fd6fe0 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -52,7 +52,7 @@ static struct perm_mask_str { }; /* convert a security permissions into a string */ -void ads_disp_perms(uint32 type) +static void ads_disp_perms(uint32 type) { int i = 0; int j = 0; @@ -82,20 +82,8 @@ void ads_disp_perms(uint32 type) puts(""); } -/* Check if ACE has OBJECT type */ -BOOL ads_ace_object(uint8 type) -{ - if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || - type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT || - type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT || - type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) { - return True; - } - return False; -} - /* display ACE */ -void ads_disp_ace(SEC_ACE *sec_ace) +static void ads_disp_ace(SEC_ACE *sec_ace) { char *access_type = "UNKNOWN"; @@ -135,7 +123,7 @@ void ads_disp_ace(SEC_ACE *sec_ace) } /* display ACL */ -void ads_disp_acl(SEC_ACL *sec_acl, char *type) +static void ads_disp_acl(SEC_ACL *sec_acl, char *type) { if (!sec_acl) printf("------- (%s) ACL not present\n", type); -- cgit From 21b9280cf516045f3ffb7d5249087a127855a38d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 8 Jul 2002 02:14:57 +0000 Subject: Kill off const warnings - add a pile of const to various places. (This used to be commit 1de04ec4735c19ec21cdef6e679cea17c734c5f6) --- source3/libads/ldap_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index d0b6c2ca8c..b6e3d189c5 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -43,7 +43,7 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user, TALLOC_CTX *ctx; ADS_MODLIST mods; ADS_STATUS status; - char *upn, *new_dn, *name, *controlstr; + const char *upn, *new_dn, *name, *controlstr; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", NULL}; -- cgit From 83060558c98051fd96ed831e22e218497ba5dfd7 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 8 Jul 2002 20:46:54 +0000 Subject: Fix length in snprintf invocation to account for "dn:" in sasl gssapi bind. Also remove unused line which incremented pointer by the wrong length anyway. Provided by Anthony Liguori (aliguori@us.ibm.com). (This used to be commit 47b7a3e0f3d101a3bcffd33db6ef4c0672b57ae0) --- source3/libads/sasl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index eb29c71fce..1b55453cac 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -171,8 +171,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) *p++ = max_msg_size>>16; *p++ = max_msg_size>>8; *p++ = max_msg_size; - snprintf(p, strlen(ads->bind_path)+1, "dn:%s", ads->bind_path); - p += strlen(ads->bind_path); + snprintf(p, strlen(ads->bind_path)+4, "dn:%s", ads->bind_path); output_token.length = strlen(ads->bind_path) + 8; -- cgit From 5ae8fa2df1e4e9b40200869ed946f3c8b9e4f2b3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 9 Jul 2002 15:06:51 +0000 Subject: make sure we disable referrals in all ldap searches - they are badly broken (This used to be commit 022073d140bae960613127a6d9422e443a8098c6) --- source3/libads/ldap.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1045b05812..7e51c203ca 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -464,6 +464,9 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, timeout.tv_usec = 0; *res = NULL; + /* see the note in ads_do_paged_search - we *must* disable referrals */ + ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); + rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, search_attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); -- cgit From 8fb570e6e0c748a9e7bf3d4207302e8dfb6ae779 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 11 Jul 2002 03:41:09 +0000 Subject: this fixes the ads dump code a char** isn't quite the same thing as a struct berval** :) (This used to be commit a92834ea9460bc49be99d6d5b0d41a817e6f0824) --- source3/libads/ldap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7e51c203ca..c9ad3e08db 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -903,11 +903,11 @@ static void dump_sd(const char *filed, struct berval **values) /* dump a string result from ldap */ -static void dump_string(const char *field, struct berval **values) +static void dump_string(const char *field, char **values) { int i; for (i=0; values[i]; i++) { - printf("%s: %s\n", field, values[i]->bv_val); + printf("%s: %s\n", field, values[i]); } } @@ -946,7 +946,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) if (!handlers[i].name) { if (!values) /* first time, indicate string conversion */ return True; - dump_string(field, (struct berval **) values); + dump_string(field, (char **)values); } return False; } -- cgit From 5d827857560ecd23c0cd5179d73e1f14a7ed993a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 11 Jul 2002 05:28:08 +0000 Subject: this implements a completely new strategy for fetching group membership from an ADS server. We now use a 'member' query on the group and do a separate call to convert the resulting distinguished name to a name, rid etc. This is *much* faster for very large numbers of groups (on a quantum test system with 10000 groups it drops the time from an hour to about 35 seconds). strangely enough, this actually *increases* the amount of ldap traffic, its just that the MS LDAP server answers these queries much faster. (This used to be commit 5538048e4f6dd224b2990f3c6a3e99fd07065f77) --- source3/libads/ldap.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c9ad3e08db..0f41269e3a 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1293,6 +1293,41 @@ char *ads_pull_string(ADS_STRUCT *ads, return ret; } +/** + * pull an array of strings from a ADS result + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX to use for allocating result string + * @param msg Results of search + * @param field Attribute to retrieve + * @return Result strings in talloc context + **/ +char **ads_pull_strings(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, void *msg, const char *field) +{ + char **values; + char **ret = NULL; + int i, n; + + values = ldap_get_values(ads->ld, msg, field); + if (!values) return NULL; + + for (i=0;values[i];i++) /* noop */ ; + n = i; + + ret = talloc(mem_ctx, sizeof(char *) * (n+1)); + + for (i=0;i Date: Fri, 12 Jul 2002 02:28:27 +0000 Subject: fix setting machine passwords in the case where a user account of the same name as the machine name exists. (we ended up setting the users password, not the machines password!) (This used to be commit fe1e6233c6f0a5654bcc3ab34f65bb570efc69b1) --- source3/libads/ldap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libads') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0f41269e3a..9d15c4e33c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1231,7 +1231,11 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, strlower(host); - asprintf(&principal, "%s@%s", host, ads->realm); + /* + we need to use the '$' form of the name here, as otherwise the + server might end up setting the password for a user instead + */ + asprintf(&principal, "%s$@%s", host, ads->realm); status = krb5_set_password(ads->kdc_server, principal, password); -- cgit