VERSION: Bump version up to 3.6.2.
[Samba.git] / source3 / web / swat.c
blobe7c0378697ab9ae82b01df4dfd0473243fbc0a5b
1 /*
2 Unix SMB/CIFS implementation.
3 Samba Web Administration Tool
4 Version 3.0.0
5 Copyright (C) Andrew Tridgell 1997-2002
6 Copyright (C) John H Terpstra 2002
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 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/>.
22 /**
23 * @defgroup swat SWAT - Samba Web Administration Tool
24 * @{
25 * @file swat.c
27 * @brief Samba Web Administration Tool.
28 **/
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"
40 static int demo_mode = False;
41 static int passwd_only = False;
42 static bool have_write_access = False;
43 static bool have_read_access = False;
44 static int iNumNonAutoPrintServices = 0;
47 * Password Management Globals
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
64 #define _(x) lang_msg_rotate(talloc_tos(),x)
66 /****************************************************************************
67 ****************************************************************************/
68 static int enum_index(int value, const struct enum_list *enumlist)
70 int i;
71 for (i=0;enumlist[i].name;i++)
72 if (value == enumlist[i].value) break;
73 return(i);
76 static char *fix_backslash(const char *str)
78 static char newstring[1024];
79 char *p = newstring;
81 while (*str) {
82 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
83 else *p++ = *str;
84 ++str;
86 *p = '\0';
87 return newstring;
90 static const char *fix_quotes(TALLOC_CTX *ctx, const char *str)
92 char *newstring = NULL;
93 char *p = NULL;
94 size_t newstring_len;
95 int quote_len = strlen("&quot;");
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++;
106 ++p;
108 newstring = TALLOC_ARRAY(ctx, char, newstring_len);
109 if (!newstring) {
110 return "";
112 for (p = newstring; *str; str++) {
113 if ( *str == '\"') {
114 strncpy( p, "&quot;", quote_len);
115 p += quote_len;
116 } else {
117 *p++ = *str;
120 *p = '\0';
121 return newstring;
124 static char *stripspaceupper(const char *str)
126 static char newstring[1024];
127 char *p = newstring;
129 while (*str) {
130 if (*str != ' ') *p++ = toupper_m(*str);
131 ++str;
133 *p = '\0';
134 return newstring;
137 static char *make_parm_name(const char *label)
139 static char parmname[1024];
140 char *p = parmname;
142 while (*label) {
143 if (*label == ' ') *p++ = '_';
144 else *p++ = *label;
145 ++label;
147 *p = '\0';
148 return parmname;
151 void get_xsrf_token(const char *username, const char *pass,
152 const char *formname, time_t xsrf_time, char token_str[33])
154 struct MD5Context md5_ctx;
155 uint8_t token[16];
156 int i;
158 token_str[0] = '\0';
159 ZERO_STRUCT(md5_ctx);
160 MD5Init(&md5_ctx);
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));
167 if (pass != NULL) {
168 MD5Update(&md5_ctx, (uint8_t *)pass, strlen(pass));
171 MD5Final(token, &md5_ctx);
173 for(i = 0; i < sizeof(token); i++) {
174 char tmp[3];
176 snprintf(tmp, sizeof(tmp), "%02x", token[i]);
177 strlcat(token_str, tmp, sizeof(tmp));
181 void print_xsrf_token(const char *username, const char *pass,
182 const char *formname)
184 char token[33];
185 time_t xsrf_time = time(NULL);
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);
194 bool verify_xsrf_token(const char *formname)
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);
206 errno = 0;
207 xsrf_time_ll = strtoll(time_str, &p, 10);
208 if (errno != 0) {
209 return false;
211 if (p == NULL) {
212 return false;
214 if (PTR_DIFF(p, time_str) > strlen(time_str)) {
215 return false;
217 if (xsrf_time_ll > _TYPE_MAXIMUM(time_t)) {
218 return false;
220 if (xsrf_time_ll < _TYPE_MINIMUM(time_t)) {
221 return false;
223 xsrf_time = xsrf_time_ll;
225 if (abs(now - xsrf_time) > XSRF_TIMEOUT) {
226 return false;
229 get_xsrf_token(username, pass, formname, xsrf_time, expected);
230 return (strncmp(expected, token, sizeof(expected)) == 0);
234 /****************************************************************************
235 include a lump of html in a page
236 ****************************************************************************/
237 static int include_html(const char *fname)
239 int fd;
240 char buf[1024];
241 int ret;
243 fd = web_open(fname, O_RDONLY, 0);
245 if (fd == -1) {
246 printf(_("ERROR: Can't open %s"), fname);
247 printf("\n");
248 return 0;
251 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
252 if (write(1, buf, ret) == -1) {
253 break;
257 close(fd);
258 return 1;
261 /****************************************************************************
262 start the page with standard stuff
263 ****************************************************************************/
264 static void print_header(void)
266 if (!cgi_waspost()) {
267 printf("Expires: 0\r\n");
269 printf("Content-type: text/html\r\n\r\n");
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");
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 **************************************************************** */
292 static const char *get_parm_translated(TALLOC_CTX *ctx,
293 const char* pAnchor, const char* pHelp, const char* pLabel)
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;
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;
308 /****************************************************************************
309 finish off the page
310 ****************************************************************************/
311 static void print_footer(void)
313 if (!include_html("include/footer.html")) {
314 printf("\n</BODY>\n</HTML>\n");
318 /****************************************************************************
319 display one editable parameter in a form
320 ****************************************************************************/
321 static void show_parameter(int snum, struct parm_struct *parm)
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();
329 if (parm->p_class == P_LOCAL && snum >= 0) {
330 ptr = lp_local_ptr_by_snum(snum, ptr);
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;
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);
359 TALLOC_FREE(utf8_s1);
360 TALLOC_FREE(utf8_s2);
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))?", ":""));
376 printf("\'\">");
377 break;
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;
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;
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;
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;
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;
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);
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;
441 printf("</td></tr>\n");
442 TALLOC_FREE(ctx);
445 /****************************************************************************
446 display a set of parameters for a service
447 ****************************************************************************/
448 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
450 int i = 0;
451 struct parm_struct *parm;
452 const char *heading = NULL;
453 const char *last_heading = NULL;
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;
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;
468 if (!( parm_filter & FLAG_ADVANCED )) {
469 if (!(parm->flags & FLAG_BASIC)) {
470 void *ptr = parm->ptr;
472 if (parm->p_class == P_LOCAL && snum >= 0) {
473 ptr = lp_local_ptr_by_snum(snum, ptr);
476 switch (parm->type) {
477 case P_CHAR:
478 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
479 break;
481 case P_LIST:
482 if (!str_list_equal(*(const char ***)ptr,
483 (const char **)(parm->def.lvalue))) continue;
484 break;
486 case P_STRING:
487 case P_USTRING:
488 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
489 break;
491 case P_BOOL:
492 case P_BOOLREV:
493 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
494 break;
496 case P_INTEGER:
497 case P_OCTAL:
498 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
499 break;
502 case P_ENUM:
503 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
504 break;
505 case P_SEP:
506 continue;
509 if (printers && !(parm->flags & FLAG_PRINT)) continue;
512 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
514 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
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;
520 show_parameter(snum, parm);
524 /****************************************************************************
525 load the smb.conf file into loadparm.
526 ****************************************************************************/
527 static bool load_config(bool save_def)
529 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
532 /****************************************************************************
533 write a config file
534 ****************************************************************************/
535 static void write_config(FILE *f, bool show_defaults)
537 TALLOC_CTX *ctx = talloc_stackframe();
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));
543 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
545 TALLOC_FREE(ctx);
548 /****************************************************************************
549 save and reload the smb.conf config file
550 ****************************************************************************/
551 static int save_reload(int snum)
553 FILE *f;
554 struct stat st;
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;
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
573 write_config(f, False);
574 if (snum >= 0)
575 lp_dump_one(f, False, snum);
576 fclose(f);
578 lp_kill_all_services();
580 if (!load_config(False)) {
581 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
582 printf("\n");
583 return 0;
585 iNumNonAutoPrintServices = lp_numservices();
586 if (pcap_cache_loaded()) {
587 load_printers(server_event_context(),
588 server_messaging_context());
591 return 1;
594 /****************************************************************************
595 commit one parameter
596 ****************************************************************************/
597 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
599 int i;
600 char *s;
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);
614 lp_do_parameter(snum, parm->label, v);
617 /****************************************************************************
618 commit a set of parameters for a service
619 ****************************************************************************/
620 static void commit_parameters(int snum)
622 int i = 0;
623 struct parm_struct *parm;
624 char *label;
625 const char *v;
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);
634 SAFE_FREE(label);
639 /****************************************************************************
640 spit out the html for a link with an image
641 ****************************************************************************/
642 static void image_link(const char *name, const char *hlink, const char *src)
644 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
645 cgi_baseurl(), hlink, src, name);
648 /****************************************************************************
649 display the main navigation controls at the top of each page along
650 with a title
651 ****************************************************************************/
652 static void show_main_buttons(void)
654 char *p;
656 if ((p = cgi_user_name()) && strcmp(p, "root")) {
657 printf(_("Logged in as <b>%s</b>"), p);
658 printf("<p>\n");
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");
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");
673 image_link(_("Password Management"), "passwd", "images/passwd.gif");
675 printf("<HR>\n");
678 /****************************************************************************
679 * Handle Display/Edit Mode CGI
680 ****************************************************************************/
681 static void ViewModeBoxes(int mode)
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");
692 /****************************************************************************
693 display a welcome page
694 ****************************************************************************/
695 static void welcome_page(void)
697 if (file_exist("help/welcome.html")) {
698 include_html("help/welcome.html");
699 } else {
700 include_html("help/welcome-no-samba-doc.html");
704 /****************************************************************************
705 display the current smb.conf
706 ****************************************************************************/
707 static void viewconfig_page(void)
709 int full_view=0;
710 const char form_name[] = "viewconfig";
712 if (!verify_xsrf_token(form_name)) {
713 goto output_page;
716 if (cgi_variable("full_view")) {
717 full_view = 1;
720 output_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);
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"));
731 printf("<p><pre>");
732 write_config(stdout, full_view);
733 printf("</pre>");
734 printf("</form>\n");
737 /****************************************************************************
738 second screen of the wizard ... Fetch Configuration Parameters
739 ****************************************************************************/
740 static void wizard_params_page(void)
742 unsigned int parm_filter = FLAG_WIZARD;
743 const char form_name[] = "wizard_params";
745 /* Here we first set and commit all the parameters that were selected
746 in the previous screen. */
748 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
750 if (!verify_xsrf_token(form_name)) {
751 goto output_page;
754 if (cgi_variable("Commit")) {
755 commit_parameters(GLOBAL_SECTION_SNUM);
756 save_reload(-1);
759 output_page:
760 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
761 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
763 if (have_write_access) {
764 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
767 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
768 printf("<p>\n");
770 printf("<table>\n");
771 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
772 printf("</table>\n");
773 printf("</form>\n");
776 /****************************************************************************
777 Utility to just rewrite the smb.conf file - effectively just cleans it up
778 ****************************************************************************/
779 static void rewritecfg_file(void)
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"));
786 /****************************************************************************
787 wizard to create/modify the smb.conf file
788 ****************************************************************************/
789 static void wizard_page(void)
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";
799 if (!verify_xsrf_token(form_name)) {
800 goto output_page;
803 if (cgi_variable("Rewrite")) {
804 (void) rewritecfg_file();
805 return;
808 if (cgi_variable("GetWizardParams")){
809 (void) wizard_params_page();
810 return;
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"));
819 /* Plain text passwords are too badly broken - use encrypted passwords only */
820 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
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;
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;
854 /* Have to create Homes share? */
855 if ((HomeExpo == 1) && (have_home == -1)) {
856 const char *unix_share = HOMES_NAME;
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);
868 /* Need to Delete Homes share? */
869 if ((HomeExpo == 0) && (have_home != -1)) {
870 lp_remove_service(have_home);
871 have_home = -1;
874 commit_parameters(GLOBAL_SECTION_SNUM);
875 save_reload(-1);
877 else
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;
885 /* Do we have a homes share? */
886 have_home = lp_servicenumber(HOMES_NAME);
888 if ((winstype == 2) && lp_wins_support())
889 winstype = 3;
891 role = lp_server_role();
893 output_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);
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");
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"));
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"));
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]);
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."));
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");
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");
951 printf("</table></center>");
952 printf("<hr>");
954 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
955 printf("</form>\n");
959 /****************************************************************************
960 display a globals editing page
961 ****************************************************************************/
962 static void globals_page(void)
964 unsigned int parm_filter = FLAG_BASIC;
965 int mode = 0;
966 const char form_name[] = "globals";
968 printf("<H2>%s</H2>\n", _("Global Parameters"));
970 if (!verify_xsrf_token(form_name)) {
971 goto output_page;
974 if (cgi_variable("Commit")) {
975 commit_parameters(GLOBAL_SECTION_SNUM);
976 save_reload(-1);
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;
986 output_page:
987 printf("<form name=\"swatform\" method=post action=globals>\n");
988 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
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;
999 printf("<br>\n");
1000 if (have_write_access) {
1001 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
1002 _("Commit Changes"));
1005 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
1006 _("Reset Values"));
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");
1015 /****************************************************************************
1016 display a shares editing page. share is in unix codepage,
1017 ****************************************************************************/
1018 static void shares_page(void)
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";
1030 printf("<H2>%s</H2>\n", _("Share Parameters"));
1032 if (!verify_xsrf_token(form_name)) {
1033 goto output_page;
1036 if (share)
1037 snum = lp_servicenumber(share);
1040 if (cgi_variable("Commit") && snum >= 0) {
1041 commit_parameters(snum);
1042 save_reload(-1);
1043 snum = lp_servicenumber(share);
1046 if (cgi_variable("Delete") && snum >= 0) {
1047 lp_remove_service(snum);
1048 save_reload(-1);
1049 share = NULL;
1050 snum = -1;
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);
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;
1071 output_page:
1072 printf("<FORM name=\"swatform\" method=post>\n");
1073 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1075 printf("<table>\n");
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;
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);
1101 printf("</select></td>\n");
1102 if (have_write_access) {
1103 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
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");
1113 printf("</table>");
1116 if (snum >= 0) {
1117 if (have_write_access) {
1118 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1121 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1122 printf("<p>\n");
1125 if (snum >= 0) {
1126 printf("<table>\n");
1127 show_parameters(snum, 1, parm_filter, 0);
1128 printf("</table>\n");
1131 printf("</FORM>\n");
1134 /*************************************************************
1135 change a password either locally or remotely
1136 *************************************************************/
1137 static bool change_password(const char *remote_machine, const char *user_name,
1138 const char *old_passwd, const char *new_passwd,
1139 int local_flags)
1141 NTSTATUS ret;
1142 char *err_str = NULL;
1143 char *msg_str = NULL;
1145 if (demo_mode) {
1146 printf("%s\n<p>", _("password change in demo mode rejected"));
1147 return False;
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);
1159 if(!initialize_password_db(True, NULL)) {
1160 printf("%s\n<p>", _("Can't setup password database vectors."));
1161 return False;
1164 ret = local_password_change(user_name, local_flags, new_passwd,
1165 &err_str, &msg_str);
1167 if(msg_str)
1168 printf("%s\n<p>", msg_str);
1169 if(err_str)
1170 printf("%s\n<p>", err_str);
1172 SAFE_FREE(msg_str);
1173 SAFE_FREE(err_str);
1174 return NT_STATUS_IS_OK(ret);
1177 /****************************************************************************
1178 do the stuff required to add or change a password
1179 ****************************************************************************/
1180 static void chg_passwd(void)
1182 const char *host;
1183 bool rslt;
1184 int local_flags = 0;
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;
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
1196 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1199 * If current user is not root, make sure old password has been specified
1200 * If REMOTE change, even root must provide old password
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;
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;
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;
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;
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";
1237 * Set up the local flags.
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);
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);
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."));
1261 return;
1264 /****************************************************************************
1265 display a password editing page
1266 ****************************************************************************/
1267 static void passwd_page(void)
1269 const char *new_name = cgi_user_name();
1270 const char passwd_form[] = "passwd";
1271 const char rpasswd_form[] = "rpasswd";
1273 if (!new_name) new_name = "";
1275 printf("<H2>%s</H2>\n", _("Server Password Management"));
1277 printf("<FORM name=\"swatform\" method=post>\n");
1278 print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form);
1280 printf("<table>\n");
1283 * Create all the dialog boxes for data collection
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);
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");
1298 * Create all the control buttons for requesting action
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"));
1312 printf("<p></FORM>\n");
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();
1324 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1326 printf("<FORM name=\"swatform\" method=post>\n");
1327 print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form);
1329 printf("<table>\n");
1332 * Create all the dialog boxes for data collection
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);
1345 printf("</table>");
1348 * Create all the control buttons for requesting action
1350 printf("<input type=submit name=%s value=\"%s\">",
1351 CHG_R_PASSWD_FLAG, _("Change Password"));
1353 printf("<p></FORM>\n");
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();
1366 /****************************************************************************
1367 display a printers editing page
1368 ****************************************************************************/
1369 static void printers_page(void)
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";
1379 if (!verify_xsrf_token(form_name)) {
1380 goto output_page;
1383 if (share)
1384 snum = lp_servicenumber(share);
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);
1395 if (cgi_variable("Delete") && snum >= 0) {
1396 lp_remove_service(snum);
1397 save_reload(-1);
1398 share = NULL;
1399 snum = -1;
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);
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;
1421 output_page:
1422 printf("<H2>%s</H2>\n", _("Printer Parameters"));
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."));
1431 printf("<FORM name=\"swatform\" method=post>\n");
1432 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
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;
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);
1461 printf("</select></td>");
1462 if (have_write_access) {
1463 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1465 printf("</tr>");
1466 printf("</table>\n");
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>");
1476 if (snum >= 0) {
1477 if (have_write_access) {
1478 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1480 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1481 printf("<p>\n");
1484 if (snum >= 0) {
1485 printf("<table>\n");
1486 show_parameters(snum, 1, parm_filter, 1);
1487 printf("</table>\n");
1489 printf("</FORM>\n");
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
1499 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1501 const char *msgstr;
1502 const char *ret;
1504 msgstr = lang_msg(msgid);
1505 if (!msgstr) {
1506 return msgid;
1509 ret = talloc_strdup(ctx, msgstr);
1511 lang_msg_free(msgstr);
1512 if (!ret) {
1513 return msgid;
1516 return ret;
1520 * main function for SWAT.
1522 int main(int argc, char *argv[])
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
1533 TALLOC_CTX *frame = talloc_stackframe();
1535 fault_setup(NULL);
1536 umask(S_IWGRP | S_IWOTH);
1538 #if defined(HAVE_SET_AUTH_PARAMETERS)
1539 set_auth_parameters(argc, argv);
1540 #endif /* HAVE_SET_AUTH_PARAMETERS */
1542 /* just in case it goes wild ... */
1543 alarm(300);
1545 setlinebuf(stdout);
1547 /* we don't want any SIGPIPE messages */
1548 BlockSignals(True,SIGPIPE);
1550 debug_set_logfile("/dev/null");
1552 /* we don't want stderr screwing us up */
1553 close(2);
1554 open("/dev/null", O_WRONLY);
1555 setup_logging("swat", DEBUG_FILE);
1557 load_case_tables();
1559 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1561 /* Parse command line options */
1563 while(poptGetNextOpt(pc) != -1) { }
1565 poptFreeContext(pc);
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());
1577 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1579 print_header();
1581 cgi_load_variables();
1583 if (!file_exist(get_dyn_CONFIGFILE())) {
1584 have_read_access = True;
1585 have_write_access = True;
1586 } else {
1587 /* check if the authenticated user has write access - if not then
1588 don't show write options */
1589 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1591 /* if the user doesn't have read access to smb.conf then
1592 don't let them view it */
1593 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1596 show_main_buttons();
1598 page = cgi_pathinfo();
1600 /* Root gets full functionality */
1601 if (have_read_access && strcmp(page, "globals")==0) {
1602 globals_page();
1603 } else if (have_read_access && strcmp(page,"shares")==0) {
1604 shares_page();
1605 } else if (have_read_access && strcmp(page,"printers")==0) {
1606 printers_page();
1607 } else if (have_read_access && strcmp(page,"status")==0) {
1608 status_page();
1609 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1610 viewconfig_page();
1611 } else if (strcmp(page,"passwd")==0) {
1612 passwd_page();
1613 } else if (have_read_access && strcmp(page,"wizard")==0) {
1614 wizard_page();
1615 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1616 wizard_params_page();
1617 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1618 rewritecfg_file();
1619 } else {
1620 welcome_page();
1623 print_footer();
1625 TALLOC_FREE(frame);
1626 return 0;
1629 /** @} **/