Explorar o código

Added support for username/groupname

Added support for username/groupname to seuid, setgid, chroot.
z3APA3A %!s(int64=7) %!d(string=hai) anos
pai
achega
5149996b20
Modificáronse 2 ficheiros con 62 adicións e 10 borrados
  1. 5 5
      man/3proxy.cfg.3
  2. 57 5
      src/conf.c

+ 5 - 5
man/3proxy.cfg.3

@@ -931,21 +931,21 @@ configuration within one minute. Any number of files may be monitored.
 .B setuid
 <uid>
 .br
- calls setuid(uid), uid must be numeric. Unix only. Warning: under some Linux
-kernels setuid() works onle for current thread. It makes it impossible to suid
+ calls setuid(uid), uid can be numeric or since 0.9 username. Unix only. Warning: under some Linux
+kernels setuid() works for current thread only. It makes it impossible to suid
 for all threads.
 
 .br
 .B setgid
 <gid>
 .br
- calls setgid(gid), gid must be numeric. Unix only.
+ calls setgid(gid), gid can be numeric or since 0.9 groupname. Unix only.
 
 .br
 .B chroot
-<path>
+<path> [<uid>] [<gid>]
 .br
- calls chroot(path). Unix only.
+ calls chroot(path) and sets gid/uid. Unix only. uid/gid supported since 0.9, can be numeric or username/groupname
 
 .br
 .B stacksize

+ 57 - 5
src/conf.c

@@ -9,6 +9,8 @@
 #include "proxy.h"
 #ifndef _WIN32
 #include <sys/resource.h>
+#include <pwd.h>
+#include <grp.h>
 #ifndef NOPLUGINS
 #include <dlfcn.h>
 #endif
@@ -1398,9 +1400,23 @@ static int h_plugin(int argc, unsigned char **argv){
 }
 
 #ifndef _WIN32
+
+uid_t strtouid(unsigned char *str){
+ uid_t res = 0;
+
+	if(!isnumber(*(char *)str)){
+		struct passwd *pw;
+		pw = getpwnam((char *)str);
+		if(pw) res = pw->pw_uid;
+	}
+	else res = atoi((char *)str);
+	return res;
+}
+
+
 static int h_setuid(int argc, unsigned char **argv){
-  int res;
-	res = atoi((char *)argv[1]);
+  uid_t res = 0;
+	res = strtouid(argv[1]);
 	if(!res || setreuid(res,res)) {
 		fprintf(stderr, "Unable to set uid %d", res);
 		return(1);
@@ -1408,10 +1424,21 @@ static int h_setuid(int argc, unsigned char **argv){
 	return 0;
 }
 
+gid_t strtogid(unsigned char *str){
+  gid_t res;
+
+	if(!isnumber(*(char *)str)){
+		struct group *gr;
+		gr = getgrnam((char *)str);
+		if(gr) res = gr->gr_gid;
+	}
+	else res = atoi((char *)str);
+}
+
 static int h_setgid(int argc, unsigned char **argv){
-  int res;
+  gid_t res = 0;
 
-	res = atoi((char *)argv[1]);
+	res = strtogid(argv[1]);
 	if(!res || setregid(res,res)) {
 		fprintf(stderr, "Unable to set gid %d", res);
 		return(1);
@@ -1421,6 +1448,22 @@ static int h_setgid(int argc, unsigned char **argv){
 
 
 static int h_chroot(int argc, unsigned char **argv){
+	uid_t uid = 0;
+	gid_t gid = 0;
+	if(argc > 2) {
+		uid = strtouid(argv[2]);
+		if(!uid){
+			fprintf(stderr, "Unable to resolve uid %s", argv[2]);
+			return(2);
+		}
+        }
+	if(argc > 3) {
+		gid = strtogid(argv[3]);
+		if(!gid){
+			fprintf(stderr, "Unable to resolve gid %s", argv[3]);
+			return(3);
+		}
+        }
 	if(!chrootp){
 		char *p;
 		if(chroot((char *)argv[1])) {
@@ -1434,6 +1477,15 @@ static int h_chroot(int argc, unsigned char **argv){
 		}
 		chrootp = mystrdup((char *)argv[1]);
 	}
+	if (gid && setregid(gid,gid)) {
+		fprintf(stderr, "Unable to set gid %d", (int)gid);
+		return(4);
+	}
+	if (uid && setreuid(uid,uid)) {
+		fprintf(stderr, "Unable to set uid %d", (int)uid);
+		return(5);
+	}
+
 	return 0;
 }
 #endif
@@ -1443,7 +1495,7 @@ struct commands specificcommands[]={
 #ifndef _WIN32
 	{specificcommands+1, "setuid", h_setuid, 2, 2},
 	{specificcommands+2, "setgid", h_setgid, 2, 2},
-	{specificcommands+3, "chroot", h_chroot, 2, 2},
+	{specificcommands+3, "chroot", h_chroot, 2, 4},
 #endif
 	{NULL, 		"", h_noop, 1, 0}
 };