1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
Patch from upstream (also applied to upstream trunk) to set the owner user/group of the control socket to that of the running uid/gid.
--- a/main.c
+++ b/main.c
@@ -42,9 +42,11 @@
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
+#include <grp.h>
#include <limits.h>
#include <netdb.h>
#include <poll.h>
+#include <pwd.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
@@ -122,6 +124,8 @@ init_config(struct cfg *cf, int argc, ch
{
int ch, i;
char *bh[2], *bh6[2], *cp;
+ struct passwd *pp;
+ struct group *gp;
bh[0] = bh[1] = bh6[0] = bh6[1] = NULL;
@@ -242,6 +246,22 @@ init_config(struct cfg *cf, int argc, ch
cp++;
}
cf->run_gname = cp;
+ cf->run_uid = -1;
+ cf->run_gid = -1;
+ if (cf->run_uname != NULL) {
+ pp = getpwnam(cf->run_uname);
+ if (pp == NULL)
+ err(1, "can't find ID for the user: %s", cf->run_uname);
+ cf->run_uid = pp->pw_uid;
+ if (cf->run_gname == NULL)
+ cf->run_gid = pp->pw_gid;
+ }
+ if (cf->run_gname != NULL) {
+ gp = getgrnam(cf->run_gname);
+ if (gp == NULL)
+ err(1, "can't find ID for the group: %s", cf->run_gname);
+ cf->run_gid = gp->gr_gid;
+ }
break;
case 'F':
@@ -364,6 +384,9 @@ init_controlfd(struct cfg *cf)
sizeof controlfd);
if (bind(controlfd, sstosa(&ifsun), sizeof ifsun) < 0)
err(1, "can't bind to a socket");
+ if ((cf->run_uname != NULL || cf->run_gname != NULL) &&
+ chown(cmd_sock, cf->run_uid, cf->run_gid) == -1)
+ err(1, "can't set owner of the socket");
if (listen(controlfd, 32) != 0)
err(1, "can't listen on a socket");
} else {
@@ -719,7 +742,7 @@ main(int argc, char **argv)
signal(SIGUSR2, fatsignal);
if (cf.run_uname != NULL || cf.run_gname != NULL) {
- if (drop_privileges(&cf, cf.run_uname, cf.run_gname) != 0) {
+ if (drop_privileges(&cf) != 0) {
rtpp_log_ewrite(RTPP_LOG_ERR, cf.glog,
"can't switch to requested user/group");
exit(1);
--- a/rtpp_defines.h
+++ b/rtpp_defines.h
@@ -102,6 +102,9 @@ struct cfg {
char *run_uname;
char *run_gname;
int no_check;
+
+ uid_t run_uid;
+ gid_t run_gid;
};
#endif
--- a/rtpp_util.c
+++ b/rtpp_util.c
@@ -172,37 +172,19 @@ seedrandom(void)
}
int
-drop_privileges(struct cfg *cf, char *uname, char *gname)
+drop_privileges(struct cfg *cf)
{
- struct passwd *pp;
- struct group *gp;
- if (gname != NULL) {
- gp = getgrnam(gname);
- if (gp == NULL) {
- rtpp_log_ewrite(RTPP_LOG_ERR, cf->glog, "can't find ID for the group: %s", gname);
- return -1;
- }
- if (setgid(gp->gr_gid) != 0) {
- rtpp_log_ewrite(RTPP_LOG_ERR, cf->glog, "can't set current group ID: %d", gp->gr_gid);
+ if (cf->run_gname != NULL) {
+ if (setgid(cf->run_gid) != 0) {
+ rtpp_log_ewrite(RTPP_LOG_ERR, cf->glog, "can't set current group ID: %d", cf->run_gid);
return -1;
}
}
- if (uname == NULL)
+ if (cf->run_uname == NULL)
return 0;
- pp = getpwnam(uname);
- if (pp == NULL) {
- rtpp_log_ewrite(RTPP_LOG_ERR, cf->glog, "can't find ID for the user: %s", uname);
- return -1;
- }
- if (gname == NULL) {
- if (setgid(pp->pw_gid) != 0) {
- rtpp_log_ewrite(RTPP_LOG_ERR, cf->glog, "can't set current group ID: %d", pp->pw_gid);
- return -1;
- }
- }
- if (setuid(pp->pw_uid) != 0) {
- rtpp_log_ewrite(RTPP_LOG_ERR, cf->glog, "can't set current user ID: %d", pp->pw_uid);
+ if (setuid(cf->run_uid) != 0) {
+ rtpp_log_ewrite(RTPP_LOG_ERR, cf->glog, "can't set current user ID: %d", cf->run_uid);
return -1;
}
return 0;
--- a/rtpp_util.h
+++ b/rtpp_util.h
@@ -53,7 +53,7 @@ const char *addr2char(struct sockaddr *)
double getctime(void);
int resolve(struct sockaddr *, int, const char *, const char *, int);
void seedrandom(void);
-int drop_privileges(struct cfg *, char *, char *);
+int drop_privileges(struct cfg *);
/* Stripped down version of sockaddr_in* for saving space */
struct sockaddr_in4_s {
|