📄 netlogon.c
字号:
/* Unix SMB/CIFS implementation. CLDAP server - netlogon handling Copyright (C) Andrew Tridgell 2005 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008 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 <http://www.gnu.org/licenses/>.*/#include "includes.h"#include "lib/ldb/include/ldb.h"#include "lib/ldb/include/ldb_errors.h"#include "lib/events/events.h"#include "lib/socket/socket.h"#include "smbd/service_task.h"#include "cldap_server/cldap_server.h"#include "librpc/gen_ndr/ndr_misc.h"#include "libcli/ldap/ldap_ndr.h"#include "libcli/security/security.h"#include "dsdb/samdb/samdb.h"#include "auth/auth.h"#include "ldb_wrap.h"#include "system/network.h"#include "lib/socket/netif.h"#include "param/param.h"/* fill in the cldap netlogon union for a given version*/NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, const char *domain, const char *netbios_domain, struct dom_sid *domain_sid, const char *domain_guid, const char *user, uint32_t acct_control, const char *src_address, uint32_t version, struct loadparm_context *lp_ctx, struct netlogon_samlogon_response *netlogon){ const char *ref_attrs[] = {"nETBIOSName", "dnsRoot", "ncName", NULL}; const char *dom_attrs[] = {"objectGUID", NULL}; const char *none_attrs[] = {NULL}; struct ldb_result *ref_res = NULL, *dom_res = NULL, *user_res = NULL; int ret; const char **services = lp_server_services(lp_ctx); uint32_t server_type; const char *pdc_name; struct GUID domain_uuid; const char *realm; const char *dns_domain; const char *pdc_dns_name; const char *flatname; const char *server_site; const char *client_site; const char *pdc_ip; struct ldb_dn *partitions_basedn; struct interface *ifaces; bool user_known; partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx); /* the domain has an optional trailing . */ if (domain && domain[strlen(domain)-1] == '.') { domain = talloc_strndup(mem_ctx, domain, strlen(domain)-1); } if (domain) { struct ldb_dn *dom_dn; /* try and find the domain */ ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &ref_res, partitions_basedn, LDB_SCOPE_ONELEVEL, ref_attrs, "(&(&(objectClass=crossRef)(dnsRoot=%s))(nETBIOSName=*))", domain); if (ret != LDB_SUCCESS) { DEBUG(2,("Unable to find referece to '%s' in sam: %s\n", domain, ldb_errstring(sam_ctx))); return NT_STATUS_NO_SUCH_DOMAIN; } else if (ref_res->count == 1) { talloc_steal(mem_ctx, dom_res); dom_dn = ldb_msg_find_attr_as_dn(sam_ctx, mem_ctx, ref_res->msgs[0], "ncName"); if (!dom_dn) { return NT_STATUS_NO_SUCH_DOMAIN; } ret = ldb_search(sam_ctx, dom_dn, LDB_SCOPE_BASE, "objectClass=domain", dom_attrs, &dom_res); if (ret != LDB_SUCCESS) { DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n", domain, ldb_dn_get_linearized(dom_dn), ldb_errstring(sam_ctx))); return NT_STATUS_NO_SUCH_DOMAIN; } talloc_steal(mem_ctx, dom_res); if (dom_res->count != 1) { DEBUG(2,("Error finding domain '%s'/'%s' in sam\n", domain, ldb_dn_get_linearized(dom_dn))); return NT_STATUS_NO_SUCH_DOMAIN; } } else if (ref_res->count > 1) { talloc_free(ref_res); return NT_STATUS_NO_SUCH_DOMAIN; } } if (netbios_domain) { struct ldb_dn *dom_dn; /* try and find the domain */ ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &ref_res, partitions_basedn, LDB_SCOPE_ONELEVEL, ref_attrs, "(&(objectClass=crossRef)(ncName=*)(nETBIOSName=%s))", netbios_domain); if (ret != LDB_SUCCESS) { DEBUG(2,("Unable to find referece to '%s' in sam: %s\n", netbios_domain, ldb_errstring(sam_ctx))); return NT_STATUS_NO_SUCH_DOMAIN; } else if (ref_res->count == 1) { talloc_steal(mem_ctx, dom_res); dom_dn = ldb_msg_find_attr_as_dn(sam_ctx, mem_ctx, ref_res->msgs[0], "ncName"); if (!dom_dn) { return NT_STATUS_NO_SUCH_DOMAIN; } ret = ldb_search(sam_ctx, dom_dn, LDB_SCOPE_BASE, "objectClass=domain", dom_attrs, &dom_res); if (ret != LDB_SUCCESS) { DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n", domain, ldb_dn_get_linearized(dom_dn), ldb_errstring(sam_ctx))); return NT_STATUS_NO_SUCH_DOMAIN; } talloc_steal(mem_ctx, dom_res); if (dom_res->count != 1) { DEBUG(2,("Error finding domain '%s'/'%s' in sam\n", domain, ldb_dn_get_linearized(dom_dn))); return NT_STATUS_NO_SUCH_DOMAIN; } } else if (ref_res->count > 1) { talloc_free(ref_res); return NT_STATUS_NO_SUCH_DOMAIN; } } if ((dom_res == NULL || dom_res->count == 0) && (domain_guid || domain_sid)) { ref_res = NULL; if (domain_guid) { ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &dom_res, NULL, LDB_SCOPE_SUBTREE, dom_attrs, "(&(objectClass=domainDNS)(objectGUID=%s))", domain_guid); } else { /* domain_sid case */ ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &dom_res, NULL, LDB_SCOPE_SUBTREE, dom_attrs, "(&(objectClass=domainDNS)(objectSID=%s))", dom_sid_string(mem_ctx, domain_sid)); } if (ret != LDB_SUCCESS) { DEBUG(2,("Unable to find referece to GUID '%s' or SID %s in sam: %s\n", domain_guid, dom_sid_string(mem_ctx, domain_sid), ldb_errstring(sam_ctx))); return NT_STATUS_NO_SUCH_DOMAIN; } else if (dom_res->count == 1) { /* try and find the domain */ ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &ref_res, partitions_basedn, LDB_SCOPE_ONELEVEL, ref_attrs, "(&(objectClass=crossRef)(ncName=%s))", ldb_dn_get_linearized(dom_res->msgs[0]->dn)); if (ret != LDB_SUCCESS) { DEBUG(2,("Unable to find referece to '%s' in sam: %s\n", ldb_dn_get_linearized(dom_res->msgs[0]->dn), ldb_errstring(sam_ctx))); return NT_STATUS_NO_SUCH_DOMAIN; } else if (ref_res->count != 1) { DEBUG(2,("Unable to find referece to '%s' in sam\n", ldb_dn_get_linearized(dom_res->msgs[0]->dn))); return NT_STATUS_NO_SUCH_DOMAIN; } } else if (dom_res->count > 1) { talloc_free(ref_res); return NT_STATUS_NO_SUCH_DOMAIN; } } if ((ref_res == NULL || ref_res->count == 0)) { DEBUG(2,("Unable to find domain reference with name %s or GUID {%s}\n", domain, domain_guid)); return NT_STATUS_NO_SUCH_DOMAIN; } if ((dom_res == NULL || dom_res->count == 0)) { DEBUG(2,("Unable to find domain with name %s or GUID {%s}\n", domain, domain_guid)); return NT_STATUS_NO_SUCH_DOMAIN; } /* work around different inputs for not-specified users */ if (!user) { user = ""; } /* Enquire about any valid username with just a CLDAP packet - * if kerberos didn't also do this, the security folks would * scream... */ if (user[0]) { \ /* Only allow some bits to be enquired: [MS-ATDS] 7.3.3.2 */ if (acct_control == (uint32_t)-1) { acct_control = 0; } acct_control = acct_control & (ACB_TEMPDUP | ACB_NORMAL | ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST); /* We must exclude disabled accounts, but otherwise do the bitwise match the client asked for */ ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &user_res, dom_res->msgs[0]->dn, LDB_SCOPE_SUBTREE,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -