s3 swat: Fix possible XSS attack (bug #8289)
[Samba.git] / source3 / web / swat.c
blob6e8789806689d242c3231fb960b2f29ec6a306cc
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
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 3 of the License, or
11 (at your option) any later version.
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.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 /**
23 * @defgroup swat SWAT - Samba Web Administration Tool
24 * @{
25 * @file swat.c
27 * @brief Samba Web Administration Tool.
28 **/
30 #include "includes.h"
31 #include "system/filesys.h"
32 #include "popt_common.h"
33 #include "web/swat_proto.h"
34 #include "printing/pcap.h"
35 #include "printing/load.h"
36 #include "passdb.h"
37 #include "intl/lang_tdb.h"
39 static int demo_mode = False;
40 static int passwd_only = False;
41 static bool have_write_access = False;
42 static bool have_read_access = False;
43 static int iNumNonAutoPrintServices = 0;
46 * Password Management Globals
48 #define SWAT_USER "username"
49 #define OLD_PSWD "old_passwd"
50 #define NEW_PSWD "new_passwd"
51 #define NEW2_PSWD "new2_passwd"
52 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
53 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
54 #define ADD_USER_FLAG "add_user_flag"
55 #define DELETE_USER_FLAG "delete_user_flag"
56 #define DISABLE_USER_FLAG "disable_user_flag"
57 #define ENABLE_USER_FLAG "enable_user_flag"
58 #define RHOST "remote_host"
60 #define _(x) lang_msg_rotate(talloc_tos(),x)
62 /****************************************************************************
63 ****************************************************************************/
64 static int enum_index(int value, const struct enum_list *enumlist)
66 int i;
67 for (i=0;enumlist[i].name;i++)
68 if (value == enumlist[i].value) break;
69 return(i);
72 static char *fix_backslash(const char *str)
74 static char newstring[1024];
75 char *p = newstring;
77 while (*str) {
78 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
79 else *p++ = *str;
80 ++str;
82 *p = '\0';
83 return newstring;
86 static const char *fix_quotes(TALLOC_CTX *ctx, const char *str)
88 char *newstring = NULL;
89 char *p = NULL;
90 size_t newstring_len;
91 int quote_len = strlen("&quot;");
93 /* Count the number of quotes. */
94 newstring_len = 1;
95 p = (char *) str;
96 while (*p) {
97 if ( *p == '\"') {
98 newstring_len += quote_len;
99 } else {
100 newstring_len++;
102 ++p;
104 newstring = TALLOC_ARRAY(ctx, char, newstring_len);
105 if (!newstring) {
106 return "";
108 for (p = newstring; *str; str++) {
109 if ( *str == '\"') {
110 strncpy( p, "&quot;", quote_len);
111 p += quote_len;
112 } else {
113 *p++ = *str;
116 *p = '\0';
117 return newstring;
120 static char *stripspaceupper(const char *str)
122 static char newstring[1024];
123 char *p = newstring;
125 while (*str) {
126 if (*str != ' ') *p++ = toupper_m(*str);
127 ++str;
129 *p = '\0';
130 return newstring;
133 static char *make_parm_name(const char *label)
135 static char parmname[1024];
136 char *p = parmname;
138 while (*label) {
139 if (*label == ' ') *p++ = '_';
140 else *p++ = *label;
141 ++label;
143 *p = '\0';
144 return parmname;
147 /****************************************************************************
148 include a lump of html in a page
149 ****************************************************************************/
150 static int include_html(const char *fname)
152 int fd;
153 char buf[1024];
154 int ret;
156 fd = web_open(fname, O_RDONLY, 0);
158 if (fd == -1) {
159 printf(_("ERROR: Can't open %s"), fname);
160 printf("\n");
161 return 0;
164 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
165 if (write(1, buf, ret) == -1) {
166 break;
170 close(fd);
171 return 1;
174 /****************************************************************************
175 start the page with standard stuff
176 ****************************************************************************/
177 static void print_header(void)
179 if (!cgi_waspost()) {
180 printf("Expires: 0\r\n");
182 printf("Content-type: text/html\r\n\r\n");
184 if (!include_html("include/header.html")) {
185 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
186 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
190 /* *******************************************************************
191 show parameter label with translated name in the following form
192 because showing original and translated label in one line looks
193 too long, and showing translated label only is unusable for
194 heavy users.
195 -------------------------------
196 HELP security [combo box][button]
197 SECURITY
198 -------------------------------
199 (capital words are translated by gettext.)
200 if no translation is available, then same form as original is
201 used.
202 "i18n_translated_parm" class is used to change the color of the
203 translated parameter with CSS.
204 **************************************************************** */
205 static const char *get_parm_translated(TALLOC_CTX *ctx,
206 const char* pAnchor, const char* pHelp, const char* pLabel)
208 const char *pTranslated = _(pLabel);
209 char *output;
210 if(strcmp(pLabel, pTranslated) != 0) {
211 output = talloc_asprintf(ctx,
212 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s <br><span class=\"i18n_translated_parm\">%s</span>",
213 pAnchor, pHelp, pLabel, pTranslated);
214 return output;
216 output = talloc_asprintf(ctx,
217 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
218 pAnchor, pHelp, pLabel);
219 return output;
221 /****************************************************************************
222 finish off the page
223 ****************************************************************************/
224 static void print_footer(void)
226 if (!include_html("include/footer.html")) {
227 printf("\n</BODY>\n</HTML>\n");
231 /****************************************************************************
232 display one editable parameter in a form
233 ****************************************************************************/
234 static void show_parameter(int snum, struct parm_struct *parm)
236 int i;
237 void *ptr = parm->ptr;
238 char *utf8_s1, *utf8_s2;
239 size_t converted_size;
240 TALLOC_CTX *ctx = talloc_stackframe();
242 if (parm->p_class == P_LOCAL && snum >= 0) {
243 ptr = lp_local_ptr_by_snum(snum, ptr);
246 printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
247 stripspaceupper(parm->label), _("Help"), parm->label));
248 switch (parm->type) {
249 case P_CHAR:
250 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
251 make_parm_name(parm->label), *(char *)ptr);
252 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
253 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
254 break;
256 case P_LIST:
257 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
258 make_parm_name(parm->label));
259 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
260 char **list = *(char ***)ptr;
261 for (;*list;list++) {
262 /* enclose in HTML encoded quotes if the string contains a space */
263 if ( strchr_m(*list, ' ') ) {
264 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
265 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
266 printf("&quot;%s&quot;%s", utf8_s1, utf8_s2);
267 } else {
268 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
269 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
270 printf("%s%s", utf8_s1, utf8_s2);
272 TALLOC_FREE(utf8_s1);
273 TALLOC_FREE(utf8_s2);
276 printf("\">");
277 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
278 _("Set Default"), make_parm_name(parm->label));
279 if (parm->def.lvalue) {
280 char **list = (char **)(parm->def.lvalue);
281 for (; *list; list++) {
282 /* enclose in HTML encoded quotes if the string contains a space */
283 if ( strchr_m(*list, ' ') )
284 printf("&quot;%s&quot;%s", *list, ((*(list+1))?", ":""));
285 else
286 printf("%s%s", *list, ((*(list+1))?", ":""));
289 printf("\'\">");
290 break;
292 case P_STRING:
293 case P_USTRING:
294 push_utf8_talloc(talloc_tos(), &utf8_s1, *(char **)ptr, &converted_size);
295 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
296 make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
297 TALLOC_FREE(utf8_s1);
298 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
299 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
300 break;
302 case P_BOOL:
303 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
304 printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
305 printf("<option %s>No", (*(bool *)ptr)?"":"selected");
306 printf("</select>");
307 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
308 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
309 break;
311 case P_BOOLREV:
312 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
313 printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
314 printf("<option %s>No", (*(bool *)ptr)?"selected":"");
315 printf("</select>");
316 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
317 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
318 break;
320 case P_INTEGER:
321 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
322 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
323 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
324 break;
326 case P_OCTAL: {
327 char *o;
328 o = octal_string(*(int *)ptr);
329 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
330 make_parm_name(parm->label), o);
331 TALLOC_FREE(o);
332 o = octal_string((int)(parm->def.ivalue));
333 printf("<input type=button value=\"%s\" "
334 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
335 _("Set Default"), make_parm_name(parm->label), o);
336 TALLOC_FREE(o);
337 break;
340 case P_ENUM:
341 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
342 for (i=0;parm->enum_list[i].name;i++) {
343 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
344 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
347 printf("</select>");
348 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
349 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
350 break;
351 case P_SEP:
352 break;
354 printf("</td></tr>\n");
355 TALLOC_FREE(ctx);
358 /****************************************************************************
359 display a set of parameters for a service
360 ****************************************************************************/
361 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
363 int i = 0;
364 struct parm_struct *parm;
365 const char *heading = NULL;
366 const char *last_heading = NULL;
368 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
369 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
370 continue;
371 if (parm->p_class == P_SEPARATOR) {
372 heading = parm->label;
373 continue;
375 if (parm->flags & FLAG_HIDE) continue;
376 if (snum >= 0) {
377 if (printers & !(parm->flags & FLAG_PRINT)) continue;
378 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
381 if (!( parm_filter & FLAG_ADVANCED )) {
382 if (!(parm->flags & FLAG_BASIC)) {
383 void *ptr = parm->ptr;
385 if (parm->p_class == P_LOCAL && snum >= 0) {
386 ptr = lp_local_ptr_by_snum(snum, ptr);
389 switch (parm->type) {
390 case P_CHAR:
391 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
392 break;
394 case P_LIST:
395 if (!str_list_equal(*(const char ***)ptr,
396 (const char **)(parm->def.lvalue))) continue;
397 break;
399 case P_STRING:
400 case P_USTRING:
401 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
402 break;
404 case P_BOOL:
405 case P_BOOLREV:
406 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
407 break;
409 case P_INTEGER:
410 case P_OCTAL:
411 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
412 break;
415 case P_ENUM:
416 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
417 break;
418 case P_SEP:
419 continue;
422 if (printers && !(parm->flags & FLAG_PRINT)) continue;
425 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
427 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
429 if (heading && heading != last_heading) {
430 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
431 last_heading = heading;
433 show_parameter(snum, parm);
437 /****************************************************************************
438 load the smb.conf file into loadparm.
439 ****************************************************************************/
440 static bool load_config(bool save_def)
442 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
445 /****************************************************************************
446 write a config file
447 ****************************************************************************/
448 static void write_config(FILE *f, bool show_defaults)
450 TALLOC_CTX *ctx = talloc_stackframe();
452 fprintf(f, "# Samba config file created using SWAT\n");
453 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
454 fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
456 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
458 TALLOC_FREE(ctx);
461 /****************************************************************************
462 save and reload the smb.conf config file
463 ****************************************************************************/
464 static int save_reload(int snum)
466 FILE *f;
467 struct stat st;
469 f = sys_fopen(get_dyn_CONFIGFILE(),"w");
470 if (!f) {
471 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
472 printf("\n");
473 return 0;
476 /* just in case they have used the buggy xinetd to create the file */
477 if (fstat(fileno(f), &st) == 0 &&
478 (st.st_mode & S_IWOTH)) {
479 #if defined HAVE_FCHMOD
480 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
481 #else
482 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
483 #endif
486 write_config(f, False);
487 if (snum >= 0)
488 lp_dump_one(f, False, snum);
489 fclose(f);
491 lp_kill_all_services();
493 if (!load_config(False)) {
494 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
495 printf("\n");
496 return 0;
498 iNumNonAutoPrintServices = lp_numservices();
499 if (pcap_cache_loaded()) {
500 load_printers(server_event_context(),
501 server_messaging_context());
504 return 1;
507 /****************************************************************************
508 commit one parameter
509 ****************************************************************************/
510 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
512 int i;
513 char *s;
515 if (snum < 0 && parm->p_class == P_LOCAL) {
516 /* this handles the case where we are changing a local
517 variable globally. We need to change the parameter in
518 all shares where it is currently set to the default */
519 for (i=0;i<lp_numservices();i++) {
520 s = lp_servicename(i);
521 if (s && (*s) && lp_is_default(i, parm)) {
522 lp_do_parameter(i, parm->label, v);
527 lp_do_parameter(snum, parm->label, v);
530 /****************************************************************************
531 commit a set of parameters for a service
532 ****************************************************************************/
533 static void commit_parameters(int snum)
535 int i = 0;
536 struct parm_struct *parm;
537 char *label;
538 const char *v;
540 while ((parm = lp_next_parameter(snum, &i, 1))) {
541 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
542 if ((v = cgi_variable(label)) != NULL) {
543 if (parm->flags & FLAG_HIDE)
544 continue;
545 commit_parameter(snum, parm, v);
547 SAFE_FREE(label);
552 /****************************************************************************
553 spit out the html for a link with an image
554 ****************************************************************************/
555 static void image_link(const char *name, const char *hlink, const char *src)
557 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
558 cgi_baseurl(), hlink, src, name);
561 /****************************************************************************
562 display the main navigation controls at the top of each page along
563 with a title
564 ****************************************************************************/
565 static void show_main_buttons(void)
567 char *p;
569 if ((p = cgi_user_name()) && strcmp(p, "root")) {
570 printf(_("Logged in as <b>%s</b>"), p);
571 printf("<p>\n");
574 image_link(_("Home"), "", "images/home.gif");
575 if (have_write_access) {
576 image_link(_("Globals"), "globals", "images/globals.gif");
577 image_link(_("Shares"), "shares", "images/shares.gif");
578 image_link(_("Printers"), "printers", "images/printers.gif");
579 image_link(_("Wizard"), "wizard", "images/wizard.gif");
581 /* root always gets all buttons, otherwise look for -P */
582 if ( have_write_access || (!passwd_only && have_read_access) ) {
583 image_link(_("Status"), "status", "images/status.gif");
584 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
586 image_link(_("Password Management"), "passwd", "images/passwd.gif");
588 printf("<HR>\n");
591 /****************************************************************************
592 * Handle Display/Edit Mode CGI
593 ****************************************************************************/
594 static void ViewModeBoxes(int mode)
596 printf("<p>%s:&nbsp;\n", _("Current View Is"));
597 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
598 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
599 printf("<br>%s:&nbsp;\n", _("Change View To"));
600 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
601 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
602 printf("</p><br>\n");
605 /****************************************************************************
606 display a welcome page
607 ****************************************************************************/
608 static void welcome_page(void)
610 if (file_exist("help/welcome.html")) {
611 include_html("help/welcome.html");
612 } else {
613 include_html("help/welcome-no-samba-doc.html");
617 /****************************************************************************
618 display the current smb.conf
619 ****************************************************************************/
620 static void viewconfig_page(void)
622 int full_view=0;
624 if (cgi_variable("full_view")) {
625 full_view = 1;
628 printf("<H2>%s</H2>\n", _("Current Config"));
629 printf("<form method=post>\n");
631 if (full_view) {
632 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
633 } else {
634 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
637 printf("<p><pre>");
638 write_config(stdout, full_view);
639 printf("</pre>");
640 printf("</form>\n");
643 /****************************************************************************
644 second screen of the wizard ... Fetch Configuration Parameters
645 ****************************************************************************/
646 static void wizard_params_page(void)
648 unsigned int parm_filter = FLAG_WIZARD;
650 /* Here we first set and commit all the parameters that were selected
651 in the previous screen. */
653 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
655 if (cgi_variable("Commit")) {
656 commit_parameters(GLOBAL_SECTION_SNUM);
657 save_reload(-1);
660 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
662 if (have_write_access) {
663 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
666 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
667 printf("<p>\n");
669 printf("<table>\n");
670 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
671 printf("</table>\n");
672 printf("</form>\n");
675 /****************************************************************************
676 Utility to just rewrite the smb.conf file - effectively just cleans it up
677 ****************************************************************************/
678 static void rewritecfg_file(void)
680 commit_parameters(GLOBAL_SECTION_SNUM);
681 save_reload(-1);
682 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
685 /****************************************************************************
686 wizard to create/modify the smb.conf file
687 ****************************************************************************/
688 static void wizard_page(void)
690 /* Set some variables to collect data from smb.conf */
691 int role = 0;
692 int winstype = 0;
693 int have_home = -1;
694 int HomeExpo = 0;
695 int SerType = 0;
697 if (cgi_variable("Rewrite")) {
698 (void) rewritecfg_file();
699 return;
702 if (cgi_variable("GetWizardParams")){
703 (void) wizard_params_page();
704 return;
707 if (cgi_variable("Commit")){
708 SerType = atoi(cgi_variable_nonull("ServerType"));
709 winstype = atoi(cgi_variable_nonull("WINSType"));
710 have_home = lp_servicenumber(HOMES_NAME);
711 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
713 /* Plain text passwords are too badly broken - use encrypted passwords only */
714 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
716 switch ( SerType ){
717 case 0:
718 /* Stand-alone Server */
719 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
720 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
721 break;
722 case 1:
723 /* Domain Member */
724 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
725 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
726 break;
727 case 2:
728 /* Domain Controller */
729 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
730 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
731 break;
733 switch ( winstype ) {
734 case 0:
735 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
736 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
737 break;
738 case 1:
739 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
740 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
741 break;
742 case 2:
743 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
744 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
745 break;
748 /* Have to create Homes share? */
749 if ((HomeExpo == 1) && (have_home == -1)) {
750 const char *unix_share = HOMES_NAME;
752 load_config(False);
753 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
754 have_home = lp_servicenumber(HOMES_NAME);
755 lp_do_parameter( have_home, "read only", "No");
756 lp_do_parameter( have_home, "valid users", "%S");
757 lp_do_parameter( have_home, "browseable", "No");
758 commit_parameters(have_home);
759 save_reload(have_home);
762 /* Need to Delete Homes share? */
763 if ((HomeExpo == 0) && (have_home != -1)) {
764 lp_remove_service(have_home);
765 have_home = -1;
768 commit_parameters(GLOBAL_SECTION_SNUM);
769 save_reload(-1);
771 else
773 /* Now determine smb.conf WINS settings */
774 if (lp_wins_support())
775 winstype = 1;
776 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
777 winstype = 2;
779 /* Do we have a homes share? */
780 have_home = lp_servicenumber(HOMES_NAME);
782 if ((winstype == 2) && lp_wins_support())
783 winstype = 3;
785 role = lp_server_role();
787 /* Here we go ... */
788 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
789 printf("<form method=post action=wizard>\n");
791 if (have_write_access) {
792 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
793 printf("%s", _("The same will happen if you press the commit button."));
794 printf("<br><br>\n");
795 printf("<center>");
796 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
797 printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
798 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
799 printf("</center>\n");
802 printf("<hr>");
803 printf("<center><table border=0>");
804 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
805 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
806 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
807 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
808 printf("</tr>\n");
809 if (role == ROLE_DOMAIN_BDC) {
810 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
812 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
813 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
814 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
815 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
816 printf("</tr>\n");
817 printf("<tr><td></td><td></td><td></td><td>%s&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
819 /* Print out the list of wins servers */
820 if(lp_wins_server_list()) {
821 int i;
822 const char **wins_servers = lp_wins_server_list();
823 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
826 printf("\"></td></tr>\n");
827 if (winstype == 3) {
828 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"));
829 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
831 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
832 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
833 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
834 printf("<td></td></tr>\n");
836 /* Enable this when we are ready ....
837 * printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
838 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
839 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
840 * printf("<td></td></tr>\n");
843 printf("</table></center>");
844 printf("<hr>");
846 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
847 printf("</form>\n");
851 /****************************************************************************
852 display a globals editing page
853 ****************************************************************************/
854 static void globals_page(void)
856 unsigned int parm_filter = FLAG_BASIC;
857 int mode = 0;
859 printf("<H2>%s</H2>\n", _("Global Parameters"));
861 if (cgi_variable("Commit")) {
862 commit_parameters(GLOBAL_SECTION_SNUM);
863 save_reload(-1);
866 if ( cgi_variable("ViewMode") )
867 mode = atoi(cgi_variable_nonull("ViewMode"));
868 if ( cgi_variable("BasicMode"))
869 mode = 0;
870 if ( cgi_variable("AdvMode"))
871 mode = 1;
873 printf("<form name=\"swatform\" method=post action=globals>\n");
875 ViewModeBoxes( mode );
876 switch ( mode ) {
877 case 0:
878 parm_filter = FLAG_BASIC;
879 break;
880 case 1:
881 parm_filter = FLAG_ADVANCED;
882 break;
884 printf("<br>\n");
885 if (have_write_access) {
886 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
887 _("Commit Changes"));
890 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
891 _("Reset Values"));
893 printf("<p>\n");
894 printf("<table>\n");
895 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
896 printf("</table>\n");
897 printf("</form>\n");
900 /****************************************************************************
901 display a shares editing page. share is in unix codepage,
902 ****************************************************************************/
903 static void shares_page(void)
905 const char *share = cgi_variable("share");
906 char *s;
907 char *utf8_s;
908 int snum = -1;
909 int i;
910 int mode = 0;
911 unsigned int parm_filter = FLAG_BASIC;
912 size_t converted_size;
914 if (share)
915 snum = lp_servicenumber(share);
917 printf("<H2>%s</H2>\n", _("Share Parameters"));
919 if (cgi_variable("Commit") && snum >= 0) {
920 commit_parameters(snum);
921 save_reload(-1);
922 snum = lp_servicenumber(share);
925 if (cgi_variable("Delete") && snum >= 0) {
926 lp_remove_service(snum);
927 save_reload(-1);
928 share = NULL;
929 snum = -1;
932 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
933 snum = lp_servicenumber(share);
934 if (snum < 0) {
935 load_config(False);
936 lp_copy_service(GLOBAL_SECTION_SNUM, share);
937 snum = lp_servicenumber(share);
938 save_reload(snum);
939 snum = lp_servicenumber(share);
943 printf("<FORM name=\"swatform\" method=post>\n");
945 printf("<table>\n");
947 if ( cgi_variable("ViewMode") )
948 mode = atoi(cgi_variable_nonull("ViewMode"));
949 if ( cgi_variable("BasicMode"))
950 mode = 0;
951 if ( cgi_variable("AdvMode"))
952 mode = 1;
954 ViewModeBoxes( mode );
955 switch ( mode ) {
956 case 0:
957 parm_filter = FLAG_BASIC;
958 break;
959 case 1:
960 parm_filter = FLAG_ADVANCED;
961 break;
963 printf("<br><tr>\n");
964 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
965 printf("<td><select name=share>\n");
966 if (snum < 0)
967 printf("<option value=\" \"> \n");
968 for (i=0;i<lp_numservices();i++) {
969 s = lp_servicename(i);
970 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
971 push_utf8_talloc(talloc_tos(), &utf8_s, s, &converted_size);
972 printf("<option %s value=\"%s\">%s\n",
973 (share && strcmp(share,s)==0)?"SELECTED":"",
974 utf8_s, utf8_s);
975 TALLOC_FREE(utf8_s);
978 printf("</select></td>\n");
979 if (have_write_access) {
980 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
982 printf("</tr>\n");
983 printf("</table>");
984 printf("<table>");
985 if (have_write_access) {
986 printf("<tr>\n");
987 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
988 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
990 printf("</table>");
993 if (snum >= 0) {
994 if (have_write_access) {
995 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
998 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
999 printf("<p>\n");
1002 if (snum >= 0) {
1003 printf("<table>\n");
1004 show_parameters(snum, 1, parm_filter, 0);
1005 printf("</table>\n");
1008 printf("</FORM>\n");
1011 /*************************************************************
1012 change a password either locally or remotely
1013 *************************************************************/
1014 static bool change_password(const char *remote_machine, const char *user_name,
1015 const char *old_passwd, const char *new_passwd,
1016 int local_flags)
1018 NTSTATUS ret;
1019 char *err_str = NULL;
1020 char *msg_str = NULL;
1022 if (demo_mode) {
1023 printf("%s\n<p>", _("password change in demo mode rejected"));
1024 return False;
1027 if (remote_machine != NULL) {
1028 ret = remote_password_change(remote_machine, user_name,
1029 old_passwd, new_passwd, &err_str);
1030 if (err_str != NULL)
1031 printf("%s\n<p>", err_str);
1032 SAFE_FREE(err_str);
1033 return NT_STATUS_IS_OK(ret);
1036 if(!initialize_password_db(True, NULL)) {
1037 printf("%s\n<p>", _("Can't setup password database vectors."));
1038 return False;
1041 ret = local_password_change(user_name, local_flags, new_passwd,
1042 &err_str, &msg_str);
1044 if(msg_str)
1045 printf("%s\n<p>", msg_str);
1046 if(err_str)
1047 printf("%s\n<p>", err_str);
1049 SAFE_FREE(msg_str);
1050 SAFE_FREE(err_str);
1051 return NT_STATUS_IS_OK(ret);
1054 /****************************************************************************
1055 do the stuff required to add or change a password
1056 ****************************************************************************/
1057 static void chg_passwd(void)
1059 const char *host;
1060 bool rslt;
1061 int local_flags = 0;
1063 /* Make sure users name has been specified */
1064 if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1065 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1066 return;
1070 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1071 * so if that's what we're doing, skip the rest of the checks
1073 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1076 * If current user is not root, make sure old password has been specified
1077 * If REMOTE change, even root must provide old password
1079 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1080 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1081 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1082 return;
1085 /* If changing a users password on a remote hosts we have to know what host */
1086 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1087 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1088 return;
1091 /* Make sure new passwords have been specified */
1092 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1093 (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1094 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1095 return;
1098 /* Make sure new passwords was typed correctly twice */
1099 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1100 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1101 return;
1105 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1106 host = cgi_variable(RHOST);
1107 } else if (am_root()) {
1108 host = NULL;
1109 } else {
1110 host = "127.0.0.1";
1114 * Set up the local flags.
1117 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1118 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1119 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1120 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1121 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1122 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1124 rslt = change_password(host,
1125 cgi_variable_nonull(SWAT_USER),
1126 cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1127 local_flags);
1129 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1130 printf("<p>");
1131 if (rslt == True) {
1132 printf("%s\n", _(" The passwd has been changed."));
1133 } else {
1134 printf("%s\n", _(" The passwd for has NOT been changed."));
1138 return;
1141 /****************************************************************************
1142 display a password editing page
1143 ****************************************************************************/
1144 static void passwd_page(void)
1146 const char *new_name = cgi_user_name();
1148 if (!new_name) new_name = "";
1150 printf("<H2>%s</H2>\n", _("Server Password Management"));
1152 printf("<FORM name=\"swatform\" method=post>\n");
1154 printf("<table>\n");
1157 * Create all the dialog boxes for data collection
1159 printf("<tr><td> %s : </td>\n", _("User Name"));
1160 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1161 if (!am_root()) {
1162 printf("<tr><td> %s : </td>\n", _("Old Password"));
1163 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("</table>\n");
1172 * Create all the control buttons for requesting action
1174 printf("<input type=submit name=%s value=\"%s\">\n",
1175 CHG_S_PASSWD_FLAG, _("Change Password"));
1176 if (demo_mode || am_root()) {
1177 printf("<input type=submit name=%s value=\"%s\">\n",
1178 ADD_USER_FLAG, _("Add New User"));
1179 printf("<input type=submit name=%s value=\"%s\">\n",
1180 DELETE_USER_FLAG, _("Delete User"));
1181 printf("<input type=submit name=%s value=\"%s\">\n",
1182 DISABLE_USER_FLAG, _("Disable User"));
1183 printf("<input type=submit name=%s value=\"%s\">\n",
1184 ENABLE_USER_FLAG, _("Enable User"));
1186 printf("<p></FORM>\n");
1189 * Do some work if change, add, disable or enable was
1190 * requested. It could be this is the first time through this
1191 * code, so there isn't anything to do. */
1192 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1193 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1194 chg_passwd();
1197 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1199 printf("<FORM name=\"swatform\" method=post>\n");
1201 printf("<table>\n");
1204 * Create all the dialog boxes for data collection
1206 printf("<tr><td> %s : </td>\n", _("User Name"));
1207 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1208 printf("<tr><td> %s : </td>\n", _("Old Password"));
1209 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1210 printf("<tr><td> %s : </td>\n", _("New Password"));
1211 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1212 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1213 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1214 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1215 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1217 printf("</table>");
1220 * Create all the control buttons for requesting action
1222 printf("<input type=submit name=%s value=\"%s\">",
1223 CHG_R_PASSWD_FLAG, _("Change Password"));
1225 printf("<p></FORM>\n");
1228 * Do some work if a request has been made to change the
1229 * password somewhere other than the server. It could be this
1230 * is the first time through this code, so there isn't
1231 * anything to do. */
1232 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1233 chg_passwd();
1238 /****************************************************************************
1239 display a printers editing page
1240 ****************************************************************************/
1241 static void printers_page(void)
1243 const char *share = cgi_variable("share");
1244 char *s;
1245 int snum=-1;
1246 int i;
1247 int mode = 0;
1248 unsigned int parm_filter = FLAG_BASIC;
1250 if (share)
1251 snum = lp_servicenumber(share);
1253 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1255 printf("<H3>%s</H3>\n", _("Important Note:"));
1256 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1257 printf("%s",_("are autoloaded printers from "));
1258 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1259 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1261 if (cgi_variable("Commit") && snum >= 0) {
1262 commit_parameters(snum);
1263 if (snum >= iNumNonAutoPrintServices)
1264 save_reload(snum);
1265 else
1266 save_reload(-1);
1267 snum = lp_servicenumber(share);
1270 if (cgi_variable("Delete") && snum >= 0) {
1271 lp_remove_service(snum);
1272 save_reload(-1);
1273 share = NULL;
1274 snum = -1;
1277 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1278 snum = lp_servicenumber(share);
1279 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1280 load_config(False);
1281 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1282 snum = lp_servicenumber(share);
1283 lp_do_parameter(snum, "print ok", "Yes");
1284 save_reload(snum);
1285 snum = lp_servicenumber(share);
1289 printf("<FORM name=\"swatform\" method=post>\n");
1291 if ( cgi_variable("ViewMode") )
1292 mode = atoi(cgi_variable_nonull("ViewMode"));
1293 if ( cgi_variable("BasicMode"))
1294 mode = 0;
1295 if ( cgi_variable("AdvMode"))
1296 mode = 1;
1298 ViewModeBoxes( mode );
1299 switch ( mode ) {
1300 case 0:
1301 parm_filter = FLAG_BASIC;
1302 break;
1303 case 1:
1304 parm_filter = FLAG_ADVANCED;
1305 break;
1307 printf("<table>\n");
1308 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1309 printf("<td><select name=\"share\">\n");
1310 if (snum < 0 || !lp_print_ok(snum))
1311 printf("<option value=\" \"> \n");
1312 for (i=0;i<lp_numservices();i++) {
1313 s = lp_servicename(i);
1314 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1315 if (i >= iNumNonAutoPrintServices)
1316 printf("<option %s value=\"%s\">[*]%s\n",
1317 (share && strcmp(share,s)==0)?"SELECTED":"",
1318 s, s);
1319 else
1320 printf("<option %s value=\"%s\">%s\n",
1321 (share && strcmp(share,s)==0)?"SELECTED":"",
1322 s, s);
1325 printf("</select></td>");
1326 if (have_write_access) {
1327 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1329 printf("</tr>");
1330 printf("</table>\n");
1332 if (have_write_access) {
1333 printf("<table>\n");
1334 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1335 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1336 printf("</table>");
1340 if (snum >= 0) {
1341 if (have_write_access) {
1342 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1344 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1345 printf("<p>\n");
1348 if (snum >= 0) {
1349 printf("<table>\n");
1350 show_parameters(snum, 1, parm_filter, 1);
1351 printf("</table>\n");
1353 printf("</FORM>\n");
1357 when the _() translation macro is used there is no obvious place to free
1358 the resulting string and there is no easy way to give a static pointer.
1359 All we can do is rotate between some static buffers and hope a single d_printf()
1360 doesn't have more calls to _() than the number of buffers
1363 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1365 const char *msgstr;
1366 const char *ret;
1368 msgstr = lang_msg(msgid);
1369 if (!msgstr) {
1370 return msgid;
1373 ret = talloc_strdup(ctx, msgstr);
1375 lang_msg_free(msgstr);
1376 if (!ret) {
1377 return msgid;
1380 return ret;
1384 * main function for SWAT.
1386 int main(int argc, char *argv[])
1388 const char *page;
1389 poptContext pc;
1390 struct poptOption long_options[] = {
1391 POPT_AUTOHELP
1392 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1393 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1394 POPT_COMMON_SAMBA
1395 POPT_TABLEEND
1397 TALLOC_CTX *frame = talloc_stackframe();
1399 fault_setup(NULL);
1400 umask(S_IWGRP | S_IWOTH);
1402 #if defined(HAVE_SET_AUTH_PARAMETERS)
1403 set_auth_parameters(argc, argv);
1404 #endif /* HAVE_SET_AUTH_PARAMETERS */
1406 /* just in case it goes wild ... */
1407 alarm(300);
1409 setlinebuf(stdout);
1411 /* we don't want any SIGPIPE messages */
1412 BlockSignals(True,SIGPIPE);
1414 debug_set_logfile("/dev/null");
1416 /* we don't want stderr screwing us up */
1417 close(2);
1418 open("/dev/null", O_WRONLY);
1419 setup_logging("swat", DEBUG_FILE);
1421 load_case_tables();
1423 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1425 /* Parse command line options */
1427 while(poptGetNextOpt(pc) != -1) { }
1429 poptFreeContext(pc);
1431 /* This should set a more apporiate log file */
1432 load_config(True);
1433 reopen_logs();
1434 load_interfaces();
1435 iNumNonAutoPrintServices = lp_numservices();
1436 if (pcap_cache_loaded()) {
1437 load_printers(server_event_context(),
1438 server_messaging_context());
1441 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1443 print_header();
1445 cgi_load_variables();
1447 if (!file_exist(get_dyn_CONFIGFILE())) {
1448 have_read_access = True;
1449 have_write_access = True;
1450 } else {
1451 /* check if the authenticated user has write access - if not then
1452 don't show write options */
1453 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1455 /* if the user doesn't have read access to smb.conf then
1456 don't let them view it */
1457 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1460 show_main_buttons();
1462 page = cgi_pathinfo();
1464 /* Root gets full functionality */
1465 if (have_read_access && strcmp(page, "globals")==0) {
1466 globals_page();
1467 } else if (have_read_access && strcmp(page,"shares")==0) {
1468 shares_page();
1469 } else if (have_read_access && strcmp(page,"printers")==0) {
1470 printers_page();
1471 } else if (have_read_access && strcmp(page,"status")==0) {
1472 status_page();
1473 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1474 viewconfig_page();
1475 } else if (strcmp(page,"passwd")==0) {
1476 passwd_page();
1477 } else if (have_read_access && strcmp(page,"wizard")==0) {
1478 wizard_page();
1479 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1480 wizard_params_page();
1481 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1482 rewritecfg_file();
1483 } else {
1484 welcome_page();
1487 print_footer();
1489 TALLOC_FREE(frame);
1490 return 0;
1493 /** @} **/