drs-fsmo: Improve handling of FSMO role takeover.
[Samba/gebeck_regimport.git] / source3 / web / swat.c
blob90e4af9958faf4cdd0c19593c4ae91f58d5220bf
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 /* FIXME ! Truncate check. JRA. */
180 (void)strlcat(token_str, tmp, sizeof(tmp));
184 void print_xsrf_token(const char *username, const char *pass,
185 const char *formname)
187 char token[33];
188 time_t xsrf_time = time(NULL);
190 get_xsrf_token(username, pass, formname, xsrf_time, token);
191 printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
192 XSRF_TOKEN, token);
193 printf("<input type=\"hidden\" name=\"%s\" value=\"%lld\">\n",
194 XSRF_TIME, (long long int)xsrf_time);
197 bool verify_xsrf_token(const char *formname)
199 char expected[33];
200 const char *username = cgi_user_name();
201 const char *pass = cgi_user_pass();
202 const char *token = cgi_variable_nonull(XSRF_TOKEN);
203 const char *time_str = cgi_variable_nonull(XSRF_TIME);
204 char *p = NULL;
205 long long xsrf_time_ll = 0;
206 time_t xsrf_time = 0;
207 time_t now = time(NULL);
209 errno = 0;
210 xsrf_time_ll = strtoll(time_str, &p, 10);
211 if (errno != 0) {
212 return false;
214 if (p == NULL) {
215 return false;
217 if (PTR_DIFF(p, time_str) > strlen(time_str)) {
218 return false;
220 if (xsrf_time_ll > _TYPE_MAXIMUM(time_t)) {
221 return false;
223 if (xsrf_time_ll < _TYPE_MINIMUM(time_t)) {
224 return false;
226 xsrf_time = xsrf_time_ll;
228 if (abs(now - xsrf_time) > XSRF_TIMEOUT) {
229 return false;
232 get_xsrf_token(username, pass, formname, xsrf_time, expected);
233 return (strncmp(expected, token, sizeof(expected)) == 0);
237 /****************************************************************************
238 include a lump of html in a page
239 ****************************************************************************/
240 static int include_html(const char *fname)
242 int fd;
243 char buf[1024];
244 int ret;
246 fd = web_open(fname, O_RDONLY, 0);
248 if (fd == -1) {
249 printf(_("ERROR: Can't open %s"), fname);
250 printf("\n");
251 return 0;
254 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
255 if (write(1, buf, ret) == -1) {
256 break;
260 close(fd);
261 return 1;
264 /****************************************************************************
265 start the page with standard stuff
266 ****************************************************************************/
267 static void print_header(void)
269 if (!cgi_waspost()) {
270 printf("Expires: 0\r\n");
272 printf("Content-type: text/html\r\n\r\n");
274 if (!include_html("include/header.html")) {
275 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
276 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
280 /* *******************************************************************
281 show parameter label with translated name in the following form
282 because showing original and translated label in one line looks
283 too long, and showing translated label only is unusable for
284 heavy users.
285 -------------------------------
286 HELP security [combo box][button]
287 SECURITY
288 -------------------------------
289 (capital words are translated by gettext.)
290 if no translation is available, then same form as original is
291 used.
292 "i18n_translated_parm" class is used to change the color of the
293 translated parameter with CSS.
294 **************************************************************** */
295 static const char *get_parm_translated(TALLOC_CTX *ctx,
296 const char* pAnchor, const char* pHelp, const char* pLabel)
298 const char *pTranslated = _(pLabel);
299 char *output;
300 if(strcmp(pLabel, pTranslated) != 0) {
301 output = talloc_asprintf(ctx,
302 "<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>",
303 pAnchor, pHelp, pLabel, pTranslated);
304 return output;
306 output = talloc_asprintf(ctx,
307 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
308 pAnchor, pHelp, pLabel);
309 return output;
311 /****************************************************************************
312 finish off the page
313 ****************************************************************************/
314 static void print_footer(void)
316 if (!include_html("include/footer.html")) {
317 printf("\n</BODY>\n</HTML>\n");
321 /****************************************************************************
322 display one editable parameter in a form
323 ****************************************************************************/
324 static void show_parameter(int snum, struct parm_struct *parm)
326 int i;
327 void *ptr;
328 char *utf8_s1, *utf8_s2;
329 size_t converted_size;
330 TALLOC_CTX *ctx = talloc_stackframe();
332 if (parm->p_class == P_LOCAL && snum >= 0) {
333 ptr = lp_local_ptr_by_snum(snum, parm);
334 } else {
335 ptr = lp_parm_ptr(NULL, parm);
338 printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
339 stripspaceupper(parm->label), _("Help"), parm->label));
340 switch (parm->type) {
341 case P_CHAR:
342 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
343 make_parm_name(parm->label), *(char *)ptr);
344 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
345 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
346 break;
348 case P_LIST:
349 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
350 make_parm_name(parm->label));
351 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
352 char **list = *(char ***)ptr;
353 for (;*list;list++) {
354 /* enclose in HTML encoded quotes if the string contains a space */
355 if ( strchr_m(*list, ' ') ) {
356 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
357 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
358 printf("&quot;%s&quot;%s", utf8_s1, utf8_s2);
359 } else {
360 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
361 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
362 printf("%s%s", utf8_s1, utf8_s2);
364 TALLOC_FREE(utf8_s1);
365 TALLOC_FREE(utf8_s2);
368 printf("\">");
369 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
370 _("Set Default"), make_parm_name(parm->label));
371 if (parm->def.lvalue) {
372 char **list = (char **)(parm->def.lvalue);
373 for (; *list; list++) {
374 /* enclose in HTML encoded quotes if the string contains a space */
375 if ( strchr_m(*list, ' ') )
376 printf("&quot;%s&quot;%s", *list, ((*(list+1))?", ":""));
377 else
378 printf("%s%s", *list, ((*(list+1))?", ":""));
381 printf("\'\">");
382 break;
384 case P_STRING:
385 case P_USTRING:
386 push_utf8_talloc(talloc_tos(), &utf8_s1, *(char **)ptr, &converted_size);
387 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
388 make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
389 TALLOC_FREE(utf8_s1);
390 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
391 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
392 break;
394 case P_BOOL:
395 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
396 printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
397 printf("<option %s>No", (*(bool *)ptr)?"":"selected");
398 printf("</select>");
399 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
400 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
401 break;
403 case P_BOOLREV:
404 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
405 printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
406 printf("<option %s>No", (*(bool *)ptr)?"selected":"");
407 printf("</select>");
408 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
409 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
410 break;
412 case P_INTEGER:
413 case P_BYTES:
414 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
415 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
416 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
417 break;
419 case P_OCTAL: {
420 char *o;
421 o = octal_string(*(int *)ptr);
422 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
423 make_parm_name(parm->label), o);
424 TALLOC_FREE(o);
425 o = octal_string((int)(parm->def.ivalue));
426 printf("<input type=button value=\"%s\" "
427 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
428 _("Set Default"), make_parm_name(parm->label), o);
429 TALLOC_FREE(o);
430 break;
433 case P_ENUM:
434 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
435 for (i=0;parm->enum_list[i].name;i++) {
436 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
437 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
440 printf("</select>");
441 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
442 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
443 break;
444 case P_SEP:
445 break;
447 printf("</td></tr>\n");
448 TALLOC_FREE(ctx);
451 /****************************************************************************
452 display a set of parameters for a service
453 ****************************************************************************/
454 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
456 int i = 0;
457 struct parm_struct *parm;
458 const char *heading = NULL;
459 const char *last_heading = NULL;
461 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
462 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
463 continue;
464 if (parm->p_class == P_SEPARATOR) {
465 heading = parm->label;
466 continue;
468 if (parm->flags & FLAG_HIDE) continue;
469 if (snum >= 0) {
470 if (printers & !(parm->flags & FLAG_PRINT)) continue;
471 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
474 if (!( parm_filter & FLAG_ADVANCED )) {
475 if (!(parm->flags & FLAG_BASIC)) {
476 void *ptr;
477 if (parm->p_class == P_LOCAL && snum >= 0) {
478 ptr = lp_local_ptr_by_snum(snum, parm);
479 } else {
480 ptr = lp_parm_ptr(NULL, parm);
483 switch (parm->type) {
484 case P_CHAR:
485 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
486 break;
488 case P_LIST:
489 if (!str_list_equal(*(const char ***)ptr,
490 (const char **)(parm->def.lvalue))) continue;
491 break;
493 case P_STRING:
494 case P_USTRING:
495 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
496 break;
498 case P_BOOL:
499 case P_BOOLREV:
500 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
501 break;
503 case P_INTEGER:
504 case P_BYTES:
505 case P_OCTAL:
506 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
507 break;
510 case P_ENUM:
511 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
512 break;
513 case P_SEP:
514 continue;
517 if (printers && !(parm->flags & FLAG_PRINT)) continue;
520 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
522 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
524 if (heading && heading != last_heading) {
525 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
526 last_heading = heading;
528 show_parameter(snum, parm);
532 /****************************************************************************
533 load the smb.conf file into loadparm.
534 ****************************************************************************/
535 static bool load_config(bool save_def)
537 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
540 /****************************************************************************
541 write a config file
542 ****************************************************************************/
543 static void write_config(FILE *f, bool show_defaults)
545 TALLOC_CTX *ctx = talloc_stackframe();
547 fprintf(f, "# Samba config file created using SWAT\n");
548 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
549 fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
551 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
553 TALLOC_FREE(ctx);
556 /****************************************************************************
557 save and reload the smb.conf config file
558 ****************************************************************************/
559 static int save_reload(int snum)
561 FILE *f;
562 struct stat st;
564 f = fopen(get_dyn_CONFIGFILE(),"w");
565 if (!f) {
566 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
567 printf("\n");
568 return 0;
571 /* just in case they have used the buggy xinetd to create the file */
572 if (fstat(fileno(f), &st) == 0 &&
573 (st.st_mode & S_IWOTH)) {
574 #if defined HAVE_FCHMOD
575 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
576 #else
577 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
578 #endif
581 write_config(f, False);
582 if (snum >= 0)
583 lp_dump_one(f, False, snum);
584 fclose(f);
586 lp_kill_all_services();
588 if (!load_config(False)) {
589 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
590 printf("\n");
591 return 0;
593 iNumNonAutoPrintServices = lp_numservices();
594 if (pcap_cache_loaded()) {
595 struct tevent_context *ev_ctx;
596 struct messaging_context *msg_ctx;
598 ev_ctx = s3_tevent_context_init(NULL);
599 if (ev_ctx == NULL) {
600 printf("s3_tevent_context_init() failed\n");
601 return 0;
603 msg_ctx = messaging_init(ev_ctx, ev_ctx);
604 if (msg_ctx == NULL) {
605 printf("messaging_init() failed\n");
606 return 0;
609 load_printers(ev_ctx, msg_ctx);
611 talloc_free(ev_ctx);
614 return 1;
617 /****************************************************************************
618 commit one parameter
619 ****************************************************************************/
620 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
622 int i;
623 char *s;
625 if (snum < 0 && parm->p_class == P_LOCAL) {
626 /* this handles the case where we are changing a local
627 variable globally. We need to change the parameter in
628 all shares where it is currently set to the default */
629 for (i=0;i<lp_numservices();i++) {
630 s = lp_servicename(talloc_tos(), i);
631 if (s && (*s) && lp_is_default(i, parm)) {
632 lp_do_parameter(i, parm->label, v);
637 lp_do_parameter(snum, parm->label, v);
640 /****************************************************************************
641 commit a set of parameters for a service
642 ****************************************************************************/
643 static void commit_parameters(int snum)
645 int i = 0;
646 struct parm_struct *parm;
647 char *label;
648 const char *v;
650 while ((parm = lp_next_parameter(snum, &i, 1))) {
651 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
652 if ((v = cgi_variable(label)) != NULL) {
653 if (parm->flags & FLAG_HIDE)
654 continue;
655 commit_parameter(snum, parm, v);
657 SAFE_FREE(label);
662 /****************************************************************************
663 spit out the html for a link with an image
664 ****************************************************************************/
665 static void image_link(const char *name, const char *hlink, const char *src)
667 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
668 cgi_baseurl(), hlink, src, name);
671 /****************************************************************************
672 display the main navigation controls at the top of each page along
673 with a title
674 ****************************************************************************/
675 static void show_main_buttons(void)
677 char *p;
679 if ((p = cgi_user_name()) && strcmp(p, "root")) {
680 printf(_("Logged in as <b>%s</b>"), p);
681 printf("<p>\n");
684 image_link(_("Home"), "", "images/home.gif");
685 if (have_write_access) {
686 image_link(_("Globals"), "globals", "images/globals.gif");
687 image_link(_("Shares"), "shares", "images/shares.gif");
688 image_link(_("Printers"), "printers", "images/printers.gif");
689 image_link(_("Wizard"), "wizard", "images/wizard.gif");
691 /* root always gets all buttons, otherwise look for -P */
692 if ( have_write_access || (!passwd_only && have_read_access) ) {
693 image_link(_("Status"), "status", "images/status.gif");
694 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
696 image_link(_("Password Management"), "passwd", "images/passwd.gif");
698 printf("<HR>\n");
701 /****************************************************************************
702 * Handle Display/Edit Mode CGI
703 ****************************************************************************/
704 static void ViewModeBoxes(int mode)
706 printf("<p>%s:&nbsp;\n", _("Current View Is"));
707 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
708 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
709 printf("<br>%s:&nbsp;\n", _("Change View To"));
710 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
711 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
712 printf("</p><br>\n");
715 /****************************************************************************
716 display a welcome page
717 ****************************************************************************/
718 static void welcome_page(void)
720 if (file_exist("help/welcome.html")) {
721 include_html("help/welcome.html");
722 } else {
723 include_html("help/welcome-no-samba-doc.html");
727 /****************************************************************************
728 display the current smb.conf
729 ****************************************************************************/
730 static void viewconfig_page(void)
732 int full_view=0;
733 const char form_name[] = "viewconfig";
735 if (!verify_xsrf_token(form_name)) {
736 goto output_page;
739 if (cgi_variable("full_view")) {
740 full_view = 1;
743 output_page:
744 printf("<H2>%s</H2>\n", _("Current Config"));
745 printf("<form method=post>\n");
746 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
748 if (full_view) {
749 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
750 } else {
751 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
754 printf("<p><pre>");
755 write_config(stdout, full_view);
756 printf("</pre>");
757 printf("</form>\n");
760 /****************************************************************************
761 second screen of the wizard ... Fetch Configuration Parameters
762 ****************************************************************************/
763 static void wizard_params_page(void)
765 unsigned int parm_filter = FLAG_WIZARD;
766 const char form_name[] = "wizard_params";
768 /* Here we first set and commit all the parameters that were selected
769 in the previous screen. */
771 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
773 if (!verify_xsrf_token(form_name)) {
774 goto output_page;
777 if (cgi_variable("Commit")) {
778 commit_parameters(GLOBAL_SECTION_SNUM);
779 save_reload(-1);
782 output_page:
783 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
784 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
786 if (have_write_access) {
787 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
790 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
791 printf("<p>\n");
793 printf("<table>\n");
794 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
795 printf("</table>\n");
796 printf("</form>\n");
799 /****************************************************************************
800 Utility to just rewrite the smb.conf file - effectively just cleans it up
801 ****************************************************************************/
802 static void rewritecfg_file(void)
804 commit_parameters(GLOBAL_SECTION_SNUM);
805 save_reload(-1);
806 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
809 /****************************************************************************
810 wizard to create/modify the smb.conf file
811 ****************************************************************************/
812 static void wizard_page(void)
814 /* Set some variables to collect data from smb.conf */
815 int role = 0;
816 int winstype = 0;
817 int have_home = -1;
818 int HomeExpo = 0;
819 int SerType = 0;
820 const char form_name[] = "wizard";
822 if (!verify_xsrf_token(form_name)) {
823 goto output_page;
826 if (cgi_variable("Rewrite")) {
827 (void) rewritecfg_file();
828 return;
831 if (cgi_variable("GetWizardParams")){
832 (void) wizard_params_page();
833 return;
836 if (cgi_variable("Commit")){
837 SerType = atoi(cgi_variable_nonull("ServerType"));
838 winstype = atoi(cgi_variable_nonull("WINSType"));
839 have_home = lp_servicenumber(HOMES_NAME);
840 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
842 /* Plain text passwords are too badly broken - use encrypted passwords only */
843 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
845 switch ( SerType ){
846 case 0:
847 /* Stand-alone Server */
848 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
849 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
850 break;
851 case 1:
852 /* Domain Member */
853 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
854 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
855 break;
856 case 2:
857 /* Domain Controller */
858 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
859 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
860 break;
862 switch ( winstype ) {
863 case 0:
864 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
865 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
866 break;
867 case 1:
868 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
869 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
870 break;
871 case 2:
872 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
873 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
874 break;
877 /* Have to create Homes share? */
878 if ((HomeExpo == 1) && (have_home == -1)) {
879 const char *unix_share = HOMES_NAME;
881 load_config(False);
882 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
883 have_home = lp_servicenumber(HOMES_NAME);
884 lp_do_parameter( have_home, "read only", "No");
885 lp_do_parameter( have_home, "valid users", "%S");
886 lp_do_parameter( have_home, "browseable", "No");
887 commit_parameters(have_home);
888 save_reload(have_home);
891 /* Need to Delete Homes share? */
892 if ((HomeExpo == 0) && (have_home != -1)) {
893 lp_remove_service(have_home);
894 have_home = -1;
897 commit_parameters(GLOBAL_SECTION_SNUM);
898 save_reload(-1);
900 else
902 /* Now determine smb.conf WINS settings */
903 if (lp_we_are_a_wins_server())
904 winstype = 1;
905 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
906 winstype = 2;
908 /* Do we have a homes share? */
909 have_home = lp_servicenumber(HOMES_NAME);
911 if ((winstype == 2) && lp_we_are_a_wins_server())
912 winstype = 3;
914 role = lp_server_role();
916 output_page:
917 /* Here we go ... */
918 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
919 printf("<form method=post action=wizard>\n");
920 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
922 if (have_write_access) {
923 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
924 printf("%s", _("The same will happen if you press the commit button."));
925 printf("<br><br>\n");
926 printf("<center>");
927 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
928 printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
929 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
930 printf("</center>\n");
933 printf("<hr>");
934 printf("<center><table border=0>");
935 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
936 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
937 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
938 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
939 printf("</tr>\n");
940 if (role == ROLE_DOMAIN_BDC) {
941 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
943 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
944 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
945 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
946 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
947 printf("</tr>\n");
948 printf("<tr><td></td><td></td><td></td><td>%s&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
950 /* Print out the list of wins servers */
951 if(lp_wins_server_list()) {
952 int i;
953 const char **wins_servers = lp_wins_server_list();
954 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
957 printf("\"></td></tr>\n");
958 if (winstype == 3) {
959 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"));
960 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
962 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
963 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
964 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
965 printf("<td></td></tr>\n");
967 /* Enable this when we are ready ....
968 * printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
969 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
970 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
971 * printf("<td></td></tr>\n");
974 printf("</table></center>");
975 printf("<hr>");
977 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
978 printf("</form>\n");
982 /****************************************************************************
983 display a globals editing page
984 ****************************************************************************/
985 static void globals_page(void)
987 unsigned int parm_filter = FLAG_BASIC;
988 int mode = 0;
989 const char form_name[] = "globals";
991 printf("<H2>%s</H2>\n", _("Global Parameters"));
993 if (!verify_xsrf_token(form_name)) {
994 goto output_page;
997 if (cgi_variable("Commit")) {
998 commit_parameters(GLOBAL_SECTION_SNUM);
999 save_reload(-1);
1002 if ( cgi_variable("ViewMode") )
1003 mode = atoi(cgi_variable_nonull("ViewMode"));
1004 if ( cgi_variable("BasicMode"))
1005 mode = 0;
1006 if ( cgi_variable("AdvMode"))
1007 mode = 1;
1009 output_page:
1010 printf("<form name=\"swatform\" method=post action=globals>\n");
1011 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1013 ViewModeBoxes( mode );
1014 switch ( mode ) {
1015 case 0:
1016 parm_filter = FLAG_BASIC;
1017 break;
1018 case 1:
1019 parm_filter = FLAG_ADVANCED;
1020 break;
1022 printf("<br>\n");
1023 if (have_write_access) {
1024 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
1025 _("Commit Changes"));
1028 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
1029 _("Reset Values"));
1031 printf("<p>\n");
1032 printf("<table>\n");
1033 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
1034 printf("</table>\n");
1035 printf("</form>\n");
1038 /****************************************************************************
1039 display a shares editing page. share is in unix codepage,
1040 ****************************************************************************/
1041 static void shares_page(void)
1043 const char *share = cgi_variable("share");
1044 char *s;
1045 char *utf8_s;
1046 int snum = -1;
1047 int i;
1048 int mode = 0;
1049 unsigned int parm_filter = FLAG_BASIC;
1050 size_t converted_size;
1051 const char form_name[] = "shares";
1053 printf("<H2>%s</H2>\n", _("Share Parameters"));
1055 if (!verify_xsrf_token(form_name)) {
1056 goto output_page;
1059 if (share)
1060 snum = lp_servicenumber(share);
1063 if (cgi_variable("Commit") && snum >= 0) {
1064 commit_parameters(snum);
1065 save_reload(-1);
1066 snum = lp_servicenumber(share);
1069 if (cgi_variable("Delete") && snum >= 0) {
1070 lp_remove_service(snum);
1071 save_reload(-1);
1072 share = NULL;
1073 snum = -1;
1076 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1077 snum = lp_servicenumber(share);
1078 if (snum < 0) {
1079 load_config(False);
1080 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1081 snum = lp_servicenumber(share);
1082 save_reload(snum);
1083 snum = lp_servicenumber(share);
1087 if ( cgi_variable("ViewMode") )
1088 mode = atoi(cgi_variable_nonull("ViewMode"));
1089 if ( cgi_variable("BasicMode"))
1090 mode = 0;
1091 if ( cgi_variable("AdvMode"))
1092 mode = 1;
1094 output_page:
1095 printf("<FORM name=\"swatform\" method=post>\n");
1096 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1098 printf("<table>\n");
1100 ViewModeBoxes( mode );
1101 switch ( mode ) {
1102 case 0:
1103 parm_filter = FLAG_BASIC;
1104 break;
1105 case 1:
1106 parm_filter = FLAG_ADVANCED;
1107 break;
1109 printf("<br><tr>\n");
1110 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1111 printf("<td><select name=share>\n");
1112 if (snum < 0)
1113 printf("<option value=\" \"> \n");
1114 for (i=0;i<lp_numservices();i++) {
1115 s = lp_servicename(talloc_tos(), i);
1116 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
1117 push_utf8_talloc(talloc_tos(), &utf8_s, s, &converted_size);
1118 printf("<option %s value=\"%s\">%s\n",
1119 (share && strcmp(share,s)==0)?"SELECTED":"",
1120 utf8_s, utf8_s);
1121 TALLOC_FREE(utf8_s);
1124 printf("</select></td>\n");
1125 if (have_write_access) {
1126 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1128 printf("</tr>\n");
1129 printf("</table>");
1130 printf("<table>");
1131 if (have_write_access) {
1132 printf("<tr>\n");
1133 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1134 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1136 printf("</table>");
1139 if (snum >= 0) {
1140 if (have_write_access) {
1141 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1144 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1145 printf("<p>\n");
1148 if (snum >= 0) {
1149 printf("<table>\n");
1150 show_parameters(snum, 1, parm_filter, 0);
1151 printf("</table>\n");
1154 printf("</FORM>\n");
1157 /*************************************************************
1158 change a password either locally or remotely
1159 *************************************************************/
1160 static bool change_password(const char *remote_machine, const char *user_name,
1161 const char *old_passwd, const char *new_passwd,
1162 int local_flags)
1164 NTSTATUS ret;
1165 char *err_str = NULL;
1166 char *msg_str = NULL;
1168 if (demo_mode) {
1169 printf("%s\n<p>", _("password change in demo mode rejected"));
1170 return False;
1173 if (remote_machine != NULL) {
1174 ret = remote_password_change(remote_machine, user_name,
1175 old_passwd, new_passwd, &err_str);
1176 if (err_str != NULL)
1177 printf("%s\n<p>", err_str);
1178 SAFE_FREE(err_str);
1179 return NT_STATUS_IS_OK(ret);
1182 if(!initialize_password_db(True, NULL)) {
1183 printf("%s\n<p>", _("Can't setup password database vectors."));
1184 return False;
1187 ret = local_password_change(user_name, local_flags, new_passwd,
1188 &err_str, &msg_str);
1190 if(msg_str)
1191 printf("%s\n<p>", msg_str);
1192 if(err_str)
1193 printf("%s\n<p>", err_str);
1195 SAFE_FREE(msg_str);
1196 SAFE_FREE(err_str);
1197 return NT_STATUS_IS_OK(ret);
1200 /****************************************************************************
1201 do the stuff required to add or change a password
1202 ****************************************************************************/
1203 static void chg_passwd(void)
1205 const char *host;
1206 bool rslt;
1207 int local_flags = 0;
1209 /* Make sure users name has been specified */
1210 if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1211 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1212 return;
1216 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1217 * so if that's what we're doing, skip the rest of the checks
1219 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1222 * If current user is not root, make sure old password has been specified
1223 * If REMOTE change, even root must provide old password
1225 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1226 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1227 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1228 return;
1231 /* If changing a users password on a remote hosts we have to know what host */
1232 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1233 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1234 return;
1237 /* Make sure new passwords have been specified */
1238 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1239 (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1240 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1241 return;
1244 /* Make sure new passwords was typed correctly twice */
1245 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1246 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1247 return;
1251 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1252 host = cgi_variable(RHOST);
1253 } else if (am_root()) {
1254 host = NULL;
1255 } else {
1256 host = "127.0.0.1";
1260 * Set up the local flags.
1263 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1264 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1265 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1266 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1267 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1268 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1270 rslt = change_password(host,
1271 cgi_variable_nonull(SWAT_USER),
1272 cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1273 local_flags);
1275 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1276 printf("<p>");
1277 if (rslt == True) {
1278 printf("%s\n", _(" The passwd has been changed."));
1279 } else {
1280 printf("%s\n", _(" The passwd has NOT been changed."));
1284 return;
1287 /****************************************************************************
1288 display a password editing page
1289 ****************************************************************************/
1290 static void passwd_page(void)
1292 const char *new_name = cgi_user_name();
1293 const char passwd_form[] = "passwd";
1294 const char rpasswd_form[] = "rpasswd";
1296 if (!new_name) new_name = "";
1298 printf("<H2>%s</H2>\n", _("Server Password Management"));
1300 printf("<FORM name=\"swatform\" method=post>\n");
1301 print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form);
1303 printf("<table>\n");
1306 * Create all the dialog boxes for data collection
1308 printf("<tr><td> %s : </td>\n", _("User Name"));
1309 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1310 if (!am_root()) {
1311 printf("<tr><td> %s : </td>\n", _("Old Password"));
1312 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1314 printf("<tr><td> %s : </td>\n", _("New Password"));
1315 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1316 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1317 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1318 printf("</table>\n");
1321 * Create all the control buttons for requesting action
1323 printf("<input type=submit name=%s value=\"%s\">\n",
1324 CHG_S_PASSWD_FLAG, _("Change Password"));
1325 if (demo_mode || am_root()) {
1326 printf("<input type=submit name=%s value=\"%s\">\n",
1327 ADD_USER_FLAG, _("Add New User"));
1328 printf("<input type=submit name=%s value=\"%s\">\n",
1329 DELETE_USER_FLAG, _("Delete User"));
1330 printf("<input type=submit name=%s value=\"%s\">\n",
1331 DISABLE_USER_FLAG, _("Disable User"));
1332 printf("<input type=submit name=%s value=\"%s\">\n",
1333 ENABLE_USER_FLAG, _("Enable User"));
1335 printf("<p></FORM>\n");
1338 * Do some work if change, add, disable or enable was
1339 * requested. It could be this is the first time through this
1340 * code, so there isn't anything to do. */
1341 if (verify_xsrf_token(passwd_form) &&
1342 ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1343 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG)))) {
1344 chg_passwd();
1347 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1349 printf("<FORM name=\"swatform\" method=post>\n");
1350 print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form);
1352 printf("<table>\n");
1355 * Create all the dialog boxes for data collection
1357 printf("<tr><td> %s : </td>\n", _("User Name"));
1358 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1359 printf("<tr><td> %s : </td>\n", _("Old Password"));
1360 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1361 printf("<tr><td> %s : </td>\n", _("New Password"));
1362 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1363 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1364 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1365 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1366 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1368 printf("</table>");
1371 * Create all the control buttons for requesting action
1373 printf("<input type=submit name=%s value=\"%s\">",
1374 CHG_R_PASSWD_FLAG, _("Change Password"));
1376 printf("<p></FORM>\n");
1379 * Do some work if a request has been made to change the
1380 * password somewhere other than the server. It could be this
1381 * is the first time through this code, so there isn't
1382 * anything to do. */
1383 if (verify_xsrf_token(passwd_form) && cgi_variable(CHG_R_PASSWD_FLAG)) {
1384 chg_passwd();
1389 /****************************************************************************
1390 display a printers editing page
1391 ****************************************************************************/
1392 static void printers_page(void)
1394 const char *share = cgi_variable("share");
1395 char *s;
1396 int snum=-1;
1397 int i;
1398 int mode = 0;
1399 unsigned int parm_filter = FLAG_BASIC;
1400 const char form_name[] = "printers";
1402 if (!verify_xsrf_token(form_name)) {
1403 goto output_page;
1406 if (share)
1407 snum = lp_servicenumber(share);
1409 if (cgi_variable("Commit") && snum >= 0) {
1410 commit_parameters(snum);
1411 if (snum >= iNumNonAutoPrintServices)
1412 save_reload(snum);
1413 else
1414 save_reload(-1);
1415 snum = lp_servicenumber(share);
1418 if (cgi_variable("Delete") && snum >= 0) {
1419 lp_remove_service(snum);
1420 save_reload(-1);
1421 share = NULL;
1422 snum = -1;
1425 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1426 snum = lp_servicenumber(share);
1427 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1428 load_config(False);
1429 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1430 snum = lp_servicenumber(share);
1431 lp_do_parameter(snum, "print ok", "Yes");
1432 save_reload(snum);
1433 snum = lp_servicenumber(share);
1437 if ( cgi_variable("ViewMode") )
1438 mode = atoi(cgi_variable_nonull("ViewMode"));
1439 if ( cgi_variable("BasicMode"))
1440 mode = 0;
1441 if ( cgi_variable("AdvMode"))
1442 mode = 1;
1444 output_page:
1445 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1447 printf("<H3>%s</H3>\n", _("Important Note:"));
1448 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1449 printf("%s",_("are autoloaded printers from "));
1450 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1451 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1454 printf("<FORM name=\"swatform\" method=post>\n");
1455 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1457 ViewModeBoxes( mode );
1458 switch ( mode ) {
1459 case 0:
1460 parm_filter = FLAG_BASIC;
1461 break;
1462 case 1:
1463 parm_filter = FLAG_ADVANCED;
1464 break;
1466 printf("<table>\n");
1467 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1468 printf("<td><select name=\"share\">\n");
1469 if (snum < 0 || !lp_print_ok(snum))
1470 printf("<option value=\" \"> \n");
1471 for (i=0;i<lp_numservices();i++) {
1472 s = lp_servicename(talloc_tos(), i);
1473 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1474 if (i >= iNumNonAutoPrintServices)
1475 printf("<option %s value=\"%s\">[*]%s\n",
1476 (share && strcmp(share,s)==0)?"SELECTED":"",
1477 s, s);
1478 else
1479 printf("<option %s value=\"%s\">%s\n",
1480 (share && strcmp(share,s)==0)?"SELECTED":"",
1481 s, s);
1484 printf("</select></td>");
1485 if (have_write_access) {
1486 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1488 printf("</tr>");
1489 printf("</table>\n");
1491 if (have_write_access) {
1492 printf("<table>\n");
1493 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1494 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1495 printf("</table>");
1499 if (snum >= 0) {
1500 if (have_write_access) {
1501 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1503 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1504 printf("<p>\n");
1507 if (snum >= 0) {
1508 printf("<table>\n");
1509 show_parameters(snum, 1, parm_filter, 1);
1510 printf("</table>\n");
1512 printf("</FORM>\n");
1516 when the _() translation macro is used there is no obvious place to free
1517 the resulting string and there is no easy way to give a static pointer.
1518 All we can do is rotate between some static buffers and hope a single d_printf()
1519 doesn't have more calls to _() than the number of buffers
1522 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1524 const char *msgstr;
1525 const char *ret;
1527 msgstr = lang_msg(msgid);
1528 if (!msgstr) {
1529 return msgid;
1532 ret = talloc_strdup(ctx, msgstr);
1534 lang_msg_free(msgstr);
1535 if (!ret) {
1536 return msgid;
1539 return ret;
1543 * main function for SWAT.
1545 int main(int argc, char *argv[])
1547 const char *page;
1548 poptContext pc;
1549 struct poptOption long_options[] = {
1550 POPT_AUTOHELP
1551 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1552 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1553 POPT_COMMON_SAMBA
1554 POPT_TABLEEND
1556 TALLOC_CTX *frame = talloc_stackframe();
1558 fault_setup();
1559 umask(S_IWGRP | S_IWOTH);
1561 #if defined(HAVE_SET_AUTH_PARAMETERS)
1562 set_auth_parameters(argc, argv);
1563 #endif /* HAVE_SET_AUTH_PARAMETERS */
1565 /* just in case it goes wild ... */
1566 alarm(300);
1568 setlinebuf(stdout);
1570 /* we don't want any SIGPIPE messages */
1571 BlockSignals(True,SIGPIPE);
1573 debug_set_logfile("/dev/null");
1575 /* we don't want stderr screwing us up */
1576 close(2);
1577 open("/dev/null", O_WRONLY);
1578 setup_logging("swat", DEBUG_FILE);
1580 load_case_tables();
1582 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1584 /* Parse command line options */
1586 while(poptGetNextOpt(pc) != -1) { }
1588 poptFreeContext(pc);
1590 /* This should set a more apporiate log file */
1591 load_config(True);
1592 reopen_logs();
1593 load_interfaces();
1594 iNumNonAutoPrintServices = lp_numservices();
1595 if (pcap_cache_loaded()) {
1596 struct tevent_context *ev_ctx;
1597 struct messaging_context *msg_ctx;
1599 ev_ctx = s3_tevent_context_init(NULL);
1600 if (ev_ctx == NULL) {
1601 printf("s3_tevent_context_init() failed\n");
1602 return 0;
1604 msg_ctx = messaging_init(ev_ctx, ev_ctx);
1605 if (msg_ctx == NULL) {
1606 printf("messaging_init() failed\n");
1607 return 0;
1610 load_printers(ev_ctx, msg_ctx);
1612 talloc_free(ev_ctx);
1615 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1617 print_header();
1619 cgi_load_variables();
1621 if (!file_exist(get_dyn_CONFIGFILE())) {
1622 have_read_access = True;
1623 have_write_access = True;
1624 } else {
1625 /* check if the authenticated user has write access - if not then
1626 don't show write options */
1627 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1629 /* if the user doesn't have read access to smb.conf then
1630 don't let them view it */
1631 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1634 show_main_buttons();
1636 page = cgi_pathinfo();
1638 /* Root gets full functionality */
1639 if (have_read_access && strcmp(page, "globals")==0) {
1640 globals_page();
1641 } else if (have_read_access && strcmp(page,"shares")==0) {
1642 shares_page();
1643 } else if (have_read_access && strcmp(page,"printers")==0) {
1644 printers_page();
1645 } else if (have_read_access && strcmp(page,"status")==0) {
1646 status_page();
1647 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1648 viewconfig_page();
1649 } else if (strcmp(page,"passwd")==0) {
1650 passwd_page();
1651 } else if (have_read_access && strcmp(page,"wizard")==0) {
1652 wizard_page();
1653 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1654 wizard_params_page();
1655 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1656 rewritecfg_file();
1657 } else {
1658 welcome_page();
1661 print_footer();
1663 TALLOC_FREE(frame);
1664 return 0;
1667 /** @} **/