summaryrefslogtreecommitdiffstats
path: root/source/web/cgi.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/web/cgi.c')
-rw-r--r--source/web/cgi.c211
1 files changed, 90 insertions, 121 deletions
diff --git a/source/web/cgi.c b/source/web/cgi.c
index 7415fbe3f15..0b86265a1e5 100644
--- a/source/web/cgi.c
+++ b/source/web/cgi.c
@@ -19,7 +19,7 @@
#include "includes.h"
-#include "../web/swat_proto.h"
+#include "smb.h"
#define MAX_VARIABLES 10000
@@ -50,12 +50,12 @@ static void unescape(char *buf)
{
char *p=buf;
- while ((p=strchr_m(p,'+')))
+ while ((p=strchr(p,'+')))
*p = ' ';
p = buf;
- while (p && *p && (p=strchr_m(p,'%'))) {
+ while (p && *p && (p=strchr(p,'%'))) {
int c1 = p[1];
int c2 = p[2];
@@ -111,7 +111,7 @@ static char *grab_line(FILE *f, int *cl)
if (c == '\r') continue;
- if (strchr_m("\n&", c)) break;
+ if (strchr("\n&", c)) break;
ret[i++] = c;
@@ -127,33 +127,40 @@ static char *grab_line(FILE *f, int *cl)
with the same name and the same or different values. Takes a file parameter
for simulating CGI invocation eg loading saved preferences.
***************************************************************************/
-void cgi_load_variables(void)
+void cgi_load_variables(FILE *f1)
{
+ FILE *f = f1;
static char *line;
char *p, *s, *tok;
- int len, i;
- FILE *f = stdin;
+ int len;
#ifdef DEBUG_COMMENTS
char dummy[100]="";
print_title(dummy);
- d_printf("<!== Start dump in cgi_load_variables() %s ==>\n",__FILE__);
+ printf("<!== Start dump in cgi_load_variables() %s ==>\n",__FILE__);
#endif
- if (!content_length) {
- p = getenv("CONTENT_LENGTH");
- len = p?atoi(p):0;
+ if (!f1) {
+ f = stdin;
+ if (!content_length) {
+ p = getenv("CONTENT_LENGTH");
+ len = p?atoi(p):0;
+ } else {
+ len = content_length;
+ }
} else {
- len = content_length;
+ fseek(f, 0, SEEK_END);
+ len = ftell(f);
+ fseek(f, 0, SEEK_SET);
}
if (len > 0 &&
- (request_post ||
+ (f1 || request_post ||
((s=getenv("REQUEST_METHOD")) &&
strcasecmp(s,"POST")==0))) {
while (len && (line=grab_line(f, &len))) {
- p = strchr_m(line,'=');
+ p = strchr(line,'=');
if (!p) continue;
*p = 0;
@@ -181,12 +188,19 @@ void cgi_load_variables(void)
}
}
+ if (f1) {
+#ifdef DEBUG_COMMENTS
+ printf("<!== End dump in cgi_load_variables() ==>\n");
+#endif
+ return;
+ }
+
fclose(stdin);
open("/dev/null", O_RDWR);
if ((s=query_string) || (s=getenv("QUERY_STRING"))) {
for (tok=strtok(s,"&;");tok;tok=strtok(NULL,"&;")) {
- p = strchr_m(tok,'=');
+ p = strchr(tok,'=');
if (!p) continue;
*p = 0;
@@ -214,24 +228,6 @@ void cgi_load_variables(void)
#ifdef DEBUG_COMMENTS
printf("<!== End dump in cgi_load_variables() ==>\n");
#endif
-
- /* variables from the client are in display charset - convert them
- to our internal charset before use */
- for (i=0;i<num_variables;i++) {
- pstring dest;
-
- convert_string(CH_DISPLAY, CH_UNIX,
- variables[i].name, -1,
- dest, sizeof(dest));
- free(variables[i].name);
- variables[i].name = strdup(dest);
-
- convert_string(CH_DISPLAY, CH_UNIX,
- variables[i].value, -1,
- dest, sizeof(dest));
- free(variables[i].value);
- variables[i].value = strdup(dest);
- }
}
@@ -269,7 +265,7 @@ static void cgi_setup_error(char *err, char *header, char *info)
}
}
- d_printf("HTTP/1.0 %s\r\n%sConnection: close\r\nContent-Type: text/html\r\n\r\n<HTML><HEAD><TITLE>%s</TITLE></HEAD><BODY><H1>%s</H1>%s<p></BODY></HTML>\r\n\r\n", err, header, err, err, info);
+ printf("HTTP/1.0 %s\r\n%sConnection: close\r\nContent-Type: text/html\r\n\r\n<HTML><HEAD><TITLE>%s</TITLE></HEAD><BODY><H1>%s</H1>%s<p></BODY></HTML>\r\n\r\n", err, header, err, err, info);
fclose(stdin);
fclose(stdout);
exit(0);
@@ -296,37 +292,6 @@ static void cgi_auth_error(void)
exit(0);
}
-/***************************************************************************
-authenticate when we are running as a CGI
- ***************************************************************************/
-static void cgi_web_auth(void)
-{
- char *user = getenv("REMOTE_USER");
- struct passwd *pwd;
- char *head = "Content-Type: text/html\r\n\r\n<HTML><BODY><H1>SWAT installation Error</H1>\n";
- char *tail = "</BODY></HTML>\r\n";
-
- if (!user) {
- printf("%sREMOTE_USER not set. Not authenticated by web server.<br>%s\n",
- head, tail);
- exit(0);
- }
-
- pwd = getpwnam_alloc(user);
- if (!pwd) {
- printf("%sCannot find user %s<br>%s\n", head, user, tail);
- exit(0);
- }
-
- setuid(0);
- setuid(pwd->pw_uid);
- if (geteuid() != pwd->pw_uid || getuid() != pwd->pw_uid) {
- printf("%sFailed to become user %s - uid=%d/%d<br>%s\n",
- head, user, (int)geteuid(), (int)getuid(), tail);
- exit(0);
- }
- passwd_free(&pwd);
-}
/***************************************************************************
decode a base64 string in-place - simple and slow algorithm
@@ -340,7 +305,7 @@ static void base64_decode(char *s)
n=i=0;
- while (*s && (p=strchr_m(b64,*s))) {
+ while (*s && (p=strchr(b64,*s))) {
idx = (int)(p - b64);
byte_offset = (i*6)/8;
bit_offset = (i*6)%8;
@@ -367,6 +332,14 @@ static BOOL cgi_handle_authorization(char *line)
{
char *p, *user, *user_pass;
struct passwd *pass = NULL;
+ BOOL got_name = False;
+ BOOL tested_pass = False;
+ fstring default_user_lookup;
+ fstring default_user_pass;
+
+ /* Dummy user lookup to take the same time as a valid user. */
+ fstrcpy(default_user_lookup, "zzzz bibble");
+ fstrcpy(default_user_pass, "123456789");
if (strncasecmp(line,"Basic ", 6)) {
goto err;
@@ -374,7 +347,7 @@ static BOOL cgi_handle_authorization(char *line)
line += 6;
while (line[0] == ' ') line++;
base64_decode(line);
- if (!(p=strchr_m(line,':'))) {
+ if (!(p=strchr(line,':'))) {
/*
* Always give the same error so a cracker
* cannot tell why we fail.
@@ -384,39 +357,58 @@ static BOOL cgi_handle_authorization(char *line)
*p = 0;
user = line;
user_pass = p+1;
-
+
/*
* Try and get the user from the UNIX password file.
*/
-
- pass = getpwnam_alloc(user);
-
+
+ if(!(pass = Get_Pwnam(user,False))) {
+ /*
+ * Always give the same error so a cracker
+ * cannot tell why we fail.
+ */
+ got_name = True;
+ goto err;
+ }
+
/*
* Validate the password they have given.
*/
-
- if NT_STATUS_IS_OK(pass_check(pass, user, user_pass,
- strlen(user_pass), NULL, False)) {
-
- if (pass) {
+
+ tested_pass = True;
+
+ if(pass_check(user, user_pass, strlen(user_pass), NULL, NULL) == True) {
+
+ /*
+ * Password was ok.
+ */
+
+ if(pass->pw_uid != 0) {
/*
- * Password was ok.
+ * We have not authenticated as root,
+ * become the user *permanently*.
*/
-
become_user_permanently(pass->pw_uid, pass->pw_gid);
-
- /* Save the users name */
- C_user = strdup(user);
- passwd_free(&pass);
- return True;
}
+
+ /* Save the users name */
+ C_user = strdup(user);
+ return True;
}
-
-err:
+
+ err:
+
+ /* Always take the same time. */
+ if (!got_name)
+ Get_Pwnam(default_user_lookup,False);
+
+ if (!tested_pass)
+ pass_check(default_user_lookup, default_user_pass,
+ strlen(default_user_pass), NULL, NULL);
+
cgi_setup_error("401 Bad Authorization", "",
"username or password incorrect");
- passwd_free(&pass);
return False;
}
@@ -450,11 +442,10 @@ static void cgi_download(char *file)
char buf[1024];
int fd, l, i;
char *p;
- char *lang;
/* sanitise the filename */
for (i=0;file[i];i++) {
- if (!isalnum((int)file[i]) && !strchr_m("/.-_", file[i])) {
+ if (!isalnum((int)file[i]) && !strchr("/.-_", file[i])) {
cgi_setup_error("404 File Not Found","",
"Illegal character in filename");
}
@@ -464,14 +455,13 @@ static void cgi_download(char *file)
cgi_setup_error("404 File Not Found","",
"The requested file was not found");
}
-
- fd = web_open(file,O_RDONLY,0);
+ fd = sys_open(file,O_RDONLY,0);
if (fd == -1) {
cgi_setup_error("404 File Not Found","",
"The requested file was not found");
}
printf("HTTP/1.0 200 OK\r\n");
- if ((p=strrchr_m(file,'.'))) {
+ if ((p=strrchr(file,'.'))) {
if (strcmp(p,".gif")==0) {
printf("Content-Type: image/gif\r\n");
} else if (strcmp(p,".jpg")==0) {
@@ -484,11 +474,6 @@ static void cgi_download(char *file)
}
printf("Expires: %s\r\n", http_timestring(time(NULL)+EXPIRY_TIME));
- lang = lang_tdb_current();
- if (lang) {
- printf("Content-Language: %s\r\n", lang);
- }
-
printf("Content-Length: %d\r\n\r\n", (int)st.st_size);
while ((l=read(fd,buf,sizeof(buf)))>0) {
fwrite(buf, 1, l, stdout);
@@ -498,40 +483,26 @@ static void cgi_download(char *file)
}
-
-
-/**
- * @brief Setup the CGI framework.
- *
- * Setup the cgi framework, handling the possibility that this program
- * is either run as a true CGI program with a gateway to a web server, or
- * is itself a mini web server.
- **/
-void cgi_setup(const char *rootdir, int auth_required)
+/***************************************************************************
+setup the cgi framework, handling the possability that this program is either
+run as a true cgi program by a web browser or is itself a mini web server
+ ***************************************************************************/
+void cgi_setup(char *rootdir, int auth_required)
{
BOOL authenticated = False;
char line[1024];
char *url=NULL;
char *p;
- char *lang;
if (chdir(rootdir)) {
cgi_setup_error("400 Server Error", "",
"chdir failed - the server is not configured correctly");
}
- /* Handle the possability we might be running as non-root */
- sec_init();
-
- if ((lang=getenv("HTTP_ACCEPT_LANGUAGE"))) {
- /* if running as a cgi program */
- web_set_lang(lang);
- }
-
/* maybe we are running under a web server */
if (getenv("CONTENT_LENGTH") || getenv("REQUEST_METHOD")) {
if (auth_required) {
- cgi_web_auth();
+ cgi_auth_error();
}
return;
}
@@ -562,8 +533,6 @@ void cgi_setup(const char *rootdir, int auth_required)
authenticated = cgi_handle_authorization(&line[15]);
} else if (strncasecmp(line,"Content-Length: ", 16)==0) {
content_length = atoi(&line[16]);
- } else if (strncasecmp(line,"Accept-Language: ", 17)==0) {
- web_set_lang(&line[17]);
}
/* ignore all other requests! */
}
@@ -578,15 +547,15 @@ void cgi_setup(const char *rootdir, int auth_required)
}
/* trim the URL */
- if ((p = strchr_m(url,' ')) || (p=strchr_m(url,'\t'))) {
+ if ((p = strchr(url,' ')) || (p=strchr(url,'\t'))) {
*p = 0;
}
- while (*url && strchr_m("\r\n",url[strlen(url)-1])) {
+ while (*url && strchr("\r\n",url[strlen(url)-1])) {
url[strlen(url)-1] = 0;
}
/* anything following a ? in the URL is part of the query string */
- if ((p=strchr_m(url,'?'))) {
+ if ((p=strchr(url,'?'))) {
query_string = p+1;
*p = 0;
}