diff options
author | Simo Sorce <ssorce@redhat.com> | 2009-04-04 12:21:18 -0400 |
---|---|---|
committer | Simo Sorce <ssorce@redhat.com> | 2009-04-07 14:27:18 -0400 |
commit | ee762f9b709224a7dc7460fc535ee992045168b8 (patch) | |
tree | daa6d444d6c52868c0a9109d360a4fe64b333df3 | |
parent | 2df2e775612734712b72dcf0adf6c66ce530a319 (diff) | |
download | sssd-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.
-rw-r--r-- | server/examples/config.ldif | 50 | ||||
-rw-r--r-- | server/examples/sssdproxylocal | 9 | ||||
-rw-r--r-- | server/examples/sssdproxytest | 9 | ||||
-rw-r--r-- | server/examples/sudo | 6 | ||||
-rw-r--r-- | server/providers/data_provider_be.c | 155 | ||||
-rw-r--r-- | server/providers/dp_backend.h | 44 | ||||
-rw-r--r-- | server/providers/ldap_be.c | 10 | ||||
-rw-r--r-- | server/providers/proxy.c | 73 |
8 files changed, 275 insertions, 81 deletions
diff --git a/server/examples/config.ldif b/server/examples/config.ldif index b848e431..6101f085 100644 --- a/server/examples/config.ldif +++ b/server/examples/config.ldif @@ -15,31 +15,28 @@ activeServices: info dn: cn=nss,cn=services,cn=config cn: nss description: NSS Responder Configuration -unixSocket: /var/lib/sss/pipes/nss -command: /usr/libexec/sssd/sssd_nss +filterGroups: root +filterGroups: foo@TEST +filterUsers: root +filterUsers: bar@TEST dn: cn=dp,cn=services,cn=config cn: dp description: Data Provider Configuration -command: /usr/libexec/sssd/sssd_dp dn: cn=monitor,cn=services,cn=config cn: monitor description: Monitor Configuration sbusTimeout: 10 -sbusAddress: unix:path=/var/lib/sss/pipes/private/dbus servicePingTime: 10 dn: cn=pam,cn=services,cn=config cn: pam -command: /usr/libexec/sssd/sssd_pam description: PAM Responder Configuration -unixSocket: /var/lib/sss/pipes/pam dn: cn=info,cn=services,cn=config cn: info description: InfoPipe Configuration -command: ./sbin/sssd_info dn: cn=domains,cn=config cn: domains @@ -48,32 +45,43 @@ description: Domains served by SSSD dn: cn=LOCAL,cn=domains,cn=config cn: LOCAL description: Reserved domain for local configurations -legacy: FALSE enumerate: 3 - -dn: cn=EXAMPLE.COM,cn=domains,cn=config -cn: EXAMPLE.COM -description: Example domain served by IPA -provider: ipa -server: ipaserver1.example.com -server: ipabackupserver.example.com -legacy: FALSE -enumerate: 0 +minId: 500 +maxId: 999 +legacy: TRUE +libName: files +libPath: /lib64/libnss_files.so.2 +magicPrivateGroups: FALSE +provider: proxy +auth-module: proxy +pam-target: sssdproxylocal dn: cn=TEST,cn=domains,cn=config cn: TEST description: TEST Ldap domain -provider: proxy -command: ./sbin/sssd_be -d 2 --provider proxy --domain TEST libName: ldap libPath: /usr/lib64/libnss_ldap.so.2 legacy: TRUE -enumerate: 0 +enumerate: 3 +useFullyQualifiedNames: TRUE +minId: 1000 +provider: proxy +auth-module: proxy +pam-target: sssdproxytest dn: cn=LDAPTEST,cn=domains,cn=config cn: LDAPTEST basedn: cn=LDAPTEST,sn=sysdb -command: ./sbin/sssd_be --provider ldap --domain LDAPTEST +command: /usr/libexec/sssd/sssd_be --provider ldap --domain LDAPTEST description: TEST PAM Ldap domain provider: ldap userSearchBase: ou=user,dc=my-domain,dc=com + +dn: cn=EXAMPLE.COM,cn=domains,cn=config +cn: EXAMPLE.COM +description: Example domain served by IPA +provider: ipa +server: ipaserver1.example.com +server: ipabackupserver.example.com +legacy: FALSE +enumerate: 0 diff --git a/server/examples/sssdproxylocal b/server/examples/sssdproxylocal new file mode 100644 index 00000000..1bc47f89 --- /dev/null +++ b/server/examples/sssdproxylocal @@ -0,0 +1,9 @@ +#%PAM-1.0 +auth sufficient pam_unix.so +auth requisite pam_succeed_if.so uid >= 500 quiet +auth required pam_deny.so + +account required pam_unix.so +account sufficient pam_succeed_if.so uid < 500 quiet +account required pam_permit.so + diff --git a/server/examples/sssdproxytest b/server/examples/sssdproxytest new file mode 100644 index 00000000..9c5cb4ad --- /dev/null +++ b/server/examples/sssdproxytest @@ -0,0 +1,9 @@ +#%PAM-1.0 +auth sufficient pam_ldap.so debug +auth requisite pam_succeed_if.so uid >= 1000 quiet +auth required pam_deny.so + +account required pam_ldap.so debug +account sufficient pam_succeed_if.so uid < 1000 quiet +account required pam_permit.so + diff --git a/server/examples/sudo b/server/examples/sudo new file mode 100644 index 00000000..4af91ba6 --- /dev/null +++ b/server/examples/sudo @@ -0,0 +1,6 @@ +#%PAM-1.0 +auth required pam_sss.so +account required pam_sss.so +password required pam_sss.so +session optional pam_keyinit.so revoke +session required pam_limits.so 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; +} |