s3 swat: Add XSRF protection to shares page
[Samba.git] / source / web / swat.c
blob4544c318e35ba6ebfcfea001d88d34230b3fde1f
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 "web/swat_proto.h"
32 #include "../lib/crypto/md5.h"
34 static int demo_mode = False;
35 static int passwd_only = False;
36 static bool have_write_access = False;
37 static bool have_read_access = False;
38 static int iNumNonAutoPrintServices = 0;
41 * Password Management Globals
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 #define XSRF_TOKEN "xsrf"
56 #define _(x) lang_msg_rotate(talloc_tos(),x)
58 /****************************************************************************
59 ****************************************************************************/
60 static int enum_index(int value, const struct enum_list *enumlist)
62 int i;
63 for (i=0;enumlist[i].name;i++)
64 if (value == enumlist[i].value) break;
65 return(i);
68 static char *fix_backslash(const char *str)
70 static char newstring[1024];
71 char *p = newstring;
73 while (*str) {
74 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
75 else *p++ = *str;
76 ++str;
78 *p = '\0';
79 return newstring;
82 static const char *fix_quotes(TALLOC_CTX *ctx, const char *str)
84 char *newstring = NULL;
85 char *p = NULL;
86 size_t newstring_len;
87 int quote_len = strlen("&quot;");
89 /* Count the number of quotes. */
90 newstring_len = 1;
91 p = (char *) str;
92 while (*p) {
93 if ( *p == '\"') {
94 newstring_len += quote_len;
95 } else {
96 newstring_len++;
98 ++p;
100 newstring = TALLOC_ARRAY(ctx, char, newstring_len);
101 if (!newstring) {
102 return "";
104 for (p = newstring; *str; str++) {
105 if ( *str == '\"') {
106 strncpy( p, "&quot;", quote_len);
107 p += quote_len;
108 } else {
109 *p++ = *str;
112 *p = '\0';
113 return newstring;
116 static char *stripspaceupper(const char *str)
118 static char newstring[1024];
119 char *p = newstring;
121 while (*str) {
122 if (*str != ' ') *p++ = toupper_ascii(*str);
123 ++str;
125 *p = '\0';
126 return newstring;
129 static char *make_parm_name(const char *label)
131 static char parmname[1024];
132 char *p = parmname;
134 while (*label) {
135 if (*label == ' ') *p++ = '_';
136 else *p++ = *label;
137 ++label;
139 *p = '\0';
140 return parmname;
143 void get_xsrf_token(const char *username, const char *pass,
144 const char *formname, char token_str[33])
146 struct MD5Context md5_ctx;
147 uint8_t token[16];
148 int i;
150 token_str[0] = '\0';
151 ZERO_STRUCT(md5_ctx);
152 MD5Init(&md5_ctx);
154 MD5Update(&md5_ctx, (uint8_t *)formname, strlen(formname));
155 if (username != NULL) {
156 MD5Update(&md5_ctx, (uint8_t *)username, strlen(username));
158 if (pass != NULL) {
159 MD5Update(&md5_ctx, (uint8_t *)pass, strlen(pass));
162 MD5Final(token, &md5_ctx);
164 for(i = 0; i < sizeof(token); i++) {
165 char tmp[3];
167 snprintf(tmp, sizeof(tmp), "%02x", token[i]);
168 strncat(token_str, tmp, sizeof(tmp));
172 void print_xsrf_token(const char *username, const char *pass,
173 const char *formname)
175 char token[33];
177 get_xsrf_token(username, pass, formname, token);
178 printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
179 XSRF_TOKEN, token);
183 bool verify_xsrf_token(const char *formname)
185 char expected[33];
186 const char *username = cgi_user_name();
187 const char *pass = cgi_user_pass();
188 const char *token = cgi_variable_nonull(XSRF_TOKEN);
190 get_xsrf_token(username, pass, formname, expected);
191 return (strncmp(expected, token, sizeof(expected)) == 0);
195 /****************************************************************************
196 include a lump of html in a page
197 ****************************************************************************/
198 static int include_html(const char *fname)
200 int fd;
201 char buf[1024];
202 int ret;
204 fd = web_open(fname, O_RDONLY, 0);
206 if (fd == -1) {
207 printf(_("ERROR: Can't open %s"), fname);
208 printf("\n");
209 return 0;
212 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
213 if (write(1, buf, ret) == -1) {
214 break;
218 close(fd);
219 return 1;
222 /****************************************************************************
223 start the page with standard stuff
224 ****************************************************************************/
225 static void print_header(void)
227 if (!cgi_waspost()) {
228 printf("Expires: 0\r\n");
230 printf("Content-type: text/html\r\n\r\n");
232 if (!include_html("include/header.html")) {
233 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
234 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
238 /* *******************************************************************
239 show parameter label with translated name in the following form
240 because showing original and translated label in one line looks
241 too long, and showing translated label only is unusable for
242 heavy users.
243 -------------------------------
244 HELP security [combo box][button]
245 SECURITY
246 -------------------------------
247 (capital words are translated by gettext.)
248 if no translation is available, then same form as original is
249 used.
250 "i18n_translated_parm" class is used to change the color of the
251 translated parameter with CSS.
252 **************************************************************** */
253 static const char *get_parm_translated(TALLOC_CTX *ctx,
254 const char* pAnchor, const char* pHelp, const char* pLabel)
256 const char *pTranslated = _(pLabel);
257 char *output;
258 if(strcmp(pLabel, pTranslated) != 0) {
259 output = talloc_asprintf(ctx,
260 "<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>",
261 pAnchor, pHelp, pLabel, pTranslated);
262 return output;
264 output = talloc_asprintf(ctx,
265 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
266 pAnchor, pHelp, pLabel);
267 return output;
269 /****************************************************************************
270 finish off the page
271 ****************************************************************************/
272 static void print_footer(void)
274 if (!include_html("include/footer.html")) {
275 printf("\n</BODY>\n</HTML>\n");
279 /****************************************************************************
280 display one editable parameter in a form
281 ****************************************************************************/
282 static void show_parameter(int snum, struct parm_struct *parm)
284 int i;
285 void *ptr = parm->ptr;
286 char *utf8_s1, *utf8_s2;
287 size_t converted_size;
288 TALLOC_CTX *ctx = talloc_stackframe();
290 if (parm->p_class == P_LOCAL && snum >= 0) {
291 ptr = lp_local_ptr(snum, ptr);
294 printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
295 stripspaceupper(parm->label), _("Help"), parm->label));
296 switch (parm->type) {
297 case P_CHAR:
298 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
299 make_parm_name(parm->label), *(char *)ptr);
300 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
301 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
302 break;
304 case P_LIST:
305 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
306 make_parm_name(parm->label));
307 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
308 char **list = *(char ***)ptr;
309 for (;*list;list++) {
310 /* enclose in HTML encoded quotes if the string contains a space */
311 if ( strchr_m(*list, ' ') ) {
312 push_utf8_allocate(&utf8_s1, *list, &converted_size);
313 push_utf8_allocate(&utf8_s2, ((*(list+1))?", ":""), &converted_size);
314 printf("&quot;%s&quot;%s", utf8_s1, utf8_s2);
315 } else {
316 push_utf8_allocate(&utf8_s1, *list, &converted_size);
317 push_utf8_allocate(&utf8_s2, ((*(list+1))?", ":""), &converted_size);
318 printf("%s%s", utf8_s1, utf8_s2);
320 SAFE_FREE(utf8_s1);
321 SAFE_FREE(utf8_s2);
324 printf("\">");
325 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
326 _("Set Default"), make_parm_name(parm->label));
327 if (parm->def.lvalue) {
328 char **list = (char **)(parm->def.lvalue);
329 for (; *list; list++) {
330 /* enclose in HTML encoded quotes if the string contains a space */
331 if ( strchr_m(*list, ' ') )
332 printf("&quot;%s&quot;%s", *list, ((*(list+1))?", ":""));
333 else
334 printf("%s%s", *list, ((*(list+1))?", ":""));
337 printf("\'\">");
338 break;
340 case P_STRING:
341 case P_USTRING:
342 push_utf8_allocate(&utf8_s1, *(char **)ptr, &converted_size);
343 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
344 make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
345 SAFE_FREE(utf8_s1);
346 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
347 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
348 break;
350 case P_BOOL:
351 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
352 printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
353 printf("<option %s>No", (*(bool *)ptr)?"":"selected");
354 printf("</select>");
355 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
356 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
357 break;
359 case P_BOOLREV:
360 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
361 printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
362 printf("<option %s>No", (*(bool *)ptr)?"selected":"");
363 printf("</select>");
364 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
365 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
366 break;
368 case P_INTEGER:
369 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
370 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
371 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
372 break;
374 case P_OCTAL: {
375 char *o;
376 o = octal_string(*(int *)ptr);
377 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
378 make_parm_name(parm->label), o);
379 TALLOC_FREE(o);
380 o = octal_string((int)(parm->def.ivalue));
381 printf("<input type=button value=\"%s\" "
382 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
383 _("Set Default"), make_parm_name(parm->label), o);
384 TALLOC_FREE(o);
385 break;
388 case P_ENUM:
389 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
390 for (i=0;parm->enum_list[i].name;i++) {
391 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
392 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
395 printf("</select>");
396 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
397 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
398 break;
399 case P_SEP:
400 break;
402 printf("</td></tr>\n");
403 TALLOC_FREE(ctx);
406 /****************************************************************************
407 display a set of parameters for a service
408 ****************************************************************************/
409 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
411 int i = 0;
412 struct parm_struct *parm;
413 const char *heading = NULL;
414 const char *last_heading = NULL;
416 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
417 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
418 continue;
419 if (parm->p_class == P_SEPARATOR) {
420 heading = parm->label;
421 continue;
423 if (parm->flags & FLAG_HIDE) continue;
424 if (snum >= 0) {
425 if (printers & !(parm->flags & FLAG_PRINT)) continue;
426 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
429 if (!( parm_filter & FLAG_ADVANCED )) {
430 if (!(parm->flags & FLAG_BASIC)) {
431 void *ptr = parm->ptr;
433 if (parm->p_class == P_LOCAL && snum >= 0) {
434 ptr = lp_local_ptr(snum, ptr);
437 switch (parm->type) {
438 case P_CHAR:
439 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
440 break;
442 case P_LIST:
443 if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
444 break;
446 case P_STRING:
447 case P_USTRING:
448 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
449 break;
451 case P_BOOL:
452 case P_BOOLREV:
453 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
454 break;
456 case P_INTEGER:
457 case P_OCTAL:
458 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
459 break;
462 case P_ENUM:
463 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
464 break;
465 case P_SEP:
466 continue;
469 if (printers && !(parm->flags & FLAG_PRINT)) continue;
472 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
474 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
476 if (heading && heading != last_heading) {
477 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
478 last_heading = heading;
480 show_parameter(snum, parm);
484 /****************************************************************************
485 load the smb.conf file into loadparm.
486 ****************************************************************************/
487 static bool load_config(bool save_def)
489 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
492 /****************************************************************************
493 write a config file
494 ****************************************************************************/
495 static void write_config(FILE *f, bool show_defaults)
497 TALLOC_CTX *ctx = talloc_stackframe();
499 fprintf(f, "# Samba config file created using SWAT\n");
500 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
501 fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
503 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
505 TALLOC_FREE(ctx);
508 /****************************************************************************
509 save and reload the smb.conf config file
510 ****************************************************************************/
511 static int save_reload(int snum)
513 FILE *f;
514 struct stat st;
516 f = sys_fopen(get_dyn_CONFIGFILE(),"w");
517 if (!f) {
518 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
519 printf("\n");
520 return 0;
523 /* just in case they have used the buggy xinetd to create the file */
524 if (fstat(fileno(f), &st) == 0 &&
525 (st.st_mode & S_IWOTH)) {
526 #if defined HAVE_FCHMOD
527 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
528 #else
529 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
530 #endif
533 write_config(f, False);
534 if (snum >= 0)
535 lp_dump_one(f, False, snum);
536 fclose(f);
538 lp_kill_all_services();
540 if (!load_config(False)) {
541 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
542 printf("\n");
543 return 0;
545 iNumNonAutoPrintServices = lp_numservices();
546 load_printers();
548 return 1;
551 /****************************************************************************
552 commit one parameter
553 ****************************************************************************/
554 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
556 int i;
557 char *s;
559 if (snum < 0 && parm->p_class == P_LOCAL) {
560 /* this handles the case where we are changing a local
561 variable globally. We need to change the parameter in
562 all shares where it is currently set to the default */
563 for (i=0;i<lp_numservices();i++) {
564 s = lp_servicename(i);
565 if (s && (*s) && lp_is_default(i, parm)) {
566 lp_do_parameter(i, parm->label, v);
571 lp_do_parameter(snum, parm->label, v);
574 /****************************************************************************
575 commit a set of parameters for a service
576 ****************************************************************************/
577 static void commit_parameters(int snum)
579 int i = 0;
580 struct parm_struct *parm;
581 char *label;
582 const char *v;
584 while ((parm = lp_next_parameter(snum, &i, 1))) {
585 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
586 if ((v = cgi_variable(label)) != NULL) {
587 if (parm->flags & FLAG_HIDE)
588 continue;
589 commit_parameter(snum, parm, v);
591 SAFE_FREE(label);
596 /****************************************************************************
597 spit out the html for a link with an image
598 ****************************************************************************/
599 static void image_link(const char *name, const char *hlink, const char *src)
601 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
602 cgi_baseurl(), hlink, src, name);
605 /****************************************************************************
606 display the main navigation controls at the top of each page along
607 with a title
608 ****************************************************************************/
609 static void show_main_buttons(void)
611 char *p;
613 if ((p = cgi_user_name()) && strcmp(p, "root")) {
614 printf(_("Logged in as <b>%s</b>"), p);
615 printf("<p>\n");
618 image_link(_("Home"), "", "images/home.gif");
619 if (have_write_access) {
620 image_link(_("Globals"), "globals", "images/globals.gif");
621 image_link(_("Shares"), "shares", "images/shares.gif");
622 image_link(_("Printers"), "printers", "images/printers.gif");
623 image_link(_("Wizard"), "wizard", "images/wizard.gif");
625 /* root always gets all buttons, otherwise look for -P */
626 if ( have_write_access || (!passwd_only && have_read_access) ) {
627 image_link(_("Status"), "status", "images/status.gif");
628 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
630 image_link(_("Password Management"), "passwd", "images/passwd.gif");
632 printf("<HR>\n");
635 /****************************************************************************
636 * Handle Display/Edit Mode CGI
637 ****************************************************************************/
638 static void ViewModeBoxes(int mode)
640 printf("<p>%s:&nbsp;\n", _("Current View Is"));
641 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
642 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
643 printf("<br>%s:&nbsp;\n", _("Change View To"));
644 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
645 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
646 printf("</p><br>\n");
649 /****************************************************************************
650 display a welcome page
651 ****************************************************************************/
652 static void welcome_page(void)
654 if (file_exist("help/welcome.html", NULL)) {
655 include_html("help/welcome.html");
656 } else {
657 include_html("help/welcome-no-samba-doc.html");
661 /****************************************************************************
662 display the current smb.conf
663 ****************************************************************************/
664 static void viewconfig_page(void)
666 int full_view=0;
667 const char form_name[] = "viewconfig";
669 if (!verify_xsrf_token(form_name)) {
670 goto output_page;
673 if (cgi_variable("full_view")) {
674 full_view = 1;
677 output_page:
678 printf("<H2>%s</H2>\n", _("Current Config"));
679 printf("<form method=post>\n");
680 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
682 if (full_view) {
683 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
684 } else {
685 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
688 printf("<p><pre>");
689 write_config(stdout, full_view);
690 printf("</pre>");
691 printf("</form>\n");
694 /****************************************************************************
695 second screen of the wizard ... Fetch Configuration Parameters
696 ****************************************************************************/
697 static void wizard_params_page(void)
699 unsigned int parm_filter = FLAG_WIZARD;
700 const char form_name[] = "wizard_params";
702 /* Here we first set and commit all the parameters that were selected
703 in the previous screen. */
705 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
707 if (!verify_xsrf_token(form_name)) {
708 goto output_page;
711 if (cgi_variable("Commit")) {
712 commit_parameters(GLOBAL_SECTION_SNUM);
713 save_reload(0);
716 output_page:
717 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
718 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
720 if (have_write_access) {
721 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
724 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
725 printf("<p>\n");
727 printf("<table>\n");
728 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
729 printf("</table>\n");
730 printf("</form>\n");
733 /****************************************************************************
734 Utility to just rewrite the smb.conf file - effectively just cleans it up
735 ****************************************************************************/
736 static void rewritecfg_file(void)
738 commit_parameters(GLOBAL_SECTION_SNUM);
739 save_reload(0);
740 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
743 /****************************************************************************
744 wizard to create/modify the smb.conf file
745 ****************************************************************************/
746 static void wizard_page(void)
748 /* Set some variables to collect data from smb.conf */
749 int role = 0;
750 int winstype = 0;
751 int have_home = -1;
752 int HomeExpo = 0;
753 int SerType = 0;
754 const char form_name[] = "wizard";
756 if (!verify_xsrf_token(form_name)) {
757 goto output_page;
760 if (cgi_variable("Rewrite")) {
761 (void) rewritecfg_file();
762 return;
765 if (cgi_variable("GetWizardParams")){
766 (void) wizard_params_page();
767 return;
770 if (cgi_variable("Commit")){
771 SerType = atoi(cgi_variable_nonull("ServerType"));
772 winstype = atoi(cgi_variable_nonull("WINSType"));
773 have_home = lp_servicenumber(HOMES_NAME);
774 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
776 /* Plain text passwords are too badly broken - use encrypted passwords only */
777 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
779 switch ( SerType ){
780 case 0:
781 /* Stand-alone Server */
782 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
783 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
784 break;
785 case 1:
786 /* Domain Member */
787 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
788 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
789 break;
790 case 2:
791 /* Domain Controller */
792 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
793 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
794 break;
796 switch ( winstype ) {
797 case 0:
798 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
799 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
800 break;
801 case 1:
802 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
803 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
804 break;
805 case 2:
806 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
807 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
808 break;
811 /* Have to create Homes share? */
812 if ((HomeExpo == 1) && (have_home == -1)) {
813 const char *unix_share = HOMES_NAME;
815 load_config(False);
816 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
817 have_home = lp_servicenumber(HOMES_NAME);
818 lp_do_parameter( have_home, "read only", "No");
819 lp_do_parameter( have_home, "valid users", "%S");
820 lp_do_parameter( have_home, "browseable", "No");
821 commit_parameters(have_home);
822 save_reload(have_home);
825 /* Need to Delete Homes share? */
826 if ((HomeExpo == 0) && (have_home != -1)) {
827 lp_remove_service(have_home);
828 have_home = -1;
831 commit_parameters(GLOBAL_SECTION_SNUM);
832 save_reload(0);
834 else
836 /* Now determine smb.conf WINS settings */
837 if (lp_wins_support())
838 winstype = 1;
839 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
840 winstype = 2;
842 /* Do we have a homes share? */
843 have_home = lp_servicenumber(HOMES_NAME);
845 if ((winstype == 2) && lp_wins_support())
846 winstype = 3;
848 role = lp_server_role();
850 output_page:
851 /* Here we go ... */
852 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
853 printf("<form method=post action=wizard>\n");
854 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
856 if (have_write_access) {
857 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
858 printf("%s", _("The same will happen if you press the commit button."));
859 printf("<br><br>\n");
860 printf("<center>");
861 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
862 printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
863 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
864 printf("</center>\n");
867 printf("<hr>");
868 printf("<center><table border=0>");
869 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
870 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
871 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
872 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
873 printf("</tr>\n");
874 if (role == ROLE_DOMAIN_BDC) {
875 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
877 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
878 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
879 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
880 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
881 printf("</tr>\n");
882 printf("<tr><td></td><td></td><td></td><td>%s&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
884 /* Print out the list of wins servers */
885 if(lp_wins_server_list()) {
886 int i;
887 const char **wins_servers = lp_wins_server_list();
888 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
891 printf("\"></td></tr>\n");
892 if (winstype == 3) {
893 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"));
894 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
896 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
897 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
898 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
899 printf("<td></td></tr>\n");
901 /* Enable this when we are ready ....
902 * printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
903 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
904 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
905 * printf("<td></td></tr>\n");
908 printf("</table></center>");
909 printf("<hr>");
911 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
912 printf("</form>\n");
916 /****************************************************************************
917 display a globals editing page
918 ****************************************************************************/
919 static void globals_page(void)
921 unsigned int parm_filter = FLAG_BASIC;
922 int mode = 0;
923 const char form_name[] = "globals";
925 printf("<H2>%s</H2>\n", _("Global Parameters"));
927 if (!verify_xsrf_token(form_name)) {
928 goto output_page;
931 if (cgi_variable("Commit")) {
932 commit_parameters(GLOBAL_SECTION_SNUM);
933 save_reload(0);
936 if ( cgi_variable("ViewMode") )
937 mode = atoi(cgi_variable_nonull("ViewMode"));
938 if ( cgi_variable("BasicMode"))
939 mode = 0;
940 if ( cgi_variable("AdvMode"))
941 mode = 1;
943 output_page:
944 printf("<form name=\"swatform\" method=post action=globals>\n");
945 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
947 ViewModeBoxes( mode );
948 switch ( mode ) {
949 case 0:
950 parm_filter = FLAG_BASIC;
951 break;
952 case 1:
953 parm_filter = FLAG_ADVANCED;
954 break;
956 printf("<br>\n");
957 if (have_write_access) {
958 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
959 _("Commit Changes"));
962 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
963 _("Reset Values"));
965 printf("<p>\n");
966 printf("<table>\n");
967 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
968 printf("</table>\n");
969 printf("</form>\n");
972 /****************************************************************************
973 display a shares editing page. share is in unix codepage,
974 ****************************************************************************/
975 static void shares_page(void)
977 const char *share = cgi_variable("share");
978 char *s;
979 char *utf8_s;
980 int snum = -1;
981 int i;
982 int mode = 0;
983 unsigned int parm_filter = FLAG_BASIC;
984 size_t converted_size;
985 const char form_name[] = "shares";
987 printf("<H2>%s</H2>\n", _("Share Parameters"));
989 if (!verify_xsrf_token(form_name)) {
990 goto output_page;
993 if (share)
994 snum = lp_servicenumber(share);
997 if (cgi_variable("Commit") && snum >= 0) {
998 commit_parameters(snum);
999 save_reload(0);
1000 snum = lp_servicenumber(share);
1003 if (cgi_variable("Delete") && snum >= 0) {
1004 lp_remove_service(snum);
1005 save_reload(0);
1006 share = NULL;
1007 snum = -1;
1010 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1011 snum = lp_servicenumber(share);
1012 if (snum < 0) {
1013 load_config(False);
1014 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1015 snum = lp_servicenumber(share);
1016 save_reload(snum);
1017 snum = lp_servicenumber(share);
1021 if ( cgi_variable("ViewMode") )
1022 mode = atoi(cgi_variable_nonull("ViewMode"));
1023 if ( cgi_variable("BasicMode"))
1024 mode = 0;
1025 if ( cgi_variable("AdvMode"))
1026 mode = 1;
1028 output_page:
1029 printf("<FORM name=\"swatform\" method=post>\n");
1030 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1032 printf("<table>\n");
1034 ViewModeBoxes( mode );
1035 switch ( mode ) {
1036 case 0:
1037 parm_filter = FLAG_BASIC;
1038 break;
1039 case 1:
1040 parm_filter = FLAG_ADVANCED;
1041 break;
1043 printf("<br><tr>\n");
1044 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1045 printf("<td><select name=share>\n");
1046 if (snum < 0)
1047 printf("<option value=\" \"> \n");
1048 for (i=0;i<lp_numservices();i++) {
1049 s = lp_servicename(i);
1050 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
1051 push_utf8_allocate(&utf8_s, s, &converted_size);
1052 printf("<option %s value=\"%s\">%s\n",
1053 (share && strcmp(share,s)==0)?"SELECTED":"",
1054 utf8_s, utf8_s);
1055 SAFE_FREE(utf8_s);
1058 printf("</select></td>\n");
1059 if (have_write_access) {
1060 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1062 printf("</tr>\n");
1063 printf("</table>");
1064 printf("<table>");
1065 if (have_write_access) {
1066 printf("<tr>\n");
1067 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1068 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1070 printf("</table>");
1073 if (snum >= 0) {
1074 if (have_write_access) {
1075 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1078 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1079 printf("<p>\n");
1082 if (snum >= 0) {
1083 printf("<table>\n");
1084 show_parameters(snum, 1, parm_filter, 0);
1085 printf("</table>\n");
1088 printf("</FORM>\n");
1091 /*************************************************************
1092 change a password either locally or remotely
1093 *************************************************************/
1094 static bool change_password(const char *remote_machine, const char *user_name,
1095 const char *old_passwd, const char *new_passwd,
1096 int local_flags)
1098 NTSTATUS ret;
1099 char *err_str = NULL;
1100 char *msg_str = NULL;
1102 if (demo_mode) {
1103 printf("%s\n<p>", _("password change in demo mode rejected"));
1104 return False;
1107 if (remote_machine != NULL) {
1108 ret = remote_password_change(remote_machine, user_name,
1109 old_passwd, new_passwd, &err_str);
1110 if (err_str != NULL)
1111 printf("%s\n<p>", err_str);
1112 SAFE_FREE(err_str);
1113 return NT_STATUS_IS_OK(ret);
1116 if(!initialize_password_db(True, NULL)) {
1117 printf("%s\n<p>", _("Can't setup password database vectors."));
1118 return False;
1121 ret = local_password_change(user_name, local_flags, new_passwd,
1122 &err_str, &msg_str);
1124 if(msg_str)
1125 printf("%s\n<p>", msg_str);
1126 if(err_str)
1127 printf("%s\n<p>", err_str);
1129 SAFE_FREE(msg_str);
1130 SAFE_FREE(err_str);
1131 return NT_STATUS_IS_OK(ret);
1134 /****************************************************************************
1135 do the stuff required to add or change a password
1136 ****************************************************************************/
1137 static void chg_passwd(void)
1139 const char *host;
1140 bool rslt;
1141 int local_flags = 0;
1143 /* Make sure users name has been specified */
1144 if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1145 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1146 return;
1150 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1151 * so if that's what we're doing, skip the rest of the checks
1153 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1156 * If current user is not root, make sure old password has been specified
1157 * If REMOTE change, even root must provide old password
1159 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1160 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1161 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1162 return;
1165 /* If changing a users password on a remote hosts we have to know what host */
1166 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1167 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1168 return;
1171 /* Make sure new passwords have been specified */
1172 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1173 (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1174 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1175 return;
1178 /* Make sure new passwords was typed correctly twice */
1179 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1180 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1181 return;
1185 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1186 host = cgi_variable(RHOST);
1187 } else if (am_root()) {
1188 host = NULL;
1189 } else {
1190 host = "127.0.0.1";
1194 * Set up the local flags.
1197 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1198 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1199 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1200 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1201 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1202 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1205 rslt = change_password(host,
1206 cgi_variable_nonull(SWAT_USER),
1207 cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1208 local_flags);
1210 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1211 printf("<p>");
1212 if (rslt == True) {
1213 printf("%s\n", _(" The passwd has been changed."));
1214 } else {
1215 printf("%s\n", _(" The passwd for has NOT been changed."));
1219 return;
1222 /****************************************************************************
1223 display a password editing page
1224 ****************************************************************************/
1225 static void passwd_page(void)
1227 const char *new_name = cgi_user_name();
1229 if (!new_name) new_name = "";
1231 printf("<H2>%s</H2>\n", _("Server Password Management"));
1233 printf("<FORM name=\"swatform\" method=post>\n");
1235 printf("<table>\n");
1238 * Create all the dialog boxes for data collection
1240 printf("<tr><td> %s : </td>\n", _("User Name"));
1241 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1242 if (!am_root()) {
1243 printf("<tr><td> %s : </td>\n", _("Old Password"));
1244 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1246 printf("<tr><td> %s : </td>\n", _("New Password"));
1247 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1248 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1249 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1250 printf("</table>\n");
1253 * Create all the control buttons for requesting action
1255 printf("<input type=submit name=%s value=\"%s\">\n",
1256 CHG_S_PASSWD_FLAG, _("Change Password"));
1257 if (demo_mode || am_root()) {
1258 printf("<input type=submit name=%s value=\"%s\">\n",
1259 ADD_USER_FLAG, _("Add New User"));
1260 printf("<input type=submit name=%s value=\"%s\">\n",
1261 DELETE_USER_FLAG, _("Delete User"));
1262 printf("<input type=submit name=%s value=\"%s\">\n",
1263 DISABLE_USER_FLAG, _("Disable User"));
1264 printf("<input type=submit name=%s value=\"%s\">\n",
1265 ENABLE_USER_FLAG, _("Enable User"));
1267 printf("<p></FORM>\n");
1270 * Do some work if change, add, disable or enable was
1271 * requested. It could be this is the first time through this
1272 * code, so there isn't anything to do. */
1273 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1274 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1275 chg_passwd();
1278 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1280 printf("<FORM name=\"swatform\" method=post>\n");
1282 printf("<table>\n");
1285 * Create all the dialog boxes for data collection
1287 printf("<tr><td> %s : </td>\n", _("User Name"));
1288 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1289 printf("<tr><td> %s : </td>\n", _("Old Password"));
1290 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1291 printf("<tr><td> %s : </td>\n", _("New Password"));
1292 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1293 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1294 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1295 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1296 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1298 printf("</table>");
1301 * Create all the control buttons for requesting action
1303 printf("<input type=submit name=%s value=\"%s\">",
1304 CHG_R_PASSWD_FLAG, _("Change Password"));
1306 printf("<p></FORM>\n");
1309 * Do some work if a request has been made to change the
1310 * password somewhere other than the server. It could be this
1311 * is the first time through this code, so there isn't
1312 * anything to do. */
1313 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1314 chg_passwd();
1319 /****************************************************************************
1320 display a printers editing page
1321 ****************************************************************************/
1322 static void printers_page(void)
1324 const char *share = cgi_variable("share");
1325 char *s;
1326 int snum=-1;
1327 int i;
1328 int mode = 0;
1329 unsigned int parm_filter = FLAG_BASIC;
1331 if (share)
1332 snum = lp_servicenumber(share);
1334 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1336 printf("<H3>%s</H3>\n", _("Important Note:"));
1337 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1338 printf("%s",_("are autoloaded printers from "));
1339 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1340 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1342 if (cgi_variable("Commit") && snum >= 0) {
1343 commit_parameters(snum);
1344 if (snum >= iNumNonAutoPrintServices)
1345 save_reload(snum);
1346 else
1347 save_reload(0);
1348 snum = lp_servicenumber(share);
1351 if (cgi_variable("Delete") && snum >= 0) {
1352 lp_remove_service(snum);
1353 save_reload(0);
1354 share = NULL;
1355 snum = -1;
1358 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1359 snum = lp_servicenumber(share);
1360 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1361 load_config(False);
1362 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1363 snum = lp_servicenumber(share);
1364 lp_do_parameter(snum, "print ok", "Yes");
1365 save_reload(snum);
1366 snum = lp_servicenumber(share);
1370 printf("<FORM name=\"swatform\" method=post>\n");
1372 if ( cgi_variable("ViewMode") )
1373 mode = atoi(cgi_variable_nonull("ViewMode"));
1374 if ( cgi_variable("BasicMode"))
1375 mode = 0;
1376 if ( cgi_variable("AdvMode"))
1377 mode = 1;
1379 ViewModeBoxes( mode );
1380 switch ( mode ) {
1381 case 0:
1382 parm_filter = FLAG_BASIC;
1383 break;
1384 case 1:
1385 parm_filter = FLAG_ADVANCED;
1386 break;
1388 printf("<table>\n");
1389 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1390 printf("<td><select name=\"share\">\n");
1391 if (snum < 0 || !lp_print_ok(snum))
1392 printf("<option value=\" \"> \n");
1393 for (i=0;i<lp_numservices();i++) {
1394 s = lp_servicename(i);
1395 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1396 if (i >= iNumNonAutoPrintServices)
1397 printf("<option %s value=\"%s\">[*]%s\n",
1398 (share && strcmp(share,s)==0)?"SELECTED":"",
1399 s, s);
1400 else
1401 printf("<option %s value=\"%s\">%s\n",
1402 (share && strcmp(share,s)==0)?"SELECTED":"",
1403 s, s);
1406 printf("</select></td>");
1407 if (have_write_access) {
1408 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1410 printf("</tr>");
1411 printf("</table>\n");
1413 if (have_write_access) {
1414 printf("<table>\n");
1415 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1416 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1417 printf("</table>");
1421 if (snum >= 0) {
1422 if (have_write_access) {
1423 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1425 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1426 printf("<p>\n");
1429 if (snum >= 0) {
1430 printf("<table>\n");
1431 show_parameters(snum, 1, parm_filter, 1);
1432 printf("</table>\n");
1434 printf("</FORM>\n");
1438 when the _() translation macro is used there is no obvious place to free
1439 the resulting string and there is no easy way to give a static pointer.
1440 All we can do is rotate between some static buffers and hope a single d_printf()
1441 doesn't have more calls to _() than the number of buffers
1444 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1446 const char *msgstr;
1447 const char *ret;
1449 msgstr = lang_msg(msgid);
1450 if (!msgstr) {
1451 return msgid;
1454 ret = talloc_strdup(ctx, msgstr);
1456 lang_msg_free(msgstr);
1457 if (!ret) {
1458 return msgid;
1461 return ret;
1465 * main function for SWAT.
1467 int main(int argc, char *argv[])
1469 const char *page;
1470 poptContext pc;
1471 struct poptOption long_options[] = {
1472 POPT_AUTOHELP
1473 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1474 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1475 POPT_COMMON_SAMBA
1476 POPT_TABLEEND
1478 TALLOC_CTX *frame = talloc_stackframe();
1480 fault_setup(NULL);
1481 umask(S_IWGRP | S_IWOTH);
1483 #if defined(HAVE_SET_AUTH_PARAMETERS)
1484 set_auth_parameters(argc, argv);
1485 #endif /* HAVE_SET_AUTH_PARAMETERS */
1487 /* just in case it goes wild ... */
1488 alarm(300);
1490 setlinebuf(stdout);
1492 /* we don't want any SIGPIPE messages */
1493 BlockSignals(True,SIGPIPE);
1495 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1496 if (!dbf) dbf = x_stderr;
1498 /* we don't want stderr screwing us up */
1499 close(2);
1500 open("/dev/null", O_WRONLY);
1502 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1504 /* Parse command line options */
1506 while(poptGetNextOpt(pc) != -1) { }
1508 poptFreeContext(pc);
1510 load_case_tables();
1512 setup_logging(argv[0],False);
1513 load_config(True);
1514 load_interfaces();
1515 iNumNonAutoPrintServices = lp_numservices();
1516 load_printers();
1518 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1520 print_header();
1522 cgi_load_variables();
1524 if (!file_exist(get_dyn_CONFIGFILE(), NULL)) {
1525 have_read_access = True;
1526 have_write_access = True;
1527 } else {
1528 /* check if the authenticated user has write access - if not then
1529 don't show write options */
1530 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1532 /* if the user doesn't have read access to smb.conf then
1533 don't let them view it */
1534 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1537 show_main_buttons();
1539 page = cgi_pathinfo();
1541 /* Root gets full functionality */
1542 if (have_read_access && strcmp(page, "globals")==0) {
1543 globals_page();
1544 } else if (have_read_access && strcmp(page,"shares")==0) {
1545 shares_page();
1546 } else if (have_read_access && strcmp(page,"printers")==0) {
1547 printers_page();
1548 } else if (have_read_access && strcmp(page,"status")==0) {
1549 status_page();
1550 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1551 viewconfig_page();
1552 } else if (strcmp(page,"passwd")==0) {
1553 passwd_page();
1554 } else if (have_read_access && strcmp(page,"wizard")==0) {
1555 wizard_page();
1556 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1557 wizard_params_page();
1558 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1559 rewritecfg_file();
1560 } else {
1561 welcome_page();
1564 print_footer();
1566 TALLOC_FREE(frame);
1567 return 0;
1570 /** @} **/