diff options
author | Jakub Hrozek <jhrozek@redhat.com> | 2012-01-03 08:12:57 +0100 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2012-02-05 19:16:16 -0500 |
commit | 1f1e6cbc59868f06dee3ab4b3df660fcb77ce1c8 (patch) | |
tree | 5add917cb8be11a8dee45f60fcacf73b56da93da | |
parent | 232b73185893a42e545b20caa9e59880e8a8a901 (diff) | |
download | sssd-1f1e6cbc59868f06dee3ab4b3df660fcb77ce1c8.tar.gz sssd-1f1e6cbc59868f06dee3ab4b3df660fcb77ce1c8.tar.bz2 sssd-1f1e6cbc59868f06dee3ab4b3df660fcb77ce1c8.zip |
AUTOFS: sysdb interface
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | src/db/sysdb.h | 3 | ||||
-rw-r--r-- | src/db/sysdb_autofs.c | 398 | ||||
-rw-r--r-- | src/db/sysdb_autofs.h | 88 | ||||
-rw-r--r-- | src/db/sysdb_ops.c | 38 |
5 files changed, 522 insertions, 7 deletions
diff --git a/Makefile.am b/Makefile.am index 9f57ac02..3efa46db 100644 --- a/Makefile.am +++ b/Makefile.am @@ -325,6 +325,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 \ @@ -385,6 +386,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 31b988eb..c689ccbe 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 00000000..e9d918e4 --- /dev/null +++ b/src/db/sysdb_autofs.c @@ -0,0 +1,398 @@ +/* + Authors: + Jakub Hrozek <jhrozek@redhat.com> + + 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 <http://www.gnu.org/licenses/>. +*/ + +#include <talloc.h> + +#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); +} + +static 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; + char *safe_map_name; + 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; + + ret = sss_filter_sanitize(tmp_ctx, map_name, &safe_map_name); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Cannot sanitize map [%s] error [%d]: %s\n", + map_name, ret, strerror(ret))); + goto done; + } + + filter = talloc_asprintf(tmp_ctx, "(&(objectclass=%s)(%s=%s))", + SYSDB_AUTOFS_MAP_OC, SYSDB_NAME, safe_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]", safe_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", safe_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 00000000..e8e5de46 --- /dev/null +++ b/src/db/sysdb_autofs.h @@ -0,0 +1,88 @@ +/* + Authors: + Jakub Hrozek <jhrozek@redhat.com> + + 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 <http://www.gnu.org/licenses/>. +*/ + +#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 8eb81938..41070843 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 <time.h> @@ -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; |