diff options
-rw-r--r-- | src/providers/data_provider_be.c | 25 | ||||
-rw-r--r-- | src/providers/dp_backend.h | 8 | ||||
-rw-r--r-- | src/responder/pam/pamsrv_cmd.c | 3 | ||||
-rw-r--r-- | src/sss_client/pam_sss.c | 110 |
4 files changed, 90 insertions, 56 deletions
diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c index 114fde52..9571d095 100644 --- a/src/providers/data_provider_be.c +++ b/src/providers/data_provider_be.c @@ -753,10 +753,12 @@ static void be_pam_handler_callback(struct be_req *req, int errnum, const char *errstr) { + struct be_client *becli = req->becli; struct pam_data *pd; DBusMessage *reply; DBusConnection *dbus_conn; dbus_bool_t dbret; + errno_t ret; DEBUG(4, ("Backend returned: (%d, %d, %s) [%s]\n", dp_err_type, errnum, errstr?errstr:"<NULL>", @@ -764,6 +766,28 @@ static void be_pam_handler_callback(struct be_req *req, pd = talloc_get_type(req->req_data, struct pam_data); + if (pd->cmd == SSS_PAM_ACCT_MGMT && + req->phase == REQ_PHASE_ACCESS && + dp_err_type == DP_ERR_OK) { + if (!becli->bectx->bet_info[BET_SELINUX].bet_ops) { + DEBUG(SSSDBG_TRACE_FUNC, + ("SELinux provider doesn't exist, " + "not sending the request to it.\n")); + } else { + req->phase = REQ_PHASE_SELINUX; + + /* Now is the time to call SELinux provider */ + ret = be_file_request(becli->bectx->bet_info[BET_SELINUX].pvt_bet_data, + req, + becli->bectx->bet_info[BET_SELINUX].bet_ops->handler); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("be_file_request failed.\n")); + goto done; + } + return; + } + } + DEBUG(4, ("Sending result [%d][%s]\n", pd->pam_status, pd->domain)); reply = (DBusMessage *)req->pvt; dbret = dp_pack_pam_response(reply, pd); @@ -852,6 +876,7 @@ static int be_pam_handler(DBusMessage *message, struct sbus_connection *conn) break; case SSS_PAM_ACCT_MGMT: target = BET_ACCESS; + be_req->phase = REQ_PHASE_ACCESS; break; case SSS_PAM_CHAUTHTOK: case SSS_PAM_CHAUTHTOK_PRELIM: diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h index 4c703326..53a382ac 100644 --- a/src/providers/dp_backend.h +++ b/src/providers/dp_backend.h @@ -132,6 +132,8 @@ struct bet_ops { }; #define MAX_BE_REQ_RESTARTS 2 +#define REQ_PHASE_ACCESS 0 +#define REQ_PHASE_SELINUX 1 struct be_req { struct be_client *becli; @@ -143,6 +145,12 @@ struct be_req { int restarts; + /* This is utilized in access provider + * request handling to indicate if access or + * selinux provider is calling the callback. + */ + int phase; + struct sss_domain_info *domain; struct sysdb_ctx *sysdb; }; diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c index 006edcd3..9c4c7706 100644 --- a/src/responder/pam/pamsrv_cmd.c +++ b/src/responder/pam/pamsrv_cmd.c @@ -582,6 +582,7 @@ static void pam_reply_delay(struct tevent_context *ev, struct tevent_timer *te, pam_reply(preq); } +static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd); static void pam_cache_auth_done(struct pam_auth_req *preq, int ret, time_t expire_date, time_t delayed_until); @@ -700,7 +701,7 @@ static void pam_reply(struct pam_auth_req *preq) return; } - if (pd->cmd == SSS_PAM_OPEN_SESSION && + if (pd->cmd == SSS_PAM_ACCT_MGMT && pd->pam_status == PAM_SUCCESS) { /* Try to fetch data from sysdb * (auth already passed -> we should have them) */ diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c index 50c5048b..3fecfabe 100644 --- a/src/sss_client/pam_sss.c +++ b/src/sss_client/pam_sss.c @@ -1180,71 +1180,71 @@ static int send_and_receive(pam_handle_t *pamh, struct pam_items *pi, pi->pam_user, pam_status, pam_strerror(pamh,pam_status)); } - } - break; - case SSS_PAM_OPEN_SESSION: - if (pi->selinux_user == NULL) { - pam_status = PAM_SUCCESS; - break; - } + } else { + if (pi->selinux_user == NULL) { + pam_status = PAM_SUCCESS; + break; + } #ifdef HAVE_SELINUX - if (asprintf(&path, "%s/logins/%s", selinux_policy_root(), - pi->pam_user) < 0 || - asprintf(&tmp_path, "%sXXXXXX", path) < 0) { - pam_status = PAM_SYSTEM_ERR; - goto done; - } + if (asprintf(&path, "%s/logins/%s", selinux_policy_root(), + pi->pam_user) < 0 || + asprintf(&tmp_path, "%sXXXXXX", path) < 0) { + pam_status = PAM_SYSTEM_ERR; + goto done; + } - oldmask = umask(022); - fd = mkstemp(tmp_path); - umask(oldmask); - if (fd < 0) { - logger(pamh, LOG_ERR, "creating the temp file for SELinux " - "data failed. %s", tmp_path); - pam_status = PAM_SYSTEM_ERR; - goto done; - } + oldmask = umask(022); + fd = mkstemp(tmp_path); + umask(oldmask); + if (fd < 0) { + logger(pamh, LOG_ERR, "creating the temp file for SELinux " + "data failed. %s", tmp_path); + pam_status = PAM_SYSTEM_ERR; + goto done; + } - /* First write filter for all services */ - services = strdup(ALL_SERVICES); - if (services == NULL) { - pam_status = PAM_SYSTEM_ERR; - goto done; - } + /* First write filter for all services */ + services = strdup(ALL_SERVICES); + if (services == NULL) { + pam_status = PAM_SYSTEM_ERR; + goto done; + } - errno = 0; - written = sss_atomic_write_s(fd, (void *)services, ALL_SERVICES_LEN); - if (written == -1) { - ret = errno; - logger(pamh, LOG_ERR, "writing to SELinux data file %s" - "failed [%d]: %s", tmp_path, ret, strerror(ret)); - pam_status = PAM_SYSTEM_ERR; - goto done; - } - len = strlen(pi->selinux_user); - - errno = 0; - written = sss_atomic_write_s(fd, pi->selinux_user, len); - if (written == -1) { - ret = errno; - logger(pamh, LOG_ERR, "writing to SELinux data file %s" - "failed [%d]: %s", tmp_path, ret, strerror(ret)); - pam_status = PAM_SYSTEM_ERR; - goto done; - } + errno = 0; + written = sss_atomic_write_s(fd, (void *)services, ALL_SERVICES_LEN); + if (written == -1) { + ret = errno; + logger(pamh, LOG_ERR, "writing to SELinux data file %s" + "failed [%d]: %s", tmp_path, ret, strerror(ret)); + pam_status = PAM_SYSTEM_ERR; + goto done; + } + len = strlen(pi->selinux_user); - if (written != len) { - logger(pamh, LOG_ERR, "Expected to write %d bytes, wrote %d", - written, len); - goto done; - } + errno = 0; + written = sss_atomic_write_s(fd, pi->selinux_user, len); + if (written == -1) { + ret = errno; + logger(pamh, LOG_ERR, "writing to SELinux data file %s" + "failed [%d]: %s", tmp_path, ret, strerror(ret)); + pam_status = PAM_SYSTEM_ERR; + goto done; + } + + if (written != len) { + logger(pamh, LOG_ERR, "Expected to write %d bytes, wrote %d", + written, len); + goto done; + } - close(fd); + close(fd); - rename(tmp_path, path); + rename(tmp_path, path); #endif /* HAVE_SELINUX */ + } break; + case SSS_PAM_OPEN_SESSION: case SSS_PAM_SETCRED: case SSS_PAM_CLOSE_SESSION: break; |