summaryrefslogtreecommitdiff
path: root/source3/nsswitch
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch')
-rw-r--r--source3/nsswitch/wbinfo.c14
-rw-r--r--source3/nsswitch/winbindd.c2
-rw-r--r--source3/nsswitch/winbindd.h3
-rw-r--r--source3/nsswitch/winbindd_cache.c4
-rw-r--r--source3/nsswitch/winbindd_cm.c103
-rw-r--r--source3/nsswitch/winbindd_misc.c1
-rw-r--r--source3/nsswitch/winbindd_nss.h3
-rw-r--r--source3/nsswitch/winbindd_rpc.c13
-rw-r--r--source3/nsswitch/winbindd_util.c39
9 files changed, 146 insertions, 36 deletions
diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c
index 74f341a490..c7dc89d43f 100644
--- a/source3/nsswitch/wbinfo.c
+++ b/source3/nsswitch/wbinfo.c
@@ -298,18 +298,20 @@ static BOOL wbinfo_domain_info(const char *domain_name)
/* Display response */
- d_printf("Name : %s\n", response.data.domain_info.name);
- d_printf("Alt_Name: %s\n", response.data.domain_info.alt_name);
+ d_printf("Name : %s\n", response.data.domain_info.name);
+ d_printf("Alt_Name : %s\n", response.data.domain_info.alt_name);
- d_printf("SID : %s\n", response.data.domain_info.sid);
+ d_printf("SID : %s\n", response.data.domain_info.sid);
- d_printf("Native : %s\n",
+ d_printf("Active Directory : %s\n",
+ response.data.domain_info.active_directory ? "Yes" : "No");
+ d_printf("Native : %s\n",
response.data.domain_info.native_mode ? "Yes" : "No");
- d_printf("Primary : %s\n",
+ d_printf("Primary : %s\n",
response.data.domain_info.primary ? "Yes" : "No");
- d_printf("Sequence: %d\n", response.data.domain_info.sequence_number);
+ d_printf("Sequence : %d\n", response.data.domain_info.sequence_number);
return True;
}
diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c
index 8ce528d2b0..4d5b08b4ec 100644
--- a/source3/nsswitch/winbindd.c
+++ b/source3/nsswitch/winbindd.c
@@ -935,6 +935,8 @@ int main(int argc, char **argv)
netsamlogon_cache_init(); /* Non-critical */
+ init_domain_list();
+
/* Loop waiting for requests */
process_loop();
diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h
index 5dbe422bc1..7c8e6256e1 100644
--- a/source3/nsswitch/winbindd.h
+++ b/source3/nsswitch/winbindd.h
@@ -95,7 +95,8 @@ struct winbindd_domain {
fstring alt_name; /* alt Domain name (if any) */
DOM_SID sid; /* SID for this domain */
BOOL native_mode; /* is this a win2k domain in native mode ? */
- BOOL primary; /* is this our primary domain ? */
+ BOOL active_directory; /* is this a win2k active directory ? */
+ BOOL primary; /* is this our primary domain ? */
/* Lookup methods for this domain (LDAP or RPC) */
struct winbindd_methods *methods;
diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c
index 2df2ea6374..8dec89a6aa 100644
--- a/source3/nsswitch/winbindd_cache.c
+++ b/source3/nsswitch/winbindd_cache.c
@@ -112,7 +112,9 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain)
break;
}
- if ( domain->native_mode ) {
+ /* if it have either of the indications of ADS,
+ use ads_methods */
+ if ( domain->active_directory || domain->native_mode ) {
domain->backend = &ads_methods;
break;
}
diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c
index 2b561be31d..53c91c01c7 100644
--- a/source3/nsswitch/winbindd_cm.c
+++ b/source3/nsswitch/winbindd_cm.c
@@ -174,16 +174,19 @@ static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const i
if ((lp_security() == SEC_ADS)
&& (new_conn->cli->protocol >= PROTOCOL_NT1 && new_conn->cli->capabilities & CAP_EXTENDED_SECURITY)) {
+ ADS_STATUS ads_status;
new_conn->cli->use_kerberos = True;
DEBUG(5, ("connecting to %s from %s with kerberos principal [%s]\n",
new_conn->controller, global_myname(), machine_krb5_principal));
- result = NT_STATUS_OK;
-
- if (!NT_STATUS_IS_OK(result = cli_session_setup_spnego(new_conn->cli, machine_krb5_principal,
- machine_password,
- lp_workgroup()))) {
- DEBUG(4,("failed kerberos session setup with %s\n", nt_errstr(result)));
+ ads_status = cli_session_setup_spnego(new_conn->cli, machine_krb5_principal,
+ machine_password,
+ lp_workgroup());
+ if (!ADS_ERR_OK(ads_status)) {
+ DEBUG(4,("failed kerberos session setup with %s\n", ads_errstr(ads_status)));
+ result = ads_ntstatus(ads_status);
+ } else {
+ result = NT_STATUS_OK;
}
}
new_conn->cli->use_kerberos = False;
@@ -405,46 +408,116 @@ static NTSTATUS get_connection_from_cache(struct winbindd_domain *domain, const
}
/**********************************************************************************
+ We can 'sense' certain things about the DC by it's replies to certain questions.
+
+ This tells us if this particular remote server is Active Directory, and if it is
+ native mode.
**********************************************************************************/
-BOOL cm_check_for_native_mode_win2k( struct winbindd_domain *domain )
+void set_dc_type_and_flags( struct winbindd_domain *domain )
{
NTSTATUS result;
struct winbindd_cm_conn conn;
DS_DOMINFO_CTR ctr;
- BOOL ret = False;
+ TALLOC_CTX *mem_ctx;
ZERO_STRUCT( conn );
ZERO_STRUCT( ctr );
+ domain->native_mode = False;
+ domain->active_directory = False;
if ( !NT_STATUS_IS_OK(result = cm_open_connection(domain, PI_LSARPC_DS, &conn)) ) {
- DEBUG(5, ("cm_check_for_native_mode_win2k: Could not open a connection to %s for PIPE_LSARPC (%s)\n",
+ DEBUG(5, ("set_dc_type_and_flags: Could not open a connection to %s for PIPE_LSARPC (%s)\n",
domain->name, nt_errstr(result)));
- return False;
+ return;
}
if ( conn.cli ) {
if ( !NT_STATUS_IS_OK(cli_ds_getprimarydominfo( conn.cli,
conn.cli->mem_ctx, DsRolePrimaryDomainInfoBasic, &ctr)) ) {
- ret = False;
goto done;
}
}
if ( (ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING)
&& !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE) )
- ret = True;
+ domain->native_mode = True;
-done:
+ /* Cheat - shut down the DS pipe, and open LSA */
+
+ cli_nt_session_close(conn.cli);
+
+ if ( cli_nt_session_open (conn.cli, PI_LSARPC) ) {
+ char *domain_name = NULL;
+ char *dns_name = NULL;
+ DOM_SID *dom_sid = NULL;
+
+ mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n", domain->name);
+ if (!mem_ctx) {
+ DEBUG(1, ("set_dc_type_and_flags: talloc_init() failed\n"));
+ return;
+ }
+
+ result = cli_lsa_open_policy2(conn.cli, mem_ctx, True,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &conn.pol);
+
+ if (NT_STATUS_IS_OK(result)) {
+ /* This particular query is exactly what Win2k clients use
+ to determine that the DC is active directory */
+ result = cli_lsa_query_info_policy2(conn.cli, mem_ctx,
+ &conn.pol,
+ 12, &domain_name,
+ &dns_name, NULL,
+ NULL, &dom_sid);
+ }
+
+ if (NT_STATUS_IS_OK(result)) {
+ if (domain_name)
+ fstrcpy(domain->name, domain_name);
+
+ if (dns_name)
+ fstrcpy(domain->alt_name, dns_name);
+ if (dom_sid)
+ sid_copy(&domain->sid, dom_sid);
+
+ domain->active_directory = True;
+ } else {
+
+ result = cli_lsa_open_policy(conn.cli, mem_ctx, True,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &conn.pol);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ result = cli_lsa_query_info_policy(conn.cli, mem_ctx,
+ &conn.pol, 5, &domain_name,
+ &dom_sid);
+
+ if (NT_STATUS_IS_OK(result)) {
+ if (domain_name)
+ fstrcpy(domain->name, domain_name);
+
+ if (dom_sid)
+ sid_copy(&domain->sid, dom_sid);
+ }
+ }
+ }
+
+done:
+
/* close the connection; no other cals use this pipe and it is called only
on reestablishing the domain list --jerry */
-
+
if ( conn.cli )
cli_shutdown( conn.cli );
- return ret;
+ talloc_destroy(mem_ctx);
+
+ return;
}
diff --git a/source3/nsswitch/winbindd_misc.c b/source3/nsswitch/winbindd_misc.c
index 95ca57a5e3..18478992f3 100644
--- a/source3/nsswitch/winbindd_misc.c
+++ b/source3/nsswitch/winbindd_misc.c
@@ -223,6 +223,7 @@ enum winbindd_result winbindd_domain_info(struct winbindd_cli_state *state)
sid_string_static(&domain->sid));
state->response.data.domain_info.native_mode = domain->native_mode;
+ state->response.data.domain_info.active_directory = domain->active_directory;
state->response.data.domain_info.primary = domain->primary;
state->response.data.domain_info.sequence_number =
diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h
index 0dd00e9b39..0d110b8afa 100644
--- a/source3/nsswitch/winbindd_nss.h
+++ b/source3/nsswitch/winbindd_nss.h
@@ -36,7 +36,7 @@
/* Update this when you change the interface. */
-#define WINBIND_INTERFACE_VERSION 8
+#define WINBIND_INTERFACE_VERSION 9
/* Socket commands */
@@ -272,6 +272,7 @@ struct winbindd_response {
fstring alt_name;
fstring sid;
BOOL native_mode;
+ BOOL active_directory;
BOOL primary;
uint32 sequence_number;
} domain_info;
diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c
index f619aa3564..21e0c3092e 100644
--- a/source3/nsswitch/winbindd_rpc.c
+++ b/source3/nsswitch/winbindd_rpc.c
@@ -950,7 +950,8 @@ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
TALLOC_CTX *mem_ctx;
CLI_POLICY_HND *hnd;
- fstring level5_dom;
+ char *level5_dom;
+ DOM_SID *alloc_sid;
int retry;
DEBUG(3,("rpc: domain_sid\n"));
@@ -965,9 +966,17 @@ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
goto done;
result = cli_lsa_query_info_policy(hnd->cli, mem_ctx,
- &hnd->pol, 0x05, level5_dom, sid);
+ &hnd->pol, 0x05, &level5_dom, &alloc_sid);
} while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
+ if (NT_STATUS_IS_OK(result)) {
+ if (alloc_sid) {
+ sid_copy(sid, alloc_sid);
+ } else {
+ result = NT_STATUS_NO_MEMORY;
+ }
+ }
+
done:
talloc_destroy(mem_ctx);
return result;
diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c
index 18946652e2..29a4ca93eb 100644
--- a/source3/nsswitch/winbindd_util.c
+++ b/source3/nsswitch/winbindd_util.c
@@ -49,6 +49,14 @@ static const fstring name_deadbeef = "<deadbeef>";
static struct winbindd_domain *_domain_list;
+/**
+ When was the last scan of trusted domains done?
+
+ 0 == not ever
+*/
+
+static time_t last_trustdom_scan;
+
struct winbindd_domain *domain_list(void)
{
/* Initialise list */
@@ -83,6 +91,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
{
struct winbindd_domain *domain;
const char *alternative_name = NULL;
+ static const DOM_SID null_sid;
/* ignore alt_name if we are not in an AD domain */
@@ -103,6 +112,13 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
return domain;
}
}
+ if (sid) {
+ if (sid_equal(sid, &null_sid) ) {
+
+ } else if (sid_equal(sid, &domain->sid)) {
+ return domain;
+ }
+ }
}
/* Create new domain entry */
@@ -134,12 +150,14 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
sid_copy(&domain->sid, sid);
}
- /* see if this is a native mode win2k domain */
+ /* set flags about native_mode, active_directory */
- domain->native_mode = cm_check_for_native_mode_win2k( domain );
+ set_dc_type_and_flags( domain );
- DEBUG(3,("add_trusted_domain: %s is a %s mode domain\n", domain->name,
- domain->native_mode ? "native" : "mixed (or NT4)" ));
+ DEBUG(3,("add_trusted_domain: %s is an %s %s domain\n", domain->name,
+ domain->active_directory ? "ADS" : "NT4",
+ domain->native_mode ? "native mode" :
+ ((domain->active_directory && !domain->native_mode) ? "mixed mode" : "")));
/* Link to domain list */
DLIST_ADD(_domain_list, domain);
@@ -157,13 +175,12 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
void rescan_trusted_domains( void )
{
- static time_t last_scan;
time_t now = time(NULL);
struct winbindd_domain *mydomain = NULL;
/* see if the time has come... */
- if ( (now > last_scan) && ((now-last_scan) < WINBINDD_RESCAN_FREQ) )
+ if ( (now > last_trustdom_scan) && ((now-last_trustdom_scan) < WINBINDD_RESCAN_FREQ) )
return;
if ( (mydomain = find_our_domain()) == NULL ) {
@@ -175,7 +192,7 @@ void rescan_trusted_domains( void )
add_trusted_domains( mydomain );
- last_scan = now;
+ last_trustdom_scan = now;
return;
}
@@ -222,7 +239,7 @@ void add_trusted_domains( struct winbindd_domain *domain )
for(i = 0; i < num_domains; i++) {
DEBUG(10,("Found domain %s\n", names[i]));
add_trusted_domain(names[i], alt_names?alt_names[i]:NULL,
- domain->methods, &dom_sids[i]);
+ domain->methods, &dom_sids[i]);
/* if the SID was empty, we better set it now */
@@ -264,7 +281,7 @@ BOOL init_domain_list(void)
/* Free existing list */
free_domain_list();
- /* Add ourselves as the first entry. It *must* be the first entry */
+ /* Add ourselves as the first entry. */
domain = add_trusted_domain( lp_workgroup(), lp_realm(), &cache_methods, NULL);
@@ -287,7 +304,9 @@ BOOL init_domain_list(void)
/* do an initial scan for trusted domains */
add_trusted_domains(domain);
-
+
+ /* avoid rescanning this right away */
+ last_trustdom_scan = time(NULL);
return True;
}