summaryrefslogtreecommitdiff
path: root/source3/nsswitch
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2004-01-13 17:55:43 +0000
committerGerald Carter <jerry@samba.org>2004-01-13 17:55:43 +0000
commit0c9adb69858c7572320d18c0fd187dd6e885f17d (patch)
treed58b1ad6bbc5ca0e9f71d17ebdaa9905268fa1d4 /source3/nsswitch
parent60079bd15bee7fe71dd43cb131f6198ca28f74eb (diff)
downloadsamba-0c9adb69858c7572320d18c0fd187dd6e885f17d.tar.gz
samba-0c9adb69858c7572320d18c0fd187dd6e885f17d.tar.bz2
samba-0c9adb69858c7572320d18c0fd187dd6e885f17d.zip
sync HEAD with recent changes in 3.0
(This used to be commit c98399e3c9d74e19b7c9d806ca8028b48866931e)
Diffstat (limited to 'source3/nsswitch')
-rw-r--r--source3/nsswitch/wbinfo.c26
-rw-r--r--source3/nsswitch/winbind_nss_freebsd.c81
-rw-r--r--source3/nsswitch/winbindd.c2
-rw-r--r--source3/nsswitch/winbindd.h3
-rw-r--r--source3/nsswitch/winbindd_ads.c2
-rw-r--r--source3/nsswitch/winbindd_cache.c6
-rw-r--r--source3/nsswitch/winbindd_cm.c103
-rw-r--r--source3/nsswitch/winbindd_group.c62
-rw-r--r--source3/nsswitch/winbindd_misc.c16
-rw-r--r--source3/nsswitch/winbindd_nss.h3
-rw-r--r--source3/nsswitch/winbindd_rpc.c13
-rw-r--r--source3/nsswitch/winbindd_sid.c8
-rw-r--r--source3/nsswitch/winbindd_user.c52
-rw-r--r--source3/nsswitch/winbindd_util.c45
-rw-r--r--source3/nsswitch/wins.c4
15 files changed, 298 insertions, 128 deletions
diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c
index 7d25524f8e..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;
}
@@ -909,14 +911,14 @@ static void wbinfo_get_auth_user(void)
char *user, *domain, *password;
/* Lift data from secrets file */
+
+ secrets_fetch_ipc_userpass(&user, &domain, &password);
- secrets_init();
-
- user = secrets_fetch(SECRETS_AUTH_USER, NULL);
- domain = secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
- password = secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
+ if ((!user || !*user) && (!domain || !*domain ) && (!password || !*password)){
- if (!user && !domain && !password) {
+ SAFE_FREE(user);
+ SAFE_FREE(domain);
+ SAFE_FREE(password);
d_printf("No authorised user configured\n");
return;
}
diff --git a/source3/nsswitch/winbind_nss_freebsd.c b/source3/nsswitch/winbind_nss_freebsd.c
new file mode 100644
index 0000000000..b73a4ce44f
--- /dev/null
+++ b/source3/nsswitch/winbind_nss_freebsd.c
@@ -0,0 +1,81 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ AIX loadable authentication module, providing identification
+ routines against Samba winbind/Windows NT Domain
+
+ Copyright (C) Aaron Collins 2003
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include "winbind_client.h"
+
+/* Make sure that the module gets registered needed by freebsd 5.1 */
+
+extern enum nss_status _nss_winbind_getgrent_r(struct group *, char *, size_t,
+ int *);
+extern enum nss_status _nss_winbind_getgrnam_r(const char *, struct group *,
+ char *, size_t, int *);
+extern enum nss_status _nss_winbind_getgrgid_r(gid_t gid, struct group *, char *,
+ size_t, int *);
+extern enum nss_status _nss_winbind_setgrent(void);
+extern enum nss_status _nss_winbind_endgrent(void);
+
+extern enum nss_status _nss_winbind_getpwent_r(struct passwd *, char *, size_t,
+ int *);
+extern enum nss_status _nss_winbind_getpwnam_r(const char *, struct passwd *,
+ char *, size_t, int *);
+extern enum nss_status _nss_winbind_getpwuid_r(gid_t gid, struct passwd *, char *,
+ size_t, int *);
+extern enum nss_status _nss_winbind_setpwent(void);
+extern enum nss_status _nss_winbind_endpwent(void);
+
+NSS_METHOD_PROTOTYPE(__nss_compat_getgrnam_r);
+NSS_METHOD_PROTOTYPE(__nss_compat_getgrgid_r);
+NSS_METHOD_PROTOTYPE(__nss_compat_getgrent_r);
+NSS_METHOD_PROTOTYPE(__nss_compat_setgrent);
+NSS_METHOD_PROTOTYPE(__nss_compat_endgrent);
+
+NSS_METHOD_PROTOTYPE(__nss_compat_getpwnam_r);
+NSS_METHOD_PROTOTYPE(__nss_compat_getpwuid_r);
+NSS_METHOD_PROTOTYPE(__nss_compat_getpwent_r);
+NSS_METHOD_PROTOTYPE(__nss_compat_setpwent);
+NSS_METHOD_PROTOTYPE(__nss_compat_endpwent);
+
+static ns_mtab methods[] = {
+{ NSDB_GROUP, "getgrnam_r", __nss_compat_getgrnam_r, _nss_winbind_getgrnam_r },
+{ NSDB_GROUP, "getgrgid_r", __nss_compat_getgrgid_r, _nss_winbind_getgrgid_r },
+{ NSDB_GROUP, "getgrent_r", __nss_compat_getgrent_r, _nss_winbind_getgrent_r },
+{ NSDB_GROUP, "endgrent", __nss_compat_setgrent, _nss_winbind_setgrent },
+{ NSDB_GROUP, "setgrent", __nss_compat_endgrent, _nss_winbind_endgrent },
+
+{ NSDB_PASSWD, "getpwnam_r", __nss_compat_getpwnam_r, _nss_winbind_getpwnam_r },
+{ NSDB_PASSWD, "getpwuid_r", __nss_compat_getpwuid_r, _nss_winbind_getpwuid_r },
+{ NSDB_PASSWD, "getpwent_r", __nss_compat_getpwent_r, _nss_winbind_getpwent_r },
+{ NSDB_PASSWD, "endpwent", __nss_compat_setpwent, _nss_winbind_setpwent },
+{ NSDB_PASSWD, "setpwent", __nss_compat_endpwent, _nss_winbind_endpwent },
+
+};
+
+ns_mtab *
+nss_module_register(const char *source, unsigned int *mtabsize,
+ nss_module_unregister_fn *unreg)
+{
+ *mtabsize = sizeof(methods)/sizeof(methods[0]);
+ *unreg = NULL;
+ return (methods);
+}
diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c
index 4c03522461..3124ef6378 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_ads.c b/source3/nsswitch/winbindd_ads.c
index ec93d494d0..e6b857f406 100644
--- a/source3/nsswitch/winbindd_ads.c
+++ b/source3/nsswitch/winbindd_ads.c
@@ -112,7 +112,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
goto done;
}
- rc = ads_search_retry(ads, &res, "(objectCategory=user)", attrs);
+ rc = ads_search_retry(ads, &res, "(objectClass=user)", attrs);
if (!ADS_ERR_OK(rc) || !res) {
DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc)));
goto done;
diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c
index a3c1706b75..8dec89a6aa 100644
--- a/source3/nsswitch/winbindd_cache.c
+++ b/source3/nsswitch/winbindd_cache.c
@@ -107,12 +107,14 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain)
case SEC_ADS: {
extern struct winbindd_methods ads_methods;
/* always obey the lp_security parameter for our domain */
- if ( strequal(lp_realm(), domain->alt_name) || strequal(lp_workgroup(), domain->name) ) {
+ if (domain->primary) {
domain->backend = &ads_methods;
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..44fc06fe54 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 = NULL;
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_group.c b/source3/nsswitch/winbindd_group.c
index 180a3db8e2..b31dc92b38 100644
--- a/source3/nsswitch/winbindd_group.c
+++ b/source3/nsswitch/winbindd_group.c
@@ -106,7 +106,7 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
*num_gr_mem = 0;
if ( !((group_name_type==SID_NAME_DOM_GRP) ||
- ((group_name_type==SID_NAME_ALIAS) && strequal(lp_workgroup(), domain->name))) )
+ ((group_name_type==SID_NAME_ALIAS) && domain->primary)) )
{
DEBUG(1, ("SID %s in domain %s isn't a domain group (%d)\n",
sid_to_string(sid_string, group_sid), domain->name,
@@ -152,15 +152,10 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
occur in Universal groups on a Windows 2000 native mode
server. */
- if (name_types[i] != SID_NAME_USER) {
- DEBUG(3, ("name %s isn't a domain user\n", the_name));
- continue;
- }
+ /* make sure to allow machine accounts */
- /* Don't bother with machine accounts */
-
- if (the_name[strlen(the_name) - 1] == '$') {
- DEBUG(10, ("%s is machine account\n", the_name));
+ if (name_types[i] != SID_NAME_USER && name_types[i] != SID_NAME_COMPUTER) {
+ DEBUG(3, ("name %s isn't a domain user\n", the_name));
continue;
}
@@ -265,22 +260,20 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state)
return WINBINDD_OK;
}
- /* should we deal with users for our domain? */
-
- if ( lp_winbind_trusted_domains_only() && strequal(name_domain, lp_workgroup())) {
- DEBUG(7,("winbindd_getgrnam: My domain -- rejecting getgrnam() for %s\\%s.\n",
- name_domain, name_group));
- return WINBINDD_ERROR;
- }
-
-
/* Get info for the domain */
if ((domain = find_domain_from_name(name_domain)) == NULL) {
- DEBUG(0, ("could not get domain sid for domain %s\n",
+ DEBUG(3, ("could not get domain sid for domain %s\n",
name_domain));
return WINBINDD_ERROR;
}
+ /* should we deal with users for our domain? */
+
+ if ( lp_winbind_trusted_domains_only() && domain->primary) {
+ DEBUG(7,("winbindd_getgrnam: My domain -- rejecting getgrnam() for %s\\%s.\n",
+ name_domain, name_group));
+ return WINBINDD_ERROR;
+ }
/* Get rid and name type from name */
@@ -292,7 +285,7 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state)
}
if ( !((name_type==SID_NAME_DOM_GRP) ||
- ((name_type==SID_NAME_ALIAS) && strequal(lp_workgroup(), domain->name))) )
+ ((name_type==SID_NAME_ALIAS) && domain->primary)) )
{
DEBUG(1, ("name '%s' is not a local or domain group: %d\n",
name_group, name_type));
@@ -383,7 +376,7 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state)
}
if ( !((name_type==SID_NAME_DOM_GRP) ||
- ((name_type==SID_NAME_ALIAS) && strequal(lp_workgroup(), domain->name))) )
+ ((name_type==SID_NAME_ALIAS) && domain->primary) ))
{
DEBUG(1, ("name '%s' is not a local or domain group: %d\n",
group_name, name_type));
@@ -441,7 +434,7 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
are a member of a Samba domain */
if ( (IS_DC || lp_winbind_trusted_domains_only())
- && strequal(domain->name, lp_workgroup()) )
+ && domain->primary )
{
continue;
}
@@ -547,7 +540,7 @@ static BOOL get_sam_group_entries(struct getent_state *ent)
and are not using LDAP to get the groups */
if ( lp_security() != SEC_ADS && domain->native_mode
- && strequal(lp_workgroup(), domain->name) )
+ && domain->primary )
{
DEBUG(4,("get_sam_group_entries: Native Mode 2k domain; enumerating local groups as well\n"));
@@ -887,7 +880,7 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
extra_data[extra_data_len++] = ',';
}
- free(groups.sam_entries);
+ SAFE_FREE(groups.sam_entries);
}
/* Assign extra_data fields in response structure */
@@ -938,21 +931,22 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
/* Parse domain and username */
parse_domain_user(state->request.data.username,
- name_domain, name_user);
-
- /* bail if there is no domain */
+ name_domain, name_user);
- if ( !*name_domain )
- goto done;
-
/* Get info for the domain */
if ((domain = find_domain_from_name(name_domain)) == NULL) {
- DEBUG(0, ("could not find domain entry for domain %s\n",
+ DEBUG(7, ("could not find domain entry for domain %s\n",
name_domain));
goto done;
}
+ if ( domain->primary && lp_winbind_trusted_domains_only()) {
+ DEBUG(7,("winbindd_getpwnam: My domain -- rejecting getgroups() for %s\\%s.\n",
+ name_domain, name_user));
+ return WINBINDD_ERROR;
+ }
+
/* Get rid and name type from name. The following costs 1 packet */
if (!winbindd_lookup_sid_by_name(domain, name_user, &user_sid,
@@ -961,7 +955,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
goto done;
}
- if (name_type != SID_NAME_USER) {
+ if (name_type != SID_NAME_USER && name_type != SID_NAME_COMPUTER) {
DEBUG(1, ("name '%s' is not a user name: %d\n",
name_user, name_type));
goto done;
@@ -1000,7 +994,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
in a win2k native mode domain. */
if ( !((sid_type==SID_NAME_DOM_GRP) ||
- ((sid_type==SID_NAME_ALIAS) && strequal(lp_workgroup(), domain->name))) )
+ ((sid_type==SID_NAME_ALIAS) && domain->primary)) )
{
DEBUG(10, ("winbindd_getgroups: sid type %d "
"for %s is not a domain group\n",
@@ -1127,7 +1121,7 @@ enum winbindd_result winbindd_getusersids(struct winbindd_cli_state *state)
sid_string_static(&user_sid)));
goto done;
}
-
+
status = domain->methods->lookup_usergroups(domain, mem_ctx,
&user_sid, &num_groups,
&user_grpsids);
diff --git a/source3/nsswitch/winbindd_misc.c b/source3/nsswitch/winbindd_misc.c
index 08b5be827d..18478992f3 100644
--- a/source3/nsswitch/winbindd_misc.c
+++ b/source3/nsswitch/winbindd_misc.c
@@ -36,7 +36,6 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat
int num_retries = 0;
struct cli_state *cli;
uint32 sec_channel_type;
- const char *contact_domain_name = NULL;
struct winbindd_domain *contact_domain;
DEBUG(3, ("[%5lu]: check machine account\n", (unsigned long)state->pid));
@@ -51,18 +50,10 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat
}
- /* use the realm name if appropriate and possible */
-
- if ( lp_security() == SEC_ADS )
- contact_domain_name = lp_realm();
-
- if ( !contact_domain_name || !*contact_domain_name )
- contact_domain_name = lp_workgroup();
-
- contact_domain = find_domain_from_name(contact_domain_name);
+ contact_domain = find_our_domain();
if (!contact_domain) {
result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- DEBUG(1, ("%s is not a trusted domain\n", contact_domain_name));
+ DEBUG(1, ("Cannot find our own domain!\n"));
goto done;
}
@@ -132,7 +123,7 @@ enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state
/* Skip own domain */
- if (strequal(domain->name, lp_workgroup())) continue;
+ if (domain->primary) continue;
/* Add domain to list */
@@ -232,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_sid.c b/source3/nsswitch/winbindd_sid.c
index 7c4c8d804a..9fbf47046d 100644
--- a/source3/nsswitch/winbindd_sid.c
+++ b/source3/nsswitch/winbindd_sid.c
@@ -152,7 +152,7 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state)
DOM_SID sid2;
uint32 rid;
- domain = find_domain_from_name( lp_workgroup() );
+ domain = find_our_domain();
if ( !domain ) {
DEBUG(0,("winbindd_sid_to_uid: can't find my own domain!\n"));
return WINBINDD_ERROR;
@@ -244,7 +244,7 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state)
uint32 rid;
unid_t id;
- domain = find_domain_from_name( lp_workgroup() );
+ domain = find_our_domain();
if ( !domain ) {
DEBUG(0,("winbindd_sid_to_uid: can't find my own domain!\n"));
return WINBINDD_ERROR;
@@ -341,7 +341,7 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state)
if ( !(pw = getpwuid(state->request.data.uid)) )
return WINBINDD_ERROR;
- if ( !(domain = find_domain_from_name(lp_workgroup())) ) {
+ if ( !(domain = find_our_domain()) ) {
DEBUG(0,("winbindd_uid_to_sid: can't find my own domain!\n"));
return WINBINDD_ERROR;
}
@@ -411,7 +411,7 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state)
if ( !(grp = getgrgid(state->request.data.gid)) )
return WINBINDD_ERROR;
- if ( !(domain = find_domain_from_name(lp_workgroup())) ) {
+ if ( !(domain = find_our_domain()) ) {
DEBUG(0,("winbindd_uid_to_sid: can't find my own domain!\n"));
return WINBINDD_ERROR;
}
diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c
index 903a2a8bfa..d08377c888 100644
--- a/source3/nsswitch/winbindd_user.c
+++ b/source3/nsswitch/winbindd_user.c
@@ -37,7 +37,8 @@ static BOOL winbindd_fill_pwent(char *dom_name, char *user_name,
char *full_name, struct winbindd_pw *pw)
{
fstring output_username;
- pstring homedir;
+ char *homedir;
+ char *shell;
fstring sid_string;
if (!pw || !dom_name || !user_name)
@@ -72,24 +73,32 @@ static BOOL winbindd_fill_pwent(char *dom_name, char *user_name,
shell. */
/* The substitution of %U and %D in the 'template homedir' is done
- by lp_string() calling standard_sub_basic(). */
+ by alloc_sub_specified() below. */
- 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());
+ homedir = alloc_sub_specified(lp_template_homedir(), user_name, dom_name, pw->pw_uid, pw->pw_gid);
+
+ if (!homedir)
+ return False;
safe_strcpy(pw->pw_dir, homedir, sizeof(pw->pw_dir) - 1);
- safe_strcpy(pw->pw_shell, lp_template_shell(),
+ SAFE_FREE(homedir);
+
+ shell = alloc_sub_specified(lp_template_shell(), user_name, dom_name, pw->pw_uid, pw->pw_gid);
+
+ if (!shell)
+ return False;
+
+ safe_strcpy(pw->pw_shell, shell,
sizeof(pw->pw_shell) - 1);
/* Password - set to "x" as we can't generate anything useful here.
Authentication can be done using the pam_winbind module. */
safe_strcpy(pw->pw_passwd, "x", sizeof(pw->pw_passwd) - 1);
-
+
return True;
}
@@ -115,7 +124,7 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state)
/* Parse domain and username */
parse_domain_user(state->request.data.username,
- name_domain, name_user);
+ name_domain, name_user);
/* if this is our local domain (or no domain), the do a local tdb search */
@@ -131,17 +140,17 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state)
/* should we deal with users for our domain? */
- if ( lp_winbind_trusted_domains_only() && strequal(name_domain, lp_workgroup())) {
- DEBUG(7,("winbindd_getpwnam: My domain -- rejecting getpwnam() for %s\\%s.\n",
- name_domain, name_user));
- return WINBINDD_ERROR;
- }
-
if ((domain = find_domain_from_name(name_domain)) == NULL) {
DEBUG(5, ("no such domain: %s\n", name_domain));
return WINBINDD_ERROR;
}
+ if ( domain->primary && lp_winbind_trusted_domains_only()) {
+ DEBUG(7,("winbindd_getpwnam: My domain -- rejecting getpwnam() for %s\\%s.\n",
+ name_domain, name_user));
+ return WINBINDD_ERROR;
+ }
+
/* Get rid and name type from name */
if (!winbindd_lookup_sid_by_name(domain, name_user, &user_sid, &name_type)) {
@@ -149,15 +158,13 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state)
return WINBINDD_ERROR;
}
- if (name_type != SID_NAME_USER) {
+ if (name_type != SID_NAME_USER && name_type != SID_NAME_COMPUTER) {
DEBUG(1, ("name '%s' is not a user name: %d\n", name_user,
name_type));
return WINBINDD_ERROR;
}
- /* Get some user info. Split the user rid from the sid obtained
- from the winbind_lookup_by_name() call and use it in a
- winbind_lookup_userinfo() */
+ /* Get some user info. */
if (!(mem_ctx = talloc_init("winbindd_getpwnam([%s]\\[%s])",
name_domain, name_user))) {
@@ -530,15 +537,6 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)
name_list = ent->sam_entries;
- /* Skip machine accounts */
-
- if (name_list[ent->sam_entry_index].
- name[strlen(name_list[ent->sam_entry_index].name) - 1]
- == '$') {
- ent->sam_entry_index++;
- continue;
- }
-
/* Lookup user info */
result = winbindd_fill_pwent(
diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c
index 4cc43e85d6..076ab1a2fc 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 */
@@ -133,12 +149,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);
@@ -156,13 +174,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 ) {
@@ -174,7 +191,7 @@ void rescan_trusted_domains( void )
add_trusted_domains( mydomain );
- last_scan = now;
+ last_trustdom_scan = now;
return;
}
@@ -200,7 +217,7 @@ void add_trusted_domains( struct winbindd_domain *domain )
return;
}
- DEBUG(1, ("scanning trusted domain list\n"));
+ DEBUG(5, ("scanning trusted domain list\n"));
if (!(mem_ctx = talloc_init("init_domain_list")))
return;
@@ -221,7 +238,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 */
@@ -263,7 +280,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);
@@ -286,7 +303,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;
}
@@ -364,10 +383,6 @@ BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain,
{
NTSTATUS result;
TALLOC_CTX *mem_ctx;
- /* Don't bother with machine accounts */
-
- if (name[strlen(name) - 1] == '$')
- return False;
mem_ctx = talloc_init("lookup_sid_by_name for %s\n", name);
if (!mem_ctx)
diff --git a/source3/nsswitch/wins.c b/source3/nsswitch/wins.c
index 779d1b2c6c..100a103924 100644
--- a/source3/nsswitch/wins.c
+++ b/source3/nsswitch/wins.c
@@ -194,7 +194,7 @@ int lookup(nsd_file_t *rq)
* response needs to be a string of the following format
* ip_address[ ip_address]*\tname[ alias]*
*/
- if (strcasecmp(map,"hosts.byaddr") == 0) {
+ if (StrCaseCmp(map,"hosts.byaddr") == 0) {
if ( status = lookup_byaddr_backend(key, &count)) {
size = strlen(key) + 1;
if (size > len) {
@@ -222,7 +222,7 @@ int lookup(nsd_file_t *rq)
response[strlen(response)-1] = '\n';
free(status);
}
- } else if (strcasecmp(map,"hosts.byname") == 0) {
+ } else if (StrCaseCmp(map,"hosts.byname") == 0) {
if (ip_list = lookup_byname_backend(key, &count)) {
for (i = count; i ; i--) {
addr = inet_ntoa(ip_list[i-1]);