diff options
author | Sumit Bose <sbose@redhat.com> | 2009-07-14 21:12:30 +0200 |
---|---|---|
committer | Sumit Bose <sbose@redhat.com> | 2009-07-14 21:12:30 +0200 |
commit | e4cf358b4b675ade617a17f8597f09da7852774e (patch) | |
tree | 54155a461c3a8006302d199f076955e2c5b407a5 | |
parent | 7f5e857a11f932c247b5a96d0d86768226ba2e96 (diff) | |
download | sssd-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.c | 222 | ||||
-rw-r--r-- | server/providers/dp_backend.h | 32 | ||||
-rw-r--r-- | server/providers/krb5/krb5_auth.c | 2 | ||||
-rw-r--r-- | server/providers/ldap/ldap_auth.c | 2 | ||||
-rw-r--r-- | server/providers/proxy.c | 4 |
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); } |