s3:torture: s/Undefined/SMB_SIGNING_DEFAULT/ s/Required/SMB_SIGNING_REQUIRED/
[Samba/gebeck_regimport.git] / source3 / web / swat.c
blob1ecaa5795d5293292b04f7f799f5f2d25e56e8c9
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"
39 #include "lib/param/loadparm.h"
41 static int demo_mode = False;
42 static int passwd_only = False;
43 static bool have_write_access = False;
44 static bool have_read_access = False;
45 static int iNumNonAutoPrintServices = 0;
48 * Password Management Globals
50 #define SWAT_USER "username"
51 #define OLD_PSWD "old_passwd"
52 #define NEW_PSWD "new_passwd"
53 #define NEW2_PSWD "new2_passwd"
54 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
55 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
56 #define ADD_USER_FLAG "add_user_flag"
57 #define DELETE_USER_FLAG "delete_user_flag"
58 #define DISABLE_USER_FLAG "disable_user_flag"
59 #define ENABLE_USER_FLAG "enable_user_flag"
60 #define RHOST "remote_host"
61 #define XSRF_TOKEN "xsrf"
62 #define XSRF_TIME "xsrf_time"
63 #define XSRF_TIMEOUT 300
65 #define _(x) lang_msg_rotate(talloc_tos(),x)
67 /****************************************************************************
68 ****************************************************************************/
69 static int enum_index(int value, const struct enum_list *enumlist)
71 int i;
72 for (i=0;enumlist[i].name;i++)
73 if (value == enumlist[i].value) break;
74 return(i);
77 static char *fix_backslash(const char *str)
79 static char newstring[1024];
80 char *p = newstring;
82 while (*str) {
83 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
84 else *p++ = *str;
85 ++str;
87 *p = '\0';
88 return newstring;
91 static const char *fix_quotes(TALLOC_CTX *ctx, char *str)
93 char *newstring = NULL;
94 char *p = NULL;
95 size_t newstring_len;
96 int quote_len = strlen("&quot;");
98 /* Count the number of quotes. */
99 newstring_len = 1;
100 p = (char *) str;
101 while (*p) {
102 if ( *p == '\"') {
103 newstring_len += quote_len;
104 } else {
105 newstring_len++;
107 ++p;
109 newstring = talloc_array(ctx, char, newstring_len);
110 if (!newstring) {
111 return "";
113 for (p = newstring; *str; str++) {
114 if ( *str == '\"') {
115 strncpy( p, "&quot;", quote_len);
116 p += quote_len;
117 } else {
118 *p++ = *str;
121 *p = '\0';
122 return newstring;
125 static char *stripspaceupper(const char *str)
127 static char newstring[1024];
128 char *p = newstring;
130 while (*str) {
131 if (*str != ' ') *p++ = toupper_m(*str);
132 ++str;
134 *p = '\0';
135 return newstring;
138 static char *make_parm_name(const char *label)
140 static char parmname[1024];
141 char *p = parmname;
143 while (*label) {
144 if (*label == ' ') *p++ = '_';
145 else *p++ = *label;
146 ++label;
148 *p = '\0';
149 return parmname;
152 void get_xsrf_token(const char *username, const char *pass,
153 const char *formname, time_t xsrf_time, char token_str[33])
155 struct MD5Context md5_ctx;
156 uint8_t token[16];
157 int i;
159 token_str[0] = '\0';
160 ZERO_STRUCT(md5_ctx);
161 MD5Init(&md5_ctx);
163 MD5Update(&md5_ctx, (uint8_t *)formname, strlen(formname));
164 MD5Update(&md5_ctx, (uint8_t *)&xsrf_time, sizeof(time_t));
165 if (username != NULL) {
166 MD5Update(&md5_ctx, (uint8_t *)username, strlen(username));
168 if (pass != NULL) {
169 MD5Update(&md5_ctx, (uint8_t *)pass, strlen(pass));
172 MD5Final(token, &md5_ctx);
174 for(i = 0; i < sizeof(token); i++) {
175 char tmp[3];
177 snprintf(tmp, sizeof(tmp), "%02x", token[i]);
178 strlcat(token_str, tmp, sizeof(tmp));
182 void print_xsrf_token(const char *username, const char *pass,
183 const char *formname)
185 char token[33];
186 time_t xsrf_time = time(NULL);
188 get_xsrf_token(username, pass, formname, xsrf_time, token);
189 printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
190 XSRF_TOKEN, token);
191 printf("<input type=\"hidden\" name=\"%s\" value=\"%lld\">\n",
192 XSRF_TIME, (long long int)xsrf_time);
195 bool verify_xsrf_token(const char *formname)
197 char expected[33];
198 const char *username = cgi_user_name();
199 const char *pass = cgi_user_pass();
200 const char *token = cgi_variable_nonull(XSRF_TOKEN);
201 const char *time_str = cgi_variable_nonull(XSRF_TIME);
202 char *p = NULL;
203 long long xsrf_time_ll = 0;
204 time_t xsrf_time = 0;
205 time_t now = time(NULL);
207 errno = 0;
208 xsrf_time_ll = strtoll(time_str, &p, 10);
209 if (errno != 0) {
210 return false;
212 if (p == NULL) {
213 return false;
215 if (PTR_DIFF(p, time_str) > strlen(time_str)) {
216 return false;
218 if (xsrf_time_ll > _TYPE_MAXIMUM(time_t)) {
219 return false;
221 if (xsrf_time_ll < _TYPE_MINIMUM(time_t)) {
222 return false;
224 xsrf_time = xsrf_time_ll;
226 if (abs(now - xsrf_time) > XSRF_TIMEOUT) {
227 return false;
230 get_xsrf_token(username, pass, formname, xsrf_time, expected);
231 return (strncmp(expected, token, sizeof(expected)) == 0);
235 /****************************************************************************
236 include a lump of html in a page
237 ****************************************************************************/
238 static int include_html(const char *fname)
240 int fd;
241 char buf[1024];
242 int ret;
244 fd = web_open(fname, O_RDONLY, 0);
246 if (fd == -1) {
247 printf(_("ERROR: Can't open %s"), fname);
248 printf("\n");
249 return 0;
252 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
253 if (write(1, buf, ret) == -1) {
254 break;
258 close(fd);
259 return 1;
262 /****************************************************************************
263 start the page with standard stuff
264 ****************************************************************************/
265 static void print_header(void)
267 if (!cgi_waspost()) {
268 printf("Expires: 0\r\n");
270 printf("Content-type: text/html\r\n\r\n");
272 if (!include_html("include/header.html")) {
273 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
274 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
278 /* *******************************************************************
279 show parameter label with translated name in the following form
280 because showing original and translated label in one line looks
281 too long, and showing translated label only is unusable for
282 heavy users.
283 -------------------------------
284 HELP security [combo box][button]
285 SECURITY
286 -------------------------------
287 (capital words are translated by gettext.)
288 if no translation is available, then same form as original is
289 used.
290 "i18n_translated_parm" class is used to change the color of the
291 translated parameter with CSS.
292 **************************************************************** */
293 static const char *get_parm_translated(TALLOC_CTX *ctx,
294 const char* pAnchor, const char* pHelp, const char* pLabel)
296 const char *pTranslated = _(pLabel);
297 char *output;
298 if(strcmp(pLabel, pTranslated) != 0) {
299 output = talloc_asprintf(ctx,
300 "<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>",
301 pAnchor, pHelp, pLabel, pTranslated);
302 return output;
304 output = talloc_asprintf(ctx,
305 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
306 pAnchor, pHelp, pLabel);
307 return output;
309 /****************************************************************************
310 finish off the page
311 ****************************************************************************/
312 static void print_footer(void)
314 if (!include_html("include/footer.html")) {
315 printf("\n</BODY>\n</HTML>\n");
319 /****************************************************************************
320 display one editable parameter in a form
321 ****************************************************************************/
322 static void show_parameter(int snum, struct parm_struct *parm)
324 int i;
325 void *ptr;
326 char *utf8_s1, *utf8_s2;
327 size_t converted_size;
328 TALLOC_CTX *ctx = talloc_stackframe();
330 if (parm->p_class == P_LOCAL && snum >= 0) {
331 ptr = lp_local_ptr_by_snum(snum, parm);
332 } else {
333 ptr = lp_parm_ptr(NULL, parm);
336 printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
337 stripspaceupper(parm->label), _("Help"), parm->label));
338 switch (parm->type) {
339 case P_CHAR:
340 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
341 make_parm_name(parm->label), *(char *)ptr);
342 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
343 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
344 break;
346 case P_LIST:
347 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
348 make_parm_name(parm->label));
349 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
350 char **list = *(char ***)ptr;
351 for (;*list;list++) {
352 /* enclose in HTML encoded quotes if the string contains a space */
353 if ( strchr_m(*list, ' ') ) {
354 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
355 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
356 printf("&quot;%s&quot;%s", utf8_s1, utf8_s2);
357 } else {
358 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
359 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
360 printf("%s%s", utf8_s1, utf8_s2);
362 TALLOC_FREE(utf8_s1);
363 TALLOC_FREE(utf8_s2);
366 printf("\">");
367 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
368 _("Set Default"), make_parm_name(parm->label));
369 if (parm->def.lvalue) {
370 char **list = (char **)(parm->def.lvalue);
371 for (; *list; list++) {
372 /* enclose in HTML encoded quotes if the string contains a space */
373 if ( strchr_m(*list, ' ') )
374 printf("&quot;%s&quot;%s", *list, ((*(list+1))?", ":""));
375 else
376 printf("%s%s", *list, ((*(list+1))?", ":""));
379 printf("\'\">");
380 break;
382 case P_STRING:
383 case P_USTRING:
384 push_utf8_talloc(talloc_tos(), &utf8_s1, *(char **)ptr, &converted_size);
385 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
386 make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
387 TALLOC_FREE(utf8_s1);
388 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
389 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
390 break;
392 case P_BOOL:
393 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
394 printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
395 printf("<option %s>No", (*(bool *)ptr)?"":"selected");
396 printf("</select>");
397 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
398 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
399 break;
401 case P_BOOLREV:
402 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
403 printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
404 printf("<option %s>No", (*(bool *)ptr)?"selected":"");
405 printf("</select>");
406 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
407 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
408 break;
410 case P_INTEGER:
411 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
412 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
413 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
414 break;
416 case P_OCTAL: {
417 char *o;
418 o = octal_string(*(int *)ptr);
419 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
420 make_parm_name(parm->label), o);
421 TALLOC_FREE(o);
422 o = octal_string((int)(parm->def.ivalue));
423 printf("<input type=button value=\"%s\" "
424 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
425 _("Set Default"), make_parm_name(parm->label), o);
426 TALLOC_FREE(o);
427 break;
430 case P_ENUM:
431 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
432 for (i=0;parm->enum_list[i].name;i++) {
433 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
434 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
437 printf("</select>");
438 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
439 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
440 break;
441 case P_SEP:
442 break;
444 printf("</td></tr>\n");
445 TALLOC_FREE(ctx);
448 /****************************************************************************
449 display a set of parameters for a service
450 ****************************************************************************/
451 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
453 int i = 0;
454 struct parm_struct *parm;
455 const char *heading = NULL;
456 const char *last_heading = NULL;
458 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
459 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
460 continue;
461 if (parm->p_class == P_SEPARATOR) {
462 heading = parm->label;
463 continue;
465 if (parm->flags & FLAG_HIDE) continue;
466 if (snum >= 0) {
467 if (printers & !(parm->flags & FLAG_PRINT)) continue;
468 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
471 if (!( parm_filter & FLAG_ADVANCED )) {
472 if (!(parm->flags & FLAG_BASIC)) {
473 void *ptr;
474 if (parm->p_class == P_LOCAL && snum >= 0) {
475 ptr = lp_local_ptr_by_snum(snum, parm);
476 } else {
477 ptr = lp_parm_ptr(NULL, parm);
480 switch (parm->type) {
481 case P_CHAR:
482 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
483 break;
485 case P_LIST:
486 if (!str_list_equal(*(const char ***)ptr,
487 (const char **)(parm->def.lvalue))) continue;
488 break;
490 case P_STRING:
491 case P_USTRING:
492 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
493 break;
495 case P_BOOL:
496 case P_BOOLREV:
497 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
498 break;
500 case P_INTEGER:
501 case P_OCTAL:
502 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
503 break;
506 case P_ENUM:
507 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
508 break;
509 case P_SEP:
510 continue;
513 if (printers && !(parm->flags & FLAG_PRINT)) continue;
516 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
518 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
520 if (heading && heading != last_heading) {
521 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
522 last_heading = heading;
524 show_parameter(snum, parm);
528 /****************************************************************************
529 load the smb.conf file into loadparm.
530 ****************************************************************************/
531 static bool load_config(bool save_def)
533 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
536 /****************************************************************************
537 write a config file
538 ****************************************************************************/
539 static void write_config(FILE *f, bool show_defaults)
541 TALLOC_CTX *ctx = talloc_stackframe();
543 fprintf(f, "# Samba config file created using SWAT\n");
544 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
545 fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
547 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
549 TALLOC_FREE(ctx);
552 /****************************************************************************
553 save and reload the smb.conf config file
554 ****************************************************************************/
555 static int save_reload(int snum)
557 FILE *f;
558 struct stat st;
560 f = sys_fopen(get_dyn_CONFIGFILE(),"w");
561 if (!f) {
562 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
563 printf("\n");
564 return 0;
567 /* just in case they have used the buggy xinetd to create the file */
568 if (fstat(fileno(f), &st) == 0 &&
569 (st.st_mode & S_IWOTH)) {
570 #if defined HAVE_FCHMOD
571 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
572 #else
573 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
574 #endif
577 write_config(f, False);
578 if (snum >= 0)
579 lp_dump_one(f, False, snum);
580 fclose(f);
582 lp_kill_all_services();
584 if (!load_config(False)) {
585 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
586 printf("\n");
587 return 0;
589 iNumNonAutoPrintServices = lp_numservices();
590 if (pcap_cache_loaded()) {
591 load_printers(server_event_context(),
592 server_messaging_context());
595 return 1;
598 /****************************************************************************
599 commit one parameter
600 ****************************************************************************/
601 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
603 int i;
604 char *s;
606 if (snum < 0 && parm->p_class == P_LOCAL) {
607 /* this handles the case where we are changing a local
608 variable globally. We need to change the parameter in
609 all shares where it is currently set to the default */
610 for (i=0;i<lp_numservices();i++) {
611 s = lp_servicename(i);
612 if (s && (*s) && lp_is_default(i, parm)) {
613 lp_do_parameter(i, parm->label, v);
618 lp_do_parameter(snum, parm->label, v);
621 /****************************************************************************
622 commit a set of parameters for a service
623 ****************************************************************************/
624 static void commit_parameters(int snum)
626 int i = 0;
627 struct parm_struct *parm;
628 char *label;
629 const char *v;
631 while ((parm = lp_next_parameter(snum, &i, 1))) {
632 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
633 if ((v = cgi_variable(label)) != NULL) {
634 if (parm->flags & FLAG_HIDE)
635 continue;
636 commit_parameter(snum, parm, v);
638 SAFE_FREE(label);
643 /****************************************************************************
644 spit out the html for a link with an image
645 ****************************************************************************/
646 static void image_link(const char *name, const char *hlink, const char *src)
648 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
649 cgi_baseurl(), hlink, src, name);
652 /****************************************************************************
653 display the main navigation controls at the top of each page along
654 with a title
655 ****************************************************************************/
656 static void show_main_buttons(void)
658 char *p;
660 if ((p = cgi_user_name()) && strcmp(p, "root")) {
661 printf(_("Logged in as <b>%s</b>"), p);
662 printf("<p>\n");
665 image_link(_("Home"), "", "images/home.gif");
666 if (have_write_access) {
667 image_link(_("Globals"), "globals", "images/globals.gif");
668 image_link(_("Shares"), "shares", "images/shares.gif");
669 image_link(_("Printers"), "printers", "images/printers.gif");
670 image_link(_("Wizard"), "wizard", "images/wizard.gif");
672 /* root always gets all buttons, otherwise look for -P */
673 if ( have_write_access || (!passwd_only && have_read_access) ) {
674 image_link(_("Status"), "status", "images/status.gif");
675 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
677 image_link(_("Password Management"), "passwd", "images/passwd.gif");
679 printf("<HR>\n");
682 /****************************************************************************
683 * Handle Display/Edit Mode CGI
684 ****************************************************************************/
685 static void ViewModeBoxes(int mode)
687 printf("<p>%s:&nbsp;\n", _("Current View Is"));
688 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
689 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
690 printf("<br>%s:&nbsp;\n", _("Change View To"));
691 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
692 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
693 printf("</p><br>\n");
696 /****************************************************************************
697 display a welcome page
698 ****************************************************************************/
699 static void welcome_page(void)
701 if (file_exist("help/welcome.html")) {
702 include_html("help/welcome.html");
703 } else {
704 include_html("help/welcome-no-samba-doc.html");
708 /****************************************************************************
709 display the current smb.conf
710 ****************************************************************************/
711 static void viewconfig_page(void)
713 int full_view=0;
714 const char form_name[] = "viewconfig";
716 if (!verify_xsrf_token(form_name)) {
717 goto output_page;
720 if (cgi_variable("full_view")) {
721 full_view = 1;
724 output_page:
725 printf("<H2>%s</H2>\n", _("Current Config"));
726 printf("<form method=post>\n");
727 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
729 if (full_view) {
730 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
731 } else {
732 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
735 printf("<p><pre>");
736 write_config(stdout, full_view);
737 printf("</pre>");
738 printf("</form>\n");
741 /****************************************************************************
742 second screen of the wizard ... Fetch Configuration Parameters
743 ****************************************************************************/
744 static void wizard_params_page(void)
746 unsigned int parm_filter = FLAG_WIZARD;
747 const char form_name[] = "wizard_params";
749 /* Here we first set and commit all the parameters that were selected
750 in the previous screen. */
752 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
754 if (!verify_xsrf_token(form_name)) {
755 goto output_page;
758 if (cgi_variable("Commit")) {
759 commit_parameters(GLOBAL_SECTION_SNUM);
760 save_reload(-1);
763 output_page:
764 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
765 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
767 if (have_write_access) {
768 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
771 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
772 printf("<p>\n");
774 printf("<table>\n");
775 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
776 printf("</table>\n");
777 printf("</form>\n");
780 /****************************************************************************
781 Utility to just rewrite the smb.conf file - effectively just cleans it up
782 ****************************************************************************/
783 static void rewritecfg_file(void)
785 commit_parameters(GLOBAL_SECTION_SNUM);
786 save_reload(-1);
787 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
790 /****************************************************************************
791 wizard to create/modify the smb.conf file
792 ****************************************************************************/
793 static void wizard_page(void)
795 /* Set some variables to collect data from smb.conf */
796 int role = 0;
797 int winstype = 0;
798 int have_home = -1;
799 int HomeExpo = 0;
800 int SerType = 0;
801 const char form_name[] = "wizard";
803 if (!verify_xsrf_token(form_name)) {
804 goto output_page;
807 if (cgi_variable("Rewrite")) {
808 (void) rewritecfg_file();
809 return;
812 if (cgi_variable("GetWizardParams")){
813 (void) wizard_params_page();
814 return;
817 if (cgi_variable("Commit")){
818 SerType = atoi(cgi_variable_nonull("ServerType"));
819 winstype = atoi(cgi_variable_nonull("WINSType"));
820 have_home = lp_servicenumber(HOMES_NAME);
821 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
823 /* Plain text passwords are too badly broken - use encrypted passwords only */
824 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
826 switch ( SerType ){
827 case 0:
828 /* Stand-alone Server */
829 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
830 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
831 break;
832 case 1:
833 /* Domain Member */
834 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
835 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
836 break;
837 case 2:
838 /* Domain Controller */
839 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
840 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
841 break;
843 switch ( winstype ) {
844 case 0:
845 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
846 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
847 break;
848 case 1:
849 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
850 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
851 break;
852 case 2:
853 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
854 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
855 break;
858 /* Have to create Homes share? */
859 if ((HomeExpo == 1) && (have_home == -1)) {
860 const char *unix_share = HOMES_NAME;
862 load_config(False);
863 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
864 have_home = lp_servicenumber(HOMES_NAME);
865 lp_do_parameter( have_home, "read only", "No");
866 lp_do_parameter( have_home, "valid users", "%S");
867 lp_do_parameter( have_home, "browseable", "No");
868 commit_parameters(have_home);
869 save_reload(have_home);
872 /* Need to Delete Homes share? */
873 if ((HomeExpo == 0) && (have_home != -1)) {
874 lp_remove_service(have_home);
875 have_home = -1;
878 commit_parameters(GLOBAL_SECTION_SNUM);
879 save_reload(-1);
881 else
883 /* Now determine smb.conf WINS settings */
884 if (lp_we_are_a_wins_server())
885 winstype = 1;
886 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
887 winstype = 2;
889 /* Do we have a homes share? */
890 have_home = lp_servicenumber(HOMES_NAME);
892 if ((winstype == 2) && lp_we_are_a_wins_server())
893 winstype = 3;
895 role = lp_server_role();
897 output_page:
898 /* Here we go ... */
899 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
900 printf("<form method=post action=wizard>\n");
901 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
903 if (have_write_access) {
904 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
905 printf("%s", _("The same will happen if you press the commit button."));
906 printf("<br><br>\n");
907 printf("<center>");
908 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
909 printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
910 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
911 printf("</center>\n");
914 printf("<hr>");
915 printf("<center><table border=0>");
916 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
917 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
918 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
919 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
920 printf("</tr>\n");
921 if (role == ROLE_DOMAIN_BDC) {
922 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
924 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
925 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
926 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
927 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
928 printf("</tr>\n");
929 printf("<tr><td></td><td></td><td></td><td>%s&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
931 /* Print out the list of wins servers */
932 if(lp_wins_server_list()) {
933 int i;
934 const char **wins_servers = lp_wins_server_list();
935 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
938 printf("\"></td></tr>\n");
939 if (winstype == 3) {
940 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"));
941 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
943 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
944 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
945 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
946 printf("<td></td></tr>\n");
948 /* Enable this when we are ready ....
949 * printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
950 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
951 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
952 * printf("<td></td></tr>\n");
955 printf("</table></center>");
956 printf("<hr>");
958 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
959 printf("</form>\n");
963 /****************************************************************************
964 display a globals editing page
965 ****************************************************************************/
966 static void globals_page(void)
968 unsigned int parm_filter = FLAG_BASIC;
969 int mode = 0;
970 const char form_name[] = "globals";
972 printf("<H2>%s</H2>\n", _("Global Parameters"));
974 if (!verify_xsrf_token(form_name)) {
975 goto output_page;
978 if (cgi_variable("Commit")) {
979 commit_parameters(GLOBAL_SECTION_SNUM);
980 save_reload(-1);
983 if ( cgi_variable("ViewMode") )
984 mode = atoi(cgi_variable_nonull("ViewMode"));
985 if ( cgi_variable("BasicMode"))
986 mode = 0;
987 if ( cgi_variable("AdvMode"))
988 mode = 1;
990 output_page:
991 printf("<form name=\"swatform\" method=post action=globals>\n");
992 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
994 ViewModeBoxes( mode );
995 switch ( mode ) {
996 case 0:
997 parm_filter = FLAG_BASIC;
998 break;
999 case 1:
1000 parm_filter = FLAG_ADVANCED;
1001 break;
1003 printf("<br>\n");
1004 if (have_write_access) {
1005 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
1006 _("Commit Changes"));
1009 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
1010 _("Reset Values"));
1012 printf("<p>\n");
1013 printf("<table>\n");
1014 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
1015 printf("</table>\n");
1016 printf("</form>\n");
1019 /****************************************************************************
1020 display a shares editing page. share is in unix codepage,
1021 ****************************************************************************/
1022 static void shares_page(void)
1024 const char *share = cgi_variable("share");
1025 char *s;
1026 char *utf8_s;
1027 int snum = -1;
1028 int i;
1029 int mode = 0;
1030 unsigned int parm_filter = FLAG_BASIC;
1031 size_t converted_size;
1032 const char form_name[] = "shares";
1034 printf("<H2>%s</H2>\n", _("Share Parameters"));
1036 if (!verify_xsrf_token(form_name)) {
1037 goto output_page;
1040 if (share)
1041 snum = lp_servicenumber(share);
1044 if (cgi_variable("Commit") && snum >= 0) {
1045 commit_parameters(snum);
1046 save_reload(-1);
1047 snum = lp_servicenumber(share);
1050 if (cgi_variable("Delete") && snum >= 0) {
1051 lp_remove_service(snum);
1052 save_reload(-1);
1053 share = NULL;
1054 snum = -1;
1057 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1058 snum = lp_servicenumber(share);
1059 if (snum < 0) {
1060 load_config(False);
1061 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1062 snum = lp_servicenumber(share);
1063 save_reload(snum);
1064 snum = lp_servicenumber(share);
1068 if ( cgi_variable("ViewMode") )
1069 mode = atoi(cgi_variable_nonull("ViewMode"));
1070 if ( cgi_variable("BasicMode"))
1071 mode = 0;
1072 if ( cgi_variable("AdvMode"))
1073 mode = 1;
1075 output_page:
1076 printf("<FORM name=\"swatform\" method=post>\n");
1077 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1079 printf("<table>\n");
1081 ViewModeBoxes( mode );
1082 switch ( mode ) {
1083 case 0:
1084 parm_filter = FLAG_BASIC;
1085 break;
1086 case 1:
1087 parm_filter = FLAG_ADVANCED;
1088 break;
1090 printf("<br><tr>\n");
1091 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1092 printf("<td><select name=share>\n");
1093 if (snum < 0)
1094 printf("<option value=\" \"> \n");
1095 for (i=0;i<lp_numservices();i++) {
1096 s = lp_servicename(i);
1097 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
1098 push_utf8_talloc(talloc_tos(), &utf8_s, s, &converted_size);
1099 printf("<option %s value=\"%s\">%s\n",
1100 (share && strcmp(share,s)==0)?"SELECTED":"",
1101 utf8_s, utf8_s);
1102 TALLOC_FREE(utf8_s);
1105 printf("</select></td>\n");
1106 if (have_write_access) {
1107 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1109 printf("</tr>\n");
1110 printf("</table>");
1111 printf("<table>");
1112 if (have_write_access) {
1113 printf("<tr>\n");
1114 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1115 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1117 printf("</table>");
1120 if (snum >= 0) {
1121 if (have_write_access) {
1122 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1125 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1126 printf("<p>\n");
1129 if (snum >= 0) {
1130 printf("<table>\n");
1131 show_parameters(snum, 1, parm_filter, 0);
1132 printf("</table>\n");
1135 printf("</FORM>\n");
1138 /*************************************************************
1139 change a password either locally or remotely
1140 *************************************************************/
1141 static bool change_password(const char *remote_machine, const char *user_name,
1142 const char *old_passwd, const char *new_passwd,
1143 int local_flags)
1145 NTSTATUS ret;
1146 char *err_str = NULL;
1147 char *msg_str = NULL;
1149 if (demo_mode) {
1150 printf("%s\n<p>", _("password change in demo mode rejected"));
1151 return False;
1154 if (remote_machine != NULL) {
1155 ret = remote_password_change(remote_machine, user_name,
1156 old_passwd, new_passwd, &err_str);
1157 if (err_str != NULL)
1158 printf("%s\n<p>", err_str);
1159 SAFE_FREE(err_str);
1160 return NT_STATUS_IS_OK(ret);
1163 if(!initialize_password_db(True, NULL)) {
1164 printf("%s\n<p>", _("Can't setup password database vectors."));
1165 return False;
1168 ret = local_password_change(user_name, local_flags, new_passwd,
1169 &err_str, &msg_str);
1171 if(msg_str)
1172 printf("%s\n<p>", msg_str);
1173 if(err_str)
1174 printf("%s\n<p>", err_str);
1176 SAFE_FREE(msg_str);
1177 SAFE_FREE(err_str);
1178 return NT_STATUS_IS_OK(ret);
1181 /****************************************************************************
1182 do the stuff required to add or change a password
1183 ****************************************************************************/
1184 static void chg_passwd(void)
1186 const char *host;
1187 bool rslt;
1188 int local_flags = 0;
1190 /* Make sure users name has been specified */
1191 if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1192 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1193 return;
1197 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1198 * so if that's what we're doing, skip the rest of the checks
1200 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1203 * If current user is not root, make sure old password has been specified
1204 * If REMOTE change, even root must provide old password
1206 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1207 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1208 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1209 return;
1212 /* If changing a users password on a remote hosts we have to know what host */
1213 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1214 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1215 return;
1218 /* Make sure new passwords have been specified */
1219 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1220 (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1221 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1222 return;
1225 /* Make sure new passwords was typed correctly twice */
1226 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1227 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1228 return;
1232 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1233 host = cgi_variable(RHOST);
1234 } else if (am_root()) {
1235 host = NULL;
1236 } else {
1237 host = "127.0.0.1";
1241 * Set up the local flags.
1244 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1245 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1246 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1247 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1248 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1249 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1251 rslt = change_password(host,
1252 cgi_variable_nonull(SWAT_USER),
1253 cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1254 local_flags);
1256 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1257 printf("<p>");
1258 if (rslt == True) {
1259 printf("%s\n", _(" The passwd has been changed."));
1260 } else {
1261 printf("%s\n", _(" The passwd has NOT been changed."));
1265 return;
1268 /****************************************************************************
1269 display a password editing page
1270 ****************************************************************************/
1271 static void passwd_page(void)
1273 const char *new_name = cgi_user_name();
1274 const char passwd_form[] = "passwd";
1275 const char rpasswd_form[] = "rpasswd";
1277 if (!new_name) new_name = "";
1279 printf("<H2>%s</H2>\n", _("Server Password Management"));
1281 printf("<FORM name=\"swatform\" method=post>\n");
1282 print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form);
1284 printf("<table>\n");
1287 * Create all the dialog boxes for data collection
1289 printf("<tr><td> %s : </td>\n", _("User Name"));
1290 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1291 if (!am_root()) {
1292 printf("<tr><td> %s : </td>\n", _("Old Password"));
1293 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1295 printf("<tr><td> %s : </td>\n", _("New Password"));
1296 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1297 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1298 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1299 printf("</table>\n");
1302 * Create all the control buttons for requesting action
1304 printf("<input type=submit name=%s value=\"%s\">\n",
1305 CHG_S_PASSWD_FLAG, _("Change Password"));
1306 if (demo_mode || am_root()) {
1307 printf("<input type=submit name=%s value=\"%s\">\n",
1308 ADD_USER_FLAG, _("Add New User"));
1309 printf("<input type=submit name=%s value=\"%s\">\n",
1310 DELETE_USER_FLAG, _("Delete User"));
1311 printf("<input type=submit name=%s value=\"%s\">\n",
1312 DISABLE_USER_FLAG, _("Disable User"));
1313 printf("<input type=submit name=%s value=\"%s\">\n",
1314 ENABLE_USER_FLAG, _("Enable User"));
1316 printf("<p></FORM>\n");
1319 * Do some work if change, add, disable or enable was
1320 * requested. It could be this is the first time through this
1321 * code, so there isn't anything to do. */
1322 if (verify_xsrf_token(passwd_form) &&
1323 ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1324 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG)))) {
1325 chg_passwd();
1328 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1330 printf("<FORM name=\"swatform\" method=post>\n");
1331 print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form);
1333 printf("<table>\n");
1336 * Create all the dialog boxes for data collection
1338 printf("<tr><td> %s : </td>\n", _("User Name"));
1339 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1340 printf("<tr><td> %s : </td>\n", _("Old Password"));
1341 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1342 printf("<tr><td> %s : </td>\n", _("New Password"));
1343 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1344 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1345 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1346 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1347 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1349 printf("</table>");
1352 * Create all the control buttons for requesting action
1354 printf("<input type=submit name=%s value=\"%s\">",
1355 CHG_R_PASSWD_FLAG, _("Change Password"));
1357 printf("<p></FORM>\n");
1360 * Do some work if a request has been made to change the
1361 * password somewhere other than the server. It could be this
1362 * is the first time through this code, so there isn't
1363 * anything to do. */
1364 if (verify_xsrf_token(passwd_form) && cgi_variable(CHG_R_PASSWD_FLAG)) {
1365 chg_passwd();
1370 /****************************************************************************
1371 display a printers editing page
1372 ****************************************************************************/
1373 static void printers_page(void)
1375 const char *share = cgi_variable("share");
1376 char *s;
1377 int snum=-1;
1378 int i;
1379 int mode = 0;
1380 unsigned int parm_filter = FLAG_BASIC;
1381 const char form_name[] = "printers";
1383 if (!verify_xsrf_token(form_name)) {
1384 goto output_page;
1387 if (share)
1388 snum = lp_servicenumber(share);
1390 if (cgi_variable("Commit") && snum >= 0) {
1391 commit_parameters(snum);
1392 if (snum >= iNumNonAutoPrintServices)
1393 save_reload(snum);
1394 else
1395 save_reload(-1);
1396 snum = lp_servicenumber(share);
1399 if (cgi_variable("Delete") && snum >= 0) {
1400 lp_remove_service(snum);
1401 save_reload(-1);
1402 share = NULL;
1403 snum = -1;
1406 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1407 snum = lp_servicenumber(share);
1408 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1409 load_config(False);
1410 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1411 snum = lp_servicenumber(share);
1412 lp_do_parameter(snum, "print ok", "Yes");
1413 save_reload(snum);
1414 snum = lp_servicenumber(share);
1418 if ( cgi_variable("ViewMode") )
1419 mode = atoi(cgi_variable_nonull("ViewMode"));
1420 if ( cgi_variable("BasicMode"))
1421 mode = 0;
1422 if ( cgi_variable("AdvMode"))
1423 mode = 1;
1425 output_page:
1426 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1428 printf("<H3>%s</H3>\n", _("Important Note:"));
1429 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1430 printf("%s",_("are autoloaded printers from "));
1431 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1432 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1435 printf("<FORM name=\"swatform\" method=post>\n");
1436 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1438 ViewModeBoxes( mode );
1439 switch ( mode ) {
1440 case 0:
1441 parm_filter = FLAG_BASIC;
1442 break;
1443 case 1:
1444 parm_filter = FLAG_ADVANCED;
1445 break;
1447 printf("<table>\n");
1448 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1449 printf("<td><select name=\"share\">\n");
1450 if (snum < 0 || !lp_print_ok(snum))
1451 printf("<option value=\" \"> \n");
1452 for (i=0;i<lp_numservices();i++) {
1453 s = lp_servicename(i);
1454 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1455 if (i >= iNumNonAutoPrintServices)
1456 printf("<option %s value=\"%s\">[*]%s\n",
1457 (share && strcmp(share,s)==0)?"SELECTED":"",
1458 s, s);
1459 else
1460 printf("<option %s value=\"%s\">%s\n",
1461 (share && strcmp(share,s)==0)?"SELECTED":"",
1462 s, s);
1465 printf("</select></td>");
1466 if (have_write_access) {
1467 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1469 printf("</tr>");
1470 printf("</table>\n");
1472 if (have_write_access) {
1473 printf("<table>\n");
1474 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1475 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1476 printf("</table>");
1480 if (snum >= 0) {
1481 if (have_write_access) {
1482 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1484 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1485 printf("<p>\n");
1488 if (snum >= 0) {
1489 printf("<table>\n");
1490 show_parameters(snum, 1, parm_filter, 1);
1491 printf("</table>\n");
1493 printf("</FORM>\n");
1497 when the _() translation macro is used there is no obvious place to free
1498 the resulting string and there is no easy way to give a static pointer.
1499 All we can do is rotate between some static buffers and hope a single d_printf()
1500 doesn't have more calls to _() than the number of buffers
1503 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1505 const char *msgstr;
1506 const char *ret;
1508 msgstr = lang_msg(msgid);
1509 if (!msgstr) {
1510 return msgid;
1513 ret = talloc_strdup(ctx, msgstr);
1515 lang_msg_free(msgstr);
1516 if (!ret) {
1517 return msgid;
1520 return ret;
1524 * main function for SWAT.
1526 int main(int argc, char *argv[])
1528 const char *page;
1529 poptContext pc;
1530 struct poptOption long_options[] = {
1531 POPT_AUTOHELP
1532 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1533 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1534 POPT_COMMON_SAMBA
1535 POPT_TABLEEND
1537 TALLOC_CTX *frame = talloc_stackframe();
1539 fault_setup();
1540 umask(S_IWGRP | S_IWOTH);
1542 #if defined(HAVE_SET_AUTH_PARAMETERS)
1543 set_auth_parameters(argc, argv);
1544 #endif /* HAVE_SET_AUTH_PARAMETERS */
1546 /* just in case it goes wild ... */
1547 alarm(300);
1549 setlinebuf(stdout);
1551 /* we don't want any SIGPIPE messages */
1552 BlockSignals(True,SIGPIPE);
1554 debug_set_logfile("/dev/null");
1556 /* we don't want stderr screwing us up */
1557 close(2);
1558 open("/dev/null", O_WRONLY);
1559 setup_logging("swat", DEBUG_FILE);
1561 load_case_tables();
1563 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1565 /* Parse command line options */
1567 while(poptGetNextOpt(pc) != -1) { }
1569 poptFreeContext(pc);
1571 /* This should set a more apporiate log file */
1572 load_config(True);
1573 reopen_logs();
1574 load_interfaces();
1575 iNumNonAutoPrintServices = lp_numservices();
1576 if (pcap_cache_loaded()) {
1577 load_printers(server_event_context(),
1578 server_messaging_context());
1581 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1583 print_header();
1585 cgi_load_variables();
1587 if (!file_exist(get_dyn_CONFIGFILE())) {
1588 have_read_access = True;
1589 have_write_access = True;
1590 } else {
1591 /* check if the authenticated user has write access - if not then
1592 don't show write options */
1593 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1595 /* if the user doesn't have read access to smb.conf then
1596 don't let them view it */
1597 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1600 show_main_buttons();
1602 page = cgi_pathinfo();
1604 /* Root gets full functionality */
1605 if (have_read_access && strcmp(page, "globals")==0) {
1606 globals_page();
1607 } else if (have_read_access && strcmp(page,"shares")==0) {
1608 shares_page();
1609 } else if (have_read_access && strcmp(page,"printers")==0) {
1610 printers_page();
1611 } else if (have_read_access && strcmp(page,"status")==0) {
1612 status_page();
1613 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1614 viewconfig_page();
1615 } else if (strcmp(page,"passwd")==0) {
1616 passwd_page();
1617 } else if (have_read_access && strcmp(page,"wizard")==0) {
1618 wizard_page();
1619 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1620 wizard_params_page();
1621 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1622 rewritecfg_file();
1623 } else {
1624 welcome_page();
1627 print_footer();
1629 TALLOC_FREE(frame);
1630 return 0;
1633 /** @} **/