1/*
2   Unix SMB/CIFS implementation.
3   Samba Web Administration Tool
4   Version 3.0.0
5   Copyright (C) Andrew Tridgell 1997-2002
6   Copyright (C) John H Terpstra 2002
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23/**
24 * @defgroup swat SWAT - Samba Web Administration Tool
25 * @{
26 * @file swat.c
27 *
28 * @brief Samba Web Administration Tool.
29 **/
30
31#include "includes.h"
32#include "web/swat_proto.h"
33
34static BOOL demo_mode = False;
35static BOOL passwd_only = False;
36static BOOL have_write_access = False;
37static BOOL have_read_access = False;
38static int iNumNonAutoPrintServices = 0;
39
40/*
41 * Password Management Globals
42 */
43#define SWAT_USER "username"
44#define OLD_PSWD "old_passwd"
45#define NEW_PSWD "new_passwd"
46#define NEW2_PSWD "new2_passwd"
47#define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
48#define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
49#define ADD_USER_FLAG "add_user_flag"
50#define DELETE_USER_FLAG "delete_user_flag"
51#define DISABLE_USER_FLAG "disable_user_flag"
52#define ENABLE_USER_FLAG "enable_user_flag"
53#define RHOST "remote_host"
54
55
56/****************************************************************************
57****************************************************************************/
58static int enum_index(int value, const struct enum_list *enumlist)
59{
60	int i;
61	for (i=0;enumlist[i].name;i++)
62		if (value == enumlist[i].value) break;
63	return(i);
64}
65
66static char *fix_backslash(const char *str)
67{
68	static char newstring[1024];
69	char *p = newstring;
70
71        while (*str) {
72                if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
73                else *p++ = *str;
74                ++str;
75        }
76	*p = '\0';
77	return newstring;
78}
79
80static char *stripspaceupper(const char *str)
81{
82	static char newstring[1024];
83	char *p = newstring;
84
85	while (*str) {
86		if (*str != ' ') *p++ = toupper(*str);
87		++str;
88	}
89	*p = '\0';
90	return newstring;
91}
92
93static char *make_parm_name(const char *label)
94{
95	static char parmname[1024];
96	char *p = parmname;
97
98	while (*label) {
99		if (*label == ' ') *p++ = '_';
100		else *p++ = *label;
101		++label;
102	}
103	*p = '\0';
104	return parmname;
105}
106
107/****************************************************************************
108  include a lump of html in a page
109****************************************************************************/
110static int include_html(const char *fname)
111{
112	int fd;
113	char buf[1024];
114	int ret;
115
116	fd = web_open(fname, O_RDONLY, 0);
117
118	if (fd == -1) {
119		printf(_("ERROR: Can't open %s"), fname);
120		printf("\n");
121		return 0;
122	}
123
124	while ((ret = read(fd, buf, sizeof(buf))) > 0) {
125		write(1, buf, ret);
126	}
127
128	close(fd);
129	return 1;
130}
131
132/****************************************************************************
133  start the page with standard stuff
134****************************************************************************/
135static void print_header(void)
136{
137	if (!cgi_waspost()) {
138		printf("Expires: 0\r\n");
139	}
140	printf("Content-type: text/html\r\n\r\n");
141
142	if (!include_html("include/header.html")) {
143		printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
144		printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
145	}
146}
147
148/* *******************************************************************
149   show parameter label with translated name in the following form
150   because showing original and translated label in one line looks
151   too long, and showing translated label only is unusable for
152   heavy users.
153   -------------------------------
154   HELP       security   [combo box][button]
155   SECURITY
156   -------------------------------
157   (capital words are translated by gettext.)
158   if no translation is available, then same form as original is
159   used.
160   "i18n_translated_parm" class is used to change the color of the
161   translated parameter with CSS.
162   **************************************************************** */
163static const char* get_parm_translated(
164	const char* pAnchor, const char* pHelp, const char* pLabel)
165{
166	const char* pTranslated = _(pLabel);
167	static pstring output;
168	if(strcmp(pLabel, pTranslated) != 0)
169	{
170		pstr_sprintf(output,
171		  "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s <br><span class=\"i18n_translated_parm\">%s</span>",
172		   pAnchor, pHelp, pLabel, pTranslated);
173		return output;
174	}
175	pstr_sprintf(output,
176	  "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
177	  pAnchor, pHelp, pLabel);
178	return output;
179}
180/****************************************************************************
181 finish off the page
182****************************************************************************/
183static void print_footer(void)
184{
185	if (!include_html("include/footer.html")) {
186		printf("\n</BODY>\n</HTML>\n");
187	}
188}
189
190/****************************************************************************
191  display one editable parameter in a form
192****************************************************************************/
193static void show_parameter(int snum, struct parm_struct *parm)
194{
195	int i;
196	void *ptr = parm->ptr;
197	char *utf8_s1, *utf8_s2;
198
199	if (parm->class == P_LOCAL && snum >= 0) {
200		ptr = lp_local_ptr(snum, ptr);
201	}
202
203	printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label));
204	switch (parm->type) {
205	case P_CHAR:
206		printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
207		       make_parm_name(parm->label), *(char *)ptr);
208		printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
209			_("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
210		break;
211
212	case P_LIST:
213		printf("<input type=text size=40 name=\"parm_%s\" value=\"",
214			make_parm_name(parm->label));
215		if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
216			char **list = *(char ***)ptr;
217			for (;*list;list++) {
218				/* enclose in quotes if the string contains a space */
219				if ( strchr_m(*list, ' ') ) {
220					push_utf8_allocate(&utf8_s1, *list);
221					push_utf8_allocate(&utf8_s2, ((*(list+1))?", ":""));
222					printf("\'%s\'%s", utf8_s1, utf8_s2);
223				} else {
224					push_utf8_allocate(&utf8_s1, *list);
225					push_utf8_allocate(&utf8_s2, ((*(list+1))?", ":""));
226					printf("%s%s", utf8_s1, utf8_s2);
227				}
228				SAFE_FREE(utf8_s1);
229				SAFE_FREE(utf8_s2);
230			}
231		}
232		printf("\">");
233		printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
234			_("Set Default"), make_parm_name(parm->label));
235		if (parm->def.lvalue) {
236			char **list = (char **)(parm->def.lvalue);
237			for (; *list; list++) {
238				/* enclose in quotes if the string contains a space */
239				if ( strchr_m(*list, ' ') )
240					printf("\'%s\'%s", *list, ((*(list+1))?", ":""));
241				else
242					printf("%s%s", *list, ((*(list+1))?", ":""));
243			}
244		}
245		printf("\'\">");
246		break;
247
248	case P_STRING:
249	case P_USTRING:
250		push_utf8_allocate(&utf8_s1, *(char **)ptr);
251		printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
252		       make_parm_name(parm->label), utf8_s1);
253		SAFE_FREE(utf8_s1);
254		printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
255			_("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
256		break;
257
258	case P_GSTRING:
259	case P_UGSTRING:
260		push_utf8_allocate(&utf8_s1, (char *)ptr);
261		printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
262		       make_parm_name(parm->label), utf8_s1);
263		SAFE_FREE(utf8_s1);
264		printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
265			_("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
266		break;
267
268	case P_BOOL:
269		printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
270		printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
271		printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
272		printf("</select>");
273		printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
274			_("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?0:1);
275		break;
276
277	case P_BOOLREV:
278		printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
279		printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
280		printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
281		printf("</select>");
282		printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
283			_("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?1:0);
284		break;
285
286	case P_INTEGER:
287		printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
288		printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
289			_("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
290		break;
291
292	case P_OCTAL:
293		printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
294		printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
295		       _("Set Default"), make_parm_name(parm->label),
296		       octal_string((int)(parm->def.ivalue)));
297		break;
298
299	case P_ENUM:
300		printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
301		for (i=0;parm->enum_list[i].name;i++) {
302			if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
303				printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
304			}
305		}
306		printf("</select>");
307		printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
308			_("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
309		break;
310	case P_SEP:
311		break;
312	}
313	printf("</td></tr>\n");
314}
315
316/****************************************************************************
317  display a set of parameters for a service
318****************************************************************************/
319static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
320{
321	int i = 0;
322	struct parm_struct *parm;
323	const char *heading = NULL;
324	const char *last_heading = NULL;
325
326	while ((parm = lp_next_parameter(snum, &i, allparameters))) {
327		if (snum < 0 && parm->class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
328			continue;
329		if (parm->class == P_SEPARATOR) {
330			heading = parm->label;
331			continue;
332		}
333		if (parm->flags & FLAG_HIDE) continue;
334		if (snum >= 0) {
335			if (printers & !(parm->flags & FLAG_PRINT)) continue;
336			if (!printers & !(parm->flags & FLAG_SHARE)) continue;
337		}
338
339		if (!( parm_filter & FLAG_ADVANCED )) {
340			if (!(parm->flags & FLAG_BASIC)) {
341					void *ptr = parm->ptr;
342
343				if (parm->class == P_LOCAL && snum >= 0) {
344					ptr = lp_local_ptr(snum, ptr);
345				}
346
347				switch (parm->type) {
348				case P_CHAR:
349					if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
350					break;
351
352				case P_LIST:
353					if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
354					break;
355
356				case P_STRING:
357				case P_USTRING:
358					if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
359					break;
360
361				case P_GSTRING:
362				case P_UGSTRING:
363					if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
364					break;
365
366				case P_BOOL:
367				case P_BOOLREV:
368					if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
369					break;
370
371				case P_INTEGER:
372				case P_OCTAL:
373					if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
374					break;
375
376
377				case P_ENUM:
378					if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
379					break;
380				case P_SEP:
381					continue;
382					}
383			}
384			if (printers && !(parm->flags & FLAG_PRINT)) continue;
385		}
386
387		if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
388
389		if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
390
391		if (heading && heading != last_heading) {
392			printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
393			last_heading = heading;
394		}
395		show_parameter(snum, parm);
396	}
397}
398
399/****************************************************************************
400  load the smb.conf file into loadparm.
401****************************************************************************/
402static BOOL load_config(BOOL save_def)
403{
404	lp_resetnumservices();
405	return lp_load(dyn_CONFIGFILE,False,save_def,False);
406}
407
408/****************************************************************************
409  write a config file
410****************************************************************************/
411static void write_config(FILE *f, BOOL show_defaults)
412{
413	fprintf(f, "# Samba config file created using SWAT\n");
414	fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
415	fprintf(f, "# Date: %s\n\n", timestring(False));
416
417	lp_dump(f, show_defaults, iNumNonAutoPrintServices);
418}
419
420/****************************************************************************
421  save and reload the smb.conf config file
422****************************************************************************/
423static int save_reload(int snum)
424{
425	FILE *f;
426	struct stat st;
427
428	f = sys_fopen(dyn_CONFIGFILE,"w");
429	if (!f) {
430		printf(_("failed to open %s for writing"), dyn_CONFIGFILE);
431		printf("\n");
432		return 0;
433	}
434
435	/* just in case they have used the buggy xinetd to create the file */
436	if (fstat(fileno(f), &st) == 0 &&
437	    (st.st_mode & S_IWOTH)) {
438#if defined HAVE_FCHMOD
439		fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
440#else
441		chmod(dyn_CONFIGFILE, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
442#endif
443	}
444
445	write_config(f, False);
446	if (snum)
447		lp_dump_one(f, False, snum);
448	fclose(f);
449
450	lp_killunused(NULL);
451
452	if (!load_config(False)) {
453                printf(_("Can't reload %s"), dyn_CONFIGFILE);
454		printf("\n");
455                return 0;
456        }
457	iNumNonAutoPrintServices = lp_numservices();
458	load_printers();
459
460	return 1;
461}
462
463/****************************************************************************
464  commit one parameter
465****************************************************************************/
466static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
467{
468	int i;
469	char *s;
470
471	if (snum < 0 && parm->class == P_LOCAL) {
472		/* this handles the case where we are changing a local
473		   variable globally. We need to change the parameter in
474		   all shares where it is currently set to the default */
475		for (i=0;i<lp_numservices();i++) {
476			s = lp_servicename(i);
477			if (s && (*s) && lp_is_default(i, parm)) {
478				lp_do_parameter(i, parm->label, v);
479			}
480		}
481	}
482
483	lp_do_parameter(snum, parm->label, v);
484}
485
486/****************************************************************************
487  commit a set of parameters for a service
488****************************************************************************/
489static void commit_parameters(int snum)
490{
491	int i = 0;
492	struct parm_struct *parm;
493	pstring label;
494	const char *v;
495
496	while ((parm = lp_next_parameter(snum, &i, 1))) {
497		slprintf(label, sizeof(label)-1, "parm_%s", make_parm_name(parm->label));
498		if ((v = cgi_variable(label))) {
499			if (parm->flags & FLAG_HIDE) continue;
500			commit_parameter(snum, parm, v);
501		}
502	}
503}
504
505/****************************************************************************
506  spit out the html for a link with an image
507****************************************************************************/
508static void image_link(const char *name, const char *hlink, const char *src)
509{
510	printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
511	       cgi_baseurl(), hlink, src, name);
512}
513
514/****************************************************************************
515  display the main navigation controls at the top of each page along
516  with a title
517****************************************************************************/
518static void show_main_buttons(void)
519{
520	char *p;
521
522	if ((p = cgi_user_name()) && strcmp(p, "root")) {
523		printf(_("Logged in as <b>%s</b>"), p);
524		printf("<p>\n");
525	}
526
527	image_link(_("Home"), "", "images/home.gif");
528	if (have_write_access) {
529		image_link(_("Globals"), "globals", "images/globals.gif");
530		image_link(_("Shares"), "shares", "images/shares.gif");
531		image_link(_("Printers"), "printers", "images/printers.gif");
532		image_link(_("Wizard"), "wizard", "images/wizard.gif");
533	}
534   /* root always gets all buttons, otherwise look for -P */
535	if ( have_write_access || (!passwd_only && have_read_access) ) {
536		image_link(_("Status"), "status", "images/status.gif");
537		image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
538	}
539	image_link(_("Password Management"), "passwd", "images/passwd.gif");
540
541	printf("<HR>\n");
542}
543
544/****************************************************************************
545 * Handle Display/Edit Mode CGI
546 ****************************************************************************/
547static void ViewModeBoxes(int mode)
548{
549	printf("<p>%s:&nbsp;\n", _("Current View Is"));
550	printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
551	printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
552	printf("<br>%s:&nbsp;\n", _("Change View To"));
553	printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
554	printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
555	printf("</p><br>\n");
556}
557
558/****************************************************************************
559  display a welcome page
560****************************************************************************/
561static void welcome_page(void)
562{
563	include_html("help/welcome.html");
564}
565
566/****************************************************************************
567  display the current smb.conf
568****************************************************************************/
569static void viewconfig_page(void)
570{
571	int full_view=0;
572
573	if (cgi_variable("full_view")) {
574		full_view = 1;
575	}
576
577	printf("<H2>%s</H2>\n", _("Current Config"));
578	printf("<form method=post>\n");
579
580	if (full_view) {
581		printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
582	} else {
583		printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
584	}
585
586	printf("<p><pre>");
587	write_config(stdout, full_view);
588	printf("</pre>");
589	printf("</form>\n");
590}
591
592/****************************************************************************
593  second screen of the wizard ... Fetch Configuration Parameters
594****************************************************************************/
595static void wizard_params_page(void)
596{
597	unsigned int parm_filter = FLAG_WIZARD;
598
599	/* Here we first set and commit all the parameters that were selected
600 	   in the previous screen. */
601
602	printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
603
604	if (cgi_variable("Commit")) {
605		commit_parameters(GLOBAL_SECTION_SNUM);
606		save_reload(0);
607	}
608
609	printf("<form name=\"swatform\" method=post action=wizard_params>\n");
610
611	if (have_write_access) {
612		printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
613	}
614
615	printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
616	printf("<p>\n");
617
618	printf("<table>\n");
619	show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
620	printf("</table>\n");
621	printf("</form>\n");
622}
623
624/****************************************************************************
625  Utility to just rewrite the smb.conf file - effectively just cleans it up
626****************************************************************************/
627static void rewritecfg_file(void)
628{
629	commit_parameters(GLOBAL_SECTION_SNUM);
630	save_reload(0);
631	printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
632}
633
634/****************************************************************************
635  wizard to create/modify the smb.conf file
636****************************************************************************/
637static void wizard_page(void)
638{
639	/* Set some variables to collect data from smb.conf */
640	int role = 0;
641	int winstype = 0;
642	int have_home = -1;
643	int HomeExpo = 0;
644	int SerType = 0;
645
646	if (cgi_variable("Rewrite")) {
647		(void) rewritecfg_file();
648		return;
649	}
650
651	if (cgi_variable("GetWizardParams")){
652		(void) wizard_params_page();
653		return;
654	}
655
656	if (cgi_variable("Commit")){
657		SerType = atoi(cgi_variable("ServerType"));
658		winstype = atoi(cgi_variable("WINSType"));
659		have_home = lp_servicenumber(HOMES_NAME);
660		HomeExpo = atoi(cgi_variable("HomeExpo"));
661
662		/* Plain text passwords are too badly broken - use encrypted passwords only */
663		lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
664
665		switch ( SerType ){
666			case 0:
667				/* Stand-alone Server */
668				lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
669				lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
670				break;
671			case 1:
672				/* Domain Member */
673				lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
674				lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
675				break;
676			case 2:
677				/* Domain Controller */
678				lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
679				lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
680				break;
681		}
682		switch ( winstype ) {
683			case 0:
684				lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
685				lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
686				break;
687			case 1:
688				lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
689				lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
690				break;
691			case 2:
692				lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
693				lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable("WINSAddr"));
694				break;
695		}
696
697		/* Have to create Homes share? */
698		if ((HomeExpo == 1) && (have_home == -1)) {
699			pstring unix_share;
700
701			pstrcpy(unix_share,HOMES_NAME);
702			load_config(False);
703			lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
704			iNumNonAutoPrintServices = lp_numservices();
705			have_home = lp_servicenumber(HOMES_NAME);
706			lp_do_parameter( have_home, "read only", "No");
707			lp_do_parameter( have_home, "valid users", "%S");
708			lp_do_parameter( have_home, "browseable", "No");
709			commit_parameters(have_home);
710		}
711
712		/* Need to Delete Homes share? */
713		if ((HomeExpo == 0) && (have_home != -1)) {
714			lp_remove_service(have_home);
715			have_home = -1;
716		}
717
718		commit_parameters(GLOBAL_SECTION_SNUM);
719		save_reload(0);
720	}
721	else
722	{
723		/* Now determine smb.conf WINS settings */
724		if (lp_wins_support())
725			winstype = 1;
726		if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
727 		        winstype = 2;
728
729
730		/* Do we have a homes share? */
731		have_home = lp_servicenumber(HOMES_NAME);
732	}
733	if ((winstype == 2) && lp_wins_support())
734		winstype = 3;
735
736	role = lp_server_role();
737
738	/* Here we go ... */
739	printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
740	printf("<form method=post action=wizard>\n");
741
742	if (have_write_access) {
743		printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
744		printf("%s", _("The same will happen if you press the commit button."));
745		printf("<br><br>\n");
746		printf("<center>");
747		printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
748		printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
749		printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
750		printf("</center>\n");
751	}
752
753	printf("<hr>");
754	printf("<center><table border=0>");
755	printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
756	printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
757	printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
758	printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
759	printf("</tr>\n");
760	if (role == ROLE_DOMAIN_BDC) {
761		printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
762	}
763	printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
764	printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
765	printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
766	printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
767	printf("</tr>\n");
768	printf("<tr><td></td><td></td><td></td><td>%s&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
769
770	/* Print out the list of wins servers */
771	if(lp_wins_server_list()) {
772		int i;
773		const char **wins_servers = lp_wins_server_list();
774		for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
775	}
776
777	printf("\"></td></tr>\n");
778	if (winstype == 3) {
779		printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Error: WINS Server Mode and WINS Support both set in smb.conf"));
780		printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
781	}
782	printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
783	printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
784	printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
785	printf("<td></td></tr>\n");
786
787	/* Enable this when we are ready ....
788	 * printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
789	 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
790	 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
791	 * printf("<td></td></tr>\n");
792	 */
793
794	printf("</table></center>");
795	printf("<hr>");
796
797	printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
798	printf("</form>\n");
799}
800
801
802/****************************************************************************
803  display a globals editing page
804****************************************************************************/
805static void globals_page(void)
806{
807	unsigned int parm_filter = FLAG_BASIC;
808	int mode = 0;
809
810	printf("<H2>%s</H2>\n", _("Global Parameters"));
811
812	if (cgi_variable("Commit")) {
813		commit_parameters(GLOBAL_SECTION_SNUM);
814		save_reload(0);
815	}
816
817	if ( cgi_variable("ViewMode") )
818		mode = atoi(cgi_variable("ViewMode"));
819	if ( cgi_variable("BasicMode"))
820		mode = 0;
821	if ( cgi_variable("AdvMode"))
822		mode = 1;
823
824	printf("<form name=\"swatform\" method=post action=globals>\n");
825
826	ViewModeBoxes( mode );
827	switch ( mode ) {
828		case 0:
829			parm_filter = FLAG_BASIC;
830			break;
831		case 1:
832			parm_filter = FLAG_ADVANCED;
833			break;
834	}
835	printf("<br>\n");
836	if (have_write_access) {
837		printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
838			_("Commit Changes"));
839	}
840
841	printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
842		 _("Reset Values"));
843
844	printf("<p>\n");
845	printf("<table>\n");
846	show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
847	printf("</table>\n");
848	printf("</form>\n");
849}
850
851/****************************************************************************
852  display a shares editing page. share is in unix codepage,
853****************************************************************************/
854static void shares_page(void)
855{
856	const char *share = cgi_variable("share");
857	char *s;
858	char *utf8_s;
859	int snum = -1;
860	int i;
861	int mode = 0;
862	unsigned int parm_filter = FLAG_BASIC;
863
864	if (share)
865		snum = lp_servicenumber(share);
866
867	printf("<H2>%s</H2>\n", _("Share Parameters"));
868
869	if (cgi_variable("Commit") && snum >= 0) {
870		commit_parameters(snum);
871		save_reload(0);
872	}
873
874	if (cgi_variable("Delete") && snum >= 0) {
875		lp_remove_service(snum);
876		save_reload(0);
877		share = NULL;
878		snum = -1;
879	}
880
881	if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
882		load_config(False);
883		lp_copy_service(GLOBAL_SECTION_SNUM, share);
884		iNumNonAutoPrintServices = lp_numservices();
885		save_reload(0);
886		snum = lp_servicenumber(share);
887	}
888
889	printf("<FORM name=\"swatform\" method=post>\n");
890
891	printf("<table>\n");
892
893	if ( cgi_variable("ViewMode") )
894		mode = atoi(cgi_variable("ViewMode"));
895	if ( cgi_variable("BasicMode"))
896		mode = 0;
897	if ( cgi_variable("AdvMode"))
898		mode = 1;
899
900	ViewModeBoxes( mode );
901	switch ( mode ) {
902		case 0:
903			parm_filter = FLAG_BASIC;
904			break;
905		case 1:
906			parm_filter = FLAG_ADVANCED;
907			break;
908	}
909	printf("<br><tr>\n");
910	printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
911	printf("<td><select name=share>\n");
912	if (snum < 0)
913		printf("<option value=\" \"> \n");
914	for (i=0;i<lp_numservices();i++) {
915		s = lp_servicename(i);
916		if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
917			push_utf8_allocate(&utf8_s, s);
918			printf("<option %s value=\"%s\">%s\n",
919			       (share && strcmp(share,s)==0)?"SELECTED":"",
920			       utf8_s, utf8_s);
921			SAFE_FREE(utf8_s);
922
923		}
924	}
925	printf("</select></td>\n");
926	if (have_write_access) {
927		printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
928	}
929	printf("</tr>\n");
930	printf("</table>");
931	printf("<table>");
932	if (have_write_access) {
933		printf("<tr>\n");
934		printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
935		printf("<td><input type=text size=30 name=newshare></td></tr>\n");
936	}
937	printf("</table>");
938
939
940	if (snum >= 0) {
941		if (have_write_access) {
942			printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
943		}
944
945		printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
946		printf("<p>\n");
947	}
948
949	if (snum >= 0) {
950		printf("<table>\n");
951		show_parameters(snum, 1, parm_filter, 0);
952		printf("</table>\n");
953	}
954
955	printf("</FORM>\n");
956}
957
958/*************************************************************
959change a password either locally or remotely
960*************************************************************/
961static BOOL change_password(const char *remote_machine, const char *user_name,
962			    const char *old_passwd, const char *new_passwd,
963				int local_flags)
964{
965	BOOL ret = False;
966	pstring err_str;
967	pstring msg_str;
968
969	if (demo_mode) {
970		printf("%s\n<p>", _("password change in demo mode rejected"));
971		return False;
972	}
973
974	if (remote_machine != NULL) {
975		ret = remote_password_change(remote_machine, user_name, old_passwd,
976									 new_passwd, err_str, sizeof(err_str));
977		if(*err_str)
978			printf("%s\n<p>", err_str);
979		return ret;
980	}
981
982	if(!initialize_password_db(True)) {
983		printf("%s\n<p>", _("Can't setup password database vectors."));
984		return False;
985	}
986
987	ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
988					 msg_str, sizeof(msg_str));
989
990	if(*msg_str)
991		printf("%s\n<p>", msg_str);
992	if(*err_str)
993		printf("%s\n<p>", err_str);
994
995	return ret;
996}
997
998/****************************************************************************
999  do the stuff required to add or change a password
1000****************************************************************************/
1001static void chg_passwd(void)
1002{
1003	const char *host;
1004	BOOL rslt;
1005	int local_flags = 0;
1006
1007	/* Make sure users name has been specified */
1008	if (strlen(cgi_variable(SWAT_USER)) == 0) {
1009		printf("<p>%s\n", _(" Must specify \"User Name\" "));
1010		return;
1011	}
1012
1013	/*
1014	 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1015	 * so if that's what we're doing, skip the rest of the checks
1016	 */
1017	if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1018
1019		/*
1020		 * If current user is not root, make sure old password has been specified
1021		 * If REMOTE change, even root must provide old password
1022		 */
1023		if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
1024		    ((cgi_variable(CHG_R_PASSWD_FLAG)) &&  (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
1025			printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1026			return;
1027		}
1028
1029		/* If changing a users password on a remote hosts we have to know what host */
1030		if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
1031			printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1032			return;
1033		}
1034
1035		/* Make sure new passwords have been specified */
1036		if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
1037		    (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
1038			printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1039			return;
1040		}
1041
1042		/* Make sure new passwords was typed correctly twice */
1043		if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
1044			printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1045			return;
1046		}
1047	}
1048
1049	if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1050		host = cgi_variable(RHOST);
1051	} else if (am_root()) {
1052		host = NULL;
1053	} else {
1054		host = "127.0.0.1";
1055	}
1056
1057	/*
1058	 * Set up the local flags.
1059	 */
1060
1061	local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1062	local_flags |= (cgi_variable(ADD_USER_FLAG) ?  LOCAL_SET_PASSWORD : 0);
1063	local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1064	local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1065	local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1066	local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1067
1068
1069	rslt = change_password(host,
1070			       cgi_variable(SWAT_USER),
1071			       cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
1072				   local_flags);
1073
1074	if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1075		printf("<p>");
1076		if (rslt == True) {
1077			printf(_(" The passwd for '%s' has been changed."), cgi_variable(SWAT_USER));
1078			printf("\n");
1079		} else {
1080			printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable(SWAT_USER));
1081			printf("\n");
1082		}
1083	}
1084
1085	return;
1086}
1087
1088/****************************************************************************
1089  display a password editing page
1090****************************************************************************/
1091static void passwd_page(void)
1092{
1093	const char *new_name = cgi_user_name();
1094
1095	/*
1096	 * After the first time through here be nice. If the user
1097	 * changed the User box text to another users name, remember it.
1098	 */
1099	if (cgi_variable(SWAT_USER)) {
1100		new_name = cgi_variable(SWAT_USER);
1101	}
1102
1103	if (!new_name) new_name = "";
1104
1105	printf("<H2>%s</H2>\n", _("Server Password Management"));
1106
1107	printf("<FORM name=\"swatform\" method=post>\n");
1108
1109	printf("<table>\n");
1110
1111	/*
1112	 * Create all the dialog boxes for data collection
1113	 */
1114	printf("<tr><td> %s : </td>\n", _("User Name"));
1115	printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1116	if (!am_root()) {
1117		printf("<tr><td> %s : </td>\n", _("Old Password"));
1118		printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1119	}
1120	printf("<tr><td> %s : </td>\n", _("New Password"));
1121	printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1122	printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1123	printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1124	printf("</table>\n");
1125
1126	/*
1127	 * Create all the control buttons for requesting action
1128	 */
1129	printf("<input type=submit name=%s value=\"%s\">\n",
1130	       CHG_S_PASSWD_FLAG, _("Change Password"));
1131	if (demo_mode || am_root()) {
1132		printf("<input type=submit name=%s value=\"%s\">\n",
1133		       ADD_USER_FLAG, _("Add New User"));
1134		printf("<input type=submit name=%s value=\"%s\">\n",
1135		       DELETE_USER_FLAG, _("Delete User"));
1136		printf("<input type=submit name=%s value=\"%s\">\n",
1137		       DISABLE_USER_FLAG, _("Disable User"));
1138		printf("<input type=submit name=%s value=\"%s\">\n",
1139		       ENABLE_USER_FLAG, _("Enable User"));
1140	}
1141	printf("<p></FORM>\n");
1142
1143	/*
1144	 * Do some work if change, add, disable or enable was
1145	 * requested. It could be this is the first time through this
1146	 * code, so there isn't anything to do.  */
1147	if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1148	    (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1149		chg_passwd();
1150	}
1151
1152	printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1153
1154	printf("<FORM name=\"swatform\" method=post>\n");
1155
1156	printf("<table>\n");
1157
1158	/*
1159	 * Create all the dialog boxes for data collection
1160	 */
1161	printf("<tr><td> %s : </td>\n", _("User Name"));
1162	printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1163	printf("<tr><td> %s : </td>\n", _("Old Password"));
1164	printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1165	printf("<tr><td> %s : </td>\n", _("New Password"));
1166	printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1167	printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1168	printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1169	printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1170	printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1171
1172	printf("</table>");
1173
1174	/*
1175	 * Create all the control buttons for requesting action
1176	 */
1177	printf("<input type=submit name=%s value=\"%s\">",
1178	       CHG_R_PASSWD_FLAG, _("Change Password"));
1179
1180	printf("<p></FORM>\n");
1181
1182	/*
1183	 * Do some work if a request has been made to change the
1184	 * password somewhere other than the server. It could be this
1185	 * is the first time through this code, so there isn't
1186	 * anything to do.  */
1187	if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1188		chg_passwd();
1189	}
1190
1191}
1192
1193/****************************************************************************
1194  display a printers editing page
1195****************************************************************************/
1196static void printers_page(void)
1197{
1198	const char *share = cgi_variable("share");
1199	char *s;
1200	int snum=-1;
1201	int i;
1202	int mode = 0;
1203	unsigned int parm_filter = FLAG_BASIC;
1204
1205	if (share)
1206		snum = lp_servicenumber(share);
1207
1208        printf("<H2>%s</H2>\n", _("Printer Parameters"));
1209
1210        printf("<H3>%s</H3>\n", _("Important Note:"));
1211        printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1212        printf(_("are autoloaded printers from "));
1213        printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1214        printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1215
1216	if (cgi_variable("Commit") && snum >= 0) {
1217		commit_parameters(snum);
1218		if (snum >= iNumNonAutoPrintServices)
1219		    save_reload(snum);
1220		else
1221		    save_reload(0);
1222	}
1223
1224	if (cgi_variable("Delete") && snum >= 0) {
1225		lp_remove_service(snum);
1226		save_reload(0);
1227		share = NULL;
1228		snum = -1;
1229	}
1230
1231	if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1232		load_config(False);
1233		lp_copy_service(GLOBAL_SECTION_SNUM, share);
1234		iNumNonAutoPrintServices = lp_numservices();
1235		snum = lp_servicenumber(share);
1236		lp_do_parameter(snum, "print ok", "Yes");
1237		save_reload(0);
1238		snum = lp_servicenumber(share);
1239	}
1240
1241	printf("<FORM name=\"swatform\" method=post>\n");
1242
1243	if ( cgi_variable("ViewMode") )
1244		mode = atoi(cgi_variable("ViewMode"));
1245        if ( cgi_variable("BasicMode"))
1246                mode = 0;
1247        if ( cgi_variable("AdvMode"))
1248                mode = 1;
1249
1250	ViewModeBoxes( mode );
1251	switch ( mode ) {
1252		case 0:
1253			parm_filter = FLAG_BASIC;
1254			break;
1255		case 1:
1256			parm_filter = FLAG_ADVANCED;
1257			break;
1258	}
1259	printf("<table>\n");
1260	printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1261	printf("<td><select name=\"share\">\n");
1262	if (snum < 0 || !lp_print_ok(snum))
1263		printf("<option value=\" \"> \n");
1264	for (i=0;i<lp_numservices();i++) {
1265		s = lp_servicename(i);
1266		if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1267                    if (i >= iNumNonAutoPrintServices)
1268                        printf("<option %s value=\"%s\">[*]%s\n",
1269                               (share && strcmp(share,s)==0)?"SELECTED":"",
1270                               s, s);
1271                    else
1272			printf("<option %s value=\"%s\">%s\n",
1273			       (share && strcmp(share,s)==0)?"SELECTED":"",
1274			       s, s);
1275		}
1276	}
1277	printf("</select></td>");
1278	if (have_write_access) {
1279		printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1280	}
1281	printf("</tr>");
1282	printf("</table>\n");
1283
1284	if (have_write_access) {
1285		printf("<table>\n");
1286		printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1287		printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1288		printf("</table>");
1289	}
1290
1291
1292	if (snum >= 0) {
1293		if (have_write_access) {
1294			printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1295		}
1296		printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1297		printf("<p>\n");
1298	}
1299
1300	if (snum >= 0) {
1301		printf("<table>\n");
1302		show_parameters(snum, 1, parm_filter, 1);
1303		printf("</table>\n");
1304	}
1305	printf("</FORM>\n");
1306}
1307
1308
1309/**
1310 * main function for SWAT.
1311 **/
1312 int main(int argc, char *argv[])
1313{
1314	int opt;
1315	const char *page;
1316	poptContext pc;
1317	struct poptOption long_options[] = {
1318		POPT_AUTOHELP
1319		{ "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1320        { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1321		POPT_COMMON_SAMBA
1322		POPT_TABLEEND
1323	};
1324
1325	fault_setup(NULL);
1326	umask(S_IWGRP | S_IWOTH);
1327
1328#if defined(HAVE_SET_AUTH_PARAMETERS)
1329	set_auth_parameters(argc, argv);
1330#endif /* HAVE_SET_AUTH_PARAMETERS */
1331
1332	/* just in case it goes wild ... */
1333	alarm(300);
1334
1335	setlinebuf(stdout);
1336
1337	/* we don't want any SIGPIPE messages */
1338	BlockSignals(True,SIGPIPE);
1339
1340	dbf = x_fopen("/dev/null", O_WRONLY, 0);
1341	if (!dbf) dbf = x_stderr;
1342
1343	/* we don't want stderr screwing us up */
1344	close(2);
1345	open("/dev/null", O_WRONLY);
1346
1347	pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1348
1349	/* Parse command line options */
1350
1351	while((opt = poptGetNextOpt(pc)) != -1) { }
1352
1353	poptFreeContext(pc);
1354
1355	setup_logging(argv[0],False);
1356	load_config(True);
1357	iNumNonAutoPrintServices = lp_numservices();
1358	load_printers();
1359
1360	cgi_setup(dyn_SWATDIR, !demo_mode);
1361
1362	print_header();
1363
1364	cgi_load_variables();
1365
1366	if (!file_exist(dyn_CONFIGFILE, NULL)) {
1367		have_read_access = True;
1368		have_write_access = True;
1369	} else {
1370		/* check if the authenticated user has write access - if not then
1371		   don't show write options */
1372		have_write_access = (access(dyn_CONFIGFILE,W_OK) == 0);
1373
1374		/* if the user doesn't have read access to smb.conf then
1375		   don't let them view it */
1376		have_read_access = (access(dyn_CONFIGFILE,R_OK) == 0);
1377	}
1378
1379	show_main_buttons();
1380
1381	page = cgi_pathinfo();
1382
1383	/* Root gets full functionality */
1384	if (have_read_access && strcmp(page, "globals")==0) {
1385		globals_page();
1386	} else if (have_read_access && strcmp(page,"shares")==0) {
1387		shares_page();
1388	} else if (have_read_access && strcmp(page,"printers")==0) {
1389		printers_page();
1390	} else if (have_read_access && strcmp(page,"status")==0) {
1391		status_page();
1392	} else if (have_read_access && strcmp(page,"viewconfig")==0) {
1393		viewconfig_page();
1394	} else if (strcmp(page,"passwd")==0) {
1395		passwd_page();
1396	} else if (have_read_access && strcmp(page,"wizard")==0) {
1397		wizard_page();
1398	} else if (have_read_access && strcmp(page,"wizard_params")==0) {
1399		wizard_params_page();
1400	} else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1401		rewritecfg_file();
1402	} else {
1403		welcome_page();
1404	}
1405
1406	print_footer();
1407	return 0;
1408}
1409
1410/** @} **/
1411