diff options
-rw-r--r-- | source4/cldap_server/netlogon.c | 25 | ||||
-rw-r--r-- | source4/nbt_server/dgram/netlogon.c | 51 | ||||
-rw-r--r-- | source4/rpc_server/lsa/dcesrv_lsa.c | 2 | ||||
-rw-r--r-- | source4/rpc_server/samr/dcesrv_samr.c | 101 |
4 files changed, 141 insertions, 38 deletions
diff --git a/source4/cldap_server/netlogon.c b/source4/cldap_server/netlogon.c index 3e99fe80b8..a39ad64a8e 100644 --- a/source4/cldap_server/netlogon.c +++ b/source4/cldap_server/netlogon.c @@ -39,8 +39,9 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd, uint32_t version, union nbt_cldap_netlogon *netlogon) { - const char *attrs[] = {"realm", "dnsDomain", "objectGUID", "name", NULL}; - struct ldb_message **res; + const char *ref_attrs[] = {"nETBIOSName", NULL}; + const char *dom_attrs[] = {"dnsDomain", "objectGUID", NULL}; + struct ldb_message **ref_res, **dom_res; int ret; const char **services = lp_server_services(); uint32_t server_type; @@ -68,7 +69,7 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd, } /* try and find the domain */ - ret = gendb_search(cldapd->samctx, mem_ctx, NULL, &res, attrs, + ret = gendb_search(cldapd->samctx, mem_ctx, NULL, &dom_res, dom_attrs, "(&(objectClass=domainDNS)(|(dnsDomain=%s)(objectGUID=%s)))", domain?domain:"", domain_guid?domain_guid:""); @@ -77,6 +78,15 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd, return NT_STATUS_NO_SUCH_DOMAIN; } + /* try and find the domain */ + ret = gendb_search(cldapd->samctx, mem_ctx, NULL, &ref_res, ref_attrs, + "(&(objectClass=crossRef)(ncName=%s))", + dom_res[0]->dn); + if (ret != 1) { + DEBUG(2,("Unable to find referece to '%s' in sam\n", dom_res[0]->dn)); + return NT_STATUS_NO_SUCH_DOMAIN; + } + server_type = NBT_SERVER_PDC | NBT_SERVER_GC | NBT_SERVER_DS | NBT_SERVER_TIMESERV | @@ -92,13 +102,14 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd, } pdc_name = talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name()); - domain_uuid = samdb_result_guid(res[0], "objectGUID"); - realm = samdb_result_string(res[0], "dnsDomain", lp_realm()); - dns_domain = samdb_result_string(res[0], "dnsDomain", lp_realm()); + domain_uuid = samdb_result_guid(dom_res[0], "objectGUID"); + realm = samdb_result_string(dom_res[0], "dnsDomain", lp_realm()); + dns_domain = samdb_result_string(dom_res[0], "dnsDomain", lp_realm()); pdc_dns_name = talloc_asprintf(mem_ctx, "%s.%s", strlower_talloc(mem_ctx, lp_netbios_name()), dns_domain); - flatname = samdb_result_string(res[0], "name", lp_workgroup()); + + flatname = samdb_result_string(ref_res[0], "nETBIOSName", lp_workgroup()); site_name = "Default-First-Site-Name"; site_name2 = "Default-First-Site-Name"; pdc_ip = iface_best_ip(src_address); diff --git a/source4/nbt_server/dgram/netlogon.c b/source4/nbt_server/dgram/netlogon.c index 0ad05f48c9..b484ca4a77 100644 --- a/source4/nbt_server/dgram/netlogon.c +++ b/source4/nbt_server/dgram/netlogon.c @@ -25,6 +25,7 @@ #include "nbt_server/nbt_server.h" #include "smbd/service_task.h" #include "lib/socket/socket.h" +#include "lib/ldb/include/ldb.h" /* reply to a GETDC request @@ -37,12 +38,31 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot, struct nbt_name *name = &packet->data.msg.dest_name; struct nbt_netlogon_packet reply; struct nbt_netlogon_response_from_pdc *pdc; + const char *ref_attrs[] = {"nETBIOSName", NULL}; + struct ldb_message **ref_res; + struct ldb_context *samctx; + int ret; /* only answer getdc requests on the PDC or LOGON names */ if (name->type != NBT_NAME_PDC && name->type != NBT_NAME_LOGON) { return; } + samctx = samdb_connect(packet); + if (samctx == NULL) { + DEBUG(2,("Unable to open sam in getdc reply\n")); + return; + } + + ret = gendb_search(samctx, samctx, NULL, &ref_res, ref_attrs, + "(&(&(nETBIOSName=%s)(objectclass=crossRef))(ncName=*))", + name->name); + + if (ret != 1) { + DEBUG(2,("Unable to find domain reference '%s' in sam\n", name->name)); + return; + } + /* setup a GETDC reply */ ZERO_STRUCT(reply); reply.command = NETLOGON_RESPONSE_FROM_PDC; @@ -50,7 +70,7 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot, pdc->pdc_name = lp_netbios_name(); pdc->unicode_pdc_name = pdc->pdc_name; - pdc->domain_name = lp_workgroup(); + pdc->domain_name = samdb_result_string(ref_res[0], "nETBIOSName", name->name);; pdc->nt_version = 1; pdc->lmnt_token = 0xFFFF; pdc->lm20_token = 0xFFFF; @@ -77,8 +97,9 @@ static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot, struct nbt_netlogon_packet reply; struct nbt_netlogon_response_from_pdc2 *pdc; struct ldb_context *samctx; - const char *attrs[] = {"realm", "dnsDomain", "objectGUID", NULL}; - struct ldb_message **res; + const char *ref_attrs[] = {"nETBIOSName", "ncName", NULL}; + const char *dom_attrs[] = {"dnsDomain", "objectGUID", NULL}; + struct ldb_message **ref_res, **dom_res; int ret; const char **services = lp_server_services(); @@ -93,11 +114,21 @@ static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot, return; } + ret = gendb_search(samctx, samctx, NULL, &ref_res, ref_attrs, + "(&(&(nETBIOSName=%s)(objectclass=crossRef))(ncName=*))", + name->name); + + if (ret != 1) { + DEBUG(2,("Unable to find domain reference '%s' in sam\n", name->name)); + return; + } + /* try and find the domain */ - ret = gendb_search(samctx, samctx, NULL, &res, attrs, - "(&(name=%s)(objectClass=domainDNS))", name->name); + ret = gendb_search_dn(samctx, samctx, + samdb_result_string(ref_res[0], "ncName", NULL), + &dom_res, dom_attrs); if (ret != 1) { - DEBUG(2,("Unable to find domain '%s' in sam\n", name->name)); + DEBUG(2,("Unable to find domain from reference '%s' in sam\n", ref_res[0]->dn)); return; } @@ -126,15 +157,15 @@ static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot, pdc->server_type |= NBT_SERVER_KDC; } - pdc->domain_uuid = samdb_result_guid(res[0], "objectGUID"); - pdc->forest = samdb_result_string(res[0], "realm", lp_realm()); - pdc->dns_domain = samdb_result_string(res[0], "dnsDomain", lp_realm()); + pdc->domain_uuid = samdb_result_guid(dom_res[0], "objectGUID"); + pdc->forest = samdb_result_string(dom_res[0], "dnsDomain", lp_realm()); + pdc->dns_domain = samdb_result_string(dom_res[0], "dnsDomain", lp_realm()); /* TODO: get our full DNS name from somewhere else */ pdc->pdc_dns_name = talloc_asprintf(packet, "%s.%s", strlower_talloc(packet, lp_netbios_name()), pdc->dns_domain); - pdc->domain = name->name; + pdc->domain = samdb_result_string(dom_res[0], "nETBIOSName", name->name);; pdc->pdc_name = lp_netbios_name(); pdc->user_name = netlogon->req.pdc2.user_name; /* TODO: we need to make sure these are in our DNS zone */ diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 9c5bad30dc..fef1c91c6f 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -372,7 +372,7 @@ static NTSTATUS lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CT static NTSTATUS lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, struct lsa_DnsDomainInfo *info) { - const char * const attrs[] = { "name", "dnsDomain", "objectGUID", "objectSid", NULL }; + const char * const attrs[] = { "dnsDomain", "objectGUID", "objectSid", NULL }; int ret; struct ldb_message **res; diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 26593d1697..57da9b79b2 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -161,7 +161,12 @@ static NTSTATUS samr_LookupDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX struct samr_connect_state *c_state; struct dcesrv_handle *h; struct dom_sid *sid; - + const char * const dom_attrs[] = { "objectSid", NULL}; + const char * const ref_attrs[] = { "ncName", NULL}; + struct ldb_message **dom_msgs; + struct ldb_message **ref_msgs; + int ret; + r->out.sid = NULL; DCESRV_PULL_HANDLE(h, r->in.connect_handle, SAMR_HANDLE_CONNECT); @@ -172,10 +177,31 @@ static NTSTATUS samr_LookupDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX return NT_STATUS_INVALID_PARAMETER; } - sid = samdb_search_dom_sid(c_state->sam_ctx, - mem_ctx, NULL, "objectSid", - "(&(name=%s)(objectclass=domain))", + if (strcasecmp(r->in.domain_name->string, "BUILTIN") == 0) { + ret = gendb_search(c_state->sam_ctx, + mem_ctx, NULL, &dom_msgs, dom_attrs, + "(objectClass=builtinDomain)"); + } else { + ret = gendb_search(c_state->sam_ctx, + mem_ctx, NULL, &ref_msgs, ref_attrs, + "(&(&(nETBIOSName=%s)(objectclass=crossRef))(ncName=*))", r->in.domain_name->string); + if (ret != 1) { + return NT_STATUS_NO_SUCH_DOMAIN; + } + + ret = gendb_search_dn(c_state->sam_ctx, mem_ctx, + samdb_result_string(ref_msgs[0], "ncName", NULL), + &dom_msgs, dom_attrs); + } + + if (ret != 1) { + return NT_STATUS_NO_SUCH_DOMAIN; + } + + sid = samdb_result_dom_sid(mem_ctx, dom_msgs[0], + "objectSid"); + if (sid == NULL) { return NT_STATUS_NO_SUCH_DOMAIN; } @@ -197,8 +223,11 @@ static NTSTATUS samr_EnumDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX struct samr_connect_state *c_state; struct dcesrv_handle *h; struct samr_SamArray *array; - const char **domains; int count, i, start_i; + const char * const dom_attrs[] = { "cn", NULL}; + const char * const ref_attrs[] = { "nETBIOSName", NULL}; + struct ldb_message **dom_msgs; + struct ldb_message **ref_msgs; *r->out.resume_handle = 0; r->out.sam = NULL; @@ -208,9 +237,9 @@ static NTSTATUS samr_EnumDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX c_state = h->data; - count = samdb_search_string_multiple(c_state->sam_ctx, - mem_ctx, NULL, &domains, - "name", "(objectclass=domain)"); + count = gendb_search(c_state->sam_ctx, + mem_ctx, NULL, &dom_msgs, dom_attrs, + "(objectClass=domain)"); if (count == -1) { DEBUG(0,("samdb: no domains found in EnumDomains\n")); return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -239,8 +268,18 @@ static NTSTATUS samr_EnumDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX } for (i=0;i<count-start_i;i++) { + int ret; array->entries[i].idx = start_i + i; - array->entries[i].name.string = domains[start_i+i]; + /* try and find the domain */ + ret = gendb_search(c_state->sam_ctx, mem_ctx, NULL, &ref_msgs, ref_attrs, + "(&(objectClass=crossRef)(ncName=%s))", + dom_msgs[0]->dn); + if (ret == 1) { + array->entries[i].name.string = samdb_result_string(ref_msgs[0], "nETBIOSName", NULL); + } else { + /* Builtin? If we can't find the reference, punt */ + array->entries[i].name.string = samdb_result_string(dom_msgs[0], "cn", NULL); + } } r->out.sam = array; @@ -261,8 +300,10 @@ static NTSTATUS samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX * const char *domain_name; struct samr_connect_state *c_state; struct samr_domain_state *d_state; - const char * const attrs[2] = { "name", NULL}; - struct ldb_message **msgs; + const char * const dom_attrs[] = { NULL}; + const char * const ref_attrs[] = { "nETBIOSName", NULL}; + struct ldb_message **dom_msgs; + struct ldb_message **ref_msgs; int ret; ZERO_STRUCTP(r->out.domain_handle); @@ -276,14 +317,22 @@ static NTSTATUS samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX * } ret = gendb_search(c_state->sam_ctx, - mem_ctx, NULL, &msgs, attrs, + mem_ctx, NULL, &dom_msgs, dom_attrs, "(&(objectSid=%s)(objectclass=domain))", ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid)); if (ret != 1) { return NT_STATUS_NO_SUCH_DOMAIN; } - domain_name = ldb_msg_find_string(msgs[0], "name", NULL); + ret = gendb_search(c_state->sam_ctx, + mem_ctx, NULL, &ref_msgs, ref_attrs, + "(&(&(nETBIOSName=*)(objectclass=crossRef))(ncName=%s))", + dom_msgs[0]->dn); + if (ret != 1) { + return NT_STATUS_NO_SUCH_DOMAIN; + } + + domain_name = ldb_msg_find_string(ref_msgs[0], "nETBIOSName", NULL); if (domain_name == NULL) { return NT_STATUS_NO_SUCH_DOMAIN; } @@ -297,7 +346,7 @@ static NTSTATUS samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX * d_state->sam_ctx = c_state->sam_ctx; d_state->domain_sid = dom_sid_dup(d_state, r->in.sid); d_state->domain_name = talloc_strdup(d_state, domain_name); - d_state->domain_dn = talloc_strdup(d_state, msgs[0]->dn); + d_state->domain_dn = talloc_strdup(d_state, dom_msgs[0]->dn); if (!d_state->domain_sid || !d_state->domain_name || !d_state->domain_dn) { talloc_free(d_state); return NT_STATUS_NO_MEMORY; @@ -356,21 +405,33 @@ static NTSTATUS samr_info_DomInfo1(struct samr_domain_state *state, static NTSTATUS samr_info_DomInfo2(struct samr_domain_state *state, TALLOC_CTX *mem_ctx, struct samr_DomInfo2 *info) { - const char * const attrs[] = { "comment", "name", NULL }; + const char * const dom_attrs[] = { "comment", NULL }; + const char * const ref_attrs[] = { "nETBIOSName", NULL }; int ret; - struct ldb_message **res; - + struct ldb_message **dom_msgs; + struct ldb_message **ref_msgs; + const char *domain_name; + ret = gendb_search_dn(state->sam_ctx, mem_ctx, - state->domain_dn , &res, attrs); + state->domain_dn, &dom_msgs, dom_attrs); if (ret != 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } + ret = gendb_search(state->sam_ctx, + mem_ctx, NULL, &ref_msgs, ref_attrs, + "(&(&(nETBIOSName=*)(objectclass=crossRef))(ncName=%s))", + dom_msgs[0]->dn); + if (ret != 1) { + return NT_STATUS_NO_SUCH_DOMAIN; + } + + domain_name = ldb_msg_find_string(ref_msgs[0], "nETBIOSName", NULL); /* where is this supposed to come from? is it settable? */ info->force_logoff_time = 0x8000000000000000LL; - info->comment.string = samdb_result_string(res[0], "comment", NULL); - info->domain_name.string = samdb_result_string(res[0], "name", NULL); + info->comment.string = samdb_result_string(dom_msgs[0], "comment", NULL); + info->domain_name.string = domain_name; info->primary.string = lp_netbios_name(); info->sequence_num = 0; |