summaryrefslogtreecommitdiff
path: root/server/providers
diff options
context:
space:
mode:
authorSimo Sorce <ssorce@redhat.com>2009-04-04 12:21:18 -0400
committerSimo Sorce <ssorce@redhat.com>2009-04-07 14:27:18 -0400
commitee762f9b709224a7dc7460fc535ee992045168b8 (patch)
treedaa6d444d6c52868c0a9109d360a4fe64b333df3 /server/providers
parent2df2e775612734712b72dcf0adf6c66ce530a319 (diff)
downloadsssd-ee762f9b709224a7dc7460fc535ee992045168b8.tar.gz
sssd-ee762f9b709224a7dc7460fc535ee992045168b8.tar.bz2
sssd-ee762f9b709224a7dc7460fc535ee992045168b8.zip
Split modules types in Identity and Authenticator
The same module may implement both types, but initializatrion will be nonetheless performed separately, once for the identity module and once for the authenticator module. Also change the proxy module to retireve the pam target name from the domain configuration so that it is possibile to create per-domain pam stacks. With this modification it is actually possibile to use normal nss and pam modules to perform a successful authentication (tested only with sudo so far) Update exmples.
Diffstat (limited to 'server/providers')
-rw-r--r--server/providers/data_provider_be.c155
-rw-r--r--server/providers/dp_backend.h44
-rw-r--r--server/providers/ldap_be.c10
-rw-r--r--server/providers/proxy.c73
4 files changed, 222 insertions, 60 deletions
diff --git a/server/providers/data_provider_be.c b/server/providers/data_provider_be.c
index 4e99f562..61844bbe 100644
--- a/server/providers/data_provider_be.c
+++ b/server/providers/data_provider_be.c
@@ -49,8 +49,6 @@
#define BE_CONF_ENTRY "config/domains/%s"
-typedef int (*be_init_fn_t)(TALLOC_CTX *, struct be_mod_ops **, void **);
-
static int service_identity(DBusMessage *message, struct sbus_conn_ctx *sconn);
static int service_pong(DBusMessage *message, struct sbus_conn_ctx *sconn);
@@ -305,7 +303,7 @@ static int be_check_online(DBusMessage *message, struct sbus_conn_ctx *sconn)
be_req->req_data = req;
- ret = be_file_request(ctx, ctx->ops->check_online, be_req);
+ ret = be_file_request(ctx, ctx->id_ops->check_online, be_req);
if (ret != EOK) {
online = MOD_OFFLINE;
err_maj = DP_ERR_FATAL;
@@ -482,7 +480,7 @@ static int be_get_account_info(DBusMessage *message, struct sbus_conn_ctx *sconn
be_req->req_data = req;
- ret = be_file_request(ctx, ctx->ops->get_account_info, be_req);
+ ret = be_file_request(ctx, ctx->id_ops->get_account_info, be_req);
if (ret != EOK) {
err_maj = DP_ERR_FATAL;
err_min = ret;
@@ -588,7 +586,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->ops->pam_handler, be_req);
+ ret = be_file_request(ctx, ctx->auth_ops->pam_handler, be_req);
if (ret != EOK) {
pam_status = PAM_SYSTEM_ERR;
goto done;
@@ -698,8 +696,7 @@ static int be_cli_init(struct be_ctx *ctx)
}
static int be_finalize(struct be_ctx *ctx);
-static void be_shutdown(struct be_req *req, int status,
- const char *errstr);
+static void be_shutdown(struct be_req *req, int status, const char *errstr);
static void be_cli_reconnect_init(struct sbus_conn_ctx *sconn, int status, void *pvt)
{
@@ -730,37 +727,76 @@ static void be_cli_reconnect_init(struct sbus_conn_ctx *sconn, int status, void
/* Kill the backend and let the monitor restart it */
ret = be_finalize(be_ctx);
if (ret != EOK) {
- DEBUG(0, ("Finalizing back-end failed with error [%d] [%s]", ret, strerror(ret)));
+ DEBUG(0, ("Finalizing back-end failed with error [%d] [%s]\n",
+ ret, strerror(ret)));
be_shutdown(NULL, ret, NULL);
}
}
-static void be_shutdown(struct be_req *req, int status,
- const char *errstr)
+static void be_shutdown(struct be_req *req, int status, const char *errstr)
{
/* Nothing left to do but exit() */
if (status == EOK)
exit(0);
/* Something went wrong in finalize */
+ DEBUG(0, ("Finalizing auth module failed with error [%d] [%s]\n",
+ status, errstr ? : strerror(status)));
+
exit(1);
}
-static int be_finalize(struct be_ctx *ctx)
+static void be_id_shutdown(struct be_req *req, int status, const char *errstr)
{
+ struct be_req *shutdown_req;
+ struct be_ctx *ctx;
int ret;
- struct be_req *shutdown_req = talloc_zero(ctx, struct be_req);
+
+ if (status != EOK) {
+ /* Something went wrong in finalize */
+ DEBUG(0, ("Finalizing auth module failed with error [%d] [%s]\n",
+ status, errstr ? : strerror(status)));
+ }
+
+ ctx = req->be_ctx;
+
+ /* Now shutdown the id module too */
+ shutdown_req = talloc_zero(ctx, struct be_req);
if (!shutdown_req) {
ret = ENOMEM;
goto fail;
}
shutdown_req->be_ctx = ctx;
- shutdown_req->fn = be_shutdown;
+ shutdown_req->fn = be_id_shutdown;
+
+ shutdown_req->pvt = ctx->pvt_id_data;
+
+ ret = be_file_request(ctx, ctx->id_ops->finalize, shutdown_req);
+ if (ret == EOK)
+ return;
+
+fail:
+ /* If we got here, we couldn't shut down cleanly. */
+ be_shutdown(NULL, ret, NULL);
+}
+
+static int be_finalize(struct be_ctx *ctx)
+{
+ struct be_req *shutdown_req;
+ int ret;
+
+ shutdown_req = talloc_zero(ctx, struct be_req);
+ if (!shutdown_req) {
+ ret = ENOMEM;
+ goto fail;
+ }
- shutdown_req->pvt = ctx->pvt_data;
+ shutdown_req->be_ctx = ctx;
+ shutdown_req->fn = be_id_shutdown;
+ shutdown_req->pvt = ctx->pvt_auth_data;
- ret = be_file_request(ctx, ctx->ops->finalize, shutdown_req);
+ ret = be_file_request(ctx, ctx->auth_ops->finalize, shutdown_req);
if (ret == EOK) return EOK;
fail:
@@ -769,13 +805,13 @@ fail:
return ret;
}
-static int load_backend(struct be_ctx *ctx)
+static int load_id_backend(struct be_ctx *ctx)
{
TALLOC_CTX *tmp_ctx;
char *path;
void *handle;
char *mod_init_fn_name;
- be_init_fn_t mod_init_fn;
+ be_id_init_fn_t mod_init_fn;
int ret;
tmp_ctx = talloc_new(ctx);
@@ -804,7 +840,7 @@ static int load_backend(struct be_ctx *ctx)
goto done;
}
- mod_init_fn = (be_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",
ctx->name, dlerror()));
@@ -812,7 +848,7 @@ static int load_backend(struct be_ctx *ctx)
goto done;
}
- ret = mod_init_fn(ctx, &ctx->ops, &ctx->pvt_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, ctx->name));
@@ -826,6 +862,75 @@ done:
return ret;
}
+static int load_auth_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;
+ int ret;
+
+ tmp_ctx = talloc_new(ctx);
+ if (!tmp_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);
+ if (!path) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ 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;
+ }
+
+ mod_init_fn_name = talloc_asprintf(tmp_ctx, "sssm_%s_auth_init", mod_name);
+ if (!mod_init_fn_name) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ mod_init_fn = (be_auth_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()));
+ ret = ELIBBAD;
+ goto done;
+ }
+
+ ret = mod_init_fn(ctx, &ctx->auth_ops, &ctx->pvt_auth_data);
+ if (ret != EOK) {
+ DEBUG(0, ("Error (%d) in module (%s) initialization!\n",
+ ret, mod_name));
+ goto done;
+ }
+
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
int be_process_init(TALLOC_CTX *mem_ctx,
const char *be_name,
const char *be_domain,
@@ -869,12 +974,22 @@ int be_process_init(TALLOC_CTX *mem_ctx,
return ret;
}
- ret = load_backend(ctx);
+ ret = load_id_backend(ctx);
if (ret != EOK) {
DEBUG(0, ("fatal error initializing data providers\n"));
return ret;
}
+ ret = load_auth_backend(ctx);
+ if (ret != EOK) {
+ if (ret != ENOENT) {
+ DEBUG(0, ("fatal error initializing data providers\n"));
+ return ret;
+ }
+ DEBUG(1, ("No authentication module provided for [%s] !!\n",
+ be_domain));
+ }
+
return EOK;
}
diff --git a/server/providers/dp_backend.h b/server/providers/dp_backend.h
index 12cfb3a5..2d1cd83e 100644
--- a/server/providers/dp_backend.h
+++ b/server/providers/dp_backend.h
@@ -27,10 +27,15 @@
#include "responder/pam/pamsrv.h"
struct be_ctx;
+struct be_id_ops;
+struct be_auth_ops;
+struct be_req;
+typedef int (*be_id_init_fn_t)(TALLOC_CTX *, struct be_id_ops **, void **);
+typedef int (*be_auth_init_fn_t)(TALLOC_CTX *, struct be_auth_ops **, void **);
typedef void (*be_shutdown_fn)(void *);
-
-struct be_mod_ops;
+typedef void (*be_req_fn_t)(struct be_req *);
+typedef void (*be_async_callback_t)(struct be_req *, int, const char *);
struct be_ctx {
struct tevent_context *ev;
@@ -42,14 +47,24 @@ struct be_ctx {
const char *domain;
const char *identity;
const char *conf_path;
- struct be_mod_ops *ops;
- void *pvt_data;
- be_shutdown_fn shutdown;
+
+ struct be_id_ops *id_ops;
+ void *pvt_id_data;
+
+ struct be_auth_ops *auth_ops;
+ void *pvt_auth_data;
};
-struct be_req;
+struct be_id_ops {
+ be_req_fn_t check_online;
+ be_req_fn_t get_account_info;
+ be_req_fn_t finalize;
+};
-typedef void (*be_async_callback_t)(struct be_req *, int, const char *);
+struct be_auth_ops {
+ be_req_fn_t pam_handler;
+ be_req_fn_t finalize;
+};
struct be_req {
struct be_ctx *be_ctx;
@@ -70,19 +85,4 @@ struct be_online_req {
int online;
};
-struct be_pam_handler {
- int pam_status;
- const char *domain;
- struct pam_data *pd;
-};
-
-typedef void (*be_req_fn_t)(struct be_req *);
-
-struct be_mod_ops {
- be_req_fn_t check_online;
- be_req_fn_t get_account_info;
- be_req_fn_t pam_handler;
- be_req_fn_t finalize;
-};
-
#endif /* __DP_BACKEND_H___ */
diff --git a/server/providers/ldap_be.c b/server/providers/ldap_be.c
index 9fe25640..2c075bd0 100644
--- a/server/providers/ldap_be.c
+++ b/server/providers/ldap_be.c
@@ -592,7 +592,7 @@ static void sdap_pam_handler(struct be_req *req)
pd = talloc_get_type(req->req_data, struct pam_data);
- sdap_ctx = talloc_get_type(req->be_ctx->pvt_data, struct sdap_ctx);
+ sdap_ctx = talloc_get_type(req->be_ctx->pvt_auth_data, struct sdap_ctx);
lr = talloc(req, struct sdap_req);
@@ -628,15 +628,15 @@ static void sdap_shutdown(struct be_req *req)
req->fn(req, EOK, NULL);
}
-struct be_mod_ops sdap_mod_ops = {
- .check_online = NULL,
- .get_account_info = NULL,
+struct be_auth_ops sdap_mod_ops = {
.pam_handler = sdap_pam_handler,
.finalize = sdap_shutdown
};
-int sssm_ldap_init(struct be_ctx *bectx, struct be_mod_ops **ops, void **pvt_data)
+int sssm_ldap_auth_init(struct be_ctx *bectx,
+ struct be_auth_ops **ops,
+ void **pvt_data)
{
struct sdap_ctx *ctx;
char *ldap_uri;
diff --git a/server/providers/proxy.c b/server/providers/proxy.c
index c87b482f..1b4a8300 100644
--- a/server/providers/proxy.c
+++ b/server/providers/proxy.c
@@ -61,6 +61,10 @@ struct proxy_ctx {
struct proxy_nss_ops ops;
};
+struct proxy_auth_ctx {
+ char *pam_target;
+};
+
struct authtok_conv {
char *authtok;
char *oldauthtok;
@@ -84,7 +88,7 @@ static int proxy_internal_conv(int num_msg, const struct pam_message **msgm,
for (i=0; i < num_msg; i++) {
switch( msgm[i]->msg_style ) {
case PAM_PROMPT_ECHO_OFF:
- DEBUG(4, ("Conversation message: %s.\n", msgm[i]->msg));
+ DEBUG(4, ("Conversation message: [%s]\n", msgm[i]->msg));
reply[i].resp_retcode = 0;
reply[i].resp = strdup(auth_data->authtok);
break;
@@ -112,14 +116,16 @@ static void proxy_pam_handler(struct be_req *req) {
struct authtok_conv *auth_data;
struct pam_conv conv;
struct pam_data *pd;
+ struct proxy_auth_ctx *ctx;;
+ ctx = talloc_get_type(req->be_ctx->pvt_auth_data, struct proxy_auth_ctx);
pd = talloc_get_type(req->req_data, struct pam_data);
conv.conv=proxy_internal_conv;
auth_data = talloc_zero(req->be_ctx, struct authtok_conv);
conv.appdata_ptr=auth_data;
- ret = pam_start("sssd_be_test", pd->user, &conv, &pamh);
+ ret = pam_start(ctx->pam_target, pd->user, &conv, &pamh);
if (ret == PAM_SUCCESS) {
DEBUG(1, ("Pam transaction started.\n"));
pam_set_item(pamh, PAM_TTY, pd->tty);
@@ -279,7 +285,7 @@ static void get_pw_name(struct be_req *req, char *name)
struct proxy_data *data;
int ret;
- ctx = talloc_get_type(req->be_ctx->pvt_data, struct proxy_ctx);
+ ctx = talloc_get_type(req->be_ctx->pvt_id_data, struct proxy_ctx);
data = talloc_zero(req, struct proxy_data);
if (!data)
@@ -340,7 +346,7 @@ static void get_pw_uid(struct be_req *req, uid_t uid)
struct proxy_data *data;
int ret;
- ctx = talloc_get_type(req->be_ctx->pvt_data, struct proxy_ctx);
+ ctx = talloc_get_type(req->be_ctx->pvt_id_data, struct proxy_ctx);
data = talloc_zero(req, struct proxy_data);
if (!data)
@@ -478,7 +484,7 @@ static void enum_users(struct be_req *req)
struct proxy_data *data;
int ret;
- ctx = talloc_get_type(req->be_ctx->pvt_data, struct proxy_ctx);
+ ctx = talloc_get_type(req->be_ctx->pvt_id_data, struct proxy_ctx);
data = talloc_zero(req, struct proxy_data);
if (!data)
@@ -551,7 +557,7 @@ static void get_gr_name(struct be_req *req, char *name)
struct proxy_data *data;
int ret;
- ctx = talloc_get_type(req->be_ctx->pvt_data, struct proxy_ctx);
+ ctx = talloc_get_type(req->be_ctx->pvt_id_data, struct proxy_ctx);
data = talloc_zero(req, struct proxy_data);
if (!data)
@@ -611,7 +617,7 @@ static void get_gr_gid(struct be_req *req, gid_t gid)
struct proxy_data *data;
int ret;
- ctx = talloc_get_type(req->be_ctx->pvt_data, struct proxy_ctx);
+ ctx = talloc_get_type(req->be_ctx->pvt_id_data, struct proxy_ctx);
data = talloc_zero(req, struct proxy_data);
if (!data)
@@ -741,7 +747,7 @@ static void enum_groups(struct be_req *req)
struct proxy_data *data;
int ret;
- ctx = talloc_get_type(req->be_ctx->pvt_data, struct proxy_ctx);
+ ctx = talloc_get_type(req->be_ctx->pvt_id_data, struct proxy_ctx);
data = talloc_zero(req, struct proxy_data);
if (!data)
@@ -920,7 +926,7 @@ static void get_initgr_user(struct be_req *req, char *name)
struct proxy_data *data;
int ret;
- ctx = talloc_get_type(req->be_ctx->pvt_data, struct proxy_ctx);
+ ctx = talloc_get_type(req->be_ctx->pvt_id_data, struct proxy_ctx);
data = talloc_zero(req, struct proxy_data);
if (!data)
@@ -1109,13 +1115,23 @@ static void proxy_shutdown(struct be_req *req)
req->fn(req, EOK, NULL);
}
-struct be_mod_ops proxy_mod_ops = {
+static void proxy_auth_shutdown(struct be_req *req)
+{
+ talloc_free(req->be_ctx->pvt_auth_data);
+ req->fn(req, EOK, NULL);
+}
+
+struct be_id_ops proxy_id_ops = {
.check_online = proxy_check_online,
.get_account_info = proxy_get_account_info,
- .pam_handler = proxy_pam_handler,
.finalize = proxy_shutdown
};
+struct be_auth_ops proxy_auth_ops = {
+ .pam_handler = proxy_pam_handler,
+ .finalize = proxy_auth_shutdown
+};
+
static void *proxy_dlsym(void *handle, const char *functemp, char *libname)
{
char *funcname;
@@ -1130,7 +1146,8 @@ static void *proxy_dlsym(void *handle, const char *functemp, char *libname)
return funcptr;
}
-int sssm_proxy_init(struct be_ctx *bectx, struct be_mod_ops **ops, void **pvt_data)
+int sssm_proxy_init(struct be_ctx *bectx,
+ struct be_id_ops **ops, void **pvt_data)
{
struct proxy_ctx *ctx;
char *libname;
@@ -1240,7 +1257,7 @@ int sssm_proxy_init(struct be_ctx *bectx, struct be_mod_ops **ops, void **pvt_da
"full groups enumeration!\n", libname));
}
- *ops = &proxy_mod_ops;
+ *ops = &proxy_id_ops;
*pvt_data = ctx;
ret = EOK;
@@ -1250,3 +1267,33 @@ done:
}
return ret;
}
+
+int sssm_proxy_auth_init(struct be_ctx *bectx,
+ struct be_auth_ops **ops, void **pvt_data)
+{
+ struct proxy_auth_ctx *ctx;
+ int ret;
+
+ ctx = talloc(bectx, struct proxy_auth_ctx);
+ if (!ctx) return ENOMEM;
+
+ ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path,
+ "pam-target", NULL, &ctx->pam_target);
+ if (ret != EOK) goto done;
+ if (!ctx->pam_target) {
+ ctx->pam_target = talloc_strdup(ctx, "sssd_pam_proxy_default");
+ if (!ctx->pam_target) {
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
+ *ops = &proxy_auth_ops;
+ *pvt_data = ctx;
+
+done:
+ if (ret != EOK) {
+ talloc_free(ctx);
+ }
+ return ret;
+}