summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLee Duncan <lduncan@suse.com>2022-05-16 17:29:30 -0700
committerGitHub <noreply@github.com>2022-05-16 17:29:30 -0700
commit433fad9ddadd62e5edf9597493f32a3b9443cc59 (patch)
treec3ac5f0733cc34595e970f027e13ac392e5c340a
parent9dc06a2a75438907cbac0a1523f4d235d28ab58b (diff)
parent4b377041ef88f7c683b0a880e937e71a773c2c68 (diff)
downloadopen-iscsi-433fad9ddadd62e5edf9597493f32a3b9443cc59.tar.gz
Merge pull request #350 from ericwmackay/ipc_auth_uid
Add ability for MGMT IPC to check UID only
-rw-r--r--etc/iscsid.conf6
-rw-r--r--usr/Makefile2
-rw-r--r--usr/event_poll.c12
-rw-r--r--usr/iscsi_ipc.h13
-rw-r--r--usr/iscsid.c6
-rw-r--r--usr/iscsistart.c2
-rw-r--r--usr/mgmt_ipc.c54
-rw-r--r--usr/mgmt_ipc.h1
-rw-r--r--usr/statics.c19
9 files changed, 89 insertions, 26 deletions
diff --git a/etc/iscsid.conf b/etc/iscsid.conf
index 2dc412f..79d8127 100644
--- a/etc/iscsid.conf
+++ b/etc/iscsid.conf
@@ -31,6 +31,12 @@
# and refuse to logout if there are any. Defaults to "No".
# iscsid.safe_logout = Yes
+# Only require UID auth for MGMT IPCs, and not username.
+# Useful if you want to run iscsid in a constrained environment.
+# Note: Only do this if you are aware of the security implications.
+# Defaults to "No".
+# iscsid.ipc_auth_uid = Yes
+
#############################
# NIC/HBA and driver settings
#############################
diff --git a/usr/Makefile b/usr/Makefile
index c5571b6..79840fc 100644
--- a/usr/Makefile
+++ b/usr/Makefile
@@ -64,7 +64,7 @@ PROGRAMS_DEST = $(addprefix $(DESTDIR)$(SBINDIR)/,$(PROGRAMS))
ISCSID_OBJS = iscsid.o session_mgmt.o discoveryd.o mntcheck.o
ISCSIADM_OBJS = iscsiadm.o session_mgmt.o mntcheck.o
-ISCSISTART_OBJS = iscsistart.o statics.o
+ISCSISTART_OBJS = iscsistart.o
# libc compat files
SYSDEPS_DIR = $(TOPDIR)/utils/sysdeps
diff --git a/usr/event_poll.c b/usr/event_poll.c
index ffd12a3..f39f899 100644
--- a/usr/event_poll.c
+++ b/usr/event_poll.c
@@ -195,8 +195,16 @@ void event_loop(struct iscsi_ipc *ipc, int control_fd, int mgmt_ipc_fd)
if (poll_array[POLL_CTRL].revents)
ipc->ctldev_handle();
- if (poll_array[POLL_IPC].revents)
- mgmt_ipc_handle(mgmt_ipc_fd);
+ if (poll_array[POLL_IPC].revents) {
+ switch (ipc->auth_type) {
+ case ISCSI_IPC_AUTH_UID:
+ mgmt_ipc_handle_uid_only(mgmt_ipc_fd);
+ break;
+ default:
+ mgmt_ipc_handle(mgmt_ipc_fd);
+ break;
+ }
+ }
if (poll_array[POLL_ALARM].revents) {
struct signalfd_siginfo si;
diff --git a/usr/iscsi_ipc.h b/usr/iscsi_ipc.h
index 47857dd..78bd29a 100644
--- a/usr/iscsi_ipc.h
+++ b/usr/iscsi_ipc.h
@@ -52,6 +52,17 @@ struct iscsi_ipc_ev_clbk {
extern void ipc_register_ev_callback(struct iscsi_ipc_ev_clbk *ipc_ev_clbk);
+enum iscsi_ipc_auth_type {
+ /* UID must have valid entry in user db */
+ ISCSI_IPC_AUTH_DEFAULT = 0,
+
+ /* Check only that UID==0 */
+ ISCSI_IPC_AUTH_UID,
+
+ /* Must be last */
+ ISCSI_IPC_AUTH_MAX,
+};
+
/**
* struct iscsi_ipc - Open-iSCSI Interface for Kernel IPC
*
@@ -63,6 +74,8 @@ struct iscsi_ipc {
int ctldev_bufmax;
+ enum iscsi_ipc_auth_type auth_type;
+
int (*ctldev_open) (void);
void (*ctldev_close) (void);
diff --git a/usr/iscsid.c b/usr/iscsid.c
index d97738c..8441037 100644
--- a/usr/iscsid.c
+++ b/usr/iscsid.c
@@ -383,6 +383,7 @@ int main(int argc, char *argv[])
char *initiatorname_file = INITIATOR_NAME_FILE;
char *pid_file = PID_FILE;
char *safe_logout;
+ char *ipc_auth_uid;
int ch, longindex;
uid_t uid = 0;
struct sigaction sa_old;
@@ -583,6 +584,11 @@ int main(int argc, char *argv[])
daemon_config.safe_logout = 1;
free(safe_logout);
+ ipc_auth_uid = cfg_get_string_param(config_file, "iscsid.ipc_auth_uid");
+ if (ipc_auth_uid && !strcmp(ipc_auth_uid, "Yes"))
+ ipc->auth_type = ISCSI_IPC_AUTH_UID;
+ free(ipc_auth_uid);
+
/* see if we have any stale sessions to recover */
sessions_to_recover = iscsi_sysfs_count_sessions();
if (sessions_to_recover) {
diff --git a/usr/iscsistart.c b/usr/iscsistart.c
index b23751b..0fb1f56 100644
--- a/usr/iscsistart.c
+++ b/usr/iscsistart.c
@@ -527,6 +527,8 @@ int main(int argc, char *argv[])
log_debug(1, "TPGT=%d", config_rec.tpgt);
log_debug(1, "IP Address=%s", config_rec.conn[0].address);
+ ipc->auth_type = ISCSI_IPC_AUTH_UID;
+
/* log the version, so that we can tell if the daemon and kernel module
* match based on what shows up in the syslog. Tarballs releases
* always install both, but Linux distributors may put the kernel module
diff --git a/usr/mgmt_ipc.c b/usr/mgmt_ipc.c
index c23bcc0..0ee513f 100644
--- a/usr/mgmt_ipc.c
+++ b/usr/mgmt_ipc.c
@@ -27,6 +27,7 @@
#include <pwd.h>
#include <sys/un.h>
#include <string.h>
+#include <stdbool.h>
#include "iscsid.h"
#include "idbm.h"
@@ -379,6 +380,32 @@ mgmt_peeruser(int sock, char *user)
return 1;
}
+static bool
+mgmt_authorized_uid(int sock)
+{
+ int authorized = false;
+ struct ucred peercred = {0};
+ socklen_t so_len = sizeof(peercred);
+
+ errno = 0;
+ if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peercred,
+ &so_len) != 0 || so_len != sizeof(peercred)) {
+ /* We didn't get a valid credentials struct. */
+ log_error("Error receiving credentials: %m");
+ goto ret_auth;
+ }
+
+ /* Only UID==0 is authorized */
+ authorized = peercred.uid ? false: true;
+
+ if (!authorized) {
+ log_error("Unauthorized user with UID=%u", peercred.uid);
+ }
+
+ret_auth:
+ return authorized;
+}
+
static void
mgmt_ipc_destroy_queue_task(queue_task_t *qtask)
{
@@ -488,7 +515,7 @@ static mgmt_ipc_fn_t * mgmt_ipc_functions[__MGMT_IPC_MAX_COMMAND] = {
[MGMT_IPC_NOTIFY_DEL_PORTAL] = mgmt_ipc_notify_del_portal,
};
-void mgmt_ipc_handle(int accept_fd)
+static void mgmt_ipc_handle_check_auth(int accept_fd, bool auth_uid_only)
{
unsigned int command;
int fd, err;
@@ -508,9 +535,16 @@ void mgmt_ipc_handle(int accept_fd)
qtask->allocated = 1;
qtask->mgmt_ipc_fd = fd;
- if (!mgmt_peeruser(fd, user) || strncmp(user, "root", PEERUSER_MAX)) {
- err = ISCSI_ERR_ACCESS;
- goto err;
+ if (auth_uid_only) {
+ if (!mgmt_authorized_uid(fd)) {
+ err = ISCSI_ERR_ACCESS;
+ goto err;
+ }
+ } else {
+ if (!mgmt_peeruser(fd, user) || strncmp(user, "root", PEERUSER_MAX)) {
+ err = ISCSI_ERR_ACCESS;
+ goto err;
+ }
}
if (mgmt_ipc_read_req(qtask) < 0) {
@@ -542,3 +576,15 @@ err:
* connection and free the qtask */
mgmt_ipc_write_rsp(qtask, err);
}
+
+void mgmt_ipc_handle(int accept_fd)
+{
+ /* Default behavior. Full auth check. */
+ mgmt_ipc_handle_check_auth(accept_fd, false);
+}
+
+void mgmt_ipc_handle_uid_only(int accept_fd)
+{
+ /* Check only originating UID. */
+ mgmt_ipc_handle_check_auth(accept_fd, true);
+}
diff --git a/usr/mgmt_ipc.h b/usr/mgmt_ipc.h
index 55972ed..cc6ef1b 100644
--- a/usr/mgmt_ipc.h
+++ b/usr/mgmt_ipc.h
@@ -115,5 +115,6 @@ int mgmt_ipc_listen(void);
int mgmt_ipc_systemd(void);
void mgmt_ipc_close(int fd);
void mgmt_ipc_handle(int accept_fd);
+void mgmt_ipc_handle_uid_only(int accept_fd);
#endif /* MGMT_IPC_H */
diff --git a/usr/statics.c b/usr/statics.c
deleted file mode 100644
index f59729b..0000000
--- a/usr/statics.c
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <unistd.h>
-#include <pwd.h>
-#include <errno.h>
-#include <sys/types.h>
-
-static struct passwd root_pw = {
- .pw_name = "root",
-};
-
-struct passwd*
-getpwuid(uid_t uid)
-{
- if (uid == 0)
- return &root_pw;
- else {
- errno = ENOENT;
- return 0;
- }
-}