s4:samba-tool: add simple command "group list"
[Samba/vl.git] / source3 / web / swat.c
blob34974b400f1b59abc45b720313d277d645ef3ec2
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"
40 #include "messages.h"
42 static int demo_mode = False;
43 static int passwd_only = False;
44 static bool have_write_access = False;
45 static bool have_read_access = False;
46 static int iNumNonAutoPrintServices = 0;
49 * Password Management Globals
51 #define SWAT_USER "username"
52 #define OLD_PSWD "old_passwd"
53 #define NEW_PSWD "new_passwd"
54 #define NEW2_PSWD "new2_passwd"
55 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
56 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
57 #define ADD_USER_FLAG "add_user_flag"
58 #define DELETE_USER_FLAG "delete_user_flag"
59 #define DISABLE_USER_FLAG "disable_user_flag"
60 #define ENABLE_USER_FLAG "enable_user_flag"
61 #define RHOST "remote_host"
62 #define XSRF_TOKEN "xsrf"
63 #define XSRF_TIME "xsrf_time"
64 #define XSRF_TIMEOUT 300
66 #define _(x) lang_msg_rotate(talloc_tos(),x)
68 /****************************************************************************
69 ****************************************************************************/
70 static int enum_index(int value, const struct enum_list *enumlist)
72 int i;
73 for (i=0;enumlist[i].name;i++)
74 if (value == enumlist[i].value) break;
75 return(i);
78 static char *fix_backslash(const char *str)
80 static char newstring[1024];
81 char *p = newstring;
83 while (*str) {
84 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
85 else *p++ = *str;
86 ++str;
88 *p = '\0';
89 return newstring;
92 static const char *fix_quotes(TALLOC_CTX *ctx, char *str)
94 char *newstring = NULL;
95 char *p = NULL;
96 size_t newstring_len;
97 int quote_len = strlen("&quot;");
99 /* Count the number of quotes. */
100 newstring_len = 1;
101 p = (char *) str;
102 while (*p) {
103 if ( *p == '\"') {
104 newstring_len += quote_len;
105 } else {
106 newstring_len++;
108 ++p;
110 newstring = talloc_array(ctx, char, newstring_len);
111 if (!newstring) {
112 return "";
114 for (p = newstring; *str; str++) {
115 if ( *str == '\"') {
116 strncpy( p, "&quot;", quote_len);
117 p += quote_len;
118 } else {
119 *p++ = *str;
122 *p = '\0';
123 return newstring;
126 static char *stripspaceupper(const char *str)
128 static char newstring[1024];
129 char *p = newstring;
131 while (*str) {
132 if (*str != ' ') *p++ = toupper_m(*str);
133 ++str;
135 *p = '\0';
136 return newstring;
139 static char *make_parm_name(const char *label)
141 static char parmname[1024];
142 char *p = parmname;
144 while (*label) {
145 if (*label == ' ') *p++ = '_';
146 else *p++ = *label;
147 ++label;
149 *p = '\0';
150 return parmname;
153 void get_xsrf_token(const char *username, const char *pass,
154 const char *formname, time_t xsrf_time, char token_str[33])
156 struct MD5Context md5_ctx;
157 uint8_t token[16];
158 int i;
160 token_str[0] = '\0';
161 ZERO_STRUCT(md5_ctx);
162 MD5Init(&md5_ctx);
164 MD5Update(&md5_ctx, (uint8_t *)formname, strlen(formname));
165 MD5Update(&md5_ctx, (uint8_t *)&xsrf_time, sizeof(time_t));
166 if (username != NULL) {
167 MD5Update(&md5_ctx, (uint8_t *)username, strlen(username));
169 if (pass != NULL) {
170 MD5Update(&md5_ctx, (uint8_t *)pass, strlen(pass));
173 MD5Final(token, &md5_ctx);
175 for(i = 0; i < sizeof(token); i++) {
176 char tmp[3];
178 snprintf(tmp, sizeof(tmp), "%02x", token[i]);
179 strlcat(token_str, tmp, sizeof(tmp));
183 void print_xsrf_token(const char *username, const char *pass,
184 const char *formname)
186 char token[33];
187 time_t xsrf_time = time(NULL);
189 get_xsrf_token(username, pass, formname, xsrf_time, token);
190 printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
191 XSRF_TOKEN, token);
192 printf("<input type=\"hidden\" name=\"%s\" value=\"%lld\">\n",
193 XSRF_TIME, (long long int)xsrf_time);
196 bool verify_xsrf_token(const char *formname)
198 char expected[33];
199 const char *username = cgi_user_name();
200 const char *pass = cgi_user_pass();
201 const char *token = cgi_variable_nonull(XSRF_TOKEN);
202 const char *time_str = cgi_variable_nonull(XSRF_TIME);
203 char *p = NULL;
204 long long xsrf_time_ll = 0;
205 time_t xsrf_time = 0;
206 time_t now = time(NULL);
208 errno = 0;
209 xsrf_time_ll = strtoll(time_str, &p, 10);
210 if (errno != 0) {
211 return false;
213 if (p == NULL) {
214 return false;
216 if (PTR_DIFF(p, time_str) > strlen(time_str)) {
217 return false;
219 if (xsrf_time_ll > _TYPE_MAXIMUM(time_t)) {
220 return false;
222 if (xsrf_time_ll < _TYPE_MINIMUM(time_t)) {
223 return false;
225 xsrf_time = xsrf_time_ll;
227 if (abs(now - xsrf_time) > XSRF_TIMEOUT) {
228 return false;
231 get_xsrf_token(username, pass, formname, xsrf_time, expected);
232 return (strncmp(expected, token, sizeof(expected)) == 0);
236 /****************************************************************************
237 include a lump of html in a page
238 ****************************************************************************/
239 static int include_html(const char *fname)
241 int fd;
242 char buf[1024];
243 int ret;
245 fd = web_open(fname, O_RDONLY, 0);
247 if (fd == -1) {
248 printf(_("ERROR: Can't open %s"), fname);
249 printf("\n");
250 return 0;
253 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
254 if (write(1, buf, ret) == -1) {
255 break;
259 close(fd);
260 return 1;
263 /****************************************************************************
264 start the page with standard stuff
265 ****************************************************************************/
266 static void print_header(void)
268 if (!cgi_waspost()) {
269 printf("Expires: 0\r\n");
271 printf("Content-type: text/html\r\n\r\n");
273 if (!include_html("include/header.html")) {
274 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
275 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
279 /* *******************************************************************
280 show parameter label with translated name in the following form
281 because showing original and translated label in one line looks
282 too long, and showing translated label only is unusable for
283 heavy users.
284 -------------------------------
285 HELP security [combo box][button]
286 SECURITY
287 -------------------------------
288 (capital words are translated by gettext.)
289 if no translation is available, then same form as original is
290 used.
291 "i18n_translated_parm" class is used to change the color of the
292 translated parameter with CSS.
293 **************************************************************** */
294 static const char *get_parm_translated(TALLOC_CTX *ctx,
295 const char* pAnchor, const char* pHelp, const char* pLabel)
297 const char *pTranslated = _(pLabel);
298 char *output;
299 if(strcmp(pLabel, pTranslated) != 0) {
300 output = talloc_asprintf(ctx,
301 "<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>",
302 pAnchor, pHelp, pLabel, pTranslated);
303 return output;
305 output = talloc_asprintf(ctx,
306 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
307 pAnchor, pHelp, pLabel);
308 return output;
310 /****************************************************************************
311 finish off the page
312 ****************************************************************************/
313 static void print_footer(void)
315 if (!include_html("include/footer.html")) {
316 printf("\n</BODY>\n</HTML>\n");
320 /****************************************************************************
321 display one editable parameter in a form
322 ****************************************************************************/
323 static void show_parameter(int snum, struct parm_struct *parm)
325 int i;
326 void *ptr;
327 char *utf8_s1, *utf8_s2;
328 size_t converted_size;
329 TALLOC_CTX *ctx = talloc_stackframe();
331 if (parm->p_class == P_LOCAL && snum >= 0) {
332 ptr = lp_local_ptr_by_snum(snum, parm);
333 } else {
334 ptr = lp_parm_ptr(NULL, parm);
337 printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
338 stripspaceupper(parm->label), _("Help"), parm->label));
339 switch (parm->type) {
340 case P_CHAR:
341 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
342 make_parm_name(parm->label), *(char *)ptr);
343 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
344 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
345 break;
347 case P_LIST:
348 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
349 make_parm_name(parm->label));
350 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
351 char **list = *(char ***)ptr;
352 for (;*list;list++) {
353 /* enclose in HTML encoded quotes if the string contains a space */
354 if ( strchr_m(*list, ' ') ) {
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("&quot;%s&quot;%s", utf8_s1, utf8_s2);
358 } else {
359 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
360 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
361 printf("%s%s", utf8_s1, utf8_s2);
363 TALLOC_FREE(utf8_s1);
364 TALLOC_FREE(utf8_s2);
367 printf("\">");
368 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
369 _("Set Default"), make_parm_name(parm->label));
370 if (parm->def.lvalue) {
371 char **list = (char **)(parm->def.lvalue);
372 for (; *list; list++) {
373 /* enclose in HTML encoded quotes if the string contains a space */
374 if ( strchr_m(*list, ' ') )
375 printf("&quot;%s&quot;%s", *list, ((*(list+1))?", ":""));
376 else
377 printf("%s%s", *list, ((*(list+1))?", ":""));
380 printf("\'\">");
381 break;
383 case P_STRING:
384 case P_USTRING:
385 push_utf8_talloc(talloc_tos(), &utf8_s1, *(char **)ptr, &converted_size);
386 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
387 make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
388 TALLOC_FREE(utf8_s1);
389 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
390 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
391 break;
393 case P_BOOL:
394 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
395 printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
396 printf("<option %s>No", (*(bool *)ptr)?"":"selected");
397 printf("</select>");
398 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
399 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
400 break;
402 case P_BOOLREV:
403 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
404 printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
405 printf("<option %s>No", (*(bool *)ptr)?"selected":"");
406 printf("</select>");
407 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
408 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
409 break;
411 case P_INTEGER:
412 case P_BYTES:
413 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
414 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
415 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
416 break;
418 case P_OCTAL: {
419 char *o;
420 o = octal_string(*(int *)ptr);
421 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
422 make_parm_name(parm->label), o);
423 TALLOC_FREE(o);
424 o = octal_string((int)(parm->def.ivalue));
425 printf("<input type=button value=\"%s\" "
426 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
427 _("Set Default"), make_parm_name(parm->label), o);
428 TALLOC_FREE(o);
429 break;
432 case P_ENUM:
433 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
434 for (i=0;parm->enum_list[i].name;i++) {
435 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
436 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
439 printf("</select>");
440 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
441 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
442 break;
443 case P_SEP:
444 break;
446 printf("</td></tr>\n");
447 TALLOC_FREE(ctx);
450 /****************************************************************************
451 display a set of parameters for a service
452 ****************************************************************************/
453 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
455 int i = 0;
456 struct parm_struct *parm;
457 const char *heading = NULL;
458 const char *last_heading = NULL;
460 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
461 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
462 continue;
463 if (parm->p_class == P_SEPARATOR) {
464 heading = parm->label;
465 continue;
467 if (parm->flags & FLAG_HIDE) continue;
468 if (snum >= 0) {
469 if (printers & !(parm->flags & FLAG_PRINT)) continue;
470 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
473 if (!( parm_filter & FLAG_ADVANCED )) {
474 if (!(parm->flags & FLAG_BASIC)) {
475 void *ptr;
476 if (parm->p_class == P_LOCAL && snum >= 0) {
477 ptr = lp_local_ptr_by_snum(snum, parm);
478 } else {
479 ptr = lp_parm_ptr(NULL, parm);
482 switch (parm->type) {
483 case P_CHAR:
484 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
485 break;
487 case P_LIST:
488 if (!str_list_equal(*(const char ***)ptr,
489 (const char **)(parm->def.lvalue))) continue;
490 break;
492 case P_STRING:
493 case P_USTRING:
494 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
495 break;
497 case P_BOOL:
498 case P_BOOLREV:
499 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
500 break;
502 case P_INTEGER:
503 case P_BYTES:
504 case P_OCTAL:
505 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
506 break;
509 case P_ENUM:
510 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
511 break;
512 case P_SEP:
513 continue;
516 if (printers && !(parm->flags & FLAG_PRINT)) continue;
519 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
521 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
523 if (heading && heading != last_heading) {
524 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
525 last_heading = heading;
527 show_parameter(snum, parm);
531 /****************************************************************************
532 load the smb.conf file into loadparm.
533 ****************************************************************************/
534 static bool load_config(bool save_def)
536 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
539 /****************************************************************************
540 write a config file
541 ****************************************************************************/
542 static void write_config(FILE *f, bool show_defaults)
544 TALLOC_CTX *ctx = talloc_stackframe();
546 fprintf(f, "# Samba config file created using SWAT\n");
547 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
548 fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
550 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
552 TALLOC_FREE(ctx);
555 /****************************************************************************
556 save and reload the smb.conf config file
557 ****************************************************************************/
558 static int save_reload(int snum)
560 FILE *f;
561 struct stat st;
563 f = sys_fopen(get_dyn_CONFIGFILE(),"w");
564 if (!f) {
565 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
566 printf("\n");
567 return 0;
570 /* just in case they have used the buggy xinetd to create the file */
571 if (fstat(fileno(f), &st) == 0 &&
572 (st.st_mode & S_IWOTH)) {
573 #if defined HAVE_FCHMOD
574 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
575 #else
576 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
577 #endif
580 write_config(f, False);
581 if (snum >= 0)
582 lp_dump_one(f, False, snum);
583 fclose(f);
585 lp_kill_all_services();
587 if (!load_config(False)) {
588 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
589 printf("\n");
590 return 0;
592 iNumNonAutoPrintServices = lp_numservices();
593 if (pcap_cache_loaded()) {
594 struct tevent_context *ev_ctx;
595 struct messaging_context *msg_ctx;
597 ev_ctx = s3_tevent_context_init(NULL);
598 if (ev_ctx == NULL) {
599 printf("s3_tevent_context_init() failed\n");
600 return 0;
602 msg_ctx = messaging_init(ev_ctx, ev_ctx);
603 if (msg_ctx == NULL) {
604 printf("messaging_init() failed\n");
605 return 0;
608 load_printers(ev_ctx, msg_ctx);
610 talloc_free(ev_ctx);
613 return 1;
616 /****************************************************************************
617 commit one parameter
618 ****************************************************************************/
619 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
621 int i;
622 char *s;
624 if (snum < 0 && parm->p_class == P_LOCAL) {
625 /* this handles the case where we are changing a local
626 variable globally. We need to change the parameter in
627 all shares where it is currently set to the default */
628 for (i=0;i<lp_numservices();i++) {
629 s = lp_servicename(i);
630 if (s && (*s) && lp_is_default(i, parm)) {
631 lp_do_parameter(i, parm->label, v);
636 lp_do_parameter(snum, parm->label, v);
639 /****************************************************************************
640 commit a set of parameters for a service
641 ****************************************************************************/
642 static void commit_parameters(int snum)
644 int i = 0;
645 struct parm_struct *parm;
646 char *label;
647 const char *v;
649 while ((parm = lp_next_parameter(snum, &i, 1))) {
650 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
651 if ((v = cgi_variable(label)) != NULL) {
652 if (parm->flags & FLAG_HIDE)
653 continue;
654 commit_parameter(snum, parm, v);
656 SAFE_FREE(label);
661 /****************************************************************************
662 spit out the html for a link with an image
663 ****************************************************************************/
664 static void image_link(const char *name, const char *hlink, const char *src)
666 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
667 cgi_baseurl(), hlink, src, name);
670 /****************************************************************************
671 display the main navigation controls at the top of each page along
672 with a title
673 ****************************************************************************/
674 static void show_main_buttons(void)
676 char *p;
678 if ((p = cgi_user_name()) && strcmp(p, "root")) {
679 printf(_("Logged in as <b>%s</b>"), p);
680 printf("<p>\n");
683 image_link(_("Home"), "", "images/home.gif");
684 if (have_write_access) {
685 image_link(_("Globals"), "globals", "images/globals.gif");
686 image_link(_("Shares"), "shares", "images/shares.gif");
687 image_link(_("Printers"), "printers", "images/printers.gif");
688 image_link(_("Wizard"), "wizard", "images/wizard.gif");
690 /* root always gets all buttons, otherwise look for -P */
691 if ( have_write_access || (!passwd_only && have_read_access) ) {
692 image_link(_("Status"), "status", "images/status.gif");
693 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
695 image_link(_("Password Management"), "passwd", "images/passwd.gif");
697 printf("<HR>\n");
700 /****************************************************************************
701 * Handle Display/Edit Mode CGI
702 ****************************************************************************/
703 static void ViewModeBoxes(int mode)
705 printf("<p>%s:&nbsp;\n", _("Current View Is"));
706 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
707 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
708 printf("<br>%s:&nbsp;\n", _("Change View To"));
709 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
710 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
711 printf("</p><br>\n");
714 /****************************************************************************
715 display a welcome page
716 ****************************************************************************/
717 static void welcome_page(void)
719 if (file_exist("help/welcome.html")) {
720 include_html("help/welcome.html");
721 } else {
722 include_html("help/welcome-no-samba-doc.html");
726 /****************************************************************************
727 display the current smb.conf
728 ****************************************************************************/
729 static void viewconfig_page(void)
731 int full_view=0;
732 const char form_name[] = "viewconfig";
734 if (!verify_xsrf_token(form_name)) {
735 goto output_page;
738 if (cgi_variable("full_view")) {
739 full_view = 1;
742 output_page:
743 printf("<H2>%s</H2>\n", _("Current Config"));
744 printf("<form method=post>\n");
745 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
747 if (full_view) {
748 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
749 } else {
750 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
753 printf("<p><pre>");
754 write_config(stdout, full_view);
755 printf("</pre>");
756 printf("</form>\n");
759 /****************************************************************************
760 second screen of the wizard ... Fetch Configuration Parameters
761 ****************************************************************************/
762 static void wizard_params_page(void)
764 unsigned int parm_filter = FLAG_WIZARD;
765 const char form_name[] = "wizard_params";
767 /* Here we first set and commit all the parameters that were selected
768 in the previous screen. */
770 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
772 if (!verify_xsrf_token(form_name)) {
773 goto output_page;
776 if (cgi_variable("Commit")) {
777 commit_parameters(GLOBAL_SECTION_SNUM);
778 save_reload(-1);
781 output_page:
782 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
783 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
785 if (have_write_access) {
786 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
789 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
790 printf("<p>\n");
792 printf("<table>\n");
793 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
794 printf("</table>\n");
795 printf("</form>\n");
798 /****************************************************************************
799 Utility to just rewrite the smb.conf file - effectively just cleans it up
800 ****************************************************************************/
801 static void rewritecfg_file(void)
803 commit_parameters(GLOBAL_SECTION_SNUM);
804 save_reload(-1);
805 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
808 /****************************************************************************
809 wizard to create/modify the smb.conf file
810 ****************************************************************************/
811 static void wizard_page(void)
813 /* Set some variables to collect data from smb.conf */
814 int role = 0;
815 int winstype = 0;
816 int have_home = -1;
817 int HomeExpo = 0;
818 int SerType = 0;
819 const char form_name[] = "wizard";
821 if (!verify_xsrf_token(form_name)) {
822 goto output_page;
825 if (cgi_variable("Rewrite")) {
826 (void) rewritecfg_file();
827 return;
830 if (cgi_variable("GetWizardParams")){
831 (void) wizard_params_page();
832 return;
835 if (cgi_variable("Commit")){
836 SerType = atoi(cgi_variable_nonull("ServerType"));
837 winstype = atoi(cgi_variable_nonull("WINSType"));
838 have_home = lp_servicenumber(HOMES_NAME);
839 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
841 /* Plain text passwords are too badly broken - use encrypted passwords only */
842 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
844 switch ( SerType ){
845 case 0:
846 /* Stand-alone Server */
847 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
848 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
849 break;
850 case 1:
851 /* Domain Member */
852 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
853 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
854 break;
855 case 2:
856 /* Domain Controller */
857 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
858 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
859 break;
861 switch ( winstype ) {
862 case 0:
863 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
864 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
865 break;
866 case 1:
867 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
868 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
869 break;
870 case 2:
871 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
872 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
873 break;
876 /* Have to create Homes share? */
877 if ((HomeExpo == 1) && (have_home == -1)) {
878 const char *unix_share = HOMES_NAME;
880 load_config(False);
881 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
882 have_home = lp_servicenumber(HOMES_NAME);
883 lp_do_parameter( have_home, "read only", "No");
884 lp_do_parameter( have_home, "valid users", "%S");
885 lp_do_parameter( have_home, "browseable", "No");
886 commit_parameters(have_home);
887 save_reload(have_home);
890 /* Need to Delete Homes share? */
891 if ((HomeExpo == 0) && (have_home != -1)) {
892 lp_remove_service(have_home);
893 have_home = -1;
896 commit_parameters(GLOBAL_SECTION_SNUM);
897 save_reload(-1);
899 else
901 /* Now determine smb.conf WINS settings */
902 if (lp_we_are_a_wins_server())
903 winstype = 1;
904 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
905 winstype = 2;
907 /* Do we have a homes share? */
908 have_home = lp_servicenumber(HOMES_NAME);
910 if ((winstype == 2) && lp_we_are_a_wins_server())
911 winstype = 3;
913 role = lp_server_role();
915 output_page:
916 /* Here we go ... */
917 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
918 printf("<form method=post action=wizard>\n");
919 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
921 if (have_write_access) {
922 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
923 printf("%s", _("The same will happen if you press the commit button."));
924 printf("<br><br>\n");
925 printf("<center>");
926 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
927 printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
928 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
929 printf("</center>\n");
932 printf("<hr>");
933 printf("<center><table border=0>");
934 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
935 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
936 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
937 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
938 printf("</tr>\n");
939 if (role == ROLE_DOMAIN_BDC) {
940 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
942 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
943 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
944 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
945 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
946 printf("</tr>\n");
947 printf("<tr><td></td><td></td><td></td><td>%s&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
949 /* Print out the list of wins servers */
950 if(lp_wins_server_list()) {
951 int i;
952 const char **wins_servers = lp_wins_server_list();
953 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
956 printf("\"></td></tr>\n");
957 if (winstype == 3) {
958 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"));
959 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
961 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
962 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
963 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
964 printf("<td></td></tr>\n");
966 /* Enable this when we are ready ....
967 * printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
968 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
969 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
970 * printf("<td></td></tr>\n");
973 printf("</table></center>");
974 printf("<hr>");
976 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
977 printf("</form>\n");
981 /****************************************************************************
982 display a globals editing page
983 ****************************************************************************/
984 static void globals_page(void)
986 unsigned int parm_filter = FLAG_BASIC;
987 int mode = 0;
988 const char form_name[] = "globals";
990 printf("<H2>%s</H2>\n", _("Global Parameters"));
992 if (!verify_xsrf_token(form_name)) {
993 goto output_page;
996 if (cgi_variable("Commit")) {
997 commit_parameters(GLOBAL_SECTION_SNUM);
998 save_reload(-1);
1001 if ( cgi_variable("ViewMode") )
1002 mode = atoi(cgi_variable_nonull("ViewMode"));
1003 if ( cgi_variable("BasicMode"))
1004 mode = 0;
1005 if ( cgi_variable("AdvMode"))
1006 mode = 1;
1008 output_page:
1009 printf("<form name=\"swatform\" method=post action=globals>\n");
1010 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1012 ViewModeBoxes( mode );
1013 switch ( mode ) {
1014 case 0:
1015 parm_filter = FLAG_BASIC;
1016 break;
1017 case 1:
1018 parm_filter = FLAG_ADVANCED;
1019 break;
1021 printf("<br>\n");
1022 if (have_write_access) {
1023 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
1024 _("Commit Changes"));
1027 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
1028 _("Reset Values"));
1030 printf("<p>\n");
1031 printf("<table>\n");
1032 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
1033 printf("</table>\n");
1034 printf("</form>\n");
1037 /****************************************************************************
1038 display a shares editing page. share is in unix codepage,
1039 ****************************************************************************/
1040 static void shares_page(void)
1042 const char *share = cgi_variable("share");
1043 char *s;
1044 char *utf8_s;
1045 int snum = -1;
1046 int i;
1047 int mode = 0;
1048 unsigned int parm_filter = FLAG_BASIC;
1049 size_t converted_size;
1050 const char form_name[] = "shares";
1052 printf("<H2>%s</H2>\n", _("Share Parameters"));
1054 if (!verify_xsrf_token(form_name)) {
1055 goto output_page;
1058 if (share)
1059 snum = lp_servicenumber(share);
1062 if (cgi_variable("Commit") && snum >= 0) {
1063 commit_parameters(snum);
1064 save_reload(-1);
1065 snum = lp_servicenumber(share);
1068 if (cgi_variable("Delete") && snum >= 0) {
1069 lp_remove_service(snum);
1070 save_reload(-1);
1071 share = NULL;
1072 snum = -1;
1075 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1076 snum = lp_servicenumber(share);
1077 if (snum < 0) {
1078 load_config(False);
1079 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1080 snum = lp_servicenumber(share);
1081 save_reload(snum);
1082 snum = lp_servicenumber(share);
1086 if ( cgi_variable("ViewMode") )
1087 mode = atoi(cgi_variable_nonull("ViewMode"));
1088 if ( cgi_variable("BasicMode"))
1089 mode = 0;
1090 if ( cgi_variable("AdvMode"))
1091 mode = 1;
1093 output_page:
1094 printf("<FORM name=\"swatform\" method=post>\n");
1095 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1097 printf("<table>\n");
1099 ViewModeBoxes( mode );
1100 switch ( mode ) {
1101 case 0:
1102 parm_filter = FLAG_BASIC;
1103 break;
1104 case 1:
1105 parm_filter = FLAG_ADVANCED;
1106 break;
1108 printf("<br><tr>\n");
1109 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1110 printf("<td><select name=share>\n");
1111 if (snum < 0)
1112 printf("<option value=\" \"> \n");
1113 for (i=0;i<lp_numservices();i++) {
1114 s = lp_servicename(i);
1115 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
1116 push_utf8_talloc(talloc_tos(), &utf8_s, s, &converted_size);
1117 printf("<option %s value=\"%s\">%s\n",
1118 (share && strcmp(share,s)==0)?"SELECTED":"",
1119 utf8_s, utf8_s);
1120 TALLOC_FREE(utf8_s);
1123 printf("</select></td>\n");
1124 if (have_write_access) {
1125 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1127 printf("</tr>\n");
1128 printf("</table>");
1129 printf("<table>");
1130 if (have_write_access) {
1131 printf("<tr>\n");
1132 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1133 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1135 printf("</table>");
1138 if (snum >= 0) {
1139 if (have_write_access) {
1140 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1143 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1144 printf("<p>\n");
1147 if (snum >= 0) {
1148 printf("<table>\n");
1149 show_parameters(snum, 1, parm_filter, 0);
1150 printf("</table>\n");
1153 printf("</FORM>\n");
1156 /*************************************************************
1157 change a password either locally or remotely
1158 *************************************************************/
1159 static bool change_password(const char *remote_machine, const char *user_name,
1160 const char *old_passwd, const char *new_passwd,
1161 int local_flags)
1163 NTSTATUS ret;
1164 char *err_str = NULL;
1165 char *msg_str = NULL;
1167 if (demo_mode) {
1168 printf("%s\n<p>", _("password change in demo mode rejected"));
1169 return False;
1172 if (remote_machine != NULL) {
1173 ret = remote_password_change(remote_machine, user_name,
1174 old_passwd, new_passwd, &err_str);
1175 if (err_str != NULL)
1176 printf("%s\n<p>", err_str);
1177 SAFE_FREE(err_str);
1178 return NT_STATUS_IS_OK(ret);
1181 if(!initialize_password_db(True, NULL)) {
1182 printf("%s\n<p>", _("Can't setup password database vectors."));
1183 return False;
1186 ret = local_password_change(user_name, local_flags, new_passwd,
1187 &err_str, &msg_str);
1189 if(msg_str)
1190 printf("%s\n<p>", msg_str);
1191 if(err_str)
1192 printf("%s\n<p>", err_str);
1194 SAFE_FREE(msg_str);
1195 SAFE_FREE(err_str);
1196 return NT_STATUS_IS_OK(ret);
1199 /****************************************************************************
1200 do the stuff required to add or change a password
1201 ****************************************************************************/
1202 static void chg_passwd(void)
1204 const char *host;
1205 bool rslt;
1206 int local_flags = 0;
1208 /* Make sure users name has been specified */
1209 if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1210 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1211 return;
1215 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1216 * so if that's what we're doing, skip the rest of the checks
1218 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1221 * If current user is not root, make sure old password has been specified
1222 * If REMOTE change, even root must provide old password
1224 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1225 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1226 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1227 return;
1230 /* If changing a users password on a remote hosts we have to know what host */
1231 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1232 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1233 return;
1236 /* Make sure new passwords have been specified */
1237 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1238 (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1239 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1240 return;
1243 /* Make sure new passwords was typed correctly twice */
1244 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1245 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1246 return;
1250 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1251 host = cgi_variable(RHOST);
1252 } else if (am_root()) {
1253 host = NULL;
1254 } else {
1255 host = "127.0.0.1";
1259 * Set up the local flags.
1262 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1263 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1264 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1265 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1266 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1267 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1269 rslt = change_password(host,
1270 cgi_variable_nonull(SWAT_USER),
1271 cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1272 local_flags);
1274 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1275 printf("<p>");
1276 if (rslt == True) {
1277 printf("%s\n", _(" The passwd has been changed."));
1278 } else {
1279 printf("%s\n", _(" The passwd has NOT been changed."));
1283 return;
1286 /****************************************************************************
1287 display a password editing page
1288 ****************************************************************************/
1289 static void passwd_page(void)
1291 const char *new_name = cgi_user_name();
1292 const char passwd_form[] = "passwd";
1293 const char rpasswd_form[] = "rpasswd";
1295 if (!new_name) new_name = "";
1297 printf("<H2>%s</H2>\n", _("Server Password Management"));
1299 printf("<FORM name=\"swatform\" method=post>\n");
1300 print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form);
1302 printf("<table>\n");
1305 * Create all the dialog boxes for data collection
1307 printf("<tr><td> %s : </td>\n", _("User Name"));
1308 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1309 if (!am_root()) {
1310 printf("<tr><td> %s : </td>\n", _("Old Password"));
1311 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1313 printf("<tr><td> %s : </td>\n", _("New Password"));
1314 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1315 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1316 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1317 printf("</table>\n");
1320 * Create all the control buttons for requesting action
1322 printf("<input type=submit name=%s value=\"%s\">\n",
1323 CHG_S_PASSWD_FLAG, _("Change Password"));
1324 if (demo_mode || am_root()) {
1325 printf("<input type=submit name=%s value=\"%s\">\n",
1326 ADD_USER_FLAG, _("Add New User"));
1327 printf("<input type=submit name=%s value=\"%s\">\n",
1328 DELETE_USER_FLAG, _("Delete User"));
1329 printf("<input type=submit name=%s value=\"%s\">\n",
1330 DISABLE_USER_FLAG, _("Disable User"));
1331 printf("<input type=submit name=%s value=\"%s\">\n",
1332 ENABLE_USER_FLAG, _("Enable User"));
1334 printf("<p></FORM>\n");
1337 * Do some work if change, add, disable or enable was
1338 * requested. It could be this is the first time through this
1339 * code, so there isn't anything to do. */
1340 if (verify_xsrf_token(passwd_form) &&
1341 ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1342 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG)))) {
1343 chg_passwd();
1346 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1348 printf("<FORM name=\"swatform\" method=post>\n");
1349 print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form);
1351 printf("<table>\n");
1354 * Create all the dialog boxes for data collection
1356 printf("<tr><td> %s : </td>\n", _("User Name"));
1357 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1358 printf("<tr><td> %s : </td>\n", _("Old Password"));
1359 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1360 printf("<tr><td> %s : </td>\n", _("New Password"));
1361 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1362 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1363 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1364 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1365 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1367 printf("</table>");
1370 * Create all the control buttons for requesting action
1372 printf("<input type=submit name=%s value=\"%s\">",
1373 CHG_R_PASSWD_FLAG, _("Change Password"));
1375 printf("<p></FORM>\n");
1378 * Do some work if a request has been made to change the
1379 * password somewhere other than the server. It could be this
1380 * is the first time through this code, so there isn't
1381 * anything to do. */
1382 if (verify_xsrf_token(passwd_form) && cgi_variable(CHG_R_PASSWD_FLAG)) {
1383 chg_passwd();
1388 /****************************************************************************
1389 display a printers editing page
1390 ****************************************************************************/
1391 static void printers_page(void)
1393 const char *share = cgi_variable("share");
1394 char *s;
1395 int snum=-1;
1396 int i;
1397 int mode = 0;
1398 unsigned int parm_filter = FLAG_BASIC;
1399 const char form_name[] = "printers";
1401 if (!verify_xsrf_token(form_name)) {
1402 goto output_page;
1405 if (share)
1406 snum = lp_servicenumber(share);
1408 if (cgi_variable("Commit") && snum >= 0) {
1409 commit_parameters(snum);
1410 if (snum >= iNumNonAutoPrintServices)
1411 save_reload(snum);
1412 else
1413 save_reload(-1);
1414 snum = lp_servicenumber(share);
1417 if (cgi_variable("Delete") && snum >= 0) {
1418 lp_remove_service(snum);
1419 save_reload(-1);
1420 share = NULL;
1421 snum = -1;
1424 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1425 snum = lp_servicenumber(share);
1426 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1427 load_config(False);
1428 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1429 snum = lp_servicenumber(share);
1430 lp_do_parameter(snum, "print ok", "Yes");
1431 save_reload(snum);
1432 snum = lp_servicenumber(share);
1436 if ( cgi_variable("ViewMode") )
1437 mode = atoi(cgi_variable_nonull("ViewMode"));
1438 if ( cgi_variable("BasicMode"))
1439 mode = 0;
1440 if ( cgi_variable("AdvMode"))
1441 mode = 1;
1443 output_page:
1444 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1446 printf("<H3>%s</H3>\n", _("Important Note:"));
1447 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1448 printf("%s",_("are autoloaded printers from "));
1449 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1450 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1453 printf("<FORM name=\"swatform\" method=post>\n");
1454 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1456 ViewModeBoxes( mode );
1457 switch ( mode ) {
1458 case 0:
1459 parm_filter = FLAG_BASIC;
1460 break;
1461 case 1:
1462 parm_filter = FLAG_ADVANCED;
1463 break;
1465 printf("<table>\n");
1466 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1467 printf("<td><select name=\"share\">\n");
1468 if (snum < 0 || !lp_print_ok(snum))
1469 printf("<option value=\" \"> \n");
1470 for (i=0;i<lp_numservices();i++) {
1471 s = lp_servicename(i);
1472 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1473 if (i >= iNumNonAutoPrintServices)
1474 printf("<option %s value=\"%s\">[*]%s\n",
1475 (share && strcmp(share,s)==0)?"SELECTED":"",
1476 s, s);
1477 else
1478 printf("<option %s value=\"%s\">%s\n",
1479 (share && strcmp(share,s)==0)?"SELECTED":"",
1480 s, s);
1483 printf("</select></td>");
1484 if (have_write_access) {
1485 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1487 printf("</tr>");
1488 printf("</table>\n");
1490 if (have_write_access) {
1491 printf("<table>\n");
1492 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1493 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1494 printf("</table>");
1498 if (snum >= 0) {
1499 if (have_write_access) {
1500 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1502 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1503 printf("<p>\n");
1506 if (snum >= 0) {
1507 printf("<table>\n");
1508 show_parameters(snum, 1, parm_filter, 1);
1509 printf("</table>\n");
1511 printf("</FORM>\n");
1515 when the _() translation macro is used there is no obvious place to free
1516 the resulting string and there is no easy way to give a static pointer.
1517 All we can do is rotate between some static buffers and hope a single d_printf()
1518 doesn't have more calls to _() than the number of buffers
1521 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1523 const char *msgstr;
1524 const char *ret;
1526 msgstr = lang_msg(msgid);
1527 if (!msgstr) {
1528 return msgid;
1531 ret = talloc_strdup(ctx, msgstr);
1533 lang_msg_free(msgstr);
1534 if (!ret) {
1535 return msgid;
1538 return ret;
1542 * main function for SWAT.
1544 int main(int argc, char *argv[])
1546 const char *page;
1547 poptContext pc;
1548 struct poptOption long_options[] = {
1549 POPT_AUTOHELP
1550 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1551 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1552 POPT_COMMON_SAMBA
1553 POPT_TABLEEND
1555 TALLOC_CTX *frame = talloc_stackframe();
1557 fault_setup();
1558 umask(S_IWGRP | S_IWOTH);
1560 #if defined(HAVE_SET_AUTH_PARAMETERS)
1561 set_auth_parameters(argc, argv);
1562 #endif /* HAVE_SET_AUTH_PARAMETERS */
1564 /* just in case it goes wild ... */
1565 alarm(300);
1567 setlinebuf(stdout);
1569 /* we don't want any SIGPIPE messages */
1570 BlockSignals(True,SIGPIPE);
1572 debug_set_logfile("/dev/null");
1574 /* we don't want stderr screwing us up */
1575 close(2);
1576 open("/dev/null", O_WRONLY);
1577 setup_logging("swat", DEBUG_FILE);
1579 load_case_tables();
1581 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1583 /* Parse command line options */
1585 while(poptGetNextOpt(pc) != -1) { }
1587 poptFreeContext(pc);
1589 /* This should set a more apporiate log file */
1590 load_config(True);
1591 reopen_logs();
1592 load_interfaces();
1593 iNumNonAutoPrintServices = lp_numservices();
1594 if (pcap_cache_loaded()) {
1595 struct tevent_context *ev_ctx;
1596 struct messaging_context *msg_ctx;
1598 ev_ctx = s3_tevent_context_init(NULL);
1599 if (ev_ctx == NULL) {
1600 printf("s3_tevent_context_init() failed\n");
1601 return 0;
1603 msg_ctx = messaging_init(ev_ctx, ev_ctx);
1604 if (msg_ctx == NULL) {
1605 printf("messaging_init() failed\n");
1606 return 0;
1609 load_printers(ev_ctx, msg_ctx);
1611 talloc_free(ev_ctx);
1614 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1616 print_header();
1618 cgi_load_variables();
1620 if (!file_exist(get_dyn_CONFIGFILE())) {
1621 have_read_access = True;
1622 have_write_access = True;
1623 } else {
1624 /* check if the authenticated user has write access - if not then
1625 don't show write options */
1626 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1628 /* if the user doesn't have read access to smb.conf then
1629 don't let them view it */
1630 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1633 show_main_buttons();
1635 page = cgi_pathinfo();
1637 /* Root gets full functionality */
1638 if (have_read_access && strcmp(page, "globals")==0) {
1639 globals_page();
1640 } else if (have_read_access && strcmp(page,"shares")==0) {
1641 shares_page();
1642 } else if (have_read_access && strcmp(page,"printers")==0) {
1643 printers_page();
1644 } else if (have_read_access && strcmp(page,"status")==0) {
1645 status_page();
1646 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1647 viewconfig_page();
1648 } else if (strcmp(page,"passwd")==0) {
1649 passwd_page();
1650 } else if (have_read_access && strcmp(page,"wizard")==0) {
1651 wizard_page();
1652 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1653 wizard_params_page();
1654 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1655 rewritecfg_file();
1656 } else {
1657 welcome_page();
1660 print_footer();
1662 TALLOC_FREE(frame);
1663 return 0;
1666 /** @} **/