X-Git-Url: http://git.samba.org/?p=samba.git;a=blobdiff_plain;f=source3%2Flibads%2Fldap.c;h=946c1a36a72b8b9cd2f1c97287a0d9c3e0e0e100;hp=eb45e3a0dd7050fbdc7609330838218031bcf024;hb=b70f23c2b581c5d455362ab37f4846de9a910055;hpb=a1de4e988d7780f687bb7ed2288faf3dfbb9da71 diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index eb45e3a0dd7..946c1a36a72 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -6,23 +6,30 @@ 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 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, 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, see . */ #include "includes.h" -#include "lib/ldb/include/includes.h" +#include "ads.h" +#include "libads/sitename_cache.h" +#include "libads/cldap.h" +#include "../lib/addns/dnsquery.h" +#include "../libds/common/flags.h" +#include "smbldap.h" +#include "../libcli/security/security.h" +#include "lib/param/loadparm.h" #ifdef HAVE_LDAP @@ -48,24 +55,59 @@ static SIG_ATOMIC_T gotalarm; Signal function to tell us we timed out. ****************************************************************/ -static void gotalarm_sig(void) +static void gotalarm_sig(int signum) { gotalarm = 1; } - LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to) + LDAP *ldap_open_with_timeout(const char *server, + struct sockaddr_storage *ss, + 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); - alarm(to); - /* End setup timeout. */ +#if defined(HAVE_LDAP_INIT_FD) && defined(SOCKET_WRAPPER) + /* Only use this private LDAP function if we are in make test, + * as this is the best way to get the emulated TCP socket into + * OpenLDAP */ + if (socket_wrapper_dir() != NULL) { + int fd, ldap_err; + NTSTATUS status; + char *uri; + + status = open_socket_out(ss, port, to, &fd); + + if (!NT_STATUS_IS_OK(status)) { + return NULL; + } + +#ifndef LDAP_PROTO_TCP +#define LDAP_PROTO_TCP 1 +#endif + uri = talloc_asprintf(talloc_tos(), "ldap://%s:%u", server, port); + if (uri == NULL) { + return NULL; + } + ldap_err = ldap_init_fd(fd, LDAP_PROTO_TCP, uri, &ldp); + talloc_free(uri); + + if (ldap_err != LDAP_SUCCESS) { + return NULL; + } + return ldp; + } +#endif + + if (to) { + /* Setup timeout */ + gotalarm = 0; + CatchSignal(SIGALRM, gotalarm_sig); + alarm(to); + /* End setup timeout. */ + } ldp = ldap_open(server, port); @@ -76,9 +118,11 @@ static void gotalarm_sig(void) DEBUG(10, ("Connected to LDAP server '%s:%d'\n", server, port)); } - /* Teardown timeout. */ - CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN); - alarm(0); + if (to) { + /* Teardown timeout. */ + alarm(0); + CatchSignal(SIGALRM, SIG_IGN); + } return ldp; } @@ -94,30 +138,53 @@ static int ldap_search_with_timeout(LDAP *ld, int sizelimit, LDAPMessage **res ) { + int to = lp_ldap_timeout(); struct timeval timeout; + struct timeval *timeout_ptr = NULL; int result; /* 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. */ + + if (to) { + timeout.tv_sec = to; + timeout.tv_usec = 0; + timeout_ptr = &timeout; + + /* Setup alarm timeout. */ + CatchSignal(SIGALRM, gotalarm_sig); + /* Make the alarm time one second beyond + the timout we're setting for the + remote search timeout, to allow that + to fire in preference. */ + alarm(to+1); + /* End setup timeout. */ + } + result = ldap_search_ext_s(ld, base, scope, filter, attrs, - attrsonly, sctrls, cctrls, &timeout, + attrsonly, sctrls, cctrls, timeout_ptr, sizelimit, res); - /* Teardown timeout. */ - CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN); - alarm(0); + if (to) { + /* Teardown alarm timeout. */ + CatchSignal(SIGALRM, SIG_IGN); + alarm(0); + } if (gotalarm != 0) return LDAP_TIMELIMIT_EXCEEDED; + /* + * A bug in OpenLDAP means ldap_search_ext_s can return + * LDAP_SUCCESS but with a NULL res pointer. Cope with + * this. See bug #6279 for details. JRA. + */ + + if (*res == NULL) { + return LDAP_TIMELIMIT_EXCEEDED; + } + return result; } @@ -162,6 +229,11 @@ bool ads_closest_dc(ADS_STRUCT *ads) return True; } + if (ads->config.client_site_name == NULL) { + DEBUG(10,("ads_closest_dc: client belongs to no site\n")); + return True; + } + DEBUG(10,("ads_closest_dc: %s is not the closest DC\n", ads->config.ldap_server_name)); @@ -175,32 +247,32 @@ bool ads_closest_dc(ADS_STRUCT *ads) */ static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc) { - char *srv; - struct nbt_cldap_netlogon_5 cldap_reply; - TALLOC_CTX *mem_ctx = NULL; + struct NETLOGON_SAM_LOGON_RESPONSE_EX cldap_reply; + TALLOC_CTX *frame = talloc_stackframe(); bool ret = false; + struct sockaddr_storage ss; + char addr[INET6_ADDRSTRLEN]; if (!server || !*server) { + TALLOC_FREE(frame); return False; } - - 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")); + if (!resolve_name(server, &ss, 0x20, true)) { + DEBUG(5,("ads_try_connect: unable to resolve name %s\n", + server )); + TALLOC_FREE(frame); return false; } + print_sockaddr(addr, sizeof(addr), &ss); - /* this copes with inet_ntoa brokenness */ - - srv = SMB_STRDUP(server); + DEBUG(5,("ads_try_connect: sending CLDAP request to %s (realm: %s)\n", + addr, ads->server.realm)); ZERO_STRUCT( 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)); + if ( !ads_cldap_netlogon_5(frame, &ss, ads->server.realm, &cldap_reply ) ) { + DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", addr)); ret = false; goto out; } @@ -209,7 +281,7 @@ static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc) 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)); + addr)); ret = false; goto out; } @@ -226,7 +298,11 @@ static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc) 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); + if (!strupper_m(ads->config.realm)) { + ret = false; + goto out; + } + ads->config.bind_path = ads_build_dn(ads->config.realm); if (*cldap_reply.server_site) { ads->config.server_site_name = @@ -236,26 +312,20 @@ static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc) ads->config.client_site_name = SMB_STRDUP(cldap_reply.client_site); } - ads->server.workgroup = SMB_STRDUP(cldap_reply.domain); + ads->server.workgroup = SMB_STRDUP(cldap_reply.domain_name); 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", - srv)); - ret = false; - goto out; - } + ads->ldap.ss = ss; /* Store our site name. */ - sitename_store( cldap_reply.domain, cldap_reply.client_site); + sitename_store( cldap_reply.domain_name, cldap_reply.client_site); sitename_store( cldap_reply.dns_domain, cldap_reply.client_site); ret = true; + out: - SAFE_FREE(srv); - TALLOC_FREE(mem_ctx); + TALLOC_FREE(frame); return ret; } @@ -267,10 +337,12 @@ static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc) static NTSTATUS ads_find_dc(ADS_STRUCT *ads) { + const char *c_domain; const char *c_realm; int count, i=0; struct ip_service *ip_list; const char *realm; + const char *domain; bool got_realm = False; bool use_own_domain = False; char *sitename; @@ -301,20 +373,52 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) 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 ... */ - } + if ( !c_realm || !*c_realm ) { + DEBUG(1, ("ads_find_dc: no realm or workgroup! Don't know " + "what to do\n")); + return NT_STATUS_INVALID_PARAMETER; /* rather need MISSING_PARAMETER ... */ + } + + if ( use_own_domain ) { + c_domain = lp_workgroup(); + } else { + c_domain = ads->server.workgroup; } realm = c_realm; + domain = c_domain; + + /* + * In case of LDAP we use get_dc_name() as that + * creates the custom krb5.conf file + */ + if (!(ads->auth.flags & ADS_AUTH_NO_BIND)) { + fstring srv_name; + struct sockaddr_storage ip_out; + + DEBUG(6,("ads_find_dc: (ldap) looking for %s '%s'\n", + (got_realm ? "realm" : "domain"), realm)); + + if (get_dc_name(domain, realm, srv_name, &ip_out)) { + /* + * we call ads_try_connect() to fill in the + * ads->config details + */ + if (ads_try_connect(ads, srv_name, false)) { + return NT_STATUS_OK; + } + } + + return NT_STATUS_NO_LOGON_SERVERS; + } sitename = sitename_fetch(realm); again: - DEBUG(6,("ads_find_dc: looking for %s '%s'\n", + DEBUG(6,("ads_find_dc: (cldap) looking for %s '%s'\n", (got_realm ? "realm" : "domain"), realm)); status = get_sorted_dc_list(realm, sitename, &ip_list, &count, got_realm); @@ -363,7 +467,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) SAFE_FREE(sitename); return NT_STATUS_OK; } - + /* keep track of failures */ add_failed_connection_entry( realm, server, NT_STATUS_UNSUCCESSFUL ); } @@ -448,12 +552,13 @@ 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; + const 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; + const char *dns_hosts_file; if (!realm) realm = lp_realm(); @@ -463,6 +568,7 @@ ADS_STATUS ads_connect_gc(ADS_STRUCT *ads) sitename = sitename_fetch(realm); } + dns_hosts_file = lp_parm_const_string(-1, "resolv", "host file", NULL); do { /* We try once with a sitename and once without (unless we don't have a sitename and then we're @@ -471,7 +577,8 @@ ADS_STATUS ads_connect_gc(ADS_STRUCT *ads) if (sitename == NULL) done = true; - nt_status = ads_dns_query_gcs(frame, realm, sitename, + nt_status = ads_dns_query_gcs(frame, dns_hosts_file, + realm, sitename, &gcs_list, &num_gcs); SAFE_FREE(sitename); @@ -531,7 +638,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) char addr[INET6_ADDRSTRLEN]; ZERO_STRUCT(ads->ldap); - ads->ldap.last_attempt = time(NULL); + ads->ldap.last_attempt = time_mono(NULL); ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_PLAIN; /* try with a user specified server */ @@ -543,9 +650,20 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) TALLOC_FREE(s); } - if (ads->server.ldap_server && - ads_try_connect(ads, ads->server.ldap_server, ads->server.gc)) { - goto got_connection; + if (ads->server.ldap_server) + { + if (ads_try_connect(ads, ads->server.ldap_server, ads->server.gc)) { + goto got_connection; + } + + /* The choice of which GC use is handled one level up in + ads_connect_gc(). If we continue on from here with + ads_find_dc() we will get GC searches on port 389 which + doesn't work. --jerry */ + + if (ads->server.gc == true) { + return ADS_ERROR(LDAP_OPERATIONS_ERROR); + } } ntstatus = ads_find_dc(ads); @@ -565,7 +683,10 @@ got_connection: /* Must use the userPrincipalName value here or sAMAccountName and not servicePrincipalName; found by Guenther Deschner */ - asprintf(&ads->auth.user_name, "%s$", global_myname() ); + if (asprintf(&ads->auth.user_name, "%s$", lp_netbios_name() ) == -1) { + DEBUG(0,("ads_connect: asprintf fail.\n")); + ads->auth.user_name = NULL; + } } if (!ads->auth.realm) { @@ -577,19 +698,8 @@ got_connection: ads->auth.kdc_server = SMB_STRDUP(addr); } -#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->config.realm); - setenv(env, ads->auth.kdc_server, 1); - free(env); - } -#endif - /* If the caller() requested no LDAP bind, then we are done */ - + if (ads->auth.flags & ADS_AUTH_NO_BIND) { status = ADS_SUCCESS; goto out; @@ -600,10 +710,11 @@ got_connection: status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); goto out; } - + /* Otherwise setup the TCP LDAP session */ ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name, + &ads->ldap.ss, ads->ldap.port, lp_ldap_timeout()); if (ads->ldap.ld == NULL) { status = ADS_ERROR(LDAP_OPERATIONS_ERROR); @@ -613,27 +724,28 @@ got_connection: /* cache the successful connection for workgroup and realm */ if (ads_closest_dc(ads)) { - print_sockaddr(addr, sizeof(addr), &ads->ldap.ss); - saf_store( ads->server.workgroup, addr); - saf_store( ads->server.realm, addr); + saf_store( ads->server.workgroup, ads->config.ldap_server_name); + saf_store( ads->server.realm, ads->config.ldap_server_name); } ldap_set_option(ads->ldap.ld, LDAP_OPT_PROTOCOL_VERSION, &version); - status = ADS_ERROR(smb_ldap_start_tls(ads->ldap.ld, version)); - if (!ADS_ERR_OK(status)) { - goto out; + if ( lp_ldap_ssl_ads() ) { + status = ADS_ERROR(smb_ldap_start_tls(ads->ldap.ld, version)); + if (!ADS_ERR_OK(status)) { + goto out; + } } /* fill in the current time and offsets */ - + status = ads_current_time( ads ); if ( !ADS_ERR_OK(status) ) { goto out; } /* Now do the bind */ - + if (ads->auth.flags & ADS_AUTH_ANON_BIND) { status = ADS_ERROR(ldap_simple_bind_s(ads->ldap.ld, NULL, NULL)); goto out; @@ -698,13 +810,13 @@ static struct berval *dup_berval(TALLOC_CTX *ctx, const struct berval *in_val) if (!in_val) return NULL; - value = TALLOC_ZERO_P(ctx, struct berval); + value = talloc_zero(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 = (char *)TALLOC_MEMDUP(ctx, in_val->bv_val, + value->bv_val = (char *)talloc_memdup(ctx, in_val->bv_val, in_val->bv_len); return value; } @@ -717,11 +829,11 @@ static struct berval **ads_dup_values(TALLOC_CTX *ctx, { struct berval **values; int i; - + if (!in_vals) return NULL; for (i=0; in_vals[i]; i++) ; /* count values */ - values = TALLOC_ZERO_ARRAY(ctx, struct berval *, i+1); + values = talloc_zero_array(ctx, struct berval *, i+1); if (!values) return NULL; for (i=0; in_vals[i]; i++) { @@ -742,7 +854,7 @@ static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals) if (!in_vals) return NULL; for (i=0; in_vals[i]; i++) ; /* count values */ - values = TALLOC_ZERO_ARRAY(ctx, char *, i+1); + values = talloc_zero_array(ctx, char *, i+1); if (!values) return NULL; for (i=0; in_vals[i]; i++) { @@ -762,11 +874,11 @@ 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++) ; /* count values */ - values = TALLOC_ZERO_ARRAY(ctx, char *, i+1); + values = talloc_zero_array(ctx, char *, i+1); if (!values) return NULL; for (i=0; in_vals[i]; i++) { @@ -801,7 +913,7 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, int *count, struct berval **cookie) { int rc, i, version; - char *utf8_expr, *utf8_path, **search_attrs; + char *utf8_expr, *utf8_path, **search_attrs = NULL; size_t converted_size; LDAPControl PagedResults, NoReferrals, ExternalCtrl, *controls[4], **rcontrols; BerElement *cookie_be = NULL; @@ -832,12 +944,12 @@ 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(talloc_tos(), &search_attrs, attrs))) { + if (!(search_attrs = str_list_copy(talloc_tos(), attrs))) { rc = LDAP_NO_MEMORY; goto done; } } - + /* Paged results only available on ldap v3 or later */ ldap_get_option(ads->ldap.ld, LDAP_OPT_PROTOCOL_VERSION, &version); if (version < LDAP_VERSION3) { @@ -847,28 +959,28 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, cookie_be = ber_alloc_t(LBER_USE_DER); if (*cookie) { - ber_printf(cookie_be, "{iO}", (ber_int_t) 1000, *cookie); + ber_printf(cookie_be, "{iO}", (ber_int_t) ads->config.ldap_page_size, *cookie); ber_bvfree(*cookie); /* don't need it from last time */ *cookie = NULL; } else { - ber_printf(cookie_be, "{io}", (ber_int_t) 1000, "", 0); + ber_printf(cookie_be, "{io}", (ber_int_t) ads->config.ldap_page_size, "", 0); } ber_flatten(cookie_be, &cookie_bv); - PagedResults.ldctl_oid = CONST_DISCARD(char *, ADS_PAGE_CTL_OID); + PagedResults.ldctl_oid = discard_const_p(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 = CONST_DISCARD(char *, ADS_NO_REFERRALS_OID); + NoReferrals.ldctl_oid = discard_const_p(char, ADS_NO_REFERRALS_OID); NoReferrals.ldctl_iscritical = (char) 0; NoReferrals.ldctl_value.bv_len = 0; - NoReferrals.ldctl_value.bv_val = CONST_DISCARD(char *, ""); + NoReferrals.ldctl_value.bv_val = discard_const_p(char, ""); if (external_control && (strequal(external_control->control, ADS_EXTENDED_DN_OID) || strequal(external_control->control, ADS_SD_FLAGS_OID))) { - ExternalCtrl.ldctl_oid = CONST_DISCARD(char *, external_control->control); + ExternalCtrl.ldctl_oid = discard_const_p(char, external_control->control); ExternalCtrl.ldctl_iscritical = (char) external_control->critical; /* win2k does not accept a ldctl_value beeing passed in */ @@ -912,7 +1024,7 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, 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) */ @@ -967,7 +1079,7 @@ done: if (ext_bv) { ber_bvfree(ext_bv); } - + /* if/when we decide to utf8-encode attrs, take out this next line */ TALLOC_FREE(search_attrs); @@ -1095,7 +1207,7 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, &res, &count, &cookie); if (!ADS_ERR_OK(status)) break; - + ads_process_results(ads, res, fn, data_area); ads_msgfree(ads, res); } @@ -1144,7 +1256,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(talloc_tos(), &search_attrs, attrs))) + if (!(search_attrs = str_list_copy(talloc_tos(), attrs))) { DEBUG(1,("ads_do_search: str_list_copy() failed!")); rc = LDAP_NO_MEMORY; @@ -1212,23 +1324,13 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path, ldap_msgfree(msg); } -/** - * 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) -{ - SAFE_FREE(mem); -} - /** * Get a dn from search results * @param ads connection to ads server * @param msg Search result * @return dn string **/ - char *ads_get_dn(ADS_STRUCT *ads, LDAPMessage *msg) + char *ads_get_dn(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, LDAPMessage *msg) { char *utf8_dn, *unix_dn; size_t converted_size; @@ -1240,7 +1342,7 @@ void ads_memfree(ADS_STRUCT *ads, void *mem) return NULL; } - if (!pull_utf8_allocate(&unix_dn, utf8_dn, &converted_size)) { + if (!pull_utf8_talloc(mem_ctx, &unix_dn, utf8_dn, &converted_size)) { DEBUG(0,("ads_get_dn: string conversion failure utf8 [%s]\n", utf8_dn )); return NULL; @@ -1293,7 +1395,7 @@ char *ads_parent_dn(const char *dn) DEBUG(1, ("asprintf failed!\n")); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - + status = ads_search(ads, res, expr, attrs); SAFE_FREE(expr); return status; @@ -1308,12 +1410,12 @@ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx) { #define ADS_MODLIST_ALLOC_SIZE 10 LDAPMod **mods; - - if ((mods = TALLOC_ZERO_ARRAY(ctx, 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; - + return (ADS_MODLIST)mods; } @@ -1346,7 +1448,7 @@ 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_ARRAY(ctx, modlist, LDAPMod *, + if (!(modlist = talloc_realloc(ctx, modlist, LDAPMod *, curmod+ADS_MODLIST_ALLOC_SIZE+1))) return ADS_ERROR(LDAP_NO_MEMORY); memset(&modlist[curmod], 0, @@ -1354,8 +1456,8 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, modlist[curmod+ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1; *mods = (ADS_MODLIST)modlist; } - - if (!(modlist[curmod] = TALLOC_ZERO_P(ctx, LDAPMod))) + + if (!(modlist[curmod] = talloc_zero(ctx, LDAPMod))) return ADS_ERROR(LDAP_NO_MEMORY); modlist[curmod]->mod_type = talloc_strdup(ctx, name); if (mod_op & LDAP_MOD_BVALUES) { @@ -1448,7 +1550,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 = { - CONST_DISCARD(char *, ADS_PERMIT_MODIFY_OID), + discard_const_p(char, ADS_PERMIT_MODIFY_OID), {0, NULL}, (char) 1}; LDAPControl *controls[2]; @@ -1456,7 +1558,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, &converted_size)) { + if (!push_utf8_talloc(talloc_tos(), &utf8_dn, mod_dn, &converted_size)) { return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } @@ -1466,7 +1568,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) mods[i] = NULL; ret = ldap_modify_ext_s(ads->ldap.ld, utf8_dn, (LDAPMod **) mods, controls, NULL); - SAFE_FREE(utf8_dn); + TALLOC_FREE(utf8_dn); return ADS_ERROR(ret); } @@ -1483,18 +1585,18 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) char *utf8_dn = NULL; size_t converted_size; - if (!push_utf8_allocate(&utf8_dn, new_dn, &converted_size)) { - DEBUG(1, ("ads_gen_add: push_utf8_allocate failed!")); + if (!push_utf8_talloc(talloc_tos(), &utf8_dn, new_dn, &converted_size)) { + DEBUG(1, ("ads_gen_add: push_utf8_talloc 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++); /* make sure the end of the list is NULL */ mods[i] = NULL; ret = ldap_add_s(ads->ldap.ld, utf8_dn, (LDAPMod**)mods); - SAFE_FREE(utf8_dn); + TALLOC_FREE(utf8_dn); return ADS_ERROR(ret); } @@ -1509,13 +1611,13 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) int ret; char *utf8_dn = NULL; size_t converted_size; - if (!push_utf8_allocate(&utf8_dn, del_dn, &converted_size)) { - DEBUG(1, ("ads_del_dn: push_utf8_allocate failed!")); + if (!push_utf8_talloc(talloc_tos(), &utf8_dn, del_dn, &converted_size)) { + DEBUG(1, ("ads_del_dn: push_utf8_talloc failed!")); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - + ret = ldap_delete_s(ads->ldap.ld, utf8_dn); - SAFE_FREE(utf8_dn); + TALLOC_FREE(utf8_dn); return ADS_ERROR(ret); } @@ -1534,12 +1636,12 @@ char *ads_ou_string(ADS_STRUCT *ads, const char *org_unit) if (!org_unit || !*org_unit) { - ret = ads_default_ou_string(ads, WELL_KNOWN_GUID_COMPUTERS); + ret = ads_default_ou_string(ads, DS_GUID_COMPUTERS_CONTAINER); /* samba4 might not yet respond to a wellknownobject-query */ return ret ? ret : SMB_STRDUP("cn=Computers"); } - + if (strequal(org_unit, "Computers")) { return SMB_STRDUP("cn=Computers"); } @@ -1585,7 +1687,7 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) } /* substitute the bind-path from the well-known-guid-search result */ - wkn_dn = ads_get_dn(ads, res); + wkn_dn = ads_get_dn(ads, talloc_tos(), res); if (!wkn_dn) { goto out; } @@ -1614,7 +1716,7 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) for (i=1; i < new_ln; i++) { char *s = NULL; - + if (asprintf(&s, "%s,%s", ret, wkn_dn_exp[i]) == -1) { SAFE_FREE(ret); goto out; @@ -1631,7 +1733,7 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) out: SAFE_FREE(base); ads_msgfree(ads, res); - ads_memfree(ads, wkn_dn); + TALLOC_FREE(wkn_dn); if (wkn_dn_exp) { ldap_value_free(wkn_dn_exp); } @@ -1687,14 +1789,14 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *account_name) return kvno; } - dn_string = ads_get_dn(ads, res); + dn_string = ads_get_dn(ads, talloc_tos(), 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)); - ads_memfree(ads, dn_string); + TALLOC_FREE(dn_string); /* --------------------------------------------------------- * 0 is returned as a default KVNO from this point on... @@ -1782,14 +1884,14 @@ ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machin talloc_destroy(ctx); return ret; } - dn_string = ads_get_dn(ads, res); + dn_string = ads_get_dn(ads, talloc_tos(), 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); - ads_memfree(ads,dn_string); + TALLOC_FREE(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)); @@ -1841,28 +1943,42 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n } /* 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)]); + if (!strupper_m(psp1)) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto out; + } + + if (!strlower_m(&psp1[strlen(spn)])) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto out; + } servicePrincipalName[0] = psp1; - + 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)]); + if (!strupper_m(psp2)) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto out; + } + + if (!strlower_m(&psp2[strlen(spn)])) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto out; + } servicePrincipalName[1] = psp2; DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n", @@ -1872,20 +1988,19 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n 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")); goto out; } - - if ( (dn_string = ads_get_dn(ads, res)) == NULL ) { + + if ( (dn_string = ads_get_dn(ads, ctx, 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")); goto out; @@ -1921,7 +2036,7 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, 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); @@ -1938,7 +2053,7 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, if ( !new_dn || !samAccountName ) { goto done; } - + #ifndef ENCTYPE_ARCFOUR_HMAC acct_control |= UF_USE_DES_KEY_ONLY; #endif @@ -1950,7 +2065,7 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name, if (!(mods = ads_init_mods(ctx))) { goto done; } - + ads_mod_str(ctx, &mods, "cn", machine_name); ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); ads_mod_strlist(ctx, &mods, "objectClass", objectClass); @@ -1962,7 +2077,7 @@ done: SAFE_FREE(machine_escaped); ads_msgfree(ads, res); talloc_destroy(ctx); - + return ret; } @@ -1998,7 +2113,7 @@ ADS_STATUS ads_move_machine_acct(ADS_STRUCT *ads, const char *machine_name, goto done; } - computer_dn = ads_get_dn(ads, res); + computer_dn = ads_get_dn(ads, talloc_tos(), res); if (!computer_dn) { rc = ADS_ERROR(LDAP_NO_MEMORY); goto done; @@ -2023,7 +2138,7 @@ ADS_STATUS ads_move_machine_acct(ADS_STRUCT *ads, const char *machine_name, done: ads_msgfree(ads, res); SAFE_FREE(filter); - SAFE_FREE(computer_dn); + TALLOC_FREE(computer_dn); SAFE_FREE(computer_rdn); if (!ADS_ERR_OK(rc)) { @@ -2056,13 +2171,16 @@ static void dump_guid(ADS_STRUCT *ads, const char *field, struct berval **values { int i; for (i=0; values[i]; i++) { + NTSTATUS status; + DATA_BLOB in = data_blob_const(values[i]->bv_val, values[i]->bv_len); + struct GUID guid; - UUID_FLAT guid; - struct GUID tmp; - - memcpy(guid.info, values[i]->bv_val, sizeof(guid.info)); - smb_uuid_unpack(guid, &tmp); - printf("%s: %s\n", field, smb_uuid_string(talloc_tos(), tmp)); + status = GUID_from_ndr_blob(&in, &guid); + if (NT_STATUS_IS_OK(status)) { + printf("%s: %s\n", field, GUID_string(talloc_tos(), &guid)); + } else { + printf("%s: INVALID GUID\n", field); + } } } @@ -2073,9 +2191,11 @@ static void dump_sid(ADS_STRUCT *ads, const char *field, struct berval **values) { int i; for (i=0; values[i]; i++) { - DOM_SID sid; + struct dom_sid sid; fstring tmp; - sid_parse(values[i]->bv_val, values[i]->bv_len, &sid); + if (!sid_parse(values[i]->bv_val, values[i]->bv_len, &sid)) { + return; + } printf("%s: %s\n", field, sid_to_fstring(tmp, &sid)); } } @@ -2148,7 +2268,7 @@ static bool ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da } for (i=0; handlers[i].name; i++) { - if (StrCaseCmp(handlers[i].name, field) == 0) { + if (strcasecmp_m(handlers[i].name, field) == 0) { if (!values) /* first time, indicate string or not */ return handlers[i].string; handlers[i].handler(ads, field, (struct berval **) values); @@ -2201,7 +2321,7 @@ static bool ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da msg = ads_next_entry(ads, msg)) { char *utf8_field; BerElement *b; - + for (utf8_field=ldap_first_attribute(ads->ldap.ld, (LDAPMessage *)msg,&b); utf8_field; @@ -2320,7 +2440,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) values = ldap_get_values(ads->ldap.ld, msg, field); if (!values) return NULL; - + if (values[0] && pull_utf8_talloc(mem_ctx, &ux_string, values[0], &converted_size)) { @@ -2353,7 +2473,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) *num_values = ldap_count_values(values); - ret = TALLOC_ARRAY(mem_ctx, char *, *num_values + 1); + ret = talloc_array(mem_ctx, char *, *num_values + 1); if (!ret) { ldap_value_free(values); return NULL; @@ -2402,7 +2522,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) size_t num_new_strings; unsigned long int range_start; unsigned long int range_end; - + /* we might have been given the whole lot anyway */ if ((strings = ads_pull_strings(ads, mem_ctx, msg, field, num_strings))) { *more_strings = False; @@ -2428,7 +2548,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) *more_strings = False; return NULL; } - + if (sscanf(&range_attr[strlen(expected_range_attrib)], "%lu-%lu", &range_start, &range_end) == 2) { *more_strings = True; @@ -2455,7 +2575,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) } 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", @@ -2466,15 +2586,15 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) return NULL; } - strings = TALLOC_REALLOC_ARRAY(mem_ctx, current_strings, char *, + strings = talloc_realloc(mem_ctx, current_strings, char *, *num_strings + num_new_strings); - + if (strings == NULL) { ldap_memfree(range_attr); *more_strings = False; return NULL; } - + if (new_strings && num_new_strings) { memcpy(&strings[*num_strings], new_strings, sizeof(*new_strings) * num_new_strings); @@ -2487,7 +2607,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) "%s;range=%d-*", field, (int)*num_strings); - + if (!*next_attribute) { DEBUG(1, ("talloc_asprintf for next attribute failed!\n")); ldap_memfree(range_attr); @@ -2536,27 +2656,22 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) **/ bool ads_pull_guid(ADS_STRUCT *ads, LDAPMessage *msg, struct GUID *guid) { - char **values; - UUID_FLAT flat_guid; + DATA_BLOB blob; + NTSTATUS status; - values = ldap_get_values(ads->ldap.ld, msg, "objectGUID"); - if (!values) - return False; - - if (values[0]) { - memcpy(&flat_guid.info, values[0], sizeof(UUID_FLAT)); - smb_uuid_unpack(flat_guid, guid); - ldap_value_free(values); - return True; + if (!smbldap_talloc_single_blob(talloc_tos(), ads->ldap.ld, msg, "objectGUID", + &blob)) { + return false; } - ldap_value_free(values); - return False; + status = GUID_from_ndr_blob(&blob, guid); + talloc_free(blob.data); + return NT_STATUS_IS_OK(status); } /** - * pull a single DOM_SID from a ADS result + * pull a single struct dom_sid from a ADS result * @param ads connection to ads server * @param msg Results of search * @param field Attribute to retrieve @@ -2564,25 +2679,13 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @return boolean inidicating success */ bool ads_pull_sid(ADS_STRUCT *ads, LDAPMessage *msg, const char *field, - DOM_SID *sid) + struct dom_sid *sid) { - struct berval **values; - bool ret = False; - - values = ldap_get_values_len(ads->ldap.ld, msg, field); - - if (!values) - return False; - - if (values[0]) - ret = sid_parse(values[0]->bv_val, values[0]->bv_len, sid); - - ldap_value_free_len(values); - return ret; + return smbldap_pull_sid(ads->ldap.ld, msg, field, sid); } /** - * pull an array of DOM_SIDs from a ADS result + * pull an array of struct 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 @@ -2591,7 +2694,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) * @return the count of SIDs pulled **/ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, - LDAPMessage *msg, const char *field, DOM_SID **sids) + LDAPMessage *msg, const char *field, struct dom_sid **sids) { struct berval **values; bool ret; @@ -2606,7 +2709,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) /* nop */ ; if (i) { - (*sids) = TALLOC_ARRAY(mem_ctx, DOM_SID, i); + (*sids) = talloc_array(mem_ctx, struct dom_sid, i); if (!(*sids)) { ldap_value_free_len(values); return 0; @@ -2624,22 +2727,23 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) count++; } } - + ldap_value_free_len(values); return count; } /** - * pull a SEC_DESC from a ADS result + * pull a struct security_descriptor 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) + * @param sd Pointer to *struct security_descriptor to store result (talloc()ed) * @return boolean inidicating success */ bool ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, - LDAPMessage *msg, const char *field, SEC_DESC **sd) + LDAPMessage *msg, const char *field, + struct security_descriptor **sd) { struct berval **values; bool ret = true; @@ -2659,7 +2763,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) ret = false; } } - + ldap_value_free_len(values); return ret; } @@ -2788,12 +2892,12 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads) } /* but save the time and offset in the original ADS_STRUCT */ - + 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)); + DEBUG(4,("KDC time offset is %d seconds\n", ads->auth.time_offset)); } ads_msgfree(ads, res); @@ -2819,7 +2923,7 @@ ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val) ADS_STATUS status; LDAPMessage *res; ADS_STRUCT *ads_s = ads; - + *val = DS_DOMAIN_FUNCTION_2000; /* establish a new ldap tcp session if necessary */ @@ -2828,6 +2932,7 @@ ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val) if ( (ads_s = ads_init( ads->server.realm, ads->server.workgroup, ads->server.ldap_server )) == NULL ) { + status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); goto done; } ads_s->auth.flags = ADS_AUTH_ANON_BIND; @@ -2838,7 +2943,7 @@ ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val) /* 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 ) { @@ -2852,7 +2957,7 @@ ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val) } DEBUG(3,("ads_domain_func_level: %d\n", *val)); - + ads_msgfree(ads, res); done: @@ -2870,7 +2975,7 @@ done: * @param sid Pointer to domain sid * @return status of search **/ -ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) +ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, struct dom_sid *sid) { const char *attrs[] = {"objectSid", NULL}; LDAPMessage *res; @@ -2884,7 +2989,7 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) return ADS_ERROR_SYSTEM(ENOENT); } ads_msgfree(ads, res); - + return ADS_SUCCESS; } @@ -2974,7 +3079,7 @@ ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const c return ADS_ERROR(LDAP_NO_SUCH_OBJECT); } - dn = ads_get_dn(ads, res); + dn = ads_get_dn(ads, mem_ctx, res); if (dn == NULL) { ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); @@ -2984,18 +3089,18 @@ ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const c parent = ads_parent_dn(ads_parent_dn(ads_parent_dn(dn))); if (parent == NULL) { ads_msgfree(ads, res); - ads_memfree(ads, dn); + TALLOC_FREE(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); + TALLOC_FREE(dn); return ADS_ERROR(LDAP_NO_MEMORY); } - ads_memfree(ads, dn); + TALLOC_FREE(dn); ads_msgfree(ads, res); return status; @@ -3085,7 +3190,7 @@ ADS_STATUS ads_get_joinable_ous(ADS_STRUCT *ads, char *dn = NULL; - dn = ads_get_dn(ads, msg); + dn = ads_get_dn(ads, talloc_tos(), msg); if (!dn) { ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); @@ -3094,12 +3199,12 @@ ADS_STATUS ads_get_joinable_ous(ADS_STRUCT *ads, if (!add_string_to_array(mem_ctx, dn, (const char ***)ous, (int *)num_ous)) { - ads_memfree(ads, dn); + TALLOC_FREE(dn); ads_msgfree(ads, res); return ADS_ERROR(LDAP_NO_MEMORY); } - ads_memfree(ads, dn); + TALLOC_FREE(dn); } ads_msgfree(ads, res); @@ -3109,61 +3214,67 @@ ADS_STATUS ads_get_joinable_ous(ADS_STRUCT *ads, /** - * pull a DOM_SID from an extended dn string - * @param mem_ctx TALLOC_CTX + * pull a struct 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 + * @param sid pointer to a struct dom_sid + * @return NT_STATUS_OK on success, + * NT_INVALID_PARAMETER on error, + * NT_STATUS_NOT_FOUND if no SID present **/ -bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, - const char *extended_dn, - enum ads_extended_dn_flags flags, - DOM_SID *sid) +ADS_STATUS ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, + const char *extended_dn, + enum ads_extended_dn_flags flags, + struct dom_sid *sid) { char *p, *q, *dn; if (!extended_dn) { - return False; + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); } /* otherwise extended_dn gets stripped off */ if ((dn = talloc_strdup(mem_ctx, extended_dn)) == NULL) { - return False; + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); } - /* + /* * 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 + * ;;CN=gd,OU=berlin,OU=suse,DC=ber,DC=suse,DC=de + * + * Object with no SID, such as an Exchange Public Folder + * ;CN=public,CN=Microsoft Exchange System Objects,DC=sd2k3ms,DC=west,DC=isilon,DC=com */ p = strchr(dn, ';'); if (!p) { - return False; + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); } if (strncmp(p, ";'); if (!q) { - return False; + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); } - + *q = '\0'; DEBUG(100,("ads_get_sid_from_extended_dn: sid string is %s\n", p)); switch (flags) { - + case ADS_EXTENDED_DN_STRING: if (!string_to_sid(sid, p)) { - return False; + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); } break; case ADS_EXTENDED_DN_HEX_STRING: { @@ -3172,68 +3283,21 @@ bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, buf_len = strhex_to_str(buf, sizeof(buf), p, strlen(p)); if (buf_len == 0) { - return False; + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); } if (!sid_parse(buf, buf_len, sid)) { DEBUG(10,("failed to parse sid\n")); - return False; + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); } break; } default: DEBUG(10,("unknown extended dn format\n")); - return False; + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); } - return True; -} - -/** - * 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 flags string type of extended_dn - * @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, - LDAPMessage *msg, - const char *field, - enum ads_extended_dn_flags flags, - DOM_SID **sids) -{ - int i; - size_t dn_count; - char **dn_strings; - - if ((dn_strings = ads_pull_strings(ads, mem_ctx, msg, field, - &dn_count)) == NULL) { - return 0; - } - - (*sids) = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, dn_count + 1); - if (!(*sids)) { - TALLOC_FREE(dn_strings); - return 0; - } - - for (i=0; ildap.ld, hostnameDN, pldap_control, NULL); if (rc) { @@ -3447,7 +3518,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) if (!ADS_ERR_OK(status)) { SAFE_FREE(host); - ads_memfree(ads, hostnameDN); + TALLOC_FREE(hostnameDN); return status; } @@ -3456,9 +3527,9 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) char *dn = NULL; - if ((dn = ads_get_dn(ads, msg_sub)) == NULL) { + if ((dn = ads_get_dn(ads, talloc_tos(), msg_sub)) == NULL) { SAFE_FREE(host); - ads_memfree(ads, hostnameDN); + TALLOC_FREE(hostnameDN); return ADS_ERROR(LDAP_NO_MEMORY); } @@ -3466,12 +3537,12 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) 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); + TALLOC_FREE(dn); + TALLOC_FREE(hostnameDN); return status; } - ads_memfree(ads, dn); + TALLOC_FREE(dn); } /* there should be no subordinate objects anymore */ @@ -3481,7 +3552,7 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) if (!ADS_ERR_OK(status) || ( (ads_count_replies(ads, res)) > 0 ) ) { SAFE_FREE(host); - ads_memfree(ads, hostnameDN); + TALLOC_FREE(hostnameDN); return status; } @@ -3490,12 +3561,12 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) 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); + TALLOC_FREE(hostnameDN); return status; } } - ads_memfree(ads, hostnameDN); + TALLOC_FREE(hostnameDN); status = ads_find_machine_acct(ads, &res, host); if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { @@ -3513,8 +3584,8 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) * @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 user_sid pointer to struct dom_sid (objectSid) + * @param primary_group_sid pointer to struct dom_sid (self composed) * @param sids pointer to sid array to allocate * @param num_sids counter of SIDs pulled * @return status of token query @@ -3522,18 +3593,18 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) 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, + struct dom_sid *user_sid, + struct dom_sid *primary_group_sid, + struct 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; + struct dom_sid *tmp_sids; + struct dom_sid tmp_user_sid; + struct dom_sid tmp_primary_group_sid; uint32 pgid; const char *attrs[] = { "objectSid", @@ -3567,12 +3638,11 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) /* hack to compose the primary group sid without knowing the * domsid */ - DOM_SID domsid; - uint32 dummy_rid; + struct dom_sid domsid; sid_copy(&domsid, &tmp_user_sid); - if (!sid_split_rid(&domsid, &dummy_rid)) { + if (!sid_split_rid(&domsid, NULL)) { ads_msgfree(ads, res); return ADS_ERROR_LDAP(LDAP_NO_MEMORY); } @@ -3644,7 +3714,7 @@ ADS_STATUS ads_find_samaccount(ADS_STRUCT *ads, status = ads_do_search_all(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, filter, attrs, &res); - + if (!ADS_ERR_OK(status)) { goto out; } @@ -3654,7 +3724,7 @@ ADS_STATUS ads_find_samaccount(ADS_STRUCT *ads, goto out; } - dn = ads_get_dn(ads, res); + dn = ads_get_dn(ads, talloc_tos(), res); if (dn == NULL) { status = ADS_ERROR(LDAP_NO_MEMORY); goto out; @@ -3677,7 +3747,7 @@ ADS_STATUS ads_find_samaccount(ADS_STRUCT *ads, } } out: - ads_memfree(ads, dn); + TALLOC_FREE(dn); ads_msgfree(ads, res); return status; @@ -3747,7 +3817,7 @@ const char *ads_get_extended_right_name_by_guid(ADS_STRUCT *ads, } expr = talloc_asprintf(mem_ctx, "(rightsGuid=%s)", - smb_uuid_string(mem_ctx, *rights_guid)); + GUID_string(mem_ctx, rights_guid)); if (!expr) { goto done; } @@ -3772,7 +3842,6 @@ const char *ads_get_extended_right_name_by_guid(ADS_STRUCT *ads, done: ads_msgfree(ads, res); return result; - } /** @@ -3787,12 +3856,13 @@ 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; + char **exploded_dn; + const char *name; + char *ou_string; - name_dn = ldb_dn_explode(mem_ctx, *account_ou); - if (name_dn) { + exploded_dn = ldap_explode_dn(*account_ou, 0); + if (exploded_dn) { + ldap_value_free(exploded_dn); return ADS_SUCCESS; } @@ -3804,20 +3874,18 @@ ADS_STATUS ads_check_ou_dn(TALLOC_CTX *mem_ctx, 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) { + exploded_dn = ldap_explode_dn(name, 0); + if (!exploded_dn) { return ADS_ERROR_LDAP(LDAP_INVALID_DN_SYNTAX); } + ldap_value_free(exploded_dn); - *account_ou = talloc_strdup(mem_ctx, name); - if (!*account_ou) { - return ADS_ERROR_LDAP(LDAP_NO_MEMORY); - } - + *account_ou = name; return ADS_SUCCESS; }