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. */
92 newstring_len
+= quote_len
;
98 newstring
= TALLOC_ARRAY(ctx
, char, newstring_len
);
102 for (p
= newstring
; *str
; str
++) {
104 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) {
159 if (write(1, buf
, ret
) == -1) {
168 /****************************************************************************
169 start the page with standard stuff
170 ****************************************************************************/
171 static void print_header(void)
173 if (!cgi_waspost()) {
174 printf("Expires: 0\r\n");
176 printf("Content-type: text/html\r\n\r\n");
178 if (!include_html("include/header.html")) {
179 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
180 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
184 /* *******************************************************************
185 show parameter label with translated name in the following form
186 because showing original and translated label in one line looks
187 too long, and showing translated label only is unusable for
189 -------------------------------
190 HELP security [combo box][button]
192 -------------------------------
193 (capital words are translated by gettext.)
194 if no translation is available, then same form as original is
196 "i18n_translated_parm" class is used to change the color of the
197 translated parameter with CSS.
198 **************************************************************** */
199 static const char *get_parm_translated(TALLOC_CTX
*ctx
,
200 const char* pAnchor
, const char* pHelp
, const char* pLabel
)
202 const char *pTranslated
= _(pLabel
);
204 if(strcmp(pLabel
, pTranslated
) != 0) {
205 output
= talloc_asprintf(ctx
,
206 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
207 pAnchor
, pHelp
, pLabel
, pTranslated
);
210 output
= talloc_asprintf(ctx
,
211 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
212 pAnchor
, pHelp
, pLabel
);
215 /****************************************************************************
217 ****************************************************************************/
218 static void print_footer(void)
220 if (!include_html("include/footer.html")) {
221 printf("\n</BODY>\n</HTML>\n");
225 /****************************************************************************
226 display one editable parameter in a form
227 ****************************************************************************/
228 static void show_parameter(int snum
, struct parm_struct
*parm
)
231 void *ptr
= parm
->ptr
;
232 char *utf8_s1
, *utf8_s2
;
233 size_t converted_size
;
234 TALLOC_CTX
*ctx
= talloc_stackframe();
236 if (parm
->p_class
== P_LOCAL
&& snum
>= 0) {
237 ptr
= lp_local_ptr_by_snum(snum
, ptr
);
240 printf("<tr><td>%s</td><td>", get_parm_translated(ctx
,
241 stripspaceupper(parm
->label
), _("Help"), parm
->label
));
242 switch (parm
->type
) {
244 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
245 make_parm_name(parm
->label
), *(char *)ptr
);
246 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
247 _("Set Default"), make_parm_name(parm
->label
),(char)(parm
->def
.cvalue
));
251 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
252 make_parm_name(parm
->label
));
253 if ((char ***)ptr
&& *(char ***)ptr
&& **(char ***)ptr
) {
254 char **list
= *(char ***)ptr
;
255 for (;*list
;list
++) {
256 /* enclose in HTML encoded quotes if the string contains a space */
257 if ( strchr_m(*list
, ' ') ) {
258 push_utf8_talloc(talloc_tos(), &utf8_s1
, *list
, &converted_size
);
259 push_utf8_talloc(talloc_tos(), &utf8_s2
, ((*(list
+1))?", ":""), &converted_size
);
260 printf(""%s"%s", utf8_s1
, utf8_s2
);
262 push_utf8_talloc(talloc_tos(), &utf8_s1
, *list
, &converted_size
);
263 push_utf8_talloc(talloc_tos(), &utf8_s2
, ((*(list
+1))?", ":""), &converted_size
);
264 printf("%s%s", utf8_s1
, utf8_s2
);
266 TALLOC_FREE(utf8_s1
);
267 TALLOC_FREE(utf8_s2
);
271 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
272 _("Set Default"), make_parm_name(parm
->label
));
273 if (parm
->def
.lvalue
) {
274 char **list
= (char **)(parm
->def
.lvalue
);
275 for (; *list
; list
++) {
276 /* enclose in HTML encoded quotes if the string contains a space */
277 if ( strchr_m(*list
, ' ') )
278 printf(""%s"%s", *list
, ((*(list
+1))?", ":""));
280 printf("%s%s", *list
, ((*(list
+1))?", ":""));
288 push_utf8_talloc(talloc_tos(), &utf8_s1
, *(char **)ptr
, &converted_size
);
289 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
290 make_parm_name(parm
->label
), fix_quotes(ctx
, utf8_s1
));
291 TALLOC_FREE(utf8_s1
);
292 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
293 _("Set Default"), make_parm_name(parm
->label
),fix_backslash((char *)(parm
->def
.svalue
)));
297 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
298 printf("<option %s>Yes", (*(bool *)ptr
)?"selected":"");
299 printf("<option %s>No", (*(bool *)ptr
)?"":"selected");
301 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
302 _("Set Default"), make_parm_name(parm
->label
),(bool)(parm
->def
.bvalue
)?0:1);
306 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
307 printf("<option %s>Yes", (*(bool *)ptr
)?"":"selected");
308 printf("<option %s>No", (*(bool *)ptr
)?"selected":"");
310 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
311 _("Set Default"), make_parm_name(parm
->label
),(bool)(parm
->def
.bvalue
)?1:0);
315 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm
->label
), *(int *)ptr
);
316 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
317 _("Set Default"), make_parm_name(parm
->label
),(int)(parm
->def
.ivalue
));
322 o
= octal_string(*(int *)ptr
);
323 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
324 make_parm_name(parm
->label
), o
);
326 o
= octal_string((int)(parm
->def
.ivalue
));
327 printf("<input type=button value=\"%s\" "
328 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
329 _("Set Default"), make_parm_name(parm
->label
), o
);
335 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
336 for (i
=0;parm
->enum_list
[i
].name
;i
++) {
337 if (i
== 0 || parm
->enum_list
[i
].value
!= parm
->enum_list
[i
-1].value
) {
338 printf("<option %s>%s",(*(int *)ptr
)==parm
->enum_list
[i
].value
?"selected":"",parm
->enum_list
[i
].name
);
342 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
343 _("Set Default"), make_parm_name(parm
->label
),enum_index((int)(parm
->def
.ivalue
),parm
->enum_list
));
348 printf("</td></tr>\n");
352 /****************************************************************************
353 display a set of parameters for a service
354 ****************************************************************************/
355 static void show_parameters(int snum
, int allparameters
, unsigned int parm_filter
, int printers
)
358 struct parm_struct
*parm
;
359 const char *heading
= NULL
;
360 const char *last_heading
= NULL
;
362 while ((parm
= lp_next_parameter(snum
, &i
, allparameters
))) {
363 if (snum
< 0 && parm
->p_class
== P_LOCAL
&& !(parm
->flags
& FLAG_GLOBAL
))
365 if (parm
->p_class
== P_SEPARATOR
) {
366 heading
= parm
->label
;
369 if (parm
->flags
& FLAG_HIDE
) continue;
371 if (printers
& !(parm
->flags
& FLAG_PRINT
)) continue;
372 if (!printers
& !(parm
->flags
& FLAG_SHARE
)) continue;
375 if (!( parm_filter
& FLAG_ADVANCED
)) {
376 if (!(parm
->flags
& FLAG_BASIC
)) {
377 void *ptr
= parm
->ptr
;
379 if (parm
->p_class
== P_LOCAL
&& snum
>= 0) {
380 ptr
= lp_local_ptr_by_snum(snum
, ptr
);
383 switch (parm
->type
) {
385 if (*(char *)ptr
== (char)(parm
->def
.cvalue
)) continue;
389 if (!str_list_equal(*(const char ***)ptr
,
390 (const char **)(parm
->def
.lvalue
))) continue;
395 if (!strcmp(*(char **)ptr
,(char *)(parm
->def
.svalue
))) continue;
400 if (*(bool *)ptr
== (bool)(parm
->def
.bvalue
)) continue;
405 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
410 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
416 if (printers
&& !(parm
->flags
& FLAG_PRINT
)) continue;
419 if ((parm_filter
& FLAG_WIZARD
) && !(parm
->flags
& FLAG_WIZARD
)) continue;
421 if ((parm_filter
& FLAG_ADVANCED
) && !(parm
->flags
& FLAG_ADVANCED
)) continue;
423 if (heading
&& heading
!= last_heading
) {
424 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading
));
425 last_heading
= heading
;
427 show_parameter(snum
, parm
);
431 /****************************************************************************
432 load the smb.conf file into loadparm.
433 ****************************************************************************/
434 static bool load_config(bool save_def
)
436 return lp_load(get_dyn_CONFIGFILE(),False
,save_def
,False
,True
);
439 /****************************************************************************
441 ****************************************************************************/
442 static void write_config(FILE *f
, bool show_defaults
)
444 TALLOC_CTX
*ctx
= talloc_stackframe();
446 fprintf(f
, "# Samba config file created using SWAT\n");
447 fprintf(f
, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
448 fprintf(f
, "# Date: %s\n\n", current_timestring(ctx
, False
));
450 lp_dump(f
, show_defaults
, iNumNonAutoPrintServices
);
455 /****************************************************************************
456 save and reload the smb.conf config file
457 ****************************************************************************/
458 static int save_reload(int snum
)
463 f
= sys_fopen(get_dyn_CONFIGFILE(),"w");
465 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
470 /* just in case they have used the buggy xinetd to create the file */
471 if (fstat(fileno(f
), &st
) == 0 &&
472 (st
.st_mode
& S_IWOTH
)) {
473 #if defined HAVE_FCHMOD
474 fchmod(fileno(f
), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
476 chmod(get_dyn_CONFIGFILE(), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
480 write_config(f
, False
);
482 lp_dump_one(f
, False
, snum
);
485 lp_kill_all_services();
487 if (!load_config(False
)) {
488 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
492 iNumNonAutoPrintServices
= lp_numservices();
498 /****************************************************************************
500 ****************************************************************************/
501 static void commit_parameter(int snum
, struct parm_struct
*parm
, const char *v
)
506 if (snum
< 0 && parm
->p_class
== P_LOCAL
) {
507 /* this handles the case where we are changing a local
508 variable globally. We need to change the parameter in
509 all shares where it is currently set to the default */
510 for (i
=0;i
<lp_numservices();i
++) {
511 s
= lp_servicename(i
);
512 if (s
&& (*s
) && lp_is_default(i
, parm
)) {
513 lp_do_parameter(i
, parm
->label
, v
);
518 lp_do_parameter(snum
, parm
->label
, v
);
521 /****************************************************************************
522 commit a set of parameters for a service
523 ****************************************************************************/
524 static void commit_parameters(int snum
)
527 struct parm_struct
*parm
;
531 while ((parm
= lp_next_parameter(snum
, &i
, 1))) {
532 if (asprintf(&label
, "parm_%s", make_parm_name(parm
->label
)) > 0) {
533 if ((v
= cgi_variable(label
)) != NULL
) {
534 if (parm
->flags
& FLAG_HIDE
)
536 commit_parameter(snum
, parm
, v
);
543 /****************************************************************************
544 spit out the html for a link with an image
545 ****************************************************************************/
546 static void image_link(const char *name
, const char *hlink
, const char *src
)
548 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
549 cgi_baseurl(), hlink
, src
, name
);
552 /****************************************************************************
553 display the main navigation controls at the top of each page along
555 ****************************************************************************/
556 static void show_main_buttons(void)
560 if ((p
= cgi_user_name()) && strcmp(p
, "root")) {
561 printf(_("Logged in as <b>%s</b>"), p
);
565 image_link(_("Home"), "", "images/home.gif");
566 if (have_write_access
) {
567 image_link(_("Globals"), "globals", "images/globals.gif");
568 image_link(_("Shares"), "shares", "images/shares.gif");
569 image_link(_("Printers"), "printers", "images/printers.gif");
570 image_link(_("Wizard"), "wizard", "images/wizard.gif");
572 /* root always gets all buttons, otherwise look for -P */
573 if ( have_write_access
|| (!passwd_only
&& have_read_access
) ) {
574 image_link(_("Status"), "status", "images/status.gif");
575 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
577 image_link(_("Password Management"), "passwd", "images/passwd.gif");
582 /****************************************************************************
583 * Handle Display/Edit Mode CGI
584 ****************************************************************************/
585 static void ViewModeBoxes(int mode
)
587 printf("<p>%s: \n", _("Current View Is"));
588 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode
== 0) ? "checked" : ""), _("Basic"));
589 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode
== 1) ? "checked" : ""), _("Advanced"));
590 printf("<br>%s: \n", _("Change View To"));
591 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
592 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
593 printf("</p><br>\n");
596 /****************************************************************************
597 display a welcome page
598 ****************************************************************************/
599 static void welcome_page(void)
601 if (file_exist("help/welcome.html")) {
602 include_html("help/welcome.html");
604 include_html("help/welcome-no-samba-doc.html");
608 /****************************************************************************
609 display the current smb.conf
610 ****************************************************************************/
611 static void viewconfig_page(void)
615 if (cgi_variable("full_view")) {
619 printf("<H2>%s</H2>\n", _("Current Config"));
620 printf("<form method=post>\n");
623 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
625 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
629 write_config(stdout
, full_view
);
634 /****************************************************************************
635 second screen of the wizard ... Fetch Configuration Parameters
636 ****************************************************************************/
637 static void wizard_params_page(void)
639 unsigned int parm_filter
= FLAG_WIZARD
;
641 /* Here we first set and commit all the parameters that were selected
642 in the previous screen. */
644 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
646 if (cgi_variable("Commit")) {
647 commit_parameters(GLOBAL_SECTION_SNUM
);
651 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
653 if (have_write_access
) {
654 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
657 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
661 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
662 printf("</table>\n");
666 /****************************************************************************
667 Utility to just rewrite the smb.conf file - effectively just cleans it up
668 ****************************************************************************/
669 static void rewritecfg_file(void)
671 commit_parameters(GLOBAL_SECTION_SNUM
);
673 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
676 /****************************************************************************
677 wizard to create/modify the smb.conf file
678 ****************************************************************************/
679 static void wizard_page(void)
681 /* Set some variables to collect data from smb.conf */
688 if (cgi_variable("Rewrite")) {
689 (void) rewritecfg_file();
693 if (cgi_variable("GetWizardParams")){
694 (void) wizard_params_page();
698 if (cgi_variable("Commit")){
699 SerType
= atoi(cgi_variable_nonull("ServerType"));
700 winstype
= atoi(cgi_variable_nonull("WINSType"));
701 have_home
= lp_servicenumber(HOMES_NAME
);
702 HomeExpo
= atoi(cgi_variable_nonull("HomeExpo"));
704 /* Plain text passwords are too badly broken - use encrypted passwords only */
705 lp_do_parameter( GLOBAL_SECTION_SNUM
, "encrypt passwords", "Yes");
709 /* Stand-alone Server */
710 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
711 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
715 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "DOMAIN" );
716 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
719 /* Domain Controller */
720 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
721 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "Yes" );
724 switch ( winstype
) {
726 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
727 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
730 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "Yes" );
731 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
734 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
735 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", cgi_variable_nonull("WINSAddr"));
739 /* Have to create Homes share? */
740 if ((HomeExpo
== 1) && (have_home
== -1)) {
741 const char *unix_share
= HOMES_NAME
;
744 lp_copy_service(GLOBAL_SECTION_SNUM
, unix_share
);
745 have_home
= lp_servicenumber(HOMES_NAME
);
746 lp_do_parameter( have_home
, "read only", "No");
747 lp_do_parameter( have_home
, "valid users", "%S");
748 lp_do_parameter( have_home
, "browseable", "No");
749 commit_parameters(have_home
);
750 save_reload(have_home
);
753 /* Need to Delete Homes share? */
754 if ((HomeExpo
== 0) && (have_home
!= -1)) {
755 lp_remove_service(have_home
);
759 commit_parameters(GLOBAL_SECTION_SNUM
);
764 /* Now determine smb.conf WINS settings */
765 if (lp_wins_support())
767 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
770 /* Do we have a homes share? */
771 have_home
= lp_servicenumber(HOMES_NAME
);
773 if ((winstype
== 2) && lp_wins_support())
776 role
= lp_server_role();
779 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
780 printf("<form method=post action=wizard>\n");
782 if (have_write_access
) {
783 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
784 printf("%s", _("The same will happen if you press the commit button."));
785 printf("<br><br>\n");
787 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
788 printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
789 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
790 printf("</center>\n");
794 printf("<center><table border=0>");
795 printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
796 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role
== ROLE_STANDALONE
) ? "checked" : ""), _("Stand Alone"));
797 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role
== ROLE_DOMAIN_MEMBER
) ? "checked" : ""), _("Domain Member"));
798 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role
== ROLE_DOMAIN_PDC
) ? "checked" : ""), _("Domain Controller"));
800 if (role
== ROLE_DOMAIN_BDC
) {
801 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
803 printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
804 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype
== 0) ? "checked" : ""), _("Not Used"));
805 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype
== 1) ? "checked" : ""), _("Server for client use"));
806 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype
== 2) ? "checked" : ""), _("Client of another WINS server"));
808 printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
810 /* Print out the list of wins servers */
811 if(lp_wins_server_list()) {
813 const char **wins_servers
= lp_wins_server_list();
814 for(i
= 0; wins_servers
[i
]; i
++) printf("%s ", wins_servers
[i
]);
817 printf("\"></td></tr>\n");
819 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"));
820 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
822 printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
823 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home
== -1) ? "" : "checked ");
824 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home
== -1 ) ? "checked" : "");
825 printf("<td></td></tr>\n");
827 /* Enable this when we are ready ....
828 * printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
829 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
830 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
831 * printf("<td></td></tr>\n");
834 printf("</table></center>");
837 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
842 /****************************************************************************
843 display a globals editing page
844 ****************************************************************************/
845 static void globals_page(void)
847 unsigned int parm_filter
= FLAG_BASIC
;
850 printf("<H2>%s</H2>\n", _("Global Parameters"));
852 if (cgi_variable("Commit")) {
853 commit_parameters(GLOBAL_SECTION_SNUM
);
857 if ( cgi_variable("ViewMode") )
858 mode
= atoi(cgi_variable_nonull("ViewMode"));
859 if ( cgi_variable("BasicMode"))
861 if ( cgi_variable("AdvMode"))
864 printf("<form name=\"swatform\" method=post action=globals>\n");
866 ViewModeBoxes( mode
);
869 parm_filter
= FLAG_BASIC
;
872 parm_filter
= FLAG_ADVANCED
;
876 if (have_write_access
) {
877 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
878 _("Commit Changes"));
881 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
886 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
887 printf("</table>\n");
891 /****************************************************************************
892 display a shares editing page. share is in unix codepage,
893 ****************************************************************************/
894 static void shares_page(void)
896 const char *share
= cgi_variable("share");
902 unsigned int parm_filter
= FLAG_BASIC
;
903 size_t converted_size
;
906 snum
= lp_servicenumber(share
);
908 printf("<H2>%s</H2>\n", _("Share Parameters"));
910 if (cgi_variable("Commit") && snum
>= 0) {
911 commit_parameters(snum
);
913 snum
= lp_servicenumber(share
);
916 if (cgi_variable("Delete") && snum
>= 0) {
917 lp_remove_service(snum
);
923 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
924 snum
= lp_servicenumber(share
);
927 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
928 snum
= lp_servicenumber(share
);
930 snum
= lp_servicenumber(share
);
934 printf("<FORM name=\"swatform\" method=post>\n");
938 if ( cgi_variable("ViewMode") )
939 mode
= atoi(cgi_variable_nonull("ViewMode"));
940 if ( cgi_variable("BasicMode"))
942 if ( cgi_variable("AdvMode"))
945 ViewModeBoxes( mode
);
948 parm_filter
= FLAG_BASIC
;
951 parm_filter
= FLAG_ADVANCED
;
954 printf("<br><tr>\n");
955 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
956 printf("<td><select name=share>\n");
958 printf("<option value=\" \"> \n");
959 for (i
=0;i
<lp_numservices();i
++) {
960 s
= lp_servicename(i
);
961 if (s
&& (*s
) && strcmp(s
,"IPC$") && !lp_print_ok(i
)) {
962 push_utf8_talloc(talloc_tos(), &utf8_s
, s
, &converted_size
);
963 printf("<option %s value=\"%s\">%s\n",
964 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
969 printf("</select></td>\n");
970 if (have_write_access
) {
971 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
976 if (have_write_access
) {
978 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
979 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
985 if (have_write_access
) {
986 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
989 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
995 show_parameters(snum
, 1, parm_filter
, 0);
996 printf("</table>\n");
1002 /*************************************************************
1003 change a password either locally or remotely
1004 *************************************************************/
1005 static bool change_password(const char *remote_machine
, const char *user_name
,
1006 const char *old_passwd
, const char *new_passwd
,
1010 char *err_str
= NULL
;
1011 char *msg_str
= NULL
;
1014 printf("%s\n<p>", _("password change in demo mode rejected"));
1018 if (remote_machine
!= NULL
) {
1019 ret
= remote_password_change(remote_machine
, user_name
,
1020 old_passwd
, new_passwd
, &err_str
);
1021 if (err_str
!= NULL
)
1022 printf("%s\n<p>", err_str
);
1024 return NT_STATUS_IS_OK(ret
);
1027 if(!initialize_password_db(True
, NULL
)) {
1028 printf("%s\n<p>", _("Can't setup password database vectors."));
1032 ret
= local_password_change(user_name
, local_flags
, new_passwd
,
1033 &err_str
, &msg_str
);
1036 printf("%s\n<p>", msg_str
);
1038 printf("%s\n<p>", err_str
);
1042 return NT_STATUS_IS_OK(ret
);
1045 /****************************************************************************
1046 do the stuff required to add or change a password
1047 ****************************************************************************/
1048 static void chg_passwd(void)
1052 int local_flags
= 0;
1054 /* Make sure users name has been specified */
1055 if (strlen(cgi_variable_nonull(SWAT_USER
)) == 0) {
1056 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1061 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1062 * so if that's what we're doing, skip the rest of the checks
1064 if (!cgi_variable(DISABLE_USER_FLAG
) && !cgi_variable(ENABLE_USER_FLAG
) && !cgi_variable(DELETE_USER_FLAG
)) {
1067 * If current user is not root, make sure old password has been specified
1068 * If REMOTE change, even root must provide old password
1070 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0)) ||
1071 ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0))) {
1072 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1076 /* If changing a users password on a remote hosts we have to know what host */
1077 if ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(RHOST
)) <= 0)) {
1078 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1082 /* Make sure new passwords have been specified */
1083 if ((strlen( cgi_variable_nonull(NEW_PSWD
)) <= 0) ||
1084 (strlen( cgi_variable_nonull(NEW2_PSWD
)) <= 0)) {
1085 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1089 /* Make sure new passwords was typed correctly twice */
1090 if (strcmp(cgi_variable_nonull(NEW_PSWD
), cgi_variable_nonull(NEW2_PSWD
)) != 0) {
1091 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1096 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1097 host
= cgi_variable(RHOST
);
1098 } else if (am_root()) {
1105 * Set up the local flags.
1108 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_ADD_USER
: 0);
1109 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1110 local_flags
|= (cgi_variable(CHG_S_PASSWD_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1111 local_flags
|= (cgi_variable(DELETE_USER_FLAG
) ? LOCAL_DELETE_USER
: 0);
1112 local_flags
|= (cgi_variable(ENABLE_USER_FLAG
) ? LOCAL_ENABLE_USER
: 0);
1113 local_flags
|= (cgi_variable(DISABLE_USER_FLAG
) ? LOCAL_DISABLE_USER
: 0);
1115 rslt
= change_password(host
,
1116 cgi_variable_nonull(SWAT_USER
),
1117 cgi_variable_nonull(OLD_PSWD
), cgi_variable_nonull(NEW_PSWD
),
1120 if(cgi_variable(CHG_S_PASSWD_FLAG
)) {
1123 printf(_(" The passwd for '%s' has been changed."), cgi_variable_nonull(SWAT_USER
));
1126 printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable_nonull(SWAT_USER
));
1134 /****************************************************************************
1135 display a password editing page
1136 ****************************************************************************/
1137 static void passwd_page(void)
1139 const char *new_name
= cgi_user_name();
1142 * After the first time through here be nice. If the user
1143 * changed the User box text to another users name, remember it.
1145 if (cgi_variable(SWAT_USER
)) {
1146 new_name
= cgi_variable_nonull(SWAT_USER
);
1149 if (!new_name
) new_name
= "";
1151 printf("<H2>%s</H2>\n", _("Server Password Management"));
1153 printf("<FORM name=\"swatform\" method=post>\n");
1155 printf("<table>\n");
1158 * Create all the dialog boxes for data collection
1160 printf("<tr><td> %s : </td>\n", _("User Name"));
1161 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER
, new_name
);
1163 printf("<tr><td> %s : </td>\n", _("Old Password"));
1164 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD
);
1166 printf("<tr><td> %s : </td>\n", _("New Password"));
1167 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1168 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1169 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1170 printf("</table>\n");
1173 * Create all the control buttons for requesting action
1175 printf("<input type=submit name=%s value=\"%s\">\n",
1176 CHG_S_PASSWD_FLAG
, _("Change Password"));
1177 if (demo_mode
|| am_root()) {
1178 printf("<input type=submit name=%s value=\"%s\">\n",
1179 ADD_USER_FLAG
, _("Add New User"));
1180 printf("<input type=submit name=%s value=\"%s\">\n",
1181 DELETE_USER_FLAG
, _("Delete User"));
1182 printf("<input type=submit name=%s value=\"%s\">\n",
1183 DISABLE_USER_FLAG
, _("Disable User"));
1184 printf("<input type=submit name=%s value=\"%s\">\n",
1185 ENABLE_USER_FLAG
, _("Enable User"));
1187 printf("<p></FORM>\n");
1190 * Do some work if change, add, disable or enable was
1191 * requested. It could be this is the first time through this
1192 * code, so there isn't anything to do. */
1193 if ((cgi_variable(CHG_S_PASSWD_FLAG
)) || (cgi_variable(ADD_USER_FLAG
)) || (cgi_variable(DELETE_USER_FLAG
)) ||
1194 (cgi_variable(DISABLE_USER_FLAG
)) || (cgi_variable(ENABLE_USER_FLAG
))) {
1198 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1200 printf("<FORM name=\"swatform\" method=post>\n");
1202 printf("<table>\n");
1205 * Create all the dialog boxes for data collection
1207 printf("<tr><td> %s : </td>\n", _("User Name"));
1208 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER
, new_name
);
1209 printf("<tr><td> %s : </td>\n", _("Old Password"));
1210 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD
);
1211 printf("<tr><td> %s : </td>\n", _("New Password"));
1212 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1213 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1214 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1215 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1216 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST
);
1221 * Create all the control buttons for requesting action
1223 printf("<input type=submit name=%s value=\"%s\">",
1224 CHG_R_PASSWD_FLAG
, _("Change Password"));
1226 printf("<p></FORM>\n");
1229 * Do some work if a request has been made to change the
1230 * password somewhere other than the server. It could be this
1231 * is the first time through this code, so there isn't
1232 * anything to do. */
1233 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1239 /****************************************************************************
1240 display a printers editing page
1241 ****************************************************************************/
1242 static void printers_page(void)
1244 const char *share
= cgi_variable("share");
1249 unsigned int parm_filter
= FLAG_BASIC
;
1252 snum
= lp_servicenumber(share
);
1254 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1256 printf("<H3>%s</H3>\n", _("Important Note:"));
1257 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1258 printf("%s",_("are autoloaded printers from "));
1259 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1260 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1262 if (cgi_variable("Commit") && snum
>= 0) {
1263 commit_parameters(snum
);
1264 if (snum
>= iNumNonAutoPrintServices
)
1268 snum
= lp_servicenumber(share
);
1271 if (cgi_variable("Delete") && snum
>= 0) {
1272 lp_remove_service(snum
);
1278 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
1279 snum
= lp_servicenumber(share
);
1280 if (snum
< 0 || snum
>= iNumNonAutoPrintServices
) {
1282 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
1283 snum
= lp_servicenumber(share
);
1284 lp_do_parameter(snum
, "print ok", "Yes");
1286 snum
= lp_servicenumber(share
);
1290 printf("<FORM name=\"swatform\" method=post>\n");
1292 if ( cgi_variable("ViewMode") )
1293 mode
= atoi(cgi_variable_nonull("ViewMode"));
1294 if ( cgi_variable("BasicMode"))
1296 if ( cgi_variable("AdvMode"))
1299 ViewModeBoxes( mode
);
1302 parm_filter
= FLAG_BASIC
;
1305 parm_filter
= FLAG_ADVANCED
;
1308 printf("<table>\n");
1309 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1310 printf("<td><select name=\"share\">\n");
1311 if (snum
< 0 || !lp_print_ok(snum
))
1312 printf("<option value=\" \"> \n");
1313 for (i
=0;i
<lp_numservices();i
++) {
1314 s
= lp_servicename(i
);
1315 if (s
&& (*s
) && strcmp(s
,"IPC$") && lp_print_ok(i
)) {
1316 if (i
>= iNumNonAutoPrintServices
)
1317 printf("<option %s value=\"%s\">[*]%s\n",
1318 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1321 printf("<option %s value=\"%s\">%s\n",
1322 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1326 printf("</select></td>");
1327 if (have_write_access
) {
1328 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1331 printf("</table>\n");
1333 if (have_write_access
) {
1334 printf("<table>\n");
1335 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1336 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1342 if (have_write_access
) {
1343 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1345 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1350 printf("<table>\n");
1351 show_parameters(snum
, 1, parm_filter
, 1);
1352 printf("</table>\n");
1354 printf("</FORM>\n");
1358 when the _() translation macro is used there is no obvious place to free
1359 the resulting string and there is no easy way to give a static pointer.
1360 All we can do is rotate between some static buffers and hope a single d_printf()
1361 doesn't have more calls to _() than the number of buffers
1364 const char *lang_msg_rotate(TALLOC_CTX
*ctx
, const char *msgid
)
1369 msgstr
= lang_msg(msgid
);
1374 ret
= talloc_strdup(ctx
, msgstr
);
1376 lang_msg_free(msgstr
);
1385 * main function for SWAT.
1387 int main(int argc
, char *argv
[])
1391 struct poptOption long_options
[] = {
1393 { "disable-authentication", 'a', POPT_ARG_VAL
, &demo_mode
, True
, "Disable authentication (demo mode)" },
1394 { "password-menu-only", 'P', POPT_ARG_VAL
, &passwd_only
, True
, "Show only change password menu" },
1398 TALLOC_CTX
*frame
= talloc_stackframe();
1401 umask(S_IWGRP
| S_IWOTH
);
1403 #if defined(HAVE_SET_AUTH_PARAMETERS)
1404 set_auth_parameters(argc
, argv
);
1405 #endif /* HAVE_SET_AUTH_PARAMETERS */
1407 /* just in case it goes wild ... */
1412 /* we don't want any SIGPIPE messages */
1413 BlockSignals(True
,SIGPIPE
);
1415 dbf
= x_fopen("/dev/null", O_WRONLY
, 0);
1416 if (!dbf
) dbf
= x_stderr
;
1418 /* we don't want stderr screwing us up */
1420 open("/dev/null", O_WRONLY
);
1422 pc
= poptGetContext("swat", argc
, (const char **) argv
, long_options
, 0);
1424 /* Parse command line options */
1426 while(poptGetNextOpt(pc
) != -1) { }
1428 poptFreeContext(pc
);
1432 setup_logging(argv
[0],False
);
1435 iNumNonAutoPrintServices
= lp_numservices();
1438 cgi_setup(get_dyn_SWATDIR(), !demo_mode
);
1442 cgi_load_variables();
1444 if (!file_exist(get_dyn_CONFIGFILE())) {
1445 have_read_access
= True
;
1446 have_write_access
= True
;
1448 /* check if the authenticated user has write access - if not then
1449 don't show write options */
1450 have_write_access
= (access(get_dyn_CONFIGFILE(),W_OK
) == 0);
1452 /* if the user doesn't have read access to smb.conf then
1453 don't let them view it */
1454 have_read_access
= (access(get_dyn_CONFIGFILE(),R_OK
) == 0);
1457 show_main_buttons();
1459 page
= cgi_pathinfo();
1461 /* Root gets full functionality */
1462 if (have_read_access
&& strcmp(page
, "globals")==0) {
1464 } else if (have_read_access
&& strcmp(page
,"shares")==0) {
1466 } else if (have_read_access
&& strcmp(page
,"printers")==0) {
1468 } else if (have_read_access
&& strcmp(page
,"status")==0) {
1470 } else if (have_read_access
&& strcmp(page
,"viewconfig")==0) {
1472 } else if (strcmp(page
,"passwd")==0) {
1474 } else if (have_read_access
&& strcmp(page
,"wizard")==0) {
1476 } else if (have_read_access
&& strcmp(page
,"wizard_params")==0) {
1477 wizard_params_page();
1478 } else if (have_read_access
&& strcmp(page
,"rewritecfg")==0) {