This mirrors similar parameters in Postgres config.
; unix socket is also used for -R.
; On debian it should be /var/run/postgresql
;unix_socket_dir = /tmp
+;unix_socket_mode = 0777
+;unix_socket_group =
;;;
;;; Authentication settings
extern char *cf_jobname;
extern char *cf_unix_socket_dir;
+extern int cf_unix_socket_mode;
+extern char *cf_unix_socket_group;
extern char *cf_listen_addr;
extern int cf_listen_port;
extern int cf_listen_backlog;
void change_user(const char *user);
+void change_file_mode(const char *fn, mode_t mode, const char *user, const char *group);
+
int cf_listen_port;
int cf_listen_backlog;
char *cf_unix_socket_dir;
+int cf_unix_socket_mode;
+char *cf_unix_socket_group;
int cf_pool_mode = POOL_SESSION;
CF_ABS("listen_backlog", CF_INT, cf_listen_backlog, CF_NO_RELOAD, "128"),
#ifndef WIN32
CF_ABS("unix_socket_dir", CF_STR, cf_unix_socket_dir, CF_NO_RELOAD, "/tmp"),
+CF_ABS("unix_socket_mode", CF_INT, cf_unix_socket_mode, CF_NO_RELOAD, "0777"),
+CF_ABS("unix_socket_group", CF_STR, cf_unix_socket_group, CF_NO_RELOAD, ""),
#endif
CF_ABS("auth_type", CF_LOOKUP(auth_type_map), cf_auth_type, 0, "md5"),
CF_ABS("auth_file", CF_STR, cf_auth_file, 0, "unconfigured_file"),
}
if (af == AF_UNIX) {
- const struct sockaddr_un *un;
- mode_t mode = 0777;
- un = (struct sockaddr_un *)sa;
- res = chmod(un->sun_path, mode);
- if (res < 0)
- /* failure to chmod to 0777 does not seem serious */
- log_warning("add_listen: chmod(%s, 0%o) failed: %s",
- un->sun_path, mode, strerror(errno));
+ struct sockaddr_un *un = (struct sockaddr_un *)sa;
+ change_file_mode(un->sun_path, cf_unix_socket_mode, NULL, cf_unix_socket_group);
} else {
tune_accept(sock, cf_tcp_defer_accept);
}
fatal("setuid() failed to work");
}
+/* set permissions & mode for file */
+void change_file_mode(const char *fn, mode_t mode,
+ const char *user_name,
+ const char *group_name)
+{
+ int res;
+ uid_t uid = -1;
+ gid_t gid = -1;
+ unsigned long val;
+ char *end;
+
+ /* user lookup */
+ if (user_name && user_name[0]) {
+ const struct passwd *pw;
+
+ val = strtoul(user_name, &end, 0);
+ if (*end == 0) {
+ uid = val;
+ } else {
+ /* check for a valid username */
+ pw = getpwnam(user_name);
+ if (!pw)
+ fatal("could not find user '%s': %s",
+ user_name, strerror(errno));
+ uid = pw->pw_uid;
+ }
+ }
+
+ /* group lookup */
+ if (group_name && group_name[0]) {
+ struct group *gr;
+
+ val = strtoul(group_name, &end, 0);
+ if (*end == 0) {
+ gid = val;
+ } else {
+ gr = getgrnam(group_name);
+ if (!gr)
+ fatal("cound not find group '%s': %s",
+ group_name, strerror(errno));
+ gid = gr->gr_gid;
+ }
+ }
+
+ /* change user/group */
+ if (uid != (uid_t)-1 || gid != (gid_t)-1) {
+ res = chown(fn, uid, gid);
+ if (res != 0)
+ fatal("chown(%s, %d, %d) failed: %s",
+ fn, uid, gid, strerror(errno));
+ }
+
+ /* change mode */
+ res = chmod(fn, mode);
+ if (res != 0)
+ fatal("Failure to chmod(%s, 0%o): %s",
+ fn, mode, strerror(errno));
+}
+