s3: Add a suicide mode to smbd
[Samba/id10ts.git] / source3 / web / swat.c
blob3d6aaf4ca7010028ef632f709f9cf69c73fce5ac
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 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
413 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
414 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
415 break;
417 case P_OCTAL: {
418 char *o;
419 o = octal_string(*(int *)ptr);
420 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
421 make_parm_name(parm->label), o);
422 TALLOC_FREE(o);
423 o = octal_string((int)(parm->def.ivalue));
424 printf("<input type=button value=\"%s\" "
425 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
426 _("Set Default"), make_parm_name(parm->label), o);
427 TALLOC_FREE(o);
428 break;
431 case P_ENUM:
432 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
433 for (i=0;parm->enum_list[i].name;i++) {
434 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
435 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
438 printf("</select>");
439 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
440 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
441 break;
442 case P_SEP:
443 break;
445 printf("</td></tr>\n");
446 TALLOC_FREE(ctx);
449 /****************************************************************************
450 display a set of parameters for a service
451 ****************************************************************************/
452 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
454 int i = 0;
455 struct parm_struct *parm;
456 const char *heading = NULL;
457 const char *last_heading = NULL;
459 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
460 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
461 continue;
462 if (parm->p_class == P_SEPARATOR) {
463 heading = parm->label;
464 continue;
466 if (parm->flags & FLAG_HIDE) continue;
467 if (snum >= 0) {
468 if (printers & !(parm->flags & FLAG_PRINT)) continue;
469 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
472 if (!( parm_filter & FLAG_ADVANCED )) {
473 if (!(parm->flags & FLAG_BASIC)) {
474 void *ptr;
475 if (parm->p_class == P_LOCAL && snum >= 0) {
476 ptr = lp_local_ptr_by_snum(snum, parm);
477 } else {
478 ptr = lp_parm_ptr(NULL, parm);
481 switch (parm->type) {
482 case P_CHAR:
483 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
484 break;
486 case P_LIST:
487 if (!str_list_equal(*(const char ***)ptr,
488 (const char **)(parm->def.lvalue))) continue;
489 break;
491 case P_STRING:
492 case P_USTRING:
493 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
494 break;
496 case P_BOOL:
497 case P_BOOLREV:
498 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
499 break;
501 case P_INTEGER:
502 case P_OCTAL:
503 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
504 break;
507 case P_ENUM:
508 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
509 break;
510 case P_SEP:
511 continue;
514 if (printers && !(parm->flags & FLAG_PRINT)) continue;
517 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
519 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
521 if (heading && heading != last_heading) {
522 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
523 last_heading = heading;
525 show_parameter(snum, parm);
529 /****************************************************************************
530 load the smb.conf file into loadparm.
531 ****************************************************************************/
532 static bool load_config(bool save_def)
534 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
537 /****************************************************************************
538 write a config file
539 ****************************************************************************/
540 static void write_config(FILE *f, bool show_defaults)
542 TALLOC_CTX *ctx = talloc_stackframe();
544 fprintf(f, "# Samba config file created using SWAT\n");
545 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
546 fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
548 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
550 TALLOC_FREE(ctx);
553 /****************************************************************************
554 save and reload the smb.conf config file
555 ****************************************************************************/
556 static int save_reload(int snum)
558 FILE *f;
559 struct stat st;
561 f = sys_fopen(get_dyn_CONFIGFILE(),"w");
562 if (!f) {
563 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
564 printf("\n");
565 return 0;
568 /* just in case they have used the buggy xinetd to create the file */
569 if (fstat(fileno(f), &st) == 0 &&
570 (st.st_mode & S_IWOTH)) {
571 #if defined HAVE_FCHMOD
572 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
573 #else
574 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
575 #endif
578 write_config(f, False);
579 if (snum >= 0)
580 lp_dump_one(f, False, snum);
581 fclose(f);
583 lp_kill_all_services();
585 if (!load_config(False)) {
586 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
587 printf("\n");
588 return 0;
590 iNumNonAutoPrintServices = lp_numservices();
591 if (pcap_cache_loaded()) {
592 struct tevent_context *ev_ctx;
593 struct messaging_context *msg_ctx;
595 ev_ctx = s3_tevent_context_init(NULL);
596 if (ev_ctx == NULL) {
597 printf("s3_tevent_context_init() failed\n");
598 return 0;
600 msg_ctx = messaging_init(ev_ctx, ev_ctx);
601 if (msg_ctx == NULL) {
602 printf("messaging_init() failed\n");
603 return 0;
606 load_printers(ev_ctx, msg_ctx);
608 talloc_free(ev_ctx);
611 return 1;
614 /****************************************************************************
615 commit one parameter
616 ****************************************************************************/
617 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
619 int i;
620 char *s;
622 if (snum < 0 && parm->p_class == P_LOCAL) {
623 /* this handles the case where we are changing a local
624 variable globally. We need to change the parameter in
625 all shares where it is currently set to the default */
626 for (i=0;i<lp_numservices();i++) {
627 s = lp_servicename(i);
628 if (s && (*s) && lp_is_default(i, parm)) {
629 lp_do_parameter(i, parm->label, v);
634 lp_do_parameter(snum, parm->label, v);
637 /****************************************************************************
638 commit a set of parameters for a service
639 ****************************************************************************/
640 static void commit_parameters(int snum)
642 int i = 0;
643 struct parm_struct *parm;
644 char *label;
645 const char *v;
647 while ((parm = lp_next_parameter(snum, &i, 1))) {
648 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
649 if ((v = cgi_variable(label)) != NULL) {
650 if (parm->flags & FLAG_HIDE)
651 continue;
652 commit_parameter(snum, parm, v);
654 SAFE_FREE(label);
659 /****************************************************************************
660 spit out the html for a link with an image
661 ****************************************************************************/
662 static void image_link(const char *name, const char *hlink, const char *src)
664 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
665 cgi_baseurl(), hlink, src, name);
668 /****************************************************************************
669 display the main navigation controls at the top of each page along
670 with a title
671 ****************************************************************************/
672 static void show_main_buttons(void)
674 char *p;
676 if ((p = cgi_user_name()) && strcmp(p, "root")) {
677 printf(_("Logged in as <b>%s</b>"), p);
678 printf("<p>\n");
681 image_link(_("Home"), "", "images/home.gif");
682 if (have_write_access) {
683 image_link(_("Globals"), "globals", "images/globals.gif");
684 image_link(_("Shares"), "shares", "images/shares.gif");
685 image_link(_("Printers"), "printers", "images/printers.gif");
686 image_link(_("Wizard"), "wizard", "images/wizard.gif");
688 /* root always gets all buttons, otherwise look for -P */
689 if ( have_write_access || (!passwd_only && have_read_access) ) {
690 image_link(_("Status"), "status", "images/status.gif");
691 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
693 image_link(_("Password Management"), "passwd", "images/passwd.gif");
695 printf("<HR>\n");
698 /****************************************************************************
699 * Handle Display/Edit Mode CGI
700 ****************************************************************************/
701 static void ViewModeBoxes(int mode)
703 printf("<p>%s:&nbsp;\n", _("Current View Is"));
704 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
705 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
706 printf("<br>%s:&nbsp;\n", _("Change View To"));
707 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
708 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
709 printf("</p><br>\n");
712 /****************************************************************************
713 display a welcome page
714 ****************************************************************************/
715 static void welcome_page(void)
717 if (file_exist("help/welcome.html")) {
718 include_html("help/welcome.html");
719 } else {
720 include_html("help/welcome-no-samba-doc.html");
724 /****************************************************************************
725 display the current smb.conf
726 ****************************************************************************/
727 static void viewconfig_page(void)
729 int full_view=0;
730 const char form_name[] = "viewconfig";
732 if (!verify_xsrf_token(form_name)) {
733 goto output_page;
736 if (cgi_variable("full_view")) {
737 full_view = 1;
740 output_page:
741 printf("<H2>%s</H2>\n", _("Current Config"));
742 printf("<form method=post>\n");
743 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
745 if (full_view) {
746 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
747 } else {
748 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
751 printf("<p><pre>");
752 write_config(stdout, full_view);
753 printf("</pre>");
754 printf("</form>\n");
757 /****************************************************************************
758 second screen of the wizard ... Fetch Configuration Parameters
759 ****************************************************************************/
760 static void wizard_params_page(void)
762 unsigned int parm_filter = FLAG_WIZARD;
763 const char form_name[] = "wizard_params";
765 /* Here we first set and commit all the parameters that were selected
766 in the previous screen. */
768 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
770 if (!verify_xsrf_token(form_name)) {
771 goto output_page;
774 if (cgi_variable("Commit")) {
775 commit_parameters(GLOBAL_SECTION_SNUM);
776 save_reload(-1);
779 output_page:
780 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
781 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
783 if (have_write_access) {
784 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
787 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
788 printf("<p>\n");
790 printf("<table>\n");
791 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
792 printf("</table>\n");
793 printf("</form>\n");
796 /****************************************************************************
797 Utility to just rewrite the smb.conf file - effectively just cleans it up
798 ****************************************************************************/
799 static void rewritecfg_file(void)
801 commit_parameters(GLOBAL_SECTION_SNUM);
802 save_reload(-1);
803 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
806 /****************************************************************************
807 wizard to create/modify the smb.conf file
808 ****************************************************************************/
809 static void wizard_page(void)
811 /* Set some variables to collect data from smb.conf */
812 int role = 0;
813 int winstype = 0;
814 int have_home = -1;
815 int HomeExpo = 0;
816 int SerType = 0;
817 const char form_name[] = "wizard";
819 if (!verify_xsrf_token(form_name)) {
820 goto output_page;
823 if (cgi_variable("Rewrite")) {
824 (void) rewritecfg_file();
825 return;
828 if (cgi_variable("GetWizardParams")){
829 (void) wizard_params_page();
830 return;
833 if (cgi_variable("Commit")){
834 SerType = atoi(cgi_variable_nonull("ServerType"));
835 winstype = atoi(cgi_variable_nonull("WINSType"));
836 have_home = lp_servicenumber(HOMES_NAME);
837 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
839 /* Plain text passwords are too badly broken - use encrypted passwords only */
840 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
842 switch ( SerType ){
843 case 0:
844 /* Stand-alone Server */
845 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
846 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
847 break;
848 case 1:
849 /* Domain Member */
850 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
851 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
852 break;
853 case 2:
854 /* Domain Controller */
855 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
856 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
857 break;
859 switch ( winstype ) {
860 case 0:
861 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
862 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
863 break;
864 case 1:
865 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
866 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
867 break;
868 case 2:
869 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
870 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
871 break;
874 /* Have to create Homes share? */
875 if ((HomeExpo == 1) && (have_home == -1)) {
876 const char *unix_share = HOMES_NAME;
878 load_config(False);
879 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
880 have_home = lp_servicenumber(HOMES_NAME);
881 lp_do_parameter( have_home, "read only", "No");
882 lp_do_parameter( have_home, "valid users", "%S");
883 lp_do_parameter( have_home, "browseable", "No");
884 commit_parameters(have_home);
885 save_reload(have_home);
888 /* Need to Delete Homes share? */
889 if ((HomeExpo == 0) && (have_home != -1)) {
890 lp_remove_service(have_home);
891 have_home = -1;
894 commit_parameters(GLOBAL_SECTION_SNUM);
895 save_reload(-1);
897 else
899 /* Now determine smb.conf WINS settings */
900 if (lp_we_are_a_wins_server())
901 winstype = 1;
902 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
903 winstype = 2;
905 /* Do we have a homes share? */
906 have_home = lp_servicenumber(HOMES_NAME);
908 if ((winstype == 2) && lp_we_are_a_wins_server())
909 winstype = 3;
911 role = lp_server_role();
913 output_page:
914 /* Here we go ... */
915 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
916 printf("<form method=post action=wizard>\n");
917 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
919 if (have_write_access) {
920 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
921 printf("%s", _("The same will happen if you press the commit button."));
922 printf("<br><br>\n");
923 printf("<center>");
924 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
925 printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
926 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
927 printf("</center>\n");
930 printf("<hr>");
931 printf("<center><table border=0>");
932 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
933 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
934 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
935 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
936 printf("</tr>\n");
937 if (role == ROLE_DOMAIN_BDC) {
938 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
940 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
941 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
942 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
943 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
944 printf("</tr>\n");
945 printf("<tr><td></td><td></td><td></td><td>%s&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
947 /* Print out the list of wins servers */
948 if(lp_wins_server_list()) {
949 int i;
950 const char **wins_servers = lp_wins_server_list();
951 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
954 printf("\"></td></tr>\n");
955 if (winstype == 3) {
956 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"));
957 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
959 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
960 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
961 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
962 printf("<td></td></tr>\n");
964 /* Enable this when we are ready ....
965 * printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
966 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
967 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
968 * printf("<td></td></tr>\n");
971 printf("</table></center>");
972 printf("<hr>");
974 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
975 printf("</form>\n");
979 /****************************************************************************
980 display a globals editing page
981 ****************************************************************************/
982 static void globals_page(void)
984 unsigned int parm_filter = FLAG_BASIC;
985 int mode = 0;
986 const char form_name[] = "globals";
988 printf("<H2>%s</H2>\n", _("Global Parameters"));
990 if (!verify_xsrf_token(form_name)) {
991 goto output_page;
994 if (cgi_variable("Commit")) {
995 commit_parameters(GLOBAL_SECTION_SNUM);
996 save_reload(-1);
999 if ( cgi_variable("ViewMode") )
1000 mode = atoi(cgi_variable_nonull("ViewMode"));
1001 if ( cgi_variable("BasicMode"))
1002 mode = 0;
1003 if ( cgi_variable("AdvMode"))
1004 mode = 1;
1006 output_page:
1007 printf("<form name=\"swatform\" method=post action=globals>\n");
1008 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1010 ViewModeBoxes( mode );
1011 switch ( mode ) {
1012 case 0:
1013 parm_filter = FLAG_BASIC;
1014 break;
1015 case 1:
1016 parm_filter = FLAG_ADVANCED;
1017 break;
1019 printf("<br>\n");
1020 if (have_write_access) {
1021 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
1022 _("Commit Changes"));
1025 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
1026 _("Reset Values"));
1028 printf("<p>\n");
1029 printf("<table>\n");
1030 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
1031 printf("</table>\n");
1032 printf("</form>\n");
1035 /****************************************************************************
1036 display a shares editing page. share is in unix codepage,
1037 ****************************************************************************/
1038 static void shares_page(void)
1040 const char *share = cgi_variable("share");
1041 char *s;
1042 char *utf8_s;
1043 int snum = -1;
1044 int i;
1045 int mode = 0;
1046 unsigned int parm_filter = FLAG_BASIC;
1047 size_t converted_size;
1048 const char form_name[] = "shares";
1050 printf("<H2>%s</H2>\n", _("Share Parameters"));
1052 if (!verify_xsrf_token(form_name)) {
1053 goto output_page;
1056 if (share)
1057 snum = lp_servicenumber(share);
1060 if (cgi_variable("Commit") && snum >= 0) {
1061 commit_parameters(snum);
1062 save_reload(-1);
1063 snum = lp_servicenumber(share);
1066 if (cgi_variable("Delete") && snum >= 0) {
1067 lp_remove_service(snum);
1068 save_reload(-1);
1069 share = NULL;
1070 snum = -1;
1073 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1074 snum = lp_servicenumber(share);
1075 if (snum < 0) {
1076 load_config(False);
1077 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1078 snum = lp_servicenumber(share);
1079 save_reload(snum);
1080 snum = lp_servicenumber(share);
1084 if ( cgi_variable("ViewMode") )
1085 mode = atoi(cgi_variable_nonull("ViewMode"));
1086 if ( cgi_variable("BasicMode"))
1087 mode = 0;
1088 if ( cgi_variable("AdvMode"))
1089 mode = 1;
1091 output_page:
1092 printf("<FORM name=\"swatform\" method=post>\n");
1093 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1095 printf("<table>\n");
1097 ViewModeBoxes( mode );
1098 switch ( mode ) {
1099 case 0:
1100 parm_filter = FLAG_BASIC;
1101 break;
1102 case 1:
1103 parm_filter = FLAG_ADVANCED;
1104 break;
1106 printf("<br><tr>\n");
1107 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1108 printf("<td><select name=share>\n");
1109 if (snum < 0)
1110 printf("<option value=\" \"> \n");
1111 for (i=0;i<lp_numservices();i++) {
1112 s = lp_servicename(i);
1113 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
1114 push_utf8_talloc(talloc_tos(), &utf8_s, s, &converted_size);
1115 printf("<option %s value=\"%s\">%s\n",
1116 (share && strcmp(share,s)==0)?"SELECTED":"",
1117 utf8_s, utf8_s);
1118 TALLOC_FREE(utf8_s);
1121 printf("</select></td>\n");
1122 if (have_write_access) {
1123 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1125 printf("</tr>\n");
1126 printf("</table>");
1127 printf("<table>");
1128 if (have_write_access) {
1129 printf("<tr>\n");
1130 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1131 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1133 printf("</table>");
1136 if (snum >= 0) {
1137 if (have_write_access) {
1138 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1141 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1142 printf("<p>\n");
1145 if (snum >= 0) {
1146 printf("<table>\n");
1147 show_parameters(snum, 1, parm_filter, 0);
1148 printf("</table>\n");
1151 printf("</FORM>\n");
1154 /*************************************************************
1155 change a password either locally or remotely
1156 *************************************************************/
1157 static bool change_password(const char *remote_machine, const char *user_name,
1158 const char *old_passwd, const char *new_passwd,
1159 int local_flags)
1161 NTSTATUS ret;
1162 char *err_str = NULL;
1163 char *msg_str = NULL;
1165 if (demo_mode) {
1166 printf("%s\n<p>", _("password change in demo mode rejected"));
1167 return False;
1170 if (remote_machine != NULL) {
1171 ret = remote_password_change(remote_machine, user_name,
1172 old_passwd, new_passwd, &err_str);
1173 if (err_str != NULL)
1174 printf("%s\n<p>", err_str);
1175 SAFE_FREE(err_str);
1176 return NT_STATUS_IS_OK(ret);
1179 if(!initialize_password_db(True, NULL)) {
1180 printf("%s\n<p>", _("Can't setup password database vectors."));
1181 return False;
1184 ret = local_password_change(user_name, local_flags, new_passwd,
1185 &err_str, &msg_str);
1187 if(msg_str)
1188 printf("%s\n<p>", msg_str);
1189 if(err_str)
1190 printf("%s\n<p>", err_str);
1192 SAFE_FREE(msg_str);
1193 SAFE_FREE(err_str);
1194 return NT_STATUS_IS_OK(ret);
1197 /****************************************************************************
1198 do the stuff required to add or change a password
1199 ****************************************************************************/
1200 static void chg_passwd(void)
1202 const char *host;
1203 bool rslt;
1204 int local_flags = 0;
1206 /* Make sure users name has been specified */
1207 if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1208 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1209 return;
1213 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1214 * so if that's what we're doing, skip the rest of the checks
1216 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1219 * If current user is not root, make sure old password has been specified
1220 * If REMOTE change, even root must provide old password
1222 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1223 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1224 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1225 return;
1228 /* If changing a users password on a remote hosts we have to know what host */
1229 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1230 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1231 return;
1234 /* Make sure new passwords have been specified */
1235 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1236 (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1237 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1238 return;
1241 /* Make sure new passwords was typed correctly twice */
1242 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1243 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1244 return;
1248 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1249 host = cgi_variable(RHOST);
1250 } else if (am_root()) {
1251 host = NULL;
1252 } else {
1253 host = "127.0.0.1";
1257 * Set up the local flags.
1260 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1261 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1262 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1263 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1264 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1265 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1267 rslt = change_password(host,
1268 cgi_variable_nonull(SWAT_USER),
1269 cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1270 local_flags);
1272 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1273 printf("<p>");
1274 if (rslt == True) {
1275 printf("%s\n", _(" The passwd has been changed."));
1276 } else {
1277 printf("%s\n", _(" The passwd has NOT been changed."));
1281 return;
1284 /****************************************************************************
1285 display a password editing page
1286 ****************************************************************************/
1287 static void passwd_page(void)
1289 const char *new_name = cgi_user_name();
1290 const char passwd_form[] = "passwd";
1291 const char rpasswd_form[] = "rpasswd";
1293 if (!new_name) new_name = "";
1295 printf("<H2>%s</H2>\n", _("Server Password Management"));
1297 printf("<FORM name=\"swatform\" method=post>\n");
1298 print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form);
1300 printf("<table>\n");
1303 * Create all the dialog boxes for data collection
1305 printf("<tr><td> %s : </td>\n", _("User Name"));
1306 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1307 if (!am_root()) {
1308 printf("<tr><td> %s : </td>\n", _("Old Password"));
1309 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1311 printf("<tr><td> %s : </td>\n", _("New Password"));
1312 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1313 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1314 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1315 printf("</table>\n");
1318 * Create all the control buttons for requesting action
1320 printf("<input type=submit name=%s value=\"%s\">\n",
1321 CHG_S_PASSWD_FLAG, _("Change Password"));
1322 if (demo_mode || am_root()) {
1323 printf("<input type=submit name=%s value=\"%s\">\n",
1324 ADD_USER_FLAG, _("Add New User"));
1325 printf("<input type=submit name=%s value=\"%s\">\n",
1326 DELETE_USER_FLAG, _("Delete User"));
1327 printf("<input type=submit name=%s value=\"%s\">\n",
1328 DISABLE_USER_FLAG, _("Disable User"));
1329 printf("<input type=submit name=%s value=\"%s\">\n",
1330 ENABLE_USER_FLAG, _("Enable User"));
1332 printf("<p></FORM>\n");
1335 * Do some work if change, add, disable or enable was
1336 * requested. It could be this is the first time through this
1337 * code, so there isn't anything to do. */
1338 if (verify_xsrf_token(passwd_form) &&
1339 ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1340 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG)))) {
1341 chg_passwd();
1344 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1346 printf("<FORM name=\"swatform\" method=post>\n");
1347 print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form);
1349 printf("<table>\n");
1352 * Create all the dialog boxes for data collection
1354 printf("<tr><td> %s : </td>\n", _("User Name"));
1355 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1356 printf("<tr><td> %s : </td>\n", _("Old Password"));
1357 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1358 printf("<tr><td> %s : </td>\n", _("New Password"));
1359 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1360 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1361 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1362 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1363 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1365 printf("</table>");
1368 * Create all the control buttons for requesting action
1370 printf("<input type=submit name=%s value=\"%s\">",
1371 CHG_R_PASSWD_FLAG, _("Change Password"));
1373 printf("<p></FORM>\n");
1376 * Do some work if a request has been made to change the
1377 * password somewhere other than the server. It could be this
1378 * is the first time through this code, so there isn't
1379 * anything to do. */
1380 if (verify_xsrf_token(passwd_form) && cgi_variable(CHG_R_PASSWD_FLAG)) {
1381 chg_passwd();
1386 /****************************************************************************
1387 display a printers editing page
1388 ****************************************************************************/
1389 static void printers_page(void)
1391 const char *share = cgi_variable("share");
1392 char *s;
1393 int snum=-1;
1394 int i;
1395 int mode = 0;
1396 unsigned int parm_filter = FLAG_BASIC;
1397 const char form_name[] = "printers";
1399 if (!verify_xsrf_token(form_name)) {
1400 goto output_page;
1403 if (share)
1404 snum = lp_servicenumber(share);
1406 if (cgi_variable("Commit") && snum >= 0) {
1407 commit_parameters(snum);
1408 if (snum >= iNumNonAutoPrintServices)
1409 save_reload(snum);
1410 else
1411 save_reload(-1);
1412 snum = lp_servicenumber(share);
1415 if (cgi_variable("Delete") && snum >= 0) {
1416 lp_remove_service(snum);
1417 save_reload(-1);
1418 share = NULL;
1419 snum = -1;
1422 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1423 snum = lp_servicenumber(share);
1424 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1425 load_config(False);
1426 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1427 snum = lp_servicenumber(share);
1428 lp_do_parameter(snum, "print ok", "Yes");
1429 save_reload(snum);
1430 snum = lp_servicenumber(share);
1434 if ( cgi_variable("ViewMode") )
1435 mode = atoi(cgi_variable_nonull("ViewMode"));
1436 if ( cgi_variable("BasicMode"))
1437 mode = 0;
1438 if ( cgi_variable("AdvMode"))
1439 mode = 1;
1441 output_page:
1442 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1444 printf("<H3>%s</H3>\n", _("Important Note:"));
1445 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1446 printf("%s",_("are autoloaded printers from "));
1447 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1448 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1451 printf("<FORM name=\"swatform\" method=post>\n");
1452 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1454 ViewModeBoxes( mode );
1455 switch ( mode ) {
1456 case 0:
1457 parm_filter = FLAG_BASIC;
1458 break;
1459 case 1:
1460 parm_filter = FLAG_ADVANCED;
1461 break;
1463 printf("<table>\n");
1464 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1465 printf("<td><select name=\"share\">\n");
1466 if (snum < 0 || !lp_print_ok(snum))
1467 printf("<option value=\" \"> \n");
1468 for (i=0;i<lp_numservices();i++) {
1469 s = lp_servicename(i);
1470 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1471 if (i >= iNumNonAutoPrintServices)
1472 printf("<option %s value=\"%s\">[*]%s\n",
1473 (share && strcmp(share,s)==0)?"SELECTED":"",
1474 s, s);
1475 else
1476 printf("<option %s value=\"%s\">%s\n",
1477 (share && strcmp(share,s)==0)?"SELECTED":"",
1478 s, s);
1481 printf("</select></td>");
1482 if (have_write_access) {
1483 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1485 printf("</tr>");
1486 printf("</table>\n");
1488 if (have_write_access) {
1489 printf("<table>\n");
1490 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1491 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1492 printf("</table>");
1496 if (snum >= 0) {
1497 if (have_write_access) {
1498 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1500 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1501 printf("<p>\n");
1504 if (snum >= 0) {
1505 printf("<table>\n");
1506 show_parameters(snum, 1, parm_filter, 1);
1507 printf("</table>\n");
1509 printf("</FORM>\n");
1513 when the _() translation macro is used there is no obvious place to free
1514 the resulting string and there is no easy way to give a static pointer.
1515 All we can do is rotate between some static buffers and hope a single d_printf()
1516 doesn't have more calls to _() than the number of buffers
1519 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1521 const char *msgstr;
1522 const char *ret;
1524 msgstr = lang_msg(msgid);
1525 if (!msgstr) {
1526 return msgid;
1529 ret = talloc_strdup(ctx, msgstr);
1531 lang_msg_free(msgstr);
1532 if (!ret) {
1533 return msgid;
1536 return ret;
1540 * main function for SWAT.
1542 int main(int argc, char *argv[])
1544 const char *page;
1545 poptContext pc;
1546 struct poptOption long_options[] = {
1547 POPT_AUTOHELP
1548 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1549 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1550 POPT_COMMON_SAMBA
1551 POPT_TABLEEND
1553 TALLOC_CTX *frame = talloc_stackframe();
1555 fault_setup();
1556 umask(S_IWGRP | S_IWOTH);
1558 #if defined(HAVE_SET_AUTH_PARAMETERS)
1559 set_auth_parameters(argc, argv);
1560 #endif /* HAVE_SET_AUTH_PARAMETERS */
1562 /* just in case it goes wild ... */
1563 alarm(300);
1565 setlinebuf(stdout);
1567 /* we don't want any SIGPIPE messages */
1568 BlockSignals(True,SIGPIPE);
1570 debug_set_logfile("/dev/null");
1572 /* we don't want stderr screwing us up */
1573 close(2);
1574 open("/dev/null", O_WRONLY);
1575 setup_logging("swat", DEBUG_FILE);
1577 load_case_tables();
1579 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1581 /* Parse command line options */
1583 while(poptGetNextOpt(pc) != -1) { }
1585 poptFreeContext(pc);
1587 /* This should set a more apporiate log file */
1588 load_config(True);
1589 reopen_logs();
1590 load_interfaces();
1591 iNumNonAutoPrintServices = lp_numservices();
1592 if (pcap_cache_loaded()) {
1593 struct tevent_context *ev_ctx;
1594 struct messaging_context *msg_ctx;
1596 ev_ctx = s3_tevent_context_init(NULL);
1597 if (ev_ctx == NULL) {
1598 printf("s3_tevent_context_init() failed\n");
1599 return 0;
1601 msg_ctx = messaging_init(ev_ctx, ev_ctx);
1602 if (msg_ctx == NULL) {
1603 printf("messaging_init() failed\n");
1604 return 0;
1607 load_printers(ev_ctx, msg_ctx);
1609 talloc_free(ev_ctx);
1612 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1614 print_header();
1616 cgi_load_variables();
1618 if (!file_exist(get_dyn_CONFIGFILE())) {
1619 have_read_access = True;
1620 have_write_access = True;
1621 } else {
1622 /* check if the authenticated user has write access - if not then
1623 don't show write options */
1624 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1626 /* if the user doesn't have read access to smb.conf then
1627 don't let them view it */
1628 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1631 show_main_buttons();
1633 page = cgi_pathinfo();
1635 /* Root gets full functionality */
1636 if (have_read_access && strcmp(page, "globals")==0) {
1637 globals_page();
1638 } else if (have_read_access && strcmp(page,"shares")==0) {
1639 shares_page();
1640 } else if (have_read_access && strcmp(page,"printers")==0) {
1641 printers_page();
1642 } else if (have_read_access && strcmp(page,"status")==0) {
1643 status_page();
1644 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1645 viewconfig_page();
1646 } else if (strcmp(page,"passwd")==0) {
1647 passwd_page();
1648 } else if (have_read_access && strcmp(page,"wizard")==0) {
1649 wizard_page();
1650 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1651 wizard_params_page();
1652 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1653 rewritecfg_file();
1654 } else {
1655 welcome_page();
1658 print_footer();
1660 TALLOC_FREE(frame);
1661 return 0;
1664 /** @} **/