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 passwd_only = False;
36 static BOOL have_write_access = False;
37 static BOOL have_read_access = False;
38 static int iNumNonAutoPrintServices = 0;
41 * Password Management Globals
43 #define SWAT_USER "username"
44 #define OLD_PSWD "old_passwd"
45 #define NEW_PSWD "new_passwd"
46 #define NEW2_PSWD "new2_passwd"
47 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
48 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
49 #define ADD_USER_FLAG "add_user_flag"
50 #define DELETE_USER_FLAG "delete_user_flag"
51 #define DISABLE_USER_FLAG "disable_user_flag"
52 #define ENABLE_USER_FLAG "enable_user_flag"
53 #define RHOST "remote_host"
56 /****************************************************************************
57 ****************************************************************************/
58 static int enum_index(int value, const struct enum_list *enumlist)
61 for (i=0;enumlist[i].name;i++)
62 if (value == enumlist[i].value) break;
66 static char *fix_backslash(const char *str)
68 static char newstring[1024];
72 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
80 static char *stripspaceupper(const char *str)
82 static char newstring[1024];
86 if (*str != ' ') *p++ = toupper(*str);
93 static char *make_parm_name(const char *label)
95 static char parmname[1024];
99 if (*label == ' ') *p++ = '_';
107 /****************************************************************************
108 include a lump of html in a page
109 ****************************************************************************/
110 static int include_html(const char *fname)
116 fd = web_open(fname, O_RDONLY, 0);
119 printf(_("ERROR: Can't open %s"), fname);
124 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
132 /****************************************************************************
133 start the page with standard stuff
134 ****************************************************************************/
135 static void print_header(void)
137 if (!cgi_waspost()) {
138 printf("Expires: 0\r\n");
140 printf("Content-type: text/html\r\n\r\n");
142 if (!include_html("include/header.html")) {
143 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
144 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
148 /* *******************************************************************
149 show parameter label with translated name in the following form
150 because showing original and translated label in one line looks
151 too long, and showing translated label only is unusable for
153 -------------------------------
154 HELP security [combo box][button]
156 -------------------------------
157 (capital words are translated by gettext.)
158 if no translation is available, then same form as original is
160 "i18n_translated_parm" class is used to change the color of the
161 translated parameter with CSS.
162 **************************************************************** */
163 static const char* get_parm_translated(
164 const char* pAnchor, const char* pHelp, const char* pLabel)
166 const char* pTranslated = _(pLabel);
167 static pstring output;
168 if(strcmp(pLabel, pTranslated) != 0)
171 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
172 pAnchor, pHelp, pLabel, pTranslated);
176 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
177 pAnchor, pHelp, pLabel);
180 /****************************************************************************
182 ****************************************************************************/
183 static void print_footer(void)
185 if (!include_html("include/footer.html")) {
186 printf("\n</BODY>\n</HTML>\n");
190 /****************************************************************************
191 display one editable parameter in a form
192 ****************************************************************************/
193 static void show_parameter(int snum, struct parm_struct *parm)
196 void *ptr = parm->ptr;
197 char *utf8_s1, *utf8_s2;
199 if (parm->class == P_LOCAL && snum >= 0) {
200 ptr = lp_local_ptr(snum, ptr);
203 printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label));
204 switch (parm->type) {
206 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
207 make_parm_name(parm->label), *(char *)ptr);
208 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
209 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
213 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
214 make_parm_name(parm->label));
215 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
216 char **list = *(char ***)ptr;
217 for (;*list;list++) {
218 /* enclose in HTML encoded quotes if the string contains a space */
219 if ( strchr_m(*list, ' ') ) {
220 push_utf8_allocate(&utf8_s1, *list);
221 push_utf8_allocate(&utf8_s2, ((*(list+1))?", ":""));
222 printf(""%s"%s", utf8_s1, utf8_s2);
224 push_utf8_allocate(&utf8_s1, *list);
225 push_utf8_allocate(&utf8_s2, ((*(list+1))?", ":""));
226 printf("%s%s", utf8_s1, utf8_s2);
233 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
234 _("Set Default"), make_parm_name(parm->label));
235 if (parm->def.lvalue) {
236 char **list = (char **)(parm->def.lvalue);
237 for (; *list; list++) {
238 /* enclose in HTML encoded quotes if the string contains a space */
239 if ( strchr_m(*list, ' ') )
240 printf(""%s"%s", *list, ((*(list+1))?", ":""));
242 printf("%s%s", *list, ((*(list+1))?", ":""));
250 push_utf8_allocate(&utf8_s1, *(char **)ptr);
251 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
252 make_parm_name(parm->label), utf8_s1);
254 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
255 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
260 push_utf8_allocate(&utf8_s1, (char *)ptr);
261 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
262 make_parm_name(parm->label), utf8_s1);
264 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
265 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
269 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
270 printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
271 printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
273 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
274 _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?0:1);
278 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
279 printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
280 printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
282 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
283 _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?1:0);
287 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
288 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
289 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
293 printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
294 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
295 _("Set Default"), make_parm_name(parm->label),
296 octal_string((int)(parm->def.ivalue)));
300 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
301 for (i=0;parm->enum_list[i].name;i++) {
302 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
303 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
307 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
308 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
313 printf("</td></tr>\n");
316 /****************************************************************************
317 display a set of parameters for a service
318 ****************************************************************************/
319 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
322 struct parm_struct *parm;
323 const char *heading = NULL;
324 const char *last_heading = NULL;
326 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
327 if (snum < 0 && parm->class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
329 if (parm->class == P_SEPARATOR) {
330 heading = parm->label;
333 if (parm->flags & FLAG_HIDE) continue;
335 if (printers & !(parm->flags & FLAG_PRINT)) continue;
336 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
339 if (!( parm_filter & FLAG_ADVANCED )) {
340 if (!(parm->flags & FLAG_BASIC)) {
341 void *ptr = parm->ptr;
343 if (parm->class == P_LOCAL && snum >= 0) {
344 ptr = lp_local_ptr(snum, ptr);
347 switch (parm->type) {
349 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
353 if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
358 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
363 if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
368 if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
373 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
378 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
384 if (printers && !(parm->flags & FLAG_PRINT)) continue;
387 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
389 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
391 if (heading && heading != last_heading) {
392 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
393 last_heading = heading;
395 show_parameter(snum, parm);
399 /****************************************************************************
400 load the smb.conf file into loadparm.
401 ****************************************************************************/
402 static BOOL load_config(BOOL save_def)
404 lp_resetnumservices();
405 return lp_load(dyn_CONFIGFILE,False,save_def,False);
408 /****************************************************************************
410 ****************************************************************************/
411 static void write_config(FILE *f, BOOL show_defaults)
413 fprintf(f, "# Samba config file created using SWAT\n");
414 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
415 fprintf(f, "# Date: %s\n\n", timestring(False));
417 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
420 /****************************************************************************
421 save and reload the smb.conf config file
422 ****************************************************************************/
423 static int save_reload(int snum)
428 f = sys_fopen(dyn_CONFIGFILE,"w");
430 printf(_("failed to open %s for writing"), dyn_CONFIGFILE);
435 /* just in case they have used the buggy xinetd to create the file */
436 if (fstat(fileno(f), &st) == 0 &&
437 (st.st_mode & S_IWOTH)) {
438 #if defined HAVE_FCHMOD
439 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
441 chmod(dyn_CONFIGFILE, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
445 write_config(f, False);
447 lp_dump_one(f, False, snum);
452 if (!load_config(False)) {
453 printf(_("Can't reload %s"), dyn_CONFIGFILE);
457 iNumNonAutoPrintServices = lp_numservices();
463 /****************************************************************************
465 ****************************************************************************/
466 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
471 if (snum < 0 && parm->class == P_LOCAL) {
472 /* this handles the case where we are changing a local
473 variable globally. We need to change the parameter in
474 all shares where it is currently set to the default */
475 for (i=0;i<lp_numservices();i++) {
476 s = lp_servicename(i);
477 if (s && (*s) && lp_is_default(i, parm)) {
478 lp_do_parameter(i, parm->label, v);
483 lp_do_parameter(snum, parm->label, v);
486 /****************************************************************************
487 commit a set of parameters for a service
488 ****************************************************************************/
489 static void commit_parameters(int snum)
492 struct parm_struct *parm;
496 while ((parm = lp_next_parameter(snum, &i, 1))) {
497 slprintf(label, sizeof(label)-1, "parm_%s", make_parm_name(parm->label));
498 if ((v = cgi_variable(label))) {
499 if (parm->flags & FLAG_HIDE) continue;
500 commit_parameter(snum, parm, v);
505 /****************************************************************************
506 spit out the html for a link with an image
507 ****************************************************************************/
508 static void image_link(const char *name, const char *hlink, const char *src)
510 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
511 cgi_baseurl(), hlink, src, name);
514 /****************************************************************************
515 display the main navigation controls at the top of each page along
517 ****************************************************************************/
518 static void show_main_buttons(void)
522 if ((p = cgi_user_name()) && strcmp(p, "root")) {
523 printf(_("Logged in as <b>%s</b>"), p);
527 image_link(_("Home"), "", "images/home.gif");
528 if (have_write_access) {
529 image_link(_("Globals"), "globals", "images/globals.gif");
530 image_link(_("Shares"), "shares", "images/shares.gif");
531 image_link(_("Printers"), "printers", "images/printers.gif");
532 image_link(_("Wizard"), "wizard", "images/wizard.gif");
534 /* root always gets all buttons, otherwise look for -P */
535 if ( have_write_access || (!passwd_only && have_read_access) ) {
536 image_link(_("Status"), "status", "images/status.gif");
537 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
539 image_link(_("Password Management"), "passwd", "images/passwd.gif");
544 /****************************************************************************
545 * Handle Display/Edit Mode CGI
546 ****************************************************************************/
547 static void ViewModeBoxes(int mode)
549 printf("<p>%s: \n", _("Current View Is"));
550 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
551 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
552 printf("<br>%s: \n", _("Change View To"));
553 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
554 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
555 printf("</p><br>\n");
558 /****************************************************************************
559 display a welcome page
560 ****************************************************************************/
561 static void welcome_page(void)
563 include_html("help/welcome.html");
566 /****************************************************************************
567 display the current smb.conf
568 ****************************************************************************/
569 static void viewconfig_page(void)
573 if (cgi_variable("full_view")) {
577 printf("<H2>%s</H2>\n", _("Current Config"));
578 printf("<form method=post>\n");
581 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
583 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
587 write_config(stdout, full_view);
592 /****************************************************************************
593 second screen of the wizard ... Fetch Configuration Parameters
594 ****************************************************************************/
595 static void wizard_params_page(void)
597 unsigned int parm_filter = FLAG_WIZARD;
599 /* Here we first set and commit all the parameters that were selected
600 in the previous screen. */
602 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
604 if (cgi_variable("Commit")) {
605 commit_parameters(GLOBAL_SECTION_SNUM);
609 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
611 if (have_write_access) {
612 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
615 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
619 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
620 printf("</table>\n");
624 /****************************************************************************
625 Utility to just rewrite the smb.conf file - effectively just cleans it up
626 ****************************************************************************/
627 static void rewritecfg_file(void)
629 commit_parameters(GLOBAL_SECTION_SNUM);
631 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
634 /****************************************************************************
635 wizard to create/modify the smb.conf file
636 ****************************************************************************/
637 static void wizard_page(void)
639 /* Set some variables to collect data from smb.conf */
646 if (cgi_variable("Rewrite")) {
647 (void) rewritecfg_file();
651 if (cgi_variable("GetWizardParams")){
652 (void) wizard_params_page();
656 if (cgi_variable("Commit")){
657 SerType = atoi(cgi_variable("ServerType"));
658 winstype = atoi(cgi_variable("WINSType"));
659 have_home = lp_servicenumber(HOMES_NAME);
660 HomeExpo = atoi(cgi_variable("HomeExpo"));
662 /* Plain text passwords are too badly broken - use encrypted passwords only */
663 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
667 /* Stand-alone Server */
668 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
669 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
673 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
674 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
677 /* Domain Controller */
678 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
679 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
682 switch ( winstype ) {
684 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
685 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
688 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
689 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
692 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
693 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable("WINSAddr"));
697 /* Have to create Homes share? */
698 if ((HomeExpo == 1) && (have_home == -1)) {
701 pstrcpy(unix_share,HOMES_NAME);
703 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
704 iNumNonAutoPrintServices = lp_numservices();
705 have_home = lp_servicenumber(HOMES_NAME);
706 lp_do_parameter( have_home, "read only", "No");
707 lp_do_parameter( have_home, "valid users", "%S");
708 lp_do_parameter( have_home, "browseable", "No");
709 commit_parameters(have_home);
712 /* Need to Delete Homes share? */
713 if ((HomeExpo == 0) && (have_home != -1)) {
714 lp_remove_service(have_home);
718 commit_parameters(GLOBAL_SECTION_SNUM);
723 /* Now determine smb.conf WINS settings */
724 if (lp_wins_support())
726 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
730 /* Do we have a homes share? */
731 have_home = lp_servicenumber(HOMES_NAME);
733 if ((winstype == 2) && lp_wins_support())
736 role = lp_server_role();
739 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
740 printf("<form method=post action=wizard>\n");
742 if (have_write_access) {
743 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
744 printf("%s", _("The same will happen if you press the commit button."));
745 printf("<br><br>\n");
747 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
748 printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
749 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
750 printf("</center>\n");
754 printf("<center><table border=0>");
755 printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
756 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
757 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
758 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
760 if (role == ROLE_DOMAIN_BDC) {
761 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
763 printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
764 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
765 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
766 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
768 printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
770 /* Print out the list of wins servers */
771 if(lp_wins_server_list()) {
773 const char **wins_servers = lp_wins_server_list();
774 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
777 printf("\"></td></tr>\n");
779 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"));
780 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
782 printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
783 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
784 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
785 printf("<td></td></tr>\n");
787 /* Enable this when we are ready ....
788 * printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
789 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
790 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
791 * printf("<td></td></tr>\n");
794 printf("</table></center>");
797 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
802 /****************************************************************************
803 display a globals editing page
804 ****************************************************************************/
805 static void globals_page(void)
807 unsigned int parm_filter = FLAG_BASIC;
810 printf("<H2>%s</H2>\n", _("Global Parameters"));
812 if (cgi_variable("Commit")) {
813 commit_parameters(GLOBAL_SECTION_SNUM);
817 if ( cgi_variable("ViewMode") )
818 mode = atoi(cgi_variable("ViewMode"));
819 if ( cgi_variable("BasicMode"))
821 if ( cgi_variable("AdvMode"))
824 printf("<form name=\"swatform\" method=post action=globals>\n");
826 ViewModeBoxes( mode );
829 parm_filter = FLAG_BASIC;
832 parm_filter = FLAG_ADVANCED;
836 if (have_write_access) {
837 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
838 _("Commit Changes"));
841 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
846 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
847 printf("</table>\n");
851 /****************************************************************************
852 display a shares editing page. share is in unix codepage,
853 ****************************************************************************/
854 static void shares_page(void)
856 const char *share = cgi_variable("share");
862 unsigned int parm_filter = FLAG_BASIC;
865 snum = lp_servicenumber(share);
867 printf("<H2>%s</H2>\n", _("Share Parameters"));
869 if (cgi_variable("Commit") && snum >= 0) {
870 commit_parameters(snum);
874 if (cgi_variable("Delete") && snum >= 0) {
875 lp_remove_service(snum);
881 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
883 lp_copy_service(GLOBAL_SECTION_SNUM, share);
884 iNumNonAutoPrintServices = lp_numservices();
886 snum = lp_servicenumber(share);
889 printf("<FORM name=\"swatform\" method=post>\n");
893 if ( cgi_variable("ViewMode") )
894 mode = atoi(cgi_variable("ViewMode"));
895 if ( cgi_variable("BasicMode"))
897 if ( cgi_variable("AdvMode"))
900 ViewModeBoxes( mode );
903 parm_filter = FLAG_BASIC;
906 parm_filter = FLAG_ADVANCED;
909 printf("<br><tr>\n");
910 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
911 printf("<td><select name=share>\n");
913 printf("<option value=\" \"> \n");
914 for (i=0;i<lp_numservices();i++) {
915 s = lp_servicename(i);
916 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
917 push_utf8_allocate(&utf8_s, s);
918 printf("<option %s value=\"%s\">%s\n",
919 (share && strcmp(share,s)==0)?"SELECTED":"",
925 printf("</select></td>\n");
926 if (have_write_access) {
927 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
932 if (have_write_access) {
934 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
935 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
941 if (have_write_access) {
942 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
945 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
951 show_parameters(snum, 1, parm_filter, 0);
952 printf("</table>\n");
958 /*************************************************************
959 change a password either locally or remotely
960 *************************************************************/
961 static BOOL change_password(const char *remote_machine, const char *user_name,
962 const char *old_passwd, const char *new_passwd,
970 printf("%s\n<p>", _("password change in demo mode rejected"));
974 if (remote_machine != NULL) {
975 ret = remote_password_change(remote_machine, user_name, old_passwd,
976 new_passwd, err_str, sizeof(err_str));
978 printf("%s\n<p>", err_str);
982 if(!initialize_password_db(True)) {
983 printf("%s\n<p>", _("Can't setup password database vectors."));
987 ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
988 msg_str, sizeof(msg_str));
991 printf("%s\n<p>", msg_str);
993 printf("%s\n<p>", err_str);
998 /****************************************************************************
999 do the stuff required to add or change a password
1000 ****************************************************************************/
1001 static void chg_passwd(void)
1005 int local_flags = 0;
1007 /* Make sure users name has been specified */
1008 if (strlen(cgi_variable(SWAT_USER)) == 0) {
1009 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1014 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1015 * so if that's what we're doing, skip the rest of the checks
1017 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1020 * If current user is not root, make sure old password has been specified
1021 * If REMOTE change, even root must provide old password
1023 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
1024 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
1025 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1029 /* If changing a users password on a remote hosts we have to know what host */
1030 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
1031 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1035 /* Make sure new passwords have been specified */
1036 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
1037 (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
1038 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1042 /* Make sure new passwords was typed correctly twice */
1043 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
1044 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1049 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1050 host = cgi_variable(RHOST);
1051 } else if (am_root()) {
1058 * Set up the local flags.
1061 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1062 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1063 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1064 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1065 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1066 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1069 rslt = change_password(host,
1070 cgi_variable(SWAT_USER),
1071 cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
1074 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1077 printf(_(" The passwd for '%s' has been changed."), cgi_variable(SWAT_USER));
1080 printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable(SWAT_USER));
1088 /****************************************************************************
1089 display a password editing page
1090 ****************************************************************************/
1091 static void passwd_page(void)
1093 const char *new_name = cgi_user_name();
1096 * After the first time through here be nice. If the user
1097 * changed the User box text to another users name, remember it.
1099 if (cgi_variable(SWAT_USER)) {
1100 new_name = cgi_variable(SWAT_USER);
1103 if (!new_name) new_name = "";
1105 printf("<H2>%s</H2>\n", _("Server Password Management"));
1107 printf("<FORM name=\"swatform\" method=post>\n");
1109 printf("<table>\n");
1112 * Create all the dialog boxes for data collection
1114 printf("<tr><td> %s : </td>\n", _("User Name"));
1115 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1117 printf("<tr><td> %s : </td>\n", _("Old Password"));
1118 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1120 printf("<tr><td> %s : </td>\n", _("New Password"));
1121 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1122 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1123 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1124 printf("</table>\n");
1127 * Create all the control buttons for requesting action
1129 printf("<input type=submit name=%s value=\"%s\">\n",
1130 CHG_S_PASSWD_FLAG, _("Change Password"));
1131 if (demo_mode || am_root()) {
1132 printf("<input type=submit name=%s value=\"%s\">\n",
1133 ADD_USER_FLAG, _("Add New User"));
1134 printf("<input type=submit name=%s value=\"%s\">\n",
1135 DELETE_USER_FLAG, _("Delete User"));
1136 printf("<input type=submit name=%s value=\"%s\">\n",
1137 DISABLE_USER_FLAG, _("Disable User"));
1138 printf("<input type=submit name=%s value=\"%s\">\n",
1139 ENABLE_USER_FLAG, _("Enable User"));
1141 printf("<p></FORM>\n");
1144 * Do some work if change, add, disable or enable was
1145 * requested. It could be this is the first time through this
1146 * code, so there isn't anything to do. */
1147 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1148 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1152 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1154 printf("<FORM name=\"swatform\" method=post>\n");
1156 printf("<table>\n");
1159 * Create all the dialog boxes for data collection
1161 printf("<tr><td> %s : </td>\n", _("User Name"));
1162 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1163 printf("<tr><td> %s : </td>\n", _("Old Password"));
1164 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1165 printf("<tr><td> %s : </td>\n", _("New Password"));
1166 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1167 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1168 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1169 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1170 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1175 * Create all the control buttons for requesting action
1177 printf("<input type=submit name=%s value=\"%s\">",
1178 CHG_R_PASSWD_FLAG, _("Change Password"));
1180 printf("<p></FORM>\n");
1183 * Do some work if a request has been made to change the
1184 * password somewhere other than the server. It could be this
1185 * is the first time through this code, so there isn't
1186 * anything to do. */
1187 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1193 /****************************************************************************
1194 display a printers editing page
1195 ****************************************************************************/
1196 static void printers_page(void)
1198 const char *share = cgi_variable("share");
1203 unsigned int parm_filter = FLAG_BASIC;
1206 snum = lp_servicenumber(share);
1208 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1210 printf("<H3>%s</H3>\n", _("Important Note:"));
1211 printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1212 printf(_("are autoloaded printers from "));
1213 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1214 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1216 if (cgi_variable("Commit") && snum >= 0) {
1217 commit_parameters(snum);
1218 if (snum >= iNumNonAutoPrintServices)
1224 if (cgi_variable("Delete") && snum >= 0) {
1225 lp_remove_service(snum);
1231 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1233 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1234 iNumNonAutoPrintServices = lp_numservices();
1235 snum = lp_servicenumber(share);
1236 lp_do_parameter(snum, "print ok", "Yes");
1238 snum = lp_servicenumber(share);
1241 printf("<FORM name=\"swatform\" method=post>\n");
1243 if ( cgi_variable("ViewMode") )
1244 mode = atoi(cgi_variable("ViewMode"));
1245 if ( cgi_variable("BasicMode"))
1247 if ( cgi_variable("AdvMode"))
1250 ViewModeBoxes( mode );
1253 parm_filter = FLAG_BASIC;
1256 parm_filter = FLAG_ADVANCED;
1259 printf("<table>\n");
1260 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1261 printf("<td><select name=\"share\">\n");
1262 if (snum < 0 || !lp_print_ok(snum))
1263 printf("<option value=\" \"> \n");
1264 for (i=0;i<lp_numservices();i++) {
1265 s = lp_servicename(i);
1266 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1267 if (i >= iNumNonAutoPrintServices)
1268 printf("<option %s value=\"%s\">[*]%s\n",
1269 (share && strcmp(share,s)==0)?"SELECTED":"",
1272 printf("<option %s value=\"%s\">%s\n",
1273 (share && strcmp(share,s)==0)?"SELECTED":"",
1277 printf("</select></td>");
1278 if (have_write_access) {
1279 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1282 printf("</table>\n");
1284 if (have_write_access) {
1285 printf("<table>\n");
1286 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1287 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1293 if (have_write_access) {
1294 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1296 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1301 printf("<table>\n");
1302 show_parameters(snum, 1, parm_filter, 1);
1303 printf("</table>\n");
1305 printf("</FORM>\n");
1310 * main function for SWAT.
1312 int main(int argc, char *argv[])
1317 struct poptOption long_options[] = {
1319 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1320 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1326 umask(S_IWGRP | S_IWOTH);
1328 #if defined(HAVE_SET_AUTH_PARAMETERS)
1329 set_auth_parameters(argc, argv);
1330 #endif /* HAVE_SET_AUTH_PARAMETERS */
1332 /* just in case it goes wild ... */
1337 /* we don't want any SIGPIPE messages */
1338 BlockSignals(True,SIGPIPE);
1340 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1341 if (!dbf) dbf = x_stderr;
1343 /* we don't want stderr screwing us up */
1345 open("/dev/null", O_WRONLY);
1347 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1349 /* Parse command line options */
1351 while((opt = poptGetNextOpt(pc)) != -1) { }
1353 poptFreeContext(pc);
1355 setup_logging(argv[0],False);
1357 iNumNonAutoPrintServices = lp_numservices();
1360 cgi_setup(dyn_SWATDIR, !demo_mode);
1364 cgi_load_variables();
1366 if (!file_exist(dyn_CONFIGFILE, NULL)) {
1367 have_read_access = True;
1368 have_write_access = True;
1370 /* check if the authenticated user has write access - if not then
1371 don't show write options */
1372 have_write_access = (access(dyn_CONFIGFILE,W_OK) == 0);
1374 /* if the user doesn't have read access to smb.conf then
1375 don't let them view it */
1376 have_read_access = (access(dyn_CONFIGFILE,R_OK) == 0);
1379 show_main_buttons();
1381 page = cgi_pathinfo();
1383 /* Root gets full functionality */
1384 if (have_read_access && strcmp(page, "globals")==0) {
1386 } else if (have_read_access && strcmp(page,"shares")==0) {
1388 } else if (have_read_access && strcmp(page,"printers")==0) {
1390 } else if (have_read_access && strcmp(page,"status")==0) {
1392 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1394 } else if (strcmp(page,"passwd")==0) {
1396 } else if (have_read_access && strcmp(page,"wizard")==0) {
1398 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1399 wizard_params_page();
1400 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {