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 static int demo_mode = False;
38 static int passwd_only = False;
39 static bool have_write_access = False;
40 static bool have_read_access = False;
41 static int iNumNonAutoPrintServices = 0;
44 * Password Management Globals
46 #define SWAT_USER "username"
47 #define OLD_PSWD "old_passwd"
48 #define NEW_PSWD "new_passwd"
49 #define NEW2_PSWD "new2_passwd"
50 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
51 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
52 #define ADD_USER_FLAG "add_user_flag"
53 #define DELETE_USER_FLAG "delete_user_flag"
54 #define DISABLE_USER_FLAG "disable_user_flag"
55 #define ENABLE_USER_FLAG "enable_user_flag"
56 #define RHOST "remote_host"
58 #define _(x) lang_msg_rotate(talloc_tos(),x)
60 /****************************************************************************
61 ****************************************************************************/
62 static int enum_index(int value, const struct enum_list *enumlist)
65 for (i=0;enumlist[i].name;i++)
66 if (value == enumlist[i].value) break;
70 static char *fix_backslash(const char *str)
72 static char newstring[1024];
76 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
84 static const char *fix_quotes(TALLOC_CTX *ctx, const char *str)
86 char *newstring = NULL;
89 int quote_len = strlen(""");
91 /* Count the number of quotes. */
96 newstring_len += quote_len;
102 newstring = TALLOC_ARRAY(ctx, char, newstring_len);
106 for (p = newstring; *str; str++) {
108 strncpy( p, """, quote_len);
118 static char *stripspaceupper(const char *str)
120 static char newstring[1024];
124 if (*str != ' ') *p++ = toupper_ascii(*str);
131 static char *make_parm_name(const char *label)
133 static char parmname[1024];
137 if (*label == ' ') *p++ = '_';
145 /****************************************************************************
146 include a lump of html in a page
147 ****************************************************************************/
148 static int include_html(const char *fname)
154 fd = web_open(fname, O_RDONLY, 0);
157 printf(_("ERROR: Can't open %s"), fname);
162 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
163 if (write(1, buf, ret) == -1) {
172 /****************************************************************************
173 start the page with standard stuff
174 ****************************************************************************/
175 static void print_header(void)
177 if (!cgi_waspost()) {
178 printf("Expires: 0\r\n");
180 printf("Content-type: text/html\r\n\r\n");
182 if (!include_html("include/header.html")) {
183 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
184 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
188 /* *******************************************************************
189 show parameter label with translated name in the following form
190 because showing original and translated label in one line looks
191 too long, and showing translated label only is unusable for
193 -------------------------------
194 HELP security [combo box][button]
196 -------------------------------
197 (capital words are translated by gettext.)
198 if no translation is available, then same form as original is
200 "i18n_translated_parm" class is used to change the color of the
201 translated parameter with CSS.
202 **************************************************************** */
203 static const char *get_parm_translated(TALLOC_CTX *ctx,
204 const char* pAnchor, const char* pHelp, const char* pLabel)
206 const char *pTranslated = _(pLabel);
208 if(strcmp(pLabel, pTranslated) != 0) {
209 output = talloc_asprintf(ctx,
210 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
211 pAnchor, pHelp, pLabel, pTranslated);
214 output = talloc_asprintf(ctx,
215 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
216 pAnchor, pHelp, pLabel);
219 /****************************************************************************
221 ****************************************************************************/
222 static void print_footer(void)
224 if (!include_html("include/footer.html")) {
225 printf("\n</BODY>\n</HTML>\n");
229 /****************************************************************************
230 display one editable parameter in a form
231 ****************************************************************************/
232 static void show_parameter(int snum, struct parm_struct *parm)
235 void *ptr = parm->ptr;
236 char *utf8_s1, *utf8_s2;
237 size_t converted_size;
238 TALLOC_CTX *ctx = talloc_stackframe();
240 if (parm->p_class == P_LOCAL && snum >= 0) {
241 ptr = lp_local_ptr_by_snum(snum, ptr);
244 printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
245 stripspaceupper(parm->label), _("Help"), parm->label));
246 switch (parm->type) {
248 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
249 make_parm_name(parm->label), *(char *)ptr);
250 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
251 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
255 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
256 make_parm_name(parm->label));
257 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
258 char **list = *(char ***)ptr;
259 for (;*list;list++) {
260 /* enclose in HTML encoded quotes if the string contains a space */
261 if ( strchr_m(*list, ' ') ) {
262 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
263 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
264 printf(""%s"%s", utf8_s1, utf8_s2);
266 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
267 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
268 printf("%s%s", utf8_s1, utf8_s2);
270 TALLOC_FREE(utf8_s1);
271 TALLOC_FREE(utf8_s2);
275 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
276 _("Set Default"), make_parm_name(parm->label));
277 if (parm->def.lvalue) {
278 char **list = (char **)(parm->def.lvalue);
279 for (; *list; list++) {
280 /* enclose in HTML encoded quotes if the string contains a space */
281 if ( strchr_m(*list, ' ') )
282 printf(""%s"%s", *list, ((*(list+1))?", ":""));
284 printf("%s%s", *list, ((*(list+1))?", ":""));
292 push_utf8_talloc(talloc_tos(), &utf8_s1, *(char **)ptr, &converted_size);
293 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
294 make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
295 TALLOC_FREE(utf8_s1);
296 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
297 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
301 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
302 printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
303 printf("<option %s>No", (*(bool *)ptr)?"":"selected");
305 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
306 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
310 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
311 printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
312 printf("<option %s>No", (*(bool *)ptr)?"selected":"");
314 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
315 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
319 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
320 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
321 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
326 o = octal_string(*(int *)ptr);
327 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
328 make_parm_name(parm->label), o);
330 o = octal_string((int)(parm->def.ivalue));
331 printf("<input type=button value=\"%s\" "
332 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
333 _("Set Default"), make_parm_name(parm->label), o);
339 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
340 for (i=0;parm->enum_list[i].name;i++) {
341 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
342 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
346 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
347 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
352 printf("</td></tr>\n");
356 /****************************************************************************
357 display a set of parameters for a service
358 ****************************************************************************/
359 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
362 struct parm_struct *parm;
363 const char *heading = NULL;
364 const char *last_heading = NULL;
366 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
367 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
369 if (parm->p_class == P_SEPARATOR) {
370 heading = parm->label;
373 if (parm->flags & FLAG_HIDE) continue;
375 if (printers & !(parm->flags & FLAG_PRINT)) continue;
376 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
379 if (!( parm_filter & FLAG_ADVANCED )) {
380 if (!(parm->flags & FLAG_BASIC)) {
381 void *ptr = parm->ptr;
383 if (parm->p_class == P_LOCAL && snum >= 0) {
384 ptr = lp_local_ptr_by_snum(snum, ptr);
387 switch (parm->type) {
389 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
393 if (!str_list_equal(*(const char ***)ptr,
394 (const char **)(parm->def.lvalue))) continue;
399 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
404 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
409 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
414 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
420 if (printers && !(parm->flags & FLAG_PRINT)) continue;
423 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
425 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
427 if (heading && heading != last_heading) {
428 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
429 last_heading = heading;
431 show_parameter(snum, parm);
435 /****************************************************************************
436 load the smb.conf file into loadparm.
437 ****************************************************************************/
438 static bool load_config(bool save_def)
440 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
443 /****************************************************************************
445 ****************************************************************************/
446 static void write_config(FILE *f, bool show_defaults)
448 TALLOC_CTX *ctx = talloc_stackframe();
450 fprintf(f, "# Samba config file created using SWAT\n");
451 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
452 fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
454 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
459 /****************************************************************************
460 save and reload the smb.conf config file
461 ****************************************************************************/
462 static int save_reload(int snum)
467 f = sys_fopen(get_dyn_CONFIGFILE(),"w");
469 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
474 /* just in case they have used the buggy xinetd to create the file */
475 if (fstat(fileno(f), &st) == 0 &&
476 (st.st_mode & S_IWOTH)) {
477 #if defined HAVE_FCHMOD
478 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
480 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
484 write_config(f, False);
486 lp_dump_one(f, False, snum);
489 lp_kill_all_services();
491 if (!load_config(False)) {
492 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
496 iNumNonAutoPrintServices = lp_numservices();
497 if (pcap_cache_loaded()) {
498 load_printers(server_event_context(),
499 server_messaging_context());
505 /****************************************************************************
507 ****************************************************************************/
508 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
513 if (snum < 0 && parm->p_class == P_LOCAL) {
514 /* this handles the case where we are changing a local
515 variable globally. We need to change the parameter in
516 all shares where it is currently set to the default */
517 for (i=0;i<lp_numservices();i++) {
518 s = lp_servicename(i);
519 if (s && (*s) && lp_is_default(i, parm)) {
520 lp_do_parameter(i, parm->label, v);
525 lp_do_parameter(snum, parm->label, v);
528 /****************************************************************************
529 commit a set of parameters for a service
530 ****************************************************************************/
531 static void commit_parameters(int snum)
534 struct parm_struct *parm;
538 while ((parm = lp_next_parameter(snum, &i, 1))) {
539 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
540 if ((v = cgi_variable(label)) != NULL) {
541 if (parm->flags & FLAG_HIDE)
543 commit_parameter(snum, parm, v);
550 /****************************************************************************
551 spit out the html for a link with an image
552 ****************************************************************************/
553 static void image_link(const char *name, const char *hlink, const char *src)
555 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
556 cgi_baseurl(), hlink, src, name);
559 /****************************************************************************
560 display the main navigation controls at the top of each page along
562 ****************************************************************************/
563 static void show_main_buttons(void)
567 if ((p = cgi_user_name()) && strcmp(p, "root")) {
568 printf(_("Logged in as <b>%s</b>"), p);
572 image_link(_("Home"), "", "images/home.gif");
573 if (have_write_access) {
574 image_link(_("Globals"), "globals", "images/globals.gif");
575 image_link(_("Shares"), "shares", "images/shares.gif");
576 image_link(_("Printers"), "printers", "images/printers.gif");
577 image_link(_("Wizard"), "wizard", "images/wizard.gif");
579 /* root always gets all buttons, otherwise look for -P */
580 if ( have_write_access || (!passwd_only && have_read_access) ) {
581 image_link(_("Status"), "status", "images/status.gif");
582 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
584 image_link(_("Password Management"), "passwd", "images/passwd.gif");
589 /****************************************************************************
590 * Handle Display/Edit Mode CGI
591 ****************************************************************************/
592 static void ViewModeBoxes(int mode)
594 printf("<p>%s: \n", _("Current View Is"));
595 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
596 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
597 printf("<br>%s: \n", _("Change View To"));
598 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
599 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
600 printf("</p><br>\n");
603 /****************************************************************************
604 display a welcome page
605 ****************************************************************************/
606 static void welcome_page(void)
608 if (file_exist("help/welcome.html")) {
609 include_html("help/welcome.html");
611 include_html("help/welcome-no-samba-doc.html");
615 /****************************************************************************
616 display the current smb.conf
617 ****************************************************************************/
618 static void viewconfig_page(void)
622 if (cgi_variable("full_view")) {
626 printf("<H2>%s</H2>\n", _("Current Config"));
627 printf("<form method=post>\n");
630 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
632 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
636 write_config(stdout, full_view);
641 /****************************************************************************
642 second screen of the wizard ... Fetch Configuration Parameters
643 ****************************************************************************/
644 static void wizard_params_page(void)
646 unsigned int parm_filter = FLAG_WIZARD;
648 /* Here we first set and commit all the parameters that were selected
649 in the previous screen. */
651 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
653 if (cgi_variable("Commit")) {
654 commit_parameters(GLOBAL_SECTION_SNUM);
658 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
660 if (have_write_access) {
661 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
664 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
668 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
669 printf("</table>\n");
673 /****************************************************************************
674 Utility to just rewrite the smb.conf file - effectively just cleans it up
675 ****************************************************************************/
676 static void rewritecfg_file(void)
678 commit_parameters(GLOBAL_SECTION_SNUM);
680 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
683 /****************************************************************************
684 wizard to create/modify the smb.conf file
685 ****************************************************************************/
686 static void wizard_page(void)
688 /* Set some variables to collect data from smb.conf */
695 if (cgi_variable("Rewrite")) {
696 (void) rewritecfg_file();
700 if (cgi_variable("GetWizardParams")){
701 (void) wizard_params_page();
705 if (cgi_variable("Commit")){
706 SerType = atoi(cgi_variable_nonull("ServerType"));
707 winstype = atoi(cgi_variable_nonull("WINSType"));
708 have_home = lp_servicenumber(HOMES_NAME);
709 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
711 /* Plain text passwords are too badly broken - use encrypted passwords only */
712 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
716 /* Stand-alone Server */
717 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
718 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
722 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
723 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
726 /* Domain Controller */
727 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
728 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
731 switch ( winstype ) {
733 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
734 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
737 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
738 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
741 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
742 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
746 /* Have to create Homes share? */
747 if ((HomeExpo == 1) && (have_home == -1)) {
748 const char *unix_share = HOMES_NAME;
751 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
752 have_home = lp_servicenumber(HOMES_NAME);
753 lp_do_parameter( have_home, "read only", "No");
754 lp_do_parameter( have_home, "valid users", "%S");
755 lp_do_parameter( have_home, "browseable", "No");
756 commit_parameters(have_home);
757 save_reload(have_home);
760 /* Need to Delete Homes share? */
761 if ((HomeExpo == 0) && (have_home != -1)) {
762 lp_remove_service(have_home);
766 commit_parameters(GLOBAL_SECTION_SNUM);
771 /* Now determine smb.conf WINS settings */
772 if (lp_wins_support())
774 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
777 /* Do we have a homes share? */
778 have_home = lp_servicenumber(HOMES_NAME);
780 if ((winstype == 2) && lp_wins_support())
783 role = lp_server_role();
786 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
787 printf("<form method=post action=wizard>\n");
789 if (have_write_access) {
790 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
791 printf("%s", _("The same will happen if you press the commit button."));
792 printf("<br><br>\n");
794 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
795 printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
796 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
797 printf("</center>\n");
801 printf("<center><table border=0>");
802 printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
803 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
804 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
805 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
807 if (role == ROLE_DOMAIN_BDC) {
808 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
810 printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
811 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
812 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
813 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
815 printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
817 /* Print out the list of wins servers */
818 if(lp_wins_server_list()) {
820 const char **wins_servers = lp_wins_server_list();
821 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
824 printf("\"></td></tr>\n");
826 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"));
827 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
829 printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
830 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
831 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
832 printf("<td></td></tr>\n");
834 /* Enable this when we are ready ....
835 * printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
836 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
837 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
838 * printf("<td></td></tr>\n");
841 printf("</table></center>");
844 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
849 /****************************************************************************
850 display a globals editing page
851 ****************************************************************************/
852 static void globals_page(void)
854 unsigned int parm_filter = FLAG_BASIC;
857 printf("<H2>%s</H2>\n", _("Global Parameters"));
859 if (cgi_variable("Commit")) {
860 commit_parameters(GLOBAL_SECTION_SNUM);
864 if ( cgi_variable("ViewMode") )
865 mode = atoi(cgi_variable_nonull("ViewMode"));
866 if ( cgi_variable("BasicMode"))
868 if ( cgi_variable("AdvMode"))
871 printf("<form name=\"swatform\" method=post action=globals>\n");
873 ViewModeBoxes( mode );
876 parm_filter = FLAG_BASIC;
879 parm_filter = FLAG_ADVANCED;
883 if (have_write_access) {
884 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
885 _("Commit Changes"));
888 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
893 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
894 printf("</table>\n");
898 /****************************************************************************
899 display a shares editing page. share is in unix codepage,
900 ****************************************************************************/
901 static void shares_page(void)
903 const char *share = cgi_variable("share");
909 unsigned int parm_filter = FLAG_BASIC;
910 size_t converted_size;
913 snum = lp_servicenumber(share);
915 printf("<H2>%s</H2>\n", _("Share Parameters"));
917 if (cgi_variable("Commit") && snum >= 0) {
918 commit_parameters(snum);
920 snum = lp_servicenumber(share);
923 if (cgi_variable("Delete") && snum >= 0) {
924 lp_remove_service(snum);
930 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
931 snum = lp_servicenumber(share);
934 lp_copy_service(GLOBAL_SECTION_SNUM, share);
935 snum = lp_servicenumber(share);
937 snum = lp_servicenumber(share);
941 printf("<FORM name=\"swatform\" method=post>\n");
945 if ( cgi_variable("ViewMode") )
946 mode = atoi(cgi_variable_nonull("ViewMode"));
947 if ( cgi_variable("BasicMode"))
949 if ( cgi_variable("AdvMode"))
952 ViewModeBoxes( mode );
955 parm_filter = FLAG_BASIC;
958 parm_filter = FLAG_ADVANCED;
961 printf("<br><tr>\n");
962 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
963 printf("<td><select name=share>\n");
965 printf("<option value=\" \"> \n");
966 for (i=0;i<lp_numservices();i++) {
967 s = lp_servicename(i);
968 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
969 push_utf8_talloc(talloc_tos(), &utf8_s, s, &converted_size);
970 printf("<option %s value=\"%s\">%s\n",
971 (share && strcmp(share,s)==0)?"SELECTED":"",
976 printf("</select></td>\n");
977 if (have_write_access) {
978 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
983 if (have_write_access) {
985 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
986 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
992 if (have_write_access) {
993 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
996 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1001 printf("<table>\n");
1002 show_parameters(snum, 1, parm_filter, 0);
1003 printf("</table>\n");
1006 printf("</FORM>\n");
1009 /*************************************************************
1010 change a password either locally or remotely
1011 *************************************************************/
1012 static bool change_password(const char *remote_machine, const char *user_name,
1013 const char *old_passwd, const char *new_passwd,
1017 char *err_str = NULL;
1018 char *msg_str = NULL;
1021 printf("%s\n<p>", _("password change in demo mode rejected"));
1025 if (remote_machine != NULL) {
1026 ret = remote_password_change(remote_machine, user_name,
1027 old_passwd, new_passwd, &err_str);
1028 if (err_str != NULL)
1029 printf("%s\n<p>", err_str);
1031 return NT_STATUS_IS_OK(ret);
1034 if(!initialize_password_db(True, NULL)) {
1035 printf("%s\n<p>", _("Can't setup password database vectors."));
1039 ret = local_password_change(user_name, local_flags, new_passwd,
1040 &err_str, &msg_str);
1043 printf("%s\n<p>", msg_str);
1045 printf("%s\n<p>", err_str);
1049 return NT_STATUS_IS_OK(ret);
1052 /****************************************************************************
1053 do the stuff required to add or change a password
1054 ****************************************************************************/
1055 static void chg_passwd(void)
1059 int local_flags = 0;
1061 /* Make sure users name has been specified */
1062 if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1063 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1068 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1069 * so if that's what we're doing, skip the rest of the checks
1071 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1074 * If current user is not root, make sure old password has been specified
1075 * If REMOTE change, even root must provide old password
1077 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1078 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1079 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1083 /* If changing a users password on a remote hosts we have to know what host */
1084 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1085 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1089 /* Make sure new passwords have been specified */
1090 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1091 (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1092 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1096 /* Make sure new passwords was typed correctly twice */
1097 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1098 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1103 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1104 host = cgi_variable(RHOST);
1105 } else if (am_root()) {
1112 * Set up the local flags.
1115 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1116 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1117 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1118 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1119 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1120 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1122 rslt = change_password(host,
1123 cgi_variable_nonull(SWAT_USER),
1124 cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1127 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1130 printf(_(" The passwd for '%s' has been changed."), cgi_variable_nonull(SWAT_USER));
1133 printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable_nonull(SWAT_USER));
1141 /****************************************************************************
1142 display a password editing page
1143 ****************************************************************************/
1144 static void passwd_page(void)
1146 const char *new_name = cgi_user_name();
1149 * After the first time through here be nice. If the user
1150 * changed the User box text to another users name, remember it.
1152 if (cgi_variable(SWAT_USER)) {
1153 new_name = cgi_variable_nonull(SWAT_USER);
1156 if (!new_name) new_name = "";
1158 printf("<H2>%s</H2>\n", _("Server Password Management"));
1160 printf("<FORM name=\"swatform\" method=post>\n");
1162 printf("<table>\n");
1165 * Create all the dialog boxes for data collection
1167 printf("<tr><td> %s : </td>\n", _("User Name"));
1168 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1170 printf("<tr><td> %s : </td>\n", _("Old Password"));
1171 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1173 printf("<tr><td> %s : </td>\n", _("New Password"));
1174 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1175 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1176 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1177 printf("</table>\n");
1180 * Create all the control buttons for requesting action
1182 printf("<input type=submit name=%s value=\"%s\">\n",
1183 CHG_S_PASSWD_FLAG, _("Change Password"));
1184 if (demo_mode || am_root()) {
1185 printf("<input type=submit name=%s value=\"%s\">\n",
1186 ADD_USER_FLAG, _("Add New User"));
1187 printf("<input type=submit name=%s value=\"%s\">\n",
1188 DELETE_USER_FLAG, _("Delete User"));
1189 printf("<input type=submit name=%s value=\"%s\">\n",
1190 DISABLE_USER_FLAG, _("Disable User"));
1191 printf("<input type=submit name=%s value=\"%s\">\n",
1192 ENABLE_USER_FLAG, _("Enable User"));
1194 printf("<p></FORM>\n");
1197 * Do some work if change, add, disable or enable was
1198 * requested. It could be this is the first time through this
1199 * code, so there isn't anything to do. */
1200 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1201 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1205 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1207 printf("<FORM name=\"swatform\" method=post>\n");
1209 printf("<table>\n");
1212 * Create all the dialog boxes for data collection
1214 printf("<tr><td> %s : </td>\n", _("User Name"));
1215 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1216 printf("<tr><td> %s : </td>\n", _("Old Password"));
1217 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1218 printf("<tr><td> %s : </td>\n", _("New Password"));
1219 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1220 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1221 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1222 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1223 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1228 * Create all the control buttons for requesting action
1230 printf("<input type=submit name=%s value=\"%s\">",
1231 CHG_R_PASSWD_FLAG, _("Change Password"));
1233 printf("<p></FORM>\n");
1236 * Do some work if a request has been made to change the
1237 * password somewhere other than the server. It could be this
1238 * is the first time through this code, so there isn't
1239 * anything to do. */
1240 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1246 /****************************************************************************
1247 display a printers editing page
1248 ****************************************************************************/
1249 static void printers_page(void)
1251 const char *share = cgi_variable("share");
1256 unsigned int parm_filter = FLAG_BASIC;
1259 snum = lp_servicenumber(share);
1261 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1263 printf("<H3>%s</H3>\n", _("Important Note:"));
1264 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1265 printf("%s",_("are autoloaded printers from "));
1266 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1267 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1269 if (cgi_variable("Commit") && snum >= 0) {
1270 commit_parameters(snum);
1271 if (snum >= iNumNonAutoPrintServices)
1275 snum = lp_servicenumber(share);
1278 if (cgi_variable("Delete") && snum >= 0) {
1279 lp_remove_service(snum);
1285 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1286 snum = lp_servicenumber(share);
1287 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1289 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1290 snum = lp_servicenumber(share);
1291 lp_do_parameter(snum, "print ok", "Yes");
1293 snum = lp_servicenumber(share);
1297 printf("<FORM name=\"swatform\" method=post>\n");
1299 if ( cgi_variable("ViewMode") )
1300 mode = atoi(cgi_variable_nonull("ViewMode"));
1301 if ( cgi_variable("BasicMode"))
1303 if ( cgi_variable("AdvMode"))
1306 ViewModeBoxes( mode );
1309 parm_filter = FLAG_BASIC;
1312 parm_filter = FLAG_ADVANCED;
1315 printf("<table>\n");
1316 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1317 printf("<td><select name=\"share\">\n");
1318 if (snum < 0 || !lp_print_ok(snum))
1319 printf("<option value=\" \"> \n");
1320 for (i=0;i<lp_numservices();i++) {
1321 s = lp_servicename(i);
1322 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1323 if (i >= iNumNonAutoPrintServices)
1324 printf("<option %s value=\"%s\">[*]%s\n",
1325 (share && strcmp(share,s)==0)?"SELECTED":"",
1328 printf("<option %s value=\"%s\">%s\n",
1329 (share && strcmp(share,s)==0)?"SELECTED":"",
1333 printf("</select></td>");
1334 if (have_write_access) {
1335 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1338 printf("</table>\n");
1340 if (have_write_access) {
1341 printf("<table>\n");
1342 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1343 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1349 if (have_write_access) {
1350 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1352 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1357 printf("<table>\n");
1358 show_parameters(snum, 1, parm_filter, 1);
1359 printf("</table>\n");
1361 printf("</FORM>\n");
1365 when the _() translation macro is used there is no obvious place to free
1366 the resulting string and there is no easy way to give a static pointer.
1367 All we can do is rotate between some static buffers and hope a single d_printf()
1368 doesn't have more calls to _() than the number of buffers
1371 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1376 msgstr = lang_msg(msgid);
1381 ret = talloc_strdup(ctx, msgstr);
1383 lang_msg_free(msgstr);
1392 * main function for SWAT.
1394 int main(int argc, char *argv[])
1398 struct poptOption long_options[] = {
1400 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1401 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1405 TALLOC_CTX *frame = talloc_stackframe();
1408 umask(S_IWGRP | S_IWOTH);
1410 #if defined(HAVE_SET_AUTH_PARAMETERS)
1411 set_auth_parameters(argc, argv);
1412 #endif /* HAVE_SET_AUTH_PARAMETERS */
1414 /* just in case it goes wild ... */
1419 /* we don't want any SIGPIPE messages */
1420 BlockSignals(True,SIGPIPE);
1422 debug_set_logfile("/dev/null");
1424 /* we don't want stderr screwing us up */
1426 open("/dev/null", O_WRONLY);
1427 setup_logging("swat", DEBUG_FILE);
1431 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1433 /* Parse command line options */
1435 while(poptGetNextOpt(pc) != -1) { }
1437 poptFreeContext(pc);
1439 /* This should set a more apporiate log file */
1443 iNumNonAutoPrintServices = lp_numservices();
1444 if (pcap_cache_loaded()) {
1445 load_printers(server_event_context(),
1446 server_messaging_context());
1449 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1453 cgi_load_variables();
1455 if (!file_exist(get_dyn_CONFIGFILE())) {
1456 have_read_access = True;
1457 have_write_access = True;
1459 /* check if the authenticated user has write access - if not then
1460 don't show write options */
1461 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1463 /* if the user doesn't have read access to smb.conf then
1464 don't let them view it */
1465 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1468 show_main_buttons();
1470 page = cgi_pathinfo();
1472 /* Root gets full functionality */
1473 if (have_read_access && strcmp(page, "globals")==0) {
1475 } else if (have_read_access && strcmp(page,"shares")==0) {
1477 } else if (have_read_access && strcmp(page,"printers")==0) {
1479 } else if (have_read_access && strcmp(page,"status")==0) {
1481 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1483 } else if (strcmp(page,"passwd")==0) {
1485 } else if (have_read_access && strcmp(page,"wizard")==0) {
1487 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1488 wizard_params_page();
1489 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {