s3 swat: Add XSRF protection to viewconfig page
[Samba.git] / source / web / swat.c
blob647126fc280fce739aa31b69df6fa8509ebd756f
1 /*
2 Unix SMB/CIFS implementation.
3 Samba Web Administration Tool
4 Version 3.0.0
5 Copyright (C) Andrew Tridgell 1997-2002
6 Copyright (C) John H Terpstra 2002
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 /**
23 * @defgroup swat SWAT - Samba Web Administration Tool
24 * @{
25 * @file swat.c
27 * @brief Samba Web Administration Tool.
28 **/
30 #include "includes.h"
31 #include "web/swat_proto.h"
32 #include "../lib/crypto/md5.h"
34 static int demo_mode = False;
35 static int passwd_only = False;
36 static bool have_write_access = False;
37 static bool have_read_access = False;
38 static int iNumNonAutoPrintServices = 0;
41 * Password Management Globals
43 #define SWAT_USER "username"
44 #define OLD_PSWD "old_passwd"
45 #define NEW_PSWD "new_passwd"
46 #define NEW2_PSWD "new2_passwd"
47 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
48 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
49 #define ADD_USER_FLAG "add_user_flag"
50 #define DELETE_USER_FLAG "delete_user_flag"
51 #define DISABLE_USER_FLAG "disable_user_flag"
52 #define ENABLE_USER_FLAG "enable_user_flag"
53 #define RHOST "remote_host"
54 #define XSRF_TOKEN "xsrf"
56 #define _(x) lang_msg_rotate(talloc_tos(),x)
58 /****************************************************************************
59 ****************************************************************************/
60 static int enum_index(int value, const struct enum_list *enumlist)
62 int i;
63 for (i=0;enumlist[i].name;i++)
64 if (value == enumlist[i].value) break;
65 return(i);
68 static char *fix_backslash(const char *str)
70 static char newstring[1024];
71 char *p = newstring;
73 while (*str) {
74 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
75 else *p++ = *str;
76 ++str;
78 *p = '\0';
79 return newstring;
82 static const char *fix_quotes(TALLOC_CTX *ctx, const char *str)
84 char *newstring = NULL;
85 char *p = NULL;
86 size_t newstring_len;
87 int quote_len = strlen("&quot;");
89 /* Count the number of quotes. */
90 newstring_len = 1;
91 p = (char *) str;
92 while (*p) {
93 if ( *p == '\"') {
94 newstring_len += quote_len;
95 } else {
96 newstring_len++;
98 ++p;
100 newstring = TALLOC_ARRAY(ctx, char, newstring_len);
101 if (!newstring) {
102 return "";
104 for (p = newstring; *str; str++) {
105 if ( *str == '\"') {
106 strncpy( p, "&quot;", quote_len);
107 p += quote_len;
108 } else {
109 *p++ = *str;
112 *p = '\0';
113 return newstring;
116 static char *stripspaceupper(const char *str)
118 static char newstring[1024];
119 char *p = newstring;
121 while (*str) {
122 if (*str != ' ') *p++ = toupper_ascii(*str);
123 ++str;
125 *p = '\0';
126 return newstring;
129 static char *make_parm_name(const char *label)
131 static char parmname[1024];
132 char *p = parmname;
134 while (*label) {
135 if (*label == ' ') *p++ = '_';
136 else *p++ = *label;
137 ++label;
139 *p = '\0';
140 return parmname;
143 void get_xsrf_token(const char *username, const char *pass,
144 const char *formname, char token_str[33])
146 struct MD5Context md5_ctx;
147 uint8_t token[16];
148 int i;
150 token_str[0] = '\0';
151 ZERO_STRUCT(md5_ctx);
152 MD5Init(&md5_ctx);
154 MD5Update(&md5_ctx, (uint8_t *)formname, strlen(formname));
155 if (username != NULL) {
156 MD5Update(&md5_ctx, (uint8_t *)username, strlen(username));
158 if (pass != NULL) {
159 MD5Update(&md5_ctx, (uint8_t *)pass, strlen(pass));
162 MD5Final(token, &md5_ctx);
164 for(i = 0; i < sizeof(token); i++) {
165 char tmp[3];
167 snprintf(tmp, sizeof(tmp), "%02x", token[i]);
168 strncat(token_str, tmp, sizeof(tmp));
172 void print_xsrf_token(const char *username, const char *pass,
173 const char *formname)
175 char token[33];
177 get_xsrf_token(username, pass, formname, token);
178 printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
179 XSRF_TOKEN, token);
183 bool verify_xsrf_token(const char *formname)
185 char expected[33];
186 const char *username = cgi_user_name();
187 const char *pass = cgi_user_pass();
188 const char *token = cgi_variable_nonull(XSRF_TOKEN);
190 get_xsrf_token(username, pass, formname, expected);
191 return (strncmp(expected, token, sizeof(expected)) == 0);
195 /****************************************************************************
196 include a lump of html in a page
197 ****************************************************************************/
198 static int include_html(const char *fname)
200 int fd;
201 char buf[1024];
202 int ret;
204 fd = web_open(fname, O_RDONLY, 0);
206 if (fd == -1) {
207 printf(_("ERROR: Can't open %s"), fname);
208 printf("\n");
209 return 0;
212 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
213 if (write(1, buf, ret) == -1) {
214 break;
218 close(fd);
219 return 1;
222 /****************************************************************************
223 start the page with standard stuff
224 ****************************************************************************/
225 static void print_header(void)
227 if (!cgi_waspost()) {
228 printf("Expires: 0\r\n");
230 printf("Content-type: text/html\r\n\r\n");
232 if (!include_html("include/header.html")) {
233 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
234 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
238 /* *******************************************************************
239 show parameter label with translated name in the following form
240 because showing original and translated label in one line looks
241 too long, and showing translated label only is unusable for
242 heavy users.
243 -------------------------------
244 HELP security [combo box][button]
245 SECURITY
246 -------------------------------
247 (capital words are translated by gettext.)
248 if no translation is available, then same form as original is
249 used.
250 "i18n_translated_parm" class is used to change the color of the
251 translated parameter with CSS.
252 **************************************************************** */
253 static const char *get_parm_translated(TALLOC_CTX *ctx,
254 const char* pAnchor, const char* pHelp, const char* pLabel)
256 const char *pTranslated = _(pLabel);
257 char *output;
258 if(strcmp(pLabel, pTranslated) != 0) {
259 output = talloc_asprintf(ctx,
260 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s <br><span class=\"i18n_translated_parm\">%s</span>",
261 pAnchor, pHelp, pLabel, pTranslated);
262 return output;
264 output = talloc_asprintf(ctx,
265 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
266 pAnchor, pHelp, pLabel);
267 return output;
269 /****************************************************************************
270 finish off the page
271 ****************************************************************************/
272 static void print_footer(void)
274 if (!include_html("include/footer.html")) {
275 printf("\n</BODY>\n</HTML>\n");
279 /****************************************************************************
280 display one editable parameter in a form
281 ****************************************************************************/
282 static void show_parameter(int snum, struct parm_struct *parm)
284 int i;
285 void *ptr = parm->ptr;
286 char *utf8_s1, *utf8_s2;
287 size_t converted_size;
288 TALLOC_CTX *ctx = talloc_stackframe();
290 if (parm->p_class == P_LOCAL && snum >= 0) {
291 ptr = lp_local_ptr(snum, ptr);
294 printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
295 stripspaceupper(parm->label), _("Help"), parm->label));
296 switch (parm->type) {
297 case P_CHAR:
298 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
299 make_parm_name(parm->label), *(char *)ptr);
300 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
301 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
302 break;
304 case P_LIST:
305 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
306 make_parm_name(parm->label));
307 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
308 char **list = *(char ***)ptr;
309 for (;*list;list++) {
310 /* enclose in HTML encoded quotes if the string contains a space */
311 if ( strchr_m(*list, ' ') ) {
312 push_utf8_allocate(&utf8_s1, *list, &converted_size);
313 push_utf8_allocate(&utf8_s2, ((*(list+1))?", ":""), &converted_size);
314 printf("&quot;%s&quot;%s", utf8_s1, utf8_s2);
315 } else {
316 push_utf8_allocate(&utf8_s1, *list, &converted_size);
317 push_utf8_allocate(&utf8_s2, ((*(list+1))?", ":""), &converted_size);
318 printf("%s%s", utf8_s1, utf8_s2);
320 SAFE_FREE(utf8_s1);
321 SAFE_FREE(utf8_s2);
324 printf("\">");
325 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
326 _("Set Default"), make_parm_name(parm->label));
327 if (parm->def.lvalue) {
328 char **list = (char **)(parm->def.lvalue);
329 for (; *list; list++) {
330 /* enclose in HTML encoded quotes if the string contains a space */
331 if ( strchr_m(*list, ' ') )
332 printf("&quot;%s&quot;%s", *list, ((*(list+1))?", ":""));
333 else
334 printf("%s%s", *list, ((*(list+1))?", ":""));
337 printf("\'\">");
338 break;
340 case P_STRING:
341 case P_USTRING:
342 push_utf8_allocate(&utf8_s1, *(char **)ptr, &converted_size);
343 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
344 make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
345 SAFE_FREE(utf8_s1);
346 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
347 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
348 break;
350 case P_BOOL:
351 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
352 printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
353 printf("<option %s>No", (*(bool *)ptr)?"":"selected");
354 printf("</select>");
355 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
356 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
357 break;
359 case P_BOOLREV:
360 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
361 printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
362 printf("<option %s>No", (*(bool *)ptr)?"selected":"");
363 printf("</select>");
364 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
365 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
366 break;
368 case P_INTEGER:
369 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
370 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
371 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
372 break;
374 case P_OCTAL: {
375 char *o;
376 o = octal_string(*(int *)ptr);
377 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
378 make_parm_name(parm->label), o);
379 TALLOC_FREE(o);
380 o = octal_string((int)(parm->def.ivalue));
381 printf("<input type=button value=\"%s\" "
382 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
383 _("Set Default"), make_parm_name(parm->label), o);
384 TALLOC_FREE(o);
385 break;
388 case P_ENUM:
389 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
390 for (i=0;parm->enum_list[i].name;i++) {
391 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
392 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
395 printf("</select>");
396 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
397 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
398 break;
399 case P_SEP:
400 break;
402 printf("</td></tr>\n");
403 TALLOC_FREE(ctx);
406 /****************************************************************************
407 display a set of parameters for a service
408 ****************************************************************************/
409 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
411 int i = 0;
412 struct parm_struct *parm;
413 const char *heading = NULL;
414 const char *last_heading = NULL;
416 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
417 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
418 continue;
419 if (parm->p_class == P_SEPARATOR) {
420 heading = parm->label;
421 continue;
423 if (parm->flags & FLAG_HIDE) continue;
424 if (snum >= 0) {
425 if (printers & !(parm->flags & FLAG_PRINT)) continue;
426 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
429 if (!( parm_filter & FLAG_ADVANCED )) {
430 if (!(parm->flags & FLAG_BASIC)) {
431 void *ptr = parm->ptr;
433 if (parm->p_class == P_LOCAL && snum >= 0) {
434 ptr = lp_local_ptr(snum, ptr);
437 switch (parm->type) {
438 case P_CHAR:
439 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
440 break;
442 case P_LIST:
443 if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
444 break;
446 case P_STRING:
447 case P_USTRING:
448 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
449 break;
451 case P_BOOL:
452 case P_BOOLREV:
453 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
454 break;
456 case P_INTEGER:
457 case P_OCTAL:
458 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
459 break;
462 case P_ENUM:
463 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
464 break;
465 case P_SEP:
466 continue;
469 if (printers && !(parm->flags & FLAG_PRINT)) continue;
472 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
474 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
476 if (heading && heading != last_heading) {
477 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
478 last_heading = heading;
480 show_parameter(snum, parm);
484 /****************************************************************************
485 load the smb.conf file into loadparm.
486 ****************************************************************************/
487 static bool load_config(bool save_def)
489 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
492 /****************************************************************************
493 write a config file
494 ****************************************************************************/
495 static void write_config(FILE *f, bool show_defaults)
497 TALLOC_CTX *ctx = talloc_stackframe();
499 fprintf(f, "# Samba config file created using SWAT\n");
500 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
501 fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
503 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
505 TALLOC_FREE(ctx);
508 /****************************************************************************
509 save and reload the smb.conf config file
510 ****************************************************************************/
511 static int save_reload(int snum)
513 FILE *f;
514 struct stat st;
516 f = sys_fopen(get_dyn_CONFIGFILE(),"w");
517 if (!f) {
518 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
519 printf("\n");
520 return 0;
523 /* just in case they have used the buggy xinetd to create the file */
524 if (fstat(fileno(f), &st) == 0 &&
525 (st.st_mode & S_IWOTH)) {
526 #if defined HAVE_FCHMOD
527 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
528 #else
529 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
530 #endif
533 write_config(f, False);
534 if (snum >= 0)
535 lp_dump_one(f, False, snum);
536 fclose(f);
538 lp_kill_all_services();
540 if (!load_config(False)) {
541 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
542 printf("\n");
543 return 0;
545 iNumNonAutoPrintServices = lp_numservices();
546 load_printers();
548 return 1;
551 /****************************************************************************
552 commit one parameter
553 ****************************************************************************/
554 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
556 int i;
557 char *s;
559 if (snum < 0 && parm->p_class == P_LOCAL) {
560 /* this handles the case where we are changing a local
561 variable globally. We need to change the parameter in
562 all shares where it is currently set to the default */
563 for (i=0;i<lp_numservices();i++) {
564 s = lp_servicename(i);
565 if (s && (*s) && lp_is_default(i, parm)) {
566 lp_do_parameter(i, parm->label, v);
571 lp_do_parameter(snum, parm->label, v);
574 /****************************************************************************
575 commit a set of parameters for a service
576 ****************************************************************************/
577 static void commit_parameters(int snum)
579 int i = 0;
580 struct parm_struct *parm;
581 char *label;
582 const char *v;
584 while ((parm = lp_next_parameter(snum, &i, 1))) {
585 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
586 if ((v = cgi_variable(label)) != NULL) {
587 if (parm->flags & FLAG_HIDE)
588 continue;
589 commit_parameter(snum, parm, v);
591 SAFE_FREE(label);
596 /****************************************************************************
597 spit out the html for a link with an image
598 ****************************************************************************/
599 static void image_link(const char *name, const char *hlink, const char *src)
601 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
602 cgi_baseurl(), hlink, src, name);
605 /****************************************************************************
606 display the main navigation controls at the top of each page along
607 with a title
608 ****************************************************************************/
609 static void show_main_buttons(void)
611 char *p;
613 if ((p = cgi_user_name()) && strcmp(p, "root")) {
614 printf(_("Logged in as <b>%s</b>"), p);
615 printf("<p>\n");
618 image_link(_("Home"), "", "images/home.gif");
619 if (have_write_access) {
620 image_link(_("Globals"), "globals", "images/globals.gif");
621 image_link(_("Shares"), "shares", "images/shares.gif");
622 image_link(_("Printers"), "printers", "images/printers.gif");
623 image_link(_("Wizard"), "wizard", "images/wizard.gif");
625 /* root always gets all buttons, otherwise look for -P */
626 if ( have_write_access || (!passwd_only && have_read_access) ) {
627 image_link(_("Status"), "status", "images/status.gif");
628 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
630 image_link(_("Password Management"), "passwd", "images/passwd.gif");
632 printf("<HR>\n");
635 /****************************************************************************
636 * Handle Display/Edit Mode CGI
637 ****************************************************************************/
638 static void ViewModeBoxes(int mode)
640 printf("<p>%s:&nbsp;\n", _("Current View Is"));
641 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
642 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
643 printf("<br>%s:&nbsp;\n", _("Change View To"));
644 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
645 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
646 printf("</p><br>\n");
649 /****************************************************************************
650 display a welcome page
651 ****************************************************************************/
652 static void welcome_page(void)
654 if (file_exist("help/welcome.html", NULL)) {
655 include_html("help/welcome.html");
656 } else {
657 include_html("help/welcome-no-samba-doc.html");
661 /****************************************************************************
662 display the current smb.conf
663 ****************************************************************************/
664 static void viewconfig_page(void)
666 int full_view=0;
667 const char form_name[] = "viewconfig";
669 if (!verify_xsrf_token(form_name)) {
670 goto output_page;
673 if (cgi_variable("full_view")) {
674 full_view = 1;
677 output_page:
678 printf("<H2>%s</H2>\n", _("Current Config"));
679 printf("<form method=post>\n");
680 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
682 if (full_view) {
683 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
684 } else {
685 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
688 printf("<p><pre>");
689 write_config(stdout, full_view);
690 printf("</pre>");
691 printf("</form>\n");
694 /****************************************************************************
695 second screen of the wizard ... Fetch Configuration Parameters
696 ****************************************************************************/
697 static void wizard_params_page(void)
699 unsigned int parm_filter = FLAG_WIZARD;
701 /* Here we first set and commit all the parameters that were selected
702 in the previous screen. */
704 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
706 if (cgi_variable("Commit")) {
707 commit_parameters(GLOBAL_SECTION_SNUM);
708 save_reload(0);
711 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
713 if (have_write_access) {
714 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
717 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
718 printf("<p>\n");
720 printf("<table>\n");
721 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
722 printf("</table>\n");
723 printf("</form>\n");
726 /****************************************************************************
727 Utility to just rewrite the smb.conf file - effectively just cleans it up
728 ****************************************************************************/
729 static void rewritecfg_file(void)
731 commit_parameters(GLOBAL_SECTION_SNUM);
732 save_reload(0);
733 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
736 /****************************************************************************
737 wizard to create/modify the smb.conf file
738 ****************************************************************************/
739 static void wizard_page(void)
741 /* Set some variables to collect data from smb.conf */
742 int role = 0;
743 int winstype = 0;
744 int have_home = -1;
745 int HomeExpo = 0;
746 int SerType = 0;
748 if (cgi_variable("Rewrite")) {
749 (void) rewritecfg_file();
750 return;
753 if (cgi_variable("GetWizardParams")){
754 (void) wizard_params_page();
755 return;
758 if (cgi_variable("Commit")){
759 SerType = atoi(cgi_variable_nonull("ServerType"));
760 winstype = atoi(cgi_variable_nonull("WINSType"));
761 have_home = lp_servicenumber(HOMES_NAME);
762 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
764 /* Plain text passwords are too badly broken - use encrypted passwords only */
765 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
767 switch ( SerType ){
768 case 0:
769 /* Stand-alone Server */
770 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
771 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
772 break;
773 case 1:
774 /* Domain Member */
775 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
776 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
777 break;
778 case 2:
779 /* Domain Controller */
780 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
781 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
782 break;
784 switch ( winstype ) {
785 case 0:
786 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
787 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
788 break;
789 case 1:
790 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
791 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
792 break;
793 case 2:
794 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
795 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
796 break;
799 /* Have to create Homes share? */
800 if ((HomeExpo == 1) && (have_home == -1)) {
801 const char *unix_share = HOMES_NAME;
803 load_config(False);
804 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
805 have_home = lp_servicenumber(HOMES_NAME);
806 lp_do_parameter( have_home, "read only", "No");
807 lp_do_parameter( have_home, "valid users", "%S");
808 lp_do_parameter( have_home, "browseable", "No");
809 commit_parameters(have_home);
810 save_reload(have_home);
813 /* Need to Delete Homes share? */
814 if ((HomeExpo == 0) && (have_home != -1)) {
815 lp_remove_service(have_home);
816 have_home = -1;
819 commit_parameters(GLOBAL_SECTION_SNUM);
820 save_reload(0);
822 else
824 /* Now determine smb.conf WINS settings */
825 if (lp_wins_support())
826 winstype = 1;
827 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
828 winstype = 2;
830 /* Do we have a homes share? */
831 have_home = lp_servicenumber(HOMES_NAME);
833 if ((winstype == 2) && lp_wins_support())
834 winstype = 3;
836 role = lp_server_role();
838 /* Here we go ... */
839 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
840 printf("<form method=post action=wizard>\n");
842 if (have_write_access) {
843 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
844 printf("%s", _("The same will happen if you press the commit button."));
845 printf("<br><br>\n");
846 printf("<center>");
847 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
848 printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
849 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
850 printf("</center>\n");
853 printf("<hr>");
854 printf("<center><table border=0>");
855 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
856 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
857 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
858 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
859 printf("</tr>\n");
860 if (role == ROLE_DOMAIN_BDC) {
861 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
863 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
864 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
865 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
866 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
867 printf("</tr>\n");
868 printf("<tr><td></td><td></td><td></td><td>%s&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
870 /* Print out the list of wins servers */
871 if(lp_wins_server_list()) {
872 int i;
873 const char **wins_servers = lp_wins_server_list();
874 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
877 printf("\"></td></tr>\n");
878 if (winstype == 3) {
879 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"));
880 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
882 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
883 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
884 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
885 printf("<td></td></tr>\n");
887 /* Enable this when we are ready ....
888 * printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
889 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
890 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
891 * printf("<td></td></tr>\n");
894 printf("</table></center>");
895 printf("<hr>");
897 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
898 printf("</form>\n");
902 /****************************************************************************
903 display a globals editing page
904 ****************************************************************************/
905 static void globals_page(void)
907 unsigned int parm_filter = FLAG_BASIC;
908 int mode = 0;
910 printf("<H2>%s</H2>\n", _("Global Parameters"));
912 if (cgi_variable("Commit")) {
913 commit_parameters(GLOBAL_SECTION_SNUM);
914 save_reload(0);
917 if ( cgi_variable("ViewMode") )
918 mode = atoi(cgi_variable_nonull("ViewMode"));
919 if ( cgi_variable("BasicMode"))
920 mode = 0;
921 if ( cgi_variable("AdvMode"))
922 mode = 1;
924 printf("<form name=\"swatform\" method=post action=globals>\n");
926 ViewModeBoxes( mode );
927 switch ( mode ) {
928 case 0:
929 parm_filter = FLAG_BASIC;
930 break;
931 case 1:
932 parm_filter = FLAG_ADVANCED;
933 break;
935 printf("<br>\n");
936 if (have_write_access) {
937 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
938 _("Commit Changes"));
941 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
942 _("Reset Values"));
944 printf("<p>\n");
945 printf("<table>\n");
946 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
947 printf("</table>\n");
948 printf("</form>\n");
951 /****************************************************************************
952 display a shares editing page. share is in unix codepage,
953 ****************************************************************************/
954 static void shares_page(void)
956 const char *share = cgi_variable("share");
957 char *s;
958 char *utf8_s;
959 int snum = -1;
960 int i;
961 int mode = 0;
962 unsigned int parm_filter = FLAG_BASIC;
963 size_t converted_size;
965 if (share)
966 snum = lp_servicenumber(share);
968 printf("<H2>%s</H2>\n", _("Share Parameters"));
970 if (cgi_variable("Commit") && snum >= 0) {
971 commit_parameters(snum);
972 save_reload(0);
973 snum = lp_servicenumber(share);
976 if (cgi_variable("Delete") && snum >= 0) {
977 lp_remove_service(snum);
978 save_reload(0);
979 share = NULL;
980 snum = -1;
983 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
984 snum = lp_servicenumber(share);
985 if (snum < 0) {
986 load_config(False);
987 lp_copy_service(GLOBAL_SECTION_SNUM, share);
988 snum = lp_servicenumber(share);
989 save_reload(snum);
990 snum = lp_servicenumber(share);
994 printf("<FORM name=\"swatform\" method=post>\n");
996 printf("<table>\n");
998 if ( cgi_variable("ViewMode") )
999 mode = atoi(cgi_variable_nonull("ViewMode"));
1000 if ( cgi_variable("BasicMode"))
1001 mode = 0;
1002 if ( cgi_variable("AdvMode"))
1003 mode = 1;
1005 ViewModeBoxes( mode );
1006 switch ( mode ) {
1007 case 0:
1008 parm_filter = FLAG_BASIC;
1009 break;
1010 case 1:
1011 parm_filter = FLAG_ADVANCED;
1012 break;
1014 printf("<br><tr>\n");
1015 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1016 printf("<td><select name=share>\n");
1017 if (snum < 0)
1018 printf("<option value=\" \"> \n");
1019 for (i=0;i<lp_numservices();i++) {
1020 s = lp_servicename(i);
1021 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
1022 push_utf8_allocate(&utf8_s, s, &converted_size);
1023 printf("<option %s value=\"%s\">%s\n",
1024 (share && strcmp(share,s)==0)?"SELECTED":"",
1025 utf8_s, utf8_s);
1026 SAFE_FREE(utf8_s);
1029 printf("</select></td>\n");
1030 if (have_write_access) {
1031 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1033 printf("</tr>\n");
1034 printf("</table>");
1035 printf("<table>");
1036 if (have_write_access) {
1037 printf("<tr>\n");
1038 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1039 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1041 printf("</table>");
1044 if (snum >= 0) {
1045 if (have_write_access) {
1046 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1049 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1050 printf("<p>\n");
1053 if (snum >= 0) {
1054 printf("<table>\n");
1055 show_parameters(snum, 1, parm_filter, 0);
1056 printf("</table>\n");
1059 printf("</FORM>\n");
1062 /*************************************************************
1063 change a password either locally or remotely
1064 *************************************************************/
1065 static bool change_password(const char *remote_machine, const char *user_name,
1066 const char *old_passwd, const char *new_passwd,
1067 int local_flags)
1069 NTSTATUS ret;
1070 char *err_str = NULL;
1071 char *msg_str = NULL;
1073 if (demo_mode) {
1074 printf("%s\n<p>", _("password change in demo mode rejected"));
1075 return False;
1078 if (remote_machine != NULL) {
1079 ret = remote_password_change(remote_machine, user_name,
1080 old_passwd, new_passwd, &err_str);
1081 if (err_str != NULL)
1082 printf("%s\n<p>", err_str);
1083 SAFE_FREE(err_str);
1084 return NT_STATUS_IS_OK(ret);
1087 if(!initialize_password_db(True, NULL)) {
1088 printf("%s\n<p>", _("Can't setup password database vectors."));
1089 return False;
1092 ret = local_password_change(user_name, local_flags, new_passwd,
1093 &err_str, &msg_str);
1095 if(msg_str)
1096 printf("%s\n<p>", msg_str);
1097 if(err_str)
1098 printf("%s\n<p>", err_str);
1100 SAFE_FREE(msg_str);
1101 SAFE_FREE(err_str);
1102 return NT_STATUS_IS_OK(ret);
1105 /****************************************************************************
1106 do the stuff required to add or change a password
1107 ****************************************************************************/
1108 static void chg_passwd(void)
1110 const char *host;
1111 bool rslt;
1112 int local_flags = 0;
1114 /* Make sure users name has been specified */
1115 if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1116 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1117 return;
1121 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1122 * so if that's what we're doing, skip the rest of the checks
1124 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1127 * If current user is not root, make sure old password has been specified
1128 * If REMOTE change, even root must provide old password
1130 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1131 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1132 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1133 return;
1136 /* If changing a users password on a remote hosts we have to know what host */
1137 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1138 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1139 return;
1142 /* Make sure new passwords have been specified */
1143 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1144 (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1145 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1146 return;
1149 /* Make sure new passwords was typed correctly twice */
1150 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1151 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1152 return;
1156 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1157 host = cgi_variable(RHOST);
1158 } else if (am_root()) {
1159 host = NULL;
1160 } else {
1161 host = "127.0.0.1";
1165 * Set up the local flags.
1168 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1169 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1170 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1171 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1172 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1173 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1176 rslt = change_password(host,
1177 cgi_variable_nonull(SWAT_USER),
1178 cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1179 local_flags);
1181 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1182 printf("<p>");
1183 if (rslt == True) {
1184 printf("%s\n", _(" The passwd has been changed."));
1185 } else {
1186 printf("%s\n", _(" The passwd for has NOT been changed."));
1190 return;
1193 /****************************************************************************
1194 display a password editing page
1195 ****************************************************************************/
1196 static void passwd_page(void)
1198 const char *new_name = cgi_user_name();
1200 if (!new_name) new_name = "";
1202 printf("<H2>%s</H2>\n", _("Server Password Management"));
1204 printf("<FORM name=\"swatform\" method=post>\n");
1206 printf("<table>\n");
1209 * Create all the dialog boxes for data collection
1211 printf("<tr><td> %s : </td>\n", _("User Name"));
1212 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1213 if (!am_root()) {
1214 printf("<tr><td> %s : </td>\n", _("Old Password"));
1215 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1217 printf("<tr><td> %s : </td>\n", _("New Password"));
1218 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1219 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1220 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1221 printf("</table>\n");
1224 * Create all the control buttons for requesting action
1226 printf("<input type=submit name=%s value=\"%s\">\n",
1227 CHG_S_PASSWD_FLAG, _("Change Password"));
1228 if (demo_mode || am_root()) {
1229 printf("<input type=submit name=%s value=\"%s\">\n",
1230 ADD_USER_FLAG, _("Add New User"));
1231 printf("<input type=submit name=%s value=\"%s\">\n",
1232 DELETE_USER_FLAG, _("Delete User"));
1233 printf("<input type=submit name=%s value=\"%s\">\n",
1234 DISABLE_USER_FLAG, _("Disable User"));
1235 printf("<input type=submit name=%s value=\"%s\">\n",
1236 ENABLE_USER_FLAG, _("Enable User"));
1238 printf("<p></FORM>\n");
1241 * Do some work if change, add, disable or enable was
1242 * requested. It could be this is the first time through this
1243 * code, so there isn't anything to do. */
1244 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1245 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1246 chg_passwd();
1249 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1251 printf("<FORM name=\"swatform\" method=post>\n");
1253 printf("<table>\n");
1256 * Create all the dialog boxes for data collection
1258 printf("<tr><td> %s : </td>\n", _("User Name"));
1259 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1260 printf("<tr><td> %s : </td>\n", _("Old Password"));
1261 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1262 printf("<tr><td> %s : </td>\n", _("New Password"));
1263 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1264 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1265 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1266 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1267 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1269 printf("</table>");
1272 * Create all the control buttons for requesting action
1274 printf("<input type=submit name=%s value=\"%s\">",
1275 CHG_R_PASSWD_FLAG, _("Change Password"));
1277 printf("<p></FORM>\n");
1280 * Do some work if a request has been made to change the
1281 * password somewhere other than the server. It could be this
1282 * is the first time through this code, so there isn't
1283 * anything to do. */
1284 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1285 chg_passwd();
1290 /****************************************************************************
1291 display a printers editing page
1292 ****************************************************************************/
1293 static void printers_page(void)
1295 const char *share = cgi_variable("share");
1296 char *s;
1297 int snum=-1;
1298 int i;
1299 int mode = 0;
1300 unsigned int parm_filter = FLAG_BASIC;
1302 if (share)
1303 snum = lp_servicenumber(share);
1305 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1307 printf("<H3>%s</H3>\n", _("Important Note:"));
1308 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1309 printf("%s",_("are autoloaded printers from "));
1310 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1311 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1313 if (cgi_variable("Commit") && snum >= 0) {
1314 commit_parameters(snum);
1315 if (snum >= iNumNonAutoPrintServices)
1316 save_reload(snum);
1317 else
1318 save_reload(0);
1319 snum = lp_servicenumber(share);
1322 if (cgi_variable("Delete") && snum >= 0) {
1323 lp_remove_service(snum);
1324 save_reload(0);
1325 share = NULL;
1326 snum = -1;
1329 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1330 snum = lp_servicenumber(share);
1331 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1332 load_config(False);
1333 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1334 snum = lp_servicenumber(share);
1335 lp_do_parameter(snum, "print ok", "Yes");
1336 save_reload(snum);
1337 snum = lp_servicenumber(share);
1341 printf("<FORM name=\"swatform\" method=post>\n");
1343 if ( cgi_variable("ViewMode") )
1344 mode = atoi(cgi_variable_nonull("ViewMode"));
1345 if ( cgi_variable("BasicMode"))
1346 mode = 0;
1347 if ( cgi_variable("AdvMode"))
1348 mode = 1;
1350 ViewModeBoxes( mode );
1351 switch ( mode ) {
1352 case 0:
1353 parm_filter = FLAG_BASIC;
1354 break;
1355 case 1:
1356 parm_filter = FLAG_ADVANCED;
1357 break;
1359 printf("<table>\n");
1360 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1361 printf("<td><select name=\"share\">\n");
1362 if (snum < 0 || !lp_print_ok(snum))
1363 printf("<option value=\" \"> \n");
1364 for (i=0;i<lp_numservices();i++) {
1365 s = lp_servicename(i);
1366 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1367 if (i >= iNumNonAutoPrintServices)
1368 printf("<option %s value=\"%s\">[*]%s\n",
1369 (share && strcmp(share,s)==0)?"SELECTED":"",
1370 s, s);
1371 else
1372 printf("<option %s value=\"%s\">%s\n",
1373 (share && strcmp(share,s)==0)?"SELECTED":"",
1374 s, s);
1377 printf("</select></td>");
1378 if (have_write_access) {
1379 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1381 printf("</tr>");
1382 printf("</table>\n");
1384 if (have_write_access) {
1385 printf("<table>\n");
1386 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1387 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1388 printf("</table>");
1392 if (snum >= 0) {
1393 if (have_write_access) {
1394 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1396 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1397 printf("<p>\n");
1400 if (snum >= 0) {
1401 printf("<table>\n");
1402 show_parameters(snum, 1, parm_filter, 1);
1403 printf("</table>\n");
1405 printf("</FORM>\n");
1409 when the _() translation macro is used there is no obvious place to free
1410 the resulting string and there is no easy way to give a static pointer.
1411 All we can do is rotate between some static buffers and hope a single d_printf()
1412 doesn't have more calls to _() than the number of buffers
1415 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1417 const char *msgstr;
1418 const char *ret;
1420 msgstr = lang_msg(msgid);
1421 if (!msgstr) {
1422 return msgid;
1425 ret = talloc_strdup(ctx, msgstr);
1427 lang_msg_free(msgstr);
1428 if (!ret) {
1429 return msgid;
1432 return ret;
1436 * main function for SWAT.
1438 int main(int argc, char *argv[])
1440 const char *page;
1441 poptContext pc;
1442 struct poptOption long_options[] = {
1443 POPT_AUTOHELP
1444 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1445 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1446 POPT_COMMON_SAMBA
1447 POPT_TABLEEND
1449 TALLOC_CTX *frame = talloc_stackframe();
1451 fault_setup(NULL);
1452 umask(S_IWGRP | S_IWOTH);
1454 #if defined(HAVE_SET_AUTH_PARAMETERS)
1455 set_auth_parameters(argc, argv);
1456 #endif /* HAVE_SET_AUTH_PARAMETERS */
1458 /* just in case it goes wild ... */
1459 alarm(300);
1461 setlinebuf(stdout);
1463 /* we don't want any SIGPIPE messages */
1464 BlockSignals(True,SIGPIPE);
1466 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1467 if (!dbf) dbf = x_stderr;
1469 /* we don't want stderr screwing us up */
1470 close(2);
1471 open("/dev/null", O_WRONLY);
1473 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1475 /* Parse command line options */
1477 while(poptGetNextOpt(pc) != -1) { }
1479 poptFreeContext(pc);
1481 load_case_tables();
1483 setup_logging(argv[0],False);
1484 load_config(True);
1485 load_interfaces();
1486 iNumNonAutoPrintServices = lp_numservices();
1487 load_printers();
1489 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1491 print_header();
1493 cgi_load_variables();
1495 if (!file_exist(get_dyn_CONFIGFILE(), NULL)) {
1496 have_read_access = True;
1497 have_write_access = True;
1498 } else {
1499 /* check if the authenticated user has write access - if not then
1500 don't show write options */
1501 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1503 /* if the user doesn't have read access to smb.conf then
1504 don't let them view it */
1505 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1508 show_main_buttons();
1510 page = cgi_pathinfo();
1512 /* Root gets full functionality */
1513 if (have_read_access && strcmp(page, "globals")==0) {
1514 globals_page();
1515 } else if (have_read_access && strcmp(page,"shares")==0) {
1516 shares_page();
1517 } else if (have_read_access && strcmp(page,"printers")==0) {
1518 printers_page();
1519 } else if (have_read_access && strcmp(page,"status")==0) {
1520 status_page();
1521 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1522 viewconfig_page();
1523 } else if (strcmp(page,"passwd")==0) {
1524 passwd_page();
1525 } else if (have_read_access && strcmp(page,"wizard")==0) {
1526 wizard_page();
1527 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1528 wizard_params_page();
1529 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1530 rewritecfg_file();
1531 } else {
1532 welcome_page();
1535 print_footer();
1537 TALLOC_FREE(frame);
1538 return 0;
1541 /** @} **/