summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/providers/data_provider_be.c25
-rw-r--r--src/providers/dp_backend.h8
-rw-r--r--src/responder/pam/pamsrv_cmd.c3
-rw-r--r--src/sss_client/pam_sss.c110
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;