X-Git-Url: http://git.samba.org/?p=metze%2Fsamba%2Fwip.git;a=blobdiff_plain;f=source3%2Flibads%2Fldap.c;h=640a020a8bdbbe12cd638acfed73fdff79706e72;hp=3e5764a598b369082f367ba4c0a9a8f2aed745cb;hb=f3562424b6079065319e6a5362e5c7cdea36140e;hpb=3194ad2838bedee3eff60c767552d8a801b5eb70 diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 3e5764a598b3..640a020a8bdb 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/ldb.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,26 +138,39 @@ 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; @@ -190,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 NETLOGON_SAM_LOGON_RESPONSE_EX cldap_reply; - TALLOC_CTX *mem_ctx = NULL; + 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; } @@ -224,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; } @@ -251,26 +308,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; } @@ -321,7 +372,8 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) } if ( !c_realm || !*c_realm ) { - DEBUG(0,("ads_find_dc: no realm or workgroup! Don't know what to do\n")); + 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 ... */ } @@ -411,7 +463,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 ); } @@ -496,12 +548,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(); @@ -511,6 +564,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 @@ -519,7 +573,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); @@ -579,7 +634,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 */ @@ -624,7 +679,7 @@ got_connection: /* Must use the userPrincipalName value here or sAMAccountName and not servicePrincipalName; found by Guenther Deschner */ - if (asprintf(&ads->auth.user_name, "%s$", global_myname() ) == -1) { + if (asprintf(&ads->auth.user_name, "%s$", lp_netbios_name() ) == -1) { DEBUG(0,("ads_connect: asprintf fail.\n")); ads->auth.user_name = NULL; } @@ -639,20 +694,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 = NULL; - if (asprintf(&env, "KRB5_KDC_ADDRESS_%s", ads->config.realm) > 0) { - 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; @@ -663,10 +706,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); @@ -690,14 +734,14 @@ got_connection: } /* 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; @@ -762,13 +806,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; } @@ -781,11 +825,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++) { @@ -806,7 +850,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++) { @@ -826,11 +870,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++) { @@ -901,7 +945,7 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads, 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) { @@ -911,28 +955,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 */ @@ -976,7 +1020,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) */ @@ -1031,7 +1075,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); @@ -1159,7 +1203,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); } @@ -1347,7 +1391,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; @@ -1362,12 +1406,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; } @@ -1400,7 +1444,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, @@ -1408,8 +1452,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) { @@ -1502,7 +1546,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]; @@ -1541,7 +1585,7 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) 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 */ @@ -1567,7 +1611,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) 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); TALLOC_FREE(utf8_dn); return ADS_ERROR(ret); @@ -1588,12 +1632,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"); } @@ -1668,7 +1712,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; @@ -1895,7 +1939,7 @@ 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); @@ -1904,13 +1948,13 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n strupper_m(psp1); strlower_m(&psp1[strlen(spn)]); 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; @@ -1926,18 +1970,18 @@ 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, ctx, res)) == NULL ) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto out; } - + ret = ads_gen_mod(ads, dn_string, mods); if (!ADS_ERR_OK(ret)) { DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n")); @@ -1974,7 +2018,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); @@ -1991,7 +2035,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 @@ -2003,7 +2047,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); @@ -2015,7 +2059,7 @@ done: SAFE_FREE(machine_escaped); ads_msgfree(ads, res); talloc_destroy(ctx); - + return ret; } @@ -2076,7 +2120,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)) { @@ -2109,13 +2153,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, GUID_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); + } } } @@ -2126,9 +2173,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)); } } @@ -2201,7 +2250,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); @@ -2254,7 +2303,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; @@ -2373,7 +2422,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)) { @@ -2406,7 +2455,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; @@ -2455,7 +2504,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; @@ -2481,7 +2530,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; @@ -2508,7 +2557,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", @@ -2519,15 +2568,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); @@ -2540,7 +2589,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); @@ -2589,27 +2638,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 @@ -2617,13 +2661,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) { 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 @@ -2632,7 +2676,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; @@ -2647,7 +2691,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; @@ -2665,22 +2709,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; @@ -2700,7 +2745,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) ret = false; } } - + ldap_value_free_len(values); return ret; } @@ -2829,12 +2874,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); @@ -2860,7 +2905,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 */ @@ -2880,7 +2925,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 ) { @@ -2894,7 +2939,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: @@ -2912,7 +2957,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; @@ -2926,7 +2971,7 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid) return ADS_ERROR_SYSTEM(ENOENT); } ads_msgfree(ads, res); - + return ADS_SUCCESS; } @@ -3151,11 +3196,11 @@ ADS_STATUS ads_get_joinable_ous(ADS_STRUCT *ads, /** - * pull a DOM_SID from an extended dn string + * 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 + * @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 @@ -3163,7 +3208,7 @@ ADS_STATUS ads_get_joinable_ous(ADS_STRUCT *ads, ADS_STATUS ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, const char *extended_dn, enum ads_extended_dn_flags flags, - DOM_SID *sid) + struct dom_sid *sid) { char *p, *q, *dn; @@ -3237,61 +3282,6 @@ ADS_STATUS ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx, return ADS_ERROR_NT(NT_STATUS_OK); } -/** - * 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; - ADS_STATUS rc; - size_t dn_count, ret_count = 0; - 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) { @@ -3569,8 +3563,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 @@ -3578,18 +3572,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", @@ -3623,12 +3617,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); } @@ -3700,7 +3693,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; } @@ -3828,7 +3821,6 @@ const char *ads_get_extended_right_name_by_guid(ADS_STRUCT *ads, done: ads_msgfree(ads, res); return result; - } /** @@ -3843,39 +3835,36 @@ 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; - struct ldb_context *ldb = ldb_init(mem_ctx, NULL); + char **exploded_dn; + const char *name; + char *ou_string; - name_dn = ldb_dn_new(mem_ctx, ldb, *account_ou); - if (name_dn && ldb_dn_validate(name_dn)) { - talloc_free(ldb); + exploded_dn = ldap_explode_dn(*account_ou, 0); + if (exploded_dn) { + ldap_value_free(exploded_dn); return ADS_SUCCESS; } ou_string = ads_ou_string(ads, *account_ou); if (!ou_string) { - talloc_free(ldb); return ADS_ERROR_LDAP(LDAP_INVALID_DN_SYNTAX); } - name_dn = ldb_dn_new_fmt(mem_ctx, ldb, "%s,%s", ou_string, - ads->config.bind_path); + name = talloc_asprintf(mem_ctx, "%s,%s", ou_string, + ads->config.bind_path); SAFE_FREE(ou_string); - if (!name_dn || !ldb_dn_validate(name_dn)) { - talloc_free(ldb); - return ADS_ERROR_LDAP(LDAP_INVALID_DN_SYNTAX); + if (!name) { + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); } - *account_ou = talloc_strdup(mem_ctx, name); - if (!*account_ou) { - talloc_free(ldb); - return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + exploded_dn = ldap_explode_dn(name, 0); + if (!exploded_dn) { + return ADS_ERROR_LDAP(LDAP_INVALID_DN_SYNTAX); } + ldap_value_free(exploded_dn); - talloc_free(ldb); + *account_ou = name; return ADS_SUCCESS; }