2 Unix SMB/CIFS implementation.
3 Samba Web Administration Tool
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/>.
23 * @defgroup swat SWAT - Samba Web Administration Tool
27 * @brief Samba Web Administration Tool.
31 #include "web/swat_proto.h"
32 #include "../lib/crypto/md5.h"
34 static int demo_mode
= False
;
35 static int passwd_only
= False
;
36 static bool have_write_access
= False
;
37 static bool have_read_access
= False
;
38 static int iNumNonAutoPrintServices
= 0;
41 * Password Management Globals
43 #define SWAT_USER "username"
44 #define OLD_PSWD "old_passwd"
45 #define NEW_PSWD "new_passwd"
46 #define NEW2_PSWD "new2_passwd"
47 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
48 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
49 #define ADD_USER_FLAG "add_user_flag"
50 #define DELETE_USER_FLAG "delete_user_flag"
51 #define DISABLE_USER_FLAG "disable_user_flag"
52 #define ENABLE_USER_FLAG "enable_user_flag"
53 #define RHOST "remote_host"
54 #define XSRF_TOKEN "xsrf"
55 #define XSRF_TIME "xsrf_time"
56 #define XSRF_TIMEOUT 300
58 #define _(x) lang_msg_rotate(talloc_tos(),x)
60 /****************************************************************************
61 ****************************************************************************/
62 static int enum_index(int value
, const struct enum_list
*enumlist
)
65 for (i
=0;enumlist
[i
].name
;i
++)
66 if (value
== enumlist
[i
].value
) break;
70 static char *fix_backslash(const char *str
)
72 static char newstring
[1024];
76 if (*str
== '\\') {*p
++ = '\\';*p
++ = '\\';}
84 static const char *fix_quotes(TALLOC_CTX
*ctx
, const char *str
)
86 char *newstring
= NULL
;
89 int quote_len
= strlen(""");
91 /* Count the number of quotes. */
96 newstring_len
+= quote_len
;
102 newstring
= TALLOC_ARRAY(ctx
, char, newstring_len
);
106 for (p
= newstring
; *str
; str
++) {
108 strncpy( p
, """, quote_len
);
118 static char *stripspaceupper(const char *str
)
120 static char newstring
[1024];
124 if (*str
!= ' ') *p
++ = toupper_ascii(*str
);
131 static char *make_parm_name(const char *label
)
133 static char parmname
[1024];
137 if (*label
== ' ') *p
++ = '_';
145 void get_xsrf_token(const char *username
, const char *pass
,
146 const char *formname
, time_t xsrf_time
, char token_str
[33])
148 struct MD5Context md5_ctx
;
153 ZERO_STRUCT(md5_ctx
);
156 MD5Update(&md5_ctx
, (uint8_t *)formname
, strlen(formname
));
157 MD5Update(&md5_ctx
, (uint8_t *)&xsrf_time
, sizeof(time_t));
158 if (username
!= NULL
) {
159 MD5Update(&md5_ctx
, (uint8_t *)username
, strlen(username
));
162 MD5Update(&md5_ctx
, (uint8_t *)pass
, strlen(pass
));
165 MD5Final(token
, &md5_ctx
);
167 for(i
= 0; i
< sizeof(token
); i
++) {
170 snprintf(tmp
, sizeof(tmp
), "%02x", token
[i
]);
171 strncat(token_str
, tmp
, sizeof(tmp
));
175 void print_xsrf_token(const char *username
, const char *pass
,
176 const char *formname
)
179 time_t xsrf_time
= time(NULL
);
181 get_xsrf_token(username
, pass
, formname
, xsrf_time
, token
);
182 printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
184 printf("<input type=\"hidden\" name=\"%s\" value=\"%lld\">\n",
185 XSRF_TIME
, (long long int)xsrf_time
);
188 bool verify_xsrf_token(const char *formname
)
191 const char *username
= cgi_user_name();
192 const char *pass
= cgi_user_pass();
193 const char *token
= cgi_variable_nonull(XSRF_TOKEN
);
194 const char *time_str
= cgi_variable_nonull(XSRF_TIME
);
195 time_t xsrf_time
= 0;
196 time_t now
= time(NULL
);
198 if (sizeof(time_t) == sizeof(int)) {
199 xsrf_time
= atoi(time_str
);
200 } else if (sizeof(time_t) == sizeof(long)) {
201 xsrf_time
= atol(time_str
);
202 } else if (sizeof(time_t) == sizeof(long long)) {
203 xsrf_time
= atoll(time_str
);
206 if (abs(now
- xsrf_time
) > XSRF_TIMEOUT
) {
210 get_xsrf_token(username
, pass
, formname
, xsrf_time
, expected
);
211 return (strncmp(expected
, token
, sizeof(expected
)) == 0);
215 /****************************************************************************
216 include a lump of html in a page
217 ****************************************************************************/
218 static int include_html(const char *fname
)
224 fd
= web_open(fname
, O_RDONLY
, 0);
227 printf(_("ERROR: Can't open %s"), fname
);
232 while ((ret
= read(fd
, buf
, sizeof(buf
))) > 0) {
233 if (write(1, buf
, ret
) == -1) {
242 /****************************************************************************
243 start the page with standard stuff
244 ****************************************************************************/
245 static void print_header(void)
247 if (!cgi_waspost()) {
248 printf("Expires: 0\r\n");
250 printf("Content-type: text/html\r\n\r\n");
252 if (!include_html("include/header.html")) {
253 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
254 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
258 /* *******************************************************************
259 show parameter label with translated name in the following form
260 because showing original and translated label in one line looks
261 too long, and showing translated label only is unusable for
263 -------------------------------
264 HELP security [combo box][button]
266 -------------------------------
267 (capital words are translated by gettext.)
268 if no translation is available, then same form as original is
270 "i18n_translated_parm" class is used to change the color of the
271 translated parameter with CSS.
272 **************************************************************** */
273 static const char *get_parm_translated(TALLOC_CTX
*ctx
,
274 const char* pAnchor
, const char* pHelp
, const char* pLabel
)
276 const char *pTranslated
= _(pLabel
);
278 if(strcmp(pLabel
, pTranslated
) != 0) {
279 output
= talloc_asprintf(ctx
,
280 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
281 pAnchor
, pHelp
, pLabel
, pTranslated
);
284 output
= talloc_asprintf(ctx
,
285 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
286 pAnchor
, pHelp
, pLabel
);
289 /****************************************************************************
291 ****************************************************************************/
292 static void print_footer(void)
294 if (!include_html("include/footer.html")) {
295 printf("\n</BODY>\n</HTML>\n");
299 /****************************************************************************
300 display one editable parameter in a form
301 ****************************************************************************/
302 static void show_parameter(int snum
, struct parm_struct
*parm
)
305 void *ptr
= parm
->ptr
;
306 char *utf8_s1
, *utf8_s2
;
307 size_t converted_size
;
308 TALLOC_CTX
*ctx
= talloc_stackframe();
310 if (parm
->p_class
== P_LOCAL
&& snum
>= 0) {
311 ptr
= lp_local_ptr_by_snum(snum
, ptr
);
314 printf("<tr><td>%s</td><td>", get_parm_translated(ctx
,
315 stripspaceupper(parm
->label
), _("Help"), parm
->label
));
316 switch (parm
->type
) {
318 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
319 make_parm_name(parm
->label
), *(char *)ptr
);
320 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
321 _("Set Default"), make_parm_name(parm
->label
),(char)(parm
->def
.cvalue
));
325 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
326 make_parm_name(parm
->label
));
327 if ((char ***)ptr
&& *(char ***)ptr
&& **(char ***)ptr
) {
328 char **list
= *(char ***)ptr
;
329 for (;*list
;list
++) {
330 /* enclose in HTML encoded quotes if the string contains a space */
331 if ( strchr_m(*list
, ' ') ) {
332 push_utf8_talloc(talloc_tos(), &utf8_s1
, *list
, &converted_size
);
333 push_utf8_talloc(talloc_tos(), &utf8_s2
, ((*(list
+1))?", ":""), &converted_size
);
334 printf(""%s"%s", utf8_s1
, utf8_s2
);
336 push_utf8_talloc(talloc_tos(), &utf8_s1
, *list
, &converted_size
);
337 push_utf8_talloc(talloc_tos(), &utf8_s2
, ((*(list
+1))?", ":""), &converted_size
);
338 printf("%s%s", utf8_s1
, utf8_s2
);
340 TALLOC_FREE(utf8_s1
);
341 TALLOC_FREE(utf8_s2
);
345 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
346 _("Set Default"), make_parm_name(parm
->label
));
347 if (parm
->def
.lvalue
) {
348 char **list
= (char **)(parm
->def
.lvalue
);
349 for (; *list
; list
++) {
350 /* enclose in HTML encoded quotes if the string contains a space */
351 if ( strchr_m(*list
, ' ') )
352 printf(""%s"%s", *list
, ((*(list
+1))?", ":""));
354 printf("%s%s", *list
, ((*(list
+1))?", ":""));
362 push_utf8_talloc(talloc_tos(), &utf8_s1
, *(char **)ptr
, &converted_size
);
363 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
364 make_parm_name(parm
->label
), fix_quotes(ctx
, utf8_s1
));
365 TALLOC_FREE(utf8_s1
);
366 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
367 _("Set Default"), make_parm_name(parm
->label
),fix_backslash((char *)(parm
->def
.svalue
)));
371 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
372 printf("<option %s>Yes", (*(bool *)ptr
)?"selected":"");
373 printf("<option %s>No", (*(bool *)ptr
)?"":"selected");
375 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
376 _("Set Default"), make_parm_name(parm
->label
),(bool)(parm
->def
.bvalue
)?0:1);
380 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
381 printf("<option %s>Yes", (*(bool *)ptr
)?"":"selected");
382 printf("<option %s>No", (*(bool *)ptr
)?"selected":"");
384 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
385 _("Set Default"), make_parm_name(parm
->label
),(bool)(parm
->def
.bvalue
)?1:0);
389 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm
->label
), *(int *)ptr
);
390 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
391 _("Set Default"), make_parm_name(parm
->label
),(int)(parm
->def
.ivalue
));
396 o
= octal_string(*(int *)ptr
);
397 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
398 make_parm_name(parm
->label
), o
);
400 o
= octal_string((int)(parm
->def
.ivalue
));
401 printf("<input type=button value=\"%s\" "
402 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
403 _("Set Default"), make_parm_name(parm
->label
), o
);
409 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
410 for (i
=0;parm
->enum_list
[i
].name
;i
++) {
411 if (i
== 0 || parm
->enum_list
[i
].value
!= parm
->enum_list
[i
-1].value
) {
412 printf("<option %s>%s",(*(int *)ptr
)==parm
->enum_list
[i
].value
?"selected":"",parm
->enum_list
[i
].name
);
416 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
417 _("Set Default"), make_parm_name(parm
->label
),enum_index((int)(parm
->def
.ivalue
),parm
->enum_list
));
422 printf("</td></tr>\n");
426 /****************************************************************************
427 display a set of parameters for a service
428 ****************************************************************************/
429 static void show_parameters(int snum
, int allparameters
, unsigned int parm_filter
, int printers
)
432 struct parm_struct
*parm
;
433 const char *heading
= NULL
;
434 const char *last_heading
= NULL
;
436 while ((parm
= lp_next_parameter(snum
, &i
, allparameters
))) {
437 if (snum
< 0 && parm
->p_class
== P_LOCAL
&& !(parm
->flags
& FLAG_GLOBAL
))
439 if (parm
->p_class
== P_SEPARATOR
) {
440 heading
= parm
->label
;
443 if (parm
->flags
& FLAG_HIDE
) continue;
445 if (printers
& !(parm
->flags
& FLAG_PRINT
)) continue;
446 if (!printers
& !(parm
->flags
& FLAG_SHARE
)) continue;
449 if (!( parm_filter
& FLAG_ADVANCED
)) {
450 if (!(parm
->flags
& FLAG_BASIC
)) {
451 void *ptr
= parm
->ptr
;
453 if (parm
->p_class
== P_LOCAL
&& snum
>= 0) {
454 ptr
= lp_local_ptr_by_snum(snum
, ptr
);
457 switch (parm
->type
) {
459 if (*(char *)ptr
== (char)(parm
->def
.cvalue
)) continue;
463 if (!str_list_equal(*(const char ***)ptr
,
464 (const char **)(parm
->def
.lvalue
))) continue;
469 if (!strcmp(*(char **)ptr
,(char *)(parm
->def
.svalue
))) continue;
474 if (*(bool *)ptr
== (bool)(parm
->def
.bvalue
)) continue;
479 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
484 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
490 if (printers
&& !(parm
->flags
& FLAG_PRINT
)) continue;
493 if ((parm_filter
& FLAG_WIZARD
) && !(parm
->flags
& FLAG_WIZARD
)) continue;
495 if ((parm_filter
& FLAG_ADVANCED
) && !(parm
->flags
& FLAG_ADVANCED
)) continue;
497 if (heading
&& heading
!= last_heading
) {
498 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading
));
499 last_heading
= heading
;
501 show_parameter(snum
, parm
);
505 /****************************************************************************
506 load the smb.conf file into loadparm.
507 ****************************************************************************/
508 static bool load_config(bool save_def
)
510 return lp_load(get_dyn_CONFIGFILE(),False
,save_def
,False
,True
);
513 /****************************************************************************
515 ****************************************************************************/
516 static void write_config(FILE *f
, bool show_defaults
)
518 TALLOC_CTX
*ctx
= talloc_stackframe();
520 fprintf(f
, "# Samba config file created using SWAT\n");
521 fprintf(f
, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
522 fprintf(f
, "# Date: %s\n\n", current_timestring(ctx
, False
));
524 lp_dump(f
, show_defaults
, iNumNonAutoPrintServices
);
529 /****************************************************************************
530 save and reload the smb.conf config file
531 ****************************************************************************/
532 static int save_reload(int snum
)
537 f
= sys_fopen(get_dyn_CONFIGFILE(),"w");
539 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
544 /* just in case they have used the buggy xinetd to create the file */
545 if (fstat(fileno(f
), &st
) == 0 &&
546 (st
.st_mode
& S_IWOTH
)) {
547 #if defined HAVE_FCHMOD
548 fchmod(fileno(f
), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
550 chmod(get_dyn_CONFIGFILE(), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
554 write_config(f
, False
);
556 lp_dump_one(f
, False
, snum
);
559 lp_kill_all_services();
561 if (!load_config(False
)) {
562 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
566 iNumNonAutoPrintServices
= lp_numservices();
567 pcap_cache_reload(&load_printers
);
572 /****************************************************************************
574 ****************************************************************************/
575 static void commit_parameter(int snum
, struct parm_struct
*parm
, const char *v
)
580 if (snum
< 0 && parm
->p_class
== P_LOCAL
) {
581 /* this handles the case where we are changing a local
582 variable globally. We need to change the parameter in
583 all shares where it is currently set to the default */
584 for (i
=0;i
<lp_numservices();i
++) {
585 s
= lp_servicename(i
);
586 if (s
&& (*s
) && lp_is_default(i
, parm
)) {
587 lp_do_parameter(i
, parm
->label
, v
);
592 lp_do_parameter(snum
, parm
->label
, v
);
595 /****************************************************************************
596 commit a set of parameters for a service
597 ****************************************************************************/
598 static void commit_parameters(int snum
)
601 struct parm_struct
*parm
;
605 while ((parm
= lp_next_parameter(snum
, &i
, 1))) {
606 if (asprintf(&label
, "parm_%s", make_parm_name(parm
->label
)) > 0) {
607 if ((v
= cgi_variable(label
)) != NULL
) {
608 if (parm
->flags
& FLAG_HIDE
)
610 commit_parameter(snum
, parm
, v
);
617 /****************************************************************************
618 spit out the html for a link with an image
619 ****************************************************************************/
620 static void image_link(const char *name
, const char *hlink
, const char *src
)
622 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
623 cgi_baseurl(), hlink
, src
, name
);
626 /****************************************************************************
627 display the main navigation controls at the top of each page along
629 ****************************************************************************/
630 static void show_main_buttons(void)
634 if ((p
= cgi_user_name()) && strcmp(p
, "root")) {
635 printf(_("Logged in as <b>%s</b>"), p
);
639 image_link(_("Home"), "", "images/home.gif");
640 if (have_write_access
) {
641 image_link(_("Globals"), "globals", "images/globals.gif");
642 image_link(_("Shares"), "shares", "images/shares.gif");
643 image_link(_("Printers"), "printers", "images/printers.gif");
644 image_link(_("Wizard"), "wizard", "images/wizard.gif");
646 /* root always gets all buttons, otherwise look for -P */
647 if ( have_write_access
|| (!passwd_only
&& have_read_access
) ) {
648 image_link(_("Status"), "status", "images/status.gif");
649 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
651 image_link(_("Password Management"), "passwd", "images/passwd.gif");
656 /****************************************************************************
657 * Handle Display/Edit Mode CGI
658 ****************************************************************************/
659 static void ViewModeBoxes(int mode
)
661 printf("<p>%s: \n", _("Current View Is"));
662 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode
== 0) ? "checked" : ""), _("Basic"));
663 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode
== 1) ? "checked" : ""), _("Advanced"));
664 printf("<br>%s: \n", _("Change View To"));
665 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
666 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
667 printf("</p><br>\n");
670 /****************************************************************************
671 display a welcome page
672 ****************************************************************************/
673 static void welcome_page(void)
675 if (file_exist("help/welcome.html")) {
676 include_html("help/welcome.html");
678 include_html("help/welcome-no-samba-doc.html");
682 /****************************************************************************
683 display the current smb.conf
684 ****************************************************************************/
685 static void viewconfig_page(void)
688 const char form_name
[] = "viewconfig";
690 if (!verify_xsrf_token(form_name
)) {
694 if (cgi_variable("full_view")) {
699 printf("<H2>%s</H2>\n", _("Current Config"));
700 printf("<form method=post>\n");
701 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
704 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
706 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
710 write_config(stdout
, full_view
);
715 /****************************************************************************
716 second screen of the wizard ... Fetch Configuration Parameters
717 ****************************************************************************/
718 static void wizard_params_page(void)
720 unsigned int parm_filter
= FLAG_WIZARD
;
721 const char form_name
[] = "wizard_params";
723 /* Here we first set and commit all the parameters that were selected
724 in the previous screen. */
726 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
728 if (!verify_xsrf_token(form_name
)) {
732 if (cgi_variable("Commit")) {
733 commit_parameters(GLOBAL_SECTION_SNUM
);
738 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
739 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
741 if (have_write_access
) {
742 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
745 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
749 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
750 printf("</table>\n");
754 /****************************************************************************
755 Utility to just rewrite the smb.conf file - effectively just cleans it up
756 ****************************************************************************/
757 static void rewritecfg_file(void)
759 commit_parameters(GLOBAL_SECTION_SNUM
);
761 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
764 /****************************************************************************
765 wizard to create/modify the smb.conf file
766 ****************************************************************************/
767 static void wizard_page(void)
769 /* Set some variables to collect data from smb.conf */
775 const char form_name
[] = "wizard";
777 if (!verify_xsrf_token(form_name
)) {
781 if (cgi_variable("Rewrite")) {
782 (void) rewritecfg_file();
786 if (cgi_variable("GetWizardParams")){
787 (void) wizard_params_page();
791 if (cgi_variable("Commit")){
792 SerType
= atoi(cgi_variable_nonull("ServerType"));
793 winstype
= atoi(cgi_variable_nonull("WINSType"));
794 have_home
= lp_servicenumber(HOMES_NAME
);
795 HomeExpo
= atoi(cgi_variable_nonull("HomeExpo"));
797 /* Plain text passwords are too badly broken - use encrypted passwords only */
798 lp_do_parameter( GLOBAL_SECTION_SNUM
, "encrypt passwords", "Yes");
802 /* Stand-alone Server */
803 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
804 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
808 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "DOMAIN" );
809 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
812 /* Domain Controller */
813 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
814 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "Yes" );
817 switch ( winstype
) {
819 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
820 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
823 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "Yes" );
824 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
827 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
828 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", cgi_variable_nonull("WINSAddr"));
832 /* Have to create Homes share? */
833 if ((HomeExpo
== 1) && (have_home
== -1)) {
834 const char *unix_share
= HOMES_NAME
;
837 lp_copy_service(GLOBAL_SECTION_SNUM
, unix_share
);
838 have_home
= lp_servicenumber(HOMES_NAME
);
839 lp_do_parameter( have_home
, "read only", "No");
840 lp_do_parameter( have_home
, "valid users", "%S");
841 lp_do_parameter( have_home
, "browseable", "No");
842 commit_parameters(have_home
);
843 save_reload(have_home
);
846 /* Need to Delete Homes share? */
847 if ((HomeExpo
== 0) && (have_home
!= -1)) {
848 lp_remove_service(have_home
);
852 commit_parameters(GLOBAL_SECTION_SNUM
);
857 /* Now determine smb.conf WINS settings */
858 if (lp_wins_support())
860 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
863 /* Do we have a homes share? */
864 have_home
= lp_servicenumber(HOMES_NAME
);
866 if ((winstype
== 2) && lp_wins_support())
869 role
= lp_server_role();
873 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
874 printf("<form method=post action=wizard>\n");
875 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
877 if (have_write_access
) {
878 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
879 printf("%s", _("The same will happen if you press the commit button."));
880 printf("<br><br>\n");
882 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
883 printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
884 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
885 printf("</center>\n");
889 printf("<center><table border=0>");
890 printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
891 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role
== ROLE_STANDALONE
) ? "checked" : ""), _("Stand Alone"));
892 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role
== ROLE_DOMAIN_MEMBER
) ? "checked" : ""), _("Domain Member"));
893 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role
== ROLE_DOMAIN_PDC
) ? "checked" : ""), _("Domain Controller"));
895 if (role
== ROLE_DOMAIN_BDC
) {
896 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
898 printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
899 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype
== 0) ? "checked" : ""), _("Not Used"));
900 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype
== 1) ? "checked" : ""), _("Server for client use"));
901 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype
== 2) ? "checked" : ""), _("Client of another WINS server"));
903 printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
905 /* Print out the list of wins servers */
906 if(lp_wins_server_list()) {
908 const char **wins_servers
= lp_wins_server_list();
909 for(i
= 0; wins_servers
[i
]; i
++) printf("%s ", wins_servers
[i
]);
912 printf("\"></td></tr>\n");
914 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"));
915 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
917 printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
918 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home
== -1) ? "" : "checked ");
919 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home
== -1 ) ? "checked" : "");
920 printf("<td></td></tr>\n");
922 /* Enable this when we are ready ....
923 * printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
924 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
925 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
926 * printf("<td></td></tr>\n");
929 printf("</table></center>");
932 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
937 /****************************************************************************
938 display a globals editing page
939 ****************************************************************************/
940 static void globals_page(void)
942 unsigned int parm_filter
= FLAG_BASIC
;
944 const char form_name
[] = "globals";
946 printf("<H2>%s</H2>\n", _("Global Parameters"));
948 if (!verify_xsrf_token(form_name
)) {
952 if (cgi_variable("Commit")) {
953 commit_parameters(GLOBAL_SECTION_SNUM
);
957 if ( cgi_variable("ViewMode") )
958 mode
= atoi(cgi_variable_nonull("ViewMode"));
959 if ( cgi_variable("BasicMode"))
961 if ( cgi_variable("AdvMode"))
965 printf("<form name=\"swatform\" method=post action=globals>\n");
966 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
968 ViewModeBoxes( mode
);
971 parm_filter
= FLAG_BASIC
;
974 parm_filter
= FLAG_ADVANCED
;
978 if (have_write_access
) {
979 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
980 _("Commit Changes"));
983 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
988 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
989 printf("</table>\n");
993 /****************************************************************************
994 display a shares editing page. share is in unix codepage,
995 ****************************************************************************/
996 static void shares_page(void)
998 const char *share
= cgi_variable("share");
1004 unsigned int parm_filter
= FLAG_BASIC
;
1005 size_t converted_size
;
1006 const char form_name
[] = "shares";
1008 printf("<H2>%s</H2>\n", _("Share Parameters"));
1010 if (!verify_xsrf_token(form_name
)) {
1015 snum
= lp_servicenumber(share
);
1018 if (cgi_variable("Commit") && snum
>= 0) {
1019 commit_parameters(snum
);
1021 snum
= lp_servicenumber(share
);
1024 if (cgi_variable("Delete") && snum
>= 0) {
1025 lp_remove_service(snum
);
1031 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
1032 snum
= lp_servicenumber(share
);
1035 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
1036 snum
= lp_servicenumber(share
);
1038 snum
= lp_servicenumber(share
);
1042 if ( cgi_variable("ViewMode") )
1043 mode
= atoi(cgi_variable_nonull("ViewMode"));
1044 if ( cgi_variable("BasicMode"))
1046 if ( cgi_variable("AdvMode"))
1050 printf("<FORM name=\"swatform\" method=post>\n");
1051 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
1053 printf("<table>\n");
1055 ViewModeBoxes( mode
);
1058 parm_filter
= FLAG_BASIC
;
1061 parm_filter
= FLAG_ADVANCED
;
1064 printf("<br><tr>\n");
1065 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1066 printf("<td><select name=share>\n");
1068 printf("<option value=\" \"> \n");
1069 for (i
=0;i
<lp_numservices();i
++) {
1070 s
= lp_servicename(i
);
1071 if (s
&& (*s
) && strcmp(s
,"IPC$") && !lp_print_ok(i
)) {
1072 push_utf8_talloc(talloc_tos(), &utf8_s
, s
, &converted_size
);
1073 printf("<option %s value=\"%s\">%s\n",
1074 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1076 TALLOC_FREE(utf8_s
);
1079 printf("</select></td>\n");
1080 if (have_write_access
) {
1081 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1086 if (have_write_access
) {
1088 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1089 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1095 if (have_write_access
) {
1096 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1099 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1104 printf("<table>\n");
1105 show_parameters(snum
, 1, parm_filter
, 0);
1106 printf("</table>\n");
1109 printf("</FORM>\n");
1112 /*************************************************************
1113 change a password either locally or remotely
1114 *************************************************************/
1115 static bool change_password(const char *remote_machine
, const char *user_name
,
1116 const char *old_passwd
, const char *new_passwd
,
1120 char *err_str
= NULL
;
1121 char *msg_str
= NULL
;
1124 printf("%s\n<p>", _("password change in demo mode rejected"));
1128 if (remote_machine
!= NULL
) {
1129 ret
= remote_password_change(remote_machine
, user_name
,
1130 old_passwd
, new_passwd
, &err_str
);
1131 if (err_str
!= NULL
)
1132 printf("%s\n<p>", err_str
);
1134 return NT_STATUS_IS_OK(ret
);
1137 if(!initialize_password_db(True
, NULL
)) {
1138 printf("%s\n<p>", _("Can't setup password database vectors."));
1142 ret
= local_password_change(user_name
, local_flags
, new_passwd
,
1143 &err_str
, &msg_str
);
1146 printf("%s\n<p>", msg_str
);
1148 printf("%s\n<p>", err_str
);
1152 return NT_STATUS_IS_OK(ret
);
1155 /****************************************************************************
1156 do the stuff required to add or change a password
1157 ****************************************************************************/
1158 static void chg_passwd(void)
1162 int local_flags
= 0;
1164 /* Make sure users name has been specified */
1165 if (strlen(cgi_variable_nonull(SWAT_USER
)) == 0) {
1166 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1171 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1172 * so if that's what we're doing, skip the rest of the checks
1174 if (!cgi_variable(DISABLE_USER_FLAG
) && !cgi_variable(ENABLE_USER_FLAG
) && !cgi_variable(DELETE_USER_FLAG
)) {
1177 * If current user is not root, make sure old password has been specified
1178 * If REMOTE change, even root must provide old password
1180 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0)) ||
1181 ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0))) {
1182 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1186 /* If changing a users password on a remote hosts we have to know what host */
1187 if ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(RHOST
)) <= 0)) {
1188 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1192 /* Make sure new passwords have been specified */
1193 if ((strlen( cgi_variable_nonull(NEW_PSWD
)) <= 0) ||
1194 (strlen( cgi_variable_nonull(NEW2_PSWD
)) <= 0)) {
1195 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1199 /* Make sure new passwords was typed correctly twice */
1200 if (strcmp(cgi_variable_nonull(NEW_PSWD
), cgi_variable_nonull(NEW2_PSWD
)) != 0) {
1201 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1206 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1207 host
= cgi_variable(RHOST
);
1208 } else if (am_root()) {
1215 * Set up the local flags.
1218 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_ADD_USER
: 0);
1219 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1220 local_flags
|= (cgi_variable(CHG_S_PASSWD_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1221 local_flags
|= (cgi_variable(DELETE_USER_FLAG
) ? LOCAL_DELETE_USER
: 0);
1222 local_flags
|= (cgi_variable(ENABLE_USER_FLAG
) ? LOCAL_ENABLE_USER
: 0);
1223 local_flags
|= (cgi_variable(DISABLE_USER_FLAG
) ? LOCAL_DISABLE_USER
: 0);
1226 rslt
= change_password(host
,
1227 cgi_variable_nonull(SWAT_USER
),
1228 cgi_variable_nonull(OLD_PSWD
), cgi_variable_nonull(NEW_PSWD
),
1231 if(cgi_variable(CHG_S_PASSWD_FLAG
)) {
1234 printf("%s\n", _(" The passwd has been changed."));
1236 printf("%s\n", _(" The passwd for has NOT been changed."));
1243 /****************************************************************************
1244 display a password editing page
1245 ****************************************************************************/
1246 static void passwd_page(void)
1248 const char *new_name
= cgi_user_name();
1249 const char passwd_form
[] = "passwd";
1250 const char rpasswd_form
[] = "rpasswd";
1252 if (!new_name
) new_name
= "";
1254 printf("<H2>%s</H2>\n", _("Server Password Management"));
1256 printf("<FORM name=\"swatform\" method=post>\n");
1257 print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form
);
1259 printf("<table>\n");
1262 * Create all the dialog boxes for data collection
1264 printf("<tr><td> %s : </td>\n", _("User Name"));
1265 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER
, new_name
);
1267 printf("<tr><td> %s : </td>\n", _("Old Password"));
1268 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD
);
1270 printf("<tr><td> %s : </td>\n", _("New Password"));
1271 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1272 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1273 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1274 printf("</table>\n");
1277 * Create all the control buttons for requesting action
1279 printf("<input type=submit name=%s value=\"%s\">\n",
1280 CHG_S_PASSWD_FLAG
, _("Change Password"));
1281 if (demo_mode
|| am_root()) {
1282 printf("<input type=submit name=%s value=\"%s\">\n",
1283 ADD_USER_FLAG
, _("Add New User"));
1284 printf("<input type=submit name=%s value=\"%s\">\n",
1285 DELETE_USER_FLAG
, _("Delete User"));
1286 printf("<input type=submit name=%s value=\"%s\">\n",
1287 DISABLE_USER_FLAG
, _("Disable User"));
1288 printf("<input type=submit name=%s value=\"%s\">\n",
1289 ENABLE_USER_FLAG
, _("Enable User"));
1291 printf("<p></FORM>\n");
1294 * Do some work if change, add, disable or enable was
1295 * requested. It could be this is the first time through this
1296 * code, so there isn't anything to do. */
1297 if (verify_xsrf_token(passwd_form
) &&
1298 ((cgi_variable(CHG_S_PASSWD_FLAG
)) || (cgi_variable(ADD_USER_FLAG
)) || (cgi_variable(DELETE_USER_FLAG
)) ||
1299 (cgi_variable(DISABLE_USER_FLAG
)) || (cgi_variable(ENABLE_USER_FLAG
)))) {
1303 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1305 printf("<FORM name=\"swatform\" method=post>\n");
1306 print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form
);
1308 printf("<table>\n");
1311 * Create all the dialog boxes for data collection
1313 printf("<tr><td> %s : </td>\n", _("User Name"));
1314 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER
, new_name
);
1315 printf("<tr><td> %s : </td>\n", _("Old Password"));
1316 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD
);
1317 printf("<tr><td> %s : </td>\n", _("New Password"));
1318 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1319 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1320 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1321 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1322 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST
);
1327 * Create all the control buttons for requesting action
1329 printf("<input type=submit name=%s value=\"%s\">",
1330 CHG_R_PASSWD_FLAG
, _("Change Password"));
1332 printf("<p></FORM>\n");
1335 * Do some work if a request has been made to change the
1336 * password somewhere other than the server. It could be this
1337 * is the first time through this code, so there isn't
1338 * anything to do. */
1339 if (verify_xsrf_token(passwd_form
) && cgi_variable(CHG_R_PASSWD_FLAG
)) {
1345 /****************************************************************************
1346 display a printers editing page
1347 ****************************************************************************/
1348 static void printers_page(void)
1350 const char *share
= cgi_variable("share");
1355 unsigned int parm_filter
= FLAG_BASIC
;
1356 const char form_name
[] = "printers";
1358 if (!verify_xsrf_token(form_name
)) {
1363 snum
= lp_servicenumber(share
);
1365 if (cgi_variable("Commit") && snum
>= 0) {
1366 commit_parameters(snum
);
1367 if (snum
>= iNumNonAutoPrintServices
)
1371 snum
= lp_servicenumber(share
);
1374 if (cgi_variable("Delete") && snum
>= 0) {
1375 lp_remove_service(snum
);
1381 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
1382 snum
= lp_servicenumber(share
);
1383 if (snum
< 0 || snum
>= iNumNonAutoPrintServices
) {
1385 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
1386 snum
= lp_servicenumber(share
);
1387 lp_do_parameter(snum
, "print ok", "Yes");
1389 snum
= lp_servicenumber(share
);
1393 if ( cgi_variable("ViewMode") )
1394 mode
= atoi(cgi_variable_nonull("ViewMode"));
1395 if ( cgi_variable("BasicMode"))
1397 if ( cgi_variable("AdvMode"))
1401 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1403 printf("<H3>%s</H3>\n", _("Important Note:"));
1404 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1405 printf("%s",_("are autoloaded printers from "));
1406 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1407 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1410 printf("<FORM name=\"swatform\" method=post>\n");
1411 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
1413 ViewModeBoxes( mode
);
1416 parm_filter
= FLAG_BASIC
;
1419 parm_filter
= FLAG_ADVANCED
;
1422 printf("<table>\n");
1423 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1424 printf("<td><select name=\"share\">\n");
1425 if (snum
< 0 || !lp_print_ok(snum
))
1426 printf("<option value=\" \"> \n");
1427 for (i
=0;i
<lp_numservices();i
++) {
1428 s
= lp_servicename(i
);
1429 if (s
&& (*s
) && strcmp(s
,"IPC$") && lp_print_ok(i
)) {
1430 if (i
>= iNumNonAutoPrintServices
)
1431 printf("<option %s value=\"%s\">[*]%s\n",
1432 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1435 printf("<option %s value=\"%s\">%s\n",
1436 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1440 printf("</select></td>");
1441 if (have_write_access
) {
1442 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1445 printf("</table>\n");
1447 if (have_write_access
) {
1448 printf("<table>\n");
1449 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1450 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1456 if (have_write_access
) {
1457 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1459 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1464 printf("<table>\n");
1465 show_parameters(snum
, 1, parm_filter
, 1);
1466 printf("</table>\n");
1468 printf("</FORM>\n");
1472 when the _() translation macro is used there is no obvious place to free
1473 the resulting string and there is no easy way to give a static pointer.
1474 All we can do is rotate between some static buffers and hope a single d_printf()
1475 doesn't have more calls to _() than the number of buffers
1478 const char *lang_msg_rotate(TALLOC_CTX
*ctx
, const char *msgid
)
1483 msgstr
= lang_msg(msgid
);
1488 ret
= talloc_strdup(ctx
, msgstr
);
1490 lang_msg_free(msgstr
);
1499 * main function for SWAT.
1501 int main(int argc
, char *argv
[])
1505 struct poptOption long_options
[] = {
1507 { "disable-authentication", 'a', POPT_ARG_VAL
, &demo_mode
, True
, "Disable authentication (demo mode)" },
1508 { "password-menu-only", 'P', POPT_ARG_VAL
, &passwd_only
, True
, "Show only change password menu" },
1512 TALLOC_CTX
*frame
= talloc_stackframe();
1515 umask(S_IWGRP
| S_IWOTH
);
1517 #if defined(HAVE_SET_AUTH_PARAMETERS)
1518 set_auth_parameters(argc
, argv
);
1519 #endif /* HAVE_SET_AUTH_PARAMETERS */
1521 /* just in case it goes wild ... */
1526 /* we don't want any SIGPIPE messages */
1527 BlockSignals(True
,SIGPIPE
);
1529 dbf
= x_fopen("/dev/null", O_WRONLY
, 0);
1530 if (!dbf
) dbf
= x_stderr
;
1532 /* we don't want stderr screwing us up */
1534 open("/dev/null", O_WRONLY
);
1536 pc
= poptGetContext("swat", argc
, (const char **) argv
, long_options
, 0);
1538 /* Parse command line options */
1540 while(poptGetNextOpt(pc
) != -1) { }
1542 poptFreeContext(pc
);
1546 setup_logging(argv
[0],False
);
1549 iNumNonAutoPrintServices
= lp_numservices();
1550 pcap_cache_reload(&load_printers
);
1552 cgi_setup(get_dyn_SWATDIR(), !demo_mode
);
1556 cgi_load_variables();
1558 if (!file_exist(get_dyn_CONFIGFILE())) {
1559 have_read_access
= True
;
1560 have_write_access
= True
;
1562 /* check if the authenticated user has write access - if not then
1563 don't show write options */
1564 have_write_access
= (access(get_dyn_CONFIGFILE(),W_OK
) == 0);
1566 /* if the user doesn't have read access to smb.conf then
1567 don't let them view it */
1568 have_read_access
= (access(get_dyn_CONFIGFILE(),R_OK
) == 0);
1571 show_main_buttons();
1573 page
= cgi_pathinfo();
1575 /* Root gets full functionality */
1576 if (have_read_access
&& strcmp(page
, "globals")==0) {
1578 } else if (have_read_access
&& strcmp(page
,"shares")==0) {
1580 } else if (have_read_access
&& strcmp(page
,"printers")==0) {
1582 } else if (have_read_access
&& strcmp(page
,"status")==0) {
1584 } else if (have_read_access
&& strcmp(page
,"viewconfig")==0) {
1586 } else if (strcmp(page
,"passwd")==0) {
1588 } else if (have_read_access
&& strcmp(page
,"wizard")==0) {
1590 } else if (have_read_access
&& strcmp(page
,"wizard_params")==0) {
1591 wizard_params_page();
1592 } else if (have_read_access
&& strcmp(page
,"rewritecfg")==0) {