summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2009-07-14 21:12:30 +0200
committerSumit Bose <sbose@redhat.com>2009-07-14 21:12:30 +0200
commite4cf358b4b675ade617a17f8597f09da7852774e (patch)
tree54155a461c3a8006302d199f076955e2c5b407a5
parent7f5e857a11f932c247b5a96d0d86768226ba2e96 (diff)
downloadsssd-e4cf358b4b675ade617a17f8597f09da7852774e.tar.gz
sssd-e4cf358b4b675ade617a17f8597f09da7852774e.tar.xz
sssd-e4cf358b4b675ade617a17f8597f09da7852774e.zip
add infrastructure to handle new backend targetsnew_backend_target
-rw-r--r--server/providers/data_provider_be.c222
-rw-r--r--server/providers/dp_backend.h32
-rw-r--r--server/providers/krb5/krb5_auth.c2
-rw-r--r--server/providers/ldap/ldap_auth.c2
-rw-r--r--server/providers/proxy.c4
5 files changed, 203 insertions, 59 deletions
diff --git a/server/providers/data_provider_be.c b/server/providers/data_provider_be.c
index 6cd86e896..370bbaa67 100644
--- a/server/providers/data_provider_be.c
+++ b/server/providers/data_provider_be.c
@@ -71,6 +71,17 @@ struct sbus_method be_methods[] = {
{ NULL, NULL }
};
+static struct be_target_data be_target_data[] = {
+ {BE_TARGET_NULL, NULL, NULL},
+ {BE_TARGET_ID, NULL, NULL},
+ {BE_TARGET_AUTH, "auth-module", "sssm_%s_auth_init"},
+ {BE_TARGET_ACCESS, "access-module", "sssm_%s_access_init"},
+ {BE_TARGET_CHPASS, "chpass-module", "sssm_%s_chpass_init"},
+ {BE_TARGET_MAX, NULL, NULL}
+};
+
+
+
static int service_identity(DBusMessage *message, struct sbus_conn_ctx *sconn)
{
dbus_uint16_t version = DATA_PROVIDER_VERSION;
@@ -548,6 +559,7 @@ static int be_pam_handler(DBusMessage *message, struct sbus_conn_ctx *sconn)
struct pam_data *pd = NULL;
struct be_req *be_req = NULL;
uint32_t pam_status = PAM_SYSTEM_ERR;
+ enum be_target target = BE_TARGET_NULL;
user_data = sbus_conn_get_private_data(sconn);
if (!user_data) return EINVAL;
@@ -561,10 +573,6 @@ static int be_pam_handler(DBusMessage *message, struct sbus_conn_ctx *sconn)
return ENOMEM;
}
- /* return an error if no auth backend is configured */
- if (!ctx->auth_ops)
- goto done;
-
pd = talloc_zero(ctx, struct pam_data);
if (!pd) return ENOMEM;
@@ -580,6 +588,29 @@ static int be_pam_handler(DBusMessage *message, struct sbus_conn_ctx *sconn)
DEBUG(4, ("Got request with the following data\n"));
DEBUG_PAM_DATA(4, pd);
+ switch (pd->cmd) {
+ case SSS_PAM_AUTHENTICATE:
+ target = BE_TARGET_AUTH;
+ break;
+ case SSS_PAM_ACCT_MGMT:
+ target = BE_TARGET_ACCESS;
+ break;
+ case SSS_PAM_CHAUTHTOK:
+ target = BE_TARGET_CHPASS;
+ break;
+ default:
+ DEBUG(7, ("Unsupported PAM command [%d].\n", pd->cmd));
+ pam_status = PAM_SUCCESS;
+ ret = EOK;
+ goto done;
+ }
+
+ /* return an error if corresponding backend target is configured */
+ if (!ctx->be_target_info[target].target_ops) {
+ DEBUG(7, ("Undefined backend target.\n"));
+ goto done;
+ }
+
be_req = talloc_zero(ctx, struct be_req);
if (!be_req)
goto done;
@@ -589,7 +620,7 @@ static int be_pam_handler(DBusMessage *message, struct sbus_conn_ctx *sconn)
be_req->pvt = reply;
be_req->req_data = pd;
- ret = be_file_request(ctx, ctx->auth_ops->pam_handler, be_req);
+ ret = be_file_request(ctx, ctx->be_target_info[target].target_ops->pam_handler, be_req);
if (ret != EOK)
goto done;
@@ -793,9 +824,9 @@ static int be_finalize(struct be_ctx *ctx)
shutdown_req->be_ctx = ctx;
shutdown_req->fn = be_id_shutdown;
- shutdown_req->pvt = ctx->pvt_auth_data;
+ shutdown_req->pvt = ctx->be_target_info[BE_TARGET_AUTH].pvt_target_data;
- ret = be_file_request(ctx, ctx->auth_ops->finalize, shutdown_req);
+ ret = be_file_request(ctx, ctx->be_target_info[BE_TARGET_AUTH].target_ops->finalize, shutdown_req);
if (ret == EOK) return EOK;
fail:
@@ -804,53 +835,122 @@ fail:
return ret;
}
-static int load_id_backend(struct be_ctx *ctx)
+static void be_target_access_permit(struct be_req *be_req)
+{
+ struct pam_data *pd = talloc_get_type(be_req->req_data, struct pam_data);
+ DEBUG(9, ("be_target_access_permit called, returning PAM_SUCCESS.\n"));
+
+ pd->pam_status = PAM_SUCCESS;
+ be_req->fn(be_req, PAM_SUCCESS, NULL);
+}
+
+static struct be_auth_ops be_target_access_permit_ops = {
+ .pam_handler = be_target_access_permit,
+ .finalize = NULL
+};
+
+static int load_backend_module(struct be_ctx *ctx,
+ enum be_target be_target,
+ struct be_auth_ops **be_ops,
+ void **be_pvt_data)
{
TALLOC_CTX *tmp_ctx;
- char *path;
+ int ret = EINVAL;
+ bool already_loaded = false;
+ int lb=0;
+ char *mod_name = NULL;
+ char *path = NULL;
void *handle;
- char *mod_init_fn_name;
- be_id_init_fn_t mod_init_fn;
- int ret;
+ char *mod_init_fn_name = NULL;
+ be_auth_init_fn_t mod_init_fn = NULL;
+
+ if (be_target <= BE_TARGET_NULL || be_target >= BE_TARGET_MAX ||
+ be_target != be_target_data[be_target].be_target) {
+ DEBUG(2, ("invalid be_target or be_target_data corrupted.\n"));
+ return EINVAL;
+ }
+ if (be_target == BE_TARGET_ID) {
+ DEBUG(2, ("BE_TARGET_ID not implemented.\n"));
+ return ENOSYS;
+ }
tmp_ctx = talloc_new(ctx);
if (!tmp_ctx) {
+ DEBUG(7, ("talloc_new failed.\n"));
return ENOMEM;
}
- path = talloc_asprintf(tmp_ctx, "%s/libsss_%s.so",
- DATA_PROVIDER_PLUGINS_PATH, ctx->name);
- if (!path) {
- ret = ENOMEM;
+ ret = confdb_get_string(ctx->cdb, tmp_ctx, ctx->conf_path,
+ be_target_data[be_target].option_name, NULL,
+ &mod_name);
+ if (ret != EOK) {
+ ret = EFAULT;
goto done;
}
-
- handle = dlopen(path, RTLD_NOW);
- if (!handle) {
- DEBUG(0, ("Unable to load %s module with path (%s), error: %s\n",
- ctx->name, path, dlerror()));
- ret = ELIBACC;
+ if (!mod_name) {
+ ret = ENOENT;
goto done;
}
- mod_init_fn_name = talloc_asprintf(tmp_ctx, "sssm_%s_init", ctx->name);
- if (!mod_init_fn_name) {
+ mod_init_fn_name = talloc_asprintf(tmp_ctx,
+ be_target_data[be_target].mod_init_fn_name_fmt,
+ mod_name);
+ if (mod_init_fn_name == NULL) {
+ DEBUG(7, ("talloc_asprintf failed\n"));
ret = ENOMEM;
goto done;
}
- mod_init_fn = (be_id_init_fn_t)dlsym(handle, mod_init_fn_name);
- if (!mod_init_fn) {
- DEBUG(0, ("Unable to load init fn from module %s, error: %s\n",
- ctx->name, dlerror()));
+
+ lb = 0;
+ while(ctx->loaded_be[lb].be_name != NULL) {
+ if (strncmp(ctx->loaded_be[lb].be_name, mod_name,
+ strlen(mod_name)) == 0) {
+ DEBUG(7, ("Backend [%s] already loaded.\n", mod_name));
+ already_loaded = true;
+ break;
+ }
+
+ ++lb;
+ if (lb >= BE_TARGET_MAX) {
+ DEBUG(2, ("Backend context corrupted.\n"));
+ return EINVAL;
+ }
+ }
+
+ if (!already_loaded) {
+ path = talloc_asprintf(tmp_ctx, "%s/libsss_%s.so",
+ DATA_PROVIDER_PLUGINS_PATH, mod_name);
+ if (!path) {
+ return ENOMEM;
+ }
+
+ DEBUG(7, ("Loading backend [%s] with path [%s].\n", mod_name, path));
+ handle = dlopen(path, RTLD_NOW);
+ if (!handle) {
+ DEBUG(0, ("Unable to load %s module with path (%s), error: %s\n",
+ mod_name, path, dlerror()));
+ ret = ELIBACC;
+ goto done;
+ }
+
+ ctx->loaded_be[lb].be_name = talloc_strdup(ctx, mod_name);
+ ctx->loaded_be[lb].handle = handle;
+ }
+
+ mod_init_fn = (be_auth_init_fn_t)dlsym(ctx->loaded_be[lb].handle,
+ mod_init_fn_name);
+ if (mod_init_fn == NULL) {
+ DEBUG(0, ("Unable to load init fn %s from module %s, error: %s\n",
+ mod_init_fn_name, mod_name, dlerror()));
ret = ELIBBAD;
goto done;
}
- ret = mod_init_fn(ctx, &ctx->id_ops, &ctx->pvt_id_data);
+ ret = mod_init_fn(ctx, be_ops, be_pvt_data);
if (ret != EOK) {
- DEBUG(0, ("Error (%d) in module (%s) initialization!\n",
- ret, ctx->name));
+ DEBUG(0, ("Error (%d) in module (%s) initialization (%s)!\n",
+ ret, mod_name, mod_init_fn_name));
goto done;
}
@@ -861,14 +961,13 @@ done:
return ret;
}
-static int load_auth_backend(struct be_ctx *ctx)
+static int load_id_backend(struct be_ctx *ctx)
{
TALLOC_CTX *tmp_ctx;
- char *mod_name;
char *path;
void *handle;
char *mod_init_fn_name;
- be_auth_init_fn_t mod_init_fn;
+ be_id_init_fn_t mod_init_fn;
int ret;
tmp_ctx = talloc_new(ctx);
@@ -876,19 +975,8 @@ static int load_auth_backend(struct be_ctx *ctx)
return ENOMEM;
}
- ret = confdb_get_string(ctx->cdb, tmp_ctx, ctx->conf_path,
- "auth-module", NULL, &mod_name);
- if (ret != EOK) {
- ret = EFAULT;
- goto done;
- }
- if (!mod_name) {
- ret = ENOENT;
- goto done;
- }
-
path = talloc_asprintf(tmp_ctx, "%s/libsss_%s.so",
- DATA_PROVIDER_PLUGINS_PATH, mod_name);
+ DATA_PROVIDER_PLUGINS_PATH, ctx->name);
if (!path) {
ret = ENOMEM;
goto done;
@@ -897,29 +985,29 @@ static int load_auth_backend(struct be_ctx *ctx)
handle = dlopen(path, RTLD_NOW);
if (!handle) {
DEBUG(0, ("Unable to load %s module with path (%s), error: %s\n",
- mod_name, path, dlerror()));
+ ctx->name, path, dlerror()));
ret = ELIBACC;
goto done;
}
- mod_init_fn_name = talloc_asprintf(tmp_ctx, "sssm_%s_auth_init", mod_name);
+ mod_init_fn_name = talloc_asprintf(tmp_ctx, "sssm_%s_init", ctx->name);
if (!mod_init_fn_name) {
ret = ENOMEM;
goto done;
}
- mod_init_fn = (be_auth_init_fn_t)dlsym(handle, mod_init_fn_name);
+ mod_init_fn = (be_id_init_fn_t)dlsym(handle, mod_init_fn_name);
if (!mod_init_fn) {
DEBUG(0, ("Unable to load init fn from module %s, error: %s\n",
- mod_name, dlerror()));
+ ctx->name, dlerror()));
ret = ELIBBAD;
goto done;
}
- ret = mod_init_fn(ctx, &ctx->auth_ops, &ctx->pvt_auth_data);
+ ret = mod_init_fn(ctx, &ctx->id_ops, &ctx->pvt_id_data);
if (ret != EOK) {
DEBUG(0, ("Error (%d) in module (%s) initialization!\n",
- ret, mod_name));
+ ret, ctx->name));
goto done;
}
@@ -984,7 +1072,9 @@ int be_process_init(TALLOC_CTX *mem_ctx,
return ret;
}
- ret = load_auth_backend(ctx);
+ ret = load_backend_module(ctx, BE_TARGET_AUTH,
+ &ctx->be_target_info[BE_TARGET_AUTH].target_ops,
+ &ctx->be_target_info[BE_TARGET_AUTH].pvt_target_data);
if (ret != EOK) {
if (ret != ENOENT) {
DEBUG(0, ("fatal error initializing data providers\n"));
@@ -994,6 +1084,32 @@ int be_process_init(TALLOC_CTX *mem_ctx,
be_domain));
}
+ ret = load_backend_module(ctx, BE_TARGET_ACCESS,
+ &ctx->be_target_info[BE_TARGET_ACCESS].target_ops,
+ &ctx->be_target_info[BE_TARGET_ACCESS].pvt_target_data);
+ if (ret != EOK) {
+ if (ret != ENOENT) {
+ DEBUG(0, ("fatal error initializing data providers\n"));
+ return ret;
+ }
+ DEBUG(1, ("No access control module provided for [%s] "
+ "using be_target_access_permit!!\n", be_domain));
+ ctx->be_target_info[BE_TARGET_ACCESS].target_ops = &be_target_access_permit_ops;
+ ctx->be_target_info[BE_TARGET_ACCESS].pvt_target_data = NULL;
+ }
+
+ ret = load_backend_module(ctx, BE_TARGET_CHPASS,
+ &ctx->be_target_info[BE_TARGET_CHPASS].target_ops,
+ &ctx->be_target_info[BE_TARGET_CHPASS].pvt_target_data);
+ if (ret != EOK) {
+ if (ret != ENOENT) {
+ DEBUG(0, ("fatal error initializing data providers\n"));
+ return ret;
+ }
+ DEBUG(1, ("No change password module provided for [%s] !!\n",
+ be_domain));
+ }
+
return EOK;
}
diff --git a/server/providers/dp_backend.h b/server/providers/dp_backend.h
index 27f79eb7a..3a07827a8 100644
--- a/server/providers/dp_backend.h
+++ b/server/providers/dp_backend.h
@@ -36,6 +36,33 @@ typedef void (*be_shutdown_fn)(void *);
typedef void (*be_req_fn_t)(struct be_req *);
typedef void (*be_async_callback_t)(struct be_req *, int, const char *);
+enum be_target {
+ BE_TARGET_NULL = 0,
+ BE_TARGET_ID,
+ BE_TARGET_AUTH,
+ BE_TARGET_ACCESS,
+ BE_TARGET_CHPASS,
+ BE_TARGET_MAX
+};
+
+struct be_target_data {
+ enum be_target be_target;
+ const char *option_name;
+ const char *mod_init_fn_name_fmt;
+};
+
+struct loaded_be {
+ char *be_name;
+ void *handle;
+};
+
+struct be_target_info {
+ enum be_target be_target;
+ struct be_auth_ops *target_ops;
+ void *pvt_target_data;
+};
+
+
struct be_ctx {
struct tevent_context *ev;
struct confdb_ctx *cdb;
@@ -47,11 +74,12 @@ struct be_ctx {
const char *identity;
const char *conf_path;
+ struct loaded_be loaded_be[BE_TARGET_MAX];
+
struct be_id_ops *id_ops;
void *pvt_id_data;
- struct be_auth_ops *auth_ops;
- void *pvt_auth_data;
+ struct be_target_info be_target_info[BE_TARGET_MAX];
};
struct be_id_ops {
diff --git a/server/providers/krb5/krb5_auth.c b/server/providers/krb5/krb5_auth.c
index 2cbdc993b..5b2483f89 100644
--- a/server/providers/krb5/krb5_auth.c
+++ b/server/providers/krb5/krb5_auth.c
@@ -88,7 +88,7 @@ static int krb5_setup(struct be_req *req, struct krb5_req **krb5_req)
pd = talloc_get_type(req->req_data, struct pam_data);
- krb5_ctx = talloc_get_type(req->be_ctx->pvt_auth_data, struct krb5_ctx);
+ krb5_ctx = talloc_get_type(req->be_ctx->be_target_info[BE_TARGET_AUTH].pvt_target_data, struct krb5_ctx);
kr = talloc_zero(req, struct krb5_req);
if (kr == NULL) {
diff --git a/server/providers/ldap/ldap_auth.c b/server/providers/ldap/ldap_auth.c
index e36338577..df5ad0af2 100644
--- a/server/providers/ldap/ldap_auth.c
+++ b/server/providers/ldap/ldap_auth.c
@@ -322,7 +322,7 @@ static void sdap_pam_auth_send(struct be_req *breq)
struct tevent_req *subreq;
struct pam_data *pd;
- ctx = talloc_get_type(breq->be_ctx->pvt_auth_data, struct sdap_auth_ctx);
+ ctx = talloc_get_type(breq->be_ctx->be_target_info[BE_TARGET_AUTH].pvt_target_data, struct sdap_auth_ctx);
pd = talloc_get_type(breq->req_data, struct pam_data);
pd->pam_status = PAM_SYSTEM_ERR;
diff --git a/server/providers/proxy.c b/server/providers/proxy.c
index 23360945b..762e90e4a 100644
--- a/server/providers/proxy.c
+++ b/server/providers/proxy.c
@@ -171,7 +171,7 @@ static void proxy_pam_handler(struct be_req *req) {
struct proxy_auth_ctx *ctx;;
bool cache_auth_data = false;
- ctx = talloc_get_type(req->be_ctx->pvt_auth_data, struct proxy_auth_ctx);
+ ctx = talloc_get_type(req->be_ctx->be_target_info[BE_TARGET_AUTH].pvt_target_data, struct proxy_auth_ctx);
pd = talloc_get_type(req->req_data, struct pam_data);
conv.conv=proxy_internal_conv;
@@ -2053,7 +2053,7 @@ static void proxy_shutdown(struct be_req *req)
static void proxy_auth_shutdown(struct be_req *req)
{
- talloc_free(req->be_ctx->pvt_auth_data);
+ talloc_free(req->be_ctx->be_target_info[BE_TARGET_AUTH].pvt_target_data);
req->fn(req, EOK, NULL);
}