summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-05-26 03:05:37 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:17:02 -0500
commit44d2a46580da126866f704e5cf9b6599635f5f01 (patch)
tree59410b0ba2fd51788153a879d9a01d013453b9aa
parente8e8eab400fbc310bcf1af8dd1d5436fe9e1cac4 (diff)
downloadsamba-44d2a46580da126866f704e5cf9b6599635f5f01.tar.gz
samba-44d2a46580da126866f704e5cf9b6599635f5f01.tar.bz2
samba-44d2a46580da126866f704e5cf9b6599635f5f01.zip
r6987: - make sure esp pages cannot read data outside of the swat directory
- don't expose the real system path to esp scripts - fixed absolute paths in include() calls (This used to be commit 6535611aa22f51b7376be3c15715e8040a059736)
-rw-r--r--source4/web_server/esp/esp.h2
-rw-r--r--source4/web_server/esp/espProcs.c8
-rw-r--r--source4/web_server/http.c79
3 files changed, 44 insertions, 45 deletions
diff --git a/source4/web_server/esp/esp.h b/source4/web_server/esp/esp.h
index 33ab9d7ac9..4503cacbb7 100644
--- a/source4/web_server/esp/esp.h
+++ b/source4/web_server/esp/esp.h
@@ -99,7 +99,7 @@ typedef struct Esp {
char *(*getSessionId)(EspHandle handle);
int (*mapToStorage)(EspHandle handle, char *path, int len, char *uri,
int flags);
- int (*readFile)(EspHandle handle, char **buf, int *len, char *path);
+ int (*readFile)(EspHandle handle, char **buf, int *len, const char *path);
void (*redirect)(EspHandle handle, int code, char *url);
void (*setCookie)(EspHandle handle, char *name, char *value,
int lifetime, char *path, bool secure);
diff --git a/source4/web_server/esp/espProcs.c b/source4/web_server/esp/espProcs.c
index a8da800213..5c99e092c9 100644
--- a/source4/web_server/esp/espProcs.c
+++ b/source4/web_server/esp/espProcs.c
@@ -77,8 +77,12 @@ static int includeProc(EspRequest *ep, int argc, char **argv)
esp = ep->esp;
mprAssert(argv);
for (i = 0; i < argc; i++) {
- mprGetDirName(dir, sizeof(dir), ep->docPath);
- mprSprintf(path, sizeof(path), "%s/%s", dir, argv[i]);
+ if (argv[i][0] != '/') {
+ mprGetDirName(dir, sizeof(dir), ep->docPath);
+ mprSprintf(path, sizeof(path), "%s/%s", dir, argv[i]);
+ } else {
+ mprSprintf(path, sizeof(path), "%s", argv[i]);
+ }
if (esp->readFile(ep->requestHandle, &buf, &size, path) < 0) {
espError(ep, "Can't read include file: %s", path);
diff --git a/source4/web_server/http.c b/source4/web_server/http.c
index 5f89e47163..fa03830295 100644
--- a/source4/web_server/http.c
+++ b/source4/web_server/http.c
@@ -97,14 +97,45 @@ static void http_output_headers(struct websrv_context *web)
}
/*
+ return the local path for a URL
+*/
+static const char *http_local_path(struct websrv_context *web, const char *url)
+{
+ int i;
+ char *path;
+
+ /* check that the url is OK */
+ if (url[0] != '/') return NULL;
+
+ for (i=0;url[i];i++) {
+ if ((!isalnum(url[i]) && !strchr("./", url[i])) ||
+ (url[i] == '.' && strchr("/.", url[i+1]))) {
+ return NULL;
+ }
+ }
+
+ path = talloc_asprintf(web, "%s/%s", lp_swat_directory(), url+1);
+ if (path == NULL) return NULL;
+
+ if (directory_exist(path)) {
+ path = talloc_asprintf_append(path, "/index.html");
+ }
+ return path;
+}
+
+/*
called when esp wants to read a file to support include() calls
*/
-static int http_readFile(EspHandle handle, char **buf, int *len, char *path)
+static int http_readFile(EspHandle handle, char **buf, int *len, const char *path)
{
+ struct websrv_context *web = talloc_get_type(handle, struct websrv_context);
int fd = -1;
struct stat st;
*buf = NULL;
+ path = http_local_path(web, path);
+ if (path == NULL) goto failed;
+
fd = open(path, O_RDONLY);
if (fd == -1 || fstat(fd, &st) != 0 || !S_ISREG(st.st_mode)) goto failed;
@@ -263,33 +294,6 @@ void http_error_unix(struct websrv_context *web, const char *info)
http_error(web, code, info);
}
-/*
- return the local path for a URL
-*/
-static const char *http_local_path(struct websrv_context *web, const char *url)
-{
- int i;
- char *path;
-
- /* check that the url is OK */
- if (url[0] != '/') return NULL;
-
- for (i=0;url[i];i++) {
- if ((!isalnum(url[i]) && !strchr("./", url[i])) ||
- (url[i] == '.' && strchr("/.", url[i+1]))) {
- return NULL;
- }
- }
-
- path = talloc_asprintf(web, "%s/%s", lp_swat_directory(), url+1);
- if (path == NULL) return NULL;
-
- if (directory_exist(path)) {
- path = talloc_asprintf_append(path, "/index.html");
- }
- return path;
-}
-
/*
a simple file request
@@ -356,6 +360,7 @@ static void http_setup_arrays(struct esp_state *esp)
espSetStringVar(req, ESP_SERVER_OBJ, "SERVER_PORT",
talloc_asprintf(esp, "%u", socket_get_my_port(web->conn->socket)));
espSetStringVar(req, ESP_SERVER_OBJ, "SERVER_PROTOCOL", "http");
+ espSetStringVar(esp->req, ESP_REQUEST_OBJ, "SCRIPT_FILENAME", web->input.url);
}
@@ -369,34 +374,24 @@ static void esp_request(struct esp_state *esp)
{
struct websrv_context *web = esp->web;
const char *url = web->input.url;
- const char *path;
size_t size;
int res;
char *emsg = NULL, *buf;
http_setup_arrays(esp);
- path = http_local_path(web, url);
- if (path == NULL) goto invalid;
-
- espSetStringVar(esp->req, ESP_REQUEST_OBJ, "SCRIPT_FILENAME", path);
-
- if (http_readFile(web, &buf, &size, path) != 0) {
- http_error_unix(web, path);
+ if (http_readFile(web, &buf, &size, url) != 0) {
+ http_error_unix(web, url);
return;
}
- res = espProcessRequest(esp->req, path, buf, &emsg);
+ res = espProcessRequest(esp->req, url, buf, &emsg);
if (res != 0 && emsg) {
- http_writeBlock(esp, emsg, strlen(emsg));
+ http_writeBlock(web, emsg, strlen(emsg));
}
talloc_free(buf);
http_output_headers(web);
EVENT_FD_WRITEABLE(web->conn->event.fde);
- return;
-
-invalid:
- http_error(web, 400, "Malformed URL");
}