summaryrefslogtreecommitdiff
path: root/src/responder
diff options
context:
space:
mode:
Diffstat (limited to 'src/responder')
-rw-r--r--src/responder/common/responder.h3
-rw-r--r--src/responder/common/responder_common.c53
2 files changed, 55 insertions, 1 deletions
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index ea6ba583..deb1e5a3 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -101,6 +101,9 @@ struct cli_ctx {
struct cli_request *creq;
struct cli_protocol_version *cli_protocol_version;
int priv;
+ int32_t client_euid;
+ int32_t client_egid;
+ int32_t client_pid;
};
struct sss_cmd_table {
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index ff27f62c..54d6c49e 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -19,6 +19,9 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/* for struct ucred */
+#define _GNU_SOURCE
+
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
@@ -29,7 +32,8 @@
#include <string.h>
#include <sys/time.h>
#include <errno.h>
-#include "popt.h"
+#include <popt.h>
+#include "config.h"
#include "util/util.h"
#include "db/sysdb.h"
#include "confdb/confdb.h"
@@ -61,6 +65,40 @@ static int client_destructor(struct cli_ctx *ctx)
return 0;
}
+static errno_t get_client_cred(struct cli_ctx *cctx)
+{
+#ifdef HAVE_UCRED
+ int ret;
+ struct ucred client_cred;
+ socklen_t client_cred_len = sizeof(client_cred);
+
+ cctx->client_euid = -1;
+ cctx->client_egid = -1;
+ cctx->client_pid = -1;
+
+ ret = getsockopt(cctx->cfd, SOL_SOCKET, SO_PEERCRED, &client_cred,
+ &client_cred_len);
+ if (ret != EOK) {
+ ret = errno;
+ DEBUG(1, ("getsock failed [%d][%s].\n", ret, strerror(ret)));
+ return ret;
+ }
+ if (client_cred_len != sizeof(struct ucred)) {
+ DEBUG(1, ("getsockopt returned unexpected message size.\n"));
+ return ENOMSG;
+ }
+
+ cctx->client_euid = client_cred.uid;
+ cctx->client_egid = client_cred.gid;
+ cctx->client_pid = client_cred.pid;
+
+ DEBUG(9, ("Client creds: euid[%d] egid[%d] pid[%d].\n",
+ cctx->client_euid, cctx->client_egid, cctx->client_pid));
+#endif
+
+ return EOK;
+}
+
static void client_send(struct cli_ctx *cctx)
{
int ret;
@@ -214,6 +252,12 @@ static void accept_priv_fd_handler(struct tevent_context *ev,
cctx->priv = 1;
+ ret = get_client_cred(cctx);
+ if (ret != EOK) {
+ DEBUG(2, ("get_client_cred failed, "
+ "client cred may not be available.\n"));
+ }
+
cctx->cfde = tevent_add_fd(ev, cctx, cctx->cfd,
TEVENT_FD_READ, client_fd_handler, cctx);
if (!cctx->cfde) {
@@ -240,6 +284,7 @@ static void accept_fd_handler(struct tevent_context *ev,
struct resp_ctx *rctx = talloc_get_type(ptr, struct resp_ctx);
struct cli_ctx *cctx;
socklen_t len;
+ int ret;
cctx = talloc_zero(rctx, struct cli_ctx);
if (!cctx) {
@@ -265,6 +310,12 @@ static void accept_fd_handler(struct tevent_context *ev,
return;
}
+ ret = get_client_cred(cctx);
+ if (ret != EOK) {
+ DEBUG(2, ("get_client_cred failed, "
+ "client cred may not be available.\n"));
+ }
+
cctx->cfde = tevent_add_fd(ev, cctx, cctx->cfd,
TEVENT_FD_READ, client_fd_handler, cctx);
if (!cctx->cfde) {