s3: Fix bug #9085.
[Samba.git] / source3 / web / swat.c
blob754e3cee732fec28583b221581ba8cb118e441d4
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"
55 #define XSRF_TIME "xsrf_time"
56 #define XSRF_TIMEOUT 300
58 #define _(x) lang_msg_rotate(talloc_tos(),x)
60 /****************************************************************************
61 ****************************************************************************/
62 static int enum_index(int value, const struct enum_list *enumlist)
64 int i;
65 for (i=0;enumlist[i].name;i++)
66 if (value == enumlist[i].value) break;
67 return(i);
70 static char *fix_backslash(const char *str)
72 static char newstring[1024];
73 char *p = newstring;
75 while (*str) {
76 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
77 else *p++ = *str;
78 ++str;
80 *p = '\0';
81 return newstring;
84 static const char *fix_quotes(TALLOC_CTX *ctx, const char *str)
86 char *newstring = NULL;
87 char *p = NULL;
88 size_t newstring_len;
89 int quote_len = strlen("&quot;");
91 /* Count the number of quotes. */
92 newstring_len = 1;
93 p = (char *) str;
94 while (*p) {
95 if ( *p == '\"') {
96 newstring_len += quote_len;
97 } else {
98 newstring_len++;
100 ++p;
102 newstring = TALLOC_ARRAY(ctx, char, newstring_len);
103 if (!newstring) {
104 return "";
106 for (p = newstring; *str; str++) {
107 if ( *str == '\"') {
108 strncpy( p, "&quot;", quote_len);
109 p += quote_len;
110 } else {
111 *p++ = *str;
114 *p = '\0';
115 return newstring;
118 static char *stripspaceupper(const char *str)
120 static char newstring[1024];
121 char *p = newstring;
123 while (*str) {
124 if (*str != ' ') *p++ = toupper_ascii(*str);
125 ++str;
127 *p = '\0';
128 return newstring;
131 static char *make_parm_name(const char *label)
133 static char parmname[1024];
134 char *p = parmname;
136 while (*label) {
137 if (*label == ' ') *p++ = '_';
138 else *p++ = *label;
139 ++label;
141 *p = '\0';
142 return parmname;
145 void get_xsrf_token(const char *username, const char *pass,
146 const char *formname, time_t xsrf_time, char token_str[33])
148 struct MD5Context md5_ctx;
149 uint8_t token[16];
150 int i;
152 token_str[0] = '\0';
153 ZERO_STRUCT(md5_ctx);
154 MD5Init(&md5_ctx);
156 MD5Update(&md5_ctx, (uint8_t *)formname, strlen(formname));
157 MD5Update(&md5_ctx, (uint8_t *)&xsrf_time, sizeof(time_t));
158 if (username != NULL) {
159 MD5Update(&md5_ctx, (uint8_t *)username, strlen(username));
161 if (pass != NULL) {
162 MD5Update(&md5_ctx, (uint8_t *)pass, strlen(pass));
165 MD5Final(token, &md5_ctx);
167 for(i = 0; i < sizeof(token); i++) {
168 char tmp[3];
170 snprintf(tmp, sizeof(tmp), "%02x", token[i]);
171 strlcat(token_str, tmp, sizeof(tmp));
175 void print_xsrf_token(const char *username, const char *pass,
176 const char *formname)
178 char token[33];
179 time_t xsrf_time = time(NULL);
181 get_xsrf_token(username, pass, formname, xsrf_time, token);
182 printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
183 XSRF_TOKEN, token);
184 printf("<input type=\"hidden\" name=\"%s\" value=\"%lld\">\n",
185 XSRF_TIME, (long long int)xsrf_time);
188 bool verify_xsrf_token(const char *formname)
190 char expected[33];
191 const char *username = cgi_user_name();
192 const char *pass = cgi_user_pass();
193 const char *token = cgi_variable_nonull(XSRF_TOKEN);
194 const char *time_str = cgi_variable_nonull(XSRF_TIME);
195 char *p = NULL;
196 long long xsrf_time_ll = 0;
197 time_t xsrf_time = 0;
198 time_t now = time(NULL);
200 errno = 0;
201 xsrf_time_ll = strtoll(time_str, &p, 10);
202 if (errno != 0) {
203 return false;
205 if (p == NULL) {
206 return false;
208 if (PTR_DIFF(p, time_str) > strlen(time_str)) {
209 return false;
211 if (xsrf_time_ll > _TYPE_MAXIMUM(time_t)) {
212 return false;
214 if (xsrf_time_ll < _TYPE_MINIMUM(time_t)) {
215 return false;
217 xsrf_time = xsrf_time_ll;
219 if (abs(now - xsrf_time) > XSRF_TIMEOUT) {
220 return false;
223 get_xsrf_token(username, pass, formname, xsrf_time, expected);
224 return (strncmp(expected, token, sizeof(expected)) == 0);
228 /****************************************************************************
229 include a lump of html in a page
230 ****************************************************************************/
231 static int include_html(const char *fname)
233 int fd;
234 char buf[1024];
235 int ret;
237 fd = web_open(fname, O_RDONLY, 0);
239 if (fd == -1) {
240 printf(_("ERROR: Can't open %s"), fname);
241 printf("\n");
242 return 0;
245 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
246 if (write(1, buf, ret) == -1) {
247 break;
251 close(fd);
252 return 1;
255 /****************************************************************************
256 start the page with standard stuff
257 ****************************************************************************/
258 static void print_header(void)
260 if (!cgi_waspost()) {
261 printf("Expires: 0\r\n");
263 printf("Content-type: text/html\r\n\r\n");
265 if (!include_html("include/header.html")) {
266 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
267 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
271 /* *******************************************************************
272 show parameter label with translated name in the following form
273 because showing original and translated label in one line looks
274 too long, and showing translated label only is unusable for
275 heavy users.
276 -------------------------------
277 HELP security [combo box][button]
278 SECURITY
279 -------------------------------
280 (capital words are translated by gettext.)
281 if no translation is available, then same form as original is
282 used.
283 "i18n_translated_parm" class is used to change the color of the
284 translated parameter with CSS.
285 **************************************************************** */
286 static const char *get_parm_translated(TALLOC_CTX *ctx,
287 const char* pAnchor, const char* pHelp, const char* pLabel)
289 const char *pTranslated = _(pLabel);
290 char *output;
291 if(strcmp(pLabel, pTranslated) != 0) {
292 output = talloc_asprintf(ctx,
293 "<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>",
294 pAnchor, pHelp, pLabel, pTranslated);
295 return output;
297 output = talloc_asprintf(ctx,
298 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
299 pAnchor, pHelp, pLabel);
300 return output;
302 /****************************************************************************
303 finish off the page
304 ****************************************************************************/
305 static void print_footer(void)
307 if (!include_html("include/footer.html")) {
308 printf("\n</BODY>\n</HTML>\n");
312 /****************************************************************************
313 display one editable parameter in a form
314 ****************************************************************************/
315 static void show_parameter(int snum, struct parm_struct *parm)
317 int i;
318 void *ptr = parm->ptr;
319 char *utf8_s1, *utf8_s2;
320 size_t converted_size;
321 TALLOC_CTX *ctx = talloc_stackframe();
323 if (parm->p_class == P_LOCAL && snum >= 0) {
324 ptr = lp_local_ptr_by_snum(snum, ptr);
327 printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
328 stripspaceupper(parm->label), _("Help"), parm->label));
329 switch (parm->type) {
330 case P_CHAR:
331 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
332 make_parm_name(parm->label), *(char *)ptr);
333 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
334 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
335 break;
337 case P_LIST:
338 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
339 make_parm_name(parm->label));
340 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
341 char **list = *(char ***)ptr;
342 for (;*list;list++) {
343 /* enclose in HTML encoded quotes if the string contains a space */
344 if ( strchr_m(*list, ' ') ) {
345 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
346 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
347 printf("&quot;%s&quot;%s", utf8_s1, utf8_s2);
348 } else {
349 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
350 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
351 printf("%s%s", utf8_s1, utf8_s2);
353 TALLOC_FREE(utf8_s1);
354 TALLOC_FREE(utf8_s2);
357 printf("\">");
358 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
359 _("Set Default"), make_parm_name(parm->label));
360 if (parm->def.lvalue) {
361 char **list = (char **)(parm->def.lvalue);
362 for (; *list; list++) {
363 /* enclose in HTML encoded quotes if the string contains a space */
364 if ( strchr_m(*list, ' ') )
365 printf("&quot;%s&quot;%s", *list, ((*(list+1))?", ":""));
366 else
367 printf("%s%s", *list, ((*(list+1))?", ":""));
370 printf("\'\">");
371 break;
373 case P_STRING:
374 case P_USTRING:
375 push_utf8_talloc(talloc_tos(), &utf8_s1, *(char **)ptr, &converted_size);
376 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
377 make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
378 TALLOC_FREE(utf8_s1);
379 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
380 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
381 break;
383 case P_BOOL:
384 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
385 printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
386 printf("<option %s>No", (*(bool *)ptr)?"":"selected");
387 printf("</select>");
388 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
389 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
390 break;
392 case P_BOOLREV:
393 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
394 printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
395 printf("<option %s>No", (*(bool *)ptr)?"selected":"");
396 printf("</select>");
397 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
398 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
399 break;
401 case P_INTEGER:
402 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
403 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
404 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
405 break;
407 case P_OCTAL: {
408 char *o;
409 o = octal_string(*(int *)ptr);
410 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
411 make_parm_name(parm->label), o);
412 TALLOC_FREE(o);
413 o = octal_string((int)(parm->def.ivalue));
414 printf("<input type=button value=\"%s\" "
415 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
416 _("Set Default"), make_parm_name(parm->label), o);
417 TALLOC_FREE(o);
418 break;
421 case P_ENUM:
422 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
423 for (i=0;parm->enum_list[i].name;i++) {
424 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
425 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
428 printf("</select>");
429 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
430 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
431 break;
432 case P_SEP:
433 break;
435 printf("</td></tr>\n");
436 TALLOC_FREE(ctx);
439 /****************************************************************************
440 display a set of parameters for a service
441 ****************************************************************************/
442 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
444 int i = 0;
445 struct parm_struct *parm;
446 const char *heading = NULL;
447 const char *last_heading = NULL;
449 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
450 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
451 continue;
452 if (parm->p_class == P_SEPARATOR) {
453 heading = parm->label;
454 continue;
456 if (parm->flags & FLAG_HIDE) continue;
457 if (snum >= 0) {
458 if (printers & !(parm->flags & FLAG_PRINT)) continue;
459 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
462 if (!( parm_filter & FLAG_ADVANCED )) {
463 if (!(parm->flags & FLAG_BASIC)) {
464 void *ptr = parm->ptr;
466 if (parm->p_class == P_LOCAL && snum >= 0) {
467 ptr = lp_local_ptr_by_snum(snum, ptr);
470 switch (parm->type) {
471 case P_CHAR:
472 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
473 break;
475 case P_LIST:
476 if (!str_list_equal(*(const char ***)ptr,
477 (const char **)(parm->def.lvalue))) continue;
478 break;
480 case P_STRING:
481 case P_USTRING:
482 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
483 break;
485 case P_BOOL:
486 case P_BOOLREV:
487 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
488 break;
490 case P_INTEGER:
491 case P_OCTAL:
492 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
493 break;
496 case P_ENUM:
497 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
498 break;
499 case P_SEP:
500 continue;
503 if (printers && !(parm->flags & FLAG_PRINT)) continue;
506 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
508 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
510 if (heading && heading != last_heading) {
511 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
512 last_heading = heading;
514 show_parameter(snum, parm);
518 /****************************************************************************
519 load the smb.conf file into loadparm.
520 ****************************************************************************/
521 static bool load_config(bool save_def)
523 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
526 /****************************************************************************
527 write a config file
528 ****************************************************************************/
529 static void write_config(FILE *f, bool show_defaults)
531 TALLOC_CTX *ctx = talloc_stackframe();
533 fprintf(f, "# Samba config file created using SWAT\n");
534 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
535 fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
537 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
539 TALLOC_FREE(ctx);
542 /****************************************************************************
543 save and reload the smb.conf config file
544 ****************************************************************************/
545 static int save_reload(int snum)
547 FILE *f;
548 struct stat st;
550 f = sys_fopen(get_dyn_CONFIGFILE(),"w");
551 if (!f) {
552 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
553 printf("\n");
554 return 0;
557 /* just in case they have used the buggy xinetd to create the file */
558 if (fstat(fileno(f), &st) == 0 &&
559 (st.st_mode & S_IWOTH)) {
560 #if defined HAVE_FCHMOD
561 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
562 #else
563 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
564 #endif
567 write_config(f, False);
568 if (snum >= 0)
569 lp_dump_one(f, False, snum);
570 fclose(f);
572 lp_kill_all_services();
574 if (!load_config(False)) {
575 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
576 printf("\n");
577 return 0;
579 iNumNonAutoPrintServices = lp_numservices();
580 pcap_cache_reload(&load_printers);
582 return 1;
585 /****************************************************************************
586 commit one parameter
587 ****************************************************************************/
588 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
590 int i;
591 char *s;
593 if (snum < 0 && parm->p_class == P_LOCAL) {
594 /* this handles the case where we are changing a local
595 variable globally. We need to change the parameter in
596 all shares where it is currently set to the default */
597 for (i=0;i<lp_numservices();i++) {
598 s = lp_servicename(i);
599 if (s && (*s) && lp_is_default(i, parm)) {
600 lp_do_parameter(i, parm->label, v);
605 lp_do_parameter(snum, parm->label, v);
608 /****************************************************************************
609 commit a set of parameters for a service
610 ****************************************************************************/
611 static void commit_parameters(int snum)
613 int i = 0;
614 struct parm_struct *parm;
615 char *label;
616 const char *v;
618 while ((parm = lp_next_parameter(snum, &i, 1))) {
619 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
620 if ((v = cgi_variable(label)) != NULL) {
621 if (parm->flags & FLAG_HIDE)
622 continue;
623 commit_parameter(snum, parm, v);
625 SAFE_FREE(label);
630 /****************************************************************************
631 spit out the html for a link with an image
632 ****************************************************************************/
633 static void image_link(const char *name, const char *hlink, const char *src)
635 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
636 cgi_baseurl(), hlink, src, name);
639 /****************************************************************************
640 display the main navigation controls at the top of each page along
641 with a title
642 ****************************************************************************/
643 static void show_main_buttons(void)
645 char *p;
647 if ((p = cgi_user_name()) && strcmp(p, "root")) {
648 printf(_("Logged in as <b>%s</b>"), p);
649 printf("<p>\n");
652 image_link(_("Home"), "", "images/home.gif");
653 if (have_write_access) {
654 image_link(_("Globals"), "globals", "images/globals.gif");
655 image_link(_("Shares"), "shares", "images/shares.gif");
656 image_link(_("Printers"), "printers", "images/printers.gif");
657 image_link(_("Wizard"), "wizard", "images/wizard.gif");
659 /* root always gets all buttons, otherwise look for -P */
660 if ( have_write_access || (!passwd_only && have_read_access) ) {
661 image_link(_("Status"), "status", "images/status.gif");
662 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
664 image_link(_("Password Management"), "passwd", "images/passwd.gif");
666 printf("<HR>\n");
669 /****************************************************************************
670 * Handle Display/Edit Mode CGI
671 ****************************************************************************/
672 static void ViewModeBoxes(int mode)
674 printf("<p>%s:&nbsp;\n", _("Current View Is"));
675 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
676 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
677 printf("<br>%s:&nbsp;\n", _("Change View To"));
678 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
679 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
680 printf("</p><br>\n");
683 /****************************************************************************
684 display a welcome page
685 ****************************************************************************/
686 static void welcome_page(void)
688 if (file_exist("help/welcome.html")) {
689 include_html("help/welcome.html");
690 } else {
691 include_html("help/welcome-no-samba-doc.html");
695 /****************************************************************************
696 display the current smb.conf
697 ****************************************************************************/
698 static void viewconfig_page(void)
700 int full_view=0;
701 const char form_name[] = "viewconfig";
703 if (!verify_xsrf_token(form_name)) {
704 goto output_page;
707 if (cgi_variable("full_view")) {
708 full_view = 1;
711 output_page:
712 printf("<H2>%s</H2>\n", _("Current Config"));
713 printf("<form method=post>\n");
714 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
716 if (full_view) {
717 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
718 } else {
719 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
722 printf("<p><pre>");
723 write_config(stdout, full_view);
724 printf("</pre>");
725 printf("</form>\n");
728 /****************************************************************************
729 second screen of the wizard ... Fetch Configuration Parameters
730 ****************************************************************************/
731 static void wizard_params_page(void)
733 unsigned int parm_filter = FLAG_WIZARD;
734 const char form_name[] = "wizard_params";
736 /* Here we first set and commit all the parameters that were selected
737 in the previous screen. */
739 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
741 if (!verify_xsrf_token(form_name)) {
742 goto output_page;
745 if (cgi_variable("Commit")) {
746 commit_parameters(GLOBAL_SECTION_SNUM);
747 save_reload(-1);
750 output_page:
751 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
752 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
754 if (have_write_access) {
755 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
758 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
759 printf("<p>\n");
761 printf("<table>\n");
762 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
763 printf("</table>\n");
764 printf("</form>\n");
767 /****************************************************************************
768 Utility to just rewrite the smb.conf file - effectively just cleans it up
769 ****************************************************************************/
770 static void rewritecfg_file(void)
772 commit_parameters(GLOBAL_SECTION_SNUM);
773 save_reload(-1);
774 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
777 /****************************************************************************
778 wizard to create/modify the smb.conf file
779 ****************************************************************************/
780 static void wizard_page(void)
782 /* Set some variables to collect data from smb.conf */
783 int role = 0;
784 int winstype = 0;
785 int have_home = -1;
786 int HomeExpo = 0;
787 int SerType = 0;
788 const char form_name[] = "wizard";
790 if (!verify_xsrf_token(form_name)) {
791 goto output_page;
794 if (cgi_variable("Rewrite")) {
795 (void) rewritecfg_file();
796 return;
799 if (cgi_variable("GetWizardParams")){
800 (void) wizard_params_page();
801 return;
804 if (cgi_variable("Commit")){
805 SerType = atoi(cgi_variable_nonull("ServerType"));
806 winstype = atoi(cgi_variable_nonull("WINSType"));
807 have_home = lp_servicenumber(HOMES_NAME);
808 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
810 /* Plain text passwords are too badly broken - use encrypted passwords only */
811 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
813 switch ( SerType ){
814 case 0:
815 /* Stand-alone Server */
816 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
817 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
818 break;
819 case 1:
820 /* Domain Member */
821 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
822 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
823 break;
824 case 2:
825 /* Domain Controller */
826 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
827 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
828 break;
830 switch ( winstype ) {
831 case 0:
832 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
833 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
834 break;
835 case 1:
836 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
837 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
838 break;
839 case 2:
840 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
841 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
842 break;
845 /* Have to create Homes share? */
846 if ((HomeExpo == 1) && (have_home == -1)) {
847 const char *unix_share = HOMES_NAME;
849 load_config(False);
850 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
851 have_home = lp_servicenumber(HOMES_NAME);
852 lp_do_parameter( have_home, "read only", "No");
853 lp_do_parameter( have_home, "valid users", "%S");
854 lp_do_parameter( have_home, "browseable", "No");
855 commit_parameters(have_home);
856 save_reload(have_home);
859 /* Need to Delete Homes share? */
860 if ((HomeExpo == 0) && (have_home != -1)) {
861 lp_remove_service(have_home);
862 have_home = -1;
865 commit_parameters(GLOBAL_SECTION_SNUM);
866 save_reload(-1);
868 else
870 /* Now determine smb.conf WINS settings */
871 if (lp_wins_support())
872 winstype = 1;
873 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
874 winstype = 2;
876 /* Do we have a homes share? */
877 have_home = lp_servicenumber(HOMES_NAME);
879 if ((winstype == 2) && lp_wins_support())
880 winstype = 3;
882 role = lp_server_role();
884 output_page:
885 /* Here we go ... */
886 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
887 printf("<form method=post action=wizard>\n");
888 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
890 if (have_write_access) {
891 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
892 printf("%s", _("The same will happen if you press the commit button."));
893 printf("<br><br>\n");
894 printf("<center>");
895 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
896 printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
897 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
898 printf("</center>\n");
901 printf("<hr>");
902 printf("<center><table border=0>");
903 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
904 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
905 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
906 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
907 printf("</tr>\n");
908 if (role == ROLE_DOMAIN_BDC) {
909 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
911 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
912 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
913 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
914 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
915 printf("</tr>\n");
916 printf("<tr><td></td><td></td><td></td><td>%s&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
918 /* Print out the list of wins servers */
919 if(lp_wins_server_list()) {
920 int i;
921 const char **wins_servers = lp_wins_server_list();
922 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
925 printf("\"></td></tr>\n");
926 if (winstype == 3) {
927 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"));
928 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
930 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
931 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
932 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
933 printf("<td></td></tr>\n");
935 /* Enable this when we are ready ....
936 * printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
937 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
938 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
939 * printf("<td></td></tr>\n");
942 printf("</table></center>");
943 printf("<hr>");
945 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
946 printf("</form>\n");
950 /****************************************************************************
951 display a globals editing page
952 ****************************************************************************/
953 static void globals_page(void)
955 unsigned int parm_filter = FLAG_BASIC;
956 int mode = 0;
957 const char form_name[] = "globals";
959 printf("<H2>%s</H2>\n", _("Global Parameters"));
961 if (!verify_xsrf_token(form_name)) {
962 goto output_page;
965 if (cgi_variable("Commit")) {
966 commit_parameters(GLOBAL_SECTION_SNUM);
967 save_reload(-1);
970 if ( cgi_variable("ViewMode") )
971 mode = atoi(cgi_variable_nonull("ViewMode"));
972 if ( cgi_variable("BasicMode"))
973 mode = 0;
974 if ( cgi_variable("AdvMode"))
975 mode = 1;
977 output_page:
978 printf("<form name=\"swatform\" method=post action=globals>\n");
979 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
981 ViewModeBoxes( mode );
982 switch ( mode ) {
983 case 0:
984 parm_filter = FLAG_BASIC;
985 break;
986 case 1:
987 parm_filter = FLAG_ADVANCED;
988 break;
990 printf("<br>\n");
991 if (have_write_access) {
992 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
993 _("Commit Changes"));
996 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
997 _("Reset Values"));
999 printf("<p>\n");
1000 printf("<table>\n");
1001 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
1002 printf("</table>\n");
1003 printf("</form>\n");
1006 /****************************************************************************
1007 display a shares editing page. share is in unix codepage,
1008 ****************************************************************************/
1009 static void shares_page(void)
1011 const char *share = cgi_variable("share");
1012 char *s;
1013 char *utf8_s;
1014 int snum = -1;
1015 int i;
1016 int mode = 0;
1017 unsigned int parm_filter = FLAG_BASIC;
1018 size_t converted_size;
1019 const char form_name[] = "shares";
1021 printf("<H2>%s</H2>\n", _("Share Parameters"));
1023 if (!verify_xsrf_token(form_name)) {
1024 goto output_page;
1027 if (share)
1028 snum = lp_servicenumber(share);
1031 if (cgi_variable("Commit") && snum >= 0) {
1032 commit_parameters(snum);
1033 save_reload(-1);
1034 snum = lp_servicenumber(share);
1037 if (cgi_variable("Delete") && snum >= 0) {
1038 lp_remove_service(snum);
1039 save_reload(-1);
1040 share = NULL;
1041 snum = -1;
1044 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1045 snum = lp_servicenumber(share);
1046 if (snum < 0) {
1047 load_config(False);
1048 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1049 snum = lp_servicenumber(share);
1050 save_reload(snum);
1051 snum = lp_servicenumber(share);
1055 if ( cgi_variable("ViewMode") )
1056 mode = atoi(cgi_variable_nonull("ViewMode"));
1057 if ( cgi_variable("BasicMode"))
1058 mode = 0;
1059 if ( cgi_variable("AdvMode"))
1060 mode = 1;
1062 output_page:
1063 printf("<FORM name=\"swatform\" method=post>\n");
1064 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1066 printf("<table>\n");
1068 ViewModeBoxes( mode );
1069 switch ( mode ) {
1070 case 0:
1071 parm_filter = FLAG_BASIC;
1072 break;
1073 case 1:
1074 parm_filter = FLAG_ADVANCED;
1075 break;
1077 printf("<br><tr>\n");
1078 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1079 printf("<td><select name=share>\n");
1080 if (snum < 0)
1081 printf("<option value=\" \"> \n");
1082 for (i=0;i<lp_numservices();i++) {
1083 s = lp_servicename(i);
1084 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
1085 push_utf8_talloc(talloc_tos(), &utf8_s, s, &converted_size);
1086 printf("<option %s value=\"%s\">%s\n",
1087 (share && strcmp(share,s)==0)?"SELECTED":"",
1088 utf8_s, utf8_s);
1089 TALLOC_FREE(utf8_s);
1092 printf("</select></td>\n");
1093 if (have_write_access) {
1094 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1096 printf("</tr>\n");
1097 printf("</table>");
1098 printf("<table>");
1099 if (have_write_access) {
1100 printf("<tr>\n");
1101 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1102 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1104 printf("</table>");
1107 if (snum >= 0) {
1108 if (have_write_access) {
1109 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1112 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1113 printf("<p>\n");
1116 if (snum >= 0) {
1117 printf("<table>\n");
1118 show_parameters(snum, 1, parm_filter, 0);
1119 printf("</table>\n");
1122 printf("</FORM>\n");
1125 /*************************************************************
1126 change a password either locally or remotely
1127 *************************************************************/
1128 static bool change_password(const char *remote_machine, const char *user_name,
1129 const char *old_passwd, const char *new_passwd,
1130 int local_flags)
1132 NTSTATUS ret;
1133 char *err_str = NULL;
1134 char *msg_str = NULL;
1136 if (demo_mode) {
1137 printf("%s\n<p>", _("password change in demo mode rejected"));
1138 return False;
1141 if (remote_machine != NULL) {
1142 ret = remote_password_change(remote_machine, user_name,
1143 old_passwd, new_passwd, &err_str);
1144 if (err_str != NULL)
1145 printf("%s\n<p>", err_str);
1146 SAFE_FREE(err_str);
1147 return NT_STATUS_IS_OK(ret);
1150 if(!initialize_password_db(True, NULL)) {
1151 printf("%s\n<p>", _("Can't setup password database vectors."));
1152 return False;
1155 ret = local_password_change(user_name, local_flags, new_passwd,
1156 &err_str, &msg_str);
1158 if(msg_str)
1159 printf("%s\n<p>", msg_str);
1160 if(err_str)
1161 printf("%s\n<p>", err_str);
1163 SAFE_FREE(msg_str);
1164 SAFE_FREE(err_str);
1165 return NT_STATUS_IS_OK(ret);
1168 /****************************************************************************
1169 do the stuff required to add or change a password
1170 ****************************************************************************/
1171 static void chg_passwd(void)
1173 const char *host;
1174 bool rslt;
1175 int local_flags = 0;
1177 /* Make sure users name has been specified */
1178 if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1179 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1180 return;
1184 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1185 * so if that's what we're doing, skip the rest of the checks
1187 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1190 * If current user is not root, make sure old password has been specified
1191 * If REMOTE change, even root must provide old password
1193 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1194 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1195 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1196 return;
1199 /* If changing a users password on a remote hosts we have to know what host */
1200 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1201 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1202 return;
1205 /* Make sure new passwords have been specified */
1206 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1207 (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1208 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1209 return;
1212 /* Make sure new passwords was typed correctly twice */
1213 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1214 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1215 return;
1219 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1220 host = cgi_variable(RHOST);
1221 } else if (am_root()) {
1222 host = NULL;
1223 } else {
1224 host = "127.0.0.1";
1228 * Set up the local flags.
1231 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1232 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1233 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1234 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1235 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1236 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1239 rslt = change_password(host,
1240 cgi_variable_nonull(SWAT_USER),
1241 cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1242 local_flags);
1244 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1245 printf("<p>");
1246 if (rslt == True) {
1247 printf("%s\n", _(" The passwd has been changed."));
1248 } else {
1249 printf("%s\n", _(" The passwd has NOT been changed."));
1253 return;
1256 /****************************************************************************
1257 display a password editing page
1258 ****************************************************************************/
1259 static void passwd_page(void)
1261 const char *new_name = cgi_user_name();
1262 const char passwd_form[] = "passwd";
1263 const char rpasswd_form[] = "rpasswd";
1265 if (!new_name) new_name = "";
1267 printf("<H2>%s</H2>\n", _("Server Password Management"));
1269 printf("<FORM name=\"swatform\" method=post>\n");
1270 print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form);
1272 printf("<table>\n");
1275 * Create all the dialog boxes for data collection
1277 printf("<tr><td> %s : </td>\n", _("User Name"));
1278 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1279 if (!am_root()) {
1280 printf("<tr><td> %s : </td>\n", _("Old Password"));
1281 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1283 printf("<tr><td> %s : </td>\n", _("New Password"));
1284 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1285 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1286 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1287 printf("</table>\n");
1290 * Create all the control buttons for requesting action
1292 printf("<input type=submit name=%s value=\"%s\">\n",
1293 CHG_S_PASSWD_FLAG, _("Change Password"));
1294 if (demo_mode || am_root()) {
1295 printf("<input type=submit name=%s value=\"%s\">\n",
1296 ADD_USER_FLAG, _("Add New User"));
1297 printf("<input type=submit name=%s value=\"%s\">\n",
1298 DELETE_USER_FLAG, _("Delete User"));
1299 printf("<input type=submit name=%s value=\"%s\">\n",
1300 DISABLE_USER_FLAG, _("Disable User"));
1301 printf("<input type=submit name=%s value=\"%s\">\n",
1302 ENABLE_USER_FLAG, _("Enable User"));
1304 printf("<p></FORM>\n");
1307 * Do some work if change, add, disable or enable was
1308 * requested. It could be this is the first time through this
1309 * code, so there isn't anything to do. */
1310 if (verify_xsrf_token(passwd_form) &&
1311 ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1312 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG)))) {
1313 chg_passwd();
1316 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1318 printf("<FORM name=\"swatform\" method=post>\n");
1319 print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form);
1321 printf("<table>\n");
1324 * Create all the dialog boxes for data collection
1326 printf("<tr><td> %s : </td>\n", _("User Name"));
1327 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1328 printf("<tr><td> %s : </td>\n", _("Old Password"));
1329 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1330 printf("<tr><td> %s : </td>\n", _("New Password"));
1331 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1332 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1333 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1334 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1335 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1337 printf("</table>");
1340 * Create all the control buttons for requesting action
1342 printf("<input type=submit name=%s value=\"%s\">",
1343 CHG_R_PASSWD_FLAG, _("Change Password"));
1345 printf("<p></FORM>\n");
1348 * Do some work if a request has been made to change the
1349 * password somewhere other than the server. It could be this
1350 * is the first time through this code, so there isn't
1351 * anything to do. */
1352 if (verify_xsrf_token(passwd_form) && cgi_variable(CHG_R_PASSWD_FLAG)) {
1353 chg_passwd();
1358 /****************************************************************************
1359 display a printers editing page
1360 ****************************************************************************/
1361 static void printers_page(void)
1363 const char *share = cgi_variable("share");
1364 char *s;
1365 int snum=-1;
1366 int i;
1367 int mode = 0;
1368 unsigned int parm_filter = FLAG_BASIC;
1369 const char form_name[] = "printers";
1371 if (!verify_xsrf_token(form_name)) {
1372 goto output_page;
1375 if (share)
1376 snum = lp_servicenumber(share);
1378 if (cgi_variable("Commit") && snum >= 0) {
1379 commit_parameters(snum);
1380 if (snum >= iNumNonAutoPrintServices)
1381 save_reload(snum);
1382 else
1383 save_reload(-1);
1384 snum = lp_servicenumber(share);
1387 if (cgi_variable("Delete") && snum >= 0) {
1388 lp_remove_service(snum);
1389 save_reload(-1);
1390 share = NULL;
1391 snum = -1;
1394 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1395 snum = lp_servicenumber(share);
1396 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1397 load_config(False);
1398 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1399 snum = lp_servicenumber(share);
1400 lp_do_parameter(snum, "print ok", "Yes");
1401 save_reload(snum);
1402 snum = lp_servicenumber(share);
1406 if ( cgi_variable("ViewMode") )
1407 mode = atoi(cgi_variable_nonull("ViewMode"));
1408 if ( cgi_variable("BasicMode"))
1409 mode = 0;
1410 if ( cgi_variable("AdvMode"))
1411 mode = 1;
1413 output_page:
1414 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1416 printf("<H3>%s</H3>\n", _("Important Note:"));
1417 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1418 printf("%s",_("are autoloaded printers from "));
1419 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1420 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1423 printf("<FORM name=\"swatform\" method=post>\n");
1424 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1426 ViewModeBoxes( mode );
1427 switch ( mode ) {
1428 case 0:
1429 parm_filter = FLAG_BASIC;
1430 break;
1431 case 1:
1432 parm_filter = FLAG_ADVANCED;
1433 break;
1435 printf("<table>\n");
1436 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1437 printf("<td><select name=\"share\">\n");
1438 if (snum < 0 || !lp_print_ok(snum))
1439 printf("<option value=\" \"> \n");
1440 for (i=0;i<lp_numservices();i++) {
1441 s = lp_servicename(i);
1442 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1443 if (i >= iNumNonAutoPrintServices)
1444 printf("<option %s value=\"%s\">[*]%s\n",
1445 (share && strcmp(share,s)==0)?"SELECTED":"",
1446 s, s);
1447 else
1448 printf("<option %s value=\"%s\">%s\n",
1449 (share && strcmp(share,s)==0)?"SELECTED":"",
1450 s, s);
1453 printf("</select></td>");
1454 if (have_write_access) {
1455 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1457 printf("</tr>");
1458 printf("</table>\n");
1460 if (have_write_access) {
1461 printf("<table>\n");
1462 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1463 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1464 printf("</table>");
1468 if (snum >= 0) {
1469 if (have_write_access) {
1470 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1472 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1473 printf("<p>\n");
1476 if (snum >= 0) {
1477 printf("<table>\n");
1478 show_parameters(snum, 1, parm_filter, 1);
1479 printf("</table>\n");
1481 printf("</FORM>\n");
1485 when the _() translation macro is used there is no obvious place to free
1486 the resulting string and there is no easy way to give a static pointer.
1487 All we can do is rotate between some static buffers and hope a single d_printf()
1488 doesn't have more calls to _() than the number of buffers
1491 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1493 const char *msgstr;
1494 const char *ret;
1496 msgstr = lang_msg(msgid);
1497 if (!msgstr) {
1498 return msgid;
1501 ret = talloc_strdup(ctx, msgstr);
1503 lang_msg_free(msgstr);
1504 if (!ret) {
1505 return msgid;
1508 return ret;
1512 * main function for SWAT.
1514 int main(int argc, char *argv[])
1516 const char *page;
1517 poptContext pc;
1518 struct poptOption long_options[] = {
1519 POPT_AUTOHELP
1520 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1521 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1522 POPT_COMMON_SAMBA
1523 POPT_TABLEEND
1525 TALLOC_CTX *frame = talloc_stackframe();
1527 fault_setup(NULL);
1528 umask(S_IWGRP | S_IWOTH);
1530 #if defined(HAVE_SET_AUTH_PARAMETERS)
1531 set_auth_parameters(argc, argv);
1532 #endif /* HAVE_SET_AUTH_PARAMETERS */
1534 /* just in case it goes wild ... */
1535 alarm(300);
1537 setlinebuf(stdout);
1539 /* we don't want any SIGPIPE messages */
1540 BlockSignals(True,SIGPIPE);
1542 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1543 if (!dbf) dbf = x_stderr;
1545 /* we don't want stderr screwing us up */
1546 close(2);
1547 open("/dev/null", O_WRONLY);
1549 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1551 /* Parse command line options */
1553 while(poptGetNextOpt(pc) != -1) { }
1555 poptFreeContext(pc);
1557 load_case_tables();
1559 setup_logging(argv[0],False);
1560 load_config(True);
1561 load_interfaces();
1562 iNumNonAutoPrintServices = lp_numservices();
1563 pcap_cache_reload(&load_printers);
1565 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1567 print_header();
1569 cgi_load_variables();
1571 if (!file_exist(get_dyn_CONFIGFILE())) {
1572 have_read_access = True;
1573 have_write_access = True;
1574 } else {
1575 /* check if the authenticated user has write access - if not then
1576 don't show write options */
1577 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1579 /* if the user doesn't have read access to smb.conf then
1580 don't let them view it */
1581 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1584 show_main_buttons();
1586 page = cgi_pathinfo();
1588 /* Root gets full functionality */
1589 if (have_read_access && strcmp(page, "globals")==0) {
1590 globals_page();
1591 } else if (have_read_access && strcmp(page,"shares")==0) {
1592 shares_page();
1593 } else if (have_read_access && strcmp(page,"printers")==0) {
1594 printers_page();
1595 } else if (have_read_access && strcmp(page,"status")==0) {
1596 status_page();
1597 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1598 viewconfig_page();
1599 } else if (strcmp(page,"passwd")==0) {
1600 passwd_page();
1601 } else if (have_read_access && strcmp(page,"wizard")==0) {
1602 wizard_page();
1603 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1604 wizard_params_page();
1605 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1606 rewritecfg_file();
1607 } else {
1608 welcome_page();
1611 print_footer();
1613 TALLOC_FREE(frame);
1614 return 0;
1617 /** @} **/