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(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_allocate(&utf8_s1
, *list
, &converted_size
);
259 push_utf8_allocate(&utf8_s2
, ((*(list
+1))?", ":""), &converted_size
);
260 printf(""%s"%s", utf8_s1
, utf8_s2
);
262 push_utf8_allocate(&utf8_s1
, *list
, &converted_size
);
263 push_utf8_allocate(&utf8_s2
, ((*(list
+1))?", ":""), &converted_size
);
264 printf("%s%s", utf8_s1
, 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_allocate(&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
));
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(snum
, ptr
);
383 switch (parm
->type
) {
385 if (*(char *)ptr
== (char)(parm
->def
.cvalue
)) continue;
389 if (!str_list_compare(*(char ***)ptr
, (char **)(parm
->def
.lvalue
))) continue;
394 if (!strcmp(*(char **)ptr
,(char *)(parm
->def
.svalue
))) continue;
399 if (*(bool *)ptr
== (bool)(parm
->def
.bvalue
)) continue;
404 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
409 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
415 if (printers
&& !(parm
->flags
& FLAG_PRINT
)) continue;
418 if ((parm_filter
& FLAG_WIZARD
) && !(parm
->flags
& FLAG_WIZARD
)) continue;
420 if ((parm_filter
& FLAG_ADVANCED
) && !(parm
->flags
& FLAG_ADVANCED
)) continue;
422 if (heading
&& heading
!= last_heading
) {
423 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading
));
424 last_heading
= heading
;
426 show_parameter(snum
, parm
);
430 /****************************************************************************
431 load the smb.conf file into loadparm.
432 ****************************************************************************/
433 static bool load_config(bool save_def
)
435 return lp_load(get_dyn_CONFIGFILE(),False
,save_def
,False
,True
);
438 /****************************************************************************
440 ****************************************************************************/
441 static void write_config(FILE *f
, bool show_defaults
)
443 TALLOC_CTX
*ctx
= talloc_stackframe();
445 fprintf(f
, "# Samba config file created using SWAT\n");
446 fprintf(f
, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
447 fprintf(f
, "# Date: %s\n\n", current_timestring(ctx
, False
));
449 lp_dump(f
, show_defaults
, iNumNonAutoPrintServices
);
454 /****************************************************************************
455 save and reload the smb.conf config file
456 ****************************************************************************/
457 static int save_reload(int snum
)
462 f
= sys_fopen(get_dyn_CONFIGFILE(),"w");
464 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
469 /* just in case they have used the buggy xinetd to create the file */
470 if (fstat(fileno(f
), &st
) == 0 &&
471 (st
.st_mode
& S_IWOTH
)) {
472 #if defined HAVE_FCHMOD
473 fchmod(fileno(f
), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
475 chmod(get_dyn_CONFIGFILE(), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
479 write_config(f
, False
);
481 lp_dump_one(f
, False
, snum
);
484 lp_kill_all_services();
486 if (!load_config(False
)) {
487 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
491 iNumNonAutoPrintServices
= lp_numservices();
497 /****************************************************************************
499 ****************************************************************************/
500 static void commit_parameter(int snum
, struct parm_struct
*parm
, const char *v
)
505 if (snum
< 0 && parm
->p_class
== P_LOCAL
) {
506 /* this handles the case where we are changing a local
507 variable globally. We need to change the parameter in
508 all shares where it is currently set to the default */
509 for (i
=0;i
<lp_numservices();i
++) {
510 s
= lp_servicename(i
);
511 if (s
&& (*s
) && lp_is_default(i
, parm
)) {
512 lp_do_parameter(i
, parm
->label
, v
);
517 lp_do_parameter(snum
, parm
->label
, v
);
520 /****************************************************************************
521 commit a set of parameters for a service
522 ****************************************************************************/
523 static void commit_parameters(int snum
)
526 struct parm_struct
*parm
;
530 while ((parm
= lp_next_parameter(snum
, &i
, 1))) {
531 if (asprintf(&label
, "parm_%s", make_parm_name(parm
->label
)) > 0) {
532 if ((v
= cgi_variable(label
)) != NULL
) {
533 if (parm
->flags
& FLAG_HIDE
)
535 commit_parameter(snum
, parm
, v
);
542 /****************************************************************************
543 spit out the html for a link with an image
544 ****************************************************************************/
545 static void image_link(const char *name
, const char *hlink
, const char *src
)
547 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
548 cgi_baseurl(), hlink
, src
, name
);
551 /****************************************************************************
552 display the main navigation controls at the top of each page along
554 ****************************************************************************/
555 static void show_main_buttons(void)
559 if ((p
= cgi_user_name()) && strcmp(p
, "root")) {
560 printf(_("Logged in as <b>%s</b>"), p
);
564 image_link(_("Home"), "", "images/home.gif");
565 if (have_write_access
) {
566 image_link(_("Globals"), "globals", "images/globals.gif");
567 image_link(_("Shares"), "shares", "images/shares.gif");
568 image_link(_("Printers"), "printers", "images/printers.gif");
569 image_link(_("Wizard"), "wizard", "images/wizard.gif");
571 /* root always gets all buttons, otherwise look for -P */
572 if ( have_write_access
|| (!passwd_only
&& have_read_access
) ) {
573 image_link(_("Status"), "status", "images/status.gif");
574 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
576 image_link(_("Password Management"), "passwd", "images/passwd.gif");
581 /****************************************************************************
582 * Handle Display/Edit Mode CGI
583 ****************************************************************************/
584 static void ViewModeBoxes(int mode
)
586 printf("<p>%s: \n", _("Current View Is"));
587 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode
== 0) ? "checked" : ""), _("Basic"));
588 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode
== 1) ? "checked" : ""), _("Advanced"));
589 printf("<br>%s: \n", _("Change View To"));
590 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
591 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
592 printf("</p><br>\n");
595 /****************************************************************************
596 display a welcome page
597 ****************************************************************************/
598 static void welcome_page(void)
600 if (file_exist("help/welcome.html", NULL
)) {
601 include_html("help/welcome.html");
603 include_html("help/welcome-no-samba-doc.html");
607 /****************************************************************************
608 display the current smb.conf
609 ****************************************************************************/
610 static void viewconfig_page(void)
614 if (cgi_variable("full_view")) {
618 printf("<H2>%s</H2>\n", _("Current Config"));
619 printf("<form method=post>\n");
622 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
624 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
628 write_config(stdout
, full_view
);
633 /****************************************************************************
634 second screen of the wizard ... Fetch Configuration Parameters
635 ****************************************************************************/
636 static void wizard_params_page(void)
638 unsigned int parm_filter
= FLAG_WIZARD
;
640 /* Here we first set and commit all the parameters that were selected
641 in the previous screen. */
643 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
645 if (cgi_variable("Commit")) {
646 commit_parameters(GLOBAL_SECTION_SNUM
);
650 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
652 if (have_write_access
) {
653 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
656 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
660 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
661 printf("</table>\n");
665 /****************************************************************************
666 Utility to just rewrite the smb.conf file - effectively just cleans it up
667 ****************************************************************************/
668 static void rewritecfg_file(void)
670 commit_parameters(GLOBAL_SECTION_SNUM
);
672 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
675 /****************************************************************************
676 wizard to create/modify the smb.conf file
677 ****************************************************************************/
678 static void wizard_page(void)
680 /* Set some variables to collect data from smb.conf */
687 if (cgi_variable("Rewrite")) {
688 (void) rewritecfg_file();
692 if (cgi_variable("GetWizardParams")){
693 (void) wizard_params_page();
697 if (cgi_variable("Commit")){
698 SerType
= atoi(cgi_variable_nonull("ServerType"));
699 winstype
= atoi(cgi_variable_nonull("WINSType"));
700 have_home
= lp_servicenumber(HOMES_NAME
);
701 HomeExpo
= atoi(cgi_variable_nonull("HomeExpo"));
703 /* Plain text passwords are too badly broken - use encrypted passwords only */
704 lp_do_parameter( GLOBAL_SECTION_SNUM
, "encrypt passwords", "Yes");
708 /* Stand-alone Server */
709 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
710 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
714 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "DOMAIN" );
715 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
718 /* Domain Controller */
719 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
720 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "Yes" );
723 switch ( winstype
) {
725 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
726 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
729 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "Yes" );
730 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
733 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
734 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", cgi_variable_nonull("WINSAddr"));
738 /* Have to create Homes share? */
739 if ((HomeExpo
== 1) && (have_home
== -1)) {
740 const char *unix_share
= HOMES_NAME
;
743 lp_copy_service(GLOBAL_SECTION_SNUM
, unix_share
);
744 have_home
= lp_servicenumber(HOMES_NAME
);
745 lp_do_parameter( have_home
, "read only", "No");
746 lp_do_parameter( have_home
, "valid users", "%S");
747 lp_do_parameter( have_home
, "browseable", "No");
748 commit_parameters(have_home
);
749 save_reload(have_home
);
752 /* Need to Delete Homes share? */
753 if ((HomeExpo
== 0) && (have_home
!= -1)) {
754 lp_remove_service(have_home
);
758 commit_parameters(GLOBAL_SECTION_SNUM
);
763 /* Now determine smb.conf WINS settings */
764 if (lp_wins_support())
766 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
769 /* Do we have a homes share? */
770 have_home
= lp_servicenumber(HOMES_NAME
);
772 if ((winstype
== 2) && lp_wins_support())
775 role
= lp_server_role();
778 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
779 printf("<form method=post action=wizard>\n");
781 if (have_write_access
) {
782 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
783 printf("%s", _("The same will happen if you press the commit button."));
784 printf("<br><br>\n");
786 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
787 printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
788 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
789 printf("</center>\n");
793 printf("<center><table border=0>");
794 printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
795 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role
== ROLE_STANDALONE
) ? "checked" : ""), _("Stand Alone"));
796 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role
== ROLE_DOMAIN_MEMBER
) ? "checked" : ""), _("Domain Member"));
797 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role
== ROLE_DOMAIN_PDC
) ? "checked" : ""), _("Domain Controller"));
799 if (role
== ROLE_DOMAIN_BDC
) {
800 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
802 printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
803 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype
== 0) ? "checked" : ""), _("Not Used"));
804 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype
== 1) ? "checked" : ""), _("Server for client use"));
805 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype
== 2) ? "checked" : ""), _("Client of another WINS server"));
807 printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
809 /* Print out the list of wins servers */
810 if(lp_wins_server_list()) {
812 const char **wins_servers
= lp_wins_server_list();
813 for(i
= 0; wins_servers
[i
]; i
++) printf("%s ", wins_servers
[i
]);
816 printf("\"></td></tr>\n");
818 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"));
819 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
821 printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
822 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home
== -1) ? "" : "checked ");
823 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home
== -1 ) ? "checked" : "");
824 printf("<td></td></tr>\n");
826 /* Enable this when we are ready ....
827 * printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
828 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
829 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
830 * printf("<td></td></tr>\n");
833 printf("</table></center>");
836 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
841 /****************************************************************************
842 display a globals editing page
843 ****************************************************************************/
844 static void globals_page(void)
846 unsigned int parm_filter
= FLAG_BASIC
;
849 printf("<H2>%s</H2>\n", _("Global Parameters"));
851 if (cgi_variable("Commit")) {
852 commit_parameters(GLOBAL_SECTION_SNUM
);
856 if ( cgi_variable("ViewMode") )
857 mode
= atoi(cgi_variable_nonull("ViewMode"));
858 if ( cgi_variable("BasicMode"))
860 if ( cgi_variable("AdvMode"))
863 printf("<form name=\"swatform\" method=post action=globals>\n");
865 ViewModeBoxes( mode
);
868 parm_filter
= FLAG_BASIC
;
871 parm_filter
= FLAG_ADVANCED
;
875 if (have_write_access
) {
876 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
877 _("Commit Changes"));
880 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
885 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
886 printf("</table>\n");
890 /****************************************************************************
891 display a shares editing page. share is in unix codepage,
892 ****************************************************************************/
893 static void shares_page(void)
895 const char *share
= cgi_variable("share");
901 unsigned int parm_filter
= FLAG_BASIC
;
902 size_t converted_size
;
905 snum
= lp_servicenumber(share
);
907 printf("<H2>%s</H2>\n", _("Share Parameters"));
909 if (cgi_variable("Commit") && snum
>= 0) {
910 commit_parameters(snum
);
912 snum
= lp_servicenumber(share
);
915 if (cgi_variable("Delete") && snum
>= 0) {
916 lp_remove_service(snum
);
922 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
923 snum
= lp_servicenumber(share
);
926 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
927 snum
= lp_servicenumber(share
);
929 snum
= lp_servicenumber(share
);
933 printf("<FORM name=\"swatform\" method=post>\n");
937 if ( cgi_variable("ViewMode") )
938 mode
= atoi(cgi_variable_nonull("ViewMode"));
939 if ( cgi_variable("BasicMode"))
941 if ( cgi_variable("AdvMode"))
944 ViewModeBoxes( mode
);
947 parm_filter
= FLAG_BASIC
;
950 parm_filter
= FLAG_ADVANCED
;
953 printf("<br><tr>\n");
954 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
955 printf("<td><select name=share>\n");
957 printf("<option value=\" \"> \n");
958 for (i
=0;i
<lp_numservices();i
++) {
959 s
= lp_servicename(i
);
960 if (s
&& (*s
) && strcmp(s
,"IPC$") && !lp_print_ok(i
)) {
961 push_utf8_allocate(&utf8_s
, s
, &converted_size
);
962 printf("<option %s value=\"%s\">%s\n",
963 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
968 printf("</select></td>\n");
969 if (have_write_access
) {
970 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
975 if (have_write_access
) {
977 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
978 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
984 if (have_write_access
) {
985 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
988 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
994 show_parameters(snum
, 1, parm_filter
, 0);
995 printf("</table>\n");
1001 /*************************************************************
1002 change a password either locally or remotely
1003 *************************************************************/
1004 static bool change_password(const char *remote_machine
, const char *user_name
,
1005 const char *old_passwd
, const char *new_passwd
,
1009 char *err_str
= NULL
;
1010 char *msg_str
= NULL
;
1013 printf("%s\n<p>", _("password change in demo mode rejected"));
1017 if (remote_machine
!= NULL
) {
1018 ret
= remote_password_change(remote_machine
, user_name
,
1019 old_passwd
, new_passwd
, &err_str
);
1020 if (err_str
!= NULL
)
1021 printf("%s\n<p>", err_str
);
1023 return NT_STATUS_IS_OK(ret
);
1026 if(!initialize_password_db(True
, NULL
)) {
1027 printf("%s\n<p>", _("Can't setup password database vectors."));
1031 ret
= local_password_change(user_name
, local_flags
, new_passwd
,
1032 &err_str
, &msg_str
);
1035 printf("%s\n<p>", msg_str
);
1037 printf("%s\n<p>", err_str
);
1041 return NT_STATUS_IS_OK(ret
);
1044 /****************************************************************************
1045 do the stuff required to add or change a password
1046 ****************************************************************************/
1047 static void chg_passwd(void)
1051 int local_flags
= 0;
1053 /* Make sure users name has been specified */
1054 if (strlen(cgi_variable_nonull(SWAT_USER
)) == 0) {
1055 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1060 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1061 * so if that's what we're doing, skip the rest of the checks
1063 if (!cgi_variable(DISABLE_USER_FLAG
) && !cgi_variable(ENABLE_USER_FLAG
) && !cgi_variable(DELETE_USER_FLAG
)) {
1066 * If current user is not root, make sure old password has been specified
1067 * If REMOTE change, even root must provide old password
1069 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0)) ||
1070 ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0))) {
1071 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1075 /* If changing a users password on a remote hosts we have to know what host */
1076 if ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(RHOST
)) <= 0)) {
1077 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1081 /* Make sure new passwords have been specified */
1082 if ((strlen( cgi_variable_nonull(NEW_PSWD
)) <= 0) ||
1083 (strlen( cgi_variable_nonull(NEW2_PSWD
)) <= 0)) {
1084 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1088 /* Make sure new passwords was typed correctly twice */
1089 if (strcmp(cgi_variable_nonull(NEW_PSWD
), cgi_variable_nonull(NEW2_PSWD
)) != 0) {
1090 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1095 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1096 host
= cgi_variable(RHOST
);
1097 } else if (am_root()) {
1104 * Set up the local flags.
1107 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_ADD_USER
: 0);
1108 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1109 local_flags
|= (cgi_variable(CHG_S_PASSWD_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1110 local_flags
|= (cgi_variable(DELETE_USER_FLAG
) ? LOCAL_DELETE_USER
: 0);
1111 local_flags
|= (cgi_variable(ENABLE_USER_FLAG
) ? LOCAL_ENABLE_USER
: 0);
1112 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("%s\n", _(" The passwd has been changed."));
1125 printf("%s\n", _(" The passwd for has NOT been changed."));
1132 /****************************************************************************
1133 display a password editing page
1134 ****************************************************************************/
1135 static void passwd_page(void)
1137 const char *new_name
= cgi_user_name();
1139 if (!new_name
) new_name
= "";
1141 printf("<H2>%s</H2>\n", _("Server Password Management"));
1143 printf("<FORM name=\"swatform\" method=post>\n");
1145 printf("<table>\n");
1148 * Create all the dialog boxes for data collection
1150 printf("<tr><td> %s : </td>\n", _("User Name"));
1151 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER
, new_name
);
1153 printf("<tr><td> %s : </td>\n", _("Old Password"));
1154 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD
);
1156 printf("<tr><td> %s : </td>\n", _("New Password"));
1157 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1158 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1159 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1160 printf("</table>\n");
1163 * Create all the control buttons for requesting action
1165 printf("<input type=submit name=%s value=\"%s\">\n",
1166 CHG_S_PASSWD_FLAG
, _("Change Password"));
1167 if (demo_mode
|| am_root()) {
1168 printf("<input type=submit name=%s value=\"%s\">\n",
1169 ADD_USER_FLAG
, _("Add New User"));
1170 printf("<input type=submit name=%s value=\"%s\">\n",
1171 DELETE_USER_FLAG
, _("Delete User"));
1172 printf("<input type=submit name=%s value=\"%s\">\n",
1173 DISABLE_USER_FLAG
, _("Disable User"));
1174 printf("<input type=submit name=%s value=\"%s\">\n",
1175 ENABLE_USER_FLAG
, _("Enable User"));
1177 printf("<p></FORM>\n");
1180 * Do some work if change, add, disable or enable was
1181 * requested. It could be this is the first time through this
1182 * code, so there isn't anything to do. */
1183 if ((cgi_variable(CHG_S_PASSWD_FLAG
)) || (cgi_variable(ADD_USER_FLAG
)) || (cgi_variable(DELETE_USER_FLAG
)) ||
1184 (cgi_variable(DISABLE_USER_FLAG
)) || (cgi_variable(ENABLE_USER_FLAG
))) {
1188 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1190 printf("<FORM name=\"swatform\" method=post>\n");
1192 printf("<table>\n");
1195 * Create all the dialog boxes for data collection
1197 printf("<tr><td> %s : </td>\n", _("User Name"));
1198 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER
, new_name
);
1199 printf("<tr><td> %s : </td>\n", _("Old Password"));
1200 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD
);
1201 printf("<tr><td> %s : </td>\n", _("New Password"));
1202 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1203 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1204 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1205 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1206 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST
);
1211 * Create all the control buttons for requesting action
1213 printf("<input type=submit name=%s value=\"%s\">",
1214 CHG_R_PASSWD_FLAG
, _("Change Password"));
1216 printf("<p></FORM>\n");
1219 * Do some work if a request has been made to change the
1220 * password somewhere other than the server. It could be this
1221 * is the first time through this code, so there isn't
1222 * anything to do. */
1223 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1229 /****************************************************************************
1230 display a printers editing page
1231 ****************************************************************************/
1232 static void printers_page(void)
1234 const char *share
= cgi_variable("share");
1239 unsigned int parm_filter
= FLAG_BASIC
;
1242 snum
= lp_servicenumber(share
);
1244 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1246 printf("<H3>%s</H3>\n", _("Important Note:"));
1247 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1248 printf("%s",_("are autoloaded printers from "));
1249 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1250 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1252 if (cgi_variable("Commit") && snum
>= 0) {
1253 commit_parameters(snum
);
1254 if (snum
>= iNumNonAutoPrintServices
)
1258 snum
= lp_servicenumber(share
);
1261 if (cgi_variable("Delete") && snum
>= 0) {
1262 lp_remove_service(snum
);
1268 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
1269 snum
= lp_servicenumber(share
);
1270 if (snum
< 0 || snum
>= iNumNonAutoPrintServices
) {
1272 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
1273 snum
= lp_servicenumber(share
);
1274 lp_do_parameter(snum
, "print ok", "Yes");
1276 snum
= lp_servicenumber(share
);
1280 printf("<FORM name=\"swatform\" method=post>\n");
1282 if ( cgi_variable("ViewMode") )
1283 mode
= atoi(cgi_variable_nonull("ViewMode"));
1284 if ( cgi_variable("BasicMode"))
1286 if ( cgi_variable("AdvMode"))
1289 ViewModeBoxes( mode
);
1292 parm_filter
= FLAG_BASIC
;
1295 parm_filter
= FLAG_ADVANCED
;
1298 printf("<table>\n");
1299 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1300 printf("<td><select name=\"share\">\n");
1301 if (snum
< 0 || !lp_print_ok(snum
))
1302 printf("<option value=\" \"> \n");
1303 for (i
=0;i
<lp_numservices();i
++) {
1304 s
= lp_servicename(i
);
1305 if (s
&& (*s
) && strcmp(s
,"IPC$") && lp_print_ok(i
)) {
1306 if (i
>= iNumNonAutoPrintServices
)
1307 printf("<option %s value=\"%s\">[*]%s\n",
1308 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1311 printf("<option %s value=\"%s\">%s\n",
1312 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1316 printf("</select></td>");
1317 if (have_write_access
) {
1318 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1321 printf("</table>\n");
1323 if (have_write_access
) {
1324 printf("<table>\n");
1325 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1326 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1332 if (have_write_access
) {
1333 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1335 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1340 printf("<table>\n");
1341 show_parameters(snum
, 1, parm_filter
, 1);
1342 printf("</table>\n");
1344 printf("</FORM>\n");
1348 when the _() translation macro is used there is no obvious place to free
1349 the resulting string and there is no easy way to give a static pointer.
1350 All we can do is rotate between some static buffers and hope a single d_printf()
1351 doesn't have more calls to _() than the number of buffers
1354 const char *lang_msg_rotate(TALLOC_CTX
*ctx
, const char *msgid
)
1359 msgstr
= lang_msg(msgid
);
1364 ret
= talloc_strdup(ctx
, msgstr
);
1366 lang_msg_free(msgstr
);
1375 * main function for SWAT.
1377 int main(int argc
, char *argv
[])
1381 struct poptOption long_options
[] = {
1383 { "disable-authentication", 'a', POPT_ARG_VAL
, &demo_mode
, True
, "Disable authentication (demo mode)" },
1384 { "password-menu-only", 'P', POPT_ARG_VAL
, &passwd_only
, True
, "Show only change password menu" },
1388 TALLOC_CTX
*frame
= talloc_stackframe();
1391 umask(S_IWGRP
| S_IWOTH
);
1393 #if defined(HAVE_SET_AUTH_PARAMETERS)
1394 set_auth_parameters(argc
, argv
);
1395 #endif /* HAVE_SET_AUTH_PARAMETERS */
1397 /* just in case it goes wild ... */
1402 /* we don't want any SIGPIPE messages */
1403 BlockSignals(True
,SIGPIPE
);
1405 dbf
= x_fopen("/dev/null", O_WRONLY
, 0);
1406 if (!dbf
) dbf
= x_stderr
;
1408 /* we don't want stderr screwing us up */
1410 open("/dev/null", O_WRONLY
);
1412 pc
= poptGetContext("swat", argc
, (const char **) argv
, long_options
, 0);
1414 /* Parse command line options */
1416 while(poptGetNextOpt(pc
) != -1) { }
1418 poptFreeContext(pc
);
1422 setup_logging(argv
[0],False
);
1425 iNumNonAutoPrintServices
= lp_numservices();
1428 cgi_setup(get_dyn_SWATDIR(), !demo_mode
);
1432 cgi_load_variables();
1434 if (!file_exist(get_dyn_CONFIGFILE(), NULL
)) {
1435 have_read_access
= True
;
1436 have_write_access
= True
;
1438 /* check if the authenticated user has write access - if not then
1439 don't show write options */
1440 have_write_access
= (access(get_dyn_CONFIGFILE(),W_OK
) == 0);
1442 /* if the user doesn't have read access to smb.conf then
1443 don't let them view it */
1444 have_read_access
= (access(get_dyn_CONFIGFILE(),R_OK
) == 0);
1447 show_main_buttons();
1449 page
= cgi_pathinfo();
1451 /* Root gets full functionality */
1452 if (have_read_access
&& strcmp(page
, "globals")==0) {
1454 } else if (have_read_access
&& strcmp(page
,"shares")==0) {
1456 } else if (have_read_access
&& strcmp(page
,"printers")==0) {
1458 } else if (have_read_access
&& strcmp(page
,"status")==0) {
1460 } else if (have_read_access
&& strcmp(page
,"viewconfig")==0) {
1462 } else if (strcmp(page
,"passwd")==0) {
1464 } else if (have_read_access
&& strcmp(page
,"wizard")==0) {
1466 } else if (have_read_access
&& strcmp(page
,"wizard_params")==0) {
1467 wizard_params_page();
1468 } else if (have_read_access
&& strcmp(page
,"rewritecfg")==0) {