summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2002-01-18 02:37:55 +0000
committerAndrew Bartlett <abartlet@samba.org>2002-01-18 02:37:55 +0000
commit1fb9ccc4e2a91bf7124fba076ffa5458a1cbf404 (patch)
treee62b44816d89c4b8ad6ce5ccaf3050afc148ce20 /source3
parent9d05373a767cef2e841640f192e74da37fbb099f (diff)
downloadsamba-1fb9ccc4e2a91bf7124fba076ffa5458a1cbf404.tar.gz
samba-1fb9ccc4e2a91bf7124fba076ffa5458a1cbf404.tar.bz2
samba-1fb9ccc4e2a91bf7124fba076ffa5458a1cbf404.zip
This is the 'winbind default domain' patch from Alexander Bokovoy
<a.bokovoy@sam-solutions.net>. The idea is the domain\username is rather harsh for unix systems - people don't expect to have to FTP, SSH and (in particular) e-mail with a username like that. This 'corrects' that - but is not without its own problems. As you can see from the changes to files like username.c and wb_client.c (smbd's winbind client code) a lot of assumptions are made in a lot of places about lp_winbind_seperator determining a users's status as a domain or local user. The main change I will shortly be making is to investigate and kill off winbind_initgroups() - as far as I know it was a workaround for an old bug in winbind itself (and a bug in RH 5.2) and should no longer be relevent. I am also going to move to using the 'winbind uid' and 'winbind gid' paramaters to determine a user/groups's 'local' status, rather than the presence of the seperator. As such, this functionality is recommended for servers providing unix services, but is currently less than optimal for windows clients. (TODO: remove all references to lp_winbind_seperator() and lp_winbind_use_default_domain() from smbd) Andrew Bartlett (This used to be commit 07a21fcd2311d2d9b430b99303e3532a8c1159e4)
Diffstat (limited to 'source3')
-rw-r--r--source3/lib/username.c2
-rw-r--r--source3/libsmb/cli_netlogon.c6
-rw-r--r--source3/nsswitch/wb_client.c70
-rw-r--r--source3/nsswitch/wbinfo.c13
-rw-r--r--source3/nsswitch/winbindd_group.c12
-rw-r--r--source3/nsswitch/winbindd_pam.c21
-rw-r--r--source3/nsswitch/winbindd_proto.h2
-rw-r--r--source3/nsswitch/winbindd_user.c10
-rw-r--r--source3/nsswitch/winbindd_util.c56
-rw-r--r--source3/param/loadparm.c4
10 files changed, 146 insertions, 50 deletions
diff --git a/source3/lib/username.c b/source3/lib/username.c
index 9541ebeb08..7c8c9c740d 100644
--- a/source3/lib/username.c
+++ b/source3/lib/username.c
@@ -33,7 +33,7 @@ static struct passwd *uname_string_combinations2(char *s, int offset, struct pas
BOOL name_is_local(const char *name)
{
- return !strchr_m(name, *lp_winbind_separator());
+ return !(strchr_m(name, *lp_winbind_separator()) || lp_winbind_use_default_domain());
}
/****************************************************************************
diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c
index 9223683854..f95ee89a29 100644
--- a/source3/libsmb/cli_netlogon.c
+++ b/source3/libsmb/cli_netlogon.c
@@ -509,8 +509,8 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
**/
NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- char *username, char *domain, char *workstation,
- uint8 chal[8],
+ const char *username, const char *domain, const char *workstation,
+ const uint8 chal[8],
DATA_BLOB lm_response, DATA_BLOB nt_response,
NET_USER_INFO_3 *info3)
@@ -554,7 +554,7 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c
init_id_info2(&ctr.auth.id2, domain,
0, /* param_ctrl */
0xdead, 0xbeef, /* LUID? */
- username, workstation_name_slash, (uchar*)chal,
+ username, workstation_name_slash, (const uchar*)chal,
lm_response.data, lm_response.length, nt_response.data, nt_response.length);
init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname,
diff --git a/source3/nsswitch/wb_client.c b/source3/nsswitch/wb_client.c
index 7bfa65176c..04734c7f8e 100644
--- a/source3/nsswitch/wb_client.c
+++ b/source3/nsswitch/wb_client.c
@@ -32,21 +32,47 @@ NSS_STATUS winbindd_request(int req_type,
/* Copy of parse_domain_user from winbindd_util.c. Parse a string of the
form DOMAIN/user into a domain and a user */
+extern fstring global_myworkgroup;
static BOOL parse_domain_user(const char *domuser, fstring domain, fstring user)
{
char *p = strchr(domuser,*lp_winbind_separator());
- if (!p)
+ if (!(p || lp_winbind_use_default_domain()))
return False;
-
- fstrcpy(user, p+1);
- fstrcpy(domain, domuser);
- domain[PTR_DIFF(p, domuser)] = 0;
+
+ if(!p && lp_winbind_use_default_domain()) {
+ fstrcpy(user, domuser);
+ fstrcpy(domain, global_myworkgroup);
+ } else {
+ fstrcpy(user, p+1);
+ fstrcpy(domain, domuser);
+ domain[PTR_DIFF(p, domuser)] = 0;
+ }
strupper(domain);
return True;
}
+/*
+ Fill DOMAIN\\USERNAME entry accounting 'winbind use default domain' and
+ 'winbind separator' options.
+ This means:
+ - omit DOMAIN when 'winbind use default domain = true' and DOMAIN is
+ global_myworkgroup
+
+*/
+static void fill_domain_username(fstring name, const char *domain, const char *user)
+{
+ if(lp_winbind_use_default_domain() &&
+ !strcmp(global_myworkgroup, domain)) {
+ strlcpy(name, user, sizeof(fstring));
+ } else {
+ slprintf(name, sizeof(fstring) - 1, "%s%s%s",
+ domain, lp_winbind_separator(),
+ user);
+ }
+}
+
/* Call winbindd to convert a name to a sid */
BOOL winbind_lookup_name(const char *name, DOM_SID *sid,
@@ -60,10 +86,11 @@ BOOL winbind_lookup_name(const char *name, DOM_SID *sid,
return False;
/*
- * Don't do the lookup if the name has no separator.
+ * Don't do the lookup if the name has no separator _and_ we are not in
+ * 'winbind use default domain' mode.
*/
- if (!strchr(name, *lp_winbind_separator()))
+ if (!(strchr(name, *lp_winbind_separator()) || lp_winbind_use_default_domain()))
return False;
/* Send off request */
@@ -291,7 +318,7 @@ int winbind_initgroups(char *user, gid_t gid)
/* Call normal initgroups if we are a local user */
- if (!strchr(user, *lp_winbind_separator())) {
+ if (!(strchr(user, *lp_winbind_separator()) || lp_winbind_use_default_domain())) {
return initgroups(user, gid);
}
@@ -337,11 +364,17 @@ int winbind_initgroups(char *user, gid_t gid)
}
} else {
-
- /* The call failed. Set errno to something so we don't get
- a bogus value from the last failed system call. */
-
- errno = EIO;
+ /* The call failed but if 'winbind use default domain' is 'true', we
+ should call normal initgroups. */
+
+ if (lp_winbind_use_default_domain()) {
+ return initgroups(user, gid);
+ } else {
+ /* The call failed. Set errno to something so we don't get
+ a bogus value from the last failed system call. */
+
+ errno = EIO;
+ }
}
/* Free response data if necessary */
@@ -363,10 +396,11 @@ int winbind_getgroups(const char *user, int size, gid_t *list)
int result, i;
/*
- * Don't do the lookup if the name has no separator.
+ * Don't do the lookup if the name has no separator _and_ we are not in
+ * 'winbind use default domain' mode.
*/
- if (!strchr(user, *lp_winbind_separator()))
+ if (!(strchr(user, *lp_winbind_separator()) || lp_winbind_use_default_domain()))
return -1;
/* Fetch list of groups */
@@ -410,8 +444,7 @@ BOOL winbind_uidtoname(fstring name, uid_t uid)
if (name_type != SID_NAME_USER)
return False;
- slprintf(name, sizeof(fstring)-1, "%s%s%s", dom_name,
- lp_winbind_separator(), user_name);
+ fill_domain_username(name, dom_name, user_name);
return True;
}
@@ -433,8 +466,7 @@ BOOL winbind_gidtoname(fstring name, gid_t gid)
if (name_type != SID_NAME_DOM_GRP)
return False;
- slprintf(name, sizeof(fstring)-1, "%s%s%s", dom_name,
- lp_winbind_separator(), group_name);
+ fill_domain_username(name, dom_name, group_name);
return True;
}
diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c
index ab5d98bf9e..c6a0b040cb 100644
--- a/source3/nsswitch/wbinfo.c
+++ b/source3/nsswitch/wbinfo.c
@@ -66,8 +66,11 @@ static BOOL parse_wbinfo_domain_user(const char *domuser, fstring domain, fstrin
char *p = strchr(domuser,get_winbind_separator());
- if (!p)
- return False;
+ if (!p) {
+ fstrcpy(user, domuser);
+ domain[0]=0;
+ return True;
+ }
fstrcpy(user, p+1);
fstrcpy(domain, domuser);
@@ -361,17 +364,11 @@ static BOOL wbinfo_auth_crap(char *username)
fstring name_domain;
fstring pass;
char *p;
- char sep = get_winbind_separator();
/*
* Don't do the lookup if the name has no separator.
*/
- if (!strchr(username, sep)) {
- printf("no domain seperator (%c) in username - failing\n", sep);
- return False;
- }
-
/* Send off request */
ZERO_STRUCT(request);
diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c
index cd4254acfc..a70f94781e 100644
--- a/source3/nsswitch/winbindd_group.c
+++ b/source3/nsswitch/winbindd_group.c
@@ -128,8 +128,7 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
/* Append domain name */
- snprintf(name, sizeof(name), "%s%s%s", domain->name,
- lp_winbind_separator(), the_name);
+ fill_domain_username(name, domain->name, the_name);
len = strlen(name);
@@ -299,6 +298,7 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state)
if (strcmp(lp_winbind_separator(),"\\"))
string_sub(group_name, "\\", lp_winbind_separator(),
sizeof(fstring));
+ strip_domain_name_if_needed(&group_name);
if (!((name_type == SID_NAME_ALIAS) ||
(name_type == SID_NAME_DOM_GRP))) {
@@ -558,10 +558,9 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
/* Fill in group entry */
- slprintf(domain_group_name, sizeof(domain_group_name) - 1,
- "%s%s%s", ent->domain_name, lp_winbind_separator(),
+ fill_domain_username(domain_group_name, ent->domain_name,
name_list[ent->sam_entry_index].acct_name);
-
+
result = fill_grent(&group_list[group_list_ndx],
domain_group_name, group_gid);
@@ -732,8 +731,7 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
groups.sam_entries)[i].acct_name;
fstring name;
- snprintf(name, sizeof(name), "%s%s%s", domain->name,
- lp_winbind_separator(), group_name);
+ fill_domain_username(name, domain->name, group_name);
/* Append to extra data */
memcpy(&extra_data[extra_data_len], name,
diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c
index 95f0d527bb..87c5d0fb4b 100644
--- a/source3/nsswitch/winbindd_pam.c
+++ b/source3/nsswitch/winbindd_pam.c
@@ -56,7 +56,7 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
if (!parse_domain_user(state->request.data.auth.user, name_domain,
name_user)) {
- DEBUG(5,("no domain seperator (%s) in username (%s) - failing fauth\n", lp_winbind_separator(), state->request.data.auth.user));
+ DEBUG(5,("no domain seperator (%s) in username (%s) - failing auth\n", lp_winbind_separator(), state->request.data.auth.user));
talloc_destroy(mem_ctx);
return WINBINDD_ERROR;
}
@@ -131,6 +131,7 @@ 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;
+ const char *domain = NULL;
DATA_BLOB lm_resp, nt_resp;
@@ -144,6 +145,22 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
return WINBINDD_ERROR;
}
+ if (*state->request.data.auth_crap.domain) {
+ domain = talloc_strdup(mem_ctx, state->request.data.auth_crap.domain);
+ } else if (lp_winbind_use_default_domain()) {
+ domain = talloc_strdup(mem_ctx, lp_workgroup());
+ } else {
+ DEBUG(5,("no domain specified with username (%s) - failing auth\n", state->request.data.auth.user));
+ talloc_destroy(mem_ctx);
+ return WINBINDD_ERROR;
+ }
+
+ if (!domain) {
+ DEBUG(0,("winbindd_pam_auth_crap: talloc_strdup failed!\n"));
+ talloc_destroy(mem_ctx);
+ return WINBINDD_ERROR;
+ }
+
lm_resp = data_blob_talloc(mem_ctx, state->request.data.auth_crap.lm_resp, state->request.data.auth_crap.lm_resp_len);
nt_resp = data_blob_talloc(mem_ctx, state->request.data.auth_crap.nt_resp, state->request.data.auth_crap.nt_resp_len);
@@ -169,7 +186,7 @@ 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, state->request.data.auth_crap.domain,
+ state->request.data.auth_crap.user, domain,
global_myname, state->request.data.auth_crap.chal,
lm_resp, nt_resp,
&info3);
diff --git a/source3/nsswitch/winbindd_proto.h b/source3/nsswitch/winbindd_proto.h
index bfadcc9a6c..565c08f549 100644
--- a/source3/nsswitch/winbindd_proto.h
+++ b/source3/nsswitch/winbindd_proto.h
@@ -117,4 +117,6 @@ void free_getent_state(struct getent_state *state);
BOOL winbindd_param_init(void);
BOOL check_domain_env(char *domain_env, char *domain);
BOOL parse_domain_user(const char *domuser, fstring domain, fstring user);
+void strip_domain_name_if_needed(fstring *name);
+void fill_domain_username(fstring name, const char *domain, const char *user);
#endif /* _PROTO_H_ */
diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c
index e5cacbb989..6a825c81f4 100644
--- a/source3/nsswitch/winbindd_user.c
+++ b/source3/nsswitch/winbindd_user.c
@@ -217,6 +217,7 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state)
if (strcmp("\\", lp_winbind_separator()))
string_sub(user_name, "\\", lp_winbind_separator(),
sizeof(fstring));
+ strip_domain_name_if_needed(&user_name);
/* Get some user info */
@@ -500,9 +501,8 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)
/* Lookup user info */
- slprintf(domain_user_name, sizeof(domain_user_name) - 1,
- "%s%s%s", ent->domain_name, sep,
- name_list[ent->sam_entry_index].name);
+ fill_domain_username(domain_user_name, ent->domain_name,
+ name_list[ent->sam_entry_index].name);
result = winbindd_fill_pwent(
ent->domain_name,
@@ -596,9 +596,7 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
fstrcpy(acct_name, info[i].acct_name);
}
- slprintf(name, sizeof(name) - 1, "%s%s%s",
- domain->name, lp_winbind_separator(),
- acct_name);
+ fill_domain_username(name, domain->name, acct_name);
/* Append to extra data */
memcpy(&extra_data[extra_data_len], name,
diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c
index f90e89c23f..640b581ce3 100644
--- a/source3/nsswitch/winbindd_util.c
+++ b/source3/nsswitch/winbindd_util.c
@@ -348,17 +348,65 @@ BOOL check_domain_env(char *domain_env, char *domain)
}
/* Parse a string of the form DOMAIN/user into a domain and a user */
+extern fstring global_myworkgroup;
BOOL parse_domain_user(const char *domuser, fstring domain, fstring user)
{
char *p = strchr(domuser,*lp_winbind_separator());
- if (!p)
+ if (!(p || lp_winbind_use_default_domain()))
return False;
- fstrcpy(user, p+1);
- fstrcpy(domain, domuser);
- domain[PTR_DIFF(p, domuser)] = 0;
+ if(!p && lp_winbind_use_default_domain()) {
+ fstrcpy(user, domuser);
+ fstrcpy(domain, global_myworkgroup);
+ } else {
+ fstrcpy(user, p+1);
+ fstrcpy(domain, domuser);
+ domain[PTR_DIFF(p, domuser)] = 0;
+ }
strupper(domain);
return True;
}
+
+/*
+ Strip domain name if it is same as default domain name and
+ winbind use default domain = true
+
+ it assumes that name is actually fstring so that memory management
+ isn't needed.
+*/
+void strip_domain_name_if_needed(fstring *name)
+{
+ if(lp_winbind_use_default_domain()) {
+ char *sep = lp_winbind_separator();
+ char *new_name = strchr(*name, *sep);
+ if(new_name) {
+ *new_name = 0;
+ if (!strcmp(global_myworkgroup, *name)) {
+ new_name++;
+ safe_strcpy(*name, new_name, sizeof(fstring));
+ } else *new_name = *sep;
+ }
+ }
+}
+
+/*
+ Fill DOMAIN\\USERNAME entry accounting 'winbind use default domain' and
+ 'winbind separator' options.
+ This means:
+ - omit DOMAIN when 'winbind use default domain = true' and DOMAIN is
+ global_myworkgroup
+
+*/
+void fill_domain_username(fstring name, const char *domain, const char *user)
+{
+ if(lp_winbind_use_default_domain() &&
+ !strcmp(global_myworkgroup, domain)) {
+ strlcpy(name, user, sizeof(fstring));
+ } else {
+ slprintf(name, sizeof(fstring) - 1, "%s%s%s",
+ domain, lp_winbind_separator(),
+ user);
+ }
+}
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index d19d20f3f9..fce5fcde49 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -155,6 +155,7 @@ typedef struct
char *szWinbindSeparator;
BOOL bWinbindEnumUsers;
BOOL bWinbindEnumGroups;
+ BOOL bWinbindUseDefaultDomain;
char *szAddShareCommand;
char *szChangeShareCommand;
char *szDeleteShareCommand;
@@ -1043,6 +1044,7 @@ static struct parm_struct parm_table[] = {
{"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, 0},
{"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, 0},
{"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, 0},
+ {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, 0},
{NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
};
@@ -1368,6 +1370,7 @@ static void init_globals(void)
Globals.winbind_cache_time = 15;
Globals.bWinbindEnumUsers = True;
Globals.bWinbindEnumGroups = True;
+ Globals.bWinbindUseDefaultDomain = False;
Globals.bUseSpnego = True;
@@ -1511,6 +1514,7 @@ FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
FN_GLOBAL_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
+FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
#ifdef WITH_LDAP_SAM
FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)