summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/auth/auth_domain.c121
1 files changed, 90 insertions, 31 deletions
diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c
index 50bad0bd30..d0b5b4db7f 100644
--- a/source3/auth/auth_domain.c
+++ b/source3/auth/auth_domain.c
@@ -29,6 +29,87 @@ BOOL global_machine_password_needs_changing = False;
extern pstring global_myname;
extern userdom_struct current_user_info;
+
+/*
+ resolve the name of a DC in ways appropriate for an ADS domain mode
+ an ADS domain may not have Netbios enabled at all, so this is
+ quite different from the RPC case
+ Note that we ignore the 'server' parameter here. That has the effect of using
+ the 'ADS server' smb.conf parameter, which is what we really want anyway
+ */
+static NTSTATUS ads_resolve_dc(const char *server,
+ fstring remote_machine,
+ struct in_addr *dest_ip)
+{
+ ADS_STRUCT *ads;
+ ads = ads_init_simple();
+ if (!ads) {
+ return NT_STATUS_NO_LOGON_SERVERS;
+ }
+
+#ifdef HAVE_ADS
+ /* a full ads_connect() is actually overkill, as we don't srictly need
+ to do the SASL auth in order to get the info we need, but libads
+ doesn't offer a better way right now */
+ if (!ADS_ERR_OK(ads_connect(ads))) {
+ return NT_STATUS_NO_LOGON_SERVERS;
+ }
+#endif
+
+ fstrcpy(remote_machine, ads->ldap_server_name);
+ strupper(remote_machine);
+ *dest_ip = *interpret_addr2(ads->ldap_server);
+ ads_destroy(&ads);
+
+ if (!*remote_machine) {
+ return NT_STATUS_NO_LOGON_SERVERS;
+ }
+
+ DEBUG(4,("ads_resolve_dc: using server='%s' IP=%s\n",
+ remote_machine, inet_ntoa(*dest_ip)));
+
+ return NT_STATUS_OK;
+}
+
+/*
+ resolve the name of a DC in ways appropriate for RPC domain mode
+ this relies on the server supporting netbios and port 137 not being
+ firewalled
+ */
+static NTSTATUS rpc_resolve_dc(const char *server,
+ fstring remote_machine,
+ struct in_addr *dest_ip)
+{
+ if (is_ipaddress(server)) {
+ struct in_addr to_ip = *interpret_addr2(server);
+
+ /* we need to know the machines netbios name - this is a lousy
+ way to find it, but until we have a RPC call that does this
+ it will have to do */
+ if (!name_status_find("*", 0x20, 0x20, to_ip, remote_machine)) {
+ DEBUG(2, ("connect_to_domain_password_server: Can't "
+ "resolve name for IP %s\n", server));
+ return NT_STATUS_NO_LOGON_SERVERS;
+ }
+
+ *dest_ip = to_ip;
+ return NT_STATUS_OK;
+ }
+
+ fstrcpy(remote_machine, server);
+ strupper(remote_machine);
+ if (!resolve_name(remote_machine, dest_ip, 0x20)) {
+ DEBUG(1,("connect_to_domain_password_server: Can't resolve address for %s\n",
+ remote_machine));
+ return NT_STATUS_NO_LOGON_SERVERS;
+ }
+
+ DEBUG(4,("rpc_resolve_dc: using server='%s' IP=%s\n",
+ remote_machine, inet_ntoa(*dest_ip)));
+
+ return NT_STATUS_OK;
+}
+
/**
* Connect to a remote server for domain security authenticaion.
*
@@ -50,38 +131,16 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
fstring remote_machine;
NTSTATUS result;
- if (is_ipaddress(server)) {
- struct in_addr to_ip;
-
- /* we shouldn't have 255.255.255.255 forthe IP address of
- a password server anyways */
- if ((to_ip.s_addr=inet_addr(server)) == 0xFFFFFFFF) {
- DEBUG (0,("connect_to_domain_password_server: inet_addr(%s) returned 0xFFFFFFFF!\n", server));
- return NT_STATUS_NO_LOGON_SERVERS;
- }
-
- if (lp_security() == SEC_ADS) {
- /* if in ADS mode then we know that port 445
- will work and *SMBSERVER will be recognised
- anyway. This avoids an expensive netbios
- lookup. */
- fstrcpy(remote_machine, "*SMBSERVER");
- } else if (!name_status_find("*", 0x20, 0x20, to_ip, remote_machine)) {
- DEBUG(0, ("connect_to_domain_password_server: Can't "
- "resolve name for IP %s\n", server));
- return NT_STATUS_NO_LOGON_SERVERS;
- }
-
- /* we know the IP - smb.conf specified it! */
- dest_ip = to_ip;
+ if (lp_security() == SEC_ADS) {
+ result = ads_resolve_dc(server, remote_machine, &dest_ip);
} else {
- fstrcpy(remote_machine, server);
- strupper(remote_machine);
- if (!resolve_name(remote_machine, &dest_ip, 0x20)) {
- DEBUG(1,("connect_to_domain_password_server: Can't resolve address for %s\n",
- remote_machine));
- return NT_STATUS_NO_LOGON_SERVERS;
- }
+ result = rpc_resolve_dc(server, remote_machine, &dest_ip);
+ }
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(2,("connect_to_domain_password_server: unable to resolve DC: %s\n",
+ nt_errstr(result)));
+ return result;
}
if (ismyip(dest_ip)) {