瀏覽代碼

Add pid, uid, user to context

Serj Kalichev 1 年之前
父節點
當前提交
84b410dad7
共有 3 個文件被更改,包括 69 次插入10 次删除
  1. 17 9
      bin/klish/interactive.c
  2. 26 1
      klish/ktp/ktpd_session.c
  3. 26 0
      plugins/script/script.c

+ 17 - 9
bin/klish/interactive.c

@@ -41,8 +41,7 @@ static bool_t stdin_cb(faux_eloop_t *eloop, faux_eloop_type_e type,
 static bool_t sigwinch_cb(faux_eloop_t *eloop, faux_eloop_type_e type,
 	void *associated_data, void *user_data);
 
-static bool_t ktp_sync_auth(ktp_session_t *ktp, int *retcode,
-	faux_error_t *error);
+static bool_t ktp_sync_auth(ktp_session_t *ktp, int *retcode);
 static void reset_hotkey_table(ctx_t *ctx);
 static bool_t interactive_stdout_cb(ktp_session_t *ktp, const char *line, size_t len,
 	void *user_data);
@@ -94,7 +93,7 @@ int klish_interactive_shell(ktp_session_t *ktp, struct options *opts)
 	// prompt from the server. Generally it must be necessary for
 	// non-interactive session too but for now is not implemented.
 	ktp_session_set_cb(ktp, KTP_SESSION_CB_AUTH_ACK, auth_ack_cb, &ctx);
-	if (!ktp_sync_auth(ktp, &auth_rc, ktp_session_error(ktp)))
+	if (!ktp_sync_auth(ktp, &auth_rc))
 		goto cleanup;
 	if (auth_rc < 0)
 		goto cleanup;
@@ -234,9 +233,8 @@ bool_t auth_ack_cb(ktp_session_t *ktp, const faux_msg_t *msg, void *udata)
 		faux_error_node_t *err_iter = faux_error_iter(error);
 		const char *err = NULL;
 		while ((err = faux_error_each(&err_iter)))
-			fprintf(stderr, "Error: %s\n", err);
+			fprintf(stderr, "Error: auth: %s\n", err);
 	}
-	faux_error_free(error);
 
 	// Operation is finished so restore stdin handler
 	faux_eloop_add_fd(ktp_session_eloop(ktp), STDIN_FILENO, POLLIN,
@@ -712,15 +710,25 @@ bool_t help_ack_cb(ktp_session_t *ktp, const faux_msg_t *msg, void *udata)
 }
 
 
-static bool_t ktp_sync_auth(ktp_session_t *ktp, int *retcode,
-	faux_error_t *error)
+static bool_t ktp_sync_auth(ktp_session_t *ktp, int *retcode)
 {
-	if (!ktp_session_auth(ktp, error))
+	faux_error_t *error = NULL;
+	bool_t rc = BOOL_FALSE;
+
+	assert(ktp);
+
+	error = faux_error_new();
+	if (!ktp_session_auth(ktp, error)) {
+		faux_error_free(error);
 		return BOOL_FALSE;
+	}
 
 	faux_eloop_loop(ktp_session_eloop(ktp));
 
-	return ktp_session_retcode(ktp, retcode);
+	rc = ktp_session_retcode(ktp, retcode);
+	faux_error_free(error);
+
+	return rc;
 }
 
 

+ 26 - 1
klish/ktp/ktpd_session.c

@@ -1,3 +1,4 @@
+#define _GNU_SOURCE
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -18,6 +19,7 @@
 #include <faux/async.h>
 #include <faux/msg.h>
 #include <faux/eloop.h>
+#include <faux/sysdb.h>
 #include <klish/ksession.h>
 #include <klish/ksession_parse.h>
 #include <klish/ktp.h>
@@ -244,14 +246,37 @@ static bool_t ktpd_session_process_auth(ktpd_session_t *ktpd, faux_msg_t *msg)
 {
 	ktp_cmd_e cmd = KTP_AUTH_ACK;
 	uint32_t status = KTP_STATUS_NONE;
+	faux_msg_t *ack = NULL;
 	char *prompt = NULL;
 	uint8_t retcode8bit = 0;
+	struct ucred ucred = {};
+	socklen_t len = sizeof(ucred);
+	int sock = -1;
+	char *user = NULL;
 
 	assert(ktpd);
 	assert(msg);
 
+	// Get UNIX socket peer information
+	sock = faux_async_fd(ktpd->async);
+	if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &ucred, &len) < 0) {
+		const char *err = "Can't get peer credentials";
+		syslog(LOG_ERR, "%s for connection %d", err, sock);
+		ack = ktp_msg_preform(cmd, KTP_STATUS_ERROR | KTP_STATUS_EXIT);
+		faux_msg_add_param(ack, KTP_PARAM_ERROR, err, strlen(err));
+		faux_msg_send_async(ack, ktpd->async);
+		faux_msg_free(ack);
+		ktpd->exit = BOOL_TRUE;
+		return BOOL_FALSE;
+	}
+	ksession_set_pid(ktpd->session, ucred.pid);
+	ksession_set_uid(ktpd->session, ucred.uid);
+	user = faux_sysdb_name_by_uid(ucred.uid);
+	ksession_set_user(ktpd->session, user);
+	faux_str_free(user);
+
 	// Prepare ACK message
-	faux_msg_t *ack = ktp_msg_preform(cmd, status);
+	ack = ktp_msg_preform(cmd, status);
 	faux_msg_add_param(ack, KTP_PARAM_RETCODE, &retcode8bit, 1);
 	// Generate prompt
 	prompt = generate_prompt(ktpd);

+ 26 - 0
plugins/script/script.c

@@ -101,9 +101,14 @@ static bool_t populate_env(kcontext_t *context)
 {
 	kcontext_type_e type = KCONTEXT_TYPE_NONE;
 	const kentry_t *entry = NULL;
+	const ksession_t *session = NULL;
 	const char *str = NULL;
+	pid_t pid = -1;
+	uid_t uid = -1;
 
 	assert(context);
+	session = kcontext_session(context);
+	assert(session);
 
 	// Type
 	type = kcontext_type(context);
@@ -121,6 +126,27 @@ static bool_t populate_env(kcontext_t *context)
 	if (str)
 		setenv(PREFIX"VALUE", str, OVERWRITE);
 
+	// PID
+	pid = ksession_pid(session);
+	if (pid != -1) {
+		char *t = faux_str_sprintf("%lld", (long long int)pid);
+		setenv(PREFIX"PID", t, OVERWRITE);
+		faux_str_free(t);
+	}
+
+	// UID
+	uid = ksession_uid(session);
+	if (uid != -1) {
+		char *t = faux_str_sprintf("%lld", (long long int)uid);
+		setenv(PREFIX"UID", t, OVERWRITE);
+		faux_str_free(t);
+	}
+
+	// User
+	str = ksession_user(session);
+	if (str)
+		setenv(PREFIX"USER", str, OVERWRITE);
+
 	// Parameters
 	populate_env_kpargv(kcontext_pargv(context), PREFIX);