2 Unix SMB/CIFS implementation.
3 Samba Web Administration Tool
5 Copyright (C) Andrew Tridgell 1997-2002
6 Copyright (C) John H Terpstra 2002
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 * @defgroup swat SWAT - Samba Web Administration Tool
27 * @brief Samba Web Administration Tool.
31 #include "system/filesys.h"
32 #include "popt_common.h"
33 #include "web/swat_proto.h"
34 #include "printing/pcap.h"
35 #include "printing/load.h"
37 #include "intl/lang_tdb.h"
39 static int demo_mode
= False
;
40 static int passwd_only
= False
;
41 static bool have_write_access
= False
;
42 static bool have_read_access
= False
;
43 static int iNumNonAutoPrintServices
= 0;
46 * Password Management Globals
48 #define SWAT_USER "username"
49 #define OLD_PSWD "old_passwd"
50 #define NEW_PSWD "new_passwd"
51 #define NEW2_PSWD "new2_passwd"
52 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
53 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
54 #define ADD_USER_FLAG "add_user_flag"
55 #define DELETE_USER_FLAG "delete_user_flag"
56 #define DISABLE_USER_FLAG "disable_user_flag"
57 #define ENABLE_USER_FLAG "enable_user_flag"
58 #define RHOST "remote_host"
60 #define _(x) lang_msg_rotate(talloc_tos(),x)
62 /****************************************************************************
63 ****************************************************************************/
64 static int enum_index(int value
, const struct enum_list
*enumlist
)
67 for (i
=0;enumlist
[i
].name
;i
++)
68 if (value
== enumlist
[i
].value
) break;
72 static char *fix_backslash(const char *str
)
74 static char newstring
[1024];
78 if (*str
== '\\') {*p
++ = '\\';*p
++ = '\\';}
86 static const char *fix_quotes(TALLOC_CTX
*ctx
, char *str
)
88 char *newstring
= NULL
;
91 int quote_len
= strlen(""");
93 /* Count the number of quotes. */
98 newstring_len
+= quote_len
;
104 newstring
= talloc_array(ctx
, char, newstring_len
);
108 for (p
= newstring
; *str
; str
++) {
110 strncpy( p
, """, quote_len
);
120 static char *stripspaceupper(const char *str
)
122 static char newstring
[1024];
126 if (*str
!= ' ') *p
++ = toupper_ascii(*str
);
133 static char *make_parm_name(const char *label
)
135 static char parmname
[1024];
139 if (*label
== ' ') *p
++ = '_';
147 /****************************************************************************
148 include a lump of html in a page
149 ****************************************************************************/
150 static int include_html(const char *fname
)
156 fd
= web_open(fname
, O_RDONLY
, 0);
159 printf(_("ERROR: Can't open %s"), fname
);
164 while ((ret
= read(fd
, buf
, sizeof(buf
))) > 0) {
165 if (write(1, buf
, ret
) == -1) {
174 /****************************************************************************
175 start the page with standard stuff
176 ****************************************************************************/
177 static void print_header(void)
179 if (!cgi_waspost()) {
180 printf("Expires: 0\r\n");
182 printf("Content-type: text/html\r\n\r\n");
184 if (!include_html("include/header.html")) {
185 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
186 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
190 /* *******************************************************************
191 show parameter label with translated name in the following form
192 because showing original and translated label in one line looks
193 too long, and showing translated label only is unusable for
195 -------------------------------
196 HELP security [combo box][button]
198 -------------------------------
199 (capital words are translated by gettext.)
200 if no translation is available, then same form as original is
202 "i18n_translated_parm" class is used to change the color of the
203 translated parameter with CSS.
204 **************************************************************** */
205 static const char *get_parm_translated(TALLOC_CTX
*ctx
,
206 const char* pAnchor
, const char* pHelp
, const char* pLabel
)
208 const char *pTranslated
= _(pLabel
);
210 if(strcmp(pLabel
, pTranslated
) != 0) {
211 output
= talloc_asprintf(ctx
,
212 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
213 pAnchor
, pHelp
, pLabel
, pTranslated
);
216 output
= talloc_asprintf(ctx
,
217 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
218 pAnchor
, pHelp
, pLabel
);
221 /****************************************************************************
223 ****************************************************************************/
224 static void print_footer(void)
226 if (!include_html("include/footer.html")) {
227 printf("\n</BODY>\n</HTML>\n");
231 /****************************************************************************
232 display one editable parameter in a form
233 ****************************************************************************/
234 static void show_parameter(int snum
, struct parm_struct
*parm
)
237 void *ptr
= parm
->ptr
;
238 char *utf8_s1
, *utf8_s2
;
239 size_t converted_size
;
240 TALLOC_CTX
*ctx
= talloc_stackframe();
242 if (parm
->p_class
== P_LOCAL
&& snum
>= 0) {
243 ptr
= lp_local_ptr_by_snum(snum
, ptr
);
246 printf("<tr><td>%s</td><td>", get_parm_translated(ctx
,
247 stripspaceupper(parm
->label
), _("Help"), parm
->label
));
248 switch (parm
->type
) {
250 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
251 make_parm_name(parm
->label
), *(char *)ptr
);
252 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
253 _("Set Default"), make_parm_name(parm
->label
),(char)(parm
->def
.cvalue
));
257 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
258 make_parm_name(parm
->label
));
259 if ((char ***)ptr
&& *(char ***)ptr
&& **(char ***)ptr
) {
260 char **list
= *(char ***)ptr
;
261 for (;*list
;list
++) {
262 /* enclose in HTML encoded quotes if the string contains a space */
263 if ( strchr_m(*list
, ' ') ) {
264 push_utf8_talloc(talloc_tos(), &utf8_s1
, *list
, &converted_size
);
265 push_utf8_talloc(talloc_tos(), &utf8_s2
, ((*(list
+1))?", ":""), &converted_size
);
266 printf(""%s"%s", utf8_s1
, utf8_s2
);
268 push_utf8_talloc(talloc_tos(), &utf8_s1
, *list
, &converted_size
);
269 push_utf8_talloc(talloc_tos(), &utf8_s2
, ((*(list
+1))?", ":""), &converted_size
);
270 printf("%s%s", utf8_s1
, utf8_s2
);
272 TALLOC_FREE(utf8_s1
);
273 TALLOC_FREE(utf8_s2
);
277 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
278 _("Set Default"), make_parm_name(parm
->label
));
279 if (parm
->def
.lvalue
) {
280 char **list
= (char **)(parm
->def
.lvalue
);
281 for (; *list
; list
++) {
282 /* enclose in HTML encoded quotes if the string contains a space */
283 if ( strchr_m(*list
, ' ') )
284 printf(""%s"%s", *list
, ((*(list
+1))?", ":""));
286 printf("%s%s", *list
, ((*(list
+1))?", ":""));
294 push_utf8_talloc(talloc_tos(), &utf8_s1
, *(char **)ptr
, &converted_size
);
295 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
296 make_parm_name(parm
->label
), fix_quotes(ctx
, utf8_s1
));
297 TALLOC_FREE(utf8_s1
);
298 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
299 _("Set Default"), make_parm_name(parm
->label
),fix_backslash((char *)(parm
->def
.svalue
)));
303 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
304 printf("<option %s>Yes", (*(bool *)ptr
)?"selected":"");
305 printf("<option %s>No", (*(bool *)ptr
)?"":"selected");
307 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
308 _("Set Default"), make_parm_name(parm
->label
),(bool)(parm
->def
.bvalue
)?0:1);
312 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
313 printf("<option %s>Yes", (*(bool *)ptr
)?"":"selected");
314 printf("<option %s>No", (*(bool *)ptr
)?"selected":"");
316 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
317 _("Set Default"), make_parm_name(parm
->label
),(bool)(parm
->def
.bvalue
)?1:0);
321 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm
->label
), *(int *)ptr
);
322 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
323 _("Set Default"), make_parm_name(parm
->label
),(int)(parm
->def
.ivalue
));
328 o
= octal_string(*(int *)ptr
);
329 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
330 make_parm_name(parm
->label
), o
);
332 o
= octal_string((int)(parm
->def
.ivalue
));
333 printf("<input type=button value=\"%s\" "
334 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
335 _("Set Default"), make_parm_name(parm
->label
), o
);
341 printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
342 for (i
=0;parm
->enum_list
[i
].name
;i
++) {
343 if (i
== 0 || parm
->enum_list
[i
].value
!= parm
->enum_list
[i
-1].value
) {
344 printf("<option %s>%s",(*(int *)ptr
)==parm
->enum_list
[i
].value
?"selected":"",parm
->enum_list
[i
].name
);
348 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
349 _("Set Default"), make_parm_name(parm
->label
),enum_index((int)(parm
->def
.ivalue
),parm
->enum_list
));
354 printf("</td></tr>\n");
358 /****************************************************************************
359 display a set of parameters for a service
360 ****************************************************************************/
361 static void show_parameters(int snum
, int allparameters
, unsigned int parm_filter
, int printers
)
364 struct parm_struct
*parm
;
365 const char *heading
= NULL
;
366 const char *last_heading
= NULL
;
368 while ((parm
= lp_next_parameter(snum
, &i
, allparameters
))) {
369 if (snum
< 0 && parm
->p_class
== P_LOCAL
&& !(parm
->flags
& FLAG_GLOBAL
))
371 if (parm
->p_class
== P_SEPARATOR
) {
372 heading
= parm
->label
;
375 if (parm
->flags
& FLAG_HIDE
) continue;
377 if (printers
& !(parm
->flags
& FLAG_PRINT
)) continue;
378 if (!printers
& !(parm
->flags
& FLAG_SHARE
)) continue;
381 if (!( parm_filter
& FLAG_ADVANCED
)) {
382 if (!(parm
->flags
& FLAG_BASIC
)) {
383 void *ptr
= parm
->ptr
;
385 if (parm
->p_class
== P_LOCAL
&& snum
>= 0) {
386 ptr
= lp_local_ptr_by_snum(snum
, ptr
);
389 switch (parm
->type
) {
391 if (*(char *)ptr
== (char)(parm
->def
.cvalue
)) continue;
395 if (!str_list_equal(*(const char ***)ptr
,
396 (const char **)(parm
->def
.lvalue
))) continue;
401 if (!strcmp(*(char **)ptr
,(char *)(parm
->def
.svalue
))) continue;
406 if (*(bool *)ptr
== (bool)(parm
->def
.bvalue
)) continue;
411 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
416 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
422 if (printers
&& !(parm
->flags
& FLAG_PRINT
)) continue;
425 if ((parm_filter
& FLAG_WIZARD
) && !(parm
->flags
& FLAG_WIZARD
)) continue;
427 if ((parm_filter
& FLAG_ADVANCED
) && !(parm
->flags
& FLAG_ADVANCED
)) continue;
429 if (heading
&& heading
!= last_heading
) {
430 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading
));
431 last_heading
= heading
;
433 show_parameter(snum
, parm
);
437 /****************************************************************************
438 load the smb.conf file into loadparm.
439 ****************************************************************************/
440 static bool load_config(bool save_def
)
442 return lp_load(get_dyn_CONFIGFILE(),False
,save_def
,False
,True
);
445 /****************************************************************************
447 ****************************************************************************/
448 static void write_config(FILE *f
, bool show_defaults
)
450 TALLOC_CTX
*ctx
= talloc_stackframe();
452 fprintf(f
, "# Samba config file created using SWAT\n");
453 fprintf(f
, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
454 fprintf(f
, "# Date: %s\n\n", current_timestring(ctx
, False
));
456 lp_dump(f
, show_defaults
, iNumNonAutoPrintServices
);
461 /****************************************************************************
462 save and reload the smb.conf config file
463 ****************************************************************************/
464 static int save_reload(int snum
)
469 f
= sys_fopen(get_dyn_CONFIGFILE(),"w");
471 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
476 /* just in case they have used the buggy xinetd to create the file */
477 if (fstat(fileno(f
), &st
) == 0 &&
478 (st
.st_mode
& S_IWOTH
)) {
479 #if defined HAVE_FCHMOD
480 fchmod(fileno(f
), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
482 chmod(get_dyn_CONFIGFILE(), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
486 write_config(f
, False
);
488 lp_dump_one(f
, False
, snum
);
491 lp_kill_all_services();
493 if (!load_config(False
)) {
494 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
498 iNumNonAutoPrintServices
= lp_numservices();
499 if (pcap_cache_loaded()) {
500 load_printers(server_event_context(),
501 server_messaging_context());
507 /****************************************************************************
509 ****************************************************************************/
510 static void commit_parameter(int snum
, struct parm_struct
*parm
, const char *v
)
515 if (snum
< 0 && parm
->p_class
== P_LOCAL
) {
516 /* this handles the case where we are changing a local
517 variable globally. We need to change the parameter in
518 all shares where it is currently set to the default */
519 for (i
=0;i
<lp_numservices();i
++) {
520 s
= lp_servicename(i
);
521 if (s
&& (*s
) && lp_is_default(i
, parm
)) {
522 lp_do_parameter(i
, parm
->label
, v
);
527 lp_do_parameter(snum
, parm
->label
, v
);
530 /****************************************************************************
531 commit a set of parameters for a service
532 ****************************************************************************/
533 static void commit_parameters(int snum
)
536 struct parm_struct
*parm
;
540 while ((parm
= lp_next_parameter(snum
, &i
, 1))) {
541 if (asprintf(&label
, "parm_%s", make_parm_name(parm
->label
)) > 0) {
542 if ((v
= cgi_variable(label
)) != NULL
) {
543 if (parm
->flags
& FLAG_HIDE
)
545 commit_parameter(snum
, parm
, v
);
552 /****************************************************************************
553 spit out the html for a link with an image
554 ****************************************************************************/
555 static void image_link(const char *name
, const char *hlink
, const char *src
)
557 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
558 cgi_baseurl(), hlink
, src
, name
);
561 /****************************************************************************
562 display the main navigation controls at the top of each page along
564 ****************************************************************************/
565 static void show_main_buttons(void)
569 if ((p
= cgi_user_name()) && strcmp(p
, "root")) {
570 printf(_("Logged in as <b>%s</b>"), p
);
574 image_link(_("Home"), "", "images/home.gif");
575 if (have_write_access
) {
576 image_link(_("Globals"), "globals", "images/globals.gif");
577 image_link(_("Shares"), "shares", "images/shares.gif");
578 image_link(_("Printers"), "printers", "images/printers.gif");
579 image_link(_("Wizard"), "wizard", "images/wizard.gif");
581 /* root always gets all buttons, otherwise look for -P */
582 if ( have_write_access
|| (!passwd_only
&& have_read_access
) ) {
583 image_link(_("Status"), "status", "images/status.gif");
584 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
586 image_link(_("Password Management"), "passwd", "images/passwd.gif");
591 /****************************************************************************
592 * Handle Display/Edit Mode CGI
593 ****************************************************************************/
594 static void ViewModeBoxes(int mode
)
596 printf("<p>%s: \n", _("Current View Is"));
597 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode
== 0) ? "checked" : ""), _("Basic"));
598 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode
== 1) ? "checked" : ""), _("Advanced"));
599 printf("<br>%s: \n", _("Change View To"));
600 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
601 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
602 printf("</p><br>\n");
605 /****************************************************************************
606 display a welcome page
607 ****************************************************************************/
608 static void welcome_page(void)
610 if (file_exist("help/welcome.html")) {
611 include_html("help/welcome.html");
613 include_html("help/welcome-no-samba-doc.html");
617 /****************************************************************************
618 display the current smb.conf
619 ****************************************************************************/
620 static void viewconfig_page(void)
624 if (cgi_variable("full_view")) {
628 printf("<H2>%s</H2>\n", _("Current Config"));
629 printf("<form method=post>\n");
632 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
634 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
638 write_config(stdout
, full_view
);
643 /****************************************************************************
644 second screen of the wizard ... Fetch Configuration Parameters
645 ****************************************************************************/
646 static void wizard_params_page(void)
648 unsigned int parm_filter
= FLAG_WIZARD
;
650 /* Here we first set and commit all the parameters that were selected
651 in the previous screen. */
653 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
655 if (cgi_variable("Commit")) {
656 commit_parameters(GLOBAL_SECTION_SNUM
);
660 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
662 if (have_write_access
) {
663 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
666 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
670 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
671 printf("</table>\n");
675 /****************************************************************************
676 Utility to just rewrite the smb.conf file - effectively just cleans it up
677 ****************************************************************************/
678 static void rewritecfg_file(void)
680 commit_parameters(GLOBAL_SECTION_SNUM
);
682 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
685 /****************************************************************************
686 wizard to create/modify the smb.conf file
687 ****************************************************************************/
688 static void wizard_page(void)
690 /* Set some variables to collect data from smb.conf */
697 if (cgi_variable("Rewrite")) {
698 (void) rewritecfg_file();
702 if (cgi_variable("GetWizardParams")){
703 (void) wizard_params_page();
707 if (cgi_variable("Commit")){
708 SerType
= atoi(cgi_variable_nonull("ServerType"));
709 winstype
= atoi(cgi_variable_nonull("WINSType"));
710 have_home
= lp_servicenumber(HOMES_NAME
);
711 HomeExpo
= atoi(cgi_variable_nonull("HomeExpo"));
713 /* Plain text passwords are too badly broken - use encrypted passwords only */
714 lp_do_parameter( GLOBAL_SECTION_SNUM
, "encrypt passwords", "Yes");
718 /* Stand-alone Server */
719 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
720 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
724 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "DOMAIN" );
725 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
728 /* Domain Controller */
729 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
730 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "Yes" );
733 switch ( winstype
) {
735 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
736 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
739 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "Yes" );
740 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
743 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
744 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", cgi_variable_nonull("WINSAddr"));
748 /* Have to create Homes share? */
749 if ((HomeExpo
== 1) && (have_home
== -1)) {
750 const char *unix_share
= HOMES_NAME
;
753 lp_copy_service(GLOBAL_SECTION_SNUM
, unix_share
);
754 have_home
= lp_servicenumber(HOMES_NAME
);
755 lp_do_parameter( have_home
, "read only", "No");
756 lp_do_parameter( have_home
, "valid users", "%S");
757 lp_do_parameter( have_home
, "browseable", "No");
758 commit_parameters(have_home
);
759 save_reload(have_home
);
762 /* Need to Delete Homes share? */
763 if ((HomeExpo
== 0) && (have_home
!= -1)) {
764 lp_remove_service(have_home
);
768 commit_parameters(GLOBAL_SECTION_SNUM
);
773 /* Now determine smb.conf WINS settings */
774 if (lp_wins_support())
776 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
779 /* Do we have a homes share? */
780 have_home
= lp_servicenumber(HOMES_NAME
);
782 if ((winstype
== 2) && lp_wins_support())
785 role
= lp_server_role();
788 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
789 printf("<form method=post action=wizard>\n");
791 if (have_write_access
) {
792 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
793 printf("%s", _("The same will happen if you press the commit button."));
794 printf("<br><br>\n");
796 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
797 printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
798 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
799 printf("</center>\n");
803 printf("<center><table border=0>");
804 printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
805 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role
== ROLE_STANDALONE
) ? "checked" : ""), _("Stand Alone"));
806 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role
== ROLE_DOMAIN_MEMBER
) ? "checked" : ""), _("Domain Member"));
807 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role
== ROLE_DOMAIN_PDC
) ? "checked" : ""), _("Domain Controller"));
809 if (role
== ROLE_DOMAIN_BDC
) {
810 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
812 printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
813 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype
== 0) ? "checked" : ""), _("Not Used"));
814 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype
== 1) ? "checked" : ""), _("Server for client use"));
815 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype
== 2) ? "checked" : ""), _("Client of another WINS server"));
817 printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
819 /* Print out the list of wins servers */
820 if(lp_wins_server_list()) {
822 const char **wins_servers
= lp_wins_server_list();
823 for(i
= 0; wins_servers
[i
]; i
++) printf("%s ", wins_servers
[i
]);
826 printf("\"></td></tr>\n");
828 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"));
829 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
831 printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
832 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home
== -1) ? "" : "checked ");
833 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home
== -1 ) ? "checked" : "");
834 printf("<td></td></tr>\n");
836 /* Enable this when we are ready ....
837 * printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
838 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
839 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
840 * printf("<td></td></tr>\n");
843 printf("</table></center>");
846 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
851 /****************************************************************************
852 display a globals editing page
853 ****************************************************************************/
854 static void globals_page(void)
856 unsigned int parm_filter
= FLAG_BASIC
;
859 printf("<H2>%s</H2>\n", _("Global Parameters"));
861 if (cgi_variable("Commit")) {
862 commit_parameters(GLOBAL_SECTION_SNUM
);
866 if ( cgi_variable("ViewMode") )
867 mode
= atoi(cgi_variable_nonull("ViewMode"));
868 if ( cgi_variable("BasicMode"))
870 if ( cgi_variable("AdvMode"))
873 printf("<form name=\"swatform\" method=post action=globals>\n");
875 ViewModeBoxes( mode
);
878 parm_filter
= FLAG_BASIC
;
881 parm_filter
= FLAG_ADVANCED
;
885 if (have_write_access
) {
886 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
887 _("Commit Changes"));
890 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
895 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
896 printf("</table>\n");
900 /****************************************************************************
901 display a shares editing page. share is in unix codepage,
902 ****************************************************************************/
903 static void shares_page(void)
905 const char *share
= cgi_variable("share");
911 unsigned int parm_filter
= FLAG_BASIC
;
912 size_t converted_size
;
915 snum
= lp_servicenumber(share
);
917 printf("<H2>%s</H2>\n", _("Share Parameters"));
919 if (cgi_variable("Commit") && snum
>= 0) {
920 commit_parameters(snum
);
922 snum
= lp_servicenumber(share
);
925 if (cgi_variable("Delete") && snum
>= 0) {
926 lp_remove_service(snum
);
932 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
933 snum
= lp_servicenumber(share
);
936 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
937 snum
= lp_servicenumber(share
);
939 snum
= lp_servicenumber(share
);
943 printf("<FORM name=\"swatform\" method=post>\n");
947 if ( cgi_variable("ViewMode") )
948 mode
= atoi(cgi_variable_nonull("ViewMode"));
949 if ( cgi_variable("BasicMode"))
951 if ( cgi_variable("AdvMode"))
954 ViewModeBoxes( mode
);
957 parm_filter
= FLAG_BASIC
;
960 parm_filter
= FLAG_ADVANCED
;
963 printf("<br><tr>\n");
964 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
965 printf("<td><select name=share>\n");
967 printf("<option value=\" \"> \n");
968 for (i
=0;i
<lp_numservices();i
++) {
969 s
= lp_servicename(i
);
970 if (s
&& (*s
) && strcmp(s
,"IPC$") && !lp_print_ok(i
)) {
971 push_utf8_talloc(talloc_tos(), &utf8_s
, s
, &converted_size
);
972 printf("<option %s value=\"%s\">%s\n",
973 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
978 printf("</select></td>\n");
979 if (have_write_access
) {
980 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
985 if (have_write_access
) {
987 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
988 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
994 if (have_write_access
) {
995 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
998 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1003 printf("<table>\n");
1004 show_parameters(snum
, 1, parm_filter
, 0);
1005 printf("</table>\n");
1008 printf("</FORM>\n");
1011 /*************************************************************
1012 change a password either locally or remotely
1013 *************************************************************/
1014 static bool change_password(const char *remote_machine
, const char *user_name
,
1015 const char *old_passwd
, const char *new_passwd
,
1019 char *err_str
= NULL
;
1020 char *msg_str
= NULL
;
1023 printf("%s\n<p>", _("password change in demo mode rejected"));
1027 if (remote_machine
!= NULL
) {
1028 ret
= remote_password_change(remote_machine
, user_name
,
1029 old_passwd
, new_passwd
, &err_str
);
1030 if (err_str
!= NULL
)
1031 printf("%s\n<p>", err_str
);
1033 return NT_STATUS_IS_OK(ret
);
1036 if(!initialize_password_db(True
, NULL
)) {
1037 printf("%s\n<p>", _("Can't setup password database vectors."));
1041 ret
= local_password_change(user_name
, local_flags
, new_passwd
,
1042 &err_str
, &msg_str
);
1045 printf("%s\n<p>", msg_str
);
1047 printf("%s\n<p>", err_str
);
1051 return NT_STATUS_IS_OK(ret
);
1054 /****************************************************************************
1055 do the stuff required to add or change a password
1056 ****************************************************************************/
1057 static void chg_passwd(void)
1061 int local_flags
= 0;
1063 /* Make sure users name has been specified */
1064 if (strlen(cgi_variable_nonull(SWAT_USER
)) == 0) {
1065 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1070 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1071 * so if that's what we're doing, skip the rest of the checks
1073 if (!cgi_variable(DISABLE_USER_FLAG
) && !cgi_variable(ENABLE_USER_FLAG
) && !cgi_variable(DELETE_USER_FLAG
)) {
1076 * If current user is not root, make sure old password has been specified
1077 * If REMOTE change, even root must provide old password
1079 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0)) ||
1080 ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(OLD_PSWD
)) <= 0))) {
1081 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1085 /* If changing a users password on a remote hosts we have to know what host */
1086 if ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable_nonull(RHOST
)) <= 0)) {
1087 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1091 /* Make sure new passwords have been specified */
1092 if ((strlen( cgi_variable_nonull(NEW_PSWD
)) <= 0) ||
1093 (strlen( cgi_variable_nonull(NEW2_PSWD
)) <= 0)) {
1094 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1098 /* Make sure new passwords was typed correctly twice */
1099 if (strcmp(cgi_variable_nonull(NEW_PSWD
), cgi_variable_nonull(NEW2_PSWD
)) != 0) {
1100 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1105 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1106 host
= cgi_variable(RHOST
);
1107 } else if (am_root()) {
1114 * Set up the local flags.
1117 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_ADD_USER
: 0);
1118 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1119 local_flags
|= (cgi_variable(CHG_S_PASSWD_FLAG
) ? LOCAL_SET_PASSWORD
: 0);
1120 local_flags
|= (cgi_variable(DELETE_USER_FLAG
) ? LOCAL_DELETE_USER
: 0);
1121 local_flags
|= (cgi_variable(ENABLE_USER_FLAG
) ? LOCAL_ENABLE_USER
: 0);
1122 local_flags
|= (cgi_variable(DISABLE_USER_FLAG
) ? LOCAL_DISABLE_USER
: 0);
1124 rslt
= change_password(host
,
1125 cgi_variable_nonull(SWAT_USER
),
1126 cgi_variable_nonull(OLD_PSWD
), cgi_variable_nonull(NEW_PSWD
),
1129 if(cgi_variable(CHG_S_PASSWD_FLAG
)) {
1132 printf(_(" The passwd for '%s' has been changed."), cgi_variable_nonull(SWAT_USER
));
1135 printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable_nonull(SWAT_USER
));
1143 /****************************************************************************
1144 display a password editing page
1145 ****************************************************************************/
1146 static void passwd_page(void)
1148 const char *new_name
= cgi_user_name();
1151 * After the first time through here be nice. If the user
1152 * changed the User box text to another users name, remember it.
1154 if (cgi_variable(SWAT_USER
)) {
1155 new_name
= cgi_variable_nonull(SWAT_USER
);
1158 if (!new_name
) new_name
= "";
1160 printf("<H2>%s</H2>\n", _("Server Password Management"));
1162 printf("<FORM name=\"swatform\" method=post>\n");
1164 printf("<table>\n");
1167 * Create all the dialog boxes for data collection
1169 printf("<tr><td> %s : </td>\n", _("User Name"));
1170 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER
, new_name
);
1172 printf("<tr><td> %s : </td>\n", _("Old Password"));
1173 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD
);
1175 printf("<tr><td> %s : </td>\n", _("New Password"));
1176 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1177 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1178 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1179 printf("</table>\n");
1182 * Create all the control buttons for requesting action
1184 printf("<input type=submit name=%s value=\"%s\">\n",
1185 CHG_S_PASSWD_FLAG
, _("Change Password"));
1186 if (demo_mode
|| am_root()) {
1187 printf("<input type=submit name=%s value=\"%s\">\n",
1188 ADD_USER_FLAG
, _("Add New User"));
1189 printf("<input type=submit name=%s value=\"%s\">\n",
1190 DELETE_USER_FLAG
, _("Delete User"));
1191 printf("<input type=submit name=%s value=\"%s\">\n",
1192 DISABLE_USER_FLAG
, _("Disable User"));
1193 printf("<input type=submit name=%s value=\"%s\">\n",
1194 ENABLE_USER_FLAG
, _("Enable User"));
1196 printf("<p></FORM>\n");
1199 * Do some work if change, add, disable or enable was
1200 * requested. It could be this is the first time through this
1201 * code, so there isn't anything to do. */
1202 if ((cgi_variable(CHG_S_PASSWD_FLAG
)) || (cgi_variable(ADD_USER_FLAG
)) || (cgi_variable(DELETE_USER_FLAG
)) ||
1203 (cgi_variable(DISABLE_USER_FLAG
)) || (cgi_variable(ENABLE_USER_FLAG
))) {
1207 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1209 printf("<FORM name=\"swatform\" method=post>\n");
1211 printf("<table>\n");
1214 * Create all the dialog boxes for data collection
1216 printf("<tr><td> %s : </td>\n", _("User Name"));
1217 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER
, new_name
);
1218 printf("<tr><td> %s : </td>\n", _("Old Password"));
1219 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD
);
1220 printf("<tr><td> %s : </td>\n", _("New Password"));
1221 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1222 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1223 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1224 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1225 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST
);
1230 * Create all the control buttons for requesting action
1232 printf("<input type=submit name=%s value=\"%s\">",
1233 CHG_R_PASSWD_FLAG
, _("Change Password"));
1235 printf("<p></FORM>\n");
1238 * Do some work if a request has been made to change the
1239 * password somewhere other than the server. It could be this
1240 * is the first time through this code, so there isn't
1241 * anything to do. */
1242 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1248 /****************************************************************************
1249 display a printers editing page
1250 ****************************************************************************/
1251 static void printers_page(void)
1253 const char *share
= cgi_variable("share");
1258 unsigned int parm_filter
= FLAG_BASIC
;
1261 snum
= lp_servicenumber(share
);
1263 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1265 printf("<H3>%s</H3>\n", _("Important Note:"));
1266 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1267 printf("%s",_("are autoloaded printers from "));
1268 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1269 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1271 if (cgi_variable("Commit") && snum
>= 0) {
1272 commit_parameters(snum
);
1273 if (snum
>= iNumNonAutoPrintServices
)
1277 snum
= lp_servicenumber(share
);
1280 if (cgi_variable("Delete") && snum
>= 0) {
1281 lp_remove_service(snum
);
1287 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
1288 snum
= lp_servicenumber(share
);
1289 if (snum
< 0 || snum
>= iNumNonAutoPrintServices
) {
1291 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
1292 snum
= lp_servicenumber(share
);
1293 lp_do_parameter(snum
, "print ok", "Yes");
1295 snum
= lp_servicenumber(share
);
1299 printf("<FORM name=\"swatform\" method=post>\n");
1301 if ( cgi_variable("ViewMode") )
1302 mode
= atoi(cgi_variable_nonull("ViewMode"));
1303 if ( cgi_variable("BasicMode"))
1305 if ( cgi_variable("AdvMode"))
1308 ViewModeBoxes( mode
);
1311 parm_filter
= FLAG_BASIC
;
1314 parm_filter
= FLAG_ADVANCED
;
1317 printf("<table>\n");
1318 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1319 printf("<td><select name=\"share\">\n");
1320 if (snum
< 0 || !lp_print_ok(snum
))
1321 printf("<option value=\" \"> \n");
1322 for (i
=0;i
<lp_numservices();i
++) {
1323 s
= lp_servicename(i
);
1324 if (s
&& (*s
) && strcmp(s
,"IPC$") && lp_print_ok(i
)) {
1325 if (i
>= iNumNonAutoPrintServices
)
1326 printf("<option %s value=\"%s\">[*]%s\n",
1327 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1330 printf("<option %s value=\"%s\">%s\n",
1331 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1335 printf("</select></td>");
1336 if (have_write_access
) {
1337 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1340 printf("</table>\n");
1342 if (have_write_access
) {
1343 printf("<table>\n");
1344 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1345 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1351 if (have_write_access
) {
1352 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1354 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1359 printf("<table>\n");
1360 show_parameters(snum
, 1, parm_filter
, 1);
1361 printf("</table>\n");
1363 printf("</FORM>\n");
1367 when the _() translation macro is used there is no obvious place to free
1368 the resulting string and there is no easy way to give a static pointer.
1369 All we can do is rotate between some static buffers and hope a single d_printf()
1370 doesn't have more calls to _() than the number of buffers
1373 const char *lang_msg_rotate(TALLOC_CTX
*ctx
, const char *msgid
)
1378 msgstr
= lang_msg(msgid
);
1383 ret
= talloc_strdup(ctx
, msgstr
);
1385 lang_msg_free(msgstr
);
1394 * main function for SWAT.
1396 int main(int argc
, char *argv
[])
1400 struct poptOption long_options
[] = {
1402 { "disable-authentication", 'a', POPT_ARG_VAL
, &demo_mode
, True
, "Disable authentication (demo mode)" },
1403 { "password-menu-only", 'P', POPT_ARG_VAL
, &passwd_only
, True
, "Show only change password menu" },
1407 TALLOC_CTX
*frame
= talloc_stackframe();
1410 umask(S_IWGRP
| S_IWOTH
);
1412 #if defined(HAVE_SET_AUTH_PARAMETERS)
1413 set_auth_parameters(argc
, argv
);
1414 #endif /* HAVE_SET_AUTH_PARAMETERS */
1416 /* just in case it goes wild ... */
1421 /* we don't want any SIGPIPE messages */
1422 BlockSignals(True
,SIGPIPE
);
1424 debug_set_logfile("/dev/null");
1426 /* we don't want stderr screwing us up */
1428 open("/dev/null", O_WRONLY
);
1429 setup_logging("swat", DEBUG_FILE
);
1433 pc
= poptGetContext("swat", argc
, (const char **) argv
, long_options
, 0);
1435 /* Parse command line options */
1437 while(poptGetNextOpt(pc
) != -1) { }
1439 poptFreeContext(pc
);
1441 /* This should set a more apporiate log file */
1445 iNumNonAutoPrintServices
= lp_numservices();
1446 if (pcap_cache_loaded()) {
1447 load_printers(server_event_context(),
1448 server_messaging_context());
1451 cgi_setup(get_dyn_SWATDIR(), !demo_mode
);
1455 cgi_load_variables();
1457 if (!file_exist(get_dyn_CONFIGFILE())) {
1458 have_read_access
= True
;
1459 have_write_access
= True
;
1461 /* check if the authenticated user has write access - if not then
1462 don't show write options */
1463 have_write_access
= (access(get_dyn_CONFIGFILE(),W_OK
) == 0);
1465 /* if the user doesn't have read access to smb.conf then
1466 don't let them view it */
1467 have_read_access
= (access(get_dyn_CONFIGFILE(),R_OK
) == 0);
1470 show_main_buttons();
1472 page
= cgi_pathinfo();
1474 /* Root gets full functionality */
1475 if (have_read_access
&& strcmp(page
, "globals")==0) {
1477 } else if (have_read_access
&& strcmp(page
,"shares")==0) {
1479 } else if (have_read_access
&& strcmp(page
,"printers")==0) {
1481 } else if (have_read_access
&& strcmp(page
,"status")==0) {
1483 } else if (have_read_access
&& strcmp(page
,"viewconfig")==0) {
1485 } else if (strcmp(page
,"passwd")==0) {
1487 } else if (have_read_access
&& strcmp(page
,"wizard")==0) {
1489 } else if (have_read_access
&& strcmp(page
,"wizard_params")==0) {
1490 wizard_params_page();
1491 } else if (have_read_access
&& strcmp(page
,"rewritecfg")==0) {