summaryrefslogtreecommitdiff
path: root/community/webfs/webfs.patch
diff options
context:
space:
mode:
Diffstat (limited to 'community/webfs/webfs.patch')
-rw-r--r--community/webfs/webfs.patch250
1 files changed, 250 insertions, 0 deletions
diff --git a/community/webfs/webfs.patch b/community/webfs/webfs.patch
new file mode 100644
index 000000000..fca51a630
--- /dev/null
+++ b/community/webfs/webfs.patch
@@ -0,0 +1,250 @@
+# This patch performs the following:
+#
+# 1) user/group names my now be set to the system maximum using
+# sysconf(_SC_LOGIN_NAME_MAX). They were previously hardcoded to 16 chars.
+#
+# 2) supplementary groups are now set according to the user webfs is running as.
+# previously they were left as the calling user, which could be dangerous
+# ex: sudo webfsd -u nobody, would leave webfsd with all of root's groups!
+#
+# 3) the supplementary group list is no longer made empty when using -g
+#
+# 4) supplementary groups are now checked for read access when generating
+# directory listings
+#
+# 5) in ls.c/ls() changed type of uid and gid to uid_t and gid_t
+#
+# 6) in ls.c/ls() fixed a problem where the uid of the file was being compared
+# to the gid of the user to check for readability
+#
+# 7) added a -G option to ignore/remove all supplementary groups
+#
+# 8) updated man page to reflect -G option
+#
+# 9) when the uid is 0, all files are now displayed as readable.
+#
+
+diff -urp webfs-1.21-orig/httpd.h webfs-1.21/httpd.h
+--- webfs-1.21-orig/httpd.h 2004-06-10 05:45:50.000000000 -0400
++++ webfs-1.21/httpd.h 2010-03-27 14:57:07.631540000 -0400
+@@ -169,6 +169,8 @@ extern int lifespan;
+ extern int no_listing;
+ extern time_t now;
+ extern int have_tty;
++extern gid_t *grp_list;
++extern int grp_num;
+
+ #ifdef USE_SSL
+ extern int with_ssl;
+diff -urp webfs-1.21-orig/ls.c webfs-1.21/ls.c
+--- webfs-1.21-orig/ls.c 2004-06-10 05:45:50.000000000 -0400
++++ webfs-1.21/ls.c 2010-03-28 10:52:09.449259926 -0400
+@@ -194,7 +194,9 @@ ls(time_t now, char *hostname, char *fil
+ struct myfile **files = NULL;
+ struct myfile **re1;
+ char *h1,*h2,*re2,*buf = NULL;
+- int count,len,size,i,uid,gid;
++ int count,len,size,i;
++ uid_t uid;
++ gid_t gid;
+ char line[1024];
+ char *pw = NULL, *gr = NULL;
+
+@@ -241,14 +243,23 @@ ls(time_t now, char *hostname, char *fil
+ files[count]->r = 0;
+ if (S_ISDIR(files[count]->s.st_mode) ||
+ S_ISREG(files[count]->s.st_mode)) {
+- if (files[count]->s.st_uid == uid &&
++ if (uid == 0)
++ files[count]->r = 1;
++ else if (files[count]->s.st_uid == uid &&
+ files[count]->s.st_mode & 0400)
+ files[count]->r = 1;
+- else if (files[count]->s.st_uid == gid &&
++ else if (files[count]->s.st_gid == gid &&
+ files[count]->s.st_mode & 0040)
+- files[count]->r = 1; /* FIXME: check additional groups */
++ files[count]->r = 1;
+ else if (files[count]->s.st_mode & 0004)
+ files[count]->r = 1;
++ else {
++ for (i = 0; i < grp_num; i++) {
++ if (files[count]->s.st_gid == grp_list[i] &&
++ files[count]->s.st_mode & 0400)
++ files[count]->r = 1;
++ }
++ }
+ }
+ }
+ closedir(dir);
+diff -urp webfs-1.21-orig/webfsd.c webfs-1.21/webfsd.c
+--- webfs-1.21-orig/webfsd.c 2004-06-10 05:45:50.000000000 -0400
++++ webfs-1.21/webfsd.c 2010-03-28 10:36:33.992517000 -0400
+@@ -42,8 +42,8 @@ char *listen_port = "8000";
+ int virtualhosts = 0;
+ int canonicalhost = 0;
+ char server_host[256];
+-char user[17];
+-char group[17];
++char *user;
++char *group;
+ char *mimetypes = MIMEFILE;
+ char *pidfile = NULL;
+ char *logfile = NULL;
+@@ -57,6 +57,9 @@ int have_tty = 1;
+ int max_conn = 32;
+ int lifespan = -1;
+ int no_listing = 0;
++int setsupgroups = 1;
++gid_t *grp_list = NULL;
++int grp_num = 0;
+
+ time_t now;
+ int slisten;
+@@ -167,6 +170,7 @@ usage(char *name)
+ gr = getgrgid(getgid());
+ fprintf(stderr,
+ " -u user run as user >user< [%s]\n"
++ " -G set supplementary group list to empty\n"
+ " -g group run as group >group< [%s]\n",
+ pw ? pw->pw_name : "???",
+ gr ? gr->gr_name : "???");
+@@ -189,6 +193,7 @@ fix_ug(void)
+ {
+ struct passwd *pw = NULL;
+ struct group *gr = NULL;
++ int numgroupsmax, i;
+
+ /* root is allowed to use any uid/gid,
+ * others will get their real uid/gid */
+@@ -214,6 +219,20 @@ fix_ug(void)
+ exit(1);
+ }
+
++ /* get supplementary groups */
++ if (setsupgroups) {
++ numgroupsmax = sysconf(_SC_NGROUPS_MAX) + 1;
++ grp_list = (gid_t*) malloc(numgroupsmax * sizeof(gid_t));
++
++ if (grp_list != NULL) {
++ grp_num = getgrouplist(pw->pw_name, pw->pw_gid,
++ grp_list, &numgroupsmax);
++ } else {
++ xerror(LOG_ERR, "failed to get group list - "
++ "removing all sup groups", NULL);
++ }
++ }
++
+ /* chroot to $DOCUMENT_ROOT (must be done here as getpwuid needs
+ /etc and chroot works as root only) */
+ if (do_chroot) {
+@@ -227,14 +246,22 @@ fix_ug(void)
+ /* set group */
+ if (getegid() != gr->gr_gid || getgid() != gr->gr_gid) {
+ setgid(gr->gr_gid);
+- setgroups(0, NULL);
+ }
+ if (getegid() != gr->gr_gid || getgid() != gr->gr_gid) {
+ xerror(LOG_ERR,"setgid failed",NULL);
+ exit(1);
+ }
+- strncpy(group,gr->gr_name,16);
++
++ if (strlen(gr->gr_name) < sysconf(_SC_LOGIN_NAME_MAX))
++ strcpy(group,gr->gr_name);
++ else
++ xerror(LOG_ERR,"groupname too long",NULL);
+
++ /* set supplementary groups */
++ if (geteuid() == 0)
++ if (setgroups(grp_num, grp_list) != 0)
++ xerror(LOG_ERR, "failed to set supplementary groups", NULL);
++
+ /* set user */
+ if (geteuid() != pw->pw_uid || getuid() != pw->pw_uid)
+ setuid(pw->pw_uid);
+@@ -242,11 +269,23 @@ fix_ug(void)
+ xerror(LOG_ERR,"setuid failed",NULL);
+ exit(1);
+ }
+- strncpy(user,pw->pw_name,16);
+-
+- if (debug)
+- fprintf(stderr,"fix_ug: uid=%d euid=%d / gid=%d egid=%d\n",
++
++ if (strlen(pw->pw_name) < sysconf(_SC_LOGIN_NAME_MAX))
++ strcpy(user,pw->pw_name);
++ else
++ xerror(LOG_ERR,"username too long",NULL);
++
++ if (debug) {
++ fprintf(stderr,"fix_ug: uid=%d euid=%d / gid=%d egid=%d / gids: ",
+ getuid(),geteuid(),getgid(),getegid());
++
++ for (i = 0; i < grp_num; i++) {
++ fprintf(stderr, "%d ", grp_list[i]);
++ }
++
++ fprintf(stderr, "\n");
++ }
++
+ }
+
+ /* ---------------------------------------------------------------------- */
+@@ -687,6 +726,10 @@ main(int argc, char *argv[])
+ char serv[16];
+ char mypid[12];
+
++ /* allocate space for user/group names. _SC_LOGIN_NAME_MAX includes \0 */
++ user = (char *)malloc(sizeof(char) * sysconf(_SC_LOGIN_NAME_MAX));
++ group = (char *)malloc(sizeof(char) * sysconf(_SC_LOGIN_NAME_MAX));
++
+ uid = getuid();
+ euid = geteuid();
+ if (uid != euid)
+@@ -702,7 +745,7 @@ main(int argc, char *argv[])
+ /* parse options */
+ for (;;) {
+ if (-1 == (c = getopt(argc,argv,"hvsdF46jS"
+- "r:R:f:p:n:N:i:t:c:a:u:g:l:L:m:y:b:k:e:x:C:P:~:")))
++ "r:R:f:p:n:N:i:t:c:a:u:Gg:l:L:m:y:b:k:e:x:C:P:~:")))
+ break;
+ switch (c) {
+ case 'h':
+@@ -759,10 +802,19 @@ main(int argc, char *argv[])
+ max_dircache = atoi(optarg);
+ break;
+ case 'u':
+- strncpy(user,optarg,16);
++ if (strlen(optarg) < sysconf(_SC_LOGIN_NAME_MAX))
++ strcpy(user,optarg);
++ else
++ xerror(LOG_ERR,"username too long",NULL);
++ break;
++ case 'G':
++ setsupgroups = 0;
+ break;
+ case 'g':
+- strncpy(group,optarg,16);
++ if (strlen(optarg) < sysconf(_SC_LOGIN_NAME_MAX))
++ strcpy(group,optarg);
++ else
++ xerror(LOG_ERR,"groupname too long",NULL);
+ break;
+ case 'L':
+ flushlog = 1;
+diff -urp webfs-1.21-orig/webfsd.man webfs-1.21/webfsd.man
+--- webfs-1.21-orig/webfsd.man 2004-06-08 08:52:02.000000000 -0400
++++ webfs-1.21/webfsd.man 2010-03-28 10:37:09.495798000 -0400
+@@ -95,6 +95,9 @@ Use >file< as pidfile.
+ Set \fBu\fPid to >user< (after binding to the tcp port). This
+ option is allowed for root only.
+ .TP
++.B -G
++Set the supplementary group list to empty.
++.TP
+ .B -g group
+ Set \fBg\fPid to >group< (after binding to the tcp port). This
+ option is allowed for root only.
+
+