diff --git a/source4/cldap_server/netlogon.c b/source4/cldap_server/netlogon.c index ce49f084f82..252ae884ea4 100644 --- a/source4/cldap_server/netlogon.c +++ b/source4/cldap_server/netlogon.c @@ -33,6 +33,7 @@ static NTSTATUS cldapd_netlogon_fill(struct cldap_socket *cldap, TALLOC_CTX *mem_ctx, const char *domain, + const char *domain_guid, const char *user, const char *src_address, uint32_t version, @@ -61,13 +62,15 @@ static NTSTATUS cldapd_netlogon_fill(struct cldap_socket *cldap, } /* the domain has an optional trailing . */ - if (domain[strlen(domain)-1] == '.') { + if (domain && domain[strlen(domain)-1] == '.') { domain = talloc_strndup(mem_ctx, domain, strlen(domain)-1); } /* try and find the domain */ ret = gendb_search(samctx, samctx, NULL, &res, attrs, - "(&(dnsDomain=%s)(objectClass=domainDNS))", domain); + "(&(objectClass=domainDNS)(|(dnsDomain=%s)(objectGUID=%s)))", + domain?domain:"", + domain_guid?domain_guid:""); if (ret != 1) { DEBUG(2,("Unable to find domain '%s' in sam\n", domain)); return NT_STATUS_NO_SUCH_DOMAIN; @@ -210,9 +213,13 @@ void cldapd_netlogon_request(struct cldap_socket *cldap, t->u.simple.value.length); } if (strcasecmp(t->u.simple.attr, "DomainGuid") == 0) { - domain_guid = talloc_strndup(tmp_ctx, - t->u.simple.value.data, - t->u.simple.value.length); + NTSTATUS enc_status; + struct GUID guid; + enc_status = ldap_decode_ndr_GUID(tmp_ctx, + t->u.simple.value, &guid); + if (NT_STATUS_IS_OK(enc_status)) { + domain_guid = GUID_string(tmp_ctx, &guid); + } } if (strcasecmp(t->u.simple.attr, "DomainSid") == 0) { domain_sid = talloc_strndup(tmp_ctx, @@ -234,14 +241,19 @@ void cldapd_netlogon_request(struct cldap_socket *cldap, } } - if (domain == NULL || host == NULL || version == -1) { + if (domain_guid == NULL && domain == NULL) { + domain = lp_realm(); + } + + if (version == -1) { goto failed; } - DEBUG(0,("cldap netlogon query domain=%s host=%s user=%s version=%d\n", - domain, host, user, version)); + DEBUG(0,("cldap netlogon query domain=%s host=%s user=%s version=%d guid=%s\n", + domain, host, user, version, domain_guid)); - status = cldapd_netlogon_fill(cldap, tmp_ctx, domain, user, src_address, + status = cldapd_netlogon_fill(cldap, tmp_ctx, domain, domain_guid, + user, src_address, version, &netlogon); if (!NT_STATUS_IS_OK(status)) { goto failed; diff --git a/source4/lib/ldb/common/ldb_parse.c b/source4/lib/ldb/common/ldb_parse.c index d9f7dbe524f..5221ef45563 100644 --- a/source4/lib/ldb/common/ldb_parse.c +++ b/source4/lib/ldb/common/ldb_parse.c @@ -170,7 +170,7 @@ static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *ctx, const char *s) ret->operation = LDB_OP_SIMPLE; ret->u.simple.attr = l; - ret->u.simple.value.data = val; + ret->u.simple.value.data = val?val:discard_const_p(char, ""); ret->u.simple.value.length = val?strlen(val):0; return ret; diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index cc7f1a10bcc..0c6a466f27c 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -110,7 +110,7 @@ static struct ldap_parse_tree *ldap_parse_filter(TALLOC_CTX *mem_ctx, decode a RFC2254 binary string representation of a buffer. Used in LDAP filters. */ -static struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str) +struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str) { int i, j; struct ldap_val ret; diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 8d4294cf764..54a96d9672a 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -326,6 +326,7 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, struct ldap_parse_tree *ldap_parse_filter_string(TALLOC_CTX *mem_ctx, const char *s); const char *ldap_binary_encode(TALLOC_CTX *mem_ctx, DATA_BLOB blob); +struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str); /* The following definitions come from libcli/ldap/ldap_client.c */ @@ -384,5 +385,6 @@ struct ldap_message *ldap_ldif2msg(TALLOC_CTX *mem_ctx, const char *s); const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid); const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); +NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldap_val val, struct GUID *guid); #endif diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 45d9b2729e0..2db85d8f092 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -74,3 +74,19 @@ const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) data_blob_free(&blob); return ret; } + +/* + decode a NDR GUID from a ldap filter element +*/ +NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldap_val val, struct GUID *guid) +{ + DATA_BLOB blob; + NTSTATUS status; + + blob.data = val.data; + blob.length = val.length; + status = ndr_pull_struct_blob(&blob, mem_ctx, guid, + (ndr_pull_flags_fn_t)ndr_pull_GUID); + talloc_free(val.data); + return status; +}