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
;
159 char *nonce
= cgi_nonce();
162 ZERO_STRUCT(md5_ctx
);
165 MD5Update(&md5_ctx
, (uint8_t *)formname
, strlen(formname
));
166 MD5Update(&md5_ctx
, (uint8_t *)&xsrf_time
, sizeof(time_t));
167 if (username
!= NULL
) {
168 MD5Update(&md5_ctx
, (uint8_t *)username
, strlen(username
));
171 MD5Update(&md5_ctx
, (uint8_t *)pass
, strlen(pass
));
173 MD5Update(&md5_ctx
, (uint8_t *)nonce
, strlen(nonce
));
175 MD5Final(token
, &md5_ctx
);
177 for(i
= 0; i
< sizeof(token
); i
++) {
180 snprintf(tmp
, sizeof(tmp
), "%02x", token
[i
]);
181 /* FIXME ! Truncate check. JRA. */
182 (void)strlcat(token_str
, tmp
, sizeof(tmp
));
186 void print_xsrf_token(const char *username
, const char *pass
,
187 const char *formname
)
190 time_t xsrf_time
= time(NULL
);
192 get_xsrf_token(username
, pass
, formname
, xsrf_time
, token
);
193 printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
195 printf("<input type=\"hidden\" name=\"%s\" value=\"%lld\">\n",
196 XSRF_TIME
, (long long int)xsrf_time
);
199 bool verify_xsrf_token(const char *formname
)
202 const char *username
= cgi_user_name();
203 const char *pass
= cgi_user_pass();
204 const char *token
= cgi_variable_nonull(XSRF_TOKEN
);
205 const char *time_str
= cgi_variable_nonull(XSRF_TIME
);
207 long long xsrf_time_ll
= 0;
208 time_t xsrf_time
= 0;
209 time_t now
= time(NULL
);
212 xsrf_time_ll
= strtoll(time_str
, &p
, 10);
219 if (PTR_DIFF(p
, time_str
) > strlen(time_str
)) {
222 if (xsrf_time_ll
> _TYPE_MAXIMUM(time_t)) {
225 if (xsrf_time_ll
< _TYPE_MINIMUM(time_t)) {
228 xsrf_time
= xsrf_time_ll
;
230 if (abs(now
- xsrf_time
) > XSRF_TIMEOUT
) {
234 get_xsrf_token(username
, pass
, formname
, xsrf_time
, expected
);
235 return (strncmp(expected
, token
, sizeof(expected
)) == 0);
239 /****************************************************************************
240 include a lump of html in a page
241 ****************************************************************************/
242 static int include_html(const char *fname
)
248 fd
= web_open(fname
, O_RDONLY
, 0);
251 printf(_("ERROR: Can't open %s"), fname
);
256 while ((ret
= read(fd
, buf
, sizeof(buf
))) > 0) {
257 if (write(1, buf
, ret
) == -1) {
266 /****************************************************************************
267 start the page with standard stuff
268 ****************************************************************************/
269 static void print_header(void)
271 if (!cgi_waspost()) {
272 printf("Expires: 0\r\n");
274 printf("Content-type: text/html\r\n");
275 printf("X-Frame-Options: DENY\r\n\r\n");
277 if (!include_html("include/header.html")) {
278 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
279 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
283 /* *******************************************************************
284 show parameter label with translated name in the following form
285 because showing original and translated label in one line looks
286 too long, and showing translated label only is unusable for
288 -------------------------------
289 HELP security [combo box][button]
291 -------------------------------
292 (capital words are translated by gettext.)
293 if no translation is available, then same form as original is
295 "i18n_translated_parm" class is used to change the color of the
296 translated parameter with CSS.
297 **************************************************************** */
298 static const char *get_parm_translated(TALLOC_CTX
*ctx
,
299 const char* pAnchor
, const char* pHelp
, const char* pLabel
)
301 const char *pTranslated
= _(pLabel
);
303 if(strcmp(pLabel
, pTranslated
) != 0) {
304 output
= talloc_asprintf(ctx
,
305 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
306 pAnchor
, pHelp
, pLabel
, pTranslated
);
309 output
= talloc_asprintf(ctx
,
310 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
311 pAnchor
, pHelp
, pLabel
);
314 /****************************************************************************
316 ****************************************************************************/
317 static void print_footer(void)
319 if (!include_html("include/footer.html")) {
320 printf("\n</BODY>\n</HTML>\n");
324 /****************************************************************************
325 display one editable parameter in a form
326 ****************************************************************************/
327 static void show_parameter(int snum
, struct parm_struct
*parm
)
331 char *utf8_s1
, *utf8_s2
;
332 size_t converted_size
;
333 TALLOC_CTX
*ctx
= talloc_stackframe();
335 if (parm
->p_class
== P_LOCAL
&& snum
>= 0) {
336 ptr
= lp_local_ptr_by_snum(snum
, parm
);
338 ptr
= lp_parm_ptr(NULL
, parm
);
341 printf("<tr><td>%s</td><td>", get_parm_translated(ctx
,
342 stripspaceupper(parm
->label
), _("Help"), parm
->label
));
343 switch (parm
->type
) {
345 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
346 make_parm_name(parm
->label
), *(char *)ptr
);
347 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
348 _("Set Default"), make_parm_name(parm
->label
),(char)(parm
->def
.cvalue
));
352 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
353 make_parm_name(parm
->label
));
354 if ((char ***)ptr
&& *(char ***)ptr
&& **(char ***)ptr
) {
355 char **list
= *(char ***)ptr
;
356 for (;*list
;list
++) {
357 /* enclose in HTML encoded quotes if the string contains a space */
358 if ( strchr_m(*list
, ' ') ) {
359 push_utf8_talloc(talloc_tos(), &utf8_s1
, *list
, &converted_size
);
360 push_utf8_talloc(talloc_tos(), &utf8_s2
, ((*(list
+1))?", ":""), &converted_size
);
361 printf(""%s"%s", utf8_s1
, utf8_s2
);
363 push_utf8_talloc(talloc_tos(), &utf8_s1
, *list
, &converted_size
);
364 push_utf8_talloc(talloc_tos(), &utf8_s2
, ((*(list
+1))?", ":""), &converted_size
);
365 printf("%s%s", utf8_s1
, utf8_s2
);
367 TALLOC_FREE(utf8_s1
);
368 TALLOC_FREE(utf8_s2
);
372 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
373 _("Set Default"), make_parm_name(parm
->label
));
374 if (parm
->def
.lvalue
) {
375 char **list
= (char **)(parm
->def
.lvalue
);
376 for (; *list
; list
++) {
377 /* enclose in HTML encoded quotes if the string contains a space */
378 if ( strchr_m(*list
, ' ') )
379 printf(""%s"%s", *list
, ((*(list
+1))?", ":""));
381 printf("%s%s", *list
, ((*(list
+1))?", ":""));
389 push_utf8_talloc(talloc_tos(), &utf8_s1
, *(char **)ptr
, &converted_size
);
390 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
391 make_parm_name(parm
->label
), fix_quotes(ctx
, utf8_s1
));
392 TALLOC_FREE(utf8_s1
);
393 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
394 _("Set Default"), make_parm_name(parm
->label
),fix_backslash((char *)(parm
->def
.svalue
)));
398 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
399 printf("<option %s>Yes", (*(bool *)ptr
)?"selected":"");
400 printf("<option %s>No", (*(bool *)ptr
)?"":"selected");
402 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
403 _("Set Default"), make_parm_name(parm
->label
),(bool)(parm
->def
.bvalue
)?0:1);
407 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
408 printf("<option %s>Yes", (*(bool *)ptr
)?"":"selected");
409 printf("<option %s>No", (*(bool *)ptr
)?"selected":"");
411 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
412 _("Set Default"), make_parm_name(parm
->label
),(bool)(parm
->def
.bvalue
)?1:0);
417 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm
->label
), *(int *)ptr
);
418 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
419 _("Set Default"), make_parm_name(parm
->label
),(int)(parm
->def
.ivalue
));
424 o
= octal_string(*(int *)ptr
);
425 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
426 make_parm_name(parm
->label
), o
);
428 o
= octal_string((int)(parm
->def
.ivalue
));
429 printf("<input type=button value=\"%s\" "
430 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
431 _("Set Default"), make_parm_name(parm
->label
), o
);
437 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
438 for (i
=0;parm
->enum_list
[i
].name
;i
++) {
439 if (i
== 0 || parm
->enum_list
[i
].value
!= parm
->enum_list
[i
-1].value
) {
440 printf("<option %s>%s",(*(int *)ptr
)==parm
->enum_list
[i
].value
?"selected":"",parm
->enum_list
[i
].name
);
444 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
445 _("Set Default"), make_parm_name(parm
->label
),enum_index((int)(parm
->def
.ivalue
),parm
->enum_list
));
450 printf("</td></tr>\n");
454 /****************************************************************************
455 display a set of parameters for a service
456 ****************************************************************************/
457 static void show_parameters(int snum
, int allparameters
, unsigned int parm_filter
, int printers
)
460 struct parm_struct
*parm
;
461 const char *heading
= NULL
;
462 const char *last_heading
= NULL
;
464 while ((parm
= lp_next_parameter(snum
, &i
, allparameters
))) {
465 if (snum
< 0 && parm
->p_class
== P_LOCAL
&& !(parm
->flags
& FLAG_GLOBAL
))
467 if (parm
->p_class
== P_SEPARATOR
) {
468 heading
= parm
->label
;
471 if (parm
->flags
& FLAG_HIDE
) continue;
473 if (printers
& !(parm
->flags
& FLAG_PRINT
)) continue;
474 if (!printers
& !(parm
->flags
& FLAG_SHARE
)) continue;
477 if (!( parm_filter
& FLAG_ADVANCED
)) {
478 if (!(parm
->flags
& FLAG_BASIC
)) {
480 if (parm
->p_class
== P_LOCAL
&& snum
>= 0) {
481 ptr
= lp_local_ptr_by_snum(snum
, parm
);
483 ptr
= lp_parm_ptr(NULL
, parm
);
486 switch (parm
->type
) {
488 if (*(char *)ptr
== (char)(parm
->def
.cvalue
)) continue;
492 if (!str_list_equal(*(const char ***)ptr
,
493 (const char **)(parm
->def
.lvalue
))) continue;
498 if (!strcmp(*(char **)ptr
,(char *)(parm
->def
.svalue
))) continue;
503 if (*(bool *)ptr
== (bool)(parm
->def
.bvalue
)) continue;
509 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
514 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
520 if (printers
&& !(parm
->flags
& FLAG_PRINT
)) continue;
523 if ((parm_filter
& FLAG_WIZARD
) && !(parm
->flags
& FLAG_WIZARD
)) continue;
525 if ((parm_filter
& FLAG_ADVANCED
) && !(parm
->flags
& FLAG_ADVANCED
)) continue;
527 if (heading
&& heading
!= last_heading
) {
528 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading
));
529 last_heading
= heading
;
531 show_parameter(snum
, parm
);
535 /****************************************************************************
536 load the smb.conf file into loadparm.
537 ****************************************************************************/
538 static bool load_config(bool save_def
)
540 return lp_load(get_dyn_CONFIGFILE(),False
,save_def
,False
,True
);
543 /****************************************************************************
545 ****************************************************************************/
546 static void write_config(FILE *f
, bool show_defaults
)
548 TALLOC_CTX
*ctx
= talloc_stackframe();
550 fprintf(f
, "# Samba config file created using SWAT\n");
551 fprintf(f
, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
552 fprintf(f
, "# Date: %s\n\n", current_timestring(ctx
, False
));
554 lp_dump(f
, show_defaults
, iNumNonAutoPrintServices
);
559 /****************************************************************************
560 save and reload the smb.conf config file
561 ****************************************************************************/
562 static int save_reload(int snum
)
567 f
= fopen(get_dyn_CONFIGFILE(),"w");
569 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
574 /* just in case they have used the buggy xinetd to create the file */
575 if (fstat(fileno(f
), &st
) == 0 &&
576 (st
.st_mode
& S_IWOTH
)) {
577 #if defined HAVE_FCHMOD
578 fchmod(fileno(f
), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
580 chmod(get_dyn_CONFIGFILE(), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
584 write_config(f
, False
);
586 lp_dump_one(f
, False
, snum
);
589 lp_kill_all_services();
591 if (!load_config(False
)) {
592 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
596 iNumNonAutoPrintServices
= lp_numservices();
597 if (pcap_cache_loaded()) {
598 struct tevent_context
*ev_ctx
;
599 struct messaging_context
*msg_ctx
;
601 ev_ctx
= s3_tevent_context_init(NULL
);
602 if (ev_ctx
== NULL
) {
603 printf("s3_tevent_context_init() failed\n");
606 msg_ctx
= messaging_init(ev_ctx
, ev_ctx
);
607 if (msg_ctx
== NULL
) {
608 printf("messaging_init() failed\n");
612 load_printers(ev_ctx
, msg_ctx
);
620 /****************************************************************************
622 ****************************************************************************/
623 static void commit_parameter(int snum
, struct parm_struct
*parm
, const char *v
)
628 if (snum
< 0 && parm
->p_class
== P_LOCAL
) {
629 /* this handles the case where we are changing a local
630 variable globally. We need to change the parameter in
631 all shares where it is currently set to the default */
632 for (i
=0;i
<lp_numservices();i
++) {
633 s
= lp_servicename(talloc_tos(), i
);
634 if (s
&& (*s
) && lp_is_default(i
, parm
)) {
635 lp_do_parameter(i
, parm
->label
, v
);
640 lp_do_parameter(snum
, parm
->label
, v
);
643 /****************************************************************************
644 commit a set of parameters for a service
645 ****************************************************************************/
646 static void commit_parameters(int snum
)
649 struct parm_struct
*parm
;
653 while ((parm
= lp_next_parameter(snum
, &i
, 1))) {
654 if (asprintf(&label
, "parm_%s", make_parm_name(parm
->label
)) > 0) {
655 if ((v
= cgi_variable(label
)) != NULL
) {
656 if (parm
->flags
& FLAG_HIDE
)
658 commit_parameter(snum
, parm
, v
);
665 /****************************************************************************
666 spit out the html for a link with an image
667 ****************************************************************************/
668 static void image_link(const char *name
, const char *hlink
, const char *src
)
670 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
671 cgi_baseurl(), hlink
, src
, name
);
674 /****************************************************************************
675 display the main navigation controls at the top of each page along
677 ****************************************************************************/
678 static void show_main_buttons(void)
682 if ((p
= cgi_user_name()) && strcmp(p
, "root")) {
683 printf(_("Logged in as <b>%s</b>"), p
);
687 image_link(_("Home"), "", "images/home.gif");
688 if (have_write_access
) {
689 image_link(_("Globals"), "globals", "images/globals.gif");
690 image_link(_("Shares"), "shares", "images/shares.gif");
691 image_link(_("Printers"), "printers", "images/printers.gif");
692 image_link(_("Wizard"), "wizard", "images/wizard.gif");
694 /* root always gets all buttons, otherwise look for -P */
695 if ( have_write_access
|| (!passwd_only
&& have_read_access
) ) {
696 image_link(_("Status"), "status", "images/status.gif");
697 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
699 image_link(_("Password Management"), "passwd", "images/passwd.gif");
704 /****************************************************************************
705 * Handle Display/Edit Mode CGI
706 ****************************************************************************/
707 static void ViewModeBoxes(int mode
)
709 printf("<p>%s: \n", _("Current View Is"));
710 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode
== 0) ? "checked" : ""), _("Basic"));
711 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode
== 1) ? "checked" : ""), _("Advanced"));
712 printf("<br>%s: \n", _("Change View To"));
713 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
714 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
715 printf("</p><br>\n");
718 /****************************************************************************
719 display a welcome page
720 ****************************************************************************/
721 static void welcome_page(void)
723 if (file_exist("help/welcome.html")) {
724 include_html("help/welcome.html");
726 include_html("help/welcome-no-samba-doc.html");
730 /****************************************************************************
731 display the current smb.conf
732 ****************************************************************************/
733 static void viewconfig_page(void)
736 const char form_name
[] = "viewconfig";
738 if (!verify_xsrf_token(form_name
)) {
742 if (cgi_variable("full_view")) {
747 printf("<H2>%s</H2>\n", _("Current Config"));
748 printf("<form method=post>\n");
749 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
752 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
754 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
758 write_config(stdout
, full_view
);
763 /****************************************************************************
764 second screen of the wizard ... Fetch Configuration Parameters
765 ****************************************************************************/
766 static void wizard_params_page(void)
768 unsigned int parm_filter
= FLAG_WIZARD
;
769 const char form_name
[] = "wizard_params";
771 /* Here we first set and commit all the parameters that were selected
772 in the previous screen. */
774 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
776 if (!verify_xsrf_token(form_name
)) {
780 if (cgi_variable("Commit")) {
781 commit_parameters(GLOBAL_SECTION_SNUM
);
786 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
787 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
789 if (have_write_access
) {
790 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
793 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
797 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
798 printf("</table>\n");
802 /****************************************************************************
803 Utility to just rewrite the smb.conf file - effectively just cleans it up
804 ****************************************************************************/
805 static void rewritecfg_file(void)
807 commit_parameters(GLOBAL_SECTION_SNUM
);
809 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
812 /****************************************************************************
813 wizard to create/modify the smb.conf file
814 ****************************************************************************/
815 static void wizard_page(void)
817 /* Set some variables to collect data from smb.conf */
823 const char form_name
[] = "wizard";
825 if (!verify_xsrf_token(form_name
)) {
829 if (cgi_variable("Rewrite")) {
830 (void) rewritecfg_file();
834 if (cgi_variable("GetWizardParams")){
835 (void) wizard_params_page();
839 if (cgi_variable("Commit")){
840 SerType
= atoi(cgi_variable_nonull("ServerType"));
841 winstype
= atoi(cgi_variable_nonull("WINSType"));
842 have_home
= lp_servicenumber(HOMES_NAME
);
843 HomeExpo
= atoi(cgi_variable_nonull("HomeExpo"));
845 /* Plain text passwords are too badly broken - use encrypted passwords only */
846 lp_do_parameter( GLOBAL_SECTION_SNUM
, "encrypt passwords", "Yes");
850 /* Stand-alone Server */
851 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
852 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
856 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "DOMAIN" );
857 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
860 /* Domain Controller */
861 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
862 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "Yes" );
865 switch ( winstype
) {
867 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
868 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
871 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "Yes" );
872 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
875 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
876 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", cgi_variable_nonull("WINSAddr"));
880 /* Have to create Homes share? */
881 if ((HomeExpo
== 1) && (have_home
== -1)) {
882 const char *unix_share
= HOMES_NAME
;
885 lp_copy_service(GLOBAL_SECTION_SNUM
, unix_share
);
886 have_home
= lp_servicenumber(HOMES_NAME
);
887 lp_do_parameter( have_home
, "read only", "No");
888 lp_do_parameter( have_home
, "valid users", "%S");
889 lp_do_parameter( have_home
, "browseable", "No");
890 commit_parameters(have_home
);
891 save_reload(have_home
);
894 /* Need to Delete Homes share? */
895 if ((HomeExpo
== 0) && (have_home
!= -1)) {
896 lp_remove_service(have_home
);
900 commit_parameters(GLOBAL_SECTION_SNUM
);
905 /* Now determine smb.conf WINS settings */
906 if (lp_we_are_a_wins_server())
908 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
911 /* Do we have a homes share? */
912 have_home
= lp_servicenumber(HOMES_NAME
);
914 if ((winstype
== 2) && lp_we_are_a_wins_server())
917 role
= lp_server_role();
921 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
922 printf("<form method=post action=wizard>\n");
923 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
925 if (have_write_access
) {
926 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
927 printf("%s", _("The same will happen if you press the commit button."));
928 printf("<br><br>\n");
930 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
931 printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
932 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
933 printf("</center>\n");
937 printf("<center><table border=0>");
938 printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
939 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role
== ROLE_STANDALONE
) ? "checked" : ""), _("Stand Alone"));
940 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role
== ROLE_DOMAIN_MEMBER
) ? "checked" : ""), _("Domain Member"));
941 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role
== ROLE_DOMAIN_PDC
) ? "checked" : ""), _("Domain Controller"));
943 if (role
== ROLE_DOMAIN_BDC
) {
944 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
946 printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
947 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype
== 0) ? "checked" : ""), _("Not Used"));
948 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype
== 1) ? "checked" : ""), _("Server for client use"));
949 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype
== 2) ? "checked" : ""), _("Client of another WINS server"));
951 printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
953 /* Print out the list of wins servers */
954 if(lp_wins_server_list()) {
956 const char **wins_servers
= lp_wins_server_list();
957 for(i
= 0; wins_servers
[i
]; i
++) printf("%s ", wins_servers
[i
]);
960 printf("\"></td></tr>\n");
962 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"));
963 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
965 printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
966 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home
== -1) ? "" : "checked ");
967 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home
== -1 ) ? "checked" : "");
968 printf("<td></td></tr>\n");
970 /* Enable this when we are ready ....
971 * printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
972 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
973 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
974 * printf("<td></td></tr>\n");
977 printf("</table></center>");
980 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
985 /****************************************************************************
986 display a globals editing page
987 ****************************************************************************/
988 static void globals_page(void)
990 unsigned int parm_filter
= FLAG_BASIC
;
992 const char form_name
[] = "globals";
994 printf("<H2>%s</H2>\n", _("Global Parameters"));
996 if (!verify_xsrf_token(form_name
)) {
1000 if (cgi_variable("Commit")) {
1001 commit_parameters(GLOBAL_SECTION_SNUM
);
1005 if ( cgi_variable("ViewMode") )
1006 mode
= atoi(cgi_variable_nonull("ViewMode"));
1007 if ( cgi_variable("BasicMode"))
1009 if ( cgi_variable("AdvMode"))
1013 printf("<form name=\"swatform\" method=post action=globals>\n");
1014 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
1016 ViewModeBoxes( mode
);
1019 parm_filter
= FLAG_BASIC
;
1022 parm_filter
= FLAG_ADVANCED
;
1026 if (have_write_access
) {
1027 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
1028 _("Commit Changes"));
1031 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
1035 printf("<table>\n");
1036 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
1037 printf("</table>\n");
1038 printf("</form>\n");
1041 /****************************************************************************
1042 display a shares editing page. share is in unix codepage,
1043 ****************************************************************************/
1044 static void shares_page(void)
1046 const char *share
= cgi_variable("share");
1052 unsigned int parm_filter
= FLAG_BASIC
;
1053 size_t converted_size
;
1054 const char form_name
[] = "shares";
1056 printf("<H2>%s</H2>\n", _("Share Parameters"));
1058 if (!verify_xsrf_token(form_name
)) {
1063 snum
= lp_servicenumber(share
);
1066 if (cgi_variable("Commit") && snum
>= 0) {
1067 commit_parameters(snum
);
1069 snum
= lp_servicenumber(share
);
1072 if (cgi_variable("Delete") && snum
>= 0) {
1073 lp_remove_service(snum
);
1079 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
1080 snum
= lp_servicenumber(share
);
1083 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
1084 snum
= lp_servicenumber(share
);
1086 snum
= lp_servicenumber(share
);
1090 if ( cgi_variable("ViewMode") )
1091 mode
= atoi(cgi_variable_nonull("ViewMode"));
1092 if ( cgi_variable("BasicMode"))
1094 if ( cgi_variable("AdvMode"))
1098 printf("<FORM name=\"swatform\" method=post>\n");
1099 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
1101 printf("<table>\n");
1103 ViewModeBoxes( mode
);
1106 parm_filter
= FLAG_BASIC
;
1109 parm_filter
= FLAG_ADVANCED
;
1112 printf("<br><tr>\n");
1113 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1114 printf("<td><select name=share>\n");
1116 printf("<option value=\" \"> \n");
1117 for (i
=0;i
<lp_numservices();i
++) {
1118 s
= lp_servicename(talloc_tos(), i
);
1119 if (s
&& (*s
) && strcmp(s
,"IPC$") && !lp_print_ok(i
)) {
1120 push_utf8_talloc(talloc_tos(), &utf8_s
, s
, &converted_size
);
1121 printf("<option %s value=\"%s\">%s\n",
1122 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1124 TALLOC_FREE(utf8_s
);
1127 printf("</select></td>\n");
1128 if (have_write_access
) {
1129 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1134 if (have_write_access
) {
1136 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1137 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1143 if (have_write_access
) {
1144 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1147 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1152 printf("<table>\n");
1153 show_parameters(snum
, 1, parm_filter
, 0);
1154 printf("</table>\n");
1157 printf("</FORM>\n");
1160 /*************************************************************
1161 change a password either locally or remotely
1162 *************************************************************/
1163 static bool change_password(const char *remote_machine
, const char *user_name
,
1164 const char *old_passwd
, const char *new_passwd
,
1168 char *err_str
= NULL
;
1169 char *msg_str
= NULL
;
1172 printf("%s\n<p>", _("password change in demo mode rejected"));
1176 if (remote_machine
!= NULL
) {
1177 ret
= remote_password_change(remote_machine
, user_name
,
1178 old_passwd
, new_passwd
, &err_str
);
1179 if (err_str
!= NULL
)
1180 printf("%s\n<p>", err_str
);
1182 return NT_STATUS_IS_OK(ret
);
1185 if(!initialize_password_db(True
, NULL
)) {
1186 printf("%s\n<p>", _("Can't setup password database vectors."));
1190 ret
= local_password_change(user_name
, local_flags
, new_passwd
,
1191 &err_str
, &msg_str
);
1194 printf("%s\n<p>", msg_str
);
1196 printf("%s\n<p>", err_str
);
1200 return NT_STATUS_IS_OK(ret
);
1203 /****************************************************************************
1204 do the stuff required to add or change a password
1205 ****************************************************************************/
1206 static void chg_passwd(void)
1210 int local_flags
= 0;
1212 /* Make sure users name has been specified */
1213 if (strlen(cgi_variable_nonull(SWAT_USER
)) == 0) {
1214 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1219 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1220 * so if that's what we're doing, skip the rest of the checks
1222 if (!cgi_variable(DISABLE_USER_FLAG
) && !cgi_variable(ENABLE_USER_FLAG
) && !cgi_variable(DELETE_USER_FLAG
)) {
1225 * If current user is not root, make sure old password has been specified
1226 * If REMOTE change, even root must provide old password
1228 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0)) ||
1229 ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0))) {
1230 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1234 /* If changing a users password on a remote hosts we have to know what host */
1235 if ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(RHOST
)) <= 0)) {
1236 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1240 /* Make sure new passwords have been specified */
1241 if ((strlen( cgi_variable_nonull(NEW_PSWD
)) <= 0) ||
1242 (strlen( cgi_variable_nonull(NEW2_PSWD
)) <= 0)) {
1243 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1247 /* Make sure new passwords was typed correctly twice */
1248 if (strcmp(cgi_variable_nonull(NEW_PSWD
), cgi_variable_nonull(NEW2_PSWD
)) != 0) {
1249 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1254 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1255 host
= cgi_variable(RHOST
);
1256 } else if (am_root()) {
1263 * Set up the local flags.
1266 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_ADD_USER
: 0);
1267 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1268 local_flags
|= (cgi_variable(CHG_S_PASSWD_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1269 local_flags
|= (cgi_variable(DELETE_USER_FLAG
) ? LOCAL_DELETE_USER
: 0);
1270 local_flags
|= (cgi_variable(ENABLE_USER_FLAG
) ? LOCAL_ENABLE_USER
: 0);
1271 local_flags
|= (cgi_variable(DISABLE_USER_FLAG
) ? LOCAL_DISABLE_USER
: 0);
1273 rslt
= change_password(host
,
1274 cgi_variable_nonull(SWAT_USER
),
1275 cgi_variable_nonull(OLD_PSWD
), cgi_variable_nonull(NEW_PSWD
),
1278 if(cgi_variable(CHG_S_PASSWD_FLAG
)) {
1281 printf("%s\n", _(" The passwd has been changed."));
1283 printf("%s\n", _(" The passwd has NOT been changed."));
1290 /****************************************************************************
1291 display a password editing page
1292 ****************************************************************************/
1293 static void passwd_page(void)
1295 const char *new_name
= cgi_user_name();
1296 const char passwd_form
[] = "passwd";
1297 const char rpasswd_form
[] = "rpasswd";
1299 if (!new_name
) new_name
= "";
1301 printf("<H2>%s</H2>\n", _("Server Password Management"));
1303 printf("<FORM name=\"swatform\" method=post>\n");
1304 print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form
);
1306 printf("<table>\n");
1309 * Create all the dialog boxes for data collection
1311 printf("<tr><td> %s : </td>\n", _("User Name"));
1312 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER
, new_name
);
1314 printf("<tr><td> %s : </td>\n", _("Old Password"));
1315 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD
);
1317 printf("<tr><td> %s : </td>\n", _("New Password"));
1318 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1319 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1320 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1321 printf("</table>\n");
1324 * Create all the control buttons for requesting action
1326 printf("<input type=submit name=%s value=\"%s\">\n",
1327 CHG_S_PASSWD_FLAG
, _("Change Password"));
1328 if (demo_mode
|| am_root()) {
1329 printf("<input type=submit name=%s value=\"%s\">\n",
1330 ADD_USER_FLAG
, _("Add New User"));
1331 printf("<input type=submit name=%s value=\"%s\">\n",
1332 DELETE_USER_FLAG
, _("Delete User"));
1333 printf("<input type=submit name=%s value=\"%s\">\n",
1334 DISABLE_USER_FLAG
, _("Disable User"));
1335 printf("<input type=submit name=%s value=\"%s\">\n",
1336 ENABLE_USER_FLAG
, _("Enable User"));
1338 printf("<p></FORM>\n");
1341 * Do some work if change, add, disable or enable was
1342 * requested. It could be this is the first time through this
1343 * code, so there isn't anything to do. */
1344 if (verify_xsrf_token(passwd_form
) &&
1345 ((cgi_variable(CHG_S_PASSWD_FLAG
)) || (cgi_variable(ADD_USER_FLAG
)) || (cgi_variable(DELETE_USER_FLAG
)) ||
1346 (cgi_variable(DISABLE_USER_FLAG
)) || (cgi_variable(ENABLE_USER_FLAG
)))) {
1350 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1352 printf("<FORM name=\"swatform\" method=post>\n");
1353 print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form
);
1355 printf("<table>\n");
1358 * Create all the dialog boxes for data collection
1360 printf("<tr><td> %s : </td>\n", _("User Name"));
1361 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER
, new_name
);
1362 printf("<tr><td> %s : </td>\n", _("Old Password"));
1363 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD
);
1364 printf("<tr><td> %s : </td>\n", _("New Password"));
1365 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1366 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1367 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1368 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1369 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST
);
1374 * Create all the control buttons for requesting action
1376 printf("<input type=submit name=%s value=\"%s\">",
1377 CHG_R_PASSWD_FLAG
, _("Change Password"));
1379 printf("<p></FORM>\n");
1382 * Do some work if a request has been made to change the
1383 * password somewhere other than the server. It could be this
1384 * is the first time through this code, so there isn't
1385 * anything to do. */
1386 if (verify_xsrf_token(passwd_form
) && cgi_variable(CHG_R_PASSWD_FLAG
)) {
1392 /****************************************************************************
1393 display a printers editing page
1394 ****************************************************************************/
1395 static void printers_page(void)
1397 const char *share
= cgi_variable("share");
1402 unsigned int parm_filter
= FLAG_BASIC
;
1403 const char form_name
[] = "printers";
1405 if (!verify_xsrf_token(form_name
)) {
1410 snum
= lp_servicenumber(share
);
1412 if (cgi_variable("Commit") && snum
>= 0) {
1413 commit_parameters(snum
);
1414 if (snum
>= iNumNonAutoPrintServices
)
1418 snum
= lp_servicenumber(share
);
1421 if (cgi_variable("Delete") && snum
>= 0) {
1422 lp_remove_service(snum
);
1428 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
1429 snum
= lp_servicenumber(share
);
1430 if (snum
< 0 || snum
>= iNumNonAutoPrintServices
) {
1432 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
1433 snum
= lp_servicenumber(share
);
1434 lp_do_parameter(snum
, "print ok", "Yes");
1436 snum
= lp_servicenumber(share
);
1440 if ( cgi_variable("ViewMode") )
1441 mode
= atoi(cgi_variable_nonull("ViewMode"));
1442 if ( cgi_variable("BasicMode"))
1444 if ( cgi_variable("AdvMode"))
1448 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1450 printf("<H3>%s</H3>\n", _("Important Note:"));
1451 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1452 printf("%s",_("are autoloaded printers from "));
1453 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1454 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1457 printf("<FORM name=\"swatform\" method=post>\n");
1458 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name
);
1460 ViewModeBoxes( mode
);
1463 parm_filter
= FLAG_BASIC
;
1466 parm_filter
= FLAG_ADVANCED
;
1469 printf("<table>\n");
1470 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1471 printf("<td><select name=\"share\">\n");
1472 if (snum
< 0 || !lp_print_ok(snum
))
1473 printf("<option value=\" \"> \n");
1474 for (i
=0;i
<lp_numservices();i
++) {
1475 s
= lp_servicename(talloc_tos(), i
);
1476 if (s
&& (*s
) && strcmp(s
,"IPC$") && lp_print_ok(i
)) {
1477 if (i
>= iNumNonAutoPrintServices
)
1478 printf("<option %s value=\"%s\">[*]%s\n",
1479 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1482 printf("<option %s value=\"%s\">%s\n",
1483 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1487 printf("</select></td>");
1488 if (have_write_access
) {
1489 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1492 printf("</table>\n");
1494 if (have_write_access
) {
1495 printf("<table>\n");
1496 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1497 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1503 if (have_write_access
) {
1504 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1506 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1511 printf("<table>\n");
1512 show_parameters(snum
, 1, parm_filter
, 1);
1513 printf("</table>\n");
1515 printf("</FORM>\n");
1519 when the _() translation macro is used there is no obvious place to free
1520 the resulting string and there is no easy way to give a static pointer.
1521 All we can do is rotate between some static buffers and hope a single d_printf()
1522 doesn't have more calls to _() than the number of buffers
1525 const char *lang_msg_rotate(TALLOC_CTX
*ctx
, const char *msgid
)
1530 msgstr
= lang_msg(msgid
);
1535 ret
= talloc_strdup(ctx
, msgstr
);
1537 lang_msg_free(msgstr
);
1546 * main function for SWAT.
1548 int main(int argc
, char *argv
[])
1552 struct poptOption long_options
[] = {
1554 { "disable-authentication", 'a', POPT_ARG_VAL
, &demo_mode
, True
, "Disable authentication (demo mode)" },
1555 { "password-menu-only", 'P', POPT_ARG_VAL
, &passwd_only
, True
, "Show only change password menu" },
1559 TALLOC_CTX
*frame
= talloc_stackframe();
1562 umask(S_IWGRP
| S_IWOTH
);
1564 #if defined(HAVE_SET_AUTH_PARAMETERS)
1565 set_auth_parameters(argc
, argv
);
1566 #endif /* HAVE_SET_AUTH_PARAMETERS */
1568 /* just in case it goes wild ... */
1573 /* we don't want any SIGPIPE messages */
1574 BlockSignals(True
,SIGPIPE
);
1576 debug_set_logfile("/dev/null");
1578 /* we don't want stderr screwing us up */
1580 open("/dev/null", O_WRONLY
);
1581 setup_logging("swat", DEBUG_FILE
);
1585 pc
= poptGetContext("swat", argc
, (const char **) argv
, long_options
, 0);
1587 /* Parse command line options */
1589 while(poptGetNextOpt(pc
) != -1) { }
1591 poptFreeContext(pc
);
1593 /* This should set a more apporiate log file */
1597 iNumNonAutoPrintServices
= lp_numservices();
1598 if (pcap_cache_loaded()) {
1599 struct tevent_context
*ev_ctx
;
1600 struct messaging_context
*msg_ctx
;
1602 ev_ctx
= s3_tevent_context_init(NULL
);
1603 if (ev_ctx
== NULL
) {
1604 printf("s3_tevent_context_init() failed\n");
1607 msg_ctx
= messaging_init(ev_ctx
, ev_ctx
);
1608 if (msg_ctx
== NULL
) {
1609 printf("messaging_init() failed\n");
1613 load_printers(ev_ctx
, msg_ctx
);
1615 talloc_free(ev_ctx
);
1618 cgi_setup(get_dyn_SWATDIR(), !demo_mode
);
1622 cgi_load_variables();
1624 if (!file_exist(get_dyn_CONFIGFILE())) {
1625 have_read_access
= True
;
1626 have_write_access
= True
;
1628 /* check if the authenticated user has write access - if not then
1629 don't show write options */
1630 have_write_access
= (access(get_dyn_CONFIGFILE(),W_OK
) == 0);
1632 /* if the user doesn't have read access to smb.conf then
1633 don't let them view it */
1634 have_read_access
= (access(get_dyn_CONFIGFILE(),R_OK
) == 0);
1637 show_main_buttons();
1639 page
= cgi_pathinfo();
1641 /* Root gets full functionality */
1642 if (have_read_access
&& strcmp(page
, "globals")==0) {
1644 } else if (have_read_access
&& strcmp(page
,"shares")==0) {
1646 } else if (have_read_access
&& strcmp(page
,"printers")==0) {
1648 } else if (have_read_access
&& strcmp(page
,"status")==0) {
1650 } else if (have_read_access
&& strcmp(page
,"viewconfig")==0) {
1652 } else if (strcmp(page
,"passwd")==0) {
1654 } else if (have_read_access
&& strcmp(page
,"wizard")==0) {
1656 } else if (have_read_access
&& strcmp(page
,"wizard_params")==0) {
1657 wizard_params_page();
1658 } else if (have_read_access
&& strcmp(page
,"rewritecfg")==0) {