diff options
Diffstat (limited to 'src/providers/proxy/proxy_init.c')
-rw-r--r-- | src/providers/proxy/proxy_init.c | 675 |
1 files changed, 248 insertions, 427 deletions
diff --git a/src/providers/proxy/proxy_init.c b/src/providers/proxy/proxy_init.c index 0a6b11d4a..3a4cee91e 100644 --- a/src/providers/proxy/proxy_init.c +++ b/src/providers/proxy/proxy_init.c @@ -27,60 +27,26 @@ #include "util/sss_format.h" #include "providers/proxy/proxy.h" -static int client_registration(struct sbus_request *dbus_req, void *data); - -static struct data_provider_iface proxy_methods = { - { &data_provider_iface_meta, 0 }, - .RegisterService = client_registration, - .pamHandler = NULL, - .sudoHandler = NULL, - .autofsHandler = NULL, - .hostHandler = NULL, - .getDomains = NULL, - .getAccountInfo = NULL, -}; - -static void proxy_shutdown(struct be_req *req) -{ - /* TODO: Clean up any internal data */ - be_req_terminate(req, DP_ERR_OK, EOK, NULL); -} - -static void proxy_auth_shutdown(struct be_req *req) -{ - struct be_ctx *be_ctx = be_req_get_be_ctx(req); - talloc_free(be_ctx->bet_info[BET_AUTH].pvt_bet_data); - be_req_terminate(req, DP_ERR_OK, EOK, NULL); -} - -struct bet_ops proxy_id_ops = { - .handler = proxy_get_account_info, - .finalize = proxy_shutdown, - .check_online = NULL -}; - -struct bet_ops proxy_auth_ops = { - .handler = proxy_pam_handler, - .finalize = proxy_auth_shutdown -}; - -struct bet_ops proxy_access_ops = { - .handler = proxy_pam_handler, - .finalize = proxy_auth_shutdown -}; - -struct bet_ops proxy_chpass_ops = { - .handler = proxy_pam_handler, - .finalize = proxy_auth_shutdown -}; - -static void *proxy_dlsym(void *handle, const char *functemp, char *libname) +#define NSS_FN_NAME "_nss_%s_%s" + +#define ERROR_INITGR "The '%s' library does not provides the " \ + "_nss_XXX_initgroups_dyn function!\n" \ + "initgroups will be slow as it will require " \ + "full groups enumeration!\n" +#define ERROR_NETGR "The '%s' library does not support netgroups.\n" +#define ERROR_SERV "The '%s' library does not support services.\n" + +static void *proxy_dlsym(void *handle, + const char *name, + const char *libname) { char *funcname; void *funcptr; - funcname = talloc_asprintf(NULL, functemp, libname); - if (funcname == NULL) return NULL; + funcname = talloc_asprintf(NULL, NSS_FN_NAME, libname, name); + if (funcname == NULL) { + return NULL; + } funcptr = dlsym(handle, funcname); talloc_free(funcname); @@ -88,476 +54,331 @@ static void *proxy_dlsym(void *handle, const char *functemp, char *libname) return funcptr; } -int sssm_proxy_id_init(struct be_ctx *bectx, - struct bet_ops **ops, void **pvt_data) +static errno_t proxy_id_conf(TALLOC_CTX *mem_ctx, + struct be_ctx *be_ctx, + char **_libname, + char **_libpath, + bool *_fast_alias) { - struct proxy_id_ctx *ctx; + TALLOC_CTX *tmp_ctx; char *libname; char *libpath; - int ret; + bool fast_alias; + errno_t ret; - ctx = talloc_zero(bectx, struct proxy_id_ctx); - if (!ctx) { + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } - ctx->be = bectx; - ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path, + ret = confdb_get_string(be_ctx->cdb, tmp_ctx, be_ctx->conf_path, CONFDB_PROXY_LIBNAME, NULL, &libname); - if (ret != EOK) goto done; - if (libname == NULL) { + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read confdb [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } else if (libname == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "No library name given\n"); ret = ENOENT; goto done; } - ret = confdb_get_bool(bectx->cdb, bectx->conf_path, - CONFDB_PROXY_FAST_ALIAS, false, &ctx->fast_alias); - if (ret != EOK) goto done; - - libpath = talloc_asprintf(ctx, "libnss_%s.so.2", libname); - if (!libpath) { - ret = ENOMEM; + ret = confdb_get_bool(be_ctx->cdb, be_ctx->conf_path, + CONFDB_PROXY_FAST_ALIAS, false, &fast_alias); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read confdb [%d]: %s\n", + ret, sss_strerror(ret)); goto done; } - ctx->handle = dlopen(libpath, RTLD_NOW); - if (!ctx->handle) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Unable to load %s module with path, error: %s\n", - libpath, dlerror()); - ret = ELIBACC; + libpath = talloc_asprintf(tmp_ctx, "libnss_%s.so.2", libname); + if (libpath == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed\n"); + ret = ENOMEM; goto done; } - ctx->ops.getpwnam_r = proxy_dlsym(ctx->handle, "_nss_%s_getpwnam_r", - libname); - if (!ctx->ops.getpwnam_r) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Failed to load NSS fns, error: %s\n", dlerror()); - ret = ELIBBAD; - goto done; - } + *_libname = talloc_steal(mem_ctx, libname); + *_libpath = talloc_steal(mem_ctx, libpath); + *_fast_alias = fast_alias; - ctx->ops.getpwuid_r = proxy_dlsym(ctx->handle, "_nss_%s_getpwuid_r", - libname); - if (!ctx->ops.getpwuid_r) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Failed to load NSS fns, error: %s\n", dlerror()); - ret = ELIBBAD; - goto done; - } + ret = EOK; - ctx->ops.setpwent = proxy_dlsym(ctx->handle, "_nss_%s_setpwent", libname); - if (!ctx->ops.setpwent) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Failed to load NSS fns, error: %s\n", dlerror()); - ret = ELIBBAD; - goto done; - } +done: + talloc_free(tmp_ctx); - ctx->ops.getpwent_r = proxy_dlsym(ctx->handle, "_nss_%s_getpwent_r", - libname); - if (!ctx->ops.getpwent_r) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Failed to load NSS fns, error: %s\n", dlerror()); - ret = ELIBBAD; - goto done; - } + return ret; +} - ctx->ops.endpwent = proxy_dlsym(ctx->handle, "_nss_%s_endpwent", libname); - if (!ctx->ops.endpwent) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Failed to load NSS fns, error: %s\n", dlerror()); - ret = ELIBBAD; - goto done; +static errno_t proxy_id_load_symbols(struct proxy_nss_ops *ops, + const char *libname, + void *handle) +{ + int i; + struct {void **dest; + const char *name; + const char *custom_error; + bool is_fatal; + } symbols[] = { + {(void**)&ops->getpwnam_r, "getpwnam_r", NULL, true}, + {(void**)&ops->getpwuid_r, "getpwuid_r", NULL, true}, + {(void**)&ops->setpwent, "setpwent", NULL, true}, + {(void**)&ops->getpwent_r, "getpwent_r", NULL, true}, + {(void**)&ops->endpwent, "endpwent", NULL, true}, + {(void**)&ops->getgrnam_r, "getgrnam_r", NULL, true}, + {(void**)&ops->getgrgid_r, "getgrgid_r", NULL, true}, + {(void**)&ops->setgrent, "setgrent", NULL, true}, + {(void**)&ops->getgrent_r, "getgrent_r", NULL, true}, + {(void**)&ops->endgrent, "endgrent", NULL, true}, + {(void**)&ops->initgroups_dyn, "initgroups_dyn", ERROR_INITGR, false}, + {(void**)&ops->setnetgrent, "setnetgrent", ERROR_NETGR, false}, + {(void**)&ops->getnetgrent_r, "getnetgrent_r", ERROR_NETGR, false}, + {(void**)&ops->endnetgrent, "endnetgrent", ERROR_NETGR, false}, + {(void**)&ops->getservbyname_r, "getservbyname_r", ERROR_SERV, false}, + {(void**)&ops->getservbyport_r, "getservbyport_r", ERROR_SERV, false}, + {(void**)&ops->setservent, "setservent", ERROR_SERV, false}, + {(void**)&ops->getservent_r, "getservent_r", ERROR_SERV, false}, + {(void**)&ops->endservent, "endservent", ERROR_SERV, false}, + {NULL, NULL, NULL, false} + }; + + for (i = 0; symbols[i].dest != NULL; i++) { + *symbols[i].dest = proxy_dlsym(handle, symbols[i].name, libname); + if (*symbols[i].dest == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load _nss_%s_%s, " + "error: %s.\n", libname, symbols[i].name, dlerror()); + + if (symbols[i].custom_error != NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, symbols[i].custom_error, libname); + } + + if (symbols[i].is_fatal) { + return ELIBBAD; + } + } } - ctx->ops.getgrnam_r = proxy_dlsym(ctx->handle, "_nss_%s_getgrnam_r", - libname); - if (!ctx->ops.getgrnam_r) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Failed to load NSS fns, error: %s\n", dlerror()); - ret = ELIBBAD; - goto done; - } + return EOK; +} - ctx->ops.getgrgid_r = proxy_dlsym(ctx->handle, "_nss_%s_getgrgid_r", - libname); - if (!ctx->ops.getgrgid_r) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Failed to load NSS fns, error: %s\n", dlerror()); - ret = ELIBBAD; - goto done; - } +static errno_t proxy_setup_sbus(TALLOC_CTX *mem_ctx, + struct proxy_auth_ctx *ctx, + struct be_ctx *be_ctx) +{ + char *sbus_address; + errno_t ret; - ctx->ops.setgrent = proxy_dlsym(ctx->handle, "_nss_%s_setgrent", libname); - if (!ctx->ops.setgrent) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Failed to load NSS fns, error: %s\n", dlerror()); - ret = ELIBBAD; - goto done; + sbus_address = talloc_asprintf(mem_ctx, "unix:path=%s/%s_%s", PIPE_PATH, + PROXY_CHILD_PIPE, be_ctx->domain->name); + if (sbus_address == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed.\n"); + return ENOMEM; } - ctx->ops.getgrent_r = proxy_dlsym(ctx->handle, "_nss_%s_getgrent_r", - libname); - if (!ctx->ops.getgrent_r) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Failed to load NSS fns, error: %s\n", dlerror()); - ret = ELIBBAD; - goto done; + ret = sbus_new_server(mem_ctx, be_ctx->ev, sbus_address, 0, be_ctx->gid, + false, &ctx->sbus_srv, proxy_client_init, ctx); + talloc_free(sbus_address); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "Could not set up sbus server.\n"); + return ret; } - ctx->ops.endgrent = proxy_dlsym(ctx->handle, "_nss_%s_endgrent", libname); - if (!ctx->ops.endgrent) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Failed to load NSS fns, error: %s\n", dlerror()); - ret = ELIBBAD; - goto done; - } + return EOK; +} - ctx->ops.initgroups_dyn = proxy_dlsym(ctx->handle, "_nss_%s_initgroups_dyn", - libname); - if (!ctx->ops.initgroups_dyn) { - DEBUG(SSSDBG_CRIT_FAILURE, "The '%s' library does not provides the " - "_nss_XXX_initgroups_dyn function!\n" - "initgroups will be slow as it will require " - "full groups enumeration!\n", libname); - } +static errno_t proxy_auth_conf(TALLOC_CTX *mem_ctx, + struct be_ctx *be_ctx, + char **_pam_target) +{ + char *pam_target; + errno_t ret; - ctx->ops.setnetgrent = proxy_dlsym(ctx->handle, "_nss_%s_setnetgrent", - libname); - if (!ctx->ops.setnetgrent) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Failed to load _nss_%s_setnetgrent, error: %s. " - "The library does not support netgroups.\n", libname, - dlerror()); + ret = confdb_get_string(be_ctx->cdb, mem_ctx, be_ctx->conf_path, + CONFDB_PROXY_PAM_TARGET, NULL, &pam_target); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read confdb [%d]: %s\n", + ret, sss_strerror(ret)); + return ret; } - ctx->ops.getnetgrent_r = proxy_dlsym(ctx->handle, "_nss_%s_getnetgrent_r", - libname); - if (!ctx->ops.getgrent_r) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Failed to load _nss_%s_getnetgrent_r, error: %s. " - "The library does not support netgroups.\n", libname, - dlerror()); + if (pam_target == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Missing option %s.\n", + CONFDB_PROXY_PAM_TARGET); + return EINVAL; } - ctx->ops.endnetgrent = proxy_dlsym(ctx->handle, "_nss_%s_endnetgrent", - libname); - if (!ctx->ops.endnetgrent) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Failed to load _nss_%s_endnetgrent, error: %s. " - "The library does not support netgroups.\n", libname, - dlerror()); - } + *_pam_target = pam_target; - ctx->ops.getservbyname_r = proxy_dlsym(ctx->handle, - "_nss_%s_getservbyname_r", - libname); - if (!ctx->ops.getservbyname_r) { - DEBUG(SSSDBG_MINOR_FAILURE, - "Failed to load _nss_%s_getservbyname_r, error: %s. " - "The library does not support services.\n", - libname, - dlerror()); - } + return EOK; +} - ctx->ops.getservbyport_r = proxy_dlsym(ctx->handle, - "_nss_%s_getservbyport_r", - libname); - if (!ctx->ops.getservbyport_r) { - DEBUG(SSSDBG_MINOR_FAILURE, - "Failed to load _nss_%s_getservbyport_r, error: %s. " - "The library does not support services.\n", - libname, - dlerror()); - } +static errno_t proxy_init_auth_ctx(TALLOC_CTX *mem_ctx, + struct be_ctx *be_ctx, + struct proxy_auth_ctx **_auth_ctx) +{ + struct proxy_auth_ctx *auth_ctx; + errno_t ret; + int hret; - ctx->ops.setservent = proxy_dlsym(ctx->handle, - "_nss_%s_setservent", - libname); - if (!ctx->ops.setservent) { - DEBUG(SSSDBG_MINOR_FAILURE, - "Failed to load _nss_%s_setservent, error: %s. " - "The library does not support services.\n", - libname, - dlerror()); + auth_ctx = talloc_zero(mem_ctx, struct proxy_auth_ctx); + if (auth_ctx == NULL) { + return ENOMEM; } - ctx->ops.getservent_r = proxy_dlsym(ctx->handle, - "_nss_%s_getservent_r", - libname); - if (!ctx->ops.getservent_r) { - DEBUG(SSSDBG_MINOR_FAILURE, - "Failed to load _nss_%s_getservent_r, error: %s. " - "The library does not support services.\n", - libname, - dlerror()); - } + auth_ctx->be = be_ctx; + auth_ctx->timeout_ms = SSS_CLI_SOCKET_TIMEOUT / 4; + auth_ctx->next_id = 1; - ctx->ops.endservent = proxy_dlsym(ctx->handle, - "_nss_%s_endservent", - libname); - if (!ctx->ops.endservent) { - DEBUG(SSSDBG_MINOR_FAILURE, - "Failed to load _nss_%s_endservent, error: %s. " - "The library does not support services.\n", - libname, - dlerror()); + ret = proxy_auth_conf(auth_ctx, be_ctx, &auth_ctx->pam_target); + if (ret != EOK) { + goto done; } - *ops = &proxy_id_ops; - *pvt_data = ctx; - ret = EOK; - -done: + ret = proxy_setup_sbus(auth_ctx, auth_ctx, be_ctx); if (ret != EOK) { - talloc_free(ctx); + goto done; } - return ret; -} - -struct proxy_client { - struct proxy_auth_ctx *proxy_auth_ctx; - struct sbus_connection *conn; - struct tevent_timer *timeout; - bool initialized; -}; - -static void init_timeout(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval t, void *ptr); -static int proxy_client_init(struct sbus_connection *conn, void *data) -{ - struct proxy_auth_ctx *proxy_auth_ctx; - struct proxy_client *proxy_cli; - struct timeval tv; - proxy_auth_ctx = talloc_get_type(data, struct proxy_auth_ctx); - - /* hang off this memory to the connection so that when the connection - * is freed we can potentially call a destructor */ + /* Set up request hash table */ + /* FIXME: get max_children from configuration file */ + auth_ctx->max_children = 10; - proxy_cli = talloc_zero(conn, struct proxy_client); - if (!proxy_cli) { - DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory?!\n"); - talloc_zfree(conn); - return ENOMEM; - } - proxy_cli->proxy_auth_ctx = proxy_auth_ctx; - proxy_cli->conn = conn; - proxy_cli->initialized = false; - - /* 5 seconds should be plenty */ - tv = tevent_timeval_current_ofs(5, 0); - - proxy_cli->timeout = tevent_add_timer(proxy_auth_ctx->be->ev, proxy_cli, - tv, init_timeout, proxy_cli); - if (!proxy_cli->timeout) { - DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory?!\n"); - talloc_zfree(conn); - return ENOMEM; + hret = hash_create(auth_ctx->max_children * 2, &auth_ctx->request_table, + NULL, NULL); + if (hret != HASH_SUCCESS) { + DEBUG(SSSDBG_FATAL_FAILURE, "Could not initialize request table\n"); + ret = EIO; + goto done; } - DEBUG(SSSDBG_CONF_SETTINGS, - "Set-up proxy client ID timeout [%p]\n", proxy_cli->timeout); - return sbus_conn_register_iface(conn, &proxy_methods.vtable, - DP_PATH, proxy_cli); -} + *_auth_ctx = auth_ctx; -static void init_timeout(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval t, void *ptr) -{ - struct proxy_client *proxy_cli; - - DEBUG(SSSDBG_OP_FAILURE, - "Client timed out before Identification [%p]!\n", te); - - proxy_cli = talloc_get_type(ptr, struct proxy_client); + ret = EOK; - sbus_disconnect(proxy_cli->conn); - talloc_zfree(proxy_cli); +done: + if (ret != EOK) { + talloc_free(auth_ctx); + } - /* If we time out here, we will also time out to - * pc_init_timeout(), so we'll finish the request - * there. - */ + return ret; } -static int client_registration(struct sbus_request *dbus_req, void *data) +errno_t sssm_proxy_init(TALLOC_CTX *mem_ctx, + struct be_ctx *be_ctx, + struct data_provider *provider, + const char *module_name, + void **_module_data) { - dbus_uint16_t version = DATA_PROVIDER_VERSION; - struct sbus_connection *conn; - struct proxy_client *proxy_cli; - dbus_uint16_t cli_ver; - uint32_t cli_id; - int hret; - hash_key_t key; - hash_value_t value; - struct tevent_req *req; - struct proxy_child_ctx *child_ctx; - struct pc_init_ctx *init_ctx; - int ret; - - conn = dbus_req->conn; - proxy_cli = talloc_get_type(data, struct proxy_client); - if (!proxy_cli) { - DEBUG(SSSDBG_FATAL_FAILURE, "Connection holds no valid init data\n"); - return EINVAL; - } + struct proxy_auth_ctx *auth_ctx; + errno_t ret; - /* First thing, cancel the timeout */ - DEBUG(SSSDBG_CONF_SETTINGS, - "Cancel proxy client ID timeout [%p]\n", proxy_cli->timeout); - talloc_zfree(proxy_cli->timeout); - - if (!sbus_request_parse_or_finish(dbus_req, - DBUS_TYPE_UINT16, &cli_ver, - DBUS_TYPE_UINT32, &cli_id, - DBUS_TYPE_INVALID)) { - sbus_disconnect(conn); - return EOK; /* handled */ + if (!dp_target_enabled(provider, module_name, + DPT_ACCESS, DPT_AUTH, DPT_CHPASS)) { + return EOK; } - DEBUG(SSSDBG_FUNC_DATA, "Proxy client [%"PRIu32"] connected\n", cli_id); - - /* Check the hash table */ - key.type = HASH_KEY_ULONG; - key.ul = cli_id; - if (!hash_has_key(proxy_cli->proxy_auth_ctx->request_table, &key)) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Unknown child ID. Killing the connection\n"); - sbus_disconnect(proxy_cli->conn); - return EIO; - } + /* Initialize auth_ctx since one of the access, auth or chpass is set. */ - /* reply that all is ok */ - ret = sbus_request_return_and_finish(dbus_req, - DBUS_TYPE_UINT16, &version, - DBUS_TYPE_INVALID); + ret = proxy_init_auth_ctx(mem_ctx, be_ctx, &auth_ctx); if (ret != EOK) { - sbus_disconnect(conn); + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create auth context [%d]: %s\n", + ret, sss_strerror(ret)); return ret; } - hret = hash_lookup(proxy_cli->proxy_auth_ctx->request_table, &key, &value); - if (hret != HASH_SUCCESS) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Hash error [%d][%s]\n", hret, hash_error_string(hret)); - sbus_disconnect(conn); - } - - /* Signal that the child is up and ready to receive the request */ - req = talloc_get_type(value.ptr, struct tevent_req); - child_ctx = tevent_req_data(req, struct proxy_child_ctx); - - if (!child_ctx->running) { - /* This should hopefully be impossible, but protect - * against it anyway. If we're not marked running, then - * the init_req will be NULL below and things will - * break. - */ - DEBUG(SSSDBG_CRIT_FAILURE, "Client connection from a request " - "that's not marked as running\n"); - return EIO; - } - - init_ctx = tevent_req_data(child_ctx->init_req, struct pc_init_ctx); - init_ctx->conn = conn; - tevent_req_done(child_ctx->init_req); - child_ctx->init_req = NULL; + *_module_data = auth_ctx; return EOK; } -int sssm_proxy_auth_init(struct be_ctx *bectx, - struct bet_ops **ops, void **pvt_data) +errno_t sssm_proxy_id_init(TALLOC_CTX *mem_ctx, + struct be_ctx *be_ctx, + void *module_data, + struct dp_method *dp_methods) { - struct proxy_auth_ctx *ctx; - int ret; - int hret; - char *sbus_address; - - /* If we're already set up, just return that */ - if(bectx->bet_info[BET_AUTH].mod_name && - strcmp("proxy", bectx->bet_info[BET_AUTH].mod_name) == 0) { - DEBUG(SSSDBG_TRACE_INTERNAL, - "Re-using proxy_auth_ctx for this provider\n"); - *ops = bectx->bet_info[BET_AUTH].bet_ops; - *pvt_data = bectx->bet_info[BET_AUTH].pvt_bet_data; - return EOK; - } + struct proxy_id_ctx *ctx; + char *libname; + char *libpath; + errno_t ret; - ctx = talloc_zero(bectx, struct proxy_auth_ctx); - if (!ctx) { + ctx = talloc_zero(mem_ctx, struct proxy_id_ctx); + if (ctx == NULL) { return ENOMEM; } - ctx->be = bectx; - ctx->timeout_ms = SSS_CLI_SOCKET_TIMEOUT/4; - ctx->next_id = 1; - - ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path, - CONFDB_PROXY_PAM_TARGET, NULL, - &ctx->pam_target); - if (ret != EOK) goto done; - if (!ctx->pam_target) { - DEBUG(SSSDBG_CRIT_FAILURE, "Missing option proxy_pam_target.\n"); - ret = EINVAL; + + ctx->be = be_ctx; + + ret = proxy_id_conf(ctx, be_ctx, &libname, &libpath, &ctx->fast_alias); + if (ret != EOK) { goto done; } - sbus_address = talloc_asprintf(ctx, "unix:path=%s/%s_%s", PIPE_PATH, - PROXY_CHILD_PIPE, bectx->domain->name); - if (sbus_address == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); - ret = ENOMEM; + ctx->handle = dlopen(libpath, RTLD_NOW); + if (ctx->handle == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Unable to load %s module, " + "error: %s\n", libpath, dlerror()); + ret = ELIBACC; goto done; } - ret = sbus_new_server(ctx, bectx->ev, sbus_address, 0, bectx->gid, - false, &ctx->sbus_srv, proxy_client_init, ctx); + ret = proxy_id_load_symbols(&ctx->ops, libname, ctx->handle); if (ret != EOK) { - DEBUG(SSSDBG_FATAL_FAILURE, "Could not set up sbus server.\n"); + DEBUG(SSSDBG_FATAL_FAILURE, "Unable to load NSS symbols [%d]: %s\n", + ret, sss_strerror(ret)); goto done; } - /* Set up request hash table */ - /* FIXME: get max_children from configuration file */ - ctx->max_children = 10; + dp_set_method(dp_methods, DPM_ACCOUNT_HANDLER, + proxy_account_info_handler_send, proxy_account_info_handler_recv, ctx, + struct proxy_id_ctx, struct be_acct_req, struct dp_reply_std); - hret = hash_create(ctx->max_children * 2, &ctx->request_table, - NULL, NULL); - if (hret != HASH_SUCCESS) { - DEBUG(SSSDBG_FATAL_FAILURE, "Could not initialize request table\n"); - ret = EIO; - goto done; - } - - *ops = &proxy_auth_ops; - *pvt_data = ctx; + ret = EOK; done: if (ret != EOK) { talloc_free(ctx); } + return ret; } -int sssm_proxy_access_init(struct be_ctx *bectx, - struct bet_ops **ops, void **pvt_data) +errno_t sssm_proxy_auth_init(TALLOC_CTX *mem_ctx, + struct be_ctx *be_ctx, + void *module_data, + struct dp_method *dp_methods) { - int ret; - ret = sssm_proxy_auth_init(bectx, ops, pvt_data); - *ops = &proxy_access_ops; - return ret; + struct proxy_auth_ctx *auth_ctx; + + auth_ctx = talloc_get_type(module_data, struct proxy_auth_ctx); + + dp_set_method(dp_methods, DPM_AUTH_HANDLER, + proxy_pam_handler_send, proxy_pam_handler_recv, auth_ctx, + struct proxy_auth_ctx, struct pam_data, struct pam_data *); + + return EOK; } -int sssm_proxy_chpass_init(struct be_ctx *bectx, - struct bet_ops **ops, void **pvt_data) +errno_t sssm_proxy_chpass_init(TALLOC_CTX *mem_ctx, + struct be_ctx *be_ctx, + void *module_data, + struct dp_method *dp_methods) { - int ret; - ret = sssm_proxy_auth_init(bectx, ops, pvt_data); - *ops = &proxy_chpass_ops; - return ret; + return sssm_proxy_auth_init(mem_ctx, be_ctx, module_data, dp_methods); +} + +errno_t sssm_proxy_access_init(TALLOC_CTX *mem_ctx, + struct be_ctx *be_ctx, + void *module_data, + struct dp_method *dp_methods) +{ + struct proxy_auth_ctx *auth_ctx; + + auth_ctx = talloc_get_type(module_data, struct proxy_auth_ctx); + + dp_set_method(dp_methods, DPM_ACCESS_HANDLER, + proxy_pam_handler_send, proxy_pam_handler_recv, auth_ctx, + struct proxy_auth_ctx, struct pam_data, struct pam_data *); + + return EOK; } |