winbindd: Add option to preserve case of user names and groups

Christof Schmitt cs at samba.org
Mon Sep 15 16:57:48 MDT 2014


On Mon, Sep 08, 2014 at 04:39:01PM +0200, Alexander Werth wrote:
> Hi,
> 
> I've encountered an use case where the enforced canonicalization of user
> names and groups to lower case by winbind creates problems and written a
> patch to make this optional.
> The use case is the generation of user names from uid's and gid's for
> NFS4 ACLs on a system using winbind as nss backend.
> NFS4 clients are typically not case insensitive unless they are using
> winbind as well. In particular some nfs4 clients use nss ldap to resove
> the same names winbind get's from the AD.
> If the winbind on the server enforces lower case user and group names
> these names will not be recognized on the clients.
> Doing the canonicalization to lower case allows to cache the reverse
> lookup entries of the name to id lookups.
> Apparently an earlier attempt to always remove the enforced
> canonicalization to lower case had been rejected.
> Since both ways have their advantages I added an option to preserve the
> case of user names and group names.
> The default is to behave as we do now and not preserve the case.
> The attached patch applies to samba master.
> 
> Please share your thoughts or concerns.
> 
> Cheers,
> Alexander Werth
> 
> 

> >From aba2d6afea7f6355225415b12ca80794666be445 Mon Sep 17 00:00:00 2001
> From: Alexander Werth <alexander.werth at de.ibm.com>
> Date: Mon, 8 Sep 2014 11:15:52 +0200
> Subject: [PATCH] winbindd: Add option to preserve case of user names and
>  groups
> 
> Signed-off-by: Alexander Werth <alexander.werth at de.ibm.com>
> ---
>  .../smbdotconf/winbind/winbindpreservecase.xml     | 29 ++++++++++++++++++++++
>  lib/param/param_table.c                            |  9 +++++++
>  source3/winbindd/wb_fill_pwent.c                   |  8 +++---
>  source3/winbindd/winbindd_cache.c                  |  3 ++-
>  source3/winbindd/winbindd_util.c                   | 18 +++++++++++---
>  5 files changed, 59 insertions(+), 8 deletions(-)
>  create mode 100644 docs-xml/smbdotconf/winbind/winbindpreservecase.xml
> 
> diff --git a/docs-xml/smbdotconf/winbind/winbindpreservecase.xml b/docs-xml/smbdotconf/winbind/winbindpreservecase.xml
> new file mode 100644
> index 0000000..b4d05cf
> --- /dev/null
> +++ b/docs-xml/smbdotconf/winbind/winbindpreservecase.xml
> @@ -0,0 +1,29 @@
> +<samba:parameter name="winbind preserve case"
> +		 context="G"
> +		 type="boolean"
> +		 advanced="1" developer="1"
> +		 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
> +<description>
> +	<para>This parameter controls whether winbindd will
> +	  preserve the case of all user and group names.
> +	  If not all names are canonicalized to lower case.
> +	  Enforced canonicalization to lower case allows to add
> +	  reverse cache entries on case insensitive name to id
> +	  lookups. As a tradeoff all returned names are lower case
> +	  even if they are stored as mixed case in the AD server.
> +	  This option is enabled by default.
> +	  This option is particularly important if the returned user
> +	  and group names are used in a case sensitive match on
> +	  another host.
> +	  For example if the generated usernames are used in NFSv4
> +	  ACLs and the remote host uses a case sensitive matching for
> +	  these usernames with the nss_ldap module instead of the
> +	  nss_winbind module. In this case the option should be
> +	  disabled.
> +	</para>
> +
> +</description>
> +
> +<value type="default">no</value>
> +<value type="example">yes</value>
> +</samba:parameter>
> diff --git a/lib/param/param_table.c b/lib/param/param_table.c
> index d3f60c3..c75e0e2 100644
> --- a/lib/param/param_table.c
> +++ b/lib/param/param_table.c
> @@ -4146,6 +4146,15 @@ struct parm_struct parm_table[] = {
>  		.flags		= FLAG_ADVANCED,
>  	},
>  	{
> +		.label		= "winbind preserve case",
> +		.type		= P_BOOL,
> +		.p_class	= P_GLOBAL,
> +		.offset		= GLOBAL_VAR(winbind_preserve_case),
> +		.special	= NULL,
> +		.enum_list	= NULL,
> +		.flags		= FLAG_ADVANCED,
> +	},
> +	{
>  		.label		= "winbind rpc only",
>  		.type		= P_BOOL,
>  		.p_class	= P_GLOBAL,
> diff --git a/source3/winbindd/wb_fill_pwent.c b/source3/winbindd/wb_fill_pwent.c
> index 206827c..a5fb6c7 100644
> --- a/source3/winbindd/wb_fill_pwent.c
> +++ b/source3/winbindd/wb_fill_pwent.c
> @@ -138,9 +138,11 @@ static void wb_fill_pwent_getgrsid_done(struct tevent_req *subreq)
>  	/* Username */
>  
>  	fstrcpy(user_name, state->info->acct_name);
> -	if (!strlower_m(user_name)) {
> -		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
> -		return;
> +	if (!lp_winbind_preserve_case()) {
> +		if (!strlower_m(user_name)) {
> +			tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
> +			return;
> +		}
>  	}
>  	status = normalize_name_map(state, domain, user_name, &mapped_name);
>  
> diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c
> index 9ec46cf..401e3c9 100644
> --- a/source3/winbindd/winbindd_cache.c
> +++ b/source3/winbindd/winbindd_cache.c
> @@ -1896,7 +1896,8 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
>  		wcache_save_name_to_sid(domain, status, domain_name, name, sid, *type);
>  
>  		/* Only save the reverse mapping if this was not a UPN */
> -		if (!strchr(name, '@')) {
> +		/* and winbind isn't set to preserve the case of names.*/
> +		if (!lp_winbind_preserve_case() && !strchr(name, '@')) {
>  			if (!strupper_m(discard_const_p(char, domain_name))) {
>  				return NT_STATUS_INVALID_PARAMETER;
>  			}
> diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
> index 35cc524..4560105 100644
> --- a/source3/winbindd/winbindd_util.c
> +++ b/source3/winbindd/winbindd_util.c
> @@ -947,14 +947,18 @@ bool canonicalize_username(fstring username_inout, fstring domain, fstring user)
>      Also, if omit DOMAIN if 'winbind trusted domains only = true', as the
>      username is then unqualified in unix
>  
> -    We always canonicalize as UPPERCASE DOMAIN, lowercase username.
> +    We always canonicalize the domain to UPPERCASE DOMAIN.
> +    The user or group names are canonicalized depending on the
> +    winbind preserve case setting to lowercase names.
>  */
>  void fill_domain_username(fstring name, const char *domain, const char *user, bool can_assume)
>  {
>  	fstring tmp_user;
>  
>  	fstrcpy(tmp_user, user);
> -	(void)strlower_m(tmp_user);
> +	if (!lp_winbind_preserve_case()) {
> +		(void)strlower_m(tmp_user);
> +	}
>  
>  	if (can_assume && assume_domain(domain)) {
>  		strlcpy(name, tmp_user, sizeof(fstring));
> @@ -977,11 +981,17 @@ char *fill_domain_username_talloc(TALLOC_CTX *mem_ctx,
>  	char *tmp_user, *name;
>  
>  	tmp_user = talloc_strdup(mem_ctx, user);
> -	if (!strlower_m(tmp_user)) {
> -		TALLOC_FREE(tmp_user);
> +	if (tmp_user == NULL) {
>  		return NULL;
>  	}
>  
> +	if (!lp_winbind_preserve_case()) {
> +		if (!strlower_m(tmp_user)) {
> +			TALLOC_FREE(tmp_user);
> +			return NULL;
> +		}
> +	}
> +
>  	if (can_assume && assume_domain(domain)) {
>  		name = tmp_user;
>  	} else {
> -- 
> 1.9.3
> 

Reviewed-by: Christof Schmitt <cs at samba.org>


More information about the samba-technical mailing list