dpward / rpms / sssd

Forked from rpms/sssd 3 years ago
Clone

Blame SOURCES/0078-AD-support-for-subdomain_homedir.patch

2fc102
From 0b813ab764fd0b255e342765b79533e1869cd06e Mon Sep 17 00:00:00 2001
2fc102
From: Pavel Reichl <preichl@redhat.com>
2fc102
Date: Wed, 22 Jan 2014 16:47:22 +0000
2fc102
Subject: [PATCH 78/80] AD: support for subdomain_homedir
2fc102
2fc102
Homedir is defaultly set accordingly to subdomain_homedir for users from AD.
2fc102
2fc102
Resolves:
2fc102
https://fedorahosted.org/sssd/ticket/2169
2fc102
2fc102
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
2fc102
---
2fc102
 src/providers/ipa/ipa_subdomains_id.c | 190 ++++++++++++++++++++++++++++++++++
2fc102
 1 file changed, 190 insertions(+)
2fc102
2fc102
diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c
2fc102
index c29a2a3047af105966b636422105abd15e8a3992..fb1ad896885866dd9c34f9db960e09d92763f86d 100644
2fc102
--- a/src/providers/ipa/ipa_subdomains_id.c
2fc102
+++ b/src/providers/ipa/ipa_subdomains_id.c
2fc102
@@ -25,6 +25,7 @@
2fc102
 #include <errno.h>
2fc102
 
2fc102
 #include "util/util.h"
2fc102
+#include "util/sss_nss.h"
2fc102
 #include "util/strtonum.h"
2fc102
 #include "db/sysdb.h"
2fc102
 #include "providers/ldap/ldap_common.h"
2fc102
@@ -350,6 +351,185 @@ ipa_get_ad_id_ctx(struct ipa_id_ctx *ipa_ctx,
2fc102
     return (iter) ? iter->ad_id_ctx : NULL;
2fc102
 }
2fc102
 
2fc102
+static errno_t
2fc102
+get_subdomain_homedir_of_user(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom,
2fc102
+                              const char *fqname, uint32_t uid,
2fc102
+                              const char **_homedir)
2fc102
+{
2fc102
+    errno_t ret;
2fc102
+    char *name;
2fc102
+    const char *homedir;
2fc102
+    TALLOC_CTX *tmp_ctx;
2fc102
+
2fc102
+    tmp_ctx = talloc_new(mem_ctx);
2fc102
+    if (tmp_ctx == NULL) {
2fc102
+        ret = ENOMEM;
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    ret = sss_parse_name(tmp_ctx, dom->names, fqname, NULL, &name);
2fc102
+    if (ret != EOK) {
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    homedir = expand_homedir_template(tmp_ctx, dom->subdomain_homedir, name,
2fc102
+                                      uid, NULL, dom->name, dom->flat_name);
2fc102
+
2fc102
+    if (homedir == NULL) {
2fc102
+        DEBUG(SSSDBG_OP_FAILURE, ("expand_homedir_template failed\n"));
2fc102
+        ret = ENOMEM;
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    if (_homedir == NULL) {
2fc102
+        ret = EINVAL;
2fc102
+        goto done;
2fc102
+    }
2fc102
+    *_homedir = talloc_steal(mem_ctx, homedir);
2fc102
+
2fc102
+done:
2fc102
+    talloc_free(tmp_ctx);
2fc102
+    return ret;
2fc102
+}
2fc102
+
2fc102
+static errno_t
2fc102
+store_homedir_of_user(struct sss_domain_info *domain,
2fc102
+                      const char *fqname, const char *homedir)
2fc102
+{
2fc102
+    errno_t ret;
2fc102
+    errno_t sret;
2fc102
+    TALLOC_CTX *tmp_ctx;
2fc102
+    bool in_transaction = false;
2fc102
+    struct sysdb_attrs *attrs;
2fc102
+    struct sysdb_ctx *sysdb = domain->sysdb;
2fc102
+
2fc102
+    tmp_ctx = talloc_new(NULL);
2fc102
+    if (tmp_ctx == NULL) {
2fc102
+        ret = ENOMEM;
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    attrs = sysdb_new_attrs(tmp_ctx);
2fc102
+    if (attrs == NULL) {
2fc102
+        ret = ENOMEM;
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    ret = sysdb_attrs_add_string(attrs, SYSDB_HOMEDIR, homedir);
2fc102
+    if (ret != EOK) {
2fc102
+        DEBUG(SSSDBG_MINOR_FAILURE, ("Error setting homedir: [%s]\n",
2fc102
+                                     strerror(ret)));
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    ret = sysdb_transaction_start(sysdb);
2fc102
+    if (ret != EOK) {
2fc102
+        DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to start transaction\n"));
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    in_transaction = true;
2fc102
+
2fc102
+    ret = sysdb_set_user_attr(sysdb, domain, fqname, attrs, SYSDB_MOD_REP);
2fc102
+    if (ret != EOK) {
2fc102
+        DEBUG(SSSDBG_CRIT_FAILURE,
2fc102
+              ("Failed to update homedir information!\n"));
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    ret = sysdb_transaction_commit(sysdb);
2fc102
+    if (ret != EOK) {
2fc102
+        DEBUG(SSSDBG_CRIT_FAILURE,
2fc102
+              ("Cannot commit sysdb transaction [%d]: %s.\n",
2fc102
+               ret, strerror(ret)));
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    in_transaction = false;
2fc102
+
2fc102
+done:
2fc102
+    if (in_transaction) {
2fc102
+        sret = sysdb_transaction_cancel(sysdb);
2fc102
+        if (sret != EOK) {
2fc102
+            DEBUG(SSSDBG_CRIT_FAILURE, ("Could not cancel transaction.\n"));
2fc102
+        }
2fc102
+    }
2fc102
+    talloc_free(tmp_ctx);
2fc102
+    return ret;
2fc102
+}
2fc102
+
2fc102
+static errno_t
2fc102
+apply_subdomain_homedir(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom,
2fc102
+                        int filter_type, const char *filter_value)
2fc102
+{
2fc102
+    errno_t ret;
2fc102
+    uint32_t uid;
2fc102
+    const char *fqname;
2fc102
+    const char *homedir = NULL;
2fc102
+    struct ldb_result *res;
2fc102
+
2fc102
+    if (filter_type == BE_FILTER_NAME) {
2fc102
+        ret = sysdb_getpwnam(mem_ctx, dom->sysdb, dom, filter_value, &res;;
2fc102
+    } else if (filter_type == BE_FILTER_IDNUM) {
2fc102
+        errno = 0;
2fc102
+        uid = strtouint32(filter_value, NULL, 10);
2fc102
+        if (errno != 0) {
2fc102
+            ret = errno;
2fc102
+            goto done;
2fc102
+        }
2fc102
+        ret = sysdb_getpwuid(mem_ctx, dom->sysdb, dom, uid, &res;;
2fc102
+    } else {
2fc102
+        DEBUG(SSSDBG_OP_FAILURE,
2fc102
+              ("Unsupported filter type: [%d].\n", filter_type));
2fc102
+        ret = EINVAL;
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    if (ret != EOK) {
2fc102
+        DEBUG(SSSDBG_OP_FAILURE,
2fc102
+              ("Failed to make request to our cache: [%d]: [%s]\n",
2fc102
+               ret, sss_strerror(ret)));
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    if (res->count == 0) {
2fc102
+        ret = ENOENT;
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    /*
2fc102
+     * Homedir is always overriden by subdomain_homedir even if it was
2fc102
+     * explicitly set by user.
2fc102
+     */
2fc102
+    fqname = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL);
2fc102
+    uid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_UIDNUM, 0);
2fc102
+    if (uid == 0) {
2fc102
+        DEBUG(SSSDBG_OP_FAILURE, ("UID for user [%s] is not known.\n",
2fc102
+                                  filter_value));
2fc102
+        ret = ENOENT;
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    ret = get_subdomain_homedir_of_user(mem_ctx, dom, fqname, uid, &homedir);
2fc102
+    if (ret != EOK) {
2fc102
+        DEBUG(SSSDBG_OP_FAILURE,
2fc102
+              ("get_subdomain_homedir_of_user failed: [%d]: [%s]\n",
2fc102
+               ret, sss_strerror(ret)));
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+    ret = store_homedir_of_user(dom, fqname, homedir);
2fc102
+    if (ret != EOK) {
2fc102
+        DEBUG(SSSDBG_OP_FAILURE,
2fc102
+              ("store_homedir_of_user failed: [%d]: [%s]\n",
2fc102
+               ret, sss_strerror(ret)));
2fc102
+        goto done;
2fc102
+    }
2fc102
+
2fc102
+done:
2fc102
+    return ret;
2fc102
+}
2fc102
+
2fc102
 static void
2fc102
 ipa_get_ad_acct_ad_part_done(struct tevent_req *subreq)
2fc102
 {
2fc102
@@ -367,6 +547,16 @@ ipa_get_ad_acct_ad_part_done(struct tevent_req *subreq)
2fc102
         return;
2fc102
     }
2fc102
 
2fc102
+    ret = apply_subdomain_homedir(state, state->user_dom,
2fc102
+                                  state->ar->filter_type,
2fc102
+                                  state->ar->filter_value);
2fc102
+    if (ret != EOK) {
2fc102
+        DEBUG(SSSDBG_OP_FAILURE,
2fc102
+              ("apply_subdomain_homedir failed: [%d]: [%s].\n",
2fc102
+               ret, sss_strerror(ret)));
2fc102
+        goto fail;
2fc102
+    }
2fc102
+
2fc102
     if ((state->ar->entry_type & BE_REQ_TYPE_MASK) != BE_REQ_INITGROUPS) {
2fc102
         tevent_req_done(req);
2fc102
         return;
2fc102
-- 
2fc102
1.8.5.3
2fc102