>From d246c5301184559af43d7d7f3d3e0a61b9157ab2 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik 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 #include +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