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"
38 static int demo_mode = False;
39 static int passwd_only = False;
40 static bool have_write_access = False;
41 static bool have_read_access = False;
42 static int iNumNonAutoPrintServices = 0;
45 * Password Management Globals
47 #define SWAT_USER "username"
48 #define OLD_PSWD "old_passwd"
49 #define NEW_PSWD "new_passwd"
50 #define NEW2_PSWD "new2_passwd"
51 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
52 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
53 #define ADD_USER_FLAG "add_user_flag"
54 #define DELETE_USER_FLAG "delete_user_flag"
55 #define DISABLE_USER_FLAG "disable_user_flag"
56 #define ENABLE_USER_FLAG "enable_user_flag"
57 #define RHOST "remote_host"
59 #define _(x) lang_msg_rotate(talloc_tos(),x)
61 /****************************************************************************
62 ****************************************************************************/
63 static int enum_index(int value, const struct enum_list *enumlist)
66 for (i=0;enumlist[i].name;i++)
67 if (value == enumlist[i].value) break;
71 static char *fix_backslash(const char *str)
73 static char newstring[1024];
77 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
85 static const char *fix_quotes(TALLOC_CTX *ctx, const char *str)
87 char *newstring = NULL;
90 int quote_len = strlen(""");
92 /* Count the number of quotes. */
97 newstring_len += quote_len;
103 newstring = TALLOC_ARRAY(ctx, char, newstring_len);
107 for (p = newstring; *str; str++) {
109 strncpy( p, """, quote_len);
119 static char *stripspaceupper(const char *str)
121 static char newstring[1024];
125 if (*str != ' ') *p++ = toupper_ascii(*str);
132 static char *make_parm_name(const char *label)
134 static char parmname[1024];
138 if (*label == ' ') *p++ = '_';
146 /****************************************************************************
147 include a lump of html in a page
148 ****************************************************************************/
149 static int include_html(const char *fname)
155 fd = web_open(fname, O_RDONLY, 0);
158 printf(_("ERROR: Can't open %s"), fname);
163 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
164 if (write(1, buf, ret) == -1) {
173 /****************************************************************************
174 start the page with standard stuff
175 ****************************************************************************/
176 static void print_header(void)
178 if (!cgi_waspost()) {
179 printf("Expires: 0\r\n");
181 printf("Content-type: text/html\r\n\r\n");
183 if (!include_html("include/header.html")) {
184 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
185 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
189 /* *******************************************************************
190 show parameter label with translated name in the following form
191 because showing original and translated label in one line looks
192 too long, and showing translated label only is unusable for
194 -------------------------------
195 HELP security [combo box][button]
197 -------------------------------
198 (capital words are translated by gettext.)
199 if no translation is available, then same form as original is
201 "i18n_translated_parm" class is used to change the color of the
202 translated parameter with CSS.
203 **************************************************************** */
204 static const char *get_parm_translated(TALLOC_CTX *ctx,
205 const char* pAnchor, const char* pHelp, const char* pLabel)
207 const char *pTranslated = _(pLabel);
209 if(strcmp(pLabel, pTranslated) != 0) {
210 output = talloc_asprintf(ctx,
211 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
212 pAnchor, pHelp, pLabel, pTranslated);
215 output = talloc_asprintf(ctx,
216 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
217 pAnchor, pHelp, pLabel);
220 /****************************************************************************
222 ****************************************************************************/
223 static void print_footer(void)
225 if (!include_html("include/footer.html")) {
226 printf("\n</BODY>\n</HTML>\n");
230 /****************************************************************************
231 display one editable parameter in a form
232 ****************************************************************************/
233 static void show_parameter(int snum, struct parm_struct *parm)
236 void *ptr = parm->ptr;
237 char *utf8_s1, *utf8_s2;
238 size_t converted_size;
239 TALLOC_CTX *ctx = talloc_stackframe();
241 if (parm->p_class == P_LOCAL && snum >= 0) {
242 ptr = lp_local_ptr_by_snum(snum, ptr);
245 printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
246 stripspaceupper(parm->label), _("Help"), parm->label));
247 switch (parm->type) {
249 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
250 make_parm_name(parm->label), *(char *)ptr);
251 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
252 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
256 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
257 make_parm_name(parm->label));
258 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
259 char **list = *(char ***)ptr;
260 for (;*list;list++) {
261 /* enclose in HTML encoded quotes if the string contains a space */
262 if ( strchr_m(*list, ' ') ) {
263 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
264 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
265 printf(""%s"%s", utf8_s1, utf8_s2);
267 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
268 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
269 printf("%s%s", utf8_s1, utf8_s2);
271 TALLOC_FREE(utf8_s1);
272 TALLOC_FREE(utf8_s2);
276 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
277 _("Set Default"), make_parm_name(parm->label));
278 if (parm->def.lvalue) {
279 char **list = (char **)(parm->def.lvalue);
280 for (; *list; list++) {
281 /* enclose in HTML encoded quotes if the string contains a space */
282 if ( strchr_m(*list, ' ') )
283 printf(""%s"%s", *list, ((*(list+1))?", ":""));
285 printf("%s%s", *list, ((*(list+1))?", ":""));
293 push_utf8_talloc(talloc_tos(), &utf8_s1, *(char **)ptr, &converted_size);
294 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
295 make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
296 TALLOC_FREE(utf8_s1);
297 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
298 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
302 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
303 printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
304 printf("<option %s>No", (*(bool *)ptr)?"":"selected");
306 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
307 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
311 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
312 printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
313 printf("<option %s>No", (*(bool *)ptr)?"selected":"");
315 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
316 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
320 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
321 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
322 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
327 o = octal_string(*(int *)ptr);
328 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
329 make_parm_name(parm->label), o);
331 o = octal_string((int)(parm->def.ivalue));
332 printf("<input type=button value=\"%s\" "
333 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
334 _("Set Default"), make_parm_name(parm->label), o);
340 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
341 for (i=0;parm->enum_list[i].name;i++) {
342 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
343 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
347 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
348 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
353 printf("</td></tr>\n");
357 /****************************************************************************
358 display a set of parameters for a service
359 ****************************************************************************/
360 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
363 struct parm_struct *parm;
364 const char *heading = NULL;
365 const char *last_heading = NULL;
367 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
368 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
370 if (parm->p_class == P_SEPARATOR) {
371 heading = parm->label;
374 if (parm->flags & FLAG_HIDE) continue;
376 if (printers & !(parm->flags & FLAG_PRINT)) continue;
377 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
380 if (!( parm_filter & FLAG_ADVANCED )) {
381 if (!(parm->flags & FLAG_BASIC)) {
382 void *ptr = parm->ptr;
384 if (parm->p_class == P_LOCAL && snum >= 0) {
385 ptr = lp_local_ptr_by_snum(snum, ptr);
388 switch (parm->type) {
390 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
394 if (!str_list_equal(*(const char ***)ptr,
395 (const char **)(parm->def.lvalue))) continue;
400 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
405 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
410 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
415 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
421 if (printers && !(parm->flags & FLAG_PRINT)) continue;
424 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
426 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
428 if (heading && heading != last_heading) {
429 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
430 last_heading = heading;
432 show_parameter(snum, parm);
436 /****************************************************************************
437 load the smb.conf file into loadparm.
438 ****************************************************************************/
439 static bool load_config(bool save_def)
441 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
444 /****************************************************************************
446 ****************************************************************************/
447 static void write_config(FILE *f, bool show_defaults)
449 TALLOC_CTX *ctx = talloc_stackframe();
451 fprintf(f, "# Samba config file created using SWAT\n");
452 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
453 fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
455 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
460 /****************************************************************************
461 save and reload the smb.conf config file
462 ****************************************************************************/
463 static int save_reload(int snum)
468 f = sys_fopen(get_dyn_CONFIGFILE(),"w");
470 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
475 /* just in case they have used the buggy xinetd to create the file */
476 if (fstat(fileno(f), &st) == 0 &&
477 (st.st_mode & S_IWOTH)) {
478 #if defined HAVE_FCHMOD
479 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
481 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
485 write_config(f, False);
487 lp_dump_one(f, False, snum);
490 lp_kill_all_services();
492 if (!load_config(False)) {
493 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
497 iNumNonAutoPrintServices = lp_numservices();
498 if (pcap_cache_loaded()) {
499 load_printers(server_event_context(),
500 server_messaging_context());
506 /****************************************************************************
508 ****************************************************************************/
509 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
514 if (snum < 0 && parm->p_class == P_LOCAL) {
515 /* this handles the case where we are changing a local
516 variable globally. We need to change the parameter in
517 all shares where it is currently set to the default */
518 for (i=0;i<lp_numservices();i++) {
519 s = lp_servicename(i);
520 if (s && (*s) && lp_is_default(i, parm)) {
521 lp_do_parameter(i, parm->label, v);
526 lp_do_parameter(snum, parm->label, v);
529 /****************************************************************************
530 commit a set of parameters for a service
531 ****************************************************************************/
532 static void commit_parameters(int snum)
535 struct parm_struct *parm;
539 while ((parm = lp_next_parameter(snum, &i, 1))) {
540 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
541 if ((v = cgi_variable(label)) != NULL) {
542 if (parm->flags & FLAG_HIDE)
544 commit_parameter(snum, parm, v);
551 /****************************************************************************
552 spit out the html for a link with an image
553 ****************************************************************************/
554 static void image_link(const char *name, const char *hlink, const char *src)
556 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
557 cgi_baseurl(), hlink, src, name);
560 /****************************************************************************
561 display the main navigation controls at the top of each page along
563 ****************************************************************************/
564 static void show_main_buttons(void)
568 if ((p = cgi_user_name()) && strcmp(p, "root")) {
569 printf(_("Logged in as <b>%s</b>"), p);
573 image_link(_("Home"), "", "images/home.gif");
574 if (have_write_access) {
575 image_link(_("Globals"), "globals", "images/globals.gif");
576 image_link(_("Shares"), "shares", "images/shares.gif");
577 image_link(_("Printers"), "printers", "images/printers.gif");
578 image_link(_("Wizard"), "wizard", "images/wizard.gif");
580 /* root always gets all buttons, otherwise look for -P */
581 if ( have_write_access || (!passwd_only && have_read_access) ) {
582 image_link(_("Status"), "status", "images/status.gif");
583 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
585 image_link(_("Password Management"), "passwd", "images/passwd.gif");
590 /****************************************************************************
591 * Handle Display/Edit Mode CGI
592 ****************************************************************************/
593 static void ViewModeBoxes(int mode)
595 printf("<p>%s: \n", _("Current View Is"));
596 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
597 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
598 printf("<br>%s: \n", _("Change View To"));
599 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
600 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
601 printf("</p><br>\n");
604 /****************************************************************************
605 display a welcome page
606 ****************************************************************************/
607 static void welcome_page(void)
609 if (file_exist("help/welcome.html")) {
610 include_html("help/welcome.html");
612 include_html("help/welcome-no-samba-doc.html");
616 /****************************************************************************
617 display the current smb.conf
618 ****************************************************************************/
619 static void viewconfig_page(void)
623 if (cgi_variable("full_view")) {
627 printf("<H2>%s</H2>\n", _("Current Config"));
628 printf("<form method=post>\n");
631 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
633 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
637 write_config(stdout, full_view);
642 /****************************************************************************
643 second screen of the wizard ... Fetch Configuration Parameters
644 ****************************************************************************/
645 static void wizard_params_page(void)
647 unsigned int parm_filter = FLAG_WIZARD;
649 /* Here we first set and commit all the parameters that were selected
650 in the previous screen. */
652 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
654 if (cgi_variable("Commit")) {
655 commit_parameters(GLOBAL_SECTION_SNUM);
659 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
661 if (have_write_access) {
662 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
665 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
669 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
670 printf("</table>\n");
674 /****************************************************************************
675 Utility to just rewrite the smb.conf file - effectively just cleans it up
676 ****************************************************************************/
677 static void rewritecfg_file(void)
679 commit_parameters(GLOBAL_SECTION_SNUM);
681 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
684 /****************************************************************************
685 wizard to create/modify the smb.conf file
686 ****************************************************************************/
687 static void wizard_page(void)
689 /* Set some variables to collect data from smb.conf */
696 if (cgi_variable("Rewrite")) {
697 (void) rewritecfg_file();
701 if (cgi_variable("GetWizardParams")){
702 (void) wizard_params_page();
706 if (cgi_variable("Commit")){
707 SerType = atoi(cgi_variable_nonull("ServerType"));
708 winstype = atoi(cgi_variable_nonull("WINSType"));
709 have_home = lp_servicenumber(HOMES_NAME);
710 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
712 /* Plain text passwords are too badly broken - use encrypted passwords only */
713 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
717 /* Stand-alone Server */
718 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
719 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
723 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
724 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
727 /* Domain Controller */
728 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
729 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
732 switch ( winstype ) {
734 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
735 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
738 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
739 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
742 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
743 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
747 /* Have to create Homes share? */
748 if ((HomeExpo == 1) && (have_home == -1)) {
749 const char *unix_share = HOMES_NAME;
752 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
753 have_home = lp_servicenumber(HOMES_NAME);
754 lp_do_parameter( have_home, "read only", "No");
755 lp_do_parameter( have_home, "valid users", "%S");
756 lp_do_parameter( have_home, "browseable", "No");
757 commit_parameters(have_home);
758 save_reload(have_home);
761 /* Need to Delete Homes share? */
762 if ((HomeExpo == 0) && (have_home != -1)) {
763 lp_remove_service(have_home);
767 commit_parameters(GLOBAL_SECTION_SNUM);
772 /* Now determine smb.conf WINS settings */
773 if (lp_wins_support())
775 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
778 /* Do we have a homes share? */
779 have_home = lp_servicenumber(HOMES_NAME);
781 if ((winstype == 2) && lp_wins_support())
784 role = lp_server_role();
787 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
788 printf("<form method=post action=wizard>\n");
790 if (have_write_access) {
791 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
792 printf("%s", _("The same will happen if you press the commit button."));
793 printf("<br><br>\n");
795 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
796 printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
797 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
798 printf("</center>\n");
802 printf("<center><table border=0>");
803 printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
804 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
805 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
806 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
808 if (role == ROLE_DOMAIN_BDC) {
809 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
811 printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
812 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
813 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
814 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
816 printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
818 /* Print out the list of wins servers */
819 if(lp_wins_server_list()) {
821 const char **wins_servers = lp_wins_server_list();
822 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
825 printf("\"></td></tr>\n");
827 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Error: WINS Server Mode and WINS Support both set in smb.conf"));
828 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
830 printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
831 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
832 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
833 printf("<td></td></tr>\n");
835 /* Enable this when we are ready ....
836 * printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
837 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
838 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
839 * printf("<td></td></tr>\n");
842 printf("</table></center>");
845 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
850 /****************************************************************************
851 display a globals editing page
852 ****************************************************************************/
853 static void globals_page(void)
855 unsigned int parm_filter = FLAG_BASIC;
858 printf("<H2>%s</H2>\n", _("Global Parameters"));
860 if (cgi_variable("Commit")) {
861 commit_parameters(GLOBAL_SECTION_SNUM);
865 if ( cgi_variable("ViewMode") )
866 mode = atoi(cgi_variable_nonull("ViewMode"));
867 if ( cgi_variable("BasicMode"))
869 if ( cgi_variable("AdvMode"))
872 printf("<form name=\"swatform\" method=post action=globals>\n");
874 ViewModeBoxes( mode );
877 parm_filter = FLAG_BASIC;
880 parm_filter = FLAG_ADVANCED;
884 if (have_write_access) {
885 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
886 _("Commit Changes"));
889 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
894 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
895 printf("</table>\n");
899 /****************************************************************************
900 display a shares editing page. share is in unix codepage,
901 ****************************************************************************/
902 static void shares_page(void)
904 const char *share = cgi_variable("share");
910 unsigned int parm_filter = FLAG_BASIC;
911 size_t converted_size;
914 snum = lp_servicenumber(share);
916 printf("<H2>%s</H2>\n", _("Share Parameters"));
918 if (cgi_variable("Commit") && snum >= 0) {
919 commit_parameters(snum);
921 snum = lp_servicenumber(share);
924 if (cgi_variable("Delete") && snum >= 0) {
925 lp_remove_service(snum);
931 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
932 snum = lp_servicenumber(share);
935 lp_copy_service(GLOBAL_SECTION_SNUM, share);
936 snum = lp_servicenumber(share);
938 snum = lp_servicenumber(share);
942 printf("<FORM name=\"swatform\" method=post>\n");
946 if ( cgi_variable("ViewMode") )
947 mode = atoi(cgi_variable_nonull("ViewMode"));
948 if ( cgi_variable("BasicMode"))
950 if ( cgi_variable("AdvMode"))
953 ViewModeBoxes( mode );
956 parm_filter = FLAG_BASIC;
959 parm_filter = FLAG_ADVANCED;
962 printf("<br><tr>\n");
963 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
964 printf("<td><select name=share>\n");
966 printf("<option value=\" \"> \n");
967 for (i=0;i<lp_numservices();i++) {
968 s = lp_servicename(i);
969 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
970 push_utf8_talloc(talloc_tos(), &utf8_s, s, &converted_size);
971 printf("<option %s value=\"%s\">%s\n",
972 (share && strcmp(share,s)==0)?"SELECTED":"",
977 printf("</select></td>\n");
978 if (have_write_access) {
979 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
984 if (have_write_access) {
986 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
987 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
993 if (have_write_access) {
994 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
997 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1002 printf("<table>\n");
1003 show_parameters(snum, 1, parm_filter, 0);
1004 printf("</table>\n");
1007 printf("</FORM>\n");
1010 /*************************************************************
1011 change a password either locally or remotely
1012 *************************************************************/
1013 static bool change_password(const char *remote_machine, const char *user_name,
1014 const char *old_passwd, const char *new_passwd,
1018 char *err_str = NULL;
1019 char *msg_str = NULL;
1022 printf("%s\n<p>", _("password change in demo mode rejected"));
1026 if (remote_machine != NULL) {
1027 ret = remote_password_change(remote_machine, user_name,
1028 old_passwd, new_passwd, &err_str);
1029 if (err_str != NULL)
1030 printf("%s\n<p>", err_str);
1032 return NT_STATUS_IS_OK(ret);
1035 if(!initialize_password_db(True, NULL)) {
1036 printf("%s\n<p>", _("Can't setup password database vectors."));
1040 ret = local_password_change(user_name, local_flags, new_passwd,
1041 &err_str, &msg_str);
1044 printf("%s\n<p>", msg_str);
1046 printf("%s\n<p>", err_str);
1050 return NT_STATUS_IS_OK(ret);
1053 /****************************************************************************
1054 do the stuff required to add or change a password
1055 ****************************************************************************/
1056 static void chg_passwd(void)
1060 int local_flags = 0;
1062 /* Make sure users name has been specified */
1063 if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1064 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1069 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1070 * so if that's what we're doing, skip the rest of the checks
1072 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1075 * If current user is not root, make sure old password has been specified
1076 * If REMOTE change, even root must provide old password
1078 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1079 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1080 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1084 /* If changing a users password on a remote hosts we have to know what host */
1085 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1086 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1090 /* Make sure new passwords have been specified */
1091 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1092 (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1093 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1097 /* Make sure new passwords was typed correctly twice */
1098 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1099 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1104 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1105 host = cgi_variable(RHOST);
1106 } else if (am_root()) {
1113 * Set up the local flags.
1116 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1117 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1118 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1119 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1120 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1121 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1123 rslt = change_password(host,
1124 cgi_variable_nonull(SWAT_USER),
1125 cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1128 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1131 printf(_(" The passwd for '%s' has been changed."), cgi_variable_nonull(SWAT_USER));
1134 printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable_nonull(SWAT_USER));
1142 /****************************************************************************
1143 display a password editing page
1144 ****************************************************************************/
1145 static void passwd_page(void)
1147 const char *new_name = cgi_user_name();
1150 * After the first time through here be nice. If the user
1151 * changed the User box text to another users name, remember it.
1153 if (cgi_variable(SWAT_USER)) {
1154 new_name = cgi_variable_nonull(SWAT_USER);
1157 if (!new_name) new_name = "";
1159 printf("<H2>%s</H2>\n", _("Server Password Management"));
1161 printf("<FORM name=\"swatform\" method=post>\n");
1163 printf("<table>\n");
1166 * Create all the dialog boxes for data collection
1168 printf("<tr><td> %s : </td>\n", _("User Name"));
1169 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1171 printf("<tr><td> %s : </td>\n", _("Old Password"));
1172 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1174 printf("<tr><td> %s : </td>\n", _("New Password"));
1175 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1176 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1177 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1178 printf("</table>\n");
1181 * Create all the control buttons for requesting action
1183 printf("<input type=submit name=%s value=\"%s\">\n",
1184 CHG_S_PASSWD_FLAG, _("Change Password"));
1185 if (demo_mode || am_root()) {
1186 printf("<input type=submit name=%s value=\"%s\">\n",
1187 ADD_USER_FLAG, _("Add New User"));
1188 printf("<input type=submit name=%s value=\"%s\">\n",
1189 DELETE_USER_FLAG, _("Delete User"));
1190 printf("<input type=submit name=%s value=\"%s\">\n",
1191 DISABLE_USER_FLAG, _("Disable User"));
1192 printf("<input type=submit name=%s value=\"%s\">\n",
1193 ENABLE_USER_FLAG, _("Enable User"));
1195 printf("<p></FORM>\n");
1198 * Do some work if change, add, disable or enable was
1199 * requested. It could be this is the first time through this
1200 * code, so there isn't anything to do. */
1201 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1202 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1206 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1208 printf("<FORM name=\"swatform\" method=post>\n");
1210 printf("<table>\n");
1213 * Create all the dialog boxes for data collection
1215 printf("<tr><td> %s : </td>\n", _("User Name"));
1216 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1217 printf("<tr><td> %s : </td>\n", _("Old Password"));
1218 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1219 printf("<tr><td> %s : </td>\n", _("New Password"));
1220 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1221 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1222 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1223 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1224 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1229 * Create all the control buttons for requesting action
1231 printf("<input type=submit name=%s value=\"%s\">",
1232 CHG_R_PASSWD_FLAG, _("Change Password"));
1234 printf("<p></FORM>\n");
1237 * Do some work if a request has been made to change the
1238 * password somewhere other than the server. It could be this
1239 * is the first time through this code, so there isn't
1240 * anything to do. */
1241 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1247 /****************************************************************************
1248 display a printers editing page
1249 ****************************************************************************/
1250 static void printers_page(void)
1252 const char *share = cgi_variable("share");
1257 unsigned int parm_filter = FLAG_BASIC;
1260 snum = lp_servicenumber(share);
1262 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1264 printf("<H3>%s</H3>\n", _("Important Note:"));
1265 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1266 printf("%s",_("are autoloaded printers from "));
1267 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1268 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1270 if (cgi_variable("Commit") && snum >= 0) {
1271 commit_parameters(snum);
1272 if (snum >= iNumNonAutoPrintServices)
1276 snum = lp_servicenumber(share);
1279 if (cgi_variable("Delete") && snum >= 0) {
1280 lp_remove_service(snum);
1286 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1287 snum = lp_servicenumber(share);
1288 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1290 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1291 snum = lp_servicenumber(share);
1292 lp_do_parameter(snum, "print ok", "Yes");
1294 snum = lp_servicenumber(share);
1298 printf("<FORM name=\"swatform\" method=post>\n");
1300 if ( cgi_variable("ViewMode") )
1301 mode = atoi(cgi_variable_nonull("ViewMode"));
1302 if ( cgi_variable("BasicMode"))
1304 if ( cgi_variable("AdvMode"))
1307 ViewModeBoxes( mode );
1310 parm_filter = FLAG_BASIC;
1313 parm_filter = FLAG_ADVANCED;
1316 printf("<table>\n");
1317 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1318 printf("<td><select name=\"share\">\n");
1319 if (snum < 0 || !lp_print_ok(snum))
1320 printf("<option value=\" \"> \n");
1321 for (i=0;i<lp_numservices();i++) {
1322 s = lp_servicename(i);
1323 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1324 if (i >= iNumNonAutoPrintServices)
1325 printf("<option %s value=\"%s\">[*]%s\n",
1326 (share && strcmp(share,s)==0)?"SELECTED":"",
1329 printf("<option %s value=\"%s\">%s\n",
1330 (share && strcmp(share,s)==0)?"SELECTED":"",
1334 printf("</select></td>");
1335 if (have_write_access) {
1336 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1339 printf("</table>\n");
1341 if (have_write_access) {
1342 printf("<table>\n");
1343 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1344 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1350 if (have_write_access) {
1351 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1353 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1358 printf("<table>\n");
1359 show_parameters(snum, 1, parm_filter, 1);
1360 printf("</table>\n");
1362 printf("</FORM>\n");
1366 when the _() translation macro is used there is no obvious place to free
1367 the resulting string and there is no easy way to give a static pointer.
1368 All we can do is rotate between some static buffers and hope a single d_printf()
1369 doesn't have more calls to _() than the number of buffers
1372 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1377 msgstr = lang_msg(msgid);
1382 ret = talloc_strdup(ctx, msgstr);
1384 lang_msg_free(msgstr);
1393 * main function for SWAT.
1395 int main(int argc, char *argv[])
1399 struct poptOption long_options[] = {
1401 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1402 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1406 TALLOC_CTX *frame = talloc_stackframe();
1409 umask(S_IWGRP | S_IWOTH);
1411 #if defined(HAVE_SET_AUTH_PARAMETERS)
1412 set_auth_parameters(argc, argv);
1413 #endif /* HAVE_SET_AUTH_PARAMETERS */
1415 /* just in case it goes wild ... */
1420 /* we don't want any SIGPIPE messages */
1421 BlockSignals(True,SIGPIPE);
1423 debug_set_logfile("/dev/null");
1425 /* we don't want stderr screwing us up */
1427 open("/dev/null", O_WRONLY);
1428 setup_logging("swat", DEBUG_FILE);
1432 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1434 /* Parse command line options */
1436 while(poptGetNextOpt(pc) != -1) { }
1438 poptFreeContext(pc);
1440 /* This should set a more apporiate log file */
1444 iNumNonAutoPrintServices = lp_numservices();
1445 if (pcap_cache_loaded()) {
1446 load_printers(server_event_context(),
1447 server_messaging_context());
1450 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1454 cgi_load_variables();
1456 if (!file_exist(get_dyn_CONFIGFILE())) {
1457 have_read_access = True;
1458 have_write_access = True;
1460 /* check if the authenticated user has write access - if not then
1461 don't show write options */
1462 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1464 /* if the user doesn't have read access to smb.conf then
1465 don't let them view it */
1466 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1469 show_main_buttons();
1471 page = cgi_pathinfo();
1473 /* Root gets full functionality */
1474 if (have_read_access && strcmp(page, "globals")==0) {
1476 } else if (have_read_access && strcmp(page,"shares")==0) {
1478 } else if (have_read_access && strcmp(page,"printers")==0) {
1480 } else if (have_read_access && strcmp(page,"status")==0) {
1482 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1484 } else if (strcmp(page,"passwd")==0) {
1486 } else if (have_read_access && strcmp(page,"wizard")==0) {
1488 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1489 wizard_params_page();
1490 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {