summaryrefslogtreecommitdiff
path: root/source3/nsswitch
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2002-08-17 17:00:51 +0000
committerJelmer Vernooij <jelmer@samba.org>2002-08-17 17:00:51 +0000
commitb2edf254eda92f775e7d3d9b6793b4d77f9000b6 (patch)
tree18eb2564a769678c774a19bb07c00fc4aa7b2758 /source3/nsswitch
parent669a39fae36f8bc60753c9b352556ef8ffaeb568 (diff)
downloadsamba-b2edf254eda92f775e7d3d9b6793b4d77f9000b6.tar.gz
samba-b2edf254eda92f775e7d3d9b6793b4d77f9000b6.tar.bz2
samba-b2edf254eda92f775e7d3d9b6793b4d77f9000b6.zip
sync 3.0 branch with head
(This used to be commit 3928578b52cfc949be5e0ef444fce1558d75f290)
Diffstat (limited to 'source3/nsswitch')
-rw-r--r--source3/nsswitch/pam_winbind.c18
-rw-r--r--source3/nsswitch/wb_client.c6
-rw-r--r--source3/nsswitch/wb_common.c17
-rw-r--r--source3/nsswitch/wbinfo.c7
-rw-r--r--source3/nsswitch/winbindd.c7
-rw-r--r--source3/nsswitch/winbindd.h8
-rw-r--r--source3/nsswitch/winbindd_ads.c119
-rw-r--r--source3/nsswitch/winbindd_cache.c15
-rw-r--r--source3/nsswitch/winbindd_cm.c196
-rw-r--r--source3/nsswitch/winbindd_group.c6
-rw-r--r--source3/nsswitch/winbindd_nss.h12
-rw-r--r--source3/nsswitch/winbindd_pam.c139
-rw-r--r--source3/nsswitch/winbindd_rpc.c15
-rw-r--r--source3/nsswitch/winbindd_sid.c15
-rw-r--r--source3/nsswitch/winbindd_user.c3
-rw-r--r--source3/nsswitch/winbindd_util.c118
-rw-r--r--source3/nsswitch/winbindd_wins.c6
17 files changed, 467 insertions, 240 deletions
diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c
index 4739cfbf7a..29ceca4e79 100644
--- a/source3/nsswitch/pam_winbind.c
+++ b/source3/nsswitch/pam_winbind.c
@@ -79,7 +79,7 @@ static int converse(pam_handle_t *pamh, int nargs,
}
-int _make_remark(pam_handle_t * pamh, int type, const char *text)
+static int _make_remark(pam_handle_t * pamh, int type, const char *text)
{
int retval = PAM_SUCCESS;
@@ -163,6 +163,10 @@ static int winbind_auth_request(const char *user, const char *pass, int ctrl)
/* password expired */
_pam_log(LOG_WARNING, "user `%s' password expired", user);
return retval;
+ case PAM_NEW_AUTHTOK_REQD:
+ /* password expired */
+ _pam_log(LOG_WARNING, "user `%s' new password required", user);
+ return retval;
case PAM_USER_UNKNOWN:
/* the user does not exist */
if (ctrl & WINBIND_DEBUG_ARG)
@@ -241,12 +245,12 @@ static char *_pam_delete(register char *xx)
* obtain a password from the user
*/
-int _winbind_read_password(pam_handle_t * pamh
- ,unsigned int ctrl
- ,const char *comment
- ,const char *prompt1
- ,const char *prompt2
- ,const char **pass)
+static int _winbind_read_password(pam_handle_t * pamh
+ ,unsigned int ctrl
+ ,const char *comment
+ ,const char *prompt1
+ ,const char *prompt2
+ ,const char **pass)
{
int authtok_flag;
int retval;
diff --git a/source3/nsswitch/wb_client.c b/source3/nsswitch/wb_client.c
index bcb339864a..9ac1515d7d 100644
--- a/source3/nsswitch/wb_client.c
+++ b/source3/nsswitch/wb_client.c
@@ -65,7 +65,7 @@ BOOL winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid,
/* Call winbindd to convert sid to name */
-BOOL winbind_lookup_sid(DOM_SID *sid,
+BOOL winbind_lookup_sid(const DOM_SID *sid,
fstring dom_name, fstring name,
enum SID_NAME_USE *name_type)
{
@@ -102,7 +102,7 @@ BOOL winbind_lookup_sid(DOM_SID *sid,
/* Call winbindd to convert SID to uid */
-BOOL winbind_sid_to_uid(uid_t *puid, DOM_SID *sid)
+BOOL winbind_sid_to_uid(uid_t *puid, const DOM_SID *sid)
{
struct winbindd_request request;
struct winbindd_response response;
@@ -168,7 +168,7 @@ BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
/* Call winbindd to convert SID to gid */
-BOOL winbind_sid_to_gid(gid_t *pgid, DOM_SID *sid)
+BOOL winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid)
{
struct winbindd_request request;
struct winbindd_response response;
diff --git a/source3/nsswitch/wb_common.c b/source3/nsswitch/wb_common.c
index 89dd625241..9bc9faafb5 100644
--- a/source3/nsswitch/wb_common.c
+++ b/source3/nsswitch/wb_common.c
@@ -28,7 +28,6 @@
/* Global variables. These are effectively the client state information */
int winbindd_fd = -1; /* fd for winbindd socket */
-static char *excluded_domain;
/* Free a response structure */
@@ -40,16 +39,6 @@ void free_response(struct winbindd_response *response)
SAFE_FREE(response->extra_data);
}
-/*
- smbd needs to be able to exclude lookups for its own domain
-*/
-void winbind_exclude_domain(const char *domain)
-{
- SAFE_FREE(excluded_domain);
- excluded_domain = strdup(domain);
-}
-
-
/* Initialise a request structure */
void init_request(struct winbindd_request *request, int request_type)
@@ -325,12 +314,6 @@ NSS_STATUS winbindd_send_request(int req_type, struct winbindd_request *request)
return NSS_STATUS_NOTFOUND;
}
- /* smbd may have excluded this domain */
- if (excluded_domain &&
- strcasecmp(excluded_domain, request->domain) == 0) {
- return NSS_STATUS_NOTFOUND;
- }
-
if (!request) {
ZERO_STRUCT(lrequest);
request = &lrequest;
diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c
index d0af10a0e6..4d36acc51b 100644
--- a/source3/nsswitch/wbinfo.c
+++ b/source3/nsswitch/wbinfo.c
@@ -255,8 +255,7 @@ static BOOL wbinfo_check_secret(void)
ZERO_STRUCT(response);
- result = winbindd_request(WINBINDD_CHECK_MACHACC, NULL, &response) ==
- NSS_STATUS_SUCCESS;
+ result = winbindd_request(WINBINDD_CHECK_MACHACC, NULL, &response);
d_printf("checking the trust secret via RPC calls %s\n",
(result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
@@ -490,9 +489,9 @@ static BOOL wbinfo_auth_crap(char *username)
generate_random_buffer(request.data.auth_crap.chal, 8, False);
- SMBencrypt((uchar *)pass, request.data.auth_crap.chal,
+ SMBencrypt(pass, request.data.auth_crap.chal,
(uchar *)request.data.auth_crap.lm_resp);
- SMBNTencrypt((uchar *)pass, request.data.auth_crap.chal,
+ SMBNTencrypt(pass, request.data.auth_crap.chal,
(uchar *)request.data.auth_crap.nt_resp);
request.data.auth_crap.lm_resp_len = 24;
diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c
index 358d9add3a..256c0203c0 100644
--- a/source3/nsswitch/winbindd.c
+++ b/source3/nsswitch/winbindd.c
@@ -25,7 +25,7 @@
/* List of all connected clients */
-struct winbindd_cli_state *client_list;
+static struct winbindd_cli_state *client_list;
static int num_clients;
BOOL opt_nocache = False;
BOOL opt_dual_daemon = False;
@@ -375,6 +375,9 @@ void winbind_process_packet(struct winbindd_cli_state *state)
{
/* Process request */
+ /* Ensure null termination of entire request */
+ state->request.domain[sizeof(state->request.domain)-1]='\0';
+
state->pid = state->request.pid;
process_request(state);
@@ -688,6 +691,8 @@ int winbind_setup_common(void)
}
+ namecache_enable(); /* Enable netbios namecache */
+
/* Get list of domains we look up requests for. This includes the
domain which we are a member of as well as any trusted
domains. */
diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h
index 11d399be49..dd92ecefe6 100644
--- a/source3/nsswitch/winbindd.h
+++ b/source3/nsswitch/winbindd.h
@@ -88,7 +88,7 @@ typedef struct {
struct winbindd_domain {
fstring name; /* Domain name */
- fstring full_name; /* full Domain name (realm) */
+ fstring alt_name; /* alt Domain name (if any) */
DOM_SID sid; /* SID for this domain */
/* Lookup methods for this domain (LDAP or RPC) */
@@ -170,11 +170,15 @@ struct winbindd_methods {
TALLOC_CTX *mem_ctx,
uint32 *num_domains,
char ***names,
+ char ***alt_names,
DOM_SID **dom_sids);
/* find the domain sid */
NTSTATUS (*domain_sid)(struct winbindd_domain *domain,
DOM_SID *sid);
+
+ /* setup the list of alternate names for the domain, if any */
+ NTSTATUS (*alternate_name)(struct winbindd_domain *domain);
};
/* Used to glue a policy handle and cli_state together */
@@ -190,6 +194,8 @@ typedef struct {
#include "rpc_client.h"
#define WINBINDD_ESTABLISH_LOOP 30
+#define WINBINDD_RESCAN_FREQ 300
+
#define DOM_SEQUENCE_NONE ((uint32)-1)
/* SETENV */
diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c
index b61348adfe..b0b70178a4 100644
--- a/source3/nsswitch/winbindd_ads.c
+++ b/source3/nsswitch/winbindd_ads.c
@@ -61,8 +61,8 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope
if (*res) ads_msgfree(ads, *res);
*res = NULL;
- DEBUG(3,("Reopening ads connection to %s after error %s\n",
- ads->ldap_server, ads_errstr(status)));
+ DEBUG(3,("Reopening ads connection to realm '%s' after error %s\n",
+ ads->config.realm, ads_errstr(status)));
if (ads->ld) {
ldap_unbind(ads->ld);
}
@@ -87,7 +87,7 @@ ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res,
const char *exp,
const char **attrs)
{
- return ads_do_search_retry(ads, ads->bind_path, LDAP_SCOPE_SUBTREE,
+ return ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE,
exp, attrs, res);
}
@@ -108,8 +108,6 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
ADS_STRUCT *ads;
ADS_STATUS status;
char *ccache;
- struct in_addr server_ip;
- char *sname;
if (domain->private) {
return (ADS_STRUCT *)domain->private;
@@ -120,30 +118,23 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
SETENV("KRB5CCNAME", ccache, 1);
unlink(ccache);
- if (resolve_name(domain->name, &server_ip, 0x1b)) {
- sname = inet_ntoa(server_ip);
- } else if (resolve_name(domain->name, &server_ip, 0x1c)) {
- sname = inet_ntoa(server_ip);
- } else {
- if (strcasecmp(domain->name, lp_workgroup()) != 0) {
- DEBUG(1,("can't find domain controller for %s\n", domain->name));
- return NULL;
- }
- sname = NULL;
- }
-
- ads = ads_init(primary_realm, domain->name, NULL, NULL, NULL);
+ ads = ads_init(domain->alt_name, domain->name, NULL);
if (!ads) {
DEBUG(1,("ads_init for domain %s failed\n", domain->name));
return NULL;
}
/* the machine acct password might have change - fetch it every time */
- SAFE_FREE(ads->password);
- ads->password = secrets_fetch_machine_password();
+ SAFE_FREE(ads->auth.password);
+ ads->auth.password = secrets_fetch_machine_password();
+
+ if (primary_realm) {
+ SAFE_FREE(ads->auth.realm);
+ ads->auth.realm = strdup(primary_realm);
+ }
status = ads_connect(ads);
- if (!ADS_ERR_OK(status) || !ads->realm) {
+ if (!ADS_ERR_OK(status) || !ads->config.realm) {
extern struct winbindd_methods msrpc_methods;
DEBUG(1,("ads_connect for domain %s failed: %s\n",
domain->name, ads_errstr(status)));
@@ -161,11 +152,9 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
/* remember our primary realm for trusted domain support */
if (!primary_realm) {
- primary_realm = strdup(ads->realm);
+ primary_realm = strdup(ads->config.realm);
}
- fstrcpy(domain->full_name, ads->server_realm);
-
domain->private = (void *)ads;
return ads;
}
@@ -405,7 +394,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
/* accept either the win2000 or the pre-win2000 username */
asprintf(&exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))",
- name, name, ads->realm);
+ name, name, ads->config.realm);
rc = ads_search_retry(ads, &res, exp, attrs);
free(exp);
if (!ADS_ERR_OK(rc)) {
@@ -535,49 +524,6 @@ failed:
return False;
}
-
-/* convert a sid to a distnguished name */
-static NTSTATUS sid_to_distinguished_name(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *sid,
- char **dn)
-{
- ADS_STRUCT *ads = NULL;
- const char *attrs[] = {"distinguishedName", NULL};
- ADS_STATUS rc;
- void *msg = NULL;
- char *exp;
- char *sidstr;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
-
- DEBUG(3,("ads: sid_to_distinguished_name\n"));
-
- ads = ads_cached_connection(domain);
- if (!ads) goto done;
-
- sidstr = sid_binstring(sid);
- asprintf(&exp, "(objectSid=%s)", sidstr);
- rc = ads_search_retry(ads, &msg, exp, attrs);
- free(exp);
- free(sidstr);
- if (!ADS_ERR_OK(rc)) {
- DEBUG(1,("sid_to_distinguished_name ads_search: %s\n", ads_errstr(rc)));
- goto done;
- }
-
- *dn = ads_pull_string(ads, mem_ctx, msg, "distinguishedName");
-
- status = NT_STATUS_OK;
-
- DEBUG(3,("ads sid_to_distinguished_name mapped %s\n", *dn));
-
-done:
- if (msg) ads_msgfree(ads, msg);
-
- return status;
-}
-
-
/* Lookup user information from a rid */
static NTSTATUS query_user(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
@@ -831,6 +777,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
uint32 *num_domains,
char ***names,
+ char ***alt_names,
DOM_SID **dom_sids)
{
ADS_STRUCT *ads;
@@ -842,7 +789,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
ads = ads_cached_connection(domain);
if (!ads) return NT_STATUS_UNSUCCESSFUL;
- rc = ads_trusted_domains(ads, mem_ctx, num_domains, names, dom_sids);
+ rc = ads_trusted_domains(ads, mem_ctx, num_domains, names, alt_names, dom_sids);
return ads_ntstatus(rc);
}
@@ -867,6 +814,37 @@ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
return ads_ntstatus(rc);
}
+
+/* find alternate names list for the domain - for ADS this is the
+ netbios name */
+static NTSTATUS alternate_name(struct winbindd_domain *domain)
+{
+ ADS_STRUCT *ads;
+ ADS_STATUS rc;
+ TALLOC_CTX *ctx;
+ char *workgroup;
+
+ ads = ads_cached_connection(domain);
+ if (!ads) return NT_STATUS_UNSUCCESSFUL;
+
+ if (!(ctx = talloc_init_named("alternate_name"))) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ rc = ads_workgroup_name(ads, ctx, &workgroup);
+
+ if (ADS_ERR_OK(rc)) {
+ fstrcpy(domain->name, workgroup);
+ fstrcpy(domain->alt_name, ads->config.realm);
+ strupper(domain->alt_name);
+ strupper(domain->name);
+ }
+
+ talloc_destroy(ctx);
+
+ return ads_ntstatus(rc);
+}
+
/* the ADS backend methods are exposed via this structure */
struct winbindd_methods ads_methods = {
True,
@@ -879,7 +857,8 @@ struct winbindd_methods ads_methods = {
lookup_groupmem,
sequence_number,
trusted_domains,
- domain_sid
+ domain_sid,
+ alternate_name
};
#endif
diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c
index a607727867..060139af3e 100644
--- a/source3/nsswitch/winbindd_cache.c
+++ b/source3/nsswitch/winbindd_cache.c
@@ -873,13 +873,14 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
uint32 *num_domains,
char ***names,
+ char ***alt_names,
DOM_SID **dom_sids)
{
struct winbind_cache *cache = get_cache(domain);
/* we don't cache this call */
return cache->backend->trusted_domains(domain, mem_ctx, num_domains,
- names, dom_sids);
+ names, alt_names, dom_sids);
}
/* find the domain sid */
@@ -891,6 +892,15 @@ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
return cache->backend->domain_sid(domain, sid);
}
+/* find the alternate names for the domain, if any */
+static NTSTATUS alternate_name(struct winbindd_domain *domain)
+{
+ struct winbind_cache *cache = get_cache(domain);
+
+ /* we don't cache this call */
+ return cache->backend->alternate_name(domain);
+}
+
/* the ADS backend methods are exposed via this structure */
struct winbindd_methods cache_methods = {
True,
@@ -903,5 +913,6 @@ struct winbindd_methods cache_methods = {
lookup_groupmem,
sequence_number,
trusted_domains,
- domain_sid
+ domain_sid,
+ alternate_name
};
diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c
index 3ab97ed408..2dec9f0558 100644
--- a/source3/nsswitch/winbindd_cm.c
+++ b/source3/nsswitch/winbindd_cm.c
@@ -90,12 +90,122 @@ struct get_dc_name_cache {
struct get_dc_name_cache *prev, *next;
};
+
+/*
+ find the DC for a domain using methods appropriate for a ADS domain
+*/
+static BOOL cm_ads_find_dc(const char *domain, struct in_addr *dc_ip, fstring srv_name)
+{
+ ADS_STRUCT *ads;
+ const char *realm = domain;
+
+ if (strcasecmp(realm, lp_workgroup()) == 0) {
+ realm = lp_realm();
+ }
+
+ ads = ads_init(realm, domain, NULL);
+ if (!ads) {
+ return False;
+ }
+
+ /* we don't need to bind, just connect */
+ ads->auth.no_bind = 1;
+
+ DEBUG(4,("cm_ads_find_dc: domain=%s\n", domain));
+
+#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 */
+ ads_connect(ads);
+#endif
+
+ if (!ads->config.realm) {
+ return False;
+ }
+
+ fstrcpy(srv_name, ads->config.ldap_server_name);
+ strupper(srv_name);
+ *dc_ip = ads->ldap_ip;
+ ads_destroy(&ads);
+
+ DEBUG(4,("cm_ads_find_dc: using server='%s' IP=%s\n",
+ srv_name, inet_ntoa(*dc_ip)));
+
+ 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;
+
+ /* Lookup domain controller name. Try the real PDC first to avoid
+ SAM sync delays */
+ if (!get_dc_list(True, domain, &ip_list, &count)) {
+ if (!get_dc_list(False, domain, &ip_list, &count)) {
+ DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
+ return False;
+ }
+ }
+
+ /* Pick a nice close server */
+ /* Look for DC on local net */
+ for (i = 0; i < count; i++) {
+ if (!is_local_net(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;
+ }
+ zero_ip(&ip_list[i]);
+ }
+
+ /*
+ * Secondly try and contact a random PDC/BDC.
+ */
+
+ i = (sys_random() % count);
+
+ if (!is_zero_ip(ip_list[i]) &&
+ name_status_find(domain, 0x1c, 0x20,
+ ip_list[i], srv_name)) {
+ *dc_ip = ip_list[i];
+ SAFE_FREE(ip_list);
+ return True;
+ }
+ zero_ip(&ip_list[i]); /* Tried and failed. */
+
+ /* Finally return first DC that we can contact using a node
+ status */
+ 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)
{
static struct get_dc_name_cache *get_dc_name_cache;
struct get_dc_name_cache *dcc;
- struct in_addr *ip_list, dc_ip;
- int count, i;
+ struct in_addr dc_ip;
+ BOOL ret;
/* Check the cache for previous lookups */
@@ -144,66 +254,22 @@ static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr
DLIST_ADD(get_dc_name_cache, dcc);
- /* Lookup domain controller name. Try the real PDC first to avoid
- SAM sync delays */
- if (!get_dc_list(True, domain, &ip_list, &count)) {
- if (!get_dc_list(False, domain, &ip_list, &count)) {
- DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
- return False;
- }
- }
+ zero_ip(&dc_ip);
- /* Pick a nice close server */
- /* Look for DC on local net */
-
- for (i = 0; i < count; i++) {
- if (!is_local_net(ip_list[i]))
- continue;
-
- if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) {
- dc_ip = ip_list[i];
- goto done;
- }
- zero_ip(&ip_list[i]);
+ ret = False;
+ if (lp_security() == SEC_ADS) {
+ ret = cm_ads_find_dc(domain, &dc_ip, srv_name);
}
-
- /*
- * Secondly try and contact a random PDC/BDC.
- */
-
- i = (sys_random() % count);
-
- if (!is_zero_ip(ip_list[i]) &&
- name_status_find(domain, 0x1c, 0x20,
- ip_list[i], srv_name)) {
- dc_ip = ip_list[i];
- goto done;
+ if (!ret) {
+ /* fall back on rpc methods if the ADS methods fail */
+ ret = cm_rpc_find_dc(domain, &dc_ip, srv_name);
}
- zero_ip(&ip_list[i]); /* Tried and failed. */
- /* Finally return first DC that we can contact */
-
- 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];
- goto done;
- }
+ if (!ret) {
+ return False;
}
- /* No-one to talk to )-: */
- return False; /* Boo-hoo */
-
- done:
- /* We have the netbios name and IP address of a domain controller.
- Ideally we should sent a SAMLOGON request to determine whether
- the DC is alive and kicking. If we can catch a dead DC before
- performing a cli_connect() we can avoid a 30-second timeout. */
-
/* We have a name so make the cache entry positive now */
-
fstrcpy(dcc->srv_name, srv_name);
DEBUG(3, ("cm_get_dc_name: Returning DC %s (%s) for domain %s\n", srv_name,
@@ -211,8 +277,6 @@ static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr
*ip_out = dc_ip;
- SAFE_FREE(ip_list);
-
return True;
}
@@ -262,11 +326,23 @@ static struct failed_connection_cache *failed_connection_cache;
/* Add an entry to the failed conneciton cache */
-static void add_failed_connection_entry(struct winbindd_cm_conn *new_conn, NTSTATUS result) {
+static void add_failed_connection_entry(struct winbindd_cm_conn *new_conn,
+ NTSTATUS result)
+{
struct failed_connection_cache *fcc;
SMB_ASSERT(!NT_STATUS_IS_OK(result));
+ /* Check we already aren't in the cache */
+
+ for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
+ if (strequal(fcc->domain_name, new_conn->domain)) {
+ DEBUG(10, ("domain %s already tried and failed\n",
+ fcc->domain_name));
+ return;
+ }
+ }
+
/* Create negative lookup cache entry for this domain and controller */
if (!(fcc = (struct failed_connection_cache *)
@@ -794,7 +870,7 @@ NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd,
return result;
}
- result = new_cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+ result = cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd);
if (!NT_STATUS_IS_OK(result)) {
@@ -808,7 +884,7 @@ NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd,
}
/* Try again */
- result = new_cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+ result = cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd);
}
diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c
index 20563ba7bd..abb6b9da75 100644
--- a/source3/nsswitch/winbindd_group.c
+++ b/source3/nsswitch/winbindd_group.c
@@ -196,6 +196,9 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state)
gid_t gid;
int gr_mem_len;
+ /* Ensure null termination */
+ state->request.data.groupname[sizeof(state->request.data.groupname)-1]='\0';
+
DEBUG(3, ("[%5d]: getgrnam %s\n", state->pid,
state->request.data.groupname));
@@ -783,6 +786,9 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
int i;
TALLOC_CTX *mem_ctx;
+ /* Ensure null termination */
+ state->request.data.username[sizeof(state->request.data.username)-1]='\0';
+
DEBUG(3, ("[%5d]: getgroups %s\n", state->pid,
state->request.data.username));
diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h
index 0f0e40a2ec..9eea94e7c0 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 4
+#define WINBIND_INTERFACE_VERSION 5
/* Socket commands */
@@ -107,6 +107,12 @@ enum winbindd_cmd {
WINBINDD_NUM_CMDS
};
+#define WINBIND_PAM_INFO3_NDR 0x0001
+#define WINBIND_PAM_INFO3_TEXT 0x0002
+#define WINBIND_PAM_NTKEY 0x0004
+#define WINBIND_PAM_LMKEY 0x0008
+#define WINBIND_PAM_CONTACT_TRUSTDOM 0x0010
+
/* Winbind request structure */
struct winbindd_request {
@@ -132,6 +138,8 @@ struct winbindd_request {
uint16 lm_resp_len;
fstring nt_resp;
uint16 nt_resp_len;
+ fstring workstation;
+ uint32 flags;
} auth_crap;
struct {
fstring user;
@@ -216,6 +224,8 @@ struct winbindd_response {
fstring nt_status_string;
fstring error_string;
int pam_error;
+ char nt_session_key[16];
+ char first_8_lm_hash[8];
} auth;
} data;
diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c
index e608f826c9..a8b508a49c 100644
--- a/source3/nsswitch/winbindd_pam.c
+++ b/source3/nsswitch/winbindd_pam.c
@@ -23,17 +23,41 @@
*/
#include "winbindd.h"
-
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
+
+static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx,
+ struct winbindd_cli_state *state,
+ NET_USER_INFO_3 *info3)
+{
+ prs_struct ps;
+ uint32 size;
+ if (!prs_init(&ps, 256 /* Random, non-zero number */, mem_ctx, MARSHALL)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ if (!net_io_user_info3("", info3, &ps, 1, 3)) {
+ prs_mem_free(&ps);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ size = prs_data_size(&ps);
+ state->response.extra_data = memdup(prs_data_p(&ps), size);
+ if (!state->response.extra_data) {
+ prs_mem_free(&ps);
+ return NT_STATUS_NO_MEMORY;
+ }
+ state->response.length += size;
+ prs_mem_free(&ps);
+ return NT_STATUS_OK;
+}
+
/* Return a password structure from a username. */
enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
{
NTSTATUS result;
fstring name_domain, name_user;
- int passlen;
unsigned char trust_passwd[16];
time_t last_change_time;
uint32 smb_uid_low;
@@ -46,6 +70,12 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
extern pstring global_myname;
+ /* Ensure null termination */
+ state->request.data.auth.user[sizeof(state->request.data.auth.user)-1]='\0';
+
+ /* Ensure null termination */
+ state->request.data.auth.pass[sizeof(state->request.data.auth.pass)-1]='\0';
+
DEBUG(3, ("[%5d]: pam auth %s\n", state->pid,
state->request.data.auth.user));
@@ -64,16 +94,14 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
goto done;
}
- passlen = strlen(state->request.data.auth.pass);
-
{
unsigned char local_lm_response[24];
unsigned char local_nt_response[24];
generate_random_buffer(chal, 8, False);
- SMBencrypt( (const uchar *)state->request.data.auth.pass, chal, local_lm_response);
+ SMBencrypt(state->request.data.auth.pass, chal, local_lm_response);
- SMBNTencrypt((const uchar *)state->request.data.auth.pass, chal, local_nt_response);
+ SMBNTencrypt(state->request.data.auth.pass, chal, local_nt_response);
lm_resp = data_blob_talloc(mem_ctx, local_lm_response, sizeof(local_lm_response));
nt_resp = data_blob_talloc(mem_ctx, local_nt_response, sizeof(local_nt_response));
@@ -140,34 +168,67 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
NET_USER_INFO_3 info3;
struct cli_state *cli = NULL;
TALLOC_CTX *mem_ctx = NULL;
- const char *domain = NULL;
+ char *user = NULL;
+ char *domain = NULL;
+ char *contact_domain;
+ char *workstation;
DATA_BLOB lm_resp, nt_resp;
extern pstring global_myname;
- DEBUG(3, ("[%5d]: pam auth crap domain: %s user: %s\n", state->pid,
- state->request.data.auth_crap.domain, state->request.data.auth_crap.user));
+ /* Ensure null termination */
+ state->request.data.auth_crap.user[sizeof(state->request.data.auth_crap.user)-1]='\0';
+
+ /* Ensure null termination */
+ state->request.data.auth_crap.domain[sizeof(state->request.data.auth_crap.domain)-1]='\0';
- if (!(mem_ctx = talloc_init_named("winbind pam auth crap for %s", state->request.data.auth.user))) {
+ if (!(mem_ctx = talloc_init_named("winbind pam auth crap for (utf8) %s", state->request.data.auth.user))) {
DEBUG(0, ("winbindd_pam_auth_crap: could not talloc_init()!\n"));
result = NT_STATUS_NO_MEMORY;
goto done;
}
+ if (pull_utf8_talloc(mem_ctx, &user, state->request.data.auth_crap.user) < 0) {
+ DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
+ }
+
if (*state->request.data.auth_crap.domain) {
- domain = talloc_strdup(mem_ctx, state->request.data.auth_crap.domain);
+ if (pull_utf8_talloc(mem_ctx, &domain, state->request.data.auth_crap.domain) < 0) {
+ DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
+ }
} else if (lp_winbind_use_default_domain()) {
- domain = talloc_strdup(mem_ctx, lp_workgroup());
+ domain = lp_workgroup();
} else {
- DEBUG(5,("no domain specified with username (%s) - failing auth\n", state->request.data.auth.user));
+ DEBUG(5,("no domain specified with username (%s) - failing auth\n",
+ user));
result = NT_STATUS_INVALID_PARAMETER;
goto done;
}
- if (!domain) {
- DEBUG(0,("winbindd_pam_auth_crap: talloc_strdup failed!\n"));
- result = NT_STATUS_NO_MEMORY;
+ DEBUG(3, ("[%5d]: pam auth crap domain: %s user: %s\n", state->pid,
+ domain, user));
+
+ if (lp_allow_trusted_domains() && (state->request.data.auth_crap.flags & WINBIND_PAM_CONTACT_TRUSTDOM)) {
+ contact_domain = domain;
+ } else {
+ contact_domain = lp_workgroup();
+ }
+
+ if (*state->request.data.auth_crap.workstation) {
+ if (pull_utf8_talloc(mem_ctx, &workstation, state->request.data.auth_crap.workstation) < 0) {
+ DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
+ }
+ } else {
+ workstation = global_myname;
+ }
+
+ if (state->request.data.auth_crap.lm_resp_len > sizeof(state->request.data.auth_crap.lm_resp)
+ || state->request.data.auth_crap.nt_resp_len > sizeof(state->request.data.auth_crap.nt_resp)) {
+ DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n",
+ state->request.data.auth_crap.lm_resp_len,
+ state->request.data.auth_crap.nt_resp_len));
+ result = NT_STATUS_INVALID_PARAMETER;
goto done;
}
@@ -175,13 +236,15 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
nt_resp = data_blob_talloc(mem_ctx, state->request.data.auth_crap.nt_resp, state->request.data.auth_crap.nt_resp_len);
/*
- * Get the machine account password for our primary domain
+ * Get the machine account password for the domain to contact.
+ * This is either our own domain for a workstation, or possibly
+ * any domain for a PDC with trusted domains.
*/
- if (!secrets_fetch_trust_account_password(
- lp_workgroup(), trust_passwd, &last_change_time)) {
+ if (!secrets_fetch_trust_account_password (
+ contact_domain, trust_passwd, &last_change_time)) {
DEBUG(0, ("winbindd_pam_auth: could not fetch trust account "
- "password for domain %s\n", lp_workgroup()));
+ "password for domain %s\n", contact_domain));
result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
goto done;
}
@@ -189,7 +252,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
ZERO_STRUCT(info3);
/* Don't shut this down - it belongs to the connection cache code */
- result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, &cli);
+ result = cm_get_netlogon_cli(contact_domain, trust_passwd, &cli);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n", nt_errstr(result)));
@@ -197,27 +260,43 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
}
result = cli_netlogon_sam_network_logon(cli, mem_ctx,
- state->request.data.auth_crap.user, domain,
- global_myname, state->request.data.auth_crap.chal,
+ user, domain,
+ workstation, state->request.data.auth_crap.chal,
lm_resp, nt_resp,
&info3);
if (NT_STATUS_IS_OK(result)) {
uni_group_cache_store_netlogon(mem_ctx, &info3);
+ if (state->request.data.auth_crap.flags & WINBIND_PAM_INFO3_NDR) {
+ result = append_info3_as_ndr(mem_ctx, state, &info3);
+ }
+
+#if 0
+ /* we don't currently do this stuff right */
+ if (state->request.data.auth_crap.flags & WINBIND_PAM_NTKEY) {
+ SMB_ASSERT(sizeof(state->response.data.auth.nt_session_key) == sizeof(info3.user_sess_key));
+ memcpy(state->response.data.auth.nt_session_key, info3.user_sess_key, sizeof(state->response.data.auth.nt_session_key) /* 16 */);
+ }
+ if (state->request.data.auth_crap.flags & WINBIND_PAM_LMKEY) {
+ SMB_ASSERT(sizeof(state->response.data.auth.nt_session_key) <= sizeof(info3.user_sess_key));
+ memcpy(state->response.data.auth.first_8_lm_hash, info3.padding, sizeof(state->response.data.auth.nt_session_key) /* 16 */);
+ }
+#endif
}
done:
state->response.data.auth.nt_status = NT_STATUS_V(result);
- fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
- fstrcpy(state->response.data.auth.error_string, nt_errstr(result));
+ push_utf8_fstring(state->response.data.auth.nt_status_string, nt_errstr(result));
+ push_utf8_fstring(state->response.data.auth.error_string, nt_errstr(result));
state->response.data.auth.pam_error = nt_status_to_pam(result);
- DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("NTLM CRAP authenticaion for user [%s]\\[%s] returned %s (PAM: %d)\n",
- state->request.data.auth_crap.domain,
- state->request.data.auth_crap.user,
- state->response.data.auth.nt_status_string,
- state->response.data.auth.pam_error));
+ DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
+ ("NTLM CRAP authenticaion for user [%s]\\[%s] returned %s (PAM: %d)\n",
+ domain,
+ user,
+ state->response.data.auth.nt_status_string,
+ state->response.data.auth.pam_error));
if (mem_ctx)
talloc_destroy(mem_ctx);
diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c
index 2bb0e8c49f..5ec34f663d 100644
--- a/source3/nsswitch/winbindd_rpc.c
+++ b/source3/nsswitch/winbindd_rpc.c
@@ -575,22 +575,23 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
uint32 *num_domains,
char ***names,
+ char ***alt_names,
DOM_SID **dom_sids)
{
CLI_POLICY_HND *hnd;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 enum_ctx = 0;
- uint32 pref_num_domains = 5;
DEBUG(3,("rpc: trusted_domains\n"));
*num_domains = 0;
+ *alt_names = NULL;
if (!(hnd = cm_get_lsa_handle(lp_workgroup())))
goto done;
result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx,
- &hnd->pol, &enum_ctx, &pref_num_domains,
+ &hnd->pol, &enum_ctx,
num_domains, names, dom_sids);
done:
return result;
@@ -621,6 +622,13 @@ done:
return status;
}
+/* find alternate names list for the domain - none for rpc */
+static NTSTATUS alternate_name(struct winbindd_domain *domain)
+{
+ return NT_STATUS_OK;
+}
+
+
/* the rpc backend methods are exposed via this structure */
struct winbindd_methods msrpc_methods = {
False,
@@ -633,5 +641,6 @@ struct winbindd_methods msrpc_methods = {
lookup_groupmem,
sequence_number,
trusted_domains,
- domain_sid
+ domain_sid,
+ alternate_name
};
diff --git a/source3/nsswitch/winbindd_sid.c b/source3/nsswitch/winbindd_sid.c
index 372898a08a..44f857d6be 100644
--- a/source3/nsswitch/winbindd_sid.c
+++ b/source3/nsswitch/winbindd_sid.c
@@ -36,6 +36,9 @@ enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state)
fstring name;
fstring dom_name;
+ /* Ensure null termination */
+ state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
+
DEBUG(3, ("[%5d]: lookupsid %s\n", state->pid,
state->request.data.sid));
@@ -79,6 +82,12 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state)
DOM_SID sid;
struct winbindd_domain *domain;
+ /* Ensure null termination */
+ state->request.data.sid[sizeof(state->request.data.name.dom_name)-1]='\0';
+
+ /* Ensure null termination */
+ state->request.data.sid[sizeof(state->request.data.name.name)-1]='\0';
+
DEBUG(3, ("[%5d]: lookupname %s%s%s\n", state->pid,
state->request.data.name.dom_name,
lp_winbind_separator(),
@@ -112,6 +121,9 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state)
{
DOM_SID sid;
+ /* Ensure null termination */
+ state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
+
DEBUG(3, ("[%5d]: sid to uid %s\n", state->pid,
state->request.data.sid));
@@ -139,6 +151,9 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state)
{
DOM_SID sid;
+ /* Ensure null termination */
+ state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
+
DEBUG(3, ("[%5d]: sid to gid %s\n", state->pid,
state->request.data.sid));
diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c
index 55593d6ae5..4f57fd2c72 100644
--- a/source3/nsswitch/winbindd_user.c
+++ b/source3/nsswitch/winbindd_user.c
@@ -103,6 +103,9 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state)
struct winbindd_domain *domain;
TALLOC_CTX *mem_ctx;
+ /* Ensure null termination */
+ state->request.data.username[sizeof(state->request.data.username)-1]='\0';
+
DEBUG(3, ("[%5d]: getpwnam %s\n", state->pid,
state->request.data.username));
diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c
index d5668a2bb6..daa3abb340 100644
--- a/source3/nsswitch/winbindd_util.c
+++ b/source3/nsswitch/winbindd_util.c
@@ -74,19 +74,17 @@ void free_domain_list(void)
}
/* Add a trusted domain to our list of domains */
-
-static struct winbindd_domain *add_trusted_domain(char *domain_name,
- struct winbindd_methods *methods)
+static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name,
+ struct winbindd_methods *methods,
+ DOM_SID *sid)
{
struct winbindd_domain *domain;
/* We can't call domain_list() as this function is called from
init_domain_list() and we'll get stuck in a loop. */
-
for (domain = _domain_list; domain; domain = domain->next) {
- if (strcmp(domain_name, domain->name) == 0) {
- DEBUG(3, ("domain %s already in domain list\n",
- domain_name));
+ if (strcmp(domain_name, domain->name) == 0 ||
+ strcmp(domain_name, domain->alt_name) == 0) {
return domain;
}
}
@@ -101,40 +99,95 @@ static struct winbindd_domain *add_trusted_domain(char *domain_name,
ZERO_STRUCTP(domain);
+ /* prioritise the short name */
+ if (strchr_m(domain_name, '.') && alt_name && *alt_name) {
+ fstrcpy(domain->name, alt_name);
+ fstrcpy(domain->alt_name, domain_name);
+ } else {
fstrcpy(domain->name, domain_name);
+ if (alt_name) {
+ fstrcpy(domain->alt_name, alt_name);
+ }
+ }
+
domain->methods = methods;
domain->sequence_number = DOM_SEQUENCE_NONE;
domain->last_seq_check = 0;
+ if (sid) {
+ sid_copy(&domain->sid, sid);
+ }
/* Link to domain list */
-
DLIST_ADD(_domain_list, domain);
+ DEBUG(1,("Added domain %s %s %s\n",
+ domain->name, domain->alt_name,
+ sid?sid_string_static(&domain->sid):""));
+
return domain;
}
-/* Look up global info for the winbind daemon */
+/*
+ rescan our domains looking for new trusted domains
+ */
+void rescan_trusted_domains(void)
+{
+ struct winbindd_domain *domain;
+ TALLOC_CTX *mem_ctx;
+ static time_t last_scan;
+ time_t t = time(NULL);
+
+ /* ony rescan every few minutes */
+ if ((unsigned)(t - last_scan) < WINBINDD_RESCAN_FREQ) {
+ return;
+ }
+ last_scan = time(NULL);
+
+ DEBUG(1, ("scanning trusted domain list\n"));
+
+ if (!(mem_ctx = talloc_init_named("init_domain_list")))
+ return;
+
+ for (domain = _domain_list; domain; domain = domain->next) {
+ NTSTATUS result;
+ char **names;
+ char **alt_names;
+ int num_domains = 0;
+ DOM_SID *dom_sids;
+ int i;
+
+ result = domain->methods->trusted_domains(domain, mem_ctx, &num_domains,
+ &names, &alt_names, &dom_sids);
+ if (!NT_STATUS_IS_OK(result)) {
+ continue;
+ }
+
+ /* Add each domain to the trusted domain list. Each domain inherits
+ 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]);
+ }
+ }
+
+ talloc_destroy(mem_ctx);
+}
+
+/* Look up global info for the winbind daemon */
BOOL init_domain_list(void)
{
NTSTATUS result;
- TALLOC_CTX *mem_ctx;
extern struct winbindd_methods cache_methods;
struct winbindd_domain *domain;
- DOM_SID *dom_sids;
- char **names;
- int num_domains = 0;
-
- if (!(mem_ctx = talloc_init_named("init_domain_list")))
- return False;
/* Free existing list */
-
free_domain_list();
/* Add ourselves as the first entry */
-
- domain = add_trusted_domain(lp_workgroup(), &cache_methods);
+ 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 */
@@ -147,29 +200,12 @@ BOOL init_domain_list(void)
result = cache_methods.domain_sid(domain, &domain->sid);
}
- DEBUG(1,("Added domain %s (%s)\n",
- domain->name,
- sid_string_static(&domain->sid)));
-
- DEBUG(1, ("getting trusted domain list\n"));
+ /* get any alternate name for the primary domain */
+ cache_methods.alternate_name(domain);
- result = cache_methods.trusted_domains(domain, mem_ctx, &num_domains,
- &names, &dom_sids);
+ /* do an initial scan for trusted domains */
+ rescan_trusted_domains();
- /* Add each domain to the trusted domain list */
- if (NT_STATUS_IS_OK(result)) {
- int i;
- for(i = 0; i < num_domains; i++) {
- domain = add_trusted_domain(names[i], &cache_methods);
- if (!domain) continue;
- sid_copy(&domain->sid, &dom_sids[i]);
- DEBUG(1,("Added domain %s (%s)\n",
- domain->name,
- sid_string_static(&domain->sid)));
- }
- }
-
- talloc_destroy(mem_ctx);
return True;
}
@@ -184,7 +220,7 @@ struct winbindd_domain *find_domain_from_name(const char *domain_name)
for (domain = domain_list(); domain != NULL; domain = domain->next) {
if (strequal(domain_name, domain->name) ||
- strequal(domain_name, domain->full_name))
+ (domain->alt_name[0] && strequal(domain_name, domain->alt_name)))
return domain;
}
diff --git a/source3/nsswitch/winbindd_wins.c b/source3/nsswitch/winbindd_wins.c
index 8f9a7414bd..8ddd5dc10d 100644
--- a/source3/nsswitch/winbindd_wins.c
+++ b/source3/nsswitch/winbindd_wins.c
@@ -122,6 +122,9 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state)
int i, count, maxlen, size;
struct node_status *status;
+ /* Ensure null termination */
+ state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0';
+
DEBUG(3, ("[%5d]: wins_byip %s\n", state->pid,
state->request.data.winsreq));
@@ -166,6 +169,9 @@ enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state)
fstring response;
char * addr;
+ /* Ensure null termination */
+ state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0';
+
DEBUG(3, ("[%5d]: wins_byname %s\n", state->pid,
state->request.data.winsreq));