From 926f4d9125fa76d54e9abeba372ee78e9545182b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 11 Sep 1997 02:17:16 +0000 Subject: cgi.c is a simple set of CGI manipulation routines wsmbconf.c is a rudimentary web based smb.conf editor. Its really there just to demonstrate how such an editor can hook into loadparm.c, I don't expect anyone to actually use it as is. wsmbstatus.c is a simple web based smbstatus. Its probably broken. (This used to be commit ced5205f72ba58d677f3cfa480fddc58ec9faa27) --- source3/web/cgi.c | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 source3/web/cgi.c (limited to 'source3/web') diff --git a/source3/web/cgi.c b/source3/web/cgi.c new file mode 100644 index 0000000000..56c293985d --- /dev/null +++ b/source3/web/cgi.c @@ -0,0 +1,163 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + some simple CGI helper routines + Copyright (C) Andrew Tridgell 1997 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#include "includes.h" + +#define MAX_VARIABLES 512 + +struct var { + char *name; + char *value; +}; + +static struct var variables[MAX_VARIABLES]; +static int num_variables; + + +static int grab_line(int *cl, char *line, int maxsize) +{ + int i = 0; + + while ((*cl)) { + int c = fgetc(stdin); + (*cl)--; + + if (c == EOF) { + (*cl) = 0; + break; + } + + if (c == '+') { + c = ' '; + } + + if (c == '\r') continue; + + if (strchr("\n&", c)) break; + + if (c == '%' && (*cl) >= 2) { + int c1, c2; + c1 = fgetc(stdin); + c2 = fgetc(stdin); + (*cl) -= 2; + if (c1 == EOF || c2 == EOF) break; + if (c1 >= '0' && c1 <= '9') + c1 = c1 - '0'; + else if (c1 >= 'A' && c1 <= 'F') + c1 = 10 + c1 - 'A'; + else if (c1 >= 'a' && c1 <= 'f') + c1 = 10 + c1 - 'a'; + else break; + + if (c2 >= '0' && c2 <= '9') + c2 = c2 - '0'; + else if (c2 >= 'A' && c2 <= 'F') + c2 = 10 + c2 - 'A'; + else if (c2 >= 'a' && c2 <= 'f') + c2 = 10 + c2 - 'a'; + else break; + + c = (c1<<4) | c2; + } + + line[i++] = c; + + if (i == maxsize) break; + } + + /* now unescape the line */ + + + line[i] = 0; + return 1; +} + + +/*************************************************************************** + load all the variables passed to the CGI program + ***************************************************************************/ +void cgi_load_variables(void) +{ + static pstring line; + char *p; + int len; + + if (!(p=getenv("CONTENT_LENGTH"))) return; + + len = atoi(p); + + if (len <= 0) return; + + + + while (len && grab_line(&len, line, sizeof(line)-1)) { + p = strchr(line,'='); + if (!p) continue; + + *p = 0; + + variables[num_variables].name = strdup(line); + variables[num_variables].value = strdup(p+1); + + if (!variables[num_variables].name || + !variables[num_variables].value) + continue; + +#if 0 + printf("%s=%s
\n", + variables[num_variables].name, + variables[num_variables].value); +#endif + + num_variables++; + if (num_variables == MAX_VARIABLES) break; + } + + fclose(stdin); +} + + +/*************************************************************************** + find a variable passed via CGI + ***************************************************************************/ +char *cgi_variable(char *name) +{ + int i; + + for (i=0;i Date: Sat, 22 Nov 1997 07:51:23 +0000 Subject: this new cgi code includes the ability to act as a mini web server, allowing people to use web configuration of Samba without installing a web server (This used to be commit b4e05c360e77cbf27a95920b613bfe6bc874ea1b) --- source3/web/cgi.c | 577 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 510 insertions(+), 67 deletions(-) (limited to 'source3/web') diff --git a/source3/web/cgi.c b/source3/web/cgi.c index 56c293985d..3739d712d3 100644 --- a/source3/web/cgi.c +++ b/source3/web/cgi.c @@ -1,6 +1,4 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. some simple CGI helper routines Copyright (C) Andrew Tridgell 1997 @@ -20,9 +18,19 @@ */ -#include "includes.h" +#include +#include +#include +#include +#include +#include +#include -#define MAX_VARIABLES 512 +#define MAX_VARIABLES 10000 + +#ifdef DEBUG_COMMENTS +extern void print_title(char *fmt, ...); +#endif struct var { char *name; @@ -31,14 +39,60 @@ struct var { static struct var variables[MAX_VARIABLES]; static int num_variables; +static int content_length; +static int request_post; +static int request_get; +static char *query_string; + +static void unescape(char *buf) +{ + char *p=buf; + + while ((p=strchr(p,'+'))) + *p = ' '; + + p = buf; + + while (p && *p && (p=strchr(p,'%'))) { + int c1 = p[1]; + int c2 = p[2]; + + if (c1 >= '0' && c1 <= '9') + c1 = c1 - '0'; + else if (c1 >= 'A' && c1 <= 'F') + c1 = 10 + c1 - 'A'; + else if (c1 >= 'a' && c1 <= 'f') + c1 = 10 + c1 - 'a'; + else {p++; continue;} + + if (c2 >= '0' && c2 <= '9') + c2 = c2 - '0'; + else if (c2 >= 'A' && c2 <= 'F') + c2 = 10 + c2 - 'A'; + else if (c2 >= 'a' && c2 <= 'f') + c2 = 10 + c2 - 'a'; + else {p++; continue;} + + *p = (c1<<4) | c2; + + memcpy(p+1, p+3, strlen(p+3)+1); + p++; + } +} -static int grab_line(int *cl, char *line, int maxsize) +static char *grab_line(FILE *f, int *cl) { + char *ret; int i = 0; + int len = 1024; + + ret = (char *)malloc(len); + if (!ret) return NULL; + while ((*cl)) { - int c = fgetc(stdin); + int c = fgetc(f); (*cl)--; if (c == EOF) { @@ -46,98 +100,140 @@ static int grab_line(int *cl, char *line, int maxsize) break; } - if (c == '+') { - c = ' '; - } - if (c == '\r') continue; if (strchr("\n&", c)) break; - if (c == '%' && (*cl) >= 2) { - int c1, c2; - c1 = fgetc(stdin); - c2 = fgetc(stdin); - (*cl) -= 2; - if (c1 == EOF || c2 == EOF) break; - if (c1 >= '0' && c1 <= '9') - c1 = c1 - '0'; - else if (c1 >= 'A' && c1 <= 'F') - c1 = 10 + c1 - 'A'; - else if (c1 >= 'a' && c1 <= 'f') - c1 = 10 + c1 - 'a'; - else break; - - if (c2 >= '0' && c2 <= '9') - c2 = c2 - '0'; - else if (c2 >= 'A' && c2 <= 'F') - c2 = 10 + c2 - 'A'; - else if (c2 >= 'a' && c2 <= 'f') - c2 = 10 + c2 - 'a'; - else break; - - c = (c1<<4) | c2; - } - - line[i++] = c; + ret[i++] = c; - if (i == maxsize) break; + if (i == len-1) { + char *ret2; + ret2 = (char *)realloc(ret, len*2); + if (!ret2) return ret; + len *= 2; + ret = ret2; + } } - - /* now unescape the line */ - line[i] = 0; - return 1; + ret[i] = 0; + return ret; } - /*************************************************************************** - load all the variables passed to the CGI program + load all the variables passed to the CGI program. May have multiple variables + 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) { - static pstring line; - char *p; + FILE *f = f1; + static char *line; + char *p, *s, *tok; int len; - if (!(p=getenv("CONTENT_LENGTH"))) return; +#ifdef DEBUG_COMMENTS + char dummy[100]=""; + print_title(dummy); + printf("\n",__FILE__); +#endif - len = atoi(p); + if (!f1) { + f = stdin; + if (!content_length) { + p = getenv("CONTENT_LENGTH"); + len = p?atoi(p):0; + } else { + len = content_length; + } + } else { + fseek(f, 0, SEEK_END); + len = ftell(f); + fseek(f, 0, SEEK_SET); + } - if (len <= 0) return; - + if (len > 0 && + (f1 || request_post || + ((s=getenv("REQUEST_METHOD")) && + strcasecmp(s,"POST")==0))) { + while (len && (line=grab_line(f, &len))) { + p = strchr(line,'='); + if (!p) continue; + + *p = 0; + + variables[num_variables].name = strdup(line); + variables[num_variables].value = strdup(p+1); - while (len && grab_line(&len, line, sizeof(line)-1)) { - p = strchr(line,'='); - if (!p) continue; + free(line); + + if (!variables[num_variables].name || + !variables[num_variables].value) + continue; - *p = 0; + unescape(variables[num_variables].value); + unescape(variables[num_variables].name); - variables[num_variables].name = strdup(line); - variables[num_variables].value = strdup(p+1); - - if (!variables[num_variables].name || - !variables[num_variables].value) - continue; - -#if 0 - printf("%s=%s
\n", - variables[num_variables].name, - variables[num_variables].value); +#ifdef DEBUG_COMMENTS + printf("\n", + variables[num_variables].name, + variables[num_variables].value); #endif + + num_variables++; + if (num_variables == MAX_VARIABLES) break; + } + } - num_variables++; - if (num_variables == MAX_VARIABLES) break; + if (f1) { +#ifdef DEBUG_COMMENTS + printf("\n"); +#endif + return; } fclose(stdin); + + if ((s=query_string) || (s=getenv("QUERY_STRING"))) { + for (tok=strtok(s,"&;");tok;tok=strtok(NULL,"&;")) { + p = strchr(tok,'='); + if (!p) continue; + + *p = 0; + + variables[num_variables].name = strdup(tok); + variables[num_variables].value = strdup(p+1); + + if (!variables[num_variables].name || + !variables[num_variables].value) + continue; + + unescape(variables[num_variables].value); + unescape(variables[num_variables].name); + +#ifdef DEBUG_COMMENTS + printf("\n", + variables[num_variables].name, + variables[num_variables].value); +#endif + num_variables++; + if (num_variables == MAX_VARIABLES) break; + } + + } +#ifdef DEBUG_COMMENTS + printf("\n"); +#endif } /*************************************************************************** find a variable passed via CGI + Doesn't quite do what you think in the case of POST text variables, because + if they exist they might have a value of "" or even " ", depending on the + browser. Also doesn't allow for variables[] containing multiple variables + with the same name and the same or different values. ***************************************************************************/ char *cgi_variable(char *name) { @@ -149,6 +245,15 @@ char *cgi_variable(char *name) return NULL; } +/*************************************************************************** +return a particular cgi variable + ***************************************************************************/ +char *cgi_vnum(int i, char **name) +{ + if (i < 0 || i >= num_variables) return NULL; + *name = variables[i].name; + return variables[i].value; +} /*************************************************************************** return the value of a CGI boolean variable. @@ -161,3 +266,341 @@ int cgi_boolean(char *name, int def) return strcmp(p, "1") == 0; } + +/*************************************************************************** +like strdup() but quotes < > and & + ***************************************************************************/ +char *quotedup(char *s) +{ + int i, n=0; + int len; + char *ret; + char *d; + + if (!s) return strdup(""); + + len = strlen(s); + + for (i=0;i' || s[i] == '&') + n++; + + ret = malloc(len + n*6 + 1); + + if (!ret) return NULL; + + d = ret; + + for (i=0;i': + strcpy(d, ">"); + d += 4; + break; + + case '&': + strcpy(d, "&"); + d += 5; + break; + + default: + *d++ = s[i]; + } + } + + *d = 0; + + return ret; +} + + +/*************************************************************************** +like strdup() but quotes a wide range of characters + ***************************************************************************/ +char *urlquote(char *s) +{ + int i, n=0; + int len; + char *ret; + char *d; + char *qlist = "\"\n\r'&<> \t+;"; + + if (!s) return strdup(""); + + len = strlen(s); + + for (i=0;i%s

%s

%s

\r\n", err, header, err, err, info); + exit(0); +} + + +/*************************************************************************** +decode a base64 string in-place - simple and slow algorithm + ***************************************************************************/ +static void base64_decode(char *s) +{ + char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + int bit_offset, byte_offset, idx, i; + unsigned char *d = (unsigned char *)s; + char *p; + + i=0; + + while (*s && (p=strchr(b64,*s))) { + idx = (int)(p - b64); + byte_offset = (i*6)/8; + bit_offset = (i*6)%8; + d[byte_offset] &= ~((1<<(8-bit_offset))-1); + if (bit_offset < 3) { + d[byte_offset] |= (idx << (2-bit_offset)); + } else { + d[byte_offset] |= (idx >> (bit_offset-2)); + d[byte_offset+1] = 0; + d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF; + } + s++; i++; + } +} + + +/*************************************************************************** +handle a http authentication line + ***************************************************************************/ +static int cgi_handle_authorization(char *line) +{ + char *p, *user, *pass; + struct passwd *pwd; + int ret=0; + + if (strncasecmp(line,"Basic ", 6)) { + cgi_setup_error("401 Bad Authorization", "", + "Only basic authorization is understood"); + } + line += 6; + while (line[0] == ' ') line++; + base64_decode(line); + if (!(p=strchr(line,':'))) { + cgi_setup_error("401 Bad Authorization", "", + "username/password must be supplied"); + } + *p = 0; + user = line; + pass = p+1; + + /* currently only allow connections as root */ + if (strcasecmp(user,"root")) { + cgi_setup_error("401 Bad Authorization", "", + "incorrect username/password"); + } + + pwd = getpwnam(user); + + if (!strcmp((char *)crypt(pass, pwd->pw_passwd),pwd->pw_passwd)) { + ret = 1; + } + + memset(pass, 0, strlen(pass)); + + return ret; +} + + +/*************************************************************************** +handle a file download + ***************************************************************************/ +static void cgi_download(char *file) +{ + struct stat st; + char buf[1024]; + int fd, l; + char *p; + + if (!file_exist(file, &st)) { + cgi_setup_error("404 File Not Found","", + "The requested file was not found"); + } + fd = open(file,O_RDONLY); + if (fd == -1) { + cgi_setup_error("404 File Not Found","", + "The requested file was not found"); + } + printf("HTTP/1.1 200 OK\r\n"); + if ((p=strrchr(file,'.'))) { + if (strcmp(p,".gif")==0 || strcmp(p,".jpg")==0) { + printf("Content-Type: image/gif\r\n"); + } else { + printf("Content-Type: text/html\r\n"); + } + } + 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); + } + close(fd); + exit(0); +} + + +/*************************************************************************** +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 authenticated = 0; + char line[1024]; + char *url=NULL; + char *p; + + if (chdir(rootdir)) { + cgi_setup_error("400 Server Error", "", + "chdir failed - the server is not configured correctly"); + } + + if (getenv("CONTENT_LENGTH") || getenv("REQUEST_METHOD")) { + /* assume we are running under a real web server */ + return; + } + + /* we are a mini-web server. We need to read the request from stdin + and handle authentication etc */ + while (fgets(line, sizeof(line)-1, stdin)) { + if (line[0] == '\r' || line[0] == '\n') break; + if (strncasecmp(line,"GET ", 4)==0) { + request_get = 1; + url = strdup(&line[4]); + } else if (strncasecmp(line,"POST ", 5)==0) { + request_post = 1; + url = strdup(&line[5]); + } else if (strncasecmp(line,"PUT ", 4)==0) { + cgi_setup_error("400 Bad Request", "", + "This server does not accept PUT requests"); + } else if (strncasecmp(line,"Authorization: ", 15)==0) { + authenticated = cgi_handle_authorization(&line[15]); + } else if (strncasecmp(line,"Content-Length: ", 16)==0) { + content_length = atoi(&line[16]); + } + /* ignore all other requests! */ + } + + if (!authenticated) { + cgi_setup_error("401 Authorization Required", + "WWW-Authenticate: Basic realm=\"samba\"\r\n", + "You must be authenticated to use this service"); + } + + if (!url) { + cgi_setup_error("400 Bad Request", "", + "You must specify a GET or POST request"); + } + + /* trim the URL */ + if ((p = strchr(url,' ')) || (p=strchr(url,'\t'))) { + *p = 0; + } + 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(url,'?'))) { + query_string = p+1; + *p = 0; + } + + if (strcmp(url,"/")) { + cgi_download(url+1); + } + + printf("HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n"); + +} -- cgit From 74f06e4062634fa4f8cb46915280dedf73d58c6f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Nov 1997 02:42:22 +0000 Subject: minor wsmbconf and cgi changes (This used to be commit bca9c49e6f24c2ee79cbb9b6ebf69d6647146fc1) --- source3/web/cgi.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'source3/web') diff --git a/source3/web/cgi.c b/source3/web/cgi.c index 3739d712d3..f165c56110 100644 --- a/source3/web/cgi.c +++ b/source3/web/cgi.c @@ -501,9 +501,22 @@ static void cgi_download(char *file) { struct stat st; char buf[1024]; - int fd, l; + int fd, l, i; char *p; + /* sanitise the filename */ + for (i=0;file[i];i++) { + if (!isalnum(file[i]) && !strchr("/.-_", file[i])) { + cgi_setup_error("404 File Not Found","", + "Illegal character in filename"); + } + } + + if (strstr(file,"..")) { + cgi_setup_error("404 File Not Found","", + "Relative paths not allowed"); + } + if (!file_exist(file, &st)) { cgi_setup_error("404 File Not Found","", "The requested file was not found"); @@ -574,7 +587,7 @@ void cgi_setup(char *rootdir) if (!authenticated) { cgi_setup_error("401 Authorization Required", - "WWW-Authenticate: Basic realm=\"samba\"\r\n", + "WWW-Authenticate: Basic realm=\"root\"\r\n", "You must be authenticated to use this service"); } @@ -604,3 +617,5 @@ void cgi_setup(char *rootdir) printf("HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n"); } + + -- cgit From 96eed00608226370ca4177fd9c8a4ae54d17517d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 12 Jan 1998 00:32:27 +0000 Subject: propogate my cgi changes to the main branch (This used to be commit 215c97e83ac74757cffb4f64176c80ddb845d65f) --- source3/web/cgi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/web') diff --git a/source3/web/cgi.c b/source3/web/cgi.c index f165c56110..e697f5537a 100644 --- a/source3/web/cgi.c +++ b/source3/web/cgi.c @@ -614,7 +614,7 @@ void cgi_setup(char *rootdir) cgi_download(url+1); } - printf("HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n"); + printf("HTTP/1.1 200 OK\r\nConnection: close\r\n"); } -- cgit From 55f400bd84f26027f5ec9b7fa06b22895de7557c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Jan 1998 13:27:43 +0000 Subject: This is *not* a big change (although it looks like one). This is merely updating the Copyright statements from 1997 to 1998. It's a once a year thing :-). NO OTHER CHANGES WERE MADE. Jeremy. (This used to be commit b9c16977231efb274e08856f7f3f4408dad6d96c) --- source3/web/cgi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/web') diff --git a/source3/web/cgi.c b/source3/web/cgi.c index e697f5537a..ae60d72b7b 100644 --- a/source3/web/cgi.c +++ b/source3/web/cgi.c @@ -1,6 +1,6 @@ /* some simple CGI helper routines - Copyright (C) Andrew Tridgell 1997 + Copyright (C) Andrew Tridgell 1997-1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From 35d67dd80aa3ba72b75683cb1f35c81066e21223 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 8 Mar 1998 14:14:49 +0000 Subject: Jeremy is going to hate me ... These are some hacks on SWAT. Maybe users will actually be able to work out how to use it now. Unfortunately these changes required some editing in loadparm.c and smb.h which will make Jeremys merge job harder. Sorry! (This used to be commit 674c88a6bf4c8009769a482c53f105efdc54bbc8) --- source3/web/cgi.c | 13 +- source3/web/swat.c | 483 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 494 insertions(+), 2 deletions(-) create mode 100644 source3/web/swat.c (limited to 'source3/web') diff --git a/source3/web/cgi.c b/source3/web/cgi.c index ae60d72b7b..7c84f47ada 100644 --- a/source3/web/cgi.c +++ b/source3/web/cgi.c @@ -43,6 +43,7 @@ static int content_length; static int request_post; static int request_get; static char *query_string; +static char *baseurl; static void unescape(char *buf) { @@ -610,12 +611,20 @@ void cgi_setup(char *rootdir) *p = 0; } - if (strcmp(url,"/")) { + if (strstr(url+1,"..")==0 && file_exist(url+1)) { cgi_download(url+1); } printf("HTTP/1.1 200 OK\r\nConnection: close\r\n"); - + + baseurl = url+1; } +/*************************************************************************** +return the current pages URL + ***************************************************************************/ +char *cgi_baseurl(void) +{ + return baseurl; +} diff --git a/source3/web/swat.c b/source3/web/swat.c new file mode 100644 index 0000000000..4810d87af3 --- /dev/null +++ b/source3/web/swat.c @@ -0,0 +1,483 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + html smb.conf editing - prototype only + Copyright (C) Andrew Tridgell 1997-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" +#include "smb.h" + +#define GLOBALS_SNUM -2 +#define DEFAULTS_SNUM -1 + +static pstring servicesf = CONFIGFILE; + + +/* start the page with standard stuff */ +static void print_header(void) +{ + printf("Content-type: text/html\r\n\r\n"); + printf("\n"); + printf("\n\nSamba Web Administration Tool\n\n\n\n"); +} + + +/* finish off the page */ +static void print_footer(void) +{ + printf("\n\n\n"); +} + +/* include a lump of html in a page */ +static void include_html(char *fname) +{ + FILE *f = fopen(fname,"r"); + char buf[1024]; + int ret; + + if (!f) { + printf("ERROR: Can't open %s\n", fname); + return; + } + + while (!feof(f)) { + ret = fread(buf, 1, sizeof(buf), f); + if (ret <= 0) break; + fwrite(buf, 1, ret, stdout); + } + + fclose(f); +} + + +/* display one editable parameter */ +static void show_parameter(int snum, struct parm_struct *parm) +{ + int i; + void *ptr = parm->ptr; + + if (parm->class == P_LOCAL) { + ptr = lp_local_ptr(snum, ptr); + } + + printf("? %s", + parm->label, parm->label); + + switch (parm->type) { + case P_CHAR: + printf("", + parm->label, *(char *)ptr); + break; + + case P_STRING: + case P_USTRING: + printf("", + parm->label, *(char **)ptr); + break; + + case P_GSTRING: + case P_UGSTRING: + printf("", + parm->label, (char *)ptr); + break; + + case P_BOOL: + printf("yes  ", parm->label, (*(BOOL *)ptr)?"CHECKED":""); + printf("no", parm->label, (*(BOOL *)ptr)?"":"CHECKED"); + break; + + case P_BOOLREV: + printf("yes  ", parm->label, (*(BOOL *)ptr)?"":"CHECKED"); + printf("no", parm->label, (*(BOOL *)ptr)?"CHECKED":""); + break; + + case P_INTEGER: + printf("", parm->label, *(int *)ptr); + break; + + case P_OCTAL: + printf("", parm->label, *(int *)ptr); + break; + + case P_ENUM: + for (i=0;parm->enum_list[i].name;i++) + printf("%s  ", + parm->label, parm->enum_list[i].name, + (*(int *)ptr)==parm->enum_list[i].value?"CHECKED":"", + parm->enum_list[i].name); + break; + + } + printf("\n"); +} + +/* display a set of parameters for a service */ +static void show_parameters(int snum, int allparameters, int advanced, int printers) +{ + int i = 0; + struct parm_struct *parm; + + printf("\n"); + + while ((parm = lp_next_parameter(snum, &i, allparameters))) { + if (parm->flags & FLAG_HIDE) continue; + if (!advanced) { + if (!printers && !(parm->flags & FLAG_BASIC)) continue; + if (printers && !(parm->flags & FLAG_PRINT)) continue; + } + show_parameter(snum, parm); + } + printf("
\n"); +} + + +static int save_reload(void) +{ + FILE *f; + + f = fopen(servicesf,"w"); + if (!f) { + printf("failed to open %s for writing\n", servicesf); + return 0; + } + + fprintf(f, "# Samba config file created using SWAT\n"); + + lp_dump(f); + + fclose(f); + + lp_killunused(NULL); + + if (!lp_load(servicesf,False)) { + printf("Can't reload %s\n", servicesf); + return 0; + } + + return 1; +} + + + +/* commit a set of parameters for a service */ +static void commit_parameters(int snum) +{ + int i = 0; + struct parm_struct *parm; + pstring label; + char *v; + + while ((parm = lp_next_parameter(snum, &i, 1))) { + sprintf(label, "parm_%s", parm->label); + if ((v = cgi_variable(label))) { + lp_do_parameter(snum, parm->label, v); + } + } + + save_reload(); +} + + +/* load the smb.conf file into loadparm. */ +static void load_config(void) +{ + if (!lp_load(servicesf,False)) { + printf("Can't load %s - using defaults

\n", + servicesf); + } +} + +/* spit out the html for a link with an image */ +static void image_link(char *name,char *hlink, char *src, int width, int height) +{ + printf("\"%s\"\n", hlink, width, height, src, name); +} + +/* display the main navigation controls at the top of each page along + with a title */ +static void show_main_buttons(void) +{ + printf("

Samba Web Administration Tool

\n"); + + image_link("Globals", "globals", "images/globals.gif", 50, 50); + image_link("Shares", "shares", "images/shares.gif", 50, 50); + image_link("Printers", "printers", "images/printers.gif", 50, 50); + + printf("
\n"); +} + +/* display a welcome page */ +static void welcome_page(void) +{ + include_html("help/welcome.html"); +} + + +/* display a globals editing page */ +static void globals_page(void) +{ + int advanced = 0; + + printf("

Global Variables

\n"); + + if (cgi_variable("Advanced") && !cgi_variable("Basic")) + advanced = 1; + + if (cgi_variable("Commit")) { + commit_parameters(GLOBALS_SNUM); + } + + printf("
\n"); + + printf("\n"); + if (advanced == 0) { + printf("\n"); + } else { + printf("\n"); + } + printf("

\n"); + + show_parameters(GLOBALS_SNUM, 1, advanced, 0); + + if (advanced) { + printf("\n"); + } + + printf("

\n"); +} + +/* display a shares editing page */ +static void shares_page(void) +{ + char *share = cgi_variable("share"); + char *s; + int snum=-1; + int i; + int advanced = 0; + + if (share) + snum = lp_servicenumber(share); + + printf("

Share Parameters

\n"); + + if (cgi_variable("Advanced") && !cgi_variable("Basic")) + advanced = 1; + + if (cgi_variable("Commit") && snum >= 0) { + commit_parameters(snum); + } + + if (cgi_variable("Delete") && snum >= 0) { + lp_remove_service(snum); + save_reload(); + share = NULL; + snum = -1; + } + + if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) { + lp_copy_service(DEFAULTS_SNUM, share); + save_reload(); + snum = lp_servicenumber(share); + } + + printf("
\n"); + + printf("\n"); + printf("\n"); + printf("

"); + + printf("

\n"); + printf("\n"); + printf("
"); + + + if (snum >= 0) { + printf("\n"); + printf("\n"); + if (advanced == 0) { + printf("\n"); + } else { + printf("\n"); + } + printf("

\n"); + } + + if (snum >= 0) { + show_parameters(snum, 1, advanced, 0); + } + + if (advanced) { + printf("\n"); + } + + printf("

\n"); +} + + +/* display a printers editing page */ +static void printers_page(void) +{ + char *share = cgi_variable("share"); + char *s; + int snum=-1; + int i; + int advanced = 0; + + if (share) + snum = lp_servicenumber(share); + + printf("

Printer Parameters

\n"); + + if (cgi_variable("Advanced") && !cgi_variable("Basic")) + advanced = 1; + + if (cgi_variable("Commit") && snum >= 0) { + commit_parameters(snum); + } + + if (cgi_variable("Delete") && snum >= 0) { + lp_remove_service(snum); + save_reload(); + share = NULL; + snum = -1; + } + + if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) { + lp_copy_service(DEFAULTS_SNUM, share); + snum = lp_servicenumber(share); + lp_do_parameter(snum, "print ok", "Yes"); + save_reload(); + snum = lp_servicenumber(share); + } + + printf("
\n"); + + printf("\n"); + printf("\n"); + printf("

"); + + printf("

\n"); + printf("\n"); + printf("
"); + + + if (snum >= 0) { + printf("\n"); + printf("\n"); + if (advanced == 0) { + printf("\n"); + } else { + printf("\n"); + } + printf("

\n"); + } + + if (snum >= 0) { + show_parameters(snum, 1, advanced, 1); + } + + if (advanced) { + printf("\n"); + } + + printf("

\n"); +} + + +int main(int argc, char *argv[]) +{ + extern char *optarg; + extern int optind; + extern FILE *dbf; + int opt; + char *page; + + /* just in case it goes wild ... */ + alarm(300); + + dbf = fopen("/dev/null", "w"); + + if (!dbf) dbf = stderr; + + cgi_setup(SWATDIR); + + while ((opt = getopt(argc, argv,"s:")) != EOF) { + switch (opt) { + case 's': + pstrcpy(servicesf,optarg); + break; + } + } + + + print_header(); + + charset_initialise(); + + /* if this binary is setuid then run completely as root */ + setuid(0); + + load_config(); + + cgi_load_variables(NULL); + + show_main_buttons(); + + page = cgi_baseurl(); + + if (strcmp(page, "globals")==0) { + globals_page(); + } else if (strcmp(page,"shares")==0) { + shares_page(); + } else if (strcmp(page,"printers")==0) { + printers_page(); + } else { + welcome_page(); + } + + print_footer(); + return 0; +} + + -- cgit From 6a37b245e3894c5a3a62bf38d4eef27be5f209e8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 8 Mar 1998 14:31:50 +0000 Subject: allow for non-authenticated SWAT for demo purposes (This used to be commit 6e1237568b559c006ee5429308ac47e97cc4a1c4) --- source3/web/cgi.c | 4 ++-- source3/web/swat.c | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'source3/web') diff --git a/source3/web/cgi.c b/source3/web/cgi.c index 7c84f47ada..83158fc1a5 100644 --- a/source3/web/cgi.c +++ b/source3/web/cgi.c @@ -548,7 +548,7 @@ static void cgi_download(char *file) 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) +void cgi_setup(char *rootdir, int auth_required) { int authenticated = 0; char line[1024]; @@ -586,7 +586,7 @@ void cgi_setup(char *rootdir) /* ignore all other requests! */ } - if (!authenticated) { + if (auth_required && !authenticated) { cgi_setup_error("401 Authorization Required", "WWW-Authenticate: Basic realm=\"root\"\r\n", "You must be authenticated to use this service"); diff --git a/source3/web/swat.c b/source3/web/swat.c index 4810d87af3..6a5b4f51f1 100644 --- a/source3/web/swat.c +++ b/source3/web/swat.c @@ -432,6 +432,7 @@ int main(int argc, char *argv[]) extern FILE *dbf; int opt; char *page; + int auth_required = 1; /* just in case it goes wild ... */ alarm(300); @@ -440,16 +441,18 @@ int main(int argc, char *argv[]) if (!dbf) dbf = stderr; - cgi_setup(SWATDIR); - - while ((opt = getopt(argc, argv,"s:")) != EOF) { + while ((opt = getopt(argc, argv,"s:a")) != EOF) { switch (opt) { case 's': pstrcpy(servicesf,optarg); break; + case 'a': + auth_required = 0; + break; } } + cgi_setup(SWATDIR, auth_required); print_header(); -- cgit From c03c56b2e29fd773b19b01d22be4ce347be9f05b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 8 Mar 1998 14:52:45 +0000 Subject: - remove redundent strstr() - don't show printers in shares page (This used to be commit 2b4204a7769a974a74a7658e787274f6251b1d69) --- source3/web/cgi.c | 5 ----- source3/web/swat.c | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'source3/web') diff --git a/source3/web/cgi.c b/source3/web/cgi.c index 83158fc1a5..9ce8c4d91e 100644 --- a/source3/web/cgi.c +++ b/source3/web/cgi.c @@ -513,11 +513,6 @@ static void cgi_download(char *file) } } - if (strstr(file,"..")) { - cgi_setup_error("404 File Not Found","", - "Relative paths not allowed"); - } - if (!file_exist(file, &st)) { cgi_setup_error("404 File Not Found","", "The requested file was not found"); diff --git a/source3/web/swat.c b/source3/web/swat.c index 6a5b4f51f1..508c8944b4 100644 --- a/source3/web/swat.c +++ b/source3/web/swat.c @@ -308,7 +308,7 @@ static void shares_page(void) printf("