source: trunk/server/source3/web/swat.c@ 751

Last change on this file since 751 was 751, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.9

File size: 50.4 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 Samba Web Administration Tool
4 Version 3.0.0
5 Copyright (C) Andrew Tridgell 1997-2002
6 Copyright (C) John H Terpstra 2002
7
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.
12
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.
17
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/>.
20*/
21
22/**
23 * @defgroup swat SWAT - Samba Web Administration Tool
24 * @{
25 * @file swat.c
26 *
27 * @brief Samba Web Administration Tool.
28 **/
29
30#include "includes.h"
31#include "system/filesys.h"
32#include "popt_common.h"
33#include "web/swat_proto.h"
34#include "printing/pcap.h"
35#include "printing/load.h"
36#include "passdb.h"
37#include "intl/lang_tdb.h"
38#include "../lib/crypto/md5.h"
39
40static int demo_mode = False;
41static int passwd_only = False;
42static bool have_write_access = False;
43static bool have_read_access = False;
44static int iNumNonAutoPrintServices = 0;
45
46/*
47 * Password Management Globals
48 */
49#define SWAT_USER "username"
50#define OLD_PSWD "old_passwd"
51#define NEW_PSWD "new_passwd"
52#define NEW2_PSWD "new2_passwd"
53#define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
54#define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
55#define ADD_USER_FLAG "add_user_flag"
56#define DELETE_USER_FLAG "delete_user_flag"
57#define DISABLE_USER_FLAG "disable_user_flag"
58#define ENABLE_USER_FLAG "enable_user_flag"
59#define RHOST "remote_host"
60#define XSRF_TOKEN "xsrf"
61#define XSRF_TIME "xsrf_time"
62#define XSRF_TIMEOUT 300
63
64#define _(x) lang_msg_rotate(talloc_tos(),x)
65
66/****************************************************************************
67****************************************************************************/
68static int enum_index(int value, const struct enum_list *enumlist)
69{
70 int i;
71 for (i=0;enumlist[i].name;i++)
72 if (value == enumlist[i].value) break;
73 return(i);
74}
75
76static char *fix_backslash(const char *str)
77{
78 static char newstring[1024];
79 char *p = newstring;
80
81 while (*str) {
82 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
83 else *p++ = *str;
84 ++str;
85 }
86 *p = '\0';
87 return newstring;
88}
89
90static const char *fix_quotes(TALLOC_CTX *ctx, const char *str)
91{
92 char *newstring = NULL;
93 char *p = NULL;
94 size_t newstring_len;
95 int quote_len = strlen("&quot;");
96
97 /* Count the number of quotes. */
98 newstring_len = 1;
99 p = (char *) str;
100 while (*p) {
101 if ( *p == '\"') {
102 newstring_len += quote_len;
103 } else {
104 newstring_len++;
105 }
106 ++p;
107 }
108 newstring = TALLOC_ARRAY(ctx, char, newstring_len);
109 if (!newstring) {
110 return "";
111 }
112 for (p = newstring; *str; str++) {
113 if ( *str == '\"') {
114 strncpy( p, "&quot;", quote_len);
115 p += quote_len;
116 } else {
117 *p++ = *str;
118 }
119 }
120 *p = '\0';
121 return newstring;
122}
123
124static char *stripspaceupper(const char *str)
125{
126 static char newstring[1024];
127 char *p = newstring;
128
129 while (*str) {
130 if (*str != ' ') *p++ = toupper_m(*str);
131 ++str;
132 }
133 *p = '\0';
134 return newstring;
135}
136
137static char *make_parm_name(const char *label)
138{
139 static char parmname[1024];
140 char *p = parmname;
141
142 while (*label) {
143 if (*label == ' ') *p++ = '_';
144 else *p++ = *label;
145 ++label;
146 }
147 *p = '\0';
148 return parmname;
149}
150
151void get_xsrf_token(const char *username, const char *pass,
152 const char *formname, time_t xsrf_time, char token_str[33])
153{
154 MD5_CTX md5_ctx;
155 uint8_t token[16];
156 int i;
157
158 token_str[0] = '\0';
159 ZERO_STRUCT(md5_ctx);
160 MD5Init(&md5_ctx);
161
162 MD5Update(&md5_ctx, (uint8_t *)formname, strlen(formname));
163 MD5Update(&md5_ctx, (uint8_t *)&xsrf_time, sizeof(time_t));
164 if (username != NULL) {
165 MD5Update(&md5_ctx, (uint8_t *)username, strlen(username));
166 }
167 if (pass != NULL) {
168 MD5Update(&md5_ctx, (uint8_t *)pass, strlen(pass));
169 }
170
171 MD5Final(token, &md5_ctx);
172
173 for(i = 0; i < sizeof(token); i++) {
174 char tmp[3];
175
176 snprintf(tmp, sizeof(tmp), "%02x", token[i]);
177 strlcat(token_str, tmp, sizeof(tmp));
178 }
179}
180
181void print_xsrf_token(const char *username, const char *pass,
182 const char *formname)
183{
184 char token[33];
185 time_t xsrf_time = time(NULL);
186
187 get_xsrf_token(username, pass, formname, xsrf_time, token);
188 printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
189 XSRF_TOKEN, token);
190 printf("<input type=\"hidden\" name=\"%s\" value=\"%lld\">\n",
191 XSRF_TIME, (long long int)xsrf_time);
192}
193
194bool verify_xsrf_token(const char *formname)
195{
196 char expected[33];
197 const char *username = cgi_user_name();
198 const char *pass = cgi_user_pass();
199 const char *token = cgi_variable_nonull(XSRF_TOKEN);
200 const char *time_str = cgi_variable_nonull(XSRF_TIME);
201 char *p = NULL;
202 long long xsrf_time_ll = 0;
203 time_t xsrf_time = 0;
204 time_t now = time(NULL);
205
206 errno = 0;
207 xsrf_time_ll = strtoll(time_str, &p, 10);
208 if (errno != 0) {
209 return false;
210 }
211 if (p == NULL) {
212 return false;
213 }
214 if (PTR_DIFF(p, time_str) > strlen(time_str)) {
215 return false;
216 }
217 if (xsrf_time_ll > _TYPE_MAXIMUM(time_t)) {
218 return false;
219 }
220 if (xsrf_time_ll < _TYPE_MINIMUM(time_t)) {
221 return false;
222 }
223 xsrf_time = xsrf_time_ll;
224
225 if (abs(now - xsrf_time) > XSRF_TIMEOUT) {
226 return false;
227 }
228
229 get_xsrf_token(username, pass, formname, xsrf_time, expected);
230 return (strncmp(expected, token, sizeof(expected)) == 0);
231}
232
233
234/****************************************************************************
235 include a lump of html in a page
236****************************************************************************/
237static int include_html(const char *fname)
238{
239 int fd;
240 char buf[1024];
241 int ret;
242
243 fd = web_open(fname, O_RDONLY, 0);
244
245 if (fd == -1) {
246 printf(_("ERROR: Can't open %s"), fname);
247 printf("\n");
248 return 0;
249 }
250
251 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
252 if (write(1, buf, ret) == -1) {
253 break;
254 }
255 }
256
257 close(fd);
258 return 1;
259}
260
261/****************************************************************************
262 start the page with standard stuff
263****************************************************************************/
264static void print_header(void)
265{
266 if (!cgi_waspost()) {
267 printf("Expires: 0\r\n");
268 }
269 printf("Content-type: text/html\r\n\r\n");
270
271 if (!include_html("include/header.html")) {
272 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
273 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
274 }
275}
276
277/* *******************************************************************
278 show parameter label with translated name in the following form
279 because showing original and translated label in one line looks
280 too long, and showing translated label only is unusable for
281 heavy users.
282 -------------------------------
283 HELP security [combo box][button]
284 SECURITY
285 -------------------------------
286 (capital words are translated by gettext.)
287 if no translation is available, then same form as original is
288 used.
289 "i18n_translated_parm" class is used to change the color of the
290 translated parameter with CSS.
291 **************************************************************** */
292static const char *get_parm_translated(TALLOC_CTX *ctx,
293 const char* pAnchor, const char* pHelp, const char* pLabel)
294{
295 const char *pTranslated = _(pLabel);
296 char *output;
297 if(strcmp(pLabel, pTranslated) != 0) {
298 output = talloc_asprintf(ctx,
299 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s <br><span class=\"i18n_translated_parm\">%s</span>",
300 pAnchor, pHelp, pLabel, pTranslated);
301 return output;
302 }
303 output = talloc_asprintf(ctx,
304 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
305 pAnchor, pHelp, pLabel);
306 return output;
307}
308/****************************************************************************
309 finish off the page
310****************************************************************************/
311static void print_footer(void)
312{
313 if (!include_html("include/footer.html")) {
314 printf("\n</BODY>\n</HTML>\n");
315 }
316}
317
318/****************************************************************************
319 display one editable parameter in a form
320****************************************************************************/
321static void show_parameter(int snum, struct parm_struct *parm)
322{
323 int i;
324 void *ptr = parm->ptr;
325 char *utf8_s1, *utf8_s2;
326 size_t converted_size;
327 TALLOC_CTX *ctx = talloc_stackframe();
328
329 if (parm->p_class == P_LOCAL && snum >= 0) {
330 ptr = lp_local_ptr_by_snum(snum, ptr);
331 }
332
333 printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
334 stripspaceupper(parm->label), _("Help"), parm->label));
335 switch (parm->type) {
336 case P_CHAR:
337 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
338 make_parm_name(parm->label), *(char *)ptr);
339 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
340 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
341 break;
342
343 case P_LIST:
344 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
345 make_parm_name(parm->label));
346 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
347 char **list = *(char ***)ptr;
348 for (;*list;list++) {
349 /* enclose in HTML encoded quotes if the string contains a space */
350 if ( strchr_m(*list, ' ') ) {
351 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
352 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
353 printf("&quot;%s&quot;%s", utf8_s1, utf8_s2);
354 } else {
355 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
356 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
357 printf("%s%s", utf8_s1, utf8_s2);
358 }
359 TALLOC_FREE(utf8_s1);
360 TALLOC_FREE(utf8_s2);
361 }
362 }
363 printf("\">");
364 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
365 _("Set Default"), make_parm_name(parm->label));
366 if (parm->def.lvalue) {
367 char **list = (char **)(parm->def.lvalue);
368 for (; *list; list++) {
369 /* enclose in HTML encoded quotes if the string contains a space */
370 if ( strchr_m(*list, ' ') )
371 printf("&quot;%s&quot;%s", *list, ((*(list+1))?", ":""));
372 else
373 printf("%s%s", *list, ((*(list+1))?", ":""));
374 }
375 }
376 printf("\'\">");
377 break;
378
379 case P_STRING:
380 case P_USTRING:
381 push_utf8_talloc(talloc_tos(), &utf8_s1, *(char **)ptr, &converted_size);
382 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
383 make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
384 TALLOC_FREE(utf8_s1);
385 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
386 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
387 break;
388
389 case P_BOOL:
390 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
391 printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
392 printf("<option %s>No", (*(bool *)ptr)?"":"selected");
393 printf("</select>");
394 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
395 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
396 break;
397
398 case P_BOOLREV:
399 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
400 printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
401 printf("<option %s>No", (*(bool *)ptr)?"selected":"");
402 printf("</select>");
403 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
404 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
405 break;
406
407 case P_INTEGER:
408 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
409 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
410 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
411 break;
412
413 case P_OCTAL: {
414 char *o;
415 o = octal_string(*(int *)ptr);
416 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
417 make_parm_name(parm->label), o);
418 TALLOC_FREE(o);
419 o = octal_string((int)(parm->def.ivalue));
420 printf("<input type=button value=\"%s\" "
421 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
422 _("Set Default"), make_parm_name(parm->label), o);
423 TALLOC_FREE(o);
424 break;
425 }
426
427 case P_ENUM:
428 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
429 for (i=0;parm->enum_list[i].name;i++) {
430 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
431 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
432 }
433 }
434 printf("</select>");
435 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
436 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
437 break;
438 case P_SEP:
439 break;
440 }
441 printf("</td></tr>\n");
442 TALLOC_FREE(ctx);
443}
444
445/****************************************************************************
446 display a set of parameters for a service
447****************************************************************************/
448static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
449{
450 int i = 0;
451 struct parm_struct *parm;
452 const char *heading = NULL;
453 const char *last_heading = NULL;
454
455 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
456 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
457 continue;
458 if (parm->p_class == P_SEPARATOR) {
459 heading = parm->label;
460 continue;
461 }
462 if (parm->flags & FLAG_HIDE) continue;
463 if (snum >= 0) {
464 if (printers & !(parm->flags & FLAG_PRINT)) continue;
465 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
466 }
467
468 if (!( parm_filter & FLAG_ADVANCED )) {
469 if (!(parm->flags & FLAG_BASIC)) {
470 void *ptr = parm->ptr;
471
472 if (parm->p_class == P_LOCAL && snum >= 0) {
473 ptr = lp_local_ptr_by_snum(snum, ptr);
474 }
475
476 switch (parm->type) {
477 case P_CHAR:
478 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
479 break;
480
481 case P_LIST:
482 if (!str_list_equal(*(const char ***)ptr,
483 (const char **)(parm->def.lvalue))) continue;
484 break;
485
486 case P_STRING:
487 case P_USTRING:
488 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
489 break;
490
491 case P_BOOL:
492 case P_BOOLREV:
493 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
494 break;
495
496 case P_INTEGER:
497 case P_OCTAL:
498 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
499 break;
500
501
502 case P_ENUM:
503 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
504 break;
505 case P_SEP:
506 continue;
507 }
508 }
509 if (printers && !(parm->flags & FLAG_PRINT)) continue;
510 }
511
512 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
513
514 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
515
516 if (heading && heading != last_heading) {
517 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
518 last_heading = heading;
519 }
520 show_parameter(snum, parm);
521 }
522}
523
524/****************************************************************************
525 load the smb.conf file into loadparm.
526****************************************************************************/
527static bool load_config(bool save_def)
528{
529 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
530}
531
532/****************************************************************************
533 write a config file
534****************************************************************************/
535static void write_config(FILE *f, bool show_defaults)
536{
537 TALLOC_CTX *ctx = talloc_stackframe();
538
539 fprintf(f, "# Samba config file created using SWAT\n");
540 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
541 fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
542
543 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
544
545 TALLOC_FREE(ctx);
546}
547
548/****************************************************************************
549 save and reload the smb.conf config file
550****************************************************************************/
551static int save_reload(int snum)
552{
553 FILE *f;
554 struct stat st;
555
556 f = sys_fopen(get_dyn_CONFIGFILE(),"w");
557 if (!f) {
558 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
559 printf("\n");
560 return 0;
561 }
562
563 /* just in case they have used the buggy xinetd to create the file */
564 if (fstat(fileno(f), &st) == 0 &&
565 (st.st_mode & S_IWOTH)) {
566#if defined HAVE_FCHMOD
567 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
568#else
569 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
570#endif
571 }
572
573 write_config(f, False);
574 if (snum >= 0)
575 lp_dump_one(f, False, snum);
576 fclose(f);
577
578 lp_kill_all_services();
579
580 if (!load_config(False)) {
581 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
582 printf("\n");
583 return 0;
584 }
585 iNumNonAutoPrintServices = lp_numservices();
586 if (pcap_cache_loaded()) {
587 load_printers(server_event_context(),
588 server_messaging_context());
589 }
590
591 return 1;
592}
593
594/****************************************************************************
595 commit one parameter
596****************************************************************************/
597static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
598{
599 int i;
600 char *s;
601
602 if (snum < 0 && parm->p_class == P_LOCAL) {
603 /* this handles the case where we are changing a local
604 variable globally. We need to change the parameter in
605 all shares where it is currently set to the default */
606 for (i=0;i<lp_numservices();i++) {
607 s = lp_servicename(i);
608 if (s && (*s) && lp_is_default(i, parm)) {
609 lp_do_parameter(i, parm->label, v);
610 }
611 }
612 }
613
614 lp_do_parameter(snum, parm->label, v);
615}
616
617/****************************************************************************
618 commit a set of parameters for a service
619****************************************************************************/
620static void commit_parameters(int snum)
621{
622 int i = 0;
623 struct parm_struct *parm;
624 char *label;
625 const char *v;
626
627 while ((parm = lp_next_parameter(snum, &i, 1))) {
628 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
629 if ((v = cgi_variable(label)) != NULL) {
630 if (parm->flags & FLAG_HIDE)
631 continue;
632 commit_parameter(snum, parm, v);
633 }
634 SAFE_FREE(label);
635 }
636 }
637}
638
639/****************************************************************************
640 spit out the html for a link with an image
641****************************************************************************/
642static void image_link(const char *name, const char *hlink, const char *src)
643{
644 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
645 cgi_baseurl(), hlink, src, name);
646}
647
648/****************************************************************************
649 display the main navigation controls at the top of each page along
650 with a title
651****************************************************************************/
652static void show_main_buttons(void)
653{
654 char *p;
655
656 if ((p = cgi_user_name()) && strcmp(p, "root")) {
657 printf(_("Logged in as <b>%s</b>"), p);
658 printf("<p>\n");
659 }
660
661 image_link(_("Home"), "", "images/home.gif");
662 if (have_write_access) {
663 image_link(_("Globals"), "globals", "images/globals.gif");
664 image_link(_("Shares"), "shares", "images/shares.gif");
665 image_link(_("Printers"), "printers", "images/printers.gif");
666 image_link(_("Wizard"), "wizard", "images/wizard.gif");
667 }
668 /* root always gets all buttons, otherwise look for -P */
669 if ( have_write_access || (!passwd_only && have_read_access) ) {
670 image_link(_("Status"), "status", "images/status.gif");
671 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
672 }
673 image_link(_("Password Management"), "passwd", "images/passwd.gif");
674
675 printf("<HR>\n");
676}
677
678/****************************************************************************
679 * Handle Display/Edit Mode CGI
680 ****************************************************************************/
681static void ViewModeBoxes(int mode)
682{
683 printf("<p>%s:&nbsp;\n", _("Current View Is"));
684 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
685 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
686 printf("<br>%s:&nbsp;\n", _("Change View To"));
687 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
688 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
689 printf("</p><br>\n");
690}
691
692/****************************************************************************
693 display a welcome page
694****************************************************************************/
695static void welcome_page(void)
696{
697 if (file_exist("help/welcome.html")) {
698 include_html("help/welcome.html");
699 } else {
700 include_html("help/welcome-no-samba-doc.html");
701 }
702}
703
704/****************************************************************************
705 display the current smb.conf
706****************************************************************************/
707static void viewconfig_page(void)
708{
709 int full_view=0;
710 const char form_name[] = "viewconfig";
711
712 if (!verify_xsrf_token(form_name)) {
713 goto output_page;
714 }
715
716 if (cgi_variable("full_view")) {
717 full_view = 1;
718 }
719
720output_page:
721 printf("<H2>%s</H2>\n", _("Current Config"));
722 printf("<form method=post>\n");
723 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
724
725 if (full_view) {
726 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
727 } else {
728 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
729 }
730
731 printf("<p><pre>");
732 write_config(stdout, full_view);
733 printf("</pre>");
734 printf("</form>\n");
735}
736
737/****************************************************************************
738 second screen of the wizard ... Fetch Configuration Parameters
739****************************************************************************/
740static void wizard_params_page(void)
741{
742 unsigned int parm_filter = FLAG_WIZARD;
743 const char form_name[] = "wizard_params";
744
745 /* Here we first set and commit all the parameters that were selected
746 in the previous screen. */
747
748 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
749
750 if (!verify_xsrf_token(form_name)) {
751 goto output_page;
752 }
753
754 if (cgi_variable("Commit")) {
755 commit_parameters(GLOBAL_SECTION_SNUM);
756 save_reload(-1);
757 }
758
759output_page:
760 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
761 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
762
763 if (have_write_access) {
764 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
765 }
766
767 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
768 printf("<p>\n");
769
770 printf("<table>\n");
771 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
772 printf("</table>\n");
773 printf("</form>\n");
774}
775
776/****************************************************************************
777 Utility to just rewrite the smb.conf file - effectively just cleans it up
778****************************************************************************/
779static void rewritecfg_file(void)
780{
781 commit_parameters(GLOBAL_SECTION_SNUM);
782 save_reload(-1);
783 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
784}
785
786/****************************************************************************
787 wizard to create/modify the smb.conf file
788****************************************************************************/
789static void wizard_page(void)
790{
791 /* Set some variables to collect data from smb.conf */
792 int role = 0;
793 int winstype = 0;
794 int have_home = -1;
795 int HomeExpo = 0;
796 int SerType = 0;
797 const char form_name[] = "wizard";
798
799 if (!verify_xsrf_token(form_name)) {
800 goto output_page;
801 }
802
803 if (cgi_variable("Rewrite")) {
804 (void) rewritecfg_file();
805 return;
806 }
807
808 if (cgi_variable("GetWizardParams")){
809 (void) wizard_params_page();
810 return;
811 }
812
813 if (cgi_variable("Commit")){
814 SerType = atoi(cgi_variable_nonull("ServerType"));
815 winstype = atoi(cgi_variable_nonull("WINSType"));
816 have_home = lp_servicenumber(HOMES_NAME);
817 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
818
819 /* Plain text passwords are too badly broken - use encrypted passwords only */
820 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
821
822 switch ( SerType ){
823 case 0:
824 /* Stand-alone Server */
825 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
826 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
827 break;
828 case 1:
829 /* Domain Member */
830 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
831 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
832 break;
833 case 2:
834 /* Domain Controller */
835 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
836 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
837 break;
838 }
839 switch ( winstype ) {
840 case 0:
841 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
842 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
843 break;
844 case 1:
845 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
846 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
847 break;
848 case 2:
849 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
850 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
851 break;
852 }
853
854 /* Have to create Homes share? */
855 if ((HomeExpo == 1) && (have_home == -1)) {
856 const char *unix_share = HOMES_NAME;
857
858 load_config(False);
859 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
860 have_home = lp_servicenumber(HOMES_NAME);
861 lp_do_parameter( have_home, "read only", "No");
862 lp_do_parameter( have_home, "valid users", "%S");
863 lp_do_parameter( have_home, "browseable", "No");
864 commit_parameters(have_home);
865 save_reload(have_home);
866 }
867
868 /* Need to Delete Homes share? */
869 if ((HomeExpo == 0) && (have_home != -1)) {
870 lp_remove_service(have_home);
871 have_home = -1;
872 }
873
874 commit_parameters(GLOBAL_SECTION_SNUM);
875 save_reload(-1);
876 }
877 else
878 {
879 /* Now determine smb.conf WINS settings */
880 if (lp_wins_support())
881 winstype = 1;
882 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
883 winstype = 2;
884
885 /* Do we have a homes share? */
886 have_home = lp_servicenumber(HOMES_NAME);
887 }
888 if ((winstype == 2) && lp_wins_support())
889 winstype = 3;
890
891 role = lp_server_role();
892
893output_page:
894 /* Here we go ... */
895 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
896 printf("<form method=post action=wizard>\n");
897 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
898
899 if (have_write_access) {
900 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
901 printf("%s", _("The same will happen if you press the commit button."));
902 printf("<br><br>\n");
903 printf("<center>");
904 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
905 printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
906 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
907 printf("</center>\n");
908 }
909
910 printf("<hr>");
911 printf("<center><table border=0>");
912 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
913 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
914 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
915 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
916 printf("</tr>\n");
917 if (role == ROLE_DOMAIN_BDC) {
918 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
919 }
920 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
921 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
922 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
923 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
924 printf("</tr>\n");
925 printf("<tr><td></td><td></td><td></td><td>%s&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
926
927 /* Print out the list of wins servers */
928 if(lp_wins_server_list()) {
929 int i;
930 const char **wins_servers = lp_wins_server_list();
931 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
932 }
933
934 printf("\"></td></tr>\n");
935 if (winstype == 3) {
936 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"));
937 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
938 }
939 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
940 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
941 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
942 printf("<td></td></tr>\n");
943
944 /* Enable this when we are ready ....
945 * printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
946 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
947 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
948 * printf("<td></td></tr>\n");
949 */
950
951 printf("</table></center>");
952 printf("<hr>");
953
954 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
955 printf("</form>\n");
956}
957
958
959/****************************************************************************
960 display a globals editing page
961****************************************************************************/
962static void globals_page(void)
963{
964 unsigned int parm_filter = FLAG_BASIC;
965 int mode = 0;
966 const char form_name[] = "globals";
967
968 printf("<H2>%s</H2>\n", _("Global Parameters"));
969
970 if (!verify_xsrf_token(form_name)) {
971 goto output_page;
972 }
973
974 if (cgi_variable("Commit")) {
975 commit_parameters(GLOBAL_SECTION_SNUM);
976 save_reload(-1);
977 }
978
979 if ( cgi_variable("ViewMode") )
980 mode = atoi(cgi_variable_nonull("ViewMode"));
981 if ( cgi_variable("BasicMode"))
982 mode = 0;
983 if ( cgi_variable("AdvMode"))
984 mode = 1;
985
986output_page:
987 printf("<form name=\"swatform\" method=post action=globals>\n");
988 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
989
990 ViewModeBoxes( mode );
991 switch ( mode ) {
992 case 0:
993 parm_filter = FLAG_BASIC;
994 break;
995 case 1:
996 parm_filter = FLAG_ADVANCED;
997 break;
998 }
999 printf("<br>\n");
1000 if (have_write_access) {
1001 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
1002 _("Commit Changes"));
1003 }
1004
1005 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
1006 _("Reset Values"));
1007
1008 printf("<p>\n");
1009 printf("<table>\n");
1010 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
1011 printf("</table>\n");
1012 printf("</form>\n");
1013}
1014
1015/****************************************************************************
1016 display a shares editing page. share is in unix codepage,
1017****************************************************************************/
1018static void shares_page(void)
1019{
1020 const char *share = cgi_variable("share");
1021 char *s;
1022 char *utf8_s;
1023 int snum = -1;
1024 int i;
1025 int mode = 0;
1026 unsigned int parm_filter = FLAG_BASIC;
1027 size_t converted_size;
1028 const char form_name[] = "shares";
1029
1030 printf("<H2>%s</H2>\n", _("Share Parameters"));
1031
1032 if (!verify_xsrf_token(form_name)) {
1033 goto output_page;
1034 }
1035
1036 if (share)
1037 snum = lp_servicenumber(share);
1038
1039
1040 if (cgi_variable("Commit") && snum >= 0) {
1041 commit_parameters(snum);
1042 save_reload(-1);
1043 snum = lp_servicenumber(share);
1044 }
1045
1046 if (cgi_variable("Delete") && snum >= 0) {
1047 lp_remove_service(snum);
1048 save_reload(-1);
1049 share = NULL;
1050 snum = -1;
1051 }
1052
1053 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1054 snum = lp_servicenumber(share);
1055 if (snum < 0) {
1056 load_config(False);
1057 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1058 snum = lp_servicenumber(share);
1059 save_reload(snum);
1060 snum = lp_servicenumber(share);
1061 }
1062 }
1063
1064 if ( cgi_variable("ViewMode") )
1065 mode = atoi(cgi_variable_nonull("ViewMode"));
1066 if ( cgi_variable("BasicMode"))
1067 mode = 0;
1068 if ( cgi_variable("AdvMode"))
1069 mode = 1;
1070
1071output_page:
1072 printf("<FORM name=\"swatform\" method=post>\n");
1073 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1074
1075 printf("<table>\n");
1076
1077 ViewModeBoxes( mode );
1078 switch ( mode ) {
1079 case 0:
1080 parm_filter = FLAG_BASIC;
1081 break;
1082 case 1:
1083 parm_filter = FLAG_ADVANCED;
1084 break;
1085 }
1086 printf("<br><tr>\n");
1087 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1088 printf("<td><select name=share>\n");
1089 if (snum < 0)
1090 printf("<option value=\" \"> \n");
1091 for (i=0;i<lp_numservices();i++) {
1092 s = lp_servicename(i);
1093 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
1094 push_utf8_talloc(talloc_tos(), &utf8_s, s, &converted_size);
1095 printf("<option %s value=\"%s\">%s\n",
1096 (share && strcmp(share,s)==0)?"SELECTED":"",
1097 utf8_s, utf8_s);
1098 TALLOC_FREE(utf8_s);
1099 }
1100 }
1101 printf("</select></td>\n");
1102 if (have_write_access) {
1103 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1104 }
1105 printf("</tr>\n");
1106 printf("</table>");
1107 printf("<table>");
1108 if (have_write_access) {
1109 printf("<tr>\n");
1110 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1111 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1112 }
1113 printf("</table>");
1114
1115
1116 if (snum >= 0) {
1117 if (have_write_access) {
1118 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1119 }
1120
1121 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1122 printf("<p>\n");
1123 }
1124
1125 if (snum >= 0) {
1126 printf("<table>\n");
1127 show_parameters(snum, 1, parm_filter, 0);
1128 printf("</table>\n");
1129 }
1130
1131 printf("</FORM>\n");
1132}
1133
1134/*************************************************************
1135change a password either locally or remotely
1136*************************************************************/
1137static bool change_password(const char *remote_machine, const char *user_name,
1138 const char *old_passwd, const char *new_passwd,
1139 int local_flags)
1140{
1141 NTSTATUS ret;
1142 char *err_str = NULL;
1143 char *msg_str = NULL;
1144
1145 if (demo_mode) {
1146 printf("%s\n<p>", _("password change in demo mode rejected"));
1147 return False;
1148 }
1149
1150 if (remote_machine != NULL) {
1151 ret = remote_password_change(remote_machine, user_name,
1152 old_passwd, new_passwd, &err_str);
1153 if (err_str != NULL)
1154 printf("%s\n<p>", err_str);
1155 SAFE_FREE(err_str);
1156 return NT_STATUS_IS_OK(ret);
1157 }
1158
1159 if(!initialize_password_db(True, NULL)) {
1160 printf("%s\n<p>", _("Can't setup password database vectors."));
1161 return False;
1162 }
1163
1164 ret = local_password_change(user_name, local_flags, new_passwd,
1165 &err_str, &msg_str);
1166
1167 if(msg_str)
1168 printf("%s\n<p>", msg_str);
1169 if(err_str)
1170 printf("%s\n<p>", err_str);
1171
1172 SAFE_FREE(msg_str);
1173 SAFE_FREE(err_str);
1174 return NT_STATUS_IS_OK(ret);
1175}
1176
1177/****************************************************************************
1178 do the stuff required to add or change a password
1179****************************************************************************/
1180static void chg_passwd(void)
1181{
1182 const char *host;
1183 bool rslt;
1184 int local_flags = 0;
1185
1186 /* Make sure users name has been specified */
1187 if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1188 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1189 return;
1190 }
1191
1192 /*
1193 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1194 * so if that's what we're doing, skip the rest of the checks
1195 */
1196 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1197
1198 /*
1199 * If current user is not root, make sure old password has been specified
1200 * If REMOTE change, even root must provide old password
1201 */
1202 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1203 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1204 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1205 return;
1206 }
1207
1208 /* If changing a users password on a remote hosts we have to know what host */
1209 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1210 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1211 return;
1212 }
1213
1214 /* Make sure new passwords have been specified */
1215 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1216 (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1217 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1218 return;
1219 }
1220
1221 /* Make sure new passwords was typed correctly twice */
1222 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1223 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1224 return;
1225 }
1226 }
1227
1228 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1229 host = cgi_variable(RHOST);
1230 } else if (am_root()) {
1231 host = NULL;
1232 } else {
1233 host = "127.0.0.1";
1234 }
1235
1236 /*
1237 * Set up the local flags.
1238 */
1239
1240 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1241 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1242 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1243 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1244 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1245 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1246
1247 rslt = change_password(host,
1248 cgi_variable_nonull(SWAT_USER),
1249 cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1250 local_flags);
1251
1252 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1253 printf("<p>");
1254 if (rslt == True) {
1255 printf("%s\n", _(" The passwd has been changed."));
1256 } else {
1257 printf("%s\n", _(" The passwd has NOT been changed."));
1258 }
1259 }
1260
1261 return;
1262}
1263
1264/****************************************************************************
1265 display a password editing page
1266****************************************************************************/
1267static void passwd_page(void)
1268{
1269 const char *new_name = cgi_user_name();
1270 const char passwd_form[] = "passwd";
1271 const char rpasswd_form[] = "rpasswd";
1272
1273 if (!new_name) new_name = "";
1274
1275 printf("<H2>%s</H2>\n", _("Server Password Management"));
1276
1277 printf("<FORM name=\"swatform\" method=post>\n");
1278 print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form);
1279
1280 printf("<table>\n");
1281
1282 /*
1283 * Create all the dialog boxes for data collection
1284 */
1285 printf("<tr><td> %s : </td>\n", _("User Name"));
1286 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1287 if (!am_root()) {
1288 printf("<tr><td> %s : </td>\n", _("Old Password"));
1289 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1290 }
1291 printf("<tr><td> %s : </td>\n", _("New Password"));
1292 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1293 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1294 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1295 printf("</table>\n");
1296
1297 /*
1298 * Create all the control buttons for requesting action
1299 */
1300 printf("<input type=submit name=%s value=\"%s\">\n",
1301 CHG_S_PASSWD_FLAG, _("Change Password"));
1302 if (demo_mode || am_root()) {
1303 printf("<input type=submit name=%s value=\"%s\">\n",
1304 ADD_USER_FLAG, _("Add New User"));
1305 printf("<input type=submit name=%s value=\"%s\">\n",
1306 DELETE_USER_FLAG, _("Delete User"));
1307 printf("<input type=submit name=%s value=\"%s\">\n",
1308 DISABLE_USER_FLAG, _("Disable User"));
1309 printf("<input type=submit name=%s value=\"%s\">\n",
1310 ENABLE_USER_FLAG, _("Enable User"));
1311 }
1312 printf("<p></FORM>\n");
1313
1314 /*
1315 * Do some work if change, add, disable or enable was
1316 * requested. It could be this is the first time through this
1317 * code, so there isn't anything to do. */
1318 if (verify_xsrf_token(passwd_form) &&
1319 ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1320 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG)))) {
1321 chg_passwd();
1322 }
1323
1324 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1325
1326 printf("<FORM name=\"swatform\" method=post>\n");
1327 print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form);
1328
1329 printf("<table>\n");
1330
1331 /*
1332 * Create all the dialog boxes for data collection
1333 */
1334 printf("<tr><td> %s : </td>\n", _("User Name"));
1335 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1336 printf("<tr><td> %s : </td>\n", _("Old Password"));
1337 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1338 printf("<tr><td> %s : </td>\n", _("New Password"));
1339 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1340 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1341 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1342 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1343 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1344
1345 printf("</table>");
1346
1347 /*
1348 * Create all the control buttons for requesting action
1349 */
1350 printf("<input type=submit name=%s value=\"%s\">",
1351 CHG_R_PASSWD_FLAG, _("Change Password"));
1352
1353 printf("<p></FORM>\n");
1354
1355 /*
1356 * Do some work if a request has been made to change the
1357 * password somewhere other than the server. It could be this
1358 * is the first time through this code, so there isn't
1359 * anything to do. */
1360 if (verify_xsrf_token(passwd_form) && cgi_variable(CHG_R_PASSWD_FLAG)) {
1361 chg_passwd();
1362 }
1363
1364}
1365
1366/****************************************************************************
1367 display a printers editing page
1368****************************************************************************/
1369static void printers_page(void)
1370{
1371 const char *share = cgi_variable("share");
1372 char *s;
1373 int snum=-1;
1374 int i;
1375 int mode = 0;
1376 unsigned int parm_filter = FLAG_BASIC;
1377 const char form_name[] = "printers";
1378
1379 if (!verify_xsrf_token(form_name)) {
1380 goto output_page;
1381 }
1382
1383 if (share)
1384 snum = lp_servicenumber(share);
1385
1386 if (cgi_variable("Commit") && snum >= 0) {
1387 commit_parameters(snum);
1388 if (snum >= iNumNonAutoPrintServices)
1389 save_reload(snum);
1390 else
1391 save_reload(-1);
1392 snum = lp_servicenumber(share);
1393 }
1394
1395 if (cgi_variable("Delete") && snum >= 0) {
1396 lp_remove_service(snum);
1397 save_reload(-1);
1398 share = NULL;
1399 snum = -1;
1400 }
1401
1402 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1403 snum = lp_servicenumber(share);
1404 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1405 load_config(False);
1406 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1407 snum = lp_servicenumber(share);
1408 lp_do_parameter(snum, "print ok", "Yes");
1409 save_reload(snum);
1410 snum = lp_servicenumber(share);
1411 }
1412 }
1413
1414 if ( cgi_variable("ViewMode") )
1415 mode = atoi(cgi_variable_nonull("ViewMode"));
1416 if ( cgi_variable("BasicMode"))
1417 mode = 0;
1418 if ( cgi_variable("AdvMode"))
1419 mode = 1;
1420
1421output_page:
1422 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1423
1424 printf("<H3>%s</H3>\n", _("Important Note:"));
1425 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1426 printf("%s",_("are autoloaded printers from "));
1427 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1428 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1429
1430
1431 printf("<FORM name=\"swatform\" method=post>\n");
1432 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1433
1434 ViewModeBoxes( mode );
1435 switch ( mode ) {
1436 case 0:
1437 parm_filter = FLAG_BASIC;
1438 break;
1439 case 1:
1440 parm_filter = FLAG_ADVANCED;
1441 break;
1442 }
1443 printf("<table>\n");
1444 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1445 printf("<td><select name=\"share\">\n");
1446 if (snum < 0 || !lp_print_ok(snum))
1447 printf("<option value=\" \"> \n");
1448 for (i=0;i<lp_numservices();i++) {
1449 s = lp_servicename(i);
1450 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1451 if (i >= iNumNonAutoPrintServices)
1452 printf("<option %s value=\"%s\">[*]%s\n",
1453 (share && strcmp(share,s)==0)?"SELECTED":"",
1454 s, s);
1455 else
1456 printf("<option %s value=\"%s\">%s\n",
1457 (share && strcmp(share,s)==0)?"SELECTED":"",
1458 s, s);
1459 }
1460 }
1461 printf("</select></td>");
1462 if (have_write_access) {
1463 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1464 }
1465 printf("</tr>");
1466 printf("</table>\n");
1467
1468 if (have_write_access) {
1469 printf("<table>\n");
1470 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1471 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1472 printf("</table>");
1473 }
1474
1475
1476 if (snum >= 0) {
1477 if (have_write_access) {
1478 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1479 }
1480 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1481 printf("<p>\n");
1482 }
1483
1484 if (snum >= 0) {
1485 printf("<table>\n");
1486 show_parameters(snum, 1, parm_filter, 1);
1487 printf("</table>\n");
1488 }
1489 printf("</FORM>\n");
1490}
1491
1492/*
1493 when the _() translation macro is used there is no obvious place to free
1494 the resulting string and there is no easy way to give a static pointer.
1495 All we can do is rotate between some static buffers and hope a single d_printf()
1496 doesn't have more calls to _() than the number of buffers
1497*/
1498
1499const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1500{
1501 const char *msgstr;
1502 const char *ret;
1503
1504 msgstr = lang_msg(msgid);
1505 if (!msgstr) {
1506 return msgid;
1507 }
1508
1509 ret = talloc_strdup(ctx, msgstr);
1510
1511 lang_msg_free(msgstr);
1512 if (!ret) {
1513 return msgid;
1514 }
1515
1516 return ret;
1517}
1518
1519/**
1520 * main function for SWAT.
1521 **/
1522 int main(int argc, char *argv[])
1523{
1524 const char *page;
1525 poptContext pc;
1526 struct poptOption long_options[] = {
1527 POPT_AUTOHELP
1528 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1529 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1530 POPT_COMMON_SAMBA
1531 POPT_TABLEEND
1532 };
1533 TALLOC_CTX *frame = talloc_stackframe();
1534
1535 fault_setup(NULL);
1536 umask(S_IWGRP | S_IWOTH);
1537
1538#if defined(HAVE_SET_AUTH_PARAMETERS)
1539 set_auth_parameters(argc, argv);
1540#endif /* HAVE_SET_AUTH_PARAMETERS */
1541
1542 /* just in case it goes wild ... */
1543 alarm(300);
1544
1545 setlinebuf(stdout);
1546
1547 /* we don't want any SIGPIPE messages */
1548 BlockSignals(True,SIGPIPE);
1549
1550 debug_set_logfile("/dev/null");
1551
1552 /* we don't want stderr screwing us up */
1553 close(2);
1554 open("/dev/null", O_WRONLY);
1555 setup_logging("swat", DEBUG_FILE);
1556
1557 load_case_tables();
1558
1559 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1560
1561 /* Parse command line options */
1562
1563 while(poptGetNextOpt(pc) != -1) { }
1564
1565 poptFreeContext(pc);
1566
1567 /* This should set a more apporiate log file */
1568 load_config(True);
1569 reopen_logs();
1570 load_interfaces();
1571 iNumNonAutoPrintServices = lp_numservices();
1572 if (pcap_cache_loaded()) {
1573 load_printers(server_event_context(),
1574 server_messaging_context());
1575 }
1576
1577#ifndef __OS2__
1578 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1579#else
1580#if 0
1581 debug_set_logfile("swat.log"); // this produces a logfile in the dir where swat.exe is located.
1582#endif
1583 fstring path;
1584 fstrcpy(path, getcwd(NULL, _MAX_PATH));
1585 fstrcat(path, "/swat");
1586 cgi_setup(path, !demo_mode);
1587#endif
1588
1589 print_header();
1590
1591 cgi_load_variables();
1592
1593 if (!file_exist(get_dyn_CONFIGFILE())) {
1594 have_read_access = True;
1595 have_write_access = True;
1596 } else {
1597 /* check if the authenticated user has write access - if not then
1598 don't show write options */
1599 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1600
1601 /* if the user doesn't have read access to smb.conf then
1602 don't let them view it */
1603 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1604 }
1605
1606 show_main_buttons();
1607
1608 page = cgi_pathinfo();
1609
1610 /* Root gets full functionality */
1611 if (have_read_access && strcmp(page, "globals")==0) {
1612 globals_page();
1613 } else if (have_read_access && strcmp(page,"shares")==0) {
1614 shares_page();
1615 } else if (have_read_access && strcmp(page,"printers")==0) {
1616 printers_page();
1617 } else if (have_read_access && strcmp(page,"status")==0) {
1618 status_page();
1619 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1620 viewconfig_page();
1621 } else if (strcmp(page,"passwd")==0) {
1622 passwd_page();
1623 } else if (have_read_access && strcmp(page,"wizard")==0) {
1624 wizard_page();
1625 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1626 wizard_params_page();
1627 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1628 rewritecfg_file();
1629 } else {
1630 welcome_page();
1631 }
1632
1633 print_footer();
1634
1635 TALLOC_FREE(frame);
1636 return 0;
1637}
1638
1639/** @} **/
Note: See TracBrowser for help on using the repository browser.