2 Unix SMB/CIFS implementation.
3 Samba Web Administration Tool
5 Copyright (C) Andrew Tridgell 1997-2002
6 Copyright (C) John H Terpstra 2002
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 * @defgroup swat SWAT - Samba Web Administration Tool
27 * @brief Samba Web Administration Tool.
31 #include "web/swat_proto.h"
33 static int demo_mode
= False
;
34 static int passwd_only
= False
;
35 static bool have_write_access
= False
;
36 static bool have_read_access
= False
;
37 static int iNumNonAutoPrintServices
= 0;
40 * Password Management Globals
42 #define SWAT_USER "username"
43 #define OLD_PSWD "old_passwd"
44 #define NEW_PSWD "new_passwd"
45 #define NEW2_PSWD "new2_passwd"
46 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
47 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
48 #define ADD_USER_FLAG "add_user_flag"
49 #define DELETE_USER_FLAG "delete_user_flag"
50 #define DISABLE_USER_FLAG "disable_user_flag"
51 #define ENABLE_USER_FLAG "enable_user_flag"
52 #define RHOST "remote_host"
54 #define _(x) lang_msg_rotate(talloc_tos(),x)
56 /****************************************************************************
57 ****************************************************************************/
58 static int enum_index(int value
, const struct enum_list
*enumlist
)
61 for (i
=0;enumlist
[i
].name
;i
++)
62 if (value
== enumlist
[i
].value
) break;
66 static char *fix_backslash(const char *str
)
68 static char newstring
[1024];
72 if (*str
== '\\') {*p
++ = '\\';*p
++ = '\\';}
80 static const char *fix_quotes(TALLOC_CTX
*ctx
, const char *str
)
82 char *newstring
= NULL
;
85 int quote_len
= strlen(""");
87 /* Count the number of quotes. */
91 newstring_len
+= quote_len
;
97 newstring
= TALLOC_ARRAY(ctx
, char, newstring_len
);
101 for (p
= newstring
; *str
; str
++) {
103 strncpy( p
, """, quote_len
);
114 static char *stripspaceupper(const char *str
)
116 static char newstring
[1024];
120 if (*str
!= ' ') *p
++ = toupper_ascii(*str
);
127 static char *make_parm_name(const char *label
)
129 static char parmname
[1024];
133 if (*label
== ' ') *p
++ = '_';
141 /****************************************************************************
142 include a lump of html in a page
143 ****************************************************************************/
144 static int include_html(const char *fname
)
150 fd
= web_open(fname
, O_RDONLY
, 0);
153 printf(_("ERROR: Can't open %s"), fname
);
158 while ((ret
= read(fd
, buf
, sizeof(buf
))) > 0) {
166 /****************************************************************************
167 start the page with standard stuff
168 ****************************************************************************/
169 static void print_header(void)
171 if (!cgi_waspost()) {
172 printf("Expires: 0\r\n");
174 printf("Content-type: text/html\r\n\r\n");
176 if (!include_html("include/header.html")) {
177 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
178 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
182 /* *******************************************************************
183 show parameter label with translated name in the following form
184 because showing original and translated label in one line looks
185 too long, and showing translated label only is unusable for
187 -------------------------------
188 HELP security [combo box][button]
190 -------------------------------
191 (capital words are translated by gettext.)
192 if no translation is available, then same form as original is
194 "i18n_translated_parm" class is used to change the color of the
195 translated parameter with CSS.
196 **************************************************************** */
197 static const char *get_parm_translated(TALLOC_CTX
*ctx
,
198 const char* pAnchor
, const char* pHelp
, const char* pLabel
)
200 const char *pTranslated
= _(pLabel
);
202 if(strcmp(pLabel
, pTranslated
) != 0) {
203 output
= talloc_asprintf(ctx
,
204 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
205 pAnchor
, pHelp
, pLabel
, pTranslated
);
208 output
= talloc_asprintf(ctx
,
209 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
210 pAnchor
, pHelp
, pLabel
);
213 /****************************************************************************
215 ****************************************************************************/
216 static void print_footer(void)
218 if (!include_html("include/footer.html")) {
219 printf("\n</BODY>\n</HTML>\n");
223 /****************************************************************************
224 display one editable parameter in a form
225 ****************************************************************************/
226 static void show_parameter(int snum
, struct parm_struct
*parm
)
229 void *ptr
= parm
->ptr
;
230 char *utf8_s1
, *utf8_s2
;
231 TALLOC_CTX
*ctx
= talloc_stackframe();
233 if (parm
->p_class
== P_LOCAL
&& snum
>= 0) {
234 ptr
= lp_local_ptr(snum
, ptr
);
237 printf("<tr><td>%s</td><td>", get_parm_translated(ctx
,
238 stripspaceupper(parm
->label
), _("Help"), parm
->label
));
239 switch (parm
->type
) {
241 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
242 make_parm_name(parm
->label
), *(char *)ptr
);
243 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
244 _("Set Default"), make_parm_name(parm
->label
),(char)(parm
->def
.cvalue
));
248 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
249 make_parm_name(parm
->label
));
250 if ((char ***)ptr
&& *(char ***)ptr
&& **(char ***)ptr
) {
251 char **list
= *(char ***)ptr
;
252 for (;*list
;list
++) {
253 /* enclose in HTML encoded quotes if the string contains a space */
254 if ( strchr_m(*list
, ' ') ) {
255 push_utf8_allocate(&utf8_s1
, *list
);
256 push_utf8_allocate(&utf8_s2
, ((*(list
+1))?", ":""));
257 printf(""%s"%s", utf8_s1
, utf8_s2
);
259 push_utf8_allocate(&utf8_s1
, *list
);
260 push_utf8_allocate(&utf8_s2
, ((*(list
+1))?", ":""));
261 printf("%s%s", utf8_s1
, utf8_s2
);
268 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
269 _("Set Default"), make_parm_name(parm
->label
));
270 if (parm
->def
.lvalue
) {
271 char **list
= (char **)(parm
->def
.lvalue
);
272 for (; *list
; list
++) {
273 /* enclose in HTML encoded quotes if the string contains a space */
274 if ( strchr_m(*list
, ' ') )
275 printf(""%s"%s", *list
, ((*(list
+1))?", ":""));
277 printf("%s%s", *list
, ((*(list
+1))?", ":""));
285 push_utf8_allocate(&utf8_s1
, *(char **)ptr
);
286 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
287 make_parm_name(parm
->label
), fix_quotes(ctx
, utf8_s1
));
289 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
290 _("Set Default"), make_parm_name(parm
->label
),fix_backslash((char *)(parm
->def
.svalue
)));
295 push_utf8_allocate(&utf8_s1
, (char *)ptr
);
296 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
297 make_parm_name(parm
->label
), fix_quotes(ctx
, utf8_s1
));
299 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
300 _("Set Default"), make_parm_name(parm
->label
),fix_backslash((char *)(parm
->def
.svalue
)));
304 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
305 printf("<option %s>Yes", (*(bool *)ptr
)?"selected":"");
306 printf("<option %s>No", (*(bool *)ptr
)?"":"selected");
308 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
309 _("Set Default"), make_parm_name(parm
->label
),(bool)(parm
->def
.bvalue
)?0:1);
313 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
314 printf("<option %s>Yes", (*(bool *)ptr
)?"":"selected");
315 printf("<option %s>No", (*(bool *)ptr
)?"selected":"");
317 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
318 _("Set Default"), make_parm_name(parm
->label
),(bool)(parm
->def
.bvalue
)?1:0);
322 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm
->label
), *(int *)ptr
);
323 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
324 _("Set Default"), make_parm_name(parm
->label
),(int)(parm
->def
.ivalue
));
329 o
= octal_string(*(int *)ptr
);
330 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
331 make_parm_name(parm
->label
), o
);
333 o
= octal_string((int)(parm
->def
.ivalue
));
334 printf("<input type=button value=\"%s\" "
335 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
336 _("Set Default"), make_parm_name(parm
->label
), o
);
342 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
343 for (i
=0;parm
->enum_list
[i
].name
;i
++) {
344 if (i
== 0 || parm
->enum_list
[i
].value
!= parm
->enum_list
[i
-1].value
) {
345 printf("<option %s>%s",(*(int *)ptr
)==parm
->enum_list
[i
].value
?"selected":"",parm
->enum_list
[i
].name
);
349 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
350 _("Set Default"), make_parm_name(parm
->label
),enum_index((int)(parm
->def
.ivalue
),parm
->enum_list
));
355 printf("</td></tr>\n");
359 /****************************************************************************
360 display a set of parameters for a service
361 ****************************************************************************/
362 static void show_parameters(int snum
, int allparameters
, unsigned int parm_filter
, int printers
)
365 struct parm_struct
*parm
;
366 const char *heading
= NULL
;
367 const char *last_heading
= NULL
;
369 while ((parm
= lp_next_parameter(snum
, &i
, allparameters
))) {
370 if (snum
< 0 && parm
->p_class
== P_LOCAL
&& !(parm
->flags
& FLAG_GLOBAL
))
372 if (parm
->p_class
== P_SEPARATOR
) {
373 heading
= parm
->label
;
376 if (parm
->flags
& FLAG_HIDE
) continue;
378 if (printers
& !(parm
->flags
& FLAG_PRINT
)) continue;
379 if (!printers
& !(parm
->flags
& FLAG_SHARE
)) continue;
382 if (!( parm_filter
& FLAG_ADVANCED
)) {
383 if (!(parm
->flags
& FLAG_BASIC
)) {
384 void *ptr
= parm
->ptr
;
386 if (parm
->p_class
== P_LOCAL
&& snum
>= 0) {
387 ptr
= lp_local_ptr(snum
, ptr
);
390 switch (parm
->type
) {
392 if (*(char *)ptr
== (char)(parm
->def
.cvalue
)) continue;
396 if (!str_list_compare(*(char ***)ptr
, (char **)(parm
->def
.lvalue
))) continue;
401 if (!strcmp(*(char **)ptr
,(char *)(parm
->def
.svalue
))) continue;
406 if (!strcmp((char *)ptr
,(char *)(parm
->def
.svalue
))) continue;
411 if (*(bool *)ptr
== (bool)(parm
->def
.bvalue
)) continue;
416 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
421 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
427 if (printers
&& !(parm
->flags
& FLAG_PRINT
)) continue;
430 if ((parm_filter
& FLAG_WIZARD
) && !(parm
->flags
& FLAG_WIZARD
)) continue;
432 if ((parm_filter
& FLAG_ADVANCED
) && !(parm
->flags
& FLAG_ADVANCED
)) continue;
434 if (heading
&& heading
!= last_heading
) {
435 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading
));
436 last_heading
= heading
;
438 show_parameter(snum
, parm
);
442 /****************************************************************************
443 load the smb.conf file into loadparm.
444 ****************************************************************************/
445 static bool load_config(bool save_def
)
447 lp_resetnumservices();
448 return lp_load(dyn_CONFIGFILE
,False
,save_def
,False
,True
);
451 /****************************************************************************
453 ****************************************************************************/
454 static void write_config(FILE *f
, bool show_defaults
)
456 fprintf(f
, "# Samba config file created using SWAT\n");
457 fprintf(f
, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
458 fprintf(f
, "# Date: %s\n\n", current_timestring(False
));
460 lp_dump(f
, show_defaults
, iNumNonAutoPrintServices
);
463 /****************************************************************************
464 save and reload the smb.conf config file
465 ****************************************************************************/
466 static int save_reload(int snum
)
471 f
= sys_fopen(dyn_CONFIGFILE
,"w");
473 printf(_("failed to open %s for writing"), dyn_CONFIGFILE
);
478 /* just in case they have used the buggy xinetd to create the file */
479 if (fstat(fileno(f
), &st
) == 0 &&
480 (st
.st_mode
& S_IWOTH
)) {
481 #if defined HAVE_FCHMOD
482 fchmod(fileno(f
), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
484 chmod(dyn_CONFIGFILE
, S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
488 write_config(f
, False
);
490 lp_dump_one(f
, False
, snum
);
495 if (!load_config(False
)) {
496 printf(_("Can't reload %s"), dyn_CONFIGFILE
);
500 iNumNonAutoPrintServices
= lp_numservices();
506 /****************************************************************************
508 ****************************************************************************/
509 static void commit_parameter(int snum
, struct parm_struct
*parm
, const char *v
)
514 if (snum
< 0 && parm
->p_class
== P_LOCAL
) {
515 /* this handles the case where we are changing a local
516 variable globally. We need to change the parameter in
517 all shares where it is currently set to the default */
518 for (i
=0;i
<lp_numservices();i
++) {
519 s
= lp_servicename(i
);
520 if (s
&& (*s
) && lp_is_default(i
, parm
)) {
521 lp_do_parameter(i
, parm
->label
, v
);
526 lp_do_parameter(snum
, parm
->label
, v
);
529 /****************************************************************************
530 commit a set of parameters for a service
531 ****************************************************************************/
532 static void commit_parameters(int snum
)
535 struct parm_struct
*parm
;
539 while ((parm
= lp_next_parameter(snum
, &i
, 1))) {
540 if (asprintf(&label
, "parm_%s", make_parm_name(parm
->label
)) > 0) {
541 if ((v
= cgi_variable(label
)) != NULL
) {
542 if (parm
->flags
& FLAG_HIDE
)
544 commit_parameter(snum
, parm
, v
);
551 /****************************************************************************
552 spit out the html for a link with an image
553 ****************************************************************************/
554 static void image_link(const char *name
, const char *hlink
, const char *src
)
556 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
557 cgi_baseurl(), hlink
, src
, name
);
560 /****************************************************************************
561 display the main navigation controls at the top of each page along
563 ****************************************************************************/
564 static void show_main_buttons(void)
568 if ((p
= cgi_user_name()) && strcmp(p
, "root")) {
569 printf(_("Logged in as <b>%s</b>"), p
);
573 image_link(_("Home"), "", "images/home.gif");
574 if (have_write_access
) {
575 image_link(_("Globals"), "globals", "images/globals.gif");
576 image_link(_("Shares"), "shares", "images/shares.gif");
577 image_link(_("Printers"), "printers", "images/printers.gif");
578 image_link(_("Wizard"), "wizard", "images/wizard.gif");
580 /* root always gets all buttons, otherwise look for -P */
581 if ( have_write_access
|| (!passwd_only
&& have_read_access
) ) {
582 image_link(_("Status"), "status", "images/status.gif");
583 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
585 image_link(_("Password Management"), "passwd", "images/passwd.gif");
590 /****************************************************************************
591 * Handle Display/Edit Mode CGI
592 ****************************************************************************/
593 static void ViewModeBoxes(int mode
)
595 printf("<p>%s: \n", _("Current View Is"));
596 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode
== 0) ? "checked" : ""), _("Basic"));
597 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode
== 1) ? "checked" : ""), _("Advanced"));
598 printf("<br>%s: \n", _("Change View To"));
599 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
600 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
601 printf("</p><br>\n");
604 /****************************************************************************
605 display a welcome page
606 ****************************************************************************/
607 static void welcome_page(void)
609 if (file_exist("help/welcome.html", NULL
)) {
610 include_html("help/welcome.html");
612 include_html("help/welcome-no-samba-doc.html");
616 /****************************************************************************
617 display the current smb.conf
618 ****************************************************************************/
619 static void viewconfig_page(void)
623 if (cgi_variable("full_view")) {
627 printf("<H2>%s</H2>\n", _("Current Config"));
628 printf("<form method=post>\n");
631 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
633 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
637 write_config(stdout
, full_view
);
642 /****************************************************************************
643 second screen of the wizard ... Fetch Configuration Parameters
644 ****************************************************************************/
645 static void wizard_params_page(void)
647 unsigned int parm_filter
= FLAG_WIZARD
;
649 /* Here we first set and commit all the parameters that were selected
650 in the previous screen. */
652 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
654 if (cgi_variable("Commit")) {
655 commit_parameters(GLOBAL_SECTION_SNUM
);
659 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
661 if (have_write_access
) {
662 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
665 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
669 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
670 printf("</table>\n");
674 /****************************************************************************
675 Utility to just rewrite the smb.conf file - effectively just cleans it up
676 ****************************************************************************/
677 static void rewritecfg_file(void)
679 commit_parameters(GLOBAL_SECTION_SNUM
);
681 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
684 /****************************************************************************
685 wizard to create/modify the smb.conf file
686 ****************************************************************************/
687 static void wizard_page(void)
689 /* Set some variables to collect data from smb.conf */
696 if (cgi_variable("Rewrite")) {
697 (void) rewritecfg_file();
701 if (cgi_variable("GetWizardParams")){
702 (void) wizard_params_page();
706 if (cgi_variable("Commit")){
707 SerType
= atoi(cgi_variable_nonull("ServerType"));
708 winstype
= atoi(cgi_variable_nonull("WINSType"));
709 have_home
= lp_servicenumber(HOMES_NAME
);
710 HomeExpo
= atoi(cgi_variable_nonull("HomeExpo"));
712 /* Plain text passwords are too badly broken - use encrypted passwords only */
713 lp_do_parameter( GLOBAL_SECTION_SNUM
, "encrypt passwords", "Yes");
717 /* Stand-alone Server */
718 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
719 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
723 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "DOMAIN" );
724 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
727 /* Domain Controller */
728 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
729 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "Yes" );
732 switch ( winstype
) {
734 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
735 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
738 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "Yes" );
739 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
742 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
743 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", cgi_variable_nonull("WINSAddr"));
747 /* Have to create Homes share? */
748 if ((HomeExpo
== 1) && (have_home
== -1)) {
749 const char *unix_share
= HOMES_NAME
;
752 lp_copy_service(GLOBAL_SECTION_SNUM
, unix_share
);
753 iNumNonAutoPrintServices
= lp_numservices();
754 have_home
= lp_servicenumber(HOMES_NAME
);
755 lp_do_parameter( have_home
, "read only", "No");
756 lp_do_parameter( have_home
, "valid users", "%S");
757 lp_do_parameter( have_home
, "browseable", "No");
758 commit_parameters(have_home
);
761 /* Need to Delete Homes share? */
762 if ((HomeExpo
== 0) && (have_home
!= -1)) {
763 lp_remove_service(have_home
);
767 commit_parameters(GLOBAL_SECTION_SNUM
);
772 /* Now determine smb.conf WINS settings */
773 if (lp_wins_support())
775 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
778 /* Do we have a homes share? */
779 have_home
= lp_servicenumber(HOMES_NAME
);
781 if ((winstype
== 2) && lp_wins_support())
784 role
= lp_server_role();
787 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
788 printf("<form method=post action=wizard>\n");
790 if (have_write_access
) {
791 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
792 printf("%s", _("The same will happen if you press the commit button."));
793 printf("<br><br>\n");
795 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
796 printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
797 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
798 printf("</center>\n");
802 printf("<center><table border=0>");
803 printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
804 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role
== ROLE_STANDALONE
) ? "checked" : ""), _("Stand Alone"));
805 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role
== ROLE_DOMAIN_MEMBER
) ? "checked" : ""), _("Domain Member"));
806 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role
== ROLE_DOMAIN_PDC
) ? "checked" : ""), _("Domain Controller"));
808 if (role
== ROLE_DOMAIN_BDC
) {
809 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
811 printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
812 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype
== 0) ? "checked" : ""), _("Not Used"));
813 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype
== 1) ? "checked" : ""), _("Server for client use"));
814 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype
== 2) ? "checked" : ""), _("Client of another WINS server"));
816 printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
818 /* Print out the list of wins servers */
819 if(lp_wins_server_list()) {
821 const char **wins_servers
= lp_wins_server_list();
822 for(i
= 0; wins_servers
[i
]; i
++) printf("%s ", wins_servers
[i
]);
825 printf("\"></td></tr>\n");
827 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"));
828 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
830 printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
831 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home
== -1) ? "" : "checked ");
832 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home
== -1 ) ? "checked" : "");
833 printf("<td></td></tr>\n");
835 /* Enable this when we are ready ....
836 * printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
837 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
838 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
839 * printf("<td></td></tr>\n");
842 printf("</table></center>");
845 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
850 /****************************************************************************
851 display a globals editing page
852 ****************************************************************************/
853 static void globals_page(void)
855 unsigned int parm_filter
= FLAG_BASIC
;
858 printf("<H2>%s</H2>\n", _("Global Parameters"));
860 if (cgi_variable("Commit")) {
861 commit_parameters(GLOBAL_SECTION_SNUM
);
865 if ( cgi_variable("ViewMode") )
866 mode
= atoi(cgi_variable_nonull("ViewMode"));
867 if ( cgi_variable("BasicMode"))
869 if ( cgi_variable("AdvMode"))
872 printf("<form name=\"swatform\" method=post action=globals>\n");
874 ViewModeBoxes( mode
);
877 parm_filter
= FLAG_BASIC
;
880 parm_filter
= FLAG_ADVANCED
;
884 if (have_write_access
) {
885 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
886 _("Commit Changes"));
889 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
894 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
895 printf("</table>\n");
899 /****************************************************************************
900 display a shares editing page. share is in unix codepage,
901 ****************************************************************************/
902 static void shares_page(void)
904 const char *share
= cgi_variable("share");
910 unsigned int parm_filter
= FLAG_BASIC
;
913 snum
= lp_servicenumber(share
);
915 printf("<H2>%s</H2>\n", _("Share Parameters"));
917 if (cgi_variable("Commit") && snum
>= 0) {
918 commit_parameters(snum
);
922 if (cgi_variable("Delete") && snum
>= 0) {
923 lp_remove_service(snum
);
929 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
931 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
932 iNumNonAutoPrintServices
= lp_numservices();
934 snum
= lp_servicenumber(share
);
937 printf("<FORM name=\"swatform\" method=post>\n");
941 if ( cgi_variable("ViewMode") )
942 mode
= atoi(cgi_variable_nonull("ViewMode"));
943 if ( cgi_variable("BasicMode"))
945 if ( cgi_variable("AdvMode"))
948 ViewModeBoxes( mode
);
951 parm_filter
= FLAG_BASIC
;
954 parm_filter
= FLAG_ADVANCED
;
957 printf("<br><tr>\n");
958 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
959 printf("<td><select name=share>\n");
961 printf("<option value=\" \"> \n");
962 for (i
=0;i
<lp_numservices();i
++) {
963 s
= lp_servicename(i
);
964 if (s
&& (*s
) && strcmp(s
,"IPC$") && !lp_print_ok(i
)) {
965 push_utf8_allocate(&utf8_s
, s
);
966 printf("<option %s value=\"%s\">%s\n",
967 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
973 printf("</select></td>\n");
974 if (have_write_access
) {
975 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
980 if (have_write_access
) {
982 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
983 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
989 if (have_write_access
) {
990 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
993 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
999 show_parameters(snum
, 1, parm_filter
, 0);
1000 printf("</table>\n");
1003 printf("</FORM>\n");
1006 /*************************************************************
1007 change a password either locally or remotely
1008 *************************************************************/
1009 static bool change_password(const char *remote_machine
, const char *user_name
,
1010 const char *old_passwd
, const char *new_passwd
,
1014 char *err_str
= NULL
;
1015 char *msg_str
= NULL
;
1018 printf("%s\n<p>", _("password change in demo mode rejected"));
1022 if (remote_machine
!= NULL
) {
1023 ret
= remote_password_change(remote_machine
, user_name
,
1024 old_passwd
, new_passwd
, &err_str
);
1025 if (err_str
!= NULL
)
1026 printf("%s\n<p>", err_str
);
1028 return NT_STATUS_IS_OK(ret
);
1031 if(!initialize_password_db(True
, NULL
)) {
1032 printf("%s\n<p>", _("Can't setup password database vectors."));
1036 ret
= local_password_change(user_name
, local_flags
, new_passwd
,
1037 &err_str
, &msg_str
);
1040 printf("%s\n<p>", msg_str
);
1042 printf("%s\n<p>", err_str
);
1046 return NT_STATUS_IS_OK(ret
);
1049 /****************************************************************************
1050 do the stuff required to add or change a password
1051 ****************************************************************************/
1052 static void chg_passwd(void)
1056 int local_flags
= 0;
1058 /* Make sure users name has been specified */
1059 if (strlen(cgi_variable_nonull(SWAT_USER
)) == 0) {
1060 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1065 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1066 * so if that's what we're doing, skip the rest of the checks
1068 if (!cgi_variable(DISABLE_USER_FLAG
) && !cgi_variable(ENABLE_USER_FLAG
) && !cgi_variable(DELETE_USER_FLAG
)) {
1071 * If current user is not root, make sure old password has been specified
1072 * If REMOTE change, even root must provide old password
1074 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0)) ||
1075 ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0))) {
1076 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1080 /* If changing a users password on a remote hosts we have to know what host */
1081 if ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(RHOST
)) <= 0)) {
1082 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1086 /* Make sure new passwords have been specified */
1087 if ((strlen( cgi_variable_nonull(NEW_PSWD
)) <= 0) ||
1088 (strlen( cgi_variable_nonull(NEW2_PSWD
)) <= 0)) {
1089 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1093 /* Make sure new passwords was typed correctly twice */
1094 if (strcmp(cgi_variable_nonull(NEW_PSWD
), cgi_variable_nonull(NEW2_PSWD
)) != 0) {
1095 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1100 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1101 host
= cgi_variable(RHOST
);
1102 } else if (am_root()) {
1109 * Set up the local flags.
1112 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_ADD_USER
: 0);
1113 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1114 local_flags
|= (cgi_variable(CHG_S_PASSWD_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1115 local_flags
|= (cgi_variable(DELETE_USER_FLAG
) ? LOCAL_DELETE_USER
: 0);
1116 local_flags
|= (cgi_variable(ENABLE_USER_FLAG
) ? LOCAL_ENABLE_USER
: 0);
1117 local_flags
|= (cgi_variable(DISABLE_USER_FLAG
) ? LOCAL_DISABLE_USER
: 0);
1120 rslt
= change_password(host
,
1121 cgi_variable_nonull(SWAT_USER
),
1122 cgi_variable_nonull(OLD_PSWD
), cgi_variable_nonull(NEW_PSWD
),
1125 if(cgi_variable(CHG_S_PASSWD_FLAG
)) {
1128 printf(_(" The passwd for '%s' has been changed."), cgi_variable_nonull(SWAT_USER
));
1131 printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable_nonull(SWAT_USER
));
1139 /****************************************************************************
1140 display a password editing page
1141 ****************************************************************************/
1142 static void passwd_page(void)
1144 const char *new_name
= cgi_user_name();
1147 * After the first time through here be nice. If the user
1148 * changed the User box text to another users name, remember it.
1150 if (cgi_variable(SWAT_USER
)) {
1151 new_name
= cgi_variable_nonull(SWAT_USER
);
1154 if (!new_name
) new_name
= "";
1156 printf("<H2>%s</H2>\n", _("Server Password Management"));
1158 printf("<FORM name=\"swatform\" method=post>\n");
1160 printf("<table>\n");
1163 * Create all the dialog boxes for data collection
1165 printf("<tr><td> %s : </td>\n", _("User Name"));
1166 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER
, new_name
);
1168 printf("<tr><td> %s : </td>\n", _("Old Password"));
1169 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD
);
1171 printf("<tr><td> %s : </td>\n", _("New Password"));
1172 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1173 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1174 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1175 printf("</table>\n");
1178 * Create all the control buttons for requesting action
1180 printf("<input type=submit name=%s value=\"%s\">\n",
1181 CHG_S_PASSWD_FLAG
, _("Change Password"));
1182 if (demo_mode
|| am_root()) {
1183 printf("<input type=submit name=%s value=\"%s\">\n",
1184 ADD_USER_FLAG
, _("Add New User"));
1185 printf("<input type=submit name=%s value=\"%s\">\n",
1186 DELETE_USER_FLAG
, _("Delete User"));
1187 printf("<input type=submit name=%s value=\"%s\">\n",
1188 DISABLE_USER_FLAG
, _("Disable User"));
1189 printf("<input type=submit name=%s value=\"%s\">\n",
1190 ENABLE_USER_FLAG
, _("Enable User"));
1192 printf("<p></FORM>\n");
1195 * Do some work if change, add, disable or enable was
1196 * requested. It could be this is the first time through this
1197 * code, so there isn't anything to do. */
1198 if ((cgi_variable(CHG_S_PASSWD_FLAG
)) || (cgi_variable(ADD_USER_FLAG
)) || (cgi_variable(DELETE_USER_FLAG
)) ||
1199 (cgi_variable(DISABLE_USER_FLAG
)) || (cgi_variable(ENABLE_USER_FLAG
))) {
1203 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1205 printf("<FORM name=\"swatform\" method=post>\n");
1207 printf("<table>\n");
1210 * Create all the dialog boxes for data collection
1212 printf("<tr><td> %s : </td>\n", _("User Name"));
1213 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER
, new_name
);
1214 printf("<tr><td> %s : </td>\n", _("Old Password"));
1215 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD
);
1216 printf("<tr><td> %s : </td>\n", _("New Password"));
1217 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1218 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1219 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1220 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1221 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST
);
1226 * Create all the control buttons for requesting action
1228 printf("<input type=submit name=%s value=\"%s\">",
1229 CHG_R_PASSWD_FLAG
, _("Change Password"));
1231 printf("<p></FORM>\n");
1234 * Do some work if a request has been made to change the
1235 * password somewhere other than the server. It could be this
1236 * is the first time through this code, so there isn't
1237 * anything to do. */
1238 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1244 /****************************************************************************
1245 display a printers editing page
1246 ****************************************************************************/
1247 static void printers_page(void)
1249 const char *share
= cgi_variable("share");
1254 unsigned int parm_filter
= FLAG_BASIC
;
1257 snum
= lp_servicenumber(share
);
1259 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1261 printf("<H3>%s</H3>\n", _("Important Note:"));
1262 printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1263 printf(_("are autoloaded printers from "));
1264 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1265 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1267 if (cgi_variable("Commit") && snum
>= 0) {
1268 commit_parameters(snum
);
1269 if (snum
>= iNumNonAutoPrintServices
)
1275 if (cgi_variable("Delete") && snum
>= 0) {
1276 lp_remove_service(snum
);
1282 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
1284 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
1285 iNumNonAutoPrintServices
= lp_numservices();
1286 snum
= lp_servicenumber(share
);
1287 lp_do_parameter(snum
, "print ok", "Yes");
1289 snum
= lp_servicenumber(share
);
1292 printf("<FORM name=\"swatform\" method=post>\n");
1294 if ( cgi_variable("ViewMode") )
1295 mode
= atoi(cgi_variable_nonull("ViewMode"));
1296 if ( cgi_variable("BasicMode"))
1298 if ( cgi_variable("AdvMode"))
1301 ViewModeBoxes( mode
);
1304 parm_filter
= FLAG_BASIC
;
1307 parm_filter
= FLAG_ADVANCED
;
1310 printf("<table>\n");
1311 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1312 printf("<td><select name=\"share\">\n");
1313 if (snum
< 0 || !lp_print_ok(snum
))
1314 printf("<option value=\" \"> \n");
1315 for (i
=0;i
<lp_numservices();i
++) {
1316 s
= lp_servicename(i
);
1317 if (s
&& (*s
) && strcmp(s
,"IPC$") && lp_print_ok(i
)) {
1318 if (i
>= iNumNonAutoPrintServices
)
1319 printf("<option %s value=\"%s\">[*]%s\n",
1320 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1323 printf("<option %s value=\"%s\">%s\n",
1324 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1328 printf("</select></td>");
1329 if (have_write_access
) {
1330 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1333 printf("</table>\n");
1335 if (have_write_access
) {
1336 printf("<table>\n");
1337 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1338 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1344 if (have_write_access
) {
1345 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1347 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1352 printf("<table>\n");
1353 show_parameters(snum
, 1, parm_filter
, 1);
1354 printf("</table>\n");
1356 printf("</FORM>\n");
1360 when the _() translation macro is used there is no obvious place to free
1361 the resulting string and there is no easy way to give a static pointer.
1362 All we can do is rotate between some static buffers and hope a single d_printf()
1363 doesn't have more calls to _() than the number of buffers
1366 const char *lang_msg_rotate(TALLOC_CTX
*ctx
, const char *msgid
)
1371 msgstr
= lang_msg(msgid
);
1376 ret
= talloc_strdup(ctx
, msgstr
);
1378 lang_msg_free(msgstr
);
1387 * main function for SWAT.
1389 int main(int argc
, char *argv
[])
1393 struct poptOption long_options
[] = {
1395 { "disable-authentication", 'a', POPT_ARG_VAL
, &demo_mode
, True
, "Disable authentication (demo mode)" },
1396 { "password-menu-only", 'P', POPT_ARG_VAL
, &passwd_only
, True
, "Show only change password menu" },
1400 TALLOC_CTX
*frame
= talloc_stackframe();
1403 umask(S_IWGRP
| S_IWOTH
);
1405 #if defined(HAVE_SET_AUTH_PARAMETERS)
1406 set_auth_parameters(argc
, argv
);
1407 #endif /* HAVE_SET_AUTH_PARAMETERS */
1409 /* just in case it goes wild ... */
1414 /* we don't want any SIGPIPE messages */
1415 BlockSignals(True
,SIGPIPE
);
1417 dbf
= x_fopen("/dev/null", O_WRONLY
, 0);
1418 if (!dbf
) dbf
= x_stderr
;
1420 /* we don't want stderr screwing us up */
1422 open("/dev/null", O_WRONLY
);
1424 pc
= poptGetContext("swat", argc
, (const char **) argv
, long_options
, 0);
1426 /* Parse command line options */
1428 while(poptGetNextOpt(pc
) != -1) { }
1430 poptFreeContext(pc
);
1434 setup_logging(argv
[0],False
);
1437 iNumNonAutoPrintServices
= lp_numservices();
1440 cgi_setup(dyn_SWATDIR
, !demo_mode
);
1444 cgi_load_variables();
1446 if (!file_exist(dyn_CONFIGFILE
, NULL
)) {
1447 have_read_access
= True
;
1448 have_write_access
= True
;
1450 /* check if the authenticated user has write access - if not then
1451 don't show write options */
1452 have_write_access
= (access(dyn_CONFIGFILE
,W_OK
) == 0);
1454 /* if the user doesn't have read access to smb.conf then
1455 don't let them view it */
1456 have_read_access
= (access(dyn_CONFIGFILE
,R_OK
) == 0);
1459 show_main_buttons();
1461 page
= cgi_pathinfo();
1463 /* Root gets full functionality */
1464 if (have_read_access
&& strcmp(page
, "globals")==0) {
1466 } else if (have_read_access
&& strcmp(page
,"shares")==0) {
1468 } else if (have_read_access
&& strcmp(page
,"printers")==0) {
1470 } else if (have_read_access
&& strcmp(page
,"status")==0) {
1472 } else if (have_read_access
&& strcmp(page
,"viewconfig")==0) {
1474 } else if (strcmp(page
,"passwd")==0) {
1476 } else if (have_read_access
&& strcmp(page
,"wizard")==0) {
1478 } else if (have_read_access
&& strcmp(page
,"wizard_params")==0) {
1479 wizard_params_page();
1480 } else if (have_read_access
&& strcmp(page
,"rewritecfg")==0) {