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 size_t converted_size
;
232 TALLOC_CTX
*ctx
= talloc_stackframe();
234 if (parm
->p_class
== P_LOCAL
&& snum
>= 0) {
235 ptr
= lp_local_ptr(snum
, ptr
);
238 printf("<tr><td>%s</td><td>", get_parm_translated(ctx
,
239 stripspaceupper(parm
->label
), _("Help"), parm
->label
));
240 switch (parm
->type
) {
242 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
243 make_parm_name(parm
->label
), *(char *)ptr
);
244 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
245 _("Set Default"), make_parm_name(parm
->label
),(char)(parm
->def
.cvalue
));
249 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
250 make_parm_name(parm
->label
));
251 if ((char ***)ptr
&& *(char ***)ptr
&& **(char ***)ptr
) {
252 char **list
= *(char ***)ptr
;
253 for (;*list
;list
++) {
254 /* enclose in HTML encoded quotes if the string contains a space */
255 if ( strchr_m(*list
, ' ') ) {
256 push_utf8_allocate(&utf8_s1
, *list
, &converted_size
);
257 push_utf8_allocate(&utf8_s2
, ((*(list
+1))?", ":""), &converted_size
);
258 printf(""%s"%s", utf8_s1
, utf8_s2
);
260 push_utf8_allocate(&utf8_s1
, *list
, &converted_size
);
261 push_utf8_allocate(&utf8_s2
, ((*(list
+1))?", ":""), &converted_size
);
262 printf("%s%s", utf8_s1
, utf8_s2
);
269 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
270 _("Set Default"), make_parm_name(parm
->label
));
271 if (parm
->def
.lvalue
) {
272 char **list
= (char **)(parm
->def
.lvalue
);
273 for (; *list
; list
++) {
274 /* enclose in HTML encoded quotes if the string contains a space */
275 if ( strchr_m(*list
, ' ') )
276 printf(""%s"%s", *list
, ((*(list
+1))?", ":""));
278 printf("%s%s", *list
, ((*(list
+1))?", ":""));
286 push_utf8_allocate(&utf8_s1
, *(char **)ptr
, &converted_size
);
287 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
288 make_parm_name(parm
->label
), fix_quotes(ctx
, utf8_s1
));
290 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
291 _("Set Default"), make_parm_name(parm
->label
),fix_backslash((char *)(parm
->def
.svalue
)));
295 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
296 printf("<option %s>Yes", (*(bool *)ptr
)?"selected":"");
297 printf("<option %s>No", (*(bool *)ptr
)?"":"selected");
299 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
300 _("Set Default"), make_parm_name(parm
->label
),(bool)(parm
->def
.bvalue
)?0:1);
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
)?1:0);
313 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm
->label
), *(int *)ptr
);
314 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
315 _("Set Default"), make_parm_name(parm
->label
),(int)(parm
->def
.ivalue
));
320 o
= octal_string(*(int *)ptr
);
321 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
322 make_parm_name(parm
->label
), o
);
324 o
= octal_string((int)(parm
->def
.ivalue
));
325 printf("<input type=button value=\"%s\" "
326 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
327 _("Set Default"), make_parm_name(parm
->label
), o
);
333 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
334 for (i
=0;parm
->enum_list
[i
].name
;i
++) {
335 if (i
== 0 || parm
->enum_list
[i
].value
!= parm
->enum_list
[i
-1].value
) {
336 printf("<option %s>%s",(*(int *)ptr
)==parm
->enum_list
[i
].value
?"selected":"",parm
->enum_list
[i
].name
);
340 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
341 _("Set Default"), make_parm_name(parm
->label
),enum_index((int)(parm
->def
.ivalue
),parm
->enum_list
));
346 printf("</td></tr>\n");
350 /****************************************************************************
351 display a set of parameters for a service
352 ****************************************************************************/
353 static void show_parameters(int snum
, int allparameters
, unsigned int parm_filter
, int printers
)
356 struct parm_struct
*parm
;
357 const char *heading
= NULL
;
358 const char *last_heading
= NULL
;
360 while ((parm
= lp_next_parameter(snum
, &i
, allparameters
))) {
361 if (snum
< 0 && parm
->p_class
== P_LOCAL
&& !(parm
->flags
& FLAG_GLOBAL
))
363 if (parm
->p_class
== P_SEPARATOR
) {
364 heading
= parm
->label
;
367 if (parm
->flags
& FLAG_HIDE
) continue;
369 if (printers
& !(parm
->flags
& FLAG_PRINT
)) continue;
370 if (!printers
& !(parm
->flags
& FLAG_SHARE
)) continue;
373 if (!( parm_filter
& FLAG_ADVANCED
)) {
374 if (!(parm
->flags
& FLAG_BASIC
)) {
375 void *ptr
= parm
->ptr
;
377 if (parm
->p_class
== P_LOCAL
&& snum
>= 0) {
378 ptr
= lp_local_ptr(snum
, ptr
);
381 switch (parm
->type
) {
383 if (*(char *)ptr
== (char)(parm
->def
.cvalue
)) continue;
387 if (!str_list_compare(*(char ***)ptr
, (char **)(parm
->def
.lvalue
))) continue;
392 if (!strcmp(*(char **)ptr
,(char *)(parm
->def
.svalue
))) continue;
397 if (*(bool *)ptr
== (bool)(parm
->def
.bvalue
)) continue;
402 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
407 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
413 if (printers
&& !(parm
->flags
& FLAG_PRINT
)) continue;
416 if ((parm_filter
& FLAG_WIZARD
) && !(parm
->flags
& FLAG_WIZARD
)) continue;
418 if ((parm_filter
& FLAG_ADVANCED
) && !(parm
->flags
& FLAG_ADVANCED
)) continue;
420 if (heading
&& heading
!= last_heading
) {
421 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading
));
422 last_heading
= heading
;
424 show_parameter(snum
, parm
);
428 /****************************************************************************
429 load the smb.conf file into loadparm.
430 ****************************************************************************/
431 static bool load_config(bool save_def
)
433 lp_resetnumservices();
434 return lp_load(get_dyn_CONFIGFILE(),False
,save_def
,False
,True
);
437 /****************************************************************************
439 ****************************************************************************/
440 static void write_config(FILE *f
, bool show_defaults
)
442 TALLOC_CTX
*ctx
= talloc_stackframe();
444 fprintf(f
, "# Samba config file created using SWAT\n");
445 fprintf(f
, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
446 fprintf(f
, "# Date: %s\n\n", current_timestring(ctx
, False
));
448 lp_dump(f
, show_defaults
, iNumNonAutoPrintServices
);
453 /****************************************************************************
454 save and reload the smb.conf config file
455 ****************************************************************************/
456 static int save_reload(int snum
)
461 f
= sys_fopen(get_dyn_CONFIGFILE(),"w");
463 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
468 /* just in case they have used the buggy xinetd to create the file */
469 if (fstat(fileno(f
), &st
) == 0 &&
470 (st
.st_mode
& S_IWOTH
)) {
471 #if defined HAVE_FCHMOD
472 fchmod(fileno(f
), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
474 chmod(get_dyn_CONFIGFILE(), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
478 write_config(f
, False
);
480 lp_dump_one(f
, False
, snum
);
483 lp_kill_all_services();
485 if (!load_config(False
)) {
486 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
490 iNumNonAutoPrintServices
= lp_numservices();
496 /****************************************************************************
498 ****************************************************************************/
499 static void commit_parameter(int snum
, struct parm_struct
*parm
, const char *v
)
504 if (snum
< 0 && parm
->p_class
== P_LOCAL
) {
505 /* this handles the case where we are changing a local
506 variable globally. We need to change the parameter in
507 all shares where it is currently set to the default */
508 for (i
=0;i
<lp_numservices();i
++) {
509 s
= lp_servicename(i
);
510 if (s
&& (*s
) && lp_is_default(i
, parm
)) {
511 lp_do_parameter(i
, parm
->label
, v
);
516 lp_do_parameter(snum
, parm
->label
, v
);
519 /****************************************************************************
520 commit a set of parameters for a service
521 ****************************************************************************/
522 static void commit_parameters(int snum
)
525 struct parm_struct
*parm
;
529 while ((parm
= lp_next_parameter(snum
, &i
, 1))) {
530 if (asprintf(&label
, "parm_%s", make_parm_name(parm
->label
)) > 0) {
531 if ((v
= cgi_variable(label
)) != NULL
) {
532 if (parm
->flags
& FLAG_HIDE
)
534 commit_parameter(snum
, parm
, v
);
541 /****************************************************************************
542 spit out the html for a link with an image
543 ****************************************************************************/
544 static void image_link(const char *name
, const char *hlink
, const char *src
)
546 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
547 cgi_baseurl(), hlink
, src
, name
);
550 /****************************************************************************
551 display the main navigation controls at the top of each page along
553 ****************************************************************************/
554 static void show_main_buttons(void)
558 if ((p
= cgi_user_name()) && strcmp(p
, "root")) {
559 printf(_("Logged in as <b>%s</b>"), p
);
563 image_link(_("Home"), "", "images/home.gif");
564 if (have_write_access
) {
565 image_link(_("Globals"), "globals", "images/globals.gif");
566 image_link(_("Shares"), "shares", "images/shares.gif");
567 image_link(_("Printers"), "printers", "images/printers.gif");
568 image_link(_("Wizard"), "wizard", "images/wizard.gif");
570 /* root always gets all buttons, otherwise look for -P */
571 if ( have_write_access
|| (!passwd_only
&& have_read_access
) ) {
572 image_link(_("Status"), "status", "images/status.gif");
573 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
575 image_link(_("Password Management"), "passwd", "images/passwd.gif");
580 /****************************************************************************
581 * Handle Display/Edit Mode CGI
582 ****************************************************************************/
583 static void ViewModeBoxes(int mode
)
585 printf("<p>%s: \n", _("Current View Is"));
586 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode
== 0) ? "checked" : ""), _("Basic"));
587 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode
== 1) ? "checked" : ""), _("Advanced"));
588 printf("<br>%s: \n", _("Change View To"));
589 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
590 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
591 printf("</p><br>\n");
594 /****************************************************************************
595 display a welcome page
596 ****************************************************************************/
597 static void welcome_page(void)
599 if (file_exist("help/welcome.html", NULL
)) {
600 include_html("help/welcome.html");
602 include_html("help/welcome-no-samba-doc.html");
606 /****************************************************************************
607 display the current smb.conf
608 ****************************************************************************/
609 static void viewconfig_page(void)
613 if (cgi_variable("full_view")) {
617 printf("<H2>%s</H2>\n", _("Current Config"));
618 printf("<form method=post>\n");
621 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
623 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
627 write_config(stdout
, full_view
);
632 /****************************************************************************
633 second screen of the wizard ... Fetch Configuration Parameters
634 ****************************************************************************/
635 static void wizard_params_page(void)
637 unsigned int parm_filter
= FLAG_WIZARD
;
639 /* Here we first set and commit all the parameters that were selected
640 in the previous screen. */
642 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
644 if (cgi_variable("Commit")) {
645 commit_parameters(GLOBAL_SECTION_SNUM
);
649 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
651 if (have_write_access
) {
652 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
655 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
659 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
660 printf("</table>\n");
664 /****************************************************************************
665 Utility to just rewrite the smb.conf file - effectively just cleans it up
666 ****************************************************************************/
667 static void rewritecfg_file(void)
669 commit_parameters(GLOBAL_SECTION_SNUM
);
671 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
674 /****************************************************************************
675 wizard to create/modify the smb.conf file
676 ****************************************************************************/
677 static void wizard_page(void)
679 /* Set some variables to collect data from smb.conf */
686 if (cgi_variable("Rewrite")) {
687 (void) rewritecfg_file();
691 if (cgi_variable("GetWizardParams")){
692 (void) wizard_params_page();
696 if (cgi_variable("Commit")){
697 SerType
= atoi(cgi_variable_nonull("ServerType"));
698 winstype
= atoi(cgi_variable_nonull("WINSType"));
699 have_home
= lp_servicenumber(HOMES_NAME
);
700 HomeExpo
= atoi(cgi_variable_nonull("HomeExpo"));
702 /* Plain text passwords are too badly broken - use encrypted passwords only */
703 lp_do_parameter( GLOBAL_SECTION_SNUM
, "encrypt passwords", "Yes");
707 /* Stand-alone Server */
708 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
709 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
713 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "DOMAIN" );
714 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
717 /* Domain Controller */
718 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
719 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "Yes" );
722 switch ( winstype
) {
724 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
725 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
728 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "Yes" );
729 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
732 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
733 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", cgi_variable_nonull("WINSAddr"));
737 /* Have to create Homes share? */
738 if ((HomeExpo
== 1) && (have_home
== -1)) {
739 const char *unix_share
= HOMES_NAME
;
742 lp_copy_service(GLOBAL_SECTION_SNUM
, unix_share
);
743 iNumNonAutoPrintServices
= lp_numservices();
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
);
751 /* Need to Delete Homes share? */
752 if ((HomeExpo
== 0) && (have_home
!= -1)) {
753 lp_remove_service(have_home
);
757 commit_parameters(GLOBAL_SECTION_SNUM
);
762 /* Now determine smb.conf WINS settings */
763 if (lp_wins_support())
765 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
768 /* Do we have a homes share? */
769 have_home
= lp_servicenumber(HOMES_NAME
);
771 if ((winstype
== 2) && lp_wins_support())
774 role
= lp_server_role();
777 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
778 printf("<form method=post action=wizard>\n");
780 if (have_write_access
) {
781 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
782 printf("%s", _("The same will happen if you press the commit button."));
783 printf("<br><br>\n");
785 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
786 printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
787 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
788 printf("</center>\n");
792 printf("<center><table border=0>");
793 printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
794 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role
== ROLE_STANDALONE
) ? "checked" : ""), _("Stand Alone"));
795 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role
== ROLE_DOMAIN_MEMBER
) ? "checked" : ""), _("Domain Member"));
796 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role
== ROLE_DOMAIN_PDC
) ? "checked" : ""), _("Domain Controller"));
798 if (role
== ROLE_DOMAIN_BDC
) {
799 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
801 printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
802 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype
== 0) ? "checked" : ""), _("Not Used"));
803 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype
== 1) ? "checked" : ""), _("Server for client use"));
804 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype
== 2) ? "checked" : ""), _("Client of another WINS server"));
806 printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
808 /* Print out the list of wins servers */
809 if(lp_wins_server_list()) {
811 const char **wins_servers
= lp_wins_server_list();
812 for(i
= 0; wins_servers
[i
]; i
++) printf("%s ", wins_servers
[i
]);
815 printf("\"></td></tr>\n");
817 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"));
818 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
820 printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
821 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home
== -1) ? "" : "checked ");
822 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home
== -1 ) ? "checked" : "");
823 printf("<td></td></tr>\n");
825 /* Enable this when we are ready ....
826 * printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
827 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
828 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
829 * printf("<td></td></tr>\n");
832 printf("</table></center>");
835 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
840 /****************************************************************************
841 display a globals editing page
842 ****************************************************************************/
843 static void globals_page(void)
845 unsigned int parm_filter
= FLAG_BASIC
;
848 printf("<H2>%s</H2>\n", _("Global Parameters"));
850 if (cgi_variable("Commit")) {
851 commit_parameters(GLOBAL_SECTION_SNUM
);
855 if ( cgi_variable("ViewMode") )
856 mode
= atoi(cgi_variable_nonull("ViewMode"));
857 if ( cgi_variable("BasicMode"))
859 if ( cgi_variable("AdvMode"))
862 printf("<form name=\"swatform\" method=post action=globals>\n");
864 ViewModeBoxes( mode
);
867 parm_filter
= FLAG_BASIC
;
870 parm_filter
= FLAG_ADVANCED
;
874 if (have_write_access
) {
875 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
876 _("Commit Changes"));
879 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
884 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
885 printf("</table>\n");
889 /****************************************************************************
890 display a shares editing page. share is in unix codepage,
891 ****************************************************************************/
892 static void shares_page(void)
894 const char *share
= cgi_variable("share");
900 unsigned int parm_filter
= FLAG_BASIC
;
901 size_t converted_size
;
904 snum
= lp_servicenumber(share
);
906 printf("<H2>%s</H2>\n", _("Share Parameters"));
908 if (cgi_variable("Commit") && snum
>= 0) {
909 commit_parameters(snum
);
913 if (cgi_variable("Delete") && snum
>= 0) {
914 lp_remove_service(snum
);
920 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
922 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
923 iNumNonAutoPrintServices
= lp_numservices();
925 snum
= lp_servicenumber(share
);
928 printf("<FORM name=\"swatform\" method=post>\n");
932 if ( cgi_variable("ViewMode") )
933 mode
= atoi(cgi_variable_nonull("ViewMode"));
934 if ( cgi_variable("BasicMode"))
936 if ( cgi_variable("AdvMode"))
939 ViewModeBoxes( mode
);
942 parm_filter
= FLAG_BASIC
;
945 parm_filter
= FLAG_ADVANCED
;
948 printf("<br><tr>\n");
949 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
950 printf("<td><select name=share>\n");
952 printf("<option value=\" \"> \n");
953 for (i
=0;i
<lp_numservices();i
++) {
954 s
= lp_servicename(i
);
955 if (s
&& (*s
) && strcmp(s
,"IPC$") && !lp_print_ok(i
)) {
956 push_utf8_allocate(&utf8_s
, s
, &converted_size
);
957 printf("<option %s value=\"%s\">%s\n",
958 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
964 printf("</select></td>\n");
965 if (have_write_access
) {
966 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
971 if (have_write_access
) {
973 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
974 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
980 if (have_write_access
) {
981 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
984 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
990 show_parameters(snum
, 1, parm_filter
, 0);
991 printf("</table>\n");
997 /*************************************************************
998 change a password either locally or remotely
999 *************************************************************/
1000 static bool change_password(const char *remote_machine
, const char *user_name
,
1001 const char *old_passwd
, const char *new_passwd
,
1005 char *err_str
= NULL
;
1006 char *msg_str
= NULL
;
1009 printf("%s\n<p>", _("password change in demo mode rejected"));
1013 if (remote_machine
!= NULL
) {
1014 ret
= remote_password_change(remote_machine
, user_name
,
1015 old_passwd
, new_passwd
, &err_str
);
1016 if (err_str
!= NULL
)
1017 printf("%s\n<p>", err_str
);
1019 return NT_STATUS_IS_OK(ret
);
1022 if(!initialize_password_db(True
, NULL
)) {
1023 printf("%s\n<p>", _("Can't setup password database vectors."));
1027 ret
= local_password_change(user_name
, local_flags
, new_passwd
,
1028 &err_str
, &msg_str
);
1031 printf("%s\n<p>", msg_str
);
1033 printf("%s\n<p>", err_str
);
1037 return NT_STATUS_IS_OK(ret
);
1040 /****************************************************************************
1041 do the stuff required to add or change a password
1042 ****************************************************************************/
1043 static void chg_passwd(void)
1047 int local_flags
= 0;
1049 /* Make sure users name has been specified */
1050 if (strlen(cgi_variable_nonull(SWAT_USER
)) == 0) {
1051 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1056 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1057 * so if that's what we're doing, skip the rest of the checks
1059 if (!cgi_variable(DISABLE_USER_FLAG
) && !cgi_variable(ENABLE_USER_FLAG
) && !cgi_variable(DELETE_USER_FLAG
)) {
1062 * If current user is not root, make sure old password has been specified
1063 * If REMOTE change, even root must provide old password
1065 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0)) ||
1066 ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0))) {
1067 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1071 /* If changing a users password on a remote hosts we have to know what host */
1072 if ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(RHOST
)) <= 0)) {
1073 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1077 /* Make sure new passwords have been specified */
1078 if ((strlen( cgi_variable_nonull(NEW_PSWD
)) <= 0) ||
1079 (strlen( cgi_variable_nonull(NEW2_PSWD
)) <= 0)) {
1080 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1084 /* Make sure new passwords was typed correctly twice */
1085 if (strcmp(cgi_variable_nonull(NEW_PSWD
), cgi_variable_nonull(NEW2_PSWD
)) != 0) {
1086 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1091 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1092 host
= cgi_variable(RHOST
);
1093 } else if (am_root()) {
1100 * Set up the local flags.
1103 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_ADD_USER
: 0);
1104 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1105 local_flags
|= (cgi_variable(CHG_S_PASSWD_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1106 local_flags
|= (cgi_variable(DELETE_USER_FLAG
) ? LOCAL_DELETE_USER
: 0);
1107 local_flags
|= (cgi_variable(ENABLE_USER_FLAG
) ? LOCAL_ENABLE_USER
: 0);
1108 local_flags
|= (cgi_variable(DISABLE_USER_FLAG
) ? LOCAL_DISABLE_USER
: 0);
1111 rslt
= change_password(host
,
1112 cgi_variable_nonull(SWAT_USER
),
1113 cgi_variable_nonull(OLD_PSWD
), cgi_variable_nonull(NEW_PSWD
),
1116 if(cgi_variable(CHG_S_PASSWD_FLAG
)) {
1119 printf(_(" The passwd for '%s' has been changed."), cgi_variable_nonull(SWAT_USER
));
1122 printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable_nonull(SWAT_USER
));
1130 /****************************************************************************
1131 display a password editing page
1132 ****************************************************************************/
1133 static void passwd_page(void)
1135 const char *new_name
= cgi_user_name();
1138 * After the first time through here be nice. If the user
1139 * changed the User box text to another users name, remember it.
1141 if (cgi_variable(SWAT_USER
)) {
1142 new_name
= cgi_variable_nonull(SWAT_USER
);
1145 if (!new_name
) new_name
= "";
1147 printf("<H2>%s</H2>\n", _("Server Password Management"));
1149 printf("<FORM name=\"swatform\" method=post>\n");
1151 printf("<table>\n");
1154 * Create all the dialog boxes for data collection
1156 printf("<tr><td> %s : </td>\n", _("User Name"));
1157 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER
, new_name
);
1159 printf("<tr><td> %s : </td>\n", _("Old Password"));
1160 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD
);
1162 printf("<tr><td> %s : </td>\n", _("New Password"));
1163 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1164 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1165 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1166 printf("</table>\n");
1169 * Create all the control buttons for requesting action
1171 printf("<input type=submit name=%s value=\"%s\">\n",
1172 CHG_S_PASSWD_FLAG
, _("Change Password"));
1173 if (demo_mode
|| am_root()) {
1174 printf("<input type=submit name=%s value=\"%s\">\n",
1175 ADD_USER_FLAG
, _("Add New User"));
1176 printf("<input type=submit name=%s value=\"%s\">\n",
1177 DELETE_USER_FLAG
, _("Delete User"));
1178 printf("<input type=submit name=%s value=\"%s\">\n",
1179 DISABLE_USER_FLAG
, _("Disable User"));
1180 printf("<input type=submit name=%s value=\"%s\">\n",
1181 ENABLE_USER_FLAG
, _("Enable User"));
1183 printf("<p></FORM>\n");
1186 * Do some work if change, add, disable or enable was
1187 * requested. It could be this is the first time through this
1188 * code, so there isn't anything to do. */
1189 if ((cgi_variable(CHG_S_PASSWD_FLAG
)) || (cgi_variable(ADD_USER_FLAG
)) || (cgi_variable(DELETE_USER_FLAG
)) ||
1190 (cgi_variable(DISABLE_USER_FLAG
)) || (cgi_variable(ENABLE_USER_FLAG
))) {
1194 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1196 printf("<FORM name=\"swatform\" method=post>\n");
1198 printf("<table>\n");
1201 * Create all the dialog boxes for data collection
1203 printf("<tr><td> %s : </td>\n", _("User Name"));
1204 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER
, new_name
);
1205 printf("<tr><td> %s : </td>\n", _("Old Password"));
1206 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD
);
1207 printf("<tr><td> %s : </td>\n", _("New Password"));
1208 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1209 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1210 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1211 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1212 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST
);
1217 * Create all the control buttons for requesting action
1219 printf("<input type=submit name=%s value=\"%s\">",
1220 CHG_R_PASSWD_FLAG
, _("Change Password"));
1222 printf("<p></FORM>\n");
1225 * Do some work if a request has been made to change the
1226 * password somewhere other than the server. It could be this
1227 * is the first time through this code, so there isn't
1228 * anything to do. */
1229 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1235 /****************************************************************************
1236 display a printers editing page
1237 ****************************************************************************/
1238 static void printers_page(void)
1240 const char *share
= cgi_variable("share");
1245 unsigned int parm_filter
= FLAG_BASIC
;
1248 snum
= lp_servicenumber(share
);
1250 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1252 printf("<H3>%s</H3>\n", _("Important Note:"));
1253 printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1254 printf(_("are autoloaded printers from "));
1255 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1256 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1258 if (cgi_variable("Commit") && snum
>= 0) {
1259 commit_parameters(snum
);
1260 if (snum
>= iNumNonAutoPrintServices
)
1266 if (cgi_variable("Delete") && snum
>= 0) {
1267 lp_remove_service(snum
);
1273 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
1275 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
1276 iNumNonAutoPrintServices
= lp_numservices();
1277 snum
= lp_servicenumber(share
);
1278 lp_do_parameter(snum
, "print ok", "Yes");
1280 snum
= lp_servicenumber(share
);
1283 printf("<FORM name=\"swatform\" method=post>\n");
1285 if ( cgi_variable("ViewMode") )
1286 mode
= atoi(cgi_variable_nonull("ViewMode"));
1287 if ( cgi_variable("BasicMode"))
1289 if ( cgi_variable("AdvMode"))
1292 ViewModeBoxes( mode
);
1295 parm_filter
= FLAG_BASIC
;
1298 parm_filter
= FLAG_ADVANCED
;
1301 printf("<table>\n");
1302 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1303 printf("<td><select name=\"share\">\n");
1304 if (snum
< 0 || !lp_print_ok(snum
))
1305 printf("<option value=\" \"> \n");
1306 for (i
=0;i
<lp_numservices();i
++) {
1307 s
= lp_servicename(i
);
1308 if (s
&& (*s
) && strcmp(s
,"IPC$") && lp_print_ok(i
)) {
1309 if (i
>= iNumNonAutoPrintServices
)
1310 printf("<option %s value=\"%s\">[*]%s\n",
1311 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1314 printf("<option %s value=\"%s\">%s\n",
1315 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1319 printf("</select></td>");
1320 if (have_write_access
) {
1321 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1324 printf("</table>\n");
1326 if (have_write_access
) {
1327 printf("<table>\n");
1328 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1329 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1335 if (have_write_access
) {
1336 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1338 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1343 printf("<table>\n");
1344 show_parameters(snum
, 1, parm_filter
, 1);
1345 printf("</table>\n");
1347 printf("</FORM>\n");
1351 when the _() translation macro is used there is no obvious place to free
1352 the resulting string and there is no easy way to give a static pointer.
1353 All we can do is rotate between some static buffers and hope a single d_printf()
1354 doesn't have more calls to _() than the number of buffers
1357 const char *lang_msg_rotate(TALLOC_CTX
*ctx
, const char *msgid
)
1362 msgstr
= lang_msg(msgid
);
1367 ret
= talloc_strdup(ctx
, msgstr
);
1369 lang_msg_free(msgstr
);
1378 * main function for SWAT.
1380 int main(int argc
, char *argv
[])
1384 struct poptOption long_options
[] = {
1386 { "disable-authentication", 'a', POPT_ARG_VAL
, &demo_mode
, True
, "Disable authentication (demo mode)" },
1387 { "password-menu-only", 'P', POPT_ARG_VAL
, &passwd_only
, True
, "Show only change password menu" },
1391 TALLOC_CTX
*frame
= talloc_stackframe();
1394 umask(S_IWGRP
| S_IWOTH
);
1396 #if defined(HAVE_SET_AUTH_PARAMETERS)
1397 set_auth_parameters(argc
, argv
);
1398 #endif /* HAVE_SET_AUTH_PARAMETERS */
1400 /* just in case it goes wild ... */
1405 /* we don't want any SIGPIPE messages */
1406 BlockSignals(True
,SIGPIPE
);
1408 dbf
= x_fopen("/dev/null", O_WRONLY
, 0);
1409 if (!dbf
) dbf
= x_stderr
;
1411 /* we don't want stderr screwing us up */
1413 open("/dev/null", O_WRONLY
);
1415 pc
= poptGetContext("swat", argc
, (const char **) argv
, long_options
, 0);
1417 /* Parse command line options */
1419 while(poptGetNextOpt(pc
) != -1) { }
1421 poptFreeContext(pc
);
1425 setup_logging(argv
[0],False
);
1428 iNumNonAutoPrintServices
= lp_numservices();
1431 cgi_setup(get_dyn_SWATDIR(), !demo_mode
);
1435 cgi_load_variables();
1437 if (!file_exist(get_dyn_CONFIGFILE(), NULL
)) {
1438 have_read_access
= True
;
1439 have_write_access
= True
;
1441 /* check if the authenticated user has write access - if not then
1442 don't show write options */
1443 have_write_access
= (access(get_dyn_CONFIGFILE(),W_OK
) == 0);
1445 /* if the user doesn't have read access to smb.conf then
1446 don't let them view it */
1447 have_read_access
= (access(get_dyn_CONFIGFILE(),R_OK
) == 0);
1450 show_main_buttons();
1452 page
= cgi_pathinfo();
1454 /* Root gets full functionality */
1455 if (have_read_access
&& strcmp(page
, "globals")==0) {
1457 } else if (have_read_access
&& strcmp(page
,"shares")==0) {
1459 } else if (have_read_access
&& strcmp(page
,"printers")==0) {
1461 } else if (have_read_access
&& strcmp(page
,"status")==0) {
1463 } else if (have_read_access
&& strcmp(page
,"viewconfig")==0) {
1465 } else if (strcmp(page
,"passwd")==0) {
1467 } else if (have_read_access
&& strcmp(page
,"wizard")==0) {
1469 } else if (have_read_access
&& strcmp(page
,"wizard_params")==0) {
1470 wizard_params_page();
1471 } else if (have_read_access
&& strcmp(page
,"rewritecfg")==0) {