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