[SSSD] NSS: Add config option to expand homedir template format

Lukas Slebodnik lslebodn at redhat.com
Fri Mar 14 09:51:31 UTC 2014


On (12/03/14 14:52), Pavel Reichl wrote:
>On Tue, 2014-03-04 at 10:29 +0100, Lukas Slebodnik wrote:
>> On (03/03/14 13:35), Lukas Slebodnik wrote:
>> >On (31/01/14 23:58), Jakub Hrozek wrote:
>> >>On Fri, Jan 31, 2014 at 11:55:25AM +0100, Pavel Březina wrote:
>> >>> On 12/02/2013 04:12 PM, Lukas Slebodnik wrote:
>> >>> >ehlo,
>> >>> >
>> >>> >attached patches address ticket #1853
>> >>> >
>> >>> >LS
>> >>> 
>> >>> Hi,
>> >>> these patches no longer apply.
>> >>
>> >>for patches targeting 1.12, i would prefer to rebase them on top of Nikolai's
>> >                       ^^^^
>> >                       1.11
>> >>and Stephen's logging patches, those are the first to go to master now.
>> >
>> >Rebased patches are attached,
>> >
>> >LS
>> 
>> Sending rebased patches on top of "ipa-server-mode: use lower-case user name
>> for home dir"
>> 
>> LS
>> _______________________________________________
>> sssd-devel mailing list
>> sssd-devel at lists.fedorahosted.org
>> https://lists.fedorahosted.org/mailman/listinfo/sssd-devel
Please configure your email agent. It breaks lines longer than 80 lines
but quoted line prefix is missing on next line.

It is difficult to find out what is reply and what is wrapped line.

Example:
> ---
>  src/providers/ipa/ipa_s2n_exop.c      | 17 ++++++++++----
>  src/providers/ipa/ipa_subdomains_id.c | 27 ++++++++++++++--------
>  src/responder/nss/nsssrv_cmd.c        | 35
++++++++++++++++++----------
>  src/responder/pac/pacsrv_utils.c      | 14 ++++++++++--
>  src/util/sss_nss.c                    | 43
++++++++++++++++++++---------------
>  src/util/sss_nss.h                    | 12 +++++++---
>  6 files changed, 99 insertions(+), 49 deletions(-)



>
>Hello Lukas,
>
>I'm afraid I have some troubles witch patches:
>
>ipa user-find test_home
>--------------
>1 user matched
>--------------
>  User login: test_home
>  First name: test
>  Last name: home
>  Home directory: %H/test_home
>  Login shell: /bin/bash
>  Email address: test_home at ipa.work
>  UID: 1994000007
>  GID: 1994000007
>  Account disabled: False
>  Password: False
>  Kerberos keys available: False
>----------------------------
>Number of entries returned 1
>----------------------------
># getent passwd test_home
>test_home:*:1994000007:1994000007:test home:/:/bin/bash]
>
>I suppose homedir should rather be /home/test_home then /.
>

There were lot of changes in last three months. I spend some time with rebasing
patches but unfortunately git didn't help me with merging the most important
part of the last patch. (and I didn't test rebased patches before sending
to the sssd-devel)

>> 
>> @@ -318,6 +316,7 @@ static int fill_pwent(struct sss_packet *packet,
>>      bool packet_initialized = false;
>>      int ncret;
>>      TALLOC_CTX *tmp_ctx = NULL;
>> +    struct sss_nss_homedir_ctx *homedir_ctx;
>>  
>>      to_sized_string(&pwfield, nctx->pwfield);
>>  
>> @@ -373,7 +372,19 @@ static int fill_pwent(struct sss_packet *packet,
>>          } else {
>>              to_sized_string(&gecos, tmpstr);
>>          }
>> -        tmpstr = get_homedir_override(tmp_ctx, msg, nctx, dom,
>name.str, uid);
>> +
>> +        homedir_ctx = talloc_zero(tmp_ctx, struct
>sss_nss_homedir_ctx);
>> +        if (! homedir_ctx) {
>> +            num = 0;
>> +            ret = ENOMEM;
>> +            goto done;;
>> +        }
>> +
>> +        homedir_ctx->username = name.str;
>> +        homedir_ctx->uid = uid;
>> +        homedir_ctx->domain = dom->name;
>
>Should not be homedir_ctx->config_homedir_substr set to
>nctx->homedir_substring or rather domain->homedir_substring if not
>empty?
>
It was in function get_homedir_override (in the 1st version of patch)
Fixed in attacehd patches.
>> +
>> +        tmpstr = get_homedir_override(tmp_ctx, msg, nctx, dom,
>homedir_ctx);
>>          if (!tmpstr) {
>>              to_sized_string(&homedir, "/");
>>          } else {
>> }
>
>
>I have noticed a few interesting construction regarding our code style:
>
>patch 2:
>
>> From f06de6cf3130d0b01b04152e11933d1c4d875ea6 Mon Sep 17 00:00:00 2001
>> From: Lukas Slebodnik <lslebodn at redhat.com>
>> Date: Mon, 2 Dec 2013 13:03:33 +0100
>> Subject: [PATCH 2/3] NSS: Refactor expand_homedir_template
>> 
>> Function expand_homedir_template had lot of parameters.
>> After adding new expand option, all function call should be rewritten,
>> (usually argument NULL will be added)
>> 
>> This patch wraps all necessary arguments to structure.
>> ---
>>  src/providers/ipa/ipa_s2n_exop.c      | 17 ++++++++++----
>>  src/providers/ipa/ipa_subdomains_id.c | 27 ++++++++++++++--------
>>  src/responder/nss/nsssrv_cmd.c        | 35
>++++++++++++++++++----------
>>  src/responder/pac/pacsrv_utils.c      | 14 ++++++++++--
>>  src/util/sss_nss.c                    | 43
>++++++++++++++++++++---------------
>>  src/util/sss_nss.h                    | 12 +++++++---
>>  6 files changed, 99 insertions(+), 49 deletions(-)
>> 
>> diff --git a/src/providers/ipa/ipa_s2n_exop.c
>b/src/providers/ipa/ipa_s2n_exop.c
>> index
>59a99061ac3ad6f24a8af50e9c1d574282301a1d..02e87f86b75f4b5603b8be2e11e25c0a9fcdec7c 100644
>> --- a/src/providers/ipa/ipa_s2n_exop.c
>> +++ b/src/providers/ipa/ipa_s2n_exop.c
>> @@ -648,6 +648,7 @@ static void ipa_s2n_get_user_done(struct
>tevent_req *subreq)
>>      struct resp_attrs *simple_attrs = NULL;
>>      time_t now;
>>      uint64_t timeout = 10*60*60; /* FIXME: find a better timeout ! */
>> +    struct sss_nss_homedir_ctx *homedir_ctx;
>>      const char *homedir = NULL;
>>      struct sysdb_attrs *user_attrs = NULL;
>>      struct sysdb_attrs *group_attrs = NULL;
>> @@ -738,13 +739,19 @@ static void ipa_s2n_get_user_done(struct
>tevent_req *subreq)
>>      switch (attrs->response_type) {
>>               case RESP_USER:
>>              if (state->dom->subdomain_homedir) {
>>              +                homedir_ctx = talloc_zero(state, struct
>sss_nss_homedir_ctx);
>> +                if (! homedir_ctx) {
>> +                    ret = ENOMEM;
>> +                    goto done;
>> +                }
>
>I think it is now prefered to use if (homedir_ctx == NULL) to highlight
>homedir_ctx is a pointer,
I cannot find anything about prefered way
    http://www.freeipa.org/page/Coding_Style
>but I defintly think that the space after ! is redundant.
>
It *IS NOT*
'!' is very similar to 'l'
You can compare following three lines.
                if (link) {
                if (!ink) {
                if (! ink) {



>> +                homedir_ctx->username = attrs->a.user.pw_name;
>> +                homedir_ctx->uid = attrs->a.user.pw_uid;
>> +                homedir_ctx->domain = state->dom->name;
>> +                homedir_ctx->flatname = state->dom->flat_name;
>> +
>>                  homedir =  expand_homedir_template(state,
>>
>state->dom->subdomain_homedir,
>> -
>attrs->a.user.pw_name,
>> -
>attrs->a.user.pw_uid,
>> -                                                   NULL,
>> -                                                   state->dom->name,
>> -
>state->dom->flat_name);
>> +                                                   homedir_ctx);
>>                  if (homedir == NULL) {
>>                      ret = ENOMEM;
>>                      goto done;
>> diff --git a/src/providers/ipa/ipa_subdomains_id.c
>b/src/providers/ipa/ipa_subdomains_id.c
>> index
>0adf806066ec34b8c42ddf4d0cbd2d23f05caa50..1766e33708cd29da18c3ac4d0b94ccc33583a851 100644
>> --- a/src/providers/ipa/ipa_subdomains_id.c
>> +++ b/src/providers/ipa/ipa_subdomains_id.c
>> @@ -357,10 +357,10 @@ get_subdomain_homedir_of_user(TALLOC_CTX
>*mem_ctx, struct sss_domain_info *dom,
>>                                const char **_homedir)
>>  {
>>      errno_t ret;
>> -    char *name;
>> -    char *lc_name;
>> +    const char *name;
>>      const char *homedir;
>>      TALLOC_CTX *tmp_ctx;
>> +    struct sss_nss_homedir_ctx *homedir_ctx;
>>  
>>      tmp_ctx = talloc_new(mem_ctx);
>>      if (tmp_ctx == NULL) {
>>      @@ -368,22 +368,31 @@ get_subdomain_homedir_of_user(TALLOC_CTX
>*mem_ctx, struct sss_domain_info *dom,
>>          goto done;
>>      }
>>  
>> -    ret = sss_parse_name(tmp_ctx, dom->names, fqname, NULL, &name);
>> +    homedir_ctx = talloc_zero(tmp_ctx, struct sss_nss_homedir_ctx);
>> +    if (! homedir_ctx) {
>> +        ret = ENOMEM;
>> +        goto done;
>> +    }
>
>same as above
>
>> +
>> +    homedir_ctx->uid = uid;
>> +    homedir_ctx->domain = dom->name;
>> +    homedir_ctx->flatname = dom->flat_name;
>> +    ret = sss_parse_name_const(tmp_ctx, dom->names, fqname,
>> +                               NULL, &name);
>>      if (ret != EOK) {
>>          goto done;
>>      }
>>  
>>      /* To be compatible with the old winbind based user lookups and
>IPA
>>       * clients the user name in the home directory path will be
>lower-case. */
>> -    lc_name = sss_tc_utf8_str_tolower(tmp_ctx, name);
>> -    if (lc_name == NULL) {
>> -        ret =ENOMEM;
>> +    homedir_ctx->username = sss_tc_utf8_str_tolower(tmp_ctx, name);
>> +    if (homedir_ctx->username == NULL) {
>> +        ret = ENOMEM;
>>          goto done;
>>      }
>>  
>> -    homedir = expand_homedir_template(tmp_ctx,
>dom->subdomain_homedir, lc_name,
>> -                                      uid, NULL, dom->name,
>dom->flat_name);
>> -
>> +    homedir = expand_homedir_template(tmp_ctx,
>dom->subdomain_homedir,
>> +                                      homedir_ctx);
>>      if (homedir == NULL) {
>>          DEBUG(SSSDBG_OP_FAILURE, "expand_homedir_template failed\n");
>>          ret = ENOMEM;
>> @@ -373,7 +372,19 @@ static int fill_pwent(struct sss_packet *packet,
>>          } else {
>>              to_sized_string(&gecos, tmpstr);
>>          }
>> -        tmpstr = get_homedir_override(tmp_ctx, msg, nctx, dom,
>name.str, uid);
>> +
>> +        homedir_ctx = talloc_zero(tmp_ctx, struct
>sss_nss_homedir_ctx);
>> +        if (! homedir_ctx) {
>> +            num = 0;
>> +            ret = ENOMEM;
>> +            goto done;;
>> +        }
>
>same as above and please remove the redundant ;
>
Fixed

>> +
>> +        homedir_ctx->username = name.str;
>> +        homedir_ctx->uid = uid;
>> +        homedir_ctx->domain = dom->name;
>> +
>> +        tmpstr = get_homedir_override(tmp_ctx, msg, nctx, dom,
>homedir_ctx);
>>          if (!tmpstr) {
>>              to_sized_string(&homedir, "/");
>>          } else {
>> diff --git a/src/responder/pac/pacsrv_utils.c
>b/src/responder/pac/pacsrv_utils.c
>> index
>035fe84c0f39aaa40a403a8ac5f19527b2191267..4bf5585e8de667850ef520fa372d7e114f2cab1a 100644
>> --- a/src/responder/pac/pacsrv_utils.c
>> +++ b/src/responder/pac/pacsrv_utils.c
>> @@ -353,6 +353,7 @@ errno_t get_pwd_from_pac(TALLOC_CTX *mem_ctx,
>>      char *upn;
>>      hash_key_t key;
>>      hash_value_t value;
>> +    struct sss_nss_homedir_ctx *homedir_ctx;
>>  
>>      pwd = talloc_zero(mem_ctx, struct passwd);
>>      if (pwd == NULL) {
>> @@ -439,9 +440,18 @@ errno_t get_pwd_from_pac(TALLOC_CTX *mem_ctx,
>>      /* Check if there is a special homedir template for sub-domains.
>If not a
>>       * fallback will be added by the NSS responder. */
>>      if (IS_SUBDOMAIN(dom) && dom->subdomain_homedir) {
>>      +        homedir_ctx = talloc_zero(pwd, struct
>sss_nss_homedir_ctx);
>> +        if (! homedir_ctx) {
>> +            ret = ENOMEM;
>> +            goto done;;
>> +        }
>
>same as above and please remove the redundant ;
>
Fixed

>> +        homedir_ctx->username = lname;
>> +        homedir_ctx->uid = pwd->pw_uid;
>> +        homedir_ctx->domain = dom->name;
>> +        homedir_ctx->flatname = dom->flat_name;
>> +
>>          pwd->pw_dir = expand_homedir_template(pwd,
>dom->subdomain_homedir,
>> -                                              lname, pwd->pw_uid,
>NULL,
>> -                                              dom->name,
>dom->flat_name);
>> +                                              homedir_ctx);
>>          if (pwd->pw_dir == NULL) {
>>              ret = ENOMEM;
>>              goto done;
>> diff --git a/src/util/sss_nss.c b/src/util/sss_nss.c
>> index
>406c95cd0f76c9e73705bc49b4261160d26bfc58..efc6e3e2c66944c236a5d62df9e573b15a9f5840 100644
>> --- a/src/util/sss_nss.c
>> +++ b/src/util/sss_nss.c
>> @@ -23,9 +23,7 @@
>>  #include "util/sss_nss.h"
>>  
>>  char *expand_homedir_template(TALLOC_CTX *mem_ctx, const char
>*template,
>> -                              const char *username, uint32_t uid,
>> -                              const char *original, const char
>*domain,
>> -                              const char *flatname)
>> +                              struct sss_nss_homedir_ctx
>*homedir_ctx)
>>  {
>>      char *copy;
>>      char *p;
>> @@ -40,6 +38,11 @@ char *expand_homedir_template(TALLOC_CTX *mem_ctx,
>const char *template,
>>          return NULL;
>>      }
>>  
>> +    if (! homedir_ctx) {
>> +        DEBUG(SSSDBG_CRIT_FAILURE, ("Missing home directory
>data.\n"));
>> +        return NULL;
>> +    }
>
>same as above
>
>
>
>patch 3
>
>
>> diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
>> index
>9a13f723de601413205cbb580a92791015b94aa1..cc8b2691262ed9b893bcb693eb1cbb2c05446a60 100644
>> --- a/src/confdb/confdb.c
>> +++ b/src/confdb/confdb.c
>> @@ -1118,6 +1118,16 @@ static int confdb_get_domain_internal(struct
>confdb_ctx *cdb,
>>      }
>>  
>>      tmp = ldb_msg_find_attr_as_string(res->msgs[0],
>> +                                      CONFDB_NSS_HOMEDIR_SUBSTRING,
>NULL);
>> +    if (tmp != NULL) {
>> +        domain->homedir_substr = talloc_strdup(domain, tmp);
>> +        if (!domain->homedir_substr) {
>> +            ret = ENOMEM;
>> +            goto done;
>> +        }
>> +    }
>
>Please use uniform form of testing to NULL IMO the first one is
>prefered.
>
I prefer short version.
Anyway, we are not consistent. There is place for discussion.

>> diff --git a/src/man/include/homedir_substring.xml
>b/src/man/include/homedir_substring.xml
>> new file mode 100644
>> index
>0000000000000000000000000000000000000000..8ac83b7d665cfa8bc9b81bcbea780b40cb64ef62
>> --- /dev/null
>> +++ b/src/man/include/homedir_substring.xml
>> @@ -0,0 +1,16 @@
>> +<varlistentry>
>> +    <term>homedir_substring (string)</term>
>> +    <listitem>
>> +        <para>
>> +            Value of this option will be used in the expansion of
>> +            <emphasis>override_homedir</emphasis> option if template
>contains
>> +            format string <emphasis>%H</emphasis>. LDAP directory can
>directly
>> +            contain template and this option can be used to expand
>home
>> +            directory for each machine (or Operating system).
>> +            It can be set in the [nss] section or per-domain.
>
>If this option is set in both [nss] and domain section which value is
>then used?
>
Updated.

>> +        </para>
>> +        <para>
>> +            Default: /home
>> +        </para>
>> +    </listitem>
>> +</varlistentry>

Updated verion of patches are attached.

LS
-------------- next part --------------
>From 40dcb132b3dd79fd9f1ec0cf5af0ae69e2467b10 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn at redhat.com>
Date: Fri, 28 Feb 2014 23:42:19 +0100
Subject: [PATCH 1/3] UTIL: Add function sss_parse_name_const

Variable with type 'const char *' can be used as output argument in function
sss_parse_name, but there will be warning.

warning: passing 'const char **' to parameter of type 'char **'
         discards qualifiers in nested pointer types
         [-Wincompatible-pointer-types-discards-qualifiers]
---
 src/util/usertools.c | 22 ++++++++++++++++++++++
 src/util/util.h      |  4 ++++
 2 files changed, 26 insertions(+)

diff --git a/src/util/usertools.c b/src/util/usertools.c
index 51927393db02449c883042bad77a6aa839591708..486d99d9f39da2487dc1cb98c83829d1bde3cf88 100644
--- a/src/util/usertools.c
+++ b/src/util/usertools.c
@@ -366,6 +366,28 @@ int sss_parse_name(TALLOC_CTX *memctx,
     return EOK;
 }
 
+int sss_parse_name_const(TALLOC_CTX *memctx,
+                         struct sss_names_ctx *snctx, const char *orig,
+                         const char **_domain, const char **_name)
+{
+    char *domain;
+    char *name;
+    int ret;
+
+    ret = sss_parse_name(memctx, snctx, orig,
+                         (_domain == NULL) ? NULL : &domain,
+                         (_name == NULL) ? NULL : &name);
+    if (_domain) {
+        *_domain = domain;
+    }
+
+    if (_name) {
+        *_name = name;
+    }
+
+    return ret;
+}
+
 static struct sss_domain_info * match_any_domain_or_subdomain_name(
                                                 struct sss_domain_info *dom,
                                                 const char *dmatch)
diff --git a/src/util/util.h b/src/util/util.h
index c74ff5b56fdcb362386e4bb01bd293d7e3bf42a1..651ce5fdc8c34c005224128350e7a4ad0c935639 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -279,6 +279,10 @@ int sss_parse_name(TALLOC_CTX *memctx,
                    struct sss_names_ctx *snctx,
                    const char *orig, char **_domain, char **_name);
 
+int sss_parse_name_const(TALLOC_CTX *memctx,
+                         struct sss_names_ctx *snctx, const char *orig,
+                         const char **_domain, const char **_name);
+
 int sss_parse_name_for_domains(TALLOC_CTX *memctx,
                                struct sss_domain_info *domains,
                                const char *default_domain,
-- 
1.8.5.3

-------------- next part --------------
>From d246c5301184559af43d7d7f3d3e0a61b9157ab2 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn at redhat.com>
Date: Mon, 2 Dec 2013 13:03:33 +0100
Subject: [PATCH 2/3] NSS: Refactor expand_homedir_template

Function expand_homedir_template had lot of parameters.
After adding new expand option, all function call should be rewritten,
(usually argument NULL will be added)

This patch wraps all necessary arguments to structure.
---
 src/providers/ipa/ipa_s2n_exop.c      | 17 +++++++++-----
 src/providers/ipa/ipa_subdomains_id.c | 27 ++++++++++++++--------
 src/responder/nss/nsssrv_cmd.c        | 35 +++++++++++++++++++----------
 src/responder/pac/pacsrv_utils.c      | 14 ++++++++++--
 src/util/sss_nss.c                    | 42 ++++++++++++++++++++---------------
 src/util/sss_nss.h                    | 12 +++++++---
 6 files changed, 98 insertions(+), 49 deletions(-)

diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
index 59a99061ac3ad6f24a8af50e9c1d574282301a1d..02e87f86b75f4b5603b8be2e11e25c0a9fcdec7c 100644
--- a/src/providers/ipa/ipa_s2n_exop.c
+++ b/src/providers/ipa/ipa_s2n_exop.c
@@ -648,6 +648,7 @@ static void ipa_s2n_get_user_done(struct tevent_req *subreq)
     struct resp_attrs *simple_attrs = NULL;
     time_t now;
     uint64_t timeout = 10*60*60; /* FIXME: find a better timeout ! */
+    struct sss_nss_homedir_ctx *homedir_ctx;
     const char *homedir = NULL;
     struct sysdb_attrs *user_attrs = NULL;
     struct sysdb_attrs *group_attrs = NULL;
@@ -738,13 +739,19 @@ static void ipa_s2n_get_user_done(struct tevent_req *subreq)
     switch (attrs->response_type) {
         case RESP_USER:
             if (state->dom->subdomain_homedir) {
+                homedir_ctx = talloc_zero(state, struct sss_nss_homedir_ctx);
+                if (! homedir_ctx) {
+                    ret = ENOMEM;
+                    goto done;
+                }
+                homedir_ctx->username = attrs->a.user.pw_name;
+                homedir_ctx->uid = attrs->a.user.pw_uid;
+                homedir_ctx->domain = state->dom->name;
+                homedir_ctx->flatname = state->dom->flat_name;
+
                 homedir =  expand_homedir_template(state,
                                                    state->dom->subdomain_homedir,
-                                                   attrs->a.user.pw_name,
-                                                   attrs->a.user.pw_uid,
-                                                   NULL,
-                                                   state->dom->name,
-                                                   state->dom->flat_name);
+                                                   homedir_ctx);
                 if (homedir == NULL) {
                     ret = ENOMEM;
                     goto done;
diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c
index bef96e6582ab2eb26ebd048d007d4d6faeca12b0..1255fccdbb6b67ea15cd7e49ff8b45094694b293 100644
--- a/src/providers/ipa/ipa_subdomains_id.c
+++ b/src/providers/ipa/ipa_subdomains_id.c
@@ -366,10 +366,10 @@ get_subdomain_homedir_of_user(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom,
                               const char **_homedir)
 {
     errno_t ret;
-    char *name;
-    char *lc_name;
+    const char *name;
     const char *homedir;
     TALLOC_CTX *tmp_ctx;
+    struct sss_nss_homedir_ctx *homedir_ctx;
 
     tmp_ctx = talloc_new(mem_ctx);
     if (tmp_ctx == NULL) {
@@ -377,22 +377,31 @@ get_subdomain_homedir_of_user(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom,
         goto done;
     }
 
-    ret = sss_parse_name(tmp_ctx, dom->names, fqname, NULL, &name);
+    homedir_ctx = talloc_zero(tmp_ctx, struct sss_nss_homedir_ctx);
+    if (! homedir_ctx) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    homedir_ctx->uid = uid;
+    homedir_ctx->domain = dom->name;
+    homedir_ctx->flatname = dom->flat_name;
+    ret = sss_parse_name_const(tmp_ctx, dom->names, fqname,
+                               NULL, &name);
     if (ret != EOK) {
         goto done;
     }
 
     /* To be compatible with the old winbind based user lookups and IPA
      * clients the user name in the home directory path will be lower-case. */
-    lc_name = sss_tc_utf8_str_tolower(tmp_ctx, name);
-    if (lc_name == NULL) {
-        ret =ENOMEM;
+    homedir_ctx->username = sss_tc_utf8_str_tolower(tmp_ctx, name);
+    if (! homedir_ctx->username) {
+        ret = ENOMEM;
         goto done;
     }
 
-    homedir = expand_homedir_template(tmp_ctx, dom->subdomain_homedir, lc_name,
-                                      uid, NULL, dom->name, dom->flat_name);
-
+    homedir = expand_homedir_template(tmp_ctx, dom->subdomain_homedir,
+                                      homedir_ctx);
     if (homedir == NULL) {
         DEBUG(SSSDBG_OP_FAILURE, "expand_homedir_template failed\n");
         ret = ENOMEM;
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index e91093561979e164f01ecdf18508e659031c777d..cb912d7c9adcabd68823bae6d516e6eaf138feab 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -172,18 +172,18 @@ static const char *get_homedir_override(TALLOC_CTX *mem_ctx,
                                         struct ldb_message *msg,
                                         struct nss_ctx *nctx,
                                         struct sss_domain_info *dom,
-                                        const char *orig_name,
-                                        uint32_t uid)
+                                        struct sss_nss_homedir_ctx *homedir_ctx)
 {
     const char *homedir;
-    char *name;
-    char *domname;
+    const char *orig_name = homedir_ctx->username;
     errno_t ret;
 
     homedir = ldb_msg_find_attr_as_string(msg, SYSDB_HOMEDIR, NULL);
+    homedir_ctx->original = homedir;
 
     /* Subdomain users store FQDN in their name attribute */
-    ret = sss_parse_name(mem_ctx, dom->names, orig_name, &domname, &name);
+    ret = sss_parse_name_const(mem_ctx, dom->names, orig_name,
+                               NULL, &homedir_ctx->username);
     if (ret != EOK) {
         DEBUG(SSSDBG_MINOR_FAILURE, "Could not parse [%s] into "
               "name-value components.\n", orig_name);
@@ -195,10 +195,10 @@ static const char *get_homedir_override(TALLOC_CTX *mem_ctx,
      */
     if (dom->override_homedir) {
         return expand_homedir_template(mem_ctx, dom->override_homedir,
-                                       name, uid, homedir, dom->name, NULL);
+                                       homedir_ctx);
     } else if (nctx->override_homedir) {
         return expand_homedir_template(mem_ctx, nctx->override_homedir,
-                                       name, uid, homedir, dom->name, NULL);
+                                       homedir_ctx);
     }
 
     if (!homedir || *homedir == '\0') {
@@ -207,12 +207,10 @@ static const char *get_homedir_override(TALLOC_CTX *mem_ctx,
          */
         if (dom->fallback_homedir) {
             return expand_homedir_template(mem_ctx, dom->fallback_homedir,
-                                           name, uid, homedir,
-                                           dom->name, NULL);
+                                           homedir_ctx);
         } else if (nctx->fallback_homedir) {
             return expand_homedir_template(mem_ctx, nctx->fallback_homedir,
-                                           name, uid, homedir,
-                                           dom->name, NULL);
+                                           homedir_ctx);
         }
     }
 
@@ -318,6 +316,7 @@ static int fill_pwent(struct sss_packet *packet,
     bool packet_initialized = false;
     int ncret;
     TALLOC_CTX *tmp_ctx = NULL;
+    struct sss_nss_homedir_ctx *homedir_ctx;
 
     to_sized_string(&pwfield, nctx->pwfield);
 
@@ -373,7 +372,19 @@ static int fill_pwent(struct sss_packet *packet,
         } else {
             to_sized_string(&gecos, tmpstr);
         }
-        tmpstr = get_homedir_override(tmp_ctx, msg, nctx, dom, name.str, uid);
+
+        homedir_ctx = talloc_zero(tmp_ctx, struct sss_nss_homedir_ctx);
+        if (! homedir_ctx) {
+            num = 0;
+            ret = ENOMEM;
+            goto done;
+        }
+
+        homedir_ctx->username = name.str;
+        homedir_ctx->uid = uid;
+        homedir_ctx->domain = dom->name;
+
+        tmpstr = get_homedir_override(tmp_ctx, msg, nctx, dom, homedir_ctx);
         if (!tmpstr) {
             to_sized_string(&homedir, "/");
         } else {
diff --git a/src/responder/pac/pacsrv_utils.c b/src/responder/pac/pacsrv_utils.c
index 035fe84c0f39aaa40a403a8ac5f19527b2191267..ba4f6987454ef57211385713c98a519fe690c6ef 100644
--- a/src/responder/pac/pacsrv_utils.c
+++ b/src/responder/pac/pacsrv_utils.c
@@ -353,6 +353,7 @@ errno_t get_pwd_from_pac(TALLOC_CTX *mem_ctx,
     char *upn;
     hash_key_t key;
     hash_value_t value;
+    struct sss_nss_homedir_ctx *homedir_ctx;
 
     pwd = talloc_zero(mem_ctx, struct passwd);
     if (pwd == NULL) {
@@ -439,9 +440,18 @@ errno_t get_pwd_from_pac(TALLOC_CTX *mem_ctx,
     /* Check if there is a special homedir template for sub-domains. If not a
      * fallback will be added by the NSS responder. */
     if (IS_SUBDOMAIN(dom) && dom->subdomain_homedir) {
+        homedir_ctx = talloc_zero(pwd, struct sss_nss_homedir_ctx);
+        if (! homedir_ctx) {
+            ret = ENOMEM;
+            goto done;
+        }
+        homedir_ctx->username = lname;
+        homedir_ctx->uid = pwd->pw_uid;
+        homedir_ctx->domain = dom->name;
+        homedir_ctx->flatname = dom->flat_name;
+
         pwd->pw_dir = expand_homedir_template(pwd, dom->subdomain_homedir,
-                                              lname, pwd->pw_uid, NULL,
-                                              dom->name, dom->flat_name);
+                                              homedir_ctx);
         if (pwd->pw_dir == NULL) {
             ret = ENOMEM;
             goto done;
diff --git a/src/util/sss_nss.c b/src/util/sss_nss.c
index 406c95cd0f76c9e73705bc49b4261160d26bfc58..c5e964c03d4c6cd56a8458d14cb25d5c49c0dd0b 100644
--- a/src/util/sss_nss.c
+++ b/src/util/sss_nss.c
@@ -23,9 +23,7 @@
 #include "util/sss_nss.h"
 
 char *expand_homedir_template(TALLOC_CTX *mem_ctx, const char *template,
-                              const char *username, uint32_t uid,
-                              const char *original, const char *domain,
-                              const char *flatname)
+                              struct sss_nss_homedir_ctx *homedir_ctx)
 {
     char *copy;
     char *p;
@@ -40,6 +38,11 @@ char *expand_homedir_template(TALLOC_CTX *mem_ctx, const char *template,
         return NULL;
     }
 
+    if (! homedir_ctx) {
+        DEBUG(SSSDBG_CRIT_FAILURE, ("Missing home directory data.\n"));
+        return NULL;
+    }
+
     tmp_ctx = talloc_new(NULL);
     if (!tmp_ctx) return NULL;
 
@@ -66,67 +69,70 @@ char *expand_homedir_template(TALLOC_CTX *mem_ctx, const char *template,
         }
         switch( *n ) {
             case 'u':
-                if (username == NULL) {
-                    DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand user name template "
-                                                "because user name is empty.\n");
+                if (! homedir_ctx->username) {
+                    DEBUG(SSSDBG_CRIT_FAILURE,
+                          "Cannot expand user name template because user name "
+                          "is empty.\n");
                     goto done;
                 }
                 result = talloc_asprintf_append(result, "%s%s", p,
-                                                username);
+                                                homedir_ctx->username);
                 break;
 
             case 'U':
-                if (uid == 0) {
+                if (homedir_ctx->uid == 0) {
                     DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand uid template "
                                                 "because uid is invalid.\n");
                     goto done;
                 }
                 result = talloc_asprintf_append(result, "%s%d", p,
-                                                uid);
+                                                homedir_ctx->uid);
                 break;
 
             case 'd':
-                if (domain == NULL) {
+                if (! homedir_ctx->domain) {
                     DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand domain name "
                                                 "template because domain name "
                                                 "is empty.\n");
                     goto done;
                 }
                 result = talloc_asprintf_append(result, "%s%s", p,
-                                                domain);
+                                                homedir_ctx->domain);
                 break;
 
             case 'f':
-                if (domain == NULL || username == NULL) {
+                if (! homedir_ctx->domain || ! homedir_ctx->username) {
                     DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand fully qualified "
                                                 "name template because domain "
                                                 "or user name is empty.\n");
                     goto done;
                 }
                 result = talloc_asprintf_append(result, "%s%s@%s", p,
-                                                username, domain);
+                                                homedir_ctx->username,
+                                                homedir_ctx->domain);
                 break;
 
             case 'o':
-                if (original == NULL) {
+                if (! homedir_ctx->original) {
                     DEBUG(SSSDBG_CRIT_FAILURE,
                           "Original home directory for %s is not available, "
-                           "using empty string\n", username);
+                           "using empty string\n", homedir_ctx->username);
                     orig = "";
                 } else {
-                    orig = original;
+                    orig = homedir_ctx->original;
                 }
                 result = talloc_asprintf_append(result, "%s%s", p, orig);
                 break;
 
             case 'F':
-                if (flatname == NULL) {
+                if (! homedir_ctx->flatname) {
                     DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand domain name "
                                                 "template because domain flat "
                                                 "name is empty.\n");
                     goto done;
                 }
-                result = talloc_asprintf_append(result, "%s%s", p, flatname);
+                result = talloc_asprintf_append(result, "%s%s", p,
+                                                homedir_ctx->flatname);
                 break;
 
             case '%':
diff --git a/src/util/sss_nss.h b/src/util/sss_nss.h
index 6dcdbaef376ffb6cc45733ce6af8aeceaabe05bb..771b9ce58db858f8cef8cac6ae3bf9fb382ef0d0 100644
--- a/src/util/sss_nss.h
+++ b/src/util/sss_nss.h
@@ -25,8 +25,14 @@
 #include <sys/types.h>
 #include <talloc.h>
 
+struct sss_nss_homedir_ctx {
+    const char *username;
+    uint32_t uid;
+    const char *original;
+    const char *domain;
+    const char *flatname;
+};
+
 char *expand_homedir_template(TALLOC_CTX *mem_ctx, const char *template,
-                              const char *username, uint32_t uid,
-                              const char *original, const char *domain,
-                              const char *flatname);
+                              struct sss_nss_homedir_ctx *homedir_ctx);
 #endif
-- 
1.8.5.3

-------------- next part --------------
>From c52ce81272c0027109bbb4e75bed0c5371053182 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn at redhat.com>
Date: Mon, 2 Dec 2013 14:19:09 +0100
Subject: [PATCH 3/3] NSS: Add option to expand homedir template format

LDAP server can contain template for home directory instead of plain string.
This patch adds new expand option "%H", which will be replaced with value
from configuration option homedir_substring (from sssd.conf)

Resolves:
https://fedorahosted.org/sssd/ticket/1853
---
 src/confdb/confdb.c                   | 10 ++++++++++
 src/confdb/confdb.h                   |  3 +++
 src/config/SSSDConfigTest.py          |  2 ++
 src/config/etc/sssd.api.conf          |  2 ++
 src/man/include/homedir_substring.xml | 17 +++++++++++++++++
 src/man/include/override_homedir.xml  |  7 +++++++
 src/man/sssd-ad.5.xml                 |  1 +
 src/man/sssd.conf.5.xml               |  1 +
 src/providers/ipa/ipa_s2n_exop.c      |  1 +
 src/providers/ipa/ipa_subdomains_id.c |  1 +
 src/responder/nss/nsssrv.c            |  6 ++++++
 src/responder/nss/nsssrv.h            |  1 +
 src/responder/nss/nsssrv_cmd.c        | 11 +++++++++--
 src/util/sss_nss.c                    | 11 +++++++++++
 src/util/sss_nss.h                    |  1 +
 15 files changed, 73 insertions(+), 2 deletions(-)
 create mode 100644 src/man/include/homedir_substring.xml

diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index 9a13f723de601413205cbb580a92791015b94aa1..1da285df1aff0412f70a66370a5b50e483d719e5 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -1118,6 +1118,16 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
     }
 
     tmp = ldb_msg_find_attr_as_string(res->msgs[0],
+                                      CONFDB_NSS_HOMEDIR_SUBSTRING, NULL);
+    if (tmp) {
+        domain->homedir_substr = talloc_strdup(domain, tmp);
+        if (! domain->homedir_substr) {
+            ret = ENOMEM;
+            goto done;
+        }
+    }
+
+    tmp = ldb_msg_find_attr_as_string(res->msgs[0],
                                       CONFDB_NSS_OVERRIDE_SHELL, NULL);
     if (tmp != NULL) {
         domain->override_shell = talloc_strdup(domain, tmp);
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index 11a9252126089d2ac6edb4a1da92bcd545a9635c..49abcfa17695c6b64681da2400e35ee927604364 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -97,6 +97,8 @@
 #define CONFDB_NSS_SHELL_FALLBACK "shell_fallback"
 #define CONFDB_NSS_DEFAULT_SHELL "default_shell"
 #define CONFDB_MEMCACHE_TIMEOUT "memcache_timeout"
+#define CONFDB_NSS_HOMEDIR_SUBSTRING "homedir_substring"
+#define CONFDB_DEFAULT_HOMEDIR_SUBSTRING "/home"
 
 /* PAM */
 #define CONFDB_PAM_CONF_ENTRY "config/pam"
@@ -216,6 +218,7 @@ struct sss_domain_info {
     const char *override_homedir;
     const char *fallback_homedir;
     const char *subdomain_homedir;
+    const char *homedir_substr;
     const char *override_shell;
     const char *default_shell;
 
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
index bfec8d058f6df2dc636eb0873b0e33495f40be7b..5eb900b1aba32ada9115db175d75cddf2760f7e0 100755
--- a/src/config/SSSDConfigTest.py
+++ b/src/config/SSSDConfigTest.py
@@ -522,6 +522,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
             'case_sensitive',
             'override_homedir',
             'fallback_homedir',
+            'homedir_substring',
             'override_shell',
             'default_shell',
             'pwd_expiration_warning',
@@ -879,6 +880,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
             'case_sensitive',
             'override_homedir',
             'fallback_homedir',
+            'homedir_substring',
             'override_shell',
             'default_shell',
             'pwd_expiration_warning',
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
index 14e80639e8b26884c2ebe3affee29cd1bc4e8037..b76aba572b9920c0715f8e9d7a8578bd26760be1 100644
--- a/src/config/etc/sssd.api.conf
+++ b/src/config/etc/sssd.api.conf
@@ -36,6 +36,7 @@ filter_users_in_groups = bool, None, false
 pwfield = str, None, false
 override_homedir = str, None, false
 fallback_homedir = str, None, false
+homedir_substring = str, None, false, /home
 override_shell = str, None, false
 allowed_shells = list, str, false
 vetoed_shells = list, str, false
@@ -113,6 +114,7 @@ override_gid = int, None, false
 case_sensitive = bool, None, false
 override_homedir = str, None, false
 fallback_homedir = str, None, false
+homedir_substring = str, None, false
 override_shell = str, None, false
 default_shell = str, None, false
 description = str, None, false
diff --git a/src/man/include/homedir_substring.xml b/src/man/include/homedir_substring.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d138c473e186f64a87e09ea09e9684091e571f3c
--- /dev/null
+++ b/src/man/include/homedir_substring.xml
@@ -0,0 +1,17 @@
+<varlistentry>
+    <term>homedir_substring (string)</term>
+    <listitem>
+        <para>
+            Value of this option will be used in the expansion of
+            <emphasis>override_homedir</emphasis> option if template contains
+            format string <emphasis>%H</emphasis>. LDAP directory can directly
+            contain template and this option can be used to expand home
+            directory for each machine (or Operating system).
+            It can be set in the [nss] section or per-domain.
+            The value from domain section has higher priority.
+        </para>
+        <para>
+            Default: /home
+        </para>
+    </listitem>
+</varlistentry>
diff --git a/src/man/include/override_homedir.xml b/src/man/include/override_homedir.xml
index 773d0b6616858ab5c0139033255bc60076857651..552d7eb9d3c8c4ec01cface4e062723ef9c29e1f 100644
--- a/src/man/include/override_homedir.xml
+++ b/src/man/include/override_homedir.xml
@@ -31,6 +31,13 @@
                     </para></listitem>
             </varlistentry>
             <varlistentry>
+                <term>%H</term>
+                <listitem><para>
+                    The value of configure option
+                    <emphasis>homedir_substring</emphasis>.
+                    </para></listitem>
+            </varlistentry>
+            <varlistentry>
                 <term>%%</term>
                 <listitem><para>a literal '%'</para>
                 </listitem>
diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml
index 1e38c13a95fcbcc242f3e9e8c9eda6e23e7a67c7..36acc5da14327f4137e7561a01eed4cad2ee1ac6 100644
--- a/src/man/sssd-ad.5.xml
+++ b/src/man/sssd-ad.5.xml
@@ -349,6 +349,7 @@ FOREST:EXAMPLE.COM:(memberOf=cn=admins,ou=groups,dc=example,dc=com)
                 </varlistentry>
 
                 <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="include/override_homedir.xml" />
+                <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="include/homedir_substring.xml" />
 
                 <varlistentry>
                     <term>krb5_use_enterprise_principal (boolean)</term>
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index 4c5337606418f440f7b0e1523cfb48f8bebad431..1b96f31e94b77e0c9e984b0c6613ab056c00fef1 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -512,6 +512,7 @@
                     </listitem>
                 </varlistentry>
                 <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="include/override_homedir.xml" />
+                <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="include/homedir_substring.xml" />
                 <varlistentry>
                     <term>fallback_homedir (string)</term>
                     <listitem>
diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
index 02e87f86b75f4b5603b8be2e11e25c0a9fcdec7c..5b1d0d87640de0cf7c2319c863e5df3b5dbaaa84 100644
--- a/src/providers/ipa/ipa_s2n_exop.c
+++ b/src/providers/ipa/ipa_s2n_exop.c
@@ -748,6 +748,7 @@ static void ipa_s2n_get_user_done(struct tevent_req *subreq)
                 homedir_ctx->uid = attrs->a.user.pw_uid;
                 homedir_ctx->domain = state->dom->name;
                 homedir_ctx->flatname = state->dom->flat_name;
+                homedir_ctx->config_homedir_substr = state->dom->homedir_substr;
 
                 homedir =  expand_homedir_template(state,
                                                    state->dom->subdomain_homedir,
diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c
index 1255fccdbb6b67ea15cd7e49ff8b45094694b293..c6018807075960046c7b33eef089ed7e8bfcbee2 100644
--- a/src/providers/ipa/ipa_subdomains_id.c
+++ b/src/providers/ipa/ipa_subdomains_id.c
@@ -386,6 +386,7 @@ get_subdomain_homedir_of_user(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom,
     homedir_ctx->uid = uid;
     homedir_ctx->domain = dom->name;
     homedir_ctx->flatname = dom->flat_name;
+    homedir_ctx->config_homedir_substr = dom->homedir_substr;
     ret = sss_parse_name_const(tmp_ctx, dom->names, fqname,
                                NULL, &name);
     if (ret != EOK) {
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index a385f2943e68022c0cc2fe8022000e9d8e8854d4..46fa57c3b6c40adaa20cd5fd4e142c2829ceaca1 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -303,6 +303,12 @@ static int nss_get_config(struct nss_ctx *nctx,
                             &nctx->default_shell);
     if (ret != EOK) goto done;
 
+    ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
+                            CONFDB_NSS_HOMEDIR_SUBSTRING,
+                            CONFDB_DEFAULT_HOMEDIR_SUBSTRING,
+                            &nctx->homedir_substr);
+    if (ret != EOK) goto done;
+
     ret = 0;
 done:
     return ret;
diff --git a/src/responder/nss/nsssrv.h b/src/responder/nss/nsssrv.h
index a36589837529a7b61768845eb3493197b13df8cd..a5b946b7e4a38d7d8b35ec5df1b6644d01896470 100644
--- a/src/responder/nss/nsssrv.h
+++ b/src/responder/nss/nsssrv.h
@@ -62,6 +62,7 @@ struct nss_ctx {
 
     char *override_homedir;
     char *fallback_homedir;
+    char *homedir_substr;
     char **allowed_shells;
     char *override_shell;
     char **vetoed_shells;
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index cb912d7c9adcabd68823bae6d516e6eaf138feab..ef7e0e411d6fb8cfe9fb8d053af3e61b16de1d65 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -190,6 +190,13 @@ static const char *get_homedir_override(TALLOC_CTX *mem_ctx,
         return NULL;
     }
 
+    /* Check to see which homedir_prefix to use. */
+    if (dom->homedir_substr) {
+        homedir_ctx->config_homedir_substr = dom->homedir_substr;
+    } else if (nctx->homedir_substr) {
+        homedir_ctx->config_homedir_substr = nctx->homedir_substr;
+    }
+
     /* Check whether we are unconditionally overriding the server
      * for home directory locations.
      */
@@ -214,8 +221,8 @@ static const char *get_homedir_override(TALLOC_CTX *mem_ctx,
         }
     }
 
-    /* Return the value we got from the provider */
-    return talloc_strdup(mem_ctx, homedir);
+    /* Provider can also return template, try to expand it.*/
+    return expand_homedir_template(mem_ctx, homedir, homedir_ctx);
 }
 
 static const char *get_shell_override(TALLOC_CTX *mem_ctx,
diff --git a/src/util/sss_nss.c b/src/util/sss_nss.c
index c5e964c03d4c6cd56a8458d14cb25d5c49c0dd0b..5495d6870f9a5321096c9b0515f9ad261f4d6cf5 100644
--- a/src/util/sss_nss.c
+++ b/src/util/sss_nss.c
@@ -135,6 +135,17 @@ char *expand_homedir_template(TALLOC_CTX *mem_ctx, const char *template,
                                                 homedir_ctx->flatname);
                 break;
 
+            case 'H':
+                if (! homedir_ctx->config_homedir_substr) {
+                    DEBUG(SSSDBG_CRIT_FAILURE,
+                          ("Cannot expand home directory substring template "
+                           "substring is empty.\n"));
+                    goto done;
+                }
+                result = talloc_asprintf_append(result, "%s%s", p,
+                                           homedir_ctx->config_homedir_substr);
+                break;
+
             case '%':
                 result = talloc_asprintf_append(result, "%s%%", p);
                 break;
diff --git a/src/util/sss_nss.h b/src/util/sss_nss.h
index 771b9ce58db858f8cef8cac6ae3bf9fb382ef0d0..19bf26589a9a5d76369f56ef9ecf7bedbb29e07b 100644
--- a/src/util/sss_nss.h
+++ b/src/util/sss_nss.h
@@ -31,6 +31,7 @@ struct sss_nss_homedir_ctx {
     const char *original;
     const char *domain;
     const char *flatname;
+    const char *config_homedir_substr;
 };
 
 char *expand_homedir_template(TALLOC_CTX *mem_ctx, const char *template,
-- 
1.8.5.3



More information about the sssd-devel mailing list