summaryrefslogtreecommitdiff
path: root/source3/nsswitch/winbindd_cm.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch/winbindd_cm.c')
-rw-r--r--source3/nsswitch/winbindd_cm.c80
1 files changed, 71 insertions, 9 deletions
diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c
index 56810f221e..eda962088d 100644
--- a/source3/nsswitch/winbindd_cm.c
+++ b/source3/nsswitch/winbindd_cm.c
@@ -77,6 +77,9 @@ struct winbindd_cm_conn {
static struct winbindd_cm_conn *cm_conns = NULL;
+static NTSTATUS get_connection_from_cache(struct winbindd_domain *domain,
+ const char *pipe_name,
+ struct winbindd_cm_conn **conn_out);
/* Choose between anonymous or authenticated connections. We need to use
an authenticated connection if DCs have the RestrictAnonymous registry
@@ -133,6 +136,53 @@ static NTSTATUS setup_schannel(struct cli_state *cli)
return ret;
}
+static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
+ fstring dcname, struct in_addr *dc_ip)
+{
+ struct winbindd_domain *our_domain;
+ NTSTATUS result;
+ struct winbindd_cm_conn *conn;
+ TALLOC_CTX *mem_ctx;
+
+ fstring tmp;
+ char *p;
+
+ if (IS_DC)
+ return False;
+
+ if (domain->primary)
+ return False;
+
+ if ((our_domain = find_our_domain()) == NULL)
+ return False;
+
+ result = get_connection_from_cache(our_domain, PIPE_NETLOGON, &conn);
+ if (!NT_STATUS_IS_OK(result))
+ return False;
+
+ if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL)
+ return False;
+
+ result = cli_netlogon_getdcname(conn->cli, mem_ctx, domain->name, tmp);
+
+ talloc_destroy(mem_ctx);
+
+ if (!NT_STATUS_IS_OK(result))
+ return False;
+
+ /* cli_netlogon_getdcname gives us a name with \\ */
+ p = tmp;
+ if (*p == '\\') p+=1;
+ if (*p == '\\') p+=1;
+
+ fstrcpy(dcname, p);
+
+ if (!resolve_name(dcname, dc_ip, 0x20))
+ return False;
+
+ return True;
+}
+
/* Open a connction to the remote server, cache failures for 30 seconds */
static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const int pipe_index,
@@ -148,15 +198,19 @@ static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const i
ZERO_STRUCT(dc_ip);
fstrcpy(new_conn->domain, domain->name);
-
- /* connection failure cache has been moved inside of get_dc_name
- so we can deal with half dead DC's --jerry */
- if (!get_dc_name(domain->name, domain->alt_name[0] ? domain->alt_name : NULL,
- new_conn->controller, &dc_ip)) {
- result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
- add_failed_connection_entry(domain->name, "", result);
- return result;
+ if (!get_dc_name_via_netlogon(domain, new_conn->controller, &dc_ip)) {
+
+ /* connection failure cache has been moved inside of
+ get_dc_name so we can deal with half dead DC's --jerry */
+
+ if (!get_dc_name(domain->name, domain->alt_name[0] ?
+ domain->alt_name : NULL,
+ new_conn->controller, &dc_ip)) {
+ result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
+ add_failed_connection_entry(domain->name, "", result);
+ return result;
+ }
}
/* Initialise SMB connection */
@@ -282,7 +336,7 @@ static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const i
failed. This allows existing setups to continue working,
while solving the win2003 '100 user' limit for systems that
are joined properly */
- if (NT_STATUS_IS_OK(result)) {
+ if (NT_STATUS_IS_OK(result) && (domain->primary)) {
NTSTATUS status = setup_schannel(new_conn->cli);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3,("schannel refused - continuing without schannel (%s)\n",
@@ -461,10 +515,16 @@ void set_dc_type_and_flags( struct winbindd_domain *domain )
domain->native_mode = False;
domain->active_directory = False;
+
+ if (domain->internal) {
+ domain->initialized = True;
+ return;
+ }
if ( !NT_STATUS_IS_OK(result = cm_open_connection(domain, PI_LSARPC_DS, &conn)) ) {
DEBUG(5, ("set_dc_type_and_flags: Could not open a connection to %s for PIPE_LSARPC (%s)\n",
domain->name, nt_errstr(result)));
+ domain->initialized = True;
return;
}
@@ -551,6 +611,8 @@ done:
cli_shutdown( conn.cli );
talloc_destroy(mem_ctx);
+
+ domain->initialized = True;
return;
}