Module Name: src Committed By: snj Date: Fri Apr 15 19:01:05 UTC 2016
Modified Files: src/libexec/httpd [netbsd-7]: CHANGES bozohttpd.8 bozohttpd.c bozohttpd.h cgi-bozo.c src/libexec/httpd/lua [netbsd-7]: bozo.lua glue.c Log Message: Pull up following revision(s) (requested by mrg in ticket #1141): libexec/httpd/CHANGES: up to 1.22 libexec/httpd/bozohttpd.8: up to 1.59 libexec/httpd/bozohttpd.c: up to 1.80 libexec/httpd/bozohttpd.h: up to 1.45 libexec/httpd/cgi-bozo.c: up to 1.33 libexec/httpd/lua/bozo.lua: up to 1.2 libexec/httpd/lua/glue.c: up to 1.2 Import bozohttpd 20151028: o add CGI support for ~user translation (-E switch) o add redirects to ~user translation o fix bugs around ~user translation o add schema detection for absolute redirects o fixed few memory leaks o bunch of minor tweaks o removed -r support o smarter redirects -- Changes in 20150320: o fix redirection handling o support transport stream (.ts) and video object (.vob) files o directory listings show correct file sizes for large files -- updates and bozohttpd 20160415: o add search-word support for CGI o fix a security issue in CGI suffix handler support which would allow remote code execution, from s...@netbsd.org o -C option supports now CGI scripts only To generate a diff of this commit: cvs rdiff -u -r1.19.2.2 -r1.19.2.3 src/libexec/httpd/CHANGES cvs rdiff -u -r1.46.4.5 -r1.46.4.6 src/libexec/httpd/bozohttpd.8 cvs rdiff -u -r1.56.2.5 -r1.56.2.6 src/libexec/httpd/bozohttpd.c cvs rdiff -u -r1.33.2.3 -r1.33.2.4 src/libexec/httpd/bozohttpd.h cvs rdiff -u -r1.25.2.3 -r1.25.2.4 src/libexec/httpd/cgi-bozo.c cvs rdiff -u -r1.1.1.1 -r1.1.1.1.30.1 src/libexec/httpd/lua/bozo.lua \ src/libexec/httpd/lua/glue.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/libexec/httpd/CHANGES diff -u src/libexec/httpd/CHANGES:1.19.2.2 src/libexec/httpd/CHANGES:1.19.2.3 --- src/libexec/httpd/CHANGES:1.19.2.2 Sun Apr 10 10:33:11 2016 +++ src/libexec/httpd/CHANGES Fri Apr 15 19:01:05 2016 @@ -1,5 +1,11 @@ $eterna: CHANGES,v 1.78 2011/11/18 01:25:11 mrg Exp $ +changes in bozohttpd 20160415: + o add search-word support for CGI + o fix a security issue in CGI suffix handler support which would + allow remote code execution, from s...@netbsd.org + o -C option supports now CGI scripts only + changes in bozohttpd 20151028: o add CGI support for ~user translation (-E switch) o add redirects to ~user translation Index: src/libexec/httpd/bozohttpd.8 diff -u src/libexec/httpd/bozohttpd.8:1.46.4.5 src/libexec/httpd/bozohttpd.8:1.46.4.6 --- src/libexec/httpd/bozohttpd.8:1.46.4.5 Sun Apr 10 10:33:11 2016 +++ src/libexec/httpd/bozohttpd.8 Fri Apr 15 19:01:05 2016 @@ -1,4 +1,4 @@ -.\" $NetBSD: bozohttpd.8,v 1.46.4.5 2016/04/10 10:33:11 martin Exp $ +.\" $NetBSD: bozohttpd.8,v 1.46.4.6 2016/04/15 19:01:05 snj Exp $ .\" .\" $eterna: bozohttpd.8,v 1.101 2011/11/18 01:25:11 mrg Exp $ .\" @@ -507,7 +507,7 @@ with PHP, one must use the option to specify a CGI handler for a particular file type. Typically this will be like: .Bd -literal -httpd -C .php /usr/pkg/bin/php /var/www +httpd -C .php /usr/pkg/bin/php-cgi /var/www .Ed .Sh SEE ALSO .Xr inetd.conf 5 , @@ -615,7 +615,8 @@ provided many fixes and enhancements for .Aq Mt s...@netbsd.org fixed memory leaks, various issues with userdir support, information disclosure issues, added support for using CGI handlers -with directory indexing and provided various other fixes. +with directory indexing, found several security issues and provided +various other fixes. .It .An Arnaud Lacombe .Aq Mt a...@netbsd.org Index: src/libexec/httpd/bozohttpd.c diff -u src/libexec/httpd/bozohttpd.c:1.56.2.5 src/libexec/httpd/bozohttpd.c:1.56.2.6 --- src/libexec/httpd/bozohttpd.c:1.56.2.5 Sun Apr 10 10:33:11 2016 +++ src/libexec/httpd/bozohttpd.c Fri Apr 15 19:01:05 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: bozohttpd.c,v 1.56.2.5 2016/04/10 10:33:11 martin Exp $ */ +/* $NetBSD: bozohttpd.c,v 1.56.2.6 2016/04/15 19:01:05 snj Exp $ */ /* $eterna: bozohttpd.c,v 1.178 2011/11/18 09:21:15 mrg Exp $ */ @@ -109,7 +109,7 @@ #define INDEX_HTML "index.html" #endif #ifndef SERVER_SOFTWARE -#define SERVER_SOFTWARE "bozohttpd/20151231" +#define SERVER_SOFTWARE "bozohttpd/20160415" #endif #ifndef DIRECT_ACCESS_FILE #define DIRECT_ACCESS_FILE ".bzdirect" @@ -348,6 +348,15 @@ bozo_clean_request(bozo_httpreq_t *reque ohdr = hdr; } free(ohdr); + ohdr = NULL; + for (hdr = SIMPLEQ_FIRST(&request->hr_replheaders); hdr; + hdr = SIMPLEQ_NEXT(hdr, h_next)) { + free(hdr->h_value); + free(hdr->h_header); + free(ohdr); + ohdr = hdr; + } + free(ohdr); free(request); } @@ -363,20 +372,33 @@ alarmer(int sig) } /* + * a list of header quirks: currently, a list of headers that + * can't be folded into a single line. + */ +const char *header_quirks[] = { "WWW-Authenticate", NULL }; + +/* * add or merge this header (val: str) into the requests list */ static bozoheaders_t * -addmerge_header(bozo_httpreq_t *request, char *val, - char *str, ssize_t len) +addmerge_header(bozo_httpreq_t *request, struct qheaders *headers, + const char *val, const char *str, ssize_t len) { struct bozohttpd_t *httpd = request->hr_httpd; - struct bozoheaders *hdr; + struct bozoheaders *hdr = NULL; + const char **quirk; USE_ARG(len); - /* do we exist already? */ - SIMPLEQ_FOREACH(hdr, &request->hr_headers, h_next) { - if (strcasecmp(val, hdr->h_header) == 0) + for (quirk = header_quirks; *quirk; quirk++) + if (strcasecmp(*quirk, val) == 0) break; + + if (*quirk == NULL) { + /* do we exist already? */ + SIMPLEQ_FOREACH(hdr, headers, h_next) { + if (strcasecmp(val, hdr->h_header) == 0) + break; + } } if (hdr) { @@ -396,13 +418,30 @@ addmerge_header(bozo_httpreq_t *request, else hdr->h_value = bozostrdup(httpd, request, " "); - SIMPLEQ_INSERT_TAIL(&request->hr_headers, hdr, h_next); + SIMPLEQ_INSERT_TAIL(headers, hdr, h_next); request->hr_nheaders++; } return hdr; } +bozoheaders_t * +addmerge_reqheader(bozo_httpreq_t *request, const char *val, const char *str, + ssize_t len) +{ + + return addmerge_header(request, &request->hr_headers, val, str, len); +} + +bozoheaders_t * +addmerge_replheader(bozo_httpreq_t *request, const char *val, const char *str, + ssize_t len) +{ + + return addmerge_header(request, &request->hr_replheaders, + val, str, len); +} + /* * as the prototype string is not constant (eg, "HTTP/1.1" is equivalent * to "HTTP/001.01"), we MUST parse this. @@ -538,6 +577,7 @@ bozo_read_request(bozohttpd_t *httpd) request->hr_virthostname = NULL; request->hr_file = NULL; request->hr_oldfile = NULL; + SIMPLEQ_INIT(&request->hr_replheaders); bozo_auth_init(request); slen = sizeof(ss); @@ -673,7 +713,7 @@ bozo_read_request(bozohttpd_t *httpd) if (bozo_auth_check_headers(request, val, str, len)) goto next_header; - hdr = addmerge_header(request, val, str, len); + hdr = addmerge_reqheader(request, val, str, len); if (strcasecmp(hdr->h_header, "content-type") == 0) request->hr_content_type = hdr->h_value; @@ -1248,19 +1288,17 @@ check_bzredirect(bozo_httpreq_t *request } /* this fixes the %HH hack that RFC2396 requires. */ -static int -fix_url_percent(bozo_httpreq_t *request) +int +bozo_decode_url_percent(bozo_httpreq_t *request, char *str) { bozohttpd_t *httpd = request->hr_httpd; - char *s, *t, buf[3], *url; + char *s, *t, buf[3]; char *end; /* if end is not-zero, we don't translate beyond that */ - url = request->hr_file; - - end = url + strlen(url); + end = str + strlen(str); /* fast forward to the first % */ - if ((s = strchr(url, '%')) == NULL) + if ((s = strchr(str, '%')) == NULL) return 0; t = s; @@ -1312,7 +1350,7 @@ fix_url_percent(bozo_httpreq_t *request) } while (*s); *t = '\0'; - debug((httpd, DEBUG_FAT, "fix_url_percent returns %s in url", + debug((httpd, DEBUG_FAT, "bozo_decode_url_percent returns `%s'", request->hr_file)); return 0; @@ -1343,7 +1381,7 @@ transform_request(bozo_httpreq_t *reques file = NULL; *isindex = 0; debug((httpd, DEBUG_FAT, "tf_req: file %s", request->hr_file)); - if (fix_url_percent(request)) { + if (bozo_decode_url_percent(request, request->hr_file)) { goto bad_done; } if (check_virtual(request)) { @@ -1680,6 +1718,12 @@ bozo_print_header(bozo_httpreq_t *reques bozohttpd_t *httpd = request->hr_httpd; off_t len; char date[40]; + bozoheaders_t *hdr; + + SIMPLEQ_FOREACH(hdr, &request->hr_replheaders, h_next) { + bozo_printf(httpd, "%s: %s\r\n", hdr->h_header, + hdr->h_value); + } bozo_printf(httpd, "Date: %s\r\n", bozo_http_date(date, sizeof(date))); bozo_printf(httpd, "Server: %s\r\n", httpd->server_software); @@ -1901,6 +1945,7 @@ bozo_http_error(bozohttpd_t *httpd, int const char *proto = (request && request->hr_proto) ? request->hr_proto : httpd->consts.http_11; int size; + bozoheaders_t *hdr; debug((httpd, DEBUG_FAT, "bozo_http_error %d: %s", code, msg)); if (header == NULL || reason == NULL) { @@ -1963,8 +2008,14 @@ bozo_http_error(bozohttpd_t *httpd, int size = 0; bozo_printf(httpd, "%s %s\r\n", proto, header); - if (request) + + if (request) { bozo_auth_check_401(request, code); + SIMPLEQ_FOREACH(hdr, &request->hr_replheaders, h_next) { + bozo_printf(httpd, "%s: %s\r\n", hdr->h_header, + hdr->h_value); + } + } bozo_printf(httpd, "Content-Type: text/html\r\n"); bozo_printf(httpd, "Content-Length: %d\r\n", size); Index: src/libexec/httpd/bozohttpd.h diff -u src/libexec/httpd/bozohttpd.h:1.33.2.3 src/libexec/httpd/bozohttpd.h:1.33.2.4 --- src/libexec/httpd/bozohttpd.h:1.33.2.3 Sun Apr 10 10:33:11 2016 +++ src/libexec/httpd/bozohttpd.h Fri Apr 15 19:01:05 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: bozohttpd.h,v 1.33.2.3 2016/04/10 10:33:11 martin Exp $ */ +/* $NetBSD: bozohttpd.h,v 1.33.2.4 2016/04/15 19:01:05 snj Exp $ */ /* $eterna: bozohttpd.h,v 1.39 2011/11/18 09:21:15 mrg Exp $ */ @@ -54,6 +54,7 @@ typedef struct bozoheaders { /*const*/ char *h_value; /* this gets free()'ed etc at times */ SIMPLEQ_ENTRY(bozoheaders) h_next; } bozoheaders_t; +SIMPLEQ_HEAD(qheaders, bozoheaders); #ifndef NO_LUA_SUPPORT typedef struct lua_handler { @@ -172,8 +173,9 @@ typedef struct bozo_httpreq_t { /*const*/ char *hr_authuser; /*const*/ char *hr_authpass; #endif - SIMPLEQ_HEAD(, bozoheaders) hr_headers; - int hr_nheaders; + struct qheaders hr_headers; + struct qheaders hr_replheaders; + int hr_nheaders; } bozo_httpreq_t; /* helper to access the "active" host name from a httpd/request pair */ @@ -225,6 +227,7 @@ void bozo_print_header(bozo_httpreq_t *, const char *); char *bozo_escape_rfc3986(bozohttpd_t *httpd, const char *url, int absolute); char *bozo_escape_html(bozohttpd_t *httpd, const char *url); +int bozo_decode_url_percent(bozo_httpreq_t *, char *); /* these are similar to libc functions, no underscore here */ void bozowarn(bozohttpd_t *, const char *, ...) @@ -355,6 +358,10 @@ int bozo_setup(bozohttpd_t *, bozoprefs_ bozo_httpreq_t *bozo_read_request(bozohttpd_t *); void bozo_process_request(bozo_httpreq_t *); void bozo_clean_request(bozo_httpreq_t *); +bozoheaders_t *addmerge_reqheader(bozo_httpreq_t *, const char *, + const char *, ssize_t); +bozoheaders_t *addmerge_replheader(bozo_httpreq_t *, const char *, + const char *, ssize_t); /* variables */ int bozo_set_pref(bozohttpd_t *, bozoprefs_t *, const char *, const char *); Index: src/libexec/httpd/cgi-bozo.c diff -u src/libexec/httpd/cgi-bozo.c:1.25.2.3 src/libexec/httpd/cgi-bozo.c:1.25.2.4 --- src/libexec/httpd/cgi-bozo.c:1.25.2.3 Sun Apr 10 10:33:11 2016 +++ src/libexec/httpd/cgi-bozo.c Fri Apr 15 19:01:05 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: cgi-bozo.c,v 1.25.2.3 2016/04/10 10:33:11 martin Exp $ */ +/* $NetBSD: cgi-bozo.c,v 1.25.2.4 2016/04/15 19:01:05 snj Exp $ */ /* $eterna: cgi-bozo.c,v 1.40 2011/11/18 09:21:15 mrg Exp $ */ @@ -212,6 +212,136 @@ append_index_html(bozohttpd_t *httpd, ch "append_index_html: url adjusted to `%s'", *url)); } +/* This function parse search-string according to section 4.4 of RFC3875 */ +static char ** +parse_search_string(bozo_httpreq_t *request, const char *query, size_t *args_len) +{ + struct bozohttpd_t *httpd = request->hr_httpd; + size_t i; + char *s, *str, **args; + + *args_len = 0; + + /* URI MUST not contain any unencoded '=' - RFC3875, section 4.4 */ + if (strchr(query, '=')) { + return NULL; + } + + str = bozostrdup(httpd, request, query); + + /* + * there's no more arguments than '+' chars in the query string as it's + * the separator + */ + *args_len = 1; + /* count '+' in str */ + for (s = str; (s = strchr(s, '+')); (*args_len)++); + + args = bozomalloc(httpd, sizeof(*args) * (*args_len + 1)); + + args[0] = str; + args[*args_len] = NULL; + for (s = str, i = 0; (s = strchr(s, '+'));) { + *s = '\0'; + s++; + args[i++] = s; + } + + /* + * check if search-strings are valid: + * + * RFC3875, section 4.4: + * + * search-string = search-word *( "+" search-word ) + * search-word = 1*schar + * schar = unreserved | escaped | xreserved + * xreserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "," | + * "$" + * + * section 2.3: + * + * hex = digit | "A" | "B" | "C" | "D" | "E" | "F" | "a" | + * "b" | "c" | "d" | "e" | "f" + * escaped = "%" hex hex + * unreserved = alpha | digit | mark + * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" + * + * section 2.2: + * + * alpha = lowalpha | hialpha + * lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | + * "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | + * "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | + * "y" | "z" + * hialpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | + * "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | + * "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | + * "Y" | "Z" + * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | + * "8" | "9" + */ +#define UNRESERVED_CHAR "-_.!~*'()" +#define XRESERVED_CHAR ";/?:@&=,$" + + for (i = 0; i < *args_len; i++) { + s = args[i]; + /* search-word MUST have at least one schar */ + if (*s == '\0') + goto parse_err; + while(*s) { + /* check if it's unreserved */ + if (isalpha((int)*s) || isdigit((int)*s) || + strchr(UNRESERVED_CHAR, *s)) { + s++; + continue; + } + + /* check if it's escaped */ + if (*s == '%') { + if (s[1] == '\0' || s[2] == '\0') + goto parse_err; + if (!isxdigit((int)s[1]) || + !isxdigit((int)s[2])) + goto parse_err; + s += 3; + continue; + } + + /* check if it's xreserved */ + + if (strchr(XRESERVED_CHAR, *s)) { + s++; + continue; + } + + goto parse_err; + } + } + + /* decode percent encoding */ + for (i = 0; i < *args_len; i++) { + if (bozo_decode_url_percent(request, args[i])) + goto parse_err; + } + + /* allocate each arg separately */ + for (i = 0; i < *args_len; i++) + args[i] = bozostrdup(httpd, request, args[i]); + free(str); + + return args; + +parse_err: + + free (*args); + free (str); + *args = NULL; + *args_len = 0; + + return 0; + +} + void bozo_cgi_setbin(bozohttpd_t *httpd, const char *path) { @@ -249,9 +379,9 @@ bozo_process_cgi(bozo_httpreq_t *request bozoheaders_t *headp; const char *type, *clen, *info, *cgihandler; char *query, *s, *t, *path, *env, *command, *file, *url; - char **envp, **curenvp, *argv[4]; + char **envp, **curenvp, **argv, **search_string_argv = NULL; char *uri; - size_t len; + size_t i, len, search_string_argc = 0; ssize_t rbytes; pid_t pid; int envpsize, ix, nph; @@ -312,12 +442,25 @@ bozo_process_cgi(bozo_httpreq_t *request } else if (len - 1 == CGIBIN_PREFIX_LEN) /* url is "/cgi-bin/" */ append_index_html(httpd, &file); + /* RFC3875 sect. 4.4. - search-string support */ + if (query != NULL) { + search_string_argv = parse_search_string(request, query, + &search_string_argc); + } + + debug((httpd, DEBUG_NORMAL, "parse_search_string args no: %lu", + search_string_argc)); + for (i = 0; i < search_string_argc; i++) { + debug((httpd, DEBUG_FAT, + "search_string[%lu]: `%s'", i, search_string_argv[i])); + } + + argv = bozomalloc(httpd, sizeof(*argv) * (3 + search_string_argc)); + ix = 0; if (cgihandler) { command = file + 1; path = bozostrdup(httpd, request, cgihandler); - argv[ix++] = path; - /* argv[] = [ path, command, query, NULL ] */ } else { command = file + CGIBIN_PREFIX_LEN + 1; if ((s = strchr(command, '/')) != NULL) { @@ -329,12 +472,15 @@ bozo_process_cgi(bozo_httpreq_t *request strcpy(path, httpd->cgibin); strcat(path, "/"); strcat(path, command); - /* argv[] = [ command, query, NULL ] */ } - argv[ix++] = command; - argv[ix++] = query; - argv[ix++] = NULL; + argv[ix++] = path; + + /* copy search-string args */ + for (i = 0; i < search_string_argc; i++) + argv[ix++] = search_string_argv[i]; + + argv[ix++] = NULL; nph = strncmp(command, "nph-", 4) == 0; type = request->hr_content_type; @@ -400,8 +546,11 @@ bozo_process_cgi(bozo_httpreq_t *request bozo_setenv(httpd, "REQUEST_URI", uri, curenvp++); bozo_setenv(httpd, "DATE_GMT", bozo_http_date(date, sizeof(date)), curenvp++); + /* RFC3875 section 4.1.7 says that QUERY_STRING MUST be defined. */ if (query && *query) bozo_setenv(httpd, "QUERY_STRING", query, curenvp++); + else + bozo_setenv(httpd, "QUERY_STRING", "", curenvp++); if (info && *info) bozo_setenv(httpd, "PATH_INFO", info, curenvp++); if (type && *type) @@ -425,8 +574,13 @@ bozo_process_cgi(bozo_httpreq_t *request bozo_setenv(httpd, "REDIRECT_STATUS", "200", curenvp++); bozo_auth_cgi_setenv(request, &curenvp); - debug((httpd, DEBUG_FAT, "bozo_process_cgi: going exec %s, %s %s %s", - path, argv[0], strornull(argv[1]), strornull(argv[2]))); + debug((httpd, DEBUG_FAT, "bozo_process_cgi: going exec %s with args:", + path)); + + for (i = 0; argv[i] != NULL; i++) { + debug((httpd, DEBUG_FAT, "bozo_process_cgi: argv[%lu] = `%s'", + i, argv[i])); + } if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sv) == -1) bozoerr(httpd, 1, "child socketpair failed: %s", @@ -461,6 +615,9 @@ bozo_process_cgi(bozo_httpreq_t *request free(query); free(file); free(url); + for (i = 0; i < search_string_argc; i++) + free(search_string_argv[i]); + free(search_string_argv); close(sv[1]); @@ -500,6 +657,10 @@ bozo_process_cgi(bozo_httpreq_t *request exit(0); out: + + for (i = 0; i < search_string_argc; i++) + free(search_string_argv[i]); + free(search_string_argv); free(query); free(file); free(url); Index: src/libexec/httpd/lua/bozo.lua diff -u src/libexec/httpd/lua/bozo.lua:1.1.1.1 src/libexec/httpd/lua/bozo.lua:1.1.1.1.30.1 --- src/libexec/httpd/lua/bozo.lua:1.1.1.1 Mon May 10 03:30:04 2010 +++ src/libexec/httpd/lua/bozo.lua Fri Apr 15 19:01:05 2016 @@ -35,6 +35,7 @@ dofile "optparse.lua" opt = OptionParser{usage="%prog [options] root [vhost]", version="20091105"} opt.add_option{"-C", "--cgimap", action="store", dest="cgimap", help="--cgimap 's t'"} +opt.add_option{"-E", "--enable-user-cgibin", action="store_true", dest="enableusercgibin", help="--enable-user-cgibin"} opt.add_option{"-H", "--hide-dots", action="store_true", dest="hidedots", help="--hide-dots"} opt.add_option{"-I", "--portnum", action="store", dest="portnum", help="--portnum number"} opt.add_option{"-M", "--dynamicmime", action="store", dest="dynmime", help="--dynamicmime 'suffix type a b'"} @@ -50,7 +51,6 @@ opt.add_option{"-f", "--foreground", act opt.add_option{"-i", "--bindaddr", action="store", dest="bindaddress", help="--bindaddr address"} opt.add_option{"-n", "--numeric", action="store_true", dest="numeric", help="--numeric"} opt.add_option{"-p", "--public-html", action="store", dest="public_html", help="--public-html dir"} -opt.add_option{"-r", "--trusted-referal", action="store_true", dest="trustedref", help="trusted referal"} opt.add_option{"-s", "--logtostderr", action="store_true", dest="logstderr", help="log to stderr"} opt.add_option{"-t", "--chroot", action="store", dest="chroot", help="--chroot dir"} opt.add_option{"-u", "--enable-users", action="store_true", dest="enableusers", help="--enable-users"} @@ -141,6 +141,9 @@ end if options.hidedots then bozohttpd.set_pref(prefs, "hide dots", "true") end +if options.enableusercgibin then + bozohttpd.set_pref(prefs, "enable user cgibin", "true") +end if options.dirindex then bozohttpd.set_pref(prefs, "directory indexing", "true") end Index: src/libexec/httpd/lua/glue.c diff -u src/libexec/httpd/lua/glue.c:1.1.1.1 src/libexec/httpd/lua/glue.c:1.1.1.1.30.1 --- src/libexec/httpd/lua/glue.c:1.1.1.1 Mon May 10 03:30:04 2010 +++ src/libexec/httpd/lua/glue.c Fri Apr 15 19:01:05 2016 @@ -92,11 +92,13 @@ l_init_httpd(lua_State *L) static int l_init_prefs(lua_State *L) { + bozohttpd_t *httpd; bozoprefs_t *prefs; prefs = lua_newuserdata(L, sizeof(*prefs)); (void) memset(prefs, 0x0, sizeof(*prefs)); - (void) bozo_init_prefs(prefs); + httpd = lua_touserdata(L, 1); + (void) bozo_init_prefs(httpd, prefs); return 1; }