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 "popt_common.h"
32 #include "web/swat_proto.h"
33 #include "printing/pcap.h"
34 #include "printing/load.h"
36 static int demo_mode = False;
37 static int passwd_only = False;
38 static bool have_write_access = False;
39 static bool have_read_access = False;
40 static int iNumNonAutoPrintServices = 0;
43 * Password Management Globals
45 #define SWAT_USER "username"
46 #define OLD_PSWD "old_passwd"
47 #define NEW_PSWD "new_passwd"
48 #define NEW2_PSWD "new2_passwd"
49 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
50 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
51 #define ADD_USER_FLAG "add_user_flag"
52 #define DELETE_USER_FLAG "delete_user_flag"
53 #define DISABLE_USER_FLAG "disable_user_flag"
54 #define ENABLE_USER_FLAG "enable_user_flag"
55 #define RHOST "remote_host"
57 #define _(x) lang_msg_rotate(talloc_tos(),x)
59 /****************************************************************************
60 ****************************************************************************/
61 static int enum_index(int value, const struct enum_list *enumlist)
64 for (i=0;enumlist[i].name;i++)
65 if (value == enumlist[i].value) break;
69 static char *fix_backslash(const char *str)
71 static char newstring[1024];
75 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
83 static const char *fix_quotes(TALLOC_CTX *ctx, const char *str)
85 char *newstring = NULL;
88 int quote_len = strlen(""");
90 /* Count the number of quotes. */
95 newstring_len += quote_len;
101 newstring = TALLOC_ARRAY(ctx, char, newstring_len);
105 for (p = newstring; *str; str++) {
107 strncpy( p, """, quote_len);
117 static char *stripspaceupper(const char *str)
119 static char newstring[1024];
123 if (*str != ' ') *p++ = toupper_ascii(*str);
130 static char *make_parm_name(const char *label)
132 static char parmname[1024];
136 if (*label == ' ') *p++ = '_';
144 /****************************************************************************
145 include a lump of html in a page
146 ****************************************************************************/
147 static int include_html(const char *fname)
153 fd = web_open(fname, O_RDONLY, 0);
156 printf(_("ERROR: Can't open %s"), fname);
161 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
162 if (write(1, buf, ret) == -1) {
171 /****************************************************************************
172 start the page with standard stuff
173 ****************************************************************************/
174 static void print_header(void)
176 if (!cgi_waspost()) {
177 printf("Expires: 0\r\n");
179 printf("Content-type: text/html\r\n\r\n");
181 if (!include_html("include/header.html")) {
182 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
183 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
187 /* *******************************************************************
188 show parameter label with translated name in the following form
189 because showing original and translated label in one line looks
190 too long, and showing translated label only is unusable for
192 -------------------------------
193 HELP security [combo box][button]
195 -------------------------------
196 (capital words are translated by gettext.)
197 if no translation is available, then same form as original is
199 "i18n_translated_parm" class is used to change the color of the
200 translated parameter with CSS.
201 **************************************************************** */
202 static const char *get_parm_translated(TALLOC_CTX *ctx,
203 const char* pAnchor, const char* pHelp, const char* pLabel)
205 const char *pTranslated = _(pLabel);
207 if(strcmp(pLabel, pTranslated) != 0) {
208 output = talloc_asprintf(ctx,
209 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
210 pAnchor, pHelp, pLabel, pTranslated);
213 output = talloc_asprintf(ctx,
214 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
215 pAnchor, pHelp, pLabel);
218 /****************************************************************************
220 ****************************************************************************/
221 static void print_footer(void)
223 if (!include_html("include/footer.html")) {
224 printf("\n</BODY>\n</HTML>\n");
228 /****************************************************************************
229 display one editable parameter in a form
230 ****************************************************************************/
231 static void show_parameter(int snum, struct parm_struct *parm)
234 void *ptr = parm->ptr;
235 char *utf8_s1, *utf8_s2;
236 size_t converted_size;
237 TALLOC_CTX *ctx = talloc_stackframe();
239 if (parm->p_class == P_LOCAL && snum >= 0) {
240 ptr = lp_local_ptr_by_snum(snum, ptr);
243 printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
244 stripspaceupper(parm->label), _("Help"), parm->label));
245 switch (parm->type) {
247 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
248 make_parm_name(parm->label), *(char *)ptr);
249 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
250 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
254 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
255 make_parm_name(parm->label));
256 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
257 char **list = *(char ***)ptr;
258 for (;*list;list++) {
259 /* enclose in HTML encoded quotes if the string contains a space */
260 if ( strchr_m(*list, ' ') ) {
261 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
262 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
263 printf(""%s"%s", utf8_s1, utf8_s2);
265 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
266 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
267 printf("%s%s", utf8_s1, utf8_s2);
269 TALLOC_FREE(utf8_s1);
270 TALLOC_FREE(utf8_s2);
274 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
275 _("Set Default"), make_parm_name(parm->label));
276 if (parm->def.lvalue) {
277 char **list = (char **)(parm->def.lvalue);
278 for (; *list; list++) {
279 /* enclose in HTML encoded quotes if the string contains a space */
280 if ( strchr_m(*list, ' ') )
281 printf(""%s"%s", *list, ((*(list+1))?", ":""));
283 printf("%s%s", *list, ((*(list+1))?", ":""));
291 push_utf8_talloc(talloc_tos(), &utf8_s1, *(char **)ptr, &converted_size);
292 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
293 make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
294 TALLOC_FREE(utf8_s1);
295 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
296 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
300 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
301 printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
302 printf("<option %s>No", (*(bool *)ptr)?"":"selected");
304 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
305 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
309 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
310 printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
311 printf("<option %s>No", (*(bool *)ptr)?"selected":"");
313 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
314 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
318 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
319 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
320 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
325 o = octal_string(*(int *)ptr);
326 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
327 make_parm_name(parm->label), o);
329 o = octal_string((int)(parm->def.ivalue));
330 printf("<input type=button value=\"%s\" "
331 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
332 _("Set Default"), make_parm_name(parm->label), o);
338 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
339 for (i=0;parm->enum_list[i].name;i++) {
340 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
341 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
345 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
346 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
351 printf("</td></tr>\n");
355 /****************************************************************************
356 display a set of parameters for a service
357 ****************************************************************************/
358 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
361 struct parm_struct *parm;
362 const char *heading = NULL;
363 const char *last_heading = NULL;
365 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
366 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
368 if (parm->p_class == P_SEPARATOR) {
369 heading = parm->label;
372 if (parm->flags & FLAG_HIDE) continue;
374 if (printers & !(parm->flags & FLAG_PRINT)) continue;
375 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
378 if (!( parm_filter & FLAG_ADVANCED )) {
379 if (!(parm->flags & FLAG_BASIC)) {
380 void *ptr = parm->ptr;
382 if (parm->p_class == P_LOCAL && snum >= 0) {
383 ptr = lp_local_ptr_by_snum(snum, ptr);
386 switch (parm->type) {
388 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
392 if (!str_list_equal(*(const char ***)ptr,
393 (const char **)(parm->def.lvalue))) continue;
398 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
403 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
408 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
413 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
419 if (printers && !(parm->flags & FLAG_PRINT)) continue;
422 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
424 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
426 if (heading && heading != last_heading) {
427 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
428 last_heading = heading;
430 show_parameter(snum, parm);
434 /****************************************************************************
435 load the smb.conf file into loadparm.
436 ****************************************************************************/
437 static bool load_config(bool save_def)
439 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
442 /****************************************************************************
444 ****************************************************************************/
445 static void write_config(FILE *f, bool show_defaults)
447 TALLOC_CTX *ctx = talloc_stackframe();
449 fprintf(f, "# Samba config file created using SWAT\n");
450 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
451 fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
453 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
458 /****************************************************************************
459 save and reload the smb.conf config file
460 ****************************************************************************/
461 static int save_reload(int snum)
466 f = sys_fopen(get_dyn_CONFIGFILE(),"w");
468 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
473 /* just in case they have used the buggy xinetd to create the file */
474 if (fstat(fileno(f), &st) == 0 &&
475 (st.st_mode & S_IWOTH)) {
476 #if defined HAVE_FCHMOD
477 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
479 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
483 write_config(f, False);
485 lp_dump_one(f, False, snum);
488 lp_kill_all_services();
490 if (!load_config(False)) {
491 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
495 iNumNonAutoPrintServices = lp_numservices();
496 if (pcap_cache_loaded()) {
497 load_printers(server_event_context(),
498 server_messaging_context());
504 /****************************************************************************
506 ****************************************************************************/
507 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
512 if (snum < 0 && parm->p_class == P_LOCAL) {
513 /* this handles the case where we are changing a local
514 variable globally. We need to change the parameter in
515 all shares where it is currently set to the default */
516 for (i=0;i<lp_numservices();i++) {
517 s = lp_servicename(i);
518 if (s && (*s) && lp_is_default(i, parm)) {
519 lp_do_parameter(i, parm->label, v);
524 lp_do_parameter(snum, parm->label, v);
527 /****************************************************************************
528 commit a set of parameters for a service
529 ****************************************************************************/
530 static void commit_parameters(int snum)
533 struct parm_struct *parm;
537 while ((parm = lp_next_parameter(snum, &i, 1))) {
538 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
539 if ((v = cgi_variable(label)) != NULL) {
540 if (parm->flags & FLAG_HIDE)
542 commit_parameter(snum, parm, v);
549 /****************************************************************************
550 spit out the html for a link with an image
551 ****************************************************************************/
552 static void image_link(const char *name, const char *hlink, const char *src)
554 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
555 cgi_baseurl(), hlink, src, name);
558 /****************************************************************************
559 display the main navigation controls at the top of each page along
561 ****************************************************************************/
562 static void show_main_buttons(void)
566 if ((p = cgi_user_name()) && strcmp(p, "root")) {
567 printf(_("Logged in as <b>%s</b>"), p);
571 image_link(_("Home"), "", "images/home.gif");
572 if (have_write_access) {
573 image_link(_("Globals"), "globals", "images/globals.gif");
574 image_link(_("Shares"), "shares", "images/shares.gif");
575 image_link(_("Printers"), "printers", "images/printers.gif");
576 image_link(_("Wizard"), "wizard", "images/wizard.gif");
578 /* root always gets all buttons, otherwise look for -P */
579 if ( have_write_access || (!passwd_only && have_read_access) ) {
580 image_link(_("Status"), "status", "images/status.gif");
581 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
583 image_link(_("Password Management"), "passwd", "images/passwd.gif");
588 /****************************************************************************
589 * Handle Display/Edit Mode CGI
590 ****************************************************************************/
591 static void ViewModeBoxes(int mode)
593 printf("<p>%s: \n", _("Current View Is"));
594 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
595 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
596 printf("<br>%s: \n", _("Change View To"));
597 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
598 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
599 printf("</p><br>\n");
602 /****************************************************************************
603 display a welcome page
604 ****************************************************************************/
605 static void welcome_page(void)
607 if (file_exist("help/welcome.html")) {
608 include_html("help/welcome.html");
610 include_html("help/welcome-no-samba-doc.html");
614 /****************************************************************************
615 display the current smb.conf
616 ****************************************************************************/
617 static void viewconfig_page(void)
621 if (cgi_variable("full_view")) {
625 printf("<H2>%s</H2>\n", _("Current Config"));
626 printf("<form method=post>\n");
629 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
631 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
635 write_config(stdout, full_view);
640 /****************************************************************************
641 second screen of the wizard ... Fetch Configuration Parameters
642 ****************************************************************************/
643 static void wizard_params_page(void)
645 unsigned int parm_filter = FLAG_WIZARD;
647 /* Here we first set and commit all the parameters that were selected
648 in the previous screen. */
650 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
652 if (cgi_variable("Commit")) {
653 commit_parameters(GLOBAL_SECTION_SNUM);
657 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
659 if (have_write_access) {
660 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
663 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
667 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
668 printf("</table>\n");
672 /****************************************************************************
673 Utility to just rewrite the smb.conf file - effectively just cleans it up
674 ****************************************************************************/
675 static void rewritecfg_file(void)
677 commit_parameters(GLOBAL_SECTION_SNUM);
679 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
682 /****************************************************************************
683 wizard to create/modify the smb.conf file
684 ****************************************************************************/
685 static void wizard_page(void)
687 /* Set some variables to collect data from smb.conf */
694 if (cgi_variable("Rewrite")) {
695 (void) rewritecfg_file();
699 if (cgi_variable("GetWizardParams")){
700 (void) wizard_params_page();
704 if (cgi_variable("Commit")){
705 SerType = atoi(cgi_variable_nonull("ServerType"));
706 winstype = atoi(cgi_variable_nonull("WINSType"));
707 have_home = lp_servicenumber(HOMES_NAME);
708 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
710 /* Plain text passwords are too badly broken - use encrypted passwords only */
711 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
715 /* Stand-alone Server */
716 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
717 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
721 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
722 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
725 /* Domain Controller */
726 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
727 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
730 switch ( winstype ) {
732 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
733 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
736 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
737 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
740 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
741 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
745 /* Have to create Homes share? */
746 if ((HomeExpo == 1) && (have_home == -1)) {
747 const char *unix_share = HOMES_NAME;
750 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
751 have_home = lp_servicenumber(HOMES_NAME);
752 lp_do_parameter( have_home, "read only", "No");
753 lp_do_parameter( have_home, "valid users", "%S");
754 lp_do_parameter( have_home, "browseable", "No");
755 commit_parameters(have_home);
756 save_reload(have_home);
759 /* Need to Delete Homes share? */
760 if ((HomeExpo == 0) && (have_home != -1)) {
761 lp_remove_service(have_home);
765 commit_parameters(GLOBAL_SECTION_SNUM);
770 /* Now determine smb.conf WINS settings */
771 if (lp_wins_support())
773 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
776 /* Do we have a homes share? */
777 have_home = lp_servicenumber(HOMES_NAME);
779 if ((winstype == 2) && lp_wins_support())
782 role = lp_server_role();
785 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
786 printf("<form method=post action=wizard>\n");
788 if (have_write_access) {
789 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
790 printf("%s", _("The same will happen if you press the commit button."));
791 printf("<br><br>\n");
793 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
794 printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
795 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
796 printf("</center>\n");
800 printf("<center><table border=0>");
801 printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
802 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
803 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
804 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
806 if (role == ROLE_DOMAIN_BDC) {
807 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
809 printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
810 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
811 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
812 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
814 printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
816 /* Print out the list of wins servers */
817 if(lp_wins_server_list()) {
819 const char **wins_servers = lp_wins_server_list();
820 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
823 printf("\"></td></tr>\n");
825 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"));
826 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
828 printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
829 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
830 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
831 printf("<td></td></tr>\n");
833 /* Enable this when we are ready ....
834 * printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
835 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
836 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
837 * printf("<td></td></tr>\n");
840 printf("</table></center>");
843 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
848 /****************************************************************************
849 display a globals editing page
850 ****************************************************************************/
851 static void globals_page(void)
853 unsigned int parm_filter = FLAG_BASIC;
856 printf("<H2>%s</H2>\n", _("Global Parameters"));
858 if (cgi_variable("Commit")) {
859 commit_parameters(GLOBAL_SECTION_SNUM);
863 if ( cgi_variable("ViewMode") )
864 mode = atoi(cgi_variable_nonull("ViewMode"));
865 if ( cgi_variable("BasicMode"))
867 if ( cgi_variable("AdvMode"))
870 printf("<form name=\"swatform\" method=post action=globals>\n");
872 ViewModeBoxes( mode );
875 parm_filter = FLAG_BASIC;
878 parm_filter = FLAG_ADVANCED;
882 if (have_write_access) {
883 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
884 _("Commit Changes"));
887 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
892 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
893 printf("</table>\n");
897 /****************************************************************************
898 display a shares editing page. share is in unix codepage,
899 ****************************************************************************/
900 static void shares_page(void)
902 const char *share = cgi_variable("share");
908 unsigned int parm_filter = FLAG_BASIC;
909 size_t converted_size;
912 snum = lp_servicenumber(share);
914 printf("<H2>%s</H2>\n", _("Share Parameters"));
916 if (cgi_variable("Commit") && snum >= 0) {
917 commit_parameters(snum);
919 snum = lp_servicenumber(share);
922 if (cgi_variable("Delete") && snum >= 0) {
923 lp_remove_service(snum);
929 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
930 snum = lp_servicenumber(share);
933 lp_copy_service(GLOBAL_SECTION_SNUM, share);
934 snum = lp_servicenumber(share);
936 snum = lp_servicenumber(share);
940 printf("<FORM name=\"swatform\" method=post>\n");
944 if ( cgi_variable("ViewMode") )
945 mode = atoi(cgi_variable_nonull("ViewMode"));
946 if ( cgi_variable("BasicMode"))
948 if ( cgi_variable("AdvMode"))
951 ViewModeBoxes( mode );
954 parm_filter = FLAG_BASIC;
957 parm_filter = FLAG_ADVANCED;
960 printf("<br><tr>\n");
961 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
962 printf("<td><select name=share>\n");
964 printf("<option value=\" \"> \n");
965 for (i=0;i<lp_numservices();i++) {
966 s = lp_servicename(i);
967 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
968 push_utf8_talloc(talloc_tos(), &utf8_s, s, &converted_size);
969 printf("<option %s value=\"%s\">%s\n",
970 (share && strcmp(share,s)==0)?"SELECTED":"",
975 printf("</select></td>\n");
976 if (have_write_access) {
977 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
982 if (have_write_access) {
984 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
985 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
991 if (have_write_access) {
992 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
995 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1000 printf("<table>\n");
1001 show_parameters(snum, 1, parm_filter, 0);
1002 printf("</table>\n");
1005 printf("</FORM>\n");
1008 /*************************************************************
1009 change a password either locally or remotely
1010 *************************************************************/
1011 static bool change_password(const char *remote_machine, const char *user_name,
1012 const char *old_passwd, const char *new_passwd,
1016 char *err_str = NULL;
1017 char *msg_str = NULL;
1020 printf("%s\n<p>", _("password change in demo mode rejected"));
1024 if (remote_machine != NULL) {
1025 ret = remote_password_change(remote_machine, user_name,
1026 old_passwd, new_passwd, &err_str);
1027 if (err_str != NULL)
1028 printf("%s\n<p>", err_str);
1030 return NT_STATUS_IS_OK(ret);
1033 if(!initialize_password_db(True, NULL)) {
1034 printf("%s\n<p>", _("Can't setup password database vectors."));
1038 ret = local_password_change(user_name, local_flags, new_passwd,
1039 &err_str, &msg_str);
1042 printf("%s\n<p>", msg_str);
1044 printf("%s\n<p>", err_str);
1048 return NT_STATUS_IS_OK(ret);
1051 /****************************************************************************
1052 do the stuff required to add or change a password
1053 ****************************************************************************/
1054 static void chg_passwd(void)
1058 int local_flags = 0;
1060 /* Make sure users name has been specified */
1061 if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1062 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1067 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1068 * so if that's what we're doing, skip the rest of the checks
1070 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1073 * If current user is not root, make sure old password has been specified
1074 * If REMOTE change, even root must provide old password
1076 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1077 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1078 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1082 /* If changing a users password on a remote hosts we have to know what host */
1083 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1084 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1088 /* Make sure new passwords have been specified */
1089 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1090 (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1091 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1095 /* Make sure new passwords was typed correctly twice */
1096 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1097 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1102 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1103 host = cgi_variable(RHOST);
1104 } else if (am_root()) {
1111 * Set up the local flags.
1114 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1115 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1116 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1117 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1118 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1119 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1121 rslt = change_password(host,
1122 cgi_variable_nonull(SWAT_USER),
1123 cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1126 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1129 printf(_(" The passwd for '%s' has been changed."), cgi_variable_nonull(SWAT_USER));
1132 printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable_nonull(SWAT_USER));
1140 /****************************************************************************
1141 display a password editing page
1142 ****************************************************************************/
1143 static void passwd_page(void)
1145 const char *new_name = cgi_user_name();
1148 * After the first time through here be nice. If the user
1149 * changed the User box text to another users name, remember it.
1151 if (cgi_variable(SWAT_USER)) {
1152 new_name = cgi_variable_nonull(SWAT_USER);
1155 if (!new_name) new_name = "";
1157 printf("<H2>%s</H2>\n", _("Server Password Management"));
1159 printf("<FORM name=\"swatform\" method=post>\n");
1161 printf("<table>\n");
1164 * Create all the dialog boxes for data collection
1166 printf("<tr><td> %s : </td>\n", _("User Name"));
1167 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1169 printf("<tr><td> %s : </td>\n", _("Old Password"));
1170 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1172 printf("<tr><td> %s : </td>\n", _("New Password"));
1173 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1174 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1175 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1176 printf("</table>\n");
1179 * Create all the control buttons for requesting action
1181 printf("<input type=submit name=%s value=\"%s\">\n",
1182 CHG_S_PASSWD_FLAG, _("Change Password"));
1183 if (demo_mode || am_root()) {
1184 printf("<input type=submit name=%s value=\"%s\">\n",
1185 ADD_USER_FLAG, _("Add New User"));
1186 printf("<input type=submit name=%s value=\"%s\">\n",
1187 DELETE_USER_FLAG, _("Delete User"));
1188 printf("<input type=submit name=%s value=\"%s\">\n",
1189 DISABLE_USER_FLAG, _("Disable User"));
1190 printf("<input type=submit name=%s value=\"%s\">\n",
1191 ENABLE_USER_FLAG, _("Enable User"));
1193 printf("<p></FORM>\n");
1196 * Do some work if change, add, disable or enable was
1197 * requested. It could be this is the first time through this
1198 * code, so there isn't anything to do. */
1199 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1200 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1204 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1206 printf("<FORM name=\"swatform\" method=post>\n");
1208 printf("<table>\n");
1211 * Create all the dialog boxes for data collection
1213 printf("<tr><td> %s : </td>\n", _("User Name"));
1214 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1215 printf("<tr><td> %s : </td>\n", _("Old Password"));
1216 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1217 printf("<tr><td> %s : </td>\n", _("New Password"));
1218 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1219 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1220 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1221 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1222 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1227 * Create all the control buttons for requesting action
1229 printf("<input type=submit name=%s value=\"%s\">",
1230 CHG_R_PASSWD_FLAG, _("Change Password"));
1232 printf("<p></FORM>\n");
1235 * Do some work if a request has been made to change the
1236 * password somewhere other than the server. It could be this
1237 * is the first time through this code, so there isn't
1238 * anything to do. */
1239 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1245 /****************************************************************************
1246 display a printers editing page
1247 ****************************************************************************/
1248 static void printers_page(void)
1250 const char *share = cgi_variable("share");
1255 unsigned int parm_filter = FLAG_BASIC;
1258 snum = lp_servicenumber(share);
1260 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1262 printf("<H3>%s</H3>\n", _("Important Note:"));
1263 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1264 printf("%s",_("are autoloaded printers from "));
1265 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1266 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1268 if (cgi_variable("Commit") && snum >= 0) {
1269 commit_parameters(snum);
1270 if (snum >= iNumNonAutoPrintServices)
1274 snum = lp_servicenumber(share);
1277 if (cgi_variable("Delete") && snum >= 0) {
1278 lp_remove_service(snum);
1284 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1285 snum = lp_servicenumber(share);
1286 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1288 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1289 snum = lp_servicenumber(share);
1290 lp_do_parameter(snum, "print ok", "Yes");
1292 snum = lp_servicenumber(share);
1296 printf("<FORM name=\"swatform\" method=post>\n");
1298 if ( cgi_variable("ViewMode") )
1299 mode = atoi(cgi_variable_nonull("ViewMode"));
1300 if ( cgi_variable("BasicMode"))
1302 if ( cgi_variable("AdvMode"))
1305 ViewModeBoxes( mode );
1308 parm_filter = FLAG_BASIC;
1311 parm_filter = FLAG_ADVANCED;
1314 printf("<table>\n");
1315 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1316 printf("<td><select name=\"share\">\n");
1317 if (snum < 0 || !lp_print_ok(snum))
1318 printf("<option value=\" \"> \n");
1319 for (i=0;i<lp_numservices();i++) {
1320 s = lp_servicename(i);
1321 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1322 if (i >= iNumNonAutoPrintServices)
1323 printf("<option %s value=\"%s\">[*]%s\n",
1324 (share && strcmp(share,s)==0)?"SELECTED":"",
1327 printf("<option %s value=\"%s\">%s\n",
1328 (share && strcmp(share,s)==0)?"SELECTED":"",
1332 printf("</select></td>");
1333 if (have_write_access) {
1334 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1337 printf("</table>\n");
1339 if (have_write_access) {
1340 printf("<table>\n");
1341 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1342 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1348 if (have_write_access) {
1349 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1351 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1356 printf("<table>\n");
1357 show_parameters(snum, 1, parm_filter, 1);
1358 printf("</table>\n");
1360 printf("</FORM>\n");
1364 when the _() translation macro is used there is no obvious place to free
1365 the resulting string and there is no easy way to give a static pointer.
1366 All we can do is rotate between some static buffers and hope a single d_printf()
1367 doesn't have more calls to _() than the number of buffers
1370 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1375 msgstr = lang_msg(msgid);
1380 ret = talloc_strdup(ctx, msgstr);
1382 lang_msg_free(msgstr);
1391 * main function for SWAT.
1393 int main(int argc, char *argv[])
1397 struct poptOption long_options[] = {
1399 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1400 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1404 TALLOC_CTX *frame = talloc_stackframe();
1407 umask(S_IWGRP | S_IWOTH);
1409 #if defined(HAVE_SET_AUTH_PARAMETERS)
1410 set_auth_parameters(argc, argv);
1411 #endif /* HAVE_SET_AUTH_PARAMETERS */
1413 /* just in case it goes wild ... */
1418 /* we don't want any SIGPIPE messages */
1419 BlockSignals(True,SIGPIPE);
1421 debug_set_logfile("/dev/null");
1423 /* we don't want stderr screwing us up */
1425 open("/dev/null", O_WRONLY);
1426 setup_logging("swat", DEBUG_FILE);
1430 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1432 /* Parse command line options */
1434 while(poptGetNextOpt(pc) != -1) { }
1436 poptFreeContext(pc);
1438 /* This should set a more apporiate log file */
1442 iNumNonAutoPrintServices = lp_numservices();
1443 if (pcap_cache_loaded()) {
1444 load_printers(server_event_context(),
1445 server_messaging_context());
1448 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1452 cgi_load_variables();
1454 if (!file_exist(get_dyn_CONFIGFILE())) {
1455 have_read_access = True;
1456 have_write_access = True;
1458 /* check if the authenticated user has write access - if not then
1459 don't show write options */
1460 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1462 /* if the user doesn't have read access to smb.conf then
1463 don't let them view it */
1464 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1467 show_main_buttons();
1469 page = cgi_pathinfo();
1471 /* Root gets full functionality */
1472 if (have_read_access && strcmp(page, "globals")==0) {
1474 } else if (have_read_access && strcmp(page,"shares")==0) {
1476 } else if (have_read_access && strcmp(page,"printers")==0) {
1478 } else if (have_read_access && strcmp(page,"status")==0) {
1480 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1482 } else if (strcmp(page,"passwd")==0) {
1484 } else if (have_read_access && strcmp(page,"wizard")==0) {
1486 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1487 wizard_params_page();
1488 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {