From 55b6cebbd49be484fb6dcde2f8cb8412bb116276 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 27 Sep 2002 03:05:20 +0000 Subject: Some small cleanups to the libads code (mainly error checking), and give a sane prototype for the push_utf8_allocate code. Andrew Bartlett (This used to be commit ce00a3238ed8a82639c4d0ee3e960f7000b1a7b0) --- source3/libads/ads_status.c | 6 ++++++ source3/libads/ldap.c | 27 ++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c index d85f9c9b58..80fdb99eac 100644 --- a/source3/libads/ads_status.c +++ b/source3/libads/ads_status.c @@ -72,6 +72,12 @@ NTSTATUS ads_ntstatus(ADS_STATUS status) if (status.error_type == ADS_ERROR_NT){ return status.err.nt_status; } +#ifdef HAVE_LDAP + if ((status.error_type == ADS_ERROR_LDAP) + && (status.err.rc == LDAP_NO_MEMORY)) { + return NT_STATUS_NO_MEMORY; + } +#endif if (ADS_ERR_OK(status)) return NT_STATUS_OK; return NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 7a0afb1a81..b4c7c3970c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -741,7 +741,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 +902,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 +928,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 +953,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 +1004,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); -- cgit From 7e4afe538147bf31689f47232d5f2b04830dda1d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 27 Sep 2002 12:23:47 +0000 Subject: Move a number of ADS related functions out into utility libs, so that things like metze's sam_ads can also use them. Also add error checking etc to a few more functions. Andrew Bartlett (This used to be commit c864edf4fbf8a6c37888a14b861d7c12cf503d4f) --- source3/libads/ads_ldap.c | 145 ++++++++++++++++++++++++++++++++++++++++++++ source3/libads/ads_utils.c | 20 ++++-- source3/libads/kerberos.c | 9 ++- source3/libads/ldap.c | 99 ++++++++++++++++++++++-------- source3/libads/ldap_utils.c | 90 +++++++++++++++++++++++++++ 5 files changed, 332 insertions(+), 31 deletions(-) create mode 100644 source3/libads/ads_ldap.c create mode 100644 source3/libads/ldap_utils.c (limited to 'source3/libads') diff --git a/source3/libads/ads_ldap.c b/source3/libads/ads_ldap.c new file mode 100644 index 0000000000..8c39a89762 --- /dev/null +++ b/source3/libads/ads_ldap.c @@ -0,0 +1,145 @@ +/* + Unix SMB/CIFS implementation. + + Winbind ADS backend functions + + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Andrew Bartlett 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 + 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_LDAP + +/* convert a single name to a sid in a domain */ +NTSTATUS ads_name_to_sid(ADS_STRUCT *ads, + const char *name, + DOM_SID *sid, + enum SID_NAME_USE *type) +{ + const char *attrs[] = {"objectSid", "sAMAccountType", NULL}; + int count; + ADS_STATUS rc; + void *res = NULL; + char *exp; + uint32 t; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + + if (asprintf(&exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))", + name, name, ads->config.realm) == -1) { + DEBUG(1,("ads_name_to_sid: asprintf failed!\n")); + status = NT_STATUS_NO_MEMORY; + goto done; + } + + rc = ads_search_retry(ads, &res, exp, attrs); + free(exp); + if (!ADS_ERR_OK(rc)) { + DEBUG(1,("name_to_sid ads_search: %s\n", ads_errstr(rc))); + goto done; + } + + count = ads_count_replies(ads, res); + if (count != 1) { + DEBUG(1,("name_to_sid: %s not found\n", name)); + goto done; + } + + if (!ads_pull_sid(ads, res, "objectSid", sid)) { + DEBUG(1,("No sid for %s !?\n", name)); + goto done; + } + + if (!ads_pull_uint32(ads, res, "sAMAccountType", &t)) { + DEBUG(1,("No sAMAccountType for %s !?\n", name)); + goto done; + } + + *type = ads_atype_map(t); + + status = NT_STATUS_OK; + + DEBUG(3,("ads name_to_sid mapped %s\n", name)); + +done: + if (res) ads_msgfree(ads, res); + + return status; +} + +/* convert a sid to a user or group name */ +NTSTATUS ads_sid_to_name(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + DOM_SID *sid, + char **name, + enum SID_NAME_USE *type) +{ + const char *attrs[] = {"userPrincipalName", + "sAMAccountName", + "sAMAccountType", NULL}; + ADS_STATUS rc; + void *msg = NULL; + char *exp = NULL; + char *sidstr = NULL; + uint32 atype; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + + if (!(sidstr = sid_binstring(sid))) { + DEBUG(1,("ads_sid_to_name: sid_binstring failed!\n")); + status = NT_STATUS_NO_MEMORY; + goto done; + } + + if (asprintf(&exp, "(objectSid=%s)", sidstr) == -1) { + DEBUG(1,("ads_sid_to_name: asprintf failed!\n")); + status = NT_STATUS_NO_MEMORY; + goto done; + } + + rc = ads_search_retry(ads, &msg, exp, attrs); + if (!ADS_ERR_OK(rc)) { + status = ads_ntstatus(rc); + DEBUG(1,("ads_sid_to_name ads_search: %s\n", ads_errstr(rc))); + goto done; + } + + if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype)) { + goto done; + } + + *name = ads_pull_username(ads, mem_ctx, msg); + if (!*name) { + DEBUG(1,("ads_sid_to_name: ads_pull_username retuned NULL!\n")); + status = NT_STATUS_NO_MEMORY; + goto done; + } + + *type = ads_atype_map(atype); + + status = NT_STATUS_OK; + + DEBUG(3,("ads sid_to_name mapped %s\n", *name)); + +done: + if (msg) ads_msgfree(ads, msg); + + SAFE_FREE(exp); + SAFE_FREE(sidstr); + + return status; +} + +#endif diff --git a/source3/libads/ads_utils.c b/source3/libads/ads_utils.c index fc8a270021..626c177926 100644 --- a/source3/libads/ads_utils.c +++ b/source3/libads/ads_utils.c @@ -3,7 +3,8 @@ ads (active directory) utility library Copyright (C) Stefan (metze) Metzmacher 2002 - + 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 @@ -21,9 +22,6 @@ #include "includes.h" -#ifdef HAVE_ADS - - /* translated the ACB_CTRL Flags to UserFlags (userAccountControl) */ @@ -168,4 +166,16 @@ uint32 ads_gtype2atype(uint32 gtype) return atype; } -#endif +/* turn a sAMAccountType into a SID_NAME_USE */ +enum SID_NAME_USE ads_atype_map(uint32 atype) +{ + switch (atype & 0xF0000000) { + case ATYPE_GLOBAL_GROUP: + return SID_NAME_DOM_GRP; + case ATYPE_ACCOUNT: + return SID_NAME_USER; + default: + DEBUG(1,("hmm, need to map account type 0x%x\n", atype)); + } + return SID_NAME_UNKNOWN; +} diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index a80837cf4d..b586d84226 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -114,7 +114,14 @@ int ads_kinit_password(ADS_STRUCT *ads) char *s; int ret; - asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm); + if (asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm) == -1) { + return KRB5_CC_NOMEM; + } + + if (!ads->auth.password) { + return KRB5_LIBOS_CANTREADPWD; + } + ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset); if (ret) { diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b4c7c3970c..e09ffeb3f6 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1337,9 +1337,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; @@ -1356,37 +1354,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); @@ -1398,16 +1398,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); + return ret; } /** @@ -1613,6 +1608,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 diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c new file mode 100644 index 0000000000..fbc9eb433f --- /dev/null +++ b/source3/libads/ldap_utils.c @@ -0,0 +1,90 @@ +/* + Unix SMB/CIFS implementation. + + Some Helpful wrappers on LDAP + + 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" +/* + a wrapper around ldap_search_s that retries depending on the error code + this is supposed to catch dropped connections and auto-reconnect +*/ +ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope, + const char *exp, + const char **attrs, void **res) +{ + ADS_STATUS status; + int count = 3; + char *bp; + + if (!ads->ld && + time(NULL) - ads->last_attempt < ADS_RECONNECT_TIME) { + return ADS_ERROR(LDAP_SERVER_DOWN); + } + + bp = strdup(bind_path); + + while (count--) { + status = ads_do_search_all(ads, bp, scope, exp, attrs, res); + if (ADS_ERR_OK(status)) { + DEBUG(5,("Search for %s gave %d replies\n", + exp, ads_count_replies(ads, *res))); + free(bp); + return status; + } + + if (*res) ads_msgfree(ads, *res); + *res = NULL; + DEBUG(3,("Reopening ads connection to realm '%s' after error %s\n", + ads->config.realm, ads_errstr(status))); + if (ads->ld) { + ldap_unbind(ads->ld); + } + ads->ld = NULL; + status = ads_connect(ads); + if (!ADS_ERR_OK(status)) { + DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n", + ads_errstr(status))); + ads_destroy(&ads); + free(bp); + return status; + } + } + free(bp); + + DEBUG(1,("ads reopen failed after error %s\n", ads_errstr(status))); + return status; +} + + +ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res, + const char *exp, + const char **attrs) +{ + return ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, + exp, attrs, res); +} + +ADS_STATUS ads_search_retry_dn(ADS_STRUCT *ads, void **res, + const char *dn, + const char **attrs) +{ + return ads_do_search_retry(ads, dn, LDAP_SCOPE_BASE, + "(objectclass=*)", attrs, res); +} -- cgit From bc828246dbe367252232e5baa54ee9fc9d53ca69 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 28 Sep 2002 00:47:06 +0000 Subject: This needs to be #ifdef HAVE_LDAP. (This used to be commit 2b54a2fc2c85ea139e2acdbbc2f14b969c0c6315) --- source3/libads/ldap_utils.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libads') diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index fbc9eb433f..9e4b8a1de9 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -21,6 +21,8 @@ */ #include "includes.h" + +#ifdef HAVE_LDAP /* a wrapper around ldap_search_s that retries depending on the error code this is supposed to catch dropped connections and auto-reconnect @@ -88,3 +90,4 @@ ADS_STATUS ads_search_retry_dn(ADS_STRUCT *ads, void **res, return ads_do_search_retry(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res); } +#endif -- cgit From 8b197158c9a7a4c881a86381f06c96d5091b5a76 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 28 Sep 2002 12:27:04 +0000 Subject: Add the beginings of sam_ads to the tree. This module, primarilly the work of "Stefan (metze) Metzmacher" , uses the Active Directory schema to store the user/group/other information. I've been testing it against a real AD server, and it is intended to work with OpenLDAP as well. I've moved a few functions around in our other libads code, which has made it easier to tap into that existing code. Also, I've made some changes to the SAM interface, I hope there are not too many objections... To ensure we don't get silly bugs in the skel module, it is now in the default compile. This way you should not forget to update it :-) Andrew Bartlett (This used to be commit 24fb0cde2f0b657df1c99474cd694438c94a566e) --- source3/libads/ads_ldap.c | 2 +- source3/libads/ads_struct.c | 1 + source3/libads/ldap.c | 43 +++++++++++++++++++++++++++++++++++++++++-- source3/libads/ldap_utils.c | 3 +++ 4 files changed, 46 insertions(+), 3 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/ads_ldap.c b/source3/libads/ads_ldap.c index 8c39a89762..05b016539e 100644 --- a/source3/libads/ads_ldap.c +++ b/source3/libads/ads_ldap.c @@ -83,7 +83,7 @@ done: /* convert a sid to a user or group name */ NTSTATUS ads_sid_to_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, - DOM_SID *sid, + const DOM_SID *sid, char **name, enum SID_NAME_USE *type) { diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index b68c822ce3..3cdd015bf4 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -122,6 +122,7 @@ void ads_destroy(ADS_STRUCT **ads) SAFE_FREE((*ads)->server.realm); SAFE_FREE((*ads)->server.workgroup); SAFE_FREE((*ads)->server.ldap_server); + SAFE_FREE((*ads)->server.ldap_uri); SAFE_FREE((*ads)->auth.realm); SAFE_FREE((*ads)->auth.password); diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index e09ffeb3f6..1004ea229c 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/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); } @@ -1771,8 +1809,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); diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index 9e4b8a1de9..907f7c8aff 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -42,6 +42,9 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope bp = strdup(bind_path); + if (!bp) + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + while (count--) { status = ads_do_search_all(ads, bp, scope, exp, attrs, res); if (ADS_ERR_OK(status)) { -- cgit From 4e73790e3a20be5c7bf8fa3b62d9d41ba246b59c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 28 Sep 2002 14:42:32 +0000 Subject: Try to compile as much as possible with only ldap, but not kerberos. (This used to be commit 9615ab10c006d8027f6a8b7dd3770eb77304dbdc) --- source3/libads/disp_sec.c | 3 --- source3/libads/krb5_setpw.c | 31 +++++++++++++++++++++++++++++++ source3/libads/ldap.c | 33 +-------------------------------- source3/libads/sasl.c | 4 +++- 4 files changed, 35 insertions(+), 36 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index a930fd6fe0..a7b0bf6f07 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -20,8 +20,6 @@ #include "includes.h" -#ifdef HAVE_ADS - static struct perm_mask_str { uint32 mask; char *str; @@ -158,5 +156,4 @@ void ads_disp_sd(SEC_DESC *sd) printf("-------------- End Of Security Descriptor\n"); } -#endif diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index a49b6cbe3b..8079c0953f 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -471,4 +471,35 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, } +/** + * 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; +} + #endif diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 1004ea229c..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 @@ -1443,37 +1443,6 @@ ads_set_sd_error: return ret; } -/** - * 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; -} - /** * pull the first entry from a ADS result * @param ads connection to ads server diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index f7dd01084a..aa7d99a5f7 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -20,7 +20,7 @@ #include "includes.h" -#ifdef HAVE_ADS +#ifdef HAVE_LDAP /* perform a LDAP/SASL/SPNEGO/NTLMSSP bind (just how many layers can @@ -190,10 +190,12 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) } DEBUG(3,("got principal=%s\n", principal)); +#ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && got_kerberos_mechanism && ads_kinit_password(ads) == 0) { return ads_sasl_spnego_krb5_bind(ads, principal); } +#endif /* lets do NTLMSSP ... this has the big advantage that we don't need to sync clocks, and we don't rely on special versions of the krb5 -- cgit