2 Unix SMB/Netbios implementation.
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.
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
{
58 static const html_conversion entities
[] = {
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
)
75 for (i
=0;enumlist
[i
].name
;i
++)
76 if (value
== enumlist
[i
].value
) break;
80 static char *fix_backslash(char *str
)
82 static char newstring
[1024];
86 if (*str
== '\\') {*p
++ = '\\';*p
++ = '\\';}
94 static char *htmlentities(char *str
)
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
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
);
111 if (!entities
[j
].src
) {
115 if (length
== destlen
) {
118 p
= dststr
= malloc(destlen
+ 1);
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
);
132 if (!entities
[j
].src
) {
139 static char *stripspace(char *str
)
141 static char newstring
[1024];
145 if (*str
!= ' ') *p
++ = *str
;
152 static char *make_parm_name(char *label
)
154 static char parmname
[1024];
158 if (*label
== ' ') *p
++ = '_';
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");
176 printf("ERROR: Can't open %s\n", fname
);
181 ret
= fread(buf
, 1, sizeof(buf
), f
);
183 fwrite(buf
, 1, ret
, stdout
);
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 /****************************************************************************
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
)
222 void *ptr
= parm
->ptr
;
225 if (parm
->class == P_LOCAL
&& snum
>= 0) {
226 ptr
= lp_local_ptr(snum
, ptr
);
229 str
= stripspace(parm
->label
);
231 printf("<tr><td><A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\">Help</A> %s</td><td>",
234 switch (parm
->type
) {
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
));
244 str
= htmlentities(*(char **)ptr
);
245 printf("<input type=\"text\" size=\"40\" name=\"parm_%s\" value=\"%s\">",
246 make_parm_name(parm
->label
), 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
)));
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
)));
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");
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);
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":"");
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);
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
++) {
286 printf(",%s:%d",debug_classname_from_index(i
),((int *)ptr
)[i
]);
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
));
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
)));
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
);
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
));
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
)
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
))
334 if (parm
->class == P_SEPARATOR
) {
335 heading
= parm
->label
;
338 if (parm
->flags
& FLAG_HIDE
) continue;
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
) {
353 if (*(char *)ptr
== (char)(parm
->def
.cvalue
)) 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 (strequal(parm
->label
,"log level"))
375 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
380 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) 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 /****************************************************************************
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
)
429 f
= sys_fopen(servicesf
,"w");
431 printf("failed to open %s for writing\n", servicesf
);
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
);
443 lp_dump_one(f
, False
, snum
, _dos_to_unix_static
);
448 if (!load_config(False
)) {
449 printf("Can't reload %s\n", servicesf
);
452 iNumNonAutoPrintServices
= lp_numservices();
458 /****************************************************************************
460 ****************************************************************************/
461 static void commit_parameter(int snum
, struct parm_struct
*parm
, char *v
)
466 /* lp_do_parameter() will do unix_to_dos(v). */
467 if(parm
->flags
& FLAG_DOS_STRING
)
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
)
491 struct parm_struct
*parm
;
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
516 ****************************************************************************/
517 static void show_main_buttons(void)
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");
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)
556 if (cgi_variable("full_view")) {
560 printf("<H2>Current Config</H2>\n");
561 printf("<form method=post>\n");
564 printf("<input type=submit name=\"normal_view\" value=\"Normal View\">\n");
566 printf("<input type=submit name=\"full_view\" value=\"Full View\">\n");
570 write_config(stdout
, full_view
, _dos_to_dos_static
);
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
);
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");
602 show_parameters(GLOBALS_SNUM
, 1, parm_filter
, 0);
603 printf("</table>\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
);
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 */
629 if (cgi_variable("Rewrite")) {
630 (void) rewritecfg_file();
634 if (cgi_variable("GetWizardParams")){
635 (void) wizard_params_page();
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");
650 /* Stand-alone Server */
651 lp_do_parameter( GLOBALS_SNUM
, "security", "USER" );
652 lp_do_parameter( GLOBALS_SNUM
, "domain logons", "No" );
656 lp_do_parameter( GLOBALS_SNUM
, "security", "DOMAIN" );
657 lp_do_parameter( GLOBALS_SNUM
, "domain logons", "No" );
660 /* Domain Controller */
661 lp_do_parameter( GLOBALS_SNUM
, "security", "USER" );
662 lp_do_parameter( GLOBALS_SNUM
, "domain logons", "Yes" );
665 switch ( winstype
) {
667 lp_do_parameter( GLOBALS_SNUM
, "wins support", "No" );
668 lp_do_parameter( GLOBALS_SNUM
, "wins server", "" );
671 lp_do_parameter( GLOBALS_SNUM
, "wins support", "Yes" );
672 lp_do_parameter( GLOBALS_SNUM
, "wins server", "" );
675 lp_do_parameter( GLOBALS_SNUM
, "wins support", "No" );
676 lp_do_parameter( GLOBALS_SNUM
, "wins server", cgi_variable("WINSAddr"));
680 /* Have to create Homes share? */
681 if ((HomeExpo
== 1) && (have_home
== -1)) {
684 pstrcpy(unix_share
, dos_to_unix_static(HOMES_NAME
));
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
);
701 commit_parameters(GLOBALS_SNUM
);
706 /* Now determine smb.conf WINS settings */
707 if (lp_wins_support())
709 if (strlen(lp_wins_server()) != 0 )
712 /* Do we have a homes share? */
713 have_home
= lp_servicenumber(HOMES_NAME
);
715 if ((winstype
== 2) && lp_wins_support())
718 role
= lp_server_role();
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.");
729 printf("<input type=submit name=\"Rewrite\" value=\"Rewrite smb.conf file\"> ");
730 printf("<input type=submit name=\"Commit\" value=\"Commit\"> ");
731 printf("<input type=submit name=\"GetWizardParams\" value=\"Edit Parameter Values\">");
736 printf("<center><table border=0>");
737 printf("<tr><td><b>%s</b></td>\n", "Server Type: ");
738 printf("<td><input type=radio name=\"ServerType\" value=0 %s> Stand Alone </td>", (role
== ROLE_STANDALONE
) ? "checked" : "");
739 printf("<td><input type=radio name=\"ServerType\" value=1 %s> Domain Member </td>", (role
== ROLE_DOMAIN_MEMBER
) ? "checked" : "");
740 printf("<td><input type=radio name=\"ServerType\" value=2 %s> Domain Controller </td>", (role
== ROLE_DOMAIN_PDC
) ? "checked" : "");
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: ");
746 printf("<td><input type=radio name=\"WINSType\" value=0 %s> Not Used </td>", (winstype
== 0) ? "checked" : "");
747 printf("<td><input type=radio name=\"WINSType\" value=1 %s> Server for client use </td>", (winstype
== 1) ? "checked" : "");
748 printf("<td><input type=radio name=\"WINSType\" value=2 %s> Client of another WINS server </td>", (winstype
== 2) ? "checked" : "");
749 printf("<tr><td></td><td></td><td></td><td>Remote WINS Server <input type=text size=\"16\" name=\"WINSAddr\" value=\"\%s\"></td></tr>",lp_wins_server());
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>");
755 printf("<tr><td><b>%s</b></td>\n","Expose Home Directories: ");
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: ");
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>");
770 printf("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment.\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
);
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");
801 printf("<input type=submit name=\"Basic\" value=\"Basic View\">\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");
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");
826 unsigned int parm_filter
= FLAG_BASIC
;
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
);
841 if (cgi_variable("Delete") && snum
>= 0) {
842 lp_remove_service(snum
);
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(). */
852 pstrcpy(unix_share
, dos_to_unix_static(share
));
854 lp_copy_service(GLOBALS_SNUM
, unix_share
);
855 iNumNonAutoPrintServices
= lp_numservices();
857 snum
= lp_servicenumber(share
);
860 printf("<FORM name=\"swatform\" method=post>\n");
864 printf("<td><input type=submit name=selectshare value=\"Choose Share\"></td>\n");
865 printf("<td><select name=share>\n");
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":"",
876 printf("</select></td>\n");
877 if (have_write_access
) {
878 printf("<td><input type=submit name=\"Delete\" value=\"Delete Share\"></td>\n");
883 if (have_write_access
) {
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");
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");
900 printf("<input type=submit name=\"Basic\" value=\"Basic View\">\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");
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
,
930 printf("password change in demo mode rejected\n<p>");
934 if (remote_machine
!= NULL
) {
935 ret
= remote_password_change(remote_machine
, user_name
, old_passwd
,
936 new_passwd
, err_str
, sizeof(err_str
));
938 printf("%s\n<p>", err_str
);
942 if(!initialize_password_db(False
)) {
943 printf("Can't setup password database vectors.\n<p>");
947 ret
= local_password_change(user_name
, local_flags
, new_passwd
, err_str
, sizeof(err_str
),
948 msg_str
, sizeof(msg_str
));
951 printf("%s\n<p>", msg_str
);
953 printf("%s\n<p>", err_str
);
958 /****************************************************************************
959 do the stuff required to add or change a password
960 ****************************************************************************/
961 static void chg_passwd(void)
967 /* Make sure users name has been specified */
968 if (strlen(cgi_variable(SWAT_USER
)) == 0) {
969 printf("<p> Must specify \"User Name\" \n");
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");
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");
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");
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");
1009 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1010 host
= cgi_variable(RHOST
);
1011 } else if (am_root()) {
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
),
1031 if(local_flags
== 0) {
1033 printf("<p> The passwd for '%s' has been changed. \n", cgi_variable(SWAT_USER
));
1035 printf("<p> The passwd for '%s' has NOT been changed. \n",cgi_variable(SWAT_USER
));
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
);
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",
1085 if (demo_mode
|| am_root()) {
1086 printf("<input type=submit name=%s value=\"Add New User\">\n",
1088 printf("<input type=submit name=%s value=\"Delete User\">\n",
1090 printf("<input type=submit name=%s value=\"Disable User\">\n",
1092 printf("<input type=submit name=%s value=\"Enable User\">\n",
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
))) {
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
);
1129 * Create all the control buttons for requesting action
1131 printf("<input type=submit name=%s value=\"Change Password\">",
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
)) {
1147 /****************************************************************************
1148 display a printers editing page
1149 ****************************************************************************/
1150 static void printers_page(void)
1152 char *share
= cgi_variable("share");
1156 unsigned int parm_filter
= FLAG_BASIC
;
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
)
1180 if (cgi_variable("Delete") && snum
>= 0) {
1181 lp_remove_service(snum
);
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(). */
1191 pstrcpy(unix_share
, dos_to_unix_static(share
));
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");
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":"",
1216 printf("<option %s value=\"%s\">%s\n",
1217 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1221 printf("</select></td>");
1222 if (have_write_access
) {
1223 printf("<td><input type=submit name=\"Delete\" value=\"Delete Printer\"></td>\n");
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");
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");
1244 printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
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 /****************************************************************************
1264 ****************************************************************************/
1265 int main(int argc
, char *argv
[])
1267 extern char *optarg
;
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 ... */
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 */
1291 open("/dev/null", O_WRONLY
);
1293 while ((opt
= getopt(argc
, argv
,"s:a")) != EOF
) {
1296 pstrcpy(servicesf
,optarg
);
1304 setup_logging(argv
[0],False
);
1305 charset_initialise();
1307 iNumNonAutoPrintServices
= lp_numservices();
1309 codepage_initialise(lp_client_code_page());
1311 cgi_setup(SWATDIR
, !demo_mode
);
1315 cgi_load_variables(NULL
);
1317 if (!file_exist(servicesf
, NULL
)) {
1318 have_read_access
= True
;
1319 have_write_access
= True
;
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) {
1338 } else if (have_read_access
&& strcmp(page
,"shares")==0) {
1340 } else if (have_read_access
&& strcmp(page
,"printers")==0) {
1342 } else if (have_read_access
&& strcmp(page
,"wizard")==0) {
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) {
1348 } else if (have_read_access
&& strcmp(page
,"viewconfig")==0) {
1350 } else if (have_read_access
&& strcmp(page
,"rewritecfg")==0) {
1352 } else if (strcmp(page
,"passwd")==0) {