s3 swat: Create random nonce in CGI mode
[Samba.git] / source / web / swat.c
blob146f1cf7d2d73879dd8847aeebbfea2fa083dba3
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"
33 static int demo_mode = False;
34 static int passwd_only = False;
35 static bool have_write_access = False;
36 static bool have_read_access = False;
37 static int iNumNonAutoPrintServices = 0;
40 * Password Management Globals
42 #define SWAT_USER "username"
43 #define OLD_PSWD "old_passwd"
44 #define NEW_PSWD "new_passwd"
45 #define NEW2_PSWD "new2_passwd"
46 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
47 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
48 #define ADD_USER_FLAG "add_user_flag"
49 #define DELETE_USER_FLAG "delete_user_flag"
50 #define DISABLE_USER_FLAG "disable_user_flag"
51 #define ENABLE_USER_FLAG "enable_user_flag"
52 #define RHOST "remote_host"
53 #define XSRF_TOKEN "xsrf"
54 #define XSRF_TIME "xsrf_time"
55 #define XSRF_TIMEOUT 300
57 #define _(x) lang_msg_rotate(talloc_tos(),x)
59 /****************************************************************************
60 ****************************************************************************/
61 static int enum_index(int value, const struct enum_list *enumlist)
63 int i;
64 for (i=0;enumlist[i].name;i++)
65 if (value == enumlist[i].value) break;
66 return(i);
69 static char *fix_backslash(const char *str)
71 static char newstring[1024];
72 char *p = newstring;
74 while (*str) {
75 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
76 else *p++ = *str;
77 ++str;
79 *p = '\0';
80 return newstring;
83 static const char *fix_quotes(TALLOC_CTX *ctx, const char *str)
85 char *newstring = NULL;
86 char *p = NULL;
87 size_t newstring_len;
88 int quote_len = strlen("&quot;");
90 /* Count the number of quotes. */
91 newstring_len = 1;
92 p = (char *) str;
93 while (*p) {
94 if ( *p == '\"') {
95 newstring_len += quote_len;
96 } else {
97 newstring_len++;
99 ++p;
101 newstring = TALLOC_ARRAY(ctx, char, newstring_len);
102 if (!newstring) {
103 return "";
105 for (p = newstring; *str; str++) {
106 if ( *str == '\"') {
107 strncpy( p, "&quot;", quote_len);
108 p += quote_len;
109 } else {
110 *p++ = *str;
113 *p = '\0';
114 return newstring;
117 static char *stripspaceupper(const char *str)
119 static char newstring[1024];
120 char *p = newstring;
122 while (*str) {
123 if (*str != ' ') *p++ = toupper_ascii(*str);
124 ++str;
126 *p = '\0';
127 return newstring;
130 static char *make_parm_name(const char *label)
132 static char parmname[1024];
133 char *p = parmname;
135 while (*label) {
136 if (*label == ' ') *p++ = '_';
137 else *p++ = *label;
138 ++label;
140 *p = '\0';
141 return parmname;
144 void get_xsrf_token(const char *username, const char *pass,
145 const char *formname, time_t xsrf_time, char token_str[33])
147 struct MD5Context md5_ctx;
148 uint8_t token[16];
149 int i;
151 token_str[0] = '\0';
152 ZERO_STRUCT(md5_ctx);
153 MD5Init(&md5_ctx);
155 MD5Update(&md5_ctx, (uint8_t *)formname, strlen(formname));
156 MD5Update(&md5_ctx, (uint8_t *)&xsrf_time, sizeof(time_t));
157 if (username != NULL) {
158 MD5Update(&md5_ctx, (uint8_t *)username, strlen(username));
160 if (pass != NULL) {
161 MD5Update(&md5_ctx, (uint8_t *)pass, strlen(pass));
164 MD5Final(token, &md5_ctx);
166 for(i = 0; i < sizeof(token); i++) {
167 char tmp[3];
169 snprintf(tmp, sizeof(tmp), "%02x", token[i]);
170 strncat(token_str, tmp, sizeof(tmp));
174 void print_xsrf_token(const char *username, const char *pass,
175 const char *formname)
177 char token[33];
178 time_t xsrf_time = time(NULL);
180 get_xsrf_token(username, pass, formname, xsrf_time, token);
181 printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
182 XSRF_TOKEN, token);
183 printf("<input type=\"hidden\" name=\"%s\" value=\"%lld\">\n",
184 XSRF_TIME, (long long int)xsrf_time);
187 bool verify_xsrf_token(const char *formname)
189 char expected[33];
190 const char *username = cgi_user_name();
191 const char *pass = cgi_user_pass();
192 const char *token = cgi_variable_nonull(XSRF_TOKEN);
193 const char *time_str = cgi_variable_nonull(XSRF_TIME);
194 time_t xsrf_time = 0;
195 time_t now = time(NULL);
197 if (sizeof(time_t) == sizeof(int)) {
198 xsrf_time = atoi(time_str);
199 } else if (sizeof(time_t) == sizeof(long)) {
200 xsrf_time = atol(time_str);
201 } else if (sizeof(time_t) == sizeof(long long)) {
202 xsrf_time = atoll(time_str);
205 if (abs(now - xsrf_time) > XSRF_TIMEOUT) {
206 return false;
209 get_xsrf_token(username, pass, formname, xsrf_time, expected);
210 return (strncmp(expected, token, sizeof(expected)) == 0);
214 /****************************************************************************
215 include a lump of html in a page
216 ****************************************************************************/
217 static int include_html(const char *fname)
219 int fd;
220 char buf[1024];
221 int ret;
223 fd = web_open(fname, O_RDONLY, 0);
225 if (fd == -1) {
226 printf(_("ERROR: Can't open %s"), fname);
227 printf("\n");
228 return 0;
231 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
232 if (write(1, buf, ret) == -1) {
233 break;
237 close(fd);
238 return 1;
241 /****************************************************************************
242 start the page with standard stuff
243 ****************************************************************************/
244 static void print_header(void)
246 if (!cgi_waspost()) {
247 printf("Expires: 0\r\n");
249 printf("Content-type: text/html\r\n\r\n");
251 if (!include_html("include/header.html")) {
252 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
253 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
257 /* *******************************************************************
258 show parameter label with translated name in the following form
259 because showing original and translated label in one line looks
260 too long, and showing translated label only is unusable for
261 heavy users.
262 -------------------------------
263 HELP security [combo box][button]
264 SECURITY
265 -------------------------------
266 (capital words are translated by gettext.)
267 if no translation is available, then same form as original is
268 used.
269 "i18n_translated_parm" class is used to change the color of the
270 translated parameter with CSS.
271 **************************************************************** */
272 static const char *get_parm_translated(TALLOC_CTX *ctx,
273 const char* pAnchor, const char* pHelp, const char* pLabel)
275 const char *pTranslated = _(pLabel);
276 char *output;
277 if(strcmp(pLabel, pTranslated) != 0) {
278 output = talloc_asprintf(ctx,
279 "<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>",
280 pAnchor, pHelp, pLabel, pTranslated);
281 return output;
283 output = talloc_asprintf(ctx,
284 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
285 pAnchor, pHelp, pLabel);
286 return output;
288 /****************************************************************************
289 finish off the page
290 ****************************************************************************/
291 static void print_footer(void)
293 if (!include_html("include/footer.html")) {
294 printf("\n</BODY>\n</HTML>\n");
298 /****************************************************************************
299 display one editable parameter in a form
300 ****************************************************************************/
301 static void show_parameter(int snum, struct parm_struct *parm)
303 int i;
304 void *ptr = parm->ptr;
305 char *utf8_s1, *utf8_s2;
306 size_t converted_size;
307 TALLOC_CTX *ctx = talloc_stackframe();
309 if (parm->p_class == P_LOCAL && snum >= 0) {
310 ptr = lp_local_ptr(snum, ptr);
313 printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
314 stripspaceupper(parm->label), _("Help"), parm->label));
315 switch (parm->type) {
316 case P_CHAR:
317 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
318 make_parm_name(parm->label), *(char *)ptr);
319 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
320 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
321 break;
323 case P_LIST:
324 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
325 make_parm_name(parm->label));
326 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
327 char **list = *(char ***)ptr;
328 for (;*list;list++) {
329 /* enclose in HTML encoded quotes if the string contains a space */
330 if ( strchr_m(*list, ' ') ) {
331 push_utf8_allocate(&utf8_s1, *list, &converted_size);
332 push_utf8_allocate(&utf8_s2, ((*(list+1))?", ":""), &converted_size);
333 printf("&quot;%s&quot;%s", utf8_s1, utf8_s2);
334 } else {
335 push_utf8_allocate(&utf8_s1, *list, &converted_size);
336 push_utf8_allocate(&utf8_s2, ((*(list+1))?", ":""), &converted_size);
337 printf("%s%s", utf8_s1, utf8_s2);
339 SAFE_FREE(utf8_s1);
340 SAFE_FREE(utf8_s2);
343 printf("\">");
344 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
345 _("Set Default"), make_parm_name(parm->label));
346 if (parm->def.lvalue) {
347 char **list = (char **)(parm->def.lvalue);
348 for (; *list; list++) {
349 /* enclose in HTML encoded quotes if the string contains a space */
350 if ( strchr_m(*list, ' ') )
351 printf("&quot;%s&quot;%s", *list, ((*(list+1))?", ":""));
352 else
353 printf("%s%s", *list, ((*(list+1))?", ":""));
356 printf("\'\">");
357 break;
359 case P_STRING:
360 case P_USTRING:
361 push_utf8_allocate(&utf8_s1, *(char **)ptr, &converted_size);
362 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
363 make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
364 SAFE_FREE(utf8_s1);
365 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
366 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
367 break;
369 case P_BOOL:
370 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
371 printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
372 printf("<option %s>No", (*(bool *)ptr)?"":"selected");
373 printf("</select>");
374 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
375 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
376 break;
378 case P_BOOLREV:
379 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
380 printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
381 printf("<option %s>No", (*(bool *)ptr)?"selected":"");
382 printf("</select>");
383 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
384 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
385 break;
387 case P_INTEGER:
388 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
389 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
390 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
391 break;
393 case P_OCTAL: {
394 char *o;
395 o = octal_string(*(int *)ptr);
396 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
397 make_parm_name(parm->label), o);
398 TALLOC_FREE(o);
399 o = octal_string((int)(parm->def.ivalue));
400 printf("<input type=button value=\"%s\" "
401 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
402 _("Set Default"), make_parm_name(parm->label), o);
403 TALLOC_FREE(o);
404 break;
407 case P_ENUM:
408 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
409 for (i=0;parm->enum_list[i].name;i++) {
410 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
411 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
414 printf("</select>");
415 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
416 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
417 break;
418 case P_SEP:
419 break;
421 printf("</td></tr>\n");
422 TALLOC_FREE(ctx);
425 /****************************************************************************
426 display a set of parameters for a service
427 ****************************************************************************/
428 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
430 int i = 0;
431 struct parm_struct *parm;
432 const char *heading = NULL;
433 const char *last_heading = NULL;
435 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
436 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
437 continue;
438 if (parm->p_class == P_SEPARATOR) {
439 heading = parm->label;
440 continue;
442 if (parm->flags & FLAG_HIDE) continue;
443 if (snum >= 0) {
444 if (printers & !(parm->flags & FLAG_PRINT)) continue;
445 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
448 if (!( parm_filter & FLAG_ADVANCED )) {
449 if (!(parm->flags & FLAG_BASIC)) {
450 void *ptr = parm->ptr;
452 if (parm->p_class == P_LOCAL && snum >= 0) {
453 ptr = lp_local_ptr(snum, ptr);
456 switch (parm->type) {
457 case P_CHAR:
458 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
459 break;
461 case P_LIST:
462 if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
463 break;
465 case P_STRING:
466 case P_USTRING:
467 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
468 break;
470 case P_BOOL:
471 case P_BOOLREV:
472 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
473 break;
475 case P_INTEGER:
476 case P_OCTAL:
477 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
478 break;
481 case P_ENUM:
482 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
483 break;
484 case P_SEP:
485 continue;
488 if (printers && !(parm->flags & FLAG_PRINT)) continue;
491 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
493 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
495 if (heading && heading != last_heading) {
496 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
497 last_heading = heading;
499 show_parameter(snum, parm);
503 /****************************************************************************
504 load the smb.conf file into loadparm.
505 ****************************************************************************/
506 static bool load_config(bool save_def)
508 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
511 /****************************************************************************
512 write a config file
513 ****************************************************************************/
514 static void write_config(FILE *f, bool show_defaults)
516 TALLOC_CTX *ctx = talloc_stackframe();
518 fprintf(f, "# Samba config file created using SWAT\n");
519 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
520 fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
522 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
524 TALLOC_FREE(ctx);
527 /****************************************************************************
528 save and reload the smb.conf config file
529 ****************************************************************************/
530 static int save_reload(int snum)
532 FILE *f;
533 struct stat st;
535 f = sys_fopen(get_dyn_CONFIGFILE(),"w");
536 if (!f) {
537 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
538 printf("\n");
539 return 0;
542 /* just in case they have used the buggy xinetd to create the file */
543 if (fstat(fileno(f), &st) == 0 &&
544 (st.st_mode & S_IWOTH)) {
545 #if defined HAVE_FCHMOD
546 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
547 #else
548 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
549 #endif
552 write_config(f, False);
553 if (snum >= 0)
554 lp_dump_one(f, False, snum);
555 fclose(f);
557 lp_kill_all_services();
559 if (!load_config(False)) {
560 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
561 printf("\n");
562 return 0;
564 iNumNonAutoPrintServices = lp_numservices();
565 load_printers();
567 return 1;
570 /****************************************************************************
571 commit one parameter
572 ****************************************************************************/
573 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
575 int i;
576 char *s;
578 if (snum < 0 && parm->p_class == P_LOCAL) {
579 /* this handles the case where we are changing a local
580 variable globally. We need to change the parameter in
581 all shares where it is currently set to the default */
582 for (i=0;i<lp_numservices();i++) {
583 s = lp_servicename(i);
584 if (s && (*s) && lp_is_default(i, parm)) {
585 lp_do_parameter(i, parm->label, v);
590 lp_do_parameter(snum, parm->label, v);
593 /****************************************************************************
594 commit a set of parameters for a service
595 ****************************************************************************/
596 static void commit_parameters(int snum)
598 int i = 0;
599 struct parm_struct *parm;
600 char *label;
601 const char *v;
603 while ((parm = lp_next_parameter(snum, &i, 1))) {
604 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
605 if ((v = cgi_variable(label)) != NULL) {
606 if (parm->flags & FLAG_HIDE)
607 continue;
608 commit_parameter(snum, parm, v);
610 SAFE_FREE(label);
615 /****************************************************************************
616 spit out the html for a link with an image
617 ****************************************************************************/
618 static void image_link(const char *name, const char *hlink, const char *src)
620 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
621 cgi_baseurl(), hlink, src, name);
624 /****************************************************************************
625 display the main navigation controls at the top of each page along
626 with a title
627 ****************************************************************************/
628 static void show_main_buttons(void)
630 char *p;
632 if ((p = cgi_user_name()) && strcmp(p, "root")) {
633 printf(_("Logged in as <b>%s</b>"), p);
634 printf("<p>\n");
637 image_link(_("Home"), "", "images/home.gif");
638 if (have_write_access) {
639 image_link(_("Globals"), "globals", "images/globals.gif");
640 image_link(_("Shares"), "shares", "images/shares.gif");
641 image_link(_("Printers"), "printers", "images/printers.gif");
642 image_link(_("Wizard"), "wizard", "images/wizard.gif");
644 /* root always gets all buttons, otherwise look for -P */
645 if ( have_write_access || (!passwd_only && have_read_access) ) {
646 image_link(_("Status"), "status", "images/status.gif");
647 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
649 image_link(_("Password Management"), "passwd", "images/passwd.gif");
651 printf("<HR>\n");
654 /****************************************************************************
655 * Handle Display/Edit Mode CGI
656 ****************************************************************************/
657 static void ViewModeBoxes(int mode)
659 printf("<p>%s:&nbsp;\n", _("Current View Is"));
660 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
661 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
662 printf("<br>%s:&nbsp;\n", _("Change View To"));
663 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
664 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
665 printf("</p><br>\n");
668 /****************************************************************************
669 display a welcome page
670 ****************************************************************************/
671 static void welcome_page(void)
673 if (file_exist("help/welcome.html", NULL)) {
674 include_html("help/welcome.html");
675 } else {
676 include_html("help/welcome-no-samba-doc.html");
680 /****************************************************************************
681 display the current smb.conf
682 ****************************************************************************/
683 static void viewconfig_page(void)
685 int full_view=0;
686 const char form_name[] = "viewconfig";
688 if (!verify_xsrf_token(form_name)) {
689 goto output_page;
692 if (cgi_variable("full_view")) {
693 full_view = 1;
696 output_page:
697 printf("<H2>%s</H2>\n", _("Current Config"));
698 printf("<form method=post>\n");
699 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
701 if (full_view) {
702 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
703 } else {
704 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
707 printf("<p><pre>");
708 write_config(stdout, full_view);
709 printf("</pre>");
710 printf("</form>\n");
713 /****************************************************************************
714 second screen of the wizard ... Fetch Configuration Parameters
715 ****************************************************************************/
716 static void wizard_params_page(void)
718 unsigned int parm_filter = FLAG_WIZARD;
719 const char form_name[] = "wizard_params";
721 /* Here we first set and commit all the parameters that were selected
722 in the previous screen. */
724 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
726 if (!verify_xsrf_token(form_name)) {
727 goto output_page;
730 if (cgi_variable("Commit")) {
731 commit_parameters(GLOBAL_SECTION_SNUM);
732 save_reload(0);
735 output_page:
736 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
737 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
739 if (have_write_access) {
740 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
743 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
744 printf("<p>\n");
746 printf("<table>\n");
747 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
748 printf("</table>\n");
749 printf("</form>\n");
752 /****************************************************************************
753 Utility to just rewrite the smb.conf file - effectively just cleans it up
754 ****************************************************************************/
755 static void rewritecfg_file(void)
757 commit_parameters(GLOBAL_SECTION_SNUM);
758 save_reload(0);
759 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
762 /****************************************************************************
763 wizard to create/modify the smb.conf file
764 ****************************************************************************/
765 static void wizard_page(void)
767 /* Set some variables to collect data from smb.conf */
768 int role = 0;
769 int winstype = 0;
770 int have_home = -1;
771 int HomeExpo = 0;
772 int SerType = 0;
773 const char form_name[] = "wizard";
775 if (!verify_xsrf_token(form_name)) {
776 goto output_page;
779 if (cgi_variable("Rewrite")) {
780 (void) rewritecfg_file();
781 return;
784 if (cgi_variable("GetWizardParams")){
785 (void) wizard_params_page();
786 return;
789 if (cgi_variable("Commit")){
790 SerType = atoi(cgi_variable_nonull("ServerType"));
791 winstype = atoi(cgi_variable_nonull("WINSType"));
792 have_home = lp_servicenumber(HOMES_NAME);
793 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
795 /* Plain text passwords are too badly broken - use encrypted passwords only */
796 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
798 switch ( SerType ){
799 case 0:
800 /* Stand-alone Server */
801 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
802 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
803 break;
804 case 1:
805 /* Domain Member */
806 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
807 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
808 break;
809 case 2:
810 /* Domain Controller */
811 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
812 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
813 break;
815 switch ( winstype ) {
816 case 0:
817 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
818 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
819 break;
820 case 1:
821 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
822 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
823 break;
824 case 2:
825 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
826 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
827 break;
830 /* Have to create Homes share? */
831 if ((HomeExpo == 1) && (have_home == -1)) {
832 const char *unix_share = HOMES_NAME;
834 load_config(False);
835 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
836 have_home = lp_servicenumber(HOMES_NAME);
837 lp_do_parameter( have_home, "read only", "No");
838 lp_do_parameter( have_home, "valid users", "%S");
839 lp_do_parameter( have_home, "browseable", "No");
840 commit_parameters(have_home);
841 save_reload(have_home);
844 /* Need to Delete Homes share? */
845 if ((HomeExpo == 0) && (have_home != -1)) {
846 lp_remove_service(have_home);
847 have_home = -1;
850 commit_parameters(GLOBAL_SECTION_SNUM);
851 save_reload(0);
853 else
855 /* Now determine smb.conf WINS settings */
856 if (lp_wins_support())
857 winstype = 1;
858 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
859 winstype = 2;
861 /* Do we have a homes share? */
862 have_home = lp_servicenumber(HOMES_NAME);
864 if ((winstype == 2) && lp_wins_support())
865 winstype = 3;
867 role = lp_server_role();
869 output_page:
870 /* Here we go ... */
871 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
872 printf("<form method=post action=wizard>\n");
873 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
875 if (have_write_access) {
876 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
877 printf("%s", _("The same will happen if you press the commit button."));
878 printf("<br><br>\n");
879 printf("<center>");
880 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
881 printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
882 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
883 printf("</center>\n");
886 printf("<hr>");
887 printf("<center><table border=0>");
888 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
889 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
890 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
891 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
892 printf("</tr>\n");
893 if (role == ROLE_DOMAIN_BDC) {
894 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
896 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
897 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
898 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
899 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
900 printf("</tr>\n");
901 printf("<tr><td></td><td></td><td></td><td>%s&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
903 /* Print out the list of wins servers */
904 if(lp_wins_server_list()) {
905 int i;
906 const char **wins_servers = lp_wins_server_list();
907 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
910 printf("\"></td></tr>\n");
911 if (winstype == 3) {
912 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"));
913 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
915 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
916 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
917 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
918 printf("<td></td></tr>\n");
920 /* Enable this when we are ready ....
921 * printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
922 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
923 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
924 * printf("<td></td></tr>\n");
927 printf("</table></center>");
928 printf("<hr>");
930 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
931 printf("</form>\n");
935 /****************************************************************************
936 display a globals editing page
937 ****************************************************************************/
938 static void globals_page(void)
940 unsigned int parm_filter = FLAG_BASIC;
941 int mode = 0;
942 const char form_name[] = "globals";
944 printf("<H2>%s</H2>\n", _("Global Parameters"));
946 if (!verify_xsrf_token(form_name)) {
947 goto output_page;
950 if (cgi_variable("Commit")) {
951 commit_parameters(GLOBAL_SECTION_SNUM);
952 save_reload(0);
955 if ( cgi_variable("ViewMode") )
956 mode = atoi(cgi_variable_nonull("ViewMode"));
957 if ( cgi_variable("BasicMode"))
958 mode = 0;
959 if ( cgi_variable("AdvMode"))
960 mode = 1;
962 output_page:
963 printf("<form name=\"swatform\" method=post action=globals>\n");
964 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
966 ViewModeBoxes( mode );
967 switch ( mode ) {
968 case 0:
969 parm_filter = FLAG_BASIC;
970 break;
971 case 1:
972 parm_filter = FLAG_ADVANCED;
973 break;
975 printf("<br>\n");
976 if (have_write_access) {
977 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
978 _("Commit Changes"));
981 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
982 _("Reset Values"));
984 printf("<p>\n");
985 printf("<table>\n");
986 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
987 printf("</table>\n");
988 printf("</form>\n");
991 /****************************************************************************
992 display a shares editing page. share is in unix codepage,
993 ****************************************************************************/
994 static void shares_page(void)
996 const char *share = cgi_variable("share");
997 char *s;
998 char *utf8_s;
999 int snum = -1;
1000 int i;
1001 int mode = 0;
1002 unsigned int parm_filter = FLAG_BASIC;
1003 size_t converted_size;
1004 const char form_name[] = "shares";
1006 printf("<H2>%s</H2>\n", _("Share Parameters"));
1008 if (!verify_xsrf_token(form_name)) {
1009 goto output_page;
1012 if (share)
1013 snum = lp_servicenumber(share);
1016 if (cgi_variable("Commit") && snum >= 0) {
1017 commit_parameters(snum);
1018 save_reload(0);
1019 snum = lp_servicenumber(share);
1022 if (cgi_variable("Delete") && snum >= 0) {
1023 lp_remove_service(snum);
1024 save_reload(0);
1025 share = NULL;
1026 snum = -1;
1029 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1030 snum = lp_servicenumber(share);
1031 if (snum < 0) {
1032 load_config(False);
1033 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1034 snum = lp_servicenumber(share);
1035 save_reload(snum);
1036 snum = lp_servicenumber(share);
1040 if ( cgi_variable("ViewMode") )
1041 mode = atoi(cgi_variable_nonull("ViewMode"));
1042 if ( cgi_variable("BasicMode"))
1043 mode = 0;
1044 if ( cgi_variable("AdvMode"))
1045 mode = 1;
1047 output_page:
1048 printf("<FORM name=\"swatform\" method=post>\n");
1049 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1051 printf("<table>\n");
1053 ViewModeBoxes( mode );
1054 switch ( mode ) {
1055 case 0:
1056 parm_filter = FLAG_BASIC;
1057 break;
1058 case 1:
1059 parm_filter = FLAG_ADVANCED;
1060 break;
1062 printf("<br><tr>\n");
1063 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1064 printf("<td><select name=share>\n");
1065 if (snum < 0)
1066 printf("<option value=\" \"> \n");
1067 for (i=0;i<lp_numservices();i++) {
1068 s = lp_servicename(i);
1069 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
1070 push_utf8_allocate(&utf8_s, s, &converted_size);
1071 printf("<option %s value=\"%s\">%s\n",
1072 (share && strcmp(share,s)==0)?"SELECTED":"",
1073 utf8_s, utf8_s);
1074 SAFE_FREE(utf8_s);
1077 printf("</select></td>\n");
1078 if (have_write_access) {
1079 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1081 printf("</tr>\n");
1082 printf("</table>");
1083 printf("<table>");
1084 if (have_write_access) {
1085 printf("<tr>\n");
1086 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1087 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1089 printf("</table>");
1092 if (snum >= 0) {
1093 if (have_write_access) {
1094 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1097 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1098 printf("<p>\n");
1101 if (snum >= 0) {
1102 printf("<table>\n");
1103 show_parameters(snum, 1, parm_filter, 0);
1104 printf("</table>\n");
1107 printf("</FORM>\n");
1110 /*************************************************************
1111 change a password either locally or remotely
1112 *************************************************************/
1113 static bool change_password(const char *remote_machine, const char *user_name,
1114 const char *old_passwd, const char *new_passwd,
1115 int local_flags)
1117 NTSTATUS ret;
1118 char *err_str = NULL;
1119 char *msg_str = NULL;
1121 if (demo_mode) {
1122 printf("%s\n<p>", _("password change in demo mode rejected"));
1123 return False;
1126 if (remote_machine != NULL) {
1127 ret = remote_password_change(remote_machine, user_name,
1128 old_passwd, new_passwd, &err_str);
1129 if (err_str != NULL)
1130 printf("%s\n<p>", err_str);
1131 SAFE_FREE(err_str);
1132 return NT_STATUS_IS_OK(ret);
1135 if(!initialize_password_db(True, NULL)) {
1136 printf("%s\n<p>", _("Can't setup password database vectors."));
1137 return False;
1140 ret = local_password_change(user_name, local_flags, new_passwd,
1141 &err_str, &msg_str);
1143 if(msg_str)
1144 printf("%s\n<p>", msg_str);
1145 if(err_str)
1146 printf("%s\n<p>", err_str);
1148 SAFE_FREE(msg_str);
1149 SAFE_FREE(err_str);
1150 return NT_STATUS_IS_OK(ret);
1153 /****************************************************************************
1154 do the stuff required to add or change a password
1155 ****************************************************************************/
1156 static void chg_passwd(void)
1158 const char *host;
1159 bool rslt;
1160 int local_flags = 0;
1162 /* Make sure users name has been specified */
1163 if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1164 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1165 return;
1169 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1170 * so if that's what we're doing, skip the rest of the checks
1172 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1175 * If current user is not root, make sure old password has been specified
1176 * If REMOTE change, even root must provide old password
1178 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1179 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1180 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1181 return;
1184 /* If changing a users password on a remote hosts we have to know what host */
1185 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1186 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1187 return;
1190 /* Make sure new passwords have been specified */
1191 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1192 (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1193 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1194 return;
1197 /* Make sure new passwords was typed correctly twice */
1198 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1199 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1200 return;
1204 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1205 host = cgi_variable(RHOST);
1206 } else if (am_root()) {
1207 host = NULL;
1208 } else {
1209 host = "127.0.0.1";
1213 * Set up the local flags.
1216 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1217 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1218 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1219 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1220 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1221 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1224 rslt = change_password(host,
1225 cgi_variable_nonull(SWAT_USER),
1226 cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1227 local_flags);
1229 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1230 printf("<p>");
1231 if (rslt == True) {
1232 printf("%s\n", _(" The passwd has been changed."));
1233 } else {
1234 printf("%s\n", _(" The passwd for has NOT been changed."));
1238 return;
1241 /****************************************************************************
1242 display a password editing page
1243 ****************************************************************************/
1244 static void passwd_page(void)
1246 const char *new_name = cgi_user_name();
1247 const char passwd_form[] = "passwd";
1248 const char rpasswd_form[] = "rpasswd";
1250 if (!new_name) new_name = "";
1252 printf("<H2>%s</H2>\n", _("Server Password Management"));
1254 printf("<FORM name=\"swatform\" method=post>\n");
1255 print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form);
1257 printf("<table>\n");
1260 * Create all the dialog boxes for data collection
1262 printf("<tr><td> %s : </td>\n", _("User Name"));
1263 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1264 if (!am_root()) {
1265 printf("<tr><td> %s : </td>\n", _("Old Password"));
1266 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1268 printf("<tr><td> %s : </td>\n", _("New Password"));
1269 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1270 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1271 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1272 printf("</table>\n");
1275 * Create all the control buttons for requesting action
1277 printf("<input type=submit name=%s value=\"%s\">\n",
1278 CHG_S_PASSWD_FLAG, _("Change Password"));
1279 if (demo_mode || am_root()) {
1280 printf("<input type=submit name=%s value=\"%s\">\n",
1281 ADD_USER_FLAG, _("Add New User"));
1282 printf("<input type=submit name=%s value=\"%s\">\n",
1283 DELETE_USER_FLAG, _("Delete User"));
1284 printf("<input type=submit name=%s value=\"%s\">\n",
1285 DISABLE_USER_FLAG, _("Disable User"));
1286 printf("<input type=submit name=%s value=\"%s\">\n",
1287 ENABLE_USER_FLAG, _("Enable User"));
1289 printf("<p></FORM>\n");
1292 * Do some work if change, add, disable or enable was
1293 * requested. It could be this is the first time through this
1294 * code, so there isn't anything to do. */
1295 if (verify_xsrf_token(passwd_form) &&
1296 ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1297 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG)))) {
1298 chg_passwd();
1301 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1303 printf("<FORM name=\"swatform\" method=post>\n");
1304 print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form);
1306 printf("<table>\n");
1309 * Create all the dialog boxes for data collection
1311 printf("<tr><td> %s : </td>\n", _("User Name"));
1312 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1313 printf("<tr><td> %s : </td>\n", _("Old Password"));
1314 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1315 printf("<tr><td> %s : </td>\n", _("New Password"));
1316 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1317 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1318 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1319 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1320 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1322 printf("</table>");
1325 * Create all the control buttons for requesting action
1327 printf("<input type=submit name=%s value=\"%s\">",
1328 CHG_R_PASSWD_FLAG, _("Change Password"));
1330 printf("<p></FORM>\n");
1333 * Do some work if a request has been made to change the
1334 * password somewhere other than the server. It could be this
1335 * is the first time through this code, so there isn't
1336 * anything to do. */
1337 if (verify_xsrf_token(passwd_form) && cgi_variable(CHG_R_PASSWD_FLAG)) {
1338 chg_passwd();
1343 /****************************************************************************
1344 display a printers editing page
1345 ****************************************************************************/
1346 static void printers_page(void)
1348 const char *share = cgi_variable("share");
1349 char *s;
1350 int snum=-1;
1351 int i;
1352 int mode = 0;
1353 unsigned int parm_filter = FLAG_BASIC;
1354 const char form_name[] = "printers";
1356 if (!verify_xsrf_token(form_name)) {
1357 goto output_page;
1360 if (share)
1361 snum = lp_servicenumber(share);
1363 if (cgi_variable("Commit") && snum >= 0) {
1364 commit_parameters(snum);
1365 if (snum >= iNumNonAutoPrintServices)
1366 save_reload(snum);
1367 else
1368 save_reload(0);
1369 snum = lp_servicenumber(share);
1372 if (cgi_variable("Delete") && snum >= 0) {
1373 lp_remove_service(snum);
1374 save_reload(0);
1375 share = NULL;
1376 snum = -1;
1379 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1380 snum = lp_servicenumber(share);
1381 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1382 load_config(False);
1383 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1384 snum = lp_servicenumber(share);
1385 lp_do_parameter(snum, "print ok", "Yes");
1386 save_reload(snum);
1387 snum = lp_servicenumber(share);
1391 if ( cgi_variable("ViewMode") )
1392 mode = atoi(cgi_variable_nonull("ViewMode"));
1393 if ( cgi_variable("BasicMode"))
1394 mode = 0;
1395 if ( cgi_variable("AdvMode"))
1396 mode = 1;
1398 output_page:
1399 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1401 printf("<H3>%s</H3>\n", _("Important Note:"));
1402 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1403 printf("%s",_("are autoloaded printers from "));
1404 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1405 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1408 printf("<FORM name=\"swatform\" method=post>\n");
1409 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1411 ViewModeBoxes( mode );
1412 switch ( mode ) {
1413 case 0:
1414 parm_filter = FLAG_BASIC;
1415 break;
1416 case 1:
1417 parm_filter = FLAG_ADVANCED;
1418 break;
1420 printf("<table>\n");
1421 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1422 printf("<td><select name=\"share\">\n");
1423 if (snum < 0 || !lp_print_ok(snum))
1424 printf("<option value=\" \"> \n");
1425 for (i=0;i<lp_numservices();i++) {
1426 s = lp_servicename(i);
1427 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1428 if (i >= iNumNonAutoPrintServices)
1429 printf("<option %s value=\"%s\">[*]%s\n",
1430 (share && strcmp(share,s)==0)?"SELECTED":"",
1431 s, s);
1432 else
1433 printf("<option %s value=\"%s\">%s\n",
1434 (share && strcmp(share,s)==0)?"SELECTED":"",
1435 s, s);
1438 printf("</select></td>");
1439 if (have_write_access) {
1440 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1442 printf("</tr>");
1443 printf("</table>\n");
1445 if (have_write_access) {
1446 printf("<table>\n");
1447 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1448 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1449 printf("</table>");
1453 if (snum >= 0) {
1454 if (have_write_access) {
1455 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1457 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1458 printf("<p>\n");
1461 if (snum >= 0) {
1462 printf("<table>\n");
1463 show_parameters(snum, 1, parm_filter, 1);
1464 printf("</table>\n");
1466 printf("</FORM>\n");
1470 when the _() translation macro is used there is no obvious place to free
1471 the resulting string and there is no easy way to give a static pointer.
1472 All we can do is rotate between some static buffers and hope a single d_printf()
1473 doesn't have more calls to _() than the number of buffers
1476 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1478 const char *msgstr;
1479 const char *ret;
1481 msgstr = lang_msg(msgid);
1482 if (!msgstr) {
1483 return msgid;
1486 ret = talloc_strdup(ctx, msgstr);
1488 lang_msg_free(msgstr);
1489 if (!ret) {
1490 return msgid;
1493 return ret;
1497 * main function for SWAT.
1499 int main(int argc, char *argv[])
1501 const char *page;
1502 poptContext pc;
1503 struct poptOption long_options[] = {
1504 POPT_AUTOHELP
1505 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1506 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1507 POPT_COMMON_SAMBA
1508 POPT_TABLEEND
1510 TALLOC_CTX *frame = talloc_stackframe();
1512 fault_setup(NULL);
1513 umask(S_IWGRP | S_IWOTH);
1515 #if defined(HAVE_SET_AUTH_PARAMETERS)
1516 set_auth_parameters(argc, argv);
1517 #endif /* HAVE_SET_AUTH_PARAMETERS */
1519 /* just in case it goes wild ... */
1520 alarm(300);
1522 setlinebuf(stdout);
1524 /* we don't want any SIGPIPE messages */
1525 BlockSignals(True,SIGPIPE);
1527 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1528 if (!dbf) dbf = x_stderr;
1530 /* we don't want stderr screwing us up */
1531 close(2);
1532 open("/dev/null", O_WRONLY);
1534 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1536 /* Parse command line options */
1538 while(poptGetNextOpt(pc) != -1) { }
1540 poptFreeContext(pc);
1542 load_case_tables();
1544 setup_logging(argv[0],False);
1545 load_config(True);
1546 load_interfaces();
1547 iNumNonAutoPrintServices = lp_numservices();
1548 load_printers();
1550 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1552 print_header();
1554 cgi_load_variables();
1556 if (!file_exist(get_dyn_CONFIGFILE(), NULL)) {
1557 have_read_access = True;
1558 have_write_access = True;
1559 } else {
1560 /* check if the authenticated user has write access - if not then
1561 don't show write options */
1562 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1564 /* if the user doesn't have read access to smb.conf then
1565 don't let them view it */
1566 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1569 show_main_buttons();
1571 page = cgi_pathinfo();
1573 /* Root gets full functionality */
1574 if (have_read_access && strcmp(page, "globals")==0) {
1575 globals_page();
1576 } else if (have_read_access && strcmp(page,"shares")==0) {
1577 shares_page();
1578 } else if (have_read_access && strcmp(page,"printers")==0) {
1579 printers_page();
1580 } else if (have_read_access && strcmp(page,"status")==0) {
1581 status_page();
1582 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1583 viewconfig_page();
1584 } else if (strcmp(page,"passwd")==0) {
1585 passwd_page();
1586 } else if (have_read_access && strcmp(page,"wizard")==0) {
1587 wizard_page();
1588 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1589 wizard_params_page();
1590 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1591 rewritecfg_file();
1592 } else {
1593 welcome_page();
1596 print_footer();
1598 TALLOC_FREE(frame);
1599 return 0;
1602 /** @} **/