s3 swat: Add XSRF protection to shares page
[Samba.git] / source3 / web / swat.c
blobf1f226ba9c77a5fea68b17f4811abe06851c63cb
1 /*
2 Unix SMB/CIFS implementation.
3 Samba Web Administration Tool
4 Version 3.0.0
5 Copyright (C) Andrew Tridgell 1997-2002
6 Copyright (C) John H Terpstra 2002
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 /**
23 * @defgroup swat SWAT - Samba Web Administration Tool
24 * @{
25 * @file swat.c
27 * @brief Samba Web Administration Tool.
28 **/
30 #include "includes.h"
31 #include "web/swat_proto.h"
32 #include "../lib/crypto/md5.h"
34 static int demo_mode = False;
35 static int passwd_only = False;
36 static bool have_write_access = False;
37 static bool have_read_access = False;
38 static int iNumNonAutoPrintServices = 0;
41 * Password Management Globals
43 #define SWAT_USER "username"
44 #define OLD_PSWD "old_passwd"
45 #define NEW_PSWD "new_passwd"
46 #define NEW2_PSWD "new2_passwd"
47 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
48 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
49 #define ADD_USER_FLAG "add_user_flag"
50 #define DELETE_USER_FLAG "delete_user_flag"
51 #define DISABLE_USER_FLAG "disable_user_flag"
52 #define ENABLE_USER_FLAG "enable_user_flag"
53 #define RHOST "remote_host"
54 #define XSRF_TOKEN "xsrf"
56 #define _(x) lang_msg_rotate(talloc_tos(),x)
58 /****************************************************************************
59 ****************************************************************************/
60 static int enum_index(int value, const struct enum_list *enumlist)
62 int i;
63 for (i=0;enumlist[i].name;i++)
64 if (value == enumlist[i].value) break;
65 return(i);
68 static char *fix_backslash(const char *str)
70 static char newstring[1024];
71 char *p = newstring;
73 while (*str) {
74 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
75 else *p++ = *str;
76 ++str;
78 *p = '\0';
79 return newstring;
82 static const char *fix_quotes(TALLOC_CTX *ctx, const char *str)
84 char *newstring = NULL;
85 char *p = NULL;
86 size_t newstring_len;
87 int quote_len = strlen("&quot;");
89 /* Count the number of quotes. */
90 newstring_len = 1;
91 p = (char *) str;
92 while (*p) {
93 if ( *p == '\"') {
94 newstring_len += quote_len;
95 } else {
96 newstring_len++;
98 ++p;
100 newstring = TALLOC_ARRAY(ctx, char, newstring_len);
101 if (!newstring) {
102 return "";
104 for (p = newstring; *str; str++) {
105 if ( *str == '\"') {
106 strncpy( p, "&quot;", quote_len);
107 p += quote_len;
108 } else {
109 *p++ = *str;
112 *p = '\0';
113 return newstring;
116 static char *stripspaceupper(const char *str)
118 static char newstring[1024];
119 char *p = newstring;
121 while (*str) {
122 if (*str != ' ') *p++ = toupper_ascii(*str);
123 ++str;
125 *p = '\0';
126 return newstring;
129 static char *make_parm_name(const char *label)
131 static char parmname[1024];
132 char *p = parmname;
134 while (*label) {
135 if (*label == ' ') *p++ = '_';
136 else *p++ = *label;
137 ++label;
139 *p = '\0';
140 return parmname;
143 void get_xsrf_token(const char *username, const char *pass,
144 const char *formname, char token_str[33])
146 struct MD5Context md5_ctx;
147 uint8_t token[16];
148 int i;
150 token_str[0] = '\0';
151 ZERO_STRUCT(md5_ctx);
152 MD5Init(&md5_ctx);
154 MD5Update(&md5_ctx, (uint8_t *)formname, strlen(formname));
155 if (username != NULL) {
156 MD5Update(&md5_ctx, (uint8_t *)username, strlen(username));
158 if (pass != NULL) {
159 MD5Update(&md5_ctx, (uint8_t *)pass, strlen(pass));
162 MD5Final(token, &md5_ctx);
164 for(i = 0; i < sizeof(token); i++) {
165 char tmp[3];
167 snprintf(tmp, sizeof(tmp), "%02x", token[i]);
168 strncat(token_str, tmp, sizeof(tmp));
172 void print_xsrf_token(const char *username, const char *pass,
173 const char *formname)
175 char token[33];
177 get_xsrf_token(username, pass, formname, token);
178 printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
179 XSRF_TOKEN, token);
183 bool verify_xsrf_token(const char *formname)
185 char expected[33];
186 const char *username = cgi_user_name();
187 const char *pass = cgi_user_pass();
188 const char *token = cgi_variable_nonull(XSRF_TOKEN);
190 get_xsrf_token(username, pass, formname, expected);
191 return (strncmp(expected, token, sizeof(expected)) == 0);
195 /****************************************************************************
196 include a lump of html in a page
197 ****************************************************************************/
198 static int include_html(const char *fname)
200 int fd;
201 char buf[1024];
202 int ret;
204 fd = web_open(fname, O_RDONLY, 0);
206 if (fd == -1) {
207 printf(_("ERROR: Can't open %s"), fname);
208 printf("\n");
209 return 0;
212 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
213 if (write(1, buf, ret) == -1) {
214 break;
218 close(fd);
219 return 1;
222 /****************************************************************************
223 start the page with standard stuff
224 ****************************************************************************/
225 static void print_header(void)
227 if (!cgi_waspost()) {
228 printf("Expires: 0\r\n");
230 printf("Content-type: text/html\r\n\r\n");
232 if (!include_html("include/header.html")) {
233 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
234 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
238 /* *******************************************************************
239 show parameter label with translated name in the following form
240 because showing original and translated label in one line looks
241 too long, and showing translated label only is unusable for
242 heavy users.
243 -------------------------------
244 HELP security [combo box][button]
245 SECURITY
246 -------------------------------
247 (capital words are translated by gettext.)
248 if no translation is available, then same form as original is
249 used.
250 "i18n_translated_parm" class is used to change the color of the
251 translated parameter with CSS.
252 **************************************************************** */
253 static const char *get_parm_translated(TALLOC_CTX *ctx,
254 const char* pAnchor, const char* pHelp, const char* pLabel)
256 const char *pTranslated = _(pLabel);
257 char *output;
258 if(strcmp(pLabel, pTranslated) != 0) {
259 output = talloc_asprintf(ctx,
260 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s <br><span class=\"i18n_translated_parm\">%s</span>",
261 pAnchor, pHelp, pLabel, pTranslated);
262 return output;
264 output = talloc_asprintf(ctx,
265 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
266 pAnchor, pHelp, pLabel);
267 return output;
269 /****************************************************************************
270 finish off the page
271 ****************************************************************************/
272 static void print_footer(void)
274 if (!include_html("include/footer.html")) {
275 printf("\n</BODY>\n</HTML>\n");
279 /****************************************************************************
280 display one editable parameter in a form
281 ****************************************************************************/
282 static void show_parameter(int snum, struct parm_struct *parm)
284 int i;
285 void *ptr = parm->ptr;
286 char *utf8_s1, *utf8_s2;
287 size_t converted_size;
288 TALLOC_CTX *ctx = talloc_stackframe();
290 if (parm->p_class == P_LOCAL && snum >= 0) {
291 ptr = lp_local_ptr_by_snum(snum, ptr);
294 printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
295 stripspaceupper(parm->label), _("Help"), parm->label));
296 switch (parm->type) {
297 case P_CHAR:
298 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
299 make_parm_name(parm->label), *(char *)ptr);
300 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
301 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
302 break;
304 case P_LIST:
305 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
306 make_parm_name(parm->label));
307 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
308 char **list = *(char ***)ptr;
309 for (;*list;list++) {
310 /* enclose in HTML encoded quotes if the string contains a space */
311 if ( strchr_m(*list, ' ') ) {
312 push_utf8_allocate(&utf8_s1, *list, &converted_size);
313 push_utf8_allocate(&utf8_s2, ((*(list+1))?", ":""), &converted_size);
314 printf("&quot;%s&quot;%s", utf8_s1, utf8_s2);
315 } else {
316 push_utf8_allocate(&utf8_s1, *list, &converted_size);
317 push_utf8_allocate(&utf8_s2, ((*(list+1))?", ":""), &converted_size);
318 printf("%s%s", utf8_s1, utf8_s2);
320 SAFE_FREE(utf8_s1);
321 SAFE_FREE(utf8_s2);
324 printf("\">");
325 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
326 _("Set Default"), make_parm_name(parm->label));
327 if (parm->def.lvalue) {
328 char **list = (char **)(parm->def.lvalue);
329 for (; *list; list++) {
330 /* enclose in HTML encoded quotes if the string contains a space */
331 if ( strchr_m(*list, ' ') )
332 printf("&quot;%s&quot;%s", *list, ((*(list+1))?", ":""));
333 else
334 printf("%s%s", *list, ((*(list+1))?", ":""));
337 printf("\'\">");
338 break;
340 case P_STRING:
341 case P_USTRING:
342 push_utf8_allocate(&utf8_s1, *(char **)ptr, &converted_size);
343 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
344 make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
345 SAFE_FREE(utf8_s1);
346 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
347 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
348 break;
350 case P_BOOL:
351 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
352 printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
353 printf("<option %s>No", (*(bool *)ptr)?"":"selected");
354 printf("</select>");
355 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
356 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
357 break;
359 case P_BOOLREV:
360 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
361 printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
362 printf("<option %s>No", (*(bool *)ptr)?"selected":"");
363 printf("</select>");
364 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
365 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
366 break;
368 case P_INTEGER:
369 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
370 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
371 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
372 break;
374 case P_OCTAL: {
375 char *o;
376 o = octal_string(*(int *)ptr);
377 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
378 make_parm_name(parm->label), o);
379 TALLOC_FREE(o);
380 o = octal_string((int)(parm->def.ivalue));
381 printf("<input type=button value=\"%s\" "
382 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
383 _("Set Default"), make_parm_name(parm->label), o);
384 TALLOC_FREE(o);
385 break;
388 case P_ENUM:
389 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
390 for (i=0;parm->enum_list[i].name;i++) {
391 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
392 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
395 printf("</select>");
396 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
397 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
398 break;
399 case P_SEP:
400 break;
402 printf("</td></tr>\n");
403 TALLOC_FREE(ctx);
406 /****************************************************************************
407 display a set of parameters for a service
408 ****************************************************************************/
409 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
411 int i = 0;
412 struct parm_struct *parm;
413 const char *heading = NULL;
414 const char *last_heading = NULL;
416 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
417 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
418 continue;
419 if (parm->p_class == P_SEPARATOR) {
420 heading = parm->label;
421 continue;
423 if (parm->flags & FLAG_HIDE) continue;
424 if (snum >= 0) {
425 if (printers & !(parm->flags & FLAG_PRINT)) continue;
426 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
429 if (!( parm_filter & FLAG_ADVANCED )) {
430 if (!(parm->flags & FLAG_BASIC)) {
431 void *ptr = parm->ptr;
433 if (parm->p_class == P_LOCAL && snum >= 0) {
434 ptr = lp_local_ptr_by_snum(snum, ptr);
437 switch (parm->type) {
438 case P_CHAR:
439 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
440 break;
442 case P_LIST:
443 if (!str_list_equal(*(const char ***)ptr,
444 (const char **)(parm->def.lvalue))) continue;
445 break;
447 case P_STRING:
448 case P_USTRING:
449 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
450 break;
452 case P_BOOL:
453 case P_BOOLREV:
454 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
455 break;
457 case P_INTEGER:
458 case P_OCTAL:
459 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
460 break;
463 case P_ENUM:
464 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
465 break;
466 case P_SEP:
467 continue;
470 if (printers && !(parm->flags & FLAG_PRINT)) continue;
473 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
475 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
477 if (heading && heading != last_heading) {
478 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
479 last_heading = heading;
481 show_parameter(snum, parm);
485 /****************************************************************************
486 load the smb.conf file into loadparm.
487 ****************************************************************************/
488 static bool load_config(bool save_def)
490 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
493 /****************************************************************************
494 write a config file
495 ****************************************************************************/
496 static void write_config(FILE *f, bool show_defaults)
498 TALLOC_CTX *ctx = talloc_stackframe();
500 fprintf(f, "# Samba config file created using SWAT\n");
501 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
502 fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
504 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
506 TALLOC_FREE(ctx);
509 /****************************************************************************
510 save and reload the smb.conf config file
511 ****************************************************************************/
512 static int save_reload(int snum)
514 FILE *f;
515 struct stat st;
517 f = sys_fopen(get_dyn_CONFIGFILE(),"w");
518 if (!f) {
519 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
520 printf("\n");
521 return 0;
524 /* just in case they have used the buggy xinetd to create the file */
525 if (fstat(fileno(f), &st) == 0 &&
526 (st.st_mode & S_IWOTH)) {
527 #if defined HAVE_FCHMOD
528 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
529 #else
530 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
531 #endif
534 write_config(f, False);
535 if (snum >= 0)
536 lp_dump_one(f, False, snum);
537 fclose(f);
539 lp_kill_all_services();
541 if (!load_config(False)) {
542 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
543 printf("\n");
544 return 0;
546 iNumNonAutoPrintServices = lp_numservices();
547 load_printers();
549 return 1;
552 /****************************************************************************
553 commit one parameter
554 ****************************************************************************/
555 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
557 int i;
558 char *s;
560 if (snum < 0 && parm->p_class == P_LOCAL) {
561 /* this handles the case where we are changing a local
562 variable globally. We need to change the parameter in
563 all shares where it is currently set to the default */
564 for (i=0;i<lp_numservices();i++) {
565 s = lp_servicename(i);
566 if (s && (*s) && lp_is_default(i, parm)) {
567 lp_do_parameter(i, parm->label, v);
572 lp_do_parameter(snum, parm->label, v);
575 /****************************************************************************
576 commit a set of parameters for a service
577 ****************************************************************************/
578 static void commit_parameters(int snum)
580 int i = 0;
581 struct parm_struct *parm;
582 char *label;
583 const char *v;
585 while ((parm = lp_next_parameter(snum, &i, 1))) {
586 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
587 if ((v = cgi_variable(label)) != NULL) {
588 if (parm->flags & FLAG_HIDE)
589 continue;
590 commit_parameter(snum, parm, v);
592 SAFE_FREE(label);
597 /****************************************************************************
598 spit out the html for a link with an image
599 ****************************************************************************/
600 static void image_link(const char *name, const char *hlink, const char *src)
602 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
603 cgi_baseurl(), hlink, src, name);
606 /****************************************************************************
607 display the main navigation controls at the top of each page along
608 with a title
609 ****************************************************************************/
610 static void show_main_buttons(void)
612 char *p;
614 if ((p = cgi_user_name()) && strcmp(p, "root")) {
615 printf(_("Logged in as <b>%s</b>"), p);
616 printf("<p>\n");
619 image_link(_("Home"), "", "images/home.gif");
620 if (have_write_access) {
621 image_link(_("Globals"), "globals", "images/globals.gif");
622 image_link(_("Shares"), "shares", "images/shares.gif");
623 image_link(_("Printers"), "printers", "images/printers.gif");
624 image_link(_("Wizard"), "wizard", "images/wizard.gif");
626 /* root always gets all buttons, otherwise look for -P */
627 if ( have_write_access || (!passwd_only && have_read_access) ) {
628 image_link(_("Status"), "status", "images/status.gif");
629 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
631 image_link(_("Password Management"), "passwd", "images/passwd.gif");
633 printf("<HR>\n");
636 /****************************************************************************
637 * Handle Display/Edit Mode CGI
638 ****************************************************************************/
639 static void ViewModeBoxes(int mode)
641 printf("<p>%s:&nbsp;\n", _("Current View Is"));
642 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
643 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
644 printf("<br>%s:&nbsp;\n", _("Change View To"));
645 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
646 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
647 printf("</p><br>\n");
650 /****************************************************************************
651 display a welcome page
652 ****************************************************************************/
653 static void welcome_page(void)
655 if (file_exist("help/welcome.html")) {
656 include_html("help/welcome.html");
657 } else {
658 include_html("help/welcome-no-samba-doc.html");
662 /****************************************************************************
663 display the current smb.conf
664 ****************************************************************************/
665 static void viewconfig_page(void)
667 int full_view=0;
668 const char form_name[] = "viewconfig";
670 if (!verify_xsrf_token(form_name)) {
671 goto output_page;
674 if (cgi_variable("full_view")) {
675 full_view = 1;
678 output_page:
679 printf("<H2>%s</H2>\n", _("Current Config"));
680 printf("<form method=post>\n");
681 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
683 if (full_view) {
684 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
685 } else {
686 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
689 printf("<p><pre>");
690 write_config(stdout, full_view);
691 printf("</pre>");
692 printf("</form>\n");
695 /****************************************************************************
696 second screen of the wizard ... Fetch Configuration Parameters
697 ****************************************************************************/
698 static void wizard_params_page(void)
700 unsigned int parm_filter = FLAG_WIZARD;
701 const char form_name[] = "wizard_params";
703 /* Here we first set and commit all the parameters that were selected
704 in the previous screen. */
706 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
708 if (!verify_xsrf_token(form_name)) {
709 goto output_page;
712 if (cgi_variable("Commit")) {
713 commit_parameters(GLOBAL_SECTION_SNUM);
714 save_reload(0);
717 output_page:
718 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
719 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
721 if (have_write_access) {
722 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
725 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
726 printf("<p>\n");
728 printf("<table>\n");
729 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
730 printf("</table>\n");
731 printf("</form>\n");
734 /****************************************************************************
735 Utility to just rewrite the smb.conf file - effectively just cleans it up
736 ****************************************************************************/
737 static void rewritecfg_file(void)
739 commit_parameters(GLOBAL_SECTION_SNUM);
740 save_reload(0);
741 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
744 /****************************************************************************
745 wizard to create/modify the smb.conf file
746 ****************************************************************************/
747 static void wizard_page(void)
749 /* Set some variables to collect data from smb.conf */
750 int role = 0;
751 int winstype = 0;
752 int have_home = -1;
753 int HomeExpo = 0;
754 int SerType = 0;
755 const char form_name[] = "wizard";
757 if (!verify_xsrf_token(form_name)) {
758 goto output_page;
761 if (cgi_variable("Rewrite")) {
762 (void) rewritecfg_file();
763 return;
766 if (cgi_variable("GetWizardParams")){
767 (void) wizard_params_page();
768 return;
771 if (cgi_variable("Commit")){
772 SerType = atoi(cgi_variable_nonull("ServerType"));
773 winstype = atoi(cgi_variable_nonull("WINSType"));
774 have_home = lp_servicenumber(HOMES_NAME);
775 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
777 /* Plain text passwords are too badly broken - use encrypted passwords only */
778 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
780 switch ( SerType ){
781 case 0:
782 /* Stand-alone Server */
783 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
784 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
785 break;
786 case 1:
787 /* Domain Member */
788 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
789 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
790 break;
791 case 2:
792 /* Domain Controller */
793 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
794 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
795 break;
797 switch ( winstype ) {
798 case 0:
799 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
800 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
801 break;
802 case 1:
803 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
804 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
805 break;
806 case 2:
807 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
808 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
809 break;
812 /* Have to create Homes share? */
813 if ((HomeExpo == 1) && (have_home == -1)) {
814 const char *unix_share = HOMES_NAME;
816 load_config(False);
817 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
818 have_home = lp_servicenumber(HOMES_NAME);
819 lp_do_parameter( have_home, "read only", "No");
820 lp_do_parameter( have_home, "valid users", "%S");
821 lp_do_parameter( have_home, "browseable", "No");
822 commit_parameters(have_home);
823 save_reload(have_home);
826 /* Need to Delete Homes share? */
827 if ((HomeExpo == 0) && (have_home != -1)) {
828 lp_remove_service(have_home);
829 have_home = -1;
832 commit_parameters(GLOBAL_SECTION_SNUM);
833 save_reload(0);
835 else
837 /* Now determine smb.conf WINS settings */
838 if (lp_wins_support())
839 winstype = 1;
840 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
841 winstype = 2;
843 /* Do we have a homes share? */
844 have_home = lp_servicenumber(HOMES_NAME);
846 if ((winstype == 2) && lp_wins_support())
847 winstype = 3;
849 role = lp_server_role();
851 output_page:
852 /* Here we go ... */
853 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
854 printf("<form method=post action=wizard>\n");
855 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
857 if (have_write_access) {
858 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
859 printf("%s", _("The same will happen if you press the commit button."));
860 printf("<br><br>\n");
861 printf("<center>");
862 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
863 printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
864 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
865 printf("</center>\n");
868 printf("<hr>");
869 printf("<center><table border=0>");
870 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
871 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
872 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
873 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
874 printf("</tr>\n");
875 if (role == ROLE_DOMAIN_BDC) {
876 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
878 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
879 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
880 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
881 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
882 printf("</tr>\n");
883 printf("<tr><td></td><td></td><td></td><td>%s&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
885 /* Print out the list of wins servers */
886 if(lp_wins_server_list()) {
887 int i;
888 const char **wins_servers = lp_wins_server_list();
889 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
892 printf("\"></td></tr>\n");
893 if (winstype == 3) {
894 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"));
895 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
897 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
898 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
899 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
900 printf("<td></td></tr>\n");
902 /* Enable this when we are ready ....
903 * printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
904 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
905 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
906 * printf("<td></td></tr>\n");
909 printf("</table></center>");
910 printf("<hr>");
912 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
913 printf("</form>\n");
917 /****************************************************************************
918 display a globals editing page
919 ****************************************************************************/
920 static void globals_page(void)
922 unsigned int parm_filter = FLAG_BASIC;
923 int mode = 0;
924 const char form_name[] = "globals";
926 printf("<H2>%s</H2>\n", _("Global Parameters"));
928 if (!verify_xsrf_token(form_name)) {
929 goto output_page;
932 if (cgi_variable("Commit")) {
933 commit_parameters(GLOBAL_SECTION_SNUM);
934 save_reload(0);
937 if ( cgi_variable("ViewMode") )
938 mode = atoi(cgi_variable_nonull("ViewMode"));
939 if ( cgi_variable("BasicMode"))
940 mode = 0;
941 if ( cgi_variable("AdvMode"))
942 mode = 1;
944 output_page:
945 printf("<form name=\"swatform\" method=post action=globals>\n");
946 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
948 ViewModeBoxes( mode );
949 switch ( mode ) {
950 case 0:
951 parm_filter = FLAG_BASIC;
952 break;
953 case 1:
954 parm_filter = FLAG_ADVANCED;
955 break;
957 printf("<br>\n");
958 if (have_write_access) {
959 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
960 _("Commit Changes"));
963 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
964 _("Reset Values"));
966 printf("<p>\n");
967 printf("<table>\n");
968 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
969 printf("</table>\n");
970 printf("</form>\n");
973 /****************************************************************************
974 display a shares editing page. share is in unix codepage,
975 ****************************************************************************/
976 static void shares_page(void)
978 const char *share = cgi_variable("share");
979 char *s;
980 char *utf8_s;
981 int snum = -1;
982 int i;
983 int mode = 0;
984 unsigned int parm_filter = FLAG_BASIC;
985 size_t converted_size;
986 const char form_name[] = "shares";
988 printf("<H2>%s</H2>\n", _("Share Parameters"));
990 if (!verify_xsrf_token(form_name)) {
991 goto output_page;
994 if (share)
995 snum = lp_servicenumber(share);
998 if (cgi_variable("Commit") && snum >= 0) {
999 commit_parameters(snum);
1000 save_reload(0);
1001 snum = lp_servicenumber(share);
1004 if (cgi_variable("Delete") && snum >= 0) {
1005 lp_remove_service(snum);
1006 save_reload(0);
1007 share = NULL;
1008 snum = -1;
1011 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1012 snum = lp_servicenumber(share);
1013 if (snum < 0) {
1014 load_config(False);
1015 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1016 snum = lp_servicenumber(share);
1017 save_reload(snum);
1018 snum = lp_servicenumber(share);
1022 if ( cgi_variable("ViewMode") )
1023 mode = atoi(cgi_variable_nonull("ViewMode"));
1024 if ( cgi_variable("BasicMode"))
1025 mode = 0;
1026 if ( cgi_variable("AdvMode"))
1027 mode = 1;
1029 output_page:
1030 printf("<FORM name=\"swatform\" method=post>\n");
1031 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1033 printf("<table>\n");
1035 ViewModeBoxes( mode );
1036 switch ( mode ) {
1037 case 0:
1038 parm_filter = FLAG_BASIC;
1039 break;
1040 case 1:
1041 parm_filter = FLAG_ADVANCED;
1042 break;
1044 printf("<br><tr>\n");
1045 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1046 printf("<td><select name=share>\n");
1047 if (snum < 0)
1048 printf("<option value=\" \"> \n");
1049 for (i=0;i<lp_numservices();i++) {
1050 s = lp_servicename(i);
1051 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
1052 push_utf8_allocate(&utf8_s, s, &converted_size);
1053 printf("<option %s value=\"%s\">%s\n",
1054 (share && strcmp(share,s)==0)?"SELECTED":"",
1055 utf8_s, utf8_s);
1056 SAFE_FREE(utf8_s);
1059 printf("</select></td>\n");
1060 if (have_write_access) {
1061 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1063 printf("</tr>\n");
1064 printf("</table>");
1065 printf("<table>");
1066 if (have_write_access) {
1067 printf("<tr>\n");
1068 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1069 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1071 printf("</table>");
1074 if (snum >= 0) {
1075 if (have_write_access) {
1076 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1079 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1080 printf("<p>\n");
1083 if (snum >= 0) {
1084 printf("<table>\n");
1085 show_parameters(snum, 1, parm_filter, 0);
1086 printf("</table>\n");
1089 printf("</FORM>\n");
1092 /*************************************************************
1093 change a password either locally or remotely
1094 *************************************************************/
1095 static bool change_password(const char *remote_machine, const char *user_name,
1096 const char *old_passwd, const char *new_passwd,
1097 int local_flags)
1099 NTSTATUS ret;
1100 char *err_str = NULL;
1101 char *msg_str = NULL;
1103 if (demo_mode) {
1104 printf("%s\n<p>", _("password change in demo mode rejected"));
1105 return False;
1108 if (remote_machine != NULL) {
1109 ret = remote_password_change(remote_machine, user_name,
1110 old_passwd, new_passwd, &err_str);
1111 if (err_str != NULL)
1112 printf("%s\n<p>", err_str);
1113 SAFE_FREE(err_str);
1114 return NT_STATUS_IS_OK(ret);
1117 if(!initialize_password_db(True, NULL)) {
1118 printf("%s\n<p>", _("Can't setup password database vectors."));
1119 return False;
1122 ret = local_password_change(user_name, local_flags, new_passwd,
1123 &err_str, &msg_str);
1125 if(msg_str)
1126 printf("%s\n<p>", msg_str);
1127 if(err_str)
1128 printf("%s\n<p>", err_str);
1130 SAFE_FREE(msg_str);
1131 SAFE_FREE(err_str);
1132 return NT_STATUS_IS_OK(ret);
1135 /****************************************************************************
1136 do the stuff required to add or change a password
1137 ****************************************************************************/
1138 static void chg_passwd(void)
1140 const char *host;
1141 bool rslt;
1142 int local_flags = 0;
1144 /* Make sure users name has been specified */
1145 if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1146 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1147 return;
1151 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1152 * so if that's what we're doing, skip the rest of the checks
1154 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1157 * If current user is not root, make sure old password has been specified
1158 * If REMOTE change, even root must provide old password
1160 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1161 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1162 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1163 return;
1166 /* If changing a users password on a remote hosts we have to know what host */
1167 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1168 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1169 return;
1172 /* Make sure new passwords have been specified */
1173 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1174 (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1175 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1176 return;
1179 /* Make sure new passwords was typed correctly twice */
1180 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1181 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1182 return;
1186 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1187 host = cgi_variable(RHOST);
1188 } else if (am_root()) {
1189 host = NULL;
1190 } else {
1191 host = "127.0.0.1";
1195 * Set up the local flags.
1198 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1199 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1200 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1201 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1202 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1203 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1206 rslt = change_password(host,
1207 cgi_variable_nonull(SWAT_USER),
1208 cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1209 local_flags);
1211 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1212 printf("<p>");
1213 if (rslt == True) {
1214 printf("%s\n", _(" The passwd has been changed."));
1215 } else {
1216 printf("%s\n", _(" The passwd for has NOT been changed."));
1220 return;
1223 /****************************************************************************
1224 display a password editing page
1225 ****************************************************************************/
1226 static void passwd_page(void)
1228 const char *new_name = cgi_user_name();
1230 if (!new_name) new_name = "";
1232 printf("<H2>%s</H2>\n", _("Server Password Management"));
1234 printf("<FORM name=\"swatform\" method=post>\n");
1236 printf("<table>\n");
1239 * Create all the dialog boxes for data collection
1241 printf("<tr><td> %s : </td>\n", _("User Name"));
1242 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1243 if (!am_root()) {
1244 printf("<tr><td> %s : </td>\n", _("Old Password"));
1245 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1247 printf("<tr><td> %s : </td>\n", _("New Password"));
1248 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1249 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1250 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1251 printf("</table>\n");
1254 * Create all the control buttons for requesting action
1256 printf("<input type=submit name=%s value=\"%s\">\n",
1257 CHG_S_PASSWD_FLAG, _("Change Password"));
1258 if (demo_mode || am_root()) {
1259 printf("<input type=submit name=%s value=\"%s\">\n",
1260 ADD_USER_FLAG, _("Add New User"));
1261 printf("<input type=submit name=%s value=\"%s\">\n",
1262 DELETE_USER_FLAG, _("Delete User"));
1263 printf("<input type=submit name=%s value=\"%s\">\n",
1264 DISABLE_USER_FLAG, _("Disable User"));
1265 printf("<input type=submit name=%s value=\"%s\">\n",
1266 ENABLE_USER_FLAG, _("Enable User"));
1268 printf("<p></FORM>\n");
1271 * Do some work if change, add, disable or enable was
1272 * requested. It could be this is the first time through this
1273 * code, so there isn't anything to do. */
1274 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1275 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1276 chg_passwd();
1279 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1281 printf("<FORM name=\"swatform\" method=post>\n");
1283 printf("<table>\n");
1286 * Create all the dialog boxes for data collection
1288 printf("<tr><td> %s : </td>\n", _("User Name"));
1289 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1290 printf("<tr><td> %s : </td>\n", _("Old Password"));
1291 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1292 printf("<tr><td> %s : </td>\n", _("New Password"));
1293 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1294 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1295 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1296 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1297 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1299 printf("</table>");
1302 * Create all the control buttons for requesting action
1304 printf("<input type=submit name=%s value=\"%s\">",
1305 CHG_R_PASSWD_FLAG, _("Change Password"));
1307 printf("<p></FORM>\n");
1310 * Do some work if a request has been made to change the
1311 * password somewhere other than the server. It could be this
1312 * is the first time through this code, so there isn't
1313 * anything to do. */
1314 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1315 chg_passwd();
1320 /****************************************************************************
1321 display a printers editing page
1322 ****************************************************************************/
1323 static void printers_page(void)
1325 const char *share = cgi_variable("share");
1326 char *s;
1327 int snum=-1;
1328 int i;
1329 int mode = 0;
1330 unsigned int parm_filter = FLAG_BASIC;
1332 if (share)
1333 snum = lp_servicenumber(share);
1335 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1337 printf("<H3>%s</H3>\n", _("Important Note:"));
1338 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1339 printf("%s",_("are autoloaded printers from "));
1340 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1341 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1343 if (cgi_variable("Commit") && snum >= 0) {
1344 commit_parameters(snum);
1345 if (snum >= iNumNonAutoPrintServices)
1346 save_reload(snum);
1347 else
1348 save_reload(0);
1349 snum = lp_servicenumber(share);
1352 if (cgi_variable("Delete") && snum >= 0) {
1353 lp_remove_service(snum);
1354 save_reload(0);
1355 share = NULL;
1356 snum = -1;
1359 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1360 snum = lp_servicenumber(share);
1361 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1362 load_config(False);
1363 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1364 snum = lp_servicenumber(share);
1365 lp_do_parameter(snum, "print ok", "Yes");
1366 save_reload(snum);
1367 snum = lp_servicenumber(share);
1371 printf("<FORM name=\"swatform\" method=post>\n");
1373 if ( cgi_variable("ViewMode") )
1374 mode = atoi(cgi_variable_nonull("ViewMode"));
1375 if ( cgi_variable("BasicMode"))
1376 mode = 0;
1377 if ( cgi_variable("AdvMode"))
1378 mode = 1;
1380 ViewModeBoxes( mode );
1381 switch ( mode ) {
1382 case 0:
1383 parm_filter = FLAG_BASIC;
1384 break;
1385 case 1:
1386 parm_filter = FLAG_ADVANCED;
1387 break;
1389 printf("<table>\n");
1390 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1391 printf("<td><select name=\"share\">\n");
1392 if (snum < 0 || !lp_print_ok(snum))
1393 printf("<option value=\" \"> \n");
1394 for (i=0;i<lp_numservices();i++) {
1395 s = lp_servicename(i);
1396 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1397 if (i >= iNumNonAutoPrintServices)
1398 printf("<option %s value=\"%s\">[*]%s\n",
1399 (share && strcmp(share,s)==0)?"SELECTED":"",
1400 s, s);
1401 else
1402 printf("<option %s value=\"%s\">%s\n",
1403 (share && strcmp(share,s)==0)?"SELECTED":"",
1404 s, s);
1407 printf("</select></td>");
1408 if (have_write_access) {
1409 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1411 printf("</tr>");
1412 printf("</table>\n");
1414 if (have_write_access) {
1415 printf("<table>\n");
1416 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1417 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1418 printf("</table>");
1422 if (snum >= 0) {
1423 if (have_write_access) {
1424 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1426 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1427 printf("<p>\n");
1430 if (snum >= 0) {
1431 printf("<table>\n");
1432 show_parameters(snum, 1, parm_filter, 1);
1433 printf("</table>\n");
1435 printf("</FORM>\n");
1439 when the _() translation macro is used there is no obvious place to free
1440 the resulting string and there is no easy way to give a static pointer.
1441 All we can do is rotate between some static buffers and hope a single d_printf()
1442 doesn't have more calls to _() than the number of buffers
1445 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1447 const char *msgstr;
1448 const char *ret;
1450 msgstr = lang_msg(msgid);
1451 if (!msgstr) {
1452 return msgid;
1455 ret = talloc_strdup(ctx, msgstr);
1457 lang_msg_free(msgstr);
1458 if (!ret) {
1459 return msgid;
1462 return ret;
1466 * main function for SWAT.
1468 int main(int argc, char *argv[])
1470 const char *page;
1471 poptContext pc;
1472 struct poptOption long_options[] = {
1473 POPT_AUTOHELP
1474 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1475 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1476 POPT_COMMON_SAMBA
1477 POPT_TABLEEND
1479 TALLOC_CTX *frame = talloc_stackframe();
1481 fault_setup(NULL);
1482 umask(S_IWGRP | S_IWOTH);
1484 #if defined(HAVE_SET_AUTH_PARAMETERS)
1485 set_auth_parameters(argc, argv);
1486 #endif /* HAVE_SET_AUTH_PARAMETERS */
1488 /* just in case it goes wild ... */
1489 alarm(300);
1491 setlinebuf(stdout);
1493 /* we don't want any SIGPIPE messages */
1494 BlockSignals(True,SIGPIPE);
1496 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1497 if (!dbf) dbf = x_stderr;
1499 /* we don't want stderr screwing us up */
1500 close(2);
1501 open("/dev/null", O_WRONLY);
1503 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1505 /* Parse command line options */
1507 while(poptGetNextOpt(pc) != -1) { }
1509 poptFreeContext(pc);
1511 load_case_tables();
1513 setup_logging(argv[0],False);
1514 load_config(True);
1515 load_interfaces();
1516 iNumNonAutoPrintServices = lp_numservices();
1517 load_printers();
1519 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1521 print_header();
1523 cgi_load_variables();
1525 if (!file_exist(get_dyn_CONFIGFILE())) {
1526 have_read_access = True;
1527 have_write_access = True;
1528 } else {
1529 /* check if the authenticated user has write access - if not then
1530 don't show write options */
1531 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1533 /* if the user doesn't have read access to smb.conf then
1534 don't let them view it */
1535 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1538 show_main_buttons();
1540 page = cgi_pathinfo();
1542 /* Root gets full functionality */
1543 if (have_read_access && strcmp(page, "globals")==0) {
1544 globals_page();
1545 } else if (have_read_access && strcmp(page,"shares")==0) {
1546 shares_page();
1547 } else if (have_read_access && strcmp(page,"printers")==0) {
1548 printers_page();
1549 } else if (have_read_access && strcmp(page,"status")==0) {
1550 status_page();
1551 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1552 viewconfig_page();
1553 } else if (strcmp(page,"passwd")==0) {
1554 passwd_page();
1555 } else if (have_read_access && strcmp(page,"wizard")==0) {
1556 wizard_page();
1557 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1558 wizard_params_page();
1559 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1560 rewritecfg_file();
1561 } else {
1562 welcome_page();
1565 print_footer();
1567 TALLOC_FREE(frame);
1568 return 0;
1571 /** @} **/