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 2 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, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * @defgroup swat SWAT - Samba Web Administration Tool
28 * @brief Samba Web Administration Tool.
32 #include "../web/swat_proto.h"
34 static BOOL demo_mode = False;
35 static BOOL have_write_access = False;
36 static BOOL have_read_access = False;
37 static int iNumNonAutoPrintServices = 0;
40 * Password Management Globals
42 #define SWAT_USER "username"
43 #define OLD_PSWD "old_passwd"
44 #define NEW_PSWD "new_passwd"
45 #define NEW2_PSWD "new2_passwd"
46 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
47 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
48 #define ADD_USER_FLAG "add_user_flag"
49 #define DELETE_USER_FLAG "delete_user_flag"
50 #define DISABLE_USER_FLAG "disable_user_flag"
51 #define ENABLE_USER_FLAG "enable_user_flag"
52 #define RHOST "remote_host"
54 /* FUNCTION DECLARATIONS */
56 BOOL remote_password_change(const char *rmachine, const char *username,
57 const char *old_pw, const char *new_pw,
58 char *err_str, size_t err_str_len);
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 char *stripspaceupper(const char *str)
87 static char newstring[1024];
91 if (*str != ' ') *p++ = toupper(*str);
98 static char *make_parm_name(const char *label)
100 static char parmname[1024];
104 if (*label == ' ') *p++ = '_';
112 /****************************************************************************
113 include a lump of html in a page
114 ****************************************************************************/
115 static int include_html(const char *fname)
121 fd = web_open(fname, O_RDONLY, 0);
124 d_printf(_("ERROR: Can't open %s"), fname);
129 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
137 /****************************************************************************
138 start the page with standard stuff
139 ****************************************************************************/
140 static void print_header(void)
142 if (!cgi_waspost()) {
143 d_printf("Expires: 0\r\n");
145 d_printf("Content-type: text/html\r\n\r\n");
147 if (!include_html("include/header.html")) {
148 d_printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
149 d_printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
153 /* *******************************************************************
154 show parameter label with translated name in the following form
155 because showing original and translated label in one line looks
156 too long, and showing translated label only is unusable for
158 -------------------------------
159 HELP security [combo box][button]
161 -------------------------------
162 (capital words are translated by gettext.)
163 if no translation is available, then same form as original is
165 "i18n_translated_parm" class is used to change the color of the
166 translated parameter with CSS.
167 **************************************************************** */
168 static const char* get_parm_translated(
169 const char* pAnchor, const char* pHelp, const char* pLabel)
171 const char* pTranslated = _(pLabel);
172 static pstring output;
173 if(strcmp(pLabel, pTranslated) != 0)
176 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
177 pAnchor, pHelp, pLabel, pTranslated);
181 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
182 pAnchor, pHelp, pLabel);
185 /****************************************************************************
187 ****************************************************************************/
188 static void print_footer(void)
190 if (!include_html("include/footer.html")) {
191 d_printf("\n</BODY>\n</HTML>\n");
195 /****************************************************************************
196 display one editable parameter in a form
197 ****************************************************************************/
198 static void show_parameter(int snum, struct parm_struct *parm)
201 void *ptr = parm->ptr;
203 if (parm->class == P_LOCAL && snum >= 0) {
204 ptr = lp_local_ptr(snum, ptr);
207 printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label));
208 switch (parm->type) {
210 d_printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
211 make_parm_name(parm->label), *(char *)ptr);
212 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
213 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
217 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"",
218 make_parm_name(parm->label));
219 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
220 char **list = *(char ***)ptr;
221 for (;*list;list++) {
222 /* enclose in quotes if the string contains a space */
223 if ( strchr_m(*list, ' ') )
224 d_printf("\'%s\'%s", *list, ((*(list+1))?", ":""));
226 d_printf("%s%s", *list, ((*(list+1))?", ":""));
230 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
231 _("Set Default"), make_parm_name(parm->label));
232 if (parm->def.lvalue) {
233 char **list = (char **)(parm->def.lvalue);
234 for (; *list; list++) {
235 /* enclose in quotes if the string contains a space */
236 if ( strchr_m(*list, ' ') )
237 d_printf("\'%s\'%s", *list, ((*(list+1))?", ":""));
239 d_printf("%s%s", *list, ((*(list+1))?", ":""));
247 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
248 make_parm_name(parm->label), *(char **)ptr);
249 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
250 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
255 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
256 make_parm_name(parm->label), (char *)ptr);
257 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
258 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
262 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
263 d_printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
264 d_printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
265 d_printf("</select>");
266 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
267 _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?0:1);
271 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
272 d_printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
273 d_printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
274 d_printf("</select>");
275 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
276 _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?1:0);
280 d_printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
281 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
282 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
286 d_printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
287 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
288 _("Set Default"), make_parm_name(parm->label),
289 octal_string((int)(parm->def.ivalue)));
293 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
294 for (i=0;parm->enum_list[i].name;i++) {
295 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
296 d_printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
299 d_printf("</select>");
300 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
301 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
306 d_printf("</td></tr>\n");
309 /****************************************************************************
310 display a set of parameters for a service
311 ****************************************************************************/
312 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
315 struct parm_struct *parm;
316 const char *heading = NULL;
317 const char *last_heading = NULL;
319 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
320 if (snum < 0 && parm->class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
322 if (parm->class == P_SEPARATOR) {
323 heading = parm->label;
326 if (parm->flags & FLAG_HIDE) continue;
328 if (printers & !(parm->flags & FLAG_PRINT)) continue;
329 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
332 if (!( parm_filter & FLAG_ADVANCED )) {
333 if (!(parm->flags & FLAG_BASIC)) {
334 void *ptr = parm->ptr;
336 if (parm->class == P_LOCAL && snum >= 0) {
337 ptr = lp_local_ptr(snum, ptr);
340 switch (parm->type) {
342 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
346 if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
351 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
356 if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
361 if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
366 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
371 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
377 if (printers && !(parm->flags & FLAG_PRINT)) continue;
380 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
382 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
384 if (heading && heading != last_heading) {
385 d_printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
386 last_heading = heading;
388 show_parameter(snum, parm);
392 /****************************************************************************
393 load the smb.conf file into loadparm.
394 ****************************************************************************/
395 static BOOL load_config(BOOL save_def)
397 lp_resetnumservices();
398 return lp_load(dyn_CONFIGFILE,False,save_def,False);
401 /****************************************************************************
403 ****************************************************************************/
404 static void write_config(FILE *f, BOOL show_defaults)
406 fprintf(f, "# Samba config file created using SWAT\n");
407 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
408 fprintf(f, "# Date: %s\n\n", timestring(False));
410 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
413 /****************************************************************************
414 save and reload the smb.conf config file
415 ****************************************************************************/
416 static int save_reload(int snum)
421 f = sys_fopen(dyn_CONFIGFILE,"w");
423 d_printf(_("failed to open %s for writing"), dyn_CONFIGFILE);
428 /* just in case they have used the buggy xinetd to create the file */
429 if (fstat(fileno(f), &st) == 0 &&
430 (st.st_mode & S_IWOTH)) {
431 #if defined HAVE_FCHMOD
432 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
434 chmod(dyn_CONFIGFILE, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
438 write_config(f, False);
440 lp_dump_one(f, False, snum);
445 if (!load_config(False)) {
446 d_printf(_("Can't reload %s"), dyn_CONFIGFILE);
450 iNumNonAutoPrintServices = lp_numservices();
456 /****************************************************************************
458 ****************************************************************************/
459 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
464 if (snum < 0 && parm->class == P_LOCAL) {
465 /* this handles the case where we are changing a local
466 variable globally. We need to change the parameter in
467 all shares where it is currently set to the default */
468 for (i=0;i<lp_numservices();i++) {
469 s = lp_servicename(i);
470 if (s && (*s) && lp_is_default(i, parm)) {
471 lp_do_parameter(i, parm->label, v);
476 lp_do_parameter(snum, parm->label, v);
479 /****************************************************************************
480 commit a set of parameters for a service
481 ****************************************************************************/
482 static void commit_parameters(int snum)
485 struct parm_struct *parm;
489 while ((parm = lp_next_parameter(snum, &i, 1))) {
490 slprintf(label, sizeof(label)-1, "parm_%s", make_parm_name(parm->label));
491 if ((v = cgi_variable(label))) {
492 if (parm->flags & FLAG_HIDE) continue;
493 commit_parameter(snum, parm, v);
498 /****************************************************************************
499 spit out the html for a link with an image
500 ****************************************************************************/
501 static void image_link(const char *name, const char *hlink, const char *src)
503 d_printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
504 cgi_baseurl(), hlink, src, name);
507 /****************************************************************************
508 display the main navigation controls at the top of each page along
510 ****************************************************************************/
511 static void show_main_buttons(void)
515 if ((p = cgi_user_name()) && strcmp(p, "root")) {
516 d_printf(_("Logged in as <b>%s</b>"), p);
520 image_link(_("Home"), "", "images/home.gif");
521 if (have_write_access) {
522 image_link(_("Globals"), "globals", "images/globals.gif");
523 image_link(_("Shares"), "shares", "images/shares.gif");
524 image_link(_("Printers"), "printers", "images/printers.gif");
525 image_link(_("Wizard"), "wizard", "images/wizard.gif");
527 if (have_read_access) {
528 image_link(_("Status"), "status", "images/status.gif");
529 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
531 image_link(_("Password Management"), "passwd", "images/passwd.gif");
536 /****************************************************************************
537 * Handle Display/Edit Mode CGI
538 ****************************************************************************/
539 static void ViewModeBoxes(int mode)
541 d_printf("<p>%s: \n", _("Current View Is"));
542 d_printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
543 d_printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
544 d_printf("<br>%s: \n", _("Change View To"));
545 d_printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
546 d_printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
547 d_printf("</p><br>\n");
550 /****************************************************************************
551 display a welcome page
552 ****************************************************************************/
553 static void welcome_page(void)
555 include_html("help/welcome.html");
558 /****************************************************************************
559 display the current smb.conf
560 ****************************************************************************/
561 static void viewconfig_page(void)
565 if (cgi_variable("full_view")) {
569 d_printf("<H2>%s</H2>\n", _("Current Config"));
570 d_printf("<form method=post>\n");
573 d_printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
575 d_printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
578 d_printf("<p><pre>");
579 write_config(stdout, full_view);
581 d_printf("</form>\n");
584 /****************************************************************************
585 second screen of the wizard ... Fetch Configuration Parameters
586 ****************************************************************************/
587 static void wizard_params_page(void)
589 unsigned int parm_filter = FLAG_WIZARD;
591 /* Here we first set and commit all the parameters that were selected
592 in the previous screen. */
594 d_printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
596 if (cgi_variable("Commit")) {
597 commit_parameters(GLOBAL_SECTION_SNUM);
601 d_printf("<form name=\"swatform\" method=post action=wizard_params>\n");
603 if (have_write_access) {
604 d_printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
607 d_printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
610 d_printf("<table>\n");
611 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
612 d_printf("</table>\n");
613 d_printf("</form>\n");
616 /****************************************************************************
617 Utility to just rewrite the smb.conf file - effectively just cleans it up
618 ****************************************************************************/
619 static void rewritecfg_file(void)
621 commit_parameters(GLOBAL_SECTION_SNUM);
623 d_printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
626 /****************************************************************************
627 wizard to create/modify the smb.conf file
628 ****************************************************************************/
629 static void wizard_page(void)
631 /* Set some variables to collect data from smb.conf */
638 if (cgi_variable("Rewrite")) {
639 (void) rewritecfg_file();
643 if (cgi_variable("GetWizardParams")){
644 (void) wizard_params_page();
648 if (cgi_variable("Commit")){
649 SerType = atoi(cgi_variable("ServerType"));
650 winstype = atoi(cgi_variable("WINSType"));
651 have_home = lp_servicenumber(HOMES_NAME);
652 HomeExpo = atoi(cgi_variable("HomeExpo"));
654 /* Plain text passwords are too badly broken - use encrypted passwords only */
655 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
659 /* Stand-alone Server */
660 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
661 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
665 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
666 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
669 /* Domain Controller */
670 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
671 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
674 switch ( winstype ) {
676 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
677 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
680 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
681 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
684 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
685 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable("WINSAddr"));
689 /* Have to create Homes share? */
690 if ((HomeExpo == 1) && (have_home == -1)) {
693 pstrcpy(unix_share,HOMES_NAME);
695 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
696 iNumNonAutoPrintServices = lp_numservices();
697 have_home = lp_servicenumber(HOMES_NAME);
698 lp_do_parameter( have_home, "read only", "No");
699 lp_do_parameter( have_home, "valid users", "%S");
700 lp_do_parameter( have_home, "browseable", "No");
701 commit_parameters(have_home);
704 /* Need to Delete Homes share? */
705 if ((HomeExpo == 0) && (have_home != -1)) {
706 lp_remove_service(have_home);
710 commit_parameters(GLOBAL_SECTION_SNUM);
715 /* Now determine smb.conf WINS settings */
716 if (lp_wins_support())
718 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
722 /* Do we have a homes share? */
723 have_home = lp_servicenumber(HOMES_NAME);
725 if ((winstype == 2) && lp_wins_support())
728 role = lp_server_role();
731 d_printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
732 d_printf("<form method=post action=wizard>\n");
734 if (have_write_access) {
735 d_printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
736 d_printf("%s", _("The same will happen if you press the commit button."));
737 d_printf("<br><br>\n");
738 d_printf("<center>");
739 d_printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
740 d_printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
741 d_printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
742 d_printf("</center>\n");
746 d_printf("<center><table border=0>");
747 d_printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
748 d_printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
749 d_printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
750 d_printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
752 if (role == ROLE_DOMAIN_BDC) {
753 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
755 d_printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
756 d_printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
757 d_printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
758 d_printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
760 d_printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
762 /* Print out the list of wins servers */
763 if(lp_wins_server_list()) {
765 const char **wins_servers = lp_wins_server_list();
766 for(i = 0; wins_servers[i]; i++) d_printf("%s ", wins_servers[i]);
769 d_printf("\"></td></tr>\n");
771 d_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"));
772 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
774 d_printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
775 d_printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
776 d_printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
777 d_printf("<td></td></tr>\n");
779 /* Enable this when we are ready ....
780 * d_printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
781 * d_printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
782 * d_printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
783 * d_printf("<td></td></tr>\n");
786 d_printf("</table></center>");
789 d_printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
790 d_printf("</form>\n");
794 /****************************************************************************
795 display a globals editing page
796 ****************************************************************************/
797 static void globals_page(void)
799 unsigned int parm_filter = FLAG_BASIC;
802 d_printf("<H2>%s</H2>\n", _("Global Parameters"));
804 if (cgi_variable("Commit")) {
805 commit_parameters(GLOBAL_SECTION_SNUM);
809 if ( cgi_variable("ViewMode") )
810 mode = atoi(cgi_variable("ViewMode"));
811 if ( cgi_variable("BasicMode"))
813 if ( cgi_variable("AdvMode"))
816 d_printf("<form name=\"swatform\" method=post action=globals>\n");
818 ViewModeBoxes( mode );
821 parm_filter = FLAG_BASIC;
824 parm_filter = FLAG_ADVANCED;
828 if (have_write_access) {
829 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
830 _("Commit Changes"));
833 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
837 d_printf("<table>\n");
838 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
839 d_printf("</table>\n");
840 d_printf("</form>\n");
843 /****************************************************************************
844 display a shares editing page. share is in unix codepage, and must be in
845 dos codepage. FIXME !!! JRA.
846 ****************************************************************************/
847 static void shares_page(void)
849 const char *share = cgi_variable("share");
854 unsigned int parm_filter = FLAG_BASIC;
857 snum = lp_servicenumber(share);
859 d_printf("<H2>%s</H2>\n", _("Share Parameters"));
861 if (cgi_variable("Commit") && snum >= 0) {
862 commit_parameters(snum);
866 if (cgi_variable("Delete") && snum >= 0) {
867 lp_remove_service(snum);
873 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
875 lp_copy_service(GLOBAL_SECTION_SNUM, share);
876 iNumNonAutoPrintServices = lp_numservices();
878 snum = lp_servicenumber(share);
881 d_printf("<FORM name=\"swatform\" method=post>\n");
883 d_printf("<table>\n");
885 if ( cgi_variable("ViewMode") )
886 mode = atoi(cgi_variable("ViewMode"));
887 if ( cgi_variable("BasicMode"))
889 if ( cgi_variable("AdvMode"))
892 ViewModeBoxes( mode );
895 parm_filter = FLAG_BASIC;
898 parm_filter = FLAG_ADVANCED;
901 d_printf("<br><tr>\n");
902 d_printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
903 d_printf("<td><select name=share>\n");
905 d_printf("<option value=\" \"> \n");
906 for (i=0;i<lp_numservices();i++) {
907 s = lp_servicename(i);
908 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
909 d_printf("<option %s value=\"%s\">%s\n",
910 (share && strcmp(share,s)==0)?"SELECTED":"",
914 d_printf("</select></td>\n");
915 if (have_write_access) {
916 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
919 d_printf("</table>");
921 if (have_write_access) {
923 d_printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
924 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
926 d_printf("</table>");
930 if (have_write_access) {
931 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
934 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
939 d_printf("<table>\n");
940 show_parameters(snum, 1, parm_filter, 0);
941 d_printf("</table>\n");
944 d_printf("</FORM>\n");
947 /*************************************************************
948 change a password either locally or remotely
949 *************************************************************/
950 static BOOL change_password(const char *remote_machine, const char *user_name,
951 const char *old_passwd, const char *new_passwd,
959 d_printf("%s\n<p>", _("password change in demo mode rejected"));
963 if (remote_machine != NULL) {
964 ret = remote_password_change(remote_machine, user_name, old_passwd,
965 new_passwd, err_str, sizeof(err_str));
967 d_printf("%s\n<p>", err_str);
971 if(!initialize_password_db(True)) {
972 d_printf("%s\n<p>", _("Can't setup password database vectors."));
976 ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
977 msg_str, sizeof(msg_str));
980 d_printf("%s\n<p>", msg_str);
982 d_printf("%s\n<p>", err_str);
987 /****************************************************************************
988 do the stuff required to add or change a password
989 ****************************************************************************/
990 static void chg_passwd(void)
996 /* Make sure users name has been specified */
997 if (strlen(cgi_variable(SWAT_USER)) == 0) {
998 d_printf("<p>%s\n", _(" Must specify \"User Name\" "));
1003 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1004 * so if that's what we're doing, skip the rest of the checks
1006 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1009 * If current user is not root, make sure old password has been specified
1010 * If REMOTE change, even root must provide old password
1012 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
1013 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
1014 d_printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1018 /* If changing a users password on a remote hosts we have to know what host */
1019 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
1020 d_printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1024 /* Make sure new passwords have been specified */
1025 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
1026 (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
1027 d_printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1031 /* Make sure new passwords was typed correctly twice */
1032 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
1033 d_printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1038 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1039 host = cgi_variable(RHOST);
1040 } else if (am_root()) {
1047 * Set up the local flags.
1050 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1051 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1052 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1053 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1055 rslt = change_password(host,
1056 cgi_variable(SWAT_USER),
1057 cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
1060 if(local_flags == 0) {
1063 d_printf(_(" The passwd for '%s' has been changed."), cgi_variable(SWAT_USER));
1066 d_printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable(SWAT_USER));
1074 /****************************************************************************
1075 display a password editing page
1076 ****************************************************************************/
1077 static void passwd_page(void)
1079 const char *new_name = cgi_user_name();
1082 * After the first time through here be nice. If the user
1083 * changed the User box text to another users name, remember it.
1085 if (cgi_variable(SWAT_USER)) {
1086 new_name = cgi_variable(SWAT_USER);
1089 if (!new_name) new_name = "";
1091 d_printf("<H2>%s</H2>\n", _("Server Password Management"));
1093 d_printf("<FORM name=\"swatform\" method=post>\n");
1095 d_printf("<table>\n");
1098 * Create all the dialog boxes for data collection
1100 d_printf("<tr><td> %s : </td>\n", _("User Name"));
1101 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1103 d_printf("<tr><td> %s : </td>\n", _("Old Password"));
1104 d_printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1106 d_printf("<tr><td> %s : </td>\n", _("New Password"));
1107 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1108 d_printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1109 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1110 d_printf("</table>\n");
1113 * Create all the control buttons for requesting action
1115 d_printf("<input type=submit name=%s value=\"%s\">\n",
1116 CHG_S_PASSWD_FLAG, _("Change Password"));
1117 if (demo_mode || am_root()) {
1118 d_printf("<input type=submit name=%s value=\"%s\">\n",
1119 ADD_USER_FLAG, _("Add New User"));
1120 d_printf("<input type=submit name=%s value=\"%s\">\n",
1121 DELETE_USER_FLAG, _("Delete User"));
1122 d_printf("<input type=submit name=%s value=\"%s\">\n",
1123 DISABLE_USER_FLAG, _("Disable User"));
1124 d_printf("<input type=submit name=%s value=\"%s\">\n",
1125 ENABLE_USER_FLAG, _("Enable User"));
1127 d_printf("<p></FORM>\n");
1130 * Do some work if change, add, disable or enable was
1131 * requested. It could be this is the first time through this
1132 * code, so there isn't anything to do. */
1133 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1134 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1138 d_printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1140 d_printf("<FORM name=\"swatform\" method=post>\n");
1142 d_printf("<table>\n");
1145 * Create all the dialog boxes for data collection
1147 d_printf("<tr><td> %s : </td>\n", _("User Name"));
1148 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1149 d_printf("<tr><td> %s : </td>\n", _("Old Password"));
1150 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1151 d_printf("<tr><td> %s : </td>\n", _("New Password"));
1152 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1153 d_printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1154 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1155 d_printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1156 d_printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1158 d_printf("</table>");
1161 * Create all the control buttons for requesting action
1163 d_printf("<input type=submit name=%s value=\"%s\">",
1164 CHG_R_PASSWD_FLAG, _("Change Password"));
1166 d_printf("<p></FORM>\n");
1169 * Do some work if a request has been made to change the
1170 * password somewhere other than the server. It could be this
1171 * is the first time through this code, so there isn't
1172 * anything to do. */
1173 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1179 /****************************************************************************
1180 display a printers editing page
1181 ****************************************************************************/
1182 static void printers_page(void)
1184 const char *share = cgi_variable("share");
1189 unsigned int parm_filter = FLAG_BASIC;
1192 snum = lp_servicenumber(share);
1194 d_printf("<H2>%s</H2>\n", _("Printer Parameters"));
1196 d_printf("<H3>%s</H3>\n", _("Important Note:"));
1197 d_printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1198 d_printf(_("are autoloaded printers from "));
1199 d_printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1200 d_printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1202 if (cgi_variable("Commit") && snum >= 0) {
1203 commit_parameters(snum);
1204 if (snum >= iNumNonAutoPrintServices)
1210 if (cgi_variable("Delete") && snum >= 0) {
1211 lp_remove_service(snum);
1217 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1219 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1220 iNumNonAutoPrintServices = lp_numservices();
1221 snum = lp_servicenumber(share);
1222 lp_do_parameter(snum, "print ok", "Yes");
1224 snum = lp_servicenumber(share);
1227 d_printf("<FORM name=\"swatform\" method=post>\n");
1229 if ( cgi_variable("ViewMode") )
1230 mode = atoi(cgi_variable("ViewMode"));
1231 if ( cgi_variable("BasicMode"))
1233 if ( cgi_variable("AdvMode"))
1236 ViewModeBoxes( mode );
1239 parm_filter = FLAG_BASIC;
1242 parm_filter = FLAG_ADVANCED;
1245 d_printf("<table>\n");
1246 d_printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1247 d_printf("<td><select name=\"share\">\n");
1248 if (snum < 0 || !lp_print_ok(snum))
1249 d_printf("<option value=\" \"> \n");
1250 for (i=0;i<lp_numservices();i++) {
1251 s = lp_servicename(i);
1252 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1253 if (i >= iNumNonAutoPrintServices)
1254 d_printf("<option %s value=\"%s\">[*]%s\n",
1255 (share && strcmp(share,s)==0)?"SELECTED":"",
1258 d_printf("<option %s value=\"%s\">%s\n",
1259 (share && strcmp(share,s)==0)?"SELECTED":"",
1263 d_printf("</select></td>");
1264 if (have_write_access) {
1265 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1268 d_printf("</table>\n");
1270 if (have_write_access) {
1271 d_printf("<table>\n");
1272 d_printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1273 d_printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1274 d_printf("</table>");
1279 if (have_write_access) {
1280 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1282 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1287 d_printf("<table>\n");
1288 show_parameters(snum, 1, parm_filter, 1);
1289 d_printf("</table>\n");
1291 d_printf("</FORM>\n");
1296 * main function for SWAT.
1298 int main(int argc, char *argv[])
1303 struct poptOption long_options[] = {
1305 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1311 umask(S_IWGRP | S_IWOTH);
1313 #if defined(HAVE_SET_AUTH_PARAMETERS)
1314 set_auth_parameters(argc, argv);
1315 #endif /* HAVE_SET_AUTH_PARAMETERS */
1317 /* just in case it goes wild ... */
1322 /* we don't want any SIGPIPE messages */
1323 BlockSignals(True,SIGPIPE);
1325 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1326 if (!dbf) dbf = x_stderr;
1328 /* we don't want stderr screwing us up */
1330 open("/dev/null", O_WRONLY);
1332 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1334 /* Parse command line options */
1336 while((opt = poptGetNextOpt(pc)) != -1) { }
1338 poptFreeContext(pc);
1340 setup_logging(argv[0],False);
1342 iNumNonAutoPrintServices = lp_numservices();
1345 cgi_setup(dyn_SWATDIR, !demo_mode);
1349 cgi_load_variables();
1351 if (!file_exist(dyn_CONFIGFILE, NULL)) {
1352 have_read_access = True;
1353 have_write_access = True;
1355 /* check if the authenticated user has write access - if not then
1356 don't show write options */
1357 have_write_access = (access(dyn_CONFIGFILE,W_OK) == 0);
1359 /* if the user doesn't have read access to smb.conf then
1360 don't let them view it */
1361 have_read_access = (access(dyn_CONFIGFILE,R_OK) == 0);
1364 show_main_buttons();
1366 page = cgi_pathinfo();
1368 /* Root gets full functionality */
1369 if (have_read_access && strcmp(page, "globals")==0) {
1371 } else if (have_read_access && strcmp(page,"shares")==0) {
1373 } else if (have_read_access && strcmp(page,"printers")==0) {
1375 } else if (have_read_access && strcmp(page,"status")==0) {
1377 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1379 } else if (strcmp(page,"passwd")==0) {
1381 } else if (have_read_access && strcmp(page,"wizard")==0) {
1383 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1384 wizard_params_page();
1385 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {