diff options
Diffstat (limited to 'community/webfs/webfs.patch')
-rw-r--r-- | community/webfs/webfs.patch | 250 |
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. + + |