2
Unix SMB/CIFS implementation.
3
Samba Web Administration Tool
5
Copyright (C) Andrew Tridgell 1997-2002
6
Copyright (C) John H Terpstra 2002
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
23
* @defgroup swat SWAT - Samba Web Administration Tool
27
* @brief Samba Web Administration Tool.
31
#include "web/swat_proto.h"
33
static int demo_mode = False;
34
static int passwd_only = False;
35
static bool have_write_access = False;
36
static bool have_read_access = False;
37
static int iNumNonAutoPrintServices = 0;
40
* Password Management Globals
42
#define SWAT_USER "username"
43
#define OLD_PSWD "old_passwd"
44
#define NEW_PSWD "new_passwd"
45
#define NEW2_PSWD "new2_passwd"
46
#define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
47
#define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
48
#define ADD_USER_FLAG "add_user_flag"
49
#define DELETE_USER_FLAG "delete_user_flag"
50
#define DISABLE_USER_FLAG "disable_user_flag"
51
#define ENABLE_USER_FLAG "enable_user_flag"
52
#define RHOST "remote_host"
54
#define _(x) lang_msg_rotate(talloc_tos(),x)
56
/****************************************************************************
57
****************************************************************************/
58
static int enum_index(int value, const struct enum_list *enumlist)
61
for (i=0;enumlist[i].name;i++)
62
if (value == enumlist[i].value) break;
66
static char *fix_backslash(const char *str)
68
static char newstring[1024];
72
if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
80
static const char *fix_quotes(TALLOC_CTX *ctx, const char *str)
82
char *newstring = NULL;
85
int quote_len = strlen(""");
87
/* Count the number of quotes. */
92
newstring_len += quote_len;
98
newstring = TALLOC_ARRAY(ctx, char, newstring_len);
102
for (p = newstring; *str; str++) {
104
strncpy( p, """, quote_len);
114
static char *stripspaceupper(const char *str)
116
static char newstring[1024];
120
if (*str != ' ') *p++ = toupper_ascii(*str);
127
static char *make_parm_name(const char *label)
129
static char parmname[1024];
133
if (*label == ' ') *p++ = '_';
141
/****************************************************************************
142
include a lump of html in a page
143
****************************************************************************/
144
static int include_html(const char *fname)
150
fd = web_open(fname, O_RDONLY, 0);
153
printf(_("ERROR: Can't open %s"), fname);
158
while ((ret = read(fd, buf, sizeof(buf))) > 0) {
159
if (write(1, buf, ret) == -1) {
168
/****************************************************************************
169
start the page with standard stuff
170
****************************************************************************/
171
static void print_header(void)
173
if (!cgi_waspost()) {
174
printf("Expires: 0\r\n");
176
printf("Content-type: text/html\r\n\r\n");
178
if (!include_html("include/header.html")) {
179
printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
180
printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
184
/* *******************************************************************
185
show parameter label with translated name in the following form
186
because showing original and translated label in one line looks
187
too long, and showing translated label only is unusable for
189
-------------------------------
190
HELP security [combo box][button]
192
-------------------------------
193
(capital words are translated by gettext.)
194
if no translation is available, then same form as original is
196
"i18n_translated_parm" class is used to change the color of the
197
translated parameter with CSS.
198
**************************************************************** */
199
static const char *get_parm_translated(TALLOC_CTX *ctx,
200
const char* pAnchor, const char* pHelp, const char* pLabel)
202
const char *pTranslated = _(pLabel);
204
if(strcmp(pLabel, pTranslated) != 0) {
205
output = talloc_asprintf(ctx,
206
"<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
207
pAnchor, pHelp, pLabel, pTranslated);
210
output = talloc_asprintf(ctx,
211
"<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
212
pAnchor, pHelp, pLabel);
215
/****************************************************************************
217
****************************************************************************/
218
static void print_footer(void)
220
if (!include_html("include/footer.html")) {
221
printf("\n</BODY>\n</HTML>\n");
225
/****************************************************************************
226
display one editable parameter in a form
227
****************************************************************************/
228
static void show_parameter(int snum, struct parm_struct *parm)
231
void *ptr = parm->ptr;
232
char *utf8_s1, *utf8_s2;
233
size_t converted_size;
234
TALLOC_CTX *ctx = talloc_stackframe();
236
if (parm->p_class == P_LOCAL && snum >= 0) {
237
ptr = lp_local_ptr_by_snum(snum, ptr);
240
printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
241
stripspaceupper(parm->label), _("Help"), parm->label));
242
switch (parm->type) {
244
printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
245
make_parm_name(parm->label), *(char *)ptr);
246
printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
247
_("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
251
printf("<input type=text size=40 name=\"parm_%s\" value=\"",
252
make_parm_name(parm->label));
253
if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
254
char **list = *(char ***)ptr;
255
for (;*list;list++) {
256
/* enclose in HTML encoded quotes if the string contains a space */
257
if ( strchr_m(*list, ' ') ) {
258
push_utf8_allocate(&utf8_s1, *list, &converted_size);
259
push_utf8_allocate(&utf8_s2, ((*(list+1))?", ":""), &converted_size);
260
printf(""%s"%s", utf8_s1, utf8_s2);
262
push_utf8_allocate(&utf8_s1, *list, &converted_size);
263
push_utf8_allocate(&utf8_s2, ((*(list+1))?", ":""), &converted_size);
264
printf("%s%s", utf8_s1, utf8_s2);
271
printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
272
_("Set Default"), make_parm_name(parm->label));
273
if (parm->def.lvalue) {
274
char **list = (char **)(parm->def.lvalue);
275
for (; *list; list++) {
276
/* enclose in HTML encoded quotes if the string contains a space */
277
if ( strchr_m(*list, ' ') )
278
printf(""%s"%s", *list, ((*(list+1))?", ":""));
280
printf("%s%s", *list, ((*(list+1))?", ":""));
288
push_utf8_allocate(&utf8_s1, *(char **)ptr, &converted_size);
289
printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
290
make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
292
printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
293
_("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
297
printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
298
printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
299
printf("<option %s>No", (*(bool *)ptr)?"":"selected");
301
printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
302
_("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
306
printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
307
printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
308
printf("<option %s>No", (*(bool *)ptr)?"selected":"");
310
printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
311
_("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
315
printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
316
printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
317
_("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
322
o = octal_string(*(int *)ptr);
323
printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
324
make_parm_name(parm->label), o);
326
o = octal_string((int)(parm->def.ivalue));
327
printf("<input type=button value=\"%s\" "
328
"onClick=\"swatform.parm_%s.value=\'%s\'\">",
329
_("Set Default"), make_parm_name(parm->label), o);
335
printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
336
for (i=0;parm->enum_list[i].name;i++) {
337
if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
338
printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
342
printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
343
_("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
348
printf("</td></tr>\n");
352
/****************************************************************************
353
display a set of parameters for a service
354
****************************************************************************/
355
static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
358
struct parm_struct *parm;
359
const char *heading = NULL;
360
const char *last_heading = NULL;
362
while ((parm = lp_next_parameter(snum, &i, allparameters))) {
363
if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
365
if (parm->p_class == P_SEPARATOR) {
366
heading = parm->label;
369
if (parm->flags & FLAG_HIDE) continue;
371
if (printers & !(parm->flags & FLAG_PRINT)) continue;
372
if (!printers & !(parm->flags & FLAG_SHARE)) continue;
375
if (!( parm_filter & FLAG_ADVANCED )) {
376
if (!(parm->flags & FLAG_BASIC)) {
377
void *ptr = parm->ptr;
379
if (parm->p_class == P_LOCAL && snum >= 0) {
380
ptr = lp_local_ptr_by_snum(snum, ptr);
383
switch (parm->type) {
385
if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
389
if (!str_list_equal(*(const char ***)ptr,
390
(const char **)(parm->def.lvalue))) continue;
395
if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
400
if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
405
if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
410
if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
416
if (printers && !(parm->flags & FLAG_PRINT)) continue;
419
if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
421
if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
423
if (heading && heading != last_heading) {
424
printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
425
last_heading = heading;
427
show_parameter(snum, parm);
431
/****************************************************************************
432
load the smb.conf file into loadparm.
433
****************************************************************************/
434
static bool load_config(bool save_def)
436
return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
439
/****************************************************************************
441
****************************************************************************/
442
static void write_config(FILE *f, bool show_defaults)
444
TALLOC_CTX *ctx = talloc_stackframe();
446
fprintf(f, "# Samba config file created using SWAT\n");
447
fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
448
fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
450
lp_dump(f, show_defaults, iNumNonAutoPrintServices);
455
/****************************************************************************
456
save and reload the smb.conf config file
457
****************************************************************************/
458
static int save_reload(int snum)
463
f = sys_fopen(get_dyn_CONFIGFILE(),"w");
465
printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
470
/* just in case they have used the buggy xinetd to create the file */
471
if (fstat(fileno(f), &st) == 0 &&
472
(st.st_mode & S_IWOTH)) {
473
#if defined HAVE_FCHMOD
474
fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
476
chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
480
write_config(f, False);
482
lp_dump_one(f, False, snum);
485
lp_kill_all_services();
487
if (!load_config(False)) {
488
printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
492
iNumNonAutoPrintServices = lp_numservices();
498
/****************************************************************************
500
****************************************************************************/
501
static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
506
if (snum < 0 && parm->p_class == P_LOCAL) {
507
/* this handles the case where we are changing a local
508
variable globally. We need to change the parameter in
509
all shares where it is currently set to the default */
510
for (i=0;i<lp_numservices();i++) {
511
s = lp_servicename(i);
512
if (s && (*s) && lp_is_default(i, parm)) {
513
lp_do_parameter(i, parm->label, v);
518
lp_do_parameter(snum, parm->label, v);
521
/****************************************************************************
522
commit a set of parameters for a service
523
****************************************************************************/
524
static void commit_parameters(int snum)
527
struct parm_struct *parm;
531
while ((parm = lp_next_parameter(snum, &i, 1))) {
532
if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
533
if ((v = cgi_variable(label)) != NULL) {
534
if (parm->flags & FLAG_HIDE)
536
commit_parameter(snum, parm, v);
543
/****************************************************************************
544
spit out the html for a link with an image
545
****************************************************************************/
546
static void image_link(const char *name, const char *hlink, const char *src)
548
printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
549
cgi_baseurl(), hlink, src, name);
552
/****************************************************************************
553
display the main navigation controls at the top of each page along
555
****************************************************************************/
556
static void show_main_buttons(void)
560
if ((p = cgi_user_name()) && strcmp(p, "root")) {
561
printf(_("Logged in as <b>%s</b>"), p);
565
image_link(_("Home"), "", "images/home.gif");
566
if (have_write_access) {
567
image_link(_("Globals"), "globals", "images/globals.gif");
568
image_link(_("Shares"), "shares", "images/shares.gif");
569
image_link(_("Printers"), "printers", "images/printers.gif");
570
image_link(_("Wizard"), "wizard", "images/wizard.gif");
572
/* root always gets all buttons, otherwise look for -P */
573
if ( have_write_access || (!passwd_only && have_read_access) ) {
574
image_link(_("Status"), "status", "images/status.gif");
575
image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
577
image_link(_("Password Management"), "passwd", "images/passwd.gif");
582
/****************************************************************************
583
* Handle Display/Edit Mode CGI
584
****************************************************************************/
585
static void ViewModeBoxes(int mode)
587
printf("<p>%s: \n", _("Current View Is"));
588
printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
589
printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
590
printf("<br>%s: \n", _("Change View To"));
591
printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
592
printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
593
printf("</p><br>\n");
596
/****************************************************************************
597
display a welcome page
598
****************************************************************************/
599
static void welcome_page(void)
601
if (file_exist("help/welcome.html")) {
602
include_html("help/welcome.html");
604
include_html("help/welcome-no-samba-doc.html");
608
/****************************************************************************
609
display the current smb.conf
610
****************************************************************************/
611
static void viewconfig_page(void)
615
if (cgi_variable("full_view")) {
619
printf("<H2>%s</H2>\n", _("Current Config"));
620
printf("<form method=post>\n");
623
printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
625
printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
629
write_config(stdout, full_view);
634
/****************************************************************************
635
second screen of the wizard ... Fetch Configuration Parameters
636
****************************************************************************/
637
static void wizard_params_page(void)
639
unsigned int parm_filter = FLAG_WIZARD;
641
/* Here we first set and commit all the parameters that were selected
642
in the previous screen. */
644
printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
646
if (cgi_variable("Commit")) {
647
commit_parameters(GLOBAL_SECTION_SNUM);
651
printf("<form name=\"swatform\" method=post action=wizard_params>\n");
653
if (have_write_access) {
654
printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
657
printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
661
show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
662
printf("</table>\n");
666
/****************************************************************************
667
Utility to just rewrite the smb.conf file - effectively just cleans it up
668
****************************************************************************/
669
static void rewritecfg_file(void)
671
commit_parameters(GLOBAL_SECTION_SNUM);
673
printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
676
/****************************************************************************
677
wizard to create/modify the smb.conf file
678
****************************************************************************/
679
static void wizard_page(void)
681
/* Set some variables to collect data from smb.conf */
688
if (cgi_variable("Rewrite")) {
689
(void) rewritecfg_file();
693
if (cgi_variable("GetWizardParams")){
694
(void) wizard_params_page();
698
if (cgi_variable("Commit")){
699
SerType = atoi(cgi_variable_nonull("ServerType"));
700
winstype = atoi(cgi_variable_nonull("WINSType"));
701
have_home = lp_servicenumber(HOMES_NAME);
702
HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
704
/* Plain text passwords are too badly broken - use encrypted passwords only */
705
lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
709
/* Stand-alone Server */
710
lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
711
lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
715
lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
716
lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
719
/* Domain Controller */
720
lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
721
lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
724
switch ( winstype ) {
726
lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
727
lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
730
lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
731
lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
734
lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
735
lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
739
/* Have to create Homes share? */
740
if ((HomeExpo == 1) && (have_home == -1)) {
741
const char *unix_share = HOMES_NAME;
744
lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
745
have_home = lp_servicenumber(HOMES_NAME);
746
lp_do_parameter( have_home, "read only", "No");
747
lp_do_parameter( have_home, "valid users", "%S");
748
lp_do_parameter( have_home, "browseable", "No");
749
commit_parameters(have_home);
750
save_reload(have_home);
753
/* Need to Delete Homes share? */
754
if ((HomeExpo == 0) && (have_home != -1)) {
755
lp_remove_service(have_home);
759
commit_parameters(GLOBAL_SECTION_SNUM);
764
/* Now determine smb.conf WINS settings */
765
if (lp_wins_support())
767
if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
770
/* Do we have a homes share? */
771
have_home = lp_servicenumber(HOMES_NAME);
773
if ((winstype == 2) && lp_wins_support())
776
role = lp_server_role();
779
printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
780
printf("<form method=post action=wizard>\n");
782
if (have_write_access) {
783
printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
784
printf("%s", _("The same will happen if you press the commit button."));
785
printf("<br><br>\n");
787
printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
788
printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
789
printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
790
printf("</center>\n");
794
printf("<center><table border=0>");
795
printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
796
printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
797
printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
798
printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
800
if (role == ROLE_DOMAIN_BDC) {
801
printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
803
printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
804
printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
805
printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
806
printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
808
printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
810
/* Print out the list of wins servers */
811
if(lp_wins_server_list()) {
813
const char **wins_servers = lp_wins_server_list();
814
for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
817
printf("\"></td></tr>\n");
819
printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Error: WINS Server Mode and WINS Support both set in smb.conf"));
820
printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
822
printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
823
printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
824
printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
825
printf("<td></td></tr>\n");
827
/* Enable this when we are ready ....
828
* printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
829
* printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
830
* printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
831
* printf("<td></td></tr>\n");
834
printf("</table></center>");
837
printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
842
/****************************************************************************
843
display a globals editing page
844
****************************************************************************/
845
static void globals_page(void)
847
unsigned int parm_filter = FLAG_BASIC;
850
printf("<H2>%s</H2>\n", _("Global Parameters"));
852
if (cgi_variable("Commit")) {
853
commit_parameters(GLOBAL_SECTION_SNUM);
857
if ( cgi_variable("ViewMode") )
858
mode = atoi(cgi_variable_nonull("ViewMode"));
859
if ( cgi_variable("BasicMode"))
861
if ( cgi_variable("AdvMode"))
864
printf("<form name=\"swatform\" method=post action=globals>\n");
866
ViewModeBoxes( mode );
869
parm_filter = FLAG_BASIC;
872
parm_filter = FLAG_ADVANCED;
876
if (have_write_access) {
877
printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
878
_("Commit Changes"));
881
printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
886
show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
887
printf("</table>\n");
891
/****************************************************************************
892
display a shares editing page. share is in unix codepage,
893
****************************************************************************/
894
static void shares_page(void)
896
const char *share = cgi_variable("share");
902
unsigned int parm_filter = FLAG_BASIC;
903
size_t converted_size;
906
snum = lp_servicenumber(share);
908
printf("<H2>%s</H2>\n", _("Share Parameters"));
910
if (cgi_variable("Commit") && snum >= 0) {
911
commit_parameters(snum);
913
snum = lp_servicenumber(share);
916
if (cgi_variable("Delete") && snum >= 0) {
917
lp_remove_service(snum);
923
if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
924
snum = lp_servicenumber(share);
927
lp_copy_service(GLOBAL_SECTION_SNUM, share);
928
snum = lp_servicenumber(share);
930
snum = lp_servicenumber(share);
934
printf("<FORM name=\"swatform\" method=post>\n");
938
if ( cgi_variable("ViewMode") )
939
mode = atoi(cgi_variable_nonull("ViewMode"));
940
if ( cgi_variable("BasicMode"))
942
if ( cgi_variable("AdvMode"))
945
ViewModeBoxes( mode );
948
parm_filter = FLAG_BASIC;
951
parm_filter = FLAG_ADVANCED;
954
printf("<br><tr>\n");
955
printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
956
printf("<td><select name=share>\n");
958
printf("<option value=\" \"> \n");
959
for (i=0;i<lp_numservices();i++) {
960
s = lp_servicename(i);
961
if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
962
push_utf8_allocate(&utf8_s, s, &converted_size);
963
printf("<option %s value=\"%s\">%s\n",
964
(share && strcmp(share,s)==0)?"SELECTED":"",
969
printf("</select></td>\n");
970
if (have_write_access) {
971
printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
976
if (have_write_access) {
978
printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
979
printf("<td><input type=text size=30 name=newshare></td></tr>\n");
985
if (have_write_access) {
986
printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
989
printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
995
show_parameters(snum, 1, parm_filter, 0);
996
printf("</table>\n");
1002
/*************************************************************
1003
change a password either locally or remotely
1004
*************************************************************/
1005
static bool change_password(const char *remote_machine, const char *user_name,
1006
const char *old_passwd, const char *new_passwd,
1010
char *err_str = NULL;
1011
char *msg_str = NULL;
1014
printf("%s\n<p>", _("password change in demo mode rejected"));
1018
if (remote_machine != NULL) {
1019
ret = remote_password_change(remote_machine, user_name,
1020
old_passwd, new_passwd, &err_str);
1021
if (err_str != NULL)
1022
printf("%s\n<p>", err_str);
1024
return NT_STATUS_IS_OK(ret);
1027
if(!initialize_password_db(True, NULL)) {
1028
printf("%s\n<p>", _("Can't setup password database vectors."));
1032
ret = local_password_change(user_name, local_flags, new_passwd,
1033
&err_str, &msg_str);
1036
printf("%s\n<p>", msg_str);
1038
printf("%s\n<p>", err_str);
1042
return NT_STATUS_IS_OK(ret);
1045
/****************************************************************************
1046
do the stuff required to add or change a password
1047
****************************************************************************/
1048
static void chg_passwd(void)
1052
int local_flags = 0;
1054
/* Make sure users name has been specified */
1055
if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1056
printf("<p>%s\n", _(" Must specify \"User Name\" "));
1061
* smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1062
* so if that's what we're doing, skip the rest of the checks
1064
if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1067
* If current user is not root, make sure old password has been specified
1068
* If REMOTE change, even root must provide old password
1070
if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1071
((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1072
printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1076
/* If changing a users password on a remote hosts we have to know what host */
1077
if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1078
printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1082
/* Make sure new passwords have been specified */
1083
if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1084
(strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1085
printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1089
/* Make sure new passwords was typed correctly twice */
1090
if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1091
printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1096
if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1097
host = cgi_variable(RHOST);
1098
} else if (am_root()) {
1105
* Set up the local flags.
1108
local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1109
local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1110
local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1111
local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1112
local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1113
local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1116
rslt = change_password(host,
1117
cgi_variable_nonull(SWAT_USER),
1118
cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1121
if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1124
printf(_(" The passwd for '%s' has been changed."), cgi_variable_nonull(SWAT_USER));
1127
printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable_nonull(SWAT_USER));
1135
/****************************************************************************
1136
display a password editing page
1137
****************************************************************************/
1138
static void passwd_page(void)
1140
const char *new_name = cgi_user_name();
1143
* After the first time through here be nice. If the user
1144
* changed the User box text to another users name, remember it.
1146
if (cgi_variable(SWAT_USER)) {
1147
new_name = cgi_variable_nonull(SWAT_USER);
1150
if (!new_name) new_name = "";
1152
printf("<H2>%s</H2>\n", _("Server Password Management"));
1154
printf("<FORM name=\"swatform\" method=post>\n");
1156
printf("<table>\n");
1159
* Create all the dialog boxes for data collection
1161
printf("<tr><td> %s : </td>\n", _("User Name"));
1162
printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1164
printf("<tr><td> %s : </td>\n", _("Old Password"));
1165
printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1167
printf("<tr><td> %s : </td>\n", _("New Password"));
1168
printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1169
printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1170
printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1171
printf("</table>\n");
1174
* Create all the control buttons for requesting action
1176
printf("<input type=submit name=%s value=\"%s\">\n",
1177
CHG_S_PASSWD_FLAG, _("Change Password"));
1178
if (demo_mode || am_root()) {
1179
printf("<input type=submit name=%s value=\"%s\">\n",
1180
ADD_USER_FLAG, _("Add New User"));
1181
printf("<input type=submit name=%s value=\"%s\">\n",
1182
DELETE_USER_FLAG, _("Delete User"));
1183
printf("<input type=submit name=%s value=\"%s\">\n",
1184
DISABLE_USER_FLAG, _("Disable User"));
1185
printf("<input type=submit name=%s value=\"%s\">\n",
1186
ENABLE_USER_FLAG, _("Enable User"));
1188
printf("<p></FORM>\n");
1191
* Do some work if change, add, disable or enable was
1192
* requested. It could be this is the first time through this
1193
* code, so there isn't anything to do. */
1194
if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1195
(cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1199
printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1201
printf("<FORM name=\"swatform\" method=post>\n");
1203
printf("<table>\n");
1206
* Create all the dialog boxes for data collection
1208
printf("<tr><td> %s : </td>\n", _("User Name"));
1209
printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1210
printf("<tr><td> %s : </td>\n", _("Old Password"));
1211
printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1212
printf("<tr><td> %s : </td>\n", _("New Password"));
1213
printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1214
printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1215
printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1216
printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1217
printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1222
* Create all the control buttons for requesting action
1224
printf("<input type=submit name=%s value=\"%s\">",
1225
CHG_R_PASSWD_FLAG, _("Change Password"));
1227
printf("<p></FORM>\n");
1230
* Do some work if a request has been made to change the
1231
* password somewhere other than the server. It could be this
1232
* is the first time through this code, so there isn't
1233
* anything to do. */
1234
if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1240
/****************************************************************************
1241
display a printers editing page
1242
****************************************************************************/
1243
static void printers_page(void)
1245
const char *share = cgi_variable("share");
1250
unsigned int parm_filter = FLAG_BASIC;
1253
snum = lp_servicenumber(share);
1255
printf("<H2>%s</H2>\n", _("Printer Parameters"));
1257
printf("<H3>%s</H3>\n", _("Important Note:"));
1258
printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1259
printf("%s",_("are autoloaded printers from "));
1260
printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1261
printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1263
if (cgi_variable("Commit") && snum >= 0) {
1264
commit_parameters(snum);
1265
if (snum >= iNumNonAutoPrintServices)
1269
snum = lp_servicenumber(share);
1272
if (cgi_variable("Delete") && snum >= 0) {
1273
lp_remove_service(snum);
1279
if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1280
snum = lp_servicenumber(share);
1281
if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1283
lp_copy_service(GLOBAL_SECTION_SNUM, share);
1284
snum = lp_servicenumber(share);
1285
lp_do_parameter(snum, "print ok", "Yes");
1287
snum = lp_servicenumber(share);
1291
printf("<FORM name=\"swatform\" method=post>\n");
1293
if ( cgi_variable("ViewMode") )
1294
mode = atoi(cgi_variable_nonull("ViewMode"));
1295
if ( cgi_variable("BasicMode"))
1297
if ( cgi_variable("AdvMode"))
1300
ViewModeBoxes( mode );
1303
parm_filter = FLAG_BASIC;
1306
parm_filter = FLAG_ADVANCED;
1309
printf("<table>\n");
1310
printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1311
printf("<td><select name=\"share\">\n");
1312
if (snum < 0 || !lp_print_ok(snum))
1313
printf("<option value=\" \"> \n");
1314
for (i=0;i<lp_numservices();i++) {
1315
s = lp_servicename(i);
1316
if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1317
if (i >= iNumNonAutoPrintServices)
1318
printf("<option %s value=\"%s\">[*]%s\n",
1319
(share && strcmp(share,s)==0)?"SELECTED":"",
1322
printf("<option %s value=\"%s\">%s\n",
1323
(share && strcmp(share,s)==0)?"SELECTED":"",
1327
printf("</select></td>");
1328
if (have_write_access) {
1329
printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1332
printf("</table>\n");
1334
if (have_write_access) {
1335
printf("<table>\n");
1336
printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1337
printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1343
if (have_write_access) {
1344
printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1346
printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1351
printf("<table>\n");
1352
show_parameters(snum, 1, parm_filter, 1);
1353
printf("</table>\n");
1355
printf("</FORM>\n");
1359
when the _() translation macro is used there is no obvious place to free
1360
the resulting string and there is no easy way to give a static pointer.
1361
All we can do is rotate between some static buffers and hope a single d_printf()
1362
doesn't have more calls to _() than the number of buffers
1365
const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1370
msgstr = lang_msg(msgid);
1375
ret = talloc_strdup(ctx, msgstr);
1377
lang_msg_free(msgstr);
1386
* main function for SWAT.
1388
int main(int argc, char *argv[])
1392
struct poptOption long_options[] = {
1394
{ "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1395
{ "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1399
TALLOC_CTX *frame = talloc_stackframe();
1402
umask(S_IWGRP | S_IWOTH);
1404
#if defined(HAVE_SET_AUTH_PARAMETERS)
1405
set_auth_parameters(argc, argv);
1406
#endif /* HAVE_SET_AUTH_PARAMETERS */
1408
/* just in case it goes wild ... */
1413
/* we don't want any SIGPIPE messages */
1414
BlockSignals(True,SIGPIPE);
1416
dbf = x_fopen("/dev/null", O_WRONLY, 0);
1417
if (!dbf) dbf = x_stderr;
1419
/* we don't want stderr screwing us up */
1421
open("/dev/null", O_WRONLY);
1423
pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1425
/* Parse command line options */
1427
while(poptGetNextOpt(pc) != -1) { }
1429
poptFreeContext(pc);
1433
setup_logging(argv[0],False);
1436
iNumNonAutoPrintServices = lp_numservices();
1439
cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1443
cgi_load_variables();
1445
if (!file_exist(get_dyn_CONFIGFILE())) {
1446
have_read_access = True;
1447
have_write_access = True;
1449
/* check if the authenticated user has write access - if not then
1450
don't show write options */
1451
have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1453
/* if the user doesn't have read access to smb.conf then
1454
don't let them view it */
1455
have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1458
show_main_buttons();
1460
page = cgi_pathinfo();
1462
/* Root gets full functionality */
1463
if (have_read_access && strcmp(page, "globals")==0) {
1465
} else if (have_read_access && strcmp(page,"shares")==0) {
1467
} else if (have_read_access && strcmp(page,"printers")==0) {
1469
} else if (have_read_access && strcmp(page,"status")==0) {
1471
} else if (have_read_access && strcmp(page,"viewconfig")==0) {
1473
} else if (strcmp(page,"passwd")==0) {
1475
} else if (have_read_access && strcmp(page,"wizard")==0) {
1477
} else if (have_read_access && strcmp(page,"wizard_params")==0) {
1478
wizard_params_page();
1479
} else if (have_read_access && strcmp(page,"rewritecfg")==0) {