From 6464bb0ae5d2cb774ccd5187f65a6ff83c051ed9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Nov 2001 08:54:15 +0000 Subject: added the beginnings of ADS support in smbd (This used to be commit c7f611691941ca92f57665e19d6e46b161599427) --- source3/libads/ldap.c | 324 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 source3/libads/ldap.c (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c new file mode 100644 index 0000000000..2853dbbaa3 --- /dev/null +++ b/source3/libads/ldap.c @@ -0,0 +1,324 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + ads (active directory) utility library + Copyright (C) Andrew Tridgell 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_ADS + +/* return a dn of the form "dc=AA,dc=BB,dc=CC" from a + realm of the form AA.BB.CC + caller must free +*/ +static char *ads_build_dn(const char *realm) +{ + char *p, *r; + int numdots = 0; + char *ret; + int len; + + r = strdup(realm); + + if (!r || !*r) return r; + + for (p=r; *p; p++) { + if (*p == '.') numdots++; + } + + len = (numdots+1)*4 + strlen(r) + 1; + +ret = malloc(len); + strlcpy(ret,"dc=", len); + p=strtok(r,"."); + strlcat(ret, p, len); + + while ((p=strtok(NULL,"."))) { + strlcat(ret,",dc=", len); + strlcat(ret, p, len); + } + + free(r); + + return ret; +} + +/* + return a string for an error from a ads routine +*/ +char *ads_errstr(int rc) +{ + return ldap_err2string(rc); +} + +/* + initialise a ADS_STRUCT, ready for some ads_ ops +*/ +ADS_STRUCT *ads_init(const char *realm, + const char *ldap_server, + const char *bind_path) +{ + ADS_STRUCT *ads; + + ads = (ADS_STRUCT *)xmalloc(sizeof(*ads)); + memset(ads, 0, sizeof(*ads)); + + ads->realm = realm? strdup(realm) : NULL; + ads->ldap_server = ldap_server? strdup(ldap_server) : NULL; + ads->bind_path = bind_path? strdup(bind_path) : NULL; + ads->ldap_port = LDAP_PORT; + + if (!ads->bind_path) { + ads->bind_path = ads_build_dn(ads->realm); + } + + return ads; +} + + +/* + this is a minimal interact function, just enough for SASL to talk + GSSAPI/kerberos to W2K +*/ +static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in) +{ + sasl_interact_t *interact = in; + + while (interact->id != SASL_CB_LIST_END) { + interact->result = strdup(""); + interact->len = 0; + interact++; + } + + return LDAP_SUCCESS; +} + +/* + connect to the LDAP server +*/ +int ads_connect(ADS_STRUCT *ads) +{ + int version = LDAP_VERSION3; + int rc; + + ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); + if (!ads->ld) { + return errno; + } + ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + + rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, 0, + sasl_interact, NULL); + + return rc; +} + + +/* + find a machine account given a hostname +*/ +int ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) +{ + int ret; + char *exp; + + /* the easiest way to find a machine account anywhere in the tree + is to look for hostname$ */ + asprintf(&exp, "(samAccountName=%s$)", host); + *res = NULL; + ret = ldap_search_s(ads->ld, ads->bind_path, + LDAP_SCOPE_SUBTREE, exp, NULL, 0, (LDAPMessage **)res); + free(exp); + return ret; +} + + +/* + a convenient routine for adding a generic LDAP record +*/ +int ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) +{ + int i; + va_list ap; + LDAPMod **mods; + char *name, *value; + int ret; +#define MAX_MOD_VALUES 10 + + /* count the number of attributes */ + va_start(ap, new_dn); + for (i=0; va_arg(ap, char *); i++) { + /* skip the values */ + while (va_arg(ap, char *)) ; + } + va_end(ap); + + mods = malloc(sizeof(LDAPMod *) * (i+1)); + + va_start(ap, new_dn); + for (i=0; (name=va_arg(ap, char *)); i++) { + char **values; + int j; + values = (char **)malloc(sizeof(char *) * (MAX_MOD_VALUES+1)); + for (j=0; (value=va_arg(ap, char *)) && j < MAX_MOD_VALUES; j++) { + values[j] = value; + } + values[j] = NULL; + mods[i] = malloc(sizeof(LDAPMod)); + mods[i]->mod_type = name; + mods[i]->mod_op = LDAP_MOD_ADD; + mods[i]->mod_values = values; + } + mods[i] = NULL; + va_end(ap); + + ret = ldap_add_s(ads->ld, new_dn, mods); + + for (i=0; mods[i]; i++) { + free(mods[i]->mod_values); + free(mods[i]); + } + free(mods); + + return ret; +} + +/* + add a machine account to the ADS server +*/ +static int ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname) +{ + int ret; + char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr; + + asprintf(&host_spn, "HOST/%s", hostname); + asprintf(&host_upn, "%s@%s", host_spn, ads->realm); + asprintf(&new_dn, "cn=%s,cn=Computers,%s", hostname, ads->bind_path); + asprintf(&samAccountName, "%s$", hostname); + asprintf(&controlstr, "%u", + UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT | + UF_TRUSTED_FOR_DELEGATION | UF_USE_DES_KEY_ONLY); + + ret = ads_gen_add(ads, new_dn, + "cn", hostname, NULL, + "sAMAccountName", samAccountName, NULL, + "objectClass", + "top", "person", "organizationalPerson", + "user", "computer", NULL, + "userPrincipalName", host_upn, NULL, + "servicePrincipalName", host_spn, NULL, + "dNSHostName", hostname, NULL, + "userAccountControl", controlstr, NULL, + "operatingSystem", "Samba", NULL, + "operatingSystemVersion", VERSION, NULL, + NULL); + + free(host_spn); + free(host_upn); + free(new_dn); + free(samAccountName); + free(controlstr); + + return ret; +} + +/* + dump a record from LDAP on stdout + used for debugging +*/ +void ads_dump(ADS_STRUCT *ads, void *res) +{ + char *field; + LDAPMessage *msg; + BerElement *b; + char *this_dn; + + for (msg = ldap_first_entry(ads->ld, (LDAPMessage *)res); + msg; msg = ldap_next_entry(ads->ld, msg)) { + this_dn = ldap_get_dn(ads->ld, (LDAPMessage *)res); + if (this_dn) { + printf("Dumping: %s\n", this_dn); + } + ldap_memfree(this_dn); + + for (field = ldap_first_attribute(ads->ld, msg, &b); + field; + field = ldap_next_attribute(ads->ld, msg, b)) { + char **values, **p; + values = ldap_get_values(ads->ld, msg, field); + for (p = values; *p; p++) { + printf("%s: %s\n", field, *p); + } + ldap_value_free(values); + ldap_memfree(field); + } + + ber_free(b, 1); + printf("\n"); + } +} + +/* + count how many replies are in a LDAPMessage +*/ +int ads_count_replies(ADS_STRUCT *ads, void *res) +{ + return ldap_count_entries(ads->ld, (LDAPMessage *)res); +} + +/* + join a machine to a realm, creating the machine account + and setting the machine password +*/ +int ads_join_realm(ADS_STRUCT *ads, const char *hostname) +{ + int rc; + LDAPMessage *res; + char *principal; + + rc = ads_find_machine_acct(ads, (void **)&res, hostname); + if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1) { + DEBUG(0, ("Host account for %s already exists\n", hostname)); + goto set_password; + } + + rc = ads_add_machine_acct(ads, hostname); + if (rc != LDAP_SUCCESS) { + DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(rc))); + return rc; + } + + rc = ads_find_machine_acct(ads, (void **)&res, hostname); + if (rc != LDAP_SUCCESS || ads_count_replies(ads, res) != 1) { + DEBUG(0, ("Host account test failed\n")); + /* hmmm, we need NTSTATUS */ + return -1; + } + +set_password: + asprintf(&principal, "HOST/%s@%s", hostname, ads->realm); +#if 0 + krb5_set_principal_password(principal, ads->ldap_server, hostname, ads->realm); +#endif + free(principal); + + return LDAP_SUCCESS; +} + +#endif -- cgit From ad2974cd05b4d08c8b92f505bf95aa8e8533235f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 24 Nov 2001 14:16:41 +0000 Subject: added "net join" command this completes the first stage of the smbd ADS support (This used to be commit 058a5aee901e6609969ef7e1d482a720a84a4a12) --- source3/libads/ldap.c | 103 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 91 insertions(+), 12 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2853dbbaa3..568e220c0b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -44,7 +44,7 @@ static char *ads_build_dn(const char *realm) len = (numdots+1)*4 + strlen(r) + 1; -ret = malloc(len); + ret = malloc(len); strlcpy(ret,"dc=", len); p=strtok(r,"."); strlcat(ret, p, len); @@ -67,6 +67,25 @@ char *ads_errstr(int rc) return ldap_err2string(rc); } +/* + find the ldap server from DNS + this won't work till we add a DNS packet parser. Talk about a + lousy resolv interface! +*/ +static char *find_ldap_server(ADS_STRUCT *ads) +{ + char *list = NULL; + + if (ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) { + char *p; + p = strchr(list, ':'); + if (p) *p = 0; + return list; + } + + return NULL; +} + /* initialise a ADS_STRUCT, ready for some ads_ ops */ @@ -76,7 +95,8 @@ ADS_STRUCT *ads_init(const char *realm, { ADS_STRUCT *ads; - ads = (ADS_STRUCT *)xmalloc(sizeof(*ads)); + ads = (ADS_STRUCT *)malloc(sizeof(*ads)); + if (!ads) return NULL; memset(ads, 0, sizeof(*ads)); ads->realm = realm? strdup(realm) : NULL; @@ -84,17 +104,42 @@ ADS_STRUCT *ads_init(const char *realm, ads->bind_path = bind_path? strdup(bind_path) : NULL; ads->ldap_port = LDAP_PORT; + if (!ads->realm) { + ads->realm = lp_realm(); + } if (!ads->bind_path) { ads->bind_path = ads_build_dn(ads->realm); } + if (!ads->ldap_server) { + ads->ldap_server = find_ldap_server(ads); + } + if (!ads->kdc_server) { + /* assume its the same as LDAP */ + ads->kdc_server = ads->ldap_server? strdup(ads->ldap_server) : NULL; + } return ads; } +/* + free the memory used by the ADS structure initialized with 'ads_init(...)' +*/ +void ads_destroy(ADS_STRUCT *ads) +{ + if (ads->ld) ldap_unbind(ads->ld); + SAFE_FREE(ads->realm); + SAFE_FREE(ads->ldap_server); + SAFE_FREE(ads->kdc_server); + SAFE_FREE(ads->bind_path); + ZERO_STRUCTP(ads); + free(ads); +} /* this is a minimal interact function, just enough for SASL to talk GSSAPI/kerberos to W2K + Error handling is a bit of a problem. I can't see how to get Cyrus-sasl + to give sensible errors */ static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in) { @@ -102,7 +147,7 @@ static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in) while (interact->id != SASL_CB_LIST_END) { interact->result = strdup(""); - interact->len = 0; + interact->len = strlen(interact->result); interact++; } @@ -123,7 +168,8 @@ int ads_connect(ADS_STRUCT *ads) } ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); - rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, 0, + rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, + LDAP_SASL_QUIET, sasl_interact, NULL); return rc; @@ -290,12 +336,11 @@ int ads_join_realm(ADS_STRUCT *ads, const char *hostname) { int rc; LDAPMessage *res; - char *principal; rc = ads_find_machine_acct(ads, (void **)&res, hostname); if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1) { DEBUG(0, ("Host account for %s already exists\n", hostname)); - goto set_password; + return LDAP_SUCCESS; } rc = ads_add_machine_acct(ads, hostname); @@ -311,14 +356,48 @@ int ads_join_realm(ADS_STRUCT *ads, const char *hostname) return -1; } -set_password: - asprintf(&principal, "HOST/%s@%s", hostname, ads->realm); -#if 0 - krb5_set_principal_password(principal, ads->ldap_server, hostname, ads->realm); -#endif - free(principal); + return LDAP_SUCCESS; +} +/* + delete a machine from the realm +*/ +int ads_leave_realm(ADS_STRUCT *ads, const char *hostname) +{ + int rc; + void *res; + char *hostnameDN; + + rc = ads_find_machine_acct(ads, &res, hostname); + if (rc != LDAP_SUCCESS || ads_count_replies(ads, res) != 1) { + DEBUG(0, ("Host account for %s does not exist.\n", hostname)); + return -1; + } + + hostnameDN = ldap_get_dn(ads->ld, (LDAPMessage *)res); + rc = ldap_delete_s(ads->ld, hostnameDN); + ldap_memfree(hostnameDN); + if (rc != LDAP_SUCCESS) { + DEBUG(0, ("ldap_delete_s: %s\n", ads_errstr(rc))); + return rc; + } + + rc = ads_find_machine_acct(ads, &res, hostname); + if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1 ) { + DEBUG(0, ("Failed to remove host account.\n")); + /*hmmm, we need NTSTATUS */ + return -1; + } + return LDAP_SUCCESS; } + +NTSTATUS ads_set_machine_password(ADS_STRUCT *ads, + const char *hostname, + const char *password) +{ + return krb5_set_password(ads->kdc_server, hostname, ads->realm, password); +} + #endif -- cgit From f2e969268d965338338be09d261bde31c5c2ff8b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 25 Nov 2001 00:08:48 +0000 Subject: better auto-selection of realm and ldap server (This used to be commit 69d256af4612f5c1277202eb8a7ef37eb6bb55f4) --- source3/libads/ldap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 568e220c0b..c3d80a09ec 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -69,8 +69,6 @@ char *ads_errstr(int rc) /* find the ldap server from DNS - this won't work till we add a DNS packet parser. Talk about a - lousy resolv interface! */ static char *find_ldap_server(ADS_STRUCT *ads) { @@ -111,7 +109,10 @@ ADS_STRUCT *ads_init(const char *realm, ads->bind_path = ads_build_dn(ads->realm); } if (!ads->ldap_server) { - ads->ldap_server = find_ldap_server(ads); + ads->ldap_server = lp_ads_server(); + if (!ads->ldap_server[0]) { + ads->ldap_server = find_ldap_server(ads); + } } if (!ads->kdc_server) { /* assume its the same as LDAP */ -- cgit From 3906f9dff6f83e0075ae3d08709a35a629e97fa7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 25 Nov 2001 01:06:56 +0000 Subject: added "net ads status" command (This used to be commit ae0eabd04c97320c2cf3c4575263c53cf61d03ea) --- source3/libads/ldap.c | 91 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 76 insertions(+), 15 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c3d80a09ec..812c44e7d7 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -285,6 +285,32 @@ static int ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname) return ret; } +/* + dump a binary result from ldap +*/ +static void dump_binary(const char *field, struct berval **values) +{ + int i, j; + for (i=0; values[i]; i++) { + printf("%s: ", field); + for (j=0; jbv_len; j++) { + printf("%02X", (unsigned char)values[i]->bv_val[j]); + } + printf("\n"); + } +} + +/* + dump a string result from ldap +*/ +static void dump_string(const char *field, struct berval **values) +{ + int i; + for (i=0; values[i]; i++) { + printf("%s: %s\n", field, values[i]->bv_val); + } +} + /* dump a record from LDAP on stdout used for debugging @@ -295,6 +321,14 @@ void ads_dump(ADS_STRUCT *ads, void *res) LDAPMessage *msg; BerElement *b; char *this_dn; + struct { + char *name; + void (*handler)(const char *, struct berval **); + } handlers[] = { + {"objectGUID", dump_binary}, + {"objectSid", dump_binary}, + {NULL, NULL} + }; for (msg = ldap_first_entry(ads->ld, (LDAPMessage *)res); msg; msg = ldap_next_entry(ads->ld, msg)) { @@ -307,12 +341,21 @@ void ads_dump(ADS_STRUCT *ads, void *res) for (field = ldap_first_attribute(ads->ld, msg, &b); field; field = ldap_next_attribute(ads->ld, msg, b)) { - char **values, **p; - values = ldap_get_values(ads->ld, msg, field); - for (p = values; *p; p++) { - printf("%s: %s\n", field, *p); + struct berval **values; + int i; + + values = ldap_get_values_len(ads->ld, msg, field); + + for (i=0; handlers[i].name; i++) { + if (StrCaseCmp(handlers[i].name, field) == 0) { + handlers[i].handler(field, values); + break; + } + } + if (!handlers[i].name) { + dump_string(field, values); } - ldap_value_free(values); + ldap_value_free_len(values); ldap_memfree(field); } @@ -337,26 +380,33 @@ int ads_join_realm(ADS_STRUCT *ads, const char *hostname) { int rc; LDAPMessage *res; + char *host; + + /* hostname must be lowercase */ + host = strdup(hostname); + strlower(host); - rc = ads_find_machine_acct(ads, (void **)&res, hostname); + rc = ads_find_machine_acct(ads, (void **)&res, host); if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1) { - DEBUG(0, ("Host account for %s already exists\n", hostname)); + DEBUG(0, ("Host account for %s already exists\n", host)); return LDAP_SUCCESS; } - rc = ads_add_machine_acct(ads, hostname); + rc = ads_add_machine_acct(ads, host); if (rc != LDAP_SUCCESS) { DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(rc))); return rc; } - rc = ads_find_machine_acct(ads, (void **)&res, hostname); + rc = ads_find_machine_acct(ads, (void **)&res, host); if (rc != LDAP_SUCCESS || ads_count_replies(ads, res) != 1) { DEBUG(0, ("Host account test failed\n")); /* hmmm, we need NTSTATUS */ return -1; } + free(host); + return LDAP_SUCCESS; } @@ -367,11 +417,15 @@ int ads_leave_realm(ADS_STRUCT *ads, const char *hostname) { int rc; void *res; - char *hostnameDN; + char *hostnameDN, *host; + + /* hostname must be lowercase */ + host = strdup(hostname); + strlower(host); - rc = ads_find_machine_acct(ads, &res, hostname); + rc = ads_find_machine_acct(ads, &res, host); if (rc != LDAP_SUCCESS || ads_count_replies(ads, res) != 1) { - DEBUG(0, ("Host account for %s does not exist.\n", hostname)); + DEBUG(0, ("Host account for %s does not exist.\n", host)); return -1; } @@ -383,13 +437,15 @@ int ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return rc; } - rc = ads_find_machine_acct(ads, &res, hostname); + rc = ads_find_machine_acct(ads, &res, host); if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1 ) { DEBUG(0, ("Failed to remove host account.\n")); /*hmmm, we need NTSTATUS */ return -1; } - + + free(host); + return LDAP_SUCCESS; } @@ -398,7 +454,12 @@ NTSTATUS ads_set_machine_password(ADS_STRUCT *ads, const char *hostname, const char *password) { - return krb5_set_password(ads->kdc_server, hostname, ads->realm, password); + NTSTATUS ret; + char *host = strdup(hostname); + strlower(host); + ret = krb5_set_password(ads->kdc_server, host, ads->realm, password); + free(host); + return ret; } #endif -- cgit From cb697dd72a51daa14f174fae4fede2b86e7a7fd2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 25 Nov 2001 01:31:07 +0000 Subject: added "net ads user" and "net ads group" commands (This used to be commit f482583139eedb75a23c7a720dca4e8fb7070fd5) --- source3/libads/ldap.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 812c44e7d7..604a11aa5b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -177,6 +177,19 @@ int ads_connect(ADS_STRUCT *ads) } +/* + do a general ADS search +*/ +int ads_search(ADS_STRUCT *ads, void **res, + const char *exp, + const char **attrs) +{ + *res = NULL; + return ldap_search_s(ads->ld, ads->bind_path, + LDAP_SCOPE_SUBTREE, exp, (char **)attrs, 0, (LDAPMessage **)res); +} + + /* find a machine account given a hostname */ @@ -188,9 +201,7 @@ int ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) /* the easiest way to find a machine account anywhere in the tree is to look for hostname$ */ asprintf(&exp, "(samAccountName=%s$)", host); - *res = NULL; - ret = ldap_search_s(ads->ld, ads->bind_path, - LDAP_SCOPE_SUBTREE, exp, NULL, 0, (LDAPMessage **)res); + ret = ads_search(ads, res, exp, NULL); free(exp); return ret; } @@ -320,7 +331,6 @@ void ads_dump(ADS_STRUCT *ads, void *res) char *field; LDAPMessage *msg; BerElement *b; - char *this_dn; struct { char *name; void (*handler)(const char *, struct berval **); @@ -332,12 +342,6 @@ void ads_dump(ADS_STRUCT *ads, void *res) for (msg = ldap_first_entry(ads->ld, (LDAPMessage *)res); msg; msg = ldap_next_entry(ads->ld, msg)) { - this_dn = ldap_get_dn(ads->ld, (LDAPMessage *)res); - if (this_dn) { - printf("Dumping: %s\n", this_dn); - } - ldap_memfree(this_dn); - for (field = ldap_first_attribute(ads->ld, msg, &b); field; field = ldap_next_attribute(ads->ld, msg, b)) { -- cgit From eec9e8a052407611df223fec982588e7a2bd7f49 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 Nov 2001 03:56:30 +0000 Subject: fix a bunch of places where we can double-free a cli structure (This used to be commit e2ba2383c9f679c076749a8f4fccefc3559e37ec) --- source3/libads/ldap.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 604a11aa5b..49e803a49d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -270,7 +270,7 @@ static int ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname) asprintf(&new_dn, "cn=%s,cn=Computers,%s", hostname, ads->bind_path); asprintf(&samAccountName, "%s$", hostname); asprintf(&controlstr, "%u", - UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT | + UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT | UF_TRUSTED_FOR_DELEGATION | UF_USE_DES_KEY_ONLY); ret = ads_gen_add(ads, new_dn, @@ -466,4 +466,17 @@ NTSTATUS ads_set_machine_password(ADS_STRUCT *ads, return ret; } +/* find the update serial number - this is the core of the ldap cache */ +BOOL ads_USN(ADS_STRUCT *ads, unsigned *usn) +{ + const char *attrs[] = {"highestCommittedUSN", NULL}; + int rc; + void *res; + + rc = ldap_search_s(ads->ld, ads->bind_path, + LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage *)&res); + if (rc || ads_count_replies(ads, res) != 1) return False; + return False; +} + #endif -- cgit From fe64484824d8169bf66822ebf7f6a9180a238e6e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 29 Nov 2001 06:21:56 +0000 Subject: Make better use of the ads_init() function to get the kerberos relam etc. This allows us to use automagically obtained values in future, and the value from krb5.conf now. Also fix mem leaks etc. Andrew Bartlett (This used to be commit 8f9ce717819235d98a1463f20ac659cb4b4ebbd2) --- source3/libads/ldap.c | 103 +------------------------------------------------- 1 file changed, 1 insertion(+), 102 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 49e803a49d..3e24273dc7 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -27,38 +27,6 @@ realm of the form AA.BB.CC caller must free */ -static char *ads_build_dn(const char *realm) -{ - char *p, *r; - int numdots = 0; - char *ret; - int len; - - r = strdup(realm); - - if (!r || !*r) return r; - - for (p=r; *p; p++) { - if (*p == '.') numdots++; - } - - len = (numdots+1)*4 + strlen(r) + 1; - - ret = malloc(len); - strlcpy(ret,"dc=", len); - p=strtok(r,"."); - strlcat(ret, p, len); - - while ((p=strtok(NULL,"."))) { - strlcat(ret,",dc=", len); - strlcat(ret, p, len); - } - - free(r); - - return ret; -} - /* return a string for an error from a ads routine */ @@ -67,75 +35,6 @@ char *ads_errstr(int rc) return ldap_err2string(rc); } -/* - find the ldap server from DNS -*/ -static char *find_ldap_server(ADS_STRUCT *ads) -{ - char *list = NULL; - - if (ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) { - char *p; - p = strchr(list, ':'); - if (p) *p = 0; - return list; - } - - return NULL; -} - -/* - initialise a ADS_STRUCT, ready for some ads_ ops -*/ -ADS_STRUCT *ads_init(const char *realm, - const char *ldap_server, - const char *bind_path) -{ - ADS_STRUCT *ads; - - ads = (ADS_STRUCT *)malloc(sizeof(*ads)); - if (!ads) return NULL; - memset(ads, 0, sizeof(*ads)); - - ads->realm = realm? strdup(realm) : NULL; - ads->ldap_server = ldap_server? strdup(ldap_server) : NULL; - ads->bind_path = bind_path? strdup(bind_path) : NULL; - ads->ldap_port = LDAP_PORT; - - if (!ads->realm) { - ads->realm = lp_realm(); - } - if (!ads->bind_path) { - ads->bind_path = ads_build_dn(ads->realm); - } - if (!ads->ldap_server) { - ads->ldap_server = lp_ads_server(); - if (!ads->ldap_server[0]) { - ads->ldap_server = find_ldap_server(ads); - } - } - if (!ads->kdc_server) { - /* assume its the same as LDAP */ - ads->kdc_server = ads->ldap_server? strdup(ads->ldap_server) : NULL; - } - - return ads; -} - -/* - free the memory used by the ADS structure initialized with 'ads_init(...)' -*/ -void ads_destroy(ADS_STRUCT *ads) -{ - if (ads->ld) ldap_unbind(ads->ld); - SAFE_FREE(ads->realm); - SAFE_FREE(ads->ldap_server); - SAFE_FREE(ads->kdc_server); - SAFE_FREE(ads->bind_path); - ZERO_STRUCTP(ads); - free(ads); -} - /* this is a minimal interact function, just enough for SASL to talk GSSAPI/kerberos to W2K @@ -474,7 +373,7 @@ BOOL ads_USN(ADS_STRUCT *ads, unsigned *usn) void *res; rc = ldap_search_s(ads->ld, ads->bind_path, - LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage *)&res); + LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage **)&res); if (rc || ads_count_replies(ads, res) != 1) return False; return False; } -- cgit From 2285b99cb1047ea85589ef23d4ca73278a15ee08 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Dec 2001 06:04:18 +0000 Subject: added a basic ADS backend to winbind. More work needed, but at least basic operations work (This used to be commit 88241cab983b2c7db7d477c6c4654694a7a56cd3) --- source3/libads/ldap.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 80 insertions(+), 8 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 3e24273dc7..61d805ab86 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -228,7 +228,7 @@ static void dump_string(const char *field, struct berval **values) void ads_dump(ADS_STRUCT *ads, void *res) { char *field; - LDAPMessage *msg; + void *msg; BerElement *b; struct { char *name; @@ -239,15 +239,14 @@ void ads_dump(ADS_STRUCT *ads, void *res) {NULL, NULL} }; - for (msg = ldap_first_entry(ads->ld, (LDAPMessage *)res); - msg; msg = ldap_next_entry(ads->ld, msg)) { - for (field = ldap_first_attribute(ads->ld, msg, &b); + for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { + for (field = ldap_first_attribute(ads->ld, (LDAPMessage *)msg, &b); field; - field = ldap_next_attribute(ads->ld, msg, b)) { + field = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, b)) { struct berval **values; int i; - values = ldap_get_values_len(ads->ld, msg, field); + values = ldap_get_values_len(ads->ld, (LDAPMessage *)msg, field); for (i=0; handlers[i].name; i++) { if (StrCaseCmp(handlers[i].name, field) == 0) { @@ -365,8 +364,79 @@ NTSTATUS ads_set_machine_password(ADS_STRUCT *ads, return ret; } +/* + pull the first entry from a ADS result +*/ +void *ads_first_entry(ADS_STRUCT *ads, void *res) +{ + return (void *)ldap_first_entry(ads->ld, (LDAPMessage *)res); +} + +/* + pull the next entry from a ADS result +*/ +void *ads_next_entry(ADS_STRUCT *ads, void *res) +{ + return (void *)ldap_next_entry(ads->ld, (LDAPMessage *)res); +} + +/* + pull a single string from a ADS result +*/ +char *ads_pull_string(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, void *msg, const char *field) +{ + char **values; + char *ret; + + values = ldap_get_values(ads->ld, msg, field); + + if (!values || !values[0]) return NULL; + + ret = talloc_strdup(mem_ctx, values[0]); + ldap_value_free(values); + return ret; +} + +/* + pull a single uint32 from a ADS result +*/ +BOOL ads_pull_uint32(ADS_STRUCT *ads, + void *msg, const char *field, uint32 *v) +{ + char **values; + + values = ldap_get_values(ads->ld, msg, field); + + if (!values || !values[0]) return False; + + *v = atoi(values[0]); + ldap_value_free(values); + return True; +} + +/* + pull a single DOM_SID from a ADS result +*/ +BOOL ads_pull_sid(ADS_STRUCT *ads, + void *msg, const char *field, DOM_SID *sid) +{ + struct berval **values; + BOOL ret; + + values = ldap_get_values_len(ads->ld, msg, field); + + if (!values || !values[0]) return False; + + ret = sid_parse(values[0]->bv_val, values[0]->bv_len, sid); + + ldap_value_free_len(values); + return ret; +} + + /* find the update serial number - this is the core of the ldap cache */ -BOOL ads_USN(ADS_STRUCT *ads, unsigned *usn) +BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn) { const char *attrs[] = {"highestCommittedUSN", NULL}; int rc; @@ -375,7 +445,9 @@ BOOL ads_USN(ADS_STRUCT *ads, unsigned *usn) rc = ldap_search_s(ads->ld, ads->bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage **)&res); if (rc || ads_count_replies(ads, res) != 1) return False; - return False; + return ads_pull_uint32(ads, res, "highestCommittedUSN", usn); } + + #endif -- cgit From 3ec4a4def3f3a98606ad09ca9feaf366bae7fcb2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Dec 2001 12:08:16 +0000 Subject: added ads_search_dn() and ads_pull_sids() (This used to be commit bc83d55f4400cdcdfed44622954f11580b6d2f87) --- source3/libads/ldap.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 61d805ab86..50583146c0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -88,6 +88,18 @@ int ads_search(ADS_STRUCT *ads, void **res, LDAP_SCOPE_SUBTREE, exp, (char **)attrs, 0, (LDAPMessage **)res); } +/* + do a search on a specific DistinguishedName +*/ +int ads_search_dn(ADS_STRUCT *ads, void **res, + const char *dn, + const char **attrs) +{ + *res = NULL; + return ldap_search_s(ads->ld, dn, + LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage **)res); +} + /* find a machine account given a hostname @@ -434,6 +446,35 @@ BOOL ads_pull_sid(ADS_STRUCT *ads, return ret; } +/* + pull an array of DOM_SIDs from a ADS result + return the count of SIDs pulled +*/ +int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + void *msg, const char *field, DOM_SID **sids) +{ + struct berval **values; + BOOL ret; + int count, i; + + values = ldap_get_values_len(ads->ld, msg, field); + + if (!values) return 0; + + for (i=0; values[i]; i++) /* nop */ ; + + (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * i); + + count = 0; + for (i=0; values[i]; i++) { + ret = sid_parse(values[i]->bv_val, values[i]->bv_len, &(*sids)[count]); + if (ret) count++; + } + + ldap_value_free_len(values); + return count; +} + /* find the update serial number - this is the core of the ldap cache */ BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn) @@ -443,7 +484,7 @@ BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn) void *res; rc = ldap_search_s(ads->ld, ads->bind_path, - LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage **)&res); + LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, (LDAPMessage **)&res); if (rc || ads_count_replies(ads, res) != 1) return False; return ads_pull_uint32(ads, res, "highestCommittedUSN", usn); } -- cgit From 19c0459153bd6f0ea56b84f78725a77bb70be138 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 04:44:34 +0000 Subject: added functions that convert a ads binary blob to a string (for searching on SID) (This used to be commit 31d6d049b30e364e062f108d6f9221bbdc2ebec5) --- source3/libads/ldap.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 50583146c0..34ca2ad04d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -376,6 +376,45 @@ NTSTATUS ads_set_machine_password(ADS_STRUCT *ads, return ret; } + +/* + return a RFC2254 binary string representation of a buffer + used in filters + caller must free +*/ +char *ads_binary_string(char *buf, int len) +{ + char *s; + int i, j; + const char *hex = "0123456789ABCDEF"; + s = malloc(len * 3 + 1); + if (!s) return NULL; + for (j=i=0;i> 4]; + s[j+2] = hex[((unsigned char)buf[i]) & 0xF]; + j += 3; + } + s[j] = 0; + return s; +} + +/* + return the binary string representation of a DOM_SID + caller must free +*/ +char *ads_sid_binstring(DOM_SID *sid) +{ + char *buf, *s; + int len = sid_size(sid); + buf = malloc(len); + if (!buf) return NULL; + sid_linearize(buf, len, sid); + s = ads_binary_string(buf, len); + free(buf); + return s; +} + /* pull the first entry from a ADS result */ -- cgit From 5f76385e709204151fb9c743ae9d36e0b3df48de Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 06:26:56 +0000 Subject: more memory leak fixes (This used to be commit eb6f0e91ddd2a97a907a569bc60beca99b494884) --- source3/libads/ldap.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 34ca2ad04d..251a4a6958 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -100,6 +100,14 @@ int ads_search_dn(ADS_STRUCT *ads, void **res, LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage **)res); } +/* + free up memory from a ads_search +*/ +void ads_msgfree(ADS_STRUCT *ads, void *msg) +{ + if (!msg) return; + ldap_msgfree(msg); +} /* find a machine account given a hostname -- cgit From 0799c446809a7ae239864e69995849431cd2cb00 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 07:35:57 +0000 Subject: paranoia fixes in based ldap routines for potential memory leaks (This used to be commit 13b933104e1389608e4831ca47dd8106ea0c60a5) --- source3/libads/ldap.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 251a4a6958..5b391f1282 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -446,13 +446,14 @@ char *ads_pull_string(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg, const char *field) { char **values; - char *ret; + char *ret = NULL; values = ldap_get_values(ads->ld, msg, field); - - if (!values || !values[0]) return NULL; - - ret = talloc_strdup(mem_ctx, values[0]); + if (!values) return NULL; + + if (values[0]) { + ret = talloc_strdup(mem_ctx, values[0]); + } ldap_value_free(values); return ret; } @@ -466,8 +467,11 @@ BOOL ads_pull_uint32(ADS_STRUCT *ads, char **values; values = ldap_get_values(ads->ld, msg, field); - - if (!values || !values[0]) return False; + if (!values) return False; + if (!values[0]) { + ldap_value_free(values); + return False; + } *v = atoi(values[0]); ldap_value_free(values); @@ -481,13 +485,15 @@ BOOL ads_pull_sid(ADS_STRUCT *ads, void *msg, const char *field, DOM_SID *sid) { struct berval **values; - BOOL ret; + BOOL ret = False; values = ldap_get_values_len(ads->ld, msg, field); - if (!values || !values[0]) return False; + if (!values) return False; - ret = sid_parse(values[0]->bv_val, values[0]->bv_len, sid); + if (values[0]) { + ret = sid_parse(values[0]->bv_val, values[0]->bv_len, sid); + } ldap_value_free_len(values); return ret; -- cgit From addea9645d48bc77f88ed3fa724cdd522e2f31ce Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 07:52:44 +0000 Subject: moved the sequence number fetch into the backend, and fetch the sequence number via ldap when using ads (This used to be commit 9a084f0bb91883224ad44e2b76417d10c15cce42) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 5b391f1282..b18e7927ae 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -536,7 +536,7 @@ BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn) int rc; void *res; - rc = ldap_search_s(ads->ld, ads->bind_path, + rc = ldap_search_s(ads->ld, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, (LDAPMessage **)&res); if (rc || ads_count_replies(ads, res) != 1) return False; return ads_pull_uint32(ads, res, "highestCommittedUSN", usn); -- cgit From 5d41807f4d6b80dd1c51ce2764521a2a38c88936 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 09:19:25 +0000 Subject: added timeouts and retries to ldap operations (This used to be commit 4f004eb54d66b6f811cb2f4791da6c70d77f87c2) --- source3/libads/ldap.c | 62 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 9 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b18e7927ae..14fd716058 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -62,6 +62,8 @@ int ads_connect(ADS_STRUCT *ads) int version = LDAP_VERSION3; int rc; + ads->last_attempt = time(NULL); + ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); if (!ads->ld) { return errno; @@ -75,6 +77,50 @@ int ads_connect(ADS_STRUCT *ads) return rc; } +/* + a wrapper around ldap_search_s that retries depending on the error code + this is supposed to catch dropped connections and auto-reconnect +*/ +int ads_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, + const char **attrs, void **res) +{ + struct timeval timeout; + int rc = -1, rc2; + int count = 3; + + if (!ads->ld && + time(NULL) - ads->last_attempt < ADS_RECONNECT_TIME) { + return LDAP_SERVER_DOWN; + } + + while (count--) { + *res = NULL; + timeout.tv_sec = ADS_SEARCH_TIMEOUT; + timeout.tv_usec = 0; + if (ads->ld) { + rc = ldap_search_ext_s(ads->ld, bind_path, scope, exp, attrs, 0, NULL, NULL, + &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); + if (rc == 0) return rc; + } + + if (*res) ads_msgfree(ads, *res); + *res = NULL; + DEBUG(1,("Reopening ads connection after error %s\n", ads_errstr(rc))); + if (ads->ld) { + /* we should unbind here, but that seems to trigger openldap bugs :( + ldap_unbind(ads->ld); + */ + } + ads->ld = NULL; + rc2 = ads_connect(ads); + if (rc2) { + DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n", ads_errstr(rc))); + return rc2; + } + } + DEBUG(1,("ads reopen failed after error %s\n", ads_errstr(rc))); + return rc; +} /* do a general ADS search @@ -83,9 +129,7 @@ int ads_search(ADS_STRUCT *ads, void **res, const char *exp, const char **attrs) { - *res = NULL; - return ldap_search_s(ads->ld, ads->bind_path, - LDAP_SCOPE_SUBTREE, exp, (char **)attrs, 0, (LDAPMessage **)res); + return ads_search_retry(ads, ads->bind_path, LDAP_SCOPE_SUBTREE, exp, attrs, res); } /* @@ -95,9 +139,7 @@ int ads_search_dn(ADS_STRUCT *ads, void **res, const char *dn, const char **attrs) { - *res = NULL; - return ldap_search_s(ads->ld, dn, - LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage **)res); + return ads_search_retry(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res); } /* @@ -535,11 +577,13 @@ BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn) const char *attrs[] = {"highestCommittedUSN", NULL}; int rc; void *res; + BOOL ret; - rc = ldap_search_s(ads->ld, "", - LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, (LDAPMessage **)&res); + rc = ads_search_retry(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (rc || ads_count_replies(ads, res) != 1) return False; - return ads_pull_uint32(ads, res, "highestCommittedUSN", usn); + ret = ads_pull_uint32(ads, res, "highestCommittedUSN", usn); + ads_msgfree(ads, res); + return ret; } -- cgit From 9421ad4a7a900b219f87754bc20fa14f2f22fd35 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 09:46:53 +0000 Subject: added a REALLY gross hack into kerberos_kinit_password so that winbindd can do a kinit this will be removed once we have code that gets a tgt and puts it in a place where cyrus-sasl can see it (This used to be commit 7d94f1b7365215a020d3678d03d820a7d086174f) --- source3/libads/ldap.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 14fd716058..287ea225a1 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -70,6 +70,10 @@ int ads_connect(ADS_STRUCT *ads) } ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + if (ads->password) { + kerberos_kinit_password(ads); + } + rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, LDAP_SASL_QUIET, sasl_interact, NULL); -- cgit From 8aa0a817c1c34b840eb68344a062cdbd95a06a68 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 10:14:22 +0000 Subject: handle ldap server down better (This used to be commit 0d85815c992c6ca77ba64dfb2d7538be4684654d) --- source3/libads/ldap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 287ea225a1..bfa5bbd9df 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -66,11 +66,13 @@ int ads_connect(ADS_STRUCT *ads) ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); if (!ads->ld) { - return errno; + return LDAP_SERVER_DOWN; } ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); if (ads->password) { + /* the machine acct password might have changed */ + ads->password = secrets_fetch_machine_password(); kerberos_kinit_password(ads); } -- cgit From 410dfc917f3471aec65c43f5ba421062f64496f4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 10:44:30 +0000 Subject: fixed a minor password memory leak (This used to be commit 5985d7e6eec1eb80d8d7470ee2ceda8981c7410c) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index bfa5bbd9df..60f620d2f4 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -72,6 +72,7 @@ int ads_connect(ADS_STRUCT *ads) if (ads->password) { /* the machine acct password might have changed */ + free(ads->password); ads->password = secrets_fetch_machine_password(); kerberos_kinit_password(ads); } -- cgit From d412f66cd82d8b14c8bd8d97f0235296bc8b2d23 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Dec 2001 05:41:53 +0000 Subject: added a propoer kerberos_kinit_password call contribution from remus@snapserver.com thanks! (This used to be commit 3ace8f1fcc27492d26f5ad0c3cdfc63235ca0609) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 60f620d2f4..a7c9265b18 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -74,7 +74,7 @@ int ads_connect(ADS_STRUCT *ads) /* the machine acct password might have changed */ free(ads->password); ads->password = secrets_fetch_machine_password(); - kerberos_kinit_password(ads); + ads_kinit_password(ads); } rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, -- cgit From 5d378a280f74405fccbadbfb28e1066613c76fd8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 8 Dec 2001 11:18:56 +0000 Subject: added internal sasl/gssapi code. This means we are no longer dependent on cyrus-sasl which makes the code much less fragile. Also added code to auto-determine the server name or realm (This used to be commit 435fdf276a79c2a517adcd7726933aeef3fa924b) --- source3/libads/ldap.c | 138 ++++++++++++++++++++++++++------------------------ 1 file changed, 71 insertions(+), 67 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a7c9265b18..b716966c1b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -35,25 +35,6 @@ char *ads_errstr(int rc) return ldap_err2string(rc); } -/* - this is a minimal interact function, just enough for SASL to talk - GSSAPI/kerberos to W2K - Error handling is a bit of a problem. I can't see how to get Cyrus-sasl - to give sensible errors -*/ -static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in) -{ - sasl_interact_t *interact = in; - - while (interact->id != SASL_CB_LIST_END) { - interact->result = strdup(""); - interact->len = strlen(interact->result); - interact++; - } - - return LDAP_SUCCESS; -} - /* connect to the LDAP server */ @@ -68,67 +49,38 @@ int ads_connect(ADS_STRUCT *ads) if (!ads->ld) { return LDAP_SERVER_DOWN; } + if (!ads_server_info(ads)) { + DEBUG(1,("Failed to get ldap server info\n")); + return LDAP_SERVER_DOWN; + } + ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); if (ads->password) { - /* the machine acct password might have changed */ - free(ads->password); - ads->password = secrets_fetch_machine_password(); ads_kinit_password(ads); } - rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, - LDAP_SASL_QUIET, - sasl_interact, NULL); - + rc = ads_sasl_bind(ads); return rc; } /* - a wrapper around ldap_search_s that retries depending on the error code - this is supposed to catch dropped connections and auto-reconnect + do a search with a timeout */ -int ads_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, - const char **attrs, void **res) +int ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, + const char **attrs, void **res) { struct timeval timeout; - int rc = -1, rc2; - int count = 3; - - if (!ads->ld && - time(NULL) - ads->last_attempt < ADS_RECONNECT_TIME) { - return LDAP_SERVER_DOWN; - } - while (count--) { - *res = NULL; - timeout.tv_sec = ADS_SEARCH_TIMEOUT; - timeout.tv_usec = 0; - if (ads->ld) { - rc = ldap_search_ext_s(ads->ld, bind_path, scope, exp, attrs, 0, NULL, NULL, - &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); - if (rc == 0) return rc; - } + timeout.tv_sec = ADS_SEARCH_TIMEOUT; + timeout.tv_usec = 0; + *res = NULL; - if (*res) ads_msgfree(ads, *res); - *res = NULL; - DEBUG(1,("Reopening ads connection after error %s\n", ads_errstr(rc))); - if (ads->ld) { - /* we should unbind here, but that seems to trigger openldap bugs :( - ldap_unbind(ads->ld); - */ - } - ads->ld = NULL; - rc2 = ads_connect(ads); - if (rc2) { - DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n", ads_errstr(rc))); - return rc2; - } - } - DEBUG(1,("ads reopen failed after error %s\n", ads_errstr(rc))); - return rc; + return ldap_search_ext_s(ads->ld, + bind_path, scope, + exp, attrs, 0, NULL, NULL, + &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); } - /* do a general ADS search */ @@ -136,7 +88,8 @@ int ads_search(ADS_STRUCT *ads, void **res, const char *exp, const char **attrs) { - return ads_search_retry(ads, ads->bind_path, LDAP_SCOPE_SUBTREE, exp, attrs, res); + return ads_do_search(ads, ads->bind_path, LDAP_SCOPE_SUBTREE, + exp, attrs, res); } /* @@ -146,7 +99,7 @@ int ads_search_dn(ADS_STRUCT *ads, void **res, const char *dn, const char **attrs) { - return ads_search_retry(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res); + return ads_do_search(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res); } /* @@ -586,7 +539,7 @@ BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn) void *res; BOOL ret; - rc = ads_search_retry(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + rc = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (rc || ads_count_replies(ads, res) != 1) return False; ret = ads_pull_uint32(ads, res, "highestCommittedUSN", usn); ads_msgfree(ads, res); @@ -594,5 +547,56 @@ BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn) } +/* find the servers name and realm - this can be done before authentication + The ldapServiceName field on w2k looks like this: + vnet3.home.samba.org:win2000-vnet3$@VNET3.HOME.SAMBA.ORG +*/ +BOOL ads_server_info(ADS_STRUCT *ads) +{ + const char *attrs[] = {"ldapServiceName", NULL}; + int rc; + void *res; + char **values; + char *ret, *p; + + rc = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (rc || ads_count_replies(ads, res) != 1) return False; + + values = ldap_get_values(ads->ld, res, "ldapServiceName"); + + if (!values || !values[0]) return False; + + p = strchr(values[0], ':'); + if (!p) { + ldap_value_free(values); + ldap_msgfree(res); + return False; + } + + SAFE_FREE(ads->ldap_server_name); + + ads->ldap_server_name = strdup(p+1); + p = strchr(ads->ldap_server_name, '$'); + if (!p || p[1] != '@') { + ldap_value_free(values); + ldap_msgfree(res); + SAFE_FREE(ads->ldap_server_name); + return False; + } + + *p = 0; + + /* in case the realm isn't configured in smb.conf */ + if (!ads->realm || !ads->realm[0]) { + SAFE_FREE(ads->realm); + SAFE_FREE(ads->bind_path); + ads->realm = strdup(p+2); + ads->bind_path = ads_build_dn(ads->realm); + } + + DEBUG(3,("got ldap server name %s@%s\n", ret, ads->realm)); + + return True; +} #endif -- cgit From 35eb6be4ea1b52e2f6028c979ead952a2f96f99d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 8 Dec 2001 12:00:27 +0000 Subject: fix a DEBUG() line (This used to be commit 18da530293b11d895c62d08895ee1f77d8f97a12) --- source3/libads/ldap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b716966c1b..c81f2474ae 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -557,7 +557,7 @@ BOOL ads_server_info(ADS_STRUCT *ads) int rc; void *res; char **values; - char *ret, *p; + char *p; rc = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (rc || ads_count_replies(ads, res) != 1) return False; @@ -594,7 +594,8 @@ BOOL ads_server_info(ADS_STRUCT *ads) ads->bind_path = ads_build_dn(ads->realm); } - DEBUG(3,("got ldap server name %s@%s\n", ret, ads->realm)); + DEBUG(3,("got ldap server name %s@%s\n", + ads->ldap_server_name, ads->realm)); return True; } -- cgit From e051c2c430f706835f250b10cc63e5621054b5ec Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Dec 2001 00:39:01 +0000 Subject: make sid_binstring available without HAVE_ADS (This used to be commit 4a6d29768665f71b72cf48ee34ee9a9c451232f6) --- source3/libads/ldap.c | 39 --------------------------------------- 1 file changed, 39 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c81f2474ae..2fe97ebb1a 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -386,45 +386,6 @@ NTSTATUS ads_set_machine_password(ADS_STRUCT *ads, return ret; } - -/* - return a RFC2254 binary string representation of a buffer - used in filters - caller must free -*/ -char *ads_binary_string(char *buf, int len) -{ - char *s; - int i, j; - const char *hex = "0123456789ABCDEF"; - s = malloc(len * 3 + 1); - if (!s) return NULL; - for (j=i=0;i> 4]; - s[j+2] = hex[((unsigned char)buf[i]) & 0xF]; - j += 3; - } - s[j] = 0; - return s; -} - -/* - return the binary string representation of a DOM_SID - caller must free -*/ -char *ads_sid_binstring(DOM_SID *sid) -{ - char *buf, *s; - int len = sid_size(sid); - buf = malloc(len); - if (!buf) return NULL; - sid_linearize(buf, len, sid); - s = ads_binary_string(buf, len); - free(buf); - return s; -} - /* pull the first entry from a ADS result */ -- cgit From 48c45486e3e67b96c7ea4c7044823274e9fa72e7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Dec 2001 11:16:22 +0000 Subject: allow selection of the organisational unit when joining a realm (This used to be commit f1231c2b54cac9d4fda7fa9d45fd329f1fd7b779) --- source3/libads/ldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2fe97ebb1a..09498b4384 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -181,14 +181,14 @@ int ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) /* add a machine account to the ADS server */ -static int ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname) +static int ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, const char *org_unit) { int ret; char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr; asprintf(&host_spn, "HOST/%s", hostname); asprintf(&host_upn, "%s@%s", host_spn, ads->realm); - asprintf(&new_dn, "cn=%s,cn=Computers,%s", hostname, ads->bind_path); + asprintf(&new_dn, "cn=%s,cn=%s,%s", hostname, org_unit, ads->bind_path); asprintf(&samAccountName, "%s$", hostname); asprintf(&controlstr, "%u", UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT | @@ -300,7 +300,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) join a machine to a realm, creating the machine account and setting the machine password */ -int ads_join_realm(ADS_STRUCT *ads, const char *hostname) +int ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org_unit) { int rc; LDAPMessage *res; @@ -316,7 +316,7 @@ int ads_join_realm(ADS_STRUCT *ads, const char *hostname) return LDAP_SUCCESS; } - rc = ads_add_machine_acct(ads, host); + rc = ads_add_machine_acct(ads, host, org_unit); if (rc != LDAP_SUCCESS) { DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(rc))); return rc; -- cgit From a062e58d9e47f95ac7c66668b3cfe1f72386f6e0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 19 Dec 2001 08:44:23 +0000 Subject: - added initial support for trusted domains in winbindd_ads - gss error code patch from a.bokovoy@sam-solutions.net - better sid dumping in ads_dump - fixed help in wbinfo (This used to be commit ee1c3e1f044b4ef62169ad74c5cac40eef81bfda) --- source3/libads/ldap.c | 77 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 8 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 09498b4384..b41a864ae2 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -38,20 +38,24 @@ char *ads_errstr(int rc) /* connect to the LDAP server */ -int ads_connect(ADS_STRUCT *ads) +ADS_RETURN_CODE ads_connect(ADS_STRUCT *ads) { int version = LDAP_VERSION3; - int rc; + ADS_RETURN_CODE rc; + + rc.error_type = False; ads->last_attempt = time(NULL); ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); if (!ads->ld) { - return LDAP_SERVER_DOWN; + rc.rc = LDAP_SERVER_DOWN; + return rc; } if (!ads_server_info(ads)) { DEBUG(1,("Failed to get ldap server info\n")); - return LDAP_SERVER_DOWN; + rc.rc = LDAP_SERVER_DOWN; + return rc; } ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); @@ -232,6 +236,19 @@ static void dump_binary(const char *field, struct berval **values) } } +/* + dump a sid result from ldap +*/ +static void dump_sid(const char *field, struct berval **values) +{ + int i; + for (i=0; values[i]; i++) { + DOM_SID sid; + sid_parse(values[i]->bv_val, values[i]->bv_len, &sid); + printf("%s: %s\n", field, sid_string_static(&sid)); + } +} + /* dump a string result from ldap */ @@ -257,7 +274,7 @@ void ads_dump(ADS_STRUCT *ads, void *res) void (*handler)(const char *, struct berval **); } handlers[] = { {"objectGUID", dump_binary}, - {"objectSid", dump_binary}, + {"objectSid", dump_sid}, {NULL, NULL} }; @@ -547,12 +564,16 @@ BOOL ads_server_info(ADS_STRUCT *ads) *p = 0; + SAFE_FREE(ads->server_realm); + SAFE_FREE(ads->bind_path); + + ads->server_realm = strdup(p+2); + ads->bind_path = ads_build_dn(ads->server_realm); + /* in case the realm isn't configured in smb.conf */ if (!ads->realm || !ads->realm[0]) { SAFE_FREE(ads->realm); - SAFE_FREE(ads->bind_path); - ads->realm = strdup(p+2); - ads->bind_path = ads_build_dn(ads->realm); + ads->realm = strdup(ads->server_realm); } DEBUG(3,("got ldap server name %s@%s\n", @@ -561,4 +582,44 @@ BOOL ads_server_info(ADS_STRUCT *ads) return True; } + +/* + find the list of trusted domains +*/ +BOOL ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + int *num_trusts, char ***names, DOM_SID **sids) +{ + const char *attrs[] = {"flatName", "securityIdentifier", NULL}; + int rc; + void *res, *msg; + int count, i; + + *num_trusts = 0; + + rc = ads_search(ads, &res, "(objectcategory=trustedDomain)", attrs); + if (rc) return False; + + count = ads_count_replies(ads, res); + if (count == 0) { + ads_msgfree(ads, res); + return False; + } + + (*names) = talloc(mem_ctx, sizeof(char *) * count); + (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * count); + if (! *names || ! *sids) return False; + + for (i=0, msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { + (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatName"); + ads_pull_sid(ads, msg, "securityIdentifier", &(*sids)[i]); + i++; + } + + ads_msgfree(ads, res); + + *num_trusts = i; + + return True; +} + #endif -- cgit From 1f31ace6cb771d7bf0b64091fba1d24c466ad4e5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 19 Dec 2001 12:21:12 +0000 Subject: much better ADS error handling system (This used to be commit 05a90a28843e0d69183a49a76617c5f32817df16) --- source3/libads/ldap.c | 234 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 141 insertions(+), 93 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b41a864ae2..3452614315 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -23,39 +23,83 @@ #ifdef HAVE_ADS -/* return a dn of the form "dc=AA,dc=BB,dc=CC" from a - realm of the form AA.BB.CC - caller must free +/* + build a ADS_STATUS structure +*/ +ADS_STATUS ads_build_error(enum ads_error_type etype, + int rc, int minor_status) +{ + ADS_STATUS ret; + ret.error_type = etype; + ret.rc = rc; + ret.minor_status = minor_status; + return ret; +} + +/* + do a rough conversion between ads error codes and NT status codes + we'll need to fill this in more */ +NTSTATUS ads_ntstatus(ADS_STATUS rc) +{ + if (ADS_ERR_OK(rc)) return NT_STATUS_OK; + return NT_STATUS_UNSUCCESSFUL; +} + /* return a string for an error from a ads routine */ -char *ads_errstr(int rc) +const char *ads_errstr(ADS_STATUS status) { - return ldap_err2string(rc); + gss_buffer_desc msg1, msg2; + uint32 minor; + int msg_ctx; + static char *ret; + + SAFE_FREE(ret); + msg_ctx = 0; + + switch (status.error_type) { + case ADS_ERROR_KRB5: + return error_message(status.rc); + case ADS_ERROR_LDAP: + return ldap_err2string(status.rc); + case ADS_ERROR_SYSTEM: + return strerror(status.rc); + case ADS_ERROR_GSS: + msg1.value = NULL; + msg2.value = NULL; + gss_display_status(&minor, status.rc, GSS_C_GSS_CODE, + GSS_C_NULL_OID, &msg_ctx, &msg1); + gss_display_status(&minor, status.minor_status, GSS_C_MECH_CODE, + GSS_C_NULL_OID, &msg_ctx, &msg2); + asprintf(&ret, "%s : %s", (char *)msg1.value, (char *)msg2.value); + gss_release_buffer(&minor, &msg1); + gss_release_buffer(&minor, &msg2); + return ret; + } + + return "Unknown ADS error type!?"; } /* connect to the LDAP server */ -ADS_RETURN_CODE ads_connect(ADS_STRUCT *ads) +ADS_STATUS ads_connect(ADS_STRUCT *ads) { int version = LDAP_VERSION3; - ADS_RETURN_CODE rc; - - rc.error_type = False; + ADS_STATUS status; ads->last_attempt = time(NULL); ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); if (!ads->ld) { - rc.rc = LDAP_SERVER_DOWN; - return rc; + return ADS_ERROR_SYSTEM(errno) } - if (!ads_server_info(ads)) { + status = ads_server_info(ads); + if (!ADS_ERR_OK(status)) { DEBUG(1,("Failed to get ldap server info\n")); - rc.rc = LDAP_SERVER_DOWN; - return rc; + return status; } ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); @@ -64,33 +108,35 @@ ADS_RETURN_CODE ads_connect(ADS_STRUCT *ads) ads_kinit_password(ads); } - rc = ads_sasl_bind(ads); - return rc; + return ads_sasl_bind(ads); } /* do a search with a timeout */ -int ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, - const char **attrs, void **res) +ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, + const char *exp, + const char **attrs, void **res) { struct timeval timeout; + int rc; timeout.tv_sec = ADS_SEARCH_TIMEOUT; timeout.tv_usec = 0; *res = NULL; - return ldap_search_ext_s(ads->ld, - bind_path, scope, - exp, attrs, 0, NULL, NULL, - &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); + rc = ldap_search_ext_s(ads->ld, + bind_path, scope, + exp, attrs, 0, NULL, NULL, + &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); + return ADS_ERROR(rc); } /* do a general ADS search */ -int ads_search(ADS_STRUCT *ads, void **res, - const char *exp, - const char **attrs) +ADS_STATUS ads_search(ADS_STRUCT *ads, void **res, + const char *exp, + const char **attrs) { return ads_do_search(ads, ads->bind_path, LDAP_SCOPE_SUBTREE, exp, attrs, res); @@ -99,9 +145,9 @@ int ads_search(ADS_STRUCT *ads, void **res, /* do a search on a specific DistinguishedName */ -int ads_search_dn(ADS_STRUCT *ads, void **res, - const char *dn, - const char **attrs) +ADS_STATUS ads_search_dn(ADS_STRUCT *ads, void **res, + const char *dn, + const char **attrs) { return ads_do_search(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res); } @@ -118,24 +164,24 @@ void ads_msgfree(ADS_STRUCT *ads, void *msg) /* find a machine account given a hostname */ -int ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) +ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) { - int ret; + ADS_STATUS status; char *exp; /* the easiest way to find a machine account anywhere in the tree is to look for hostname$ */ asprintf(&exp, "(samAccountName=%s$)", host); - ret = ads_search(ads, res, exp, NULL); + status = ads_search(ads, res, exp, NULL); free(exp); - return ret; + return status; } /* a convenient routine for adding a generic LDAP record */ -int ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) +ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) { int i; va_list ap; @@ -179,15 +225,16 @@ int ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) } free(mods); - return ret; + return ADS_ERROR(ret); } /* add a machine account to the ADS server */ -static int ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, const char *org_unit) +static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, + const char *org_unit) { - int ret; + ADS_STATUS ret; char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr; asprintf(&host_spn, "HOST/%s", hostname); @@ -317,9 +364,9 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) join a machine to a realm, creating the machine account and setting the machine password */ -int ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org_unit) +ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org_unit) { - int rc; + ADS_STATUS status; LDAPMessage *res; char *host; @@ -327,80 +374,78 @@ int ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org_unit) host = strdup(hostname); strlower(host); - rc = ads_find_machine_acct(ads, (void **)&res, host); - if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1) { + status = ads_find_machine_acct(ads, (void **)&res, host); + if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { DEBUG(0, ("Host account for %s already exists\n", host)); - return LDAP_SUCCESS; + return ADS_SUCCESS; } - rc = ads_add_machine_acct(ads, host, org_unit); - if (rc != LDAP_SUCCESS) { - DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(rc))); - return rc; + status = ads_add_machine_acct(ads, host, org_unit); + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(status))); + return status; } - rc = ads_find_machine_acct(ads, (void **)&res, host); - if (rc != LDAP_SUCCESS || ads_count_replies(ads, res) != 1) { + status = ads_find_machine_acct(ads, (void **)&res, host); + if (!ADS_ERR_OK(status)) { DEBUG(0, ("Host account test failed\n")); - /* hmmm, we need NTSTATUS */ - return -1; + return status; } free(host); - return LDAP_SUCCESS; + return status; } /* delete a machine from the realm */ -int ads_leave_realm(ADS_STRUCT *ads, const char *hostname) +ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) { - int rc; + ADS_STATUS status; void *res; char *hostnameDN, *host; + int rc; /* hostname must be lowercase */ host = strdup(hostname); strlower(host); - rc = ads_find_machine_acct(ads, &res, host); - if (rc != LDAP_SUCCESS || ads_count_replies(ads, res) != 1) { + status = ads_find_machine_acct(ads, &res, host); + if (!ADS_ERR_OK(status)) { DEBUG(0, ("Host account for %s does not exist.\n", host)); - return -1; + return status; } hostnameDN = ldap_get_dn(ads->ld, (LDAPMessage *)res); rc = ldap_delete_s(ads->ld, hostnameDN); ldap_memfree(hostnameDN); if (rc != LDAP_SUCCESS) { - DEBUG(0, ("ldap_delete_s: %s\n", ads_errstr(rc))); - return rc; + return ADS_ERROR(rc); } - rc = ads_find_machine_acct(ads, &res, host); - if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1 ) { - DEBUG(0, ("Failed to remove host account.\n")); - /*hmmm, we need NTSTATUS */ - return -1; + status = ads_find_machine_acct(ads, &res, host); + if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { + DEBUG(0, ("Failed to remove host account.\n")); + return status; } free(host); - return LDAP_SUCCESS; + return status; } -NTSTATUS ads_set_machine_password(ADS_STRUCT *ads, - const char *hostname, - const char *password) +ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, + const char *hostname, + const char *password) { - NTSTATUS ret; + ADS_STATUS status; char *host = strdup(hostname); strlower(host); - ret = krb5_set_password(ads->kdc_server, host, ads->realm, password); + status = krb5_set_password(ads->kdc_server, host, ads->realm, password); free(host); - return ret; + return status; } /* @@ -510,18 +555,22 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, /* find the update serial number - this is the core of the ldap cache */ -BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn) +ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) { const char *attrs[] = {"highestCommittedUSN", NULL}; - int rc; + ADS_STATUS status; void *res; - BOOL ret; - rc = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); - if (rc || ads_count_replies(ads, res) != 1) return False; - ret = ads_pull_uint32(ads, res, "highestCommittedUSN", usn); + status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) return status; + + if (ads_count_replies(ads, res) != 1) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + ads_pull_uint32(ads, res, "highestCommittedUSN", usn); ads_msgfree(ads, res); - return ret; + return ADS_SUCCESS; } @@ -529,26 +578,25 @@ BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn) The ldapServiceName field on w2k looks like this: vnet3.home.samba.org:win2000-vnet3$@VNET3.HOME.SAMBA.ORG */ -BOOL ads_server_info(ADS_STRUCT *ads) +ADS_STATUS ads_server_info(ADS_STRUCT *ads) { const char *attrs[] = {"ldapServiceName", NULL}; - int rc; + ADS_STATUS status; void *res; char **values; char *p; - rc = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); - if (rc || ads_count_replies(ads, res) != 1) return False; + status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) return status; values = ldap_get_values(ads->ld, res, "ldapServiceName"); - - if (!values || !values[0]) return False; + if (!values || !values[0]) return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); p = strchr(values[0], ':'); if (!p) { ldap_value_free(values); ldap_msgfree(res); - return False; + return ADS_ERROR(LDAP_DECODING_ERROR); } SAFE_FREE(ads->ldap_server_name); @@ -559,7 +607,7 @@ BOOL ads_server_info(ADS_STRUCT *ads) ldap_value_free(values); ldap_msgfree(res); SAFE_FREE(ads->ldap_server_name); - return False; + return ADS_ERROR(LDAP_DECODING_ERROR); } *p = 0; @@ -579,35 +627,35 @@ BOOL ads_server_info(ADS_STRUCT *ads) DEBUG(3,("got ldap server name %s@%s\n", ads->ldap_server_name, ads->realm)); - return True; + return ADS_SUCCESS; } /* find the list of trusted domains */ -BOOL ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, - int *num_trusts, char ***names, DOM_SID **sids) +ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + int *num_trusts, char ***names, DOM_SID **sids) { const char *attrs[] = {"flatName", "securityIdentifier", NULL}; - int rc; + ADS_STATUS status; void *res, *msg; int count, i; *num_trusts = 0; - rc = ads_search(ads, &res, "(objectcategory=trustedDomain)", attrs); - if (rc) return False; + status = ads_search(ads, &res, "(objectcategory=trustedDomain)", attrs); + if (!ADS_ERR_OK(status)) return status; count = ads_count_replies(ads, res); if (count == 0) { ads_msgfree(ads, res); - return False; + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); } (*names) = talloc(mem_ctx, sizeof(char *) * count); (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * count); - if (! *names || ! *sids) return False; + if (! *names || ! *sids) return ADS_ERROR(LDAP_NO_MEMORY); for (i=0, msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatName"); @@ -619,7 +667,7 @@ BOOL ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, *num_trusts = i; - return True; + return ADS_SUCCESS; } #endif -- cgit From 6c7e9dfb293f1243d9d8d8a2ac50ef12d738198e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 20 Dec 2001 03:54:52 +0000 Subject: net ads password and net ads chostpass commands from Remus Koos (This used to be commit 412e79c448bf02e3097b5c14a36fe0172d8d2895) --- source3/libads/ldap.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 3452614315..d2b9f74c4d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3,6 +3,8 @@ Version 3.0 ads (active directory) 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 @@ -442,9 +444,17 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, { ADS_STATUS status; char *host = strdup(hostname); + char *principal; + strlower(host); - status = krb5_set_password(ads->kdc_server, host, ads->realm, password); + + asprintf(&principal, "%s@%s", host, ads->realm); + + status = krb5_set_password(ads->kdc_server, principal, password); + free(host); + free(principal); + return status; } -- cgit From 401c7495ea0286a46c97a18273419f122d1168a7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 20 Dec 2001 23:35:14 +0000 Subject: added ads_domain_sid() function (This used to be commit ff002a458afa6ca378f0c6d2ec9fb74233c839a7) --- source3/libads/ldap.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d2b9f74c4d..8966ceb32a 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -680,4 +680,22 @@ ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, return ADS_SUCCESS; } +/* find the domain sid for our domain */ +ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) +{ + const char *attrs[] = {"objectSid", NULL}; + void *res; + ADS_STATUS rc; + + rc = ads_do_search(ads, ads->bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", + attrs, &res); + if (!ADS_ERR_OK(rc)) return rc; + if (!ads_pull_sid(ads, res, "objectSid", sid)) { + return ADS_ERROR_SYSTEM(ENOENT); + } + ads_msgfree(ads, res); + + return ADS_SUCCESS; +} + #endif -- cgit From 34037e2479981073c8289fe51868b29096cc5808 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 30 Dec 2001 05:59:43 +0000 Subject: Make Samba compile on RH 6.2 again. We now include the libber.h file if required, but currently we just don't use ldap. (I'll chase this up). In the meantime, I've moved the ads_status code about, its now in its own file, and has a couple of #ifdefs to allow smbd to link - becouse the lack of LDAP caused HAVE_ADS to be undefined. (I hope its not too ugly). Andrew Bartlett (This used to be commit 14407c87e2dcccae1784290e3eb7a2d611516aff) --- source3/libads/ldap.c | 59 --------------------------------------------------- 1 file changed, 59 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8966ceb32a..5503b6e353 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -25,65 +25,6 @@ #ifdef HAVE_ADS -/* - build a ADS_STATUS structure -*/ -ADS_STATUS ads_build_error(enum ads_error_type etype, - int rc, int minor_status) -{ - ADS_STATUS ret; - ret.error_type = etype; - ret.rc = rc; - ret.minor_status = minor_status; - return ret; -} - -/* - do a rough conversion between ads error codes and NT status codes - we'll need to fill this in more -*/ -NTSTATUS ads_ntstatus(ADS_STATUS rc) -{ - if (ADS_ERR_OK(rc)) return NT_STATUS_OK; - return NT_STATUS_UNSUCCESSFUL; -} - -/* - return a string for an error from a ads routine -*/ -const char *ads_errstr(ADS_STATUS status) -{ - gss_buffer_desc msg1, msg2; - uint32 minor; - int msg_ctx; - static char *ret; - - SAFE_FREE(ret); - msg_ctx = 0; - - switch (status.error_type) { - case ADS_ERROR_KRB5: - return error_message(status.rc); - case ADS_ERROR_LDAP: - return ldap_err2string(status.rc); - case ADS_ERROR_SYSTEM: - return strerror(status.rc); - case ADS_ERROR_GSS: - msg1.value = NULL; - msg2.value = NULL; - gss_display_status(&minor, status.rc, GSS_C_GSS_CODE, - GSS_C_NULL_OID, &msg_ctx, &msg1); - gss_display_status(&minor, status.minor_status, GSS_C_MECH_CODE, - GSS_C_NULL_OID, &msg_ctx, &msg2); - asprintf(&ret, "%s : %s", (char *)msg1.value, (char *)msg2.value); - gss_release_buffer(&minor, &msg1); - gss_release_buffer(&minor, &msg2); - return ret; - } - - return "Unknown ADS error type!?"; -} - /* connect to the LDAP server */ -- cgit From 9e0297b3edd01d5c9b7e99881f72421706b4f9e2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 3 Jan 2002 11:59:33 +0000 Subject: added nTSecurityDescriptor field to host acct dump (This used to be commit f383e19e095eab975bf3d4e622a5c1d1f823171b) --- source3/libads/ldap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 5503b6e353..c616f09b6e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -111,11 +111,12 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) { ADS_STATUS status; char *exp; + const char *attrs[] = {"*", "nTSecurityDescriptor", NULL}; /* the easiest way to find a machine account anywhere in the tree is to look for hostname$ */ asprintf(&exp, "(samAccountName=%s$)", host); - status = ads_search(ads, res, exp, NULL); + status = ads_search(ads, res, exp, attrs); free(exp); return status; } @@ -264,6 +265,7 @@ void ads_dump(ADS_STRUCT *ads, void *res) void (*handler)(const char *, struct berval **); } handlers[] = { {"objectGUID", dump_binary}, + {"nTSecurityDescriptor", dump_binary}, {"objectSid", dump_sid}, {NULL, NULL} }; -- cgit From 4acb3125cd42728e2bb3f971bfb9373decc1d0fb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 11 Jan 2002 04:50:45 +0000 Subject: Fix up 'net ads join' to delete and rejoin if the account already exists. This fixes up a problem where a machine would join (or downgrade by trust password change) to NT4 membership and not be able to regain full ADS membership until a 'net ads leave'. Andrew Bartlett (This used to be commit ab8ff85f03b25a0dfe4ab63886a10da81207393c) --- source3/libads/ldap.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c616f09b6e..2e93e11603 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -321,8 +321,13 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org status = ads_find_machine_acct(ads, (void **)&res, host); if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { - DEBUG(0, ("Host account for %s already exists\n", host)); - return ADS_SUCCESS; + DEBUG(0, ("Host account for %s already exists - deleting for readd\n", host)); + status = ads_leave_realm(ads, host); + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n", + host, ads->realm)); + return status; + } } status = ads_add_machine_acct(ads, host, org_unit); -- cgit From 9f85d4ad5f2bb5fdb7739b3f90c4bfac705393ce Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 16 Jan 2002 02:22:30 +0000 Subject: much better support for organisational units in ADS join (This used to be commit 7e876057d5e392f85e6fdb0f2c233b0fe76df688) --- source3/libads/ldap.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2e93e11603..d922e4c7c5 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -172,6 +172,23 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) return ADS_ERROR(ret); } +/* + build an org unit string + if org unit is Computers or blank then assume a container, otherwise + assume a \ separated list of organisational units + caller must free +*/ +char *ads_ou_string(const char *org_unit) +{ + if (!org_unit || !*org_unit || strcasecmp(org_unit, "Computers") == 0) { + return strdup("cn=Computers"); + } + + return ads_build_path(org_unit, "\\/", "ou=", 1); +} + + + /* add a machine account to the ADS server */ @@ -180,10 +197,13 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, { ADS_STATUS ret; char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr; + char *ou_str; asprintf(&host_spn, "HOST/%s", hostname); asprintf(&host_upn, "%s@%s", host_spn, ads->realm); - asprintf(&new_dn, "cn=%s,cn=%s,%s", hostname, org_unit, ads->bind_path); + ou_str = ads_ou_string(org_unit); + asprintf(&new_dn, "cn=%s,%s,%s", hostname, ou_str, ads->bind_path); + free(ou_str); asprintf(&samAccountName, "%s$", hostname); asprintf(&controlstr, "%u", UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT | -- cgit From de260eadf956cae8aeaebc2a84f46a57c0671741 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 25 Jan 2002 22:07:46 +0000 Subject: Enable net ads commands to use existing tickets if the user doesn't specify a username on the commandline. Also don't continue past the kinit if a password is entered and fails because existing tickets would be used, which may not be desired if the username was specified. (This used to be commit 7e5d7dfa834c0161460bde8a2f0d4824c0a0d1fe) --- source3/libads/ldap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d922e4c7c5..d7d2163281 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -31,6 +31,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) { int version = LDAP_VERSION3; + int code; ADS_STATUS status; ads->last_attempt = time(NULL); @@ -48,7 +49,8 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); if (ads->password) { - ads_kinit_password(ads); + if ((code = ads_kinit_password(ads))) + return ADS_ERROR_KRB5(code); } return ads_sasl_bind(ads); -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/libads/ldap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d7d2163281..0028d11b8f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. ads (active directory) utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 -- cgit From 9e75e5c1f0026459bf95985d19558bd157400a26 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 1 Feb 2002 16:14:33 +0000 Subject: Add functions for modifying an entry in ADS. Needed for printer publishing. (This used to be commit 3d8d8cef64c674f9f1240759a05766db95bfde4e) --- source3/libads/ldap.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0028d11b8f..ff927bc63c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3,7 +3,7 @@ ads (active directory) utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 - + Copyright (C) Jim McDonough 2002 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 @@ -122,6 +122,123 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) return status; } +/* + initialize a list of mods +*/ + +LDAPMod **ads_mod_list_start(int num_mods) +{ + LDAPMod **mods; + + if (num_mods < 1) + return NULL; + + mods = malloc(sizeof(LDAPMod *) * (num_mods + 1)); + memset(mods, 0, sizeof(LDAPMod *) * num_mods); + mods[num_mods] = (LDAPMod *) -1; + + return mods; +} + +/* + add an attribute to the list, with values list already constructed +*/ +static BOOL ads_mod_list_add(LDAPMod **mods, int mod_op, char *name, char **values) +{ + int curmod; + + /* find the first empty slot */ + for (curmod=0; mods[curmod] > 0; curmod++); + if (mods[curmod] == (LDAPMod *) -1) + return False; + + mods[curmod] = malloc(sizeof(LDAPMod)); + mods[curmod]->mod_type = name; + mods[curmod]->mod_values = values; + mods[curmod]->mod_op = mod_op; + return True; +} + +BOOL ads_mod_add_list(LDAPMod **mods, char *name, char **values) +{ + return ads_mod_list_add(mods, LDAP_MOD_ADD, name, values); +} + +BOOL ads_mod_repl_list(LDAPMod **mods, char *name, char **values) +{ + if (values && *values) + return ads_mod_list_add(mods, LDAP_MOD_REPLACE, name, values); + else + return ads_mod_list_add(mods, LDAP_MOD_DELETE, name, NULL); +} + +/* + add an attribute to the list, with values list to be built from args +*/ +BOOL ads_mod_list_add_var(LDAPMod **mods, int mod_op, char *name, ...) +{ + va_list ap; + int num_vals, i; + 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) { + values = malloc(sizeof(char *) * (num_vals + 1)); + 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; + } else + values = NULL; + return ads_mod_list_add(mods, mod_op, name, values); +} + +BOOL ads_mod_repl(LDAPMod **mods, char *name, char *val) +{ + if (val) + return ads_mod_list_add_var(mods, LDAP_MOD_REPLACE, name, val); + else + return ads_mod_list_add_var(mods, LDAP_MOD_DELETE, name, NULL); +} + +BOOL ads_mod_add(LDAPMod **mods, char *name, char *val) +{ + return ads_mod_list_add_var(mods, LDAP_MOD_ADD, name, val); +} + +void ads_mod_list_end(LDAPMod **mods) +{ + int i; + + if (mods) { + for (i = 0; mods[i]; i++) { + if (mods[i]->mod_values) { + free(mods[i]->mod_values); + } + free(mods[i]); + } + free(mods); + } +} + +ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, LDAPMod **mods) +{ + int ret,i; + + /* find the end of the list, marked by NULL or -1 */ + for(i=0;mods[i]>0;i++); + /* make sure the end of the list is NULL */ + mods[i] = NULL; + ret = ldap_add_s(ads->ld, mod_dn, mods); + return ADS_ERROR(ret); +} /* a convenient routine for adding a generic LDAP record -- cgit From 0c63216603fa957e04688d22bf1c0321fb2ff78a Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 1 Feb 2002 17:13:39 +0000 Subject: Fix build errors on non-ldap systems...change function parms from LDAPMod ** to void ** (This used to be commit 9467792843fdd9bc55e92bfaa2f2205279074297) --- source3/libads/ldap.c | 51 +++++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 24 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ff927bc63c..293c885342 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -123,10 +123,11 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) } /* - initialize a list of mods + initialize a list of mods - returns (void **) instead of (LDAPMod **) + so proto.h works on non-ldap systems */ -LDAPMod **ads_mod_list_start(int num_mods) +void **ads_mod_list_start(int num_mods) { LDAPMod **mods; @@ -137,34 +138,35 @@ LDAPMod **ads_mod_list_start(int num_mods) memset(mods, 0, sizeof(LDAPMod *) * num_mods); mods[num_mods] = (LDAPMod *) -1; - return mods; + return (void **) mods; } /* add an attribute to the list, with values list already constructed */ -static BOOL ads_mod_list_add(LDAPMod **mods, int mod_op, char *name, char **values) +static BOOL ads_mod_list_add(void **mods, int mod_op, char *name, char **values) { int curmod; + LDAPMod **modlist = (LDAPMod **) mods; /* find the first empty slot */ - for (curmod=0; mods[curmod] > 0; curmod++); - if (mods[curmod] == (LDAPMod *) -1) + for (curmod=0; modlist[curmod] > 0; curmod++); + if (modlist[curmod] == (LDAPMod *) -1) return False; - mods[curmod] = malloc(sizeof(LDAPMod)); - mods[curmod]->mod_type = name; - mods[curmod]->mod_values = values; - mods[curmod]->mod_op = mod_op; + modlist[curmod] = malloc(sizeof(LDAPMod)); + modlist[curmod]->mod_type = name; + modlist[curmod]->mod_values = values; + modlist[curmod]->mod_op = mod_op; return True; } -BOOL ads_mod_add_list(LDAPMod **mods, char *name, char **values) +BOOL ads_mod_add_list(void **mods, char *name, char **values) { return ads_mod_list_add(mods, LDAP_MOD_ADD, name, values); } -BOOL ads_mod_repl_list(LDAPMod **mods, char *name, char **values) +BOOL ads_mod_repl_list(void **mods, char *name, char **values) { if (values && *values) return ads_mod_list_add(mods, LDAP_MOD_REPLACE, name, values); @@ -175,7 +177,7 @@ BOOL ads_mod_repl_list(LDAPMod **mods, char *name, char **values) /* add an attribute to the list, with values list to be built from args */ -BOOL ads_mod_list_add_var(LDAPMod **mods, int mod_op, char *name, ...) +BOOL ads_mod_list_add_var(void **mods, int mod_op, char *name, ...) { va_list ap; int num_vals, i; @@ -200,7 +202,7 @@ BOOL ads_mod_list_add_var(LDAPMod **mods, int mod_op, char *name, ...) return ads_mod_list_add(mods, mod_op, name, values); } -BOOL ads_mod_repl(LDAPMod **mods, char *name, char *val) +BOOL ads_mod_repl(void **mods, char *name, char *val) { if (val) return ads_mod_list_add_var(mods, LDAP_MOD_REPLACE, name, val); @@ -208,27 +210,28 @@ BOOL ads_mod_repl(LDAPMod **mods, char *name, char *val) return ads_mod_list_add_var(mods, LDAP_MOD_DELETE, name, NULL); } -BOOL ads_mod_add(LDAPMod **mods, char *name, char *val) +BOOL ads_mod_add(void **mods, char *name, char *val) { return ads_mod_list_add_var(mods, LDAP_MOD_ADD, name, val); } -void ads_mod_list_end(LDAPMod **mods) +void ads_mod_list_end(void **mods) { int i; + LDAPMod **modlist = (LDAPMod **) mods; - if (mods) { - for (i = 0; mods[i]; i++) { - if (mods[i]->mod_values) { - free(mods[i]->mod_values); + if (modlist) { + for (i = 0; modlist[i]; i++) { + if (modlist[i]->mod_values) { + free(modlist[i]->mod_values); } - free(mods[i]); + free(modlist[i]); } - free(mods); + free(modlist); } } -ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, LDAPMod **mods) +ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, void **mods) { int ret,i; @@ -236,7 +239,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, LDAPMod **mods) for(i=0;mods[i]>0;i++); /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_add_s(ads->ld, mod_dn, mods); + ret = ldap_add_s(ads->ld, mod_dn, (LDAPMod **) mods); return ADS_ERROR(ret); } -- cgit From bb8349735f627ba4de2012f77ee3fa6ce491f394 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Sat, 2 Feb 2002 02:04:01 +0000 Subject: Minor bug fixes, plus support to remove a printer. Commented out optional attributes until a method for checking for their existence is done. (This used to be commit 538c19a6983e0423b94f743184263cd8ef9c701e) --- source3/libads/ldap.c | 67 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 11 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 293c885342..8dee73bde2 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -105,6 +105,23 @@ void ads_msgfree(ADS_STRUCT *ads, void *msg) ldap_msgfree(msg); } +/* + free up memory from various ads requests +*/ +void ads_memfree(ADS_STRUCT *ads, void *mem) +{ + if (!mem) return; + ldap_memfree(mem); +} + +/* + get a dn from search results +*/ +char *ads_get_dn(ADS_STRUCT *ads, void *res) +{ + return ldap_get_dn(ads->ld, res); +} + /* find a machine account given a hostname */ @@ -122,6 +139,24 @@ 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(char **values) +{ + char **newvals; + int i; +#define ADS_MAX_NUM_VALUES 32 + + for (i=0; values[i] && i0;i++); /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_add_s(ads->ld, mod_dn, (LDAPMod **) mods); + ret = ldap_modify_s(ads->ld, mod_dn, (LDAPMod **) mods); return ADS_ERROR(ret); } @@ -293,6 +333,11 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) return ADS_ERROR(ret); } +ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) +{ + return ADS_ERROR(ldap_delete(ads->ld, del_dn)); +} + /* build an org unit string if org unit is Computers or blank then assume a container, otherwise @@ -508,9 +553,9 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return status; } - hostnameDN = ldap_get_dn(ads->ld, (LDAPMessage *)res); + hostnameDN = ads_get_dn(ads, (LDAPMessage *)res); rc = ldap_delete_s(ads->ld, hostnameDN); - ldap_memfree(hostnameDN); + ads_memfree(ads, hostnameDN); if (rc != LDAP_SUCCESS) { return ADS_ERROR(rc); } -- cgit From 81b54940b7e9a3a3f6586972b1c9aa687e07426d Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Sat, 2 Feb 2002 22:06:10 +0000 Subject: merge in some changes from Alexey Kotovich. Return ADS_STATUS instead of BOOLs. Add support for bervals in mod lists. Also put undocumented AD ldap control in to allow modifications when an attribute does not yet exist. (This used to be commit 1a2d27b21e61be5a314f7d6c4ea0dff06a5307be) --- source3/libads/ldap.c | 121 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 88 insertions(+), 33 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8dee73bde2..75c7982105 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -37,7 +37,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); if (!ads->ld) { - return ADS_ERROR_SYSTEM(errno) + return ADS_ERROR_SYSTEM(errno); } status = ads_server_info(ads); if (!ADS_ERR_OK(status)) { @@ -150,7 +150,8 @@ static char **ads_dup_values(char **values) #define ADS_MAX_NUM_VALUES 32 for (i=0; values[i] && i 0; curmod++); if (modlist[curmod] == (LDAPMod *) -1) - return False; + return ADS_ERROR(LDAP_NO_MEMORY); - modlist[curmod] = malloc(sizeof(LDAPMod)); + if (!(modlist[curmod] = malloc(sizeof(LDAPMod)))) + return ADS_ERROR(LDAP_NO_MEMORY); modlist[curmod]->mod_type = name; modlist[curmod]->mod_values = values; modlist[curmod]->mod_op = mod_op; - return True; + return ADS_ERROR(LDAP_SUCCESS); } -BOOL ads_mod_add_list(void **mods, char *name, char **values) +ADS_STATUS ads_mod_add_list(void **mods, char *name, char **values) { char **newvals = ads_dup_values(values); - return ads_mod_list_add(mods, LDAP_MOD_ADD, name, newvals); + if (newvals) + return ads_modlist_add(mods, LDAP_MOD_ADD, name, newvals); + else + return ADS_ERROR(LDAP_NO_MEMORY); } -BOOL ads_mod_repl_list(void **mods, char *name, char **values) +ADS_STATUS ads_mod_repl_list(void **mods, char *name, char **values) { char **newvals; if (values && *values) { - newvals = ads_dup_values(values); - return ads_mod_list_add(mods, LDAP_MOD_REPLACE, name, newvals); + if (!(newvals = ads_dup_values(values))) + return ADS_ERROR(LDAP_NO_MEMORY); + else + return ads_modlist_add(mods, LDAP_MOD_REPLACE, + name, newvals); } else - return ads_mod_list_add(mods, LDAP_MOD_DELETE, name, NULL); + return ads_modlist_add(mods, LDAP_MOD_DELETE, name, NULL); } /* add an attribute to the list, with values list to be built from args */ -BOOL ads_mod_list_add_var(void **mods, int mod_op, char *name, ...) +ADS_STATUS ads_mod_add_var(void **mods, int mod_op, char *name, ...) { va_list ap; - int num_vals, i; + int num_vals, i, do_op; char *value, **values; /* count the number of values */ @@ -227,45 +236,75 @@ BOOL ads_mod_list_add_var(void **mods, int mod_op, char *name, ...) for (num_vals=0; va_arg(ap, char *); num_vals++); va_end(ap); + if (num_vals) { + if (!(values = malloc(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(mods, do_op, name, values); +} + +ADS_STATUS ads_mod_add_ber(void **mods, int mod_op, 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) { - values = malloc(sizeof(char *) * (num_vals + 1)); + if (!(values = malloc(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; - } else + do_op = mod_op; + } else { + do_op = LDAP_MOD_DELETE; values = NULL; - return ads_mod_list_add(mods, mod_op, name, values); + } + do_op |= LDAP_MOD_BVALUES; + return ads_modlist_add(mods, do_op, name, values); } -BOOL ads_mod_repl(void **mods, char *name, char *val) +ADS_STATUS ads_mod_repl(void **mods, char *name, char *val) { if (val) - return ads_mod_list_add_var(mods, LDAP_MOD_REPLACE, + return ads_mod_add_var(mods, LDAP_MOD_REPLACE, name, val, NULL); else - return ads_mod_list_add_var(mods, LDAP_MOD_DELETE, name, NULL); + return ads_mod_add_var(mods, LDAP_MOD_DELETE, name, NULL); } -BOOL ads_mod_add(void **mods, char *name, char *val) +ADS_STATUS ads_mod_add(void **mods, char *name, char *val) { - return ads_mod_list_add_var(mods, LDAP_MOD_ADD, name, val, NULL); + return ads_mod_add_var(mods, LDAP_MOD_ADD, name, val, NULL); } -void ads_mod_list_end(void **mods) +void ads_free_mods(void **mods) { int i; LDAPMod **modlist = (LDAPMod **) mods; if (modlist) { for (i = 0; modlist[i]; i++) { - if (modlist[i]->mod_values) { - free(modlist[i]->mod_values); - } - free(modlist[i]); + SAFE_FREE(modlist[i]->mod_values); + SAFE_FREE(modlist[i]); } free(modlist); } @@ -274,12 +313,28 @@ void ads_mod_list_end(void **mods) ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, void **mods) { int ret,i; - + LDAPControl control; + LDAPControl *controls[2]; + char bv_val = (char) 1; + + /* + this control seems to be necessary to have any modify + that contains a currently non-existent attribute (but + allowable for the object) to run + */ + control.ldctl_oid = "1.2.840.113556.1.4.1413"; + control.ldctl_value.bv_len = 1; + control.ldctl_value.bv_val = &bv_val; + control.ldctl_iscritical = (char) 0; + controls[0] = &control; + controls[1] = NULL; + /* find the end of the list, marked by NULL or -1 */ for(i=0;mods[i]>0;i++); /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_modify_s(ads->ld, mod_dn, (LDAPMod **) mods); + ret = ldap_modify_ext_s(ads->ld, mod_dn, (LDAPMod **) mods, + controls, NULL); return ADS_ERROR(ret); } -- cgit From 9aa88da9d5500b185299c05103d63c76f527a9dc Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 6 Feb 2002 02:28:46 +0000 Subject: Fix ldapmod list overrun check. Also better document and format ldap control for permissive modify. (This used to be commit 01e7f7c3d9006883b71e43d917d32e325cff7a15) --- source3/libads/ldap.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 75c7982105..4567a42c0f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -71,7 +71,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, rc = ldap_search_ext_s(ads->ld, bind_path, scope, - exp, attrs, 0, NULL, NULL, + exp, (char **) attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); return ADS_ERROR(rc); } @@ -187,10 +187,11 @@ static ADS_STATUS ads_modlist_add(void **mods, int mod_op, char *name, char **va LDAPMod **modlist = (LDAPMod **) mods; /* find the first empty slot */ - for (curmod=0; modlist[curmod] > 0; curmod++); + for (curmod=0; modlist[curmod] && modlist[curmod] != (LDAPMod *) -1; + curmod++); if (modlist[curmod] == (LDAPMod *) -1) return ADS_ERROR(LDAP_NO_MEMORY); - + if (!(modlist[curmod] = malloc(sizeof(LDAPMod)))) return ADS_ERROR(LDAP_NO_MEMORY); modlist[curmod]->mod_type = name; @@ -313,21 +314,17 @@ void ads_free_mods(void **mods) ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, void **mods) { int ret,i; - LDAPControl control; - LDAPControl *controls[2]; - char bv_val = (char) 1; - /* - this control seems to be necessary to have any modify - that contains a currently non-existent attribute (but - allowable for the object) to run + this control is needed to modify that contains a currently + non-existent attribute (but allowable for the object) to run */ - control.ldctl_oid = "1.2.840.113556.1.4.1413"; - control.ldctl_value.bv_len = 1; - control.ldctl_value.bv_val = &bv_val; - control.ldctl_iscritical = (char) 0; - controls[0] = &control; - controls[1] = NULL; + LDAPControl PermitModify = { + "1.2.840.113556.1.4.1413", + {0, NULL}, + (char) 1}; + LDAPControl *controls[2] = { + &PermitModify, + NULL }; /* find the end of the list, marked by NULL or -1 */ for(i=0;mods[i]>0;i++); -- cgit From fb444a546effe22e2a7c314a10473f0680be0cc6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 7 Feb 2002 02:44:37 +0000 Subject: when a trusted domain is down an ADS server will return a success on a get trusted domains query but leave the domain SID blank - we need to fail the add of the trusted domain in winbindd in that case (This used to be commit 24c7e7a3849df3a3378f7e7f20099de048f0b7bd) --- source3/libads/ldap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 4567a42c0f..a13bda5fa9 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -855,8 +855,9 @@ ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, for (i=0, msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatName"); - ads_pull_sid(ads, msg, "securityIdentifier", &(*sids)[i]); - i++; + if (ads_pull_sid(ads, msg, "securityIdentifier", &(*sids)[i])) { + i++; + } } ads_msgfree(ads, res); -- cgit From d2b65dcbff87e7d6e1f56ddffeaeed4cba2b890d Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 11 Feb 2002 15:47:02 +0000 Subject: Add ability to extend ads modification list on the fly. Also add some malloc checks and return ADS_ERROR(LDAP_NO_MEMORY) if they fail. (This used to be commit 81d76f05d8b886a86eb421d1bd8737ec7d05cbde) --- source3/libads/ldap.c | 62 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 23 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a13bda5fa9..e1d7d5d26c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -163,34 +163,41 @@ static char **ads_dup_values(char **values) so proto.h works on non-ldap systems */ -void **ads_init_mods(int num_mods) +ADS_MODLIST ads_init_mods(void) { +#define ADS_MODLIST_ALLOC_SIZE 10 LDAPMod **mods; - if (num_mods < 1) - return NULL; - - if ((mods = calloc(1, sizeof(LDAPMod *) * (num_mods + 1)))) + if ((mods = calloc(1, sizeof(LDAPMod *) * + (ADS_MODLIST_ALLOC_SIZE + 1)))) /* -1 is safety to make sure we don't go over the end. need to reset it to NULL before doing ldap modify */ - mods[num_mods] = (LDAPMod *) -1; + mods[ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1; - return (void **) mods; + return mods; } /* add an attribute to the list, with values list already constructed */ -static ADS_STATUS ads_modlist_add(void **mods, int mod_op, char *name, char **values) +static ADS_STATUS ads_modlist_add(ADS_MODLIST *mods, int mod_op, char *name, char **values) { int curmod; - LDAPMod **modlist = (LDAPMod **) mods; + LDAPMod **modlist = (LDAPMod **) *mods; /* find the first empty slot */ for (curmod=0; modlist[curmod] && modlist[curmod] != (LDAPMod *) -1; curmod++); - if (modlist[curmod] == (LDAPMod *) -1) - return ADS_ERROR(LDAP_NO_MEMORY); + if (modlist[curmod] == (LDAPMod *) -1) { + modlist = realloc(modlist, (curmod+ADS_MODLIST_ALLOC_SIZE+1) * + sizeof(LDAPMod *)); + if (!modlist) + return ADS_ERROR(LDAP_NO_MEMORY); + memset(&modlist[curmod], 0, + ADS_MODLIST_ALLOC_SIZE*sizeof(LDAPMod *)); + modlist[curmod+ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1; + *mods = modlist; + } if (!(modlist[curmod] = malloc(sizeof(LDAPMod)))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -200,7 +207,7 @@ static ADS_STATUS ads_modlist_add(void **mods, int mod_op, char *name, char **va return ADS_ERROR(LDAP_SUCCESS); } -ADS_STATUS ads_mod_add_list(void **mods, char *name, char **values) +ADS_STATUS ads_mod_add_list(ADS_MODLIST *mods, char *name, char **values) { char **newvals = ads_dup_values(values); if (newvals) @@ -209,7 +216,7 @@ ADS_STATUS ads_mod_add_list(void **mods, char *name, char **values) return ADS_ERROR(LDAP_NO_MEMORY); } -ADS_STATUS ads_mod_repl_list(void **mods, char *name, char **values) +ADS_STATUS ads_mod_repl_list(ADS_MODLIST *mods, char *name, char **values) { char **newvals; if (values && *values) { @@ -226,7 +233,7 @@ ADS_STATUS ads_mod_repl_list(void **mods, char *name, char **values) /* add an attribute to the list, with values list to be built from args */ -ADS_STATUS ads_mod_add_var(void **mods, int mod_op, char *name, ...) +ADS_STATUS ads_mod_add_var(ADS_MODLIST *mods, int mod_op, char *name, ...) { va_list ap; int num_vals, i, do_op; @@ -254,7 +261,7 @@ ADS_STATUS ads_mod_add_var(void **mods, int mod_op, char *name, ...) return ads_modlist_add(mods, do_op, name, values); } -ADS_STATUS ads_mod_add_ber(void **mods, int mod_op, char *name, ...) +ADS_STATUS ads_mod_add_ber(ADS_MODLIST *mods, int mod_op, char *name, ...) { va_list ap; int num_vals, i, do_op; @@ -283,7 +290,7 @@ ADS_STATUS ads_mod_add_ber(void **mods, int mod_op, char *name, ...) return ads_modlist_add(mods, do_op, name, values); } -ADS_STATUS ads_mod_repl(void **mods, char *name, char *val) +ADS_STATUS ads_mod_repl(ADS_MODLIST *mods, char *name, char *val) { if (val) return ads_mod_add_var(mods, LDAP_MOD_REPLACE, @@ -292,12 +299,12 @@ ADS_STATUS ads_mod_repl(void **mods, char *name, char *val) return ads_mod_add_var(mods, LDAP_MOD_DELETE, name, NULL); } -ADS_STATUS ads_mod_add(void **mods, char *name, char *val) +ADS_STATUS ads_mod_add(ADS_MODLIST *mods, char *name, char *val) { return ads_mod_add_var(mods, LDAP_MOD_ADD, name, val, NULL); } -void ads_free_mods(void **mods) +void ads_free_mods(ADS_MODLIST mods) { int i; LDAPMod **modlist = (LDAPMod **) mods; @@ -311,7 +318,7 @@ void ads_free_mods(void **mods) } } -ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, void **mods) +ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) { int ret,i; /* @@ -327,7 +334,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, void **mods) NULL }; /* find the end of the list, marked by NULL or -1 */ - for(i=0;mods[i]>0;i++); + 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, @@ -355,18 +362,27 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) } va_end(ap); - mods = malloc(sizeof(LDAPMod *) * (i+1)); + if (!(mods = malloc(sizeof(LDAPMod *) * (i+1)))) + return ADS_ERROR(LDAP_NO_MEMORY); va_start(ap, new_dn); for (i=0; (name=va_arg(ap, char *)); i++) { char **values; int j; - values = (char **)malloc(sizeof(char *) * (MAX_MOD_VALUES+1)); + if (!(values = + (char **)malloc(sizeof(char *) * (MAX_MOD_VALUES+1)))) { + free(mods); + return ADS_ERROR(LDAP_NO_MEMORY); + } for (j=0; (value=va_arg(ap, char *)) && j < MAX_MOD_VALUES; j++) { values[j] = value; } values[j] = NULL; - mods[i] = malloc(sizeof(LDAPMod)); + if (!(mods[i] = malloc(sizeof(LDAPMod)))) { + free(values); + free(mods); + return ADS_ERROR(LDAP_NO_MEMORY); + } mods[i]->mod_type = name; mods[i]->mod_op = LDAP_MOD_ADD; mods[i]->mod_values = values; -- cgit From a346cfb4677fcfcb5900e3a299bf7bc0bc76f758 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Tue, 12 Feb 2002 18:22:33 +0000 Subject: talloc'ify ads modify functions. Also add more complete berval support. (This used to be commit 1f186c60ad957c0e8157a6fd903857121c65a2e0) --- source3/libads/ldap.c | 241 +++++++++++++++++++++++++------------------------- 1 file changed, 119 insertions(+), 122 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e1d7d5d26c..682524eb4f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -143,14 +143,14 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) 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(char **values) +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] && imod_type = name; - modlist[curmod]->mod_values = values; + if (mod_op & LDAP_MOD_BVALUES) + modlist[curmod]->mod_bvalues = (struct berval **) values; + else + modlist[curmod]->mod_values = values; modlist[curmod]->mod_op = mod_op; return ADS_ERROR(LDAP_SUCCESS); } -ADS_STATUS ads_mod_add_list(ADS_MODLIST *mods, char *name, char **values) +ADS_STATUS ads_mod_add_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, + char *name, char **values) { - char **newvals = ads_dup_values(values); + char **newvals = ads_dup_values(ctx, values); if (newvals) - return ads_modlist_add(mods, LDAP_MOD_ADD, name, newvals); + return ads_modlist_add(ctx, mods, LDAP_MOD_ADD, name, newvals); else return ADS_ERROR(LDAP_NO_MEMORY); } -ADS_STATUS ads_mod_repl_list(ADS_MODLIST *mods, char *name, char **values) +ADS_STATUS ads_mod_repl_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, + char *name, char **values) { char **newvals; if (values && *values) { - if (!(newvals = ads_dup_values(values))) + if (!(newvals = ads_dup_values(ctx, values))) return ADS_ERROR(LDAP_NO_MEMORY); else - return ads_modlist_add(mods, LDAP_MOD_REPLACE, + return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, newvals); } else - return ads_modlist_add(mods, LDAP_MOD_DELETE, name, NULL); + return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); } /* add an attribute to the list, with values list to be built from args */ -ADS_STATUS ads_mod_add_var(ADS_MODLIST *mods, int mod_op, char *name, ...) +ADS_STATUS ads_mod_add_var(TALLOC_CTX *ctx, ADS_MODLIST *mods, + int mod_op, char *name, ...) { va_list ap; int num_vals, i, do_op; @@ -245,7 +250,7 @@ ADS_STATUS ads_mod_add_var(ADS_MODLIST *mods, int mod_op, char *name, ...) va_end(ap); if (num_vals) { - if (!(values = malloc(sizeof(char *) * (num_vals + 1)))) + 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 *)) && @@ -258,10 +263,11 @@ ADS_STATUS ads_mod_add_var(ADS_MODLIST *mods, int mod_op, char *name, ...) do_op = LDAP_MOD_DELETE; values = NULL; } - return ads_modlist_add(mods, do_op, name, values); + return ads_modlist_add(ctx, mods, do_op, name, values); } -ADS_STATUS ads_mod_add_ber(ADS_MODLIST *mods, int mod_op, char *name, ...) +ADS_STATUS ads_mod_add_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, + int mod_op, char *name, ...) { va_list ap; int num_vals, i, do_op; @@ -273,7 +279,8 @@ ADS_STATUS ads_mod_add_ber(ADS_MODLIST *mods, int mod_op, char *name, ...) va_end(ap); if (num_vals) { - if (!(values = malloc(sizeof(struct berval) * (num_vals + 1)))) + 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 *)) && @@ -287,34 +294,57 @@ ADS_STATUS ads_mod_add_ber(ADS_MODLIST *mods, int mod_op, char *name, ...) values = NULL; } do_op |= LDAP_MOD_BVALUES; - return ads_modlist_add(mods, do_op, name, values); + return ads_modlist_add(ctx, mods, do_op, name, values); } -ADS_STATUS ads_mod_repl(ADS_MODLIST *mods, char *name, char *val) +ADS_STATUS ads_mod_repl(TALLOC_CTX *ctx, ADS_MODLIST *mods, + char *name, char *val) { if (val) - return ads_mod_add_var(mods, LDAP_MOD_REPLACE, - name, val, NULL); + return ads_mod_add_var(ctx, mods, LDAP_MOD_REPLACE, + name, val, NULL); else - return ads_mod_add_var(mods, LDAP_MOD_DELETE, name, NULL); + return ads_mod_add_var(ctx, mods, LDAP_MOD_DELETE, name, NULL); } -ADS_STATUS ads_mod_add(ADS_MODLIST *mods, char *name, char *val) +ADS_STATUS ads_mod_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, + char *name, char *val) { - return ads_mod_add_var(mods, LDAP_MOD_ADD, name, val, NULL); + return ads_mod_add_var(ctx, mods, LDAP_MOD_ADD, name, val, NULL); } -void ads_free_mods(ADS_MODLIST mods) +ADS_STATUS ads_mod_add_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, + char *name, size_t size, char *val) { - int i; - LDAPMod **modlist = (LDAPMod **) mods; - - if (modlist) { - for (i = 0; modlist[i]; i++) { - SAFE_FREE(modlist[i]->mod_values); - SAFE_FREE(modlist[i]); - } - free(modlist); + 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); +} + +ADS_STATUS ads_mod_repl_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 (!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_ADD, name, + bval, NULL); } } @@ -342,63 +372,16 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) return ADS_ERROR(ret); } -/* - a convenient routine for adding a generic LDAP record -*/ -ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) +ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) { int i; - va_list ap; - LDAPMod **mods; - char *name, *value; - int ret; -#define MAX_MOD_VALUES 10 - - /* count the number of attributes */ - va_start(ap, new_dn); - for (i=0; va_arg(ap, char *); i++) { - /* skip the values */ - while (va_arg(ap, char *)) ; - } - va_end(ap); - if (!(mods = malloc(sizeof(LDAPMod *) * (i+1)))) - return ADS_ERROR(LDAP_NO_MEMORY); - - va_start(ap, new_dn); - for (i=0; (name=va_arg(ap, char *)); i++) { - char **values; - int j; - if (!(values = - (char **)malloc(sizeof(char *) * (MAX_MOD_VALUES+1)))) { - free(mods); - return ADS_ERROR(LDAP_NO_MEMORY); - } - for (j=0; (value=va_arg(ap, char *)) && j < MAX_MOD_VALUES; j++) { - values[j] = value; - } - values[j] = NULL; - if (!(mods[i] = malloc(sizeof(LDAPMod)))) { - free(values); - free(mods); - return ADS_ERROR(LDAP_NO_MEMORY); - } - mods[i]->mod_type = name; - mods[i]->mod_op = LDAP_MOD_ADD; - mods[i]->mod_values = values; - } + /* 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; - va_end(ap); - - ret = ldap_add_s(ads->ld, new_dn, mods); - for (i=0; mods[i]; i++) { - free(mods[i]->mod_values); - free(mods[i]); - } - free(mods); - - return ADS_ERROR(ret); + return ADS_ERROR(ldap_add_s(ads->ld, new_dn, mods)); } ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) @@ -432,37 +415,51 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ADS_STATUS ret; char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr; char *ou_str; + TALLOC_CTX *ctx; + ADS_MODLIST mods; - asprintf(&host_spn, "HOST/%s", hostname); - asprintf(&host_upn, "%s@%s", host_spn, ads->realm); + if (!(ctx = talloc_init_named("machine_account"))) + return ADS_ERROR(LDAP_NO_MEMORY); + + ret = ADS_ERROR(LDAP_NO_MEMORY); + + if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", hostname))) + goto done; + if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->realm))) + goto done; ou_str = ads_ou_string(org_unit); - asprintf(&new_dn, "cn=%s,%s,%s", hostname, ou_str, ads->bind_path); + new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str, + ads->bind_path); free(ou_str); - asprintf(&samAccountName, "%s$", hostname); - asprintf(&controlstr, "%u", - UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT | - UF_TRUSTED_FOR_DELEGATION | UF_USE_DES_KEY_ONLY); - - ret = ads_gen_add(ads, new_dn, - "cn", hostname, NULL, - "sAMAccountName", samAccountName, NULL, - "objectClass", - "top", "person", "organizationalPerson", - "user", "computer", NULL, - "userPrincipalName", host_upn, NULL, - "servicePrincipalName", host_spn, NULL, - "dNSHostName", hostname, NULL, - "userAccountControl", controlstr, NULL, - "operatingSystem", "Samba", NULL, - "operatingSystemVersion", VERSION, NULL, - NULL); - - free(host_spn); - free(host_upn); - free(new_dn); - free(samAccountName); - free(controlstr); - + if (!new_dn) + goto done; + + if (!(samAccountName = talloc_asprintf(ctx, "%s$", hostname))) + goto done; + if (!(controlstr = talloc_asprintf(ctx, "%u", + UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT | + UF_TRUSTED_FOR_DELEGATION | UF_USE_DES_KEY_ONLY))) + goto done; + + 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); + + ret = ads_gen_add(ads, new_dn, mods); + +done: + talloc_destroy(ctx); return ret; } -- cgit From 9fc99e3c552a6747a83877bda0410c951d272b81 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 13 Feb 2002 15:00:39 +0000 Subject: Fix LDAP modification operation. Cut and paste error: was LDAP_MOD_ADD, should be LDAP_MOD_REPLACE. Caught by Alexey Kotovich. (This used to be commit be48a05ed95f0f4ed02ffb996cb1ecc10811d9a0) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 682524eb4f..763f1bc354 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -343,7 +343,7 @@ ADS_STATUS ads_mod_repl_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, 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, + return ads_mod_add_ber(ctx, mods, LDAP_MOD_REPLACE, name, bval, NULL); } } -- cgit From 23e6fc25e2ed11d09be127dd40f0f05fa4a94f3a Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Mon, 4 Mar 2002 01:07:02 +0000 Subject: fix for IRIX compile error (This used to be commit 2d620909f9def17dacf2af997a32d596f4dbd827) --- source3/libads/ldap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 763f1bc354..ef1902960f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -359,9 +359,10 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) "1.2.840.113556.1.4.1413", {0, NULL}, (char) 1}; - LDAPControl *controls[2] = { - &PermitModify, - NULL }; + LDAPControl *controls[2]; + + controls[0] = &PermitModify; + controls[1] = NULL; /* find the end of the list, marked by NULL or -1 */ for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); -- cgit From cfbbf736777aca366e388882a389a214b87ca612 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 10 Mar 2002 01:54:44 +0000 Subject: yipee! Finally put in the patch from Alexey Kotovich that adds the security decsriptor code for ADS workstation accounts thanks for your patience Cat, and thanks to Andrew Bartlett for extensive reviews and suggestions about this code. (This used to be commit 6891393b5db868246fe52ff62b3dc6aa5ca6f726) --- source3/libads/ldap.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 121 insertions(+), 8 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ef1902960f..a8f9298b0f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -180,7 +180,7 @@ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx) 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, char *name, char **values) + int mod_op, const char *name, char **values) { int curmod; LDAPMod **modlist = (LDAPMod **) *mods; @@ -238,7 +238,7 @@ ADS_STATUS ads_mod_repl_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, add an attribute to the list, with values list to be built from args */ ADS_STATUS ads_mod_add_var(TALLOC_CTX *ctx, ADS_MODLIST *mods, - int mod_op, char *name, ...) + int mod_op, const char *name, ...) { va_list ap; int num_vals, i, do_op; @@ -267,7 +267,7 @@ ADS_STATUS ads_mod_add_var(TALLOC_CTX *ctx, ADS_MODLIST *mods, } ADS_STATUS ads_mod_add_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, - int mod_op, char *name, ...) + int mod_op, const char *name, ...) { va_list ap; int num_vals, i, do_op; @@ -308,7 +308,7 @@ ADS_STATUS ads_mod_repl(TALLOC_CTX *ctx, ADS_MODLIST *mods, } ADS_STATUS ads_mod_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, char *val) + const char *name, const char *val) { return ads_mod_add_var(ctx, mods, LDAP_MOD_ADD, name, val, NULL); } @@ -329,7 +329,7 @@ ADS_STATUS ads_mod_add_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, } ADS_STATUS ads_mod_repl_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, size_t size, char *val) + const char *name, size_t size, char *val) { struct berval *bval = NULL; @@ -457,7 +457,8 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ads_mod_add(ctx, &mods, "operatingSystem", "Samba"); ads_mod_add(ctx, &mods, "operatingSystemVersion", VERSION); - ret = ads_gen_add(ads, new_dn, mods); + ads_gen_add(ads, new_dn, mods); + ret = ads_set_machine_sd(ads, hostname, new_dn); done: talloc_destroy(ctx); @@ -492,6 +493,36 @@ static void dump_sid(const char *field, struct berval **values) } } +/* + dump ntSecurityDescriptor +*/ +static void dump_sd(const char *filed, struct berval **values) +{ + prs_struct ps; + + SEC_DESC *psd = 0; + TALLOC_CTX *ctx = 0; + + if (!(ctx = talloc_init_named("sec_io_desc"))) + return; + + /* prepare data */ + prs_init(&ps, values[0]->bv_len, ctx, UNMARSHALL); + prs_append_data(&ps, values[0]->bv_val, values[0]->bv_len); + ps.data_offset = 0; + + /* parse secdesc */ + if (!sec_io_desc("sd", &psd, &ps, 1)) { + prs_mem_free(&ps); + talloc_destroy(ctx); + return; + } + if (psd) ads_disp_sd(psd); + + prs_mem_free(&ps); + talloc_destroy(ctx); +} + /* dump a string result from ldap */ @@ -517,7 +548,7 @@ void ads_dump(ADS_STRUCT *ads, void *res) void (*handler)(const char *, struct berval **); } handlers[] = { {"objectGUID", dump_binary}, - {"nTSecurityDescriptor", dump_binary}, + {"nTSecurityDescriptor", dump_sd}, {"objectSid", dump_sid}, {NULL, NULL} }; @@ -573,7 +604,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org status = ads_find_machine_acct(ads, (void **)&res, host); if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { - DEBUG(0, ("Host account for %s already exists - deleting for readd\n", host)); + DEBUG(0, ("Host account for %s already exists - deleting old account\n", host)); status = ads_leave_realm(ads, host); if (!ADS_ERR_OK(status)) { DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n", @@ -637,6 +668,83 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return status; } +/* + add machine account to existing security descriptor +*/ +ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) +{ + const char *attrs[] = {"ntSecurityDescriptor", "objectSid", 0}; + char *exp = 0; + size_t sd_size = 0; + struct berval **bvals = 0; + prs_struct ps; + prs_struct ps_wire; + + LDAPMessage *res = 0; + LDAPMessage *msg = 0; + ADS_MODLIST mods = 0; + + NTSTATUS status; + ADS_STATUS ret; + DOM_SID sid; + SEC_DESC *psd = 0; + TALLOC_CTX *ctx = 0; + + if (!ads) return ADS_ERROR(LDAP_SERVER_DOWN); + + ret = ADS_ERROR(LDAP_SUCCESS); + + asprintf(&exp, "(samAccountName=%s$)", hostname); + ret = ads_search(ads, (void *) &res, exp, attrs); + + if (!ADS_ERR_OK(ret)) return ret; + + msg = ads_first_entry(ads, res); + bvals = ldap_get_values_len(ads->ld, msg, attrs[0]); + ads_pull_sid(ads, msg, attrs[1], &sid); + ads_msgfree(ads, res); +#if 0 + file_save("/tmp/sec_desc.old", bvals[0]->bv_val, bvals[0]->bv_len); +#endif + if (!(ctx = talloc_init_named("sec_io_desc"))) + return ADS_ERROR(LDAP_NO_MEMORY); + + prs_init(&ps, bvals[0]->bv_len, ctx, UNMARSHALL); + prs_append_data(&ps, bvals[0]->bv_val, bvals[0]->bv_len); + ps.data_offset = 0; + ldap_value_free_len(bvals); + + if (!sec_io_desc("sd", &psd, &ps, 1)) + goto ads_set_sd_error; + + status = sec_desc_add_sid(ctx, &psd, &sid, SEC_RIGHTS_FULL_CTRL, &sd_size); + + if (!NT_STATUS_IS_OK(status)) + goto ads_set_sd_error; + + prs_init(&ps_wire, sd_size, ctx, MARSHALL); + if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1)) + goto ads_set_sd_error; + +#if 0 + file_save("/tmp/sec_desc.new", ps_wire.data_p, sd_size); +#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); + ret = ads_gen_mod(ads, dn, mods); + + prs_mem_free(&ps); + prs_mem_free(&ps_wire); + talloc_destroy(ctx); + return ret; + +ads_set_sd_error: + prs_mem_free(&ps); + prs_mem_free(&ps_wire); + talloc_destroy(ctx); + return ADS_ERROR(LDAP_NO_MEMORY); +} ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, const char *hostname, @@ -646,6 +754,11 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, char *host = strdup(hostname); char *principal; + if (!ads->kdc_server) { + DEBUG(0, ("Unable to find KDC server\n")); + return ADS_ERROR(LDAP_SERVER_DOWN); + } + strlower(host); asprintf(&principal, "%s@%s", host, ads->realm); -- cgit From bd3a6e6cc984e91621f06a52ddc87909d9d83abc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 11 Mar 2002 04:06:30 +0000 Subject: put in the ADS DNS hack, but commented out (This used to be commit 3396a671c59e6afe70a22ce64e4a9381b1d6fef8) --- source3/libads/ldap.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a8f9298b0f..aa6e7c0036 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -47,6 +47,17 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); +#if KRB5_DNS_HACK + /* this is a really nasty hack to avoid ADS DNS problems. It needs a patch + to MIT kerberos to work (tridge) */ + { + char *env; + asprintf(&env, "KRB5_KDC_ADDRESS_%s", ads->server_realm); + setenv(env, inet_ntoa(*interpret_addr2(ads->ldap_server)), 1); + free(env); + } +#endif + if (ads->password) { if ((code = ads_kinit_password(ads))) return ADS_ERROR_KRB5(code); -- cgit From 2001b83faa9f0438adda40ffe12fea4a3dc6a733 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Mar 2002 06:43:52 +0000 Subject: detect SIZELIMIT_EXCEEDED in ldap queries and truncate the problem is, how the heck do we properly handle these? Jerry? It seems that the Win2000 ADS server only returns a max of 1000 records! (This used to be commit 93389647203395da0e894c2e57348081e755884a) --- source3/libads/ldap.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index aa6e7c0036..e53f6d87db 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -84,6 +84,10 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, bind_path, scope, exp, (char **) attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); + if (rc == LDAP_SIZELIMIT_EXCEEDED) { + DEBUG(3,("Warning! sizelimit exceeded in ldap. Truncating.\n")); + rc = 0; + } return ADS_ERROR(rc); } /* -- cgit From 0640a5ceeb974f06dc29669bdbce75fcf7154439 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 14 Mar 2002 17:48:26 +0000 Subject: This adds the Paged Result Control to ads searching. The new function, ads_do_paged_search, is the same as ads_do_search, but it also contains a count of records returned in this page, and a cookie for resuming, to be passed back. The cookie must start off NULL, and when it returns as NULL, the search is done. (This used to be commit 9afba67f9a56699e34735e1e425f97b2464f2402) --- source3/libads/ldap.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e53f6d87db..28970e8fa9 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -66,6 +66,83 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) return ads_sasl_bind(ads); } +/* Do a search with paged results. cookie must be null on the first + call, and then returned on each subsequent call. It will be null + again when the entire search is complete */ + +ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *exp, + const char **attrs, void **res, + int *count, void **cookie) +{ + int rc; +#define ADS_PAGE_CTL_OID "1.2.840.113556.1.4.319" + int version; + LDAPControl PagedResults; + BerElement *berelem = NULL; + struct berval *berval = NULL; + LDAPControl *controls[2]; + LDAPControl **rcontrols, *cur_control; + + *res = NULL; + + 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); + + berelem = ber_alloc_t(LBER_USE_DER); + if (cookie && *cookie) { + ber_printf(berelem, "{iO}", (ber_int_t) 256, *cookie); + ber_bvfree(*cookie); /* don't need it from last time */ + } else { + ber_printf(berelem, "{io}", (ber_int_t) 256, "", 0); + } + ber_flatten(berelem, &berval); + PagedResults.ldctl_oid = ADS_PAGE_CTL_OID; + PagedResults.ldctl_iscritical = (char) 1; + PagedResults.ldctl_value.bv_len = berval->bv_len; + PagedResults.ldctl_value.bv_val = berval->bv_val; + + controls[0] = &PagedResults; + controls[1] = NULL; + + *res = NULL; + + rc = ldap_search_ext_s(ads->ld, bind_path, scope, exp, + (char **) attrs, 0, controls, NULL, + NULL, LDAP_NO_LIMIT, + (LDAPMessage **)res); + ber_free(berelem, 1); + ber_bvfree(berval); + + rc = ldap_parse_result(ads->ld, *res, NULL, NULL, NULL, + NULL, &rcontrols, 0); + + for (cur_control=rcontrols[0]; cur_control; cur_control++) { + if (strcmp(ADS_PAGE_CTL_OID, cur_control->ldctl_oid) == 0) { + berelem = ber_init(&cur_control->ldctl_value); + ber_scanf(berelem,"{iO}", (ber_int_t *) count, + &berval); + /* the berval is the cookie, but must be freed when + it is all done */ + if (berval->bv_len) /* still more to do */ + *cookie=ber_bvdup(berval); + else + *cookie=NULL; + ber_bvfree(berval); + ber_free(berelem, 1); + break; + } + } + ldap_controls_free(rcontrols); + + return ADS_ERROR(rc); +} + /* do a search with a timeout */ @@ -84,10 +161,12 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, bind_path, scope, exp, (char **) attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); + if (rc == LDAP_SIZELIMIT_EXCEEDED) { DEBUG(3,("Warning! sizelimit exceeded in ldap. Truncating.\n")); rc = 0; } + return ADS_ERROR(rc); } /* -- cgit From f464ceb109bc9bdc288e0219c4b83da15ba6f1fc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 19 Mar 2002 12:58:38 +0000 Subject: fixed paged controls on my box. The problem seems to be incorrect referrals parsing in the openldap libs. By disabling referrals we get valid controls back and the cookies work. (This used to be commit 8bf487ddff240150d7a92aaa0f978dd30062c331) --- source3/libads/ldap.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 28970e8fa9..8d865dd113 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -66,6 +66,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) return ads_sasl_bind(ads); } + /* Do a search with paged results. cookie must be null on the first call, and then returned on each subsequent call. It will be null again when the entire search is complete */ @@ -96,10 +97,10 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, berelem = ber_alloc_t(LBER_USE_DER); if (cookie && *cookie) { - ber_printf(berelem, "{iO}", (ber_int_t) 256, *cookie); + ber_printf(berelem, "{iO}", (ber_int_t) 1000, *cookie); ber_bvfree(*cookie); /* don't need it from last time */ } else { - ber_printf(berelem, "{io}", (ber_int_t) 256, "", 0); + ber_printf(berelem, "{io}", (ber_int_t) 1000, "", 0); } ber_flatten(berelem, &berval); PagedResults.ldctl_oid = ADS_PAGE_CTL_OID; @@ -111,17 +112,33 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, controls[1] = NULL; *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) */ + ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); + rc = ldap_search_ext_s(ads->ld, bind_path, scope, exp, (char **) attrs, 0, controls, NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); + + if (rc) { + DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", exp, ldap_err2string(rc))); + return ADS_ERROR(rc); + } + ber_free(berelem, 1); ber_bvfree(berval); - + rc = ldap_parse_result(ads->ld, *res, NULL, NULL, NULL, NULL, &rcontrols, 0); + if (!rcontrols) { + return ADS_ERROR(rc); + } + for (cur_control=rcontrols[0]; cur_control; cur_control++) { if (strcmp(ADS_PAGE_CTL_OID, cur_control->ldctl_oid) == 0) { berelem = ber_init(&cur_control->ldctl_value); -- cgit From b462700e53df7fa64a4cd019054eae9e7f746aef Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 19 Mar 2002 22:14:53 +0000 Subject: added a ads_do_search_all() call, which is a more convenient interface to paged searches. This makes updating winbindd to used paged searches trivial. (This used to be commit 514c11b4e3fcc765a8087405333bd351c05c9e36) --- source3/libads/ldap.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8d865dd113..c8661c2ebb 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -99,6 +99,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, if (cookie && *cookie) { ber_printf(berelem, "{iO}", (ber_int_t) 1000, *cookie); ber_bvfree(*cookie); /* don't need it from last time */ + *cookie = NULL; } else { ber_printf(berelem, "{io}", (ber_int_t) 1000, "", 0); } @@ -160,6 +161,47 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, return ADS_ERROR(rc); } + +/* + this uses ads_do_paged_search() to return all entries in a large + search. The interface is the same as ads_do_search(), which makes + it more convenient than the paged interface + */ +ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *exp, + const char **attrs, void **res) +{ + void *cookie = NULL; + int count = 0; + ADS_STATUS status; + + status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, res, &count, &cookie); + + if (!ADS_ERR_OK(status)) return status; + + while (cookie) { + void *res2 = NULL; + ADS_STATUS status2; + LDAPMessage *msg, *next; + + status2 = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res2, &count, &cookie); + + if (!ADS_ERR_OK(status2)) break; + + /* this relies on the way that ldap_add_result_entry() works internally. I hope + that this works on all ldap libs, but I have only tested with openldap */ + for (msg = ads_first_entry(ads, res2); msg; msg = next) { + 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 */ + } + + return status; +} + /* do a search with a timeout */ -- cgit From 1a06eeb6dae9b148a6e70470660e51a42def2399 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 27 Mar 2002 02:58:58 +0000 Subject: Add server control to prevent referrals in paged searches. This keeps the scope limited to the domain at hand, and also keeps the openldap libs happy, since they don't currently chase referrals and return server controls properly at the same time. (This used to be commit 2bebc8a391bd80bd0e5adbedb3757fb4279ec414) --- source3/libads/ldap.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c8661c2ebb..92898bc4db 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -78,11 +78,13 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, { int rc; #define ADS_PAGE_CTL_OID "1.2.840.113556.1.4.319" +#define ADS_NO_REFERRALS_OID "1.2.840.113556.1.4.1339" int version; LDAPControl PagedResults; + LDAPControl NoReferrals; BerElement *berelem = NULL; struct berval *berval = NULL; - LDAPControl *controls[2]; + LDAPControl *controls[3]; LDAPControl **rcontrols, *cur_control; *res = NULL; @@ -105,19 +107,29 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, } ber_flatten(berelem, &berval); PagedResults.ldctl_oid = ADS_PAGE_CTL_OID; - PagedResults.ldctl_iscritical = (char) 1; + PagedResults.ldctl_iscritical = (char) 0; PagedResults.ldctl_value.bv_len = berval->bv_len; PagedResults.ldctl_value.bv_val = berval->bv_val; - - controls[0] = &PagedResults; - controls[1] = NULL; + + NoReferrals.ldctl_oid = ADS_NO_REFERRALS_OID; + NoReferrals.ldctl_iscritical = (char) 0; + NoReferrals.ldctl_value.bv_len = 0; + NoReferrals.ldctl_value.bv_val = ""; + + controls[0] = &NoReferrals; + controls[1] = &PagedResults; + controls[2] = NULL; *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) */ + result list (tridge) + + 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, -- cgit From 90ada79bbf227afd18e585b203dc1b46166a1318 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 27 Mar 2002 03:09:50 +0000 Subject: Whoops, left the paged control not critical in the paged search...kind of defeats the purpose. (This used to be commit 71806c49b366faf2466eee7352c71fcdfefd8cc1) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 92898bc4db..431c32a35c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -107,7 +107,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, } ber_flatten(berelem, &berval); PagedResults.ldctl_oid = ADS_PAGE_CTL_OID; - PagedResults.ldctl_iscritical = (char) 0; + PagedResults.ldctl_iscritical = (char) 1; PagedResults.ldctl_value.bv_len = berval->bv_len; PagedResults.ldctl_value.bv_val = berval->bv_val; -- cgit From 2ed1dfcf4e467a2816f3b768c8b37f2cdf3c7758 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 29 Mar 2002 21:06:33 +0000 Subject: Added ads_process_results(), which takes a function that is called for each entry returned from a search, and applies it to the results. Re-structured ads_dump to use this, plus changed the ber_free in ads_dump from (b,1) to (b,0), in accordance with openldap manpages. Also allows proper free of result using ldap_msgfree afterwards, so you can do something with the results after an ads_dump. (This used to be commit f01f02fc569b4f5101a37d3b493f2fe2d2b2677a) --- source3/libads/ldap.c | 93 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 73 insertions(+), 20 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 431c32a35c..9670327dbe 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -700,14 +700,12 @@ static void dump_string(const char *field, struct berval **values) } /* - dump a record from LDAP on stdout + dump a field from LDAP on stdout used for debugging */ -void ads_dump(ADS_STRUCT *ads, void *res) + +static void ads_dump_field(char *field, void **values, void *data_area) { - char *field; - void *msg; - BerElement *b; struct { char *name; void (*handler)(const char *, struct berval **); @@ -717,34 +715,89 @@ void ads_dump(ADS_STRUCT *ads, void *res) {"objectSid", dump_sid}, {NULL, NULL} }; - - for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { + int i; + + if (!field) { /* must be end of an entry */ + printf("\n"); + return; + } + + for (i=0; handlers[i].name; i++) { + if (StrCaseCmp(handlers[i].name, field) == 0) { + handlers[i].handler(field, (struct berval **) values); + break; + } + } + if (!handlers[i].name) { + dump_string(field, (struct berval **) values); + } +} + +/* + dump a result from LDAP on stdout + used for debugging +*/ + +void ads_dump(ADS_STRUCT *ads, void *res) +{ + ads_process_results(ads, res, ads_dump_field, NULL); +} + +/* + Walk through results, calling a function for each entry found. + The function receives a field name, a berval * array of values, + and a data area passed through from the start. The function is + called once with null for field and values at the end of each + entry. +*/ +void ads_process_results(ADS_STRUCT *ads, void *res, + void(*fn)(char *, void **, void *), + void *data_area) +{ + void *msg; + + for (msg = ads_first_entry(ads, res); msg; + msg = ads_next_entry(ads, msg)) { + 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; - int i; - + values = ldap_get_values_len(ads->ld, (LDAPMessage *)msg, field); + fn(field, (void **) values, data_area); - for (i=0; handlers[i].name; i++) { - if (StrCaseCmp(handlers[i].name, field) == 0) { - handlers[i].handler(field, values); - break; - } - } - if (!handlers[i].name) { - dump_string(field, values); - } ldap_value_free_len(values); ldap_memfree(field); } + ber_free(b, 0); + fn(NULL, NULL, data_area); /* completed an entry */ - ber_free(b, 1); - printf("\n"); } } +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 */ -- cgit From 417b1ce487c1db77c389587f9c187dc107d3dce4 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 4 Apr 2002 02:49:30 +0000 Subject: Add ads_err2string() function for generating error strings from an ADS_STATUS. I've got the cases besides gssapi...anyone know how to get those? (This used to be commit c937e1352207ad90e8257ad6c9f8b7c9cf92030d) --- source3/libads/ldap.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 9670327dbe..57fd3305e7 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -66,6 +66,21 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) return ads_sasl_bind(ads); } +char *ads_err2string(ADS_STATUS status) +{ + switch(status.error_type) { + case ADS_ERROR_LDAP: + return ldap_err2string(status.rc); + case ADS_ERROR_KRB5: + return error_message(status.rc); + case ADS_ERROR_GSS: + return "gssapi error"; + case ADS_ERROR_SYSTEM: + return strerror(status.rc); + default: + return "unknown error"; + } +} /* Do a search with paged results. cookie must be null on the first call, and then returned on each subsequent call. It will be null -- cgit From f21ccff91fe9dd37a57c6505fc19b7fc2c103a59 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 4 Apr 2002 03:03:00 +0000 Subject: Try harder next time to not duplicate function...take ads_err2string back out since it's already in ads_errstr() in ads_status.c (This used to be commit 0475126ffb69f0485fd31511cb13d98df74a8d5b) --- source3/libads/ldap.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 57fd3305e7..9670327dbe 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -66,21 +66,6 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) return ads_sasl_bind(ads); } -char *ads_err2string(ADS_STATUS status) -{ - switch(status.error_type) { - case ADS_ERROR_LDAP: - return ldap_err2string(status.rc); - case ADS_ERROR_KRB5: - return error_message(status.rc); - case ADS_ERROR_GSS: - return "gssapi error"; - case ADS_ERROR_SYSTEM: - return strerror(status.rc); - default: - return "unknown error"; - } -} /* Do a search with paged results. cookie must be null on the first call, and then returned on each subsequent call. It will be null -- cgit From 40260fdaf906d7f4d71a461f294e3c99b564d13c Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 5 Apr 2002 19:26:52 +0000 Subject: Several updates to get server side sorting going: - Added sort control to ads_do_paged_search. It allows a char * to be passed as the sort key. If NULL, no sort is done. - fixed a bug in the processing of controls (loop wasn't incremented properly) - Added ads_do_search_all2, which funs a function that is passed in against each entry. No ldapmessage structures are returned. Allows results to be processed as the come in on each page. I'd like ads_do_search_all2 to replace ads_do_search_all, but there's some work to be done in winbindd_ads.c first. Also, perhaps now we can do async ldap searches? Allow us to process a page while the server retrieves the next one? (This used to be commit 95bec4c8bae0e29f816ec0751bf66404e1f2098e) --- source3/libads/ldap.c | 104 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 78 insertions(+), 26 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 9670327dbe..82b7d7568c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -74,18 +74,21 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, const char **attrs, void **res, - int *count, void **cookie) + int *count, void **cookie, const char *sort) { int rc; #define ADS_PAGE_CTL_OID "1.2.840.113556.1.4.319" #define ADS_NO_REFERRALS_OID "1.2.840.113556.1.4.1339" +#define ADS_SERVER_SORT_OID "1.2.840.113556.1.4.473" int version; LDAPControl PagedResults; LDAPControl NoReferrals; - BerElement *berelem = NULL; - struct berval *berval = NULL; - LDAPControl *controls[3]; - LDAPControl **rcontrols, *cur_control; + LDAPControl ServerSort; + BerElement *cookie_be = NULL, *sort_be = NULL; + struct berval *cookie_bv= NULL, *sort_bv = NULL; + LDAPControl *controls[4]; + LDAPControl **rcontrols; + int i; *res = NULL; @@ -97,28 +100,39 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, if (version < LDAP_VERSION3) return ADS_ERROR(LDAP_NOT_SUPPORTED); - berelem = ber_alloc_t(LBER_USE_DER); + cookie_be = ber_alloc_t(LBER_USE_DER); if (cookie && *cookie) { - ber_printf(berelem, "{iO}", (ber_int_t) 1000, *cookie); + ber_printf(cookie_be, "{iO}", (ber_int_t) 1000, *cookie); ber_bvfree(*cookie); /* don't need it from last time */ *cookie = NULL; } else { - ber_printf(berelem, "{io}", (ber_int_t) 1000, "", 0); + ber_printf(cookie_be, "{io}", (ber_int_t) 1000, "", 0); } - ber_flatten(berelem, &berval); + ber_flatten(cookie_be, &cookie_bv); PagedResults.ldctl_oid = ADS_PAGE_CTL_OID; PagedResults.ldctl_iscritical = (char) 1; - PagedResults.ldctl_value.bv_len = berval->bv_len; - PagedResults.ldctl_value.bv_val = berval->bv_val; + PagedResults.ldctl_value.bv_len = cookie_bv->bv_len; + PagedResults.ldctl_value.bv_val = cookie_bv->bv_val; NoReferrals.ldctl_oid = ADS_NO_REFERRALS_OID; NoReferrals.ldctl_iscritical = (char) 0; NoReferrals.ldctl_value.bv_len = 0; NoReferrals.ldctl_value.bv_val = ""; + if (sort && *sort) { + sort_be = ber_alloc_t(LBER_USE_DER); + ber_printf(sort_be, "{{s}}", sort); + ber_flatten(sort_be, &sort_bv); + ServerSort.ldctl_oid = ADS_SERVER_SORT_OID; + ServerSort.ldctl_iscritical = (char) 0; + ServerSort.ldctl_value.bv_len = sort_bv->bv_len; + ServerSort.ldctl_value.bv_val = sort_bv->bv_val; + } + controls[0] = &NoReferrals; controls[1] = &PagedResults; - controls[2] = NULL; + controls[2] = (sort && *sort) ? &ServerSort : NULL; + controls[3] = NULL; *res = NULL; @@ -137,14 +151,18 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); + ber_free(cookie_be, 1); + ber_bvfree(cookie_bv); + if (sort && *sort) { + ber_free(sort_be, 1); + ber_bvfree(sort_bv); + } + if (rc) { DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", exp, ldap_err2string(rc))); return ADS_ERROR(rc); } - ber_free(berelem, 1); - ber_bvfree(berval); - rc = ldap_parse_result(ads->ld, *res, NULL, NULL, NULL, NULL, &rcontrols, 0); @@ -152,19 +170,19 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, return ADS_ERROR(rc); } - for (cur_control=rcontrols[0]; cur_control; cur_control++) { - if (strcmp(ADS_PAGE_CTL_OID, cur_control->ldctl_oid) == 0) { - berelem = ber_init(&cur_control->ldctl_value); - ber_scanf(berelem,"{iO}", (ber_int_t *) count, - &berval); + for (i=0; rcontrols[i]; i++) { + if (strcmp(ADS_PAGE_CTL_OID, rcontrols[i]->ldctl_oid) == 0) { + cookie_be = ber_init(&rcontrols[i]->ldctl_value); + ber_scanf(cookie_be,"{iO}", (ber_int_t *) count, + &cookie_bv); /* the berval is the cookie, but must be freed when it is all done */ - if (berval->bv_len) /* still more to do */ - *cookie=ber_bvdup(berval); + if (cookie_bv->bv_len) /* still more to do */ + *cookie=ber_bvdup(cookie_bv); else *cookie=NULL; - ber_bvfree(berval); - ber_free(berelem, 1); + ber_bvfree(cookie_bv); + ber_free(cookie_be, 1); break; } } @@ -187,7 +205,7 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, int count = 0; ADS_STATUS status; - status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, res, &count, &cookie); + status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, res, &count, &cookie, NULL); if (!ADS_ERR_OK(status)) return status; @@ -196,7 +214,7 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, ADS_STATUS status2; LDAPMessage *msg, *next; - status2 = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res2, &count, &cookie); + status2 = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res2, &count, &cookie, NULL); if (!ADS_ERR_OK(status2)) break; @@ -214,6 +232,40 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, return status; } +/* same as ads_do_search_all, but runs a function on each result, rather + than returning it. Needed to get sorting working, as the merging of + ads_do_search_all messes it up. This should eventually replace it. */ + +ADS_STATUS ads_do_search_all2(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *exp, + const char **attrs, const char *sort, + void(*fn)(char *, void **, void *), + void *data_area) +{ + void *cookie = NULL; + int count = 0; + ADS_STATUS status; + void *res; + + status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res, &count, &cookie, sort); + + if (!ADS_ERR_OK(status)) return status; + + ads_process_results(ads, res, fn, data_area); + ads_msgfree(ads, res); + + while (cookie) { + status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res, &count, &cookie, NULL); + + if (!ADS_ERR_OK(status)) break; + + ads_process_results(ads, res, fn, data_area); + ads_msgfree(ads, res); + } + + return status; +} + /* do a search with a timeout */ -- cgit From 69f41523b39f0bf487b719da2905793a5bd292ee Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 10 Apr 2002 13:28:03 +0000 Subject: A few more updates: - Add doxygen comments - remove server sort control (ms implementation was not reliable) - rename ads_do_search_all2() to ads_do_search_all_fn() (This used to be commit 7aa5fa617221019de0f4565d07842df72673e154) --- source3/libads/ldap.c | 480 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 348 insertions(+), 132 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 82b7d7568c..e2e351bd4b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -24,9 +24,19 @@ #ifdef HAVE_ADS -/* - connect to the LDAP server -*/ +/** + * @file ldap.c + * @brief basic ldap client-side routines for ads server communications + * + * The routines contained here should do the necessary ldap calls for + * ads setups. + **/ + +/** + * Connect to the LDAP server + * @param ads Pointer to an existing ADS_STRUCT + * @return status of connection + **/ ADS_STATUS ads_connect(ADS_STRUCT *ads) { int version = LDAP_VERSION3; @@ -67,26 +77,32 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) } -/* Do a search with paged results. cookie must be null on the first - call, and then returned on each subsequent call. It will be null - again when the entire search is complete */ - +/** + * Do a search with paged results. cookie must be null on the first + * call, and then returned on each subsequent call. It will be null + * again when the entire search is complete + * @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 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 + * @return status of search + **/ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, const char **attrs, void **res, - int *count, void **cookie, const char *sort) + int *count, void **cookie) { int rc; -#define ADS_PAGE_CTL_OID "1.2.840.113556.1.4.319" -#define ADS_NO_REFERRALS_OID "1.2.840.113556.1.4.1339" -#define ADS_SERVER_SORT_OID "1.2.840.113556.1.4.473" int version; LDAPControl PagedResults; LDAPControl NoReferrals; - LDAPControl ServerSort; - BerElement *cookie_be = NULL, *sort_be = NULL; - struct berval *cookie_bv= NULL, *sort_bv = NULL; - LDAPControl *controls[4]; + BerElement *cookie_be = NULL; + struct berval *cookie_bv= NULL; + LDAPControl *controls[3]; LDAPControl **rcontrols; int i; @@ -119,20 +135,10 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, NoReferrals.ldctl_value.bv_len = 0; NoReferrals.ldctl_value.bv_val = ""; - if (sort && *sort) { - sort_be = ber_alloc_t(LBER_USE_DER); - ber_printf(sort_be, "{{s}}", sort); - ber_flatten(sort_be, &sort_bv); - ServerSort.ldctl_oid = ADS_SERVER_SORT_OID; - ServerSort.ldctl_iscritical = (char) 0; - ServerSort.ldctl_value.bv_len = sort_bv->bv_len; - ServerSort.ldctl_value.bv_val = sort_bv->bv_val; - } controls[0] = &NoReferrals; controls[1] = &PagedResults; - controls[2] = (sort && *sort) ? &ServerSort : NULL; - controls[3] = NULL; + controls[2] = NULL; *res = NULL; @@ -153,10 +159,6 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, ber_free(cookie_be, 1); ber_bvfree(cookie_bv); - if (sort && *sort) { - ber_free(sort_be, 1); - ber_bvfree(sort_bv); - } if (rc) { DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", exp, ldap_err2string(rc))); @@ -192,11 +194,17 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, } -/* - this uses ads_do_paged_search() to return all entries in a large - search. The interface is the same as ads_do_search(), which makes - it more convenient than the paged interface - */ +/** + * Get all results for a search. This uses ads_do_paged_search() to return + * all entries in a large search. + * @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 res ** which will contain results - free res* with ads_msgfree() + * @return status of search + **/ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, const char **attrs, void **res) @@ -205,7 +213,8 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, int count = 0; ADS_STATUS status; - status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, res, &count, &cookie, NULL); + status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, res, + &count, &cookie); if (!ADS_ERR_OK(status)) return status; @@ -214,7 +223,8 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, ADS_STATUS status2; LDAPMessage *msg, *next; - status2 = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res2, &count, &cookie, NULL); + status2 = ads_do_paged_search(ads, bind_path, scope, exp, + attrs, &res2, &count, &cookie); if (!ADS_ERR_OK(status2)) break; @@ -232,22 +242,30 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, return status; } -/* same as ads_do_search_all, but runs a function on each result, rather - than returning it. Needed to get sorting working, as the merging of - ads_do_search_all messes it up. This should eventually replace it. */ - -ADS_STATUS ads_do_search_all2(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *exp, - const char **attrs, const char *sort, - void(*fn)(char *, void **, void *), - void *data_area) +/** + * Run a function on all results for a search. Uses ads_do_paged_search() and + * runs the function as each page is returned, using ads_process_results() + * @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 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 *), + void *data_area) { void *cookie = NULL; int count = 0; ADS_STATUS status; void *res; - status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res, &count, &cookie, sort); + status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res, + &count, &cookie); if (!ADS_ERR_OK(status)) return status; @@ -255,7 +273,8 @@ ADS_STATUS ads_do_search_all2(ADS_STRUCT *ads, const char *bind_path, ads_msgfree(ads, res); while (cookie) { - status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res, &count, &cookie, NULL); + status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, + &res, &count, &cookie); if (!ADS_ERR_OK(status)) break; @@ -266,9 +285,16 @@ ADS_STATUS ads_do_search_all2(ADS_STRUCT *ads, const char *bind_path, return status; } -/* - do a search with a timeout -*/ +/** + * Do a search with a timeout. + * @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 res ** which will contain results - free res* with ads_msgfree() + * @return status of search + **/ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp, const char **attrs, void **res) @@ -292,9 +318,14 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, return ADS_ERROR(rc); } -/* - do a general ADS search -*/ +/** + * Do a general ADS search + * @param ads connection to ads server + * @param res ** which will contain results - free res* with ads_msgfree() + * @param exp Search expression + * @param attrs Attributes to retrieve + * @return status of search + **/ ADS_STATUS ads_search(ADS_STRUCT *ads, void **res, const char *exp, const char **attrs) @@ -303,9 +334,14 @@ ADS_STATUS ads_search(ADS_STRUCT *ads, void **res, exp, attrs, res); } -/* - do a search on a specific DistinguishedName -*/ +/** + * Do a search on a specific DistinguishedName + * @param ads connection to ads server + * @param res ** which will contain results - free res* with ads_msgfree() + * @param dn DistinguishName to search + * @param attrs Attributes to retrieve + * @return status of search + **/ ADS_STATUS ads_search_dn(ADS_STRUCT *ads, void **res, const char *dn, const char **attrs) @@ -313,35 +349,46 @@ ADS_STATUS ads_search_dn(ADS_STRUCT *ads, void **res, return ads_do_search(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res); } -/* - free up memory from a ads_search -*/ +/** + * Free up memory from a ads_search + * @param ads connection to ads server + * @param msg Search results to free + **/ void ads_msgfree(ADS_STRUCT *ads, void *msg) { if (!msg) return; ldap_msgfree(msg); } -/* - free up memory from various ads requests -*/ +/** + * Free up memory from various ads requests + * @param ads connection to ads server + * @param mem Area to free + **/ void ads_memfree(ADS_STRUCT *ads, void *mem) { if (!mem) return; ldap_memfree(mem); } -/* - get a dn from search results -*/ +/** + * Get a dn from search results + * @param ads connection to ads server + * @param res Search results + * @return dn string + **/ char *ads_get_dn(ADS_STRUCT *ads, void *res) { return ldap_get_dn(ads->ld, res); } -/* - find a machine account given a hostname -*/ +/** + * Find a machine account given a hostname + * @param ads connection to ads server + * @param res ** which will contain results - free res* with ads_msgfree() + * @param host Hostname to search for + * @return status of search + **/ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) { ADS_STATUS status; @@ -375,10 +422,11 @@ static char **ads_dup_values(TALLOC_CTX *ctx, char **values) return newvals; } -/* - initialize a list of mods -*/ - +/** + * Initialize a list of mods to be used in a modify request + * @param ctx An initialized TALLOC_CTX + * @return allocated ADS_MODLIST + **/ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx) { #define ADS_MODLIST_ALLOC_SIZE 10 @@ -426,6 +474,14 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, return ADS_ERROR(LDAP_SUCCESS); } +/** + * Add an already-constructed list of values to a mod list for an ADD + * @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_add_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, char *name, char **values) { @@ -436,6 +492,14 @@ ADS_STATUS ads_mod_add_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, 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) { @@ -451,9 +515,15 @@ ADS_STATUS ads_mod_repl_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); } -/* - add an attribute to the list, with values list to be built from args -*/ +/** + * 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, ...) { @@ -483,6 +553,15 @@ ADS_STATUS ads_mod_add_var(TALLOC_CTX *ctx, ADS_MODLIST *mods, return ads_modlist_add(ctx, mods, do_op, name, values); } +/** + * Add any number of ber 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 (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, ...) { @@ -514,6 +593,14 @@ ADS_STATUS ads_mod_add_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, 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 + * @return ADS STATUS indicating success of add + **/ ADS_STATUS ads_mod_repl(TALLOC_CTX *ctx, ADS_MODLIST *mods, char *name, char *val) { @@ -524,12 +611,29 @@ ADS_STATUS ads_mod_repl(TALLOC_CTX *ctx, ADS_MODLIST *mods, 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); } +/** + * Add a single berval 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 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) { @@ -545,6 +649,15 @@ ADS_STATUS ads_mod_add_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, 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 + * @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) { @@ -565,6 +678,13 @@ ADS_STATUS ads_mod_repl_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, } } +/** + * Perform an ldap modify + * @param ads connection to ads server + * @param mod_dn DistinguishedName to modify + * @param mods list of modifications to perform + * @return status of modify + **/ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) { int ret,i; @@ -590,6 +710,13 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) return ADS_ERROR(ret); } +/** + * Perform an ldap add + * @param ads connection to ads server + * @param new_dn DistinguishedName to add + * @param mods list of attributes and values for DN + * @return status of add + **/ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) { int i; @@ -602,17 +729,24 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) return ADS_ERROR(ldap_add_s(ads->ld, new_dn, mods)); } +/** + * Delete a DistinguishedName + * @param ads connection to ads server + * @param new_dn DistinguishedName to delete + * @return status of delete + **/ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) { return ADS_ERROR(ldap_delete(ads->ld, del_dn)); } -/* - build an org unit string - if org unit is Computers or blank then assume a container, otherwise - assume a \ separated list of organisational units - caller must free -*/ +/** + * Build an org unit string + * if org unit is Computers or blank then assume a container, otherwise + * assume a \ separated list of organisational units + * @param org_unit Organizational unit + * @return org unit string - caller must free + **/ char *ads_ou_string(const char *org_unit) { if (!org_unit || !*org_unit || strcasecmp(org_unit, "Computers") == 0) { @@ -785,23 +919,29 @@ static void ads_dump_field(char *field, void **values, void *data_area) } } -/* - dump a result from LDAP on stdout - used for debugging -*/ +/** + * Dump a result from LDAP on stdout + * used for debugging + * @param ads connection to ads server + * @param res Results to dump + **/ void ads_dump(ADS_STRUCT *ads, void *res) { ads_process_results(ads, res, ads_dump_field, NULL); } -/* - Walk through results, calling a function for each entry found. - The function receives a field name, a berval * array of values, - and a data area passed through from the start. The function is - called once with null for field and values at the end of each - entry. -*/ +/** + * Walk through results, calling a function for each entry found. + * The function receives a field name, a berval * array of values, + * and a data area passed through from the start. The function is + * called once with null for field and values at the end of each + * entry. + * @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_results(ADS_STRUCT *ads, void *res, void(*fn)(char *, void **, void *), void *data_area) @@ -830,6 +970,15 @@ void ads_process_results(ADS_STRUCT *ads, void *res, } } +/** + * 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) @@ -850,18 +999,25 @@ void ads_process_entry(ADS_STRUCT *ads, void *msg, } ber_free(b, 0); } -/* - count how many replies are in a LDAPMessage -*/ +/** + * count how many replies are in a LDAPMessage + * @param ads connection to ads server + * @param res Results to count + * @return number of replies + **/ int ads_count_replies(ADS_STRUCT *ads, void *res) { return ldap_count_entries(ads->ld, (LDAPMessage *)res); } -/* - join a machine to a realm, creating the machine account - and setting the machine password -*/ +/** + * Join a machine to a realm + * Creates the machine account and sets the machine password + * @param ads connection to ads server + * @param hostname name of host to add + * @param org_unit Organizational unit to place machine in + * @return status of join + **/ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org_unit) { ADS_STATUS status; @@ -900,9 +1056,12 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org return status; } -/* - delete a machine from the realm -*/ +/** + * Delete a machine from the realm + * @param ads connection to ads server + * @param hostname Machine to remove + * @return status of delete + **/ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) { ADS_STATUS status; @@ -938,9 +1097,13 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return status; } -/* - add machine account to existing security descriptor -*/ +/** + * add machine account to existing security descriptor + * @param ads connection to ads server + * @param hostname machine to add + * @param dn DN of security descriptor + * @return status + **/ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) { const char *attrs[] = {"ntSecurityDescriptor", "objectSid", 0}; @@ -1016,6 +1179,13 @@ ads_set_sd_error: return ADS_ERROR(LDAP_NO_MEMORY); } +/** + * Set the machine account password + * @param ads connection to ads server + * @param hostname machine whose password is being set + * @param password new password + * @return status of password change + **/ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, const char *hostname, const char *password) @@ -1041,25 +1211,36 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, return status; } -/* - pull the first entry from a ADS result -*/ +/** + * pull the first entry from a ADS result + * @param ads connection to ads server + * @param res Results of search + * @return first entry from result + **/ void *ads_first_entry(ADS_STRUCT *ads, void *res) { return (void *)ldap_first_entry(ads->ld, (LDAPMessage *)res); } -/* - pull the next entry from a ADS result -*/ +/** + * pull the next entry from a ADS result + * @param ads connection to ads server + * @param res Results of search + * @return next entry from result + **/ void *ads_next_entry(ADS_STRUCT *ads, void *res) { return (void *)ldap_next_entry(ads->ld, (LDAPMessage *)res); } -/* - pull a single string from a ADS result -*/ +/** + * pull a single string 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 string in talloc context + **/ char *ads_pull_string(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg, const char *field) { @@ -1076,8 +1257,13 @@ char *ads_pull_string(ADS_STRUCT *ads, return ret; } -/* - pull a single uint32 from a ADS result +/** + * pull a single uint32 from a ADS result + * @param ads connection to ads server + * @param msg Results of search + * @param field Attribute to retrieve + * @param v Pointer to int to store result + * @return boolean inidicating success */ BOOL ads_pull_uint32(ADS_STRUCT *ads, void *msg, const char *field, uint32 *v) @@ -1096,8 +1282,13 @@ BOOL ads_pull_uint32(ADS_STRUCT *ads, return True; } -/* - pull a single DOM_SID from a ADS result +/** + * pull a single DOM_SID from a ADS result + * @param ads connection to ads server + * @param msg Results of search + * @param field Attribute to retrieve + * @param sid Pointer to sid to store result + * @return boolean inidicating success */ BOOL ads_pull_sid(ADS_STRUCT *ads, void *msg, const char *field, DOM_SID *sid) @@ -1117,10 +1308,15 @@ BOOL ads_pull_sid(ADS_STRUCT *ads, return ret; } -/* - pull an array of DOM_SIDs from a ADS result - return the count of SIDs pulled -*/ +/** + * pull an array of DOM_SIDs from a ADS result + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX for allocating sid array + * @param msg Results of search + * @param field Attribute to retrieve + * @param sids pointer to sid array to allocate + * @return the count of SIDs pulled + **/ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg, const char *field, DOM_SID **sids) { @@ -1147,7 +1343,13 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, } -/* find the update serial number - this is the core of the ldap cache */ +/** + * find the update serial number - this is the core of the ldap cache + * @param ads connection to ads server + * @param ads connection to ADS server + * @param usn Pointer to retrieved update serial number + * @return status of search + **/ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) { const char *attrs[] = {"highestCommittedUSN", NULL}; @@ -1167,10 +1369,13 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) } -/* find the servers name and realm - this can be done before authentication - The ldapServiceName field on w2k looks like this: - vnet3.home.samba.org:win2000-vnet3$@VNET3.HOME.SAMBA.ORG -*/ +/** + * Find the servers name and realm - this can be done before authentication + * The ldapServiceName field on w2k looks like this: + * vnet3.home.samba.org:win2000-vnet3$@VNET3.HOME.SAMBA.ORG + * @param ads connection to ads server + * @return status of search + **/ ADS_STATUS ads_server_info(ADS_STRUCT *ads) { const char *attrs[] = {"ldapServiceName", NULL}; @@ -1224,9 +1429,15 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) } -/* - find the list of trusted domains -*/ +/** + * find the list of trusted domains + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX for allocating results + * @param num_trusts pointer to number of trusts + * @param names pointer to trusted domain name list + * @param sids pointer to list of sids of trusted domains + * @return the count of SIDs pulled + **/ ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, int *num_trusts, char ***names, DOM_SID **sids) { @@ -1264,7 +1475,12 @@ ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, return ADS_SUCCESS; } -/* find the domain sid for our domain */ +/** + * find the domain sid for our domain + * @param ads connection to ads server + * @param sid Pointer to domain sid + * @return status of search + **/ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) { const char *attrs[] = {"objectSid", NULL}; -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/libads/ldap.c | 679 ++++++++++++++++++++++++++++---------------------- 1 file changed, 377 insertions(+), 302 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e2e351bd4b..9d15c4e33c 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 **/ /** @@ -45,10 +50,38 @@ 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) { + 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) { + SAFE_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")); @@ -76,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 @@ -84,8 +192,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 @@ -96,25 +204,46 @@ 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, **search_attrs; + LDAPControl PagedResults, NoReferrals, *controls[3], **rcontrols; BerElement *cookie_be = NULL; struct berval *cookie_bv= NULL; - LDAPControl *controls[3]; - LDAPControl **rcontrols; - int i; + TALLOC_CTX *ctx; *res = NULL; - ldap_get_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + if (!(ctx = talloc_init())) + return ADS_ERROR(LDAP_NO_MEMORY); - /* 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); + /* 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) { + rc = LDAP_NOT_SUPPORTED; + goto done; + } cookie_be = ber_alloc_t(LBER_USE_DER); if (cookie && *cookie) { @@ -143,33 +272,32 @@ 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, - (char **) attrs, 0, controls, NULL, - NULL, LDAP_NO_LIMIT, - (LDAPMessage **)res); + rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, + search_attrs, 0, controls, + NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); 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++) { @@ -189,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); } @@ -234,7 +367,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 */ } @@ -248,15 +380,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; @@ -301,14 +433,42 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, { struct timeval timeout; int rc; + 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; - rc = ldap_search_ext_s(ads->ld, - bind_path, scope, - exp, (char **) attrs, 0, NULL, 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); if (rc == LDAP_SIZELIMIT_EXCEEDED) { @@ -316,6 +476,10 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, 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); } /** @@ -367,8 +531,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); } /** @@ -379,7 +542,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((void **) &unix_dn, utf8_dn); + ldap_memfree(utf8_dn); + return unix_dn; } /** @@ -403,25 +571,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] && imod_type = name; + modlist[curmod]->mod_type = talloc_strdup(ctx, name); 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 + 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, + (const 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 + * @param vals The array of string values to add - NULL means DELETE * @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, ...) +ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const char *name, const char **vals) { - 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 - * @return ADS STATUS indicating success of add - **/ -ADS_STATUS ads_mod_repl(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, char *val) -{ - 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, (const 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) +static 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); - + const 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, (const void **) values); } /** @@ -688,6 +701,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 @@ -701,12 +715,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((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++); /* 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); } @@ -719,14 +736,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((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++); /* 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); } /** @@ -737,7 +759,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((void **) &utf8_dn, del_dn); + ret = ldap_delete(ads->ld, utf8_dn ? utf8_dn : del_dn); + return ADS_ERROR(ret); } /** @@ -769,6 +795,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); @@ -796,17 +824,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); @@ -877,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]); } } @@ -890,33 +916,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) { - dump_string(field, (struct berval **) values); + if (!values) /* first time, indicate string conversion */ + return True; + dump_string(field, (char **)values); } + return False; } /** @@ -943,62 +975,57 @@ 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, + (const char **) 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 @@ -1110,6 +1137,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; @@ -1164,7 +1192,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, ps_wire.data_p); + 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); @@ -1201,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); @@ -1246,17 +1280,58 @@ 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; } +/** + * 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: Sat, 17 Aug 2002 17:00:51 +0000 Subject: sync 3.0 branch with head (This used to be commit 3928578b52cfc949be5e0ef444fce1558d75f290) --- source3/libads/ldap.c | 389 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 321 insertions(+), 68 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 9d15c4e33c..2672489482 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -37,6 +37,165 @@ * codepoints in UTF-8). This may have to change at some point **/ + +/* + try a connection to a given ldap server, returning True and setting the servers IP + in the ads struct if successful + */ +static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) +{ + char *srv; + + if (!server || !*server) { + return False; + } + + DEBUG(5,("ads_try_connect: trying ldap server '%s' port %u\n", server, port)); + + /* this copes with inet_ntoa brokenness */ + srv = strdup(server); + + ads->ld = ldap_open(srv, port); + if (!ads->ld) { + free(srv); + return False; + } + ads->ldap_port = port; + ads->ldap_ip = *interpret_addr2(srv); + free(srv); + return True; +} + +/* used by the IP comparison function */ +struct ldap_ip { + struct in_addr ip; + unsigned port; +}; + +/* compare 2 ldap IPs by nearness to our interfaces - used in qsort */ +static int ldap_ip_compare(struct ldap_ip *ip1, struct ldap_ip *ip2) +{ + return ip_compare(&ip1->ip, &ip2->ip); +} + +/* try connecting to a ldap server via DNS */ +static BOOL ads_try_dns(ADS_STRUCT *ads) +{ + char *realm, *ptr; + char *list = NULL; + pstring tok; + struct ldap_ip *ip_list; + int count, i=0; + + realm = ads->server.realm; + if (!realm || !*realm) { + realm = lp_realm(); + } + if (!realm || !*realm) { + realm = ads->server.workgroup; + } + if (!realm || !*realm) { + realm = lp_workgroup(); + } + if (!realm) { + return False; + } + realm = smb_xstrdup(realm); + + DEBUG(6,("ads_try_dns: looking for realm '%s'\n", realm)); + if (ldap_domain2hostlist(realm, &list) != LDAP_SUCCESS) { + SAFE_FREE(realm); + return False; + } + + DEBUG(6,("ads_try_dns: ldap realm '%s' host list '%s'\n", realm, list)); + SAFE_FREE(realm); + + count = count_chars(list, ' ') + 1; + ip_list = malloc(count * sizeof(struct ldap_ip)); + if (!ip_list) { + return False; + } + + ptr = list; + while (next_token(&ptr, tok, " ", sizeof(tok))) { + unsigned port = LDAP_PORT; + char *p = strchr(tok, ':'); + if (p) { + *p = 0; + port = atoi(p+1); + } + ip_list[i].ip = *interpret_addr2(tok); + ip_list[i].port = port; + if (!is_zero_ip(ip_list[i].ip)) { + i++; + } + } + free(list); + + count = i; + + /* we sort the list of addresses by closeness to our interfaces. This + tries to prevent us using a DC on the other side of the country */ + if (count > 1) { + qsort(ip_list, count, sizeof(struct ldap_ip), + QSORT_CAST ldap_ip_compare); + } + + for (i=0;iserver.workgroup; + + if (!workgroup) { + workgroup = lp_workgroup(); + } + + DEBUG(6,("ads_try_netbios: looking for workgroup '%s'\n", workgroup)); + + /* try the PDC first */ + if (get_dc_list(True, workgroup, &ip_list, &count)) { + for (i=0;ilast_attempt = time(NULL); - ads->ld = NULL; - if (ads->ldap_server) { - ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); + /* try with a user specified server */ + if (ads->server.ldap_server && + ads_try_connect(ads, ads->server.ldap_server, LDAP_PORT)) { + goto got_connection; } - /* 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) { - SAFE_FREE(ads->ldap_server); - ads->ldap_server = strdup(inet_ntoa(ip_list[i])); - } - free(ip_list); - } + /* try with a smb.conf ads server setting if we are connecting + to the primary workgroup or realm */ + if (!ads->server.foreign && + ads_try_connect(ads, lp_ads_server(), LDAP_PORT)) { + goto got_connection; } - if (!ads->ld) { - return ADS_ERROR_SYSTEM(errno); + /* try via DNS */ + if (ads_try_dns(ads)) { + goto got_connection; + } + + /* try via netbios lookups */ + if (!lp_disable_netbios() && ads_try_netbios(ads)) { + goto got_connection; } - DEBUG(3,("Connected to LDAP server %s\n", ads->ldap_server)); + return ADS_ERROR_SYSTEM(errno?errno:ENOENT); + +got_connection: + DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap_ip))); status = ads_server_info(ads); if (!ADS_ERR_OK(status)) { @@ -90,22 +246,43 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + if (!ads->auth.user_name) { + /* by default use the machine account */ + extern pstring global_myname; + fstring myname; + fstrcpy(myname, global_myname); + strlower(myname); + asprintf(&ads->auth.user_name, "HOST/%s", myname); + } + + if (!ads->auth.realm) { + ads->auth.realm = strdup(ads->config.realm); + } + + if (!ads->auth.kdc_server) { + ads->auth.kdc_server = strdup(inet_ntoa(ads->ldap_ip)); + } + #if KRB5_DNS_HACK /* this is a really nasty hack to avoid ADS DNS problems. It needs a patch to MIT kerberos to work (tridge) */ { char *env; - asprintf(&env, "KRB5_KDC_ADDRESS_%s", ads->server_realm); - setenv(env, inet_ntoa(*interpret_addr2(ads->ldap_server)), 1); + asprintf(&env, "KRB5_KDC_ADDRESS_%s", ads->config.realm); + setenv(env, ads->auth.kdc_server, 1); free(env); } #endif - if (ads->password) { + if (ads->auth.password) { if ((code = ads_kinit_password(ads))) return ADS_ERROR_KRB5(code); } + if (ads->auth.no_bind) { + return ADS_SUCCESS; + } + return ads_sasl_bind(ads); } @@ -161,7 +338,7 @@ static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals) if (!values) return NULL; for (i=0; in_vals[i]; i++) { - push_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); + push_utf8_talloc(ctx, &values[i], in_vals[i]); } return values; } @@ -180,7 +357,7 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) if (!values) return NULL; for (i=0; in_vals[i]; i++) { - pull_utf8_talloc(ctx, (void **) &values[i], in_vals[i]); + pull_utf8_talloc(ctx, &values[i], in_vals[i]); } return values; } @@ -219,8 +396,8 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, /* 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)) { + if ((push_utf8_talloc(ctx, &utf8_exp, exp) < 0) || + (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) { rc = LDAP_NO_MEMORY; goto done; } @@ -230,7 +407,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, else { /* This would be the utf8-encoded version...*/ /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ - if (!(str_list_copy(&search_attrs, (char **) attrs))) + if (!(str_list_copy(&search_attrs, attrs))) { rc = LDAP_NO_MEMORY; goto done; @@ -442,8 +619,8 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, /* 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)) { + if ((push_utf8_talloc(ctx, &utf8_exp, exp) < 0) || + (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) { rc = LDAP_NO_MEMORY; goto done; } @@ -453,7 +630,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, else { /* This would be the utf8-encoded version...*/ /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ - if (!(str_list_copy(&search_attrs, (char **) attrs))) + if (!(str_list_copy(&search_attrs, attrs))) { rc = LDAP_NO_MEMORY; goto done; @@ -494,7 +671,7 @@ ADS_STATUS ads_search(ADS_STRUCT *ads, void **res, const char *exp, const char **attrs) { - return ads_do_search(ads, ads->bind_path, LDAP_SCOPE_SUBTREE, + return ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, exp, attrs, res); } @@ -805,11 +982,11 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", hostname))) goto done; - if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->realm))) + if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) goto done; ou_str = ads_ou_string(org_unit); new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str, - ads->bind_path); + ads->config.bind_path); free(ou_str); if (!new_dn) goto done; @@ -925,6 +1102,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) } handlers[] = { {"objectGUID", False, dump_binary}, {"nTSecurityDescriptor", False, dump_sd}, + {"dnsRecord", False, dump_binary}, {"objectSid", False, dump_sid}, {NULL, True, NULL} }; @@ -999,7 +1177,7 @@ void ads_process_results(ADS_STRUCT *ads, void *res, char *field; BOOL string; - pull_utf8_talloc(ctx, (void **) &field, utf8_field); + pull_utf8_talloc(ctx, &field, utf8_field); string = fn(field, NULL, data_area); if (string) { @@ -1061,7 +1239,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org status = ads_leave_realm(ads, host); if (!ADS_ERR_OK(status)) { DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n", - host, ads->realm)); + host, ads->config.realm)); return status; } } @@ -1224,20 +1402,15 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, char *host = strdup(hostname); char *principal; - if (!ads->kdc_server) { - DEBUG(0, ("Unable to find KDC server\n")); - return ADS_ERROR(LDAP_SERVER_DOWN); - } - strlower(host); /* 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); + asprintf(&principal, "%s$@%s", host, ads->auth.realm); - status = krb5_set_password(ads->kdc_server, principal, password); + status = krb5_set_password(ads->auth.kdc_server, principal, password); free(host); free(principal); @@ -1287,7 +1460,7 @@ char *ads_pull_string(ADS_STRUCT *ads, if (!values) return NULL; if (values[0]) { - rc = pull_utf8_talloc(mem_ctx, (void **)&ux_string, + rc = pull_utf8_talloc(mem_ctx, &ux_string, values[0]); if (rc != -1) ret = ux_string; @@ -1321,7 +1494,7 @@ char **ads_pull_strings(ADS_STRUCT *ads, ret = talloc(mem_ctx, sizeof(char *) * (n+1)); for (i=0;ildap_server_name); + SAFE_FREE(ads->config.ldap_server_name); - ads->ldap_server_name = strdup(p+1); - p = strchr(ads->ldap_server_name, '$'); + ads->config.ldap_server_name = strdup(p+1); + p = strchr(ads->config.ldap_server_name, '$'); if (!p || p[1] != '@') { ldap_value_free(values); ldap_msgfree(res); - SAFE_FREE(ads->ldap_server_name); + SAFE_FREE(ads->config.ldap_server_name); return ADS_ERROR(LDAP_DECODING_ERROR); } *p = 0; - SAFE_FREE(ads->server_realm); - SAFE_FREE(ads->bind_path); + SAFE_FREE(ads->config.realm); + SAFE_FREE(ads->config.bind_path); - ads->server_realm = strdup(p+2); - ads->bind_path = ads_build_dn(ads->server_realm); - - /* in case the realm isn't configured in smb.conf */ - if (!ads->realm || !ads->realm[0]) { - SAFE_FREE(ads->realm); - ads->realm = strdup(ads->server_realm); - } + ads->config.realm = strdup(p+2); + ads->config.bind_path = ads_build_dn(ads->config.realm); DEBUG(3,("got ldap server name %s@%s\n", - ads->ldap_server_name, ads->realm)); + ads->config.ldap_server_name, ads->config.realm)); return ADS_SUCCESS; } @@ -1514,9 +1681,13 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) * @return the count of SIDs pulled **/ ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, - int *num_trusts, char ***names, DOM_SID **sids) + int *num_trusts, + char ***names, + char ***alt_names, + DOM_SID **sids) { - const char *attrs[] = {"flatName", "securityIdentifier", NULL}; + const char *attrs[] = {"name", "flatname", "securityIdentifier", + "trustDirection", NULL}; ADS_STATUS status; void *res, *msg; int count, i; @@ -1533,11 +1704,31 @@ ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, } (*names) = talloc(mem_ctx, sizeof(char *) * count); + (*alt_names) = talloc(mem_ctx, sizeof(char *) * count); (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * count); if (! *names || ! *sids) return ADS_ERROR(LDAP_NO_MEMORY); for (i=0, msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { - (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatName"); + uint32 direction; + + /* direction is a 2 bit bitfield, 1 means they trust us + but we don't trust them, so we should not list them + as users from that domain can't login */ + if (ads_pull_uint32(ads, msg, "trustDirection", &direction) && + direction == 1) { + continue; + } + + (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "name"); + (*alt_names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatname"); + + if ((*alt_names)[i] && (*alt_names)[i][0]) { + /* we prefer the flatname as the primary name + for consistency with RPC */ + char *name = (*alt_names)[i]; + (*alt_names)[i] = (*names)[i]; + (*names)[i] = name; + } if (ads_pull_sid(ads, msg, "securityIdentifier", &(*sids)[i])) { i++; } @@ -1562,7 +1753,7 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) void *res; ADS_STATUS rc; - rc = ads_do_search(ads, ads->bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", + rc = ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(rc)) return rc; if (!ads_pull_sid(ads, res, "objectSid", sid)) { @@ -1573,4 +1764,66 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) return ADS_SUCCESS; } +/* this is rather complex - we need to find the allternate (netbios) name + for the domain, but there isn't a simple query to do this. Instead + we look for the principle names on the DCs account and find one that has + the right form, then extract the netbios name of the domain from that +*/ +ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workgroup) +{ + char *exp; + ADS_STATUS rc; + char **principles; + char *prefix; + int prefix_length; + int i; + void *res; + const char *attrs[] = {"servicePrincipalName", NULL}; + + (*workgroup) = NULL; + + asprintf(&exp, "(&(objectclass=computer)(dnshostname=%s.%s))", + ads->config.ldap_server_name, ads->config.realm); + rc = ads_search(ads, &res, exp, attrs); + free(exp); + + if (!ADS_ERR_OK(rc)) { + return rc; + } + + principles = ads_pull_strings(ads, mem_ctx, res, "servicePrincipalName"); + + ads_msgfree(ads, res); + + if (!principles) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + asprintf(&prefix, "HOST/%s.%s/", + ads->config.ldap_server_name, + ads->config.realm); + + prefix_length = strlen(prefix); + + for (i=0;principles[i]; i++) { + if (strncasecmp(principles[i], prefix, prefix_length) == 0 && + strcasecmp(ads->config.realm, principles[i]+prefix_length) != 0 && + !strchr(principles[i]+prefix_length, '.')) { + /* found an alternate (short) name for the domain. */ + DEBUG(3,("Found alternate name '%s' for realm '%s'\n", + principles[i]+prefix_length, + ads->config.realm)); + (*workgroup) = talloc_strdup(mem_ctx, principles[i]+prefix_length); + break; + } + } + free(prefix); + + if (!*workgroup) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + return ADS_SUCCESS; +} + #endif -- cgit From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/libads/ldap.c | 94 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 22 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2672489482..7a0afb1a81 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -63,6 +63,7 @@ static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) ads->ldap_port = port; ads->ldap_ip = *interpret_addr2(srv); free(srv); + return True; } @@ -204,7 +205,6 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads) ADS_STATUS ads_connect(ADS_STRUCT *ads) { int version = LDAP_VERSION3; - int code; ADS_STATUS status; ads->last_attempt = time(NULL); @@ -226,7 +226,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) /* try via DNS */ if (ads_try_dns(ads)) { goto got_connection; - } + } /* try via netbios lookups */ if (!lp_disable_netbios() && ads_try_netbios(ads)) { @@ -274,12 +274,7 @@ got_connection: } #endif - if (ads->auth.password) { - if ((code = ads_kinit_password(ads))) - return ADS_ERROR_KRB5(code); - } - - if (ads->auth.no_bind) { + if (ads->auth.flags & ADS_AUTH_NO_BIND) { return ADS_SUCCESS; } @@ -613,14 +608,17 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, char *utf8_exp, *utf8_path, **search_attrs = NULL; TALLOC_CTX *ctx; - if (!(ctx = talloc_init())) + if (!(ctx = talloc_init())) { + DEBUG(1,("ads_do_search: talloc_init() failed!")); 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, &utf8_exp, exp) < 0) || (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) { + DEBUG(1,("ads_do_search: push_utf8_talloc() failed!")); rc = LDAP_NO_MEMORY; goto done; } @@ -632,6 +630,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ if (!(str_list_copy(&search_attrs, attrs))) { + DEBUG(1,("ads_do_search: str_list_copy() failed!")); rc = LDAP_NO_MEMORY; goto done; } @@ -826,7 +825,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) { - const char *values[2] = {val, NULL}; + const char *values[2]; + + values[0] = val; + values[1] = NULL; + if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, @@ -861,7 +864,10 @@ ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, 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}; + const struct berval *values[2]; + + values[0] = val; + values[1] = 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, @@ -884,7 +890,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) non-existent attribute (but allowable for the object) to run */ LDAPControl PermitModify = { - "1.2.840.113556.1.4.1413", + ADS_PERMIT_MODIFY_OID, {0, NULL}, (char) 1}; LDAPControl *controls[2]; @@ -1410,7 +1416,7 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, */ asprintf(&principal, "%s$@%s", host, ads->auth.realm); - status = krb5_set_password(ads->auth.kdc_server, principal, password); + status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset); free(host); free(principal); @@ -1616,6 +1622,26 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) return ADS_SUCCESS; } +/* parse a ADS timestring - typical string is + '20020917091222.0Z0' which means 09:12.22 17th September + 2002, timezone 0 */ +static time_t ads_parse_time(const char *str) +{ + struct tm tm; + + ZERO_STRUCT(tm); + + if (sscanf(str, "%4d%2d%2d%2d%2d%2d", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { + return 0; + } + tm.tm_year -= 1900; + tm.tm_mon -= 1; + + return timegm(&tm); +} + /** * Find the servers name and realm - this can be done before authentication @@ -1626,22 +1652,37 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) **/ ADS_STATUS ads_server_info(ADS_STRUCT *ads) { - const char *attrs[] = {"ldapServiceName", NULL}; + const char *attrs[] = {"ldapServiceName", "currentTime", NULL}; ADS_STATUS status; void *res; - char **values; + char *value; char *p; + char *timestr; + TALLOC_CTX *ctx; + + if (!(ctx = talloc_init())) { + return ADS_ERROR(LDAP_NO_MEMORY); + } status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status)) return status; - values = ldap_get_values(ads->ld, res, "ldapServiceName"); - if (!values || !values[0]) return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + value = ads_pull_string(ads, ctx, res, "ldapServiceName"); + if (!value) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + timestr = ads_pull_string(ads, ctx, res, "currentTime"); + if (!timestr) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + ldap_msgfree(res); - p = strchr(values[0], ':'); + p = strchr(value, ':'); if (!p) { - ldap_value_free(values); - ldap_msgfree(res); + talloc_destroy(ctx); + DEBUG(1, ("ads_server_info: returned ldap server name did not contain a ':' so was deemed invalid\n")); return ADS_ERROR(LDAP_DECODING_ERROR); } @@ -1650,9 +1691,9 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) ads->config.ldap_server_name = strdup(p+1); p = strchr(ads->config.ldap_server_name, '$'); if (!p || p[1] != '@') { - ldap_value_free(values); - ldap_msgfree(res); + talloc_destroy(ctx); SAFE_FREE(ads->config.ldap_server_name); + DEBUG(1, ("ads_server_info: returned ldap server name did not contain '$@' so was deemed invalid\n")); return ADS_ERROR(LDAP_DECODING_ERROR); } @@ -1667,6 +1708,15 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) DEBUG(3,("got ldap server name %s@%s\n", ads->config.ldap_server_name, ads->config.realm)); + ads->config.current_time = ads_parse_time(timestr); + + if (ads->config.current_time != 0) { + ads->auth.time_offset = ads->config.current_time - time(NULL); + DEBUG(4,("time offset is %d seconds\n", ads->auth.time_offset)); + } + + talloc_destroy(ctx); + return ADS_SUCCESS; } -- cgit From f2d1f19a66ebaf9b88d23c0faa2412536cc74cda Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 1 Oct 2002 18:26:00 +0000 Subject: syncing up with HEAD. Seems to be a lot of differences creeping in (i ignored the new SAMBA stuff, but the rest of this looks like it should have been merged already). (This used to be commit 3de09e5cf1f667e410ee8b9516a956860ce7290f) --- source3/libads/ldap.c | 202 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 138 insertions(+), 64 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7a0afb1a81..2133bf0719 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -22,7 +22,7 @@ #include "includes.h" -#ifdef HAVE_ADS +#ifdef HAVE_LDAP /** * @file ldap.c @@ -67,6 +67,29 @@ static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) return True; } +/* + try a connection to a given ldap server, based on URL, returning True if successful + */ +static BOOL ads_try_connect_uri(ADS_STRUCT *ads) +{ +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) + DEBUG(5,("ads_try_connect: trying ldap server at URI '%s'\n", + ads->server.ldap_uri)); + + + if (ldap_initialize((LDAP**)&(ads->ld), ads->server.ldap_uri) == LDAP_SUCCESS) { + return True; + } + DEBUG(0, ("ldap_initialize: %s\n", strerror(errno))); + +#else + + DEBUG(1, ("no URL support in LDAP libs!\n")); +#endif + + return False; +} + /* used by the IP comparison function */ struct ldap_ip { struct in_addr ip; @@ -210,6 +233,13 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ads->last_attempt = time(NULL); ads->ld = NULL; + /* try with a URL based server */ + + if (ads->server.ldap_uri && + ads_try_connect_uri(ads)) { + goto got_connection; + } + /* try with a user specified server */ if (ads->server.ldap_server && ads_try_connect(ads, ads->server.ldap_server, LDAP_PORT)) { @@ -278,6 +308,14 @@ got_connection: return ADS_SUCCESS; } + if (ads->auth.flags & ADS_AUTH_ANON_BIND) { + return ADS_ERROR(ldap_simple_bind_s( ads->ld, NULL, NULL)); + } + + if (ads->auth.flags & ADS_AUTH_SIMPLE_BIND) { + return ADS_ERROR(ldap_simple_bind_s( ads->ld, ads->auth.user_name, ads->auth.password)); + } + return ads_sasl_bind(ads); } @@ -741,7 +779,11 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) /* the easiest way to find a machine account anywhere in the tree is to look for hostname$ */ - asprintf(&exp, "(samAccountName=%s$)", host); + if (asprintf(&exp, "(samAccountName=%s$)", host) == -1) { + DEBUG(1, ("asprintf failed!\n")); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + status = ads_search(ads, res, exp, attrs); free(exp); return status; @@ -898,13 +940,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((void **) &utf8_dn, mod_dn); + if (push_utf8_allocate(&utf8_dn, mod_dn) == -1) { + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } /* 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, utf8_dn ? utf8_dn : mod_dn, + ret = ldap_modify_ext_s(ads->ld, utf8_dn, (LDAPMod **) mods, controls, NULL); SAFE_FREE(utf8_dn); return ADS_ERROR(ret); @@ -922,7 +966,10 @@ 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((void **) &utf8_dn, new_dn); + if (push_utf8_allocate(&utf8_dn, new_dn) == -1) { + DEBUG(1, ("ads_gen_add: push_utf8_allocate failed!")); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } /* find the end of the list, marked by NULL or -1 */ for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); @@ -944,7 +991,11 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) { int ret; char *utf8_dn = NULL; - push_utf8_allocate((void **) &utf8_dn, del_dn); + if (push_utf8_allocate(&utf8_dn, del_dn) == -1) { + DEBUG(1, ("ads_del_dn: push_utf8_allocate failed!")); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + ret = ldap_delete(ads->ld, utf8_dn ? utf8_dn : del_dn); return ADS_ERROR(ret); } @@ -991,6 +1042,10 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) goto done; ou_str = ads_ou_string(org_unit); + if (!ou_str) { + DEBUG(1, ("ads_ou_string returned NULL (malloc failure?)\n")); + goto done; + } new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str, ads->config.bind_path); free(ou_str); @@ -1320,9 +1375,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) const char *attrs[] = {"ntSecurityDescriptor", "objectSid", 0}; char *exp = 0; size_t sd_size = 0; - struct berval **bvals = 0; struct berval bval = {0, NULL}; - prs_struct ps; prs_struct ps_wire; LDAPMessage *res = 0; @@ -1339,37 +1392,39 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) ret = ADS_ERROR(LDAP_SUCCESS); - asprintf(&exp, "(samAccountName=%s$)", hostname); + if (asprintf(&exp, "(samAccountName=%s$)", hostname) == -1) { + DEBUG(1, ("ads_set_machine_sd: asprintf failed!\n")); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + ret = ads_search(ads, (void *) &res, exp, attrs); if (!ADS_ERR_OK(ret)) return ret; msg = ads_first_entry(ads, res); - bvals = ldap_get_values_len(ads->ld, msg, attrs[0]); ads_pull_sid(ads, msg, attrs[1], &sid); - ads_msgfree(ads, res); -#if 0 - file_save("/tmp/sec_desc.old", bvals[0]->bv_val, bvals[0]->bv_len); -#endif - if (!(ctx = talloc_init_named("sec_io_desc"))) - return ADS_ERROR(LDAP_NO_MEMORY); - - prs_init(&ps, bvals[0]->bv_len, ctx, UNMARSHALL); - prs_append_data(&ps, bvals[0]->bv_val, bvals[0]->bv_len); - ps.data_offset = 0; - ldap_value_free_len(bvals); + if (!(ctx = talloc_init_named("sec_io_desc"))) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto ads_set_sd_error; + } - if (!sec_io_desc("sd", &psd, &ps, 1)) + if (!ads_pull_sd(ads, ctx, msg, attrs[0], &psd)) { + ret = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); goto ads_set_sd_error; + } status = sec_desc_add_sid(ctx, &psd, &sid, SEC_RIGHTS_FULL_CTRL, &sd_size); - if (!NT_STATUS_IS_OK(status)) + if (!NT_STATUS_IS_OK(status)) { + ret = ADS_ERROR_NT(status); goto ads_set_sd_error; + } prs_init(&ps_wire, sd_size, ctx, MARSHALL); - if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1)) + if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1)) { + ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; + } #if 0 file_save("/tmp/sec_desc.new", ps_wire.data_p, sd_size); @@ -1381,47 +1436,11 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) ads_mod_ber(ctx, &mods, attrs[0], &bval); ret = ads_gen_mod(ads, dn, mods); - prs_mem_free(&ps); - prs_mem_free(&ps_wire); - talloc_destroy(ctx); - return ret; - ads_set_sd_error: - prs_mem_free(&ps); + ads_msgfree(ads, res); prs_mem_free(&ps_wire); talloc_destroy(ctx); - return ADS_ERROR(LDAP_NO_MEMORY); -} - -/** - * Set the machine account password - * @param ads connection to ads server - * @param hostname machine whose password is being set - * @param password new password - * @return status of password change - **/ -ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, - const char *hostname, - const char *password) -{ - ADS_STATUS status; - char *host = strdup(hostname); - char *principal; - - strlower(host); - - /* - 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->auth.realm); - - status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset); - - free(host); - free(principal); - - return status; + return ret; } /** @@ -1596,6 +1615,60 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, return count; } +/** + * pull a SEC_DESC from a ADS result + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX for allocating sid array + * @param msg Results of search + * @param field Attribute to retrieve + * @param sd Pointer to *SEC_DESC to store result (talloc()ed) + * @return boolean inidicating success +*/ +BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + void *msg, const char *field, SEC_DESC **sd) +{ + struct berval **values; + prs_struct ps; + BOOL ret = False; + + values = ldap_get_values_len(ads->ld, msg, field); + + if (!values) return False; + + if (values[0]) { + prs_init(&ps, values[0]->bv_len, mem_ctx, UNMARSHALL); + prs_append_data(&ps, values[0]->bv_val, values[0]->bv_len); + ps.data_offset = 0; + + ret = sec_io_desc("sd", sd, &ps, 1); + } + + ldap_value_free_len(values); + return ret; +} + +/* + * in order to support usernames longer than 21 characters we need to + * use both the sAMAccountName and the userPrincipalName attributes + * It seems that not all users have the userPrincipalName attribute set + * + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX for allocating sid array + * @param msg Results of search + * @return the username + */ +char *ads_pull_username(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg) +{ + char *ret, *p; + + ret = ads_pull_string(ads, mem_ctx, msg, "userPrincipalName"); + if (ret && (p = strchr(ret, '@'))) { + *p = 0; + return ret; + } + return ads_pull_string(ads, mem_ctx, msg, "sAMAccountName"); +} + /** * find the update serial number - this is the core of the ldap cache @@ -1705,8 +1778,9 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) ads->config.realm = strdup(p+2); ads->config.bind_path = ads_build_dn(ads->config.realm); - DEBUG(3,("got ldap server name %s@%s\n", - ads->config.ldap_server_name, ads->config.realm)); + DEBUG(3,("got ldap server name %s@%s, using bind path: %s\n", + ads->config.ldap_server_name, ads->config.realm, + ads->config.bind_path)); ads->config.current_time = ads_parse_time(timestr); -- cgit From 4a7c48aaf0a189c7c6babb4f3745cfee0aa2b8e6 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Tue, 29 Oct 2002 14:47:11 +0000 Subject: Merge from HEAD: GUID formatting on ads dump Allow rc4-hmac when available .NET likes both forms of servicePrincipalName in machine account record (This used to be commit 89e3a3da5d5bc9e6aedeaea5a87553d72fcaac99) --- source3/libads/ldap.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2133bf0719..2359dbd7ed 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1031,6 +1031,8 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ADS_MODLIST mods; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; + char *servicePrincipalName[3] = {NULL, NULL, NULL}; + unsigned acct_control; if (!(ctx = talloc_init_named("machine_account"))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -1048,15 +1050,24 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, } new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str, ads->config.bind_path); + servicePrincipalName[0] = talloc_asprintf(ctx, "HOST/%s", hostname); + servicePrincipalName[1] = talloc_asprintf(ctx, "HOST/%s.%s", + hostname, + ads->config.realm); + strlower(&servicePrincipalName[1][5]); + free(ou_str); if (!new_dn) goto done; if (!(samAccountName = talloc_asprintf(ctx, "%s$", hostname))) goto done; - if (!(controlstr = talloc_asprintf(ctx, "%u", - UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT | - UF_TRUSTED_FOR_DELEGATION | UF_USE_DES_KEY_ONLY))) + + acct_control = UF_WORKSTATION_TRUST_ACCOUNT | UF_DONT_EXPIRE_PASSWD; +#ifndef ENCTYPE_ARCFOUR_HMAC + acct_control |= UF_USE_DES_KEY_ONLY; +#endif + if (!(controlstr = talloc_asprintf(ctx, "%u", acct_control))) goto done; if (!(mods = ads_init_mods(ctx))) @@ -1066,7 +1077,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *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_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); ads_mod_str(ctx, &mods, "dNSHostName", hostname); ads_mod_str(ctx, &mods, "userAccountControl", controlstr); ads_mod_str(ctx, &mods, "operatingSystem", "Samba"); @@ -1095,6 +1106,23 @@ static void dump_binary(const char *field, struct berval **values) } } +struct uuid { + uint32 i1; + uint16 i2; + uint16 i3; + uint8 s[8]; +}; + +static void dump_guid(const char *field, struct berval **values) +{ + int i; + GUID guid; + for (i=0; values[i]; i++) { + memcpy(guid.info, values[i]->bv_val, sizeof(guid.info)); + printf("%s: %s\n", field, uuid_string_static(guid)); + } +} + /* dump a sid result from ldap */ @@ -1161,7 +1189,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) BOOL string; void (*handler)(const char *, struct berval **); } handlers[] = { - {"objectGUID", False, dump_binary}, + {"objectGUID", False, dump_guid}, {"nTSecurityDescriptor", False, dump_sd}, {"dnsRecord", False, dump_binary}, {"objectSid", False, dump_sid}, -- cgit From ab1cf8d1cf447e85063b43b65fa05c8b4bfde2a9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 6 Nov 2002 05:14:15 +0000 Subject: Merge of get_dc_list() api change from HEAD. (This used to be commit 6ba7847ce2756fde94e530fd0bf2a055f3e27373) --- source3/libads/ldap.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2359dbd7ed..a59b78bf13 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -180,7 +180,7 @@ static BOOL ads_try_dns(ADS_STRUCT *ads) /* try connecting to a ldap server via netbios */ static BOOL ads_try_netbios(ADS_STRUCT *ads) { - struct in_addr *ip_list; + struct in_addr *ip_list, pdc_ip; int count; int i; char *workgroup = ads->server.workgroup; @@ -192,20 +192,15 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads) DEBUG(6,("ads_try_netbios: looking for workgroup '%s'\n", workgroup)); /* try the PDC first */ - if (get_dc_list(True, workgroup, &ip_list, &count)) { - for (i=0;i Date: Tue, 12 Nov 2002 23:20:50 +0000 Subject: Removed global_myworkgroup, global_myname, global_myscope. Added liberal dashes of const. This is a rather large check-in, some things may break. It does compile though :-). Jeremy. (This used to be commit f755711df8f74f9b8e8c1a2b0d07d02a931eeb89) --- source3/libads/ldap.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a59b78bf13..d5cd56001b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -105,26 +105,28 @@ static int ldap_ip_compare(struct ldap_ip *ip1, struct ldap_ip *ip2) /* try connecting to a ldap server via DNS */ static BOOL ads_try_dns(ADS_STRUCT *ads) { - char *realm, *ptr; + const char *c_realm; + const char *ptr; + char *realm; char *list = NULL; pstring tok; struct ldap_ip *ip_list; int count, i=0; - realm = ads->server.realm; - if (!realm || !*realm) { - realm = lp_realm(); + c_realm = ads->server.realm; + if (!c_realm || !*c_realm) { + c_realm = lp_realm(); } - if (!realm || !*realm) { - realm = ads->server.workgroup; + if (!c_realm || !*c_realm) { + c_realm = ads->server.workgroup; } - if (!realm || !*realm) { - realm = lp_workgroup(); + if (!c_realm || !*c_realm) { + c_realm = lp_workgroup(); } - if (!realm) { + if (!c_realm) { return False; } - realm = smb_xstrdup(realm); + realm = smb_xstrdup(c_realm); DEBUG(6,("ads_try_dns: looking for realm '%s'\n", realm)); if (ldap_domain2hostlist(realm, &list) != LDAP_SUCCESS) { @@ -183,7 +185,7 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads) struct in_addr *ip_list, pdc_ip; int count; int i; - char *workgroup = ads->server.workgroup; + const char *workgroup = ads->server.workgroup; if (!workgroup) { workgroup = lp_workgroup(); @@ -273,9 +275,8 @@ got_connection: if (!ads->auth.user_name) { /* by default use the machine account */ - extern pstring global_myname; fstring myname; - fstrcpy(myname, global_myname); + fstrcpy(myname, global_myname()); strlower(myname); asprintf(&ads->auth.user_name, "HOST/%s", myname); } @@ -435,8 +436,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, else { /* This would be the utf8-encoded version...*/ /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ - if (!(str_list_copy(&search_attrs, attrs))) - { + if (!(str_list_copy(&search_attrs, attrs))) { rc = LDAP_NO_MEMORY; goto done; } @@ -1026,7 +1026,8 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ADS_MODLIST mods; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; - char *servicePrincipalName[3] = {NULL, NULL, NULL}; + const char *servicePrincipalName[3] = {NULL, NULL, NULL}; + char *psp; unsigned acct_control; if (!(ctx = talloc_init_named("machine_account"))) @@ -1046,10 +1047,11 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str, ads->config.bind_path); servicePrincipalName[0] = talloc_asprintf(ctx, "HOST/%s", hostname); - servicePrincipalName[1] = talloc_asprintf(ctx, "HOST/%s.%s", + psp = talloc_asprintf(ctx, "HOST/%s.%s", hostname, ads->config.realm); - strlower(&servicePrincipalName[1][5]); + strlower(&psp[5]); + servicePrincipalName[1] = psp; free(ou_str); if (!new_dn) -- cgit From c64d762997c80bd9ad2d47d1799cf9ec870d455a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 15 Nov 2002 21:43:57 +0000 Subject: Updates from HEAD: - const for PACKS() in lanman.c - change auth to 'account before password' - add help to net rpc {vampire,samsync} - configure updates for sun workshop cc - become_root() around pdb_ calls in auth_util for guest login. Andrew Bartlett (This used to be commit 43e90eb6e331d478013a9c038292f245edc51bd0) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d5cd56001b..60427323b0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1790,8 +1790,8 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) p = strchr(ads->config.ldap_server_name, '$'); if (!p || p[1] != '@') { talloc_destroy(ctx); + DEBUG(1, ("ads_server_info: returned ldap server name (%s) does not contain '$@' so was deemed invalid\n", ads->config.ldap_server_name)); SAFE_FREE(ads->config.ldap_server_name); - DEBUG(1, ("ads_server_info: returned ldap server name did not contain '$@' so was deemed invalid\n")); return ADS_ERROR(LDAP_DECODING_ERROR); } -- cgit From 3ab6fcc5c6160d322bdfd2ca771dcf7954e92df7 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 23 Nov 2002 14:52:34 +0000 Subject: [merge from APP_HEAD] 90% fix for CR 1076. The password server parameter will no take things like password server = DC1 * which means to contact DC1 first and the go to auto lookup if it fails. jerry (This used to be commit 016ef8b36b30846311a5321803298f8e28719244) --- source3/libads/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 60427323b0..fcb96dd174 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -186,6 +186,7 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads) int count; int i; const char *workgroup = ads->server.workgroup; + BOOL list_ordered; if (!workgroup) { workgroup = lp_workgroup(); @@ -202,7 +203,7 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads) } /* now any DC, including backups */ - if (get_dc_list(workgroup, &ip_list, &count)) { + if (get_dc_list(workgroup, &ip_list, &count, &list_ordered)) { for (i=0;i Date: Fri, 13 Dec 2002 19:01:27 +0000 Subject: More printer publishing code. - Add published attribute to info2, needed for win clients to work properly - Return proper info on getprinter 7 This means you can now look at the sharing tab of a printer and get correct info about whether it is published or not, and change it. (This used to be commit d57bddc9b22e809c79294c7eacbd5d0f115fe990) --- source3/libads/ldap.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index fcb96dd174..af9a6451fe 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1581,6 +1581,32 @@ BOOL ads_pull_uint32(ADS_STRUCT *ads, return True; } +/** + * pull a single objectGUID from an ADS result + * @param ads connection to ADS server + * @param msg results of search + * @param guid 37-byte area to receive text guid + * @return boolean indicating success + **/ +BOOL ads_pull_guid(ADS_STRUCT *ads, + void *msg, GUID *guid) +{ + char **values; + + values = ldap_get_values(ads->ld, msg, "objectGUID"); + if (!values) return False; + + if (values[0]) { + memcpy(guid, values[0], sizeof(GUID)); + ldap_value_free(values); + return True; + } + ldap_value_free(values); + return False; + +} + + /** * pull a single DOM_SID from a ADS result * @param ads connection to ads server -- cgit From ef8bd7c4f7ae8192ea05db070962ecf0ff3615f3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 20 Dec 2002 20:21:31 +0000 Subject: Forward port the change to talloc_init() to make all talloc contexts named. Ensure we can query them. Jeremy. (This used to be commit 09a218a9f6fb0bd922940467bf8500eb4f1bcf84) --- source3/libads/ldap.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index af9a6451fe..97ccf76983 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -420,7 +420,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, *res = NULL; - if (!(ctx = talloc_init())) + if (!(ctx = talloc_init("ads_do_paged_search"))) return ADS_ERROR(LDAP_NO_MEMORY); /* 0 means the conversion worked but the result was empty @@ -642,7 +642,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, char *utf8_exp, *utf8_path, **search_attrs = NULL; TALLOC_CTX *ctx; - if (!(ctx = talloc_init())) { + if (!(ctx = talloc_init("ads_do_search"))) { DEBUG(1,("ads_do_search: talloc_init() failed!")); return ADS_ERROR(LDAP_NO_MEMORY); } @@ -1031,7 +1031,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, char *psp; unsigned acct_control; - if (!(ctx = talloc_init_named("machine_account"))) + if (!(ctx = talloc_init("machine_account"))) return ADS_ERROR(LDAP_NO_MEMORY); ret = ADS_ERROR(LDAP_NO_MEMORY); @@ -1144,7 +1144,7 @@ static void dump_sd(const char *filed, struct berval **values) SEC_DESC *psd = 0; TALLOC_CTX *ctx = 0; - if (!(ctx = talloc_init_named("sec_io_desc"))) + if (!(ctx = talloc_init("sec_io_desc"))) return; /* prepare data */ @@ -1246,7 +1246,7 @@ void ads_process_results(ADS_STRUCT *ads, void *res, void *msg; TALLOC_CTX *ctx; - if (!(ctx = talloc_init())) + if (!(ctx = talloc_init("ads_process_results"))) return; for (msg = ads_first_entry(ads, res); msg; @@ -1429,7 +1429,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) msg = ads_first_entry(ads, res); ads_pull_sid(ads, msg, attrs[1], &sid); - if (!(ctx = talloc_init_named("sec_io_desc"))) { + if (!(ctx = talloc_init("sec_io_desc"))) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; } @@ -1785,7 +1785,7 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) char *timestr; TALLOC_CTX *ctx; - if (!(ctx = talloc_init())) { + if (!(ctx = talloc_init("ads_server_info"))) { return ADS_ERROR(LDAP_NO_MEMORY); } -- cgit From 64501e44ee672936b206ed2d80e13e4c39bbd95c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 30 Dec 2002 23:55:53 +0000 Subject: Catching up with old patches. Add define for VERITAS quota support. Check return in ldap. Jeremy. (This used to be commit 66eff26fc930e37035bba8672f5fd3aeae71078d) --- source3/libads/ldap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 97ccf76983..1ed1da0b5d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -326,6 +326,8 @@ static struct berval *dup_berval(TALLOC_CTX *ctx, const struct berval *in_val) if (!in_val) return NULL; value = talloc_zero(ctx, sizeof(struct berval)); + if (value == NULL) + return NULL; if (in_val->bv_len == 0) return value; value->bv_len = in_val->bv_len; -- cgit From 634c54310c92c48dd4eceec602e230a021bdcfc5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 3 Jan 2003 08:28:12 +0000 Subject: Merge from HEAD - make Samba compile with -Wwrite-strings without additional warnings. (Adds a lot of const). Andrew Bartlett (This used to be commit 3a7458f9472432ef12c43008414925fd1ce8ea0c) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1ed1da0b5d..1743bc2dd6 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1184,8 +1184,8 @@ static void dump_string(const char *field, char **values) static BOOL ads_dump_field(char *field, void **values, void *data_area) { - struct { - char *name; + const struct { + const char *name; BOOL string; void (*handler)(const char *, struct berval **); } handlers[] = { -- cgit From 8308ec6979d8d71903cb82963827d194d8c7bff3 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 21 Jan 2003 01:21:33 +0000 Subject: sanity checks from Ken Cross (This used to be commit 9f35846b8e0d711c9101ade9e79394219045383c) --- source3/libads/ldap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1743bc2dd6..0a95e019bf 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1429,7 +1429,11 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) if (!ADS_ERR_OK(ret)) return ret; - msg = ads_first_entry(ads, res); + if ( !(msg = ads_first_entry(ads, res) )) { + ret = ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + goto ads_set_sd_error; + } + ads_pull_sid(ads, msg, attrs[1], &sid); if (!(ctx = talloc_init("sec_io_desc"))) { ret = ADS_ERROR(LDAP_NO_MEMORY); -- cgit From 963e88aa90853a7e45c72cbc6630aa705b6d4e55 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 1 Feb 2003 07:59:29 +0000 Subject: Merge LDAP filter parinoia from HEAD, a few other pdb_ldap updates and some misc libads fixes. Andrew Bartlett (This used to be commit 9c3a1710efba9fa4160004a554687d4b85927bb1) --- source3/libads/ldap.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0a95e019bf..603f17c994 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -974,7 +974,7 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_add_s(ads->ld, utf8_dn ? utf8_dn : new_dn, mods); + ret = ldap_add_s(ads->ld, utf8_dn, mods); SAFE_FREE(utf8_dn); return ADS_ERROR(ret); } @@ -994,7 +994,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - ret = ldap_delete(ads->ld, utf8_dn ? utf8_dn : del_dn); + ret = ldap_delete(ads->ld, utf8_dn); return ADS_ERROR(ret); } @@ -1029,8 +1029,8 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ADS_MODLIST mods; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; - const char *servicePrincipalName[3] = {NULL, NULL, NULL}; - char *psp; + const char *servicePrincipalName[5] = {NULL, NULL, NULL, NULL, NULL}; + char *psp, *psp2; unsigned acct_control; if (!(ctx = talloc_init("machine_account"))) @@ -1051,10 +1051,16 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ads->config.bind_path); servicePrincipalName[0] = talloc_asprintf(ctx, "HOST/%s", hostname); psp = talloc_asprintf(ctx, "HOST/%s.%s", - hostname, - ads->config.realm); + hostname, + ads->config.realm); strlower(&psp[5]); servicePrincipalName[1] = psp; + servicePrincipalName[2] = talloc_asprintf(ctx, "CIFS/%s", hostname); + psp2 = talloc_asprintf(ctx, "CIFS/%s.%s", + hostname, + ads->config.realm); + strlower(&psp2[5]); + servicePrincipalName[3] = psp2; free(ou_str); if (!new_dn) @@ -1405,6 +1411,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) size_t sd_size = 0; struct berval bval = {0, NULL}; prs_struct ps_wire; + char *escaped_hostname = escape_ldap_string_alloc(hostname); LDAPMessage *res = 0; LDAPMessage *msg = 0; @@ -1420,11 +1427,18 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) ret = ADS_ERROR(LDAP_SUCCESS); - if (asprintf(&exp, "(samAccountName=%s$)", hostname) == -1) { + if (!escaped_hostname) { + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + + if (asprintf(&exp, "(samAccountName=%s$)", escaped_hostname) == -1) { DEBUG(1, ("ads_set_machine_sd: asprintf failed!\n")); + SAFE_FREE(escaped_hostname); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } + SAFE_FREE(escaped_hostname); + ret = ads_search(ads, (void *) &res, exp, attrs); if (!ADS_ERR_OK(ret)) return ret; -- cgit From eccae5d23a5a4e2ee63891196d27cc4938019893 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 4 Feb 2003 23:44:28 +0000 Subject: Mem alloc checks. Jeremy. (This used to be commit 46ea028169426fbcad92d3d5bf786e88be8f5112) --- source3/libads/ldap.c | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 603f17c994..41e70fbcae 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1528,7 +1528,8 @@ char *ads_pull_string(ADS_STRUCT *ads, int rc; values = ldap_get_values(ads->ld, msg, field); - if (!values) return NULL; + if (!values) + return NULL; if (values[0]) { rc = pull_utf8_talloc(mem_ctx, &ux_string, @@ -1557,15 +1558,22 @@ char **ads_pull_strings(ADS_STRUCT *ads, int i, n; values = ldap_get_values(ads->ld, msg, field); - if (!values) return NULL; + if (!values) + return NULL; - for (i=0;values[i];i++) /* noop */ ; + for (i=0;values[i];i++) + /* noop */ ; n = i; ret = talloc(mem_ctx, sizeof(char *) * (n+1)); + if (!ret) { + ldap_value_free(values); + return NULL; + } for (i=0;ild, msg, field); - if (!values) return False; + if (!values) + return False; if (!values[0]) { ldap_value_free(values); return False; @@ -1614,7 +1623,8 @@ BOOL ads_pull_guid(ADS_STRUCT *ads, char **values; values = ldap_get_values(ads->ld, msg, "objectGUID"); - if (!values) return False; + if (!values) + return False; if (values[0]) { memcpy(guid, values[0], sizeof(GUID)); @@ -1643,11 +1653,11 @@ BOOL ads_pull_sid(ADS_STRUCT *ads, values = ldap_get_values_len(ads->ld, msg, field); - if (!values) return False; + if (!values) + return False; - if (values[0]) { + if (values[0]) ret = sid_parse(values[0]->bv_val, values[0]->bv_len, sid); - } ldap_value_free_len(values); return ret; @@ -1671,16 +1681,23 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, values = ldap_get_values_len(ads->ld, msg, field); - if (!values) return 0; + if (!values) + return 0; - for (i=0; values[i]; i++) /* nop */ ; + for (i=0; values[i]; i++) + /* nop */ ; (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * i); + if (!(*sids)) { + ldap_value_free_len(values); + return 0; + } count = 0; for (i=0; values[i]; i++) { ret = sid_parse(values[i]->bv_val, values[i]->bv_len, &(*sids)[count]); - if (ret) count++; + if (ret) + count++; } ldap_value_free_len(values); -- cgit From abbbaa2f6f9f05164cf146ea3c712ea5a57afaa9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 12 Feb 2003 01:07:48 +0000 Subject: Merging from HEAD - add a note about a better method for finding netbios name of workgroup (not implemented yet) Jeremy. (This used to be commit c0eab99753032f5f49bc7adeb1ff95eceb6fe0fe) --- source3/libads/ldap.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 41e70fbcae..867d124273 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1981,6 +1981,13 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) for the domain, but there isn't a simple query to do this. Instead we look for the principle names on the DCs account and find one that has the right form, then extract the netbios name of the domain from that + + NOTE! better method is this: + +bin/net -Uadministrator%XXXXX ads search '(&(objectclass=crossref)(dnsroot=VNET3.HOME.SAMBA.ORG))' nETBIOSName + +but you need to force the bind path to match the configurationNamingContext from the rootDSE + */ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workgroup) { -- cgit From 8fc1f1aead6db996a6d96efdc5f81779afc9c8d2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Feb 2003 22:55:46 +0000 Subject: Ensure that only parse_prs.c access internal members of the prs_struct. Needed to move to disk based i/o later. Jeremy. (This used to be commit a823fee5b41a5b6cd4ef05aa1f85f7725bd272a5) --- source3/libads/ldap.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 867d124273..47a94f0a08 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1157,8 +1157,8 @@ static void dump_sd(const char *filed, struct berval **values) /* prepare data */ prs_init(&ps, values[0]->bv_len, ctx, UNMARSHALL); - prs_append_data(&ps, values[0]->bv_val, values[0]->bv_len); - ps.data_offset = 0; + prs_copy_data_in(&ps, values[0]->bv_val, values[0]->bv_len); + prs_set_offset(&ps,0); /* parse secdesc */ if (!sec_io_desc("sd", &psd, &ps, 1)) { @@ -1478,7 +1478,13 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY); bval.bv_len = sd_size; - bval.bv_val = prs_data_p(&ps_wire); + bval.bv_val = talloc(ctx, sd_size); + if (!bval.bv_val) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto ads_set_sd_error; + } + prs_copy_all_data_out((char *)&bval.bv_val, &ps_wire); + ads_mod_ber(ctx, &mods, attrs[0], &bval); ret = ads_gen_mod(ads, dn, mods); @@ -1726,8 +1732,8 @@ BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, if (values[0]) { prs_init(&ps, values[0]->bv_len, mem_ctx, UNMARSHALL); - prs_append_data(&ps, values[0]->bv_val, values[0]->bv_len); - ps.data_offset = 0; + prs_copy_data_in(&ps, values[0]->bv_val, values[0]->bv_len); + prs_set_offset(&ps,0); ret = sec_io_desc("sd", sd, &ps, 1); } -- cgit From 251ea1e6776401005e302addd56a689c01924426 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 19 Feb 2003 12:31:16 +0000 Subject: Merge minor library fixes from HEAD to 3.0. - setenv() replacement - mimir's ASN1/SPNEGO typo fixes - (size_t)-1 fixes for push_* returns - function argument signed/unsigned correction - ASN1 error handling (ensure we don't use initiailsed data) - extra net ads join error checking - allow 'set security discriptor' to fail - escape ldap strings in libads. - getgrouplist() correctness fixes (include primary gid) Andrew Bartlett (This used to be commit e9d6e2ea9a3dc01d3849b925c50702cda6ddf225) --- source3/libads/ldap.c | 49 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 47a94f0a08..b7cfc8d84c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -426,10 +426,10 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, 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 + so we only fail if it's -1. In any case, it always at least nulls out the dest */ - if ((push_utf8_talloc(ctx, &utf8_exp, exp) < 0) || - (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) { + if ((push_utf8_talloc(ctx, &utf8_exp, exp) == (size_t)-1) || + (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) { rc = LDAP_NO_MEMORY; goto done; } @@ -652,8 +652,8 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, /* 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, &utf8_exp, exp) < 0) || - (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) { + if ((push_utf8_talloc(ctx, &utf8_exp, exp) == (size_t)-1) || + (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) { DEBUG(1,("ads_do_search: push_utf8_talloc() failed!")); rc = LDAP_NO_MEMORY; goto done; @@ -1022,7 +1022,7 @@ char *ads_ou_string(const char *org_unit) static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, const char *org_unit) { - ADS_STATUS ret; + ADS_STATUS ret, status; char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr; char *ou_str; TALLOC_CTX *ctx; @@ -1089,9 +1089,21 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, 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); + ret = ads_gen_add(ads, new_dn, mods); + + if (!ADS_ERR_OK(ret)) + goto done; + + /* Do not fail if we can't set security descriptor + * it shouldn't be mandatory and probably we just + * don't have enough rights to do it. + */ + status = ads_set_machine_sd(ads, hostname, new_dn); + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("Warning: ads_set_machine_sd: %s\n", + ads_errstr(status))); + } done: talloc_destroy(ctx); return ret; @@ -1406,7 +1418,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) **/ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) { - const char *attrs[] = {"ntSecurityDescriptor", "objectSid", 0}; + const char *attrs[] = {"nTSecurityDescriptor", "objectSid", 0}; char *exp = 0; size_t sd_size = 0; struct berval bval = {0, NULL}; @@ -1420,8 +1432,12 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) NTSTATUS status; ADS_STATUS ret; DOM_SID sid; - SEC_DESC *psd = 0; - TALLOC_CTX *ctx = 0; + SEC_DESC *psd = NULL; + TALLOC_CTX *ctx = NULL; + + /* Avoid segmentation fault in prs_mem_free if + * we have to bail out before prs_init */ + ps_wire.is_dynamic = False; if (!ads) return ADS_ERROR(LDAP_SERVER_DOWN); @@ -1448,7 +1464,11 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) goto ads_set_sd_error; } - ads_pull_sid(ads, msg, attrs[1], &sid); + if (!ads_pull_sid(ads, msg, attrs[1], &sid)) { + ret = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); + goto ads_set_sd_error; + } + if (!(ctx = talloc_init("sec_io_desc"))) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; @@ -1466,7 +1486,10 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) goto ads_set_sd_error; } - prs_init(&ps_wire, sd_size, ctx, MARSHALL); + if (!prs_init(&ps_wire, sd_size, ctx, MARSHALL)) { + ret = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1)) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; -- cgit From 4560329abbdbdc9dea75f32422ba9b08bcfee726 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 19 Feb 2003 15:04:04 +0000 Subject: Fix segv in net ads join...an extra & was the culprit (This used to be commit 1a9050a6fe419e14fc82674d34cc4685a7532059) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b7cfc8d84c..67669fc078 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1506,7 +1506,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; } - prs_copy_all_data_out((char *)&bval.bv_val, &ps_wire); + prs_copy_all_data_out(bval.bv_val, &ps_wire); ads_mod_ber(ctx, &mods, attrs[0], &bval); ret = ads_gen_mod(ads, dn, mods); -- cgit From d1221c9b6c369113a531063737890b58d89bf6fe Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 02:55:00 +0000 Subject: Merge from HEAD client-side authentication changes: - new kerberos code, allowing the account to change it's own password without special SD settings required - NTLMSSP client code, now seperated from cliconnect.c - NTLMv2 client code - SMB signing fixes Andrew Bartlett (This used to be commit 837680ca517982f2e5944730581a83012d4181ae) --- source3/libads/ldap.c | 51 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 18 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 67669fc078..bc90e90ea0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -816,18 +816,18 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, { int curmod; LDAPMod **modlist = (LDAPMod **) *mods; - void **values; + struct berval **ber_values; + char **char_values; if (!invals) { - values = NULL; mod_op = LDAP_MOD_DELETE; } else { if (mod_op & LDAP_MOD_BVALUES) - values = (void **) ads_dup_values(ctx, - (const struct berval **)invals); + ber_values = ads_dup_values(ctx, + (const struct berval **)invals); else - values = (void **) ads_push_strvals(ctx, - (const char **) invals); + char_values = ads_push_strvals(ctx, + (const char **) invals); } /* find the first empty slot */ @@ -846,10 +846,14 @@ 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 = talloc_strdup(ctx, name); - if (mod_op & LDAP_MOD_BVALUES) - modlist[curmod]->mod_bvalues = (struct berval **) values; - else - modlist[curmod]->mod_values = (char **) values; + if (mod_op & LDAP_MOD_BVALUES) { + modlist[curmod]->mod_bvalues = ber_values; + } else if (mod_op & LDAP_MOD_DELETE) { + modlist[curmod]->mod_values = NULL; + } else { + modlist[curmod]->mod_values = char_values; + } + modlist[curmod]->mod_op = mod_op; return ADS_ERROR(LDAP_SUCCESS); } @@ -1500,16 +1504,24 @@ 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); - bval.bv_len = sd_size; - bval.bv_val = talloc(ctx, sd_size); + bval.bv_len = prs_offset(&ps_wire); + bval.bv_val = talloc(ctx, bval.bv_len); if (!bval.bv_val) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; } - prs_copy_all_data_out(bval.bv_val, &ps_wire); - ads_mod_ber(ctx, &mods, attrs[0], &bval); - ret = ads_gen_mod(ads, dn, mods); + prs_set_offset(&ps_wire, 0); + + if (!prs_copy_data_out(bval.bv_val, &ps_wire, bval.bv_len)) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto ads_set_sd_error; + } + + ret = ads_mod_ber(ctx, &mods, attrs[0], &bval); + if (ADS_ERR_OK(ret)) { + ret = ads_gen_mod(ads, dn, mods); + } ads_set_sd_error: ads_msgfree(ads, res); @@ -1554,7 +1566,7 @@ char *ads_pull_string(ADS_STRUCT *ads, char **values; char *ret = NULL; char *ux_string; - int rc; + size_t rc; values = ldap_get_values(ads->ld, msg, field); if (!values) @@ -1563,7 +1575,7 @@ char *ads_pull_string(ADS_STRUCT *ads, if (values[0]) { rc = pull_utf8_talloc(mem_ctx, &ux_string, values[0]); - if (rc != -1) + if (rc != (size_t)-1) ret = ux_string; } @@ -1725,8 +1737,11 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, count = 0; for (i=0; values[i]; i++) { ret = sid_parse(values[i]->bv_val, values[i]->bv_len, &(*sids)[count]); - if (ret) + if (ret) { + fstring sid; + DEBUG(10, ("pulling SID: %s\n", sid_to_string(sid, &(*sids)[count]))); count++; + } } ldap_value_free_len(values); -- cgit From a65b65c87a61ed602cce36a24c14c02ad3b373bc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 03:43:49 +0000 Subject: Make sure these values are never uninitialsised. (This used to be commit eacb8dde7afa16d86586c6c896ffb6692dc53bf6) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index bc90e90ea0..29f44672f4 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -816,8 +816,8 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, { int curmod; LDAPMod **modlist = (LDAPMod **) *mods; - struct berval **ber_values; - char **char_values; + struct berval **ber_values = NULL; + char **char_values = NULL; if (!invals) { mod_op = LDAP_MOD_DELETE; -- cgit From aa4bfd47113e0212aa72be067c20da56b8381648 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 17 Mar 2003 22:41:14 +0000 Subject: merge from HEAD - dump tokenGroups as sids. (This used to be commit f0daa15521e6352e25aa998f7e682f448e0fe51a) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 29f44672f4..67827d27f3 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1215,6 +1215,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) {"nTSecurityDescriptor", False, dump_sd}, {"dnsRecord", False, dump_binary}, {"objectSid", False, dump_sid}, + {"tokenGroups", False, dump_sid}, {NULL, True, NULL} }; int i; -- cgit From f7792732e66b7fc9a6ef4a07ea35b3a2e50f3f69 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Apr 2003 17:06:51 +0000 Subject: Change variable name to get this working on gcc 3.2 (Merge from HEAD) (This used to be commit d49113caef6057905f0f5233ea3085ca5722e742) --- source3/libads/ldap.c | 66 +++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 67827d27f3..baedfb28db 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -401,7 +401,7 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) * @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 - specified in local charset + * @param expr 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 @@ -409,12 +409,12 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) * @return status of search **/ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *exp, + int scope, const char *expr, const char **attrs, void **res, int *count, void **cookie) { int rc, i, version; - char *utf8_exp, *utf8_path, **search_attrs; + char *utf8_expr, *utf8_path, **search_attrs; LDAPControl PagedResults, NoReferrals, *controls[3], **rcontrols; BerElement *cookie_be = NULL; struct berval *cookie_bv= NULL; @@ -428,7 +428,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, /* 0 means the conversion worked but the result was empty so we only fail if it's -1. In any case, it always at least nulls out the dest */ - if ((push_utf8_talloc(ctx, &utf8_exp, exp) == (size_t)-1) || + if ((push_utf8_talloc(ctx, &utf8_expr, expr) == (size_t)-1) || (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) { rc = LDAP_NO_MEMORY; goto done; @@ -489,7 +489,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, */ ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_exp, + rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_expr, search_attrs, 0, controls, NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); @@ -497,7 +497,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, ber_bvfree(cookie_bv); if (rc) { - DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", exp, ldap_err2string(rc))); + DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", expr, ldap_err2string(rc))); goto done; } @@ -541,20 +541,20 @@ done: * @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 expr Search expression * @param attrs Attributes to retrieve * @param res ** which will contain results - free res* with ads_msgfree() * @return status of search **/ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *exp, + int scope, const char *expr, const char **attrs, void **res) { void *cookie = NULL; int count = 0; ADS_STATUS status; - status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, res, + status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, res, &count, &cookie); if (!ADS_ERR_OK(status)) return status; @@ -564,7 +564,7 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, ADS_STATUS status2; LDAPMessage *msg, *next; - status2 = ads_do_paged_search(ads, bind_path, scope, exp, + status2 = ads_do_paged_search(ads, bind_path, scope, expr, attrs, &res2, &count, &cookie); if (!ADS_ERR_OK(status2)) break; @@ -588,14 +588,14 @@ 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 - specified in local charset + * @param expr 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, + int scope, const char *expr, const char **attrs, BOOL(*fn)(char *, void **, void *), void *data_area) { @@ -604,7 +604,7 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, ADS_STATUS status; void *res; - status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, &res, + status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, &res, &count, &cookie); if (!ADS_ERR_OK(status)) return status; @@ -613,7 +613,7 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, ads_msgfree(ads, res); while (cookie) { - status = ads_do_paged_search(ads, bind_path, scope, exp, attrs, + status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, &res, &count, &cookie); if (!ADS_ERR_OK(status)) break; @@ -630,18 +630,18 @@ ADS_STATUS ads_do_search_all_fn(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 expr Search expression * @param attrs Attributes to retrieve * @param res ** which will contain results - free res* with ads_msgfree() * @return status of search **/ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, - const char *exp, + const char *expr, const char **attrs, void **res) { struct timeval timeout; int rc; - char *utf8_exp, *utf8_path, **search_attrs = NULL; + char *utf8_expr, *utf8_path, **search_attrs = NULL; TALLOC_CTX *ctx; if (!(ctx = talloc_init("ads_do_search"))) { @@ -652,7 +652,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, /* 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, &utf8_exp, exp) == (size_t)-1) || + if ((push_utf8_talloc(ctx, &utf8_expr, expr) == (size_t)-1) || (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) { DEBUG(1,("ads_do_search: push_utf8_talloc() failed!")); rc = LDAP_NO_MEMORY; @@ -679,7 +679,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, /* 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, + rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_expr, search_attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); @@ -698,16 +698,16 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, * Do a general ADS search * @param ads connection to ads server * @param res ** which will contain results - free res* with ads_msgfree() - * @param exp Search expression + * @param expr Search expression * @param attrs Attributes to retrieve * @return status of search **/ ADS_STATUS ads_search(ADS_STRUCT *ads, void **res, - const char *exp, + const char *expr, const char **attrs) { return ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, - exp, attrs, res); + expr, attrs, res); } /** @@ -772,18 +772,18 @@ char *ads_get_dn(ADS_STRUCT *ads, void *res) ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) { ADS_STATUS status; - char *exp; + char *expr; const char *attrs[] = {"*", "nTSecurityDescriptor", NULL}; /* the easiest way to find a machine account anywhere in the tree is to look for hostname$ */ - if (asprintf(&exp, "(samAccountName=%s$)", host) == -1) { + if (asprintf(&expr, "(samAccountName=%s$)", host) == -1) { DEBUG(1, ("asprintf failed!\n")); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - status = ads_search(ads, res, exp, attrs); - free(exp); + status = ads_search(ads, res, expr, attrs); + free(expr); return status; } @@ -1424,7 +1424,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) { const char *attrs[] = {"nTSecurityDescriptor", "objectSid", 0}; - char *exp = 0; + char *expr = 0; size_t sd_size = 0; struct berval bval = {0, NULL}; prs_struct ps_wire; @@ -1452,7 +1452,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - if (asprintf(&exp, "(samAccountName=%s$)", escaped_hostname) == -1) { + if (asprintf(&expr, "(samAccountName=%s$)", escaped_hostname) == -1) { DEBUG(1, ("ads_set_machine_sd: asprintf failed!\n")); SAFE_FREE(escaped_hostname); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); @@ -1460,7 +1460,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) SAFE_FREE(escaped_hostname); - ret = ads_search(ads, (void *) &res, exp, attrs); + ret = ads_search(ads, (void *) &res, expr, attrs); if (!ADS_ERR_OK(ret)) return ret; @@ -2036,7 +2036,7 @@ but you need to force the bind path to match the configurationNamingContext from */ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workgroup) { - char *exp; + char *expr; ADS_STATUS rc; char **principles; char *prefix; @@ -2047,10 +2047,10 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workg (*workgroup) = NULL; - asprintf(&exp, "(&(objectclass=computer)(dnshostname=%s.%s))", + asprintf(&expr, "(&(objectclass=computer)(dnshostname=%s.%s))", ads->config.ldap_server_name, ads->config.realm); - rc = ads_search(ads, &res, exp, attrs); - free(exp); + rc = ads_search(ads, &res, expr, attrs); + free(expr); if (!ADS_ERR_OK(rc)) { return rc; -- cgit From f071020f5e49837154581c97c5af5f84d0e2de89 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 21 Apr 2003 14:09:03 +0000 Subject: Merge from HEAD - save the type of channel used to contact the DC. This allows us to join as a BDC, without appearing on the network as one until we have the database replicated, and the admin changes the configuration. This also change the SID retreval order from secrets.tdb, so we no longer require a 'net rpc getsid' - the sid fetch during the domain join is sufficient. Also minor fixes to 'net'. Andrew Bartlett (This used to be commit 876e00fd112e4aaf7519eec27f382eb99ec7562a) --- source3/libads/ldap.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index baedfb28db..3ce80975da 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1024,6 +1024,7 @@ char *ads_ou_string(const char *org_unit) add a machine account to the ADS server */ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, + uint32 account_type, const char *org_unit) { ADS_STATUS ret, status; @@ -1073,7 +1074,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, if (!(samAccountName = talloc_asprintf(ctx, "%s$", hostname))) goto done; - acct_control = UF_WORKSTATION_TRUST_ACCOUNT | UF_DONT_EXPIRE_PASSWD; + acct_control = account_type | UF_DONT_EXPIRE_PASSWD; #ifndef ENCTYPE_ARCFOUR_HMAC acct_control |= UF_USE_DES_KEY_ONLY; #endif @@ -1335,7 +1336,8 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @param org_unit Organizational unit to place machine in * @return status of join **/ -ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org_unit) +ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, + uint32 account_type, const char *org_unit) { ADS_STATUS status; LDAPMessage *res; @@ -1356,7 +1358,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org } } - status = ads_add_machine_acct(ads, host, org_unit); + status = ads_add_machine_acct(ads, host, account_type, org_unit); if (!ADS_ERR_OK(status)) { DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(status))); return status; -- cgit From 0a9396dcca1e30fa32fbcde3ee2dce86f586ba4b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 13 Jun 2003 04:35:53 +0000 Subject: Rename some uuid functions so as not to conflict with system versions. Fixes bug #154. (This used to be commit 986eae40f7669d15dc75aed340e628aa7efafddc) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 3ce80975da..c685ed53ab 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1142,7 +1142,7 @@ static void dump_guid(const char *field, struct berval **values) GUID guid; for (i=0; values[i]; i++) { memcpy(guid.info, values[i]->bv_val, sizeof(guid.info)); - printf("%s: %s\n", field, uuid_string_static(guid)); + printf("%s: %s\n", field, smb_uuid_string_static(guid)); } } -- cgit From ec0303820fa5ec185f8942604ef3d97285374988 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 16 Jun 2003 02:42:00 +0000 Subject: we need to call ads_first_entry() before using a ldap result, otherwise we can segv or return garbage (This used to be commit d1316656b03e2bc85263b65d24977923ee6f39b7) --- source3/libads/ldap.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c685ed53ab..0a59c4eb8f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -749,14 +749,15 @@ void ads_memfree(ADS_STRUCT *ads, void *mem) /** * Get a dn from search results * @param ads connection to ads server - * @param res Search results + * @param msg Search result * @return dn string **/ -char *ads_get_dn(ADS_STRUCT *ads, void *res) +char *ads_get_dn(ADS_STRUCT *ads, void *msg) { char *utf8_dn, *unix_dn; - utf8_dn = ldap_get_dn(ads->ld, res); + utf8_dn = ldap_get_dn(ads->ld, msg); + pull_utf8_allocate((void **) &unix_dn, utf8_dn); ldap_memfree(utf8_dn); return unix_dn; @@ -1078,6 +1079,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, #ifndef ENCTYPE_ARCFOUR_HMAC acct_control |= UF_USE_DES_KEY_ONLY; #endif + if (!(controlstr = talloc_asprintf(ctx, "%u", acct_control))) goto done; @@ -1384,7 +1386,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) { ADS_STATUS status; - void *res; + void *res, *msg; char *hostnameDN, *host; int rc; @@ -1398,7 +1400,12 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return status; } - hostnameDN = ads_get_dn(ads, (LDAPMessage *)res); + msg = ads_first_entry(ads, res); + if (!msg) { + return ADS_ERROR_SYSTEM(ENOENT); + } + + hostnameDN = ads_get_dn(ads, (LDAPMessage *)msg); rc = ldap_delete_s(ads->ld, hostnameDN); ads_memfree(ads, hostnameDN); if (rc != LDAP_SUCCESS) { -- cgit From f36c96d59c79a51610bb5a1fc42ac62bd8d08401 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 23 Jun 2003 19:05:23 +0000 Subject: * s/get_dc_name/rpc_dc_name/g (revert a previous change) * move back to qsort() for sorting IP address in get_dc_list() * remove dc_name_cache in cm_get_dc_name() since it slowed things down more than it helped. I've made a note of where to add in the negative connection cache in the ads code. Will come back to that. * fix rpcclient to use PRINTER_ALL_ACCESS for set printer (instead of MAX_ALLOWED) * only enumerate domain local groups in our domain * simplify ldap search for seqnum in winbindd's rpc backend (This used to be commit f8cab8635b02b205b4031279cedd804c1fb22c5b) --- source3/libads/ldap.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0a59c4eb8f..0f1f205f9b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -41,6 +41,9 @@ /* try a connection to a given ldap server, returning True and setting the servers IP in the ads struct if successful + + TODO : add a negative connection cache in here leveraged off of the one + found in the rpc code. --jerry */ static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) { -- cgit From f51d769dd303027a3dbf46fc89a482933988e866 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Jun 2003 17:41:05 +0000 Subject: large change: *) consolidates the dc location routines again (dns and netbios) get_dc_list() or get_sorted_dc_list() is the authoritative means of locating DC's again. (also inludes a flag to get_dc_list() to define if this should be a DNS only lookup or not) (however, if you set "name resolve order = hosts wins" you could still get DNS queries for domain name IFF ldap_domain2hostlist() fails. The answer? Fix your DNS setup) *) enabled DOMAIN<0x1c> lookups to be funneled through resolve_hosts resulting in a call to ldap_domain2hostlist() if lp_security() == SEC_ADS *) enables name cache for winbind ADS backend *) enable the negative connection cache for winbind ADS backend *) removes some old dead code *) consolidates some duplicate code *) moves the internal_name_resolve() to use an IP/port pair to deal with SRV RR dns replies. The namecache code also supports the IP:port syntax now as well. *) removes 'ads server' and moves the functionality back into 'password server' (which can support "hostname:port" syntax now but works fine with defaults depending on the value of lp_security()) (This used to be commit d7f7fcda425bef380441509734eca33da943c091) --- source3/libads/ldap.c | 165 ++++++++++++++------------------------------------ 1 file changed, 47 insertions(+), 118 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0f1f205f9b..a168f75e98 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -93,133 +93,75 @@ static BOOL ads_try_connect_uri(ADS_STRUCT *ads) return False; } -/* used by the IP comparison function */ -struct ldap_ip { - struct in_addr ip; - unsigned port; -}; - -/* compare 2 ldap IPs by nearness to our interfaces - used in qsort */ -static int ldap_ip_compare(struct ldap_ip *ip1, struct ldap_ip *ip2) -{ - return ip_compare(&ip1->ip, &ip2->ip); -} +/********************************************************************** + Try to find an AD dc using our internal name resolution routines + Try the realm first and then then workgroup name if netbios is not + disabled +**********************************************************************/ -/* try connecting to a ldap server via DNS */ -static BOOL ads_try_dns(ADS_STRUCT *ads) +static BOOL ads_find_dc(ADS_STRUCT *ads) { const char *c_realm; - const char *ptr; - char *realm; - char *list = NULL; - pstring tok; - struct ldap_ip *ip_list; int count, i=0; + struct ip_service *ip_list; + pstring realm; + BOOL got_realm = False; + /* realm */ c_realm = ads->server.realm; if (!c_realm || !*c_realm) { c_realm = lp_realm(); } - if (!c_realm || !*c_realm) { - c_realm = ads->server.workgroup; - } - if (!c_realm || !*c_realm) { - c_realm = lp_workgroup(); - } - if (!c_realm) { - return False; - } - realm = smb_xstrdup(c_realm); + if ( c_realm ) + got_realm = True; - DEBUG(6,("ads_try_dns: looking for realm '%s'\n", realm)); - if (ldap_domain2hostlist(realm, &list) != LDAP_SUCCESS) { - SAFE_FREE(realm); - return False; + +again: + /* we need to try once with the realm name and fallback to the + netbios domain name if we fail (if netbios has not been disabled */ + + if ( !got_realm && !lp_disable_netbios() ) { + c_realm = ads->server.workgroup; + if (!c_realm || !*c_realm) + c_realm = lp_workgroup(); + if (!c_realm) + return False; } + + pstrcpy( realm, c_realm ); - DEBUG(6,("ads_try_dns: ldap realm '%s' host list '%s'\n", realm, list)); - SAFE_FREE(realm); - - count = count_chars(list, ' ') + 1; - ip_list = malloc(count * sizeof(struct ldap_ip)); - if (!ip_list) { - return False; - } + DEBUG(6,("ads_try_dns: looking for %s realm '%s'\n", + (got_realm ? "realm" : "domain"), realm)); - ptr = list; - while (next_token(&ptr, tok, " ", sizeof(tok))) { - unsigned port = LDAP_PORT; - char *p = strchr(tok, ':'); - if (p) { - *p = 0; - port = atoi(p+1); - } - ip_list[i].ip = *interpret_addr2(tok); - ip_list[i].port = port; - if (!is_zero_ip(ip_list[i].ip)) { - i++; + if ( !get_sorted_dc_list(realm, &ip_list, &count, got_realm) ) { + /* fall back to netbios if we can */ + if ( got_realm && !lp_disable_netbios() ) { + got_realm = False; + goto again; } + + return False; } - free(list); - - count = i; - - /* we sort the list of addresses by closeness to our interfaces. This - tries to prevent us using a DC on the other side of the country */ - if (count > 1) { - qsort(ip_list, count, sizeof(struct ldap_ip), - QSORT_CAST ldap_ip_compare); - } - - for (i=0;iserver.workgroup; - BOOL list_ordered; - - if (!workgroup) { - workgroup = lp_workgroup(); - } - - DEBUG(6,("ads_try_netbios: looking for workgroup '%s'\n", workgroup)); - - /* try the PDC first */ - if (get_pdc_ip(workgroup, &pdc_ip)) { - DEBUG(6,("ads_try_netbios: trying server '%s'\n", - inet_ntoa(pdc_ip))); - if (ads_try_connect(ads, inet_ntoa(pdc_ip), LDAP_PORT)) - return True; - } - - /* now any DC, including backups */ - if (get_dc_list(workgroup, &ip_list, &count, &list_ordered)) { - for (i=0;iserver.foreign && - ads_try_connect(ads, lp_ads_server(), LDAP_PORT)) { - goto got_connection; - } - - /* try via DNS */ - if (ads_try_dns(ads)) { - goto got_connection; - } - - /* try via netbios lookups */ - if (!lp_disable_netbios() && ads_try_netbios(ads)) { + if (ads_find_dc(ads)) { goto got_connection; } -- cgit From 72876b79c9b3f0ab3cda6de42d5c8995aadd687e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Jun 2003 19:00:15 +0000 Subject: * fix typos in a few debug statements * check negative connection cache before ads_try_connect() in ads_find_dc() (This used to be commit 2a76101a3a31f5fca2f444b25e3f0486f7ef406f) --- source3/libads/ldap.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a168f75e98..60bbef821c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -130,7 +130,7 @@ again: pstrcpy( realm, c_realm ); - DEBUG(6,("ads_try_dns: looking for %s realm '%s'\n", + DEBUG(6,("ads_find_dc: looking for %s '%s'\n", (got_realm ? "realm" : "domain"), realm)); if ( !get_sorted_dc_list(realm, &ip_list, &count, got_realm) ) { @@ -147,14 +147,20 @@ again: for ( i=0; i Date: Thu, 3 Jul 2003 04:12:54 +0000 Subject: Fix bug in doxygen comments for ads search functions. (This used to be commit ae6c05ea726da13fc1a18398d1ffe56f34e1edb9) --- source3/libads/ldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 60bbef821c..53c71c405a 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -338,7 +338,7 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) * again when the entire search is complete * @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 scope Scope of search (LDAP_SCOPE_BASE | LDAP_SCOPE_ONE | LDAP_SCOPE_SUBTREE) * @param expr 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() @@ -478,7 +478,7 @@ done: * all entries in a large search. * @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 scope Scope of search (LDAP_SCOPE_BASE | LDAP_SCOPE_ONE | LDAP_SCOPE_SUBTREE) * @param expr Search expression * @param attrs Attributes to retrieve * @param res ** which will contain results - free res* with ads_msgfree() @@ -525,7 +525,7 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, * runs the function as each page is returned, using ads_process_results() * @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 scope Scope of search (LDAP_SCOPE_BASE | LDAP_SCOPE_ONE | LDAP_SCOPE_SUBTREE) * @param expr 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 @@ -567,7 +567,7 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, * Do a search with a timeout. * @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 scope Scope of search (LDAP_SCOPE_BASE | LDAP_SCOPE_ONE | LDAP_SCOPE_SUBTREE) * @param expr Search expression * @param attrs Attributes to retrieve * @param res ** which will contain results - free res* with ads_msgfree() -- cgit From ce72beb2b558d86fb49063c6b1fa00e07952ce56 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Jul 2003 19:11:31 +0000 Subject: Removed strupper/strlower macros that automatically map to strupper_m/strlower_m. I really want people to think about when they're using multibyte strings. Jeremy. (This used to be commit ff222716a08af65d26ad842ce4c2841cc6540959) --- source3/libads/ldap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 53c71c405a..1886b525d9 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -216,7 +216,7 @@ got_connection: /* by default use the machine account */ fstring myname; fstrcpy(myname, global_myname()); - strlower(myname); + strlower_m(myname); asprintf(&ads->auth.user_name, "HOST/%s", myname); } @@ -997,13 +997,13 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, psp = talloc_asprintf(ctx, "HOST/%s.%s", hostname, ads->config.realm); - strlower(&psp[5]); + strlower_m(&psp[5]); servicePrincipalName[1] = psp; servicePrincipalName[2] = talloc_asprintf(ctx, "CIFS/%s", hostname); psp2 = talloc_asprintf(ctx, "CIFS/%s.%s", hostname, ads->config.realm); - strlower(&psp2[5]); + strlower_m(&psp2[5]); servicePrincipalName[3] = psp2; free(ou_str); @@ -1285,7 +1285,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, /* hostname must be lowercase */ host = strdup(hostname); - strlower(host); + strlower_m(host); status = ads_find_machine_acct(ads, (void **)&res, host); if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { @@ -1330,7 +1330,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) /* hostname must be lowercase */ host = strdup(hostname); - strlower(host); + strlower_m(host); status = ads_find_machine_acct(ads, &res, host); if (!ADS_ERR_OK(status)) { -- cgit From b5cd4a8643169b276a3af8a9272d212d76a54dd3 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 7 Jul 2003 02:50:09 +0000 Subject: Call the synchronous version of the ldap delete function otherwise we end up treating the returned message id as an error code. (This used to be commit 42fdcef324d7a04e69c0078482e1a6b8a67ade94) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1886b525d9..92f7f7645a 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -937,7 +937,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - ret = ldap_delete(ads->ld, utf8_dn); + ret = ldap_delete_s(ads->ld, utf8_dn); return ADS_ERROR(ret); } -- cgit From 3a00cedc0107730876f5bb7626db31d253f9df8b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 23 Jul 2003 19:58:01 +0000 Subject: connect to the right realm or domain for trusted AD domains (This used to be commit 83376671c511be4bb10d3fca8e49e5f6ef792b9c) --- source3/libads/ldap.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 92f7f7645a..cf6f9375f8 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -109,12 +109,8 @@ static BOOL ads_find_dc(ADS_STRUCT *ads) /* realm */ c_realm = ads->server.realm; - if (!c_realm || !*c_realm) { - c_realm = lp_realm(); - } - if ( c_realm ) + if (c_realm && *c_realm) got_realm = True; - again: /* we need to try once with the realm name and fallback to the @@ -122,10 +118,10 @@ again: if ( !got_realm && !lp_disable_netbios() ) { c_realm = ads->server.workgroup; - if (!c_realm || !*c_realm) - c_realm = lp_workgroup(); - if (!c_realm) + if (!c_realm || !*c_realm) { + DEBUG(0,("ads_find_dc: no realm or workgroup! Was the structure initialized?\n")); return False; + } } pstrcpy( realm, c_realm ); -- cgit From c916e5e390ef3ca9577c2f1d3d58fdad6eec7748 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 25 Jul 2003 16:42:34 +0000 Subject: fix case where no realm or workgroup means to use our own (This used to be commit 6edc7e0a744a5d8c6332758b800a2646ef16dd77) --- source3/libads/ldap.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index cf6f9375f8..62520d5001 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -106,12 +106,24 @@ static BOOL ads_find_dc(ADS_STRUCT *ads) struct ip_service *ip_list; pstring realm; BOOL got_realm = False; + BOOL use_own_domain = False; + + /* if the realm and workgroup are both empty, assume they are ours */ /* realm */ c_realm = ads->server.realm; + + if ( !c_realm || !*c_realm ) { + /* special case where no realm and no workgroup means our own */ + if ( !ads->server.workgroup || !*ads->server.workgroup ) { + use_own_domain = True; + c_realm = lp_realm(); + } + } + if (c_realm && *c_realm) got_realm = True; - + again: /* we need to try once with the realm name and fallback to the netbios domain name if we fail (if netbios has not been disabled */ @@ -119,7 +131,12 @@ again: if ( !got_realm && !lp_disable_netbios() ) { c_realm = ads->server.workgroup; if (!c_realm || !*c_realm) { - DEBUG(0,("ads_find_dc: no realm or workgroup! Was the structure initialized?\n")); + if ( use_own_domain ) + c_realm = lp_workgroup(); + } + + if ( !c_realm || !*c_realm ) { + DEBUG(0,("ads_find_dc: no realm or workgroup! Don't know what to do\n")); return False; } } -- cgit From 0d087e3ba28a9061529c95799624ccc4686eb1e9 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 31 Jul 2003 05:43:47 +0000 Subject: working on transtive trusts issue: * use DsEnumerateDomainTrusts() instead of LDAP search. wbinfo -m now lists all trusted downlevel domains and all domains in the forest. Thnigs to do: o Look at Krb5 connection trusted domains o make sure to initial the trusted domain cache as soon as possible (This used to be commit 0ab00ccaedf204b39c86a9e1c2fcac5f15d0e033) --- source3/libads/ldap.c | 71 --------------------------------------------------- 1 file changed, 71 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 62520d5001..dd93502056 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1888,77 +1888,6 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) return ADS_SUCCESS; } - -/** - * find the list of trusted domains - * @param ads connection to ads server - * @param mem_ctx TALLOC_CTX for allocating results - * @param num_trusts pointer to number of trusts - * @param names pointer to trusted domain name list - * @param sids pointer to list of sids of trusted domains - * @return the count of SIDs pulled - **/ -ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, - int *num_trusts, - char ***names, - char ***alt_names, - DOM_SID **sids) -{ - const char *attrs[] = {"name", "flatname", "securityIdentifier", - "trustDirection", NULL}; - ADS_STATUS status; - void *res, *msg; - int count, i; - - *num_trusts = 0; - - status = ads_search(ads, &res, "(objectcategory=trustedDomain)", attrs); - if (!ADS_ERR_OK(status)) return status; - - count = ads_count_replies(ads, res); - if (count == 0) { - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); - } - - (*names) = talloc(mem_ctx, sizeof(char *) * count); - (*alt_names) = talloc(mem_ctx, sizeof(char *) * count); - (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * count); - if (! *names || ! *sids) return ADS_ERROR(LDAP_NO_MEMORY); - - for (i=0, msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { - uint32 direction; - - /* direction is a 2 bit bitfield, 1 means they trust us - but we don't trust them, so we should not list them - as users from that domain can't login */ - if (ads_pull_uint32(ads, msg, "trustDirection", &direction) && - direction == 1) { - continue; - } - - (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "name"); - (*alt_names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatname"); - - if ((*alt_names)[i] && (*alt_names)[i][0]) { - /* we prefer the flatname as the primary name - for consistency with RPC */ - char *name = (*alt_names)[i]; - (*alt_names)[i] = (*names)[i]; - (*names)[i] = name; - } - if (ads_pull_sid(ads, msg, "securityIdentifier", &(*sids)[i])) { - i++; - } - } - - ads_msgfree(ads, res); - - *num_trusts = i; - - return ADS_SUCCESS; -} - /** * find the domain sid for our domain * @param ads connection to ads server -- cgit From 9f2e6167d22cc06fa94495574fc29d6bcbb1dd8a Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 1 Aug 2003 15:21:20 +0000 Subject: Update my copyrights according to my agreement with IBM (This used to be commit c9b209be2b17c2e4677cc30b46b1074f48878f43) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index dd93502056..5a12288b16 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3,7 +3,7 @@ ads (active directory) utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 - Copyright (C) Jim McDonough 2002 + Copyright (C) Jim McDonough 2002 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 -- cgit From 8bfe26b62db2e671b143d93a5428f8fb64a9df05 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 20 Aug 2003 17:13:38 +0000 Subject: metze's autogenerate patch for version.h (This used to be commit ae452e51b02672a56adf18aa7a7e365eeaba9272) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 5a12288b16..3de119b5d9 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1045,7 +1045,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, 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_mod_str(ctx, &mods, "operatingSystemVersion", SAMBA_VERSION_STRING); ret = ads_gen_add(ads, new_dn, mods); -- cgit From d5bef211d0cee0f0c7fab5c890694cabd408e6e3 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 6 Sep 2003 18:02:19 +0000 Subject: revert retry loops in winbindd_ads as abartket points out, we already have ads_search_retry() for this. However, neither domain_sid() nor sequence_nunber() used this function. So modify them to us ads_do_search_retry() so we can specify the base search DN and scope. (This used to be commit 89f6adf830187d020bf4b35d1a4b2b48c7a075d0) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 3de119b5d9..e925750e0a 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1777,7 +1777,7 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) ADS_STATUS status; void *res; - status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + status = ads_do_search_retry(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status)) return status; if (ads_count_replies(ads, res) != 1) { @@ -1900,7 +1900,7 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) void *res; ADS_STATUS rc; - rc = ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", + rc = ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(rc)) return rc; if (!ads_pull_sid(ads, res, "objectSid", sid)) { -- cgit From ca1c6ebb11361dabaca22015736f3876d51833a2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 Sep 2003 22:33:06 +0000 Subject: Fix a nasty mess, and also bug #296. passdb/pdb_ldap.c was not converting to/from utf8 for some calls. The libads code gets this right. Wonder why the passdb code doesn't use it ? Jeremy. (This used to be commit 910d21d3164c2c64773031fddaad35ea88e72a04) --- source3/libads/ldap.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e925750e0a..48401cc3d8 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -709,7 +709,16 @@ char *ads_get_dn(ADS_STRUCT *ads, void *msg) utf8_dn = ldap_get_dn(ads->ld, msg); - pull_utf8_allocate((void **) &unix_dn, utf8_dn); + if (!utf8_dn) { + DEBUG (5, ("ads_get_dn: ldap_get_dn failed\n")); + return NULL; + } + + if (pull_utf8_allocate((void **) &unix_dn, utf8_dn) == (size_t)-1) { + DEBUG(0,("ads_get_dn: string conversion failure utf8 [%s]\n", + utf8_dn )); + return NULL; + } ldap_memfree(utf8_dn); return unix_dn; } -- cgit From 48958b0105dce32888497e79106e08c70af7e3ef Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 3 Oct 2003 21:43:09 +0000 Subject: don't call ads_destroy() twice; fixes segfault in winbindd when DC goes down; bug 437 (This used to be commit 1cfbd92404270e0c67a3b295fc9cf461b29d3503) --- source3/libads/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 48401cc3d8..8c3185ea5e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1787,7 +1787,8 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) void *res; status = ads_do_search_retry(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); - if (!ADS_ERR_OK(status)) return status; + if (!ADS_ERR_OK(status)) + return status; if (ads_count_replies(ads, res) != 1) { return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); -- cgit From bb0598faf58679a7ad26a1caab8eadb154a07ae2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 22 Oct 2003 23:38:20 +0000 Subject: Put strcasecmp/strncasecmp on the banned list (except for needed calls in iconv.c and nsswitch/). Using them means you're not thinking about multibyte at all and I really want to discourage that. Jeremy. (This used to be commit d7e35dfb9283d560d0ed2ab231f36ed92767dace) --- source3/libads/ldap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8c3185ea5e..b3706cb240 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -972,7 +972,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) **/ char *ads_ou_string(const char *org_unit) { - if (!org_unit || !*org_unit || strcasecmp(org_unit, "Computers") == 0) { + if (!org_unit || !*org_unit || strequal(org_unit, "Computers")) { return strdup("cn=Computers"); } @@ -1970,8 +1970,8 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workg prefix_length = strlen(prefix); for (i=0;principles[i]; i++) { - if (strncasecmp(principles[i], prefix, prefix_length) == 0 && - strcasecmp(ads->config.realm, principles[i]+prefix_length) != 0 && + if (strnequal(principles[i], prefix, prefix_length) && + !strequal(ads->config.realm, principles[i]+prefix_length) && !strchr(principles[i]+prefix_length, '.')) { /* found an alternate (short) name for the domain. */ DEBUG(3,("Found alternate name '%s' for realm '%s'\n", -- cgit From 203710ea6d74a6ff17ed3c2d718022242384ee3a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 26 Nov 2003 09:58:41 +0000 Subject: Get rid of a const warning Volker (This used to be commit 94860687c535ace0c962ca3fe7da59df05325c62) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b3706cb240..072f42513c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1933,7 +1933,7 @@ bin/net -Uadministrator%XXXXX ads search '(&(objectclass=crossref)(dnsroot=VNET3 but you need to force the bind path to match the configurationNamingContext from the rootDSE */ -ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workgroup) +ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **workgroup) { char *expr; ADS_STATUS rc; -- cgit From ec83590024abb0b30a452502285220ceee967bd2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 13 Dec 2003 01:43:54 +0000 Subject: Fix from ndb@theghet.to to allow an existing LDAP machine account to be re-used, rather than created from scratch. Jeremy. (This used to be commit 6d46e66ac2048352ca60f92fc384f60406024d4b) --- source3/libads/ldap.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 072f42513c..99227f6574 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -998,6 +998,14 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, const char *servicePrincipalName[5] = {NULL, NULL, NULL, NULL, NULL}; char *psp, *psp2; unsigned acct_control; + unsigned exists=0; + LDAPMessage *res; + + status = ads_find_machine_acct(ads, (void **)&res, hostname); + if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { + DEBUG(0, ("Host account for %s already exists - modifying old account\n", hostname)); + exists=1; + } if (!(ctx = talloc_init("machine_account"))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -1045,18 +1053,23 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, if (!(mods = ads_init_mods(ctx))) goto done; - - ads_mod_str(ctx, &mods, "cn", hostname); - ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); - ads_mod_strlist(ctx, &mods, "objectClass", objectClass); + + if (!exists) { + ads_mod_str(ctx, &mods, "cn", hostname); + ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); + ads_mod_str(ctx, &mods, "userAccountControl", controlstr); + ads_mod_strlist(ctx, &mods, "objectClass", objectClass); + } + ads_mod_str(ctx, &mods, "dNSHostName", hostname); ads_mod_str(ctx, &mods, "userPrincipalName", host_upn); ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); - 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", SAMBA_VERSION_STRING); - ret = ads_gen_add(ads, new_dn, mods); + if (!exists) + ret = ads_gen_add(ads, new_dn, mods); + else + ret = ads_gen_mod(ads, new_dn, mods); if (!ADS_ERR_OK(ret)) goto done; @@ -1065,11 +1078,13 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, * it shouldn't be mandatory and probably we just * don't have enough rights to do it. */ - status = ads_set_machine_sd(ads, hostname, new_dn); - - if (!ADS_ERR_OK(status)) { - DEBUG(0, ("Warning: ads_set_machine_sd: %s\n", - ads_errstr(status))); + if (!exists) { + status = ads_set_machine_sd(ads, hostname, new_dn); + + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("Warning: ads_set_machine_sd: %s\n", + ads_errstr(status))); + } } done: talloc_destroy(ctx); @@ -1309,6 +1324,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, host = strdup(hostname); strlower_m(host); + /* status = ads_find_machine_acct(ads, (void **)&res, host); if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { DEBUG(0, ("Host account for %s already exists - deleting old account\n", host)); @@ -1319,6 +1335,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, return status; } } + */ status = ads_add_machine_acct(ads, host, account_type, org_unit); if (!ADS_ERR_OK(status)) { -- cgit From 5eee23cc64139ba1d23101c87709e6d5198a6c68 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 31 Dec 2003 00:31:43 +0000 Subject: auth/auth_util.c: - Fill in the 'backup' idea of a domain, if the DC didn't supply one. This doesn't seem to occour in reality, hence why we missed the typo. lib/charcnv.c: lib/smbldap.c: libads/ldap.c: libsmb/libsmbclient.c: printing/nt_printing.c: - all the callers to pull_utf8_allocate() pass a char ** as the first parammeter, so don't make them all cast it to a void ** nsswitch/winbind_util.c: - Allow for a more 'correct' view of when usernames should be qualified in winbindd. If we are a PDC, or have 'winbind trusted domains only', then for the authentication returns stip the domain portion. - Fix valgrind warning about use of free()ed name when looking up our local domain. lp_workgroup() is maniplated inside a procedure that uses it's former value. Instead, use the fact that our local domain is always the first in the list. Andrew Bartlett (This used to be commit 494781f628683d6e68e8ba21ae54f738727e8c21) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 99227f6574..ce0341b72c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -714,7 +714,7 @@ char *ads_get_dn(ADS_STRUCT *ads, void *msg) return NULL; } - if (pull_utf8_allocate((void **) &unix_dn, utf8_dn) == (size_t)-1) { + if (pull_utf8_allocate(&unix_dn, utf8_dn) == (size_t)-1) { DEBUG(0,("ads_get_dn: string conversion failure utf8 [%s]\n", utf8_dn )); return NULL; -- cgit From 31ff56fd3ef310c1fab557cf26c65ab96d38fb39 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 1 Jan 2004 20:30:50 +0000 Subject: Fix for bug 707, getent group for huge ads groups (>1500 members) This introduces range retrieval of ADS attributes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I've rewritten most of Günther's patch, partly to remove code duplication and partly to get the retrieval of members in one rush, not interrupted by the lookups for the DN. Andrew, you told me that you would like to see a check whether the AD sequence number is the same before and after the retrieval to achieve atomicity. This would be trivial to add, but I'm not sure that we want this, as this adds two roundtrips to every membership query. We can not know before the first query whether we get additional range values, and at that point it's too late to ask for the USN. Tested with a group of 4000 members along with lots of small groups. Volker (This used to be commit 9d8235bf413f931e40bca0c27a25ed62b4f3d226) --- source3/libads/ldap.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 92 insertions(+), 8 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ce0341b72c..f47645c7e7 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1579,27 +1579,26 @@ char *ads_pull_string(ADS_STRUCT *ads, * @return Result strings in talloc context **/ char **ads_pull_strings(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, void *msg, const char *field) + TALLOC_CTX *mem_ctx, void *msg, const char *field, + int *num_values) { char **values; char **ret = NULL; - int i, n; + int i; values = ldap_get_values(ads->ld, msg, field); if (!values) return NULL; - for (i=0;values[i];i++) - /* noop */ ; - n = i; + *num_values = ldap_count_values(values); - ret = talloc(mem_ctx, sizeof(char *) * (n+1)); + ret = talloc(mem_ctx, sizeof(char *) * (*num_values+1)); if (!ret) { ldap_value_free(values); return NULL; } - for (i=0;ild, (LDAPMessage *)msg, &ptr); + + if (first_attr == NULL) + return NULL; + + expected_range_attrib = talloc_asprintf(mem_ctx, "%s;Range=", field); + + if (!strequal(first_attr, field) && + !strnequal(first_attr, expected_range_attrib, + strlen(expected_range_attrib))) + { + DEBUG(1, ("Expected attribute [%s], got [%s]\n", + field, first_attr)); + return NULL; + } + + second_attr = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, ptr); + ber_free(ptr, 0); + + DEBUG(10,("attr: [%s], first_attr: [%s], second_attr: [%s]\n", + field, first_attr, second_attr)); + + if ((second_attr != NULL) && + (strnequal(second_attr, expected_range_attrib, + strlen(expected_range_attrib)))) { + + /* This is the first in a row of range results. We can not ask + * for the attribute we wanted, as this is empty in the LDAP + * msg, the delivered values are in the second range-augmented + * attribute. */ + range_attr = second_attr; + + } else { + + /* Upon second and subsequent requests to get attribute + * values, first_attr carries the Range= specifier. */ + range_attr = first_attr; + + } + + /* We have to ask for more if we have a range specifier in the + * attribute and the attribute does not end in "*". */ + + *more_values = ( (strnequal(range_attr, expected_range_attrib, + strlen(expected_range_attrib))) && + (range_attr[strlen(range_attr)-1] != '*') ); + + result = ads_pull_strings(ads, mem_ctx, msg, range_attr, num_values); + + ldap_memfree(first_attr); + if (second_attr != NULL) + ldap_memfree(second_attr); + + return result; +} /** * pull a single uint32 from a ADS result @@ -1960,6 +2042,7 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * int i; void *res; const char *attrs[] = {"servicePrincipalName", NULL}; + int num_principals; (*workgroup) = NULL; @@ -1972,7 +2055,8 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * return rc; } - principles = ads_pull_strings(ads, mem_ctx, res, "servicePrincipalName"); + principles = ads_pull_strings(ads, mem_ctx, res, + "servicePrincipalName", &num_principals); ads_msgfree(ads, res); -- cgit From 9f662094af4480b45db104a156374e7213aa5d92 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 1 Jan 2004 21:10:35 +0000 Subject: After talking with abartlet remove the fix for bug 707 again. Volker (This used to be commit 0c8ee04c78543b1da3b675df4cf85ee5496c3fbf) --- source3/libads/ldap.c | 100 ++++---------------------------------------------- 1 file changed, 8 insertions(+), 92 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index f47645c7e7..ce0341b72c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1579,26 +1579,27 @@ char *ads_pull_string(ADS_STRUCT *ads, * @return Result strings in talloc context **/ char **ads_pull_strings(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, void *msg, const char *field, - int *num_values) + TALLOC_CTX *mem_ctx, void *msg, const char *field) { char **values; char **ret = NULL; - int i; + int i, n; values = ldap_get_values(ads->ld, msg, field); if (!values) return NULL; - *num_values = ldap_count_values(values); + for (i=0;values[i];i++) + /* noop */ ; + n = i; - ret = talloc(mem_ctx, sizeof(char *) * (*num_values+1)); + ret = talloc(mem_ctx, sizeof(char *) * (n+1)); if (!ret) { ldap_value_free(values); return NULL; } - for (i=0;i<*num_values;i++) { + for (i=0;ild, (LDAPMessage *)msg, &ptr); - - if (first_attr == NULL) - return NULL; - - expected_range_attrib = talloc_asprintf(mem_ctx, "%s;Range=", field); - - if (!strequal(first_attr, field) && - !strnequal(first_attr, expected_range_attrib, - strlen(expected_range_attrib))) - { - DEBUG(1, ("Expected attribute [%s], got [%s]\n", - field, first_attr)); - return NULL; - } - - second_attr = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, ptr); - ber_free(ptr, 0); - - DEBUG(10,("attr: [%s], first_attr: [%s], second_attr: [%s]\n", - field, first_attr, second_attr)); - - if ((second_attr != NULL) && - (strnequal(second_attr, expected_range_attrib, - strlen(expected_range_attrib)))) { - - /* This is the first in a row of range results. We can not ask - * for the attribute we wanted, as this is empty in the LDAP - * msg, the delivered values are in the second range-augmented - * attribute. */ - range_attr = second_attr; - - } else { - - /* Upon second and subsequent requests to get attribute - * values, first_attr carries the Range= specifier. */ - range_attr = first_attr; - - } - - /* We have to ask for more if we have a range specifier in the - * attribute and the attribute does not end in "*". */ - - *more_values = ( (strnequal(range_attr, expected_range_attrib, - strlen(expected_range_attrib))) && - (range_attr[strlen(range_attr)-1] != '*') ); - - result = ads_pull_strings(ads, mem_ctx, msg, range_attr, num_values); - - ldap_memfree(first_attr); - if (second_attr != NULL) - ldap_memfree(second_attr); - - return result; -} /** * pull a single uint32 from a ADS result @@ -2042,7 +1960,6 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * int i; void *res; const char *attrs[] = {"servicePrincipalName", NULL}; - int num_principals; (*workgroup) = NULL; @@ -2055,8 +1972,7 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * return rc; } - principles = ads_pull_strings(ads, mem_ctx, res, - "servicePrincipalName", &num_principals); + principles = ads_pull_strings(ads, mem_ctx, res, "servicePrincipalName"); ads_msgfree(ads, res); -- cgit From 685e0cbeb846cfbd09bb0f497968c5354f13de00 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 01:48:21 +0000 Subject: Fix for bug 707, getent group for huge ads groups (>1500 members) This introduces range retrieval of ADS attributes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VL rewrote most of Günther's patch, partly to remove code duplication and partly to get the retrieval of members in one rush, not interrupted by the lookups for the DN. I rewrote that patch, to ensure that we can keep an eye on the USN (sequence number) of the entry - this allows us to ensure the read was atomic. In particular, the range retrieval is now generic, for strings. It could easily be made generic for any attribute type, if need be. Andrew Bartlett (This used to be commit 131bb928f19c7b1f582c4ad9ac42e5f3d9dfb622) --- source3/libads/ldap.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 130 insertions(+), 8 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ce0341b72c..f9c7820275 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1579,27 +1579,26 @@ char *ads_pull_string(ADS_STRUCT *ads, * @return Result strings in talloc context **/ char **ads_pull_strings(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, void *msg, const char *field) + TALLOC_CTX *mem_ctx, void *msg, const char *field, + size_t *num_values) { char **values; char **ret = NULL; - int i, n; + int i; values = ldap_get_values(ads->ld, msg, field); if (!values) return NULL; - for (i=0;values[i];i++) - /* noop */ ; - n = i; + *num_values = ldap_count_values(values); - ret = talloc(mem_ctx, sizeof(char *) * (n+1)); + ret = talloc(mem_ctx, sizeof(char *) * (*num_values+1)); if (!ret) { ldap_value_free(values); return NULL; } - for (i=0;i Date: Mon, 5 Jan 2004 12:20:15 +0000 Subject: Try to keep vl happy - shorten some of these lines. (This used to be commit 3a4c56e4c60854bbd291adc7d321d3869e6dedab) --- source3/libads/ldap.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index f9c7820275..8039d3d1d4 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1674,7 +1674,8 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, &range_start) == 1) { *more_strings = False; } else { - DEBUG(1, ("ads_pull_strings_range: Cannot parse Range attriubte (%s)\n", range_attr)); + DEBUG(1, ("ads_pull_strings_range: Cannot parse Range attriubte (%s)\n", + range_attr)); ldap_memfree(range_attr); *more_strings = False; return NULL; @@ -1682,7 +1683,8 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, } if ((*num_strings) != range_start) { - DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) doesn't start at %u, but at %lu - aborting range retreival\n", + DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) doesn't start at %u, but at %lu" + " - aborting range retreival\n", range_attr, *num_strings + 1, range_start)); ldap_memfree(range_attr); *more_strings = False; @@ -1692,8 +1694,10 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, new_strings = ads_pull_strings(ads, mem_ctx, msg, range_attr, &num_new_strings); if (*more_strings && ((*num_strings + num_new_strings) != (range_end + 1))) { - DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) tells us we have %lu strings in this bunch, but we only got %lu - aborting range retreival\n", - range_attr, (unsigned long int)range_end - range_start + 1, (unsigned long int)num_new_strings)); + DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) tells us we have %lu " + "strings in this bunch, but we only got %lu - aborting range retreival\n", + range_attr, (unsigned long int)range_end - range_start + 1, + (unsigned long int)num_new_strings)); ldap_memfree(range_attr); *more_strings = False; return NULL; @@ -1996,7 +2000,8 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) p = strchr(value, ':'); if (!p) { talloc_destroy(ctx); - DEBUG(1, ("ads_server_info: returned ldap server name did not contain a ':' so was deemed invalid\n")); + DEBUG(1, ("ads_server_info: returned ldap server name did not contain a ':' " + "so was deemed invalid\n")); return ADS_ERROR(LDAP_DECODING_ERROR); } @@ -2006,7 +2011,8 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) p = strchr(ads->config.ldap_server_name, '$'); if (!p || p[1] != '@') { talloc_destroy(ctx); - DEBUG(1, ("ads_server_info: returned ldap server name (%s) does not contain '$@' so was deemed invalid\n", ads->config.ldap_server_name)); + DEBUG(1, ("ads_server_info: returned ldap server name (%s) does not contain '$@'" + " so was deemed invalid\n", ads->config.ldap_server_name)); SAFE_FREE(ads->config.ldap_server_name); return ADS_ERROR(LDAP_DECODING_ERROR); } -- cgit From d57d2d08978e37ab771479b5f2f2f7f36d867b69 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 00:31:36 +0000 Subject: Bug found by gd - the new range-reterival code did still had 'member' hardcoded into it. This didn't matter, as we only use it for 'member' so far... Andrew Bartlett (This used to be commit 8621899112e720411715ea53558d5146ff04eeb0) --- source3/libads/ldap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8039d3d1d4..15504a5202 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1661,7 +1661,7 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, } if (!attr) { ber_free(ptr, 0); - /* nothing here - this feild is just empty */ + /* nothing here - this field is just empty */ *more_strings = False; return NULL; } @@ -1720,7 +1720,8 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, if (*more_strings) { *next_attribute = talloc_asprintf(mem_ctx, - "member;range=%d-*", + "%s;range=%d-*", + field, *num_strings); if (!*next_attribute) { -- cgit From 8ad3d8c9b065f3a2040beff801bdc9dceac868a8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 13 Apr 2004 14:39:48 +0000 Subject: r196: merging struct uuid from trunk (This used to be commit 911a28361b9d8dd50597627f245ebfb57c6294fb) --- source3/libads/ldap.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 15504a5202..20a36dfdf5 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1106,20 +1106,14 @@ static void dump_binary(const char *field, struct berval **values) } } -struct uuid { - uint32 i1; - uint16 i2; - uint16 i3; - uint8 s[8]; -}; - static void dump_guid(const char *field, struct berval **values) { int i; - GUID guid; + UUID_FLAT guid; for (i=0; values[i]; i++) { memcpy(guid.info, values[i]->bv_val, sizeof(guid.info)); - printf("%s: %s\n", field, smb_uuid_string_static(guid)); + printf("%s: %s\n", field, + smb_uuid_string_static(smb_uuid_unpack_static(guid))); } } @@ -1771,16 +1765,18 @@ BOOL ads_pull_uint32(ADS_STRUCT *ads, * @return boolean indicating success **/ BOOL ads_pull_guid(ADS_STRUCT *ads, - void *msg, GUID *guid) + void *msg, struct uuid *guid) { char **values; + UUID_FLAT flat_guid; values = ldap_get_values(ads->ld, msg, "objectGUID"); if (!values) return False; if (values[0]) { - memcpy(guid, values[0], sizeof(GUID)); + memcpy(&flat_guid.info, values[0], sizeof(UUID_FLAT)); + smb_uuid_unpack(flat_guid, guid); ldap_value_free(values); return True; } -- cgit From a442c65e59cd0b7667087f90522883475dfb7eee Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 7 May 2004 17:58:06 +0000 Subject: r562: Memory leak fix in error code path from kawasa_r@itg.hitachi.co.jp. Jeremy. (This used to be commit ac501348f473045a7846ffd9bc6b9eb4682b8987) --- source3/libads/ldap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 20a36dfdf5..e156857e96 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1984,15 +1984,17 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) value = ads_pull_string(ads, ctx, res, "ldapServiceName"); if (!value) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); } timestr = ads_pull_string(ads, ctx, res, "currentTime"); if (!timestr) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); } - ldap_msgfree(res); + ads_msgfree(ads, res); p = strchr(value, ':'); if (!p) { @@ -2054,6 +2056,7 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) attrs, &res); if (!ADS_ERR_OK(rc)) return rc; if (!ads_pull_sid(ads, res, "objectSid", sid)) { + ads_msgfree(ads, res); return ADS_ERROR_SYSTEM(ENOENT); } ads_msgfree(ads, res); -- cgit From 05bc3279906d63f30df1c373a50c521a171225ab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 May 2004 01:05:59 +0000 Subject: r764: More memleak fixes in error code path from kawasa_r@itg.hitachi.co.jp. Jeremy. (This used to be commit 9647394e7c79c81ac4cf276a2c4b9e16eb053ec2) --- source3/libads/ldap.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e156857e96..e018eeb2da 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1980,17 +1980,22 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) } status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); - if (!ADS_ERR_OK(status)) return status; + if (!ADS_ERR_OK(status)) { + talloc_destroy(ctx); + return status; + } value = ads_pull_string(ads, ctx, res, "ldapServiceName"); if (!value) { ads_msgfree(ads, res); + talloc_destroy(ctx); return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); } timestr = ads_pull_string(ads, ctx, res, "currentTime"); if (!timestr) { ads_msgfree(ads, res); + talloc_destroy(ctx); return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); } -- cgit From e948458a79462bd99ef7c02b4d7ec22c6554a163 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 22 Jun 2004 00:48:59 +0000 Subject: r1215: Intermediate checkin of the new keytab code. I need to make sure I haven't broken krb5 ticket verification in the mainline code path, also need to check with valgrind. Everything now compiles (MIT, need to also check Heimdal) and the "net keytab" utility code will follow. Jeremy. (This used to be commit f0f2e28958cb9abfed216c71f291f19ea346d630) --- source3/libads/ldap.c | 353 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 293 insertions(+), 60 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e018eeb2da..3a9c41f09d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -226,11 +226,10 @@ got_connection: ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); if (!ads->auth.user_name) { - /* by default use the machine account */ - fstring myname; - fstrcpy(myname, global_myname()); - strlower_m(myname); - asprintf(&ads->auth.user_name, "HOST/%s", myname); + fstring my_fqdn; + name_to_fqdn(my_fqdn, global_myname()); + strlower_m(my_fqdn); + asprintf(&ads->auth.user_name, "host/%s", my_fqdn); } if (!ads->auth.realm) { @@ -730,7 +729,7 @@ char *ads_get_dn(ADS_STRUCT *ads, void *msg) * @param host Hostname to search for * @return status of search **/ -ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) +ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *machine) { ADS_STATUS status; char *expr; @@ -738,13 +737,13 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) /* the easiest way to find a machine account anywhere in the tree is to look for hostname$ */ - if (asprintf(&expr, "(samAccountName=%s$)", host) == -1) { + if (asprintf(&expr, "(samAccountName=%s$)", machine) == -1) { DEBUG(1, ("asprintf failed!\n")); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } status = ads_search(ads, res, expr, attrs); - free(expr); + SAFE_FREE(expr); return status; } @@ -979,18 +978,231 @@ char *ads_ou_string(const char *org_unit) return ads_build_path(org_unit, "\\/", "ou=", 1); } +/** + * Adds (appends) an item to an attribute array, rather then + * replacing the whole list + * @param ctx An initialized TALLOC_CTX + * @param mods An initialized ADS_MODLIST + * @param name name of the ldap attribute to append to + * @param vals an array of values to add + * @return status of addition + **/ + +ADS_STATUS ads_add_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, + const char *name, const char **vals) +{ + return ads_modlist_add(ctx, mods, LDAP_MOD_ADD, name, (const void **) vals); +} +/** + * Determines the computer account's current KVNO via an LDAP lookup + * @param ads An initialized ADS_STRUCT + * @param machine_name the NetBIOS name of the computer, which is used to identify the computer account. + * @return the kvno for the computer account, or -1 in case of a failure. + **/ -/* - add a machine account to the ADS server -*/ -static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, +uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) +{ + LDAPMessage *res; + uint32 kvno = (uint32)-1; /* -1 indicates a failure */ + char *filter; + const char *attrs[] = {"msDS-KeyVersionNumber", NULL}; + char *dn_string = NULL; + ADS_STATUS ret = ADS_ERROR(LDAP_SUCCESS); + + DEBUG(5,("ads_get_kvno: Searching for host %s\n", machine_name)); + if (asprintf(&filter, "(samAccountName=%s$)", machine_name) == -1) { + return kvno; + } + ret = ads_search(ads, (void**) &res, filter, attrs); + SAFE_FREE(filter); + if (!ADS_ERR_OK(ret) && ads_count_replies(ads, res)) { + DEBUG(1,("ads_get_kvno: Computer Account For %s not found.\n", machine_name)); + return kvno; + } + + dn_string = ads_get_dn(ads, res); + if (!dn_string) { + DEBUG(0,("ads_get_kvno: out of memory.\n")); + return kvno; + } + DEBUG(5,("ads_get_kvno: Using: %s\n", dn_string)); + ads_memfree(ads, dn_string); + + /* --------------------------------------------------------- + * 0 is returned as a default KVNO from this point on... + * This is done because Windows 2000 does not support key + * version numbers. Chances are that a failure in the next + * step is simply due to Windows 2000 being used for a + * domain controller. */ + kvno = 0; + + if (!ads_pull_uint32(ads, res, "msDS-KeyVersionNumber", &kvno)) { + DEBUG(3,("ads_get_kvno: Error Determining KVNO!\n")); + DEBUG(3,("ads_get_kvno: Windows 2000 does not support KVNO's, so this may be normal.\n")); + return kvno; + } + + /* Success */ + DEBUG(5,("ads_get_kvno: Looked Up KVNO of: %d\n", kvno)); + return kvno; +} + +/** + * This clears out all registered spn's for a given hostname + * @param ads An initilaized ADS_STRUCT + * @param machine_name the NetBIOS name of the computer. + * @return 0 upon success, non-zero otherwise. + **/ + +ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machine_name) +{ + TALLOC_CTX *ctx; + LDAPMessage *res; + ADS_MODLIST mods; + const char *servicePrincipalName[1] = {NULL}; + ADS_STATUS ret = ADS_ERROR(LDAP_SUCCESS); + char *dn_string = NULL; + + ret = ads_find_machine_acct(ads, (void **)&res, machine_name); + if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { + DEBUG(5,("ads_clear_service_principal_names: WARNING: Host Account for %s not found... skipping operation.\n", machine_name)); + DEBUG(5,("ads_clear_service_principal_names: WARNING: Service Principals for %s have NOT been cleared.\n", machine_name)); + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + + DEBUG(5,("ads_clear_service_principal_names: Host account for %s found\n", machine_name)); + ctx = talloc_init("ads_clear_service_principal_names"); + if (!ctx) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + if (!(mods = ads_init_mods(ctx))) { + talloc_destroy(ctx); + return ADS_ERROR(LDAP_NO_MEMORY); + } + ret = ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); + if (!ADS_ERR_OK(ret)) { + DEBUG(1,("ads_clear_service_principal_names: Error creating strlist.\n")); + talloc_destroy(ctx); + return ret; + } + dn_string = ads_get_dn(ads, res); + if (!dn_string) { + talloc_destroy(ctx); + return ADS_ERROR(LDAP_NO_MEMORY); + } + ret = ads_gen_mod(ads, dn_string, mods); + ads_memfree(ads,dn_string); + if (!ADS_ERR_OK(ret)) { + DEBUG(1,("ads_clear_service_principal_names: Error: Updating Service Principals for machine %s in LDAP\n", + machine_name)); + talloc_destroy(ctx); + return ret; + } + + talloc_destroy(ctx); + return ret; +} + +/** + * This adds a service principal name to an existing computer account + * (found by hostname) in AD. + * @param ads An initialized ADS_STRUCT + * @param machine_name the NetBIOS name of the computer, which is used to identify the computer account. + * @param spn A string of the service principal to add, i.e. 'host' + * @return 0 upon sucess, or non-zero if a failure occurs + **/ + +ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_name, const char *spn) +{ + ADS_STATUS ret; + TALLOC_CTX *ctx; + LDAPMessage *res; + char *host_spn, *host_upn, *psp1, *psp2; + ADS_MODLIST mods; + fstring my_fqdn; + char *dn_string = NULL; + const char *servicePrincipalName[3] = {NULL, NULL, NULL}; + + ret = ads_find_machine_acct(ads, (void **)&res, machine_name); + if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { + DEBUG(1,("ads_add_service_principal_name: WARNING: Host Account for %s not found... skipping operation.\n", + machine_name)); + DEBUG(1,("ads_add_service_principal_name: WARNING: Service Principal '%s/%s@%s' has NOT been added.\n", + spn, machine_name, ads->config.realm)); + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + + DEBUG(1,("ads_add_service_principal_name: Host account for %s found\n", machine_name)); + if (!(ctx = talloc_init("ads_add_service_principal_name"))) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + name_to_fqdn(my_fqdn, machine_name); + if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", my_fqdn))) { + talloc_destroy(ctx); + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) { + talloc_destroy(ctx); + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + + /* Add the extra principal */ + psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name); + strupper_m(psp1); + strlower_m(&psp1[strlen(spn)]); + DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp1, machine_name)); + servicePrincipalName[0] = psp1; + psp2 = talloc_asprintf(ctx, "%s/%s.%s", spn, machine_name, ads->config.realm); + strupper_m(psp2); + strlower_m(&psp2[strlen(spn)]); + DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp2, machine_name)); + servicePrincipalName[1] = psp2; + + if (!(mods = ads_init_mods(ctx))) { + talloc_destroy(ctx); + return ADS_ERROR(LDAP_NO_MEMORY); + } + ret = ads_add_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); + if (!ADS_ERR_OK(ret)) { + DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n")); + talloc_destroy(ctx); + return ret; + } + dn_string = ads_get_dn(ads, res); + if (!dn_string) { + talloc_destroy(ctx); + return ADS_ERROR(LDAP_NO_MEMORY); + } + ret = ads_gen_mod(ads, ads_get_dn(ads, res), mods); + ads_memfree(ads,dn_string); + if (!ADS_ERR_OK(ret)) { + DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n")); + talloc_destroy(ctx); + return ret; + } + + talloc_destroy(ctx); + return ret; +} + +/** + * adds a machine account to the ADS server + * @param ads An intialized ADS_STRUCT + * @param machine_name - the NetBIOS machine name of this account. + * @param account_type A number indicating the type of account to create + * @param org_unit The LDAP path in which to place this account + * @return 0 upon success, or non-zero otherwise +**/ + +static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name, uint32 account_type, const char *org_unit) { ADS_STATUS ret, status; char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr; - char *ou_str; TALLOC_CTX *ctx; ADS_MODLIST mods; const char *objectClass[] = {"top", "person", "organizationalPerson", @@ -999,87 +1211,106 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, char *psp, *psp2; unsigned acct_control; unsigned exists=0; + fstring my_fqdn; LDAPMessage *res; - status = ads_find_machine_acct(ads, (void **)&res, hostname); + if (!(ctx = talloc_init("ads_add_machine_acct"))) + return ADS_ERROR(LDAP_NO_MEMORY); + + ret = ADS_ERROR(LDAP_NO_MEMORY); + + name_to_fqdn(my_fqdn, machine_name); + + status = ads_find_machine_acct(ads, (void **)&res, machine_name); if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { - DEBUG(0, ("Host account for %s already exists - modifying old account\n", hostname)); + char *dn_string = ads_get_dn(ads, res); + if (!dn_string) { + DEBUG(1, ("ads_add_machine_acct: ads_get_dn returned NULL (malloc failure?)\n")); + goto done; + } + new_dn = talloc_strdup(ctx, dn_string); + ads_memfree(ads,dn_string); + DEBUG(0, ("ads_add_machine_acct: Host account for %s already exists - modifying old account\n", + machine_name)); exists=1; - } + } else { + char *ou_str = ads_ou_string(org_unit); + if (!ou_str) { + DEBUG(1, ("ads_add_machine_acct: ads_ou_string returned NULL (malloc failure?)\n")); + goto done; + } + new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", machine_name, ou_str, + ads->config.bind_path); - if (!(ctx = talloc_init("machine_account"))) - return ADS_ERROR(LDAP_NO_MEMORY); + SAFE_FREE(ou_str); + } - ret = ADS_ERROR(LDAP_NO_MEMORY); + if (!new_dn) { + goto done; + } - if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", hostname))) + if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", machine_name))) goto done; if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) goto done; - ou_str = ads_ou_string(org_unit); - if (!ou_str) { - DEBUG(1, ("ads_ou_string returned NULL (malloc failure?)\n")); - goto done; - } - new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str, - ads->config.bind_path); - servicePrincipalName[0] = talloc_asprintf(ctx, "HOST/%s", hostname); + servicePrincipalName[0] = talloc_asprintf(ctx, "HOST/%s", machine_name); psp = talloc_asprintf(ctx, "HOST/%s.%s", - hostname, - ads->config.realm); + machine_name, + ads->config.realm); strlower_m(&psp[5]); servicePrincipalName[1] = psp; - servicePrincipalName[2] = talloc_asprintf(ctx, "CIFS/%s", hostname); + servicePrincipalName[2] = talloc_asprintf(ctx, "CIFS/%s", machine_name); psp2 = talloc_asprintf(ctx, "CIFS/%s.%s", - hostname, + machine_name, ads->config.realm); strlower_m(&psp2[5]); servicePrincipalName[3] = psp2; - free(ou_str); - if (!new_dn) - goto done; - - if (!(samAccountName = talloc_asprintf(ctx, "%s$", hostname))) + if (!(samAccountName = talloc_asprintf(ctx, "%s$", machine_name))) { goto done; + } acct_control = account_type | UF_DONT_EXPIRE_PASSWD; #ifndef ENCTYPE_ARCFOUR_HMAC acct_control |= UF_USE_DES_KEY_ONLY; #endif - if (!(controlstr = talloc_asprintf(ctx, "%u", acct_control))) + if (!(controlstr = talloc_asprintf(ctx, "%u", acct_control))) { goto done; + } - if (!(mods = ads_init_mods(ctx))) + if (!(mods = ads_init_mods(ctx))) { goto done; + } if (!exists) { - ads_mod_str(ctx, &mods, "cn", hostname); + ads_mod_str(ctx, &mods, "cn", machine_name); ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); ads_mod_str(ctx, &mods, "userAccountControl", controlstr); ads_mod_strlist(ctx, &mods, "objectClass", objectClass); } - ads_mod_str(ctx, &mods, "dNSHostName", hostname); + ads_mod_str(ctx, &mods, "dNSHostName", my_fqdn); ads_mod_str(ctx, &mods, "userPrincipalName", host_upn); ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); ads_mod_str(ctx, &mods, "operatingSystem", "Samba"); ads_mod_str(ctx, &mods, "operatingSystemVersion", SAMBA_VERSION_STRING); - if (!exists) + if (!exists) { ret = ads_gen_add(ads, new_dn, mods); - else + } else { ret = ads_gen_mod(ads, new_dn, mods); + } - if (!ADS_ERR_OK(ret)) + if (!ADS_ERR_OK(ret)) { goto done; + } /* Do not fail if we can't set security descriptor * it shouldn't be mandatory and probably we just * don't have enough rights to do it. */ if (!exists) { - status = ads_set_machine_sd(ads, hostname, new_dn); + status = ads_set_machine_sd(ads, machine_name, new_dn); if (!ADS_ERR_OK(status)) { DEBUG(0, ("Warning: ads_set_machine_sd: %s\n", @@ -1303,47 +1534,49 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * Join a machine to a realm * Creates the machine account and sets the machine password * @param ads connection to ads server - * @param hostname name of host to add + * @param machine name of host to add * @param org_unit Organizational unit to place machine in * @return status of join **/ -ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, +ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, uint32 account_type, const char *org_unit) { ADS_STATUS status; LDAPMessage *res; - char *host; + char *machine; - /* hostname must be lowercase */ - host = strdup(hostname); - strlower_m(host); + /* machine name must be lowercase */ + machine = strdup(machine_name); + strlower_m(machine); /* - status = ads_find_machine_acct(ads, (void **)&res, host); + status = ads_find_machine_acct(ads, (void **)&res, machine); if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { - DEBUG(0, ("Host account for %s already exists - deleting old account\n", host)); - status = ads_leave_realm(ads, host); + DEBUG(0, ("Host account for %s already exists - deleting old account\n", machine)); + status = ads_leave_realm(ads, machine); if (!ADS_ERR_OK(status)) { DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n", - host, ads->config.realm)); + machine, ads->config.realm)); return status; } } */ - status = ads_add_machine_acct(ads, host, account_type, org_unit); + status = ads_add_machine_acct(ads, machine, account_type, org_unit); if (!ADS_ERR_OK(status)) { - DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(status))); + DEBUG(0, ("ads_add_machine_acct (%s): %s\n", machine, ads_errstr(status))); + SAFE_FREE(machine); return status; } - status = ads_find_machine_acct(ads, (void **)&res, host); + status = ads_find_machine_acct(ads, (void **)&res, machine); if (!ADS_ERR_OK(status)) { - DEBUG(0, ("Host account test failed\n")); + DEBUG(0, ("Host account test failed for machine %s\n", machine)); + SAFE_FREE(machine); return status; } - free(host); + SAFE_FREE(machine); return status; } -- cgit From 7825677b862bb62b8350b6fee458fbbecc53893f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Jun 2004 00:20:31 +0000 Subject: r1222: Valgrind memory leak fixes. Still tracking down a strange one... Can't fix the krb5 memory leaks inside that library :-(. Jeremy. (This used to be commit ad440213aaae58fb5bff6e8a6fcf811c5ba83669) --- source3/libads/ldap.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 3a9c41f09d..985d3cb576 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1003,7 +1003,7 @@ ADS_STATUS ads_add_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) { - LDAPMessage *res; + LDAPMessage *res = NULL; uint32 kvno = (uint32)-1; /* -1 indicates a failure */ char *filter; const char *attrs[] = {"msDS-KeyVersionNumber", NULL}; @@ -1018,12 +1018,14 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) SAFE_FREE(filter); if (!ADS_ERR_OK(ret) && ads_count_replies(ads, res)) { DEBUG(1,("ads_get_kvno: Computer Account For %s not found.\n", machine_name)); + ads_msgfree(ads, res); return kvno; } dn_string = ads_get_dn(ads, res); if (!dn_string) { DEBUG(0,("ads_get_kvno: out of memory.\n")); + ads_msgfree(ads, res); return kvno; } DEBUG(5,("ads_get_kvno: Using: %s\n", dn_string)); @@ -1040,11 +1042,13 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) if (!ads_pull_uint32(ads, res, "msDS-KeyVersionNumber", &kvno)) { DEBUG(3,("ads_get_kvno: Error Determining KVNO!\n")); DEBUG(3,("ads_get_kvno: Windows 2000 does not support KVNO's, so this may be normal.\n")); + ads_msgfree(ads, res); return kvno; } /* Success */ DEBUG(5,("ads_get_kvno: Looked Up KVNO of: %d\n", kvno)); + ads_msgfree(ads, res); return kvno; } @@ -1058,7 +1062,7 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machine_name) { TALLOC_CTX *ctx; - LDAPMessage *res; + LDAPMessage *res = NULL; ADS_MODLIST mods; const char *servicePrincipalName[1] = {NULL}; ADS_STATUS ret = ADS_ERROR(LDAP_SUCCESS); @@ -1068,28 +1072,33 @@ ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machin if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { DEBUG(5,("ads_clear_service_principal_names: WARNING: Host Account for %s not found... skipping operation.\n", machine_name)); DEBUG(5,("ads_clear_service_principal_names: WARNING: Service Principals for %s have NOT been cleared.\n", machine_name)); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } DEBUG(5,("ads_clear_service_principal_names: Host account for %s found\n", machine_name)); ctx = talloc_init("ads_clear_service_principal_names"); if (!ctx) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } if (!(mods = ads_init_mods(ctx))) { talloc_destroy(ctx); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } ret = ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); if (!ADS_ERR_OK(ret)) { DEBUG(1,("ads_clear_service_principal_names: Error creating strlist.\n")); + ads_msgfree(ads, res); talloc_destroy(ctx); return ret; } dn_string = ads_get_dn(ads, res); if (!dn_string) { talloc_destroy(ctx); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } ret = ads_gen_mod(ads, dn_string, mods); @@ -1097,10 +1106,12 @@ ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machin if (!ADS_ERR_OK(ret)) { DEBUG(1,("ads_clear_service_principal_names: Error: Updating Service Principals for machine %s in LDAP\n", machine_name)); + ads_msgfree(ads, res); talloc_destroy(ctx); return ret; } + ads_msgfree(ads, res); talloc_destroy(ctx); return ret; } @@ -1118,7 +1129,7 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n { ADS_STATUS ret; TALLOC_CTX *ctx; - LDAPMessage *res; + LDAPMessage *res = NULL; char *host_spn, *host_upn, *psp1, *psp2; ADS_MODLIST mods; fstring my_fqdn; @@ -1131,21 +1142,25 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n machine_name)); DEBUG(1,("ads_add_service_principal_name: WARNING: Service Principal '%s/%s@%s' has NOT been added.\n", spn, machine_name, ads->config.realm)); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } DEBUG(1,("ads_add_service_principal_name: Host account for %s found\n", machine_name)); if (!(ctx = talloc_init("ads_add_service_principal_name"))) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } name_to_fqdn(my_fqdn, machine_name); if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", my_fqdn))) { talloc_destroy(ctx); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) { talloc_destroy(ctx); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } @@ -1163,28 +1178,33 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n if (!(mods = ads_init_mods(ctx))) { talloc_destroy(ctx); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } ret = ads_add_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); if (!ADS_ERR_OK(ret)) { DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n")); talloc_destroy(ctx); + ads_msgfree(ads, res); return ret; } dn_string = ads_get_dn(ads, res); if (!dn_string) { talloc_destroy(ctx); + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } - ret = ads_gen_mod(ads, ads_get_dn(ads, res), mods); + ret = ads_gen_mod(ads, dn_string, mods); ads_memfree(ads,dn_string); if (!ADS_ERR_OK(ret)) { DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n")); talloc_destroy(ctx); + ads_msgfree(ads, res); return ret; } talloc_destroy(ctx); + ads_msgfree(ads, res); return ret; } @@ -1212,7 +1232,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name unsigned acct_control; unsigned exists=0; fstring my_fqdn; - LDAPMessage *res; + LDAPMessage *res = NULL; if (!(ctx = talloc_init("ads_add_machine_acct"))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -1318,6 +1338,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name } } done: + ads_msgfree(ads, res); talloc_destroy(ctx); return ret; } @@ -1542,7 +1563,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, uint32 account_type, const char *org_unit) { ADS_STATUS status; - LDAPMessage *res; + LDAPMessage *res = NULL; char *machine; /* machine name must be lowercase */ @@ -1577,6 +1598,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, } SAFE_FREE(machine); + ads_msgfree(ads, res); return status; } -- cgit From 569177a194ef990b55d3ad5d5243ca0f2659f25c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 1 Jul 2004 16:35:43 +0000 Subject: r1317: Patch from Joe Meadows "Joe Meadows" to add a timeout to the ldap open calls. New parameter, ldap timeout added. Jeremy. (This used to be commit e5b3094c4cc75eb07f667dd1aeb73921ed7366ac) --- source3/libads/ldap.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 985d3cb576..05d68e6ae6 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -37,6 +37,35 @@ * codepoints in UTF-8). This may have to change at some point **/ +static SIG_ATOMIC_T gotalarm; + +/*************************************************************** + Signal function to tell us we timed out. +****************************************************************/ + +static void gotalarm_sig(void) +{ + gotalarm = 1; +} + +LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) +{ + LDAP *ldp = NULL; + + /* Setup timeout */ + gotalarm = 0; + CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); + alarm(to); + /* End setup timeout. */ + + ldp = ldap_open(server, port); + + /* Teardown timeout. */ + CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN); + alarm(0); + + return ldp; +} /* try a connection to a given ldap server, returning True and setting the servers IP @@ -58,7 +87,7 @@ static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) /* this copes with inet_ntoa brokenness */ srv = strdup(server); - ads->ld = ldap_open(srv, port); + ads->ld = ldap_open_with_timeout(srv, port, lp_ldap_timeout()); if (!ads->ld) { free(srv); return False; -- cgit From 6c1baa6f4ccbbbd27b8972e49d9ec448f0ad83ba Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 3 Jul 2004 11:25:44 +0000 Subject: r1330: Fix the build for systems without ldap headers (This used to be commit b7267121af45d7173c310299bb52ae031ae1d501) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 05d68e6ae6..6b9792ec4c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -48,7 +48,7 @@ static void gotalarm_sig(void) gotalarm = 1; } -LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) + LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) { LDAP *ldp = NULL; -- cgit From 02001dfb6c3ffe3091001aeaa17e3d0b48933cfd Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 7 Jul 2004 18:15:24 +0000 Subject: r1381: fixing behavior found by gd@sernet.de; we must use the userPrincipalName value (host/hostname@REALM) and not the servicePrincipalName (host/fqdn@REALM) in the SASL binds (This used to be commit 959da6e176da9f6a687265e50489b7db3d6712c0) --- source3/libads/ldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6b9792ec4c..78ea9f1497 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -255,10 +255,10 @@ got_connection: ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); if (!ads->auth.user_name) { - fstring my_fqdn; - name_to_fqdn(my_fqdn, global_myname()); - strlower_m(my_fqdn); - asprintf(&ads->auth.user_name, "host/%s", my_fqdn); + /* have to use the userPrincipalName value here and + not servicePrincipalName; found by Guenther Deschner @ Sernet */ + + asprintf(&ads->auth.user_name, "host/%s", global_myname() ); } if (!ads->auth.realm) { -- cgit From 725d93954896052e24a6870e9e5f14106063fe78 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 27 Aug 2004 16:15:23 +0000 Subject: r2091: only use sAMAccountName and not userPrincipalName since the breaks winbindd (lookup_name() only works with the sAMAccountName) -- *please* test this change. My tests all pass but there is probably something I missed (This used to be commit 2bf08aaa37f41681b3154514792bf29a3abfdbfd) --- source3/libads/ldap.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 78ea9f1497..d1539b83da 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2184,13 +2184,19 @@ BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, */ char *ads_pull_username(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg) { +#if 0 /* JERRY */ char *ret, *p; + /* lookup_name() only works on the sAMAccountName to + returning the username portion of userPrincipalName + breaks winbindd_getpwnam() */ + ret = ads_pull_string(ads, mem_ctx, msg, "userPrincipalName"); if (ret && (p = strchr(ret, '@'))) { *p = 0; return ret; } +#endif return ads_pull_string(ads, mem_ctx, msg, "sAMAccountName"); } -- cgit From 132879b285e66bff896c761858311d7f5d43e9b6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 6 Oct 2004 16:21:35 +0000 Subject: r2832: Readd WKGUID-binding to match the correct default-locations of new User-, Group- and Machine-Accounts in Active Directory (this got lost during the last trunk-merge). This way we match e.g. default containers moved by redircmp.exe and redirusr.exe in Windows 2003 and don't blindly default to cn=Users or cn=Computers. Further wkguids can be examied via "net ads search wellknownobjects=*". This should still keep a samba3-client joining a samba4 dc. Fixes Bugzilla #1343. Guenther (This used to be commit 8836621694c95779475fa9a1acf158e5e0577288) --- source3/libads/ldap.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 73 insertions(+), 4 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d1539b83da..e5d2dfb8d3 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -995,18 +995,87 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) * Build an org unit string * if org unit is Computers or blank then assume a container, otherwise * assume a \ separated list of organisational units + * @param ads connection to ads server * @param org_unit Organizational unit * @return org unit string - caller must free **/ -char *ads_ou_string(const char *org_unit) -{ - if (!org_unit || !*org_unit || strequal(org_unit, "Computers")) { +char *ads_ou_string(ADS_STRUCT *ads, const char *org_unit) +{ + char *ret = NULL; + + if (!org_unit || !*org_unit) { + + ret = ads_default_ou_string(ads, WELL_KNOWN_GUID_COMPUTERS); + + /* samba4 might not yet respond to a wellknownobject-query */ + return ret ? ret : strdup("cn=Computers"); + } + + if (strequal(org_unit, "Computers")) { return strdup("cn=Computers"); } return ads_build_path(org_unit, "\\/", "ou=", 1); } +/** + * Get a org unit string for a well-known GUID + * @param ads connection to ads server + * @param wknguid Well known GUID + * @return org unit string - caller must free + **/ +char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) +{ + ADS_STATUS status; + void *res; + char *base, *wkn_dn, *ret, **wkn_dn_exp, **bind_dn_exp; + const char *attrs[] = {"distinguishedName", NULL}; + int new_ln, wkn_ln, bind_ln, i; + + if (wknguid == NULL) { + return NULL; + } + + if (asprintf(&base, "", wknguid, ads->config.bind_path ) == -1) { + DEBUG(1, ("asprintf failed!\n")); + return NULL; + } + + status = ads_search_dn(ads, &res, base, attrs); + if (!ADS_ERR_OK(status)) { + DEBUG(1,("Failed while searching for: %s\n", base)); + return NULL; + } + free(base); + + if (ads_count_replies(ads, res) != 1) { + return NULL; + } + + /* substitute the bind-path from the well-known-guid-search result */ + wkn_dn = ads_get_dn(ads, res); + wkn_dn_exp = ldap_explode_dn(wkn_dn, 0); + bind_dn_exp = ldap_explode_dn(ads->config.bind_path, 0); + + for (wkn_ln=0; wkn_dn_exp[wkn_ln]; wkn_ln++) + ; + for (bind_ln=0; bind_dn_exp[bind_ln]; bind_ln++) + ; + + new_ln = wkn_ln - bind_ln; + + ret = wkn_dn_exp[0]; + + for (i=1; i < new_ln; i++) { + char *s; + asprintf(&s, "%s,%s", ret, wkn_dn_exp[i]); + ret = strdup(s); + free(s); + } + + return ret; +} + /** * Adds (appends) an item to an attribute array, rather then * replacing the whole list @@ -1283,7 +1352,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name machine_name)); exists=1; } else { - char *ou_str = ads_ou_string(org_unit); + char *ou_str = ads_ou_string(ads,org_unit); if (!ou_str) { DEBUG(1, ("ads_add_machine_acct: ads_ou_string returned NULL (malloc failure?)\n")); goto done; -- cgit From f8345c1b18904169666955c98474fa2d5894a007 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 Oct 2004 00:41:41 +0000 Subject: r3273: Ensure we're consistent in the use of strchr_m for '@'. Jeremy. (This used to be commit 0f3f7b035b37bfc51d3a59d0472003c3d4ac1511) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e5d2dfb8d3..749274298f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2261,7 +2261,7 @@ char *ads_pull_username(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg) breaks winbindd_getpwnam() */ ret = ads_pull_string(ads, mem_ctx, msg, "userPrincipalName"); - if (ret && (p = strchr(ret, '@'))) { + if (ret && (p = strchr_m(ret, '@'))) { *p = 0; return ret; } -- cgit From d4a46dec34c0282500d80f20fa9c4f2a10edabed Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Nov 2004 23:50:26 +0000 Subject: r3569: Fix for bug #1651, added extra servicePrincipalNames for kerberos interop. Modified the redhat patch some... Jeremy. (This used to be commit 2ae717cd2c876649464f91093e55bed64ac5588d) --- source3/libads/ldap.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 749274298f..b2ae5aeb94 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1228,11 +1228,11 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n ADS_STATUS ret; TALLOC_CTX *ctx; LDAPMessage *res = NULL; - char *host_spn, *host_upn, *psp1, *psp2; + char *host_spn, *host_upn, *psp1, *psp2, *psp3; ADS_MODLIST mods; fstring my_fqdn; char *dn_string = NULL; - const char *servicePrincipalName[3] = {NULL, NULL, NULL}; + const char *servicePrincipalName[4] = {NULL, NULL, NULL, NULL}; ret = ads_find_machine_acct(ads, (void **)&res, machine_name); if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { @@ -1251,6 +1251,8 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n } name_to_fqdn(my_fqdn, machine_name); + strlower_m(my_fqdn); + if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", my_fqdn))) { talloc_destroy(ctx); ads_msgfree(ads, res); @@ -1274,6 +1276,17 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp2, machine_name)); servicePrincipalName[1] = psp2; + /* Add another principal in case the realm != the DNS domain, so that + * the KDC doesn't send "server principal unknown" errors to clients + * which use the DNS name in determining service principal names. */ + psp3 = talloc_asprintf(ctx, "%s/%s", spn, my_fqdn); + strupper_m(psp3); + strlower_m(&psp3[strlen(spn)]); + if (strcmp(psp2, psp3) != 0) { + DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp3, machine_name)); + servicePrincipalName[2] = psp3; + } + if (!(mods = ads_init_mods(ctx))) { talloc_destroy(ctx); ads_msgfree(ads, res); @@ -1325,12 +1338,13 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name ADS_MODLIST mods; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; - const char *servicePrincipalName[5] = {NULL, NULL, NULL, NULL, NULL}; - char *psp, *psp2; + const char *servicePrincipalName[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + char *psp, *psp2, *psp3, *psp4; unsigned acct_control; unsigned exists=0; fstring my_fqdn; LDAPMessage *res = NULL; + int i, next_spn; if (!(ctx = talloc_init("ads_add_machine_acct"))) return ADS_ERROR(LDAP_NO_MEMORY); @@ -1384,6 +1398,30 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name strlower_m(&psp2[5]); servicePrincipalName[3] = psp2; + /* Ensure servicePrincipalName[4] and [5] are unique. */ + strlower_m(my_fqdn); + psp3 = talloc_asprintf(ctx, "CIFS/%s", my_fqdn); + strlower_m(&psp3[5]); + + next_spn = 4; + for (i = 0; i < next_spn; i++) { + if (strequal(servicePrincipalName[i], psp3)) + break; + } + if (i == next_spn) { + servicePrincipalName[next_spn++] = psp3; + } + + psp4 = talloc_asprintf(ctx, "HOST/%s", my_fqdn); + strlower_m(&psp4[5]); + for (i = 0; i < next_spn; i++) { + if (strequal(servicePrincipalName[i], psp3)) + break; + } + if (i == next_spn) { + servicePrincipalName[next_spn++] = psp4; + } + if (!(samAccountName = talloc_asprintf(ctx, "%s$", machine_name))) { goto done; } @@ -1683,14 +1721,14 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, status = ads_add_machine_acct(ads, machine, account_type, org_unit); if (!ADS_ERR_OK(status)) { - DEBUG(0, ("ads_add_machine_acct (%s): %s\n", machine, ads_errstr(status))); + DEBUG(0, ("ads_join_realm: ads_add_machine_acct failed (%s): %s\n", machine, ads_errstr(status))); SAFE_FREE(machine); return status; } status = ads_find_machine_acct(ads, (void **)&res, machine); if (!ADS_ERR_OK(status)) { - DEBUG(0, ("Host account test failed for machine %s\n", machine)); + DEBUG(0, ("ads_join_realm: Host account test failed for machine %s\n", machine)); SAFE_FREE(machine); return status; } -- cgit From aad0bc6c3782099d7eb070450863663ce5d77050 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 15 Nov 2004 18:57:22 +0000 Subject: r3764: Ensure on failure that *res is always NULL. Check for malloc fail. Fixes for bug #2036. Jeremy. (This used to be commit b815247747214ba413c054746e9732d5f2b10535) --- source3/libads/ldap.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b2ae5aeb94..252cd718c8 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -456,8 +456,6 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, controls[1] = &PagedResults; controls[2] = NULL; - *res = NULL; - /* we need to disable referrals as the openldap libs don't handle them and paged results at the same time. Using them together results in the result record containing the server @@ -533,6 +531,7 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, int count = 0; ADS_STATUS status; + *res = NULL; status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, res, &count, &cookie); @@ -623,6 +622,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, char *utf8_expr, *utf8_path, **search_attrs = NULL; TALLOC_CTX *ctx; + *res = NULL; if (!(ctx = talloc_init("ads_do_search"))) { DEBUG(1,("ads_do_search: talloc_init() failed!")); return ADS_ERROR(LDAP_NO_MEMORY); @@ -653,7 +653,6 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, timeout.tv_sec = ADS_SEARCH_TIMEOUT; 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); @@ -764,6 +763,8 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *machin char *expr; const char *attrs[] = {"*", "nTSecurityDescriptor", NULL}; + *res = NULL; + /* the easiest way to find a machine account anywhere in the tree is to look for hostname$ */ if (asprintf(&expr, "(samAccountName=%s$)", machine) == -1) { @@ -2494,6 +2495,10 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * asprintf(&expr, "(&(objectclass=computer)(dnshostname=%s.%s))", ads->config.ldap_server_name, ads->config.realm); + if (expr == NULL) { + ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + rc = ads_search(ads, &res, expr, attrs); free(expr); -- cgit From 0bd9bc6ecae10fa21e4315ea9f20b52fc5883f30 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 18 Nov 2004 11:43:14 +0000 Subject: r3841: Time out in ads search queries. Even AD servers can hang. Volker (This used to be commit fc454c8ef6321fba9efa42a704c8e8c707361af3) --- source3/libads/ldap.c | 51 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 252cd718c8..7bddc0e9b5 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -67,6 +67,40 @@ static void gotalarm_sig(void) return ldp; } +static int ldap_search_with_timeout(LDAP *ld, + LDAP_CONST char *base, + int scope, + LDAP_CONST char *filter, + char **attrs, + int attrsonly, + LDAPControl **sctrls, + LDAPControl **cctrls, + struct timeval *timeout, + int sizelimit, + LDAPMessage **res ) +{ + int result; + + /* Setup timeout */ + gotalarm = 0; + CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); + alarm(lp_ldap_timeout()); + /* End setup timeout. */ + + result = ldap_search_ext_s(ld, base, scope, filter, attrs, + attrsonly, sctrls, cctrls, timeout, + sizelimit, res); + + /* Teardown timeout. */ + CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN); + alarm(0); + + if (gotalarm != 0) + return LDAP_TIMELIMIT_EXCEEDED; + + return result; +} + /* try a connection to a given ldap server, returning True and setting the servers IP in the ads struct if successful @@ -466,15 +500,17 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, */ ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_expr, - search_attrs, 0, controls, - NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); + rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr, + search_attrs, 0, controls, + NULL, NULL, LDAP_NO_LIMIT, + (LDAPMessage **)res); ber_free(cookie_be, 1); ber_bvfree(cookie_bv); if (rc) { - DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", expr, ldap_err2string(rc))); + DEBUG(3,("ldap_search_with_timeout(%s) -> %s\n", expr, + ldap_err2string(rc))); goto done; } @@ -657,9 +693,10 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, /* 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_expr, - search_attrs, 0, NULL, NULL, - &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res); + rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr, + search_attrs, 0, NULL, NULL, + &timeout, LDAP_NO_LIMIT, + (LDAPMessage **)res); if (rc == LDAP_SIZELIMIT_EXCEEDED) { DEBUG(3,("Warning! sizelimit exceeded in ldap. Truncating.\n")); -- cgit From acf9d61421faa6c0055d57fdee7db300dc5431aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Dec 2004 18:25:53 +0000 Subject: r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation functions so we can funnel through some well known functions. Should help greatly with malloc checking. HEAD patch to follow. Jeremy. (This used to be commit 620f2e608f70ba92f032720c031283d295c5c06a) --- source3/libads/ldap.c | 60 +++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7bddc0e9b5..c18e253f7b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -119,7 +119,7 @@ static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) DEBUG(5,("ads_try_connect: trying ldap server '%s' port %u\n", server, port)); /* this copes with inet_ntoa brokenness */ - srv = strdup(server); + srv = SMB_STRDUP(server); ads->ld = ldap_open_with_timeout(srv, port, lp_ldap_timeout()); if (!ads->ld) { @@ -296,11 +296,11 @@ got_connection: } if (!ads->auth.realm) { - ads->auth.realm = strdup(ads->config.realm); + ads->auth.realm = SMB_STRDUP(ads->config.realm); } if (!ads->auth.kdc_server) { - ads->auth.kdc_server = strdup(inet_ntoa(ads->ldap_ip)); + ads->auth.kdc_server = SMB_STRDUP(inet_ntoa(ads->ldap_ip)); } #if KRB5_DNS_HACK @@ -338,13 +338,13 @@ static struct berval *dup_berval(TALLOC_CTX *ctx, const struct berval *in_val) if (!in_val) return NULL; - value = talloc_zero(ctx, sizeof(struct berval)); + value = TALLOC_ZERO_P(ctx, struct berval); if (value == NULL) return NULL; 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); + value->bv_val = TALLOC_MEMDUP(ctx, in_val->bv_val, in_val->bv_len); return value; } @@ -358,9 +358,9 @@ static struct berval **ads_dup_values(TALLOC_CTX *ctx, 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 *)); + for (i=0; in_vals[i]; i++) + ; /* count values */ + values = TALLOC_ZERO_ARRAY(ctx, struct berval *, i+1); if (!values) return NULL; for (i=0; in_vals[i]; i++) { @@ -378,8 +378,9 @@ static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals) 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 *)); + for (i=0; in_vals[i]; i++) + ; /* count values */ + values = TALLOC_ZERO_ARRAY(ctx, char *, i+1); if (!values) return NULL; for (i=0; in_vals[i]; i++) { @@ -397,8 +398,9 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) 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 *)); + for (i=0; in_vals[i]; i++) + ; /* count values */ + values = TALLOC_ZERO_ARRAY(ctx, char *, i+1); if (!values) return NULL; for (i=0; in_vals[i]; i++) { @@ -824,8 +826,7 @@ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx) #define ADS_MODLIST_ALLOC_SIZE 10 LDAPMod **mods; - if ((mods = (LDAPMod **) talloc_zero(ctx, sizeof(LDAPMod *) * - (ADS_MODLIST_ALLOC_SIZE + 1)))) + if ((mods = TALLOC_ZERO_ARRAY(ctx, LDAPMod *, ADS_MODLIST_ALLOC_SIZE + 1))) /* -1 is safety to make sure we don't go over the end. need to reset it to NULL before doing ldap modify */ mods[ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1; @@ -861,8 +862,8 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, for (curmod=0; modlist[curmod] && modlist[curmod] != (LDAPMod *) -1; curmod++); if (modlist[curmod] == (LDAPMod *) -1) { - if (!(modlist = talloc_realloc(ctx, modlist, - (curmod+ADS_MODLIST_ALLOC_SIZE+1)*sizeof(LDAPMod *)))) + if (!(modlist = TALLOC_REALLOC_ARRAY(ctx, modlist, LDAPMod *, + curmod+ADS_MODLIST_ALLOC_SIZE+1))) return ADS_ERROR(LDAP_NO_MEMORY); memset(&modlist[curmod], 0, ADS_MODLIST_ALLOC_SIZE*sizeof(LDAPMod *)); @@ -870,7 +871,7 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, *mods = modlist; } - if (!(modlist[curmod] = talloc_zero(ctx, sizeof(LDAPMod)))) + if (!(modlist[curmod] = TALLOC_ZERO_P(ctx, LDAPMod))) return ADS_ERROR(LDAP_NO_MEMORY); modlist[curmod]->mod_type = talloc_strdup(ctx, name); if (mod_op & LDAP_MOD_BVALUES) { @@ -1046,11 +1047,11 @@ char *ads_ou_string(ADS_STRUCT *ads, const char *org_unit) ret = ads_default_ou_string(ads, WELL_KNOWN_GUID_COMPUTERS); /* samba4 might not yet respond to a wellknownobject-query */ - return ret ? ret : strdup("cn=Computers"); + return ret ? ret : SMB_STRDUP("cn=Computers"); } if (strequal(org_unit, "Computers")) { - return strdup("cn=Computers"); + return SMB_STRDUP("cn=Computers"); } return ads_build_path(org_unit, "\\/", "ou=", 1); @@ -1107,7 +1108,7 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) for (i=1; i < new_ln; i++) { char *s; asprintf(&s, "%s,%s", ret, wkn_dn_exp[i]); - ret = strdup(s); + ret = SMB_STRDUP(s); free(s); } @@ -1741,7 +1742,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, char *machine; /* machine name must be lowercase */ - machine = strdup(machine_name); + machine = SMB_STRDUP(machine_name); strlower_m(machine); /* @@ -1791,7 +1792,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) int rc; /* hostname must be lowercase */ - host = strdup(hostname); + host = SMB_STRDUP(hostname); strlower_m(host); status = ads_find_machine_acct(ads, &res, host); @@ -1915,7 +1916,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY); bval.bv_len = prs_offset(&ps_wire); - bval.bv_val = talloc(ctx, bval.bv_len); + bval.bv_val = TALLOC(ctx, bval.bv_len); if (!bval.bv_val) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; @@ -2015,7 +2016,7 @@ char **ads_pull_strings(ADS_STRUCT *ads, *num_values = ldap_count_values(values); - ret = talloc(mem_ctx, sizeof(char *) * (*num_values+1)); + ret = TALLOC_ARRAY(mem_ctx, char *, *num_values + 1); if (!ret) { ldap_value_free(values); return NULL; @@ -2126,9 +2127,8 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, return NULL; } - strings = talloc_realloc(mem_ctx, current_strings, - sizeof(*current_strings) * - (*num_strings + num_new_strings)); + strings = TALLOC_REALLOC_ARRAY(mem_ctx, current_strings, char *, + *num_strings + num_new_strings); if (strings == NULL) { ldap_memfree(range_attr); @@ -2265,7 +2265,7 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, for (i=0; values[i]; i++) /* nop */ ; - (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * i); + (*sids) = TALLOC_ARRAY(mem_ctx, DOM_SID, i); if (!(*sids)) { ldap_value_free_len(values); return 0; @@ -2446,7 +2446,7 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) SAFE_FREE(ads->config.ldap_server_name); - ads->config.ldap_server_name = strdup(p+1); + ads->config.ldap_server_name = SMB_STRDUP(p+1); p = strchr(ads->config.ldap_server_name, '$'); if (!p || p[1] != '@') { talloc_destroy(ctx); @@ -2461,7 +2461,7 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) SAFE_FREE(ads->config.realm); SAFE_FREE(ads->config.bind_path); - ads->config.realm = strdup(p+2); + ads->config.realm = SMB_STRDUP(p+2); ads->config.bind_path = ads_build_dn(ads->config.realm); DEBUG(3,("got ldap server name %s@%s, using bind path: %s\n", -- cgit From 883874c5628f70279ea733e08153b91ea3f83c25 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 23 Dec 2004 18:40:50 +0000 Subject: r4346: Fix cut-and-paste error - bugid #2189. Fixed by Buck Huppmann Jeremy. (This used to be commit 5c22cb082c86088add0db21541a8079c516c9fd9) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c18e253f7b..8c37a90e73 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1454,7 +1454,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name psp4 = talloc_asprintf(ctx, "HOST/%s", my_fqdn); strlower_m(&psp4[5]); for (i = 0; i < next_spn; i++) { - if (strequal(servicePrincipalName[i], psp3)) + if (strequal(servicePrincipalName[i], psp4)) break; } if (i == next_spn) { -- cgit From d16a5c4381397efa7f4de2d8c7e9299bec492eb8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Jan 2005 02:13:03 +0000 Subject: r4665: Fix inspired by posting from Joe Meadows . Make all LDAP timeouts consistent. Jeremy. (This used to be commit 0f0281c2348b10ffdea744ecade6b2be0814c872) --- source3/libads/ldap.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8c37a90e73..494bd930e4 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -75,20 +75,24 @@ static int ldap_search_with_timeout(LDAP *ld, int attrsonly, LDAPControl **sctrls, LDAPControl **cctrls, - struct timeval *timeout, int sizelimit, LDAPMessage **res ) { + struct timeval timeout; int result; - /* Setup timeout */ + /* Setup timeout for the ldap_search_ext_s call - local and remote. */ + timeout.tv_sec = lp_ldap_timeout(); + timeout.tv_usec = 0; + + /* Setup alarm timeout.... Do we need both of these ? JRA. */ gotalarm = 0; CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); alarm(lp_ldap_timeout()); /* End setup timeout. */ result = ldap_search_ext_s(ld, base, scope, filter, attrs, - attrsonly, sctrls, cctrls, timeout, + attrsonly, sctrls, cctrls, &timeout, sizelimit, res); /* Teardown timeout. */ @@ -504,14 +508,14 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr, search_attrs, 0, controls, - NULL, NULL, LDAP_NO_LIMIT, + NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); ber_free(cookie_be, 1); ber_bvfree(cookie_bv); if (rc) { - DEBUG(3,("ldap_search_with_timeout(%s) -> %s\n", expr, + DEBUG(3,("ads_do_paged_search: ldap_search_with_timeout(%s) -> %s\n", expr, ldap_err2string(rc))); goto done; } @@ -655,7 +659,6 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, const char *expr, const char **attrs, void **res) { - struct timeval timeout; int rc; char *utf8_expr, *utf8_path, **search_attrs = NULL; TALLOC_CTX *ctx; @@ -689,15 +692,12 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, } } - timeout.tv_sec = ADS_SEARCH_TIMEOUT; - timeout.tv_usec = 0; - /* 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_with_timeout(ads->ld, utf8_path, scope, utf8_expr, search_attrs, 0, NULL, NULL, - &timeout, LDAP_NO_LIMIT, + LDAP_NO_LIMIT, (LDAPMessage **)res); if (rc == LDAP_SIZELIMIT_EXCEEDED) { -- cgit From 44be949f28774cae4e79704c1c8f5d624f2bd46c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 4 Feb 2005 00:25:33 +0000 Subject: r5207: patches from Jay Fenlason @ RedHat (scooped from their Fedora packages) (This used to be commit 9019a8436162d3606f6b8584701b0832cf5a7439) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 494bd930e4..c9bba72524 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2526,7 +2526,7 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * int i; void *res; const char *attrs[] = {"servicePrincipalName", NULL}; - int num_principals; + size_t num_principals; (*workgroup) = NULL; -- cgit From a309fed583609d19c74c6f3eb63d2113b2a337d3 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 11 Feb 2005 14:31:14 +0000 Subject: r5336: BUG 2329: fix to re-enable winbindd to locate DC's when 'disable netbios = yes' (This used to be commit 75a223f1188ae0041c9e3c748af107d642f73810) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c9bba72524..6e1b011c37 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -112,7 +112,7 @@ static int ldap_search_with_timeout(LDAP *ld, TODO : add a negative connection cache in here leveraged off of the one found in the rpc code. --jerry */ -static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) +BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) { char *srv; -- cgit From 40295c41dbba119f6b4e32647fb70f51ebf390a0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 22 Mar 2005 14:48:18 +0000 Subject: r5948: more compile cleanups from Jason Mader (This used to be commit cc6c769c3c26164919dd13777d671abe02c084d9) --- source3/libads/ldap.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6e1b011c37..13e6aa5a31 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1267,7 +1267,7 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n ADS_STATUS ret; TALLOC_CTX *ctx; LDAPMessage *res = NULL; - char *host_spn, *host_upn, *psp1, *psp2, *psp3; + char *host_spn, *psp1, *psp2, *psp3; ADS_MODLIST mods; fstring my_fqdn; char *dn_string = NULL; @@ -1297,11 +1297,6 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } - if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) { - talloc_destroy(ctx); - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_SUCH_OBJECT); - } /* Add the extra principal */ psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name); -- cgit From 73d1950c010777605b1294397002cc7aa011add0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 22 Mar 2005 16:39:09 +0000 Subject: r5956: more compile warngin fixes from the Mr. Mader (This used to be commit f3f315b14d261fa56ab040db036a6f858ac06e65) --- source3/libads/ldap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 13e6aa5a31..68103a701b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -831,7 +831,7 @@ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx) need to reset it to NULL before doing ldap modify */ mods[ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1; - return mods; + return (ADS_MODLIST)mods; } @@ -868,7 +868,7 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, memset(&modlist[curmod], 0, ADS_MODLIST_ALLOC_SIZE*sizeof(LDAPMod *)); modlist[curmod+ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1; - *mods = modlist; + *mods = (ADS_MODLIST)modlist; } if (!(modlist[curmod] = TALLOC_ZERO_P(ctx, LDAPMod))) @@ -1006,7 +1006,7 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_add_s(ads->ld, utf8_dn, mods); + ret = ldap_add_s(ads->ld, utf8_dn, (LDAPMod**)mods); SAFE_FREE(utf8_dn); return ADS_ERROR(ret); } -- cgit From 9840db418bad5a39edc4a32a1786f5e2d2c9dff8 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 31 Mar 2005 05:06:04 +0000 Subject: r6149: Fixes bugs #2498 and 2484. 1. using smbc_getxattr() et al, one may now request all access control entities in the ACL without getting all other NT attributes. 2. added the ability to exclude specified attributes from the result set provided by smbc_getxattr() et al, when requesting all attributes, all NT attributes, or all DOS attributes. 3. eliminated all compiler warnings, including when --enable-developer compiler flags are in use. removed -Wcast-qual flag from list, as that is specifically to force warnings in the case of casting away qualifiers. Note: In the process of eliminating compiler warnings, a few nasties were discovered. In the file libads/sasl.c, PRIVATE kerberos interfaces are being used; and in libsmb/clikrb5.c, both PRIAVE and DEPRECATED kerberos interfaces are being used. Someone who knows kerberos should look at these and determine if there is an alternate method of accomplishing the task. (This used to be commit 994694f7f26da5099f071e1381271a70407f33bb) --- source3/libads/ldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 68103a701b..7a59da5a6d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -481,15 +481,15 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, ber_printf(cookie_be, "{io}", (ber_int_t) 1000, "", 0); } ber_flatten(cookie_be, &cookie_bv); - PagedResults.ldctl_oid = ADS_PAGE_CTL_OID; + PagedResults.ldctl_oid = CONST_DISCARD(char *, ADS_PAGE_CTL_OID); PagedResults.ldctl_iscritical = (char) 1; PagedResults.ldctl_value.bv_len = cookie_bv->bv_len; PagedResults.ldctl_value.bv_val = cookie_bv->bv_val; - NoReferrals.ldctl_oid = ADS_NO_REFERRALS_OID; + NoReferrals.ldctl_oid = CONST_DISCARD(char *, ADS_NO_REFERRALS_OID); NoReferrals.ldctl_iscritical = (char) 0; NoReferrals.ldctl_value.bv_len = 0; - NoReferrals.ldctl_value.bv_val = ""; + NoReferrals.ldctl_value.bv_val = CONST_DISCARD(char *, ""); controls[0] = &NoReferrals; @@ -962,7 +962,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) non-existent attribute (but allowable for the object) to run */ LDAPControl PermitModify = { - ADS_PERMIT_MODIFY_OID, + CONST_DISCARD(char *, ADS_PERMIT_MODIFY_OID), {0, NULL}, (char) 1}; LDAPControl *controls[2]; -- cgit From 7b9d6ac23e1a7d8136fffd2e3977b09a815da65a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 3 May 2005 07:33:49 +0000 Subject: r6595: This is Volkers new-talloc patch. Just got the go-ahead from Volker to commit. Woo Hoo ! Jeremy. (This used to be commit 316df944a456f150944761dab34add5e8c4ab699) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7a59da5a6d..04754f4e9e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1703,7 +1703,7 @@ void ads_process_results(ADS_STRUCT *ads, void *res, ldap_memfree(utf8_field); } ber_free(b, 0); - talloc_destroy_pool(ctx); + talloc_free_children(ctx); fn(NULL, NULL, data_area); /* completed an entry */ } -- cgit From 2e7f22e833fbb549f698460f9ed4d81af68b86e9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 29 Jun 2005 14:03:53 +0000 Subject: r7994: This adds support in Winbindd's "security = ads"-mode to retrieve the POSIX homedirectory and the loginshell from Active Directory's "Services for Unix". Enable it with: winbind sfu support = yes User-Accounts without SFU-Unix-Attributes will be assigned template-based Shells and Homedirs as before. Note that it doesn't matter which version of Services for Unix you use (2.0, 2.2, 3.0 or 3.5). Samba should detect the correct attributes (msSFULoginShell, msSFU30LoginShell, etc.) automatically. If you also want to share the same uid/gid-space as SFU then also use PADL's ad-idmap-Plugin: idmap backend = ad When using the idmap-plugin only those accounts will appear in Name Service Switch that have those UNIX-attributes which avoids potential uid/gid-space clashes between SFU-ids and automatically assigned idmap-ids. Guenther (This used to be commit 28b59699425b1c954d191fc0e3bd357e4a4e4cd8) --- source3/libads/ldap.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 04754f4e9e..1289015464 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2388,6 +2388,43 @@ static time_t ads_parse_time(const char *str) } +const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * oid) +{ + ADS_STATUS rc; + int count = 0; + void *res = NULL; + char *expr = NULL; + const char *attrs[] = { "lDAPDisplayName", NULL }; + + if (ads == NULL || mem_ctx == NULL || oid == NULL) { + goto done; + } + + expr = talloc_asprintf(mem_ctx, "(attributeId=%s)", oid); + if (expr == NULL) { + goto done; + } + + rc = ads_do_search_retry(ads, ads->config.schema_path, + LDAP_SCOPE_SUBTREE, expr, attrs, &res); + if (!ADS_ERR_OK(rc)) { + goto done; + } + + count = ads_count_replies(ads, res); + if (count == 0 || !res) { + goto done; + } + + return ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName"); + +done: + DEBUG(0,("ads_get_attrname_by_oid: failed to retrieve name for oid: %s\n", + oid)); + + return NULL; +} + /** * Find the servers name and realm - this can be done before authentication * The ldapServiceName field on w2k looks like this: @@ -2397,12 +2434,15 @@ static time_t ads_parse_time(const char *str) **/ ADS_STATUS ads_server_info(ADS_STRUCT *ads) { - const char *attrs[] = {"ldapServiceName", "currentTime", NULL}; + const char *attrs[] = {"ldapServiceName", + "currentTime", + "schemaNamingContext", NULL}; ADS_STATUS status; void *res; char *value; char *p; char *timestr; + char *schema_path; TALLOC_CTX *ctx; if (!(ctx = talloc_init("ads_server_info"))) { @@ -2429,6 +2469,16 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); } + schema_path = ads_pull_string(ads, ctx, res, "schemaNamingContext"); + if (!schema_path) { + ads_msgfree(ads, res); + talloc_destroy(ctx); + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + SAFE_FREE(ads->config.schema_path); + ads->config.schema_path = SMB_STRDUP(schema_path); + ads_msgfree(ads, res); p = strchr(value, ':'); @@ -2475,6 +2525,50 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads) return ADS_SUCCESS; } +/** + * Check for "Services for Unix"-Schema and load some attributes into the ADS_STRUCT + * @param ads connection to ads server + * @return BOOL status of search (False if one or more attributes couldn't be + * found in Active Directory) + **/ +BOOL ads_check_sfu_mapping(ADS_STRUCT *ads) +{ + BOOL ret = False; + TALLOC_CTX *ctx = NULL; + const char *gidnumber, *uidnumber, *homedir, *shell; + + ctx = talloc_init("ads_check_sfu_mapping"); + if (ctx == NULL) + goto done; + + gidnumber = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_GIDNUMBER_OID); + if (gidnumber == NULL) + goto done; + ads->schema.sfu_gidnumber_attr = SMB_STRDUP(gidnumber); + + uidnumber = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_UIDNUMBER_OID); + if (uidnumber == NULL) + goto done; + ads->schema.sfu_uidnumber_attr = SMB_STRDUP(uidnumber); + + homedir = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_HOMEDIR_OID); + if (homedir == NULL) + goto done; + ads->schema.sfu_homedir_attr = SMB_STRDUP(homedir); + + shell = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_SHELL_OID); + if (shell == NULL) + goto done; + ads->schema.sfu_shell_attr = SMB_STRDUP(shell); + + ret = True; +done: + if (ctx) + talloc_destroy(ctx); + + return ret; +} + /** * find the domain sid for our domain * @param ads connection to ads server -- cgit From 3f11139bf361ecc9dbcf928c48c67f2fdb95b771 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 1 Jul 2005 10:20:28 +0000 Subject: r8047: "oid" is defined in a heimdal header. With my gcc this generates a ton of shadowed variable warnings. Fix that. Volker (This used to be commit 3846c0afa1db96239b3aaf2e7ee2427b48f6e2f0) --- source3/libads/ldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1289015464..b3faad1fb1 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2388,7 +2388,7 @@ static time_t ads_parse_time(const char *str) } -const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * oid) +const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * OID) { ADS_STATUS rc; int count = 0; @@ -2396,11 +2396,11 @@ const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *expr = NULL; const char *attrs[] = { "lDAPDisplayName", NULL }; - if (ads == NULL || mem_ctx == NULL || oid == NULL) { + if (ads == NULL || mem_ctx == NULL || OID == NULL) { goto done; } - expr = talloc_asprintf(mem_ctx, "(attributeId=%s)", oid); + expr = talloc_asprintf(mem_ctx, "(attributeId=%s)", OID); if (expr == NULL) { goto done; } @@ -2420,7 +2420,7 @@ const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const done: DEBUG(0,("ads_get_attrname_by_oid: failed to retrieve name for oid: %s\n", - oid)); + OID)); return NULL; } -- cgit From 065d7e82a74166d06cb99678109d6de5d25e2298 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 1 Jul 2005 10:28:31 +0000 Subject: r8048: Replace "done" with "failed". Guenther (This used to be commit 7285edc4fe71f47ab648c31760c357fc2af29ce7) --- source3/libads/ldap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b3faad1fb1..81afd7f49e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2397,28 +2397,28 @@ const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const const char *attrs[] = { "lDAPDisplayName", NULL }; if (ads == NULL || mem_ctx == NULL || OID == NULL) { - goto done; + goto failed; } expr = talloc_asprintf(mem_ctx, "(attributeId=%s)", OID); if (expr == NULL) { - goto done; + goto failed; } rc = ads_do_search_retry(ads, ads->config.schema_path, LDAP_SCOPE_SUBTREE, expr, attrs, &res); if (!ADS_ERR_OK(rc)) { - goto done; + goto failed; } count = ads_count_replies(ads, res); if (count == 0 || !res) { - goto done; + goto failed; } return ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName"); -done: +failed: DEBUG(0,("ads_get_attrname_by_oid: failed to retrieve name for oid: %s\n", OID)); -- cgit From 54abd2aa66069e6baf7769c496f46d9dba18db39 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 30 Sep 2005 17:13:37 +0000 Subject: r10656: BIG merge from trunk. Features not copied over * \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 81afd7f49e..bf402b3499 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2104,7 +2104,7 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, if ((*num_strings) != range_start) { DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) doesn't start at %u, but at %lu" " - aborting range retreival\n", - range_attr, *num_strings + 1, range_start)); + range_attr, (unsigned int)(*num_strings) + 1, range_start)); ldap_memfree(range_attr); *more_strings = False; return NULL; @@ -2140,7 +2140,7 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, *next_attribute = talloc_asprintf(mem_ctx, "%s;range=%d-*", field, - *num_strings); + (int)*num_strings); if (!*next_attribute) { DEBUG(1, ("talloc_asprintf for next attribute failed!\n")); -- cgit From ac331c48db29afeb712bb1a1edf739354082ad7f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 22 Nov 2005 17:15:28 +0000 Subject: r11863: BUG 3196: patch from Alex Deiter to compile against the Sun LDAP client libs. But not for AD support; just ldap support (This used to be commit a33e78acedb37df47905d326411e017794721250) --- source3/libads/ldap.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index bf402b3499..6d1ca24537 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -577,8 +577,10 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, res, &count, &cookie); - if (!ADS_ERR_OK(status)) return status; + if (!ADS_ERR_OK(status)) + return status; +#ifdef HAVE_LDAP_ADD_RESULT_ENTRY while (cookie) { void *res2 = NULL; ADS_STATUS status2; @@ -598,6 +600,10 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, /* note that we do not free res2, as the memory is now part of the main returned list */ } +#else + DEBUG(0, ("no ldap_add_result_entry() support in LDAP libs!\n")); + status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); +#endif return status; } -- cgit From f6b8327fac33a7758f1c66131238a1945807e535 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 23 Nov 2005 11:21:16 +0000 Subject: r11875: Allow to use START_TLS (by manually setting "ldap ssl = start_tls") for LDAP connections to ADS (Windows 2003). Guenther (This used to be commit 95543fab0f6aa1c483b40247c16cde79cbc9c012) --- source3/libads/ldap.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6d1ca24537..e4cfc456a2 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -292,6 +292,11 @@ got_connection: ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + status = ADS_ERROR(smb_ldap_start_tls(ads->ld, version)); + if (!ADS_ERR_OK(status)) { + return status; + } + if (!ads->auth.user_name) { /* have to use the userPrincipalName value here and not servicePrincipalName; found by Guenther Deschner @ Sernet */ -- cgit From d1f91f7c723733113b4e9792042101c80dfc064c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Dec 2005 06:46:46 +0000 Subject: r12043: It's amazing the warnings you find when compiling on a 64-bit box with gcc4 and -O6... Fix a bunch of C99 dereferencing type-punned pointer will break strict-aliasing rules errors. Also added prs_int32 (not uint32...) as it's needed in one place. Find places where prs_uint32 was being used to marshall/unmarshall a time_t (a big no no on 64-bits). More warning fixes to come. Thanks to Volker for nudging me to compile like this. Jeremy. (This used to be commit c65b752604f8f58abc4e7ae8514dc2c7f086271c) --- source3/libads/ldap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e4cfc456a2..fa2a8b5ea5 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1162,7 +1162,7 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) if (asprintf(&filter, "(samAccountName=%s$)", machine_name) == -1) { return kvno; } - ret = ads_search(ads, (void**) &res, filter, attrs); + ret = ads_search(ads, (void**)(void *)&res, filter, attrs); SAFE_FREE(filter); if (!ADS_ERR_OK(ret) && ads_count_replies(ads, res)) { DEBUG(1,("ads_get_kvno: Computer Account For %s not found.\n", machine_name)); @@ -1216,7 +1216,7 @@ ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machin ADS_STATUS ret = ADS_ERROR(LDAP_SUCCESS); char *dn_string = NULL; - ret = ads_find_machine_acct(ads, (void **)&res, machine_name); + ret = ads_find_machine_acct(ads, (void **)(void *)&res, machine_name); if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { DEBUG(5,("ads_clear_service_principal_names: WARNING: Host Account for %s not found... skipping operation.\n", machine_name)); DEBUG(5,("ads_clear_service_principal_names: WARNING: Service Principals for %s have NOT been cleared.\n", machine_name)); @@ -1284,7 +1284,7 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n char *dn_string = NULL; const char *servicePrincipalName[4] = {NULL, NULL, NULL, NULL}; - ret = ads_find_machine_acct(ads, (void **)&res, machine_name); + ret = ads_find_machine_acct(ads, (void **)(void *)&res, machine_name); if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { DEBUG(1,("ads_add_service_principal_name: WARNING: Host Account for %s not found... skipping operation.\n", machine_name)); @@ -1398,7 +1398,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name name_to_fqdn(my_fqdn, machine_name); - status = ads_find_machine_acct(ads, (void **)&res, machine_name); + status = ads_find_machine_acct(ads, (void **)(void *)&res, machine_name); if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { char *dn_string = ads_get_dn(ads, res); if (!dn_string) { @@ -1771,7 +1771,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, return status; } - status = ads_find_machine_acct(ads, (void **)&res, machine); + status = ads_find_machine_acct(ads, (void **)(void *)&res, machine); if (!ADS_ERR_OK(status)) { DEBUG(0, ("ads_join_realm: Host account test failed for machine %s\n", machine)); SAFE_FREE(machine); -- cgit From 3f6d9a7b9d35331992fdd069b7752f3082fe0b1b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 12 Dec 2005 18:55:54 +0000 Subject: r12196: patch from Krishna Ganugapati Use the subtree delete ldap control when running 'net ads leave' to ensure that the machine account is actually deleted. (This used to be commit e96000c16cd182b2e2cbdc1a287002306d2965e6) --- source3/libads/ldap.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index fa2a8b5ea5..8c8401dff9 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -37,6 +37,9 @@ * codepoints in UTF-8). This may have to change at some point **/ + +#define LDAP_SERVER_TREE_DELETE_OID "1.2.840.113556.1.4.805" + static SIG_ATOMIC_T gotalarm; /*************************************************************** @@ -1796,6 +1799,11 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) void *res, *msg; char *hostnameDN, *host; int rc; + LDAPControl ldap_control; + LDAPControl * pldap_control[] = {&ldap_control, 0}; + + memset(&ldap_control, 0, sizeof(LDAPControl)); + ldap_control.ldctl_oid = (char *)LDAP_SERVER_TREE_DELETE_OID; /* hostname must be lowercase */ host = SMB_STRDUP(hostname); @@ -1813,7 +1821,15 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) } hostnameDN = ads_get_dn(ads, (LDAPMessage *)msg); - rc = ldap_delete_s(ads->ld, hostnameDN); + + + rc = ldap_delete_ext_s(ads->ld, hostnameDN, pldap_control, NULL); + if (rc) { + DEBUG(3,("ldap_delete_ext_s failed with error code %d\n", rc)); + }else { + DEBUG(3,("ldap_delete_ext_s succeeded with error code %d\n", rc)); + } + ads_memfree(ads, hostnameDN); if (rc != LDAP_SUCCESS) { return ADS_ERROR(rc); -- cgit From 92092cbcdcdb01448ef4e6acd9af88dd93c6c288 Mon Sep 17 00:00:00 2001 From: James Peach Date: Fri, 13 Jan 2006 00:07:54 +0000 Subject: r12878: Don't use non-static array initialisers. (This used to be commit 95b231f0285c65bcdc62cd453cea634f9f5e7f91) --- source3/libads/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8c8401dff9..dc93bd556c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1800,8 +1800,9 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) char *hostnameDN, *host; int rc; LDAPControl ldap_control; - LDAPControl * pldap_control[] = {&ldap_control, 0}; + LDAPControl * pldap_control[2] = {NULL, NULL}; + pldap_control[0] = &ldap_control; memset(&ldap_control, 0, sizeof(LDAPControl)); ldap_control.ldctl_oid = (char *)LDAP_SERVER_TREE_DELETE_OID; -- cgit From 855e02f1649992f05b685be96dfff4a9140170e9 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 3 Feb 2006 21:19:24 +0000 Subject: r13310: first round of server affinity patches for winbindd & net ads join (This used to be commit 6c3480f9aecc061660ad5c06347b8f1d3e11a330) --- source3/libads/ldap.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index dc93bd556c..e503da62a4 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -136,6 +136,10 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) ads->ldap_port = port; ads->ldap_ip = *interpret_addr2(srv); free(srv); + + /* cache the successful connection */ + + saf_store( ads->server.workgroup, server ); return True; } -- cgit From 0af1500fc0bafe61019f1b2ab1d9e1d369221240 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 3 Feb 2006 22:19:41 +0000 Subject: r13316: Let the carnage begin.... Sync with trunk as off r13315 (This used to be commit 17e63ac4ed8325c0d44fe62b2442449f3298559f) --- source3/libads/ldap.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e503da62a4..8444989bac 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -4,6 +4,7 @@ Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 Copyright (C) Jim McDonough 2002 + Copyright (C) Guenther Deschner 2005 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 @@ -807,6 +808,65 @@ char *ads_get_dn(ADS_STRUCT *ads, void *msg) return unix_dn; } +/** + * Get a canonical dn from search results + * @param ads connection to ads server + * @param msg Search result + * @return dn string + **/ +char *ads_get_dn_canonical(ADS_STRUCT *ads, void *msg) +{ +#ifdef HAVE_LDAP_DN2AD_CANONICAL + return ldap_dn2ad_canonical(ads_get_dn(ads, msg)); +#else + return NULL; +#endif +} + + +/** + * Get the parent dn from a search result + * @param ads connection to ads server + * @param msg Search result + * @return parent dn string + **/ +char *ads_get_parent_dn(ADS_STRUCT *ads, void *msg) +{ + char *mydn, *p, *dn; + + dn = ads_get_dn(ads, msg); + if (dn == NULL) { + return NULL; + } + + mydn = dn; + ads_memfree(ads, dn); + + p = strchr(mydn, ','); + + if (p == NULL) { + return NULL; + } + + return p+1; +} + +/** + * Get the parent from a dn + * @param dn the dn to return the parent from + * @return parent dn string + **/ +char *ads_parent_dn(const char *dn) +{ + char *p = strchr(dn, ','); + + if (p == NULL) { + return NULL; + } + + return p+1; +} + /** * Find a machine account given a hostname * @param ads connection to ads server @@ -2700,4 +2760,167 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * return ADS_SUCCESS; } +/** + * find our site name + * @param ads connection to ads server + * @param mem_ctx Pointer to talloc context + * @param site_name Pointer to the sitename + * @return status of search + **/ +ADS_STATUS ads_site_dn(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **site_name) +{ + ADS_STATUS status; + void *res; + const char *dn, *service_name; + const char *attrs[] = { "dsServiceName", NULL }; + + status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) { + return status; + } + + service_name = ads_pull_string(ads, mem_ctx, res, "dsServiceName"); + if (service_name == NULL) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + /* go up three levels */ + dn = ads_parent_dn(ads_parent_dn(ads_parent_dn(service_name))); + if (dn == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + *site_name = talloc_strdup(mem_ctx, dn); + if (*site_name == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + ads_msgfree(ads, res); + + return status; + /* + dsServiceName: CN=NTDS Settings,CN=W2K3DC,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=ber,DC=suse,DC=de + */ +} + +/** + * find the site dn where a machine resides + * @param ads connection to ads server + * @param mem_ctx Pointer to talloc context + * @param computer_name name of the machine + * @param site_name Pointer to the sitename + * @return status of search + **/ +ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *computer_name, const char **site_dn) +{ + ADS_STATUS status; + void *res; + const char *parent, *config_context, *filter; + const char *attrs[] = { "configurationNamingContext", NULL }; + char *dn; + + /* shortcut a query */ + if (strequal(computer_name, ads->config.ldap_server_name)) { + return ads_site_dn(ads, mem_ctx, site_dn); + } + + status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) { + return status; + } + + config_context = ads_pull_string(ads, mem_ctx, res, "configurationNamingContext"); + if (config_context == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + filter = talloc_asprintf(mem_ctx, "(cn=%s)", computer_name); + if (filter == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + status = ads_do_search(ads, config_context, LDAP_SCOPE_SUBTREE, filter, NULL, &res); + if (!ADS_ERR_OK(status)) { + return status; + } + + if (ads_count_replies(ads, res) != 1) { + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + + dn = ads_get_dn(ads, res); + if (dn == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + /* go up three levels */ + parent = ads_parent_dn(ads_parent_dn(ads_parent_dn(dn))); + if (parent == NULL) { + ads_memfree(ads, dn); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + *site_dn = talloc_strdup(mem_ctx, parent); + if (*site_dn == NULL) { + ads_memfree(ads, dn); + ADS_ERROR(LDAP_NO_MEMORY); + } + + ads_memfree(ads, dn); + ads_msgfree(ads, res); + + return status; +} + +/** + * get the upn suffixes for a domain + * @param ads connection to ads server + * @param mem_ctx Pointer to talloc context + * @param suffixes Pointer to an array of suffixes + * @param site_name Pointer to the number of suffixes + * @return status of search + **/ +ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **suffixes, size_t *num_suffixes) +{ + ADS_STATUS status; + void *res; + const char *config_context, *base; + const char *attrs[] = { "configurationNamingContext", NULL }; + const char *attrs2[] = { "uPNSuffixes", NULL }; + + status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) { + return status; + } + + config_context = ads_pull_string(ads, mem_ctx, res, "configurationNamingContext"); + if (config_context == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + base = talloc_asprintf(mem_ctx, "cn=Partitions,%s", config_context); + if (base == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + status = ads_search_dn(ads, &res, base, attrs2); + if (!ADS_ERR_OK(status)) { + return status; + } + + if (ads_count_replies(ads, res) != 1) { + return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + } + + suffixes = ads_pull_strings(ads, mem_ctx, &res, "uPNSuffixes", num_suffixes); + if (suffixes == NULL) { + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + ads_msgfree(ads, res); + + return status; +} + #endif -- cgit From c1ffb8d9bcad9053f3d97dc89c3ff3b023401157 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 9 Feb 2006 10:24:27 +0000 Subject: r13410: Dump a netbootGUID as a GUID. Guenther (This used to be commit 9b19a68456c7b576750aaf64c178ba5323d9a95e) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8444989bac..6d2155fae0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1684,6 +1684,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) void (*handler)(const char *, struct berval **); } handlers[] = { {"objectGUID", False, dump_guid}, + {"netbootGUID", False, dump_guid}, {"nTSecurityDescriptor", False, dump_sd}, {"dnsRecord", False, dump_binary}, {"objectSid", False, dump_sid}, -- cgit From 379bd6865f2fa46ea28024ad2bb2162ccfbb0db7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 23 Feb 2006 14:28:41 +0000 Subject: r13657: Let winbindd try to obtain the gecos field from the msSFU30Gecos attribute when "winbind nss info = sfu" is set. Fixes #3539. Guenther (This used to be commit ffce0461de130828345c44293e564ca03227607d) --- source3/libads/ldap.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6d2155fae0..cb7dbc575b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2628,7 +2628,7 @@ BOOL ads_check_sfu_mapping(ADS_STRUCT *ads) { BOOL ret = False; TALLOC_CTX *ctx = NULL; - const char *gidnumber, *uidnumber, *homedir, *shell; + const char *gidnumber, *uidnumber, *homedir, *shell, *gecos; ctx = talloc_init("ads_check_sfu_mapping"); if (ctx == NULL) @@ -2654,6 +2654,11 @@ BOOL ads_check_sfu_mapping(ADS_STRUCT *ads) goto done; ads->schema.sfu_shell_attr = SMB_STRDUP(shell); + gecos = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_GECOS_OID); + if (gecos == NULL) + goto done; + ads->schema.sfu_gecos_attr = SMB_STRDUP(gecos); + ret = True; done: if (ctx) -- cgit From c2288e6db34207948413411764175990f563168e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 7 Mar 2006 16:06:26 +0000 Subject: r13951: Fix Coverity Bug #163. This code was not used anyway :-) Volker (This used to be commit bbfb20569380529d60e3c61cd0be63a09eecfd17) --- source3/libads/ldap.c | 28 ---------------------------- 1 file changed, 28 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index cb7dbc575b..26b86f64d1 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -823,34 +823,6 @@ char *ads_get_dn_canonical(ADS_STRUCT *ads, void *msg) #endif } - -/** - * Get the parent dn from a search result - * @param ads connection to ads server - * @param msg Search result - * @return parent dn string - **/ -char *ads_get_parent_dn(ADS_STRUCT *ads, void *msg) -{ - char *mydn, *p, *dn; - - dn = ads_get_dn(ads, msg); - if (dn == NULL) { - return NULL; - } - - mydn = dn; - ads_memfree(ads, dn); - - p = strchr(mydn, ','); - - if (p == NULL) { - return NULL; - } - - return p+1; -} - /** * Get the parent from a dn * @param dn the dn to return the parent from -- cgit From 3432273ab0f647e60960152514c1df87093614af Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 7 Mar 2006 16:56:31 +0000 Subject: r13965: Make sure we always reset the userAccountControl bits when re-joining with an existing account. Guenther (This used to be commit e4c12ab167ee83772a2bdd1946b8d73613fc0d7e) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 26b86f64d1..babbabdd80 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1526,9 +1526,9 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name if (!exists) { ads_mod_str(ctx, &mods, "cn", machine_name); ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); - ads_mod_str(ctx, &mods, "userAccountControl", controlstr); ads_mod_strlist(ctx, &mods, "objectClass", objectClass); } + ads_mod_str(ctx, &mods, "userAccountControl", controlstr); ads_mod_str(ctx, &mods, "dNSHostName", my_fqdn); ads_mod_str(ctx, &mods, "userPrincipalName", host_upn); ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); -- cgit From acf0c6fb66b4182a0e5e7610d5063649ca237311 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 9 Mar 2006 22:49:38 +0000 Subject: r14118: Fix coverity bug #24. Missing return statement meant a possible NULL ptr deref. Jeremy. (This used to be commit 78ac3f9cbdabc1df9480f75fb3910a3a108a0e91) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index babbabdd80..dd49c706f4 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2692,7 +2692,7 @@ ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * asprintf(&expr, "(&(objectclass=computer)(dnshostname=%s.%s))", ads->config.ldap_server_name, ads->config.realm); if (expr == NULL) { - ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } rc = ads_search(ads, &res, expr, attrs); -- cgit From 06f7ee5d4b9d2f94c0178a0c979f50fa2f96b905 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Sun, 12 Mar 2006 19:56:10 +0000 Subject: r14252: Fix Coverity #72: free alloc'ed storage before return. Also found one more that coverity didn't find from asprintf. (This used to be commit 37b6e2c8de41754a5a1a3a6f798d57aa5d533ada) --- source3/libads/ldap.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index dd49c706f4..e1cea533a0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1914,7 +1914,10 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) * we have to bail out before prs_init */ ps_wire.is_dynamic = False; - if (!ads) return ADS_ERROR(LDAP_SERVER_DOWN); + if (!ads) { + SAFE_FREE(escaped_hostname); + return ADS_ERROR(LDAP_SERVER_DOWN); + } ret = ADS_ERROR(LDAP_SUCCESS); @@ -1932,6 +1935,8 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) ret = ads_search(ads, (void *) &res, expr, attrs); + SAFE_FREE(expr); + if (!ADS_ERR_OK(ret)) return ret; if ( !(msg = ads_first_entry(ads, res) )) { -- cgit From 92f139d4c4c7a07dd199b09b24bfc162eb1ab6bf Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 6 Apr 2006 01:46:01 +0000 Subject: r14931: Fix #1374: can't join an OU with name that contains '#' I had to eliminate "\" as an OU path separator, because it is the escape char in LDAP. We still accept "/", but using the escape char is just not a good choice. (This used to be commit 1953f63903e64e0a33eb981c51b8ca4beb673af2) --- source3/libads/ldap.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e1cea533a0..c2ebf14d2f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1083,7 +1083,8 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) /** * Build an org unit string * if org unit is Computers or blank then assume a container, otherwise - * assume a \ separated list of organisational units + * assume a / separated list of organisational units. + * jmcd: '\' is now used for escapes so certain chars can be in the ou (e.g. #) * @param ads connection to ads server * @param org_unit Organizational unit * @return org unit string - caller must free @@ -1104,7 +1105,10 @@ char *ads_ou_string(ADS_STRUCT *ads, const char *org_unit) return SMB_STRDUP("cn=Computers"); } - return ads_build_path(org_unit, "\\/", "ou=", 1); + /* jmcd: removed "\\" from the separation chars, because it is + needed as an escape for chars like '#' which are valid in an + OU name */ + return ads_build_path(org_unit, "/", "ou=", 1); } /** -- cgit From b86c19795aadd45527694e6002cdd806e928cf38 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 25 Apr 2006 20:13:05 +0000 Subject: r15250: dump some more sids. Guenther (This used to be commit 2922c7f5704e3cfcc80dc648bb3d6d9aa80aaf37) --- source3/libads/ldap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c2ebf14d2f..81aa9051d7 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1665,6 +1665,8 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) {"dnsRecord", False, dump_binary}, {"objectSid", False, dump_sid}, {"tokenGroups", False, dump_sid}, + {"tokenGroupsNoGCAcceptable", False, dump_sid}, + {"tokengroupsGlobalandUniversal", False, dump_sid}, {NULL, True, NULL} }; int i; -- cgit From 3bff11407e721a4a01b67881862d2a466ec5d103 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 5 May 2006 15:54:11 +0000 Subject: r15461: Free LDAP result in ads_get_attrname_by_oid(). Guenther (This used to be commit f4af888282ff39665f186550b9ccbbf7a9128fc2) --- source3/libads/ldap.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 81aa9051d7..a8877b5697 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2471,6 +2471,7 @@ const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const void *res = NULL; char *expr = NULL; const char *attrs[] = { "lDAPDisplayName", NULL }; + char *result; if (ads == NULL || mem_ctx == NULL || OID == NULL) { goto failed; @@ -2492,12 +2493,16 @@ const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const goto failed; } - return ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName"); + result = ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName"); + ads_msgfree(ads, res); + + return result; failed: DEBUG(0,("ads_get_attrname_by_oid: failed to retrieve name for oid: %s\n", OID)); + ads_msgfree(ads, res); return NULL; } -- cgit From 2c029a8b96ae476f1d5c2abe14ee25f98a1513d8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 12 May 2006 15:17:35 +0000 Subject: r15543: New implementation of 'net ads join' to be more like Windows XP. The motivating factor is to not require more privileges for the user account than Windows does when joining a domain. The points of interest are * net_ads_join() uses same rpc mechanisms as net_rpc_join() * Enable CLDAP queries for filling in the majority of the ADS_STRUCT->config information * Remove ldap_initialized() from sam/idmap_ad.c and libads/ldap.c * Remove some unnecessary fields from ADS_STRUCT * Manually set the dNSHostName and servicePrincipalName attribute using the machine account after the join Thanks to Guenther and Simo for the review. Still to do: * Fix the userAccountControl for DES only systems * Set the userPrincipalName in order to support things like 'kinit -k' (although we might be able to just use the sAMAccountName instead) * Re-add support for pre-creating the machine account in a specific OU (This used to be commit 4c4ea7b20f44cd200cef8c7b389d51b72eccc39b) --- source3/libads/ldap.c | 363 ++++++++++++++++++++++---------------------------- 1 file changed, 160 insertions(+), 203 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a8877b5697..6f698dc3a9 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -112,31 +112,52 @@ static int ldap_search_with_timeout(LDAP *ld, /* try a connection to a given ldap server, returning True and setting the servers IP in the ads struct if successful - - TODO : add a negative connection cache in here leveraged off of the one - found in the rpc code. --jerry */ -BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) +BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) { char *srv; + struct cldap_netlogon_reply cldap_reply; if (!server || !*server) { return False; } - - DEBUG(5,("ads_try_connect: trying ldap server '%s' port %u\n", server, port)); + + DEBUG(5,("ads_try_connect: sending CLDAP request to %s\n", server)); /* this copes with inet_ntoa brokenness */ + srv = SMB_STRDUP(server); - ads->ld = ldap_open_with_timeout(srv, port, lp_ldap_timeout()); - if (!ads->ld) { - free(srv); + ZERO_STRUCT( cldap_reply ); + + if ( !ads_cldap_netlogon( srv, ads->server.realm, &cldap_reply ) ) { + DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", srv)); return False; } - ads->ldap_port = port; + + /* Check the CLDAP reply flags */ + + if ( !(cldap_reply.flags & ADS_LDAP) ) { + DEBUG(1,("ads_try_connect: %s's CLDAP reply says it is not an LDAP server!\n", + srv)); + SAFE_FREE( srv ); + return False; + } + + /* Fill in the ads->config values */ + + SAFE_FREE(ads->config.realm); + SAFE_FREE(ads->config.bind_path); + SAFE_FREE(ads->config.ldap_server_name); + + ads->config.ldap_server_name = SMB_STRDUP(cldap_reply.hostname); + strupper_m(cldap_reply.domain); + ads->config.realm = SMB_STRDUP(cldap_reply.domain); + ads->config.bind_path = ads_build_dn(ads->config.realm); + + ads->ldap_port = LDAP_PORT; ads->ldap_ip = *interpret_addr2(srv); - free(srv); + SAFE_FREE(srv); /* cache the successful connection */ @@ -145,29 +166,6 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) return True; } -/* - try a connection to a given ldap server, based on URL, returning True if successful - */ -static BOOL ads_try_connect_uri(ADS_STRUCT *ads) -{ -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) - DEBUG(5,("ads_try_connect: trying ldap server at URI '%s'\n", - ads->server.ldap_uri)); - - - if (ldap_initialize((LDAP**)&(ads->ld), ads->server.ldap_uri) == LDAP_SUCCESS) { - return True; - } - DEBUG(0, ("ldap_initialize: %s\n", strerror(errno))); - -#else - - DEBUG(1, ("no URL support in LDAP libs!\n")); -#endif - - return False; -} - /********************************************************************** Try to find an AD dc using our internal name resolution routines Try the realm first and then then workgroup name if netbios is not @@ -233,8 +231,6 @@ again: /* if we fail this loop, then giveup since all the IP addresses returned were dead */ for ( i=0; ilast_attempt = time(NULL); ads->ld = NULL; - /* try with a URL based server */ - - if (ads->server.ldap_uri && - ads_try_connect_uri(ads)) { - goto got_connection; - } - /* try with a user specified server */ + if (ads->server.ldap_server && - ads_try_connect(ads, ads->server.ldap_server, LDAP_PORT)) { + ads_try_connect(ads, ads->server.ldap_server)) { goto got_connection; } @@ -292,22 +282,12 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) got_connection: DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap_ip))); - status = ads_server_info(ads); - if (!ADS_ERR_OK(status)) { - DEBUG(1,("Failed to get ldap server info\n")); - return status; - } - - ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); - - status = ADS_ERROR(smb_ldap_start_tls(ads->ld, version)); - if (!ADS_ERR_OK(status)) { - return status; - } - if (!ads->auth.user_name) { /* have to use the userPrincipalName value here and - not servicePrincipalName; found by Guenther Deschner @ Sernet */ + not servicePrincipalName; found by Guenther Deschner @ Sernet. + + Is this still correct? The comment does not match + the code. --jerry */ asprintf(&ads->auth.user_name, "host/%s", global_myname() ); } @@ -331,10 +311,35 @@ got_connection: } #endif + /* If the caller() requested no LDAP bind, then we are done */ + if (ads->auth.flags & ADS_AUTH_NO_BIND) { return ADS_SUCCESS; } + + /* Otherwise setup the TCP LDAP session */ + + if ( (ads->ld = ldap_open_with_timeout(ads->config.ldap_server_name, + LDAP_PORT, lp_ldap_timeout())) == NULL ) + { + return ADS_ERROR(LDAP_OPERATIONS_ERROR); + } + ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + + status = ADS_ERROR(smb_ldap_start_tls(ads->ld, version)); + if (!ADS_ERR_OK(status)) { + return status; + } + + /* fill in the current time and offsets */ + + status = ads_current_time( ads ); + if ( !ADS_ERR_OK(status) ) { + return status; + } + /* Now do the bind */ + if (ads->auth.flags & ADS_AUTH_ANON_BIND) { return ADS_ERROR(ldap_simple_bind_s( ads->ld, NULL, NULL)); } @@ -2464,7 +2469,7 @@ static time_t ads_parse_time(const char *str) } -const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char * OID) +const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, const char *schema_path, TALLOC_CTX *mem_ctx, const char * OID) { ADS_STATUS rc; int count = 0; @@ -2482,8 +2487,8 @@ const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const goto failed; } - rc = ads_do_search_retry(ads, ads->config.schema_path, - LDAP_SCOPE_SUBTREE, expr, attrs, &res); + rc = ads_do_search_retry(ads, schema_path, LDAP_SCOPE_SUBTREE, + expr, attrs, &res); if (!ADS_ERR_OK(rc)) { goto failed; } @@ -2513,97 +2518,94 @@ failed: * @param ads connection to ads server * @return status of search **/ -ADS_STATUS ads_server_info(ADS_STRUCT *ads) +ADS_STATUS ads_current_time(ADS_STRUCT *ads) { - const char *attrs[] = {"ldapServiceName", - "currentTime", - "schemaNamingContext", NULL}; + const char *attrs[] = {"currentTime", NULL}; ADS_STATUS status; void *res; - char *value; - char *p; char *timestr; - char *schema_path; TALLOC_CTX *ctx; + ADS_STRUCT *ads_s = ads; if (!(ctx = talloc_init("ads_server_info"))) { return ADS_ERROR(LDAP_NO_MEMORY); } - status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); - if (!ADS_ERR_OK(status)) { - talloc_destroy(ctx); - return status; - } + /* establish a new ldap tcp session if necessary */ - value = ads_pull_string(ads, ctx, res, "ldapServiceName"); - if (!value) { - ads_msgfree(ads, res); - talloc_destroy(ctx); - return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + if ( !ads->ld ) { + if ( (ads_s = ads_init( ads->server.realm, ads->server.workgroup, + ads->server.ldap_server )) == NULL ) + { + goto done; + } + ads_s->auth.flags = ADS_AUTH_ANON_BIND; + status = ads_connect( ads_s ); + if ( !ADS_ERR_OK(status)) + goto done; } - timestr = ads_pull_string(ads, ctx, res, "currentTime"); - if (!timestr) { - ads_msgfree(ads, res); + status = ads_do_search(ads_s, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) { talloc_destroy(ctx); - return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + goto done; } - schema_path = ads_pull_string(ads, ctx, res, "schemaNamingContext"); - if (!schema_path) { + timestr = ads_pull_string(ads_s, ctx, res, "currentTime"); + if (!timestr) { ads_msgfree(ads, res); talloc_destroy(ctx); - return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + status = ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + goto done; } - SAFE_FREE(ads->config.schema_path); - ads->config.schema_path = SMB_STRDUP(schema_path); - - ads_msgfree(ads, res); + /* but save the time and offset in the original ADS_STRUCT */ + + ads->config.current_time = ads_parse_time(timestr); - p = strchr(value, ':'); - if (!p) { - talloc_destroy(ctx); - DEBUG(1, ("ads_server_info: returned ldap server name did not contain a ':' " - "so was deemed invalid\n")); - return ADS_ERROR(LDAP_DECODING_ERROR); + if (ads->config.current_time != 0) { + ads->auth.time_offset = ads->config.current_time - time(NULL); + DEBUG(4,("time offset is %d seconds\n", ads->auth.time_offset)); } - SAFE_FREE(ads->config.ldap_server_name); + status = ADS_SUCCESS; - ads->config.ldap_server_name = SMB_STRDUP(p+1); - p = strchr(ads->config.ldap_server_name, '$'); - if (!p || p[1] != '@') { - talloc_destroy(ctx); - DEBUG(1, ("ads_server_info: returned ldap server name (%s) does not contain '$@'" - " so was deemed invalid\n", ads->config.ldap_server_name)); - SAFE_FREE(ads->config.ldap_server_name); - return ADS_ERROR(LDAP_DECODING_ERROR); +done: + /* free any temporary ads connections */ + if ( ads_s != ads ) { + ads_destroy( &ads_s ); } + talloc_destroy(ctx); - *p = 0; + return status; +} - SAFE_FREE(ads->config.realm); - SAFE_FREE(ads->config.bind_path); +/********************************************************************* +*********************************************************************/ - ads->config.realm = SMB_STRDUP(p+2); - ads->config.bind_path = ads_build_dn(ads->config.realm); +static ADS_STATUS ads_schema_path(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **schema_path) +{ + ADS_STATUS status; + void *res; + const char *schema; + const char *attrs[] = { "schemaNamingContext", NULL }; - DEBUG(3,("got ldap server name %s@%s, using bind path: %s\n", - ads->config.ldap_server_name, ads->config.realm, - ads->config.bind_path)); + status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) { + return status; + } - ads->config.current_time = ads_parse_time(timestr); + if ( (schema = ads_pull_string(ads, mem_ctx, res, "schemaNamingContext")) == NULL ) { + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } - if (ads->config.current_time != 0) { - ads->auth.time_offset = ads->config.current_time - time(NULL); - DEBUG(4,("time offset is %d seconds\n", ads->auth.time_offset)); + if ( (*schema_path = talloc_strdup(mem_ctx, schema)) == NULL ) { + return ADS_ERROR(LDAP_NO_MEMORY); } - talloc_destroy(ctx); + ads_msgfree(ads, res); - return ADS_SUCCESS; + return status; } /** @@ -2617,41 +2619,71 @@ BOOL ads_check_sfu_mapping(ADS_STRUCT *ads) BOOL ret = False; TALLOC_CTX *ctx = NULL; const char *gidnumber, *uidnumber, *homedir, *shell, *gecos; + char *schema_path; + ADS_STRUCT *ads_s = ads; + ADS_STATUS status; + + if ( (ctx = talloc_init("ads_check_sfu_mapping")) == NULL ) { + goto done; + } + + /* establish a new ldap tcp session if necessary */ - ctx = talloc_init("ads_check_sfu_mapping"); - if (ctx == NULL) + if ( !ads->ld ) { + if ( (ads_s = ads_init( ads->server.realm, ads->server.workgroup, + ads->server.ldap_server )) == NULL ) + { + goto done; + } + + ads_s->auth.flags = ADS_AUTH_ANON_BIND; + status = ads_connect( ads_s ); + if ( !ADS_ERR_OK(status)) + goto done; + } + + status = ads_schema_path( ads, ctx, &schema_path ); + if ( !ADS_ERR_OK(status) ) { + DEBUG(3,("ads_check_sfu_mapping: Unable to retrieve schema DN!\n")); goto done; + } - gidnumber = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_GIDNUMBER_OID); + gidnumber = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_GIDNUMBER_OID); if (gidnumber == NULL) goto done; ads->schema.sfu_gidnumber_attr = SMB_STRDUP(gidnumber); - uidnumber = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_UIDNUMBER_OID); + uidnumber = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_UIDNUMBER_OID); if (uidnumber == NULL) goto done; ads->schema.sfu_uidnumber_attr = SMB_STRDUP(uidnumber); - homedir = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_HOMEDIR_OID); + homedir = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_HOMEDIR_OID); if (homedir == NULL) goto done; ads->schema.sfu_homedir_attr = SMB_STRDUP(homedir); - shell = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_SHELL_OID); + shell = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_SHELL_OID); if (shell == NULL) goto done; ads->schema.sfu_shell_attr = SMB_STRDUP(shell); - gecos = ads_get_attrname_by_oid(ads, ctx, ADS_ATTR_SFU_GECOS_OID); + gecos = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_GECOS_OID); if (gecos == NULL) goto done; ads->schema.sfu_gecos_attr = SMB_STRDUP(gecos); ret = True; done: - if (ctx) + /* free any temporary ads connections */ + if ( ads_s != ads ) { + ads_destroy( &ads_s ); + } + + if (ctx) { talloc_destroy(ctx); - + } + return ret; } @@ -2679,81 +2711,6 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) return ADS_SUCCESS; } -/* this is rather complex - we need to find the allternate (netbios) name - for the domain, but there isn't a simple query to do this. Instead - we look for the principle names on the DCs account and find one that has - the right form, then extract the netbios name of the domain from that - - NOTE! better method is this: - -bin/net -Uadministrator%XXXXX ads search '(&(objectclass=crossref)(dnsroot=VNET3.HOME.SAMBA.ORG))' nETBIOSName - -but you need to force the bind path to match the configurationNamingContext from the rootDSE - -*/ -ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **workgroup) -{ - char *expr; - ADS_STATUS rc; - char **principles; - char *prefix; - int prefix_length; - int i; - void *res; - const char *attrs[] = {"servicePrincipalName", NULL}; - size_t num_principals; - - (*workgroup) = NULL; - - asprintf(&expr, "(&(objectclass=computer)(dnshostname=%s.%s))", - ads->config.ldap_server_name, ads->config.realm); - if (expr == NULL) { - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - } - - rc = ads_search(ads, &res, expr, attrs); - free(expr); - - if (!ADS_ERR_OK(rc)) { - return rc; - } - - principles = ads_pull_strings(ads, mem_ctx, res, - "servicePrincipalName", &num_principals); - - ads_msgfree(ads, res); - - if (!principles) { - return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); - } - - asprintf(&prefix, "HOST/%s.%s/", - ads->config.ldap_server_name, - ads->config.realm); - - prefix_length = strlen(prefix); - - for (i=0;principles[i]; i++) { - if (strnequal(principles[i], prefix, prefix_length) && - !strequal(ads->config.realm, principles[i]+prefix_length) && - !strchr(principles[i]+prefix_length, '.')) { - /* found an alternate (short) name for the domain. */ - DEBUG(3,("Found alternate name '%s' for realm '%s'\n", - principles[i]+prefix_length, - ads->config.realm)); - (*workgroup) = talloc_strdup(mem_ctx, principles[i]+prefix_length); - break; - } - } - free(prefix); - - if (!*workgroup) { - return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); - } - - return ADS_SUCCESS; -} - /** * find our site name * @param ads connection to ads server -- cgit From f1039b8fb461c6e1276dba8564f62ec1496a7b88 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 13 May 2006 04:39:19 +0000 Subject: r15560: Since the hotel doesn't have Sci-Fi and no "Doctor Who".... Re-add the capability to specify an OU in which to create the machine account. Done via LDAP prior to the RPC join. (This used to be commit b69ac0e30441faea7a7d677b6bb551aa8ffbf55d) --- source3/libads/ldap.c | 196 +++++++------------------------------------------- 1 file changed, 25 insertions(+), 171 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6f698dc3a9..63056645cd 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -980,6 +980,7 @@ ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, name, (const void **) vals); } +#if 0 /** * Add a single ber-encoded value to a mod list * @param ctx An initialized TALLOC_CTX @@ -1000,6 +1001,7 @@ static ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE|LDAP_MOD_BVALUES, name, (const void **) values); } +#endif /** * Perform an ldap modify @@ -1421,105 +1423,33 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n * @return 0 upon success, or non-zero otherwise **/ -static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name, - uint32 account_type, - const char *org_unit) +ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, + const char *org_unit) { - ADS_STATUS ret, status; - char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr; + ADS_STATUS ret; + char *samAccountName, *controlstr; TALLOC_CTX *ctx; ADS_MODLIST mods; + char *new_dn; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; - const char *servicePrincipalName[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; - char *psp, *psp2, *psp3, *psp4; - unsigned acct_control; - unsigned exists=0; - fstring my_fqdn; LDAPMessage *res = NULL; - int i, next_spn; - + uint32 acct_control = ( UF_WORKSTATION_TRUST_ACCOUNT |\ + UF_DONT_EXPIRE_PASSWD |\ + UF_ACCOUNTDISABLE ); + if (!(ctx = talloc_init("ads_add_machine_acct"))) return ADS_ERROR(LDAP_NO_MEMORY); ret = ADS_ERROR(LDAP_NO_MEMORY); + + new_dn = talloc_asprintf(ctx, "cn=%s,%s", machine_name, org_unit); + samAccountName = talloc_asprintf(ctx, "%s$", machine_name); - name_to_fqdn(my_fqdn, machine_name); - - status = ads_find_machine_acct(ads, (void **)(void *)&res, machine_name); - if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { - char *dn_string = ads_get_dn(ads, res); - if (!dn_string) { - DEBUG(1, ("ads_add_machine_acct: ads_get_dn returned NULL (malloc failure?)\n")); - goto done; - } - new_dn = talloc_strdup(ctx, dn_string); - ads_memfree(ads,dn_string); - DEBUG(0, ("ads_add_machine_acct: Host account for %s already exists - modifying old account\n", - machine_name)); - exists=1; - } else { - char *ou_str = ads_ou_string(ads,org_unit); - if (!ou_str) { - DEBUG(1, ("ads_add_machine_acct: ads_ou_string returned NULL (malloc failure?)\n")); - goto done; - } - new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", machine_name, ou_str, - ads->config.bind_path); - - SAFE_FREE(ou_str); - } - - if (!new_dn) { - goto done; - } - - if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", machine_name))) - goto done; - if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) - goto done; - servicePrincipalName[0] = talloc_asprintf(ctx, "HOST/%s", machine_name); - psp = talloc_asprintf(ctx, "HOST/%s.%s", - machine_name, - ads->config.realm); - strlower_m(&psp[5]); - servicePrincipalName[1] = psp; - servicePrincipalName[2] = talloc_asprintf(ctx, "CIFS/%s", machine_name); - psp2 = talloc_asprintf(ctx, "CIFS/%s.%s", - machine_name, - ads->config.realm); - strlower_m(&psp2[5]); - servicePrincipalName[3] = psp2; - - /* Ensure servicePrincipalName[4] and [5] are unique. */ - strlower_m(my_fqdn); - psp3 = talloc_asprintf(ctx, "CIFS/%s", my_fqdn); - strlower_m(&psp3[5]); - - next_spn = 4; - for (i = 0; i < next_spn; i++) { - if (strequal(servicePrincipalName[i], psp3)) - break; - } - if (i == next_spn) { - servicePrincipalName[next_spn++] = psp3; - } - - psp4 = talloc_asprintf(ctx, "HOST/%s", my_fqdn); - strlower_m(&psp4[5]); - for (i = 0; i < next_spn; i++) { - if (strequal(servicePrincipalName[i], psp4)) - break; - } - if (i == next_spn) { - servicePrincipalName[next_spn++] = psp4; - } - - if (!(samAccountName = talloc_asprintf(ctx, "%s$", machine_name))) { + if ( !new_dn || !samAccountName ) { goto done; } - - acct_control = account_type | UF_DONT_EXPIRE_PASSWD; + #ifndef ENCTYPE_ARCFOUR_HMAC acct_control |= UF_USE_DES_KEY_ONLY; #endif @@ -1531,44 +1461,18 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name if (!(mods = ads_init_mods(ctx))) { goto done; } - - if (!exists) { - ads_mod_str(ctx, &mods, "cn", machine_name); - ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); - ads_mod_strlist(ctx, &mods, "objectClass", objectClass); - } + + ads_mod_str(ctx, &mods, "cn", machine_name); + ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); + ads_mod_strlist(ctx, &mods, "objectClass", objectClass); ads_mod_str(ctx, &mods, "userAccountControl", controlstr); - ads_mod_str(ctx, &mods, "dNSHostName", my_fqdn); - ads_mod_str(ctx, &mods, "userPrincipalName", host_upn); - ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); - ads_mod_str(ctx, &mods, "operatingSystem", "Samba"); - ads_mod_str(ctx, &mods, "operatingSystemVersion", SAMBA_VERSION_STRING); - - if (!exists) { - ret = ads_gen_add(ads, new_dn, mods); - } else { - ret = ads_gen_mod(ads, new_dn, mods); - } - if (!ADS_ERR_OK(ret)) { - goto done; - } + ret = ads_gen_add(ads, new_dn, mods); - /* Do not fail if we can't set security descriptor - * it shouldn't be mandatory and probably we just - * don't have enough rights to do it. - */ - if (!exists) { - status = ads_set_machine_sd(ads, machine_name, new_dn); - - if (!ADS_ERR_OK(status)) { - DEBUG(0, ("Warning: ads_set_machine_sd: %s\n", - ads_errstr(status))); - } - } done: ads_msgfree(ads, res); talloc_destroy(ctx); + return ret; } @@ -1783,58 +1687,6 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) return ldap_count_entries(ads->ld, (LDAPMessage *)res); } -/** - * Join a machine to a realm - * Creates the machine account and sets the machine password - * @param ads connection to ads server - * @param machine name of host to add - * @param org_unit Organizational unit to place machine in - * @return status of join - **/ -ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, - uint32 account_type, const char *org_unit) -{ - ADS_STATUS status; - LDAPMessage *res = NULL; - char *machine; - - /* machine name must be lowercase */ - machine = SMB_STRDUP(machine_name); - strlower_m(machine); - - /* - status = ads_find_machine_acct(ads, (void **)&res, machine); - if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { - DEBUG(0, ("Host account for %s already exists - deleting old account\n", machine)); - status = ads_leave_realm(ads, machine); - if (!ADS_ERR_OK(status)) { - DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n", - machine, ads->config.realm)); - return status; - } - } - */ - - status = ads_add_machine_acct(ads, machine, account_type, org_unit); - if (!ADS_ERR_OK(status)) { - DEBUG(0, ("ads_join_realm: ads_add_machine_acct failed (%s): %s\n", machine, ads_errstr(status))); - SAFE_FREE(machine); - return status; - } - - status = ads_find_machine_acct(ads, (void **)(void *)&res, machine); - if (!ADS_ERR_OK(status)) { - DEBUG(0, ("ads_join_realm: Host account test failed for machine %s\n", machine)); - SAFE_FREE(machine); - return status; - } - - SAFE_FREE(machine); - ads_msgfree(ads, res); - - return status; -} - /** * Delete a machine from the realm * @param ads connection to ads server @@ -1895,6 +1747,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return status; } +#if 0 /** * add machine account to existing security descriptor * @param ads connection to ads server @@ -1902,7 +1755,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) * @param dn DN of security descriptor * @return status **/ -ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) +static ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) { const char *attrs[] = {"nTSecurityDescriptor", "objectSid", 0}; char *expr = 0; @@ -2016,6 +1869,7 @@ ads_set_sd_error: talloc_destroy(ctx); return ret; } +#endif /** * pull the first entry from a ADS result -- cgit From c290d34985830c343b19cc4ffde33ff3e67272d5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 16 May 2006 15:14:39 +0000 Subject: r15635: Fix a bogus gcc uninit variable message (This used to be commit 53f7104b4fbb4f59c18458f589e25e7b536642cb) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 63056645cd..5f0e296a04 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2473,7 +2473,7 @@ BOOL ads_check_sfu_mapping(ADS_STRUCT *ads) BOOL ret = False; TALLOC_CTX *ctx = NULL; const char *gidnumber, *uidnumber, *homedir, *shell, *gecos; - char *schema_path; + char *schema_path = NULL; ADS_STRUCT *ads_s = ads; ADS_STATUS status; -- cgit From e129dc40f71e9b10c293d8d3f923c5636597bf6f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 18 May 2006 15:08:09 +0000 Subject: r15696: Free LDAP search result. Guenther (This used to be commit ec26c355b3ef1d3d809c4fbe911ce6fcef5db955) --- source3/libads/ldap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 5f0e296a04..b208e58504 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2422,6 +2422,8 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads) DEBUG(4,("time offset is %d seconds\n", ads->auth.time_offset)); } + ads_msgfree(ads, res); + status = ADS_SUCCESS; done: -- cgit From 39c45ce4f1a0cce9dc23e6d8df3f93bb124a19a0 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 18 May 2006 16:08:28 +0000 Subject: r15697: I take no comments as no objections :) Expand the "winbind nss info" to also take "rfc2307" to support the plain posix attributes LDAP schema from win2k3-r2. This work is based on patches from Howard Wilkinson and Bob Gautier (and closes bug #3345). Guenther (This used to be commit 52423e01dc209ba5abde808a446287714ed11567) --- source3/libads/ldap.c | 150 -------------------------------------------------- 1 file changed, 150 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b208e58504..4a14527a22 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2322,49 +2322,6 @@ static time_t ads_parse_time(const char *str) return timegm(&tm); } - -const char *ads_get_attrname_by_oid(ADS_STRUCT *ads, const char *schema_path, TALLOC_CTX *mem_ctx, const char * OID) -{ - ADS_STATUS rc; - int count = 0; - void *res = NULL; - char *expr = NULL; - const char *attrs[] = { "lDAPDisplayName", NULL }; - char *result; - - if (ads == NULL || mem_ctx == NULL || OID == NULL) { - goto failed; - } - - expr = talloc_asprintf(mem_ctx, "(attributeId=%s)", OID); - if (expr == NULL) { - goto failed; - } - - rc = ads_do_search_retry(ads, schema_path, LDAP_SCOPE_SUBTREE, - expr, attrs, &res); - if (!ADS_ERR_OK(rc)) { - goto failed; - } - - count = ads_count_replies(ads, res); - if (count == 0 || !res) { - goto failed; - } - - result = ads_pull_string(ads, mem_ctx, res, "lDAPDisplayName"); - ads_msgfree(ads, res); - - return result; - -failed: - DEBUG(0,("ads_get_attrname_by_oid: failed to retrieve name for oid: %s\n", - OID)); - - ads_msgfree(ads, res); - return NULL; -} - /** * Find the servers name and realm - this can be done before authentication * The ldapServiceName field on w2k looks like this: @@ -2436,113 +2393,6 @@ done: return status; } -/********************************************************************* -*********************************************************************/ - -static ADS_STATUS ads_schema_path(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **schema_path) -{ - ADS_STATUS status; - void *res; - const char *schema; - const char *attrs[] = { "schemaNamingContext", NULL }; - - status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); - if (!ADS_ERR_OK(status)) { - return status; - } - - if ( (schema = ads_pull_string(ads, mem_ctx, res, "schemaNamingContext")) == NULL ) { - return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); - } - - if ( (*schema_path = talloc_strdup(mem_ctx, schema)) == NULL ) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - ads_msgfree(ads, res); - - return status; -} - -/** - * Check for "Services for Unix"-Schema and load some attributes into the ADS_STRUCT - * @param ads connection to ads server - * @return BOOL status of search (False if one or more attributes couldn't be - * found in Active Directory) - **/ -BOOL ads_check_sfu_mapping(ADS_STRUCT *ads) -{ - BOOL ret = False; - TALLOC_CTX *ctx = NULL; - const char *gidnumber, *uidnumber, *homedir, *shell, *gecos; - char *schema_path = NULL; - ADS_STRUCT *ads_s = ads; - ADS_STATUS status; - - if ( (ctx = talloc_init("ads_check_sfu_mapping")) == NULL ) { - goto done; - } - - /* establish a new ldap tcp session if necessary */ - - if ( !ads->ld ) { - if ( (ads_s = ads_init( ads->server.realm, ads->server.workgroup, - ads->server.ldap_server )) == NULL ) - { - goto done; - } - - ads_s->auth.flags = ADS_AUTH_ANON_BIND; - status = ads_connect( ads_s ); - if ( !ADS_ERR_OK(status)) - goto done; - } - - status = ads_schema_path( ads, ctx, &schema_path ); - if ( !ADS_ERR_OK(status) ) { - DEBUG(3,("ads_check_sfu_mapping: Unable to retrieve schema DN!\n")); - goto done; - } - - gidnumber = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_GIDNUMBER_OID); - if (gidnumber == NULL) - goto done; - ads->schema.sfu_gidnumber_attr = SMB_STRDUP(gidnumber); - - uidnumber = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_UIDNUMBER_OID); - if (uidnumber == NULL) - goto done; - ads->schema.sfu_uidnumber_attr = SMB_STRDUP(uidnumber); - - homedir = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_HOMEDIR_OID); - if (homedir == NULL) - goto done; - ads->schema.sfu_homedir_attr = SMB_STRDUP(homedir); - - shell = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_SHELL_OID); - if (shell == NULL) - goto done; - ads->schema.sfu_shell_attr = SMB_STRDUP(shell); - - gecos = ads_get_attrname_by_oid(ads_s, schema_path, ctx, ADS_ATTR_SFU_GECOS_OID); - if (gecos == NULL) - goto done; - ads->schema.sfu_gecos_attr = SMB_STRDUP(gecos); - - ret = True; -done: - /* free any temporary ads connections */ - if ( ads_s != ads ) { - ads_destroy( &ads_s ); - } - - if (ctx) { - talloc_destroy(ctx); - } - - return ret; -} - /** * find the domain sid for our domain * @param ads connection to ads server -- cgit From c60e96c392df858dd22d39d27513486c5c18c3d2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 18 May 2006 19:34:25 +0000 Subject: r15698: An attempt to make the winbind lookup_usergroups() call in security=ads more scalable: The most efficient way is to use the "tokenGroups" attribute which gives the nested group membership. As this attribute can not always be retrieved when binding with the machine account (the only garanteed way to get the tokenGroups I could find is when the machine account is a member of the "Pre Win2k Access" builtin group). Our current fallback when "tokenGroups" failed is looking for all groups where the userdn was in the "member" attribute. This behaves not very well in very large AD domains. The patch first tries the "memberOf" attribute on the user's dn in that case and directly retrieves the group's sids by using the LDAP Extended DN control from the user's object. The way to pass down the control to the ldap search call is rather painfull and probably will be rearranged later on. Successfully tested on win2k sp0, win2k sp4, wink3 sp1 and win2k3 r2. Guenther (This used to be commit 7d766b5505e4099ef7dd4e88bb000ebe38d71bd0) --- source3/libads/ldap.c | 220 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 204 insertions(+), 16 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 4a14527a22..293163c05e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -445,21 +445,25 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) * @param cookie The paged results cookie to be returned on subsequent calls * @return status of search **/ -ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *expr, - const char **attrs, void **res, - int *count, void **cookie) +ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *expr, + const char **attrs, void *args, void **res, + int *count, void **cookie) { int rc, i, version; char *utf8_expr, *utf8_path, **search_attrs; - LDAPControl PagedResults, NoReferrals, *controls[3], **rcontrols; + LDAPControl PagedResults, NoReferrals, ExtendedDn, *controls[4], **rcontrols; BerElement *cookie_be = NULL; struct berval *cookie_bv= NULL; + BerElement *extdn_be = NULL; + struct berval *extdn_bv= NULL; + TALLOC_CTX *ctx; + ads_control *external_control = (ads_control *) args; *res = NULL; - if (!(ctx = talloc_init("ads_do_paged_search"))) + if (!(ctx = talloc_init("ads_do_paged_search_args"))) return ADS_ERROR(LDAP_NO_MEMORY); /* 0 means the conversion worked but the result was empty @@ -509,10 +513,47 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, NoReferrals.ldctl_value.bv_len = 0; NoReferrals.ldctl_value.bv_val = CONST_DISCARD(char *, ""); + if (external_control && strequal(external_control->control, ADS_EXTENDED_DN_OID)) { + + ExtendedDn.ldctl_oid = CONST_DISCARD(char *, external_control->control); + ExtendedDn.ldctl_iscritical = (char) external_control->critical; + + /* win2k does not accept a ldctl_value beeing passed in */ + + if (external_control->val != 0) { + + if ((extdn_be = ber_alloc_t(LBER_USE_DER)) == NULL ) { + rc = LDAP_NO_MEMORY; + goto done; + } + + if ((ber_printf(extdn_be, "{i}", (ber_int_t) external_control->val)) == -1) { + rc = LDAP_NO_MEMORY; + goto done; + } + if ((ber_flatten(extdn_be, &extdn_bv)) == -1) { + rc = LDAP_NO_MEMORY; + goto done; + } + + ExtendedDn.ldctl_value.bv_len = extdn_bv->bv_len; + ExtendedDn.ldctl_value.bv_val = extdn_bv->bv_val; + + } else { + ExtendedDn.ldctl_value.bv_len = 0; + ExtendedDn.ldctl_value.bv_val = CONST_DISCARD(char *, ""); + } - controls[0] = &NoReferrals; - controls[1] = &PagedResults; - controls[2] = NULL; + controls[0] = &NoReferrals; + controls[1] = &PagedResults; + controls[2] = &ExtendedDn; + controls[3] = NULL; + + } else { + controls[0] = &NoReferrals; + controls[1] = &PagedResults; + controls[2] = NULL; + } /* we need to disable referrals as the openldap libs don't handle them and paged results at the same time. Using them @@ -533,7 +574,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, ber_bvfree(cookie_bv); if (rc) { - DEBUG(3,("ads_do_paged_search: ldap_search_with_timeout(%s) -> %s\n", expr, + DEBUG(3,("ads_do_paged_search_args: ldap_search_with_timeout(%s) -> %s\n", expr, ldap_err2string(rc))); goto done; } @@ -565,12 +606,29 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, done: talloc_destroy(ctx); + + if (extdn_be) { + ber_free(extdn_be, 1); + } + + if (extdn_bv) { + ber_bvfree(extdn_bv); + } + /* if/when we decide to utf8-encode attrs, take out this next line */ str_list_free(&search_attrs); return ADS_ERROR(rc); } +ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *expr, + const char **attrs, void **res, + int *count, void **cookie) +{ + return ads_do_paged_search_args(ads, bind_path, scope, expr, attrs, NULL, res, count, cookie); +} + /** * Get all results for a search. This uses ads_do_paged_search() to return @@ -583,16 +641,16 @@ done: * @param res ** which will contain results - free res* with ads_msgfree() * @return status of search **/ -ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *expr, - const char **attrs, void **res) +ADS_STATUS ads_do_search_all_args(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *expr, + const char **attrs, void *args, void **res) { void *cookie = NULL; int count = 0; ADS_STATUS status; *res = NULL; - status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, res, + status = ads_do_paged_search_args(ads, bind_path, scope, expr, attrs, args, res, &count, &cookie); if (!ADS_ERR_OK(status)) @@ -604,8 +662,8 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, ADS_STATUS status2; LDAPMessage *msg, *next; - status2 = ads_do_paged_search(ads, bind_path, scope, expr, - attrs, &res2, &count, &cookie); + status2 = ads_do_paged_search_args(ads, bind_path, scope, expr, + attrs, args, &res2, &count, &cookie); if (!ADS_ERR_OK(status2)) break; @@ -626,6 +684,13 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, return status; } +ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *expr, + const char **attrs, void **res) +{ + return ads_do_search_all_args(ads, bind_path, scope, expr, attrs, NULL, res); +} + /** * Run a function on all results for a search. Uses ads_do_paged_search() and * runs the function as each page is returned, using ads_process_results() @@ -2580,4 +2645,127 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **suffixe return status; } +/** + * pull a DOM_SID from an extended dn string + * @param mem_ctx TALLOC_CTX + * @param flags string type of extended_dn + * @param sid pointer to a DOM_SID + * @return boolean inidicating success + **/ +BOOL ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, + const char *dn, + enum ads_extended_dn_flags flags, + DOM_SID *sid) +{ + char *p, *q; + + if (!dn) { + return False; + } + + /* + * ADS_EXTENDED_DN_HEX_STRING: + * ;;CN=gd,OU=berlin,OU=suse,DC=ber,DC=suse,DC=de + * + * ADS_EXTENDED_DN_STRING (only with w2k3): + ;;CN=gd,OU=berlin,OU=suse,DC=ber,DC=suse,DC=de + */ + + p = strchr(dn, ';'); + if (!p) { + return False; + } + + if (strncmp(p, "; Date: Thu, 18 May 2006 20:12:45 +0000 Subject: r15701: change 'net ads leave' to disable the machine account in the domain (since removal implies greater permissions that Windows clients require) (This used to be commit ad1f947625612ef16adb69fc2cfeffc68a9a2e02) --- source3/libads/ldap.c | 184 -------------------------------------------------- 1 file changed, 184 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 293163c05e..3307ad83fe 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1752,190 +1752,6 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) return ldap_count_entries(ads->ld, (LDAPMessage *)res); } -/** - * Delete a machine from the realm - * @param ads connection to ads server - * @param hostname Machine to remove - * @return status of delete - **/ -ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) -{ - ADS_STATUS status; - void *res, *msg; - char *hostnameDN, *host; - int rc; - LDAPControl ldap_control; - LDAPControl * pldap_control[2] = {NULL, NULL}; - - pldap_control[0] = &ldap_control; - memset(&ldap_control, 0, sizeof(LDAPControl)); - ldap_control.ldctl_oid = (char *)LDAP_SERVER_TREE_DELETE_OID; - - /* hostname must be lowercase */ - host = SMB_STRDUP(hostname); - strlower_m(host); - - status = ads_find_machine_acct(ads, &res, host); - if (!ADS_ERR_OK(status)) { - DEBUG(0, ("Host account for %s does not exist.\n", host)); - return status; - } - - msg = ads_first_entry(ads, res); - if (!msg) { - return ADS_ERROR_SYSTEM(ENOENT); - } - - hostnameDN = ads_get_dn(ads, (LDAPMessage *)msg); - - - rc = ldap_delete_ext_s(ads->ld, hostnameDN, pldap_control, NULL); - if (rc) { - DEBUG(3,("ldap_delete_ext_s failed with error code %d\n", rc)); - }else { - DEBUG(3,("ldap_delete_ext_s succeeded with error code %d\n", rc)); - } - - ads_memfree(ads, hostnameDN); - if (rc != LDAP_SUCCESS) { - return ADS_ERROR(rc); - } - - status = ads_find_machine_acct(ads, &res, host); - if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { - DEBUG(0, ("Failed to remove host account.\n")); - return status; - } - - free(host); - - return status; -} - -#if 0 -/** - * add machine account to existing security descriptor - * @param ads connection to ads server - * @param hostname machine to add - * @param dn DN of security descriptor - * @return status - **/ -static ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) -{ - const char *attrs[] = {"nTSecurityDescriptor", "objectSid", 0}; - char *expr = 0; - size_t sd_size = 0; - struct berval bval = {0, NULL}; - prs_struct ps_wire; - char *escaped_hostname = escape_ldap_string_alloc(hostname); - - LDAPMessage *res = 0; - LDAPMessage *msg = 0; - ADS_MODLIST mods = 0; - - NTSTATUS status; - ADS_STATUS ret; - DOM_SID sid; - SEC_DESC *psd = NULL; - TALLOC_CTX *ctx = NULL; - - /* Avoid segmentation fault in prs_mem_free if - * we have to bail out before prs_init */ - ps_wire.is_dynamic = False; - - if (!ads) { - SAFE_FREE(escaped_hostname); - return ADS_ERROR(LDAP_SERVER_DOWN); - } - - ret = ADS_ERROR(LDAP_SUCCESS); - - if (!escaped_hostname) { - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - } - - if (asprintf(&expr, "(samAccountName=%s$)", escaped_hostname) == -1) { - DEBUG(1, ("ads_set_machine_sd: asprintf failed!\n")); - SAFE_FREE(escaped_hostname); - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - } - - SAFE_FREE(escaped_hostname); - - ret = ads_search(ads, (void *) &res, expr, attrs); - - SAFE_FREE(expr); - - if (!ADS_ERR_OK(ret)) return ret; - - if ( !(msg = ads_first_entry(ads, res) )) { - ret = ADS_ERROR(LDAP_NO_RESULTS_RETURNED); - goto ads_set_sd_error; - } - - if (!ads_pull_sid(ads, msg, attrs[1], &sid)) { - ret = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); - goto ads_set_sd_error; - } - - if (!(ctx = talloc_init("sec_io_desc"))) { - ret = ADS_ERROR(LDAP_NO_MEMORY); - goto ads_set_sd_error; - } - - if (!ads_pull_sd(ads, ctx, msg, attrs[0], &psd)) { - ret = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); - goto ads_set_sd_error; - } - - status = sec_desc_add_sid(ctx, &psd, &sid, SEC_RIGHTS_FULL_CTRL, &sd_size); - - if (!NT_STATUS_IS_OK(status)) { - ret = ADS_ERROR_NT(status); - goto ads_set_sd_error; - } - - if (!prs_init(&ps_wire, sd_size, ctx, MARSHALL)) { - ret = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - } - - if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1)) { - ret = ADS_ERROR(LDAP_NO_MEMORY); - goto ads_set_sd_error; - } - -#if 0 - file_save("/tmp/sec_desc.new", ps_wire.data_p, sd_size); -#endif - if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY); - - bval.bv_len = prs_offset(&ps_wire); - bval.bv_val = TALLOC(ctx, bval.bv_len); - if (!bval.bv_val) { - ret = ADS_ERROR(LDAP_NO_MEMORY); - goto ads_set_sd_error; - } - - prs_set_offset(&ps_wire, 0); - - if (!prs_copy_data_out(bval.bv_val, &ps_wire, bval.bv_len)) { - ret = ADS_ERROR(LDAP_NO_MEMORY); - goto ads_set_sd_error; - } - - ret = ads_mod_ber(ctx, &mods, attrs[0], &bval); - if (ADS_ERR_OK(ret)) { - ret = ads_gen_mod(ads, dn, mods); - } - -ads_set_sd_error: - ads_msgfree(ads, res); - prs_mem_free(&ps_wire); - talloc_destroy(ctx); - return ret; -} -#endif - /** * pull the first entry from a ADS result * @param ads connection to ads server -- cgit From ec3021dc3bca5901c70b377c6205c37ce63011df Mon Sep 17 00:00:00 2001 From: Lars Müller Date: Mon, 22 May 2006 20:35:55 +0000 Subject: r15822: Add suggestion made by Ralf Haferkamp. (This used to be commit 7c375fd540fa54ac8ae71c42ed07e01c593044b3) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 3307ad83fe..bac85f3222 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -541,7 +541,7 @@ ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, const char *bind_path, } else { ExtendedDn.ldctl_value.bv_len = 0; - ExtendedDn.ldctl_value.bv_val = CONST_DISCARD(char *, ""); + ExtendedDn.ldctl_value.bv_val = NULL; } controls[0] = &NoReferrals; -- cgit From 97f496a0e3e19a8d35f209d6896c2ebc4ccfb9db Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 9 Jun 2006 11:02:52 +0000 Subject: r16117: Make winbindd work again in security=ads. We still used the old HOST/* UPN to get e.g. users, now we need samaccountname$@REA.LM. Guenther (This used to be commit f6516a799aec2db819f79b9a1e641637422a9b4c) --- source3/libads/ldap.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index bac85f3222..7b8b41b10a 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -287,9 +287,13 @@ got_connection: not servicePrincipalName; found by Guenther Deschner @ Sernet. Is this still correct? The comment does not match - the code. --jerry */ + the code. --jerry + + Yes it is :) + - Guenther + */ - asprintf(&ads->auth.user_name, "host/%s", global_myname() ); + asprintf(&ads->auth.user_name, "%s$", global_myname() ); } if (!ads->auth.realm) { -- cgit From 1628d33ba0bb8b6cf7f5253c99b6aebcb304695f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 13 Jun 2006 13:41:04 +0000 Subject: r16190: Fix more memleaks. Guenther (This used to be commit dfebcc8e19bee06b7c03f88845314e9cfd6f398a) --- source3/libads/ldap.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7b8b41b10a..7fb5dac51b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1213,9 +1213,10 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) status = ads_search_dn(ads, &res, base, attrs); if (!ADS_ERR_OK(status)) { DEBUG(1,("Failed while searching for: %s\n", base)); + SAFE_FREE(base); return NULL; } - free(base); + SAFE_FREE(base); if (ads_count_replies(ads, res) != 1) { return NULL; @@ -1242,6 +1243,10 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) free(s); } + ads_memfree(ads, wkn_dn); + ldap_value_free(wkn_dn_exp); + ldap_value_free(bind_dn_exp); + return ret; } -- cgit From be6fd7643659406b6df986e1a96f7e9b87abfe20 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Jun 2006 23:14:12 +0000 Subject: r16322: Klocwork #481., Don't deref null on malloc fail. Jeremy. (This used to be commit dd31f3fc0e044fdae139aefcb21773249c30eb74) --- source3/libads/ldap.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7fb5dac51b..be15643ba2 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1956,8 +1956,10 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, return NULL; } - memcpy(&strings[*num_strings], new_strings, - sizeof(*new_strings) * num_new_strings); + if (new_strings && num_new_strings) { + memcpy(&strings[*num_strings], new_strings, + sizeof(*new_strings) * num_new_strings); + } (*num_strings) += num_new_strings; -- cgit From d730df0493ee8135cc2315aab3ffb1a0d3b5660a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Jun 2006 23:21:36 +0000 Subject: r16324: Klocwork #499. Allways check results from alloc. Jeremy. (This used to be commit 2b69d436da7b2902ea419f3bcc45c7b5a5c571fb) --- source3/libads/ldap.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index be15643ba2..13459ba40d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1430,16 +1430,28 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", my_fqdn))) { talloc_destroy(ctx); ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_SUCH_OBJECT); + return ADS_ERROR(LDAP_NO_MEMORY); } /* Add the extra principal */ psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name); + if (!psp1) { + talloc_destroy(ctx); + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + strupper_m(psp1); strlower_m(&psp1[strlen(spn)]); DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp1, machine_name)); servicePrincipalName[0] = psp1; psp2 = talloc_asprintf(ctx, "%s/%s.%s", spn, machine_name, ads->config.realm); + if (!psp2) { + talloc_destroy(ctx); + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + strupper_m(psp2); strlower_m(&psp2[strlen(spn)]); DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp2, machine_name)); @@ -1449,6 +1461,12 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n * the KDC doesn't send "server principal unknown" errors to clients * which use the DNS name in determining service principal names. */ psp3 = talloc_asprintf(ctx, "%s/%s", spn, my_fqdn); + if (!psp3) { + talloc_destroy(ctx); + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + strupper_m(psp3); strlower_m(&psp3[strlen(spn)]); if (strcmp(psp2, psp3) != 0) { -- cgit From 8961048d2450e01fd44d33d2c514775b071064e0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 18 Jun 2006 09:45:18 +0000 Subject: r16339: Fix Klocwork ID 277 278 (cmd_*) 485 487 488 (ldap.c) Volker (This used to be commit 5b1eba76b3ec5cb9b896a9a5641b4d83bdbdd4cf) --- source3/libads/ldap.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 13459ba40d..397d8c02f0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -904,7 +904,13 @@ char *ads_get_dn_canonical(ADS_STRUCT *ads, void *msg) **/ char *ads_parent_dn(const char *dn) { - char *p = strchr(dn, ','); + char *p; + + if (dn == NULL) { + return NULL; + } + + p = strchr(dn, ','); if (p == NULL) { return NULL; -- cgit From 8f0ea257b61f435060cfe6995e238c6d4b07de21 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 29 Jun 2006 17:11:14 +0000 Subject: r16685: Fix bug #3901 reported by jason@ncac.gwu.edu. Jeremy. (This used to be commit d48655d9c0b31d15327655140c021de29873d2c5) --- source3/libads/ldap.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 397d8c02f0..db2a51307a 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1408,7 +1408,7 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n ADS_STATUS ret; TALLOC_CTX *ctx; LDAPMessage *res = NULL; - char *host_spn, *psp1, *psp2, *psp3; + char *psp1, *psp2, *psp3; ADS_MODLIST mods; fstring my_fqdn; char *dn_string = NULL; @@ -1433,12 +1433,6 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n name_to_fqdn(my_fqdn, machine_name); strlower_m(my_fqdn); - if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", my_fqdn))) { - talloc_destroy(ctx); - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_MEMORY); - } - /* Add the extra principal */ psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name); if (!psp1) { -- cgit From 67d8c7432f116a0721b9bbff38632b8cc0535259 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 6 Jul 2006 13:38:41 +0000 Subject: r16836: When receiving a CLDAP reply make sure that we always store the correct netbios domain name in server affinity cache. Guenther (This used to be commit 08958411eeff430fb523d9b73e0259d060bac17b) --- source3/libads/ldap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index db2a51307a..ef4be210c6 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -149,18 +149,20 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) SAFE_FREE(ads->config.realm); SAFE_FREE(ads->config.bind_path); SAFE_FREE(ads->config.ldap_server_name); + SAFE_FREE(ads->server.workgroup); ads->config.ldap_server_name = SMB_STRDUP(cldap_reply.hostname); strupper_m(cldap_reply.domain); ads->config.realm = SMB_STRDUP(cldap_reply.domain); ads->config.bind_path = ads_build_dn(ads->config.realm); + ads->server.workgroup = SMB_STRDUP(cldap_reply.netbios_domain); ads->ldap_port = LDAP_PORT; ads->ldap_ip = *interpret_addr2(srv); SAFE_FREE(srv); /* cache the successful connection */ - + saf_store( ads->server.workgroup, server ); return True; -- cgit From f3e71c60727366eca0f5023c83c661c36512153d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 7 Jul 2006 11:43:47 +0000 Subject: r16861: Fixing crash bug when passing no domain/realm name to the CLDAP request. Guenther (This used to be commit 863aeb621afa7dcec1bfef8e503ef8ed363e3742) --- source3/libads/ldap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ef4be210c6..ebffd667eb 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -122,15 +122,16 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) return False; } - DEBUG(5,("ads_try_connect: sending CLDAP request to %s\n", server)); + DEBUG(5,("ads_try_connect: sending CLDAP request to %s (realm: %s)\n", + server, ads->config.realm)); /* this copes with inet_ntoa brokenness */ srv = SMB_STRDUP(server); ZERO_STRUCT( cldap_reply ); - - if ( !ads_cldap_netlogon( srv, ads->server.realm, &cldap_reply ) ) { + + if ( !ads_cldap_netlogon( srv, ads->config.realm, &cldap_reply ) ) { DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", srv)); return False; } -- cgit From 7048040be841c5abb295533ba3c0d70956fce476 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 7 Jul 2006 11:59:19 +0000 Subject: r16862: Reverting accidential changes in ads_try_connect() from previous commit. Guenther (This used to be commit 6257f9af93f2391940b2c60fe39c0bf106de15dd) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ebffd667eb..b017ff941b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -123,7 +123,7 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) } DEBUG(5,("ads_try_connect: sending CLDAP request to %s (realm: %s)\n", - server, ads->config.realm)); + server, ads->server.realm)); /* this copes with inet_ntoa brokenness */ @@ -131,7 +131,7 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) ZERO_STRUCT( cldap_reply ); - if ( !ads_cldap_netlogon( srv, ads->config.realm, &cldap_reply ) ) { + if ( !ads_cldap_netlogon( srv, ads->server.realm, &cldap_reply ) ) { DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", srv)); return False; } -- cgit From fbdcf2663b56007a438ac4f0d8d82436b1bfe688 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Jul 2006 18:01:26 +0000 Subject: r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need to do the upper layer directories but this is what everyone is waiting for.... Jeremy. (This used to be commit 9dafb7f48ca3e7af956b0a7d1720c2546fc4cfb8) --- source3/libads/ldap.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b017ff941b..58eca99f9e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -831,10 +831,11 @@ ADS_STATUS ads_search(ADS_STRUCT *ads, void **res, * @param attrs Attributes to retrieve * @return status of search **/ -ADS_STATUS ads_search_dn(ADS_STRUCT *ads, void **res, +ADS_STATUS ads_search_dn(ADS_STRUCT *ads, void *_res, const char *dn, const char **attrs) { + void **res = (void **)_res; return ads_do_search(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res); } @@ -973,8 +974,9 @@ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx) */ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, int mod_op, const char *name, - const void **invals) + const void *_invals) { + const void **invals = (const void **)_invals; int curmod; LDAPMod **modlist = (LDAPMod **) *mods; struct berval **ber_values = NULL; @@ -1037,8 +1039,7 @@ ADS_STATUS ads_mod_str(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (!val) return ads_modlist_add(ctx, mods, LDAP_MOD_DELETE, name, NULL); - return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, - (const void **) values); + return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE, name, values); } /** -- cgit From 060b155cd2f77e37086f97461f93e9ef1ff8dce2 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 11 Jul 2006 18:45:22 +0000 Subject: r16952: New derive DES salt code and Krb5 keytab generation Major points of interest: * Figure the DES salt based on the domain functional level and UPN (if present and applicable) * Only deal with the DES-CBC-MD5, DES-CBC-CRC, and RC4-HMAC keys * Remove all the case permutations in the keytab entry generation (to be partially re-added only if necessary). * Generate keytab entries based on the existing SPN values in AD The resulting keytab looks like: ktutil: list -e slot KVNO Principal ---- ---- --------------------------------------------------------------------- 1 6 host/suse10.plainjoe.org@COLOR.PLAINJOE.ORG (DES cbc mode with CRC-32) 2 6 host/suse10.plainjoe.org@COLOR.PLAINJOE.ORG (DES cbc mode with RSA-MD5) 3 6 host/suse10.plainjoe.org@COLOR.PLAINJOE.ORG (ArcFour with HMAC/md5) 4 6 host/suse10@COLOR.PLAINJOE.ORG (DES cbc mode with CRC-32) 5 6 host/suse10@COLOR.PLAINJOE.ORG (DES cbc mode with RSA-MD5) 6 6 host/suse10@COLOR.PLAINJOE.ORG (ArcFour with HMAC/md5) 7 6 suse10$@COLOR.PLAINJOE.ORG (DES cbc mode with CRC-32) 8 6 suse10$@COLOR.PLAINJOE.ORG (DES cbc mode with RSA-MD5) 9 6 suse10$@COLOR.PLAINJOE.ORG (ArcFour with HMAC/md5) The list entries are the two basic SPN values (host/NetBIOSName & host/dNSHostName) and the sAMAccountName value. The UPN will be added as well if the machine has one. This fixes 'kinit -k'. Tested keytab using mod_auth_krb and MIT's telnet. ads_verify_ticket() continues to work with RC4-HMAC and DES keys. (This used to be commit 6261dd3c67d10db6cfa2e77a8d304d3dce4050a4) --- source3/libads/ldap.c | 260 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 190 insertions(+), 70 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 58eca99f9e..a8ee770582 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -5,6 +5,7 @@ Copyright (C) Remus Koos 2001 Copyright (C) Jim McDonough 2002 Copyright (C) Guenther Deschner 2005 + Copyright (C) Gerald Carter 2006 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 @@ -286,15 +287,8 @@ got_connection: DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap_ip))); if (!ads->auth.user_name) { - /* have to use the userPrincipalName value here and - not servicePrincipalName; found by Guenther Deschner @ Sernet. - - Is this still correct? The comment does not match - the code. --jerry - - Yes it is :) - - Guenther - */ + /* Must use the userPrincipalName value here or sAMAccountName + and not servicePrincipalName; found by Guenther Deschner */ asprintf(&ads->auth.user_name, "%s$", global_myname() ); } @@ -1403,20 +1397,21 @@ ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machin * (found by hostname) in AD. * @param ads An initialized ADS_STRUCT * @param machine_name the NetBIOS name of the computer, which is used to identify the computer account. + * @param my_fqdn The fully qualified DNS name of the machine * @param spn A string of the service principal to add, i.e. 'host' * @return 0 upon sucess, or non-zero if a failure occurs **/ -ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_name, const char *spn) +ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_name, + const char *my_fqdn, const char *spn) { ADS_STATUS ret; TALLOC_CTX *ctx; LDAPMessage *res = NULL; - char *psp1, *psp2, *psp3; + char *psp1, *psp2; ADS_MODLIST mods; - fstring my_fqdn; char *dn_string = NULL; - const char *servicePrincipalName[4] = {NULL, NULL, NULL, NULL}; + const char *servicePrincipalName[3] = {NULL, NULL, NULL}; ret = ads_find_machine_acct(ads, (void **)(void *)&res, machine_name); if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { @@ -1434,78 +1429,59 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n return ADS_ERROR(LDAP_NO_MEMORY); } - name_to_fqdn(my_fqdn, machine_name); - strlower_m(my_fqdn); - - /* Add the extra principal */ - psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name); - if (!psp1) { + /* add short name spn */ + + if ( (psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name)) == NULL ) { talloc_destroy(ctx); ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } - strupper_m(psp1); strlower_m(&psp1[strlen(spn)]); - DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp1, machine_name)); servicePrincipalName[0] = psp1; - psp2 = talloc_asprintf(ctx, "%s/%s.%s", spn, machine_name, ads->config.realm); - if (!psp2) { - talloc_destroy(ctx); - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_MEMORY); - } + + DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", + psp1, machine_name)); + + /* add fully qualified spn */ + + if ( (psp2 = talloc_asprintf(ctx, "%s/%s", spn, my_fqdn)) == NULL ) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto out; + } strupper_m(psp2); strlower_m(&psp2[strlen(spn)]); - DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp2, machine_name)); servicePrincipalName[1] = psp2; - /* Add another principal in case the realm != the DNS domain, so that - * the KDC doesn't send "server principal unknown" errors to clients - * which use the DNS name in determining service principal names. */ - psp3 = talloc_asprintf(ctx, "%s/%s", spn, my_fqdn); - if (!psp3) { - talloc_destroy(ctx); - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_MEMORY); - } + DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", + psp2, machine_name)); - strupper_m(psp3); - strlower_m(&psp3[strlen(spn)]); - if (strcmp(psp2, psp3) != 0) { - DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", psp3, machine_name)); - servicePrincipalName[2] = psp3; - } - - if (!(mods = ads_init_mods(ctx))) { - talloc_destroy(ctx); - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_MEMORY); + if ( (mods = ads_init_mods(ctx)) == NULL ) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto out; } + ret = ads_add_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); if (!ADS_ERR_OK(ret)) { DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n")); - talloc_destroy(ctx); - ads_msgfree(ads, res); - return ret; + goto out; } - dn_string = ads_get_dn(ads, res); - if (!dn_string) { - talloc_destroy(ctx); - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_MEMORY); + + if ( (dn_string = ads_get_dn(ads, res)) == NULL ) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto out; } + ret = ads_gen_mod(ads, dn_string, mods); ads_memfree(ads,dn_string); if (!ADS_ERR_OK(ret)) { DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n")); - talloc_destroy(ctx); - ads_msgfree(ads, res); - return ret; + goto out; } - talloc_destroy(ctx); + out: + TALLOC_FREE( ctx ); ads_msgfree(ads, res); return ret; } @@ -2236,13 +2212,9 @@ static time_t ads_parse_time(const char *str) return timegm(&tm); } -/** - * Find the servers name and realm - this can be done before authentication - * The ldapServiceName field on w2k looks like this: - * vnet3.home.samba.org:win2000-vnet3$@VNET3.HOME.SAMBA.ORG - * @param ads connection to ads server - * @return status of search - **/ +/******************************************************************** +********************************************************************/ + ADS_STATUS ads_current_time(ADS_STRUCT *ads) { const char *attrs[] = {"currentTime", NULL}; @@ -2252,7 +2224,7 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads) TALLOC_CTX *ctx; ADS_STRUCT *ads_s = ads; - if (!(ctx = talloc_init("ads_server_info"))) { + if (!(ctx = talloc_init("ads_current_time"))) { return ADS_ERROR(LDAP_NO_MEMORY); } @@ -2272,14 +2244,12 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads) status = ads_do_search(ads_s, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status)) { - talloc_destroy(ctx); goto done; } timestr = ads_pull_string(ads_s, ctx, res, "currentTime"); if (!timestr) { ads_msgfree(ads, res); - talloc_destroy(ctx); status = ADS_ERROR(LDAP_NO_RESULTS_RETURNED); goto done; } @@ -2307,6 +2277,60 @@ done: return status; } +/******************************************************************** +********************************************************************/ + +ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val) +{ + const char *attrs[] = {"domainFunctionality", NULL}; + ADS_STATUS status; + void *res; + ADS_STRUCT *ads_s = ads; + + *val = DS_DOMAIN_FUNCTION_2000; + + /* establish a new ldap tcp session if necessary */ + + if ( !ads->ld ) { + if ( (ads_s = ads_init( ads->server.realm, ads->server.workgroup, + ads->server.ldap_server )) == NULL ) + { + goto done; + } + ads_s->auth.flags = ADS_AUTH_ANON_BIND; + status = ads_connect( ads_s ); + if ( !ADS_ERR_OK(status)) + goto done; + } + + /* If the attribute does not exist assume it is a Windows 2000 + functional domain */ + + status = ads_do_search(ads_s, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) { + if ( status.err.rc == LDAP_NO_SUCH_ATTRIBUTE ) { + status = ADS_SUCCESS; + } + goto done; + } + + if ( !ads_pull_uint32(ads_s, res, "domainFunctionality", val) ) { + DEBUG(5,("ads_domain_func_level: Failed to pull the domainFunctionality attribute.\n")); + } + DEBUG(3,("ads_domain_func_level: %d\n", *val)); + + + ads_msgfree(ads, res); + +done: + /* free any temporary ads connections */ + if ( ads_s != ads ) { + ads_destroy( &ads_s ); + } + + return status; +} + /** * find the domain sid for our domain * @param ads connection to ads server @@ -2617,4 +2641,100 @@ int ads_pull_sids_from_extendeddn(ADS_STRUCT *ads, return dn_count; } +/******************************************************************** +********************************************************************/ + +char* ads_get_dnshostname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name ) +{ + LDAPMessage *res = NULL; + ADS_STATUS status; + int count = 0; + char *name = NULL; + + status = ads_find_machine_acct(ads, (void **)(void *)&res, global_myname()); + if (!ADS_ERR_OK(status)) { + DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n", + global_myname())); + goto out; + } + + if ( (count = ads_count_replies(ads, res)) != 1 ) { + DEBUG(1,("ads_get_dnshostname: %d entries returned!\n", count)); + goto out; + } + + if ( (name = ads_pull_string(ads, ctx, res, "dNSHostName")) == NULL ) { + DEBUG(0,("ads_get_dnshostname: No dNSHostName attribute!\n")); + } + +out: + ads_msgfree(ads, res); + + return name; +} + +/******************************************************************** +********************************************************************/ + +char* ads_get_upn( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name ) +{ + LDAPMessage *res = NULL; + ADS_STATUS status; + int count = 0; + char *name = NULL; + + status = ads_find_machine_acct(ads, (void **)(void *)&res, global_myname()); + if (!ADS_ERR_OK(status)) { + DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n", + global_myname())); + goto out; + } + + if ( (count = ads_count_replies(ads, res)) != 1 ) { + DEBUG(1,("ads_get_dnshostname: %d entries returned!\n", count)); + goto out; + } + + if ( (name = ads_pull_string(ads, ctx, res, "userPrincipalName")) == NULL ) { + DEBUG(0,("ads_get_dnshostname: No userPrincipalName attribute!\n")); + } + +out: + ads_msgfree(ads, res); + + return name; +} + +/******************************************************************** +********************************************************************/ + +char* ads_get_samaccountname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name ) +{ + LDAPMessage *res = NULL; + ADS_STATUS status; + int count = 0; + char *name = NULL; + + status = ads_find_machine_acct(ads, (void **)(void *)&res, global_myname()); + if (!ADS_ERR_OK(status)) { + DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n", + global_myname())); + goto out; + } + + if ( (count = ads_count_replies(ads, res)) != 1 ) { + DEBUG(1,("ads_get_dnshostname: %d entries returned!\n", count)); + goto out; + } + + if ( (name = ads_pull_string(ads, ctx, res, "sAMAccountName")) == NULL ) { + DEBUG(0,("ads_get_dnshostname: No sAMAccountName attribute!\n")); + } + +out: + ads_msgfree(ads, res); + + return name; +} + #endif -- cgit From 846e939260c30d902952d95413d9cc3d06a82173 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 17 Jul 2006 15:00:49 +0000 Subject: r17089: Fix a possible null dereference and some memleaks. Jerry, please check. Thanks, Volker (This used to be commit b87c4952216b6302b0e1f22689b5a36b6aa65349) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a8ee770582..5d972b35fc 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -134,6 +134,7 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) if ( !ads_cldap_netlogon( srv, ads->server.realm, &cldap_reply ) ) { DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", srv)); + SAFE_FREE( srv ); return False; } -- cgit From 7c94b93af60d12bf8ffcd8d543e727878b82ddbf Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 Aug 2006 12:42:46 +0000 Subject: r17535: Reformatting, this had many tabs instead of ^$ (This used to be commit 0f483cf66c203d8590998b83cbeeb236ba06ab63) --- source3/libads/ldap.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 5d972b35fc..5ff1ce435d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -47,28 +47,28 @@ static SIG_ATOMIC_T gotalarm; /*************************************************************** Signal function to tell us we timed out. ****************************************************************/ - + static void gotalarm_sig(void) { gotalarm = 1; } - + LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) { LDAP *ldp = NULL; - + /* Setup timeout */ gotalarm = 0; CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); alarm(to); /* End setup timeout. */ - + ldp = ldap_open(server, port); - + /* Teardown timeout. */ CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN); alarm(0); - + return ldp; } -- cgit From b757699e8b14fb0d5780e2513ffe64c087f5871d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 Aug 2006 12:54:37 +0000 Subject: r17536: Add a debug message citing the reason why an LDAP connection failed, inspired by Christian M Ambach . Volker (This used to be commit cf7c83d462dc766fa6f48728d0a4e8d534cc2bd4) --- source3/libads/ldap.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 5ff1ce435d..2ceafedd30 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -65,6 +65,11 @@ static void gotalarm_sig(void) ldp = ldap_open(server, port); + if (ldp == NULL) { + DEBUG(2,("Could not open LDAP connection to %s:%d: %s\n", + server, port, strerror(errno))); + } + /* Teardown timeout. */ CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN); alarm(0); -- cgit From c804dd01171903440cd2c90153d62ab549d6b800 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 15 Aug 2006 09:53:16 +0000 Subject: r17551: Move some DEBUG to d_printf in interactive functions and return NO_LOGON_SERVERS if no domain controller was found. Thanks to Michael Adam . Volker (This used to be commit d44599de3a61707a32851f37ddfb2425949622f8) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2ceafedd30..52426c31ae 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -287,7 +287,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) goto got_connection; } - return ADS_ERROR_SYSTEM(errno?errno:ENOENT); + return ADS_ERROR_NT(NT_STATUS_NO_LOGON_SERVERS); got_connection: DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap_ip))); -- cgit From 5693e6c599a586b1bb19eea375c6b1e22526031c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 24 Aug 2006 15:43:32 +0000 Subject: r17798: Beginnings of a standalone libaddns library released under the LGPL. Original code by Krishna Ganugapati . Additional work by me. It's still got some warts, but non-secure updates do currently work. There are at least four things left to really clean up. 1. Change the memory management to use talloc() rather than malloc() and cleanup the leaks. 2. Fix the error code reporting (see initial changes to dnserr.h) 3. Fix the secure updates 4. Define a public interface in addns.h 5. Move the code in libads/dns.c into the libaddns/ directory (and under the LGPL). A few notes: * Enable the new code by compiling with --with-dnsupdate * Also adds the command 'net ads dns register' * Requires -luuid (included in the e2fsprogs-devel package). * Has only been tested on Linux platforms so there may be portability issues. (This used to be commit 36f04674aeefd93c5a0408b8967dcd48b86fdbc1) --- source3/libads/ldap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 52426c31ae..4f1f0146a7 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2691,18 +2691,18 @@ char* ads_get_upn( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name ) status = ads_find_machine_acct(ads, (void **)(void *)&res, global_myname()); if (!ADS_ERR_OK(status)) { - DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n", + DEBUG(0,("ads_get_upn: Failed to find account for %s\n", global_myname())); goto out; } if ( (count = ads_count_replies(ads, res)) != 1 ) { - DEBUG(1,("ads_get_dnshostname: %d entries returned!\n", count)); + DEBUG(1,("ads_get_upn: %d entries returned!\n", count)); goto out; } if ( (name = ads_pull_string(ads, ctx, res, "userPrincipalName")) == NULL ) { - DEBUG(0,("ads_get_dnshostname: No userPrincipalName attribute!\n")); + DEBUG(2,("ads_get_upn: No userPrincipalName attribute!\n")); } out: -- cgit From c52b3fb89f29110d2c2026a540e5dd39826bb799 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 28 Aug 2006 09:19:30 +0000 Subject: r17881: Another microstep towards better error reporting: Make get_sorted_dc_list return NTSTATUS. If we want to differentiate different name resolution problems we might want to introduce yet another error class for Samba-internal errors. Things like no route to host to the WINS server, a DNS server explicitly said host not found etc might be worth passing up. Because we can not stash everything into the existing NT_STATUS codes, what about a Samba-specific error class like NT_STATUS_DOS and NT_STATUS_LDAP? Volker (This used to be commit 60a166f0347170dff38554bed46193ce1226c8c1) --- source3/libads/ldap.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 4f1f0146a7..402e37b3c0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -182,7 +182,7 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) disabled **********************************************************************/ -static BOOL ads_find_dc(ADS_STRUCT *ads) +static NTSTATUS ads_find_dc(ADS_STRUCT *ads) { const char *c_realm; int count, i=0; @@ -190,6 +190,7 @@ static BOOL ads_find_dc(ADS_STRUCT *ads) pstring realm; BOOL got_realm = False; BOOL use_own_domain = False; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; /* if the realm and workgroup are both empty, assume they are ours */ @@ -220,7 +221,7 @@ again: if ( !c_realm || !*c_realm ) { DEBUG(0,("ads_find_dc: no realm or workgroup! Don't know what to do\n")); - return False; + return NT_STATUS_INVALID_PARAMETER; /* rather need MISSING_PARAMETER ... */ } } @@ -229,14 +230,15 @@ again: DEBUG(6,("ads_find_dc: looking for %s '%s'\n", (got_realm ? "realm" : "domain"), realm)); - if ( !get_sorted_dc_list(realm, &ip_list, &count, got_realm) ) { + status = get_sorted_dc_list(realm, &ip_list, &count, got_realm); + if (!NT_STATUS_IS_OK(status)) { /* fall back to netbios if we can */ if ( got_realm && !lp_disable_netbios() ) { got_realm = False; goto again; } - return False; + return status; } /* if we fail this loop, then giveup since all the IP addresses returned were dead */ @@ -250,7 +252,7 @@ again: if ( ads_try_connect(ads, server) ) { SAFE_FREE(ip_list); - return True; + return NT_STATUS_OK; } /* keep track of failures */ @@ -259,7 +261,7 @@ again: SAFE_FREE(ip_list); - return False; + return NT_STATUS_NO_LOGON_SERVERS; } @@ -272,6 +274,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) { int version = LDAP_VERSION3; ADS_STATUS status; + NTSTATUS ntstatus; ads->last_attempt = time(NULL); ads->ld = NULL; @@ -283,11 +286,12 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) goto got_connection; } - if (ads_find_dc(ads)) { + ntstatus = ads_find_dc(ads); + if (NT_STATUS_IS_OK(ntstatus)) { goto got_connection; } - return ADS_ERROR_NT(NT_STATUS_NO_LOGON_SERVERS); + return ADS_ERROR_NT(ntstatus); got_connection: DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap_ip))); -- cgit From 9f0c2827a4e08cb386453d1ce740f4b559b557fd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 29 Aug 2006 01:04:25 +0000 Subject: r17901: Stanford checker fix. cookie here can't be null or we'd deref null. Make interface explicit. Jeremy. (This used to be commit 4e99606ec16b978a76219b5362a23a7b06ee5468) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 402e37b3c0..c6d1fc9c60 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -506,7 +506,7 @@ ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, const char *bind_path, } cookie_be = ber_alloc_t(LBER_USE_DER); - if (cookie && *cookie) { + if (*cookie) { ber_printf(cookie_be, "{iO}", (ber_int_t) 1000, *cookie); ber_bvfree(*cookie); /* don't need it from last time */ *cookie = NULL; -- cgit From 2abab7ee6d04a62017d99578c274244a1cdd27b2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Aug 2006 04:40:03 +0000 Subject: r17928: Implement the basic store for CLDAP sitename support when looking up DC's. On every CLDAP call store the returned client sitename (if present, delete store if not) in gencache with infinate timeout. On AD DNS DC lookup, try looking for sitename DC's first, only try generic if sitename DNS lookup failed. I still haven't figured out yet how to ensure we fetch the sitename with a CLDAP query before doing the generic DC list lookup. This code is difficult to understand. I'll do some experiments and backtraces tomorrow to try and work out where to force a CLDAP site query first. Jeremy. (This used to be commit ab3f0c5b1e9c5fd192c5514cbe9451b938f9cd5d) --- source3/libads/ldap.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c6d1fc9c60..c943558bd3 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -173,6 +173,9 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) saf_store( ads->server.workgroup, server ); + /* Store our site name. */ + sitename_store( cldap_reply.client_site_name ); + return True; } -- cgit From 9d37ee52e0d616b60e6644050d259e884ee5870d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Aug 2006 18:48:49 +0000 Subject: r17937: Move the saf_ cache into the tcp ad connection code. Cause winbindd to set site support before doing the generic AD server lookup. Jeremy. (This used to be commit a9833941715472ece747bce69ef53ba8ad98d7a5) --- source3/libads/ldap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c943558bd3..947f58a8fd 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -169,10 +169,6 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) ads->ldap_ip = *interpret_addr2(srv); SAFE_FREE(srv); - /* cache the successful connection */ - - saf_store( ads->server.workgroup, server ); - /* Store our site name. */ sitename_store( cldap_reply.client_site_name ); @@ -243,7 +239,7 @@ again: return status; } - + /* if we fail this loop, then giveup since all the IP addresses returned were dead */ for ( i=0; iserver.workgroup, inet_ntoa(ads->ldap_ip)); + ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); status = ADS_ERROR(smb_ldap_start_tls(ads->ld, version)); -- cgit From 6fada7a82aa67e7b80ff003bd527092da68542c8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Aug 2006 01:20:21 +0000 Subject: r17943: The horror, the horror. Add KDC site support by writing out a custom krb5.conf file containing the KDC I need. This may suck.... Needs some testing :-). Jeremy. (This used to be commit d500e1f96d92dfcc6292c448d1b399195f762d89) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 947f58a8fd..1d192895d9 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -159,6 +159,7 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) SAFE_FREE(ads->config.ldap_server_name); SAFE_FREE(ads->server.workgroup); + ads->config.flags = cldap_reply.flags; ads->config.ldap_server_name = SMB_STRDUP(cldap_reply.hostname); strupper_m(cldap_reply.domain); ads->config.realm = SMB_STRDUP(cldap_reply.domain); -- cgit From 2fcd113f5507f643fcf80d5a9770ce72aa121ba8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Aug 2006 04:14:08 +0000 Subject: r17945: Store the server and client sitenames in the ADS struct so we can see when they match - only create the ugly krb5 hack when they do. Jeremy. (This used to be commit 9be4ecf24b6b5dacf4c2891bddb072fa7543753f) --- source3/libads/ldap.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1d192895d9..60e4c9f5b7 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -115,6 +115,27 @@ static int ldap_search_with_timeout(LDAP *ld, return result; } +#ifdef HAVE_KRB5 +/********************************************** + Do client and server sitename match ? +**********************************************/ + +BOOL ads_sitename_match(ADS_STRUCT *ads) +{ + if (ads->config.server_site_name == NULL && + ads->config.client_site_name == NULL ) { + return True; + } + if (ads->config.server_site_name && + ads->config.client_site_name && + strequal(ads->config.server_site_name, + ads->config.client_site_name)) { + return True; + } + return False; +} +#endif + /* try a connection to a given ldap server, returning True and setting the servers IP in the ads struct if successful @@ -157,6 +178,8 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) SAFE_FREE(ads->config.realm); SAFE_FREE(ads->config.bind_path); SAFE_FREE(ads->config.ldap_server_name); + SAFE_FREE(ads->config.server_site); + SAFE_FREE(ads->config.client_site); SAFE_FREE(ads->server.workgroup); ads->config.flags = cldap_reply.flags; @@ -164,6 +187,15 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) strupper_m(cldap_reply.domain); ads->config.realm = SMB_STRDUP(cldap_reply.domain); ads->config.bind_path = ads_build_dn(ads->config.realm); + if (*cldap_reply.server_site_name) { + ads->config.server_site_name = + SMB_STRDUP(cldap_reply.server_site_name); + } + if (*cldap_reply.client_site_name) { + ads->config.server_site_name = + SMB_STRDUP(cldap_reply.server_site_name); + } + ads->server.workgroup = SMB_STRDUP(cldap_reply.netbios_domain); ads->ldap_port = LDAP_PORT; -- cgit From a78c61b9cdb535d43cda6de038ec7718e8b24491 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Aug 2006 04:16:13 +0000 Subject: r17946: Fix couple of typos... Jeremy. (This used to be commit 638d53e2ad524dfe4666b79d36997dea8a44c8cd) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 60e4c9f5b7..4fbb0c7af3 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -178,8 +178,8 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) SAFE_FREE(ads->config.realm); SAFE_FREE(ads->config.bind_path); SAFE_FREE(ads->config.ldap_server_name); - SAFE_FREE(ads->config.server_site); - SAFE_FREE(ads->config.client_site); + SAFE_FREE(ads->config.server_site_name); + SAFE_FREE(ads->config.client_site_name); SAFE_FREE(ads->server.workgroup); ads->config.flags = cldap_reply.flags; -- cgit From 0c9ca3fe19249c19ac3525f3e6e19242b3e77f7f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 01:23:08 +0000 Subject: r17994: Add debugs that showed me why my site code wasn't working right. Don't update the server site when we have a client one... Jeremy. (This used to be commit 7acbcf9a6c71f8e7f9167880488613c930cef4d9) --- source3/libads/ldap.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 4fbb0c7af3..b23bc277e8 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -124,14 +124,19 @@ BOOL ads_sitename_match(ADS_STRUCT *ads) { if (ads->config.server_site_name == NULL && ads->config.client_site_name == NULL ) { + DEBUG(10,("ads_sitename_match: both null\n")); return True; } if (ads->config.server_site_name && ads->config.client_site_name && strequal(ads->config.server_site_name, ads->config.client_site_name)) { + DEBUG(10,("ads_sitename_match: name %s match\n", ads->config.server_site_name)); return True; } + DEBUG(10,("ads_sitename_match: no match %s %s\n", + ads->config.server_site_name ? ads->config.server_site_name : "NULL", + ads->config.client_site_name ? ads->config.client_site_name : "NULL")); return False; } #endif @@ -192,8 +197,8 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) SMB_STRDUP(cldap_reply.server_site_name); } if (*cldap_reply.client_site_name) { - ads->config.server_site_name = - SMB_STRDUP(cldap_reply.server_site_name); + ads->config.client_site_name = + SMB_STRDUP(cldap_reply.client_site_name); } ads->server.workgroup = SMB_STRDUP(cldap_reply.netbios_domain); -- cgit From 98cfbd3ccfb3d2255a65289410e5e358ff3d1a64 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 3 Sep 2006 03:46:07 +0000 Subject: r18015: Try and detect network failures immediately in set_dc_type_and_flags(). Fix problem when DC is down in ads_connect, where we fall back to NetBIOS and try exactly the same IP addresses we just put in the negative connection cache.... We can never succeed, so don't try lookups a second time. Jeremy. (This used to be commit 2d28f3e94a1a87bc9e9ed6630ef48b1ce17022e8) --- source3/libads/ldap.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b23bc277e8..a02f954360 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -286,6 +286,26 @@ again: if ( !NT_STATUS_IS_OK(check_negative_conn_cache(realm, server)) ) continue; + + if (!got_realm) { + /* realm in this case is a workgroup name. We need + to ignore any IP addresses in the negative connection + cache that match ip addresses returned in the ad realm + case. It sucks that I have to reproduce the logic above... */ + c_realm = ads->server.realm; + if ( !c_realm || !*c_realm ) { + if ( !ads->server.workgroup || !*ads->server.workgroup ) { + c_realm = lp_realm(); + } + } + if (c_realm && *c_realm && + !NT_STATUS_IS_OK(check_negative_conn_cache(c_realm, server))) { + /* Ensure we add the workgroup name for this + IP address as negative too. */ + add_failed_connection_entry( realm, server, NT_STATUS_UNSUCCESSFUL ); + continue; + } + } if ( ads_try_connect(ads, server) ) { SAFE_FREE(ip_list); -- cgit From ee0e397d6f003c583768803aa27716b2b7a23981 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 3 Sep 2006 21:07:16 +0000 Subject: r18019: Fix a C++ warnings: Don't use void * in libads/ for LDAPMessage anymore. Compiled it on systems with and without LDAP, I hope it does not break the build farm too badly. If it does, I'll fix it tomorrow. Volker (This used to be commit b2ff9680ebe0979fbeef7f2dabc2e3f27c959d11) --- source3/libads/ldap.c | 180 ++++++++++++++++++++++++++------------------------ 1 file changed, 92 insertions(+), 88 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a02f954360..970311d5ca 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -438,7 +438,8 @@ static struct berval *dup_berval(TALLOC_CTX *ctx, const struct berval *in_val) 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); + value->bv_val = (char *)TALLOC_MEMDUP(ctx, in_val->bv_val, + in_val->bv_len); return value; } @@ -517,10 +518,12 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) * @param cookie The paged results cookie to be returned on subsequent calls * @return status of search **/ -ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *expr, - const char **attrs, void *args, void **res, - int *count, void **cookie) +static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, + const char *bind_path, + int scope, const char *expr, + const char **attrs, void *args, + LDAPMessage **res, + int *count, struct berval **cookie) { int rc, i, version; char *utf8_expr, *utf8_path, **search_attrs; @@ -693,10 +696,10 @@ done: return ADS_ERROR(rc); } -ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *expr, - const char **attrs, void **res, - int *count, void **cookie) +static ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *expr, + const char **attrs, LDAPMessage **res, + int *count, struct berval **cookie) { return ads_do_paged_search_args(ads, bind_path, scope, expr, attrs, NULL, res, count, cookie); } @@ -713,11 +716,12 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, * @param res ** which will contain results - free res* with ads_msgfree() * @return status of search **/ -ADS_STATUS ads_do_search_all_args(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *expr, - const char **attrs, void *args, void **res) + ADS_STATUS ads_do_search_all_args(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *expr, + const char **attrs, void *args, + LDAPMessage **res) { - void *cookie = NULL; + struct berval *cookie = NULL; int count = 0; ADS_STATUS status; @@ -730,7 +734,7 @@ ADS_STATUS ads_do_search_all_args(ADS_STRUCT *ads, const char *bind_path, #ifdef HAVE_LDAP_ADD_RESULT_ENTRY while (cookie) { - void *res2 = NULL; + LDAPMessage *res2 = NULL; ADS_STATUS status2; LDAPMessage *msg, *next; @@ -756,9 +760,9 @@ ADS_STATUS ads_do_search_all_args(ADS_STRUCT *ads, const char *bind_path, return status; } -ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, - int scope, const char *expr, - const char **attrs, void **res) + ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *expr, + const char **attrs, LDAPMessage **res) { return ads_do_search_all_args(ads, bind_path, scope, expr, attrs, NULL, res); } @@ -780,10 +784,10 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, BOOL(*fn)(char *, void **, void *), void *data_area) { - void *cookie = NULL; + struct berval *cookie = NULL; int count = 0; ADS_STATUS status; - void *res; + LDAPMessage *res; status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, &res, &count, &cookie); @@ -816,9 +820,9 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, * @param res ** which will contain results - free res* with ads_msgfree() * @return status of search **/ -ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, - const char *expr, - const char **attrs, void **res) + ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, + const char *expr, + const char **attrs, LDAPMessage **res) { int rc; char *utf8_expr, *utf8_path, **search_attrs = NULL; @@ -880,9 +884,8 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope, * @param attrs Attributes to retrieve * @return status of search **/ -ADS_STATUS ads_search(ADS_STRUCT *ads, void **res, - const char *expr, - const char **attrs) + ADS_STATUS ads_search(ADS_STRUCT *ads, LDAPMessage **res, + const char *expr, const char **attrs) { return ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, expr, attrs, res); @@ -896,12 +899,11 @@ ADS_STATUS ads_search(ADS_STRUCT *ads, void **res, * @param attrs Attributes to retrieve * @return status of search **/ -ADS_STATUS ads_search_dn(ADS_STRUCT *ads, void *_res, - const char *dn, - const char **attrs) + ADS_STATUS ads_search_dn(ADS_STRUCT *ads, LDAPMessage **res, + const char *dn, const char **attrs) { - void **res = (void **)_res; - return ads_do_search(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res); + return ads_do_search(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", + attrs, res); } /** @@ -909,7 +911,7 @@ ADS_STATUS ads_search_dn(ADS_STRUCT *ads, void *_res, * @param ads connection to ads server * @param msg Search results to free **/ -void ads_msgfree(ADS_STRUCT *ads, void *msg) + void ads_msgfree(ADS_STRUCT *ads, LDAPMessage *msg) { if (!msg) return; ldap_msgfree(msg); @@ -931,7 +933,7 @@ void ads_memfree(ADS_STRUCT *ads, void *mem) * @param msg Search result * @return dn string **/ -char *ads_get_dn(ADS_STRUCT *ads, void *msg) + char *ads_get_dn(ADS_STRUCT *ads, LDAPMessage *msg) { char *utf8_dn, *unix_dn; @@ -957,7 +959,7 @@ char *ads_get_dn(ADS_STRUCT *ads, void *msg) * @param msg Search result * @return dn string **/ -char *ads_get_dn_canonical(ADS_STRUCT *ads, void *msg) + char *ads_get_dn_canonical(ADS_STRUCT *ads, LDAPMessage *msg) { #ifdef HAVE_LDAP_DN2AD_CANONICAL return ldap_dn2ad_canonical(ads_get_dn(ads, msg)); @@ -995,7 +997,8 @@ char *ads_parent_dn(const char *dn) * @param host Hostname to search for * @return status of search **/ -ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *machine) + ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, LDAPMessage **res, + const char *machine) { ADS_STATUS status; char *expr; @@ -1271,7 +1274,7 @@ char *ads_ou_string(ADS_STRUCT *ads, const char *org_unit) char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) { ADS_STATUS status; - void *res; + LDAPMessage *res; char *base, *wkn_dn, *ret, **wkn_dn_exp, **bind_dn_exp; const char *attrs[] = {"distinguishedName", NULL}; int new_ln, wkn_ln, bind_ln, i; @@ -1338,7 +1341,8 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) ADS_STATUS ads_add_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const char **vals) { - return ads_modlist_add(ctx, mods, LDAP_MOD_ADD, name, (const void **) vals); + return ads_modlist_add(ctx, mods, LDAP_MOD_ADD, name, + (const void *) vals); } /** @@ -1361,7 +1365,7 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) if (asprintf(&filter, "(samAccountName=%s$)", machine_name) == -1) { return kvno; } - ret = ads_search(ads, (void**)(void *)&res, filter, attrs); + ret = ads_search(ads, &res, filter, attrs); SAFE_FREE(filter); if (!ADS_ERR_OK(ret) && ads_count_replies(ads, res)) { DEBUG(1,("ads_get_kvno: Computer Account For %s not found.\n", machine_name)); @@ -1415,7 +1419,7 @@ ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machin ADS_STATUS ret = ADS_ERROR(LDAP_SUCCESS); char *dn_string = NULL; - ret = ads_find_machine_acct(ads, (void **)(void *)&res, machine_name); + ret = ads_find_machine_acct(ads, &res, machine_name); if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { DEBUG(5,("ads_clear_service_principal_names: WARNING: Host Account for %s not found... skipping operation.\n", machine_name)); DEBUG(5,("ads_clear_service_principal_names: WARNING: Service Principals for %s have NOT been cleared.\n", machine_name)); @@ -1484,7 +1488,7 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n char *dn_string = NULL; const char *servicePrincipalName[3] = {NULL, NULL, NULL}; - ret = ads_find_machine_acct(ads, (void **)(void *)&res, machine_name); + ret = ads_find_machine_acct(ads, &res, machine_name); if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { DEBUG(1,("ads_add_service_principal_name: WARNING: Host Account for %s not found... skipping operation.\n", machine_name)); @@ -1751,7 +1755,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) * @param res Results to dump **/ -void ads_dump(ADS_STRUCT *ads, void *res) + void ads_dump(ADS_STRUCT *ads, LDAPMessage *res) { ads_process_results(ads, res, ads_dump_field, NULL); } @@ -1767,11 +1771,11 @@ void ads_dump(ADS_STRUCT *ads, void *res) * @param fn Function for processing each result * @param data_area user-defined area to pass to function **/ -void ads_process_results(ADS_STRUCT *ads, void *res, - BOOL(*fn)(char *, void **, void *), - void *data_area) + void ads_process_results(ADS_STRUCT *ads, LDAPMessage *res, + BOOL(*fn)(char *, void **, void *), + void *data_area) { - void *msg; + LDAPMessage *msg; TALLOC_CTX *ctx; if (!(ctx = talloc_init("ads_process_results"))) @@ -1836,9 +1840,9 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @param res Results of search * @return first entry from result **/ -void *ads_first_entry(ADS_STRUCT *ads, void *res) + LDAPMessage *ads_first_entry(ADS_STRUCT *ads, LDAPMessage *res) { - return (void *)ldap_first_entry(ads->ld, (LDAPMessage *)res); + return ldap_first_entry(ads->ld, res); } /** @@ -1847,9 +1851,9 @@ void *ads_first_entry(ADS_STRUCT *ads, void *res) * @param res Results of search * @return next entry from result **/ -void *ads_next_entry(ADS_STRUCT *ads, void *res) + LDAPMessage *ads_next_entry(ADS_STRUCT *ads, LDAPMessage *res) { - return (void *)ldap_next_entry(ads->ld, (LDAPMessage *)res); + return ldap_next_entry(ads->ld, res); } /** @@ -1860,8 +1864,8 @@ void *ads_next_entry(ADS_STRUCT *ads, void *res) * @param field Attribute to retrieve * @return Result string in talloc context **/ -char *ads_pull_string(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, void *msg, const char *field) + char *ads_pull_string(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, LDAPMessage *msg, + const char *field) { char **values; char *ret = NULL; @@ -1891,9 +1895,9 @@ char *ads_pull_string(ADS_STRUCT *ads, * @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, - size_t *num_values) + char **ads_pull_strings(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + LDAPMessage *msg, const char *field, + size_t *num_values) { char **values; char **ret = NULL; @@ -1936,13 +1940,13 @@ char **ads_pull_strings(ADS_STRUCT *ads, * @param more_values Are there more values to get? * @return Result strings in talloc context **/ -char **ads_pull_strings_range(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - void *msg, const char *field, - char **current_strings, - const char **next_attribute, - size_t *num_strings, - BOOL *more_strings) + char **ads_pull_strings_range(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + LDAPMessage *msg, const char *field, + char **current_strings, + const char **next_attribute, + size_t *num_strings, + BOOL *more_strings) { char *attr; char *expected_range_attrib, *range_attr; @@ -2059,8 +2063,8 @@ char **ads_pull_strings_range(ADS_STRUCT *ads, * @param v Pointer to int to store result * @return boolean inidicating success */ -BOOL ads_pull_uint32(ADS_STRUCT *ads, - void *msg, const char *field, uint32 *v) + BOOL ads_pull_uint32(ADS_STRUCT *ads, LDAPMessage *msg, const char *field, + uint32 *v) { char **values; @@ -2084,8 +2088,7 @@ BOOL ads_pull_uint32(ADS_STRUCT *ads, * @param guid 37-byte area to receive text guid * @return boolean indicating success **/ -BOOL ads_pull_guid(ADS_STRUCT *ads, - void *msg, struct uuid *guid) + BOOL ads_pull_guid(ADS_STRUCT *ads, LDAPMessage *msg, struct uuid *guid) { char **values; UUID_FLAT flat_guid; @@ -2114,8 +2117,8 @@ BOOL ads_pull_guid(ADS_STRUCT *ads, * @param sid Pointer to sid to store result * @return boolean inidicating success */ -BOOL ads_pull_sid(ADS_STRUCT *ads, - void *msg, const char *field, DOM_SID *sid) + BOOL ads_pull_sid(ADS_STRUCT *ads, LDAPMessage *msg, const char *field, + DOM_SID *sid) { struct berval **values; BOOL ret = False; @@ -2141,8 +2144,8 @@ BOOL ads_pull_sid(ADS_STRUCT *ads, * @param sids pointer to sid array to allocate * @return the count of SIDs pulled **/ -int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, - void *msg, const char *field, DOM_SID **sids) + int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + LDAPMessage *msg, const char *field, DOM_SID **sids) { struct berval **values; BOOL ret; @@ -2185,8 +2188,8 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, * @param sd Pointer to *SEC_DESC to store result (talloc()ed) * @return boolean inidicating success */ -BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, - void *msg, const char *field, SEC_DESC **sd) + BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + LDAPMessage *msg, const char *field, SEC_DESC **sd) { struct berval **values; prs_struct ps; @@ -2218,7 +2221,8 @@ BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, * @param msg Results of search * @return the username */ -char *ads_pull_username(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg) + char *ads_pull_username(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + LDAPMessage *msg) { #if 0 /* JERRY */ char *ret, *p; @@ -2248,7 +2252,7 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) { const char *attrs[] = {"highestCommittedUSN", NULL}; ADS_STATUS status; - void *res; + LDAPMessage *res; status = ads_do_search_retry(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status)) @@ -2290,7 +2294,7 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads) { const char *attrs[] = {"currentTime", NULL}; ADS_STATUS status; - void *res; + LDAPMessage *res; char *timestr; TALLOC_CTX *ctx; ADS_STRUCT *ads_s = ads; @@ -2355,7 +2359,7 @@ ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val) { const char *attrs[] = {"domainFunctionality", NULL}; ADS_STATUS status; - void *res; + LDAPMessage *res; ADS_STRUCT *ads_s = ads; *val = DS_DOMAIN_FUNCTION_2000; @@ -2411,7 +2415,7 @@ done: ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) { const char *attrs[] = {"objectSid", NULL}; - void *res; + LDAPMessage *res; ADS_STATUS rc; rc = ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", @@ -2436,7 +2440,7 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) ADS_STATUS ads_site_dn(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **site_name) { ADS_STATUS status; - void *res; + LDAPMessage *res; const char *dn, *service_name; const char *attrs[] = { "dsServiceName", NULL }; @@ -2480,7 +2484,7 @@ ADS_STATUS ads_site_dn(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **site_n ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *computer_name, const char **site_dn) { ADS_STATUS status; - void *res; + LDAPMessage *res; const char *parent, *config_context, *filter; const char *attrs[] = { "configurationNamingContext", NULL }; char *dn; @@ -2549,7 +2553,7 @@ ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const c ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **suffixes, size_t *num_suffixes) { ADS_STATUS status; - void *res; + LDAPMessage *res; const char *config_context, *base; const char *attrs[] = { "configurationNamingContext", NULL }; const char *attrs2[] = { "uPNSuffixes", NULL }; @@ -2578,7 +2582,7 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **suffixe return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } - suffixes = ads_pull_strings(ads, mem_ctx, &res, "uPNSuffixes", num_suffixes); + suffixes = ads_pull_strings(ads, mem_ctx, res, "uPNSuffixes", num_suffixes); if (suffixes == NULL) { ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); @@ -2675,12 +2679,12 @@ BOOL ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, * @param sids pointer to sid array to allocate * @return the count of SIDs pulled **/ -int ads_pull_sids_from_extendeddn(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - void *msg, - const char *field, - enum ads_extended_dn_flags flags, - DOM_SID **sids) + int ads_pull_sids_from_extendeddn(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + LDAPMessage *msg, + const char *field, + enum ads_extended_dn_flags flags, + DOM_SID **sids) { int i; size_t dn_count; @@ -2722,7 +2726,7 @@ char* ads_get_dnshostname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine int count = 0; char *name = NULL; - status = ads_find_machine_acct(ads, (void **)(void *)&res, global_myname()); + status = ads_find_machine_acct(ads, &res, global_myname()); if (!ADS_ERR_OK(status)) { DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n", global_myname())); @@ -2754,7 +2758,7 @@ char* ads_get_upn( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name ) int count = 0; char *name = NULL; - status = ads_find_machine_acct(ads, (void **)(void *)&res, global_myname()); + status = ads_find_machine_acct(ads, &res, global_myname()); if (!ADS_ERR_OK(status)) { DEBUG(0,("ads_get_upn: Failed to find account for %s\n", global_myname())); @@ -2786,7 +2790,7 @@ char* ads_get_samaccountname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *mach int count = 0; char *name = NULL; - status = ads_find_machine_acct(ads, (void **)(void *)&res, global_myname()); + status = ads_find_machine_acct(ads, &res, global_myname()); if (!ADS_ERR_OK(status)) { DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n", global_myname())); -- cgit From 8d812f8eed301365a550bf36394c0f2774d57188 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 5 Sep 2006 06:32:46 +0000 Subject: r18063: When we get a successful connection using ADS, cache the SAF name under both the domain name and the realm name, as we could be looking up under both. Jerry please check. Jeremy. (This used to be commit 9d954d2deb46698b3834c7caf5ee0cfe628086b5) --- source3/libads/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 970311d5ca..6c3ab75340 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -393,8 +393,9 @@ got_connection: return ADS_ERROR(LDAP_OPERATIONS_ERROR); } - /* cache the successful connection */ + /* cache the successful connection for workgroup and realm */ saf_store( ads->server.workgroup, inet_ntoa(ads->ldap_ip)); + saf_store( ads->server.realm, inet_ntoa(ads->ldap_ip)); ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); -- cgit From 73d25f6f784513aa850de4a7207a1436289c107c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 6 Sep 2006 12:14:58 +0000 Subject: r18165: Fix memleaks. Guenther (This used to be commit 6f301b2dc3dd64b4396e1d0307b3d539bda67d45) --- source3/libads/ldap.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6c3ab75340..0b7ca46e3e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2260,10 +2260,15 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn) return status; if (ads_count_replies(ads, res) != 1) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); } - ads_pull_uint32(ads, res, "highestCommittedUSN", usn); + if (!ads_pull_uint32(ads, res, "highestCommittedUSN", usn)) { + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_SUCH_ATTRIBUTE); + } + ads_msgfree(ads, res); return ADS_SUCCESS; } @@ -2325,7 +2330,7 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads) timestr = ads_pull_string(ads_s, ctx, res, "currentTime"); if (!timestr) { - ads_msgfree(ads, res); + ads_msgfree(ads_s, res); status = ADS_ERROR(LDAP_NO_RESULTS_RETURNED); goto done; } -- cgit From 8c2c5c5d1d3ccbb9f3bab9136c23d1020e4e20f1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 13 Sep 2006 09:03:42 +0000 Subject: r18446: Add the ldap 'leave domain' code - call this as a non-fatal error path if the 'disable machine account' code succeeded. Jeremy. (This used to be commit f47bffa21ec1caf5ec3a6ec77af801df0b63d83a) --- source3/libads/ldap.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0b7ca46e3e..93bd9acf4c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2818,4 +2818,178 @@ out: return name; } +#if 0 + + SAVED CODE - we used to join via ldap - remember how we did this. JRA. + +/** + * Join a machine to a realm + * Creates the machine account and sets the machine password + * @param ads connection to ads server + * @param machine name of host to add + * @param org_unit Organizational unit to place machine in + * @return status of join + **/ +ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, + uint32 account_type, const char *org_unit) +{ + ADS_STATUS status; + LDAPMessage *res = NULL; + char *machine; + + /* machine name must be lowercase */ + machine = SMB_STRDUP(machine_name); + strlower_m(machine); + + /* + status = ads_find_machine_acct(ads, (void **)&res, machine); + if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { + DEBUG(0, ("Host account for %s already exists - deleting old account\n", machine)); + status = ads_leave_realm(ads, machine); + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n", + machine, ads->config.realm)); + return status; + } + } + */ + status = ads_add_machine_acct(ads, machine, account_type, org_unit); + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("ads_join_realm: ads_add_machine_acct failed (%s): %s\n", machine, ads_errstr(status))); + SAFE_FREE(machine); + return status; + } + + status = ads_find_machine_acct(ads, (void **)(void *)&res, machine); + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("ads_join_realm: Host account test failed for machine %s\n", machine)); + SAFE_FREE(machine); + return status; + } + + SAFE_FREE(machine); + ads_msgfree(ads, res); + + return status; +} +#endif + +/** + * Delete a machine from the realm + * @param ads connection to ads server + * @param hostname Machine to remove + * @return status of delete + **/ +ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) +{ + ADS_STATUS status; + void *msg; + LDAPMessage *res; + char *hostnameDN, *host; + int rc; + LDAPControl ldap_control; + LDAPControl * pldap_control[2] = {NULL, NULL}; + + pldap_control[0] = &ldap_control; + memset(&ldap_control, 0, sizeof(LDAPControl)); + ldap_control.ldctl_oid = (char *)LDAP_SERVER_TREE_DELETE_OID; + + /* hostname must be lowercase */ + host = SMB_STRDUP(hostname); + strlower_m(host); + + status = ads_find_machine_acct(ads, &res, host); + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("Host account for %s does not exist.\n", host)); + SAFE_FREE(host); + return status; + } + + msg = ads_first_entry(ads, res); + if (!msg) { + SAFE_FREE(host); + return ADS_ERROR_SYSTEM(ENOENT); + } + + hostnameDN = ads_get_dn(ads, (LDAPMessage *)msg); + + rc = ldap_delete_ext_s(ads->ld, hostnameDN, pldap_control, NULL); + if (rc) { + DEBUG(3,("ldap_delete_ext_s failed with error code %d\n", rc)); + }else { + DEBUG(3,("ldap_delete_ext_s succeeded with error code %d\n", rc)); + } + + ads_memfree(ads, hostnameDN); + if (rc != LDAP_SUCCESS) { + const char *attrs[] = { "cn", NULL }; + void *msg_sub; + + /* we only search with scope ONE, we do not expect any further + * objects to be created deeper */ + + status = ads_do_search_retry(ads, hostnameDN, LDAP_SCOPE_ONE, + "(objectclass=*)", attrs, &res); + + if (!ADS_ERR_OK(status)) { + SAFE_FREE(host); + ads_memfree(ads, hostnameDN); + return status; + } + + for (msg_sub = ads_first_entry(ads, res); msg_sub; + msg_sub = ads_next_entry(ads, msg_sub)) { + + char *dn = NULL; + + if ((dn = ads_get_dn(ads, msg_sub)) == NULL) { + SAFE_FREE(host); + ads_memfree(ads, hostnameDN); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + status = ads_del_dn(ads, dn); + if (!ADS_ERR_OK(status)) { + DEBUG(3,("failed to delete dn %s: %s\n", dn, ads_errstr(status))); + SAFE_FREE(host); + ads_memfree(ads, dn); + ads_memfree(ads, hostnameDN); + return status; + } + + ads_memfree(ads, dn); + } + + /* there should be no subordinate objects anymore */ + status = ads_do_search_retry(ads, hostnameDN, LDAP_SCOPE_ONE, + "(objectclass=*)", attrs, &res); + + if (!ADS_ERR_OK(status) || ( (ads_count_replies(ads, res)) > 0 ) ) { + SAFE_FREE(host); + ads_memfree(ads, hostnameDN); + return status; + } + + /* delete hostnameDN now */ + status = ads_del_dn(ads, hostnameDN); + if (!ADS_ERR_OK(status)) { + SAFE_FREE(host); + DEBUG(3,("failed to delete dn %s: %s\n", hostnameDN, ads_errstr(status))); + ads_memfree(ads, hostnameDN); + return status; + } + } + + ads_memfree(ads, hostnameDN); + + status = ads_find_machine_acct(ads, &res, host); + if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { + DEBUG(3, ("Failed to remove host account.\n")); + SAFE_FREE(host); + return status; + } + + SAFE_FREE(host); + return status; +} #endif -- cgit From d3237d2233a96c87417161b6a09035beb2315c1d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 13 Sep 2006 10:03:27 +0000 Subject: r18453: Attempt to fix the non-ldap build (This used to be commit 86db85423027d34cb053fc068159ddd2226e90ec) --- source3/libads/ldap.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 93bd9acf4c..57275dda55 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2874,6 +2874,8 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, } #endif +#ifdef HAVE_LDAP + /** * Delete a machine from the realm * @param ads connection to ads server @@ -2993,3 +2995,5 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return status; } #endif + +#endif -- cgit From dfa62cfa989f29138818fd4badf213fb35e8b48e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 13 Sep 2006 11:40:21 +0000 Subject: r18464: Solaris has LDAP_SCOPE_ONELEVEL. Linux seems to have it as well. Fix a C++ compat warning. Volker (This used to be commit 351e583f66714562eca1f40429bfee70f06d281c) --- source3/libads/ldap.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 57275dda55..7ea605df60 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2925,13 +2925,14 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) ads_memfree(ads, hostnameDN); if (rc != LDAP_SUCCESS) { const char *attrs[] = { "cn", NULL }; - void *msg_sub; + LDAPMessage *msg_sub; /* we only search with scope ONE, we do not expect any further * objects to be created deeper */ - status = ads_do_search_retry(ads, hostnameDN, LDAP_SCOPE_ONE, - "(objectclass=*)", attrs, &res); + status = ads_do_search_retry(ads, hostnameDN, + LDAP_SCOPE_ONELEVEL, + "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status)) { SAFE_FREE(host); @@ -2963,8 +2964,9 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) } /* there should be no subordinate objects anymore */ - status = ads_do_search_retry(ads, hostnameDN, LDAP_SCOPE_ONE, - "(objectclass=*)", attrs, &res); + status = ads_do_search_retry(ads, hostnameDN, + LDAP_SCOPE_ONELEVEL, + "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status) || ( (ads_count_replies(ads, res)) > 0 ) ) { SAFE_FREE(host); -- cgit From a4743f3a76dc88f765f9bc5dde8054b60d3045cc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 13 Sep 2006 16:21:48 +0000 Subject: r18480: Doh ! Double-free of hostnameDN. Jeremy. (This used to be commit f8984fa8b706bb76559e447b30a201e1cc2871b6) --- source3/libads/ldap.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7ea605df60..6b18bbf594 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2922,7 +2922,6 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) DEBUG(3,("ldap_delete_ext_s succeeded with error code %d\n", rc)); } - ads_memfree(ads, hostnameDN); if (rc != LDAP_SUCCESS) { const char *attrs[] = { "cn", NULL }; LDAPMessage *msg_sub; -- cgit From a0aaa82f6d360f2fe688f95791640b58231ed873 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 15 Sep 2006 14:18:52 +0000 Subject: r18552: Ensure the sitename matches before we SAF store a DC in ADS mode. Jeremy. (This used to be commit 03e1078b459531af5a2336b584b3c886c5dd1e29) --- source3/libads/ldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6b18bbf594..7b31586f7d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -115,7 +115,6 @@ static int ldap_search_with_timeout(LDAP *ld, return result; } -#ifdef HAVE_KRB5 /********************************************** Do client and server sitename match ? **********************************************/ @@ -139,7 +138,6 @@ BOOL ads_sitename_match(ADS_STRUCT *ads) ads->config.client_site_name ? ads->config.client_site_name : "NULL")); return False; } -#endif /* try a connection to a given ldap server, returning True and setting the servers IP @@ -394,8 +392,10 @@ got_connection: } /* cache the successful connection for workgroup and realm */ - saf_store( ads->server.workgroup, inet_ntoa(ads->ldap_ip)); - saf_store( ads->server.realm, inet_ntoa(ads->ldap_ip)); + if (ads_sitename_match(ads)) { + saf_store( ads->server.workgroup, inet_ntoa(ads->ldap_ip)); + saf_store( ads->server.realm, inet_ntoa(ads->ldap_ip)); + } ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); -- cgit From 664c3f41660847c110ba81759f71a70c88807a76 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 19 Sep 2006 01:07:40 +0000 Subject: r18663: Fix one more uuid -> GUID. Jeremy. (This used to be commit e568271af2b5c20cff70b72b8ab4b1b704122b40) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7b31586f7d..f9bdb9c651 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2089,7 +2089,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @param guid 37-byte area to receive text guid * @return boolean indicating success **/ - BOOL ads_pull_guid(ADS_STRUCT *ads, LDAPMessage *msg, struct uuid *guid) + BOOL ads_pull_guid(ADS_STRUCT *ads, LDAPMessage *msg, struct GUID *guid) { char **values; UUID_FLAT flat_guid; -- cgit From dd992469ddaa849e9a3ec9ae115f574210711c2b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 25 Sep 2006 16:55:19 +0000 Subject: r18902: Also dump mS-DS-CreatorSID. Guenther (This used to be commit e7cae9bbae2848ca1088a822883563062dd3f612) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index f9bdb9c651..89c34f03a9 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1724,6 +1724,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) {"tokenGroups", False, dump_sid}, {"tokenGroupsNoGCAcceptable", False, dump_sid}, {"tokengroupsGlobalandUniversal", False, dump_sid}, + {"mS-DS-CreatorSID", False, dump_sid}, {NULL, True, NULL} }; int i; -- cgit From f7633eca1824f7a5bda733e6753d5d1f850f78c3 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 26 Sep 2006 16:27:18 +0000 Subject: r18923: Fix more memleaks. Guenther (This used to be commit ecb632a1534d5178602b9143bb17712559fe2e4f) --- source3/libads/ldap.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 89c34f03a9..6077231ae2 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2458,9 +2458,12 @@ ADS_STATUS ads_site_dn(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **site_n service_name = ads_pull_string(ads, mem_ctx, res, "dsServiceName"); if (service_name == NULL) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); } + ads_msgfree(ads, res); + /* go up three levels */ dn = ads_parent_dn(ads_parent_dn(ads_parent_dn(service_name))); if (dn == NULL) { @@ -2472,8 +2475,6 @@ ADS_STATUS ads_site_dn(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **site_n return ADS_ERROR(LDAP_NO_MEMORY); } - ads_msgfree(ads, res); - return status; /* dsServiceName: CN=NTDS Settings,CN=W2K3DC,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=ber,DC=suse,DC=de @@ -2508,37 +2509,45 @@ ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const c config_context = ads_pull_string(ads, mem_ctx, res, "configurationNamingContext"); if (config_context == NULL) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } filter = talloc_asprintf(mem_ctx, "(cn=%s)", computer_name); if (filter == NULL) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } + ads_msgfree(ads, res); + status = ads_do_search(ads, config_context, LDAP_SCOPE_SUBTREE, filter, NULL, &res); if (!ADS_ERR_OK(status)) { return status; } if (ads_count_replies(ads, res) != 1) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } dn = ads_get_dn(ads, res); if (dn == NULL) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } /* go up three levels */ parent = ads_parent_dn(ads_parent_dn(ads_parent_dn(dn))); if (parent == NULL) { + ads_msgfree(ads, res); ads_memfree(ads, dn); return ADS_ERROR(LDAP_NO_MEMORY); } *site_dn = talloc_strdup(mem_ctx, parent); if (*site_dn == NULL) { + ads_msgfree(ads, res); ads_memfree(ads, dn); ADS_ERROR(LDAP_NO_MEMORY); } -- cgit From 424d7640b8d3a3e7f464ae429322b943985c11fe Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 13 Oct 2006 09:44:54 +0000 Subject: r19263: Be more accurate in telling what the sitename problem is in this DEBUG statement. Guenther (This used to be commit 62928734b820f512f940c1ed79048e14b322d060) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6077231ae2..2b36d5575e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -133,7 +133,7 @@ BOOL ads_sitename_match(ADS_STRUCT *ads) DEBUG(10,("ads_sitename_match: name %s match\n", ads->config.server_site_name)); return True; } - DEBUG(10,("ads_sitename_match: no match %s %s\n", + DEBUG(10,("ads_sitename_match: no match between server: %s and client: %s\n", ads->config.server_site_name ? ads->config.server_site_name : "NULL", ads->config.client_site_name ? ads->config.client_site_name : "NULL")); return False; -- cgit From 6b65a1c26dabfa8311592f7277c09d69e9b76226 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 1 Nov 2006 11:04:28 +0000 Subject: r19526: Fix minor memleak. Guenther (This used to be commit 61ebedc82ee7d7a98e2a52b0677d723a801ab30f) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2b36d5575e..6fbae51179 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1232,6 +1232,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) } ret = ldap_delete_s(ads->ld, utf8_dn); + SAFE_FREE(utf8_dn); return ADS_ERROR(ret); } -- cgit From 31a63ab19f2a1f717db90d1164a8b696c625e739 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 1 Nov 2006 11:19:33 +0000 Subject: r19528: Fix container handling for "net ads user" and "net ads group" functions along with some memleaks. Guenther (This used to be commit 4bad52c5b3a983418d4216a2c3f5e04926e37e94) --- source3/libads/ldap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6fbae51179..1e726f5e55 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1299,6 +1299,7 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) SAFE_FREE(base); if (ads_count_replies(ads, res) != 1) { + ads_msgfree(ads, res); return NULL; } @@ -1314,7 +1315,7 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) new_ln = wkn_ln - bind_ln; - ret = wkn_dn_exp[0]; + ret = SMB_STRDUP(wkn_dn_exp[0]); for (i=1; i < new_ln; i++) { char *s; @@ -1323,6 +1324,7 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) free(s); } + ads_msgfree(ads, res); ads_memfree(ads, wkn_dn); ldap_value_free(wkn_dn_exp); ldap_value_free(bind_dn_exp); -- cgit From e513fb27d61d31cdc1a0e723c5345a659cc2caf2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 9 Nov 2006 10:16:38 +0000 Subject: r19646: Fix memleak in the default_ou_string handling. Thanks to David Hu . Fixes #4212. Guenther (This used to be commit 4ec896cdbe441b17d91895a50ac9be61efe2f9c1) --- source3/libads/ldap.c | 48 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1e726f5e55..927b86fe93 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1276,8 +1276,8 @@ char *ads_ou_string(ADS_STRUCT *ads, const char *org_unit) char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) { ADS_STATUS status; - LDAPMessage *res; - char *base, *wkn_dn, *ret, **wkn_dn_exp, **bind_dn_exp; + LDAPMessage *res = NULL; + char *base, *wkn_dn, *ret = NULL, **wkn_dn_exp, **bind_dn_exp; const char *attrs[] = {"distinguishedName", NULL}; int new_ln, wkn_ln, bind_ln, i; @@ -1293,20 +1293,28 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) status = ads_search_dn(ads, &res, base, attrs); if (!ADS_ERR_OK(status)) { DEBUG(1,("Failed while searching for: %s\n", base)); - SAFE_FREE(base); - return NULL; + goto out; } - SAFE_FREE(base); if (ads_count_replies(ads, res) != 1) { - ads_msgfree(ads, res); - return NULL; + goto out; } /* substitute the bind-path from the well-known-guid-search result */ wkn_dn = ads_get_dn(ads, res); + if (!wkn_dn) { + goto out; + } + wkn_dn_exp = ldap_explode_dn(wkn_dn, 0); + if (!wkn_dn_exp) { + goto out; + } + bind_dn_exp = ldap_explode_dn(ads->config.bind_path, 0); + if (!bind_dn_exp) { + goto out; + } for (wkn_ln=0; wkn_dn_exp[wkn_ln]; wkn_ln++) ; @@ -1316,18 +1324,36 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) new_ln = wkn_ln - bind_ln; ret = SMB_STRDUP(wkn_dn_exp[0]); + if (!ret) { + goto out; + } for (i=1; i < new_ln; i++) { - char *s; - asprintf(&s, "%s,%s", ret, wkn_dn_exp[i]); + char *s = NULL; + + if (asprintf(&s, "%s,%s", ret, wkn_dn_exp[i]) == -1) { + SAFE_FREE(ret); + goto out; + } + + SAFE_FREE(ret); ret = SMB_STRDUP(s); free(s); + if (!ret) { + goto out; + } } + out: + SAFE_FREE(base); ads_msgfree(ads, res); ads_memfree(ads, wkn_dn); - ldap_value_free(wkn_dn_exp); - ldap_value_free(bind_dn_exp); + if (wkn_dn_exp) { + ldap_value_free(wkn_dn_exp); + } + if (bind_dn_exp) { + ldap_value_free(bind_dn_exp); + } return ret; } -- cgit From 61a38bd4b83b7f72b479e84daa5ea89164a92f85 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 10 Nov 2006 12:42:50 +0000 Subject: r19651: Fix interesting bug with the automatic site coverage in Active Directory: When having DC-less sites, AD assigns DCs from other sites to that site that does not have it's own DC. The most reliable way for us to identify the nearest DC - in that and all other cases - is the closest_dc flag in the CLDAP reply. Guenther (This used to be commit ff004f7284cb047e738ba3d3ad6602e8aa84e883) --- source3/libads/ldap.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 927b86fe93..5dcc3c33ba 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -139,6 +139,30 @@ BOOL ads_sitename_match(ADS_STRUCT *ads) return False; } +/********************************************** + Is this the closest DC ? +**********************************************/ + +BOOL ads_closest_dc(ADS_STRUCT *ads) +{ + if (ads->config.flags & ADS_CLOSEST) { + DEBUG(10,("ads_closest_dc: ADS_CLOSEST flag set\n")); + return True; + } + + /* not sure if this can ever happen */ + if (ads_sitename_match(ads)) { + DEBUG(10,("ads_closest_dc: ADS_CLOSEST flag not set but sites match\n")); + return True; + } + + DEBUG(10,("ads_closest_dc: %s is not the closest DC\n", + ads->config.ldap_server_name)); + + return False; +} + + /* try a connection to a given ldap server, returning True and setting the servers IP in the ads struct if successful @@ -392,7 +416,7 @@ got_connection: } /* cache the successful connection for workgroup and realm */ - if (ads_sitename_match(ads)) { + if (ads_closest_dc(ads)) { saf_store( ads->server.workgroup, inet_ntoa(ads->ldap_ip)); saf_store( ads->server.realm, inet_ntoa(ads->ldap_ip)); } -- cgit From bae1fcd20fb01942b40fddf7893d54063cf5ac95 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 13 Nov 2006 10:34:59 +0000 Subject: r19687: Fix uninitialized variables found by Coverity (and gcc -O1... ;-)) Volker (This used to be commit b7dc9b81696aa5434419c5378a47b41c6dee3dfa) --- source3/libads/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 5dcc3c33ba..f65ae02ede 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1301,7 +1301,8 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) { ADS_STATUS status; LDAPMessage *res = NULL; - char *base, *wkn_dn, *ret = NULL, **wkn_dn_exp, **bind_dn_exp; + char *base, *wkn_dn = NULL, *ret = NULL, **wkn_dn_exp = NULL, + **bind_dn_exp = NULL; const char *attrs[] = {"distinguishedName", NULL}; int new_ln, wkn_ln, bind_ln, i; -- cgit From d3fc370fb9e32b881bb6c626ac525246af665ea4 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 2 Jan 2007 21:45:12 +0000 Subject: r20487: Remove the unused dn2ad_canonical() call (This used to be commit 86e6ae6a9fe2a6fdaeeb503653a312662c7f50e9) --- source3/libads/ldap.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index f65ae02ede..c263e8e133 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -978,21 +978,6 @@ void ads_memfree(ADS_STRUCT *ads, void *mem) return unix_dn; } -/** - * Get a canonical dn from search results - * @param ads connection to ads server - * @param msg Search result - * @return dn string - **/ - char *ads_get_dn_canonical(ADS_STRUCT *ads, LDAPMessage *msg) -{ -#ifdef HAVE_LDAP_DN2AD_CANONICAL - return ldap_dn2ad_canonical(ads_get_dn(ads, msg)); -#else - return NULL; -#endif -} - /** * Get the parent from a dn * @param dn the dn to return the parent from @@ -2938,8 +2923,6 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name, } #endif -#ifdef HAVE_LDAP - /** * Delete a machine from the realm * @param ads connection to ads server @@ -3059,6 +3042,5 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) SAFE_FREE(host); return status; } -#endif #endif -- cgit From bfd099e148ed97394bc858e746a1a998a71ac43c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Jan 2007 18:25:35 +0000 Subject: r20857: Silence gives assent :-). Checking in the fix for site support in a network where many DC's are down. I heard via Volker there is still a bug w.r.t the wrong site being chosen with trusted domains but we'll have to layer that fix on top of this. Gd - complain if this doesn't work for you. Jeremy. (This used to be commit 97e248f89ac6548274f03f2ae7583a255da5ddb3) --- source3/libads/ldap.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c263e8e133..2ceae4d957 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -249,6 +249,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) pstring realm; BOOL got_realm = False; BOOL use_own_domain = False; + char *sitename = sitename_fetch(); NTSTATUS status = NT_STATUS_UNSUCCESSFUL; /* if the realm and workgroup are both empty, assume they are ours */ @@ -279,6 +280,7 @@ again: } if ( !c_realm || !*c_realm ) { + SAFE_FREE(sitename); DEBUG(0,("ads_find_dc: no realm or workgroup! Don't know what to do\n")); return NT_STATUS_INVALID_PARAMETER; /* rather need MISSING_PARAMETER ... */ } @@ -289,7 +291,7 @@ again: DEBUG(6,("ads_find_dc: looking for %s '%s'\n", (got_realm ? "realm" : "domain"), realm)); - status = get_sorted_dc_list(realm, &ip_list, &count, got_realm); + status = get_sorted_dc_list(realm, sitename, &ip_list, &count, got_realm); if (!NT_STATUS_IS_OK(status)) { /* fall back to netbios if we can */ if ( got_realm && !lp_disable_netbios() ) { @@ -331,6 +333,7 @@ again: if ( ads_try_connect(ads, server) ) { SAFE_FREE(ip_list); + SAFE_FREE(sitename); return NT_STATUS_OK; } @@ -339,7 +342,19 @@ again: } SAFE_FREE(ip_list); - + + /* In case we failed to contact one of our closest DC on our site we + * need to try to find another DC, retry with a site-less SRV DNS query + * - Guenther */ + + if (sitename) { + DEBUG(1,("ads_find_dc: failed to find a valid DC on our site (%s), " + "trying to find another DC\n", sitename)); + SAFE_FREE(sitename); + namecache_delete(realm, 0x1C); + goto again; + } + return NT_STATUS_NO_LOGON_SERVERS; } -- cgit From e9c294b926c0b831fd936194342ec0564f935798 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 18 Jan 2007 09:58:57 +0000 Subject: r20874: We need to distinguish client sitenames per realm. We were overwriting the stored client sitename with the sitename from each sucessfull CLDAP connection. Guenther (This used to be commit 6a13e878b5d299cb3b3d7cb33ee0d51089d9228d) --- source3/libads/ldap.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2ceae4d957..4802f79d3e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -230,7 +230,7 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) SAFE_FREE(srv); /* Store our site name. */ - sitename_store( cldap_reply.client_site_name ); + sitename_store( cldap_reply.domain, cldap_reply.client_site_name ); return True; } @@ -249,7 +249,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) pstring realm; BOOL got_realm = False; BOOL use_own_domain = False; - char *sitename = sitename_fetch(); + char *sitename; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; /* if the realm and workgroup are both empty, assume they are ours */ @@ -268,7 +268,6 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) if (c_realm && *c_realm) got_realm = True; -again: /* we need to try once with the realm name and fallback to the netbios domain name if we fail (if netbios has not been disabled */ @@ -280,7 +279,6 @@ again: } if ( !c_realm || !*c_realm ) { - SAFE_FREE(sitename); DEBUG(0,("ads_find_dc: no realm or workgroup! Don't know what to do\n")); return NT_STATUS_INVALID_PARAMETER; /* rather need MISSING_PARAMETER ... */ } @@ -288,6 +286,10 @@ again: pstrcpy( realm, c_realm ); + sitename = sitename_fetch(realm); + + again: + DEBUG(6,("ads_find_dc: looking for %s '%s'\n", (got_realm ? "realm" : "domain"), realm)); -- cgit From 8751923635b93b0c53d7939e34fb8747e025ca59 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 25 Jan 2007 16:54:53 +0000 Subject: r21021: Fix memleak. Guenther (This used to be commit 4e622572eb7939c6aa8e99fd9595bf28836bd5a3) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 4802f79d3e..d72cb4af26 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -301,6 +301,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) goto again; } + SAFE_FREE(sitename); return status; } -- cgit From 08726ffcd47eeb68eb7724e09d25322417517513 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 14 Feb 2007 20:52:23 +0000 Subject: r21349: Fix memleak in ads_upn_suffixes(). Guenther (This used to be commit 8462f323cf86f90b1bdf14a3953c5a4bda1b9533) --- source3/libads/ldap.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d72cb4af26..949d167013 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2638,9 +2638,12 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **suffixe config_context = ads_pull_string(ads, mem_ctx, res, "configurationNamingContext"); if (config_context == NULL) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } + ads_msgfree(ads, res); + base = talloc_asprintf(mem_ctx, "cn=Partitions,%s", config_context); if (base == NULL) { return ADS_ERROR(LDAP_NO_MEMORY); -- cgit From 5aa3b27949009bafe1e85d468b191f33c4c29293 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 15 Feb 2007 00:03:38 +0000 Subject: r21352: Let ads_upn_suffixes() return a pointer to an array of suffixes. Guenther (This used to be commit 7ad7847e5bbdd90fa6ae9ce91e5962f524ac2890) --- source3/libads/ldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 949d167013..dfc68fdc2b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2620,10 +2620,10 @@ ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const c * @param ads connection to ads server * @param mem_ctx Pointer to talloc context * @param suffixes Pointer to an array of suffixes - * @param site_name Pointer to the number of suffixes + * @param num_suffixes Pointer to the number of suffixes * @return status of search **/ -ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **suffixes, size_t *num_suffixes) +ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char ***suffixes, size_t *num_suffixes) { ADS_STATUS status; LDAPMessage *res; @@ -2658,8 +2658,8 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **suffixe return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } - suffixes = ads_pull_strings(ads, mem_ctx, res, "uPNSuffixes", num_suffixes); - if (suffixes == NULL) { + (*suffixes) = ads_pull_strings(ads, mem_ctx, res, "uPNSuffixes", num_suffixes); + if ((*suffixes) == NULL) { ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } -- cgit From e9e6af59510242fbc78fd2100026d8dc79f18773 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 1 Mar 2007 00:49:28 +0000 Subject: r21606: Implement escaping function for ldap RDN values Fix escaping of DN components and filters around the code Add some notes to commandline help messages about how to pass DNs revert jra's "concistency" commit to nsswitch/winbindd_ads.c, as it was incorrect. The 2 functions use DNs in different ways. - lookup_usergroups_member() uses the DN in a search filter, and must use the filter escaping function to escape it Escaping filters that include escaped DNs ("\," becomes "\5c,") is the correct way to do it (tested against W2k3). - lookup_usergroups_memberof() instead uses the DN ultimately as a base dn. Both functions do NOT need any DN escaping function as DNs can't be reliably escaped when in a string form, intead each single RDN value must be escaped separately. DNs coming from other ldap calls (like ads_get_dn()), do not need escaping as they come already escaped on the wire and passed as is by the ldap libraries DN filtering has been tested. For example now it is possible to do something like: 'net ads add user joe#5' as now the '#' character is correctly escaped when building the DN, previously such a call failed with Invalid DN Syntax. Simo. (This used to be commit 5b4838f62ab1a92bfe02626ef40d7f94c2598322) --- source3/libads/ldap.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index dfc68fdc2b..e9d8bf6bbf 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1635,6 +1635,7 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, char *samAccountName, *controlstr; TALLOC_CTX *ctx; ADS_MODLIST mods; + char *machine_escaped; char *new_dn; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; @@ -1647,8 +1648,13 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, return ADS_ERROR(LDAP_NO_MEMORY); ret = ADS_ERROR(LDAP_NO_MEMORY); - - new_dn = talloc_asprintf(ctx, "cn=%s,%s", machine_name, org_unit); + + machine_escaped = escape_rdn_val_string_alloc(machine_name); + if (!machine_escaped) { + goto done; + } + + new_dn = talloc_asprintf(ctx, "cn=%s,%s", machine_escaped, org_unit); samAccountName = talloc_asprintf(ctx, "%s$", machine_name); if ( !new_dn || !samAccountName ) { -- cgit From fae01b48994fd3168fd921af68dab1b4003adc49 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 1 Mar 2007 01:17:36 +0000 Subject: r21608: Fix a couple of memleaks in error code paths before Coverity finds them :-) Jeremy. (This used to be commit cbe725f1b09f3d0edbdf823e0862edf21e16d336) --- source3/libads/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e9d8bf6bbf..1d08a01a26 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1635,7 +1635,7 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, char *samAccountName, *controlstr; TALLOC_CTX *ctx; ADS_MODLIST mods; - char *machine_escaped; + char *machine_escaped = NULL; char *new_dn; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; @@ -1681,6 +1681,7 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, ret = ads_gen_add(ads, new_dn, mods); done: + SAFE_FREE(machine_escaped); ads_msgfree(ads, res); talloc_destroy(ctx); -- cgit From 725fcf3461f7684554938c5571a5013408ff431c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 6 Apr 2007 21:55:44 +0000 Subject: r22112: Fix memleak pointed out by Steven Danneman . Jeremy. (This used to be commit 7c45bd3a47fc2b24c5f1351a241ace2201c857d2) --- source3/libads/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1d08a01a26..b2ca68f67f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2258,7 +2258,6 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) LDAPMessage *msg, const char *field, SEC_DESC **sd) { struct berval **values; - prs_struct ps; BOOL ret = False; values = ldap_get_values_len(ads->ld, msg, field); @@ -2266,11 +2265,13 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) if (!values) return False; if (values[0]) { + prs_struct ps; prs_init(&ps, values[0]->bv_len, mem_ctx, UNMARSHALL); prs_copy_data_in(&ps, values[0]->bv_val, values[0]->bv_len); prs_set_offset(&ps,0); ret = sec_io_desc("sd", sd, &ps, 1); + prs_mem_free(&ps); } ldap_value_free_len(values); -- cgit From 8040fec0accd93b7932c1c81520540ea46c33eb6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sun, 22 Apr 2007 15:13:50 +0000 Subject: r22459: Adding ads_get_dn_from_extended_dn(), in preparation of making ranged LDAP queries more generic. Michael, feel free to overwrite these and the following. Guenther (This used to be commit 0475b8eea99ebb467e52225ad54f4302a77376b9) --- source3/libads/ldap.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b2ca68f67f..6707cbd4d0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2677,24 +2677,58 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char ***suffix return status; } +/** + * pull a dn from an extended dn string + * @param mem_ctx TALLOC_CTX + * @param extended_dn string + * @param dn pointer to the dn + * @return boolean inidicating success + **/ +BOOL ads_get_dn_from_extended_dn(TALLOC_CTX *mem_ctx, + const char *extended_dn, + char **dn) +{ + char *p; + pstring tok; + + if (!extended_dn) { + return False; + } + + while (next_token(&extended_dn, tok, ";", sizeof(tok))) { + p = tok; + } + + if ((*dn = talloc_strdup(mem_ctx, p)) == NULL) { + return False; + } + + return True; +} + /** * pull a DOM_SID from an extended dn string * @param mem_ctx TALLOC_CTX + * @param extended_dn string * @param flags string type of extended_dn * @param sid pointer to a DOM_SID * @return boolean inidicating success **/ BOOL ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, - const char *dn, + const char *extended_dn, enum ads_extended_dn_flags flags, DOM_SID *sid) { - char *p, *q; + char *p, *q, *dn; - if (!dn) { + if (!extended_dn) { return False; } + /* otherwise extended_dn gets stripped off */ + if ((dn = talloc_strdup(mem_ctx, extended_dn)) == NULL) { + return False; + } /* * ADS_EXTENDED_DN_HEX_STRING: * ;;CN=gd,OU=berlin,OU=suse,DC=ber,DC=suse,DC=de -- cgit From be8b0685a55700c6bce3681734800ec6434b0364 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 30 Apr 2007 02:39:34 +0000 Subject: r22589: Make TALLOC_ARRAY consistent across all uses. Jeremy. (This used to be commit 8968808c3b5b0208cbad9ac92eaf948f2c546dd9) --- source3/libads/ldap.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6707cbd4d0..5a34385c32 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2225,10 +2225,14 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) for (i=0; values[i]; i++) /* nop */ ; - (*sids) = TALLOC_ARRAY(mem_ctx, DOM_SID, i); - if (!(*sids)) { - ldap_value_free_len(values); - return 0; + if (i) { + (*sids) = TALLOC_ARRAY(mem_ctx, DOM_SID, i); + if (!(*sids)) { + ldap_value_free_len(values); + return 0; + } + } else { + (*sids) = NULL; } count = 0; -- cgit From 3eca3af1bcd92e575b8c5d1034efd8d516df5e6c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sun, 6 May 2007 21:45:53 +0000 Subject: r22728: Patch from Danilo Almeida : When asked to create a machine account in an OU as part of "net ads join" and the account already exists in another OU, simply move the machine object to the requested OU. (This used to be commit 3004cc6e593e6659a618de66f659f579e71c07f7) --- source3/libads/ldap.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 5a34385c32..af4347c147 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1688,6 +1688,76 @@ done: return ret; } +/** + * move a machine account to another OU on the ADS server + * @param ads - An intialized ADS_STRUCT + * @param machine_name - the NetBIOS machine name of this account. + * @param org_unit - The LDAP path in which to place this account + * @param moved - whether we moved the machine account (optional) + * @return 0 upon success, or non-zero otherwise +**/ + +ADS_STATUS ads_move_machine_acct(ADS_STRUCT *ads, const char *machine_name, + const char *org_unit, BOOL *moved) +{ + ADS_STATUS rc; + int ldap_status; + LDAPMessage *res = NULL; + char *filter = NULL; + char *computer_dn = NULL; + char *parent_dn; + char *computer_rdn = NULL; + BOOL need_move = False; + + if (asprintf(&filter, "(samAccountName=%s$)", machine_name) == -1) { + rc = ADS_ERROR(LDAP_NO_MEMORY); + goto done; + } + + /* Find pre-existing machine */ + rc = ads_search(ads, &res, filter, NULL); + if (!ADS_ERR_OK(rc)) { + goto done; + } + + computer_dn = ads_get_dn(ads, res); + if (!computer_dn) { + rc = ADS_ERROR(LDAP_NO_MEMORY); + goto done; + } + + parent_dn = ads_parent_dn(computer_dn); + if (strequal(parent_dn, org_unit)) { + goto done; + } + + need_move = True; + + if (asprintf(&computer_rdn, "CN=%s", machine_name) == -1) { + rc = ADS_ERROR(LDAP_NO_MEMORY); + goto done; + } + + ldap_status = ldap_rename2_s(ads->ld, computer_dn, computer_rdn, org_unit, 1); + rc = ADS_ERROR(ldap_status); + +done: + ads_msgfree(ads, res); + SAFE_FREE(filter); + SAFE_FREE(computer_dn); + SAFE_FREE(computer_rdn); + + if (!ADS_ERR_OK(rc)) { + need_move = False; + } + + if (moved) { + *moved = need_move; + } + + return rc; +} + /* dump a binary result from ldap */ -- cgit From 9c170fce2632e76bda6bb9a644777c978785cff1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 11 May 2007 12:52:48 +0000 Subject: r22797: We are only interested in the DACL of the security descriptor, so search with the SD_FLAGS control. Guenther (This used to be commit 648df57e53ddabe74052e816b8eba95180736208) --- source3/libads/ldap.c | 54 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 19 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index af4347c147..ff416b0085 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -570,11 +570,11 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, { int rc, i, version; char *utf8_expr, *utf8_path, **search_attrs; - LDAPControl PagedResults, NoReferrals, ExtendedDn, *controls[4], **rcontrols; + LDAPControl PagedResults, NoReferrals, ExternalCtrl, *controls[4], **rcontrols; BerElement *cookie_be = NULL; struct berval *cookie_bv= NULL; - BerElement *extdn_be = NULL; - struct berval *extdn_bv= NULL; + BerElement *ext_be = NULL; + struct berval *ext_bv= NULL; TALLOC_CTX *ctx; ads_control *external_control = (ads_control *) args; @@ -604,7 +604,6 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, } } - /* Paged results only available on ldap v3 or later */ ldap_get_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); if (version < LDAP_VERSION3) { @@ -631,40 +630,42 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, NoReferrals.ldctl_value.bv_len = 0; NoReferrals.ldctl_value.bv_val = CONST_DISCARD(char *, ""); - if (external_control && strequal(external_control->control, ADS_EXTENDED_DN_OID)) { + if (external_control && + (strequal(external_control->control, ADS_EXTENDED_DN_OID) || + strequal(external_control->control, ADS_SD_FLAGS_OID))) { - ExtendedDn.ldctl_oid = CONST_DISCARD(char *, external_control->control); - ExtendedDn.ldctl_iscritical = (char) external_control->critical; + ExternalCtrl.ldctl_oid = CONST_DISCARD(char *, external_control->control); + ExternalCtrl.ldctl_iscritical = (char) external_control->critical; /* win2k does not accept a ldctl_value beeing passed in */ if (external_control->val != 0) { - if ((extdn_be = ber_alloc_t(LBER_USE_DER)) == NULL ) { + if ((ext_be = ber_alloc_t(LBER_USE_DER)) == NULL ) { rc = LDAP_NO_MEMORY; goto done; } - if ((ber_printf(extdn_be, "{i}", (ber_int_t) external_control->val)) == -1) { + if ((ber_printf(ext_be, "{i}", (ber_int_t) external_control->val)) == -1) { rc = LDAP_NO_MEMORY; goto done; } - if ((ber_flatten(extdn_be, &extdn_bv)) == -1) { + if ((ber_flatten(ext_be, &extdn_bv)) == -1) { rc = LDAP_NO_MEMORY; goto done; } - ExtendedDn.ldctl_value.bv_len = extdn_bv->bv_len; - ExtendedDn.ldctl_value.bv_val = extdn_bv->bv_val; + ExternalCtrl.ldctl_value.bv_len = ext_bv->bv_len; + ExternalCtrl.ldctl_value.bv_val = ext_bv->bv_val; } else { - ExtendedDn.ldctl_value.bv_len = 0; - ExtendedDn.ldctl_value.bv_val = NULL; + ExternalCtrl.ldctl_value.bv_len = 0; + ExternalCtrl.ldctl_value.bv_val = NULL; } controls[0] = &NoReferrals; controls[1] = &PagedResults; - controls[2] = &ExtendedDn; + controls[2] = &ExternalCtrl; controls[3] = NULL; } else { @@ -725,12 +726,12 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, done: talloc_destroy(ctx); - if (extdn_be) { - ber_free(extdn_be, 1); + if (ext_be) { + ber_free(ext_be, 1); } - if (extdn_bv) { - ber_bvfree(extdn_bv); + if (ext_bv) { + ber_bvfree(ext_bv); } /* if/when we decide to utf8-encode attrs, take out this next line */ @@ -810,6 +811,21 @@ static ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, return ads_do_search_all_args(ads, bind_path, scope, expr, attrs, NULL, res); } + ADS_STATUS ads_do_search_all_sd_flags(ADS_STRUCT *ads, const char *bind_path, + int scope, const char *expr, + const char **attrs, uint32 sd_flags, + LDAPMessage **res) +{ + ads_control args; + + args.control = ADS_SD_FLAGS_OID; + args.val = sd_flags; + args.critical = True; + + return ads_do_search_all_args(ads, bind_path, scope, expr, attrs, &args, res); +} + + /** * Run a function on all results for a search. Uses ads_do_paged_search() and * runs the function as each page is returned, using ads_process_results() -- cgit From 75a0171857001bda9ac321e5f02dce516343f0ae Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 11 May 2007 13:19:49 +0000 Subject: r22799: Fix the build. Guenther (This used to be commit 6e911c442bf9b076f43f99576f9b588df2c39233) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ff416b0085..48be73230e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -650,7 +650,7 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, rc = LDAP_NO_MEMORY; goto done; } - if ((ber_flatten(ext_be, &extdn_bv)) == -1) { + if ((ber_flatten(ext_be, &ext_bv)) == -1) { rc = LDAP_NO_MEMORY; goto done; } -- cgit From 83564b43e3b8194b89e0fb8547a968e4f2ff022b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 11 May 2007 13:33:37 +0000 Subject: r22800: Add GPO_SID_TOKEN and an LDAP function to get tokensids from the tokenGroup attribute. Guenther (This used to be commit e4e8f840605dfdf92ca60cc8fc6a4c85336565fb) --- source3/libads/ldap.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 48be73230e..f5f273d3f2 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3196,4 +3196,108 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return status; } +/** + * pull all token-sids from an LDAP dn + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX for allocating sid array + * @param dn of LDAP object + * @param user_sid pointer to DOM_SID (objectSid) + * @param primary_group_sid pointer to DOM_SID (self composed) + * @param sids pointer to sid array to allocate + * @param num_sids counter of SIDs pulled + * @return status of token query + **/ + ADS_STATUS ads_get_tokensids(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *dn, + DOM_SID *user_sid, + DOM_SID *primary_group_sid, + DOM_SID **sids, + size_t *num_sids) +{ + ADS_STATUS status; + LDAPMessage *res = NULL; + int count = 0; + size_t tmp_num_sids; + DOM_SID *tmp_sids; + DOM_SID tmp_user_sid; + DOM_SID tmp_primary_group_sid; + uint32 pgid; + const char *attrs[] = { + "objectSid", + "tokenGroups", + "primaryGroupID", + NULL + }; + + status = ads_search_retry_dn(ads, &res, dn, attrs); + if (!ADS_ERR_OK(status)) { + return status; + } + + count = ads_count_replies(ads, res); + if (count != 1) { + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_NO_SUCH_OBJECT); + } + + if (!ads_pull_sid(ads, res, "objectSid", &tmp_user_sid)) { + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + + if (!ads_pull_uint32(ads, res, "primaryGroupID", &pgid)) { + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + + { + /* hack to compose the primary group sid without knowing the + * domsid */ + + DOM_SID domsid; + uint32 dummy_rid; + + sid_copy(&domsid, &tmp_user_sid); + + if (!sid_split_rid(&domsid, &dummy_rid)) { + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + + if (!sid_compose(&tmp_primary_group_sid, &domsid, pgid)) { + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + } + + tmp_num_sids = ads_pull_sids(ads, mem_ctx, res, "tokenGroups", &tmp_sids); + + if (tmp_num_sids == 0 || !tmp_sids) { + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + + if (num_sids) { + *num_sids = tmp_num_sids; + } + + if (sids) { + *sids = tmp_sids; + } + + if (user_sid) { + *user_sid = tmp_user_sid; + } + + if (primary_group_sid) { + *primary_group_sid = tmp_primary_group_sid; + } + + DEBUG(10,("ads_get_tokensids: returned %d sids\n", (int)tmp_num_sids + 2)); + + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_SUCCESS); +} + #endif -- cgit From 2753d30cbea6cc6689cda17182caff20d65c6f6c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 15 May 2007 10:47:40 +0000 Subject: r22893: Use ldap_rename_s instead of deprecated ldap_rename2_s. This fixes the build on solaris (host sun9). And hopefully doesn't break any other builds... :-) If it does, we need some configure magic. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks to Björn Jacke . (This used to be commit a43775ab36aa3d36108e1b5860bbee6c47e9b1b4) --- source3/libads/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index f5f273d3f2..5b87017d84 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1754,7 +1754,8 @@ ADS_STATUS ads_move_machine_acct(ADS_STRUCT *ads, const char *machine_name, goto done; } - ldap_status = ldap_rename2_s(ads->ld, computer_dn, computer_rdn, org_unit, 1); + ldap_status = ldap_rename_s(ads->ld, computer_dn, computer_rdn, + org_unit, 1, NULL, NULL); rc = ADS_ERROR(ldap_status); done: -- cgit From 5a80fa5c0c461404f6f4dc3b4218d6f235796fff Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 16 Jun 2007 00:39:52 +0000 Subject: r23514: Remove unused function ads_get_dn_from_extended_dn(). Jeremy. (This used to be commit 03763bc5287fef5f100c911041668e23d4305f8d) --- source3/libads/ldap.c | 29 ----------------------------- 1 file changed, 29 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 5b87017d84..d60afcd0d5 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2768,35 +2768,6 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char ***suffix return status; } -/** - * pull a dn from an extended dn string - * @param mem_ctx TALLOC_CTX - * @param extended_dn string - * @param dn pointer to the dn - * @return boolean inidicating success - **/ -BOOL ads_get_dn_from_extended_dn(TALLOC_CTX *mem_ctx, - const char *extended_dn, - char **dn) -{ - char *p; - pstring tok; - - if (!extended_dn) { - return False; - } - - while (next_token(&extended_dn, tok, ";", sizeof(tok))) { - p = tok; - } - - if ((*dn = talloc_strdup(mem_ctx, p)) == NULL) { - return False; - } - - return True; -} - /** * pull a DOM_SID from an extended dn string * @param mem_ctx TALLOC_CTX -- cgit From 221d06d6f3e9789bf3efc6fa52dd94e68b1804cf Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 9 Jul 2007 16:03:00 +0000 Subject: r23772: Add ads_find_samaccount() helper function. Guenther (This used to be commit 6fafa64bea4ce6a7a5917fa02ed9c564a7c93ffb) --- source3/libads/ldap.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d60afcd0d5..6f0ca3452c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3272,4 +3272,64 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return ADS_ERROR_LDAP(LDAP_SUCCESS); } +ADS_STATUS ads_find_samaccount(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *samaccountname, + uint32 *uac_ret, + const char **dn_ret) +{ + ADS_STATUS status; + const char *attrs[] = { "userAccountControl", NULL }; + const char *filter; + LDAPMessage *res = NULL; + char *dn = NULL; + uint32 uac = 0; + + filter = talloc_asprintf(mem_ctx, "(&(objectclass=user)(sAMAccountName=%s))", + samaccountname); + if (filter == NULL) { + goto out; + } + + status = ads_do_search_all(ads, ads->config.bind_path, + LDAP_SCOPE_SUBTREE, + filter, attrs, &res); + + if (!ADS_ERR_OK(status)) { + goto out; + } + + if (ads_count_replies(ads, res) != 1) { + printf("no result\n"); + goto out; + } + + dn = ads_get_dn(ads, res); + if (dn == NULL) { + status = ADS_ERROR(LDAP_NO_MEMORY); + goto out; + } + + if (!ads_pull_uint32(ads, res, "userAccountControl", &uac)) { + status = ADS_ERROR(LDAP_NO_SUCH_ATTRIBUTE); + goto out; + } + + if (uac_ret) { + *uac_ret = uac; + } + + if (dn_ret) { + *dn_ret = talloc_strdup(mem_ctx, dn); + if (!*dn_ret) { + status = ADS_ERROR(LDAP_NO_MEMORY); + goto out; + } + } + out: + ads_memfree(ads, dn); + ads_msgfree(ads, res); + + return status; +} #endif -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6f0ca3452c..a9e946e952 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -9,7 +9,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/libads/ldap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a9e946e952..dd2bf0e344 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -18,8 +18,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" -- cgit From c8e23e4091a85063929aa7d807b0c1b7d7b98d91 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 11 Jul 2007 13:17:42 +0000 Subject: r23833: Document ads_find_samaccount(). Guenther (This used to be commit 3effd1c3461301f9ccf7c55386810c36f4ee3ccc) --- source3/libads/ldap.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index dd2bf0e344..40bba683a4 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3271,6 +3271,15 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return ADS_ERROR_LDAP(LDAP_SUCCESS); } +/** + * Find a sAMAccoutName in LDAP + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX for allocating sid array + * @param samaccountname to search + * @param uac_ret uint32 pointer userAccountControl attribute value + * @param dn_ret pointer to dn + * @return status of token query + **/ ADS_STATUS ads_find_samaccount(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char *samaccountname, -- cgit From c252b04abf31c2cade71a83e8e6c650d7c41f80b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 11 Jul 2007 13:21:32 +0000 Subject: r23834: Allow to pass an ADS_STRUCT pointer down to the dump function callback in libads. Guenther (This used to be commit 311bbbafa6d860b7b632beac6d9249b0a2fafb86) --- source3/libads/ldap.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 40bba683a4..08ef13d039 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -839,7 +839,7 @@ static ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, **/ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, int scope, const char *expr, const char **attrs, - BOOL(*fn)(char *, void **, void *), + BOOL(*fn)(ADS_STRUCT *, char *, void **, void *), void *data_area) { struct berval *cookie = NULL; @@ -1777,7 +1777,7 @@ done: /* dump a binary result from ldap */ -static void dump_binary(const char *field, struct berval **values) +static void dump_binary(ADS_STRUCT *ads, const char *field, struct berval **values) { int i, j; for (i=0; values[i]; i++) { @@ -1789,7 +1789,7 @@ static void dump_binary(const char *field, struct berval **values) } } -static void dump_guid(const char *field, struct berval **values) +static void dump_guid(ADS_STRUCT *ads, const char *field, struct berval **values) { int i; UUID_FLAT guid; @@ -1803,7 +1803,7 @@ static void dump_guid(const char *field, struct berval **values) /* dump a sid result from ldap */ -static void dump_sid(const char *field, struct berval **values) +static void dump_sid(ADS_STRUCT *ads, const char *field, struct berval **values) { int i; for (i=0; values[i]; i++) { @@ -1816,7 +1816,7 @@ static void dump_sid(const char *field, struct berval **values) /* dump ntSecurityDescriptor */ -static void dump_sd(const char *filed, struct berval **values) +static void dump_sd(ADS_STRUCT *ads, const char *filed, struct berval **values) { prs_struct ps; @@ -1859,12 +1859,12 @@ static void dump_string(const char *field, char **values) used for debugging */ -static BOOL ads_dump_field(char *field, void **values, void *data_area) +static BOOL ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *data_area) { const struct { const char *name; BOOL string; - void (*handler)(const char *, struct berval **); + void (*handler)(ADS_STRUCT *, const char *, struct berval **); } handlers[] = { {"objectGUID", False, dump_guid}, {"netbootGUID", False, dump_guid}, @@ -1888,7 +1888,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) 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); + handlers[i].handler(ads, field, (struct berval **) values); break; } } @@ -1924,7 +1924,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) * @param data_area user-defined area to pass to function **/ void ads_process_results(ADS_STRUCT *ads, LDAPMessage *res, - BOOL(*fn)(char *, void **, void *), + BOOL(*fn)(ADS_STRUCT *, char *, void **, void *), void *data_area) { LDAPMessage *msg; @@ -1949,19 +1949,19 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) BOOL string; pull_utf8_talloc(ctx, &field, utf8_field); - string = fn(field, NULL, data_area); + string = fn(ads, field, NULL, data_area); if (string) { utf8_vals = ldap_get_values(ads->ld, (LDAPMessage *)msg, field); str_vals = ads_pull_strvals(ctx, (const char **) utf8_vals); - fn(field, (void **) str_vals, data_area); + fn(ads, 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); + fn(ads, field, (void **) ber_vals, data_area); ldap_value_free_len(ber_vals); } @@ -1969,7 +1969,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area) } ber_free(b, 0); talloc_free_children(ctx); - fn(NULL, NULL, data_area); /* completed an entry */ + fn(ads, NULL, NULL, data_area); /* completed an entry */ } talloc_destroy(ctx); -- cgit From f05dcab9bf3e929f796746420b784525fdf6113e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 11 Jul 2007 13:26:04 +0000 Subject: r23836: Add ads_config_path() and ads_get_extended_right_name_by_guid(). Guenther (This used to be commit 4d62f1191b52569fcdbe674773b07a44aa469520) --- source3/libads/ldap.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 08ef13d039..a1d1a2d649 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3340,4 +3340,97 @@ ADS_STATUS ads_find_samaccount(ADS_STRUCT *ads, return status; } + +/** + * find our configuration path + * @param ads connection to ads server + * @param mem_ctx Pointer to talloc context + * @param config_path Pointer to the config path + * @return status of search + **/ +ADS_STATUS ads_config_path(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + char **config_path) +{ + ADS_STATUS status; + LDAPMessage *res = NULL; + const char *config_context = NULL; + const char *attrs[] = { "configurationNamingContext", NULL }; + + status = ads_do_search(ads, "", LDAP_SCOPE_BASE, + "(objectclass=*)", attrs, &res); + if (!ADS_ERR_OK(status)) { + return status; + } + + config_context = ads_pull_string(ads, mem_ctx, res, + "configurationNamingContext"); + ads_msgfree(ads, res); + if (!config_context) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + if (config_path) { + *config_path = talloc_strdup(mem_ctx, config_context); + if (!*config_path) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + } + + return ADS_ERROR(LDAP_SUCCESS); +} + +/** + * find the displayName of an extended right + * @param ads connection to ads server + * @param config_path The config path + * @param mem_ctx Pointer to talloc context + * @param GUID struct of the rightsGUID + * @return status of search + **/ +const char *ads_get_extended_right_name_by_guid(ADS_STRUCT *ads, + const char *config_path, + TALLOC_CTX *mem_ctx, + const struct GUID *rights_guid) +{ + ADS_STATUS rc; + LDAPMessage *res = NULL; + char *expr = NULL; + const char *attrs[] = { "displayName", NULL }; + const char *result = NULL; + const char *path; + + if (!ads || !mem_ctx || !rights_guid) { + goto done; + } + + expr = talloc_asprintf(mem_ctx, "(rightsGuid=%s)", + smb_uuid_string_static(*rights_guid)); + if (!expr) { + goto done; + } + + path = talloc_asprintf(mem_ctx, "cn=Extended-Rights,%s", config_path); + if (!path) { + goto done; + } + + rc = ads_do_search_retry(ads, path, LDAP_SCOPE_SUBTREE, + expr, attrs, &res); + if (!ADS_ERR_OK(rc)) { + goto done; + } + + if (ads_count_replies(ads, res) != 1) { + goto done; + } + + result = ads_pull_string(ads, mem_ctx, res, "displayName"); + + done: + ads_msgfree(ads, res); + return result; + +} + #endif -- cgit From 9d6f8ed5e7ece2a6bf7a9f51c7dc183932539ff5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 11 Jul 2007 13:30:38 +0000 Subject: r23837: Pass ADS_STRUCT and TALLOC_CTX down to ads_disp_sd. Guenther (This used to be commit ad0a6d5703c35d48ab5bbfa8d6506d42e0cfb61d) --- source3/libads/ldap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a1d1a2d649..32cc82c925 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1837,7 +1837,9 @@ static void dump_sd(ADS_STRUCT *ads, const char *filed, struct berval **values) talloc_destroy(ctx); return; } - if (psd) ads_disp_sd(psd); + if (psd) { + ads_disp_sd(ads, ctx, psd); + } prs_mem_free(&ps); talloc_destroy(ctx); -- cgit From ed0ffc5cef4056121f707a1526688ff323445556 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 13 Jul 2007 09:53:55 +0000 Subject: r23861: Fix return code in ads_find_samaccount(). Guenther (This used to be commit 684fcf39dcc08bcf571272549222fdeb11d2725f) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 32cc82c925..84ceba2406 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3310,7 +3310,7 @@ ADS_STATUS ads_find_samaccount(ADS_STRUCT *ads, } if (ads_count_replies(ads, res) != 1) { - printf("no result\n"); + status = ADS_ERROR(LDAP_NO_RESULTS_RETURNED); goto out; } -- cgit From 2fc53c947b6c18f5e9761a26792f806ff588e239 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Jul 2007 09:48:15 +0000 Subject: r23886: add ads_disconnect() function metze (This used to be commit ba70737b7043cae89dd90f8668a24881212ac6fb) --- source3/libads/ldap.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 84ceba2406..c5c43c44c5 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -465,6 +465,18 @@ got_connection: return ads_sasl_bind(ads); } +/** + * Disconnect the LDAP server + * @param ads Pointer to an existing ADS_STRUCT + **/ +void ads_disconnect(ADS_STRUCT *ads) +{ + if (ads->ld) { + ldap_unbind(ads->ld); + ads->ld = NULL; + } +} + /* Duplicate a struct berval into talloc'ed memory */ -- cgit From 809c9d4d3136cc46dc228107918ca19d5a008a0a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Jul 2007 11:08:00 +0000 Subject: r23888: move elements belonging to the current ldap connection to a substructure. metze (This used to be commit 00909194a6c1ed193dfdb296f50f58a53450583c) --- source3/libads/ldap.c | 92 +++++++++++++++++++++++++-------------------------- 1 file changed, 46 insertions(+), 46 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c5c43c44c5..c8f68546ad 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -224,8 +224,8 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) ads->server.workgroup = SMB_STRDUP(cldap_reply.netbios_domain); - ads->ldap_port = LDAP_PORT; - ads->ldap_ip = *interpret_addr2(srv); + ads->ldap.port = LDAP_PORT; + ads->ldap.ip = *interpret_addr2(srv); SAFE_FREE(srv); /* Store our site name. */ @@ -372,8 +372,8 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ADS_STATUS status; NTSTATUS ntstatus; - ads->last_attempt = time(NULL); - ads->ld = NULL; + ads->ldap.last_attempt = time(NULL); + ads->ldap.ld = NULL; /* try with a user specified server */ @@ -390,7 +390,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) return ADS_ERROR_NT(ntstatus); got_connection: - DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap_ip))); + DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap.ip))); if (!ads->auth.user_name) { /* Must use the userPrincipalName value here or sAMAccountName @@ -404,7 +404,7 @@ got_connection: } if (!ads->auth.kdc_server) { - ads->auth.kdc_server = SMB_STRDUP(inet_ntoa(ads->ldap_ip)); + ads->auth.kdc_server = SMB_STRDUP(inet_ntoa(ads->ldap.ip)); } #if KRB5_DNS_HACK @@ -426,7 +426,7 @@ got_connection: /* Otherwise setup the TCP LDAP session */ - if ( (ads->ld = ldap_open_with_timeout(ads->config.ldap_server_name, + if ( (ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name, LDAP_PORT, lp_ldap_timeout())) == NULL ) { return ADS_ERROR(LDAP_OPERATIONS_ERROR); @@ -434,13 +434,13 @@ got_connection: /* cache the successful connection for workgroup and realm */ if (ads_closest_dc(ads)) { - saf_store( ads->server.workgroup, inet_ntoa(ads->ldap_ip)); - saf_store( ads->server.realm, inet_ntoa(ads->ldap_ip)); + saf_store( ads->server.workgroup, inet_ntoa(ads->ldap.ip)); + saf_store( ads->server.realm, inet_ntoa(ads->ldap.ip)); } - ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + ldap_set_option(ads->ldap.ld, LDAP_OPT_PROTOCOL_VERSION, &version); - status = ADS_ERROR(smb_ldap_start_tls(ads->ld, version)); + status = ADS_ERROR(smb_ldap_start_tls(ads->ldap.ld, version)); if (!ADS_ERR_OK(status)) { return status; } @@ -455,11 +455,11 @@ got_connection: /* Now do the bind */ if (ads->auth.flags & ADS_AUTH_ANON_BIND) { - return ADS_ERROR(ldap_simple_bind_s( ads->ld, NULL, NULL)); + return ADS_ERROR(ldap_simple_bind_s( ads->ldap.ld, NULL, NULL)); } if (ads->auth.flags & ADS_AUTH_SIMPLE_BIND) { - return ADS_ERROR(ldap_simple_bind_s( ads->ld, ads->auth.user_name, ads->auth.password)); + return ADS_ERROR(ldap_simple_bind_s( ads->ldap.ld, ads->auth.user_name, ads->auth.password)); } return ads_sasl_bind(ads); @@ -471,9 +471,9 @@ got_connection: **/ void ads_disconnect(ADS_STRUCT *ads) { - if (ads->ld) { - ldap_unbind(ads->ld); - ads->ld = NULL; + if (ads->ldap.ld) { + ldap_unbind(ads->ldap.ld); + ads->ldap.ld = NULL; } } @@ -616,7 +616,7 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, } /* Paged results only available on ldap v3 or later */ - ldap_get_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + ldap_get_option(ads->ldap.ld, LDAP_OPT_PROTOCOL_VERSION, &version); if (version < LDAP_VERSION3) { rc = LDAP_NOT_SUPPORTED; goto done; @@ -693,9 +693,9 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, 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); + ldap_set_option(ads->ldap.ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr, + rc = ldap_search_with_timeout(ads->ldap.ld, utf8_path, scope, utf8_expr, search_attrs, 0, controls, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); @@ -709,7 +709,7 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, goto done; } - rc = ldap_parse_result(ads->ld, *res, NULL, NULL, NULL, + rc = ldap_parse_result(ads->ldap.ld, *res, NULL, NULL, NULL, NULL, &rcontrols, 0); if (!rcontrols) { @@ -928,9 +928,9 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, } /* see the note in ads_do_paged_search - we *must* disable referrals */ - ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); + ldap_set_option(ads->ldap.ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr, + rc = ldap_search_with_timeout(ads->ldap.ld, utf8_path, scope, utf8_expr, search_attrs, 0, NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res); @@ -1007,7 +1007,7 @@ void ads_memfree(ADS_STRUCT *ads, void *mem) { char *utf8_dn, *unix_dn; - utf8_dn = ldap_get_dn(ads->ld, msg); + utf8_dn = ldap_get_dn(ads->ldap.ld, msg); if (!utf8_dn) { DEBUG (5, ("ads_get_dn: ldap_get_dn failed\n")); @@ -1237,7 +1237,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) 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, utf8_dn, + ret = ldap_modify_ext_s(ads->ldap.ld, utf8_dn, (LDAPMod **) mods, controls, NULL); SAFE_FREE(utf8_dn); return ADS_ERROR(ret); @@ -1265,7 +1265,7 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_add_s(ads->ld, utf8_dn, (LDAPMod**)mods); + ret = ldap_add_s(ads->ldap.ld, utf8_dn, (LDAPMod**)mods); SAFE_FREE(utf8_dn); return ADS_ERROR(ret); } @@ -1285,7 +1285,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - ret = ldap_delete_s(ads->ld, utf8_dn); + ret = ldap_delete_s(ads->ldap.ld, utf8_dn); SAFE_FREE(utf8_dn); return ADS_ERROR(ret); } @@ -1765,7 +1765,7 @@ ADS_STATUS ads_move_machine_acct(ADS_STRUCT *ads, const char *machine_name, goto done; } - ldap_status = ldap_rename_s(ads->ld, computer_dn, computer_rdn, + ldap_status = ldap_rename_s(ads->ldap.ld, computer_dn, computer_rdn, org_unit, 1, NULL, NULL); rc = ADS_ERROR(ldap_status); @@ -1952,10 +1952,10 @@ static BOOL ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da char *utf8_field; BerElement *b; - for (utf8_field=ldap_first_attribute(ads->ld, + for (utf8_field=ldap_first_attribute(ads->ldap.ld, (LDAPMessage *)msg,&b); utf8_field; - utf8_field=ldap_next_attribute(ads->ld, + utf8_field=ldap_next_attribute(ads->ldap.ld, (LDAPMessage *)msg,b)) { struct berval **ber_vals; char **str_vals, **utf8_vals; @@ -1966,14 +1966,14 @@ static BOOL ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da string = fn(ads, field, NULL, data_area); if (string) { - utf8_vals = ldap_get_values(ads->ld, + utf8_vals = ldap_get_values(ads->ldap.ld, (LDAPMessage *)msg, field); str_vals = ads_pull_strvals(ctx, (const char **) utf8_vals); fn(ads, field, (void **) str_vals, data_area); ldap_value_free(utf8_vals); } else { - ber_vals = ldap_get_values_len(ads->ld, + ber_vals = ldap_get_values_len(ads->ldap.ld, (LDAPMessage *)msg, field); fn(ads, field, (void **) ber_vals, data_area); @@ -1997,7 +1997,7 @@ static BOOL ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da **/ int ads_count_replies(ADS_STRUCT *ads, void *res) { - return ldap_count_entries(ads->ld, (LDAPMessage *)res); + return ldap_count_entries(ads->ldap.ld, (LDAPMessage *)res); } /** @@ -2008,7 +2008,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) **/ LDAPMessage *ads_first_entry(ADS_STRUCT *ads, LDAPMessage *res) { - return ldap_first_entry(ads->ld, res); + return ldap_first_entry(ads->ldap.ld, res); } /** @@ -2019,7 +2019,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) **/ LDAPMessage *ads_next_entry(ADS_STRUCT *ads, LDAPMessage *res) { - return ldap_next_entry(ads->ld, res); + return ldap_next_entry(ads->ldap.ld, res); } /** @@ -2038,7 +2038,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) char *ux_string; size_t rc; - values = ldap_get_values(ads->ld, msg, field); + values = ldap_get_values(ads->ldap.ld, msg, field); if (!values) return NULL; @@ -2069,7 +2069,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) char **ret = NULL; int i; - values = ldap_get_values(ads->ld, msg, field); + values = ldap_get_values(ads->ldap.ld, msg, field); if (!values) return NULL; @@ -2132,9 +2132,9 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) expected_range_attrib = talloc_asprintf(mem_ctx, "%s;Range=", field); /* look for Range result */ - for (attr = ldap_first_attribute(ads->ld, (LDAPMessage *)msg, &ptr); + for (attr = ldap_first_attribute(ads->ldap.ld, (LDAPMessage *)msg, &ptr); attr; - attr = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, ptr)) { + attr = ldap_next_attribute(ads->ldap.ld, (LDAPMessage *)msg, ptr)) { /* we ignore the fact that this is utf8, as all attributes are ascii... */ if (strnequal(attr, expected_range_attrib, strlen(expected_range_attrib))) { range_attr = attr; @@ -2234,7 +2234,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) { char **values; - values = ldap_get_values(ads->ld, msg, field); + values = ldap_get_values(ads->ldap.ld, msg, field); if (!values) return False; if (!values[0]) { @@ -2259,7 +2259,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) char **values; UUID_FLAT flat_guid; - values = ldap_get_values(ads->ld, msg, "objectGUID"); + values = ldap_get_values(ads->ldap.ld, msg, "objectGUID"); if (!values) return False; @@ -2289,7 +2289,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) struct berval **values; BOOL ret = False; - values = ldap_get_values_len(ads->ld, msg, field); + values = ldap_get_values_len(ads->ldap.ld, msg, field); if (!values) return False; @@ -2317,7 +2317,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) BOOL ret; int count, i; - values = ldap_get_values_len(ads->ld, msg, field); + values = ldap_get_values_len(ads->ldap.ld, msg, field); if (!values) return 0; @@ -2364,7 +2364,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) struct berval **values; BOOL ret = False; - values = ldap_get_values_len(ads->ld, msg, field); + values = ldap_get_values_len(ads->ldap.ld, msg, field); if (!values) return False; @@ -2481,7 +2481,7 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads) /* establish a new ldap tcp session if necessary */ - if ( !ads->ld ) { + if ( !ads->ldap.ld ) { if ( (ads_s = ads_init( ads->server.realm, ads->server.workgroup, ads->server.ldap_server )) == NULL ) { @@ -2542,7 +2542,7 @@ ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val) /* establish a new ldap tcp session if necessary */ - if ( !ads->ld ) { + if ( !ads->ldap.ld ) { if ( (ads_s = ads_init( ads->server.realm, ads->server.workgroup, ads->server.ldap_server )) == NULL ) { @@ -3100,7 +3100,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) hostnameDN = ads_get_dn(ads, (LDAPMessage *)msg); - rc = ldap_delete_ext_s(ads->ld, hostnameDN, pldap_control, NULL); + rc = ldap_delete_ext_s(ads->ldap.ld, hostnameDN, pldap_control, NULL); if (rc) { DEBUG(3,("ldap_delete_ext_s failed with error code %d\n", rc)); }else { -- cgit From 9e0c550922e44dacc57480a96dd217bc6ab28459 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 17 Jul 2007 20:28:31 +0000 Subject: r23937: Use ads_config_path() when we need to know the configration context. Guenther (This used to be commit 1a62c731c6259bf4285d3735bff8b191002553f7) --- source3/libads/ldap.c | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c8f68546ad..fe7add5e75 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2662,8 +2662,8 @@ ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const c { ADS_STATUS status; LDAPMessage *res; - const char *parent, *config_context, *filter; - const char *attrs[] = { "configurationNamingContext", NULL }; + const char *parent, *filter; + char *config_context = NULL; char *dn; /* shortcut a query */ @@ -2671,26 +2671,18 @@ ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const c return ads_site_dn(ads, mem_ctx, site_dn); } - status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + status = ads_config_path(ads, mem_ctx, &config_context); if (!ADS_ERR_OK(status)) { return status; } - config_context = ads_pull_string(ads, mem_ctx, res, "configurationNamingContext"); - if (config_context == NULL) { - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_MEMORY); - } - filter = talloc_asprintf(mem_ctx, "(cn=%s)", computer_name); if (filter == NULL) { - ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } - ads_msgfree(ads, res); - - status = ads_do_search(ads, config_context, LDAP_SCOPE_SUBTREE, filter, NULL, &res); + status = ads_do_search(ads, config_context, LDAP_SCOPE_SUBTREE, + filter, NULL, &res); if (!ADS_ERR_OK(status)) { return status; } @@ -2739,34 +2731,27 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char ***suffix { ADS_STATUS status; LDAPMessage *res; - const char *config_context, *base; - const char *attrs[] = { "configurationNamingContext", NULL }; - const char *attrs2[] = { "uPNSuffixes", NULL }; + const char *base; + char *config_context = NULL; + const char *attrs[] = { "uPNSuffixes", NULL }; - status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); + status = ads_config_path(ads, mem_ctx, &config_context); if (!ADS_ERR_OK(status)) { return status; } - config_context = ads_pull_string(ads, mem_ctx, res, "configurationNamingContext"); - if (config_context == NULL) { - ads_msgfree(ads, res); - return ADS_ERROR(LDAP_NO_MEMORY); - } - - ads_msgfree(ads, res); - base = talloc_asprintf(mem_ctx, "cn=Partitions,%s", config_context); if (base == NULL) { return ADS_ERROR(LDAP_NO_MEMORY); } - status = ads_search_dn(ads, &res, base, attrs2); + status = ads_search_dn(ads, &res, base, attrs); if (!ADS_ERR_OK(status)) { return status; } if (ads_count_replies(ads, res) != 1) { + ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } -- cgit From 07c034f7c443689749c2b4b138acb991da575c3a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Jul 2007 07:45:16 +0000 Subject: r23945: add infrastructure to select plain, sign or seal LDAP connection metze (This used to be commit 2075c05b3d8baa7d6d8510cd962471a5781740a6) --- source3/libads/ldap.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index fe7add5e75..0b73229736 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -372,8 +372,9 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ADS_STATUS status; NTSTATUS ntstatus; - ads->ldap.last_attempt = time(NULL); - ads->ldap.ld = NULL; + ZERO_STRUCT(ads->ldap); + ads->ldap.last_attempt = time(NULL); + ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_PLAIN; /* try with a user specified server */ @@ -423,6 +424,11 @@ got_connection: if (ads->auth.flags & ADS_AUTH_NO_BIND) { return ADS_SUCCESS; } + + ads->ldap.mem_ctx = talloc_new("ads LDAP connection memory"); + if (!ads->ldap.mem_ctx) { + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } /* Otherwise setup the TCP LDAP session */ @@ -475,6 +481,13 @@ void ads_disconnect(ADS_STRUCT *ads) ldap_unbind(ads->ldap.ld); ads->ldap.ld = NULL; } + if (ads->ldap.wrap_ops && ads->ldap.wrap_ops->disconnect) { + ads->ldap.wrap_ops->disconnect(ads); + } + if (ads->ldap.mem_ctx) { + talloc_free(ads->ldap.mem_ctx); + } + ZERO_STRUCT(ads->ldap); } /* -- cgit From e6875b1b45577917ff9b465623502f49755aa612 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 18 Jul 2007 11:21:21 +0000 Subject: r23951: Fix segfault. Guenther (This used to be commit 1a5c8780ae79e5ae4e6a36bfb66cd92ae7d3aa88) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0b73229736..6c9bde24b0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -425,7 +425,7 @@ got_connection: return ADS_SUCCESS; } - ads->ldap.mem_ctx = talloc_new("ads LDAP connection memory"); + ads->ldap.mem_ctx = talloc_init("ads LDAP connection memory"); if (!ads->ldap.mem_ctx) { return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } -- cgit From 8476d072d34ee8a9562aa99d628484926939ebdd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 4 Aug 2007 10:25:27 +0000 Subject: r24166: Fix Coverity ID 391 (This used to be commit 461974d2cc18c729f152356a9c30cc776f288906) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 6c9bde24b0..f8c47ca5be 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2723,7 +2723,7 @@ ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const c if (*site_dn == NULL) { ads_msgfree(ads, res); ads_memfree(ads, dn); - ADS_ERROR(LDAP_NO_MEMORY); + return ADS_ERROR(LDAP_NO_MEMORY); } ads_memfree(ads, dn); -- cgit From 6ba2d944a0b5314564f077c6e896312b03cdd236 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 6 Aug 2007 14:03:11 +0000 Subject: r24252: Dump guid of msExchMailboxGuid when returned. Guenther (This used to be commit 1142f3df546cbf4780c6f54667f7ed31b1a7621b) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index f8c47ca5be..b1a86ad3d3 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1902,6 +1902,7 @@ static BOOL ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da {"tokenGroupsNoGCAcceptable", False, dump_sid}, {"tokengroupsGlobalandUniversal", False, dump_sid}, {"mS-DS-CreatorSID", False, dump_sid}, + {"msExchMailboxGuid", False, dump_guid}, {NULL, True, NULL} }; int i; -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/libads/ldap.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b1a86ad3d3..f85d3cd7b0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -118,7 +118,7 @@ static int ldap_search_with_timeout(LDAP *ld, Do client and server sitename match ? **********************************************/ -BOOL ads_sitename_match(ADS_STRUCT *ads) +bool ads_sitename_match(ADS_STRUCT *ads) { if (ads->config.server_site_name == NULL && ads->config.client_site_name == NULL ) { @@ -142,7 +142,7 @@ BOOL ads_sitename_match(ADS_STRUCT *ads) Is this the closest DC ? **********************************************/ -BOOL ads_closest_dc(ADS_STRUCT *ads) +bool ads_closest_dc(ADS_STRUCT *ads) { if (ads->config.flags & ADS_CLOSEST) { DEBUG(10,("ads_closest_dc: ADS_CLOSEST flag set\n")); @@ -166,7 +166,7 @@ BOOL ads_closest_dc(ADS_STRUCT *ads) try a connection to a given ldap server, returning True and setting the servers IP in the ads struct if successful */ -BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) +bool ads_try_connect(ADS_STRUCT *ads, const char *server ) { char *srv; struct cldap_netlogon_reply cldap_reply; @@ -246,8 +246,8 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) int count, i=0; struct ip_service *ip_list; pstring realm; - BOOL got_realm = False; - BOOL use_own_domain = False; + bool got_realm = False; + bool use_own_domain = False; char *sitename; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; @@ -864,7 +864,7 @@ static ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, **/ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, int scope, const char *expr, const char **attrs, - BOOL(*fn)(ADS_STRUCT *, char *, void **, void *), + bool (*fn)(ADS_STRUCT *, char *, void **, void *), void *data_area) { struct berval *cookie = NULL; @@ -1738,7 +1738,7 @@ done: **/ ADS_STATUS ads_move_machine_acct(ADS_STRUCT *ads, const char *machine_name, - const char *org_unit, BOOL *moved) + const char *org_unit, bool *moved) { ADS_STATUS rc; int ldap_status; @@ -1747,7 +1747,7 @@ ADS_STATUS ads_move_machine_acct(ADS_STRUCT *ads, const char *machine_name, char *computer_dn = NULL; char *parent_dn; char *computer_rdn = NULL; - BOOL need_move = False; + bool need_move = False; if (asprintf(&filter, "(samAccountName=%s$)", machine_name) == -1) { rc = ADS_ERROR(LDAP_NO_MEMORY); @@ -1886,11 +1886,11 @@ static void dump_string(const char *field, char **values) used for debugging */ -static BOOL ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *data_area) +static bool ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *data_area) { const struct { const char *name; - BOOL string; + bool string; void (*handler)(ADS_STRUCT *, const char *, struct berval **); } handlers[] = { {"objectGUID", False, dump_guid}, @@ -1952,7 +1952,7 @@ static BOOL ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da * @param data_area user-defined area to pass to function **/ void ads_process_results(ADS_STRUCT *ads, LDAPMessage *res, - BOOL(*fn)(ADS_STRUCT *, char *, void **, void *), + bool (*fn)(ADS_STRUCT *, char *, void **, void *), void *data_area) { LDAPMessage *msg; @@ -1974,7 +1974,7 @@ static BOOL ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da struct berval **ber_vals; char **str_vals, **utf8_vals; char *field; - BOOL string; + bool string; pull_utf8_talloc(ctx, &field, utf8_field); string = fn(ads, field, NULL, data_area); @@ -2126,7 +2126,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) char **current_strings, const char **next_attribute, size_t *num_strings, - BOOL *more_strings) + bool *more_strings) { char *attr; char *expected_range_attrib, *range_attr; @@ -2243,7 +2243,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @param v Pointer to int to store result * @return boolean inidicating success */ - BOOL ads_pull_uint32(ADS_STRUCT *ads, LDAPMessage *msg, const char *field, + bool ads_pull_uint32(ADS_STRUCT *ads, LDAPMessage *msg, const char *field, uint32 *v) { char **values; @@ -2268,7 +2268,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @param guid 37-byte area to receive text guid * @return boolean indicating success **/ - BOOL ads_pull_guid(ADS_STRUCT *ads, LDAPMessage *msg, struct GUID *guid) + bool ads_pull_guid(ADS_STRUCT *ads, LDAPMessage *msg, struct GUID *guid) { char **values; UUID_FLAT flat_guid; @@ -2297,11 +2297,11 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @param sid Pointer to sid to store result * @return boolean inidicating success */ - BOOL ads_pull_sid(ADS_STRUCT *ads, LDAPMessage *msg, const char *field, + bool ads_pull_sid(ADS_STRUCT *ads, LDAPMessage *msg, const char *field, DOM_SID *sid) { struct berval **values; - BOOL ret = False; + bool ret = False; values = ldap_get_values_len(ads->ldap.ld, msg, field); @@ -2328,7 +2328,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) LDAPMessage *msg, const char *field, DOM_SID **sids) { struct berval **values; - BOOL ret; + bool ret; int count, i; values = ldap_get_values_len(ads->ldap.ld, msg, field); @@ -2372,11 +2372,11 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @param sd Pointer to *SEC_DESC to store result (talloc()ed) * @return boolean inidicating success */ - BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, + bool ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, LDAPMessage *msg, const char *field, SEC_DESC **sd) { struct berval **values; - BOOL ret = False; + bool ret = False; values = ldap_get_values_len(ads->ldap.ld, msg, field); @@ -2788,7 +2788,7 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char ***suffix * @param sid pointer to a DOM_SID * @return boolean inidicating success **/ -BOOL ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, +bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, const char *extended_dn, enum ads_extended_dn_flags flags, DOM_SID *sid) -- cgit From f88b7a076be74a29a3bf876b4e2705f4a1ecf42b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 24 Oct 2007 14:16:54 -0700 Subject: This is a large patch (sorry). Migrate from struct in_addr to struct sockaddr_storage in most places that matter (ie. not the nmbd and NetBIOS lookups). This passes make test on an IPv4 box, but I'll have to do more work/testing on IPv6 enabled boxes. This should now give us a framework for testing and finishing the IPv6 migration. It's at the state where someone with a working IPv6 setup should (theorecically) be able to type : smbclient //ipv6-address/share and have it work. Jeremy. (This used to be commit 98e154c3125d5732c37a72d74b0eb5cd7b6155fd) --- source3/libads/ldap.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index f85d3cd7b0..0294c4a5b5 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -221,13 +221,19 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) ads->config.client_site_name = SMB_STRDUP(cldap_reply.client_site_name); } - ads->server.workgroup = SMB_STRDUP(cldap_reply.netbios_domain); ads->ldap.port = LDAP_PORT; - ads->ldap.ip = *interpret_addr2(srv); + if (!interpret_string_addr(&ads->ldap.ss, srv, 0)) { + DEBUG(1,("ads_try_connect: unable to convert %s " + "to an address\n", + srv)); + SAFE_FREE( srv ); + return False; + } + SAFE_FREE(srv); - + /* Store our site name. */ sitename_store( cldap_reply.domain, cldap_reply.client_site_name ); @@ -306,10 +312,10 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) /* if we fail this loop, then giveup since all the IP addresses returned were dead */ for ( i=0; ildap); ads->ldap.last_attempt = time(NULL); @@ -378,7 +385,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) /* try with a user specified server */ - if (ads->server.ldap_server && + if (ads->server.ldap_server && ads_try_connect(ads, ads->server.ldap_server)) { goto got_connection; } @@ -391,7 +398,9 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) return ADS_ERROR_NT(ntstatus); got_connection: - DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap.ip))); + + print_sockaddr(addr, sizeof(addr), &ads->ldap.ss); + DEBUG(3,("Connected to LDAP server %s\n", addr)); if (!ads->auth.user_name) { /* Must use the userPrincipalName value here or sAMAccountName @@ -405,7 +414,8 @@ got_connection: } if (!ads->auth.kdc_server) { - ads->auth.kdc_server = SMB_STRDUP(inet_ntoa(ads->ldap.ip)); + print_sockaddr(addr, sizeof(addr), &ads->ldap.ss); + ads->auth.kdc_server = SMB_STRDUP(addr); } #if KRB5_DNS_HACK @@ -440,8 +450,9 @@ got_connection: /* cache the successful connection for workgroup and realm */ if (ads_closest_dc(ads)) { - saf_store( ads->server.workgroup, inet_ntoa(ads->ldap.ip)); - saf_store( ads->server.realm, inet_ntoa(ads->ldap.ip)); + print_sockaddr(addr, sizeof(addr), &ads->ldap.ss); + saf_store( ads->server.workgroup, addr); + saf_store( ads->server.realm, addr); } ldap_set_option(ads->ldap.ld, LDAP_OPT_PROTOCOL_VERSION, &version); -- cgit From de51d3dd5f673019325abba88b100b279169a1c8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Nov 2007 18:55:36 -0800 Subject: More pstring removal.... Jeremy. (This used to be commit 809f5ab4c595740b28425e1667e395a6058b76a8) --- source3/libads/ldap.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0294c4a5b5..01f6b00c02 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -251,7 +251,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) const char *c_realm; int count, i=0; struct ip_service *ip_list; - pstring realm; + const char *realm; bool got_realm = False; bool use_own_domain = False; char *sitename; @@ -261,7 +261,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) /* realm */ c_realm = ads->server.realm; - + if ( !c_realm || !*c_realm ) { /* special case where no realm and no workgroup means our own */ if ( !ads->server.workgroup || !*ads->server.workgroup ) { @@ -269,33 +269,33 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) c_realm = lp_realm(); } } - - if (c_realm && *c_realm) + + if (c_realm && *c_realm) got_realm = True; - - /* we need to try once with the realm name and fallback to the + + /* we need to try once with the realm name and fallback to the netbios domain name if we fail (if netbios has not been disabled */ - + if ( !got_realm && !lp_disable_netbios() ) { c_realm = ads->server.workgroup; if (!c_realm || !*c_realm) { if ( use_own_domain ) c_realm = lp_workgroup(); } - + if ( !c_realm || !*c_realm ) { DEBUG(0,("ads_find_dc: no realm or workgroup! Don't know what to do\n")); return NT_STATUS_INVALID_PARAMETER; /* rather need MISSING_PARAMETER ... */ } } - - pstrcpy( realm, c_realm ); + + realm = c_realm; sitename = sitename_fetch(realm); again: - DEBUG(6,("ads_find_dc: looking for %s '%s'\n", + DEBUG(6,("ads_find_dc: looking for %s '%s'\n", (got_realm ? "realm" : "domain"), realm)); status = get_sorted_dc_list(realm, sitename, &ip_list, &count, got_realm); @@ -305,7 +305,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) got_realm = False; goto again; } - + SAFE_FREE(sitename); return status; } @@ -338,7 +338,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) continue; } } - + if ( ads_try_connect(ads, server) ) { SAFE_FREE(ip_list); SAFE_FREE(sitename); -- cgit From 1011b32678c7b32472a909b9f515698947d2a389 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 25 Nov 2007 10:10:52 +0100 Subject: Remove some statics (This used to be commit 1fab16ffb888cd4ec18e52d9da33976a67a5d104) --- source3/libads/ldap.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 01f6b00c02..533aa3026f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1828,11 +1828,14 @@ static void dump_binary(ADS_STRUCT *ads, const char *field, struct berval **valu static void dump_guid(ADS_STRUCT *ads, const char *field, struct berval **values) { int i; - UUID_FLAT guid; for (i=0; values[i]; i++) { + + UUID_FLAT guid; + struct GUID tmp; + memcpy(guid.info, values[i]->bv_val, sizeof(guid.info)); - printf("%s: %s\n", field, - smb_uuid_string_static(smb_uuid_unpack_static(guid))); + smb_uuid_unpack(guid, &tmp); + printf("%s: %s\n", field, smb_uuid_string(talloc_tos(), tmp)); } } @@ -3429,7 +3432,7 @@ const char *ads_get_extended_right_name_by_guid(ADS_STRUCT *ads, } expr = talloc_asprintf(mem_ctx, "(rightsGuid=%s)", - smb_uuid_string_static(*rights_guid)); + smb_uuid_string(mem_ctx, *rights_guid)); if (!expr) { goto done; } -- cgit From 6f46f75dfc2c80b99a6a5fb277bab456a5fd247b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 3 Dec 2007 17:17:05 -0800 Subject: Make strhex_to_str clear on string limits. Remove pstring from web/*.c Jeremy. (This used to be commit f9c8d62389f8cb47837e5360209936176537df13) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 533aa3026f..a4ba3760c2 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2853,10 +2853,10 @@ bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, } break; case ADS_EXTENDED_DN_HEX_STRING: { - pstring buf; + fstring buf; size_t buf_len; - buf_len = strhex_to_str(buf, strlen(p), p); + buf_len = strhex_to_str(buf, sizeof(buf), p, strlen(p)); if (buf_len == 0) { return False; } -- cgit From d8ac0cecaeed2da19a286fcb4392bc6fbb10cd8b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 6 Dec 2007 13:51:25 +0100 Subject: Remove an incredible amount of whitespace. Sorry - could not resist. Michael (This used to be commit 1000c98eae0886dbdf60beb1fe64d66ec009746b) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a4ba3760c2..da4227b64c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -42,7 +42,7 @@ #define LDAP_SERVER_TREE_DELETE_OID "1.2.840.113556.1.4.805" static SIG_ATOMIC_T gotalarm; - + /*************************************************************** Signal function to tell us we timed out. ****************************************************************/ -- cgit From 900288a2b86abd247f9eb4cd15dc5617a17cfef1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 21:11:36 +0100 Subject: Replace sid_string_static by sid_string_dbg in DEBUGs (This used to be commit bb35e794ec129805e874ceba882bcc1e84791a09) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index da4227b64c..a4532cd2ea 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2367,8 +2367,8 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) for (i=0; values[i]; i++) { ret = sid_parse(values[i]->bv_val, values[i]->bv_len, &(*sids)[count]); if (ret) { - fstring sid; - DEBUG(10, ("pulling SID: %s\n", sid_to_string(sid, &(*sids)[count]))); + DEBUG(10, ("pulling SID: %s\n", + sid_string_dbg(&(*sids)[count]))); count++; } } -- cgit From 14ef4cdec1ab6be55c97d0f32780cbddbcdde218 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 22:00:39 +0100 Subject: Replace sid_string_static with sid_to_string This adds 28 fstrings on the stack, but I think an fstring on the stack is still far better than a static one. (This used to be commit c7c885078be8fd3024c186044ac28275d7609679) --- source3/libads/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a4532cd2ea..c3dd9154de 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1847,8 +1847,9 @@ static void dump_sid(ADS_STRUCT *ads, const char *field, struct berval **values) int i; for (i=0; values[i]; i++) { DOM_SID sid; + fstring tmp; sid_parse(values[i]->bv_val, values[i]->bv_len, &sid); - printf("%s: %s\n", field, sid_string_static(&sid)); + printf("%s: %s\n", field, sid_to_string(tmp, &sid)); } } -- cgit From 2e07c2ade89f4ff281c61f74cb88e09990cf5f46 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 22:47:30 +0100 Subject: s/sid_to_string/sid_to_fstring/ least surprise for callers (This used to be commit eb523ba77697346a365589101aac379febecd546) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index c3dd9154de..e9124a387c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1849,7 +1849,7 @@ static void dump_sid(ADS_STRUCT *ads, const char *field, struct berval **values) DOM_SID sid; fstring tmp; sid_parse(values[i]->bv_val, values[i]->bv_len, &sid); - printf("%s: %s\n", field, sid_to_string(tmp, &sid)); + printf("%s: %s\n", field, sid_to_fstring(tmp, &sid)); } } -- cgit From d365a43785238fc59f2fd8a262d30a2a1aae7078 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 16 Dec 2007 14:15:16 +0100 Subject: make use of unmarshall_sec_desc (This used to be commit ced0c42f055a672f6b4ab6ba809b0f63c83b431e) --- source3/libads/ldap.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e9124a387c..348ccacaee 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1858,31 +1858,24 @@ static void dump_sid(ADS_STRUCT *ads, const char *field, struct berval **values) */ static void dump_sd(ADS_STRUCT *ads, const char *filed, struct berval **values) { - prs_struct ps; - - SEC_DESC *psd = 0; - TALLOC_CTX *ctx = 0; - - if (!(ctx = talloc_init("sec_io_desc"))) - return; + TALLOC_CTX *frame = talloc_stackframe(); + struct security_descriptor *psd; + NTSTATUS status; - /* prepare data */ - prs_init(&ps, values[0]->bv_len, ctx, UNMARSHALL); - prs_copy_data_in(&ps, values[0]->bv_val, values[0]->bv_len); - prs_set_offset(&ps,0); - - /* parse secdesc */ - if (!sec_io_desc("sd", &psd, &ps, 1)) { - prs_mem_free(&ps); - talloc_destroy(ctx); + status = unmarshall_sec_desc(talloc_tos(), (uint8 *)values[0]->bv_val, + values[0]->bv_len, &psd); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("unmarshall_sec_desc failed: %s\n", + nt_errstr(status))); + TALLOC_FREE(frame); return; } + if (psd) { - ads_disp_sd(ads, ctx, psd); + ads_disp_sd(ads, talloc_tos(), psd); } - prs_mem_free(&ps); - talloc_destroy(ctx); + TALLOC_FREE(frame); } /* -- cgit From 240391be5345aef88a25c1221942202ba33588b8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 29 Dec 2007 22:47:03 +0100 Subject: Make use of [un]marshall_sec_desc (This used to be commit 54576733d6c0511dc7379f964b1cb035913b7c8d) --- source3/libads/ldap.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 348ccacaee..953693ce48 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2384,20 +2384,22 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) LDAPMessage *msg, const char *field, SEC_DESC **sd) { struct berval **values; - bool ret = False; + bool ret = true; values = ldap_get_values_len(ads->ldap.ld, msg, field); - if (!values) return False; + if (!values) return false; if (values[0]) { - prs_struct ps; - prs_init(&ps, values[0]->bv_len, mem_ctx, UNMARSHALL); - prs_copy_data_in(&ps, values[0]->bv_val, values[0]->bv_len); - prs_set_offset(&ps,0); - - ret = sec_io_desc("sd", sd, &ps, 1); - prs_mem_free(&ps); + NTSTATUS status; + status = unmarshall_sec_desc(mem_ctx, + (uint8 *)values[0]->bv_val, + values[0]->bv_len, sd); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("unmarshall_sec_desc failed: %s\n", + nt_errstr(status))); + ret = false; + } } ldap_value_free_len(values); -- cgit From b076a7e802a89bdc5b369e98c7d69d8f970d8265 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 3 Jan 2008 17:28:09 +0100 Subject: Add ads_get_joinable_ous(). Guenther (This used to be commit 5bbceac88159ef6ff83d9cc62c77c7af2116967d) --- source3/libads/ldap.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 953693ce48..843d57988c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -2790,6 +2790,66 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char ***suffix return status; } +/** + * get the joinable ous for a domain + * @param ads connection to ads server + * @param mem_ctx Pointer to talloc context + * @param ous Pointer to an array of ous + * @param num_ous Pointer to the number of ous + * @return status of search + **/ +ADS_STATUS ads_get_joinable_ous(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + char ***ous, + size_t *num_ous) +{ + ADS_STATUS status; + LDAPMessage *res = NULL; + LDAPMessage *msg = NULL; + const char *attrs[] = { "dn", NULL }; + int count = 0; + + status = ads_search(ads, &res, + "(|(objectClass=domain)(objectclass=organizationalUnit))", + attrs); + if (!ADS_ERR_OK(status)) { + return status; + } + + count = ads_count_replies(ads, res); + if (count < 1) { + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_RESULTS_RETURNED); + } + + for (msg = ads_first_entry(ads, res); msg; + msg = ads_next_entry(ads, msg)) { + + char *dn = NULL; + + dn = ads_get_dn(ads, msg); + if (!dn) { + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + if (!add_string_to_array(mem_ctx, dn, + (const char ***)ous, + (int *)num_ous)) { + ads_memfree(ads, dn); + ads_msgfree(ads, res); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + ads_memfree(ads, dn); + } + + ads_msgfree(ads, res); + + return status; +} + + /** * pull a DOM_SID from an extended dn string * @param mem_ctx TALLOC_CTX -- cgit From 3f42428f9bca5b8473501adc932405cae3c247bb Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 4 Jan 2008 21:45:28 +0100 Subject: Fix a misleading DEBUG message. At this stage, the (tcp) connection to the LDAP server has not been established, this is what is about to be attempted. What has been succesfully done, is a CLDAP netlogon query. Michael (This used to be commit 71c3c8ad4c92c5f6267b84ee1d207e5e49e9a4ec) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 843d57988c..138dfe9015 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -400,7 +400,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) got_connection: print_sockaddr(addr, sizeof(addr), &ads->ldap.ss); - DEBUG(3,("Connected to LDAP server %s\n", addr)); + DEBUG(3,("Successfully contacted LDAP server %s\n", addr)); if (!ads->auth.user_name) { /* Must use the userPrincipalName value here or sAMAccountName -- cgit From 4ad3464fb94c7088e7fd731113c682aa7756ef01 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 4 Jan 2008 21:53:25 +0100 Subject: Unindent function header. Michael (This used to be commit cafda34783f0961c9b463803c19cfcb69f836e3f) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 138dfe9015..712e7e2889 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -52,7 +52,7 @@ static void gotalarm_sig(void) gotalarm = 1; } - LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) +LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) { LDAP *ldp = NULL; -- cgit From 34e579fce5a6cc9ffa60fbe6e797b2e6b35c879e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 4 Jan 2008 21:54:02 +0100 Subject: Enhance DEBUG-verbosity of ldap_open_with_timeout(). Michael (This used to be commit 9e70d1f24dd304c363a1bde97b5af618b46edc49) --- source3/libads/ldap.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 712e7e2889..8a2b82a61d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -56,6 +56,10 @@ LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) { LDAP *ldp = NULL; + + DEBUG(10, ("Opening connection to LDAP server '%s:%d', timeout " + "%u seconds\n", server, port, to)); + /* Setup timeout */ gotalarm = 0; CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); @@ -65,8 +69,10 @@ LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) ldp = ldap_open(server, port); if (ldp == NULL) { - DEBUG(2,("Could not open LDAP connection to %s:%d: %s\n", + DEBUG(2,("Could not open connection to LDAP server %s:%d: %s\n", server, port, strerror(errno))); + } else { + DEBUG(10, ("Connected to LDAP server '%s:%d'\n", server, port)); } /* Teardown timeout. */ -- cgit From 2cb68e3898046ea0dd2ddcf1e32dc7dffca79be8 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 4 Jan 2008 21:56:57 +0100 Subject: Untangle assignment and result check. Michael (This used to be commit 465a3b356cffb855e26569d3752f15cac07208c0) --- source3/libads/ldap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8a2b82a61d..ae8e1e4d4d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -448,9 +448,9 @@ got_connection: /* Otherwise setup the TCP LDAP session */ - if ( (ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name, - LDAP_PORT, lp_ldap_timeout())) == NULL ) - { + ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name, + LDAP_PORT, lp_ldap_timeout()); + if (ads->ldap.ld == NULL) { return ADS_ERROR(LDAP_OPERATIONS_ERROR); } -- cgit From b54310cbaa9584a46decfa2a5bc4bb2a72381a98 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 4 Jan 2008 22:06:15 +0100 Subject: Add a debug message (when the LDAP server has really been connected). Michael (This used to be commit 7d9d2de39072b3291b95ac3965df0d19f83792b9) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ae8e1e4d4d..44560c852d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -453,6 +453,7 @@ got_connection: if (ads->ldap.ld == NULL) { return ADS_ERROR(LDAP_OPERATIONS_ERROR); } + DEBUG(3,("Connected to LDAP server %s\n", ads->config.ldap_server_name)); /* cache the successful connection for workgroup and realm */ if (ads_closest_dc(ads)) { -- cgit From 4aba7475effff485f265fb975cf467fffd6c7db0 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 4 Jan 2008 22:56:10 +0100 Subject: Re-Indent function ldap_open_with_timeout(). This reverts commit #cafda34783f0961c9b463803c19cfcb69f836e3f . I just learned (the hard way) that these indeted functions are not indented by accident but that the intention of this is to not include the prototype into proto.h. Michael (This used to be commit 2e5d01b2146bb9e057b2779d9fe7691ed46d9f45) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 44560c852d..975e926864 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -52,7 +52,7 @@ static void gotalarm_sig(void) gotalarm = 1; } -LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) + LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) { LDAP *ldp = NULL; -- cgit From f89fa0a6f85b74469519ba97752f45db8b879689 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 8 Jan 2008 13:46:54 +0100 Subject: Do not ignore provided machine_name in ads_get_upn(). Guenther (This used to be commit ddc1307844379f99b3dde48fc351d0326d22a7ce) --- source3/libads/ldap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 975e926864..28bc7793d7 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3026,26 +3026,26 @@ char* ads_get_upn( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name ) ADS_STATUS status; int count = 0; char *name = NULL; - - status = ads_find_machine_acct(ads, &res, global_myname()); + + status = ads_find_machine_acct(ads, &res, machine_name); if (!ADS_ERR_OK(status)) { DEBUG(0,("ads_get_upn: Failed to find account for %s\n", global_myname())); goto out; } - + if ( (count = ads_count_replies(ads, res)) != 1 ) { DEBUG(1,("ads_get_upn: %d entries returned!\n", count)); goto out; } - + if ( (name = ads_pull_string(ads, ctx, res, "userPrincipalName")) == NULL ) { DEBUG(2,("ads_get_upn: No userPrincipalName attribute!\n")); } out: ads_msgfree(ads, res); - + return name; } -- cgit From 6c764172e541decc0fa4b0314f4d26ea859c0dfe Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 31 Jan 2008 01:50:49 +0100 Subject: When running with debug level > 10, dump ads_struct in ads_connect(). Guenther (This used to be commit 2dd7c64fa8845fe502789068b877f5eaf060afc7) --- source3/libads/ldap.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 28bc7793d7..7b0adc2fc3 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -391,6 +391,13 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) /* try with a user specified server */ + if (DEBUGLEVEL >= 11) { + char *s = NDR_PRINT_STRUCT_STRING(talloc_tos(), ads_struct, ads); + DEBUG(11,("ads_connect: entering\n")); + DEBUGADD(11,("%s\n", s)); + TALLOC_FREE(s); + } + if (ads->server.ldap_server && ads_try_connect(ads, ads->server.ldap_server)) { goto got_connection; @@ -401,7 +408,8 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) goto got_connection; } - return ADS_ERROR_NT(ntstatus); + status = ADS_ERROR_NT(ntstatus); + goto out; got_connection: @@ -438,12 +446,14 @@ got_connection: /* If the caller() requested no LDAP bind, then we are done */ if (ads->auth.flags & ADS_AUTH_NO_BIND) { - return ADS_SUCCESS; + status = ADS_SUCCESS; + goto out; } ads->ldap.mem_ctx = talloc_init("ads LDAP connection memory"); if (!ads->ldap.mem_ctx) { - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + goto out; } /* Otherwise setup the TCP LDAP session */ @@ -451,7 +461,8 @@ got_connection: ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name, LDAP_PORT, lp_ldap_timeout()); if (ads->ldap.ld == NULL) { - return ADS_ERROR(LDAP_OPERATIONS_ERROR); + status = ADS_ERROR(LDAP_OPERATIONS_ERROR); + goto out; } DEBUG(3,("Connected to LDAP server %s\n", ads->config.ldap_server_name)); @@ -466,27 +477,40 @@ got_connection: status = ADS_ERROR(smb_ldap_start_tls(ads->ldap.ld, version)); if (!ADS_ERR_OK(status)) { - return status; + goto out; } /* fill in the current time and offsets */ status = ads_current_time( ads ); if ( !ADS_ERR_OK(status) ) { - return status; + goto out; } /* Now do the bind */ if (ads->auth.flags & ADS_AUTH_ANON_BIND) { - return ADS_ERROR(ldap_simple_bind_s( ads->ldap.ld, NULL, NULL)); + status = ADS_ERROR(ldap_simple_bind_s(ads->ldap.ld, NULL, NULL)); + goto out; } if (ads->auth.flags & ADS_AUTH_SIMPLE_BIND) { - return ADS_ERROR(ldap_simple_bind_s( ads->ldap.ld, ads->auth.user_name, ads->auth.password)); + status = ADS_ERROR(ldap_simple_bind_s(ads->ldap.ld, ads->auth.user_name, ads->auth.password)); + goto out; + } + + status = ads_sasl_bind(ads); + + out: + if (DEBUGLEVEL >= 11) { + char *s = NDR_PRINT_STRUCT_STRING(talloc_tos(), ads_struct, ads); + DEBUG(11,("ads_connect: leaving with: %s\n", + ads_errstr(status))); + DEBUGADD(11,("%s\n", s)); + TALLOC_FREE(s); } - return ads_sasl_bind(ads); + return status; } /** -- cgit From 2762b9a97582b9b28fd5985ba8e3d0299126820e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Feb 2008 20:57:35 +0100 Subject: Always pass a TALLOC_CTX to str_list_make and str_list_copy (This used to be commit e2c9fc4cf5f0ff725330fa44f53782db65fca37e) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7b0adc2fc3..ef6feb8ee0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -664,7 +664,7 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, else { /* This would be the utf8-encoded version...*/ /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ - if (!(str_list_copy(&search_attrs, attrs))) { + if (!(str_list_copy(talloc_tos(), &search_attrs, attrs))) { rc = LDAP_NO_MEMORY; goto done; } @@ -974,7 +974,7 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, else { /* This would be the utf8-encoded version...*/ /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */ - if (!(str_list_copy(&search_attrs, attrs))) + if (!(str_list_copy(talloc_tos(), &search_attrs, attrs))) { DEBUG(1,("ads_do_search: str_list_copy() failed!")); rc = LDAP_NO_MEMORY; -- cgit From b361956942618ec2f7c2efc60cb190858adbc516 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Feb 2008 21:05:41 +0100 Subject: str_list_free is not needed anymore (This used to be commit feddc1447d585fd108d22a36bccc576fa81197ef) --- source3/libads/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ef6feb8ee0..d6b9ba622b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -801,7 +801,7 @@ done: } /* if/when we decide to utf8-encode attrs, take out this next line */ - str_list_free(&search_attrs); + TALLOC_FREE(search_attrs); return ADS_ERROR(rc); } @@ -998,7 +998,7 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, done: talloc_destroy(ctx); /* if/when we decide to utf8-encode attrs, take out this next line */ - str_list_free(&search_attrs); + TALLOC_FREE(search_attrs); return ADS_ERROR(rc); } /** -- cgit From e06aa46b9fab1e107fea8f6453fb13deffa91e96 Mon Sep 17 00:00:00 2001 From: Marc VanHeyningen Date: Fri, 14 Mar 2008 14:26:28 -0800 Subject: Coverity fixes (This used to be commit 3fc85d22590550f0539215d020e4411bf5b14363) --- source3/libads/ldap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d6b9ba622b..9ec06e5a1d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -588,7 +588,10 @@ static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals) if (!values) return NULL; for (i=0; in_vals[i]; i++) { - push_utf8_talloc(ctx, &values[i], in_vals[i]); + if (push_utf8_talloc(ctx, &values[i], in_vals[i]) == (size_t) -1) { + TALLOC_FREE(values); + return NULL; + } } return values; } -- cgit From 561fb9daa4fa361e5db57bcc64f3a3114c6623fa Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 23 Mar 2008 19:26:35 +0100 Subject: Fix Coverity ID 487 (This used to be commit 22cee9c1afbc33b4920b72bc81569d79642172af) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 9ec06e5a1d..00d36b7edc 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3413,6 +3413,7 @@ ADS_STATUS ads_find_samaccount(ADS_STRUCT *ads, filter = talloc_asprintf(mem_ctx, "(&(objectclass=user)(sAMAccountName=%s))", samaccountname); if (filter == NULL) { + status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); goto out; } -- cgit From 33a3766f033a25b0eb47a3537101d1141d26db3f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 28 Mar 2008 16:33:54 +0100 Subject: Add ads_check_ou_dn(). Guenther (This used to be commit 380e9d26db5341d10807ccbfb413d0f53d3ffc71) --- source3/libads/ldap.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 00d36b7edc..a9eff48b3e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "lib/ldb/include/includes.h" #ifdef HAVE_LDAP @@ -3551,4 +3552,50 @@ const char *ads_get_extended_right_name_by_guid(ADS_STRUCT *ads, } +/** + * verify or build and verify an account ou + * @param mem_ctx Pointer to talloc context + * @param ads connection to ads server + * @param account_ou + * @return status of search + **/ + +ADS_STATUS ads_check_ou_dn(TALLOC_CTX *mem_ctx, + ADS_STRUCT *ads, + const char *account_ou) +{ + struct ldb_dn *name_dn = NULL; + const char *name = NULL; + char *ou_string = NULL; + + name_dn = ldb_dn_explode(mem_ctx, account_ou); + if (name_dn) { + return ADS_SUCCESS; + } + + ou_string = ads_ou_string(ads, account_ou); + if (!ou_string) { + return ADS_ERROR_LDAP(LDAP_INVALID_DN_SYNTAX); + } + + name = talloc_asprintf(mem_ctx, "%s,%s", ou_string, + ads->config.bind_path); + SAFE_FREE(ou_string); + if (!name) { + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + + name_dn = ldb_dn_explode(mem_ctx, name); + if (!name_dn) { + return ADS_ERROR_LDAP(LDAP_INVALID_DN_SYNTAX); + } + + account_ou = talloc_strdup(mem_ctx, name); + if (!account_ou) { + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + + return ADS_SUCCESS; +} + #endif -- cgit From ba98dd4989db16028a2690d382ab178524ce765b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 21 Apr 2008 19:26:32 +0200 Subject: libads: Use libnbt for CLDAP reply parsing. Guenther (This used to be commit 751f3064a508341c0ebae45e8de9f5311d915d70) --- source3/libads/ldap.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a9eff48b3e..b4a977056e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -176,7 +176,7 @@ bool ads_closest_dc(ADS_STRUCT *ads) bool ads_try_connect(ADS_STRUCT *ads, const char *server ) { char *srv; - struct cldap_netlogon_reply cldap_reply; + struct nbt_cldap_netlogon_5 cldap_reply; if (!server || !*server) { return False; @@ -199,7 +199,7 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) /* Check the CLDAP reply flags */ - if ( !(cldap_reply.flags & ADS_LDAP) ) { + if ( !(cldap_reply.server_type & ADS_LDAP) ) { DEBUG(1,("ads_try_connect: %s's CLDAP reply says it is not an LDAP server!\n", srv)); SAFE_FREE( srv ); @@ -215,20 +215,20 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) SAFE_FREE(ads->config.client_site_name); SAFE_FREE(ads->server.workgroup); - ads->config.flags = cldap_reply.flags; - ads->config.ldap_server_name = SMB_STRDUP(cldap_reply.hostname); - strupper_m(cldap_reply.domain); - ads->config.realm = SMB_STRDUP(cldap_reply.domain); + ads->config.flags = cldap_reply.server_type; + ads->config.ldap_server_name = SMB_STRDUP(cldap_reply.pdc_dns_name); + ads->config.realm = SMB_STRDUP(cldap_reply.dns_domain); + strupper_m(ads->config.realm); ads->config.bind_path = ads_build_dn(ads->config.realm); - if (*cldap_reply.server_site_name) { + if (*cldap_reply.server_site) { ads->config.server_site_name = - SMB_STRDUP(cldap_reply.server_site_name); + SMB_STRDUP(cldap_reply.server_site); } - if (*cldap_reply.client_site_name) { + if (*cldap_reply.client_site) { ads->config.client_site_name = - SMB_STRDUP(cldap_reply.client_site_name); + SMB_STRDUP(cldap_reply.client_site); } - ads->server.workgroup = SMB_STRDUP(cldap_reply.netbios_domain); + ads->server.workgroup = SMB_STRDUP(cldap_reply.domain); ads->ldap.port = LDAP_PORT; if (!interpret_string_addr(&ads->ldap.ss, srv, 0)) { @@ -242,7 +242,7 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) SAFE_FREE(srv); /* Store our site name. */ - sitename_store( cldap_reply.domain, cldap_reply.client_site_name ); + sitename_store( cldap_reply.domain, cldap_reply.client_site); return True; } -- cgit From 1dd7ab38e7f7b5dae46cef4567957c71d6b5cc23 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 21 Apr 2008 19:47:13 +0200 Subject: cldap: add talloc context to ads_cldap_netlogon(). Guenther (This used to be commit 4cee7b1bd5cd97c414b73d6f39238958480cdcf3) --- source3/libads/ldap.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b4a977056e..99df4ed8a3 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -177,6 +177,8 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) { char *srv; struct nbt_cldap_netlogon_5 cldap_reply; + TALLOC_CTX *mem_ctx = NULL; + bool ret = false; if (!server || !*server) { return False; @@ -185,16 +187,22 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) DEBUG(5,("ads_try_connect: sending CLDAP request to %s (realm: %s)\n", server, ads->server.realm)); + mem_ctx = talloc_init("ads_try_connect"); + if (!mem_ctx) { + DEBUG(0,("out of memory\n")); + return false; + } + /* this copes with inet_ntoa brokenness */ srv = SMB_STRDUP(server); ZERO_STRUCT( cldap_reply ); - if ( !ads_cldap_netlogon( srv, ads->server.realm, &cldap_reply ) ) { + if ( !ads_cldap_netlogon(mem_ctx, srv, ads->server.realm, &cldap_reply ) ) { DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", srv)); - SAFE_FREE( srv ); - return False; + ret = false; + goto out; } /* Check the CLDAP reply flags */ @@ -202,8 +210,8 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) if ( !(cldap_reply.server_type & ADS_LDAP) ) { DEBUG(1,("ads_try_connect: %s's CLDAP reply says it is not an LDAP server!\n", srv)); - SAFE_FREE( srv ); - return False; + ret = false; + goto out; } /* Fill in the ads->config values */ @@ -235,16 +243,19 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) DEBUG(1,("ads_try_connect: unable to convert %s " "to an address\n", srv)); - SAFE_FREE( srv ); - return False; + ret = false; + goto out; } - SAFE_FREE(srv); - /* Store our site name. */ sitename_store( cldap_reply.domain, cldap_reply.client_site); - return True; + ret = true; + out: + SAFE_FREE(srv); + TALLOC_FREE(mem_ctx); + + return ret; } /********************************************************************** -- cgit From bcbac69d1a38e128ffe8b763ac027d6eab33dcec Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 21 Apr 2008 19:59:27 +0200 Subject: cldap: avoid duplicate definitions so remove ads_cldap.h. Guenther (This used to be commit 538eefe22ad69540b9f73ffaa613d6be045de199) --- source3/libads/ldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 99df4ed8a3..b0f27b598b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -151,14 +151,14 @@ bool ads_sitename_match(ADS_STRUCT *ads) bool ads_closest_dc(ADS_STRUCT *ads) { - if (ads->config.flags & ADS_CLOSEST) { - DEBUG(10,("ads_closest_dc: ADS_CLOSEST flag set\n")); + if (ads->config.flags & NBT_SERVER_CLOSEST) { + DEBUG(10,("ads_closest_dc: NBT_SERVER_CLOSEST flag set\n")); return True; } /* not sure if this can ever happen */ if (ads_sitename_match(ads)) { - DEBUG(10,("ads_closest_dc: ADS_CLOSEST flag not set but sites match\n")); + DEBUG(10,("ads_closest_dc: NBT_SERVER_CLOSEST flag not set but sites match\n")); return True; } @@ -207,7 +207,7 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) /* Check the CLDAP reply flags */ - if ( !(cldap_reply.server_type & ADS_LDAP) ) { + if ( !(cldap_reply.server_type & NBT_SERVER_LDAP) ) { DEBUG(1,("ads_try_connect: %s's CLDAP reply says it is not an LDAP server!\n", srv)); ret = false; -- cgit From 778a5414b1148ea767020b5330b076fed666694f Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Fri, 25 Apr 2008 18:34:46 -0700 Subject: Fix bug 5419: memory leak in ads_do_search_all_args() when enumerating 1000s of entries The ads_do_search_all_args() function attempts to string together several LDAPMessage structures, returned across several paged ldap requests, into a single LDAPMessage structure. It does this by pulling entries off the second LDAPMessage structure and appending them to the first via the OpenLDAP specific ldap_add_result_entry() call. The problem with this approach is it skips non-entry messages such as the result, and controls. These messages are leaked. The short term solution as suggested by Volker is to replace the ads_*_entry() calls with ads_*_message() calls so we don't leak any messages. This fixes the leak but doesn't remove the dependence on the OpenLDAP specific implementation of ldap_add_result_entry(). (This used to be commit f1a5405409c396df394611e2a234522572d2860a) --- source3/libads/ldap.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b0f27b598b..9321302151 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -870,8 +870,8 @@ static ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, /* this relies on the way that ldap_add_result_entry() works internally. I hope that this works on all ldap libs, but I have only tested with openldap */ - for (msg = ads_first_entry(ads, res2); msg; msg = next) { - next = ads_next_entry(ads, msg); + for (msg = ads_first_message(ads, res2); msg; msg = next) { + next = ads_next_message(ads, msg); ldap_add_result_entry((LDAPMessage **)res, msg); } /* note that we do not free res2, as the memory is now @@ -2090,6 +2090,28 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) return ldap_next_entry(ads->ldap.ld, res); } +/** + * pull the first message from a ADS result + * @param ads connection to ads server + * @param res Results of search + * @return first message from result + **/ + LDAPMessage *ads_first_message(ADS_STRUCT *ads, LDAPMessage *res) +{ + return ldap_first_message(ads->ldap.ld, res); +} + +/** + * pull the next message from a ADS result + * @param ads connection to ads server + * @param res Results of search + * @return next message from result + **/ + LDAPMessage *ads_next_message(ADS_STRUCT *ads, LDAPMessage *res) +{ + return ldap_next_message(ads->ldap.ld, res); +} + /** * pull a single string from a ADS result * @param ads connection to ads server -- cgit From cdd9913c4a7d254ab3ef677737493f9f540272c7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 7 May 2008 15:49:09 +0200 Subject: cldap: let ads_cldap_netlogon() return all possible cldap replies. Guenther (This used to be commit 6f9d5e1cc94bc90685b54c04622b8f3357bd2f69) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 9321302151..24eb114f51 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -199,7 +199,7 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) ZERO_STRUCT( cldap_reply ); - if ( !ads_cldap_netlogon(mem_ctx, srv, ads->server.realm, &cldap_reply ) ) { + if ( !ads_cldap_netlogon_5(mem_ctx, srv, ads->server.realm, &cldap_reply ) ) { DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", srv)); ret = false; goto out; -- cgit From 847d385f7bac1c02727d7655f4e277813d4fe42c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 14 May 2008 23:50:25 +0200 Subject: Fix Bug #5465 (joining with createcomputer=ou1/ou2/ou3). Guenther (This used to be commit f3251ba03a69c2fd0335861177159a32b2bc9477) --- source3/libads/ldap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 24eb114f51..99fd645a3d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3595,18 +3595,18 @@ const char *ads_get_extended_right_name_by_guid(ADS_STRUCT *ads, ADS_STATUS ads_check_ou_dn(TALLOC_CTX *mem_ctx, ADS_STRUCT *ads, - const char *account_ou) + const char **account_ou) { struct ldb_dn *name_dn = NULL; const char *name = NULL; char *ou_string = NULL; - name_dn = ldb_dn_explode(mem_ctx, account_ou); + name_dn = ldb_dn_explode(mem_ctx, *account_ou); if (name_dn) { return ADS_SUCCESS; } - ou_string = ads_ou_string(ads, account_ou); + ou_string = ads_ou_string(ads, *account_ou); if (!ou_string) { return ADS_ERROR_LDAP(LDAP_INVALID_DN_SYNTAX); } @@ -3623,8 +3623,8 @@ ADS_STATUS ads_check_ou_dn(TALLOC_CTX *mem_ctx, return ADS_ERROR_LDAP(LDAP_INVALID_DN_SYNTAX); } - account_ou = talloc_strdup(mem_ctx, name); - if (!account_ou) { + *account_ou = talloc_strdup(mem_ctx, name); + if (!*account_ou) { return ADS_ERROR_LDAP(LDAP_NO_MEMORY); } -- cgit From eeb126a379d8d473e5e9a519b97bee543fb2b251 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 15 May 2008 16:38:32 +0200 Subject: libads/cldap: store client sitename also keyed by dns domain name. Guenther (This used to be commit 0388b2f0cc4d14b005c5b42f2c17ddcbc8bef12a) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 99fd645a3d..063645febf 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -249,6 +249,7 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) /* Store our site name. */ sitename_store( cldap_reply.domain, cldap_reply.client_site); + sitename_store( cldap_reply.dns_domain, cldap_reply.client_site); ret = true; out: -- cgit From fb37f156009611af0dd454a0fb0829a09cd638ac Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 29 Apr 2008 14:36:24 -0700 Subject: Cleanup size_t return values in callers of convert_string_allocate This patch is the second iteration of an inside-out conversion to cleanup functions in charcnv.c returning size_t == -1 to indicate failure. (This used to be commit 6b189dabc562d86dcaa685419d0cb6ea276f100d) --- source3/libads/ldap.c | 63 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 20 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 063645febf..37c0c4d0ac 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -593,7 +593,8 @@ static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals) { char **values; int i; - + size_t size; + if (!in_vals) return NULL; for (i=0; in_vals[i]; i++) ; /* count values */ @@ -601,7 +602,7 @@ static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals) if (!values) return NULL; for (i=0; in_vals[i]; i++) { - if (push_utf8_talloc(ctx, &values[i], in_vals[i]) == (size_t) -1) { + if (!push_utf8_talloc(ctx, &values[i], in_vals[i], &size)) { TALLOC_FREE(values); return NULL; } @@ -616,6 +617,7 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) { char **values; int i; + size_t converted_size; if (!in_vals) return NULL; for (i=0; in_vals[i]; i++) @@ -624,7 +626,11 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals) if (!values) return NULL; for (i=0; in_vals[i]; i++) { - pull_utf8_talloc(ctx, &values[i], in_vals[i]); + if (!pull_utf8_talloc(ctx, &values[i], in_vals[i], + &converted_size)) { + DEBUG(0,("ads_pull_strvals: pull_utf8_talloc failed: " + "%s", strerror(errno))); + } } return values; } @@ -652,6 +658,7 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, { int rc, i, version; char *utf8_expr, *utf8_path, **search_attrs; + size_t converted_size; LDAPControl PagedResults, NoReferrals, ExternalCtrl, *controls[4], **rcontrols; BerElement *cookie_be = NULL; struct berval *cookie_bv= NULL; @@ -669,8 +676,9 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, /* 0 means the conversion worked but the result was empty so we only fail if it's -1. In any case, it always at least nulls out the dest */ - if ((push_utf8_talloc(ctx, &utf8_expr, expr) == (size_t)-1) || - (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) { + if (!push_utf8_talloc(ctx, &utf8_expr, expr, &converted_size) || + !push_utf8_talloc(ctx, &utf8_path, bind_path, &converted_size)) + { rc = LDAP_NO_MEMORY; goto done; } @@ -967,6 +975,7 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, { int rc; char *utf8_expr, *utf8_path, **search_attrs = NULL; + size_t converted_size; TALLOC_CTX *ctx; *res = NULL; @@ -978,8 +987,9 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, /* 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, &utf8_expr, expr) == (size_t)-1) || - (push_utf8_talloc(ctx, &utf8_path, bind_path) == (size_t)-1)) { + if (!push_utf8_talloc(ctx, &utf8_expr, expr, &converted_size) || + !push_utf8_talloc(ctx, &utf8_path, bind_path, &converted_size)) + { DEBUG(1,("ads_do_search: push_utf8_talloc() failed!")); rc = LDAP_NO_MEMORY; goto done; @@ -1077,6 +1087,7 @@ void ads_memfree(ADS_STRUCT *ads, void *mem) char *ads_get_dn(ADS_STRUCT *ads, LDAPMessage *msg) { char *utf8_dn, *unix_dn; + size_t converted_size; utf8_dn = ldap_get_dn(ads->ldap.ld, msg); @@ -1085,7 +1096,7 @@ void ads_memfree(ADS_STRUCT *ads, void *mem) return NULL; } - if (pull_utf8_allocate(&unix_dn, utf8_dn) == (size_t)-1) { + if (!pull_utf8_allocate(&unix_dn, utf8_dn, &converted_size)) { DEBUG(0,("ads_get_dn: string conversion failure utf8 [%s]\n", utf8_dn )); return NULL; @@ -1287,6 +1298,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) { int ret,i; char *utf8_dn = NULL; + size_t converted_size; /* this control is needed to modify that contains a currently non-existent attribute (but allowable for the object) to run @@ -1300,7 +1312,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) controls[0] = &PermitModify; controls[1] = NULL; - if (push_utf8_allocate(&utf8_dn, mod_dn) == -1) { + if (!push_utf8_allocate(&utf8_dn, mod_dn, &converted_size)) { return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } @@ -1325,8 +1337,9 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) { int ret, i; char *utf8_dn = NULL; + size_t converted_size; - if (push_utf8_allocate(&utf8_dn, new_dn) == -1) { + if (!push_utf8_allocate(&utf8_dn, new_dn, &converted_size)) { DEBUG(1, ("ads_gen_add: push_utf8_allocate failed!")); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } @@ -1351,7 +1364,8 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) { int ret; char *utf8_dn = NULL; - if (push_utf8_allocate(&utf8_dn, del_dn) == -1) { + size_t converted_size; + if (!push_utf8_allocate(&utf8_dn, del_dn, &converted_size)) { DEBUG(1, ("ads_del_dn: push_utf8_allocate failed!")); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } @@ -2012,6 +2026,7 @@ static bool ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da { LDAPMessage *msg; TALLOC_CTX *ctx; + size_t converted_size; if (!(ctx = talloc_init("ads_process_results"))) return; @@ -2031,7 +2046,14 @@ static bool ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da char *field; bool string; - pull_utf8_talloc(ctx, &field, utf8_field); + if (!pull_utf8_talloc(ctx, &field, utf8_field, + &converted_size)) + { + DEBUG(0,("ads_process_results: " + "pull_utf8_talloc failed: %s", + strerror(errno))); + } + string = fn(ads, field, NULL, data_area); if (string) { @@ -2127,18 +2149,16 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) char **values; char *ret = NULL; char *ux_string; - size_t rc; + size_t converted_size; values = ldap_get_values(ads->ldap.ld, msg, field); if (!values) return NULL; - if (values[0]) { - rc = pull_utf8_talloc(mem_ctx, &ux_string, - values[0]); - if (rc != (size_t)-1) - ret = ux_string; - + if (values[0] && pull_utf8_talloc(mem_ctx, &ux_string, values[0], + &converted_size)) + { + ret = ux_string; } ldap_value_free(values); return ret; @@ -2159,6 +2179,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) char **values; char **ret = NULL; int i; + size_t converted_size; values = ldap_get_values(ads->ldap.ld, msg, field); if (!values) @@ -2173,7 +2194,9 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) } for (i=0;i<*num_values;i++) { - if (pull_utf8_talloc(mem_ctx, &ret[i], values[i]) == -1) { + if (!pull_utf8_talloc(mem_ctx, &ret[i], values[i], + &converted_size)) + { ldap_value_free(values); return NULL; } -- cgit From d261e16cfd4afc19db0c26cfb2b6389c9c174310 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 5 Jun 2008 10:25:02 +0200 Subject: Fix a memleak in ads_find_dc() in case get_sorted_dc_list() fails This is really not a proper place to fix this, but as get_gc_list() and friends are about to be replaced anyway, just work around the broken existing API (This used to be commit df8d089bc63c2a52cbdf3504cded8df620a59902) --- source3/libads/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 37c0c4d0ac..fc336d988b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -319,6 +319,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) status = get_sorted_dc_list(realm, sitename, &ip_list, &count, got_realm); if (!NT_STATUS_IS_OK(status)) { + SAFE_FREE(ip_list); /* fall back to netbios if we can */ if ( got_realm && !lp_disable_netbios() ) { got_realm = False; -- cgit From aaa2a4f447ea674080aad7bf00eabf9043ef9d4f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 17 Jun 2008 12:20:54 +0200 Subject: Revert "Fix a memleak in ads_find_dc() in case get_sorted_dc_list() fails" This reverts commit df8d089bc63c2a52cbdf3504cded8df620a59902. (This used to be commit 342f8858200ed7c446516c270e1b4284d92010d8) --- source3/libads/ldap.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index fc336d988b..37c0c4d0ac 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -319,7 +319,6 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) status = get_sorted_dc_list(realm, sitename, &ip_list, &count, got_realm); if (!NT_STATUS_IS_OK(status)) { - SAFE_FREE(ip_list); /* fall back to netbios if we can */ if ( got_realm && !lp_disable_netbios() ) { got_realm = False; -- cgit From 3688eeafa3679cec0d0b0954206d91d14f21a050 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 17 Jun 2008 16:17:03 +0200 Subject: libads: fix logic error in ads_get_kvno(). Guenther (This used to be commit 132b038581a1a91b4e70c7c44f97f52866609812) --- source3/libads/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 37c0c4d0ac..01c4b442c8 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1537,7 +1537,7 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) } ret = ads_search(ads, &res, filter, attrs); SAFE_FREE(filter); - if (!ADS_ERR_OK(ret) && ads_count_replies(ads, res)) { + if (!ADS_ERR_OK(ret) || (ads_count_replies(ads, res) != 1)) { DEBUG(1,("ads_get_kvno: Computer Account For %s not found.\n", machine_name)); ads_msgfree(ads, res); return kvno; -- cgit From 0447e6a0a7f1b16f986f0fe5304cd65ee691277c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 17 Jun 2008 16:20:29 +0200 Subject: libads: add ads_get_machine_kvno() to make ads_get_kvno() a bit more generic. Guenther (This used to be commit cb7ace209c2051ae02647188715fa6ee324c2bf6) --- source3/libads/ldap.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 01c4b442c8..7b9e51068b 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1516,13 +1516,13 @@ ADS_STATUS ads_add_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, } /** - * Determines the computer account's current KVNO via an LDAP lookup + * Determines the an account's current KVNO via an LDAP lookup * @param ads An initialized ADS_STRUCT - * @param machine_name the NetBIOS name of the computer, which is used to identify the computer account. - * @return the kvno for the computer account, or -1 in case of a failure. + * @param account_name the NT samaccountname. + * @return the kvno for the account, or -1 in case of a failure. **/ -uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) +uint32 ads_get_kvno(ADS_STRUCT *ads, const char *account_name) { LDAPMessage *res = NULL; uint32 kvno = (uint32)-1; /* -1 indicates a failure */ @@ -1531,14 +1531,14 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) char *dn_string = NULL; ADS_STATUS ret = ADS_ERROR(LDAP_SUCCESS); - DEBUG(5,("ads_get_kvno: Searching for host %s\n", machine_name)); - if (asprintf(&filter, "(samAccountName=%s$)", machine_name) == -1) { + DEBUG(5,("ads_get_kvno: Searching for account %s\n", account_name)); + if (asprintf(&filter, "(samAccountName=%s)", account_name) == -1) { return kvno; } ret = ads_search(ads, &res, filter, attrs); SAFE_FREE(filter); if (!ADS_ERR_OK(ret) || (ads_count_replies(ads, res) != 1)) { - DEBUG(1,("ads_get_kvno: Computer Account For %s not found.\n", machine_name)); + DEBUG(1,("ads_get_kvno: Account for %s not found.\n", account_name)); ads_msgfree(ads, res); return kvno; } @@ -1573,6 +1573,28 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name) return kvno; } +/** + * Determines the computer account's current KVNO via an LDAP lookup + * @param ads An initialized ADS_STRUCT + * @param machine_name the NetBIOS name of the computer, which is used to identify the computer account. + * @return the kvno for the computer account, or -1 in case of a failure. + **/ + +uint32_t ads_get_machine_kvno(ADS_STRUCT *ads, const char *machine_name) +{ + char *computer_account = NULL; + uint32_t kvno = -1; + + if (asprintf(&computer_account, "%s$", machine_name) < 0) { + return kvno; + } + + kvno = ads_get_kvno(ads, computer_account); + free(computer_account); + + return kvno; +} + /** * This clears out all registered spn's for a given hostname * @param ads An initilaized ADS_STRUCT -- cgit From 7b1f015675b99c3ee8620bd0113b817a910a0727 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Jun 2008 13:02:03 +0200 Subject: libads: add ads_connect_user_creds() that won't overwrite given user creds. Guenther (This used to be commit 026018c9f1ed0680b3ca5b26dd6b8dc466e27e0d) --- source3/libads/ldap.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7b9e51068b..7c64082ab4 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -526,6 +526,18 @@ got_connection: return status; } +/** + * Connect to the LDAP server using given credentials + * @param ads Pointer to an existing ADS_STRUCT + * @return status of connection + **/ +ADS_STATUS ads_connect_user_creds(ADS_STRUCT *ads) +{ + ads->auth.flags |= ADS_AUTH_USER_CREDS; + + return ads_connect(ads); +} + /** * Disconnect the LDAP server * @param ads Pointer to an existing ADS_STRUCT -- cgit From 9ff1ffcbee46257c3b2b13b84c2a539322493190 Mon Sep 17 00:00:00 2001 From: "Gerald W. Carter" Date: Fri, 27 Jun 2008 10:22:39 -0400 Subject: libads: Add API call to connect to a global catalog server. Extends ads_connect() to a new call ads_connect_gc() which connects on port 3268 rather than port 389. Also makes ads_try_connect() static and only used internally to ldap.c (This used to be commit f4c37dbe2c986fb7bfe510cdff3b4a9fbc06d079) --- source3/libads/ldap.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 140 insertions(+), 5 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7c64082ab4..b59dab1f13 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -173,7 +173,7 @@ bool ads_closest_dc(ADS_STRUCT *ads) try a connection to a given ldap server, returning True and setting the servers IP in the ads struct if successful */ -bool ads_try_connect(ADS_STRUCT *ads, const char *server ) +static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc) { char *srv; struct nbt_cldap_netlogon_5 cldap_reply; @@ -238,7 +238,7 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) } ads->server.workgroup = SMB_STRDUP(cldap_reply.domain); - ads->ldap.port = LDAP_PORT; + ads->ldap.port = gc ? LDAP_GC_PORT : LDAP_PORT; if (!interpret_string_addr(&ads->ldap.ss, srv, 0)) { DEBUG(1,("ads_try_connect: unable to convert %s " "to an address\n", @@ -358,7 +358,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) } } - if ( ads_try_connect(ads, server) ) { + if ( ads_try_connect(ads, server, false) ) { SAFE_FREE(ip_list); SAFE_FREE(sitename); return NT_STATUS_OK; @@ -385,6 +385,141 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) return NT_STATUS_NO_LOGON_SERVERS; } +/********************************************************************* + *********************************************************************/ + +static NTSTATUS ads_lookup_site(void) +{ + ADS_STRUCT *ads = NULL; + ADS_STATUS ads_status; + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + struct nbt_cldap_netlogon_5 cldap_reply; + + ZERO_STRUCT(cldap_reply); + + ads = ads_init(lp_realm(), NULL, NULL); + if (!ads) { + return NT_STATUS_NO_MEMORY; + } + + /* The NO_BIND here will find a DC and set the client site + but not establish the TCP connection */ + + ads->auth.flags = ADS_AUTH_NO_BIND; + ads_status = ads_connect(ads); + if (!ADS_ERR_OK(ads_status)) { + DEBUG(4, ("ads_lookup_site: ads_connect to our realm failed! (%s)\n", + ads_errstr(ads_status))); + } + nt_status = ads_ntstatus(ads_status); + + if (ads) { + ads_destroy(&ads); + } + + return nt_status; +} + +/********************************************************************* + *********************************************************************/ + +static const char* host_dns_domain(const char *fqdn) +{ + const char *p = fqdn; + + /* go to next char following '.' */ + + if ((p = strchr_m(fqdn, '.')) != NULL) { + p++; + } + + return p; +} + + +/** + * Connect to the Global Catalog server + * @param ads Pointer to an existing ADS_STRUCT + * @return status of connection + * + * Simple wrapper around ads_connect() that fills in the + * GC ldap server information + **/ + +ADS_STATUS ads_connect_gc(ADS_STRUCT *ads) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct dns_rr_srv *gcs_list; + int num_gcs; + char *realm = ads->server.realm; + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); + int i; + bool done = false; + char *sitename = NULL; + + if (!realm) + realm = lp_realm(); + + if ((sitename = sitename_fetch(realm)) == NULL) { + ads_lookup_site(); + sitename = sitename_fetch(realm); + } + + do { + /* We try once with a sitename and once without + (unless we don't have a sitename and then we're + done */ + + if (sitename == NULL) + done = true; + + nt_status = ads_dns_query_gcs(frame, realm, sitename, + &gcs_list, &num_gcs); + + SAFE_FREE(sitename); + + if (!NT_STATUS_IS_OK(nt_status)) { + ads_status = ADS_ERROR_NT(nt_status); + goto done; + } + + /* Loop until we get a successful connection or have gone + through them all. When connecting a GC server, make sure that + the realm is the server's DNS name and not the forest root */ + + for (i=0; iserver.gc = true; + ads->server.ldap_server = SMB_STRDUP(gcs_list[i].hostname); + ads->server.realm = SMB_STRDUP(host_dns_domain(ads->server.ldap_server)); + ads_status = ads_connect(ads); + if (ADS_ERR_OK(ads_status)) { + /* Reset the bind_dn to "". A Global Catalog server + may host multiple domain trees in a forest. + Windows 2003 GC server will accept "" as the search + path to imply search all domain trees in the forest */ + + SAFE_FREE(ads->config.bind_path); + ads->config.bind_path = SMB_STRDUP(""); + + + goto done; + } + SAFE_FREE(ads->server.ldap_server); + SAFE_FREE(ads->server.realm); + } + + TALLOC_FREE(gcs_list); + num_gcs = 0; + } while (!done); + +done: + SAFE_FREE(sitename); + talloc_destroy(frame); + + return ads_status; +} + /** * Connect to the LDAP server @@ -412,7 +547,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) } if (ads->server.ldap_server && - ads_try_connect(ads, ads->server.ldap_server)) { + ads_try_connect(ads, ads->server.ldap_server, ads->server.gc)) { goto got_connection; } @@ -472,7 +607,7 @@ got_connection: /* Otherwise setup the TCP LDAP session */ ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name, - LDAP_PORT, lp_ldap_timeout()); + ads->ldap.port, lp_ldap_timeout()); if (ads->ldap.ld == NULL) { status = ADS_ERROR(LDAP_OPERATIONS_ERROR); goto out; -- cgit From 825f06c3f98cc5393761612903297d7a61b70b3b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 20 Aug 2008 21:17:35 +0200 Subject: libads: remove unused vars. Guenther (This used to be commit ea9fc3bea31b11e715d9524defc18b75e5943842) --- source3/libads/ldap.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b59dab1f13..eb45e3a0dd 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -393,9 +393,6 @@ static NTSTATUS ads_lookup_site(void) ADS_STRUCT *ads = NULL; ADS_STATUS ads_status; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct nbt_cldap_netlogon_5 cldap_reply; - - ZERO_STRUCT(cldap_reply); ads = ads_init(lp_realm(), NULL, NULL); if (!ads) { -- cgit