summaryrefslogtreecommitdiff
path: root/server/providers
diff options
context:
space:
mode:
Diffstat (limited to 'server/providers')
-rw-r--r--server/providers/data_provider.c343
-rw-r--r--server/providers/data_provider.h34
-rw-r--r--server/providers/data_provider_be.c240
-rw-r--r--server/providers/dp_backend.h57
-rw-r--r--server/providers/dp_backend_store.c364
-rw-r--r--server/providers/dp_helpers.c98
-rw-r--r--server/providers/ldap_provider.c97
7 files changed, 1061 insertions, 172 deletions
diff --git a/server/providers/data_provider.c b/server/providers/data_provider.c
index 823054ab..645c1425 100644
--- a/server/providers/data_provider.c
+++ b/server/providers/data_provider.c
@@ -57,7 +57,6 @@ struct dp_ctx {
struct dp_client {
struct dp_ctx *dpctx;
struct sbus_conn_ctx *conn_ctx;
- const char *domain;
};
struct dp_backend {
@@ -83,13 +82,30 @@ static int service_identity(DBusMessage *message, void *data, DBusMessage **r);
static int service_pong(DBusMessage *message, void *data, DBusMessage **r);
struct sbus_method mon_sbus_methods[] = {
- {SERVICE_METHOD_IDENTITY, service_identity},
- {SERVICE_METHOD_PING, service_pong},
- {NULL, NULL}
+ { SERVICE_METHOD_IDENTITY, service_identity },
+ { SERVICE_METHOD_PING, service_pong },
+ { NULL, NULL }
};
+static int dp_get_account_info(DBusMessage *message, void *data, DBusMessage **r);
+
struct sbus_method dp_sbus_methods[] = {
- {NULL, NULL}
+ { DP_SRV_METHOD_GETACCTINFO, dp_get_account_info },
+ { NULL, NULL }
+};
+
+struct dp_request {
+ /* reply message to send when request is done */
+ DBusMessage *reply;
+ /* frontend client that made the request */
+ struct dp_client *src_cli;
+
+ int pending_replies;
+};
+
+struct dp_be_request {
+ struct dp_request *req;
+ struct dp_client *be_cli;
};
static int service_identity(DBusMessage *message, void *data, DBusMessage **r)
@@ -193,6 +209,7 @@ static int dp_db_init(struct dp_ctx *dpctx)
static void be_identity_check(DBusPendingCall *pending, void *data);
static void be_online_check(DBusPendingCall *pending, void *data);
+static void be_got_account_info(DBusPendingCall *pending, void *data);
static int dbus_dp_init(struct sbus_conn_ctx *conn_ctx, void *data)
{
@@ -280,7 +297,7 @@ static void be_identity_check(DBusPendingCall *pending, void *data)
* until reply is valid or timeout has occurred. If reply is NULL
* here, something is seriously wrong and we should bail out.
*/
- DEBUG(0, ("Serious error. A reply callback was called but no reply was received and no timeout occurred\n"));
+ DEBUG(0, ("Severe error. A reply callback was called but no reply was received and no timeout occurred\n"));
/* Destroy this connection */
sbus_disconnect(dpcli->conn_ctx);
@@ -382,6 +399,314 @@ static void be_online_check(DBusPendingCall *pending, void *data)
return;
}
+static void be_got_account_info(DBusPendingCall *pending, void *data)
+{
+ struct dp_be_request *bereq;
+ DBusMessage *reply;
+ DBusConnection *conn;
+ DBusError dbus_error;
+ dbus_uint16_t cli_err_maj;
+ dbus_uint32_t cli_err_min;
+ char *cli_err_msg;
+ dbus_bool_t ret;
+ int type;
+
+ bereq = talloc_get_type(data, struct dp_be_request);
+ dbus_error_init(&dbus_error);
+
+ reply = dbus_pending_call_steal_reply(pending);
+ if (!reply) {
+ /* reply should never be null. This function shouldn't be called
+ * until reply is valid or timeout has occurred. If reply is NULL
+ * here, something is seriously wrong and we should bail out.
+ */
+ DEBUG(0, ("Severe error. A reply callback was called but no reply was received and no timeout occurred\n"));
+
+ /* Destroy this connection */
+ sbus_disconnect(bereq->be_cli->conn_ctx);
+ goto done;
+ }
+
+ type = dbus_message_get_type(reply);
+ switch (type) {
+ case DBUS_MESSAGE_TYPE_METHOD_RETURN:
+ ret = dbus_message_get_args(reply, &dbus_error,
+ DBUS_TYPE_UINT16, &cli_err_maj,
+ DBUS_TYPE_UINT32, &cli_err_min,
+ DBUS_TYPE_STRING, &cli_err_msg,
+ DBUS_TYPE_INVALID);
+ if (!ret) {
+ DEBUG(1,("be_identity_check failed, to parse message, killing connection\n"));
+ sbus_disconnect(bereq->be_cli->conn_ctx);
+ goto done;
+ }
+
+ /* Set up the destructor for this service */
+ break;
+
+ case DBUS_MESSAGE_TYPE_ERROR:
+ DEBUG(0,("getAccountInfo returned an error [%s], closing connection.\n",
+ dbus_message_get_error_name(reply)));
+ /* Falling through to default intentionally*/
+ default:
+ /*
+ * Timeout or other error occurred or something
+ * unexpected happened.
+ * It doesn't matter which, because either way we
+ * know that this connection isn't trustworthy.
+ * We'll destroy it now.
+ */
+ sbus_disconnect(bereq->be_cli->conn_ctx);
+ }
+
+ /* TODO: handle errors !! */
+ if (bereq->req->pending_replies > 1) {
+ bereq->req->pending_replies--;
+ talloc_free(bereq);
+ } else {
+ conn = sbus_get_connection(bereq->be_cli->conn_ctx);
+ ret = dbus_message_append_args(bereq->req->reply,
+ DBUS_TYPE_UINT16, 0,
+ DBUS_TYPE_UINT32, 0,
+ DBUS_TYPE_STRING, "Success",
+ DBUS_TYPE_INVALID);
+ if (!ret) {
+ DEBUG(1, ("Failed to build reply ... frontend will wait for timeout ...\n"));
+ talloc_free(bereq->req);
+ goto done;
+ }
+
+ /* finally send it */
+ dbus_connection_send(conn, bereq->req->reply, NULL);
+ dbus_message_unref(bereq->req->reply);
+ talloc_free(bereq->req);
+ }
+
+done:
+ dbus_pending_call_unref(pending);
+ dbus_message_unref(reply);
+}
+
+static int dp_send_acct_req(struct dp_be_request *bereq,
+ uint32_t type, char *attrs, char *filter)
+{
+ DBusMessage *msg;
+ DBusPendingCall *pending_reply;
+ DBusConnection *conn;
+ DBusError dbus_error;
+ dbus_bool_t ret;
+
+ conn = sbus_get_connection(bereq->be_cli->conn_ctx);
+ dbus_error_init(&dbus_error);
+
+ /* create the message */
+ msg = dbus_message_new_method_call(NULL,
+ DP_CLI_PATH,
+ DP_CLI_INTERFACE,
+ DP_CLI_METHOD_GETACCTINFO);
+ if (msg == NULL) {
+ DEBUG(0,("Out of memory?!\n"));
+ return ENOMEM;
+ }
+
+ ret = dbus_message_append_args(msg,
+ DBUS_TYPE_UINT32, &type,
+ DBUS_TYPE_STRING, &attrs,
+ DBUS_TYPE_STRING, &filter,
+ DBUS_TYPE_INVALID);
+ if (!ret) {
+ DEBUG(1,("Failed to build message\n"));
+ return EIO;
+ }
+
+ ret = dbus_connection_send_with_reply(conn, msg, &pending_reply,
+ -1 /* TODO: set timeout */);
+ if (!ret) {
+ /*
+ * Critical Failure
+ * We can't communicate on this connection
+ * We'll drop it using the default destructor.
+ */
+ DEBUG(0, ("D-BUS send failed.\n"));
+ dbus_message_unref(msg);
+ return EIO;
+ }
+
+ /* Set up the reply handler */
+ dbus_pending_call_set_notify(pending_reply, be_got_account_info,
+ bereq, NULL);
+ dbus_message_unref(msg);
+
+ return EOK;
+}
+
+static int dp_get_account_info(DBusMessage *message, void *data, DBusMessage **r)
+{
+ struct sbus_message_handler_ctx *smh_ctx;
+ struct dp_client *dpcli;
+ struct dp_be_request *bereq;
+ struct dp_request *dpreq = NULL;
+ struct dp_backend *dpbe;
+ DBusMessage *reply;
+ DBusError dbus_error;
+ dbus_bool_t dbret;
+ void *user_data;
+ uint32_t type;
+ char *domain, *attrs, *filter;
+ const char *errmsg = NULL;
+ int dpret = 0, ret = 0;
+
+ if (!data) return EINVAL;
+ smh_ctx = talloc_get_type(data, struct sbus_message_handler_ctx);
+ if (!smh_ctx) return EINVAL;
+ user_data = sbus_conn_get_private_data(smh_ctx->conn_ctx);
+ if (!user_data) return EINVAL;
+ dpcli = talloc_get_type(user_data, struct dp_client);
+ if (!dpcli) return EINVAL;
+
+ dbus_error_init(&dbus_error);
+
+ ret = dbus_message_get_args(message, &dbus_error,
+ DBUS_TYPE_STRING, &domain,
+ DBUS_TYPE_UINT32, &type,
+ DBUS_TYPE_STRING, &attrs,
+ DBUS_TYPE_STRING, &filter,
+ DBUS_TYPE_INVALID);
+ if (!ret) {
+ DEBUG(1,("Failed, to parse message!\n"));
+ return EIO;
+ }
+
+ reply = dbus_message_new_method_return(message);
+
+ /* search for domain */
+ if (!domain) {
+ dpret = DP_ERR_FATAL;
+ errmsg = "Invalid Domain";
+ ret = EINVAL;
+ goto respond;
+ }
+
+ /* nothing to do for local */
+ if (strcasecmp(domain, "LOCAL") == 0) {
+ dpret = DP_ERR_OK;
+ errmsg = "Success";
+ ret = EOK;
+ goto respond;
+ }
+
+ /* all domains, fire off a request for each backend */
+ if (strcmp(domain, "*") == 0) {
+ dpreq = talloc(dpcli->dpctx, struct dp_request);
+ if (!dpreq) {
+ dpret = DP_ERR_FATAL;
+ errmsg = "Out of memory";
+ ret = ENOMEM;
+ goto respond;
+ }
+
+ dpreq->reply = reply;
+ dpreq->src_cli = dpcli;
+ dpreq->pending_replies = 0;
+
+ /* now fire off requests */
+ dpbe = dpcli->dpctx->be_list;
+ while (dpbe) {
+ bereq = talloc(dpreq, struct dp_be_request);
+ if (!bereq) {
+ DEBUG(1, ("Out of memory while sending requests\n"));
+ dpbe = dpbe->next;
+ continue;
+ }
+ bereq->req = dpreq;
+ bereq->be_cli = dpbe->dpcli;
+ ret = dp_send_acct_req(bereq, type, attrs, filter);
+ if (ret != EOK) {
+ DEBUG(2,("Failed to dispatch request to %s", dpbe->domain));
+ dpbe = dpbe->next;
+ continue;
+ }
+ dpreq->pending_replies++;
+ dpbe = dpbe->next;
+ }
+
+ if (dpreq->pending_replies == 0) {
+ dpret = DP_ERR_FATAL;
+ errmsg = "Unable to contact backends";
+ ret = EIO;
+ talloc_free(dpreq);
+ goto respond;
+ }
+
+ return EOK;
+ }
+
+ dpbe = dpcli->dpctx->be_list;
+ while (dpbe) {
+ if (strcasecmp(dpbe->domain, domain) == 0) {
+ break;
+ }
+
+ dpbe = dpbe->next;
+ }
+
+ if (dpbe) {
+ dpreq = talloc(dpcli->dpctx, struct dp_request);
+ if (!dpreq) {
+ DEBUG(1, ("Out of memory while sending request\n"));
+ dpret = DP_ERR_FATAL;
+ errmsg = "Out of memory";
+ ret = ENOMEM;
+ goto respond;
+ }
+
+ dpreq->reply = reply;
+ dpreq->src_cli = dpcli;
+ dpreq->pending_replies = 1;
+
+ bereq = talloc(dpreq, struct dp_be_request);
+ if (!bereq) {
+ DEBUG(1, ("Out of memory while sending request\n"));
+ dpret = DP_ERR_FATAL;
+ errmsg = "Out of memory";
+ ret = ENOMEM;
+ talloc_free(dpreq);
+ goto respond;
+ }
+ bereq->req = dpreq;
+ bereq->be_cli = dpbe->dpcli;
+
+ ret = dp_send_acct_req(bereq, type, attrs, filter);
+ if (ret != EOK) {
+ DEBUG(2,("Failed to dispatch request to %s", dpbe->domain));
+ dpret = DP_ERR_FATAL;
+ errmsg = "Dispatch Failed";
+ talloc_free(dpreq);
+ goto respond;
+ }
+
+ } else {
+
+ dpret = DP_ERR_FATAL;
+ errmsg = "Invalid Domain";
+ ret = EINVAL;
+ goto respond;
+ }
+
+ return EOK;
+
+respond:
+ dbret = dbus_message_append_args(reply,
+ DBUS_TYPE_UINT16, dpret,
+ DBUS_TYPE_UINT32, ret,
+ DBUS_TYPE_STRING, errmsg,
+ DBUS_TYPE_INVALID);
+ if (!dbret) return EIO;
+
+ *r = reply;
+ return EOK;
+}
+
static int dp_backend_destructor(void *ctx)
{
struct dp_backend *dpbe = talloc_get_type(ctx, struct dp_backend);
@@ -466,9 +791,9 @@ done:
return ret;
}
-int dp_process_init(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- struct confdb_ctx *cdb)
+static int dp_process_init(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct confdb_ctx *cdb)
{
struct dp_ctx *dpctx;
int ret;
diff --git a/server/providers/data_provider.h b/server/providers/data_provider.h
index a7712d08..bd610a53 100644
--- a/server/providers/data_provider.h
+++ b/server/providers/data_provider.h
@@ -24,12 +24,18 @@
#include <stdint.h>
#include <sys/un.h>
+#include <errno.h>
#include "talloc.h"
#include "tevent.h"
#include "ldb.h"
+#include "util/util.h"
+#include "confdb/confdb.h"
+#include "dbus/dbus.h"
+#include "sbus/sssd_dbus.h"
+#include "sbus_interfaces.h"
+#include "util/service_helpers.h"
#define DATA_PROVIDER_VERSION 0x0001
-#define BE_VERSION 0x0001
#define DATA_PROVIDER_SERVICE_NAME "dp"
#define DATA_PROVIDER_PIPE "private/sbus-dp"
@@ -48,9 +54,29 @@
#define DP_CLI_METHOD_IDENTITY "getIdentity"
#define DP_CLI_METHOD_ONLINE "getOnline"
+#define DP_CLI_METHOD_GETACCTINFO "getAccountInfo"
-struct dp_be_mod_ops {
- int (*check_online)(void *pvt_data, int *reply);
-};
+#define DP_SRV_METHOD_GETACCTINFO "getAccountInfo"
+
+#define DP_ERR_OK 0
+#define DP_ERR_OFFLINE 1
+#define DP_ERR_TIMEOUT 2
+#define DP_ERR_FATAL 3
+
+#define BE_ATTR_CORE 1
+#define BE_ATTR_MEM 2
+#define BE_ATTR_ALL 3
+
+#define BE_FILTER_NAME 1
+#define BE_FILTER_IDNUM 2
+
+#define BE_REQ_USER 1
+#define BE_REQ_GROUP 2
+
+int dp_sbus_cli_init(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct confdb_ctx *cdb,
+ struct sbus_method *methods,
+ struct service_sbus_ctx **srvs_ctx);
#endif /* __DATA_PROVIDER_ */
diff --git a/server/providers/data_provider_be.c b/server/providers/data_provider_be.c
index 060b4e7a..6f3f841f 100644
--- a/server/providers/data_provider_be.c
+++ b/server/providers/data_provider_be.c
@@ -1,7 +1,7 @@
/*
SSSD
- Data Provider Runner
+ Data Provider Process
Copyright (C) Simo Sorce <ssorce@redhat.com> 2008
@@ -38,45 +38,35 @@
#include "sbus/sssd_dbus.h"
#include "sbus_interfaces.h"
#include "util/btreemap.h"
-#include "providers/data_provider.h"
+#include "providers/dp_backend.h"
#include "util/service_helpers.h"
-struct be_ctx {
- struct event_context *ev;
- struct confdb_ctx *cdb;
- struct ldb_context *ldb;
- struct service_sbus_ctx *ss_ctx;
- struct service_sbus_ctx *dp_ctx;
- const char *name;
- const char *domain;
- const char *identity;
- struct dp_be_mod_ops *ops;
- void *pvt_data;
-};
-typedef int (*be_init_fn_t)(TALLOC_CTX *, struct dp_be_mod_ops **, void **);
+typedef int (*be_init_fn_t)(TALLOC_CTX *, struct be_mod_ops **, void **);
static int service_identity(DBusMessage *message, void *data, DBusMessage **r);
static int service_pong(DBusMessage *message, void *data, DBusMessage **r);
struct sbus_method mon_sbus_methods[] = {
- {SERVICE_METHOD_IDENTITY, service_identity},
- {SERVICE_METHOD_PING, service_pong},
- {NULL, NULL}
+ { SERVICE_METHOD_IDENTITY, service_identity },
+ { SERVICE_METHOD_PING, service_pong },
+ { NULL, NULL }
};
static int be_identity(DBusMessage *message, void *data, DBusMessage **r);
static int be_check_online(DBusMessage *message, void *data, DBusMessage **r);
+static int be_get_account_info(DBusMessage *message, void *data, DBusMessage **r);
struct sbus_method be_methods[] = {
{ DP_CLI_METHOD_IDENTITY, be_identity },
{ DP_CLI_METHOD_ONLINE, be_check_online },
+ { DP_CLI_METHOD_GETACCTINFO, be_get_account_info },
{ NULL, NULL }
};
static int service_identity(DBusMessage *message, void *data, DBusMessage **r)
{
- dbus_uint16_t version = BE_VERSION;
+ dbus_uint16_t version = DATA_PROVIDER_VERSION;
struct sbus_message_handler_ctx *smh_ctx;
struct be_ctx *ctx;
DBusMessage *reply;
@@ -123,7 +113,7 @@ static int service_pong(DBusMessage *message, void *data, DBusMessage **r)
static int be_identity(DBusMessage *message, void *data, DBusMessage **r)
{
- dbus_uint16_t version = BE_VERSION;
+ dbus_uint16_t version = DATA_PROVIDER_VERSION;
dbus_uint16_t clitype = DP_CLI_BACKEND;
struct sbus_message_handler_ctx *smh_ctx;
struct be_ctx *ctx;
@@ -175,7 +165,7 @@ static int be_check_online(DBusMessage *message, void *data, DBusMessage **r)
ctx = talloc_get_type(user_data, struct be_ctx);
if (!ctx) return EINVAL;
- ret = ctx->ops->check_online(ctx->pvt_data, &online);
+ ret = ctx->ops->check_online(ctx, &online);
if (ret != EOK) return ret;
reply = dbus_message_new_method_return(message);
@@ -188,6 +178,76 @@ static int be_check_online(DBusMessage *message, void *data, DBusMessage **r)
return EOK;
}
+static int be_get_account_info(DBusMessage *message, void *data, DBusMessage **r)
+{
+ struct sbus_message_handler_ctx *smh_ctx;
+ struct be_ctx *ctx;
+ DBusMessage *reply;
+ DBusError dbus_error;
+ dbus_bool_t dbret;
+ void *user_data;
+ uint32_t type;
+ char *attrs, *search_exp;
+ int attr_type, filter_type;
+ char *filter_val;
+ int ret;
+
+ if (!data) return EINVAL;
+ smh_ctx = talloc_get_type(data, struct sbus_message_handler_ctx);
+ if (!smh_ctx) return EINVAL;
+ user_data = sbus_conn_get_private_data(smh_ctx->conn_ctx);
+ if (!user_data) return EINVAL;
+ ctx = talloc_get_type(user_data, struct be_ctx);
+ if (!ctx) return EINVAL;
+
+ dbus_error_init(&dbus_error);
+
+ ret = dbus_message_get_args(message, &dbus_error,
+ DBUS_TYPE_UINT32, &type,
+ DBUS_TYPE_STRING, &attrs,
+ DBUS_TYPE_STRING, &search_exp,
+ DBUS_TYPE_INVALID);
+ if (!ret) {
+ DEBUG(1,("Failed, to parse message!\n"));
+ return EIO;
+ }
+
+ if (!attrs) {
+ if (strcmp(attrs, "core") == 0) attr_type = BE_ATTR_CORE;
+ else if (strcmp(attrs, "membership") == 0) attr_type = BE_ATTR_MEM;
+ else if (strcmp(attrs, "all") == 0) attr_type = BE_ATTR_ALL;
+ else return EINVAL;
+ }
+ else return EINVAL;
+
+ if (!search_exp) {
+ if (strncmp(search_exp, "name=", 5) == 0) {
+ filter_type = BE_FILTER_NAME;
+ filter_val = &search_exp[5];
+ } else if (strncmp(search_exp, "idnumber=", 9) == 0) {
+ filter_type = BE_FILTER_IDNUM;
+ filter_val = &search_exp[9];
+ } else return EINVAL;
+ }
+ else return EINVAL;
+
+ /* process request */
+ ret = ctx->ops->get_account_info(ctx, type, attr_type,
+ filter_type, filter_val);
+ if (ret != EOK) return ret;
+
+ reply = dbus_message_new_method_return(message);
+ dbret = dbus_message_append_args(reply,
+ DBUS_TYPE_UINT16, 0,
+ DBUS_TYPE_UINT32, 0,
+ DBUS_TYPE_STRING, "Success",
+ DBUS_TYPE_INVALID);
+ if (!dbret) return EIO;
+
+ *r = reply;
+ return EOK;
+}
+
/* mon_cli_init
* sbus channel to the monitor daemon */
static int mon_cli_init(struct be_ctx *ctx)
@@ -210,99 +270,16 @@ static int mon_cli_init(struct be_ctx *ctx)
return EOK;
}
-static int be_dp_sbus_init(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- struct confdb_ctx *cdb,
- const char *address,
- struct sbus_method *methods,
- struct service_sbus_ctx **srvs_ctx)
-{
- struct service_sbus_ctx *ss_ctx;
- struct sbus_method_ctx *sm_ctx;
- TALLOC_CTX *tmp_ctx;
- char *default_dp_address;
- char *sbus_address;
- DBusConnection *conn;
- int ret;
-
- tmp_ctx = talloc_new(mem_ctx);
- if (tmp_ctx == NULL) {
- ret = ENOMEM;
- goto done;
- }
-
- ss_ctx = talloc_zero(tmp_ctx, struct service_sbus_ctx);
- if (ss_ctx == NULL) {
- ret = ENOMEM;
- goto done;
- }
- ss_ctx->ev = ev;
-
- default_dp_address = talloc_asprintf(tmp_ctx, "unix:path=%s/%s",
- PIPE_PATH, DATA_PROVIDER_PIPE);
- if (default_dp_address == NULL) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = confdb_get_string(cdb, tmp_ctx,
- "config/services/dp", "sbusAddress",
- default_dp_address, &sbus_address);
- if (ret != EOK) goto done;
-
- ret = sbus_new_connection(ss_ctx, ss_ctx->ev,
- sbus_address, &ss_ctx->scon_ctx,
- NULL);
- if (ret != EOK) goto done;
-
- conn = sbus_get_connection(ss_ctx->scon_ctx);
-
- /* set up handler for service methods */
- sm_ctx = talloc_zero(ss_ctx, struct sbus_method_ctx);
- if (sm_ctx == NULL) {
- ret = ENOMEM;
- goto done;
- }
-
- sm_ctx->interface = talloc_strdup(sm_ctx, DATA_PROVIDER_INTERFACE);
- sm_ctx->path = talloc_strdup(sm_ctx, DATA_PROVIDER_PATH);
- if (!sm_ctx->interface || !sm_ctx->path) {
- ret = ENOMEM;
- goto done;
- }
-
- /* Set up required monitor methods */
- sm_ctx->methods = methods;
-
- sm_ctx->message_handler = sbus_message_handler;
- sbus_conn_add_method_ctx(ss_ctx->scon_ctx, sm_ctx);
-
- talloc_steal(mem_ctx, ss_ctx);
- *srvs_ctx = ss_ctx;
- ret = EOK;
-
-done:
- talloc_free(tmp_ctx);
- return ret;
-}
-
/* be_cli_init
* sbus channel to the data provider daemon */
static int be_cli_init(struct be_ctx *ctx)
{
struct service_sbus_ctx *dp_ctx;
- char *default_dp_address;
int ret;
- default_dp_address = talloc_asprintf(ctx, "unix:path=%s/%s",
- PIPE_PATH, DATA_PROVIDER_PIPE);
- if (!default_dp_address) return ENOMEM;
-
- ret = be_dp_sbus_init(ctx, ctx->ev, ctx->cdb,
- default_dp_address, be_methods,
- &dp_ctx);
+ ret = dp_sbus_cli_init(ctx, ctx->ev, ctx->cdb,
+ be_methods, &dp_ctx);
if (ret != EOK) {
- talloc_free(default_dp_address);
return ret;
}
@@ -311,51 +288,6 @@ static int be_cli_init(struct be_ctx *ctx)
/* attach be context to the connection */
sbus_conn_set_private_data(dp_ctx->scon_ctx, ctx);
- talloc_free(default_dp_address);
- return EOK;
-}
-
-static int be_db_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;
}
@@ -440,9 +372,9 @@ int be_process_init(TALLOC_CTX *mem_ctx,
return ENOMEM;
}
- ret = be_db_init(ctx);
+ ret = dp_be_cachedb_init(ctx);
if (ret != EOK) {
- DEBUG(0, ("fatal error opening database\n"));
+ DEBUG(0, ("fatal error opening cache database\n"));
return ret;
}
@@ -513,6 +445,8 @@ int main(int argc, const char *argv[])
main_ctx->confdb_ctx);
if (ret != EOK) return 3;
+ DEBUG(1, ("Backend provider %s(%s) started!", be_name, be_domain));
+
/* loop on main */
server_loop(main_ctx);
diff --git a/server/providers/dp_backend.h b/server/providers/dp_backend.h
new file mode 100644
index 00000000..81df6b7d
--- /dev/null
+++ b/server/providers/dp_backend.h
@@ -0,0 +1,57 @@
+/*
+ SSSD
+
+ Data Provider, private header file
+
+ 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/>.
+*/
+
+#ifndef __DP_BACKEND_H__
+#define __DP_BACKEND_H__
+
+#include "providers/data_provider.h"
+
+struct be_mod_ops;
+
+struct be_ctx {
+ struct event_context *ev;
+ struct confdb_ctx *cdb;
+ struct ldb_context *ldb;
+ struct service_sbus_ctx *ss_ctx;
+ struct service_sbus_ctx *dp_ctx;
+ const char *name;
+ const char *domain;
+ const char *identity;
+ struct be_mod_ops *ops;
+ void *pvt_data;
+};
+
+struct be_mod_ops {
+ int (*check_online)(struct be_ctx *, int *reply);
+ int (*get_account_info)(struct be_ctx *,
+ int entry_type, int attr_type,
+ int filter_type, char *filter_value);
+};
+
+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);
+int dp_be_remove_account_posix(struct be_ctx *ctx, char *name);
+
+int dp_be_cachedb_init(struct be_ctx *ctx);
+
+#endif /* __DP_BACKEND_H___ */
diff --git a/server/providers/dp_backend_store.c b/server/providers/dp_backend_store.c
new file mode 100644
index 00000000..e518f438
--- /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;
+}
+
diff --git a/server/providers/dp_helpers.c b/server/providers/dp_helpers.c
new file mode 100644
index 00000000..99d65f45
--- /dev/null
+++ b/server/providers/dp_helpers.c
@@ -0,0 +1,98 @@
+/*
+ SSSD
+
+ Data Provider Helpers
+
+ 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 "providers/data_provider.h"
+
+int dp_sbus_cli_init(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct confdb_ctx *cdb,
+ struct sbus_method *methods,
+ struct service_sbus_ctx **srvs_ctx)
+{
+ struct service_sbus_ctx *ss_ctx;
+ struct sbus_method_ctx *sm_ctx;
+ TALLOC_CTX *tmp_ctx;
+ char *default_dp_address;
+ char *sbus_address;
+ DBusConnection *conn;
+ int ret;
+
+ tmp_ctx = talloc_new(mem_ctx);
+ if (tmp_ctx == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ss_ctx = talloc_zero(tmp_ctx, struct service_sbus_ctx);
+ if (ss_ctx == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ ss_ctx->ev = ev;
+
+ default_dp_address = talloc_asprintf(tmp_ctx, "unix:path=%s/%s",
+ PIPE_PATH, DATA_PROVIDER_PIPE);
+ if (default_dp_address == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = confdb_get_string(cdb, tmp_ctx,
+ "config/services/dp", "sbusAddress",
+ default_dp_address, &sbus_address);
+ if (ret != EOK) goto done;
+
+ ret = sbus_new_connection(ss_ctx, ss_ctx->ev,
+ sbus_address, &ss_ctx->scon_ctx,
+ NULL);
+ if (ret != EOK) goto done;
+
+ conn = sbus_get_connection(ss_ctx->scon_ctx);
+
+ /* set up handler for service methods */
+ sm_ctx = talloc_zero(ss_ctx, struct sbus_method_ctx);
+ if (sm_ctx == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ sm_ctx->interface = talloc_strdup(sm_ctx, DATA_PROVIDER_INTERFACE);
+ sm_ctx->path = talloc_strdup(sm_ctx, DATA_PROVIDER_PATH);
+ if (!sm_ctx->interface || !sm_ctx->path) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ /* Set up required monitor methods */
+ sm_ctx->methods = methods;
+
+ sm_ctx->message_handler = sbus_message_handler;
+ sbus_conn_add_method_ctx(ss_ctx->scon_ctx, sm_ctx);
+
+ talloc_steal(mem_ctx, ss_ctx);
+ *srvs_ctx = ss_ctx;
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
diff --git a/server/providers/ldap_provider.c b/server/providers/ldap_provider.c
index a6628f40..884f843e 100644
--- a/server/providers/ldap_provider.c
+++ b/server/providers/ldap_provider.c
@@ -24,7 +24,7 @@
#include <pwd.h>
#include <grp.h>
#include "util/util.h"
-#include "providers/data_provider.h"
+#include "providers/dp_backend.h"
struct ldap_nss_ops {
enum nss_status (*getpwnam_r)(const char *name, struct passwd *result,
@@ -54,19 +54,104 @@ struct ldap_ctx {
struct ldap_nss_ops ops;
};
-static int ldap_check_online(void *pvt_data, int *reply);
+static int get_pw_name(struct be_ctx *be_ctx, struct ldap_ctx *ldap_ctx, char *name)
+{
+ struct ldap_nss_ops *ops = &ldap_ctx->ops;
+ enum nss_status status;
+ struct passwd result;
+ char *buffer;
+ int ret;
+
+ buffer = talloc_size(NULL, 4096);
+ if (!buffer) return ENOMEM;
+
+ status = ops->getpwnam_r(name, &result, buffer, 4096, &ret);
+
+ switch (status) {
+ case NSS_STATUS_NOTFOUND:
+ ret = dp_be_remove_account_posix(be_ctx, name);
+ break;
+ case NSS_STATUS_SUCCESS:
+ ret = dp_be_store_account_posix(be_ctx, name, result.pw_passwd,
+ result.pw_uid, result.pw_gid,
+ result.pw_gecos, result.pw_dir,
+ result.pw_shell);
+ break;
+ default:
+ DEBUG(2, ("ldap->getpwnam_r failed for '%s' (%d)[%s]\n",
+ name, ret, strerror(ret)));
+ talloc_free(buffer);
+ return ret;
+ }
+
+ if (ret != EOK) {
+ DEBUG(1, ("Failed to update LDB Cache for '%s' (%d) !?\n",
+ name, ret));
+ }
+
+ talloc_free(buffer);
+ return ret;
+}
-struct dp_be_mod_ops ldap_mod_ops = {
- .check_online = ldap_check_online
+static int ldap_check_online(struct be_ctx *be_ctx, int *reply);
+static int ldap_get_account_info(struct be_ctx *be_ctx,
+ int entry_type, int attr_type,
+ int filter_type, char *filter_value);
+
+struct be_mod_ops ldap_mod_ops = {
+ .check_online = ldap_check_online,
+ .get_account_info = ldap_get_account_info
};
-static int ldap_check_online(void *pvt_data, int *reply)
+static int ldap_check_online(struct be_ctx *be_ctx, int *reply)
{
*reply = MOD_ONLINE;
return EOK;
}
-int sssm_ldap_init(TALLOC_CTX *bectx, struct dp_be_mod_ops **ops, void **pvt_data)
+static int ldap_get_account_info(struct be_ctx *be_ctx,
+ int entry_type, int attr_type,
+ int filter_type, char *filter_value)
+{
+ struct ldap_ctx *ctx;
+
+ ctx = talloc_get_type(be_ctx->pvt_data, struct ldap_ctx);
+
+ switch (entry_type) {
+ case BE_REQ_USER: /* user */
+ switch (filter_type) {
+ case BE_FILTER_NAME:
+ switch (attr_type) {
+ case BE_ATTR_CORE:
+ if (strchr(filter_value, '*')) {
+ /* TODO */
+ } else {
+ return get_pw_name(be_ctx, ctx, filter_value);
+ }
+ break;
+ default:
+ return EINVAL;
+ }
+ break;
+ case BE_FILTER_IDNUM:
+ break;
+ default:
+ return EINVAL;
+ }
+ break;
+
+ case BE_REQ_GROUP: /* group */
+ /* TODO */
+ return EOK;
+
+ default: /*fail*/
+ return EINVAL;
+ }
+
+ return EOK;
+}
+
+int sssm_ldap_init(struct be_ctx *bectx, struct be_mod_ops **ops, void **pvt_data)
{
struct ldap_ctx *ctx;
void *handle;