cgi.c is a simple set of CGI manipulation routines
authorAndrew Tridgell <tridge@samba.org>
Thu, 11 Sep 1997 02:17:16 +0000 (02:17 +0000)
committerAndrew Tridgell <tridge@samba.org>
Thu, 11 Sep 1997 02:17:16 +0000 (02:17 +0000)
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/cgi.c [new file with mode: 0644]
source3/web/cgi.c [new file with mode: 0644]
source3/wsmbconf.c [new file with mode: 0644]
source3/wsmbstatus.c [new file with mode: 0644]

diff --git a/source3/cgi.c b/source3/cgi.c
new file mode 100644 (file)
index 0000000..56c2939
--- /dev/null
@@ -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<br>\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<num_variables;i++)
+               if (strcmp(variables[i].name, name) == 0)
+                       return variables[i].value;
+       return NULL;
+}
+
+
+/***************************************************************************
+  return the value of a CGI boolean variable.
+  ***************************************************************************/
+int cgi_boolean(char *name, int def)
+{
+       char *p = cgi_variable(name);
+
+       if (!p) return def;
+
+       return strcmp(p, "1") == 0;
+}
diff --git a/source3/web/cgi.c b/source3/web/cgi.c
new file mode 100644 (file)
index 0000000..56c2939
--- /dev/null
@@ -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<br>\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<num_variables;i++)
+               if (strcmp(variables[i].name, name) == 0)
+                       return variables[i].value;
+       return NULL;
+}
+
+
+/***************************************************************************
+  return the value of a CGI boolean variable.
+  ***************************************************************************/
+int cgi_boolean(char *name, int def)
+{
+       char *p = cgi_variable(name);
+
+       if (!p) return def;
+
+       return strcmp(p, "1") == 0;
+}
diff --git a/source3/wsmbconf.c b/source3/wsmbconf.c
new file mode 100644 (file)
index 0000000..25b3dea
--- /dev/null
@@ -0,0 +1,251 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   html smb.conf editing - prototype only
+   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.
+*/
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "smb.h"
+
+#define SDEFAULTS "Service defaults"
+#define SGLOBAL "Global Parameters"
+#define GLOBALS_SNUM -2
+#define DEFAULTS_SNUM -1
+
+
+/* start the page with standard stuff */
+static void print_header(void)
+{
+       printf("Content-type: text/html\n\n");
+       printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
+       printf("<HTML>\n<HEAD>\n<TITLE>smb.conf</TITLE>\n</HEAD>\n<BODY>\n\n");
+}
+
+
+/* finish off the page */
+static void print_footer(void)
+{
+       printf("\n</BODY>\n</HTML>\n");
+}
+
+/* setup persisant variables */
+static void set_persistent(char *name)
+{
+       char *p;
+       p = cgi_variable(name);
+       if (!p) return;
+       printf("<input type=hidden name=%s value=%s>\n", name, p);
+}
+
+/* display a servce, ready for editing */
+static void show_service(int snum, int allparameters)
+{
+       int i = 0;
+       pstring label, value;
+       char *sname;
+
+       if (snum == GLOBALS_SNUM) 
+               sname = SGLOBAL;
+       else if (snum == DEFAULTS_SNUM)
+               sname = SDEFAULTS;
+       else sname = lp_servicename(snum);
+
+       printf("\n<p><table border=0>\n<tr>\n<td>\n\n");
+       printf("<form method=POST>\n");
+       printf("<H3>%s</H3>\n", sname);
+       printf("<input type=hidden name=service value=\"%s\">\n", sname);
+       printf("<input type=submit name=request value=Change>\n");
+       printf("<input type=submit name=request value=Rename>\n");
+       printf("<input type=submit name=request value=Copy>\n");
+       printf("<input type=submit name=request value=Remove>\n");
+       printf("<br><input name=newvalue><br>\n");
+       printf("<select name=parameter size=5>\n");
+       
+       while (lp_next_parameter(snum, &i, label, value, allparameters)) {
+               printf("<option value=\"%s\">%s = %s\n", 
+                      label, label, value);
+       }
+
+       printf("</select>\n");
+       printf("</form>\n</td>\n</tr>\n</table>\n");
+
+       printf("<p>\n");
+}
+
+
+/* loop over all services, displaying them one after the other */
+static void show_services(void)
+{
+       int i;
+       int n;
+       int allparameters = cgi_boolean("allparameters", 0);
+
+       printf("<FORM METHOD=POST>\n");
+       printf("<p>Show all parameters?\n");
+       printf("<INPUT NAME=allparameters TYPE=checkbox VALUE=1 %s>\n",
+              allparameters?"CHECKED":"");
+
+       printf("<INPUT TYPE=submit NAME=reload VALUE=Reload>\n");
+       
+       printf("</FORM>\n");
+       
+       n = lp_numservices();
+
+       show_service(GLOBALS_SNUM, allparameters);
+       show_service(DEFAULTS_SNUM, allparameters);
+       
+       for (i=0;i<n;i++)
+               if (VALID_SNUM(i))
+                       show_service(i, allparameters);
+}
+
+
+/* load the smb.conf file into loadparm. this also does the chroot
+   to the config directory. This must be called _BEFORE_ any client
+   supplied data is parsed */
+static int load_config(void)
+{
+       static pstring servicesf = CONFIGFILE;
+       char *p;
+
+       p = strrchr(servicesf,'/');
+       if (!p) return 0;
+
+       *p = 0;
+
+       setuid(0);
+
+       if (chdir(servicesf) || chroot(servicesf)) {
+               printf("wsmbconf is not configured correctly\n");
+               return 0;
+       }
+
+       *p = '/';
+
+       if (!lp_load(p,False)) {
+               printf("<b>Can't load %s - using defaults</b><p>\n", 
+                      servicesf);
+       }
+       return 1;
+}
+
+
+static int save_reload(void)
+{
+       static pstring servicesf = CONFIGFILE;
+       char *p;
+       FILE *f;
+
+       p = strrchr(servicesf,'/');
+       if (!p) return 0;
+
+       f = fopen(p,"w");
+       if (!f) {
+               printf("failed to open %s for writing\n", servicesf);
+               return 0;
+       }
+
+       fprintf(f, "# Samba config file created using wsmbconf\n");
+
+       lp_dump(f);
+
+       fclose(f);
+
+       lp_killunused(NULL);
+
+       if (!lp_load(p,False)) {
+                printf("Can't reload %s\n", servicesf);
+                return 0;
+        }
+
+       return 1;
+}
+
+static void process_requests(void)
+{
+       char *req = cgi_variable("request");
+       char *newvalue = cgi_variable("newvalue");
+       char *parameter = cgi_variable("parameter");
+       char *service = cgi_variable("service");
+       int snum=0;
+
+       if (!req) return;
+
+       if (service) {
+               /* work out what service it is */
+               if (strcmp(service,SGLOBAL) == 0) {
+                       snum = GLOBALS_SNUM;
+               } else if (strcmp(service,SDEFAULTS) == 0) {
+                       snum = DEFAULTS_SNUM;
+               } else {
+                       snum = lp_servicenumber(service);
+                       if (snum < 0) return;
+               }
+       }
+
+       if (!newvalue)
+               newvalue = "";
+
+       if (strcmp(req,"Change") == 0) {
+               /* change the value of a parameter */
+               if (!parameter || !service) return;
+
+               lp_do_parameter(snum, parameter, newvalue); 
+       } else if (strcmp(req,"Rename") == 0) {
+               /* rename a service */
+               if (!newvalue || !service) return;
+
+               lp_rename_service(snum, newvalue);
+       } else if (strcmp(req,"Remove") == 0) {
+               /* remove a service */
+               if (!service) return;
+
+               lp_remove_service(snum);
+       } else if (strcmp(req,"Copy") == 0) {
+               /* copy a service */
+               if (!service || !newvalue) return;
+
+               lp_copy_service(snum, newvalue);
+       }
+
+       save_reload();
+}
+
+
+int main(int argc, char *argv[])
+{
+       extern FILE *dbf;
+
+       print_header();
+
+       dbf = stderr;
+
+       charset_initialise();
+
+       if (load_config()) {
+               cgi_load_variables();
+               process_requests();
+               show_services();
+       }
+       print_footer();
+       return 0;
+}
diff --git a/source3/wsmbstatus.c b/source3/wsmbstatus.c
new file mode 100644 (file)
index 0000000..2762b86
--- /dev/null
@@ -0,0 +1,87 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   html status reporting
+   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.
+*/
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+
+static void print_header(void)
+{
+       printf("Content-type: text/html\n\n");
+       printf("<HTML>\n<HEAD>\n<TITLE>smbstatus</TITLE>\n</HEAD>\n<BODY>\n\n");
+}
+
+static void print_footer(void)
+{
+       printf("\n</BODY>\n</HTML>\n");
+}
+
+static void show_connections(void)
+{
+       static pstring servicesf = CONFIGFILE;
+       pstring fname;
+       FILE *f;
+       struct connect_record crec;
+
+       if (!lp_load(servicesf,False)) {
+               printf("Can't load %s - run testparm to debug it\n", servicesf);
+               return;
+       }
+
+       strcpy(fname,lp_lockdir());
+       standard_sub_basic(fname);
+       trim_string(fname,"","/");
+       strcat(fname,"/STATUS..LCK");
+
+       f = fopen(fname,"r");
+       if (!f) {
+               printf("Couldn't open status file %s\n",fname);
+               if (!lp_status(-1))
+                       printf("You need to have status=yes in your smb config file\n");
+               return;
+       }
+
+
+       printf("\nSamba version %s\n<p>",VERSION);
+
+       while (!feof(f)) {
+               if (fread(&crec,sizeof(crec),1,f) != 1)
+                       break;
+               if (crec.magic == 0x280267 && process_exists(crec.pid)) {
+                       printf("%-10.10s   %-8s %-8s %5d   %-8s (%s) %s<br>",
+                              crec.name,uidtoname(crec.uid),
+                              gidtoname(crec.gid),crec.pid,
+                              crec.machine,crec.addr,
+                              asctime(LocalTime(&crec.start)));
+               }
+       }
+       fclose(f);
+}
+
+int main(int argc, char *argv[])
+{
+       print_header();
+       show_connections();
+       print_footer();
+       return 0;
+}