Fossil SCM

Add the --nojail option to the "server", "ui", and "http" commands.

drh 2015-02-15 19:36 trunk
Commit c5c9f1642b07cbe57485d0b78233fbca72349b9d
1 file changed +30 -18
+30 -18
--- src/main.c
+++ src/main.c
@@ -1357,12 +1357,15 @@
13571357
** zRepo might be a directory itself. In that case chroot into
13581358
** the directory zRepo.
13591359
**
13601360
** Assume the user-id and group-id of the repository, or if zRepo
13611361
** is a directory, of that directory.
1362
+**
1363
+** The noJail flag means that the chroot jail is not entered. But
1364
+** privileges are still lowered to that of the the user-id and group-id.
13621365
*/
1363
-static char *enter_chroot_jail(char *zRepo){
1366
+static char *enter_chroot_jail(char *zRepo, int noJail){
13641367
#if !defined(_WIN32)
13651368
if( getuid()==0 ){
13661369
int i;
13671370
struct stat sStat;
13681371
Blob dir;
@@ -1371,26 +1374,28 @@
13711374
db_close(1);
13721375
}
13731376
13741377
file_canonical_name(zRepo, &dir, 0);
13751378
zDir = blob_str(&dir);
1376
- if( file_isdir(zDir)==1 ){
1377
- if( file_chdir(zDir, 1) ){
1378
- fossil_fatal("unable to chroot into %s", zDir);
1379
- }
1380
- zRepo = "/";
1381
- }else{
1382
- for(i=strlen(zDir)-1; i>0 && zDir[i]!='/'; i--){}
1383
- if( zDir[i]!='/' ) fossil_fatal("bad repository name: %s", zRepo);
1384
- if( i>0 ){
1385
- zDir[i] = 0;
1379
+ if( !noJail ){
1380
+ if( file_isdir(zDir)==1 ){
13861381
if( file_chdir(zDir, 1) ){
13871382
fossil_fatal("unable to chroot into %s", zDir);
13881383
}
1389
- zDir[i] = '/';
1384
+ zRepo = "/";
1385
+ }else{
1386
+ for(i=strlen(zDir)-1; i>0 && zDir[i]!='/'; i--){}
1387
+ if( zDir[i]!='/' ) fossil_fatal("bad repository name: %s", zRepo);
1388
+ if( i>0 ){
1389
+ zDir[i] = 0;
1390
+ if( file_chdir(zDir, 1) ){
1391
+ fossil_fatal("unable to chroot into %s", zDir);
1392
+ }
1393
+ zDir[i] = '/';
1394
+ }
1395
+ zRepo = &zDir[i];
13901396
}
1391
- zRepo = &zDir[i];
13921397
}
13931398
if( stat(zRepo, &sStat)!=0 ){
13941399
fossil_fatal("cannot stat() repository: %s", zRepo);
13951400
}
13961401
i = setgid(sStat.st_gid);
@@ -2026,10 +2031,11 @@
20262031
**
20272032
** Options:
20282033
** --localauth enable automatic login for local connections
20292034
** --host NAME specify hostname of the server
20302035
** --https signal a request coming in via https
2036
+** --nojail drop root privilege but do not enter the chroot jail
20312037
** --nossl signal that no SSL connections are available
20322038
** --notfound URL use URL as "HTTP 404, object not found" page.
20332039
** --files GLOB comma-separate glob patterns for static file to serve
20342040
** --baseurl URL base URL (useful with reverse proxies)
20352041
** --scgi Interpret input as SCGI rather than HTTP
@@ -2042,10 +2048,11 @@
20422048
const char *zNotFound;
20432049
const char *zHost;
20442050
const char *zAltBase;
20452051
const char *zFileGlob;
20462052
int useSCGI;
2053
+ int noJail;
20472054
20482055
/* The winhttp module passes the --files option as --files-urlenc with
20492056
** the argument being URL encoded, to avoid wildcard expansion in the
20502057
** shell. This option is for internal use and is undocumented.
20512058
*/
@@ -2057,10 +2064,11 @@
20572064
}else{
20582065
zFileGlob = find_option("files",0,1);
20592066
}
20602067
skin_override();
20612068
zNotFound = find_option("notfound", 0, 1);
2069
+ noJail = find_option("nojail",0,0)!=0;
20622070
g.useLocalauth = find_option("localauth", 0, 0)!=0;
20632071
g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
20642072
useSCGI = find_option("scgi", 0, 0)!=0;
20652073
zAltBase = find_option("baseurl", 0, 1);
20662074
if( zAltBase ) set_base_url(zAltBase);
@@ -2093,11 +2101,11 @@
20932101
zIpAddr = cgi_ssh_remote_addr(0);
20942102
if( zIpAddr && zIpAddr[0] ){
20952103
g.fSshClient |= CGI_SSH_CLIENT;
20962104
}
20972105
}
2098
- g.zRepositoryName = enter_chroot_jail(g.zRepositoryName);
2106
+ g.zRepositoryName = enter_chroot_jail(g.zRepositoryName, noJail);
20992107
if( useSCGI ){
21002108
cgi_handle_scgi_request();
21012109
}else if( g.fSshClient & CGI_SSH_CLIENT ){
21022110
ssh_request_loop(zIpAddr, glob_create(zFileGlob));
21032111
}else{
@@ -2211,19 +2219,21 @@
22112219
** and the connection is from localhost. The optional REPOSITORY argument
22122220
** to "ui" may be a directory and will function as "server" if and only if
22132221
** the --notfound option is used.
22142222
**
22152223
** Options:
2224
+** --baseurl URL Use URL as the base (useful for reverse proxies)
2225
+** --files GLOBLIST Comma-separated list of glob patterns for static files
22162226
** --localauth enable automatic login for requests from localhost
22172227
** --localhost listen on 127.0.0.1 only (always true for "ui")
2228
+** --nojail Drop root privileges but do not enter the chroot jail
2229
+** --notfound URL Redirect
22182230
** -P|--port TCPPORT listen to request on port TCPPORT
22192231
** --th-trace trace TH1 execution (for debugging purposes)
2220
-** --baseurl URL Use URL as the base (useful for reverse proxies)
2221
-** --notfound URL Redirect
2222
-** --files GLOBLIST Comma-separated list of glob patterns for static files
22232232
** --scgi Accept SCGI rather than HTTP
22242233
** --skin LABEL Use override skin LABEL
2234
+
22252235
**
22262236
** See also: cgi, http, winsrv
22272237
*/
22282238
void cmd_webserver(void){
22292239
int iPort, mxPort; /* Range of TCP ports allowed */
@@ -2231,10 +2241,11 @@
22312241
const char *zBrowser; /* Name of web browser program */
22322242
char *zBrowserCmd = 0; /* Command to launch the web browser */
22332243
int isUiCmd; /* True if command is "ui", not "server' */
22342244
const char *zNotFound; /* The --notfound option or NULL */
22352245
int flags = 0; /* Server flags */
2246
+ int noJail; /* Do not enter the chroot jail */
22362247
const char *zAltBase; /* Argument to the --baseurl option */
22372248
const char *zFileGlob; /* Static content must match this */
22382249
char *zIpAddr = 0; /* Bind to this IP address */
22392250
22402251
#if defined(_WIN32)
@@ -2249,10 +2260,11 @@
22492260
zFileGlob = z;
22502261
}else{
22512262
zFileGlob = find_option("files",0,1);
22522263
}
22532264
skin_override();
2265
+ noJail = find_option("nojail",0,0)!=0;
22542266
g.useLocalauth = find_option("localauth", 0, 0)!=0;
22552267
Th_InitTraceLog();
22562268
zPort = find_option("port", "P", 1);
22572269
zNotFound = find_option("notfound", 0, 1);
22582270
zAltBase = find_option("baseurl", 0, 1);
@@ -2326,11 +2338,11 @@
23262338
if( g.fHttpTrace || g.fSqlTrace ){
23272339
fprintf(stderr, "====== SERVER pid %d =======\n", getpid());
23282340
}
23292341
g.cgiOutput = 1;
23302342
find_server_repository(isUiCmd && zNotFound==0, 2);
2331
- g.zRepositoryName = enter_chroot_jail(g.zRepositoryName);
2343
+ g.zRepositoryName = enter_chroot_jail(g.zRepositoryName, noJail);
23322344
if( flags & HTTP_SERVER_SCGI ){
23332345
cgi_handle_scgi_request();
23342346
}else{
23352347
cgi_handle_http_request(0);
23362348
}
23372349
--- src/main.c
+++ src/main.c
@@ -1357,12 +1357,15 @@
1357 ** zRepo might be a directory itself. In that case chroot into
1358 ** the directory zRepo.
1359 **
1360 ** Assume the user-id and group-id of the repository, or if zRepo
1361 ** is a directory, of that directory.
 
 
 
1362 */
1363 static char *enter_chroot_jail(char *zRepo){
1364 #if !defined(_WIN32)
1365 if( getuid()==0 ){
1366 int i;
1367 struct stat sStat;
1368 Blob dir;
@@ -1371,26 +1374,28 @@
1371 db_close(1);
1372 }
1373
1374 file_canonical_name(zRepo, &dir, 0);
1375 zDir = blob_str(&dir);
1376 if( file_isdir(zDir)==1 ){
1377 if( file_chdir(zDir, 1) ){
1378 fossil_fatal("unable to chroot into %s", zDir);
1379 }
1380 zRepo = "/";
1381 }else{
1382 for(i=strlen(zDir)-1; i>0 && zDir[i]!='/'; i--){}
1383 if( zDir[i]!='/' ) fossil_fatal("bad repository name: %s", zRepo);
1384 if( i>0 ){
1385 zDir[i] = 0;
1386 if( file_chdir(zDir, 1) ){
1387 fossil_fatal("unable to chroot into %s", zDir);
1388 }
1389 zDir[i] = '/';
 
 
 
 
 
 
 
 
 
 
 
1390 }
1391 zRepo = &zDir[i];
1392 }
1393 if( stat(zRepo, &sStat)!=0 ){
1394 fossil_fatal("cannot stat() repository: %s", zRepo);
1395 }
1396 i = setgid(sStat.st_gid);
@@ -2026,10 +2031,11 @@
2026 **
2027 ** Options:
2028 ** --localauth enable automatic login for local connections
2029 ** --host NAME specify hostname of the server
2030 ** --https signal a request coming in via https
 
2031 ** --nossl signal that no SSL connections are available
2032 ** --notfound URL use URL as "HTTP 404, object not found" page.
2033 ** --files GLOB comma-separate glob patterns for static file to serve
2034 ** --baseurl URL base URL (useful with reverse proxies)
2035 ** --scgi Interpret input as SCGI rather than HTTP
@@ -2042,10 +2048,11 @@
2042 const char *zNotFound;
2043 const char *zHost;
2044 const char *zAltBase;
2045 const char *zFileGlob;
2046 int useSCGI;
 
2047
2048 /* The winhttp module passes the --files option as --files-urlenc with
2049 ** the argument being URL encoded, to avoid wildcard expansion in the
2050 ** shell. This option is for internal use and is undocumented.
2051 */
@@ -2057,10 +2064,11 @@
2057 }else{
2058 zFileGlob = find_option("files",0,1);
2059 }
2060 skin_override();
2061 zNotFound = find_option("notfound", 0, 1);
 
2062 g.useLocalauth = find_option("localauth", 0, 0)!=0;
2063 g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
2064 useSCGI = find_option("scgi", 0, 0)!=0;
2065 zAltBase = find_option("baseurl", 0, 1);
2066 if( zAltBase ) set_base_url(zAltBase);
@@ -2093,11 +2101,11 @@
2093 zIpAddr = cgi_ssh_remote_addr(0);
2094 if( zIpAddr && zIpAddr[0] ){
2095 g.fSshClient |= CGI_SSH_CLIENT;
2096 }
2097 }
2098 g.zRepositoryName = enter_chroot_jail(g.zRepositoryName);
2099 if( useSCGI ){
2100 cgi_handle_scgi_request();
2101 }else if( g.fSshClient & CGI_SSH_CLIENT ){
2102 ssh_request_loop(zIpAddr, glob_create(zFileGlob));
2103 }else{
@@ -2211,19 +2219,21 @@
2211 ** and the connection is from localhost. The optional REPOSITORY argument
2212 ** to "ui" may be a directory and will function as "server" if and only if
2213 ** the --notfound option is used.
2214 **
2215 ** Options:
 
 
2216 ** --localauth enable automatic login for requests from localhost
2217 ** --localhost listen on 127.0.0.1 only (always true for "ui")
 
 
2218 ** -P|--port TCPPORT listen to request on port TCPPORT
2219 ** --th-trace trace TH1 execution (for debugging purposes)
2220 ** --baseurl URL Use URL as the base (useful for reverse proxies)
2221 ** --notfound URL Redirect
2222 ** --files GLOBLIST Comma-separated list of glob patterns for static files
2223 ** --scgi Accept SCGI rather than HTTP
2224 ** --skin LABEL Use override skin LABEL
 
2225 **
2226 ** See also: cgi, http, winsrv
2227 */
2228 void cmd_webserver(void){
2229 int iPort, mxPort; /* Range of TCP ports allowed */
@@ -2231,10 +2241,11 @@
2231 const char *zBrowser; /* Name of web browser program */
2232 char *zBrowserCmd = 0; /* Command to launch the web browser */
2233 int isUiCmd; /* True if command is "ui", not "server' */
2234 const char *zNotFound; /* The --notfound option or NULL */
2235 int flags = 0; /* Server flags */
 
2236 const char *zAltBase; /* Argument to the --baseurl option */
2237 const char *zFileGlob; /* Static content must match this */
2238 char *zIpAddr = 0; /* Bind to this IP address */
2239
2240 #if defined(_WIN32)
@@ -2249,10 +2260,11 @@
2249 zFileGlob = z;
2250 }else{
2251 zFileGlob = find_option("files",0,1);
2252 }
2253 skin_override();
 
2254 g.useLocalauth = find_option("localauth", 0, 0)!=0;
2255 Th_InitTraceLog();
2256 zPort = find_option("port", "P", 1);
2257 zNotFound = find_option("notfound", 0, 1);
2258 zAltBase = find_option("baseurl", 0, 1);
@@ -2326,11 +2338,11 @@
2326 if( g.fHttpTrace || g.fSqlTrace ){
2327 fprintf(stderr, "====== SERVER pid %d =======\n", getpid());
2328 }
2329 g.cgiOutput = 1;
2330 find_server_repository(isUiCmd && zNotFound==0, 2);
2331 g.zRepositoryName = enter_chroot_jail(g.zRepositoryName);
2332 if( flags & HTTP_SERVER_SCGI ){
2333 cgi_handle_scgi_request();
2334 }else{
2335 cgi_handle_http_request(0);
2336 }
2337
--- src/main.c
+++ src/main.c
@@ -1357,12 +1357,15 @@
1357 ** zRepo might be a directory itself. In that case chroot into
1358 ** the directory zRepo.
1359 **
1360 ** Assume the user-id and group-id of the repository, or if zRepo
1361 ** is a directory, of that directory.
1362 **
1363 ** The noJail flag means that the chroot jail is not entered. But
1364 ** privileges are still lowered to that of the the user-id and group-id.
1365 */
1366 static char *enter_chroot_jail(char *zRepo, int noJail){
1367 #if !defined(_WIN32)
1368 if( getuid()==0 ){
1369 int i;
1370 struct stat sStat;
1371 Blob dir;
@@ -1371,26 +1374,28 @@
1374 db_close(1);
1375 }
1376
1377 file_canonical_name(zRepo, &dir, 0);
1378 zDir = blob_str(&dir);
1379 if( !noJail ){
1380 if( file_isdir(zDir)==1 ){
 
 
 
 
 
 
 
 
1381 if( file_chdir(zDir, 1) ){
1382 fossil_fatal("unable to chroot into %s", zDir);
1383 }
1384 zRepo = "/";
1385 }else{
1386 for(i=strlen(zDir)-1; i>0 && zDir[i]!='/'; i--){}
1387 if( zDir[i]!='/' ) fossil_fatal("bad repository name: %s", zRepo);
1388 if( i>0 ){
1389 zDir[i] = 0;
1390 if( file_chdir(zDir, 1) ){
1391 fossil_fatal("unable to chroot into %s", zDir);
1392 }
1393 zDir[i] = '/';
1394 }
1395 zRepo = &zDir[i];
1396 }
 
1397 }
1398 if( stat(zRepo, &sStat)!=0 ){
1399 fossil_fatal("cannot stat() repository: %s", zRepo);
1400 }
1401 i = setgid(sStat.st_gid);
@@ -2026,10 +2031,11 @@
2031 **
2032 ** Options:
2033 ** --localauth enable automatic login for local connections
2034 ** --host NAME specify hostname of the server
2035 ** --https signal a request coming in via https
2036 ** --nojail drop root privilege but do not enter the chroot jail
2037 ** --nossl signal that no SSL connections are available
2038 ** --notfound URL use URL as "HTTP 404, object not found" page.
2039 ** --files GLOB comma-separate glob patterns for static file to serve
2040 ** --baseurl URL base URL (useful with reverse proxies)
2041 ** --scgi Interpret input as SCGI rather than HTTP
@@ -2042,10 +2048,11 @@
2048 const char *zNotFound;
2049 const char *zHost;
2050 const char *zAltBase;
2051 const char *zFileGlob;
2052 int useSCGI;
2053 int noJail;
2054
2055 /* The winhttp module passes the --files option as --files-urlenc with
2056 ** the argument being URL encoded, to avoid wildcard expansion in the
2057 ** shell. This option is for internal use and is undocumented.
2058 */
@@ -2057,10 +2064,11 @@
2064 }else{
2065 zFileGlob = find_option("files",0,1);
2066 }
2067 skin_override();
2068 zNotFound = find_option("notfound", 0, 1);
2069 noJail = find_option("nojail",0,0)!=0;
2070 g.useLocalauth = find_option("localauth", 0, 0)!=0;
2071 g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
2072 useSCGI = find_option("scgi", 0, 0)!=0;
2073 zAltBase = find_option("baseurl", 0, 1);
2074 if( zAltBase ) set_base_url(zAltBase);
@@ -2093,11 +2101,11 @@
2101 zIpAddr = cgi_ssh_remote_addr(0);
2102 if( zIpAddr && zIpAddr[0] ){
2103 g.fSshClient |= CGI_SSH_CLIENT;
2104 }
2105 }
2106 g.zRepositoryName = enter_chroot_jail(g.zRepositoryName, noJail);
2107 if( useSCGI ){
2108 cgi_handle_scgi_request();
2109 }else if( g.fSshClient & CGI_SSH_CLIENT ){
2110 ssh_request_loop(zIpAddr, glob_create(zFileGlob));
2111 }else{
@@ -2211,19 +2219,21 @@
2219 ** and the connection is from localhost. The optional REPOSITORY argument
2220 ** to "ui" may be a directory and will function as "server" if and only if
2221 ** the --notfound option is used.
2222 **
2223 ** Options:
2224 ** --baseurl URL Use URL as the base (useful for reverse proxies)
2225 ** --files GLOBLIST Comma-separated list of glob patterns for static files
2226 ** --localauth enable automatic login for requests from localhost
2227 ** --localhost listen on 127.0.0.1 only (always true for "ui")
2228 ** --nojail Drop root privileges but do not enter the chroot jail
2229 ** --notfound URL Redirect
2230 ** -P|--port TCPPORT listen to request on port TCPPORT
2231 ** --th-trace trace TH1 execution (for debugging purposes)
 
 
 
2232 ** --scgi Accept SCGI rather than HTTP
2233 ** --skin LABEL Use override skin LABEL
2234
2235 **
2236 ** See also: cgi, http, winsrv
2237 */
2238 void cmd_webserver(void){
2239 int iPort, mxPort; /* Range of TCP ports allowed */
@@ -2231,10 +2241,11 @@
2241 const char *zBrowser; /* Name of web browser program */
2242 char *zBrowserCmd = 0; /* Command to launch the web browser */
2243 int isUiCmd; /* True if command is "ui", not "server' */
2244 const char *zNotFound; /* The --notfound option or NULL */
2245 int flags = 0; /* Server flags */
2246 int noJail; /* Do not enter the chroot jail */
2247 const char *zAltBase; /* Argument to the --baseurl option */
2248 const char *zFileGlob; /* Static content must match this */
2249 char *zIpAddr = 0; /* Bind to this IP address */
2250
2251 #if defined(_WIN32)
@@ -2249,10 +2260,11 @@
2260 zFileGlob = z;
2261 }else{
2262 zFileGlob = find_option("files",0,1);
2263 }
2264 skin_override();
2265 noJail = find_option("nojail",0,0)!=0;
2266 g.useLocalauth = find_option("localauth", 0, 0)!=0;
2267 Th_InitTraceLog();
2268 zPort = find_option("port", "P", 1);
2269 zNotFound = find_option("notfound", 0, 1);
2270 zAltBase = find_option("baseurl", 0, 1);
@@ -2326,11 +2338,11 @@
2338 if( g.fHttpTrace || g.fSqlTrace ){
2339 fprintf(stderr, "====== SERVER pid %d =======\n", getpid());
2340 }
2341 g.cgiOutput = 1;
2342 find_server_repository(isUiCmd && zNotFound==0, 2);
2343 g.zRepositoryName = enter_chroot_jail(g.zRepositoryName, noJail);
2344 if( flags & HTTP_SERVER_SCGI ){
2345 cgi_handle_scgi_request();
2346 }else{
2347 cgi_handle_http_request(0);
2348 }
2349

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button