Просмотр исходного кода

qdevice: Add option to change socket file umask

Both qnetd and qdevice were not changing umask so local socket file
was usually not accessible by user from same user group as
qdevice/qnetd. This is mainly problem if daemon is running as coroqnetd
user and it is needed to run corosync-qnetd-tool as non-root user.

Patch adds advanced option (local_socket_umask) which allows to change
umask before socket is created.

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Jan Friesse 4 месяцев назад
Родитель
Сommit
c68be1ec68

+ 5 - 1
man/corosync-qdevice.8

@@ -31,7 +31,7 @@
 .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 .\" * THE POSSIBILITY OF SUCH DAMAGE.
 .\" */
-.TH COROSYNC-QDEVICE 8 2020-10-27
+.TH COROSYNC-QDEVICE 8 2025-10-13
 .SH NAME
 corosync-qdevice \- QDevice daemon
 .SH SYNOPSIS
@@ -357,6 +357,10 @@ Lock file location. (/var/run/corosync-qdevice/corosync-qdevice.pid)
 .B local_socket_file
 Internal IPC socket file location. (/var/run/corosync-qdevice/corosync-qdevice.sock)
 .TP
+.B local_socket_umask
+Octal value of umask used before creating of internal IPC socket file or empty if umask
+shouldn't be modified. ()
+.TP
 .B local_socket_backlog
 Parameter passed to listen syscall. (10)
 .TP

+ 5 - 1
man/corosync-qnetd.8

@@ -31,7 +31,7 @@
 .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 .\" * THE POSSIBILITY OF SUCH DAMAGE.
 .\" */
-.TH COROSYNC-QNETD 8 2020-11-18
+.TH COROSYNC-QNETD 8 2025-10-13
 .SH NAME
 corosync-qnetd \- QNet daemon
 .SH SYNOPSIS
@@ -226,6 +226,10 @@ Lock file location. (/var/run/corosync-qnetd/corosync-qnetd.pid)
 .B local_socket_file
 Internal IPC socket file location. (/var/run/corosync-qnetd/corosync-qnetd.sock)
 .TP
+.B local_socket_umask
+Octal value of umask used before creating of internal IPC socket file or empty if umask
+shouldn't be modified. ()
+.TP
 .B local_socket_backlog
 Parameter passed to listen syscall on the local socket. (10)
 .TP

+ 9 - 0
qdevices/qdevice-advanced-settings.c

@@ -34,6 +34,9 @@
 
 #include <stdlib.h>
 
+#include <sys/types.h>
+#include <sys/stat.h>
+
 #include <errno.h>
 #include <limits.h>
 #include <string.h>
@@ -57,6 +60,7 @@ qdevice_advanced_settings_init(struct qdevice_advanced_settings *settings)
 	if ((settings->local_socket_file = strdup(QDEVICE_DEFAULT_LOCAL_SOCKET_FILE)) == NULL) {
 		return (-1);
 	}
+	settings->set_local_socket_umask = 0;
 	settings->local_socket_backlog = QDEVICE_DEFAULT_LOCAL_SOCKET_BACKLOG;
 	settings->max_cs_try_again = QDEVICE_DEFAULT_MAX_CS_TRY_AGAIN;
 	if ((settings->votequorum_device_name = strdup(QDEVICE_DEFAULT_VOTEQUORUM_DEVICE_NAME)) == NULL) {
@@ -141,6 +145,11 @@ qdevice_advanced_settings_set(struct qdevice_advanced_settings *settings,
 		if ((settings->local_socket_file = strdup(value)) == NULL) {
 			return (-1);
 		}
+	} else if (strcasecmp(option, "local_socket_umask") == 0) {
+		if (utils_parse_umask(value, &settings->set_local_socket_umask,
+		    &settings->local_socket_umask) != 0) {
+			return (-2);
+		}
 	} else if (strcasecmp(option, "local_socket_backlog") == 0) {
 		if (utils_strtonum(value, QDEVICE_MIN_LOCAL_SOCKET_BACKLOG, INT_MAX, &tmpll) == -1) {
 			return (-2);

+ 4 - 0
qdevices/qdevice-advanced-settings.h

@@ -35,6 +35,8 @@
 #ifndef _QDEVICE_ADVANCED_SETTINGS_H_
 #define _QDEVICE_ADVANCED_SETTINGS_H_
 
+#include <sys/types.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -48,6 +50,8 @@ enum qdevice_advanced_settings_master_wins {
 struct qdevice_advanced_settings {
 	char *lock_file;
 	char *local_socket_file;
+	int set_local_socket_umask;
+	mode_t local_socket_umask;
 	int local_socket_backlog;
 	int max_cs_try_again;
 	char *votequorum_device_name;

+ 2 - 0
qdevices/qdevice-ipc.c

@@ -175,6 +175,8 @@ qdevice_ipc_init(struct qdevice_instance *instance)
 
 	if (unix_socket_ipc_init(&instance->local_ipc,
 	    instance->advanced_settings->local_socket_file,
+	    instance->advanced_settings->set_local_socket_umask,
+	    instance->advanced_settings->local_socket_umask,
 	    instance->advanced_settings->local_socket_backlog,
 	    instance->advanced_settings->ipc_max_clients,
 	    instance->advanced_settings->ipc_max_receive_size,

+ 9 - 0
qdevices/qnetd-advanced-settings.c

@@ -34,6 +34,9 @@
 
 #include <stdlib.h>
 
+#include <sys/types.h>
+#include <sys/stat.h>
+
 #include <errno.h>
 #include <limits.h>
 #include <string.h>
@@ -70,6 +73,7 @@ qnetd_advanced_settings_init(struct qnetd_advanced_settings *settings)
 	if ((settings->local_socket_file = strdup(QNETD_DEFAULT_LOCAL_SOCKET_FILE)) == NULL) {
 		return (-1);
 	}
+	settings->set_local_socket_umask = 0;
 	settings->local_socket_backlog = QNETD_DEFAULT_LOCAL_SOCKET_BACKLOG;
 	settings->ipc_max_clients = QNETD_DEFAULT_IPC_MAX_CLIENTS;
 	settings->ipc_max_receive_size = QNETD_DEFAULT_IPC_MAX_RECEIVE_SIZE;
@@ -178,6 +182,11 @@ qnetd_advanced_settings_set(struct qnetd_advanced_settings *settings,
 		if ((settings->local_socket_file = strdup(value)) == NULL) {
 			return (-1);
 		}
+	} else if (strcasecmp(option, "local_socket_umask") == 0) {
+		if (utils_parse_umask(value, &settings->set_local_socket_umask,
+		    &settings->local_socket_umask) != 0) {
+			return (-2);
+		}
 	} else if (strcasecmp(option, "local_socket_backlog") == 0) {
 		if (utils_strtonum(value, QNETD_MIN_LOCAL_SOCKET_BACKLOG, INT_MAX, &tmpll) == -1) {
 			return (-2);

+ 4 - 0
qdevices/qnetd-advanced-settings.h

@@ -35,6 +35,8 @@
 #ifndef _QNETD_ADVANCED_SETTINGS_H_
 #define _QNETD_ADVANCED_SETTINGS_H_
 
+#include <sys/types.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -51,6 +53,8 @@ struct qnetd_advanced_settings {
 	uint8_t dpd_enabled;
 	char *lock_file;
 	char *local_socket_file;
+	int set_local_socket_umask;
+	mode_t local_socket_umask;
 	int local_socket_backlog;
 	size_t ipc_max_clients;
 	size_t ipc_max_send_size;

+ 2 - 0
qdevices/qnetd-ipc.c

@@ -175,6 +175,8 @@ qnetd_ipc_init(struct qnetd_instance *instance)
 
 	if (unix_socket_ipc_init(&instance->local_ipc,
 	    instance->advanced_settings->local_socket_file,
+	    instance->advanced_settings->set_local_socket_umask,
+	    instance->advanced_settings->local_socket_umask,
 	    instance->advanced_settings->local_socket_backlog,
 	    instance->advanced_settings->ipc_max_clients,
 	    instance->advanced_settings->ipc_max_receive_size,

+ 23 - 0
qdevices/test-utils.c

@@ -48,6 +48,8 @@ main(void)
 	double dbl;
 	double dbli;
 	char buf[32];
+	int set_umask;
+	mode_t umask;
 
 	assert(utils_strtonum("0", 0, 100, &ll) == 0);
 	assert(ll == 0);
@@ -176,5 +178,26 @@ main(void)
 	assert(utils_strtod("inf", -1000, 1000, &dbl) == -1);
 	assert(utils_strtod("nan", -1000, 1000, &dbl) == -1);
 
+	assert(utils_parse_umask("0", &set_umask, &umask) == 0);
+	assert(set_umask == 1 && umask == 0);
+
+	assert(utils_parse_umask("02", &set_umask, &umask) == 0);
+	assert(set_umask == 1 && umask == 02);
+
+	assert(utils_parse_umask("777", &set_umask, &umask) == 0);
+	assert(set_umask == 1 && umask == 0777);
+
+	assert(utils_parse_umask("", &set_umask, &umask) == 0);
+	assert(set_umask == 0);
+
+	assert(utils_parse_umask("02", &set_umask, &umask) == 0);
+	assert(set_umask == 1 && umask == 02);
+
+	assert(utils_parse_umask("string", &set_umask, &umask) == -1);
+	assert(utils_parse_umask("888", &set_umask, &umask) == -1);
+	assert(utils_parse_umask("8", &set_umask, &umask) == -1);
+	assert(utils_parse_umask("unset", &set_umask, &umask) == -1);
+
+
 	return (0);
 }

+ 5 - 4
qdevices/unix-socket-ipc.c

@@ -39,8 +39,9 @@
 #include "unix-socket-ipc.h"
 
 int
-unix_socket_ipc_init(struct unix_socket_ipc *ipc, const char *socket_file_name, int backlog,
-    size_t max_clients, size_t max_receive_size, size_t max_send_size)
+unix_socket_ipc_init(struct unix_socket_ipc *ipc, const char *socket_file_name,
+    int set_socket_umask, mode_t socket_umask, int backlog, size_t max_clients,
+    size_t max_receive_size, size_t max_send_size)
 {
 
 	memset(ipc, 0, sizeof(*ipc));
@@ -53,8 +54,8 @@ unix_socket_ipc_init(struct unix_socket_ipc *ipc, const char *socket_file_name,
 	unix_socket_client_list_init(&ipc->clients);
 
 	ipc->backlog = backlog;
-	ipc->socket = unix_socket_server_create(ipc->socket_file_name, 1,
-		backlog);
+	ipc->socket = unix_socket_server_create(ipc->socket_file_name,
+	    set_socket_umask, socket_umask, 1, backlog);
 	if (ipc->socket < 0) {
 		free(ipc->socket_file_name);
 		return (-1);

+ 2 - 1
qdevices/unix-socket-ipc.h

@@ -53,7 +53,8 @@ struct unix_socket_ipc {
 };
 
 extern int		unix_socket_ipc_init(struct unix_socket_ipc *ipc,
-    const char *socket_file_name, int backlog, size_t max_clients, size_t max_receive_size,
+    const char *socket_file_name, int set_socket_umask, mode_t socket_umask,
+    int backlog, size_t max_clients, size_t max_receive_size,
     size_t max_send_size);
 
 extern int		unix_socket_ipc_destroy(struct unix_socket_ipc *ipc);

+ 18 - 2
qdevices/unix-socket.c

@@ -32,7 +32,9 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/stat.h>
 #include <sys/un.h>
 
 #include <errno.h>
@@ -43,10 +45,13 @@
 #include "utils.h"
 
 int
-unix_socket_server_create(const char *path, int non_blocking, int backlog)
+unix_socket_server_create(const char *path, int set_socket_umask, mode_t socket_umask,
+    int non_blocking, int backlog)
 {
 	int s;
 	struct sockaddr_un sun;
+	mode_t old_umask;
+	int bind_res;
 
 	if (strlen(path) >= sizeof(sun.sun_path) || strlen(path) == 0) {
 		errno = ENAMETOOLONG;
@@ -62,7 +67,18 @@ unix_socket_server_create(const char *path, int non_blocking, int backlog)
 
 	strncpy(sun.sun_path, path, sizeof(sun.sun_path) - 1);
 	unlink(path);
-	if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) != 0) {
+
+	if (set_socket_umask) {
+		old_umask = umask(socket_umask);
+	}
+
+	bind_res = bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun));
+
+	if (set_socket_umask) {
+		(void)umask(old_umask);
+	}
+
+	if (bind_res != 0) {
 		close(s);
 
 		return (-1);

+ 2 - 1
qdevices/unix-socket.h

@@ -43,7 +43,8 @@
 extern "C" {
 #endif
 
-extern int		unix_socket_server_create(const char *path, int non_blocking, int backlog);
+extern int		unix_socket_server_create(const char *path,
+    int set_socket_umask, mode_t socket_umask, int non_blocking, int backlog);
 
 extern int		unix_socket_client_create(const char *path, int non_blocking);
 

+ 24 - 0
qdevices/utils.c

@@ -278,3 +278,27 @@ utils_strtod(const char *str, double min_val, double max_val,
 
 	return (0);
 }
+
+/*
+ * Check if string is empty and set set_umask to 0, or parse string
+ * as umask octal number and set set_umask to 1 and umask value.
+ * Return 0 on success, otherwise -1.
+ */
+int
+utils_parse_umask(const char *str, int *set_umask, mode_t *umask)
+{
+	long long int tmpll;
+
+	if (strcmp(str, "") == 0) {
+		*set_umask = 0;
+	} else {
+		if (utils_strtonum_base(str, 0, S_IRWXU|S_IRWXG|S_IRWXO, 8, &tmpll) == -1) {
+			return (-1);
+		}
+
+		*set_umask = 1;
+		*umask = (mode_t)tmpll;
+	}
+
+	return (0);
+}

+ 3 - 0
qdevices/utils.h

@@ -71,6 +71,9 @@ extern int		utils_strtonum_base(const char *str, long long int min_val,
 extern int		utils_strtod(const char *str, double min_val, double max_val,
     double *res);
 
+extern int		utils_parse_umask(const char *str, int *set_umask,
+    mode_t *umask);
+
 #ifdef __cplusplus
 }
 #endif