clitar.c: #ifdef'ed out all the bits that were giving 'defined but not used'
[ira/wip.git] / source3 / web / swat.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Samba Web Administration Tool
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 -1
30
31 static pstring servicesf = CONFIGFILE;
32
33
34 /* we need these because we link to locking*.o */
35  void become_root(BOOL save_dir) {}
36  void unbecome_root(BOOL restore_dir) {}
37 /* We need this because we link to password.o */
38 BOOL change_oem_password(struct smb_passwd *smbpw, char *new_passwd, BOOL override) {return False;}
39 connection_struct Connections[MAX_CONNECTIONS];
40 files_struct Files[MAX_OPEN_FILES];
41 struct current_user current_user;
42
43 static int enum_index(int value, struct enum_list *enumlist)
44 {
45 int i;
46         for (i=0;enumlist[i].name;i++)
47                 if (value == enumlist[i].value) break;
48         return(i);
49 }
50
51 static char *fix_backslash(char *str)
52 {
53 static char newstring[1024];
54 char *p = newstring;
55
56         *p = '\0';
57         while (*str) {
58                 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
59                 else *p++ = *str;
60                 ++str;
61                 *p = '\0';
62         }
63         return newstring;
64 }
65
66 static char *make_parm_name(char *label)
67 {
68 static char parmname[1024];
69 char *p = parmname;
70
71         while (*label) {
72                 if (*label == ' ') *p++ = '_';
73                 else *p++ = *label;
74                 ++label;
75                 *p = '\0';
76         }
77         return parmname;
78 }
79
80 /* start the page with standard stuff */
81 static void print_header(void)
82 {
83         if (!cgi_waspost()) {
84                 printf("Expires: 0\r\n");
85         }
86         printf("Content-type: text/html\r\n\r\n");
87         printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
88         printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"%simages/background.jpg\">\n\n", cgi_rooturl());
89 }
90
91
92 /* finish off the page */
93 static void print_footer(void)
94 {
95         printf("\n</BODY>\n</HTML>\n");
96 }
97
98 /* include a lump of html in a page */
99 static void include_html(char *fname)
100 {
101         FILE *f = fopen(fname,"r");
102         char buf[1024];
103         int ret;
104
105         if (!f) {
106                 printf("ERROR: Can't open %s\n", fname);
107                 return;
108         }
109
110         while (!feof(f)) {
111                 ret = fread(buf, 1, sizeof(buf), f);
112                 if (ret <= 0) break;
113                 fwrite(buf, 1, ret, stdout);
114         }
115
116         fclose(f);
117 }
118
119
120 /* display one editable parameter in a form */
121 static void show_parameter(int snum, struct parm_struct *parm)
122 {
123         int i;
124         void *ptr = parm->ptr;
125
126         if (parm->class == P_LOCAL && snum >= 0) {
127                 ptr = lp_local_ptr(snum, ptr);
128         }
129
130         printf("<tr><td><A HREF=\"%shelp/parameters.html#%s\">?</A> %s</td><td>", 
131                cgi_rooturl(), parm->label, parm->label);
132
133         switch (parm->type) {
134         case P_CHAR:
135                 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
136                        make_parm_name(parm->label), *(char *)ptr);
137                 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
138                         make_parm_name(parm->label),(char)(parm->def.cvalue));
139                 break;
140
141         case P_STRING:
142         case P_USTRING:
143                 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
144                        make_parm_name(parm->label), *(char **)ptr);
145                 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
146                         make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
147                 break;
148
149         case P_GSTRING:
150         case P_UGSTRING:
151                 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
152                        make_parm_name(parm->label), (char *)ptr);
153                 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
154                         make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
155                 break;
156
157         case P_BOOL:
158                 printf("<select name=\"parm_%s\">",make_parm_name(parm->label)); 
159                 printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
160                 printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
161                 printf("</select>");
162                 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
163                         make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?0:1);
164                 break;
165
166         case P_BOOLREV:
167                 printf("<select name=\"parm_%s\">",make_parm_name(parm->label)); 
168                 printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
169                 printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
170                 printf("</select>");
171                 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
172                         make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?1:0);
173                 break;
174
175         case P_INTEGER:
176                 printf("<input type=text size=8 name=\"parm_%s\" value=%d>", make_parm_name(parm->label), *(int *)ptr);
177                 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
178                         make_parm_name(parm->label),(int)(parm->def.ivalue));
179                 break;
180
181         case P_OCTAL:
182                 printf("<input type=text size=8 name=\"parm_%s\" value=0%o>", make_parm_name(parm->label), *(int *)ptr);
183                 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'0%o\'\">",
184                         make_parm_name(parm->label),(int)(parm->def.ivalue));
185                 break;
186
187         case P_ENUM:
188                 printf("<select name=\"parm_%s\">",make_parm_name(parm->label)); 
189                 for (i=0;parm->enum_list[i].name;i++)
190                         printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
191                 printf("</select>");
192                 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
193                         make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
194                 break;
195         case P_SEP:
196                 break;
197         }
198         printf("</td></tr>\n");
199 }
200
201 /* display a set of parameters for a service */
202 static void show_parameters(int snum, int allparameters, int advanced, int printers)
203 {
204         int i = 0;
205         struct parm_struct *parm;
206         char *heading = NULL;
207         char *last_heading = NULL;
208
209         while ((parm = lp_next_parameter(snum, &i, allparameters))) {
210                 if (snum < 0 && parm->class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
211                         continue;
212                 if (parm->class == P_SEPARATOR) {
213                         heading = parm->label;
214                         continue;
215                 }
216                 if (parm->flags & FLAG_HIDE) continue;
217                 if (!advanced) {
218                         if (!printers && !(parm->flags & FLAG_BASIC)) {
219                                 void *ptr = parm->ptr;
220
221                                 switch (parm->type) {
222                                 case P_CHAR:
223                                         if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
224                                         break;
225
226                                 case P_STRING:
227                                 case P_USTRING:
228                                         if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
229                                         break;
230
231                                 case P_GSTRING:
232                                 case P_UGSTRING:
233                                         if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
234                                         break;
235
236                                 case P_BOOL:
237                                 case P_BOOLREV:
238                                         if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
239                                         break;
240
241                                 case P_INTEGER:
242                                 case P_OCTAL:
243                                         if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
244                                         break;
245
246
247                                 case P_ENUM:
248                                         if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
249                                         break;
250                                 case P_SEP:
251                                         continue;
252                                 }
253                         }
254                         if (printers && !(parm->flags & FLAG_PRINT)) continue;
255                 }
256                 if (heading && heading != last_heading) {
257                         printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", heading);
258                         last_heading = heading;
259                 }
260                 show_parameter(snum, parm);
261         }
262 }
263
264
265 /* write a config file */
266 static void write_config(FILE *f, BOOL show_defaults)
267 {
268         fprintf(f, "# Samba config file created using SWAT\n");
269         fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
270         fprintf(f, "# Date: %s\n\n", timestring());
271         
272         lp_dump(f, show_defaults);      
273 }
274
275
276 /* save and reoad the smb.conf config file */
277 static int save_reload(void)
278 {
279         FILE *f;
280
281         f = fopen(servicesf,"w");
282         if (!f) {
283                 printf("failed to open %s for writing\n", servicesf);
284                 return 0;
285         }
286
287         write_config(f, False);
288         fclose(f);
289
290         lp_killunused(NULL);
291
292         if (!lp_load(servicesf,False,False,False)) {
293                 printf("Can't reload %s\n", servicesf);
294                 return 0;
295         }
296
297         return 1;
298 }
299
300
301
302 /* commit one parameter */
303 static void commit_parameter(int snum, struct parm_struct *parm, char *v)
304 {
305         int i;
306         char *s;
307
308         if (snum < 0 && parm->class == P_LOCAL) {
309                 /* this handles the case where we are changing a local
310                    variable globally. We need to change the parameter in 
311                    all shares where it is currently set to the default */
312                 for (i=0;i<lp_numservices();i++) {
313                         s = lp_servicename(i);
314                         if (s && (*s) && lp_is_default(i, parm)) {
315                                 lp_do_parameter(i, parm->label, v);
316                         }
317                 }
318         }
319
320         lp_do_parameter(snum, parm->label, v);
321 }
322
323 /* commit a set of parameters for a service */
324 static void commit_parameters(int snum)
325 {
326         int i = 0;
327         struct parm_struct *parm;
328         pstring label;
329         char *v;
330
331         while ((parm = lp_next_parameter(snum, &i, 1))) {
332                 sprintf(label, "parm_%s", make_parm_name(parm->label));
333                 if ((v = cgi_variable(label))) {
334                         if (parm->flags & FLAG_HIDE) continue;
335                         commit_parameter(snum, parm, v); 
336                 }
337         }
338 }
339
340
341 /* load the smb.conf file into loadparm. */
342 static void load_config(void)
343 {
344         if (!lp_load(servicesf,False,True,False)) {
345                 printf("<b>Can't load %s - using defaults</b><p>\n", 
346                        servicesf);
347         }
348 }
349
350 /* spit out the html for a link with an image */
351 static void image_link(char *name,char *hlink, char *src, int width, int height)
352 {
353         printf("<A HREF=\"%s/%s\"><img width=%d height=%d src=\"%s%s\" alt=\"%s\"></A>\n", 
354                cgi_baseurl(),
355                hlink, width, height, 
356                cgi_rooturl(),
357                src, name);
358 }
359
360 /* display the main navigation controls at the top of each page along
361    with a title */
362 static void show_main_buttons(void)
363 {
364         printf("<H2 align=center>Samba Web Administration Tool</H2>\n");
365
366         image_link("Home", "", "images/home.gif", 50, 50);
367         image_link("Globals", "globals", "images/globals.gif", 50, 50);
368         image_link("Shares", "shares", "images/shares.gif", 50, 50);
369         image_link("Printers", "printers", "images/printers.gif", 50, 50);
370         image_link("Status", "status", "images/status.gif", 50, 50);
371         image_link("View Config", "viewconfig", "images/viewconfig.gif", 50, 50);
372
373         printf("<HR>\n");
374 }
375
376 /* display a welcome page  */
377 static void welcome_page(void)
378 {
379         include_html("help/welcome.html");
380 }
381
382
383 /* display the current smb.conf  */
384 static void viewconfig_page(void)
385 {
386         int full_view=0;
387
388         if (cgi_variable("full_view")) {
389                 full_view = 1;
390         }
391
392         printf("<H2>Current Config</H2>\n");
393         printf("<form method=post>\n");
394
395         if (full_view) {
396                 printf("<input type=submit name=\"normal_view\" value=\"Normal View\">\n");
397         } else {
398                 printf("<input type=submit name=\"full_view\" value=\"Full View\">\n");
399         }
400
401         printf("<p><pre>");
402         write_config(stdout, full_view);
403         printf("</pre>");
404         printf("</form>\n");
405 }
406
407
408 /* display a globals editing page  */
409 static void globals_page(void)
410 {
411         int advanced = 0;
412
413         printf("<H2>Global Variables</H2>\n");
414
415         if (cgi_variable("Advanced") && !cgi_variable("Basic"))
416                 advanced = 1;
417
418         if (cgi_variable("Commit")) {
419                 commit_parameters(GLOBALS_SNUM);
420                 save_reload();
421         }
422
423         printf("<FORM name=\"swatform\" method=post>\n");
424
425         printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
426         printf("<input type=reset name=\"Reset Values\" value=\"Reset Values\">\n");
427         if (advanced == 0) {
428                 printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
429         } else {
430                 printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
431         }
432         printf("<p>\n");
433         
434         printf("<table>\n");
435         show_parameters(GLOBALS_SNUM, 1, advanced, 0);
436         printf("</table>\n");
437
438         if (advanced) {
439                 printf("<input type=hidden name=\"Advanced\" value=1>\n");
440         }
441
442         printf("</FORM>\n");
443 }
444
445 /* display a shares editing page  */
446 static void shares_page(void)
447 {
448         char *share = cgi_variable("share");
449         char *s;
450         int snum=-1;
451         int i;
452         int advanced = 0;
453
454         if (share)
455                 snum = lp_servicenumber(share);
456
457         printf("<H2>Share Parameters</H2>\n");
458
459         if (cgi_variable("Advanced") && !cgi_variable("Basic"))
460                 advanced = 1;
461
462         if (cgi_variable("Commit") && snum >= 0) {
463                 commit_parameters(snum);
464                 save_reload();
465         }
466
467         if (cgi_variable("Delete") && snum >= 0) {
468                 lp_remove_service(snum);
469                 save_reload();
470                 share = NULL;
471                 snum = -1;
472         }
473
474         if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
475                 lp_copy_service(GLOBALS_SNUM, share);
476                 save_reload();
477                 snum = lp_servicenumber(share);
478         }
479
480         printf("<FORM name=\"swatform\" method=post>\n");
481
482         printf("<table>\n");
483         printf("<tr><td><input type=submit name=selectshare value=\"Choose Share\"></td>\n");
484         printf("<td><select name=share>\n");
485         if (snum < 0)
486                 printf("<option value=\" \"> \n");
487         for (i=0;i<lp_numservices();i++) {
488                 s = lp_servicename(i);
489                 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
490                         printf("<option %s value=\"%s\">%s\n", 
491                                (share && strcmp(share,s)==0)?"SELECTED":"",
492                                s, s);
493                 }
494         }
495         printf("</select></td></tr><p>");
496
497         printf("<tr><td><input type=submit name=createshare value=\"Create Share\"></td>\n");
498         printf("<td><input type=text size=30 name=newshare></td></tr>\n");
499         printf("</table>");
500
501
502         if (snum >= 0) {
503                 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
504                 printf("<input type=submit name=\"Delete\" value=\"Delete Share\">\n");
505                 if (advanced == 0) {
506                         printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
507                 } else {
508                         printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
509                 }
510                 printf("<p>\n");
511         }
512
513         if (snum >= 0) {
514                 printf("<table>\n");
515                 show_parameters(snum, 1, advanced, 0);
516                 printf("</table>\n");
517         }
518
519         if (advanced) {
520                 printf("<input type=hidden name=\"Advanced\" value=1>\n");
521         }
522
523         printf("</FORM>\n");
524 }
525
526
527 /* display a printers editing page  */
528 static void printers_page(void)
529 {
530         char *share = cgi_variable("share");
531         char *s;
532         int snum=-1;
533         int i;
534         int advanced = 0;
535
536         if (share)
537                 snum = lp_servicenumber(share);
538
539         printf("<H2>Printer Parameters</H2>\n");
540
541         if (cgi_variable("Advanced") && !cgi_variable("Basic"))
542                 advanced = 1;
543
544         if (cgi_variable("Commit") && snum >= 0) {
545                 commit_parameters(snum);
546                 save_reload();
547         }
548
549         if (cgi_variable("Delete") && snum >= 0) {
550                 lp_remove_service(snum);
551                 save_reload();
552                 share = NULL;
553                 snum = -1;
554         }
555
556         if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
557                 lp_copy_service(GLOBALS_SNUM, share);
558                 snum = lp_servicenumber(share);
559                 lp_do_parameter(snum, "print ok", "Yes");
560                 save_reload();
561                 snum = lp_servicenumber(share);
562         }
563
564         printf("<FORM name=\"swatform\" method=post>\n");
565
566         printf("<table>\n");
567         printf("<tr><td><input type=submit name=selectshare value=\"Choose Printer\"></td>\n");
568         printf("<td><select name=share>\n");
569         if (snum < 0 || !lp_print_ok(snum))
570                 printf("<option value=\" \"> \n");
571         for (i=0;i<lp_numservices();i++) {
572                 s = lp_servicename(i);
573                 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
574                         printf("<option %s value=\"%s\">%s\n", 
575                                (share && strcmp(share,s)==0)?"SELECTED":"",
576                                s, s);
577                 }
578         }
579         printf("</select></td></tr><p>");
580
581         printf("<tr><td><input type=submit name=createshare value=\"Create Printer\"></td>\n");
582         printf("<td><input type=text size=30 name=newshare></td></tr>\n");
583         printf("</table>");
584
585
586         if (snum >= 0) {
587                 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
588                 printf("<input type=submit name=\"Delete\" value=\"Delete Printer\">\n");
589                 if (advanced == 0) {
590                         printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
591                 } else {
592                         printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
593                 }
594                 printf("<p>\n");
595         }
596
597         if (snum >= 0) {
598                 printf("<table>\n");
599                 show_parameters(snum, 1, advanced, 1);
600                 printf("</table>\n");
601         }
602
603         if (advanced) {
604                 printf("<input type=hidden name=\"Advanced\" value=1>\n");
605         }
606
607         printf("</FORM>\n");
608 }
609
610
611
612 int main(int argc, char *argv[])
613 {
614         extern char *optarg;
615         extern int optind;
616         extern FILE *dbf;
617         int opt;
618         char *page;
619         int auth_required = 1;
620
621         /* just in case it goes wild ... */
622         alarm(300);
623
624         dbf = fopen("/dev/null", "w");
625
626         if (!dbf) dbf = stderr;
627
628         while ((opt = getopt(argc, argv,"s:a")) != EOF) {
629                 switch (opt) {
630                 case 's':
631                         pstrcpy(servicesf,optarg);
632                         break;    
633                 case 'a':
634                         auth_required = 0;
635                         break;    
636                 }
637         }
638
639         cgi_setup(SWATDIR, auth_required);
640
641         print_header();
642         
643         charset_initialise();
644
645         /* if this binary is setuid then run completely as root */
646         setuid(0);
647
648         load_config();
649
650         cgi_load_variables(NULL);
651
652         show_main_buttons();
653
654         page = cgi_pathinfo();
655
656         if (strcmp(page, "globals")==0) {
657                 globals_page();
658         } else if (strcmp(page,"shares")==0) {
659                 shares_page();
660         } else if (strcmp(page,"printers")==0) {
661                 printers_page();
662         } else if (strcmp(page,"status")==0) {
663                 status_page();
664         } else if (strcmp(page,"viewconfig")==0) {
665                 viewconfig_page();
666         } else {
667                 welcome_page();
668         }
669         
670         print_footer();
671         return 0;
672 }
673
674