sync'ing up for 3.0alpha20 release
[Samba.git] / source / web / swat.c
blobaf6fa82ffe565c52b02cf1b2ee664e94cbbc1767
1 /*
2 Unix SMB/CIFS implementation.
3 Samba Web Administration Tool
4 Version 3.0.0
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.
23 /**
24 * @group swat SWAT
25 * @{
26 * @file swat.c
28 * @brief Samba Web Administration Tool.
29 **/
31 #include "includes.h"
32 #include "../web/swat_proto.h"
34 #define GLOBALS_SNUM -1
36 static BOOL demo_mode = False;
37 static BOOL have_write_access = False;
38 static BOOL have_read_access = False;
39 static int iNumNonAutoPrintServices = 0;
42 * Password Management Globals
44 #define SWAT_USER "username"
45 #define OLD_PSWD "old_passwd"
46 #define NEW_PSWD "new_passwd"
47 #define NEW2_PSWD "new2_passwd"
48 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
49 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
50 #define ADD_USER_FLAG "add_user_flag"
51 #define DELETE_USER_FLAG "delete_user_flag"
52 #define DISABLE_USER_FLAG "disable_user_flag"
53 #define ENABLE_USER_FLAG "enable_user_flag"
54 #define RHOST "remote_host"
56 /* we need these because we link to locking*.o */
57 void become_root(void) {}
58 void unbecome_root(void) {}
60 /****************************************************************************
61 ****************************************************************************/
62 static int enum_index(int value, struct enum_list *enumlist)
64 int i;
65 for (i=0;enumlist[i].name;i++)
66 if (value == enumlist[i].value) break;
67 return(i);
70 static char *fix_backslash(char *str)
72 static char newstring[1024];
73 char *p = newstring;
75 while (*str) {
76 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
77 else *p++ = *str;
78 ++str;
80 *p = '\0';
81 return newstring;
84 static char *stripspaceupper(char *str)
86 static char newstring[1024];
87 char *p = newstring;
89 while (*str) {
90 if (*str != ' ') *p++ = toupper(*str);
91 ++str;
93 *p = '\0';
94 return newstring;
97 static char *make_parm_name(char *label)
99 static char parmname[1024];
100 char *p = parmname;
102 while (*label) {
103 if (*label == ' ') *p++ = '_';
104 else *p++ = *label;
105 ++label;
107 *p = '\0';
108 return parmname;
111 /****************************************************************************
112 include a lump of html in a page
113 ****************************************************************************/
114 static int include_html(char *fname)
116 int fd;
117 char buf[1024];
118 int ret;
120 fd = web_open(fname, O_RDONLY, 0);
122 if (fd == -1) {
123 d_printf("ERROR: Can't open %s\n", fname);
124 return 0;
127 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
128 write(1, buf, ret);
131 close(fd);
132 return 1;
135 /****************************************************************************
136 start the page with standard stuff
137 ****************************************************************************/
138 static void print_header(void)
140 if (!cgi_waspost()) {
141 d_printf("Expires: 0\r\n");
143 d_printf("Content-type: text/html\r\n\r\n");
145 if (!include_html("include/header.html")) {
146 d_printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
147 d_printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
151 /* *******************************************************************
152 show parameter label with translated name in the following form
153 because showing original and translated label in one line looks
154 too long, and showing translated label only is unusable for
155 heavy users.
156 -------------------------------
157 HELP security [combo box][button]
158 SECURITY
159 -------------------------------
160 (capital words are translated by gettext.)
161 if no translation is available, then same form as original is
162 used.
163 "i18n_translated_parm" class is used to change the color of the
164 translated parameter with CSS.
165 **************************************************************** */
166 static const char* get_parm_translated(
167 const char* pAnchor, const char* pHelp, const char* pLabel)
169 const char* pTranslated = _(pLabel);
170 static pstring output;
171 if(strcmp(pLabel, pTranslated) != 0)
173 snprintf(output, sizeof(output),
174 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s <br><span class=\"i18n_translated_parm\">%s</span>",
175 pAnchor, pHelp, pLabel, pTranslated);
176 return output;
178 snprintf(output, sizeof(output),
179 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
180 pAnchor, pHelp, pLabel);
181 return output;
183 /****************************************************************************
184 finish off the page
185 ****************************************************************************/
186 static void print_footer(void)
188 if (!include_html("include/footer.html")) {
189 d_printf("\n</BODY>\n</HTML>\n");
193 /****************************************************************************
194 display one editable parameter in a form
195 ****************************************************************************/
196 static void show_parameter(int snum, struct parm_struct *parm)
198 int i;
199 void *ptr = parm->ptr;
201 if (parm->class == P_LOCAL && snum >= 0) {
202 ptr = lp_local_ptr(snum, ptr);
205 printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label));
206 switch (parm->type) {
207 case P_CHAR:
208 d_printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
209 make_parm_name(parm->label), *(char *)ptr);
210 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
211 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
212 break;
214 case P_LIST:
215 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"",
216 make_parm_name(parm->label));
217 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
218 char **list = *(char ***)ptr;
219 for (;*list;list++) {
220 d_printf("%s%s", *list, ((*(list+1))?" ":""));
223 d_printf("\">");
224 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
225 _("Set Default"), make_parm_name(parm->label));
226 if (parm->def.lvalue) {
227 char **list = (char **)(parm->def.lvalue);
228 for (; *list; list++) {
229 d_printf("%s%s", *list, ((*(list+1))?" ":""));
232 d_printf("\'\">");
233 break;
235 case P_STRING:
236 case P_USTRING:
237 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
238 make_parm_name(parm->label), *(char **)ptr);
239 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
240 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
241 break;
243 case P_GSTRING:
244 case P_UGSTRING:
245 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
246 make_parm_name(parm->label), (char *)ptr);
247 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
248 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
249 break;
251 case P_BOOL:
252 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
253 d_printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
254 d_printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
255 d_printf("</select>");
256 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
257 _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?0:1);
258 break;
260 case P_BOOLREV:
261 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
262 d_printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
263 d_printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
264 d_printf("</select>");
265 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
266 _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?1:0);
267 break;
269 case P_INTEGER:
270 d_printf("<input type=text size=8 name=\"parm_%s\" value=%d>", make_parm_name(parm->label), *(int *)ptr);
271 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
272 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
273 break;
275 case P_OCTAL:
276 d_printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
277 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
278 _("Set Default"), make_parm_name(parm->label),
279 octal_string((int)(parm->def.ivalue)));
280 break;
282 case P_ENUM:
283 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
284 for (i=0;parm->enum_list[i].name;i++) {
285 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
286 d_printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
289 d_printf("</select>");
290 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
291 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
292 break;
293 case P_SEP:
294 break;
296 d_printf("</td></tr>\n");
299 /****************************************************************************
300 display a set of parameters for a service
301 ****************************************************************************/
302 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
304 int i = 0;
305 struct parm_struct *parm;
306 char *heading = NULL;
307 char *last_heading = NULL;
309 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
310 if (snum < 0 && parm->class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
311 continue;
312 if (parm->class == P_SEPARATOR) {
313 heading = parm->label;
314 continue;
316 if (parm->flags & FLAG_HIDE) continue;
317 if (snum >= 0) {
318 if (printers & !(parm->flags & FLAG_PRINT)) continue;
319 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
321 if (parm_filter == FLAG_BASIC) {
322 if (!(parm->flags & FLAG_BASIC)) {
323 void *ptr = parm->ptr;
325 if (parm->class == P_LOCAL && snum >= 0) {
326 ptr = lp_local_ptr(snum, ptr);
329 switch (parm->type) {
330 case P_CHAR:
331 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
332 break;
334 case P_LIST:
335 if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
336 break;
338 case P_STRING:
339 case P_USTRING:
340 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
341 break;
343 case P_GSTRING:
344 case P_UGSTRING:
345 if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
346 break;
348 case P_BOOL:
349 case P_BOOLREV:
350 if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
351 break;
353 case P_INTEGER:
354 case P_OCTAL:
355 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
356 break;
359 case P_ENUM:
360 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
361 break;
362 case P_SEP:
363 continue;
366 if (printers && !(parm->flags & FLAG_PRINT)) continue;
368 if (parm_filter == FLAG_WIZARD) {
369 if (!((parm->flags & FLAG_WIZARD))) continue;
371 if (parm_filter == FLAG_ADVANCED) {
372 if (!((parm->flags & FLAG_ADVANCED))) continue;
374 if (heading && heading != last_heading) {
375 d_printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
376 last_heading = heading;
378 show_parameter(snum, parm);
382 /****************************************************************************
383 load the smb.conf file into loadparm.
384 ****************************************************************************/
385 static BOOL load_config(BOOL save_def)
387 lp_resetnumservices();
388 return lp_load(dyn_CONFIGFILE,False,save_def,False);
391 /****************************************************************************
392 write a config file
393 ****************************************************************************/
394 static void write_config(FILE *f, BOOL show_defaults)
396 fprintf(f, "# Samba config file created using SWAT\n");
397 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
398 fprintf(f, "# Date: %s\n\n", timestring(False));
400 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
403 /****************************************************************************
404 save and reload the smb.conf config file
405 ****************************************************************************/
406 static int save_reload(int snum)
408 FILE *f;
409 struct stat st;
411 f = sys_fopen(dyn_CONFIGFILE,"w");
412 if (!f) {
413 d_printf("failed to open %s for writing\n", dyn_CONFIGFILE);
414 return 0;
417 /* just in case they have used the buggy xinetd to create the file */
418 if (fstat(fileno(f), &st) == 0 &&
419 (st.st_mode & S_IWOTH)) {
420 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
423 write_config(f, False);
424 if (snum)
425 lp_dump_one(f, False, snum);
426 fclose(f);
428 lp_killunused(NULL);
430 if (!load_config(False)) {
431 d_printf("Can't reload %s\n", dyn_CONFIGFILE);
432 return 0;
434 iNumNonAutoPrintServices = lp_numservices();
435 load_printers();
437 return 1;
440 /****************************************************************************
441 commit one parameter
442 ****************************************************************************/
443 static void commit_parameter(int snum, struct parm_struct *parm, char *v)
445 int i;
446 char *s;
448 if (snum < 0 && parm->class == P_LOCAL) {
449 /* this handles the case where we are changing a local
450 variable globally. We need to change the parameter in
451 all shares where it is currently set to the default */
452 for (i=0;i<lp_numservices();i++) {
453 s = lp_servicename(i);
454 if (s && (*s) && lp_is_default(i, parm)) {
455 lp_do_parameter(i, parm->label, v);
460 lp_do_parameter(snum, parm->label, v);
463 /****************************************************************************
464 commit a set of parameters for a service
465 ****************************************************************************/
466 static void commit_parameters(int snum)
468 int i = 0;
469 struct parm_struct *parm;
470 pstring label;
471 char *v;
473 while ((parm = lp_next_parameter(snum, &i, 1))) {
474 slprintf(label, sizeof(label)-1, "parm_%s", make_parm_name(parm->label));
475 if ((v = cgi_variable(label))) {
476 if (parm->flags & FLAG_HIDE) continue;
477 commit_parameter(snum, parm, v);
482 /****************************************************************************
483 spit out the html for a link with an image
484 ****************************************************************************/
485 static void image_link(const char *name, const char *hlink, const char *src)
487 d_printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
488 cgi_baseurl(), hlink, src, name);
491 /****************************************************************************
492 display the main navigation controls at the top of each page along
493 with a title
494 ****************************************************************************/
495 static void show_main_buttons(void)
497 char *p;
499 if ((p = cgi_user_name()) && strcmp(p, "root")) {
500 d_printf(_("Logged in as <b>%s</b><p>\n"), p);
503 image_link(_("Home"), "", "images/home.gif");
504 if (have_write_access) {
505 image_link(_("Globals"), "globals", "images/globals.gif");
506 image_link(_("Shares"), "shares", "images/shares.gif");
507 image_link(_("Printers"), "printers", "images/printers.gif");
508 image_link(_("Wizard"), "wizard", "images/wizard.gif");
510 if (have_read_access) {
511 image_link(_("Status"), "status", "images/status.gif");
512 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
514 image_link(_("Password Management"), "passwd", "images/passwd.gif");
516 d_printf("<HR>\n");
519 /****************************************************************************
520 * Handle Display/Edit Mode CGI
521 ****************************************************************************/
522 static void ViewModeBoxes(int mode)
524 d_printf("<p>%s\n", _("Configuration View:&nbsp"));
525 d_printf("<input type=radio name=\"ViewMode\" value=0 %s>Basic\n", (mode == 0) ? "checked" : "");
526 d_printf("<input type=radio name=\"ViewMode\" value=1 %s>Advanced\n", (mode == 1) ? "checked" : "");
527 d_printf("<input type=radio name=\"ViewMode\" value=2 %s>Developer\n", (mode == 2) ? "checked" : "");
528 d_printf("</p><br>\n");
531 /****************************************************************************
532 display a welcome page
533 ****************************************************************************/
534 static void welcome_page(void)
536 include_html("help/welcome.html");
539 /****************************************************************************
540 display the current smb.conf
541 ****************************************************************************/
542 static void viewconfig_page(void)
544 int full_view=0;
546 if (cgi_variable("full_view")) {
547 full_view = 1;
550 d_printf("<H2>%s</H2>\n", _("Current Config"));
551 d_printf("<form method=post>\n");
553 if (full_view) {
554 d_printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
555 } else {
556 d_printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
559 d_printf("<p><pre>");
560 write_config(stdout, full_view);
561 d_printf("</pre>");
562 d_printf("</form>\n");
565 /****************************************************************************
566 second screen of the wizard ... Fetch Configuration Parameters
567 ****************************************************************************/
568 static void wizard_params_page(void)
570 unsigned int parm_filter = FLAG_WIZARD;
572 /* Here we first set and commit all the parameters that were selected
573 in the previous screen. */
575 d_printf("<H2>Wizard Parameter Edit Page</H2>\n");
577 if (cgi_variable("Commit")) {
578 commit_parameters(GLOBALS_SNUM);
579 save_reload(0);
582 d_printf("<form name=\"swatform\" method=post action=wizard_params>\n");
584 if (have_write_access) {
585 d_printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
588 d_printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
589 d_printf("<p>\n");
591 d_printf("<table>\n");
592 show_parameters(GLOBALS_SNUM, 1, parm_filter, 0);
593 d_printf("</table>\n");
594 d_printf("</form>\n");
597 /****************************************************************************
598 Utility to just rewrite the smb.conf file - effectively just cleans it up
599 ****************************************************************************/
600 static void rewritecfg_file(void)
602 commit_parameters(GLOBALS_SNUM);
603 save_reload(0);
604 d_printf("<H2>Note: smb.conf %s</H2>\n", _("file has been read and rewritten"));
607 /****************************************************************************
608 wizard to create/modify the smb.conf file
609 ****************************************************************************/
610 static void wizard_page(void)
612 /* Set some variables to collect data from smb.conf */
613 int role = 0;
614 int winstype = 0;
615 int have_home = -1;
616 int HomeExpo = 0;
617 int SerType = 0;
619 if (cgi_variable("Rewrite")) {
620 (void) rewritecfg_file();
621 return;
624 if (cgi_variable("GetWizardParams")){
625 (void) wizard_params_page();
626 return;
629 if (cgi_variable("Commit")){
630 SerType = atoi(cgi_variable("ServerType"));
631 winstype = atoi(cgi_variable("WINSType"));
632 have_home = lp_servicenumber(HOMES_NAME);
633 HomeExpo = atoi(cgi_variable("HomeExpo"));
635 /* Plain text passwords are too badly broken - use encrypted passwords only */
636 lp_do_parameter( GLOBALS_SNUM, "encrypt passwords", "Yes");
638 switch ( SerType ){
639 case 0:
640 /* Stand-alone Server */
641 lp_do_parameter( GLOBALS_SNUM, "security", "USER" );
642 lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" );
643 break;
644 case 1:
645 /* Domain Member */
646 lp_do_parameter( GLOBALS_SNUM, "security", "DOMAIN" );
647 lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" );
648 break;
649 case 2:
650 /* Domain Controller */
651 lp_do_parameter( GLOBALS_SNUM, "security", "USER" );
652 lp_do_parameter( GLOBALS_SNUM, "domain logons", "Yes" );
653 break;
655 switch ( winstype ) {
656 case 0:
657 lp_do_parameter( GLOBALS_SNUM, "wins support", "No" );
658 lp_do_parameter( GLOBALS_SNUM, "wins server", "" );
659 break;
660 case 1:
661 lp_do_parameter( GLOBALS_SNUM, "wins support", "Yes" );
662 lp_do_parameter( GLOBALS_SNUM, "wins server", "" );
663 break;
664 case 2:
665 lp_do_parameter( GLOBALS_SNUM, "wins support", "No" );
666 lp_do_parameter( GLOBALS_SNUM, "wins server", cgi_variable("WINSAddr"));
667 break;
670 /* Have to create Homes share? */
671 if ((HomeExpo == 1) && (have_home == -1)) {
672 pstring unix_share;
674 pstrcpy(unix_share,HOMES_NAME);
675 load_config(False);
676 lp_copy_service(GLOBALS_SNUM, unix_share);
677 iNumNonAutoPrintServices = lp_numservices();
678 have_home = lp_servicenumber(HOMES_NAME);
679 lp_do_parameter( have_home, "read only", "No");
680 lp_do_parameter( have_home, "valid users", "%S");
681 lp_do_parameter( have_home, "browseable", "No");
682 commit_parameters(have_home);
685 /* Need to Delete Homes share? */
686 if ((HomeExpo == 0) && (have_home != -1)) {
687 lp_remove_service(have_home);
688 have_home = -1;
691 commit_parameters(GLOBALS_SNUM);
692 save_reload(0);
694 else
696 /* Now determine smb.conf WINS settings */
697 if (lp_wins_support())
698 winstype = 1;
699 /* if (strlen(lp_wins_server_list()) != 0 )
700 * winstype = 2;
703 /* Do we have a homes share? */
704 have_home = lp_servicenumber(HOMES_NAME);
706 if ((winstype == 2) && lp_wins_support())
707 winstype = 3;
709 role = lp_server_role();
711 /* Here we go ... */
712 d_printf("<H2>Samba Configuration Wizard</H2>\n");
713 d_printf("<form method=post action=wizard>\n");
715 if (have_write_access) {
716 d_printf(_("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments.\n"));
717 d_printf(_("The same will happen if you press the commit button."));
718 d_printf("<br><br>");
719 d_printf("<center>");
720 d_printf("<input type=submit name=\"Rewrite\" value=%s> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
721 d_printf("<input type=submit name=\"Commit\" value=%s> &nbsp;&nbsp;",_("Commit"));
722 d_printf("<input type=submit name=\"GetWizardParams\" value=%s>", _("Edit Parameter Values"));
723 d_printf("</center>");
726 d_printf("<hr>");
727 d_printf("<center><table border=0>");
728 d_printf("<tr><td><b>%s</b></td>\n", "Server Type:&nbsp;");
729 d_printf("<td><input type=radio name=\"ServerType\" value=0 %s> Stand Alone&nbsp;</td>", (role == ROLE_STANDALONE) ? "checked" : "");
730 d_printf("<td><input type=radio name=\"ServerType\" value=1 %s> Domain Member&nbsp;</td>", (role == ROLE_DOMAIN_MEMBER) ? "checked" : "");
731 d_printf("<td><input type=radio name=\"ServerType\" value=2 %s> Domain Controller&nbsp;</td>", (role == ROLE_DOMAIN_PDC) ? "checked" : "");
732 d_printf("</tr>");
733 if (role == ROLE_DOMAIN_BDC) {
734 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Unusual Type in smb.conf - Please Select New Mode</font></td></tr>");
736 d_printf("<tr><td><b>%s</b></td>\n", "Configure WINS As:&nbsp;");
737 d_printf("<td><input type=radio name=\"WINSType\" value=0 %s> Not Used&nbsp;</td>", (winstype == 0) ? "checked" : "");
738 d_printf("<td><input type=radio name=\"WINSType\" value=1 %s> Server for client use&nbsp;</td>", (winstype == 1) ? "checked" : "");
739 d_printf("<td><input type=radio name=\"WINSType\" value=2 %s> Client of another WINS server&nbsp;</td>", (winstype == 2) ? "checked" : "");
740 d_printf("<tr><td></td><td></td><td></td><td>Remote WINS Server&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"%s\"></td></tr>",lp_wins_server_list());
741 if (winstype == 3) {
742 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Error: WINS Server Mode and WINS Support both set in smb.conf</font></td></tr>");
743 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Please Select desired WINS mode above.</font></td></tr>");
745 d_printf("</tr>");
746 d_printf("<tr><td><b>%s</b></td>\n","Expose Home Directories:&nbsp;");
747 d_printf("<td><input type=radio name=\"HomeExpo\" value=1 %s> Yes</td>", (have_home == -1) ? "" : "checked ");
748 d_printf("<td><input type=radio name=\"HomeExpo\" value=0 %s> No</td>", (have_home == -1 ) ? "checked" : "");
749 d_printf("<td></td></tr>");
751 /* Enable this when we are ready ....
752 * d_printf("<tr><td><b>%s</b></td>\n","Is Print Server:&nbsp;");
753 * d_printf("<td><input type=radio name=\"PtrSvr\" value=1 %s> Yes</td>");
754 * d_printf("<td><input type=radio name=\"PtrSvr\" value=0 %s> No</td>");
755 * d_printf("<td></td></tr>");
758 d_printf("</table></center>");
759 d_printf("<hr>");
761 d_printf(_("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment.\n"));
762 d_printf("</form>\n");
766 /****************************************************************************
767 display a globals editing page
768 ****************************************************************************/
769 static void globals_page(void)
771 unsigned int parm_filter = FLAG_BASIC;
772 int mode = 0;
774 d_printf("<H2>%s</H2>\n", _("Global Variables"));
776 if (cgi_variable("Commit")) {
777 commit_parameters(GLOBALS_SNUM);
778 save_reload(0);
781 if ( cgi_variable("ViewMode") )
782 mode = atoi(cgi_variable("ViewMode"));
784 d_printf("<form name=\"swatform\" method=post action=globals>\n");
786 ViewModeBoxes( mode );
787 switch ( mode ) {
788 case 0:
789 parm_filter = FLAG_BASIC;
790 break;
791 case 1:
792 parm_filter = FLAG_ADVANCED;
793 break;
794 case 2:
795 parm_filter = FLAG_DEVELOPER;
796 break;
798 d_printf("<br>\n");
799 if (have_write_access) {
800 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
801 _("Commit Changes"));
804 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
805 _("Reset Values"));
807 d_printf("<p>\n");
808 d_printf("<table>\n");
809 show_parameters(GLOBALS_SNUM, 1, parm_filter, 0);
810 d_printf("</table>\n");
811 d_printf("</form>\n");
814 /****************************************************************************
815 display a shares editing page. share is in unix codepage, and must be in
816 dos codepage. FIXME !!! JRA.
817 ****************************************************************************/
818 static void shares_page(void)
820 char *share = cgi_variable("share");
821 char *s;
822 int snum = -1;
823 int i;
824 int mode = 0;
825 unsigned int parm_filter = FLAG_BASIC;
827 if (share)
828 snum = lp_servicenumber(share);
830 d_printf("<H2>%s</H2>\n", _("Share Parameters"));
832 if (cgi_variable("Commit") && snum >= 0) {
833 commit_parameters(snum);
834 save_reload(0);
837 if (cgi_variable("Delete") && snum >= 0) {
838 lp_remove_service(snum);
839 save_reload(0);
840 share = NULL;
841 snum = -1;
844 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
845 load_config(False);
846 lp_copy_service(GLOBALS_SNUM, share);
847 iNumNonAutoPrintServices = lp_numservices();
848 save_reload(0);
849 snum = lp_servicenumber(share);
852 d_printf("<FORM name=\"swatform\" method=post>\n");
854 d_printf("<table>\n");
855 if ( cgi_variable("ViewMode") )
856 mode = atoi(cgi_variable("ViewMode"));
857 ViewModeBoxes( mode );
858 switch ( mode ) {
859 case 0:
860 parm_filter = FLAG_BASIC;
861 break;
862 case 1:
863 parm_filter = FLAG_ADVANCED;
864 break;
865 case 2:
866 parm_filter = FLAG_DEVELOPER;
867 break;
869 d_printf("<br><tr>\n");
870 d_printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
871 d_printf("<td><select name=share>\n");
872 if (snum < 0)
873 d_printf("<option value=\" \"> \n");
874 for (i=0;i<lp_numservices();i++) {
875 s = lp_servicename(i);
876 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
877 d_printf("<option %s value=\"%s\">%s\n",
878 (share && strcmp(share,s)==0)?"SELECTED":"",
879 s, s);
882 d_printf("</select></td>\n");
883 if (have_write_access) {
884 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
886 d_printf("</tr>\n");
887 d_printf("</table>");
888 d_printf("<table>");
889 if (have_write_access) {
890 d_printf("<tr>\n");
891 d_printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
892 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
894 d_printf("</table>");
897 if (snum >= 0) {
898 if (have_write_access) {
899 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
902 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
903 d_printf("<p>\n");
906 if (snum >= 0) {
907 d_printf("<table>\n");
908 show_parameters(snum, 1, parm_filter, 0);
909 d_printf("</table>\n");
912 d_printf("</FORM>\n");
915 /*************************************************************
916 change a password either locally or remotely
917 *************************************************************/
918 static BOOL change_password(const char *remote_machine, char *user_name,
919 char *old_passwd, char *new_passwd,
920 int local_flags)
922 BOOL ret = False;
923 pstring err_str;
924 pstring msg_str;
926 if (demo_mode) {
927 d_printf("%s<p>", _("password change in demo mode rejected\n"));
928 return False;
931 if (remote_machine != NULL) {
932 ret = remote_password_change(remote_machine, user_name, old_passwd,
933 new_passwd, err_str, sizeof(err_str));
934 if(*err_str)
935 d_printf("%s\n<p>", err_str);
936 return ret;
939 if(!initialize_password_db(True)) {
940 d_printf("Can't setup password database vectors.\n<p>");
941 return False;
944 ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
945 msg_str, sizeof(msg_str));
947 if(*msg_str)
948 d_printf("%s\n<p>", msg_str);
949 if(*err_str)
950 d_printf("%s\n<p>", err_str);
952 return ret;
955 /****************************************************************************
956 do the stuff required to add or change a password
957 ****************************************************************************/
958 static void chg_passwd(void)
960 char *host;
961 BOOL rslt;
962 int local_flags = 0;
964 /* Make sure users name has been specified */
965 if (strlen(cgi_variable(SWAT_USER)) == 0) {
966 d_printf("<p>%s", _(" Must specify \"User Name\" \n"));
967 return;
971 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
972 * so if that's what we're doing, skip the rest of the checks
974 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
977 * If current user is not root, make sure old password has been specified
978 * If REMOTE change, even root must provide old password
980 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
981 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
982 d_printf("<p>%s", _(" Must specify \"Old Password\" \n"));
983 return;
986 /* If changing a users password on a remote hosts we have to know what host */
987 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
988 d_printf("<p>%s", _(" Must specify \"Remote Machine\" \n"));
989 return;
992 /* Make sure new passwords have been specified */
993 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
994 (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
995 d_printf("<p>%s", _(" Must specify \"New, and Re-typed Passwords\" \n"));
996 return;
999 /* Make sure new passwords was typed correctly twice */
1000 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
1001 d_printf("<p>%s", _(" Re-typed password didn't match new password\n"));
1002 return;
1006 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1007 host = cgi_variable(RHOST);
1008 } else if (am_root()) {
1009 host = NULL;
1010 } else {
1011 host = "127.0.0.1";
1015 * Set up the local flags.
1018 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1019 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1020 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1021 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1023 rslt = change_password(host,
1024 cgi_variable(SWAT_USER),
1025 cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
1026 local_flags);
1028 if(local_flags == 0) {
1029 d_printf("<p>");
1030 if (rslt == True) {
1031 d_printf(_(" The passwd for '%s' has been changed. \n"), cgi_variable(SWAT_USER));
1032 } else {
1033 d_printf(_(" The passwd for '%s' has NOT been changed. \n"), cgi_variable(SWAT_USER));
1037 return;
1040 /****************************************************************************
1041 display a password editing page
1042 ****************************************************************************/
1043 static void passwd_page(void)
1045 char *new_name = cgi_user_name();
1048 * After the first time through here be nice. If the user
1049 * changed the User box text to another users name, remember it.
1051 if (cgi_variable(SWAT_USER)) {
1052 new_name = cgi_variable(SWAT_USER);
1055 if (!new_name) new_name = "";
1057 d_printf("<H2>%s</H2>\n", _("Server Password Management"));
1059 d_printf("<FORM name=\"swatform\" method=post>\n");
1061 d_printf("<table>\n");
1064 * Create all the dialog boxes for data collection
1066 d_printf("<tr><td>%s</td>\n", _(" User Name : "));
1067 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1068 if (!am_root()) {
1069 d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
1070 d_printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1072 d_printf("<tr><td>%s</td>\n", _(" New Password : "));
1073 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1074 d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
1075 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1076 d_printf("</table>\n");
1079 * Create all the control buttons for requesting action
1081 d_printf("<input type=submit name=%s value=\"%s\">\n",
1082 CHG_S_PASSWD_FLAG, _("Change Password"));
1083 if (demo_mode || am_root()) {
1084 d_printf("<input type=submit name=%s value=\"%s\">\n",
1085 ADD_USER_FLAG, _("Add New User"));
1086 d_printf("<input type=submit name=%s value=\"%s\">\n",
1087 DELETE_USER_FLAG, _("Delete User"));
1088 d_printf("<input type=submit name=%s value=\"%s\">\n",
1089 DISABLE_USER_FLAG, _("Disable User"));
1090 d_printf("<input type=submit name=%s value=\"%s\">\n",
1091 ENABLE_USER_FLAG, _("Enable User"));
1093 d_printf("<p></FORM>\n");
1096 * Do some work if change, add, disable or enable was
1097 * requested. It could be this is the first time through this
1098 * code, so there isn't anything to do. */
1099 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1100 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1101 chg_passwd();
1104 d_printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1106 d_printf("<FORM name=\"swatform\" method=post>\n");
1108 d_printf("<table>\n");
1111 * Create all the dialog boxes for data collection
1113 d_printf("<tr><td>%s</td>\n", _(" User Name : "));
1114 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1115 d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
1116 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1117 d_printf("<tr><td>%s</td>\n", _(" New Password : "));
1118 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1119 d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
1120 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1121 d_printf("<tr><td>%s</td>\n", _(" Remote Machine : "));
1122 d_printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1124 d_printf("</table>");
1127 * Create all the control buttons for requesting action
1129 d_printf("<input type=submit name=%s value=\"%s\">",
1130 CHG_R_PASSWD_FLAG, _("Change Password"));
1132 d_printf("<p></FORM>\n");
1135 * Do some work if a request has been made to change the
1136 * password somewhere other than the server. It could be this
1137 * is the first time through this code, so there isn't
1138 * anything to do. */
1139 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1140 chg_passwd();
1145 /****************************************************************************
1146 display a printers editing page
1147 ****************************************************************************/
1148 static void printers_page(void)
1150 char *share = cgi_variable("share");
1151 char *s;
1152 int snum=-1;
1153 int i;
1154 int mode = 0;
1155 unsigned int parm_filter = FLAG_BASIC;
1157 if (share)
1158 snum = lp_servicenumber(share);
1160 d_printf("<H2>%s</H2>\n", _("Printer Parameters"));
1162 d_printf("<H3>%s</H3>\n", _("Important Note:"));
1163 d_printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1164 d_printf(_("are autoloaded printers from "));
1165 d_printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1166 d_printf(_("Attempting to delete these printers from SWAT will have no effect.\n"));
1168 if (cgi_variable("Commit") && snum >= 0) {
1169 commit_parameters(snum);
1170 if (snum >= iNumNonAutoPrintServices)
1171 save_reload(snum);
1172 else
1173 save_reload(0);
1176 if (cgi_variable("Delete") && snum >= 0) {
1177 lp_remove_service(snum);
1178 save_reload(0);
1179 share = NULL;
1180 snum = -1;
1183 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1184 load_config(False);
1185 lp_copy_service(GLOBALS_SNUM, share);
1186 iNumNonAutoPrintServices = lp_numservices();
1187 snum = lp_servicenumber(share);
1188 lp_do_parameter(snum, "print ok", "Yes");
1189 save_reload(0);
1190 snum = lp_servicenumber(share);
1193 d_printf("<FORM name=\"swatform\" method=post>\n");
1195 if ( cgi_variable("ViewMode") )
1196 mode = atoi(cgi_variable("ViewMode"));
1197 ViewModeBoxes( mode );
1198 switch ( mode ) {
1199 case 0:
1200 parm_filter = FLAG_BASIC;
1201 break;
1202 case 1:
1203 parm_filter = FLAG_ADVANCED;
1204 break;
1205 case 2:
1206 parm_filter = FLAG_DEVELOPER;
1207 break;
1209 d_printf("<table>\n");
1210 d_printf("<tr><td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Printer"));
1211 d_printf("<td><select name=share>\n");
1212 if (snum < 0 || !lp_print_ok(snum))
1213 d_printf("<option value=\" \"> \n");
1214 for (i=0;i<lp_numservices();i++) {
1215 s = lp_servicename(i);
1216 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1217 if (i >= iNumNonAutoPrintServices)
1218 d_printf("<option %s value=\"%s\">[*]%s\n",
1219 (share && strcmp(share,s)==0)?"SELECTED":"",
1220 s, s);
1221 else
1222 d_printf("<option %s value=\"%s\">%s\n",
1223 (share && strcmp(share,s)==0)?"SELECTED":"",
1224 s, s);
1227 d_printf("</select></td>");
1228 if (have_write_access) {
1229 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1231 d_printf("</tr>");
1232 d_printf("</table>\n");
1234 if (have_write_access) {
1235 d_printf("<table>\n");
1236 d_printf("<tr><td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Printer"));
1237 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1238 d_printf("</table>");
1242 if (snum >= 0) {
1243 if (have_write_access) {
1244 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1246 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1247 d_printf("<p>\n");
1250 if (snum >= 0) {
1251 d_printf("<table>\n");
1252 show_parameters(snum, 1, parm_filter, 1);
1253 d_printf("</table>\n");
1255 d_printf("</FORM>\n");
1260 * main function for SWAT.
1262 int main(int argc, char *argv[])
1264 extern char *optarg;
1265 extern int optind;
1266 int opt;
1267 char *page;
1269 fault_setup(NULL);
1270 umask(S_IWGRP | S_IWOTH);
1272 #if defined(HAVE_SET_AUTH_PARAMETERS)
1273 set_auth_parameters(argc, argv);
1274 #endif /* HAVE_SET_AUTH_PARAMETERS */
1276 /* just in case it goes wild ... */
1277 alarm(300);
1279 setlinebuf(stdout);
1281 /* we don't want any SIGPIPE messages */
1282 BlockSignals(True,SIGPIPE);
1284 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1285 if (!dbf) dbf = x_stderr;
1287 /* we don't want stderr screwing us up */
1288 close(2);
1289 open("/dev/null", O_WRONLY);
1291 while ((opt = getopt(argc, argv,"s:a")) != EOF) {
1292 switch (opt) {
1293 case 's':
1294 pstrcpy(dyn_CONFIGFILE,optarg);
1295 break;
1296 case 'a':
1297 demo_mode = True;
1298 break;
1302 setup_logging(argv[0],False);
1303 load_config(True);
1304 iNumNonAutoPrintServices = lp_numservices();
1305 load_printers();
1307 cgi_setup(dyn_SWATDIR, !demo_mode);
1309 print_header();
1311 cgi_load_variables();
1313 if (!file_exist(dyn_CONFIGFILE, NULL)) {
1314 have_read_access = True;
1315 have_write_access = True;
1316 } else {
1317 /* check if the authenticated user has write access - if not then
1318 don't show write options */
1319 have_write_access = (access(dyn_CONFIGFILE,W_OK) == 0);
1321 /* if the user doesn't have read access to smb.conf then
1322 don't let them view it */
1323 have_read_access = (access(dyn_CONFIGFILE,R_OK) == 0);
1326 show_main_buttons();
1328 page = cgi_pathinfo();
1330 /* Root gets full functionality */
1331 if (have_read_access && strcmp(page, "globals")==0) {
1332 globals_page();
1333 } else if (have_read_access && strcmp(page,"shares")==0) {
1334 shares_page();
1335 } else if (have_read_access && strcmp(page,"printers")==0) {
1336 printers_page();
1337 } else if (have_read_access && strcmp(page,"status")==0) {
1338 status_page();
1339 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1340 viewconfig_page();
1341 } else if (strcmp(page,"passwd")==0) {
1342 passwd_page();
1343 } else if (have_read_access && strcmp(page,"wizard")==0) {
1344 wizard_page();
1345 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1346 wizard_params_page();
1347 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1348 rewritecfg_file();
1349 } else {
1350 welcome_page();
1353 print_footer();
1354 return 0;
1357 /** @} **/