From b024f841a2b8559182f2809509869f34e552319e Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Tue, 3 Jan 2012 08:12:57 +0100 Subject: [PATCH 03/10] AUTOFS: sysdb interface --- Makefile.am | 2 + src/db/sysdb.h | 3 +- src/db/sysdb_autofs.c | 389 +++++++++++++++++++++++++++++++++++++++++++++++++ src/db/sysdb_autofs.h | 88 +++++++++++ src/db/sysdb_ops.c | 38 ++++- 5 files changed, 513 insertions(+), 7 deletions(-) create mode 100644 src/db/sysdb_autofs.c create mode 100644 src/db/sysdb_autofs.h diff --git a/Makefile.am b/Makefile.am index 409dc84d7fc100039804b1272e3a777d607f7b03..ff5b5084d3a5651aed66fb12bf3e65d3cc57df56 100644 --- a/Makefile.am +++ b/Makefile.am @@ -324,6 +324,7 @@ dist_noinst_HEADERS = \ src/sbus/sssd_dbus_private.h \ src/db/sysdb.h \ src/db/sysdb_sudo.h \ + src/db/sysdb_autofs.h \ src/db/sysdb_private.h \ src/db/sysdb_services.h \ src/confdb/confdb.h \ @@ -384,6 +385,7 @@ libsss_util_la_SOURCES = \ src/db/sysdb_search.c \ src/db/sysdb_upgrade.c \ src/db/sysdb_services.c \ + src/db/sysdb_autofs.c \ src/monitor/monitor_sbus.c \ src/providers/dp_auth_util.c \ src/providers/dp_pam_data_util.c \ diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 31b988eb14741b3de625c51d85cb7059fbd7c36d..c689ccbe338b90dc4e93d94c8e2ba1e478858576 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -556,7 +556,8 @@ int sysdb_store_group(struct sysdb_ctx *sysdb, enum sysdb_member_type { SYSDB_MEMBER_USER, SYSDB_MEMBER_GROUP, - SYSDB_MEMBER_SERVICE + SYSDB_MEMBER_SERVICE, + SYSDB_MEMBER_AUTOFSENTRY }; int sysdb_add_group_member(struct sysdb_ctx *sysdb, diff --git a/src/db/sysdb_autofs.c b/src/db/sysdb_autofs.c new file mode 100644 index 0000000000000000000000000000000000000000..82549d693915df26ee657fb8214100e75ca70f56 --- /dev/null +++ b/src/db/sysdb_autofs.c @@ -0,0 +1,389 @@ +/* + Authors: + Jakub Hrozek + + Copyright (C) 2012 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include + +#include "db/sysdb.h" +#include "db/sysdb_private.h" +#include "db/sysdb_autofs.h" + +struct ldb_dn * +sysdb_autofsmap_dn(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + const char *map_name) +{ + return sysdb_custom_dn(sysdb, mem_ctx, sysdb->domain->name, + map_name, AUTOFS_MAP_SUBDIR); +} + +struct ldb_dn * +sysdb_autofsentry_dn(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + const char *entry_name) +{ + return sysdb_custom_dn(sysdb, mem_ctx, sysdb->domain->name, + entry_name, AUTOFS_ENTRY_SUBDIR); +} + +char * +sysdb_autofsmap_strdn(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + const char *map_name) +{ + struct ldb_dn *dn; + char *strdn; + + dn = sysdb_autofsmap_dn(mem_ctx, sysdb, map_name); + if (!dn) return NULL; + + strdn = talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn)); + talloc_free(dn); + return strdn; +} + +errno_t +sysdb_save_autofsmap(struct sysdb_ctx *sysdb_ctx, + const char *name, + const char *autofsmapname, + struct sysdb_attrs *attrs, + int cache_timeout, + time_t now) +{ + errno_t ret; + TALLOC_CTX *tmp_ctx; + + DEBUG(SSSDBG_TRACE_FUNC, ("Adding autofs map %s\n", autofsmapname)); + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) { + return ENOMEM; + } + + if (!attrs) { + attrs = sysdb_new_attrs(tmp_ctx); + if (!attrs) { + ret = ENOMEM; + goto done; + } + } + + ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS, + SYSDB_AUTOFS_MAP_OC); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not set map object class [%d]: %s\n", + ret, strerror(ret))); + goto done; + } + + ret = sysdb_attrs_add_string(attrs, SYSDB_AUTOFS_MAP_NAME, autofsmapname); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not set map name [%d]: %s\n", + ret, strerror(ret))); + goto done; + } + + ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, name); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not set name attribute [%d]: %s\n", + ret, strerror(ret))); + goto done; + } + + ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now); + if (ret) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not set sysdb lastUpdate [%d]: %s\n", + ret, strerror(ret))); + goto done; + } + + ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE, + ((cache_timeout) ? + (now + cache_timeout) : 0)); + if (ret) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not set sysdb cache expire [%d]: %s\n", + ret, strerror(ret))); + goto done; + } + + ret = sysdb_store_custom(sysdb_ctx, name, AUTOFS_MAP_SUBDIR, attrs); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("sysdb_store_custom failed [%d]: %s\n", + ret, strerror(ret))); + goto done; + } + + ret = EOK; +done: + talloc_free(tmp_ctx); + return ret; +} + +errno_t +sysdb_delete_autofsmap(struct sysdb_ctx *sysdb_ctx, + const char *name) +{ + DEBUG(SSSDBG_TRACE_FUNC, ("Deleting autofs map %s\n", name)); + return sysdb_delete_custom(sysdb_ctx, name, AUTOFS_MAP_SUBDIR); +} + +errno_t +sysdb_get_map_byname(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + const char *map_name, + struct ldb_message **_map) +{ + errno_t ret; + TALLOC_CTX *tmp_ctx; + const char *filter; + size_t count; + struct ldb_message **msgs; + const char *attrs[] = { SYSDB_OBJECTCLASS, + SYSDB_CACHE_EXPIRE, + SYSDB_LAST_UPDATE, + SYSDB_AUTOFS_MAP_NAME, + SYSDB_MEMBER, + NULL }; + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) return ENOMEM; + + filter = talloc_asprintf(tmp_ctx, "(&(objectclass=%s)(%s=%s))", + SYSDB_AUTOFS_MAP_OC, SYSDB_NAME, map_name); + if (!filter) { + ret = EOK; + goto done; + } + + ret = sysdb_search_custom(tmp_ctx, sysdb, filter, + AUTOFS_MAP_SUBDIR, attrs, + &count, &msgs); + if (ret != EOK && ret != ENOENT) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Error looking up autofs map [%s]", map_name)); + goto done; + } else if (ret == ENOENT) { + DEBUG(SSSDBG_TRACE_FUNC, ("No such map\n")); + *_map = NULL; + goto done; + } + + if (count != 1) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("More than one map named %s\n", map_name)); + goto done; + } + + *_map = talloc_steal(mem_ctx, msgs[0]); + ret = EOK; +done: + talloc_free(tmp_ctx); + return ret; +} + +errno_t +sysdb_save_autofsentry(struct sysdb_ctx *sysdb_ctx, + const char *key, + const char *value, + struct sysdb_attrs *attrs) +{ + errno_t ret; + TALLOC_CTX *tmp_ctx; + + DEBUG(SSSDBG_TRACE_FUNC, + ("Adding autofs entry [%s] - [%s]\n", key, value)); + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) { + return ENOMEM; + } + + if (!attrs) { + attrs = sysdb_new_attrs(tmp_ctx); + if (!attrs) { + ret = ENOMEM; + goto done; + } + } + + ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS, + SYSDB_AUTOFS_ENTRY_OC); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not set entry object class [%d]: %s\n", + ret, strerror(ret))); + goto done; + } + + ret = sysdb_attrs_add_string(attrs, SYSDB_AUTOFS_ENTRY_KEY, key); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not set entry key [%d]: %s\n", + ret, strerror(ret))); + goto done; + } + + ret = sysdb_attrs_add_string(attrs, SYSDB_AUTOFS_ENTRY_VALUE, value); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not set entry key [%d]: %s\n", + ret, strerror(ret))); + goto done; + } + + ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, key); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not set name attribute [%d]: %s\n", + ret, strerror(ret))); + goto done; + } + + ret = sysdb_store_custom(sysdb_ctx, key, AUTOFS_ENTRY_SUBDIR, attrs); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("sysdb_store_custom failed [%d]: %s\n", + ret, strerror(ret))); + goto done; + } + + ret = EOK; +done: + talloc_free(tmp_ctx); + return ret; +} + +errno_t +sysdb_autofs_entries_by_map(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + const char *mapname, + size_t *_count, + struct ldb_message ***_entries) +{ + errno_t ret; + TALLOC_CTX *tmp_ctx; + char *filter; + const char *attrs[] = { SYSDB_AUTOFS_ENTRY_KEY, + SYSDB_AUTOFS_ENTRY_VALUE, + NULL }; + size_t count; + struct ldb_message **msgs; + char *mapdn; + + DEBUG(SSSDBG_TRACE_FUNC, ("Getting entries for map %s\n", mapname)); + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) { + return ENOMEM; + } + + mapdn = sysdb_autofsmap_strdn(tmp_ctx, sysdb, mapname); + if (!mapdn) { + ret = ENOMEM; + goto done; + } + + filter = talloc_asprintf(tmp_ctx, "(&(objectclass=%s)(%s=%s))", + SYSDB_AUTOFS_ENTRY_OC, SYSDB_MEMBEROF, mapdn); + if (!filter) { + ret = ENOMEM; + goto done; + } + + ret = sysdb_search_custom(tmp_ctx, sysdb, filter, AUTOFS_ENTRY_SUBDIR, + attrs, &count, &msgs); + if (ret != EOK && ret != ENOENT) { + DEBUG(SSSDBG_OP_FAILURE, ("sysdb search failed: %d\n", ret)); + goto done; + } else if (ret == ENOENT) { + DEBUG(SSSDBG_TRACE_FUNC, ("No entries for the map\n")); + *_count = 0; + *_entries = NULL; + goto done; + } + + *_count = count; + *_entries = talloc_steal(mem_ctx, msgs); + ret = EOK; + DEBUG(SSSDBG_TRACE_INTERNAL, ("found %d entries for map %s\n", + count, mapname)); +done: + talloc_free(tmp_ctx); + return ret; +} + +errno_t +sysdb_map_entry_name(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, + const char *entry_dn, char **_name) +{ + return sysdb_get_rdn(sysdb, mem_ctx, entry_dn, NULL, _name); +} + +errno_t +sysdb_autofs_map_update_members(struct sysdb_ctx *sysdb, + const char *mapname, + const char *const *add_entries, + const char *const *del_entries) +{ + errno_t ret; + int i; + + TALLOC_CTX *tmp_ctx = talloc_new(NULL); + if(!tmp_ctx) { + return ENOMEM; + } + + ret = sysdb_transaction_start(sysdb); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Failed to start update transaction\n")); + goto done; + } + + if (add_entries) { + /* Add the all te add_entries to the map */ + for (i = 0; add_entries[i]; i++) { + ret = sysdb_add_group_member(sysdb, mapname, add_entries[i], + SYSDB_MEMBER_AUTOFSENTRY); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + ("Could not add entry [%s] to map [%s]. " + "Skipping.\n", add_entries[i], mapname)); + /* Continue on, we should try to finish the rest */ + } + } + } + + if (del_entries) { + /* Add the all te del_entries to the map */ + for (i = 0; del_entries[i]; i++) { + ret = sysdb_remove_group_member(sysdb, mapname, del_entries[i], + SYSDB_MEMBER_AUTOFSENTRY); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + ("Could not del entry [%s] to map [%s]. " + "Skipping.\n", del_entries[i], mapname)); + /* Continue on, we should try to finish the rest */ + } + } + } + + ret = sysdb_transaction_commit(sysdb); +done: + if (ret != EOK) { + sysdb_transaction_cancel(sysdb); + } + talloc_free(tmp_ctx); + return ret; +} diff --git a/src/db/sysdb_autofs.h b/src/db/sysdb_autofs.h new file mode 100644 index 0000000000000000000000000000000000000000..e8e5de466dd59d1c47552364fa550671890cf350 --- /dev/null +++ b/src/db/sysdb_autofs.h @@ -0,0 +1,88 @@ +/* + Authors: + Jakub Hrozek + + Copyright (C) 2012 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _SYSDB_AUTOFS_H_ +#define _SYSDB_AUTOFS_H_ + +#include "db/sysdb.h" + +/* subdirs in cn=custom in sysdb. We don't store autofs stuff in sysdb directly + * b/c it's not name-service-switch data */ +#define AUTOFS_MAP_SUBDIR "autofsmaps" +#define AUTOFS_ENTRY_SUBDIR "autofsentries" + +#define SYSDB_AUTOFS_MAP_OC "automountMap" +#define SYSDB_AUTOFS_MAP_NAME "automountMapName" + +#define SYSDB_AUTOFS_ENTRY_OC "automount" +#define SYSDB_AUTOFS_ENTRY_KEY "automountKey" +#define SYSDB_AUTOFS_ENTRY_VALUE "automountInformation" + +struct ldb_dn * +sysdb_autofsmap_dn(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + const char *map_name); + +struct ldb_dn * +sysdb_autofsentry_dn(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + const char *entry_name); + +errno_t +sysdb_save_autofsmap(struct sysdb_ctx *sysdb_ctx, + const char *name, + const char *autofsmapname, + struct sysdb_attrs *attrs, + int cache_timeout, + time_t now); + +errno_t +sysdb_get_map_byname(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + const char *map_name, + struct ldb_message **map); + +errno_t +sysdb_delete_autofsmap(struct sysdb_ctx *sysdb_ctx, + const char *name); + +errno_t +sysdb_save_autofsentry(struct sysdb_ctx *sysdb_ctx, + const char *key, + const char *value, + struct sysdb_attrs *attrs); + +errno_t +sysdb_autofs_entries_by_map(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + const char *mapname, + size_t *_count, + struct ldb_message ***_entries); + +errno_t sysdb_map_entry_name(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, + const char *entry_dn, char **_name); + +errno_t +sysdb_autofs_map_update_members(struct sysdb_ctx *sysdb, + const char *mapname, + const char *const *add_entries, + const char *const *del_entries); + +#endif /* _SYSDB_AUTOFS_H_ */ diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index 8eb81938f23d0aa3841d5881f8f850efb4a58cc2..41070843b1ce9d65bdef95cbc03dd2c2f0cfa398 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -22,6 +22,7 @@ #include "util/util.h" #include "db/sysdb_private.h" #include "db/sysdb_services.h" +#include "db/sysdb_autofs.h" #include "util/crypto/sss_crypto.h" #include @@ -1668,24 +1669,45 @@ sysdb_group_membership_mod(struct sysdb_ctx *sysdb, return ENOMEM; } - group_dn = sysdb_group_dn(sysdb, tmp_ctx, sysdb->domain->name, group); - if (!group_dn) { - ret = ENOMEM; - goto done; - } - if (type == SYSDB_MEMBER_USER) { member_dn = sysdb_user_dn(sysdb, tmp_ctx, sysdb->domain->name, member); if (!member_dn) { ret = ENOMEM; goto done; } + + group_dn = sysdb_group_dn(sysdb, tmp_ctx, sysdb->domain->name, group); + if (!group_dn) { + ret = ENOMEM; + goto done; + } } else if (type == SYSDB_MEMBER_GROUP) { member_dn = sysdb_group_dn(sysdb, tmp_ctx, sysdb->domain->name, member); if (!member_dn) { ret = ENOMEM; goto done; } + + group_dn = sysdb_group_dn(sysdb, tmp_ctx, sysdb->domain->name, group); + if (!group_dn) { + ret = ENOMEM; + goto done; + } + } else if (type == SYSDB_MEMBER_AUTOFSENTRY) { + /* FIXME - I don't like autofs specific stuff in sysdb_ops.c + * Maybe we should introduce sysdb_common.c ? + */ + member_dn = sysdb_autofsentry_dn(tmp_ctx, sysdb, member); + if (!member_dn) { + ret = ENOMEM; + goto done; + } + + group_dn = sysdb_autofsmap_dn(tmp_ctx, sysdb, group); + if (!group_dn) { + ret = ENOMEM; + goto done; + } } else { ret = EINVAL; goto done; @@ -2937,6 +2959,10 @@ errno_t sysdb_remove_attrs(struct sysdb_ctx *sysdb, case SYSDB_MEMBER_SERVICE: msg->dn = sysdb_svc_dn(sysdb, msg, sysdb->domain->name, name); break; + + case SYSDB_MEMBER_AUTOFSENTRY: + msg->dn = sysdb_autofsmap_dn(msg, sysdb, name); + break; } if (!msg->dn) { ret = ENOMEM; -- 1.7.7.6