diff options
Diffstat (limited to 'source3/nsswitch')
-rw-r--r-- | source3/nsswitch/wb_common.c | 17 | ||||
-rw-r--r-- | source3/nsswitch/winbindd.c | 9 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_cm.c | 50 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_group.c | 13 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_nss.h | 4 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_user.c | 18 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_util.c | 17 |
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)) { |