summaryrefslogtreecommitdiffstats
path: root/server/providers/dp_backend_store.c
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2009-01-06 18:23:59 -0500
committerSimo Sorce <idra@samba.org>2009-01-06 18:23:59 -0500
commit5aa5391dcd8a7d593757c0af3a765bbce1ce2138 (patch)
tree6fe184bed37e97e72e9dfd59739aef0785e29fd8 /server/providers/dp_backend_store.c
parentc1f2536bac22d17ab658050f0cacb0528b01a87f (diff)
downloadsssd-5aa5391dcd8a7d593757c0af3a765bbce1ce2138.tar.gz
sssd-5aa5391dcd8a7d593757c0af3a765bbce1ce2138.tar.xz
sssd-5aa5391dcd8a7d593757c0af3a765bbce1ce2138.zip
Add more infrastructure to data provider to dispatch requests (still untested).
Add helper functions to connect to the data provider. Add some plumbing to the ldap provider (still untested).
Diffstat (limited to 'server/providers/dp_backend_store.c')
-rw-r--r--server/providers/dp_backend_store.c364
1 files changed, 364 insertions, 0 deletions
diff --git a/server/providers/dp_backend_store.c b/server/providers/dp_backend_store.c
new file mode 100644
index 000000000..e518f4387
--- /dev/null
+++ b/server/providers/dp_backend_store.c
@@ -0,0 +1,364 @@
+/*
+ SSSD
+
+ Data Provider Backend Storage helper funcitons
+
+ Copyright (C) Simo Sorce <ssorce@redhat.com> 2008
+
+ 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 <errno.h>
+#include "ldb.h"
+#include "ldb_errors.h"
+#include "util/util.h"
+#include "providers/dp_backend.h"
+#include <time.h>
+
+int dp_be_store_account_posix(struct be_ctx *ctx,
+ char *name, char *pwd,
+ uint64_t uid, uint64_t gid,
+ char *gecos, char *homedir, char *shell)
+{
+ TALLOC_CTX *tmp_ctx;
+ const char *attrs[] = { "uid", NULL };
+ struct ldb_dn *account_dn;
+ struct ldb_message *msg;
+ struct ldb_request *req;
+ struct ldb_result *res;
+ int lret, ret;
+ int flags;
+
+ tmp_ctx = talloc_new(ctx);
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ account_dn = ldb_dn_new_fmt(tmp_ctx, ctx->ldb,
+ "uid=%s,cn=users,cn=%s,cn=remote",
+ name, ctx->domain);
+ if (!account_dn) {
+ talloc_free(tmp_ctx);
+ return ENOMEM;
+ }
+
+ lret = ldb_transaction_start(ctx->ldb);
+ if (lret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed ldb transaction start !? (%d)\n", lret));
+ ret = EIO;
+ goto done;
+ }
+
+ res = talloc_zero(tmp_ctx, struct ldb_result);
+ if (!res) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ lret = ldb_build_search_req(&req, ctx->ldb, tmp_ctx,
+ account_dn, LDB_SCOPE_BASE,
+ "(objectClass=User)", attrs, NULL,
+ res, ldb_search_default_callback, NULL);
+ if (!lret) {
+ DEBUG(1, ("Failed to build search request (%d) !?\n", lret));
+ ret = EIO;
+ goto done;
+ }
+
+ lret = ldb_request(ctx->ldb, req);
+ if (lret == LDB_SUCCESS) {
+ lret = ldb_wait(req->handle, LDB_WAIT_ALL);
+ }
+ if (lret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed to make search request: %s(%d)[%s]\n",
+ ldb_strerror(lret), lret, ldb_errstring(ctx->ldb)));
+ ret = EIO;
+ goto done;
+ }
+
+ talloc_free(req);
+ req = NULL;
+
+ msg = ldb_msg_new(tmp_ctx);
+ if (!msg) {
+ ret = ENOMEM;
+ goto done;
+ }
+ msg->dn = account_dn;
+
+ switch (res->count) {
+ case 0:
+ flags = LDB_FLAG_MOD_ADD;
+ break;
+ case 1:
+ flags = LDB_FLAG_MOD_REPLACE;
+ break;
+ default:
+ DEBUG(0, ("Cache DB corrupted, base search returned %d results\n",
+ res->count));
+ ret = EIO;
+ goto done;
+ }
+
+ talloc_free(res);
+ res = NULL;
+
+ if (flags == LDB_FLAG_MOD_ADD) {
+ /* TODO: retrieve user objectclass list from configuration */
+ lret = ldb_msg_add_empty(msg, "objectClass", flags, NULL);
+ if (lret == LDB_SUCCESS) {
+ lret = ldb_msg_add_string(msg, "objectClass", "user");
+ }
+ if (lret != LDB_SUCCESS) {
+ ret = errno;
+ goto done;
+ }
+
+ /* TODO: retrieve user name attribute from configuration */
+ lret = ldb_msg_add_empty(msg, "uid", flags, NULL);
+ if (lret == LDB_SUCCESS) {
+ lret = ldb_msg_add_string(msg, "uid", name);
+ }
+ if (lret != LDB_SUCCESS) {
+ ret = errno;
+ goto done;
+ }
+ }
+
+ /* TODO: retrieve attribute name mappings from configuration */
+
+ /* pwd */
+ if (pwd && *pwd) {
+ lret = ldb_msg_add_empty(msg, "userPassword", flags, NULL);
+ if (lret == LDB_SUCCESS) {
+ lret = ldb_msg_add_string(msg, "userPassword", pwd);
+ }
+ } else {
+ lret = ldb_msg_add_empty(msg, "userPassword",
+ LDB_FLAG_MOD_DELETE, NULL);
+ }
+ if (lret != LDB_SUCCESS) {
+ ret = errno;
+ goto done;
+ }
+
+ /* uid */
+ if (uid) {
+ lret = ldb_msg_add_empty(msg, "uidNumber", flags, NULL);
+ if (lret == LDB_SUCCESS) {
+ lret = ldb_msg_add_fmt(msg, "uidNumber",
+ "%lu", (long unsigned)uid);
+ }
+ if (lret != LDB_SUCCESS) {
+ ret = errno;
+ goto done;
+ }
+ } else {
+ DEBUG(0, ("Cached users can't have UID == 0\n"));
+ ret = EINVAL;
+ goto done;
+ }
+
+ /* gid */
+ if (gid) {
+ lret = ldb_msg_add_empty(msg, "gidNumber", flags, NULL);
+ if (lret == LDB_SUCCESS) {
+ lret = ldb_msg_add_fmt(msg, "gidNumber",
+ "%lu", (long unsigned)gid);
+ }
+ if (lret != LDB_SUCCESS) {
+ ret = errno;
+ goto done;
+ }
+ } else {
+ DEBUG(0, ("Cached users can't have GID == 0\n"));
+ ret = EINVAL;
+ goto done;
+ }
+
+ /* gecos */
+ if (gecos && *gecos) {
+ lret = ldb_msg_add_empty(msg, "fullName", flags, NULL);
+ if (lret == LDB_SUCCESS) {
+ lret = ldb_msg_add_string(msg, "fullName", gecos);
+ }
+ } else {
+ lret = ldb_msg_add_empty(msg, "fullName",
+ LDB_FLAG_MOD_DELETE, NULL);
+ }
+ if (lret != LDB_SUCCESS) {
+ ret = errno;
+ goto done;
+ }
+
+ /* homedir */
+ if (homedir && *homedir) {
+ lret = ldb_msg_add_empty(msg, "homeDirectory", flags, NULL);
+ if (lret == LDB_SUCCESS) {
+ lret = ldb_msg_add_string(msg, "homeDirectory", homedir);
+ }
+ } else {
+ lret = ldb_msg_add_empty(msg, "homeDirectory",
+ LDB_FLAG_MOD_DELETE, NULL);
+ }
+ if (lret != LDB_SUCCESS) {
+ ret = errno;
+ goto done;
+ }
+
+ /* shell */
+ if (shell && *shell) {
+ lret = ldb_msg_add_empty(msg, "loginShell", flags, NULL);
+ if (lret == LDB_SUCCESS) {
+ lret = ldb_msg_add_string(msg, "loginShell", shell);
+ }
+ } else {
+ lret = ldb_msg_add_empty(msg, "loginShell",
+ LDB_FLAG_MOD_DELETE, NULL);
+ }
+ if (lret != LDB_SUCCESS) {
+ ret = errno;
+ goto done;
+ }
+
+ /* modification time */
+ lret = ldb_msg_add_empty(msg, "lastUpdate", flags, NULL);
+ if (lret == LDB_SUCCESS) {
+ lret = ldb_msg_add_fmt(msg, "lastUpdate",
+ "%ld", (long int)time(NULL));
+ }
+ if (lret != LDB_SUCCESS) {
+ ret = errno;
+ goto done;
+ }
+
+ if (flags == LDB_FLAG_MOD_ADD) {
+ lret = ldb_build_add_req(&req, ctx->ldb, tmp_ctx, msg, NULL,
+ NULL, ldb_op_default_callback, NULL);
+ } else {
+ lret = ldb_build_mod_req(&req, ctx->ldb, tmp_ctx, msg, NULL,
+ NULL, ldb_op_default_callback, NULL);
+ }
+ if (lret == LDB_SUCCESS) {
+ lret = ldb_request(ctx->ldb, req);
+ if (lret == LDB_SUCCESS) {
+ lret = ldb_wait(req->handle, LDB_WAIT_ALL);
+ }
+ }
+ if (lret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed to make modify request: %s(%d)[%s]\n",
+ ldb_strerror(lret), lret, ldb_errstring(ctx->ldb)));
+ ret = EIO;
+ goto done;
+ }
+
+ lret = ldb_transaction_commit(ctx->ldb);
+ if (lret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed ldb transaction start !? (%d)\n", lret));
+ ret = EIO;
+ goto done;
+ }
+
+ ret = EOK;
+
+done:
+ if (ret != EOK) {
+ lret = ldb_transaction_cancel(ctx->ldb);
+ if (lret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed to cancel ldb transaction (%d)\n", lret));
+ }
+ }
+
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+int dp_be_remove_account_posix(struct be_ctx *ctx, char *name)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_dn *account_dn;
+ int ret;
+
+ tmp_ctx = talloc_new(ctx);
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ account_dn = ldb_dn_new_fmt(tmp_ctx, ctx->ldb,
+ "uid=%s,cn=users,cn=%s,cn=remote",
+ name, ctx->domain);
+ if (!account_dn) {
+ talloc_free(tmp_ctx);
+ return ENOMEM;
+ }
+
+ ret = ldb_delete(ctx->ldb, account_dn);
+
+ if (ret != LDB_SUCCESS) {
+ DEBUG(2, ("LDB Error: %s(%d)\nError Message: [%s]\n",
+ ldb_strerror(ret), ret, ldb_errstring(ctx->ldb)));
+ ret = EIO;
+ }
+
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+/* TODO: Unify with nss_ldb and provide a single cachedb interface */
+
+int dp_be_cachedb_init(struct be_ctx *ctx)
+{
+ TALLOC_CTX *tmp_ctx;
+ char *ldb_file;
+ char *default_db_file;
+ int ret;
+
+ tmp_ctx = talloc_new(ctx);
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ default_db_file = talloc_asprintf(tmp_ctx, "%s/%s", DB_PATH, DATA_PROVIDER_DB_FILE);
+ if (!default_db_file) {
+ talloc_free(tmp_ctx);
+ return ENOMEM;
+ }
+
+ ret = confdb_get_string(ctx->cdb, tmp_ctx,
+ DATA_PROVIDER_DB_CONF_SEC, "ldbFile",
+ default_db_file, &ldb_file);
+ if (ret != EOK) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
+ ctx->ldb = ldb_init(tmp_ctx, ctx->ev);
+ if (!ctx->ldb) {
+ talloc_free(tmp_ctx);
+ return EIO;
+ }
+
+ ret = ldb_connect(ctx->ldb, ldb_file, 0, NULL);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return EIO;
+ }
+
+ talloc_steal(ctx, ctx->ldb);
+
+ talloc_free(tmp_ctx);
+ return EOK;
+}
+