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 "system/filesys.h"
32 #include "popt_common.h"
33 #include "web/swat_proto.h"
34 #include "printing/pcap.h"
35 #include "printing/load.h"
37 #include "intl/lang_tdb.h"
38 #include "../lib/crypto/md5.h"
39 #include "lib/param/loadparm.h"
42 static int demo_mode
= False
;
43 static int passwd_only
= False
;
44 static bool have_write_access
= False
;
45 static bool have_read_access
= False
;
46 static int iNumNonAutoPrintServices
= 0;
49 * Password Management Globals
51 #define SWAT_USER "username"
52 #define OLD_PSWD "old_passwd"
53 #define NEW_PSWD "new_passwd"
54 #define NEW2_PSWD "new2_passwd"
55 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
56 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
57 #define ADD_USER_FLAG "add_user_flag"
58 #define DELETE_USER_FLAG "delete_user_flag"
59 #define DISABLE_USER_FLAG "disable_user_flag"
60 #define ENABLE_USER_FLAG "enable_user_flag"
61 #define RHOST "remote_host"
62 #define XSRF_TOKEN "xsrf"
63 #define XSRF_TIME "xsrf_time"
64 #define XSRF_TIMEOUT 300
66 #define _(x) lang_msg_rotate(talloc_tos(),x)
68 /****************************************************************************
69 ****************************************************************************/
70 static int enum_index(int value
, const struct enum_list
*enumlist
)
73 for (i
=0;enumlist
[i
].name
;i
++)
74 if (value
== enumlist
[i
].value
) break;
78 static char *fix_backslash(const char *str
)
80 static char newstring
[1024];
84 if (*str
== '\\') {*p
++ = '\\';*p
++ = '\\';}
92 static const char *fix_quotes(TALLOC_CTX
*ctx
, char *str
)
94 char *newstring
= NULL
;
97 int quote_len
= strlen(""");
99 /* Count the number of quotes. */
104 newstring_len
+= quote_len
;
110 newstring
= talloc_array(ctx
, char, newstring_len
);
114 for (p
= newstring
; *str
; str
++) {
116 strncpy( p
, """, quote_len
);
126 static char *stripspaceupper(const char *str
)
128 static char newstring
[1024];
132 if (*str
!= ' ') *p
++ = toupper_m(*str
);
139 static char *make_parm_name(const char *label
)
141 static char parmname
[1024];
145 if (*label
== ' ') *p
++ = '_';
153 void get_xsrf_token(const char *username
, const char *pass
,
154 const char *formname
, time_t xsrf_time
, char token_str
[33])
156 struct MD5Context md5_ctx
;
161 ZERO_STRUCT(md5_ctx
);
164 MD5Update(&md5_ctx
, (uint8_t *)formname
, strlen(formname
));
165 MD5Update(&md5_ctx
, (uint8_t *)&xsrf_time
, sizeof(time_t));
166 if (username
!= NULL
) {
167 MD5Update(&md5_ctx
, (uint8_t *)username
, strlen(username
));
170 MD5Update(&md5_ctx
, (uint8_t *)pass
, strlen(pass
));
173 MD5Final(token
, &md5_ctx
);
175 for(i
= 0; i
< sizeof(token
); i
++) {
178 snprintf(tmp
, sizeof(tmp
), "%02x", token
[i
]);
179 /* FIXME ! Truncate check. JRA. */
180 (void)strlcat(token_str
, tmp
, sizeof(tmp
));
184 void print_xsrf_token(const char *username
, const char *pass
,
185 const char *formname
)
188 time_t xsrf_time
= time(NULL
);
190 get_xsrf_token(username
, pass
, formname
, xsrf_time
, token
);
191 printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
193 printf("<input type=\"hidden\" name=\"%s\" value=\"%lld\">\n",
194 XSRF_TIME
, (long long int)xsrf_time
);
197 bool verify_xsrf_token(const char *formname
)
200 const char *username
= cgi_user_name();
201 const char *pass
= cgi_user_pass();
202 const char *token
= cgi_variable_nonull(XSRF_TOKEN
);
203 const char *time_str
= cgi_variable_nonull(XSRF_TIME
);
205 long long xsrf_time_ll
= 0;
206 time_t xsrf_time
= 0;
207 time_t now
= time(NULL
);
210 xsrf_time_ll
= strtoll(time_str
, &p
, 10);
217 if (PTR_DIFF(p
, time_str
) > strlen(time_str
)) {
220 if (xsrf_time_ll
> _TYPE_MAXIMUM(time_t)) {
223 if (xsrf_time_ll
< _TYPE_MINIMUM(time_t)) {
226 xsrf_time
= xsrf_time_ll
;
228 if (abs(now
- xsrf_time
) > XSRF_TIMEOUT
) {
232 get_xsrf_token(username
, pass
, formname
, xsrf_time
, expected
);
233 return (strncmp(expected
, token
, sizeof(expected
)) == 0);
237 /****************************************************************************
238 include a lump of html in a page
239 ****************************************************************************/
240 static int include_html(const char *fname
)
246 fd
= web_open(fname
, O_RDONLY
, 0);
249 printf(_("ERROR: Can't open %s"), fname
);
254 while ((ret
= read(fd
, buf
, sizeof(buf
))) > 0) {
255 if (write(1, buf
, ret
) == -1) {
264 /****************************************************************************
265 start the page with standard stuff
266 ****************************************************************************/
267 static void print_header(void)
269 if (!cgi_waspost()) {
270 printf("Expires: 0\r\n");
272 printf("Content-type: text/html\r\n\r\n");
274 if (!include_html("include/header.html")) {
275 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
276 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
280 /* *******************************************************************
281 show parameter label with translated name in the following form
282 because showing original and translated label in one line looks
283 too long, and showing translated label only is unusable for
285 -------------------------------
286 HELP security [combo box][button]
288 -------------------------------
289 (capital words are translated by gettext.)
290 if no translation is available, then same form as original is
292 "i18n_translated_parm" class is used to change the color of the
293 translated parameter with CSS.
294 **************************************************************** */
295 static const char *get_parm_translated(TALLOC_CTX
*ctx
,
296 const char* pAnchor
, const char* pHelp
, const char* pLabel
)
298 const char *pTranslated
= _(pLabel
);
300 if(strcmp(pLabel
, pTranslated
) != 0) {
301 output
= talloc_asprintf(ctx
,
302 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
303 pAnchor
, pHelp
, pLabel
, pTranslated
);
306 output
= talloc_asprintf(ctx
,
307 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
308 pAnchor
, pHelp
, pLabel
);
311 /****************************************************************************
313 ****************************************************************************/
314 static void print_footer(void)
316 if (!include_html("include/footer.html")) {
317 printf("\n</BODY>\n</HTML>\n");
321 /****************************************************************************
322 display one editable parameter in a form
323 ****************************************************************************/
324 static void show_parameter(int snum
, struct parm_struct
*parm
)
328 char *utf8_s1
, *utf8_s2
;
329 size_t converted_size
;
330 TALLOC_CTX
*ctx
= talloc_stackframe();
332 if (parm
->p_class
== P_LOCAL
&& snum
>= 0) {
333 ptr
= lp_local_ptr_by_snum(snum
, parm
);
335 ptr
= lp_parm_ptr(NULL
, parm
);
338 printf("<tr><td>%s</td><td>", get_parm_translated(ctx
,
339 stripspaceupper(parm
->label
), _("Help"), parm
->label
));
340 switch (parm
->type
) {
342 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
343 make_parm_name(parm
->label
), *(char *)ptr
);
344 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
345 _("Set Default"), make_parm_name(parm
->label
),(char)(parm
->def
.cvalue
));
349 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
350 make_parm_name(parm
->label
));
351 if ((char ***)ptr
&& *(char ***)ptr
&& **(char ***)ptr
) {
352 char **list
= *(char ***)ptr
;
353 for (;*list
;list
++) {
354 /* enclose in HTML encoded quotes if the string contains a space */
355 if ( strchr_m(*list
, ' ') ) {
356 push_utf8_talloc(talloc_tos(), &utf8_s1
, *list
, &converted_size
);
357 push_utf8_talloc(talloc_tos(), &utf8_s2
, ((*(list
+1))?", ":""), &converted_size
);
358 printf(""%s"%s", utf8_s1
, utf8_s2
);
360 push_utf8_talloc(talloc_tos(), &utf8_s1
, *list
, &converted_size
);
361 push_utf8_talloc(talloc_tos(), &utf8_s2
, ((*(list
+1))?", ":""), &converted_size
);
362 printf("%s%s", utf8_s1
, utf8_s2
);
364 TALLOC_FREE(utf8_s1
);
365 TALLOC_FREE(utf8_s2
);
369 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
370 _("Set Default"), make_parm_name(parm
->label
));
371 if (parm
->def
.lvalue
) {
372 char **list
= (char **)(parm
->def
.lvalue
);
373 for (; *list
; list
++) {
374 /* enclose in HTML encoded quotes if the string contains a space */
375 if ( strchr_m(*list
, ' ') )
376 printf(""%s"%s", *list
, ((*(list
+1))?", ":""));
378 printf("%s%s", *list
, ((*(list
+1))?", ":""));
386 push_utf8_talloc(talloc_tos(), &utf8_s1
, *(char **)ptr
, &converted_size
);
387 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
388 make_parm_name(parm
->label
), fix_quotes(ctx
, utf8_s1
));
389 TALLOC_FREE(utf8_s1
);
390 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
391 _("Set Default"), make_parm_name(parm
->label
),fix_backslash((char *)(parm
->def
.svalue
)));
395 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
396 printf("<option %s>Yes", (*(bool *)ptr
)?"selected":"");
397 printf("<option %s>No", (*(bool *)ptr
)?"":"selected");
399 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
400 _("Set Default"), make_parm_name(parm
->label
),(bool)(parm
->def
.bvalue
)?0:1);
404 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
405 printf("<option %s>Yes", (*(bool *)ptr
)?"":"selected");
406 printf("<option %s>No", (*(bool *)ptr
)?"selected":"");
408 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
409 _("Set Default"), make_parm_name(parm
->label
),(bool)(parm
->def
.bvalue
)?1:0);
414 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm
->label
), *(int *)ptr
);
415 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
416 _("Set Default"), make_parm_name(parm
->label
),(int)(parm
->def
.ivalue
));
421 o
= octal_string(*(int *)ptr
);
422 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
423 make_parm_name(parm
->label
), o
);
425 o
= octal_string((int)(parm
->def
.ivalue
));
426 printf("<input type=button value=\"%s\" "
427 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
428 _("Set Default"), make_parm_name(parm
->label
), o
);
434 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
435 for (i
=0;parm
->enum_list
[i
].name
;i
++) {
436 if (i
== 0 || parm
->enum_list
[i
].value
!= parm
->enum_list
[i
-1].value
) {
437 printf("<option %s>%s",(*(int *)ptr
)==parm
->enum_list
[i
].value
?"selected":"",parm
->enum_list
[i
].name
);
441 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
442 _("Set Default"), make_parm_name(parm
->label
),enum_index((int)(parm
->def
.ivalue
),parm
->enum_list
));
447 printf("</td></tr>\n");
451 /****************************************************************************
452 display a set of parameters for a service
453 ****************************************************************************/
454 static void show_parameters(int snum
, int allparameters
, unsigned int parm_filter
, int printers
)
457 struct parm_struct
*parm
;
458 const char *heading
= NULL
;
459 const char *last_heading
= NULL
;
461 while ((parm
= lp_next_parameter(snum
, &i
, allparameters
))) {
462 if (snum
< 0 && parm
->p_class
== P_LOCAL
&& !(parm
->flags
& FLAG_GLOBAL
))
464 if (parm
->p_class
== P_SEPARATOR
) {
465 heading
= parm
->label
;
468 if (parm
->flags
& FLAG_HIDE
) continue;
470 if (printers
& !(parm
->flags
& FLAG_PRINT
)) continue;
471 if (!printers
& !(parm
->flags
& FLAG_SHARE
)) continue;
474 if (!( parm_filter
& FLAG_ADVANCED
)) {
475 if (!(parm
->flags
& FLAG_BASIC
)) {
477 if (parm
->p_class
== P_LOCAL
&& snum
>= 0) {
478 ptr
= lp_local_ptr_by_snum(snum
, parm
);
480 ptr
= lp_parm_ptr(NULL
, parm
);
483 switch (parm
->type
) {
485 if (*(char *)ptr
== (char)(parm
->def
.cvalue
)) continue;
489 if (!str_list_equal(*(const char ***)ptr
,
490 (const char **)(parm
->def
.lvalue
))) continue;
495 if (!strcmp(*(char **)ptr
,(char *)(parm
->def
.svalue
))) continue;
500 if (*(bool *)ptr
== (bool)(parm
->def
.bvalue
)) continue;
506 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
511 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
517 if (printers
&& !(parm
->flags
& FLAG_PRINT
)) continue;
520 if ((parm_filter
& FLAG_WIZARD
) && !(parm
->flags
& FLAG_WIZARD
)) continue;
522 if ((parm_filter
& FLAG_ADVANCED
) && !(parm
->flags
& FLAG_ADVANCED
)) continue;
524 if (heading
&& heading
!= last_heading
) {
525 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading
));
526 last_heading
= heading
;
528 show_parameter(snum
, parm
);
532 /****************************************************************************
533 load the smb.conf file into loadparm.
534 ****************************************************************************/
535 static bool load_config(bool save_def
)
537 return lp_load(get_dyn_CONFIGFILE(),False
,save_def
,False
,True
);
540 /****************************************************************************
542 ****************************************************************************/
543 static void write_config(FILE *f
, bool show_defaults
)
545 TALLOC_CTX
*ctx
= talloc_stackframe();
547 fprintf(f
, "# Samba config file created using SWAT\n");
548 fprintf(f
, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
549 fprintf(f
, "# Date: %s\n\n", current_timestring(ctx
, False
));
551 lp_dump(f
, show_defaults
, iNumNonAutoPrintServices
);
556 /****************************************************************************
557 save and reload the smb.conf config file
558 ****************************************************************************/
559 static int save_reload(int snum
)
564 f
= fopen(get_dyn_CONFIGFILE(),"w");
566 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
571 /* just in case they have used the buggy xinetd to create the file */
572 if (fstat(fileno(f
), &st
) == 0 &&
573 (st
.st_mode
& S_IWOTH
)) {
574 #if defined HAVE_FCHMOD
575 fchmod(fileno(f
), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
577 chmod(get_dyn_CONFIGFILE(), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
581 write_config(f
, False
);
583 lp_dump_one(f
, False
, snum
);
586 lp_kill_all_services();
588 if (!load_config(False
)) {
589 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
593 iNumNonAutoPrintServices
= lp_numservices();
594 if (pcap_cache_loaded()) {
595 struct tevent_context
*ev_ctx
;
596 struct messaging_context
*msg_ctx
;
598 ev_ctx
= s3_tevent_context_init(NULL
);
599 if (ev_ctx
== NULL
) {
600 printf("s3_tevent_context_init() failed\n");
603 msg_ctx
= messaging_init(ev_ctx
, ev_ctx
);
604 if (msg_ctx
== NULL
) {
605 printf("messaging_init() failed\n");
609 load_printers(ev_ctx
, msg_ctx
);
617 /****************************************************************************
619 ****************************************************************************/
620 static void commit_parameter(int snum
, struct parm_struct
*parm
, const char *v
)
625 if (snum
< 0 && parm
->p_class
== P_LOCAL
) {
626 /* this handles the case where we are changing a local
627 variable globally. We need to change the parameter in
628 all shares where it is currently set to the default */
629 for (i
=0;i
<lp_numservices();i
++) {
630 s
= lp_servicename(i
);
631 if (s
&& (*s
) && lp_is_default(i
, parm
)) {
632 lp_do_parameter(i
, parm
->label
, v
);
637 lp_do_parameter(snum
, parm
->label
, v
);
640 /****************************************************************************
641 commit a set of parameters for a service
642 ****************************************************************************/
643 static void commit_parameters(int snum
)
646 struct parm_struct
*parm
;
650 while ((parm
= lp_next_parameter(snum
, &i
, 1))) {
651 if (asprintf(&label
, "parm_%s", make_parm_name(parm
->label
)) > 0) {
652 if ((v
= cgi_variable(label
)) != NULL
) {
653 if (parm
->flags
& FLAG_HIDE
)
655 commit_parameter(snum
, parm
, v
);
662 /****************************************************************************
663 spit out the html for a link with an image
664 ****************************************************************************/
665 static void image_link(const char *name
, const char *hlink
, const char *src
)
667 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
668 cgi_baseurl(), hlink
, src
, name
);
671 /****************************************************************************
672 display the main navigation controls at the top of each page along
674 ****************************************************************************/
675 static void show_main_buttons(void)
679 if ((p
= cgi_user_name()) && strcmp(p
, "root")) {
680 printf(_("Logged in as <b>%s</b>"), p
);
684 image_link(_("Home"), "", "images/home.gif");
685 if (have_write_access
) {
686 image_link(_("Globals"), "globals", "images/globals.gif");
687 image_link(_("Shares"), "shares", "images/shares.gif");
688 image_link(_("Printers"), "printers", "images/printers.gif");
689 image_link(_("Wizard"), "wizard", "images/wizard.gif");
691 /* root always gets all buttons, otherwise look for -P */
692 if ( have_write_access
|| (!passwd_only
&& have_read_access
) ) {
693 image_link(_("Status"), "status", "images/status.gif");
694 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
696 image_link(_("Password Management"), "passwd", "images/passwd.gif");
701 /****************************************************************************
702 * Handle Display/Edit Mode CGI
703 ****************************************************************************/
704 static void ViewModeBoxes(int mode
)
706 printf("<p>%s: \n", _("Current View Is"));
707 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode
== 0) ? "checked" : ""), _("Basic"));
708 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode
== 1) ? "checked" : ""), _("Advanced"));
709 printf("<br>%s: \n", _("Change View To"));
710 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
711 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
712 printf("</p><br>\n");
715 /****************************************************************************
716 display a welcome page
717 ****************************************************************************/
718 static void welcome_page(void)
720 if (file_exist("help/welcome.html")) {
721 include_html("help/welcome.html");
723 include_html("help/welcome-no-samba-doc.html");
727 /****************************************************************************
728 display the current smb.conf
729 ****************************************************************************/
730 static void viewconfig_page(void)
733 const char form_name
[] = "viewconfig";
735 if (!verify_xsrf_token(form_name
)) {
739 if (cgi_variable("full_view")) {
744 printf("<H2>%s</H2>\n", _("Current Config"));
745 printf("<form method=post>\n");
746 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
749 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
751 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
755 write_config(stdout
, full_view
);
760 /****************************************************************************
761 second screen of the wizard ... Fetch Configuration Parameters
762 ****************************************************************************/
763 static void wizard_params_page(void)
765 unsigned int parm_filter
= FLAG_WIZARD
;
766 const char form_name
[] = "wizard_params";
768 /* Here we first set and commit all the parameters that were selected
769 in the previous screen. */
771 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
773 if (!verify_xsrf_token(form_name
)) {
777 if (cgi_variable("Commit")) {
778 commit_parameters(GLOBAL_SECTION_SNUM
);
783 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
784 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
786 if (have_write_access
) {
787 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
790 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
794 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
795 printf("</table>\n");
799 /****************************************************************************
800 Utility to just rewrite the smb.conf file - effectively just cleans it up
801 ****************************************************************************/
802 static void rewritecfg_file(void)
804 commit_parameters(GLOBAL_SECTION_SNUM
);
806 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
809 /****************************************************************************
810 wizard to create/modify the smb.conf file
811 ****************************************************************************/
812 static void wizard_page(void)
814 /* Set some variables to collect data from smb.conf */
820 const char form_name
[] = "wizard";
822 if (!verify_xsrf_token(form_name
)) {
826 if (cgi_variable("Rewrite")) {
827 (void) rewritecfg_file();
831 if (cgi_variable("GetWizardParams")){
832 (void) wizard_params_page();
836 if (cgi_variable("Commit")){
837 SerType
= atoi(cgi_variable_nonull("ServerType"));
838 winstype
= atoi(cgi_variable_nonull("WINSType"));
839 have_home
= lp_servicenumber(HOMES_NAME
);
840 HomeExpo
= atoi(cgi_variable_nonull("HomeExpo"));
842 /* Plain text passwords are too badly broken - use encrypted passwords only */
843 lp_do_parameter( GLOBAL_SECTION_SNUM
, "encrypt passwords", "Yes");
847 /* Stand-alone Server */
848 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
849 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
853 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "DOMAIN" );
854 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
857 /* Domain Controller */
858 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
859 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "Yes" );
862 switch ( winstype
) {
864 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
865 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
868 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "Yes" );
869 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
872 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
873 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", cgi_variable_nonull("WINSAddr"));
877 /* Have to create Homes share? */
878 if ((HomeExpo
== 1) && (have_home
== -1)) {
879 const char *unix_share
= HOMES_NAME
;
882 lp_copy_service(GLOBAL_SECTION_SNUM
, unix_share
);
883 have_home
= lp_servicenumber(HOMES_NAME
);
884 lp_do_parameter( have_home
, "read only", "No");
885 lp_do_parameter( have_home
, "valid users", "%S");
886 lp_do_parameter( have_home
, "browseable", "No");
887 commit_parameters(have_home
);
888 save_reload(have_home
);
891 /* Need to Delete Homes share? */
892 if ((HomeExpo
== 0) && (have_home
!= -1)) {
893 lp_remove_service(have_home
);
897 commit_parameters(GLOBAL_SECTION_SNUM
);
902 /* Now determine smb.conf WINS settings */
903 if (lp_we_are_a_wins_server())
905 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
908 /* Do we have a homes share? */
909 have_home
= lp_servicenumber(HOMES_NAME
);
911 if ((winstype
== 2) && lp_we_are_a_wins_server())
914 role
= lp_server_role();
918 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
919 printf("<form method=post action=wizard>\n");
920 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
922 if (have_write_access
) {
923 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
924 printf("%s", _("The same will happen if you press the commit button."));
925 printf("<br><br>\n");
927 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
928 printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
929 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
930 printf("</center>\n");
934 printf("<center><table border=0>");
935 printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
936 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role
== ROLE_STANDALONE
) ? "checked" : ""), _("Stand Alone"));
937 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role
== ROLE_DOMAIN_MEMBER
) ? "checked" : ""), _("Domain Member"));
938 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role
== ROLE_DOMAIN_PDC
) ? "checked" : ""), _("Domain Controller"));
940 if (role
== ROLE_DOMAIN_BDC
) {
941 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
943 printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
944 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype
== 0) ? "checked" : ""), _("Not Used"));
945 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype
== 1) ? "checked" : ""), _("Server for client use"));
946 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype
== 2) ? "checked" : ""), _("Client of another WINS server"));
948 printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
950 /* Print out the list of wins servers */
951 if(lp_wins_server_list()) {
953 const char **wins_servers
= lp_wins_server_list();
954 for(i
= 0; wins_servers
[i
]; i
++) printf("%s ", wins_servers
[i
]);
957 printf("\"></td></tr>\n");
959 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"));
960 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
962 printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
963 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home
== -1) ? "" : "checked ");
964 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home
== -1 ) ? "checked" : "");
965 printf("<td></td></tr>\n");
967 /* Enable this when we are ready ....
968 * printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
969 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
970 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
971 * printf("<td></td></tr>\n");
974 printf("</table></center>");
977 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
982 /****************************************************************************
983 display a globals editing page
984 ****************************************************************************/
985 static void globals_page(void)
987 unsigned int parm_filter
= FLAG_BASIC
;
989 const char form_name
[] = "globals";
991 printf("<H2>%s</H2>\n", _("Global Parameters"));
993 if (!verify_xsrf_token(form_name
)) {
997 if (cgi_variable("Commit")) {
998 commit_parameters(GLOBAL_SECTION_SNUM
);
1002 if ( cgi_variable("ViewMode") )
1003 mode
= atoi(cgi_variable_nonull("ViewMode"));
1004 if ( cgi_variable("BasicMode"))
1006 if ( cgi_variable("AdvMode"))
1010 printf("<form name=\"swatform\" method=post action=globals>\n");
1011 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
1013 ViewModeBoxes( mode
);
1016 parm_filter
= FLAG_BASIC
;
1019 parm_filter
= FLAG_ADVANCED
;
1023 if (have_write_access
) {
1024 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
1025 _("Commit Changes"));
1028 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
1032 printf("<table>\n");
1033 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
1034 printf("</table>\n");
1035 printf("</form>\n");
1038 /****************************************************************************
1039 display a shares editing page. share is in unix codepage,
1040 ****************************************************************************/
1041 static void shares_page(void)
1043 const char *share
= cgi_variable("share");
1049 unsigned int parm_filter
= FLAG_BASIC
;
1050 size_t converted_size
;
1051 const char form_name
[] = "shares";
1053 printf("<H2>%s</H2>\n", _("Share Parameters"));
1055 if (!verify_xsrf_token(form_name
)) {
1060 snum
= lp_servicenumber(share
);
1063 if (cgi_variable("Commit") && snum
>= 0) {
1064 commit_parameters(snum
);
1066 snum
= lp_servicenumber(share
);
1069 if (cgi_variable("Delete") && snum
>= 0) {
1070 lp_remove_service(snum
);
1076 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
1077 snum
= lp_servicenumber(share
);
1080 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
1081 snum
= lp_servicenumber(share
);
1083 snum
= lp_servicenumber(share
);
1087 if ( cgi_variable("ViewMode") )
1088 mode
= atoi(cgi_variable_nonull("ViewMode"));
1089 if ( cgi_variable("BasicMode"))
1091 if ( cgi_variable("AdvMode"))
1095 printf("<FORM name=\"swatform\" method=post>\n");
1096 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
1098 printf("<table>\n");
1100 ViewModeBoxes( mode
);
1103 parm_filter
= FLAG_BASIC
;
1106 parm_filter
= FLAG_ADVANCED
;
1109 printf("<br><tr>\n");
1110 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1111 printf("<td><select name=share>\n");
1113 printf("<option value=\" \"> \n");
1114 for (i
=0;i
<lp_numservices();i
++) {
1115 s
= lp_servicename(i
);
1116 if (s
&& (*s
) && strcmp(s
,"IPC$") && !lp_print_ok(i
)) {
1117 push_utf8_talloc(talloc_tos(), &utf8_s
, s
, &converted_size
);
1118 printf("<option %s value=\"%s\">%s\n",
1119 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1121 TALLOC_FREE(utf8_s
);
1124 printf("</select></td>\n");
1125 if (have_write_access
) {
1126 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1131 if (have_write_access
) {
1133 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1134 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1140 if (have_write_access
) {
1141 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1144 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1149 printf("<table>\n");
1150 show_parameters(snum
, 1, parm_filter
, 0);
1151 printf("</table>\n");
1154 printf("</FORM>\n");
1157 /*************************************************************
1158 change a password either locally or remotely
1159 *************************************************************/
1160 static bool change_password(const char *remote_machine
, const char *user_name
,
1161 const char *old_passwd
, const char *new_passwd
,
1165 char *err_str
= NULL
;
1166 char *msg_str
= NULL
;
1169 printf("%s\n<p>", _("password change in demo mode rejected"));
1173 if (remote_machine
!= NULL
) {
1174 ret
= remote_password_change(remote_machine
, user_name
,
1175 old_passwd
, new_passwd
, &err_str
);
1176 if (err_str
!= NULL
)
1177 printf("%s\n<p>", err_str
);
1179 return NT_STATUS_IS_OK(ret
);
1182 if(!initialize_password_db(True
, NULL
)) {
1183 printf("%s\n<p>", _("Can't setup password database vectors."));
1187 ret
= local_password_change(user_name
, local_flags
, new_passwd
,
1188 &err_str
, &msg_str
);
1191 printf("%s\n<p>", msg_str
);
1193 printf("%s\n<p>", err_str
);
1197 return NT_STATUS_IS_OK(ret
);
1200 /****************************************************************************
1201 do the stuff required to add or change a password
1202 ****************************************************************************/
1203 static void chg_passwd(void)
1207 int local_flags
= 0;
1209 /* Make sure users name has been specified */
1210 if (strlen(cgi_variable_nonull(SWAT_USER
)) == 0) {
1211 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1216 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1217 * so if that's what we're doing, skip the rest of the checks
1219 if (!cgi_variable(DISABLE_USER_FLAG
) && !cgi_variable(ENABLE_USER_FLAG
) && !cgi_variable(DELETE_USER_FLAG
)) {
1222 * If current user is not root, make sure old password has been specified
1223 * If REMOTE change, even root must provide old password
1225 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0)) ||
1226 ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0))) {
1227 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1231 /* If changing a users password on a remote hosts we have to know what host */
1232 if ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(RHOST
)) <= 0)) {
1233 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1237 /* Make sure new passwords have been specified */
1238 if ((strlen( cgi_variable_nonull(NEW_PSWD
)) <= 0) ||
1239 (strlen( cgi_variable_nonull(NEW2_PSWD
)) <= 0)) {
1240 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1244 /* Make sure new passwords was typed correctly twice */
1245 if (strcmp(cgi_variable_nonull(NEW_PSWD
), cgi_variable_nonull(NEW2_PSWD
)) != 0) {
1246 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1251 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1252 host
= cgi_variable(RHOST
);
1253 } else if (am_root()) {
1260 * Set up the local flags.
1263 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_ADD_USER
: 0);
1264 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1265 local_flags
|= (cgi_variable(CHG_S_PASSWD_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1266 local_flags
|= (cgi_variable(DELETE_USER_FLAG
) ? LOCAL_DELETE_USER
: 0);
1267 local_flags
|= (cgi_variable(ENABLE_USER_FLAG
) ? LOCAL_ENABLE_USER
: 0);
1268 local_flags
|= (cgi_variable(DISABLE_USER_FLAG
) ? LOCAL_DISABLE_USER
: 0);
1270 rslt
= change_password(host
,
1271 cgi_variable_nonull(SWAT_USER
),
1272 cgi_variable_nonull(OLD_PSWD
), cgi_variable_nonull(NEW_PSWD
),
1275 if(cgi_variable(CHG_S_PASSWD_FLAG
)) {
1278 printf("%s\n", _(" The passwd has been changed."));
1280 printf("%s\n", _(" The passwd has NOT been changed."));
1287 /****************************************************************************
1288 display a password editing page
1289 ****************************************************************************/
1290 static void passwd_page(void)
1292 const char *new_name
= cgi_user_name();
1293 const char passwd_form
[] = "passwd";
1294 const char rpasswd_form
[] = "rpasswd";
1296 if (!new_name
) new_name
= "";
1298 printf("<H2>%s</H2>\n", _("Server Password Management"));
1300 printf("<FORM name=\"swatform\" method=post>\n");
1301 print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form
);
1303 printf("<table>\n");
1306 * Create all the dialog boxes for data collection
1308 printf("<tr><td> %s : </td>\n", _("User Name"));
1309 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER
, new_name
);
1311 printf("<tr><td> %s : </td>\n", _("Old Password"));
1312 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD
);
1314 printf("<tr><td> %s : </td>\n", _("New Password"));
1315 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1316 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1317 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1318 printf("</table>\n");
1321 * Create all the control buttons for requesting action
1323 printf("<input type=submit name=%s value=\"%s\">\n",
1324 CHG_S_PASSWD_FLAG
, _("Change Password"));
1325 if (demo_mode
|| am_root()) {
1326 printf("<input type=submit name=%s value=\"%s\">\n",
1327 ADD_USER_FLAG
, _("Add New User"));
1328 printf("<input type=submit name=%s value=\"%s\">\n",
1329 DELETE_USER_FLAG
, _("Delete User"));
1330 printf("<input type=submit name=%s value=\"%s\">\n",
1331 DISABLE_USER_FLAG
, _("Disable User"));
1332 printf("<input type=submit name=%s value=\"%s\">\n",
1333 ENABLE_USER_FLAG
, _("Enable User"));
1335 printf("<p></FORM>\n");
1338 * Do some work if change, add, disable or enable was
1339 * requested. It could be this is the first time through this
1340 * code, so there isn't anything to do. */
1341 if (verify_xsrf_token(passwd_form
) &&
1342 ((cgi_variable(CHG_S_PASSWD_FLAG
)) || (cgi_variable(ADD_USER_FLAG
)) || (cgi_variable(DELETE_USER_FLAG
)) ||
1343 (cgi_variable(DISABLE_USER_FLAG
)) || (cgi_variable(ENABLE_USER_FLAG
)))) {
1347 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1349 printf("<FORM name=\"swatform\" method=post>\n");
1350 print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form
);
1352 printf("<table>\n");
1355 * Create all the dialog boxes for data collection
1357 printf("<tr><td> %s : </td>\n", _("User Name"));
1358 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER
, new_name
);
1359 printf("<tr><td> %s : </td>\n", _("Old Password"));
1360 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD
);
1361 printf("<tr><td> %s : </td>\n", _("New Password"));
1362 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1363 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1364 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1365 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1366 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST
);
1371 * Create all the control buttons for requesting action
1373 printf("<input type=submit name=%s value=\"%s\">",
1374 CHG_R_PASSWD_FLAG
, _("Change Password"));
1376 printf("<p></FORM>\n");
1379 * Do some work if a request has been made to change the
1380 * password somewhere other than the server. It could be this
1381 * is the first time through this code, so there isn't
1382 * anything to do. */
1383 if (verify_xsrf_token(passwd_form
) && cgi_variable(CHG_R_PASSWD_FLAG
)) {
1389 /****************************************************************************
1390 display a printers editing page
1391 ****************************************************************************/
1392 static void printers_page(void)
1394 const char *share
= cgi_variable("share");
1399 unsigned int parm_filter
= FLAG_BASIC
;
1400 const char form_name
[] = "printers";
1402 if (!verify_xsrf_token(form_name
)) {
1407 snum
= lp_servicenumber(share
);
1409 if (cgi_variable("Commit") && snum
>= 0) {
1410 commit_parameters(snum
);
1411 if (snum
>= iNumNonAutoPrintServices
)
1415 snum
= lp_servicenumber(share
);
1418 if (cgi_variable("Delete") && snum
>= 0) {
1419 lp_remove_service(snum
);
1425 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
1426 snum
= lp_servicenumber(share
);
1427 if (snum
< 0 || snum
>= iNumNonAutoPrintServices
) {
1429 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
1430 snum
= lp_servicenumber(share
);
1431 lp_do_parameter(snum
, "print ok", "Yes");
1433 snum
= lp_servicenumber(share
);
1437 if ( cgi_variable("ViewMode") )
1438 mode
= atoi(cgi_variable_nonull("ViewMode"));
1439 if ( cgi_variable("BasicMode"))
1441 if ( cgi_variable("AdvMode"))
1445 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1447 printf("<H3>%s</H3>\n", _("Important Note:"));
1448 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1449 printf("%s",_("are autoloaded printers from "));
1450 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1451 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1454 printf("<FORM name=\"swatform\" method=post>\n");
1455 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
1457 ViewModeBoxes( mode
);
1460 parm_filter
= FLAG_BASIC
;
1463 parm_filter
= FLAG_ADVANCED
;
1466 printf("<table>\n");
1467 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1468 printf("<td><select name=\"share\">\n");
1469 if (snum
< 0 || !lp_print_ok(snum
))
1470 printf("<option value=\" \"> \n");
1471 for (i
=0;i
<lp_numservices();i
++) {
1472 s
= lp_servicename(i
);
1473 if (s
&& (*s
) && strcmp(s
,"IPC$") && lp_print_ok(i
)) {
1474 if (i
>= iNumNonAutoPrintServices
)
1475 printf("<option %s value=\"%s\">[*]%s\n",
1476 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1479 printf("<option %s value=\"%s\">%s\n",
1480 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1484 printf("</select></td>");
1485 if (have_write_access
) {
1486 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1489 printf("</table>\n");
1491 if (have_write_access
) {
1492 printf("<table>\n");
1493 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1494 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1500 if (have_write_access
) {
1501 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1503 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1508 printf("<table>\n");
1509 show_parameters(snum
, 1, parm_filter
, 1);
1510 printf("</table>\n");
1512 printf("</FORM>\n");
1516 when the _() translation macro is used there is no obvious place to free
1517 the resulting string and there is no easy way to give a static pointer.
1518 All we can do is rotate between some static buffers and hope a single d_printf()
1519 doesn't have more calls to _() than the number of buffers
1522 const char *lang_msg_rotate(TALLOC_CTX
*ctx
, const char *msgid
)
1527 msgstr
= lang_msg(msgid
);
1532 ret
= talloc_strdup(ctx
, msgstr
);
1534 lang_msg_free(msgstr
);
1543 * main function for SWAT.
1545 int main(int argc
, char *argv
[])
1549 struct poptOption long_options
[] = {
1551 { "disable-authentication", 'a', POPT_ARG_VAL
, &demo_mode
, True
, "Disable authentication (demo mode)" },
1552 { "password-menu-only", 'P', POPT_ARG_VAL
, &passwd_only
, True
, "Show only change password menu" },
1556 TALLOC_CTX
*frame
= talloc_stackframe();
1559 umask(S_IWGRP
| S_IWOTH
);
1561 #if defined(HAVE_SET_AUTH_PARAMETERS)
1562 set_auth_parameters(argc
, argv
);
1563 #endif /* HAVE_SET_AUTH_PARAMETERS */
1565 /* just in case it goes wild ... */
1570 /* we don't want any SIGPIPE messages */
1571 BlockSignals(True
,SIGPIPE
);
1573 debug_set_logfile("/dev/null");
1575 /* we don't want stderr screwing us up */
1577 open("/dev/null", O_WRONLY
);
1578 setup_logging("swat", DEBUG_FILE
);
1582 pc
= poptGetContext("swat", argc
, (const char **) argv
, long_options
, 0);
1584 /* Parse command line options */
1586 while(poptGetNextOpt(pc
) != -1) { }
1588 poptFreeContext(pc
);
1590 /* This should set a more apporiate log file */
1594 iNumNonAutoPrintServices
= lp_numservices();
1595 if (pcap_cache_loaded()) {
1596 struct tevent_context
*ev_ctx
;
1597 struct messaging_context
*msg_ctx
;
1599 ev_ctx
= s3_tevent_context_init(NULL
);
1600 if (ev_ctx
== NULL
) {
1601 printf("s3_tevent_context_init() failed\n");
1604 msg_ctx
= messaging_init(ev_ctx
, ev_ctx
);
1605 if (msg_ctx
== NULL
) {
1606 printf("messaging_init() failed\n");
1610 load_printers(ev_ctx
, msg_ctx
);
1612 talloc_free(ev_ctx
);
1615 cgi_setup(get_dyn_SWATDIR(), !demo_mode
);
1619 cgi_load_variables();
1621 if (!file_exist(get_dyn_CONFIGFILE())) {
1622 have_read_access
= True
;
1623 have_write_access
= True
;
1625 /* check if the authenticated user has write access - if not then
1626 don't show write options */
1627 have_write_access
= (access(get_dyn_CONFIGFILE(),W_OK
) == 0);
1629 /* if the user doesn't have read access to smb.conf then
1630 don't let them view it */
1631 have_read_access
= (access(get_dyn_CONFIGFILE(),R_OK
) == 0);
1634 show_main_buttons();
1636 page
= cgi_pathinfo();
1638 /* Root gets full functionality */
1639 if (have_read_access
&& strcmp(page
, "globals")==0) {
1641 } else if (have_read_access
&& strcmp(page
,"shares")==0) {
1643 } else if (have_read_access
&& strcmp(page
,"printers")==0) {
1645 } else if (have_read_access
&& strcmp(page
,"status")==0) {
1647 } else if (have_read_access
&& strcmp(page
,"viewconfig")==0) {
1649 } else if (strcmp(page
,"passwd")==0) {
1651 } else if (have_read_access
&& strcmp(page
,"wizard")==0) {
1653 } else if (have_read_access
&& strcmp(page
,"wizard_params")==0) {
1654 wizard_params_page();
1655 } else if (have_read_access
&& strcmp(page
,"rewritecfg")==0) {