summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2014-09-25 09:38:26 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-10-20 16:15:03 +0200
commit89b065cb85f57e80760ce4d4b1215b533e249e92 (patch)
tree18c10357e0d783bf99ce86501a95e904c5fa3cf2
parentd70023a7fa95c8c12683de965a76ec38a6234ae5 (diff)
downloadsssd-89b065cb85f57e80760ce4d4b1215b533e249e92.tar.gz
sssd-89b065cb85f57e80760ce4d4b1215b533e249e92.tar.xz
sssd-89b065cb85f57e80760ce4d4b1215b533e249e92.zip
sysdb: add sysdb_getpwnam/uid_with_views()
View-aware drop-in replacements for sysdb_getpwnam() and sysdb_getpwuid(). Reviewed-by: Pavel Březina <pbrezina@redhat.com>
-rw-r--r--src/db/sysdb.h24
-rw-r--r--src/db/sysdb_search.c134
-rw-r--r--src/db/sysdb_views.c128
3 files changed, 286 insertions, 0 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 8d4759e59..2db1a1c6a 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -201,6 +201,7 @@
SYSDB_SID_STR, \
SYSDB_UPN, \
SYSDB_OVERRIDE_DN, \
+ SYSDB_OVERRIDE_OBJECT_DN, \
SYSDB_DEFAULT_OVERRIDE_NAME, \
NULL}
@@ -210,6 +211,7 @@
SYSDB_DEFAULT_ATTRS, \
SYSDB_SID_STR, \
SYSDB_OVERRIDE_DN, \
+ SYSDB_OVERRIDE_OBJECT_DN, \
SYSDB_DEFAULT_OVERRIDE_NAME, \
NULL}
@@ -456,10 +458,32 @@ errno_t sysdb_search_group_override_by_name(TALLOC_CTX *mem_ctx,
struct ldb_result **override_obj,
struct ldb_result **orig_obj);
+errno_t sysdb_search_user_override_by_uid(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ uid_t uid,
+ struct ldb_result **override_obj,
+ struct ldb_result **orig_obj);
+
+errno_t sysdb_search_group_override_by_gid(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ gid_t gid,
+ struct ldb_result **override_obj,
+ struct ldb_result **orig_obj);
+
errno_t sysdb_add_overrides_to_object(struct sss_domain_info *domain,
struct ldb_message *obj,
struct ldb_message *override_obj);
+errno_t sysdb_getpwnam_with_views(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *name,
+ struct ldb_result **res);
+
+errno_t sysdb_getpwuid_with_views(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ uid_t uid,
+ struct ldb_result **res);
+
/* Sysdb initialization.
* call this function *only* once to initialize the database and get
* the sysdb ctx */
diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c
index d51d2134a..886071910 100644
--- a/src/db/sysdb_search.c
+++ b/src/db/sysdb_search.c
@@ -83,6 +83,73 @@ done:
return ret;
}
+errno_t sysdb_getpwnam_with_views(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *name,
+ struct ldb_result **res)
+{
+ int ret;
+ struct ldb_result *orig_obj = NULL;
+ struct ldb_result *override_obj = NULL;
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
+ return ENOMEM;
+ }
+
+ /* If there are views we first have to search the overrides for matches */
+ if (DOM_HAS_VIEWS(domain)) {
+ ret = sysdb_search_user_override_by_name(tmp_ctx, domain, name,
+ &override_obj, &orig_obj);
+ if (ret != EOK && ret != ENOENT) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sysdb_search_override_by_name failed.\n");
+ goto done;
+ }
+ }
+
+ /* If there are no views or nothing was found in the overrides the
+ * original objects are searched. */
+ if (orig_obj == NULL) {
+ ret = sysdb_getpwnam(tmp_ctx, domain, name, &orig_obj);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_getpwnam failed.\n");
+ goto done;
+ }
+ }
+
+ /* If there are views we have to check if override values must be added to
+ * the original object. */
+ if (DOM_HAS_VIEWS(domain) && orig_obj->count == 1) {
+ ret = sysdb_add_overrides_to_object(domain, orig_obj->msgs[0],
+ override_obj == NULL ? NULL : override_obj ->msgs[0]);
+ if (ret != EOK && ret != ENOENT) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n");
+ goto done;
+ }
+
+ if (ret == ENOENT) {
+ *res = talloc_zero(mem_ctx, struct ldb_result);
+ if (*res == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n");
+ ret = ENOMEM;
+ } else {
+ ret = EOK;
+ }
+ goto done;
+ }
+ }
+
+ *res = talloc_steal(mem_ctx, orig_obj);
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
int sysdb_getpwuid(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
uid_t uid,
@@ -121,6 +188,73 @@ done:
return ret;
}
+errno_t sysdb_getpwuid_with_views(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ uid_t uid,
+ struct ldb_result **res)
+{
+ int ret;
+ struct ldb_result *orig_obj = NULL;
+ struct ldb_result *override_obj = NULL;
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
+ return ENOMEM;
+ }
+
+ /* If there are views we first have to search the overrides for matches */
+ if (DOM_HAS_VIEWS(domain)) {
+ ret = sysdb_search_user_override_by_uid(tmp_ctx, domain, uid,
+ &override_obj, &orig_obj);
+ if (ret != EOK && ret != ENOENT) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sysdb_search_user_override_by_uid failed.\n");
+ goto done;
+ }
+ }
+
+ /* If there are no views or nothing was found in the overrides the
+ * original objects are searched. */
+ if (orig_obj == NULL) {
+ ret = sysdb_getpwuid(tmp_ctx, domain, uid, &orig_obj);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_getpwuid failed.\n");
+ goto done;
+ }
+ }
+
+ /* If there are views we have to check if override values must be added to
+ * the original object. */
+ if (DOM_HAS_VIEWS(domain) && orig_obj->count == 1) {
+ ret = sysdb_add_overrides_to_object(domain, orig_obj->msgs[0],
+ override_obj == NULL ? NULL : override_obj->msgs[0]);
+ if (ret != EOK && ret != ENOENT) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n");
+ goto done;
+ }
+
+ if (ret == ENOENT) {
+ *res = talloc_zero(mem_ctx, struct ldb_result);
+ if (*res == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n");
+ ret = ENOMEM;
+ } else {
+ ret = EOK;
+ }
+ goto done;
+ }
+ }
+
+ *res = talloc_steal(mem_ctx, orig_obj);
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
int sysdb_enumpwent(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
struct ldb_result **_res)
diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c
index 4bad81dae..86c231dad 100644
--- a/src/db/sysdb_views.c
+++ b/src/db/sysdb_views.c
@@ -648,7 +648,9 @@ done:
#define SYSDB_USER_NAME_OVERRIDE_FILTER "(&(objectClass="SYSDB_OVERRIDE_USER_CLASS")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))"
+#define SYSDB_USER_UID_OVERRIDE_FILTER "(&(objectClass="SYSDB_OVERRIDE_USER_CLASS")("SYSDB_UIDNUM"=%lu))"
#define SYSDB_GROUP_NAME_OVERRIDE_FILTER "(&(objectClass="SYSDB_OVERRIDE_GROUP_CLASS")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))"
+#define SYSDB_GROUP_GID_OVERRIDE_FILTER "(&(objectClass="SYSDB_OVERRIDE_GROUP_CLASS")("SYSDB_GIDNUM"=%lu))"
enum override_object_type {
OO_TYPE_UNDEF = 0,
@@ -802,6 +804,132 @@ errno_t sysdb_search_group_override_by_name(TALLOC_CTX *mem_ctx,
override_obj, orig_obj);
}
+static errno_t sysdb_search_override_by_id(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ unsigned long int id,
+ enum override_object_type type,
+ struct ldb_result **override_obj,
+ struct ldb_result **orig_obj)
+{
+ TALLOC_CTX *tmp_ctx;
+ static const char *user_attrs[] = SYSDB_PW_ATTRS;
+ static const char *group_attrs[] = SYSDB_GRSRC_ATTRS;
+ const char **attrs;
+ struct ldb_dn *base_dn;
+ struct ldb_result *override_res;
+ struct ldb_result *orig_res;
+ int ret;
+ const char *orig_obj_dn;
+ const char *filter;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb,
+ SYSDB_TMPL_VIEW_SEARCH_BASE, domain->view_name);
+ if (base_dn == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new_fmt failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ switch(type) {
+ case OO_TYPE_USER:
+ filter = SYSDB_USER_UID_OVERRIDE_FILTER;
+ attrs = user_attrs;
+ break;
+ case OO_TYPE_GROUP:
+ filter = SYSDB_GROUP_GID_OVERRIDE_FILTER;
+ attrs = group_attrs;
+ break;
+ default:
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected override object type [%d].\n",
+ type);
+ ret = EINVAL;
+ goto done;
+ }
+
+ ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &override_res, base_dn,
+ LDB_SCOPE_SUBTREE, attrs, filter, id);
+ if (ret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ if (override_res->count == 0) {
+ DEBUG(SSSDBG_TRACE_FUNC,
+ "No user override found for %s with id [%lu].\n",
+ (type == OO_TYPE_USER ? "user" : "group"), id);
+ ret = ENOENT;
+ goto done;
+ } else if (override_res->count > 1) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Found more than one override for id [%lu]\n.", id);
+ ret = EINVAL;
+ goto done;
+ }
+
+ if (orig_obj != NULL) {
+ orig_obj_dn = ldb_msg_find_attr_as_string(override_res->msgs[0],
+ SYSDB_OVERRIDE_OBJECT_DN,
+ NULL);
+ if (orig_obj_dn == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Missing link to original object in override [%s].\n",
+ ldb_dn_get_linearized(override_res->msgs[0]->dn));
+ ret = EINVAL;
+ goto done;
+ }
+
+ base_dn = ldb_dn_new(tmp_ctx, domain->sysdb->ldb, orig_obj_dn);
+ if (base_dn == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &orig_res, base_dn,
+ LDB_SCOPE_BASE, attrs, NULL);
+ if (ret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ *orig_obj = talloc_steal(mem_ctx, orig_res);
+ }
+
+
+ *override_obj = talloc_steal(mem_ctx, override_res);
+
+ ret = EOK;
+
+done:
+ talloc_zfree(tmp_ctx);
+ return ret;
+}
+
+errno_t sysdb_search_user_override_by_uid(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ uid_t uid,
+ struct ldb_result **override_obj,
+ struct ldb_result **orig_obj)
+{
+ return sysdb_search_override_by_id(mem_ctx, domain, uid, OO_TYPE_USER,
+ override_obj, orig_obj);
+}
+
+errno_t sysdb_search_group_override_by_gid(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ gid_t gid,
+ struct ldb_result **override_obj,
+ struct ldb_result **orig_obj)
+{
+ return sysdb_search_override_by_id(mem_ctx, domain, gid, OO_TYPE_GROUP,
+ override_obj, orig_obj);
+}
+
/**
* @brief Add override data to the original object
*