diff options
Diffstat (limited to 'server')
-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; +} |