508c8944b4000595f7ff540b8db57fe3e98c9d43
[samba.git] / source3 / web / swat.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    html smb.conf editing - prototype only
5    Copyright (C) Andrew Tridgell 1997-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #ifdef SYSLOG
23 #undef SYSLOG
24 #endif
25
26 #include "includes.h"
27 #include "smb.h"
28
29 #define GLOBALS_SNUM -2
30 #define DEFAULTS_SNUM -1
31
32 static pstring servicesf = CONFIGFILE;
33
34
35 /* start the page with standard stuff */
36 static void print_header(void)
37 {
38         printf("Content-type: text/html\r\n\r\n");
39         printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
40         printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY>\n\n");
41 }
42
43
44 /* finish off the page */
45 static void print_footer(void)
46 {
47         printf("\n</BODY>\n</HTML>\n");
48 }
49
50 /* include a lump of html in a page */
51 static void include_html(char *fname)
52 {
53         FILE *f = fopen(fname,"r");
54         char buf[1024];
55         int ret;
56
57         if (!f) {
58                 printf("ERROR: Can't open %s\n", fname);
59                 return;
60         }
61
62         while (!feof(f)) {
63                 ret = fread(buf, 1, sizeof(buf), f);
64                 if (ret <= 0) break;
65                 fwrite(buf, 1, ret, stdout);
66         }
67
68         fclose(f);
69 }
70
71
72 /* display one editable parameter */
73 static void show_parameter(int snum, struct parm_struct *parm)
74 {
75         int i;
76         void *ptr = parm->ptr;
77
78         if (parm->class == P_LOCAL) {
79                 ptr = lp_local_ptr(snum, ptr);
80         }
81
82         printf("<tr><td><A HREF=\"help/parameters.html#%s\">?</A> %s</td><td>", 
83                parm->label, parm->label);
84
85         switch (parm->type) {
86         case P_CHAR:
87                 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
88                        parm->label, *(char *)ptr);
89                 break;
90
91         case P_STRING:
92         case P_USTRING:
93                 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
94                        parm->label, *(char **)ptr);
95                 break;
96
97         case P_GSTRING:
98         case P_UGSTRING:
99                 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
100                        parm->label, (char *)ptr);
101                 break;
102
103         case P_BOOL:
104                 printf("<input type=radio name=\"parm_%s\" value=Yes %s>yes&nbsp;&nbsp;", parm->label, (*(BOOL *)ptr)?"CHECKED":"");
105                 printf("<input type=radio name=\"parm_%s\" value=No %s>no", parm->label, (*(BOOL *)ptr)?"":"CHECKED");
106                 break;
107
108         case P_BOOLREV:
109                 printf("<input type=radio name=\"parm_%s\" value=Yes %s>yes&nbsp;&nbsp;", parm->label, (*(BOOL *)ptr)?"":"CHECKED");
110                 printf("<input type=radio name=\"parm_%s\" value=No %s>no", parm->label, (*(BOOL *)ptr)?"CHECKED":"");
111                 break;
112
113         case P_INTEGER:
114                 printf("<input type=text size=8 name=\"parm_%s\" value=%d>", parm->label, *(int *)ptr);
115                 break;
116
117         case P_OCTAL:
118                 printf("<input type=text size=8 name=\"parm_%s\" value=0%o>", parm->label, *(int *)ptr);
119                 break;
120
121         case P_ENUM:
122                 for (i=0;parm->enum_list[i].name;i++)
123                         printf("<input type=radio name=\"parm_%s\" value=%s %s>%s&nbsp;&nbsp;", 
124                                parm->label, parm->enum_list[i].name, 
125                                (*(int *)ptr)==parm->enum_list[i].value?"CHECKED":"", 
126                                parm->enum_list[i].name);
127                 break;
128                         
129         }
130         printf("</td></tr>\n");
131 }
132
133 /* display a set of parameters for a service */
134 static void show_parameters(int snum, int allparameters, int advanced, int printers)
135 {
136         int i = 0;
137         struct parm_struct *parm;
138
139         printf("<table>\n");
140
141         while ((parm = lp_next_parameter(snum, &i, allparameters))) {
142                 if (parm->flags & FLAG_HIDE) continue;
143                 if (!advanced) {
144                         if (!printers && !(parm->flags & FLAG_BASIC)) continue;
145                         if (printers && !(parm->flags & FLAG_PRINT)) continue;
146                 }
147                 show_parameter(snum, parm);
148         }
149         printf("</table>\n");
150 }
151
152
153 static int save_reload(void)
154 {
155         FILE *f;
156
157         f = fopen(servicesf,"w");
158         if (!f) {
159                 printf("failed to open %s for writing\n", servicesf);
160                 return 0;
161         }
162
163         fprintf(f, "# Samba config file created using SWAT\n");
164
165         lp_dump(f);
166
167         fclose(f);
168
169         lp_killunused(NULL);
170
171         if (!lp_load(servicesf,False)) {
172                 printf("Can't reload %s\n", servicesf);
173                 return 0;
174         }
175
176         return 1;
177 }
178
179
180
181 /* commit a set of parameters for a service */
182 static void commit_parameters(int snum)
183 {
184         int i = 0;
185         struct parm_struct *parm;
186         pstring label;
187         char *v;
188
189         while ((parm = lp_next_parameter(snum, &i, 1))) {
190                 sprintf(label, "parm_%s", parm->label);
191                 if ((v = cgi_variable(label))) {
192                         lp_do_parameter(snum, parm->label, v); 
193                 }
194         }
195
196         save_reload();
197 }
198
199
200 /* load the smb.conf file into loadparm. */
201 static void load_config(void)
202 {
203         if (!lp_load(servicesf,False)) {
204                 printf("<b>Can't load %s - using defaults</b><p>\n", 
205                        servicesf);
206         }
207 }
208
209 /* spit out the html for a link with an image */
210 static void image_link(char *name,char *hlink, char *src, int width, int height)
211 {
212         printf("<A HREF=\"%s\"><img width=%d height=%d src=\"%s\" alt=\"%s\"></A>\n", hlink, width, height, src, name);
213 }
214
215 /* display the main navigation controls at the top of each page along
216    with a title */
217 static void show_main_buttons(void)
218 {
219         printf("<H2 align=center>Samba Web Administration Tool</H2>\n");
220
221         image_link("Globals", "globals", "images/globals.gif", 50, 50);
222         image_link("Shares", "shares", "images/shares.gif", 50, 50);
223         image_link("Printers", "printers", "images/printers.gif", 50, 50);
224
225         printf("<HR>\n");
226 }
227
228 /* display a welcome page  */
229 static void welcome_page(void)
230 {
231         include_html("help/welcome.html");
232 }
233
234
235 /* display a globals editing page  */
236 static void globals_page(void)
237 {
238         int advanced = 0;
239
240         printf("<H2>Global Variables</H2>\n");
241
242         if (cgi_variable("Advanced") && !cgi_variable("Basic"))
243                 advanced = 1;
244
245         if (cgi_variable("Commit")) {
246                 commit_parameters(GLOBALS_SNUM);
247         }
248
249         printf("<FORM method=post>\n");
250
251         printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
252         if (advanced == 0) {
253                 printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
254         } else {
255                 printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
256         }
257         printf("<p>\n");
258         
259         show_parameters(GLOBALS_SNUM, 1, advanced, 0);
260
261         if (advanced) {
262                 printf("<input type=hidden name=\"Advanced\" value=1>\n");
263         }
264
265         printf("</form>\n");
266 }
267
268 /* display a shares editing page  */
269 static void shares_page(void)
270 {
271         char *share = cgi_variable("share");
272         char *s;
273         int snum=-1;
274         int i;
275         int advanced = 0;
276
277         if (share)
278                 snum = lp_servicenumber(share);
279
280         printf("<H2>Share Parameters</H2>\n");
281
282         if (cgi_variable("Advanced") && !cgi_variable("Basic"))
283                 advanced = 1;
284
285         if (cgi_variable("Commit") && snum >= 0) {
286                 commit_parameters(snum);
287         }
288
289         if (cgi_variable("Delete") && snum >= 0) {
290                 lp_remove_service(snum);
291                 save_reload();
292                 share = NULL;
293                 snum = -1;
294         }
295
296         if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
297                 lp_copy_service(DEFAULTS_SNUM, share);
298                 save_reload();
299                 snum = lp_servicenumber(share);
300         }
301
302         printf("<FORM method=post>\n");
303
304         printf("<table>\n");
305         printf("<tr><td><input type=submit name=selectshare value=\"Choose Share\"></td>\n");
306         printf("<td><select name=share>\n");
307         if (snum < 0)
308                 printf("<option value=\" \"> \n");
309         for (i=0;i<lp_numservices();i++) {
310                 s = lp_servicename(i);
311                 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
312                         printf("<option %s value=\"%s\">%s\n", 
313                                (share && strcmp(share,s)==0)?"SELECTED":"",
314                                s, s);
315                 }
316         }
317         printf("</select></td></tr><p>");
318
319         printf("<tr><td><input type=submit name=createshare value=\"Create Share\"></td>\n");
320         printf("<td><input type=text size=30 name=newshare></td></tr>\n");
321         printf("</table>");
322
323
324         if (snum >= 0) {
325                 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
326                 printf("<input type=submit name=\"Delete\" value=\"Delete Share\">\n");
327                 if (advanced == 0) {
328                         printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
329                 } else {
330                         printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
331                 }
332                 printf("<p>\n");
333         }
334
335         if (snum >= 0) {
336                 show_parameters(snum, 1, advanced, 0);
337         }
338
339         if (advanced) {
340                 printf("<input type=hidden name=\"Advanced\" value=1>\n");
341         }
342
343         printf("</FORM>\n");
344 }
345
346
347 /* display a printers editing page  */
348 static void printers_page(void)
349 {
350         char *share = cgi_variable("share");
351         char *s;
352         int snum=-1;
353         int i;
354         int advanced = 0;
355
356         if (share)
357                 snum = lp_servicenumber(share);
358
359         printf("<H2>Printer Parameters</H2>\n");
360
361         if (cgi_variable("Advanced") && !cgi_variable("Basic"))
362                 advanced = 1;
363
364         if (cgi_variable("Commit") && snum >= 0) {
365                 commit_parameters(snum);
366         }
367
368         if (cgi_variable("Delete") && snum >= 0) {
369                 lp_remove_service(snum);
370                 save_reload();
371                 share = NULL;
372                 snum = -1;
373         }
374
375         if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
376                 lp_copy_service(DEFAULTS_SNUM, share);
377                 snum = lp_servicenumber(share);
378                 lp_do_parameter(snum, "print ok", "Yes");
379                 save_reload();
380                 snum = lp_servicenumber(share);
381         }
382
383         printf("<FORM method=post>\n");
384
385         printf("<table>\n");
386         printf("<tr><td><input type=submit name=selectshare value=\"Choose Printer\"></td>\n");
387         printf("<td><select name=share>\n");
388         if (snum < 0 || !lp_print_ok(snum))
389                 printf("<option value=\" \"> \n");
390         for (i=0;i<lp_numservices();i++) {
391                 s = lp_servicename(i);
392                 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
393                         printf("<option %s value=\"%s\">%s\n", 
394                                (share && strcmp(share,s)==0)?"SELECTED":"",
395                                s, s);
396                 }
397         }
398         printf("</select></td></tr><p>");
399
400         printf("<tr><td><input type=submit name=createshare value=\"Create Printer\"></td>\n");
401         printf("<td><input type=text size=30 name=newshare></td></tr>\n");
402         printf("</table>");
403
404
405         if (snum >= 0) {
406                 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
407                 printf("<input type=submit name=\"Delete\" value=\"Delete Printer\">\n");
408                 if (advanced == 0) {
409                         printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
410                 } else {
411                         printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
412                 }
413                 printf("<p>\n");
414         }
415
416         if (snum >= 0) {
417                 show_parameters(snum, 1, advanced, 1);
418         }
419
420         if (advanced) {
421                 printf("<input type=hidden name=\"Advanced\" value=1>\n");
422         }
423
424         printf("</FORM>\n");
425 }
426
427
428 int main(int argc, char *argv[])
429 {
430         extern char *optarg;
431         extern int optind;
432         extern FILE *dbf;
433         int opt;
434         char *page;
435         int auth_required = 1;
436
437         /* just in case it goes wild ... */
438         alarm(300);
439
440         dbf = fopen("/dev/null", "w");
441
442         if (!dbf) dbf = stderr;
443
444         while ((opt = getopt(argc, argv,"s:a")) != EOF) {
445                 switch (opt) {
446                 case 's':
447                         pstrcpy(servicesf,optarg);
448                         break;    
449                 case 'a':
450                         auth_required = 0;
451                         break;    
452                 }
453         }
454
455         cgi_setup(SWATDIR, auth_required);
456
457         print_header();
458
459         charset_initialise();
460
461         /* if this binary is setuid then run completely as root */
462         setuid(0);
463
464         load_config();
465
466         cgi_load_variables(NULL);
467
468         show_main_buttons();
469
470         page = cgi_baseurl();
471
472         if (strcmp(page, "globals")==0) {
473                 globals_page();
474         } else if (strcmp(page,"shares")==0) {
475                 shares_page();
476         } else if (strcmp(page,"printers")==0) {
477                 printers_page();
478         } else {
479                 welcome_page();
480         }
481         
482         print_footer();
483         return 0;
484 }
485
486