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 2 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, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * @defgroup swat SWAT - Samba Web Administration Tool
28 * @brief Samba Web Administration Tool.
32 #include "web/swat_proto.h"
34 static BOOL demo_mode
= False
;
35 static BOOL 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
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 char *fix_quotes(const char *str
)
85 static pstring newstring
;
87 size_t newstring_len
= sizeof(newstring
);
88 int quote_len
= strlen(""");
91 if ( *str
== '\"' && (newstring_len
- PTR_DIFF(p
, newstring
) - 1) > quote_len
) {
92 strncpy( p
, """, quote_len
);
103 static char *stripspaceupper(const char *str
)
105 static char newstring
[1024];
109 if (*str
!= ' ') *p
++ = toupper_ascii(*str
);
116 static char *make_parm_name(const char *label
)
118 static char parmname
[1024];
122 if (*label
== ' ') *p
++ = '_';
130 void get_xsrf_token(const char *username
, const char *pass
,
131 const char *formname
, time_t xsrf_time
, char token_str
[33])
133 struct MD5Context md5_ctx
;
138 ZERO_STRUCT(md5_ctx
);
141 MD5Update(&md5_ctx
, (uint8_t *)formname
, strlen(formname
));
142 MD5Update(&md5_ctx
, (uint8_t *)&xsrf_time
, sizeof(time_t));
143 if (username
!= NULL
) {
144 MD5Update(&md5_ctx
, (uint8_t *)username
, strlen(username
));
147 MD5Update(&md5_ctx
, (uint8_t *)pass
, strlen(pass
));
150 MD5Final(token
, &md5_ctx
);
152 for(i
= 0; i
< sizeof(token
); i
++) {
155 snprintf(tmp
, sizeof(tmp
), "%02x", token
[i
]);
156 strncat(token_str
, tmp
, sizeof(tmp
));
160 void print_xsrf_token(const char *username
, const char *pass
,
161 const char *formname
)
164 time_t xsrf_time
= time(NULL
);
166 get_xsrf_token(username
, pass
, formname
, xsrf_time
, token
);
167 printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
169 printf("<input type=\"hidden\" name=\"%s\" value=\"%lld\">\n",
170 XSRF_TIME
, (long long int)xsrf_time
);
173 BOOL
verify_xsrf_token(const char *formname
)
176 const char *username
= cgi_user_name();
177 const char *pass
= cgi_user_pass();
178 const char *token
= cgi_variable_nonull(XSRF_TOKEN
);
179 const char *time_str
= cgi_variable_nonull(XSRF_TIME
);
180 time_t xsrf_time
= 0;
181 time_t now
= time(NULL
);
183 if (sizeof(time_t) == sizeof(int)) {
184 xsrf_time
= atoi(time_str
);
185 } else if (sizeof(time_t) == sizeof(long)) {
186 xsrf_time
= atol(time_str
);
187 } else if (sizeof(time_t) == sizeof(long long)) {
188 xsrf_time
= atoll(time_str
);
191 if (abs(now
- xsrf_time
) > XSRF_TIMEOUT
) {
195 get_xsrf_token(username
, pass
, formname
, xsrf_time
, expected
);
196 return (strncmp(expected
, token
, sizeof(expected
)) == 0);
200 /****************************************************************************
201 include a lump of html in a page
202 ****************************************************************************/
203 static int include_html(const char *fname
)
209 fd
= web_open(fname
, O_RDONLY
, 0);
212 printf(_("ERROR: Can't open %s"), fname
);
217 while ((ret
= read(fd
, buf
, sizeof(buf
))) > 0) {
225 /****************************************************************************
226 start the page with standard stuff
227 ****************************************************************************/
228 static void print_header(void)
230 if (!cgi_waspost()) {
231 printf("Expires: 0\r\n");
233 printf("Content-type: text/html\r\n\r\n");
235 if (!include_html("include/header.html")) {
236 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
237 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
241 /* *******************************************************************
242 show parameter label with translated name in the following form
243 because showing original and translated label in one line looks
244 too long, and showing translated label only is unusable for
246 -------------------------------
247 HELP security [combo box][button]
249 -------------------------------
250 (capital words are translated by gettext.)
251 if no translation is available, then same form as original is
253 "i18n_translated_parm" class is used to change the color of the
254 translated parameter with CSS.
255 **************************************************************** */
256 static const char* get_parm_translated(
257 const char* pAnchor
, const char* pHelp
, const char* pLabel
)
259 const char* pTranslated
= _(pLabel
);
260 static pstring output
;
261 if(strcmp(pLabel
, pTranslated
) != 0)
264 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
265 pAnchor
, pHelp
, pLabel
, pTranslated
);
269 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
270 pAnchor
, pHelp
, pLabel
);
273 /****************************************************************************
275 ****************************************************************************/
276 static void print_footer(void)
278 if (!include_html("include/footer.html")) {
279 printf("\n</BODY>\n</HTML>\n");
283 /****************************************************************************
284 display one editable parameter in a form
285 ****************************************************************************/
286 static void show_parameter(int snum
, struct parm_struct
*parm
)
289 void *ptr
= parm
->ptr
;
290 char *utf8_s1
, *utf8_s2
;
292 if (parm
->p_class
== P_LOCAL
&& snum
>= 0) {
293 ptr
= lp_local_ptr(snum
, ptr
);
296 printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm
->label
), _("Help"), parm
->label
));
297 switch (parm
->type
) {
299 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
300 make_parm_name(parm
->label
), *(char *)ptr
);
301 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
302 _("Set Default"), make_parm_name(parm
->label
),(char)(parm
->def
.cvalue
));
306 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
307 make_parm_name(parm
->label
));
308 if ((char ***)ptr
&& *(char ***)ptr
&& **(char ***)ptr
) {
309 char **list
= *(char ***)ptr
;
310 for (;*list
;list
++) {
311 /* enclose in HTML encoded quotes if the string contains a space */
312 if ( strchr_m(*list
, ' ') ) {
313 push_utf8_allocate(&utf8_s1
, *list
);
314 push_utf8_allocate(&utf8_s2
, ((*(list
+1))?", ":""));
315 printf(""%s"%s", utf8_s1
, utf8_s2
);
317 push_utf8_allocate(&utf8_s1
, *list
);
318 push_utf8_allocate(&utf8_s2
, ((*(list
+1))?", ":""));
319 printf("%s%s", utf8_s1
, utf8_s2
);
326 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
327 _("Set Default"), make_parm_name(parm
->label
));
328 if (parm
->def
.lvalue
) {
329 char **list
= (char **)(parm
->def
.lvalue
);
330 for (; *list
; list
++) {
331 /* enclose in HTML encoded quotes if the string contains a space */
332 if ( strchr_m(*list
, ' ') )
333 printf(""%s"%s", *list
, ((*(list
+1))?", ":""));
335 printf("%s%s", *list
, ((*(list
+1))?", ":""));
343 push_utf8_allocate(&utf8_s1
, *(char **)ptr
);
344 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
345 make_parm_name(parm
->label
), fix_quotes(utf8_s1
));
347 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
348 _("Set Default"), make_parm_name(parm
->label
),fix_backslash((char *)(parm
->def
.svalue
)));
353 push_utf8_allocate(&utf8_s1
, (char *)ptr
);
354 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
355 make_parm_name(parm
->label
), fix_quotes(utf8_s1
));
357 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
358 _("Set Default"), make_parm_name(parm
->label
),fix_backslash((char *)(parm
->def
.svalue
)));
362 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
363 printf("<option %s>Yes", (*(BOOL
*)ptr
)?"selected":"");
364 printf("<option %s>No", (*(BOOL
*)ptr
)?"":"selected");
366 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
367 _("Set Default"), make_parm_name(parm
->label
),(BOOL
)(parm
->def
.bvalue
)?0:1);
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
)?1:0);
380 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm
->label
), *(int *)ptr
);
381 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
382 _("Set Default"), make_parm_name(parm
->label
),(int)(parm
->def
.ivalue
));
386 printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm
->label
), octal_string(*(int *)ptr
));
387 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
388 _("Set Default"), make_parm_name(parm
->label
),
389 octal_string((int)(parm
->def
.ivalue
)));
393 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
394 for (i
=0;parm
->enum_list
[i
].name
;i
++) {
395 if (i
== 0 || parm
->enum_list
[i
].value
!= parm
->enum_list
[i
-1].value
) {
396 printf("<option %s>%s",(*(int *)ptr
)==parm
->enum_list
[i
].value
?"selected":"",parm
->enum_list
[i
].name
);
400 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
401 _("Set Default"), make_parm_name(parm
->label
),enum_index((int)(parm
->def
.ivalue
),parm
->enum_list
));
406 printf("</td></tr>\n");
409 /****************************************************************************
410 display a set of parameters for a service
411 ****************************************************************************/
412 static void show_parameters(int snum
, int allparameters
, unsigned int parm_filter
, int printers
)
415 struct parm_struct
*parm
;
416 const char *heading
= NULL
;
417 const char *last_heading
= NULL
;
419 while ((parm
= lp_next_parameter(snum
, &i
, allparameters
))) {
420 if (snum
< 0 && parm
->p_class
== P_LOCAL
&& !(parm
->flags
& FLAG_GLOBAL
))
422 if (parm
->p_class
== P_SEPARATOR
) {
423 heading
= parm
->label
;
426 if (parm
->flags
& FLAG_HIDE
) continue;
428 if (printers
& !(parm
->flags
& FLAG_PRINT
)) continue;
429 if (!printers
& !(parm
->flags
& FLAG_SHARE
)) continue;
432 if (!( parm_filter
& FLAG_ADVANCED
)) {
433 if (!(parm
->flags
& FLAG_BASIC
)) {
434 void *ptr
= parm
->ptr
;
436 if (parm
->p_class
== P_LOCAL
&& snum
>= 0) {
437 ptr
= lp_local_ptr(snum
, ptr
);
440 switch (parm
->type
) {
442 if (*(char *)ptr
== (char)(parm
->def
.cvalue
)) continue;
446 if (!str_list_compare(*(char ***)ptr
, (char **)(parm
->def
.lvalue
))) continue;
451 if (!strcmp(*(char **)ptr
,(char *)(parm
->def
.svalue
))) continue;
456 if (!strcmp((char *)ptr
,(char *)(parm
->def
.svalue
))) continue;
461 if (*(BOOL
*)ptr
== (BOOL
)(parm
->def
.bvalue
)) continue;
466 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
471 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
477 if (printers
&& !(parm
->flags
& FLAG_PRINT
)) continue;
480 if ((parm_filter
& FLAG_WIZARD
) && !(parm
->flags
& FLAG_WIZARD
)) continue;
482 if ((parm_filter
& FLAG_ADVANCED
) && !(parm
->flags
& FLAG_ADVANCED
)) continue;
484 if (heading
&& heading
!= last_heading
) {
485 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading
));
486 last_heading
= heading
;
488 show_parameter(snum
, parm
);
492 /****************************************************************************
493 load the smb.conf file into loadparm.
494 ****************************************************************************/
495 static BOOL
load_config(BOOL save_def
)
497 lp_resetnumservices();
498 return lp_load(dyn_CONFIGFILE
,False
,save_def
,False
,True
);
501 /****************************************************************************
503 ****************************************************************************/
504 static void write_config(FILE *f
, BOOL show_defaults
)
506 fprintf(f
, "# Samba config file created using SWAT\n");
507 fprintf(f
, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
508 fprintf(f
, "# Date: %s\n\n", current_timestring(False
));
510 lp_dump(f
, show_defaults
, iNumNonAutoPrintServices
);
513 /****************************************************************************
514 save and reload the smb.conf config file
515 ****************************************************************************/
516 static int save_reload(int snum
)
521 f
= sys_fopen(dyn_CONFIGFILE
,"w");
523 printf(_("failed to open %s for writing"), dyn_CONFIGFILE
);
528 /* just in case they have used the buggy xinetd to create the file */
529 if (fstat(fileno(f
), &st
) == 0 &&
530 (st
.st_mode
& S_IWOTH
)) {
531 #if defined HAVE_FCHMOD
532 fchmod(fileno(f
), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
534 chmod(dyn_CONFIGFILE
, S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
538 write_config(f
, False
);
540 lp_dump_one(f
, False
, snum
);
545 if (!load_config(False
)) {
546 printf(_("Can't reload %s"), dyn_CONFIGFILE
);
550 iNumNonAutoPrintServices
= lp_numservices();
556 /****************************************************************************
558 ****************************************************************************/
559 static void commit_parameter(int snum
, struct parm_struct
*parm
, const char *v
)
564 if (snum
< 0 && parm
->p_class
== P_LOCAL
) {
565 /* this handles the case where we are changing a local
566 variable globally. We need to change the parameter in
567 all shares where it is currently set to the default */
568 for (i
=0;i
<lp_numservices();i
++) {
569 s
= lp_servicename(i
);
570 if (s
&& (*s
) && lp_is_default(i
, parm
)) {
571 lp_do_parameter(i
, parm
->label
, v
);
576 lp_do_parameter(snum
, parm
->label
, v
);
579 /****************************************************************************
580 commit a set of parameters for a service
581 ****************************************************************************/
582 static void commit_parameters(int snum
)
585 struct parm_struct
*parm
;
589 while ((parm
= lp_next_parameter(snum
, &i
, 1))) {
590 slprintf(label
, sizeof(label
)-1, "parm_%s", make_parm_name(parm
->label
));
591 if ((v
= cgi_variable(label
)) != NULL
) {
592 if (parm
->flags
& FLAG_HIDE
) continue;
593 commit_parameter(snum
, parm
, v
);
598 /****************************************************************************
599 spit out the html for a link with an image
600 ****************************************************************************/
601 static void image_link(const char *name
, const char *hlink
, const char *src
)
603 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
604 cgi_baseurl(), hlink
, src
, name
);
607 /****************************************************************************
608 display the main navigation controls at the top of each page along
610 ****************************************************************************/
611 static void show_main_buttons(void)
615 if ((p
= cgi_user_name()) && strcmp(p
, "root")) {
616 printf(_("Logged in as <b>%s</b>"), p
);
620 image_link(_("Home"), "", "images/home.gif");
621 if (have_write_access
) {
622 image_link(_("Globals"), "globals", "images/globals.gif");
623 image_link(_("Shares"), "shares", "images/shares.gif");
624 image_link(_("Printers"), "printers", "images/printers.gif");
625 image_link(_("Wizard"), "wizard", "images/wizard.gif");
627 /* root always gets all buttons, otherwise look for -P */
628 if ( have_write_access
|| (!passwd_only
&& have_read_access
) ) {
629 image_link(_("Status"), "status", "images/status.gif");
630 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
632 image_link(_("Password Management"), "passwd", "images/passwd.gif");
637 /****************************************************************************
638 * Handle Display/Edit Mode CGI
639 ****************************************************************************/
640 static void ViewModeBoxes(int mode
)
642 printf("<p>%s: \n", _("Current View Is"));
643 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode
== 0) ? "checked" : ""), _("Basic"));
644 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode
== 1) ? "checked" : ""), _("Advanced"));
645 printf("<br>%s: \n", _("Change View To"));
646 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
647 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
648 printf("</p><br>\n");
651 /****************************************************************************
652 display a welcome page
653 ****************************************************************************/
654 static void welcome_page(void)
656 if (file_exist("help/welcome.html", NULL
)) {
657 include_html("help/welcome.html");
659 include_html("help/welcome-no-samba-doc.html");
663 /****************************************************************************
664 display the current smb.conf
665 ****************************************************************************/
666 static void viewconfig_page(void)
669 const char form_name
[] = "viewconfig";
671 if (!verify_xsrf_token(form_name
)) {
675 if (cgi_variable("full_view")) {
680 printf("<H2>%s</H2>\n", _("Current Config"));
681 printf("<form method=post>\n");
682 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
685 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
687 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
691 write_config(stdout
, full_view
);
696 /****************************************************************************
697 second screen of the wizard ... Fetch Configuration Parameters
698 ****************************************************************************/
699 static void wizard_params_page(void)
701 unsigned int parm_filter
= FLAG_WIZARD
;
702 const char form_name
[] = "wizard_params";
704 /* Here we first set and commit all the parameters that were selected
705 in the previous screen. */
707 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
709 if (!verify_xsrf_token(form_name
)) {
713 if (cgi_variable("Commit")) {
714 commit_parameters(GLOBAL_SECTION_SNUM
);
719 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
720 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
722 if (have_write_access
) {
723 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
726 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
730 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
731 printf("</table>\n");
735 /****************************************************************************
736 Utility to just rewrite the smb.conf file - effectively just cleans it up
737 ****************************************************************************/
738 static void rewritecfg_file(void)
740 commit_parameters(GLOBAL_SECTION_SNUM
);
742 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
745 /****************************************************************************
746 wizard to create/modify the smb.conf file
747 ****************************************************************************/
748 static void wizard_page(void)
750 /* Set some variables to collect data from smb.conf */
756 const char form_name
[] = "wizard";
758 if (!verify_xsrf_token(form_name
)) {
762 if (cgi_variable("Rewrite")) {
763 (void) rewritecfg_file();
767 if (cgi_variable("GetWizardParams")){
768 (void) wizard_params_page();
772 if (cgi_variable("Commit")){
773 SerType
= atoi(cgi_variable_nonull("ServerType"));
774 winstype
= atoi(cgi_variable_nonull("WINSType"));
775 have_home
= lp_servicenumber(HOMES_NAME
);
776 HomeExpo
= atoi(cgi_variable_nonull("HomeExpo"));
778 /* Plain text passwords are too badly broken - use encrypted passwords only */
779 lp_do_parameter( GLOBAL_SECTION_SNUM
, "encrypt passwords", "Yes");
783 /* Stand-alone Server */
784 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
785 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
789 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "DOMAIN" );
790 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
793 /* Domain Controller */
794 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
795 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "Yes" );
798 switch ( winstype
) {
800 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
801 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
804 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "Yes" );
805 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
808 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
809 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", cgi_variable_nonull("WINSAddr"));
813 /* Have to create Homes share? */
814 if ((HomeExpo
== 1) && (have_home
== -1)) {
817 pstrcpy(unix_share
,HOMES_NAME
);
819 lp_copy_service(GLOBAL_SECTION_SNUM
, unix_share
);
820 iNumNonAutoPrintServices
= lp_numservices();
821 have_home
= lp_servicenumber(HOMES_NAME
);
822 lp_do_parameter( have_home
, "read only", "No");
823 lp_do_parameter( have_home
, "valid users", "%S");
824 lp_do_parameter( have_home
, "browseable", "No");
825 commit_parameters(have_home
);
828 /* Need to Delete Homes share? */
829 if ((HomeExpo
== 0) && (have_home
!= -1)) {
830 lp_remove_service(have_home
);
834 commit_parameters(GLOBAL_SECTION_SNUM
);
839 /* Now determine smb.conf WINS settings */
840 if (lp_wins_support())
842 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
846 /* Do we have a homes share? */
847 have_home
= lp_servicenumber(HOMES_NAME
);
849 if ((winstype
== 2) && lp_wins_support())
852 role
= lp_server_role();
856 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
857 printf("<form method=post action=wizard>\n");
858 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
860 if (have_write_access
) {
861 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
862 printf("%s", _("The same will happen if you press the commit button."));
863 printf("<br><br>\n");
865 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
866 printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
867 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
868 printf("</center>\n");
872 printf("<center><table border=0>");
873 printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
874 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role
== ROLE_STANDALONE
) ? "checked" : ""), _("Stand Alone"));
875 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role
== ROLE_DOMAIN_MEMBER
) ? "checked" : ""), _("Domain Member"));
876 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role
== ROLE_DOMAIN_PDC
) ? "checked" : ""), _("Domain Controller"));
878 if (role
== ROLE_DOMAIN_BDC
) {
879 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
881 printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
882 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype
== 0) ? "checked" : ""), _("Not Used"));
883 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype
== 1) ? "checked" : ""), _("Server for client use"));
884 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype
== 2) ? "checked" : ""), _("Client of another WINS server"));
886 printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
888 /* Print out the list of wins servers */
889 if(lp_wins_server_list()) {
891 const char **wins_servers
= lp_wins_server_list();
892 for(i
= 0; wins_servers
[i
]; i
++) printf("%s ", wins_servers
[i
]);
895 printf("\"></td></tr>\n");
897 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"));
898 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
900 printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
901 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home
== -1) ? "" : "checked ");
902 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home
== -1 ) ? "checked" : "");
903 printf("<td></td></tr>\n");
905 /* Enable this when we are ready ....
906 * printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
907 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
908 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
909 * printf("<td></td></tr>\n");
912 printf("</table></center>");
915 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
920 /****************************************************************************
921 display a globals editing page
922 ****************************************************************************/
923 static void globals_page(void)
925 unsigned int parm_filter
= FLAG_BASIC
;
927 const char form_name
[] = "globals";
929 printf("<H2>%s</H2>\n", _("Global Parameters"));
931 if (!verify_xsrf_token(form_name
)) {
935 if (cgi_variable("Commit")) {
936 commit_parameters(GLOBAL_SECTION_SNUM
);
940 if ( cgi_variable("ViewMode") )
941 mode
= atoi(cgi_variable_nonull("ViewMode"));
942 if ( cgi_variable("BasicMode"))
944 if ( cgi_variable("AdvMode"))
948 printf("<form name=\"swatform\" method=post action=globals>\n");
949 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
951 ViewModeBoxes( mode
);
954 parm_filter
= FLAG_BASIC
;
957 parm_filter
= FLAG_ADVANCED
;
961 if (have_write_access
) {
962 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
963 _("Commit Changes"));
966 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
971 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
972 printf("</table>\n");
976 /****************************************************************************
977 display a shares editing page. share is in unix codepage,
978 ****************************************************************************/
979 static void shares_page(void)
981 const char *share
= cgi_variable("share");
987 unsigned int parm_filter
= FLAG_BASIC
;
988 const char form_name
[] = "shares";
990 printf("<H2>%s</H2>\n", _("Share Parameters"));
992 if (!verify_xsrf_token(form_name
)) {
997 snum
= lp_servicenumber(share
);
999 if (cgi_variable("Commit") && snum
>= 0) {
1000 commit_parameters(snum
);
1004 if (cgi_variable("Delete") && snum
>= 0) {
1005 lp_remove_service(snum
);
1011 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
1013 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
1014 iNumNonAutoPrintServices
= lp_numservices();
1016 snum
= lp_servicenumber(share
);
1019 if ( cgi_variable("ViewMode") )
1020 mode
= atoi(cgi_variable_nonull("ViewMode"));
1021 if ( cgi_variable("BasicMode"))
1023 if ( cgi_variable("AdvMode"))
1027 printf("<FORM name=\"swatform\" method=post>\n");
1028 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
1030 printf("<table>\n");
1032 ViewModeBoxes( mode
);
1035 parm_filter
= FLAG_BASIC
;
1038 parm_filter
= FLAG_ADVANCED
;
1041 printf("<br><tr>\n");
1042 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1043 printf("<td><select name=share>\n");
1045 printf("<option value=\" \"> \n");
1046 for (i
=0;i
<lp_numservices();i
++) {
1047 s
= lp_servicename(i
);
1048 if (s
&& (*s
) && strcmp(s
,"IPC$") && !lp_print_ok(i
)) {
1049 push_utf8_allocate(&utf8_s
, s
);
1050 printf("<option %s value=\"%s\">%s\n",
1051 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1057 printf("</select></td>\n");
1058 if (have_write_access
) {
1059 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1064 if (have_write_access
) {
1066 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1067 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1073 if (have_write_access
) {
1074 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1077 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1082 printf("<table>\n");
1083 show_parameters(snum
, 1, parm_filter
, 0);
1084 printf("</table>\n");
1087 printf("</FORM>\n");
1090 /*************************************************************
1091 change a password either locally or remotely
1092 *************************************************************/
1093 static BOOL
change_password(const char *remote_machine
, const char *user_name
,
1094 const char *old_passwd
, const char *new_passwd
,
1102 printf("%s\n<p>", _("password change in demo mode rejected"));
1106 if (remote_machine
!= NULL
) {
1107 ret
= remote_password_change(remote_machine
, user_name
, old_passwd
,
1108 new_passwd
, err_str
, sizeof(err_str
));
1110 printf("%s\n<p>", err_str
);
1111 return NT_STATUS_IS_OK(ret
);
1114 if(!initialize_password_db(True
)) {
1115 printf("%s\n<p>", _("Can't setup password database vectors."));
1119 ret
= local_password_change(user_name
, local_flags
, new_passwd
, err_str
, sizeof(err_str
),
1120 msg_str
, sizeof(msg_str
));
1123 printf("%s\n<p>", msg_str
);
1125 printf("%s\n<p>", err_str
);
1127 return NT_STATUS_IS_OK(ret
);
1130 /****************************************************************************
1131 do the stuff required to add or change a password
1132 ****************************************************************************/
1133 static void chg_passwd(void)
1137 int local_flags
= 0;
1139 /* Make sure users name has been specified */
1140 if (strlen(cgi_variable_nonull(SWAT_USER
)) == 0) {
1141 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1146 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1147 * so if that's what we're doing, skip the rest of the checks
1149 if (!cgi_variable(DISABLE_USER_FLAG
) && !cgi_variable(ENABLE_USER_FLAG
) && !cgi_variable(DELETE_USER_FLAG
)) {
1152 * If current user is not root, make sure old password has been specified
1153 * If REMOTE change, even root must provide old password
1155 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0)) ||
1156 ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0))) {
1157 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1161 /* If changing a users password on a remote hosts we have to know what host */
1162 if ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(RHOST
)) <= 0)) {
1163 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1167 /* Make sure new passwords have been specified */
1168 if ((strlen( cgi_variable_nonull(NEW_PSWD
)) <= 0) ||
1169 (strlen( cgi_variable_nonull(NEW2_PSWD
)) <= 0)) {
1170 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1174 /* Make sure new passwords was typed correctly twice */
1175 if (strcmp(cgi_variable_nonull(NEW_PSWD
), cgi_variable_nonull(NEW2_PSWD
)) != 0) {
1176 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1181 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1182 host
= cgi_variable(RHOST
);
1183 } else if (am_root()) {
1190 * Set up the local flags.
1193 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_ADD_USER
: 0);
1194 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1195 local_flags
|= (cgi_variable(CHG_S_PASSWD_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1196 local_flags
|= (cgi_variable(DELETE_USER_FLAG
) ? LOCAL_DELETE_USER
: 0);
1197 local_flags
|= (cgi_variable(ENABLE_USER_FLAG
) ? LOCAL_ENABLE_USER
: 0);
1198 local_flags
|= (cgi_variable(DISABLE_USER_FLAG
) ? LOCAL_DISABLE_USER
: 0);
1201 rslt
= change_password(host
,
1202 cgi_variable_nonull(SWAT_USER
),
1203 cgi_variable_nonull(OLD_PSWD
), cgi_variable_nonull(NEW_PSWD
),
1206 if(cgi_variable(CHG_S_PASSWD_FLAG
)) {
1209 printf("%s\n", _(" The passwd has been changed."));
1211 printf("%s\n", _(" The passwd has NOT been changed."));
1218 /****************************************************************************
1219 display a password editing page
1220 ****************************************************************************/
1221 static void passwd_page(void)
1223 const char *new_name
= cgi_user_name();
1224 const char passwd_form
[] = "passwd";
1225 const char rpasswd_form
[] = "rpasswd";
1227 if (!new_name
) new_name
= "";
1229 printf("<H2>%s</H2>\n", _("Server Password Management"));
1231 printf("<FORM name=\"swatform\" method=post>\n");
1232 print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form
);
1234 printf("<table>\n");
1237 * Create all the dialog boxes for data collection
1239 printf("<tr><td> %s : </td>\n", _("User Name"));
1240 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER
, new_name
);
1242 printf("<tr><td> %s : </td>\n", _("Old Password"));
1243 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD
);
1245 printf("<tr><td> %s : </td>\n", _("New Password"));
1246 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1247 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1248 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1249 printf("</table>\n");
1252 * Create all the control buttons for requesting action
1254 printf("<input type=submit name=%s value=\"%s\">\n",
1255 CHG_S_PASSWD_FLAG
, _("Change Password"));
1256 if (demo_mode
|| am_root()) {
1257 printf("<input type=submit name=%s value=\"%s\">\n",
1258 ADD_USER_FLAG
, _("Add New User"));
1259 printf("<input type=submit name=%s value=\"%s\">\n",
1260 DELETE_USER_FLAG
, _("Delete User"));
1261 printf("<input type=submit name=%s value=\"%s\">\n",
1262 DISABLE_USER_FLAG
, _("Disable User"));
1263 printf("<input type=submit name=%s value=\"%s\">\n",
1264 ENABLE_USER_FLAG
, _("Enable User"));
1266 printf("<p></FORM>\n");
1269 * Do some work if change, add, disable or enable was
1270 * requested. It could be this is the first time through this
1271 * code, so there isn't anything to do. */
1272 if (verify_xsrf_token(passwd_form
) &&
1273 ((cgi_variable(CHG_S_PASSWD_FLAG
)) || (cgi_variable(ADD_USER_FLAG
)) || (cgi_variable(DELETE_USER_FLAG
)) ||
1274 (cgi_variable(DISABLE_USER_FLAG
)) || (cgi_variable(ENABLE_USER_FLAG
)))) {
1278 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1280 printf("<FORM name=\"swatform\" method=post>\n");
1281 print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form
);
1283 printf("<table>\n");
1286 * Create all the dialog boxes for data collection
1288 printf("<tr><td> %s : </td>\n", _("User Name"));
1289 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER
, new_name
);
1290 printf("<tr><td> %s : </td>\n", _("Old Password"));
1291 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD
);
1292 printf("<tr><td> %s : </td>\n", _("New Password"));
1293 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1294 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1295 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1296 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1297 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST
);
1302 * Create all the control buttons for requesting action
1304 printf("<input type=submit name=%s value=\"%s\">",
1305 CHG_R_PASSWD_FLAG
, _("Change Password"));
1307 printf("<p></FORM>\n");
1310 * Do some work if a request has been made to change the
1311 * password somewhere other than the server. It could be this
1312 * is the first time through this code, so there isn't
1313 * anything to do. */
1314 if (verify_xsrf_token(passwd_form
) && cgi_variable(CHG_R_PASSWD_FLAG
)) {
1320 /****************************************************************************
1321 display a printers editing page
1322 ****************************************************************************/
1323 static void printers_page(void)
1325 const char *share
= cgi_variable("share");
1330 unsigned int parm_filter
= FLAG_BASIC
;
1331 const char form_name
[] = "printers";
1333 if (!verify_xsrf_token(form_name
)) {
1338 snum
= lp_servicenumber(share
);
1340 if (cgi_variable("Commit") && snum
>= 0) {
1341 commit_parameters(snum
);
1342 if (snum
>= iNumNonAutoPrintServices
)
1348 if (cgi_variable("Delete") && snum
>= 0) {
1349 lp_remove_service(snum
);
1355 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
1357 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
1358 iNumNonAutoPrintServices
= lp_numservices();
1359 snum
= lp_servicenumber(share
);
1360 lp_do_parameter(snum
, "print ok", "Yes");
1362 snum
= lp_servicenumber(share
);
1365 if ( cgi_variable("ViewMode") )
1366 mode
= atoi(cgi_variable_nonull("ViewMode"));
1367 if ( cgi_variable("BasicMode"))
1369 if ( cgi_variable("AdvMode"))
1373 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1375 printf("<H3>%s</H3>\n", _("Important Note:"));
1376 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1377 printf("%s",_("are autoloaded printers from "));
1378 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1379 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1382 printf("<FORM name=\"swatform\" method=post>\n");
1383 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
1385 ViewModeBoxes( mode
);
1388 parm_filter
= FLAG_BASIC
;
1391 parm_filter
= FLAG_ADVANCED
;
1394 printf("<table>\n");
1395 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1396 printf("<td><select name=\"share\">\n");
1397 if (snum
< 0 || !lp_print_ok(snum
))
1398 printf("<option value=\" \"> \n");
1399 for (i
=0;i
<lp_numservices();i
++) {
1400 s
= lp_servicename(i
);
1401 if (s
&& (*s
) && strcmp(s
,"IPC$") && lp_print_ok(i
)) {
1402 if (i
>= iNumNonAutoPrintServices
)
1403 printf("<option %s value=\"%s\">[*]%s\n",
1404 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1407 printf("<option %s value=\"%s\">%s\n",
1408 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1412 printf("</select></td>");
1413 if (have_write_access
) {
1414 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1417 printf("</table>\n");
1419 if (have_write_access
) {
1420 printf("<table>\n");
1421 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1422 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1428 if (have_write_access
) {
1429 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1431 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1436 printf("<table>\n");
1437 show_parameters(snum
, 1, parm_filter
, 1);
1438 printf("</table>\n");
1440 printf("</FORM>\n");
1445 * main function for SWAT.
1447 int main(int argc
, char *argv
[])
1451 struct poptOption long_options
[] = {
1453 { "disable-authentication", 'a', POPT_ARG_VAL
, &demo_mode
, True
, "Disable authentication (demo mode)" },
1454 { "password-menu-only", 'P', POPT_ARG_VAL
, &passwd_only
, True
, "Show only change password menu" },
1460 umask(S_IWGRP
| S_IWOTH
);
1462 #if defined(HAVE_SET_AUTH_PARAMETERS)
1463 set_auth_parameters(argc
, argv
);
1464 #endif /* HAVE_SET_AUTH_PARAMETERS */
1466 /* just in case it goes wild ... */
1471 /* we don't want any SIGPIPE messages */
1472 BlockSignals(True
,SIGPIPE
);
1474 dbf
= x_fopen("/dev/null", O_WRONLY
, 0);
1475 if (!dbf
) dbf
= x_stderr
;
1477 /* we don't want stderr screwing us up */
1479 open("/dev/null", O_WRONLY
);
1481 pc
= poptGetContext("swat", argc
, (const char **) argv
, long_options
, 0);
1483 /* Parse command line options */
1485 while(poptGetNextOpt(pc
) != -1) { }
1487 poptFreeContext(pc
);
1491 setup_logging(argv
[0],False
);
1494 iNumNonAutoPrintServices
= lp_numservices();
1497 cgi_setup(dyn_SWATDIR
, !demo_mode
);
1501 cgi_load_variables();
1503 if (!file_exist(dyn_CONFIGFILE
, NULL
)) {
1504 have_read_access
= True
;
1505 have_write_access
= True
;
1507 /* check if the authenticated user has write access - if not then
1508 don't show write options */
1509 have_write_access
= (access(dyn_CONFIGFILE
,W_OK
) == 0);
1511 /* if the user doesn't have read access to smb.conf then
1512 don't let them view it */
1513 have_read_access
= (access(dyn_CONFIGFILE
,R_OK
) == 0);
1516 show_main_buttons();
1518 page
= cgi_pathinfo();
1520 /* Root gets full functionality */
1521 if (have_read_access
&& strcmp(page
, "globals")==0) {
1523 } else if (have_read_access
&& strcmp(page
,"shares")==0) {
1525 } else if (have_read_access
&& strcmp(page
,"printers")==0) {
1527 } else if (have_read_access
&& strcmp(page
,"status")==0) {
1529 } else if (have_read_access
&& strcmp(page
,"viewconfig")==0) {
1531 } else if (strcmp(page
,"passwd")==0) {
1533 } else if (have_read_access
&& strcmp(page
,"wizard")==0) {
1535 } else if (have_read_access
&& strcmp(page
,"wizard_params")==0) {
1536 wizard_params_page();
1537 } else if (have_read_access
&& strcmp(page
,"rewritecfg")==0) {