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"
33 static int demo_mode
= False
;
34 static int passwd_only
= False
;
35 static bool have_write_access
= False
;
36 static bool have_read_access
= False
;
37 static int iNumNonAutoPrintServices
= 0;
40 * Password Management Globals
42 #define SWAT_USER "username"
43 #define OLD_PSWD "old_passwd"
44 #define NEW_PSWD "new_passwd"
45 #define NEW2_PSWD "new2_passwd"
46 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
47 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
48 #define ADD_USER_FLAG "add_user_flag"
49 #define DELETE_USER_FLAG "delete_user_flag"
50 #define DISABLE_USER_FLAG "disable_user_flag"
51 #define ENABLE_USER_FLAG "enable_user_flag"
52 #define RHOST "remote_host"
53 #define XSRF_TOKEN "xsrf"
54 #define XSRF_TIME "xsrf_time"
55 #define XSRF_TIMEOUT 300
57 #define _(x) lang_msg_rotate(talloc_tos(),x)
59 /****************************************************************************
60 ****************************************************************************/
61 static int enum_index(int value
, const struct enum_list
*enumlist
)
64 for (i
=0;enumlist
[i
].name
;i
++)
65 if (value
== enumlist
[i
].value
) break;
69 static char *fix_backslash(const char *str
)
71 static char newstring
[1024];
75 if (*str
== '\\') {*p
++ = '\\';*p
++ = '\\';}
83 static const char *fix_quotes(TALLOC_CTX
*ctx
, const char *str
)
85 char *newstring
= NULL
;
88 int quote_len
= strlen(""");
90 /* Count the number of quotes. */
95 newstring_len
+= quote_len
;
101 newstring
= TALLOC_ARRAY(ctx
, char, newstring_len
);
105 for (p
= newstring
; *str
; str
++) {
107 strncpy( p
, """, quote_len
);
117 static char *stripspaceupper(const char *str
)
119 static char newstring
[1024];
123 if (*str
!= ' ') *p
++ = toupper_ascii(*str
);
130 static char *make_parm_name(const char *label
)
132 static char parmname
[1024];
136 if (*label
== ' ') *p
++ = '_';
144 void get_xsrf_token(const char *username
, const char *pass
,
145 const char *formname
, time_t xsrf_time
, char token_str
[33])
147 struct MD5Context md5_ctx
;
152 ZERO_STRUCT(md5_ctx
);
155 MD5Update(&md5_ctx
, (uint8_t *)formname
, strlen(formname
));
156 MD5Update(&md5_ctx
, (uint8_t *)&xsrf_time
, sizeof(time_t));
157 if (username
!= NULL
) {
158 MD5Update(&md5_ctx
, (uint8_t *)username
, strlen(username
));
161 MD5Update(&md5_ctx
, (uint8_t *)pass
, strlen(pass
));
164 MD5Final(token
, &md5_ctx
);
166 for(i
= 0; i
< sizeof(token
); i
++) {
169 snprintf(tmp
, sizeof(tmp
), "%02x", token
[i
]);
170 strncat(token_str
, tmp
, sizeof(tmp
));
174 void print_xsrf_token(const char *username
, const char *pass
,
175 const char *formname
)
178 time_t xsrf_time
= time(NULL
);
180 get_xsrf_token(username
, pass
, formname
, xsrf_time
, token
);
181 printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
183 printf("<input type=\"hidden\" name=\"%s\" value=\"%lld\">\n",
184 XSRF_TIME
, (long long int)xsrf_time
);
187 bool verify_xsrf_token(const char *formname
)
190 const char *username
= cgi_user_name();
191 const char *pass
= cgi_user_pass();
192 const char *token
= cgi_variable_nonull(XSRF_TOKEN
);
193 const char *time_str
= cgi_variable_nonull(XSRF_TIME
);
195 long long xsrf_time_ll
= 0;
196 time_t xsrf_time
= 0;
197 time_t now
= time(NULL
);
200 xsrf_time_ll
= strtoll(time_str
, &p
, 10);
207 if (PTR_DIFF(p
, time_str
) > strlen(time_str
)) {
210 if (xsrf_time_ll
> _TYPE_MAXIMUM(time_t)) {
213 if (xsrf_time_ll
< _TYPE_MINIMUM(time_t)) {
216 xsrf_time
= xsrf_time_ll
;
218 if (abs(now
- xsrf_time
) > XSRF_TIMEOUT
) {
222 get_xsrf_token(username
, pass
, formname
, xsrf_time
, expected
);
223 return (strncmp(expected
, token
, sizeof(expected
)) == 0);
227 /****************************************************************************
228 include a lump of html in a page
229 ****************************************************************************/
230 static int include_html(const char *fname
)
236 fd
= web_open(fname
, O_RDONLY
, 0);
239 printf(_("ERROR: Can't open %s"), fname
);
244 while ((ret
= read(fd
, buf
, sizeof(buf
))) > 0) {
245 if (write(1, buf
, ret
) == -1) {
254 /****************************************************************************
255 start the page with standard stuff
256 ****************************************************************************/
257 static void print_header(void)
259 if (!cgi_waspost()) {
260 printf("Expires: 0\r\n");
262 printf("Content-type: text/html\r\n\r\n");
264 if (!include_html("include/header.html")) {
265 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
266 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
270 /* *******************************************************************
271 show parameter label with translated name in the following form
272 because showing original and translated label in one line looks
273 too long, and showing translated label only is unusable for
275 -------------------------------
276 HELP security [combo box][button]
278 -------------------------------
279 (capital words are translated by gettext.)
280 if no translation is available, then same form as original is
282 "i18n_translated_parm" class is used to change the color of the
283 translated parameter with CSS.
284 **************************************************************** */
285 static const char *get_parm_translated(TALLOC_CTX
*ctx
,
286 const char* pAnchor
, const char* pHelp
, const char* pLabel
)
288 const char *pTranslated
= _(pLabel
);
290 if(strcmp(pLabel
, pTranslated
) != 0) {
291 output
= talloc_asprintf(ctx
,
292 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
293 pAnchor
, pHelp
, pLabel
, pTranslated
);
296 output
= talloc_asprintf(ctx
,
297 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
298 pAnchor
, pHelp
, pLabel
);
301 /****************************************************************************
303 ****************************************************************************/
304 static void print_footer(void)
306 if (!include_html("include/footer.html")) {
307 printf("\n</BODY>\n</HTML>\n");
311 /****************************************************************************
312 display one editable parameter in a form
313 ****************************************************************************/
314 static void show_parameter(int snum
, struct parm_struct
*parm
)
317 void *ptr
= parm
->ptr
;
318 char *utf8_s1
, *utf8_s2
;
319 size_t converted_size
;
320 TALLOC_CTX
*ctx
= talloc_stackframe();
322 if (parm
->p_class
== P_LOCAL
&& snum
>= 0) {
323 ptr
= lp_local_ptr(snum
, ptr
);
326 printf("<tr><td>%s</td><td>", get_parm_translated(ctx
,
327 stripspaceupper(parm
->label
), _("Help"), parm
->label
));
328 switch (parm
->type
) {
330 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
331 make_parm_name(parm
->label
), *(char *)ptr
);
332 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
333 _("Set Default"), make_parm_name(parm
->label
),(char)(parm
->def
.cvalue
));
337 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
338 make_parm_name(parm
->label
));
339 if ((char ***)ptr
&& *(char ***)ptr
&& **(char ***)ptr
) {
340 char **list
= *(char ***)ptr
;
341 for (;*list
;list
++) {
342 /* enclose in HTML encoded quotes if the string contains a space */
343 if ( strchr_m(*list
, ' ') ) {
344 push_utf8_allocate(&utf8_s1
, *list
, &converted_size
);
345 push_utf8_allocate(&utf8_s2
, ((*(list
+1))?", ":""), &converted_size
);
346 printf(""%s"%s", utf8_s1
, utf8_s2
);
348 push_utf8_allocate(&utf8_s1
, *list
, &converted_size
);
349 push_utf8_allocate(&utf8_s2
, ((*(list
+1))?", ":""), &converted_size
);
350 printf("%s%s", utf8_s1
, utf8_s2
);
357 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
358 _("Set Default"), make_parm_name(parm
->label
));
359 if (parm
->def
.lvalue
) {
360 char **list
= (char **)(parm
->def
.lvalue
);
361 for (; *list
; list
++) {
362 /* enclose in HTML encoded quotes if the string contains a space */
363 if ( strchr_m(*list
, ' ') )
364 printf(""%s"%s", *list
, ((*(list
+1))?", ":""));
366 printf("%s%s", *list
, ((*(list
+1))?", ":""));
374 push_utf8_allocate(&utf8_s1
, *(char **)ptr
, &converted_size
);
375 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
376 make_parm_name(parm
->label
), fix_quotes(ctx
, utf8_s1
));
378 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
379 _("Set Default"), make_parm_name(parm
->label
),fix_backslash((char *)(parm
->def
.svalue
)));
383 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
384 printf("<option %s>Yes", (*(bool *)ptr
)?"selected":"");
385 printf("<option %s>No", (*(bool *)ptr
)?"":"selected");
387 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
388 _("Set Default"), make_parm_name(parm
->label
),(bool)(parm
->def
.bvalue
)?0:1);
392 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
393 printf("<option %s>Yes", (*(bool *)ptr
)?"":"selected");
394 printf("<option %s>No", (*(bool *)ptr
)?"selected":"");
396 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
397 _("Set Default"), make_parm_name(parm
->label
),(bool)(parm
->def
.bvalue
)?1:0);
401 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm
->label
), *(int *)ptr
);
402 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
403 _("Set Default"), make_parm_name(parm
->label
),(int)(parm
->def
.ivalue
));
408 o
= octal_string(*(int *)ptr
);
409 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
410 make_parm_name(parm
->label
), o
);
412 o
= octal_string((int)(parm
->def
.ivalue
));
413 printf("<input type=button value=\"%s\" "
414 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
415 _("Set Default"), make_parm_name(parm
->label
), o
);
421 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
422 for (i
=0;parm
->enum_list
[i
].name
;i
++) {
423 if (i
== 0 || parm
->enum_list
[i
].value
!= parm
->enum_list
[i
-1].value
) {
424 printf("<option %s>%s",(*(int *)ptr
)==parm
->enum_list
[i
].value
?"selected":"",parm
->enum_list
[i
].name
);
428 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
429 _("Set Default"), make_parm_name(parm
->label
),enum_index((int)(parm
->def
.ivalue
),parm
->enum_list
));
434 printf("</td></tr>\n");
438 /****************************************************************************
439 display a set of parameters for a service
440 ****************************************************************************/
441 static void show_parameters(int snum
, int allparameters
, unsigned int parm_filter
, int printers
)
444 struct parm_struct
*parm
;
445 const char *heading
= NULL
;
446 const char *last_heading
= NULL
;
448 while ((parm
= lp_next_parameter(snum
, &i
, allparameters
))) {
449 if (snum
< 0 && parm
->p_class
== P_LOCAL
&& !(parm
->flags
& FLAG_GLOBAL
))
451 if (parm
->p_class
== P_SEPARATOR
) {
452 heading
= parm
->label
;
455 if (parm
->flags
& FLAG_HIDE
) continue;
457 if (printers
& !(parm
->flags
& FLAG_PRINT
)) continue;
458 if (!printers
& !(parm
->flags
& FLAG_SHARE
)) continue;
461 if (!( parm_filter
& FLAG_ADVANCED
)) {
462 if (!(parm
->flags
& FLAG_BASIC
)) {
463 void *ptr
= parm
->ptr
;
465 if (parm
->p_class
== P_LOCAL
&& snum
>= 0) {
466 ptr
= lp_local_ptr(snum
, ptr
);
469 switch (parm
->type
) {
471 if (*(char *)ptr
== (char)(parm
->def
.cvalue
)) continue;
475 if (!str_list_compare(*(char ***)ptr
, (char **)(parm
->def
.lvalue
))) continue;
480 if (!strcmp(*(char **)ptr
,(char *)(parm
->def
.svalue
))) continue;
485 if (*(bool *)ptr
== (bool)(parm
->def
.bvalue
)) continue;
490 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
495 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
501 if (printers
&& !(parm
->flags
& FLAG_PRINT
)) continue;
504 if ((parm_filter
& FLAG_WIZARD
) && !(parm
->flags
& FLAG_WIZARD
)) continue;
506 if ((parm_filter
& FLAG_ADVANCED
) && !(parm
->flags
& FLAG_ADVANCED
)) continue;
508 if (heading
&& heading
!= last_heading
) {
509 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading
));
510 last_heading
= heading
;
512 show_parameter(snum
, parm
);
516 /****************************************************************************
517 load the smb.conf file into loadparm.
518 ****************************************************************************/
519 static bool load_config(bool save_def
)
521 return lp_load(get_dyn_CONFIGFILE(),False
,save_def
,False
,True
);
524 /****************************************************************************
526 ****************************************************************************/
527 static void write_config(FILE *f
, bool show_defaults
)
529 TALLOC_CTX
*ctx
= talloc_stackframe();
531 fprintf(f
, "# Samba config file created using SWAT\n");
532 fprintf(f
, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
533 fprintf(f
, "# Date: %s\n\n", current_timestring(ctx
, False
));
535 lp_dump(f
, show_defaults
, iNumNonAutoPrintServices
);
540 /****************************************************************************
541 save and reload the smb.conf config file
542 ****************************************************************************/
543 static int save_reload(int snum
)
548 f
= sys_fopen(get_dyn_CONFIGFILE(),"w");
550 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
555 /* just in case they have used the buggy xinetd to create the file */
556 if (fstat(fileno(f
), &st
) == 0 &&
557 (st
.st_mode
& S_IWOTH
)) {
558 #if defined HAVE_FCHMOD
559 fchmod(fileno(f
), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
561 chmod(get_dyn_CONFIGFILE(), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
565 write_config(f
, False
);
567 lp_dump_one(f
, False
, snum
);
570 lp_kill_all_services();
572 if (!load_config(False
)) {
573 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
577 iNumNonAutoPrintServices
= lp_numservices();
583 /****************************************************************************
585 ****************************************************************************/
586 static void commit_parameter(int snum
, struct parm_struct
*parm
, const char *v
)
591 if (snum
< 0 && parm
->p_class
== P_LOCAL
) {
592 /* this handles the case where we are changing a local
593 variable globally. We need to change the parameter in
594 all shares where it is currently set to the default */
595 for (i
=0;i
<lp_numservices();i
++) {
596 s
= lp_servicename(i
);
597 if (s
&& (*s
) && lp_is_default(i
, parm
)) {
598 lp_do_parameter(i
, parm
->label
, v
);
603 lp_do_parameter(snum
, parm
->label
, v
);
606 /****************************************************************************
607 commit a set of parameters for a service
608 ****************************************************************************/
609 static void commit_parameters(int snum
)
612 struct parm_struct
*parm
;
616 while ((parm
= lp_next_parameter(snum
, &i
, 1))) {
617 if (asprintf(&label
, "parm_%s", make_parm_name(parm
->label
)) > 0) {
618 if ((v
= cgi_variable(label
)) != NULL
) {
619 if (parm
->flags
& FLAG_HIDE
)
621 commit_parameter(snum
, parm
, v
);
628 /****************************************************************************
629 spit out the html for a link with an image
630 ****************************************************************************/
631 static void image_link(const char *name
, const char *hlink
, const char *src
)
633 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
634 cgi_baseurl(), hlink
, src
, name
);
637 /****************************************************************************
638 display the main navigation controls at the top of each page along
640 ****************************************************************************/
641 static void show_main_buttons(void)
645 if ((p
= cgi_user_name()) && strcmp(p
, "root")) {
646 printf(_("Logged in as <b>%s</b>"), p
);
650 image_link(_("Home"), "", "images/home.gif");
651 if (have_write_access
) {
652 image_link(_("Globals"), "globals", "images/globals.gif");
653 image_link(_("Shares"), "shares", "images/shares.gif");
654 image_link(_("Printers"), "printers", "images/printers.gif");
655 image_link(_("Wizard"), "wizard", "images/wizard.gif");
657 /* root always gets all buttons, otherwise look for -P */
658 if ( have_write_access
|| (!passwd_only
&& have_read_access
) ) {
659 image_link(_("Status"), "status", "images/status.gif");
660 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
662 image_link(_("Password Management"), "passwd", "images/passwd.gif");
667 /****************************************************************************
668 * Handle Display/Edit Mode CGI
669 ****************************************************************************/
670 static void ViewModeBoxes(int mode
)
672 printf("<p>%s: \n", _("Current View Is"));
673 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode
== 0) ? "checked" : ""), _("Basic"));
674 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode
== 1) ? "checked" : ""), _("Advanced"));
675 printf("<br>%s: \n", _("Change View To"));
676 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
677 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
678 printf("</p><br>\n");
681 /****************************************************************************
682 display a welcome page
683 ****************************************************************************/
684 static void welcome_page(void)
686 if (file_exist("help/welcome.html", NULL
)) {
687 include_html("help/welcome.html");
689 include_html("help/welcome-no-samba-doc.html");
693 /****************************************************************************
694 display the current smb.conf
695 ****************************************************************************/
696 static void viewconfig_page(void)
699 const char form_name
[] = "viewconfig";
701 if (!verify_xsrf_token(form_name
)) {
705 if (cgi_variable("full_view")) {
710 printf("<H2>%s</H2>\n", _("Current Config"));
711 printf("<form method=post>\n");
712 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
715 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
717 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
721 write_config(stdout
, full_view
);
726 /****************************************************************************
727 second screen of the wizard ... Fetch Configuration Parameters
728 ****************************************************************************/
729 static void wizard_params_page(void)
731 unsigned int parm_filter
= FLAG_WIZARD
;
732 const char form_name
[] = "wizard_params";
734 /* Here we first set and commit all the parameters that were selected
735 in the previous screen. */
737 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
739 if (!verify_xsrf_token(form_name
)) {
743 if (cgi_variable("Commit")) {
744 commit_parameters(GLOBAL_SECTION_SNUM
);
749 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
750 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
752 if (have_write_access
) {
753 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
756 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
760 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
761 printf("</table>\n");
765 /****************************************************************************
766 Utility to just rewrite the smb.conf file - effectively just cleans it up
767 ****************************************************************************/
768 static void rewritecfg_file(void)
770 commit_parameters(GLOBAL_SECTION_SNUM
);
772 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
775 /****************************************************************************
776 wizard to create/modify the smb.conf file
777 ****************************************************************************/
778 static void wizard_page(void)
780 /* Set some variables to collect data from smb.conf */
786 const char form_name
[] = "wizard";
788 if (!verify_xsrf_token(form_name
)) {
792 if (cgi_variable("Rewrite")) {
793 (void) rewritecfg_file();
797 if (cgi_variable("GetWizardParams")){
798 (void) wizard_params_page();
802 if (cgi_variable("Commit")){
803 SerType
= atoi(cgi_variable_nonull("ServerType"));
804 winstype
= atoi(cgi_variable_nonull("WINSType"));
805 have_home
= lp_servicenumber(HOMES_NAME
);
806 HomeExpo
= atoi(cgi_variable_nonull("HomeExpo"));
808 /* Plain text passwords are too badly broken - use encrypted passwords only */
809 lp_do_parameter( GLOBAL_SECTION_SNUM
, "encrypt passwords", "Yes");
813 /* Stand-alone Server */
814 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
815 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
819 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "DOMAIN" );
820 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
823 /* Domain Controller */
824 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
825 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "Yes" );
828 switch ( winstype
) {
830 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
831 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
834 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "Yes" );
835 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
838 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
839 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", cgi_variable_nonull("WINSAddr"));
843 /* Have to create Homes share? */
844 if ((HomeExpo
== 1) && (have_home
== -1)) {
845 const char *unix_share
= HOMES_NAME
;
848 lp_copy_service(GLOBAL_SECTION_SNUM
, unix_share
);
849 have_home
= lp_servicenumber(HOMES_NAME
);
850 lp_do_parameter( have_home
, "read only", "No");
851 lp_do_parameter( have_home
, "valid users", "%S");
852 lp_do_parameter( have_home
, "browseable", "No");
853 commit_parameters(have_home
);
854 save_reload(have_home
);
857 /* Need to Delete Homes share? */
858 if ((HomeExpo
== 0) && (have_home
!= -1)) {
859 lp_remove_service(have_home
);
863 commit_parameters(GLOBAL_SECTION_SNUM
);
868 /* Now determine smb.conf WINS settings */
869 if (lp_wins_support())
871 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
874 /* Do we have a homes share? */
875 have_home
= lp_servicenumber(HOMES_NAME
);
877 if ((winstype
== 2) && lp_wins_support())
880 role
= lp_server_role();
884 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
885 printf("<form method=post action=wizard>\n");
886 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
888 if (have_write_access
) {
889 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
890 printf("%s", _("The same will happen if you press the commit button."));
891 printf("<br><br>\n");
893 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
894 printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
895 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
896 printf("</center>\n");
900 printf("<center><table border=0>");
901 printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
902 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role
== ROLE_STANDALONE
) ? "checked" : ""), _("Stand Alone"));
903 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role
== ROLE_DOMAIN_MEMBER
) ? "checked" : ""), _("Domain Member"));
904 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role
== ROLE_DOMAIN_PDC
) ? "checked" : ""), _("Domain Controller"));
906 if (role
== ROLE_DOMAIN_BDC
) {
907 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
909 printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
910 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype
== 0) ? "checked" : ""), _("Not Used"));
911 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype
== 1) ? "checked" : ""), _("Server for client use"));
912 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype
== 2) ? "checked" : ""), _("Client of another WINS server"));
914 printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
916 /* Print out the list of wins servers */
917 if(lp_wins_server_list()) {
919 const char **wins_servers
= lp_wins_server_list();
920 for(i
= 0; wins_servers
[i
]; i
++) printf("%s ", wins_servers
[i
]);
923 printf("\"></td></tr>\n");
925 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"));
926 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
928 printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
929 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home
== -1) ? "" : "checked ");
930 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home
== -1 ) ? "checked" : "");
931 printf("<td></td></tr>\n");
933 /* Enable this when we are ready ....
934 * printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
935 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
936 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
937 * printf("<td></td></tr>\n");
940 printf("</table></center>");
943 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
948 /****************************************************************************
949 display a globals editing page
950 ****************************************************************************/
951 static void globals_page(void)
953 unsigned int parm_filter
= FLAG_BASIC
;
955 const char form_name
[] = "globals";
957 printf("<H2>%s</H2>\n", _("Global Parameters"));
959 if (!verify_xsrf_token(form_name
)) {
963 if (cgi_variable("Commit")) {
964 commit_parameters(GLOBAL_SECTION_SNUM
);
968 if ( cgi_variable("ViewMode") )
969 mode
= atoi(cgi_variable_nonull("ViewMode"));
970 if ( cgi_variable("BasicMode"))
972 if ( cgi_variable("AdvMode"))
976 printf("<form name=\"swatform\" method=post action=globals>\n");
977 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
979 ViewModeBoxes( mode
);
982 parm_filter
= FLAG_BASIC
;
985 parm_filter
= FLAG_ADVANCED
;
989 if (have_write_access
) {
990 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
991 _("Commit Changes"));
994 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
999 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
1000 printf("</table>\n");
1001 printf("</form>\n");
1004 /****************************************************************************
1005 display a shares editing page. share is in unix codepage,
1006 ****************************************************************************/
1007 static void shares_page(void)
1009 const char *share
= cgi_variable("share");
1015 unsigned int parm_filter
= FLAG_BASIC
;
1016 size_t converted_size
;
1017 const char form_name
[] = "shares";
1019 printf("<H2>%s</H2>\n", _("Share Parameters"));
1021 if (!verify_xsrf_token(form_name
)) {
1026 snum
= lp_servicenumber(share
);
1029 if (cgi_variable("Commit") && snum
>= 0) {
1030 commit_parameters(snum
);
1032 snum
= lp_servicenumber(share
);
1035 if (cgi_variable("Delete") && snum
>= 0) {
1036 lp_remove_service(snum
);
1042 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
1043 snum
= lp_servicenumber(share
);
1046 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
1047 snum
= lp_servicenumber(share
);
1049 snum
= lp_servicenumber(share
);
1053 if ( cgi_variable("ViewMode") )
1054 mode
= atoi(cgi_variable_nonull("ViewMode"));
1055 if ( cgi_variable("BasicMode"))
1057 if ( cgi_variable("AdvMode"))
1061 printf("<FORM name=\"swatform\" method=post>\n");
1062 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
1064 printf("<table>\n");
1066 ViewModeBoxes( mode
);
1069 parm_filter
= FLAG_BASIC
;
1072 parm_filter
= FLAG_ADVANCED
;
1075 printf("<br><tr>\n");
1076 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1077 printf("<td><select name=share>\n");
1079 printf("<option value=\" \"> \n");
1080 for (i
=0;i
<lp_numservices();i
++) {
1081 s
= lp_servicename(i
);
1082 if (s
&& (*s
) && strcmp(s
,"IPC$") && !lp_print_ok(i
)) {
1083 push_utf8_allocate(&utf8_s
, s
, &converted_size
);
1084 printf("<option %s value=\"%s\">%s\n",
1085 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1090 printf("</select></td>\n");
1091 if (have_write_access
) {
1092 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1097 if (have_write_access
) {
1099 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1100 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1106 if (have_write_access
) {
1107 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1110 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1115 printf("<table>\n");
1116 show_parameters(snum
, 1, parm_filter
, 0);
1117 printf("</table>\n");
1120 printf("</FORM>\n");
1123 /*************************************************************
1124 change a password either locally or remotely
1125 *************************************************************/
1126 static bool change_password(const char *remote_machine
, const char *user_name
,
1127 const char *old_passwd
, const char *new_passwd
,
1131 char *err_str
= NULL
;
1132 char *msg_str
= NULL
;
1135 printf("%s\n<p>", _("password change in demo mode rejected"));
1139 if (remote_machine
!= NULL
) {
1140 ret
= remote_password_change(remote_machine
, user_name
,
1141 old_passwd
, new_passwd
, &err_str
);
1142 if (err_str
!= NULL
)
1143 printf("%s\n<p>", err_str
);
1145 return NT_STATUS_IS_OK(ret
);
1148 if(!initialize_password_db(True
, NULL
)) {
1149 printf("%s\n<p>", _("Can't setup password database vectors."));
1153 ret
= local_password_change(user_name
, local_flags
, new_passwd
,
1154 &err_str
, &msg_str
);
1157 printf("%s\n<p>", msg_str
);
1159 printf("%s\n<p>", err_str
);
1163 return NT_STATUS_IS_OK(ret
);
1166 /****************************************************************************
1167 do the stuff required to add or change a password
1168 ****************************************************************************/
1169 static void chg_passwd(void)
1173 int local_flags
= 0;
1175 /* Make sure users name has been specified */
1176 if (strlen(cgi_variable_nonull(SWAT_USER
)) == 0) {
1177 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1182 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1183 * so if that's what we're doing, skip the rest of the checks
1185 if (!cgi_variable(DISABLE_USER_FLAG
) && !cgi_variable(ENABLE_USER_FLAG
) && !cgi_variable(DELETE_USER_FLAG
)) {
1188 * If current user is not root, make sure old password has been specified
1189 * If REMOTE change, even root must provide old password
1191 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0)) ||
1192 ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0))) {
1193 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1197 /* If changing a users password on a remote hosts we have to know what host */
1198 if ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(RHOST
)) <= 0)) {
1199 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1203 /* Make sure new passwords have been specified */
1204 if ((strlen( cgi_variable_nonull(NEW_PSWD
)) <= 0) ||
1205 (strlen( cgi_variable_nonull(NEW2_PSWD
)) <= 0)) {
1206 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1210 /* Make sure new passwords was typed correctly twice */
1211 if (strcmp(cgi_variable_nonull(NEW_PSWD
), cgi_variable_nonull(NEW2_PSWD
)) != 0) {
1212 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1217 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1218 host
= cgi_variable(RHOST
);
1219 } else if (am_root()) {
1226 * Set up the local flags.
1229 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_ADD_USER
: 0);
1230 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1231 local_flags
|= (cgi_variable(CHG_S_PASSWD_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1232 local_flags
|= (cgi_variable(DELETE_USER_FLAG
) ? LOCAL_DELETE_USER
: 0);
1233 local_flags
|= (cgi_variable(ENABLE_USER_FLAG
) ? LOCAL_ENABLE_USER
: 0);
1234 local_flags
|= (cgi_variable(DISABLE_USER_FLAG
) ? LOCAL_DISABLE_USER
: 0);
1237 rslt
= change_password(host
,
1238 cgi_variable_nonull(SWAT_USER
),
1239 cgi_variable_nonull(OLD_PSWD
), cgi_variable_nonull(NEW_PSWD
),
1242 if(cgi_variable(CHG_S_PASSWD_FLAG
)) {
1245 printf("%s\n", _(" The passwd has been changed."));
1247 printf("%s\n", _(" The passwd has NOT been changed."));
1254 /****************************************************************************
1255 display a password editing page
1256 ****************************************************************************/
1257 static void passwd_page(void)
1259 const char *new_name
= cgi_user_name();
1260 const char passwd_form
[] = "passwd";
1261 const char rpasswd_form
[] = "rpasswd";
1263 if (!new_name
) new_name
= "";
1265 printf("<H2>%s</H2>\n", _("Server Password Management"));
1267 printf("<FORM name=\"swatform\" method=post>\n");
1268 print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form
);
1270 printf("<table>\n");
1273 * Create all the dialog boxes for data collection
1275 printf("<tr><td> %s : </td>\n", _("User Name"));
1276 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER
, new_name
);
1278 printf("<tr><td> %s : </td>\n", _("Old Password"));
1279 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD
);
1281 printf("<tr><td> %s : </td>\n", _("New Password"));
1282 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1283 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1284 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1285 printf("</table>\n");
1288 * Create all the control buttons for requesting action
1290 printf("<input type=submit name=%s value=\"%s\">\n",
1291 CHG_S_PASSWD_FLAG
, _("Change Password"));
1292 if (demo_mode
|| am_root()) {
1293 printf("<input type=submit name=%s value=\"%s\">\n",
1294 ADD_USER_FLAG
, _("Add New User"));
1295 printf("<input type=submit name=%s value=\"%s\">\n",
1296 DELETE_USER_FLAG
, _("Delete User"));
1297 printf("<input type=submit name=%s value=\"%s\">\n",
1298 DISABLE_USER_FLAG
, _("Disable User"));
1299 printf("<input type=submit name=%s value=\"%s\">\n",
1300 ENABLE_USER_FLAG
, _("Enable User"));
1302 printf("<p></FORM>\n");
1305 * Do some work if change, add, disable or enable was
1306 * requested. It could be this is the first time through this
1307 * code, so there isn't anything to do. */
1308 if (verify_xsrf_token(passwd_form
) &&
1309 ((cgi_variable(CHG_S_PASSWD_FLAG
)) || (cgi_variable(ADD_USER_FLAG
)) || (cgi_variable(DELETE_USER_FLAG
)) ||
1310 (cgi_variable(DISABLE_USER_FLAG
)) || (cgi_variable(ENABLE_USER_FLAG
)))) {
1314 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1316 printf("<FORM name=\"swatform\" method=post>\n");
1317 print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form
);
1319 printf("<table>\n");
1322 * Create all the dialog boxes for data collection
1324 printf("<tr><td> %s : </td>\n", _("User Name"));
1325 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER
, new_name
);
1326 printf("<tr><td> %s : </td>\n", _("Old Password"));
1327 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD
);
1328 printf("<tr><td> %s : </td>\n", _("New Password"));
1329 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1330 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1331 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1332 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1333 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST
);
1338 * Create all the control buttons for requesting action
1340 printf("<input type=submit name=%s value=\"%s\">",
1341 CHG_R_PASSWD_FLAG
, _("Change Password"));
1343 printf("<p></FORM>\n");
1346 * Do some work if a request has been made to change the
1347 * password somewhere other than the server. It could be this
1348 * is the first time through this code, so there isn't
1349 * anything to do. */
1350 if (verify_xsrf_token(passwd_form
) && cgi_variable(CHG_R_PASSWD_FLAG
)) {
1356 /****************************************************************************
1357 display a printers editing page
1358 ****************************************************************************/
1359 static void printers_page(void)
1361 const char *share
= cgi_variable("share");
1366 unsigned int parm_filter
= FLAG_BASIC
;
1367 const char form_name
[] = "printers";
1369 if (!verify_xsrf_token(form_name
)) {
1374 snum
= lp_servicenumber(share
);
1376 if (cgi_variable("Commit") && snum
>= 0) {
1377 commit_parameters(snum
);
1378 if (snum
>= iNumNonAutoPrintServices
)
1382 snum
= lp_servicenumber(share
);
1385 if (cgi_variable("Delete") && snum
>= 0) {
1386 lp_remove_service(snum
);
1392 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
1393 snum
= lp_servicenumber(share
);
1394 if (snum
< 0 || snum
>= iNumNonAutoPrintServices
) {
1396 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
1397 snum
= lp_servicenumber(share
);
1398 lp_do_parameter(snum
, "print ok", "Yes");
1400 snum
= lp_servicenumber(share
);
1404 if ( cgi_variable("ViewMode") )
1405 mode
= atoi(cgi_variable_nonull("ViewMode"));
1406 if ( cgi_variable("BasicMode"))
1408 if ( cgi_variable("AdvMode"))
1412 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1414 printf("<H3>%s</H3>\n", _("Important Note:"));
1415 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1416 printf("%s",_("are autoloaded printers from "));
1417 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1418 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1421 printf("<FORM name=\"swatform\" method=post>\n");
1422 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
1424 ViewModeBoxes( mode
);
1427 parm_filter
= FLAG_BASIC
;
1430 parm_filter
= FLAG_ADVANCED
;
1433 printf("<table>\n");
1434 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1435 printf("<td><select name=\"share\">\n");
1436 if (snum
< 0 || !lp_print_ok(snum
))
1437 printf("<option value=\" \"> \n");
1438 for (i
=0;i
<lp_numservices();i
++) {
1439 s
= lp_servicename(i
);
1440 if (s
&& (*s
) && strcmp(s
,"IPC$") && lp_print_ok(i
)) {
1441 if (i
>= iNumNonAutoPrintServices
)
1442 printf("<option %s value=\"%s\">[*]%s\n",
1443 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1446 printf("<option %s value=\"%s\">%s\n",
1447 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1451 printf("</select></td>");
1452 if (have_write_access
) {
1453 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1456 printf("</table>\n");
1458 if (have_write_access
) {
1459 printf("<table>\n");
1460 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1461 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1467 if (have_write_access
) {
1468 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1470 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1475 printf("<table>\n");
1476 show_parameters(snum
, 1, parm_filter
, 1);
1477 printf("</table>\n");
1479 printf("</FORM>\n");
1483 when the _() translation macro is used there is no obvious place to free
1484 the resulting string and there is no easy way to give a static pointer.
1485 All we can do is rotate between some static buffers and hope a single d_printf()
1486 doesn't have more calls to _() than the number of buffers
1489 const char *lang_msg_rotate(TALLOC_CTX
*ctx
, const char *msgid
)
1494 msgstr
= lang_msg(msgid
);
1499 ret
= talloc_strdup(ctx
, msgstr
);
1501 lang_msg_free(msgstr
);
1510 * main function for SWAT.
1512 int main(int argc
, char *argv
[])
1516 struct poptOption long_options
[] = {
1518 { "disable-authentication", 'a', POPT_ARG_VAL
, &demo_mode
, True
, "Disable authentication (demo mode)" },
1519 { "password-menu-only", 'P', POPT_ARG_VAL
, &passwd_only
, True
, "Show only change password menu" },
1523 TALLOC_CTX
*frame
= talloc_stackframe();
1526 umask(S_IWGRP
| S_IWOTH
);
1528 #if defined(HAVE_SET_AUTH_PARAMETERS)
1529 set_auth_parameters(argc
, argv
);
1530 #endif /* HAVE_SET_AUTH_PARAMETERS */
1532 /* just in case it goes wild ... */
1537 /* we don't want any SIGPIPE messages */
1538 BlockSignals(True
,SIGPIPE
);
1540 dbf
= x_fopen("/dev/null", O_WRONLY
, 0);
1541 if (!dbf
) dbf
= x_stderr
;
1543 /* we don't want stderr screwing us up */
1545 open("/dev/null", O_WRONLY
);
1547 pc
= poptGetContext("swat", argc
, (const char **) argv
, long_options
, 0);
1549 /* Parse command line options */
1551 while(poptGetNextOpt(pc
) != -1) { }
1553 poptFreeContext(pc
);
1557 setup_logging(argv
[0],False
);
1560 iNumNonAutoPrintServices
= lp_numservices();
1563 cgi_setup(get_dyn_SWATDIR(), !demo_mode
);
1567 cgi_load_variables();
1569 if (!file_exist(get_dyn_CONFIGFILE(), NULL
)) {
1570 have_read_access
= True
;
1571 have_write_access
= True
;
1573 /* check if the authenticated user has write access - if not then
1574 don't show write options */
1575 have_write_access
= (access(get_dyn_CONFIGFILE(),W_OK
) == 0);
1577 /* if the user doesn't have read access to smb.conf then
1578 don't let them view it */
1579 have_read_access
= (access(get_dyn_CONFIGFILE(),R_OK
) == 0);
1582 show_main_buttons();
1584 page
= cgi_pathinfo();
1586 /* Root gets full functionality */
1587 if (have_read_access
&& strcmp(page
, "globals")==0) {
1589 } else if (have_read_access
&& strcmp(page
,"shares")==0) {
1591 } else if (have_read_access
&& strcmp(page
,"printers")==0) {
1593 } else if (have_read_access
&& strcmp(page
,"status")==0) {
1595 } else if (have_read_access
&& strcmp(page
,"viewconfig")==0) {
1597 } else if (strcmp(page
,"passwd")==0) {
1599 } else if (have_read_access
&& strcmp(page
,"wizard")==0) {
1601 } else if (have_read_access
&& strcmp(page
,"wizard_params")==0) {
1602 wizard_params_page();
1603 } else if (have_read_access
&& strcmp(page
,"rewritecfg")==0) {