summaryrefslogtreecommitdiff
path: root/source3/nsswitch
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch')
-rw-r--r--source3/nsswitch/wb_common.c17
-rw-r--r--source3/nsswitch/winbindd.c9
-rw-r--r--source3/nsswitch/winbindd_cm.c50
-rw-r--r--source3/nsswitch/winbindd_group.c13
-rw-r--r--source3/nsswitch/winbindd_nss.h4
-rw-r--r--source3/nsswitch/winbindd_user.c18
-rw-r--r--source3/nsswitch/winbindd_util.c17
7 files changed, 105 insertions, 23 deletions
diff --git a/source3/nsswitch/wb_common.c b/source3/nsswitch/wb_common.c
index 89c751a4ef..51792f63fe 100644
--- a/source3/nsswitch/wb_common.c
+++ b/source3/nsswitch/wb_common.c
@@ -24,7 +24,8 @@
Boston, MA 02111-1307, USA.
*/
-#include "winbind_client.h"
+#include "winbind_nss_config.h"
+#include "winbindd_nss.h"
/* Global variables. These are effectively the client state information */
@@ -44,11 +45,25 @@ void free_response(struct winbindd_response *response)
void init_request(struct winbindd_request *request, int request_type)
{
+ static char *domain_env;
+ static BOOL initialised;
+
request->length = sizeof(struct winbindd_request);
request->cmd = (enum winbindd_cmd)request_type;
request->pid = getpid();
+ request->domain[0] = '\0';
+
+ if (!initialised) {
+ initialised = True;
+ domain_env = getenv(WINBINDD_DOMAIN_ENV);
+ }
+ if (domain_env) {
+ strncpy(request->domain, domain_env,
+ sizeof(request->domain) - 1);
+ request->domain[sizeof(request->domain) - 1] = '\0';
+ }
}
/* Initialise a response structure */
diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c
index b4d1773e9c..4bfec1afe4 100644
--- a/source3/nsswitch/winbindd.c
+++ b/source3/nsswitch/winbindd.c
@@ -362,7 +362,7 @@ void winbind_process_packet(struct winbindd_cli_state *state)
/* Process request */
/* Ensure null termination of entire request */
- state->request.null_term = '\0';
+ state->request.domain[sizeof(state->request.domain)-1]='\0';
state->pid = state->request.pid;
@@ -519,12 +519,6 @@ static void process_loop(void)
/* Initialise fd lists for select() */
listen_sock = open_winbindd_socket();
-
- if (listen_sock == -1) {
- perror("open_winbind_socket");
- exit(1);
- }
-
maxfd = listen_sock;
FD_ZERO(&r_fds);
@@ -869,7 +863,6 @@ static void usage(void)
process_loop();
- trustdom_cache_shutdown();
uni_group_cache_shutdown();
return 0;
}
diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c
index 075da1e2b2..403bc38052 100644
--- a/source3/nsswitch/winbindd_cm.c
+++ b/source3/nsswitch/winbindd_cm.c
@@ -135,6 +135,54 @@ static BOOL cm_ads_find_dc(const char *domain, struct in_addr *dc_ip, fstring sr
return True;
}
+/*
+ find the DC for a domain using methods appropriate for a RPC domain
+*/
+static BOOL cm_rpc_find_dc(const char *domain, struct in_addr *dc_ip, fstring srv_name)
+{
+ struct in_addr *ip_list = NULL;
+ int count, i;
+ BOOL list_ordered;
+
+ if (!get_dc_list(domain, &ip_list, &count, &list_ordered)) {
+ struct in_addr pdc_ip;
+
+ if (!get_pdc_ip(domain, &pdc_ip)) {
+ DEBUG(3, ("Could not look up any DCs for domain %s\n",
+ domain));
+ return False;
+ }
+
+ ip_list = (struct in_addr *)malloc(sizeof(struct in_addr));
+
+ if (!ip_list)
+ return False;
+
+ ip_list[0] = pdc_ip;
+ count = 1;
+ }
+
+ /* Pick a nice close server, but only if the list was not ordered */
+ if (!list_ordered && (count > 1) ) {
+ qsort(ip_list, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
+ }
+
+ for (i = 0; i < count; i++) {
+ if (is_zero_ip(ip_list[i]))
+ continue;
+
+ if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) {
+ *dc_ip = ip_list[i];
+ SAFE_FREE(ip_list);
+ return True;
+ }
+ }
+
+
+ SAFE_FREE(ip_list);
+
+ return False;
+}
static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
@@ -199,7 +247,7 @@ static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr
}
if (!ret) {
/* fall back on rpc methods if the ADS methods fail */
- ret = rpc_find_dc(domain, srv_name, &dc_ip);
+ ret = cm_rpc_find_dc(domain, &dc_ip, srv_name);
}
if (!ret) {
diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c
index ab6268583f..507d5caf0f 100644
--- a/source3/nsswitch/winbindd_group.c
+++ b/source3/nsswitch/winbindd_group.c
@@ -356,6 +356,13 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
for (domain = domain_list(); domain != NULL; domain = domain->next) {
struct getent_state *domain_state;
+ /* Skip domains other than WINBINDD_DOMAIN environment
+ variable */
+
+ if ((strcmp(state->request.domain, "") != 0) &&
+ !check_domain_env(state->request.domain, domain->name))
+ continue;
+
/* Create a state record for this domain */
if ((domain_state = (struct getent_state *)
@@ -741,6 +748,12 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
ZERO_STRUCT(groups);
+ /* Skip domains other than WINBINDD_DOMAIN environment
+ variable */
+ if ((strcmp(state->request.domain, "") != 0) &&
+ !check_domain_env(state->request.domain, domain->name))
+ continue;
+
/* Get list of sam groups */
ZERO_STRUCT(groups);
fstrcpy(groups.domain_name, domain->name);
diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h
index 5c2db2ac2c..368bf10cea 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 6
+#define WINBIND_INTERFACE_VERSION 5
/* Socket commands */
@@ -156,7 +156,7 @@ struct winbindd_request {
} name;
uint32 num_entries; /* getpwent, getgrent */
} data;
- char null_term;
+ fstring domain; /* {set,get,end}{pw,gr}ent() */
};
/* Response values */
diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c
index bb281463ce..56bcb3d818 100644
--- a/source3/nsswitch/winbindd_user.c
+++ b/source3/nsswitch/winbindd_user.c
@@ -73,6 +73,7 @@ static BOOL winbindd_fill_pwent(char *dom_name, char *user_name,
by lp_string() calling standard_sub_basic(). */
fstrcpy(current_user_info.smb_name, user_name);
+ sub_set_smb_name(user_name);
fstrcpy(current_user_info.domain, dom_name);
pstrcpy(homedir, lp_template_homedir());
@@ -284,6 +285,16 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state)
for(domain = domain_list(); domain != NULL; domain = domain->next) {
struct getent_state *domain_state;
+ /*
+ * Skip domains other than WINBINDD_DOMAIN environment
+ * variable.
+ */
+
+ if ((strcmp(state->request.domain, "") != 0) &&
+ !check_domain_env(state->request.domain,
+ domain->name))
+ continue;
+
/* Create a state record for this domain */
if ((domain_state = (struct getent_state *)
@@ -541,6 +552,13 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
struct winbindd_methods *methods;
int i;
+ /* Skip domains other than WINBINDD_DOMAIN environment
+ variable */
+
+ if ((strcmp(state->request.domain, "") != 0) &&
+ !check_domain_env(state->request.domain, domain->name))
+ continue;
+
methods = domain->methods;
/* Query display info */
diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c
index c1bb5cec7c..5ad4bada37 100644
--- a/source3/nsswitch/winbindd_util.c
+++ b/source3/nsswitch/winbindd_util.c
@@ -178,7 +178,7 @@ void rescan_trusted_domains(void)
int i;
result = domain->methods->trusted_domains(domain, mem_ctx, &num_domains,
- &names, &alt_names, &dom_sids);
+ &names, &alt_names, &dom_sids);
if (!NT_STATUS_IS_OK(result)) {
continue;
}
@@ -187,12 +187,9 @@ void rescan_trusted_domains(void)
the access methods of its parent */
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]);
-
- /* store trusted domain in the cache */
- trustdom_cache_store(names[i], alt_names ? alt_names[i] : NULL,
- &dom_sids[i], t + WINBINDD_RESCAN_FREQ);
+ add_trusted_domain(names[i],
+ alt_names?alt_names[i]:NULL,
+ domain->methods, &dom_sids[i]);
}
}
@@ -212,10 +209,8 @@ BOOL init_domain_list(void)
/* Add ourselves as the first entry */
domain = add_trusted_domain(lp_workgroup(), NULL, &cache_methods, NULL);
- /*
- * Now we *must* get the domain sid for our primary domain. Go into
- * a holding pattern until that is available
- */
+ /* Now we *must* get the domain sid for our primary domain. Go into
+ a holding pattern until that is available */
result = cache_methods.domain_sid(domain, &domain->sid);
while (!NT_STATUS_IS_OK(result)) {