1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

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 07a21fcd23)
This commit is contained in:
Andrew Bartlett 2002-01-18 02:37:55 +00:00
parent 9d05373a76
commit 1fb9ccc4e2
12 changed files with 177 additions and 50 deletions

View File

@ -762,6 +762,7 @@
<listitem><para><link linkend="WINBINDGID"><parameter>winbind gid</parameter></link></para></listitem>
<listitem><para><link linkend="WINBINDSEPARATOR"><parameter>winbind separator</parameter></link></para></listitem>
<listitem><para><link linkend="WINBINDUID"><parameter>winbind uid</parameter></link></para></listitem>
<listitem><para><link linkend="WINBINDUSEDEFAULTDOMAIN"><parameter>winbind use default domain</parameter></link></para></listitem>
<listitem><para><link linkend="WINSHOOK"><parameter>wins hook</parameter></link></para></listitem>
<listitem><para><link linkend="WINSPROXY"><parameter>wins proxy</parameter></link></para></listitem>
<listitem><para><link linkend="WINSSERVER"><parameter>wins server</parameter></link></para></listitem>
@ -8195,7 +8196,23 @@ veto files = /.AppleDouble/.bin/.AppleDesktop/Network Trash Folder/
</varlistentry>
<varlistentry>
<term>winbind use default domain</term>
<varlistentry>
<term><anchor id="WINBINDUSEDEFAULTDOMAIN">winbind use default domain</term>
<listitem><para>This parameter specifies whether the <ulink url="winbindd.8.html">
winbindd(8)</ulink>
daemon should operate on users without domain component in their username.
Users without a domain component are treated as is part of the winbindd server's
own domain. While this does not benifit Windows users, it makes SSH, FTP and e-mail
function in a way much closer to the way they would in a native unix system.</para>
<para>Default: <command>winbind use default domain = &lt;falseg&gt;
</command></para>
<para>Example: <command>winbind use default domain = true</command></para>
</listitem>
</varlistentry>
<varlistentry>

View File

@ -276,6 +276,20 @@ group: files winbind
<para>Default: <command>template shell = /bin/false </command>
</para></listitem>
</varlistentry>
<varlistentry>
<term>winbind use default domain</term>
<listitem><para>This parameter specifies whether the <command>winbindd</command>
daemon should operate on users without domain component in their username.
Users without a domain component are treated as is part of the winbindd server's
own domain. While this does not benifit Windows users, it makes SSH, FTP and e-mail
function in a way much closer to the way they would in a native unix system.</para>
<para>Default: <command>winbind use default domain = &lt;falseg&gt;
</command></para>
<para>Example: <command>winbind use default domain = true</command></para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -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());
}
/****************************************************************************

View File

@ -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,

View File

@ -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. */
/* 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;
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;
}

View File

@ -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);

View File

@ -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,

View File

@ -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);

View File

@ -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_ */

View File

@ -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,

View File

@ -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);
}
}

View File

@ -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)