if we are adding a new sambaAccount, make sure that we add a
[Samba.git] / source / web / swat.c
blobc5c211672edc16fe8fec84f93f5318320855e8e5
1 /*
2 Unix SMB/Netbios implementation.
3 Version 2.2.6
4 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.
23 #ifdef SYSLOG
24 #undef SYSLOG
25 #endif
27 #include "includes.h"
28 #include "smb.h"
30 #define GLOBALS_SNUM -1
32 static pstring servicesf = CONFIGFILE;
33 static BOOL demo_mode = False;
34 static BOOL have_write_access = False;
35 static BOOL have_read_access = False;
36 static int iNumNonAutoPrintServices = 0;
39 * Password Management Globals
41 #define SWAT_USER "username"
42 #define OLD_PSWD "old_passwd"
43 #define NEW_PSWD "new_passwd"
44 #define NEW2_PSWD "new2_passwd"
45 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
46 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
47 #define ADD_USER_FLAG "add_user_flag"
48 #define DELETE_USER_FLAG "delete_user_flag"
49 #define DISABLE_USER_FLAG "disable_user_flag"
50 #define ENABLE_USER_FLAG "enable_user_flag"
51 #define RHOST "remote_host"
53 typedef struct html_conversion {
54 char src;
55 char *dest;
56 } html_conversion;
58 static const html_conversion entities[] = {
59 { '"', """ },
60 { '&', "&" },
61 { '<', "&lt;" },
62 { '>', "&gt;" },
63 { '\0', NULL },
66 /* we need these because we link to locking*.o */
67 void become_root(void) {}
68 void unbecome_root(void) {}
70 /****************************************************************************
71 ****************************************************************************/
72 static int enum_index(int value, struct enum_list *enumlist)
74 int i;
75 for (i=0;enumlist[i].name;i++)
76 if (value == enumlist[i].value) break;
77 return(i);
80 static char *fix_backslash(char *str)
82 static char newstring[1024];
83 char *p = newstring;
85 while (*str) {
86 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
87 else *p++ = *str;
88 ++str;
90 *p = '\0';
91 return newstring;
94 static char *htmlentities(char *str)
96 int i,j, destlen = 0;
97 int length = strlen(str);
98 /* Feel free to use a pstring if appropriate -- I haven't
99 checked if it's guaranteed to be long enough, and suspect it
100 isn't. -SRL */
101 char *dststr = NULL;
102 char *p;
104 for (i = 0; i < length; i++) {
105 for (j = 0; entities[j].src; j++) {
106 if (str[i] == entities[j].src) {
107 destlen += strlen(entities[j].dest);
108 break;
111 if (!entities[j].src) {
112 destlen++;
115 if (length == destlen) {
116 return(strdup(str));
118 p = dststr = malloc(destlen + 1);
119 if (!dststr) {
120 return(NULL);
122 dststr[destlen] = '\0';
123 for (i = 0; i < length; i++) {
124 for (j = 0; entities[j].src; j++) {
125 if (str[i] == entities[j].src) {
126 strncpy(p, entities[j].dest,
127 strlen(entities[j].dest));
128 p += strlen(entities[j].dest);
129 break;
132 if (!entities[j].src) {
133 *p++ = str[i];
136 return(dststr);
139 static char *stripspace(char *str)
141 static char newstring[1024];
142 char *p = newstring;
144 while (*str) {
145 if (*str != ' ') *p++ = *str;
146 ++str;
148 *p = '\0';
149 return newstring;
152 static char *make_parm_name(char *label)
154 static char parmname[1024];
155 char *p = parmname;
157 while (*label) {
158 if (*label == ' ') *p++ = '_';
159 else *p++ = *label;
160 ++label;
162 *p = '\0';
163 return parmname;
166 /****************************************************************************
167 include a lump of html in a page
168 ****************************************************************************/
169 static int include_html(char *fname)
171 FILE *f = sys_fopen(fname,"r");
172 char buf[1024];
173 int ret;
175 if (!f) {
176 printf("ERROR: Can't open %s\n", fname);
177 return 0;
180 while (!feof(f)) {
181 ret = fread(buf, 1, sizeof(buf), f);
182 if (ret <= 0) break;
183 fwrite(buf, 1, ret, stdout);
186 fclose(f);
187 return 1;
190 /****************************************************************************
191 start the page with standard stuff
192 ****************************************************************************/
193 static void print_header(void)
195 if (!cgi_waspost()) {
196 printf("Expires: 0\r\n");
198 printf("Content-type: text/html\r\n\r\n");
200 if (!include_html("include/header.html")) {
201 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
202 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
206 /****************************************************************************
207 finish off the page
208 ****************************************************************************/
209 static void print_footer(void)
211 if (!include_html("include/footer.html")) {
212 printf("\n</BODY>\n</HTML>\n");
216 /****************************************************************************
217 display one editable parameter in a form
218 ****************************************************************************/
219 static void show_parameter(int snum, struct parm_struct *parm)
221 int i;
222 void *ptr = parm->ptr;
223 char* str;
225 if (parm->class == P_LOCAL && snum >= 0) {
226 ptr = lp_local_ptr(snum, ptr);
229 str = stripspace(parm->label);
230 strupper (str);
231 printf("<tr><td><A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\">Help</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s</td><td>",
232 str, parm->label);
234 switch (parm->type) {
235 case P_CHAR:
236 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
237 make_parm_name(parm->label), *(char *)ptr);
238 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
239 make_parm_name(parm->label),(char)(parm->def.cvalue));
240 break;
242 case P_STRING:
243 case P_USTRING:
244 str = htmlentities(*(char **)ptr);
245 printf("<input type=\"text\" size=\"40\" name=\"parm_%s\" value=\"%s\">",
246 make_parm_name(parm->label), str);
247 if (str != NULL) {
248 free(str);
250 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
251 make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
252 break;
254 case P_GSTRING:
255 case P_UGSTRING:
256 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
257 make_parm_name(parm->label), (char *)ptr);
258 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
259 make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
260 break;
262 case P_BOOL:
263 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
264 printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
265 printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
266 printf("</select>");
267 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
268 make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?0:1);
269 break;
271 case P_BOOLREV:
272 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
273 printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
274 printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
275 printf("</select>");
276 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
277 make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?1:0);
278 break;
280 case P_INTEGER:
281 if (strequal(parm->label,"log level")) {
282 printf("<input type=text size=40 name=\"parm_%s\" value=%d",
283 make_parm_name(parm->label),*(int *)ptr);
284 for (i = 1; i < DBGC_LAST; i ++) {
285 if (((int *)ptr)[i])
286 printf(",%s:%d",debug_classname_from_index(i),((int *)ptr)[i]);
288 printf(">");
289 } else {
290 printf("<input type=text size=8 name=\"parm_%s\" value=%d>",
291 make_parm_name(parm->label), *(int *)ptr);
293 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
294 make_parm_name(parm->label),(int)(parm->def.ivalue));
295 break;
297 case P_OCTAL:
298 printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
299 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
300 make_parm_name(parm->label),
301 octal_string((int)(parm->def.ivalue)));
302 break;
304 case P_ENUM:
305 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
306 for (i=0;parm->enum_list[i].name;i++) {
307 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
308 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
311 printf("</select>");
312 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
313 make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
314 break;
315 case P_SEP:
316 break;
318 printf("</td></tr>\n");
321 /****************************************************************************
322 display a set of parameters for a service
323 ****************************************************************************/
324 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
326 int i = 0;
327 struct parm_struct *parm;
328 char *heading = NULL;
329 char *last_heading = NULL;
331 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
332 if (snum < 0 && parm->class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
333 continue;
334 if (parm->class == P_SEPARATOR) {
335 heading = parm->label;
336 continue;
338 if (parm->flags & FLAG_HIDE) continue;
339 if (snum >= 0) {
340 if (printers & !(parm->flags & FLAG_PRINT)) continue;
341 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
343 if (parm_filter == FLAG_BASIC) {
344 if (!(parm->flags & FLAG_BASIC)) {
345 void *ptr = parm->ptr;
347 if (parm->class == P_LOCAL && snum >= 0) {
348 ptr = lp_local_ptr(snum, ptr);
351 switch (parm->type) {
352 case P_CHAR:
353 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
354 break;
356 case P_STRING:
357 case P_USTRING:
358 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
359 break;
361 case P_GSTRING:
362 case P_UGSTRING:
363 if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
364 break;
366 case P_BOOL:
367 case P_BOOLREV:
368 if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
369 break;
371 case P_INTEGER:
372 case P_OCTAL:
373 if (strequal(parm->label,"log level"))
374 break;
375 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
376 break;
379 case P_ENUM:
380 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
381 break;
382 case P_SEP:
383 continue;
386 if (printers && !(parm->flags & FLAG_PRINT)) continue;
388 if (parm_filter == FLAG_WIZARD) {
389 if (!((parm->flags & FLAG_WIZARD))) 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(servicesf,False,save_def,False);
408 /****************************************************************************
409 write a config file
410 ****************************************************************************/
412 static void write_config(FILE *f, BOOL show_defaults, char *(*dos_to_ext)(const char *))
414 fprintf(f, "# Samba config file created using SWAT\n");
415 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
416 fprintf(f, "# Date: %s\n\n", timestring(False));
418 lp_dump(f, show_defaults, iNumNonAutoPrintServices, dos_to_ext);
421 /****************************************************************************
422 save and reload the smb.conf config file
423 ****************************************************************************/
424 static int save_reload(int snum)
426 FILE *f;
427 struct stat st;
429 f = sys_fopen(servicesf,"w");
430 if (!f) {
431 printf("failed to open %s for writing\n", servicesf);
432 return 0;
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 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
441 write_config(f, False, _dos_to_unix_static);
442 if (snum)
443 lp_dump_one(f, False, snum, _dos_to_unix_static);
444 fclose(f);
446 lp_killunused(NULL);
448 if (!load_config(False)) {
449 printf("Can't reload %s\n", servicesf);
450 return 0;
452 iNumNonAutoPrintServices = lp_numservices();
453 load_printers();
455 return 1;
458 /****************************************************************************
459 commit one parameter
460 ****************************************************************************/
461 static void commit_parameter(int snum, struct parm_struct *parm, char *v)
463 int i;
464 char *s;
466 /* lp_do_parameter() will do unix_to_dos(v). */
467 if(parm->flags & FLAG_DOS_STRING)
468 dos_to_unix(v);
470 if (snum < 0 && parm->class == P_LOCAL) {
471 /* this handles the case where we are changing a local
472 variable globally. We need to change the parameter in
473 all shares where it is currently set to the default */
474 for (i=0;i<lp_numservices();i++) {
475 s = lp_servicename(i);
476 if (s && (*s) && lp_is_default(i, parm)) {
477 lp_do_parameter(i, parm->label, v);
482 lp_do_parameter(snum, parm->label, v);
485 /****************************************************************************
486 commit a set of parameters for a service
487 ****************************************************************************/
488 static void commit_parameters(int snum)
490 int i = 0;
491 struct parm_struct *parm;
492 pstring label;
493 char *v;
495 while ((parm = lp_next_parameter(snum, &i, 1))) {
496 slprintf(label, sizeof(label)-1, "parm_%s", make_parm_name(parm->label));
497 if ((v = cgi_variable(label))) {
498 if (parm->flags & FLAG_HIDE) continue;
499 commit_parameter(snum, parm, v);
504 /****************************************************************************
505 spit out the html for a link with an image
506 ****************************************************************************/
507 static void image_link(char *name,char *hlink, char *src)
509 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
510 cgi_baseurl(), hlink, src, name);
513 /****************************************************************************
514 display the main navigation controls at the top of each page along
515 with a title
516 ****************************************************************************/
517 static void show_main_buttons(void)
519 char *p;
521 if ((p = cgi_user_name()) && strcmp(p, "root")) {
522 printf("Logged in as <b>%s</b><p>\n", p);
525 image_link("Home", "", "images/home.gif");
526 if (have_write_access) {
527 image_link("Globals", "globals", "images/globals.gif");
528 image_link("Shares", "shares", "images/shares.gif");
529 image_link("Printers", "printers", "images/printers.gif");
530 image_link("Wizard", "wizard", "images/wizard.gif");
532 if (have_read_access) {
533 image_link("Status", "status", "images/status.gif");
534 image_link("View Config", "viewconfig","images/viewconfig.gif");
536 image_link("Password Management", "passwd", "images/passwd.gif");
538 printf("<HR>\n");
541 /****************************************************************************
542 display a welcome page
543 ****************************************************************************/
544 static void welcome_page(void)
546 include_html("help/welcome.html");
549 /****************************************************************************
550 display the current smb.conf
551 ****************************************************************************/
552 static void viewconfig_page(void)
554 int full_view=0;
556 if (cgi_variable("full_view")) {
557 full_view = 1;
560 printf("<H2>Current Config</H2>\n");
561 printf("<form method=post>\n");
563 if (full_view) {
564 printf("<input type=submit name=\"normal_view\" value=\"Normal View\">\n");
565 } else {
566 printf("<input type=submit name=\"full_view\" value=\"Full View\">\n");
569 printf("<p><pre>");
570 write_config(stdout, full_view, _dos_to_dos_static);
571 printf("</pre>");
572 printf("</form>\n");
575 /****************************************************************************
576 second screen of the wizard ... Fetch Configuration Parameters
577 ****************************************************************************/
578 static void wizard_params_page(void)
580 unsigned int parm_filter = FLAG_WIZARD;
582 /* Here we first set and commit all the parameters that were selected
583 in the previous screen. */
585 printf("<H2>Wizard Parameter Edit Page ...</H2>\n");
587 if (cgi_variable("Commit")) {
588 commit_parameters(GLOBALS_SNUM);
589 save_reload(0);
592 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
594 if (have_write_access) {
595 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
598 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
599 printf("<p>\n");
601 printf("<table>\n");
602 show_parameters(GLOBALS_SNUM, 1, parm_filter, 0);
603 printf("</table>\n");
604 printf("</form>\n");
607 /****************************************************************************
608 Utility to just rewrite the smb.conf file - effectively just cleans it up
609 ****************************************************************************/
610 static void rewritecfg_file(void)
612 commit_parameters(GLOBALS_SNUM);
613 save_reload(0);
614 printf("<H2>Note: smb.conf file has been read and rewritten</H2>\n");
617 /****************************************************************************
618 wizard to create/modify the smb.conf file
619 ****************************************************************************/
620 static void wizard_page(void)
622 /* Set some variables to collect data from smb.conf */
623 int role = 0;
624 int winstype = 0;
625 int have_home = -1;
626 int HomeExpo = 0;
627 int SerType = 0;
629 if (cgi_variable("Rewrite")) {
630 (void) rewritecfg_file();
631 return;
634 if (cgi_variable("GetWizardParams")){
635 (void) wizard_params_page();
636 return;
639 if (cgi_variable("Commit")){
640 SerType = atoi(cgi_variable("ServerType"));
641 winstype = atoi(cgi_variable("WINSType"));
642 have_home = lp_servicenumber(HOMES_NAME);
643 HomeExpo = atoi(cgi_variable("HomeExpo"));
645 /* Plain text passwords are too badly broken - use encrypted passwords only */
646 lp_do_parameter( GLOBALS_SNUM, "encrypt passwords", "Yes");
648 switch ( SerType ){
649 case 0:
650 /* Stand-alone Server */
651 lp_do_parameter( GLOBALS_SNUM, "security", "USER" );
652 lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" );
653 break;
654 case 1:
655 /* Domain Member */
656 lp_do_parameter( GLOBALS_SNUM, "security", "DOMAIN" );
657 lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" );
658 break;
659 case 2:
660 /* Domain Controller */
661 lp_do_parameter( GLOBALS_SNUM, "security", "USER" );
662 lp_do_parameter( GLOBALS_SNUM, "domain logons", "Yes" );
663 break;
665 switch ( winstype ) {
666 case 0:
667 lp_do_parameter( GLOBALS_SNUM, "wins support", "No" );
668 lp_do_parameter( GLOBALS_SNUM, "wins server", "" );
669 break;
670 case 1:
671 lp_do_parameter( GLOBALS_SNUM, "wins support", "Yes" );
672 lp_do_parameter( GLOBALS_SNUM, "wins server", "" );
673 break;
674 case 2:
675 lp_do_parameter( GLOBALS_SNUM, "wins support", "No" );
676 lp_do_parameter( GLOBALS_SNUM, "wins server", cgi_variable("WINSAddr"));
677 break;
680 /* Have to create Homes share? */
681 if ((HomeExpo == 1) && (have_home == -1)) {
682 pstring unix_share;
684 pstrcpy(unix_share, dos_to_unix_static(HOMES_NAME));
685 load_config(False);
686 lp_copy_service(GLOBALS_SNUM, unix_share);
687 iNumNonAutoPrintServices = lp_numservices();
688 have_home = lp_servicenumber(HOMES_NAME);
689 lp_do_parameter( have_home, "read only", "No");
690 lp_do_parameter( have_home, "valid users", "%S");
691 lp_do_parameter( have_home, "browseable", "No");
692 commit_parameters(have_home);
695 /* Need to Delete Homes share? */
696 if ((HomeExpo == 0) && (have_home != -1)) {
697 lp_remove_service(have_home);
698 have_home = -1;
701 commit_parameters(GLOBALS_SNUM);
702 save_reload(0);
704 else
706 /* Now determine smb.conf WINS settings */
707 if (lp_wins_support())
708 winstype = 1;
709 if (strlen(lp_wins_server()) != 0 )
710 winstype = 2;
712 /* Do we have a homes share? */
713 have_home = lp_servicenumber(HOMES_NAME);
715 if ((winstype == 2) && lp_wins_support())
716 winstype = 3;
718 role = lp_server_role();
720 /* Here we go ... */
721 printf("<H2>Samba Configuration Wizard</H2>\n");
722 printf("<form method=post action=wizard>\n");
724 if (have_write_access) {
725 printf("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments.\n");
726 printf("The same will happen if you press the commit button.");
727 printf("<br><br>");
728 printf("<center>");
729 printf("<input type=submit name=\"Rewrite\" value=\"Rewrite smb.conf file\"> &nbsp;&nbsp;");
730 printf("<input type=submit name=\"Commit\" value=\"Commit\"> &nbsp;&nbsp;");
731 printf("<input type=submit name=\"GetWizardParams\" value=\"Edit Parameter Values\">");
732 printf("</center>");
735 printf("<hr>");
736 printf("<center><table border=0>");
737 printf("<tr><td><b>%s</b></td>\n", "Server Type:&nbsp;");
738 printf("<td><input type=radio name=\"ServerType\" value=0 %s> Stand Alone&nbsp;</td>", (role == ROLE_STANDALONE) ? "checked" : "");
739 printf("<td><input type=radio name=\"ServerType\" value=1 %s> Domain Member&nbsp;</td>", (role == ROLE_DOMAIN_MEMBER) ? "checked" : "");
740 printf("<td><input type=radio name=\"ServerType\" value=2 %s> Domain Controller&nbsp;</td>", (role == ROLE_DOMAIN_PDC) ? "checked" : "");
741 printf("</tr>");
742 if (role == ROLE_DOMAIN_BDC) {
743 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Unusual Type in smb.conf - Please Select New Mode</font></td></tr>");
745 printf("<tr><td><b>%s</b></td>\n", "Configure WINS As:&nbsp;");
746 printf("<td><input type=radio name=\"WINSType\" value=0 %s> Not Used&nbsp;</td>", (winstype == 0) ? "checked" : "");
747 printf("<td><input type=radio name=\"WINSType\" value=1 %s> Server for client use&nbsp;</td>", (winstype == 1) ? "checked" : "");
748 printf("<td><input type=radio name=\"WINSType\" value=2 %s> Client of another WINS server&nbsp;</td>", (winstype == 2) ? "checked" : "");
749 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());
750 if (winstype == 3) {
751 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>");
752 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Please Select desired WINS mode above.</font></td></tr>");
754 printf("</tr>");
755 printf("<tr><td><b>%s</b></td>\n","Expose Home Directories:&nbsp;");
756 printf("<td><input type=radio name=\"HomeExpo\" value=1 %s> Yes</td>", (have_home == -1) ? "" : "checked ");
757 printf("<td><input type=radio name=\"HomeExpo\" value=0 %s> No</td>", (have_home == -1 ) ? "checked" : "");
758 printf("<td></td></tr>");
760 /* Enable this when we are ready ....
761 * printf("<tr><td><b>%s</b></td>\n","Is Print Server:&nbsp;");
762 * printf("<td><input type=radio name=\"PtrSvr\" value=1 %s> Yes</td>");
763 * printf("<td><input type=radio name=\"PtrSvr\" value=0 %s> No</td>");
764 * printf("<td></td></tr>");
767 printf("</table></center>");
768 printf("<hr>");
770 printf("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment.\n");
771 printf("</form>\n");
774 /****************************************************************************
775 display a globals editing page
776 ****************************************************************************/
777 static void globals_page(void)
779 unsigned int parm_filter = FLAG_BASIC;
781 printf("<H2>Global Variables</H2>\n");
783 if (cgi_variable("Advanced") && !cgi_variable("Basic"))
784 parm_filter = FLAG_ADVANCED;
786 if (cgi_variable("Commit")) {
787 commit_parameters(GLOBALS_SNUM);
788 save_reload(0);
791 printf("<FORM name=\"swatform\" method=post>\n");
793 if (have_write_access) {
794 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
797 printf("<input type=reset name=\"Reset Values\" value=\"Reset Values\">\n");
798 if (parm_filter != FLAG_ADVANCED) {
799 printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
800 } else {
801 printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
803 printf("<p>\n");
805 printf("<table>\n");
806 show_parameters(GLOBALS_SNUM, 1, parm_filter, 0);
807 printf("</table>\n");
809 if (parm_filter == FLAG_ADVANCED) {
810 printf("<input type=hidden name=\"Advanced\" value=1>\n");
813 printf("</FORM>\n");
816 /****************************************************************************
817 display a shares editing page. share is in unix codepage, and must be in
818 dos codepage. FIXME !!! JRA.
819 ****************************************************************************/
820 static void shares_page(void)
822 char *share = cgi_variable("share");
823 char *s;
824 int snum=-1;
825 int i;
826 unsigned int parm_filter = FLAG_BASIC;
828 if (share)
829 snum = lp_servicenumber(share);
831 printf("<H2>Share Parameters</H2>\n");
833 if (cgi_variable("Advanced") && !cgi_variable("Basic"))
834 parm_filter = FLAG_ADVANCED;
836 if (cgi_variable("Commit") && snum >= 0) {
837 commit_parameters(snum);
838 save_reload(0);
841 if (cgi_variable("Delete") && snum >= 0) {
842 lp_remove_service(snum);
843 save_reload(0);
844 share = NULL;
845 snum = -1;
848 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
849 /* add_a_service() which is called by lp_copy_service()
850 will do unix_to_dos() conversion, so we need dos_to_unix() before the lp_copy_service(). */
851 pstring unix_share;
852 pstrcpy(unix_share, dos_to_unix_static(share));
853 load_config(False);
854 lp_copy_service(GLOBALS_SNUM, unix_share);
855 iNumNonAutoPrintServices = lp_numservices();
856 save_reload(0);
857 snum = lp_servicenumber(share);
860 printf("<FORM name=\"swatform\" method=post>\n");
862 printf("<table>\n");
863 printf("<tr>\n");
864 printf("<td><input type=submit name=selectshare value=\"Choose Share\"></td>\n");
865 printf("<td><select name=share>\n");
866 if (snum < 0)
867 printf("<option value=\" \"> \n");
868 for (i=0;i<lp_numservices();i++) {
869 s = lp_servicename(i);
870 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
871 printf("<option %s value=\"%s\">%s\n",
872 (share && strcmp(share,s)==0)?"SELECTED":"",
873 s, s);
876 printf("</select></td>\n");
877 if (have_write_access) {
878 printf("<td><input type=submit name=\"Delete\" value=\"Delete Share\"></td>\n");
880 printf("</tr>\n");
881 printf("</table>");
882 printf("<table>");
883 if (have_write_access) {
884 printf("<tr>\n");
885 printf("<td><input type=submit name=createshare value=\"Create Share\"></td>\n");
886 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
888 printf("</table>");
891 if (snum >= 0) {
892 if (have_write_access) {
893 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
896 printf("<input type=reset name=\"Reset Values\" value=\"Reset Values\">\n");
897 if (parm_filter != FLAG_ADVANCED) {
898 printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
899 } else {
900 printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
902 printf("<p>\n");
905 if (snum >= 0) {
906 printf("<table>\n");
907 show_parameters(snum, 1, parm_filter, 0);
908 printf("</table>\n");
911 if (parm_filter == FLAG_ADVANCED) {
912 printf("<input type=hidden name=\"Advanced\" value=1>\n");
915 printf("</FORM>\n");
918 /*************************************************************
919 change a password either locally or remotely
920 *************************************************************/
921 static BOOL change_password(const char *remote_machine, char *user_name,
922 char *old_passwd, char *new_passwd,
923 int local_flags)
925 BOOL ret = False;
926 pstring err_str;
927 pstring msg_str;
929 if (demo_mode) {
930 printf("password change in demo mode rejected\n<p>");
931 return False;
934 if (remote_machine != NULL) {
935 ret = remote_password_change(remote_machine, user_name, old_passwd,
936 new_passwd, err_str, sizeof(err_str));
937 if(*err_str)
938 printf("%s\n<p>", err_str);
939 return ret;
942 if(!initialize_password_db(False)) {
943 printf("Can't setup password database vectors.\n<p>");
944 return False;
947 ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
948 msg_str, sizeof(msg_str));
950 if(*msg_str)
951 printf("%s\n<p>", msg_str);
952 if(*err_str)
953 printf("%s\n<p>", err_str);
955 return ret;
958 /****************************************************************************
959 do the stuff required to add or change a password
960 ****************************************************************************/
961 static void chg_passwd(void)
963 char *host;
964 BOOL rslt;
965 int local_flags = 0;
967 /* Make sure users name has been specified */
968 if (strlen(cgi_variable(SWAT_USER)) == 0) {
969 printf("<p> Must specify \"User Name\" \n");
970 return;
974 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
975 * so if that's what we're doing, skip the rest of the checks
977 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
980 * If current user is not root, make sure old password has been specified
981 * If REMOTE change, even root must provide old password
983 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
984 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
985 printf("<p> Must specify \"Old Password\" \n");
986 return;
989 /* If changing a users password on a remote hosts we have to know what host */
990 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
991 printf("<p> Must specify \"Remote Machine\" \n");
992 return;
995 /* Make sure new passwords have been specified */
996 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
997 (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
998 printf("<p> Must specify \"New, and Re-typed Passwords\" \n");
999 return;
1002 /* Make sure new passwords was typed correctly twice */
1003 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
1004 printf("<p> Re-typed password didn't match new password\n");
1005 return;
1009 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1010 host = cgi_variable(RHOST);
1011 } else if (am_root()) {
1012 host = NULL;
1013 } else {
1014 host = "127.0.0.1";
1018 * Set up the local flags.
1021 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1022 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1023 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1024 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1026 rslt = change_password(host,
1027 cgi_variable(SWAT_USER),
1028 cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
1029 local_flags);
1031 if(local_flags == 0) {
1032 if (rslt == True) {
1033 printf("<p> The passwd for '%s' has been changed. \n", cgi_variable(SWAT_USER));
1034 } else {
1035 printf("<p> The passwd for '%s' has NOT been changed. \n",cgi_variable(SWAT_USER));
1039 return;
1042 /****************************************************************************
1043 display a password editing page
1044 ****************************************************************************/
1045 static void passwd_page(void)
1047 char *new_name = cgi_user_name();
1050 * After the first time through here be nice. If the user
1051 * changed the User box text to another users name, remember it.
1053 if (cgi_variable(SWAT_USER)) {
1054 new_name = cgi_variable(SWAT_USER);
1057 if (!new_name) new_name = "";
1059 printf("<H2>Server Password Management</H2>\n");
1061 printf("<FORM name=\"swatform\" method=post>\n");
1063 printf("<table>\n");
1066 * Create all the dialog boxes for data collection
1068 printf("<tr><td> User Name : </td>\n");
1069 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1070 if (!am_root()) {
1071 printf("<tr><td> Old Password : </td>\n");
1072 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1074 printf("<tr><td> New Password : </td>\n");
1075 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1076 printf("<tr><td> Re-type New Password : </td>\n");
1077 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1078 printf("</table>\n");
1081 * Create all the control buttons for requesting action
1083 printf("<input type=submit name=%s value=\"Change Password\">\n",
1084 CHG_S_PASSWD_FLAG);
1085 if (demo_mode || am_root()) {
1086 printf("<input type=submit name=%s value=\"Add New User\">\n",
1087 ADD_USER_FLAG);
1088 printf("<input type=submit name=%s value=\"Delete User\">\n",
1089 DELETE_USER_FLAG);
1090 printf("<input type=submit name=%s value=\"Disable User\">\n",
1091 DISABLE_USER_FLAG);
1092 printf("<input type=submit name=%s value=\"Enable User\">\n",
1093 ENABLE_USER_FLAG);
1095 printf("<p></FORM>\n");
1098 * Do some work if change, add, disable or enable was
1099 * requested. It could be this is the first time through this
1100 * code, so there isn't anything to do. */
1101 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1102 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1103 chg_passwd();
1106 printf("<H2>Client/Server Password Management</H2>\n");
1108 printf("<FORM name=\"swatform\" method=post>\n");
1110 printf("<table>\n");
1113 * Create all the dialog boxes for data collection
1115 printf("<tr><td> User Name : </td>\n");
1116 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1117 printf("<tr><td> Old Password : </td>\n");
1118 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1119 printf("<tr><td> New Password : </td>\n");
1120 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1121 printf("<tr><td> Re-type New Password : </td>\n");
1122 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1123 printf("<tr><td> Remote Machine : </td>\n");
1124 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1126 printf("</table>");
1129 * Create all the control buttons for requesting action
1131 printf("<input type=submit name=%s value=\"Change Password\">",
1132 CHG_R_PASSWD_FLAG);
1134 printf("<p></FORM>\n");
1137 * Do some work if a request has been made to change the
1138 * password somewhere other than the server. It could be this
1139 * is the first time through this code, so there isn't
1140 * anything to do. */
1141 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1142 chg_passwd();
1147 /****************************************************************************
1148 display a printers editing page
1149 ****************************************************************************/
1150 static void printers_page(void)
1152 char *share = cgi_variable("share");
1153 char *s;
1154 int snum=-1;
1155 int i;
1156 unsigned int parm_filter = FLAG_BASIC;
1158 if (share)
1159 snum = lp_servicenumber(share);
1161 printf("<H2>Printer Parameters</H2>\n");
1163 printf("<H3>Important Note:</H3>\n");
1164 printf("Printer names marked with [*] in the Choose Printer drop-down box ");
1165 printf("are autoloaded printers from ");
1166 printf("<A HREF=\"/swat/help/smb.conf.5.html#PRINTCAPNAME\" target=\"docs\">Printcap Name</A>.\n");
1167 printf("Attempting to delete these printers from SWAT will have no effect.\n");
1169 if (cgi_variable("Advanced") && !cgi_variable("Basic"))
1170 parm_filter = FLAG_ADVANCED;
1172 if (cgi_variable("Commit") && snum >= 0) {
1173 commit_parameters(snum);
1174 if (snum >= iNumNonAutoPrintServices)
1175 save_reload(snum);
1176 else
1177 save_reload(0);
1180 if (cgi_variable("Delete") && snum >= 0) {
1181 lp_remove_service(snum);
1182 save_reload(0);
1183 share = NULL;
1184 snum = -1;
1187 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1188 /* add_a_service() which is called by lp_copy_service()
1189 will do unix_to_dos() conversion, so we need dos_to_unix() before the lp_copy_service(). */
1190 pstring unix_share;
1191 pstrcpy(unix_share, dos_to_unix_static(share));
1192 load_config(False);
1193 lp_copy_service(GLOBALS_SNUM, unix_share);
1194 iNumNonAutoPrintServices = lp_numservices();
1195 snum = lp_servicenumber(share);
1196 lp_do_parameter(snum, "print ok", "Yes");
1197 save_reload(0);
1198 snum = lp_servicenumber(share);
1201 printf("<FORM name=\"swatform\" method=post>\n");
1203 printf("<table>\n");
1204 printf("<tr><td><input type=submit name=selectshare value=\"Choose Printer\"></td>\n");
1205 printf("<td><select name=share>\n");
1206 if (snum < 0 || !lp_print_ok(snum))
1207 printf("<option value=\" \"> \n");
1208 for (i=0;i<lp_numservices();i++) {
1209 s = lp_servicename(i);
1210 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1211 if (i >= iNumNonAutoPrintServices)
1212 printf("<option %s value=\"%s\">[*]%s\n",
1213 (share && strcmp(share,s)==0)?"SELECTED":"",
1214 s, s);
1215 else
1216 printf("<option %s value=\"%s\">%s\n",
1217 (share && strcmp(share,s)==0)?"SELECTED":"",
1218 s, s);
1221 printf("</select></td>");
1222 if (have_write_access) {
1223 printf("<td><input type=submit name=\"Delete\" value=\"Delete Printer\"></td>\n");
1225 printf("</tr>");
1226 printf("</table>\n");
1228 if (have_write_access) {
1229 printf("<table>\n");
1230 printf("<tr><td><input type=submit name=createshare value=\"Create Printer\"></td>\n");
1231 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1232 printf("</table>");
1236 if (snum >= 0) {
1237 if (have_write_access) {
1238 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
1240 printf("<input type=reset name=\"Reset Values\" value=\"Reset Values\">\n");
1241 if (parm_filter != FLAG_ADVANCED) {
1242 printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
1243 } else {
1244 printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
1246 printf("<p>\n");
1249 if (snum >= 0) {
1250 printf("<table>\n");
1251 show_parameters(snum, 1, parm_filter, 1);
1252 printf("</table>\n");
1255 if (parm_filter == FLAG_ADVANCED) {
1256 printf("<input type=hidden name=\"Advanced\" value=1>\n");
1259 printf("</FORM>\n");
1262 /****************************************************************************
1263 MAIN()
1264 ****************************************************************************/
1265 int main(int argc, char *argv[])
1267 extern char *optarg;
1268 extern int optind;
1269 extern FILE *dbf;
1270 int opt;
1271 char *page;
1273 fault_setup(NULL);
1274 umask(S_IWGRP | S_IWOTH);
1276 #if defined(HAVE_SET_AUTH_PARAMETERS)
1277 set_auth_parameters(argc, argv);
1278 #endif /* HAVE_SET_AUTH_PARAMETERS */
1280 /* just in case it goes wild ... */
1281 alarm(300);
1283 /* we don't want any SIGPIPE messages */
1284 BlockSignals(True,SIGPIPE);
1286 dbf = sys_fopen("/dev/null", "w");
1287 if (!dbf) dbf = stderr;
1289 /* we don't want stderr screwing us up */
1290 close(2);
1291 open("/dev/null", O_WRONLY);
1293 while ((opt = getopt(argc, argv,"s:a")) != EOF) {
1294 switch (opt) {
1295 case 's':
1296 pstrcpy(servicesf,optarg);
1297 break;
1298 case 'a':
1299 demo_mode = True;
1300 break;
1304 setup_logging(argv[0],False);
1305 charset_initialise();
1306 load_config(True);
1307 iNumNonAutoPrintServices = lp_numservices();
1308 load_printers();
1309 codepage_initialise(lp_client_code_page());
1311 cgi_setup(SWATDIR, !demo_mode);
1313 print_header();
1315 cgi_load_variables(NULL);
1317 if (!file_exist(servicesf, NULL)) {
1318 have_read_access = True;
1319 have_write_access = True;
1320 } else {
1321 /* check if the authenticated user has write access - if not then
1322 don't show write options */
1323 have_write_access = (access(servicesf,W_OK) == 0);
1325 /* if the user doesn't have read access to smb.conf then
1326 don't let them view it */
1327 have_read_access = (access(servicesf,R_OK) == 0);
1331 show_main_buttons();
1333 page = cgi_pathinfo();
1335 /* Root gets full functionality */
1336 if (have_read_access && strcmp(page, "globals")==0) {
1337 globals_page();
1338 } else if (have_read_access && strcmp(page,"shares")==0) {
1339 shares_page();
1340 } else if (have_read_access && strcmp(page,"printers")==0) {
1341 printers_page();
1342 } else if (have_read_access && strcmp(page,"wizard")==0) {
1343 wizard_page();
1344 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1345 wizard_params_page();
1346 } else if (have_read_access && strcmp(page,"status")==0) {
1347 status_page();
1348 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1349 viewconfig_page();
1350 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1351 rewritecfg_file();
1352 } else if (strcmp(page,"passwd")==0) {
1353 passwd_page();
1354 } else {
1355 welcome_page();
1358 print_footer();
1359 return 0;