s3:registry/regfio read SD from the correct location
[Samba.git] / source3 / web / swat.c
blob640cd5d0862fb5285afb866565f54269ac9dd116
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;
159 char *nonce = cgi_nonce();
161 token_str[0] = '\0';
162 ZERO_STRUCT(md5_ctx);
163 MD5Init(&md5_ctx);
165 MD5Update(&md5_ctx, (uint8_t *)formname, strlen(formname));
166 MD5Update(&md5_ctx, (uint8_t *)&xsrf_time, sizeof(time_t));
167 if (username != NULL) {
168 MD5Update(&md5_ctx, (uint8_t *)username, strlen(username));
170 if (pass != NULL) {
171 MD5Update(&md5_ctx, (uint8_t *)pass, strlen(pass));
173 MD5Update(&md5_ctx, (uint8_t *)nonce, strlen(nonce));
175 MD5Final(token, &md5_ctx);
177 for(i = 0; i < sizeof(token); i++) {
178 char tmp[3];
180 snprintf(tmp, sizeof(tmp), "%02x", token[i]);
181 /* FIXME ! Truncate check. JRA. */
182 (void)strlcat(token_str, tmp, sizeof(tmp));
186 void print_xsrf_token(const char *username, const char *pass,
187 const char *formname)
189 char token[33];
190 time_t xsrf_time = time(NULL);
192 get_xsrf_token(username, pass, formname, xsrf_time, token);
193 printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
194 XSRF_TOKEN, token);
195 printf("<input type=\"hidden\" name=\"%s\" value=\"%lld\">\n",
196 XSRF_TIME, (long long int)xsrf_time);
199 bool verify_xsrf_token(const char *formname)
201 char expected[33];
202 const char *username = cgi_user_name();
203 const char *pass = cgi_user_pass();
204 const char *token = cgi_variable_nonull(XSRF_TOKEN);
205 const char *time_str = cgi_variable_nonull(XSRF_TIME);
206 char *p = NULL;
207 long long xsrf_time_ll = 0;
208 time_t xsrf_time = 0;
209 time_t now = time(NULL);
211 errno = 0;
212 xsrf_time_ll = strtoll(time_str, &p, 10);
213 if (errno != 0) {
214 return false;
216 if (p == NULL) {
217 return false;
219 if (PTR_DIFF(p, time_str) > strlen(time_str)) {
220 return false;
222 if (xsrf_time_ll > _TYPE_MAXIMUM(time_t)) {
223 return false;
225 if (xsrf_time_ll < _TYPE_MINIMUM(time_t)) {
226 return false;
228 xsrf_time = xsrf_time_ll;
230 if (abs(now - xsrf_time) > XSRF_TIMEOUT) {
231 return false;
234 get_xsrf_token(username, pass, formname, xsrf_time, expected);
235 return (strncmp(expected, token, sizeof(expected)) == 0);
239 /****************************************************************************
240 include a lump of html in a page
241 ****************************************************************************/
242 static int include_html(const char *fname)
244 int fd;
245 char buf[1024];
246 int ret;
248 fd = web_open(fname, O_RDONLY, 0);
250 if (fd == -1) {
251 printf(_("ERROR: Can't open %s"), fname);
252 printf("\n");
253 return 0;
256 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
257 if (write(1, buf, ret) == -1) {
258 break;
262 close(fd);
263 return 1;
266 /****************************************************************************
267 start the page with standard stuff
268 ****************************************************************************/
269 static void print_header(void)
271 if (!cgi_waspost()) {
272 printf("Expires: 0\r\n");
274 printf("Content-type: text/html\r\n");
275 printf("X-Frame-Options: DENY\r\n\r\n");
277 if (!include_html("include/header.html")) {
278 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
279 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
283 /* *******************************************************************
284 show parameter label with translated name in the following form
285 because showing original and translated label in one line looks
286 too long, and showing translated label only is unusable for
287 heavy users.
288 -------------------------------
289 HELP security [combo box][button]
290 SECURITY
291 -------------------------------
292 (capital words are translated by gettext.)
293 if no translation is available, then same form as original is
294 used.
295 "i18n_translated_parm" class is used to change the color of the
296 translated parameter with CSS.
297 **************************************************************** */
298 static const char *get_parm_translated(TALLOC_CTX *ctx,
299 const char* pAnchor, const char* pHelp, const char* pLabel)
301 const char *pTranslated = _(pLabel);
302 char *output;
303 if(strcmp(pLabel, pTranslated) != 0) {
304 output = talloc_asprintf(ctx,
305 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s <br><span class=\"i18n_translated_parm\">%s</span>",
306 pAnchor, pHelp, pLabel, pTranslated);
307 return output;
309 output = talloc_asprintf(ctx,
310 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
311 pAnchor, pHelp, pLabel);
312 return output;
314 /****************************************************************************
315 finish off the page
316 ****************************************************************************/
317 static void print_footer(void)
319 if (!include_html("include/footer.html")) {
320 printf("\n</BODY>\n</HTML>\n");
324 /****************************************************************************
325 display one editable parameter in a form
326 ****************************************************************************/
327 static void show_parameter(int snum, struct parm_struct *parm)
329 int i;
330 void *ptr;
331 char *utf8_s1, *utf8_s2;
332 size_t converted_size;
333 TALLOC_CTX *ctx = talloc_stackframe();
335 if (parm->p_class == P_LOCAL && snum >= 0) {
336 ptr = lp_local_ptr_by_snum(snum, parm);
337 } else {
338 ptr = lp_parm_ptr(NULL, parm);
341 printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
342 stripspaceupper(parm->label), _("Help"), parm->label));
343 switch (parm->type) {
344 case P_CHAR:
345 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
346 make_parm_name(parm->label), *(char *)ptr);
347 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
348 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
349 break;
351 case P_LIST:
352 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
353 make_parm_name(parm->label));
354 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
355 char **list = *(char ***)ptr;
356 for (;*list;list++) {
357 /* enclose in HTML encoded quotes if the string contains a space */
358 if ( strchr_m(*list, ' ') ) {
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("&quot;%s&quot;%s", utf8_s1, utf8_s2);
362 } else {
363 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
364 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
365 printf("%s%s", utf8_s1, utf8_s2);
367 TALLOC_FREE(utf8_s1);
368 TALLOC_FREE(utf8_s2);
371 printf("\">");
372 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
373 _("Set Default"), make_parm_name(parm->label));
374 if (parm->def.lvalue) {
375 char **list = (char **)(parm->def.lvalue);
376 for (; *list; list++) {
377 /* enclose in HTML encoded quotes if the string contains a space */
378 if ( strchr_m(*list, ' ') )
379 printf("&quot;%s&quot;%s", *list, ((*(list+1))?", ":""));
380 else
381 printf("%s%s", *list, ((*(list+1))?", ":""));
384 printf("\'\">");
385 break;
387 case P_STRING:
388 case P_USTRING:
389 push_utf8_talloc(talloc_tos(), &utf8_s1, *(char **)ptr, &converted_size);
390 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
391 make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
392 TALLOC_FREE(utf8_s1);
393 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
394 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
395 break;
397 case P_BOOL:
398 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
399 printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
400 printf("<option %s>No", (*(bool *)ptr)?"":"selected");
401 printf("</select>");
402 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
403 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
404 break;
406 case P_BOOLREV:
407 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
408 printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
409 printf("<option %s>No", (*(bool *)ptr)?"selected":"");
410 printf("</select>");
411 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
412 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
413 break;
415 case P_INTEGER:
416 case P_BYTES:
417 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
418 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
419 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
420 break;
422 case P_OCTAL: {
423 char *o;
424 o = octal_string(*(int *)ptr);
425 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
426 make_parm_name(parm->label), o);
427 TALLOC_FREE(o);
428 o = octal_string((int)(parm->def.ivalue));
429 printf("<input type=button value=\"%s\" "
430 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
431 _("Set Default"), make_parm_name(parm->label), o);
432 TALLOC_FREE(o);
433 break;
436 case P_ENUM:
437 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
438 for (i=0;parm->enum_list[i].name;i++) {
439 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
440 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
443 printf("</select>");
444 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
445 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
446 break;
447 case P_SEP:
448 break;
450 printf("</td></tr>\n");
451 TALLOC_FREE(ctx);
454 /****************************************************************************
455 display a set of parameters for a service
456 ****************************************************************************/
457 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
459 int i = 0;
460 struct parm_struct *parm;
461 const char *heading = NULL;
462 const char *last_heading = NULL;
464 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
465 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
466 continue;
467 if (parm->p_class == P_SEPARATOR) {
468 heading = parm->label;
469 continue;
471 if (parm->flags & FLAG_HIDE) continue;
472 if (snum >= 0) {
473 if (printers & !(parm->flags & FLAG_PRINT)) continue;
474 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
477 if (!( parm_filter & FLAG_ADVANCED )) {
478 if (!(parm->flags & FLAG_BASIC)) {
479 void *ptr;
480 if (parm->p_class == P_LOCAL && snum >= 0) {
481 ptr = lp_local_ptr_by_snum(snum, parm);
482 } else {
483 ptr = lp_parm_ptr(NULL, parm);
486 switch (parm->type) {
487 case P_CHAR:
488 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
489 break;
491 case P_LIST:
492 if (!str_list_equal(*(const char ***)ptr,
493 (const char **)(parm->def.lvalue))) continue;
494 break;
496 case P_STRING:
497 case P_USTRING:
498 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
499 break;
501 case P_BOOL:
502 case P_BOOLREV:
503 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
504 break;
506 case P_INTEGER:
507 case P_BYTES:
508 case P_OCTAL:
509 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
510 break;
513 case P_ENUM:
514 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
515 break;
516 case P_SEP:
517 continue;
520 if (printers && !(parm->flags & FLAG_PRINT)) continue;
523 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
525 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
527 if (heading && heading != last_heading) {
528 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
529 last_heading = heading;
531 show_parameter(snum, parm);
535 /****************************************************************************
536 load the smb.conf file into loadparm.
537 ****************************************************************************/
538 static bool load_config(bool save_def)
540 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
543 /****************************************************************************
544 write a config file
545 ****************************************************************************/
546 static void write_config(FILE *f, bool show_defaults)
548 TALLOC_CTX *ctx = talloc_stackframe();
550 fprintf(f, "# Samba config file created using SWAT\n");
551 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
552 fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
554 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
556 TALLOC_FREE(ctx);
559 /****************************************************************************
560 save and reload the smb.conf config file
561 ****************************************************************************/
562 static int save_reload(int snum)
564 FILE *f;
565 struct stat st;
567 f = fopen(get_dyn_CONFIGFILE(),"w");
568 if (!f) {
569 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
570 printf("\n");
571 return 0;
574 /* just in case they have used the buggy xinetd to create the file */
575 if (fstat(fileno(f), &st) == 0 &&
576 (st.st_mode & S_IWOTH)) {
577 #if defined HAVE_FCHMOD
578 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
579 #else
580 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
581 #endif
584 write_config(f, False);
585 if (snum >= 0)
586 lp_dump_one(f, False, snum);
587 fclose(f);
589 lp_kill_all_services();
591 if (!load_config(False)) {
592 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
593 printf("\n");
594 return 0;
596 iNumNonAutoPrintServices = lp_numservices();
597 if (pcap_cache_loaded(NULL)) {
598 struct tevent_context *ev_ctx;
599 struct messaging_context *msg_ctx;
601 ev_ctx = s3_tevent_context_init(NULL);
602 if (ev_ctx == NULL) {
603 printf("s3_tevent_context_init() failed\n");
604 return 0;
606 msg_ctx = messaging_init(ev_ctx, ev_ctx);
607 if (msg_ctx == NULL) {
608 printf("messaging_init() failed\n");
609 return 0;
612 load_printers(ev_ctx, msg_ctx);
614 talloc_free(ev_ctx);
617 return 1;
620 /****************************************************************************
621 commit one parameter
622 ****************************************************************************/
623 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
625 int i;
626 char *s;
628 if (snum < 0 && parm->p_class == P_LOCAL) {
629 /* this handles the case where we are changing a local
630 variable globally. We need to change the parameter in
631 all shares where it is currently set to the default */
632 for (i=0;i<lp_numservices();i++) {
633 s = lp_servicename(talloc_tos(), i);
634 if (s && (*s) && lp_is_default(i, parm)) {
635 lp_do_parameter(i, parm->label, v);
640 lp_do_parameter(snum, parm->label, v);
643 /****************************************************************************
644 commit a set of parameters for a service
645 ****************************************************************************/
646 static void commit_parameters(int snum)
648 int i = 0;
649 struct parm_struct *parm;
650 char *label;
651 const char *v;
653 while ((parm = lp_next_parameter(snum, &i, 1))) {
654 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
655 if ((v = cgi_variable(label)) != NULL) {
656 if (parm->flags & FLAG_HIDE)
657 continue;
658 commit_parameter(snum, parm, v);
660 SAFE_FREE(label);
665 /****************************************************************************
666 spit out the html for a link with an image
667 ****************************************************************************/
668 static void image_link(const char *name, const char *hlink, const char *src)
670 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
671 cgi_baseurl(), hlink, src, name);
674 /****************************************************************************
675 display the main navigation controls at the top of each page along
676 with a title
677 ****************************************************************************/
678 static void show_main_buttons(void)
680 char *p;
682 if ((p = cgi_user_name()) && strcmp(p, "root")) {
683 printf(_("Logged in as <b>%s</b>"), p);
684 printf("<p>\n");
687 image_link(_("Home"), "", "images/home.gif");
688 if (have_write_access) {
689 image_link(_("Globals"), "globals", "images/globals.gif");
690 image_link(_("Shares"), "shares", "images/shares.gif");
691 image_link(_("Printers"), "printers", "images/printers.gif");
692 image_link(_("Wizard"), "wizard", "images/wizard.gif");
694 /* root always gets all buttons, otherwise look for -P */
695 if ( have_write_access || (!passwd_only && have_read_access) ) {
696 image_link(_("Status"), "status", "images/status.gif");
697 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
699 image_link(_("Password Management"), "passwd", "images/passwd.gif");
701 printf("<HR>\n");
704 /****************************************************************************
705 * Handle Display/Edit Mode CGI
706 ****************************************************************************/
707 static void ViewModeBoxes(int mode)
709 printf("<p>%s:&nbsp;\n", _("Current View Is"));
710 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
711 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
712 printf("<br>%s:&nbsp;\n", _("Change View To"));
713 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
714 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
715 printf("</p><br>\n");
718 /****************************************************************************
719 display a welcome page
720 ****************************************************************************/
721 static void welcome_page(void)
723 if (file_exist("help/welcome.html")) {
724 include_html("help/welcome.html");
725 } else {
726 include_html("help/welcome-no-samba-doc.html");
730 /****************************************************************************
731 display the current smb.conf
732 ****************************************************************************/
733 static void viewconfig_page(void)
735 int full_view=0;
736 const char form_name[] = "viewconfig";
738 if (!verify_xsrf_token(form_name)) {
739 goto output_page;
742 if (cgi_variable("full_view")) {
743 full_view = 1;
746 output_page:
747 printf("<H2>%s</H2>\n", _("Current Config"));
748 printf("<form method=post>\n");
749 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
751 if (full_view) {
752 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
753 } else {
754 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
757 printf("<p><pre>");
758 write_config(stdout, full_view);
759 printf("</pre>");
760 printf("</form>\n");
763 /****************************************************************************
764 second screen of the wizard ... Fetch Configuration Parameters
765 ****************************************************************************/
766 static void wizard_params_page(void)
768 unsigned int parm_filter = FLAG_WIZARD;
769 const char form_name[] = "wizard_params";
771 /* Here we first set and commit all the parameters that were selected
772 in the previous screen. */
774 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
776 if (!verify_xsrf_token(form_name)) {
777 goto output_page;
780 if (cgi_variable("Commit")) {
781 commit_parameters(GLOBAL_SECTION_SNUM);
782 save_reload(-1);
785 output_page:
786 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
787 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
789 if (have_write_access) {
790 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
793 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
794 printf("<p>\n");
796 printf("<table>\n");
797 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
798 printf("</table>\n");
799 printf("</form>\n");
802 /****************************************************************************
803 Utility to just rewrite the smb.conf file - effectively just cleans it up
804 ****************************************************************************/
805 static void rewritecfg_file(void)
807 commit_parameters(GLOBAL_SECTION_SNUM);
808 save_reload(-1);
809 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
812 /****************************************************************************
813 wizard to create/modify the smb.conf file
814 ****************************************************************************/
815 static void wizard_page(void)
817 /* Set some variables to collect data from smb.conf */
818 int role = 0;
819 int winstype = 0;
820 int have_home = -1;
821 int HomeExpo = 0;
822 int SerType = 0;
823 const char form_name[] = "wizard";
825 if (!verify_xsrf_token(form_name)) {
826 goto output_page;
829 if (cgi_variable("Rewrite")) {
830 (void) rewritecfg_file();
831 return;
834 if (cgi_variable("GetWizardParams")){
835 (void) wizard_params_page();
836 return;
839 if (cgi_variable("Commit")){
840 SerType = atoi(cgi_variable_nonull("ServerType"));
841 winstype = atoi(cgi_variable_nonull("WINSType"));
842 have_home = lp_servicenumber(HOMES_NAME);
843 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
845 /* Plain text passwords are too badly broken - use encrypted passwords only */
846 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
848 switch ( SerType ){
849 case 0:
850 /* Stand-alone Server */
851 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
852 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
853 break;
854 case 1:
855 /* Domain Member */
856 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
857 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
858 break;
859 case 2:
860 /* Domain Controller */
861 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
862 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
863 break;
865 switch ( winstype ) {
866 case 0:
867 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
868 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
869 break;
870 case 1:
871 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
872 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
873 break;
874 case 2:
875 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
876 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
877 break;
880 /* Have to create Homes share? */
881 if ((HomeExpo == 1) && (have_home == -1)) {
882 const char *unix_share = HOMES_NAME;
884 load_config(False);
885 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
886 have_home = lp_servicenumber(HOMES_NAME);
887 lp_do_parameter( have_home, "read only", "No");
888 lp_do_parameter( have_home, "valid users", "%S");
889 lp_do_parameter( have_home, "browseable", "No");
890 commit_parameters(have_home);
891 save_reload(have_home);
894 /* Need to Delete Homes share? */
895 if ((HomeExpo == 0) && (have_home != -1)) {
896 lp_remove_service(have_home);
897 have_home = -1;
900 commit_parameters(GLOBAL_SECTION_SNUM);
901 save_reload(-1);
903 else
905 /* Now determine smb.conf WINS settings */
906 if (lp_we_are_a_wins_server())
907 winstype = 1;
908 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
909 winstype = 2;
911 /* Do we have a homes share? */
912 have_home = lp_servicenumber(HOMES_NAME);
914 if ((winstype == 2) && lp_we_are_a_wins_server())
915 winstype = 3;
917 role = lp_server_role();
919 output_page:
920 /* Here we go ... */
921 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
922 printf("<form method=post action=wizard>\n");
923 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
925 if (have_write_access) {
926 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
927 printf("%s", _("The same will happen if you press the commit button."));
928 printf("<br><br>\n");
929 printf("<center>");
930 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
931 printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
932 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
933 printf("</center>\n");
936 printf("<hr>");
937 printf("<center><table border=0>");
938 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
939 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
940 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
941 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
942 printf("</tr>\n");
943 if (role == ROLE_DOMAIN_BDC) {
944 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
946 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
947 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
948 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
949 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
950 printf("</tr>\n");
951 printf("<tr><td></td><td></td><td></td><td>%s&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
953 /* Print out the list of wins servers */
954 if(lp_wins_server_list()) {
955 int i;
956 const char **wins_servers = lp_wins_server_list();
957 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
960 printf("\"></td></tr>\n");
961 if (winstype == 3) {
962 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"));
963 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
965 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
966 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
967 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
968 printf("<td></td></tr>\n");
970 /* Enable this when we are ready ....
971 * printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
972 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
973 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
974 * printf("<td></td></tr>\n");
977 printf("</table></center>");
978 printf("<hr>");
980 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
981 printf("</form>\n");
985 /****************************************************************************
986 display a globals editing page
987 ****************************************************************************/
988 static void globals_page(void)
990 unsigned int parm_filter = FLAG_BASIC;
991 int mode = 0;
992 const char form_name[] = "globals";
994 printf("<H2>%s</H2>\n", _("Global Parameters"));
996 if (!verify_xsrf_token(form_name)) {
997 goto output_page;
1000 if (cgi_variable("Commit")) {
1001 commit_parameters(GLOBAL_SECTION_SNUM);
1002 save_reload(-1);
1005 if ( cgi_variable("ViewMode") )
1006 mode = atoi(cgi_variable_nonull("ViewMode"));
1007 if ( cgi_variable("BasicMode"))
1008 mode = 0;
1009 if ( cgi_variable("AdvMode"))
1010 mode = 1;
1012 output_page:
1013 printf("<form name=\"swatform\" method=post action=globals>\n");
1014 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1016 ViewModeBoxes( mode );
1017 switch ( mode ) {
1018 case 0:
1019 parm_filter = FLAG_BASIC;
1020 break;
1021 case 1:
1022 parm_filter = FLAG_ADVANCED;
1023 break;
1025 printf("<br>\n");
1026 if (have_write_access) {
1027 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
1028 _("Commit Changes"));
1031 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
1032 _("Reset Values"));
1034 printf("<p>\n");
1035 printf("<table>\n");
1036 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
1037 printf("</table>\n");
1038 printf("</form>\n");
1041 /****************************************************************************
1042 display a shares editing page. share is in unix codepage,
1043 ****************************************************************************/
1044 static void shares_page(void)
1046 const char *share = cgi_variable("share");
1047 char *s;
1048 char *utf8_s;
1049 int snum = -1;
1050 int i;
1051 int mode = 0;
1052 unsigned int parm_filter = FLAG_BASIC;
1053 size_t converted_size;
1054 const char form_name[] = "shares";
1056 printf("<H2>%s</H2>\n", _("Share Parameters"));
1058 if (!verify_xsrf_token(form_name)) {
1059 goto output_page;
1062 if (share)
1063 snum = lp_servicenumber(share);
1066 if (cgi_variable("Commit") && snum >= 0) {
1067 commit_parameters(snum);
1068 save_reload(-1);
1069 snum = lp_servicenumber(share);
1072 if (cgi_variable("Delete") && snum >= 0) {
1073 lp_remove_service(snum);
1074 save_reload(-1);
1075 share = NULL;
1076 snum = -1;
1079 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1080 snum = lp_servicenumber(share);
1081 if (snum < 0) {
1082 load_config(False);
1083 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1084 snum = lp_servicenumber(share);
1085 save_reload(snum);
1086 snum = lp_servicenumber(share);
1090 if ( cgi_variable("ViewMode") )
1091 mode = atoi(cgi_variable_nonull("ViewMode"));
1092 if ( cgi_variable("BasicMode"))
1093 mode = 0;
1094 if ( cgi_variable("AdvMode"))
1095 mode = 1;
1097 output_page:
1098 printf("<FORM name=\"swatform\" method=post>\n");
1099 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1101 printf("<table>\n");
1103 ViewModeBoxes( mode );
1104 switch ( mode ) {
1105 case 0:
1106 parm_filter = FLAG_BASIC;
1107 break;
1108 case 1:
1109 parm_filter = FLAG_ADVANCED;
1110 break;
1112 printf("<br><tr>\n");
1113 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1114 printf("<td><select name=share>\n");
1115 if (snum < 0)
1116 printf("<option value=\" \"> \n");
1117 for (i=0;i<lp_numservices();i++) {
1118 s = lp_servicename(talloc_tos(), i);
1119 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
1120 push_utf8_talloc(talloc_tos(), &utf8_s, s, &converted_size);
1121 printf("<option %s value=\"%s\">%s\n",
1122 (share && strcmp(share,s)==0)?"SELECTED":"",
1123 utf8_s, utf8_s);
1124 TALLOC_FREE(utf8_s);
1127 printf("</select></td>\n");
1128 if (have_write_access) {
1129 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1131 printf("</tr>\n");
1132 printf("</table>");
1133 printf("<table>");
1134 if (have_write_access) {
1135 printf("<tr>\n");
1136 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1137 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1139 printf("</table>");
1142 if (snum >= 0) {
1143 if (have_write_access) {
1144 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1147 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1148 printf("<p>\n");
1151 if (snum >= 0) {
1152 printf("<table>\n");
1153 show_parameters(snum, 1, parm_filter, 0);
1154 printf("</table>\n");
1157 printf("</FORM>\n");
1160 /*************************************************************
1161 change a password either locally or remotely
1162 *************************************************************/
1163 static bool change_password(const char *remote_machine, const char *user_name,
1164 const char *old_passwd, const char *new_passwd,
1165 int local_flags)
1167 NTSTATUS ret;
1168 char *err_str = NULL;
1169 char *msg_str = NULL;
1171 if (demo_mode) {
1172 printf("%s\n<p>", _("password change in demo mode rejected"));
1173 return False;
1176 if (remote_machine != NULL) {
1177 ret = remote_password_change(remote_machine, user_name,
1178 old_passwd, new_passwd, &err_str);
1179 if (err_str != NULL)
1180 printf("%s\n<p>", err_str);
1181 SAFE_FREE(err_str);
1182 return NT_STATUS_IS_OK(ret);
1185 if(!initialize_password_db(True, NULL)) {
1186 printf("%s\n<p>", _("Can't setup password database vectors."));
1187 return False;
1190 ret = local_password_change(user_name, local_flags, new_passwd,
1191 &err_str, &msg_str);
1193 if(msg_str)
1194 printf("%s\n<p>", msg_str);
1195 if(err_str)
1196 printf("%s\n<p>", err_str);
1198 SAFE_FREE(msg_str);
1199 SAFE_FREE(err_str);
1200 return NT_STATUS_IS_OK(ret);
1203 /****************************************************************************
1204 do the stuff required to add or change a password
1205 ****************************************************************************/
1206 static void chg_passwd(void)
1208 const char *host;
1209 bool rslt;
1210 int local_flags = 0;
1212 /* Make sure users name has been specified */
1213 if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1214 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1215 return;
1219 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1220 * so if that's what we're doing, skip the rest of the checks
1222 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1225 * If current user is not root, make sure old password has been specified
1226 * If REMOTE change, even root must provide old password
1228 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1229 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1230 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1231 return;
1234 /* If changing a users password on a remote hosts we have to know what host */
1235 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1236 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1237 return;
1240 /* Make sure new passwords have been specified */
1241 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1242 (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1243 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1244 return;
1247 /* Make sure new passwords was typed correctly twice */
1248 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1249 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1250 return;
1254 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1255 host = cgi_variable(RHOST);
1256 } else if (am_root()) {
1257 host = NULL;
1258 } else {
1259 host = "127.0.0.1";
1263 * Set up the local flags.
1266 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1267 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1268 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1269 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1270 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1271 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1273 rslt = change_password(host,
1274 cgi_variable_nonull(SWAT_USER),
1275 cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1276 local_flags);
1278 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1279 printf("<p>");
1280 if (rslt == True) {
1281 printf("%s\n", _(" The passwd has been changed."));
1282 } else {
1283 printf("%s\n", _(" The passwd has NOT been changed."));
1287 return;
1290 /****************************************************************************
1291 display a password editing page
1292 ****************************************************************************/
1293 static void passwd_page(void)
1295 const char *new_name = cgi_user_name();
1296 const char passwd_form[] = "passwd";
1297 const char rpasswd_form[] = "rpasswd";
1299 if (!new_name) new_name = "";
1301 printf("<H2>%s</H2>\n", _("Server Password Management"));
1303 printf("<FORM name=\"swatform\" method=post>\n");
1304 print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form);
1306 printf("<table>\n");
1309 * Create all the dialog boxes for data collection
1311 printf("<tr><td> %s : </td>\n", _("User Name"));
1312 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1313 if (!am_root()) {
1314 printf("<tr><td> %s : </td>\n", _("Old Password"));
1315 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1317 printf("<tr><td> %s : </td>\n", _("New Password"));
1318 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1319 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1320 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1321 printf("</table>\n");
1324 * Create all the control buttons for requesting action
1326 printf("<input type=submit name=%s value=\"%s\">\n",
1327 CHG_S_PASSWD_FLAG, _("Change Password"));
1328 if (demo_mode || am_root()) {
1329 printf("<input type=submit name=%s value=\"%s\">\n",
1330 ADD_USER_FLAG, _("Add New User"));
1331 printf("<input type=submit name=%s value=\"%s\">\n",
1332 DELETE_USER_FLAG, _("Delete User"));
1333 printf("<input type=submit name=%s value=\"%s\">\n",
1334 DISABLE_USER_FLAG, _("Disable User"));
1335 printf("<input type=submit name=%s value=\"%s\">\n",
1336 ENABLE_USER_FLAG, _("Enable User"));
1338 printf("<p></FORM>\n");
1341 * Do some work if change, add, disable or enable was
1342 * requested. It could be this is the first time through this
1343 * code, so there isn't anything to do. */
1344 if (verify_xsrf_token(passwd_form) &&
1345 ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1346 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG)))) {
1347 chg_passwd();
1350 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1352 printf("<FORM name=\"swatform\" method=post>\n");
1353 print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form);
1355 printf("<table>\n");
1358 * Create all the dialog boxes for data collection
1360 printf("<tr><td> %s : </td>\n", _("User Name"));
1361 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1362 printf("<tr><td> %s : </td>\n", _("Old Password"));
1363 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1364 printf("<tr><td> %s : </td>\n", _("New Password"));
1365 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1366 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1367 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1368 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1369 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1371 printf("</table>");
1374 * Create all the control buttons for requesting action
1376 printf("<input type=submit name=%s value=\"%s\">",
1377 CHG_R_PASSWD_FLAG, _("Change Password"));
1379 printf("<p></FORM>\n");
1382 * Do some work if a request has been made to change the
1383 * password somewhere other than the server. It could be this
1384 * is the first time through this code, so there isn't
1385 * anything to do. */
1386 if (verify_xsrf_token(passwd_form) && cgi_variable(CHG_R_PASSWD_FLAG)) {
1387 chg_passwd();
1392 /****************************************************************************
1393 display a printers editing page
1394 ****************************************************************************/
1395 static void printers_page(void)
1397 const char *share = cgi_variable("share");
1398 char *s;
1399 int snum=-1;
1400 int i;
1401 int mode = 0;
1402 unsigned int parm_filter = FLAG_BASIC;
1403 const char form_name[] = "printers";
1405 if (!verify_xsrf_token(form_name)) {
1406 goto output_page;
1409 if (share)
1410 snum = lp_servicenumber(share);
1412 if (cgi_variable("Commit") && snum >= 0) {
1413 commit_parameters(snum);
1414 if (snum >= iNumNonAutoPrintServices)
1415 save_reload(snum);
1416 else
1417 save_reload(-1);
1418 snum = lp_servicenumber(share);
1421 if (cgi_variable("Delete") && snum >= 0) {
1422 lp_remove_service(snum);
1423 save_reload(-1);
1424 share = NULL;
1425 snum = -1;
1428 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1429 snum = lp_servicenumber(share);
1430 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1431 load_config(False);
1432 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1433 snum = lp_servicenumber(share);
1434 lp_do_parameter(snum, "print ok", "Yes");
1435 save_reload(snum);
1436 snum = lp_servicenumber(share);
1440 if ( cgi_variable("ViewMode") )
1441 mode = atoi(cgi_variable_nonull("ViewMode"));
1442 if ( cgi_variable("BasicMode"))
1443 mode = 0;
1444 if ( cgi_variable("AdvMode"))
1445 mode = 1;
1447 output_page:
1448 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1450 printf("<H3>%s</H3>\n", _("Important Note:"));
1451 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1452 printf("%s",_("are autoloaded printers from "));
1453 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1454 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1457 printf("<FORM name=\"swatform\" method=post>\n");
1458 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1460 ViewModeBoxes( mode );
1461 switch ( mode ) {
1462 case 0:
1463 parm_filter = FLAG_BASIC;
1464 break;
1465 case 1:
1466 parm_filter = FLAG_ADVANCED;
1467 break;
1469 printf("<table>\n");
1470 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1471 printf("<td><select name=\"share\">\n");
1472 if (snum < 0 || !lp_print_ok(snum))
1473 printf("<option value=\" \"> \n");
1474 for (i=0;i<lp_numservices();i++) {
1475 s = lp_servicename(talloc_tos(), i);
1476 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1477 if (i >= iNumNonAutoPrintServices)
1478 printf("<option %s value=\"%s\">[*]%s\n",
1479 (share && strcmp(share,s)==0)?"SELECTED":"",
1480 s, s);
1481 else
1482 printf("<option %s value=\"%s\">%s\n",
1483 (share && strcmp(share,s)==0)?"SELECTED":"",
1484 s, s);
1487 printf("</select></td>");
1488 if (have_write_access) {
1489 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1491 printf("</tr>");
1492 printf("</table>\n");
1494 if (have_write_access) {
1495 printf("<table>\n");
1496 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1497 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1498 printf("</table>");
1502 if (snum >= 0) {
1503 if (have_write_access) {
1504 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1506 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1507 printf("<p>\n");
1510 if (snum >= 0) {
1511 printf("<table>\n");
1512 show_parameters(snum, 1, parm_filter, 1);
1513 printf("</table>\n");
1515 printf("</FORM>\n");
1519 when the _() translation macro is used there is no obvious place to free
1520 the resulting string and there is no easy way to give a static pointer.
1521 All we can do is rotate between some static buffers and hope a single d_printf()
1522 doesn't have more calls to _() than the number of buffers
1525 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1527 const char *msgstr;
1528 const char *ret;
1530 msgstr = lang_msg(msgid);
1531 if (!msgstr) {
1532 return msgid;
1535 ret = talloc_strdup(ctx, msgstr);
1537 lang_msg_free(msgstr);
1538 if (!ret) {
1539 return msgid;
1542 return ret;
1546 * main function for SWAT.
1548 int main(int argc, char *argv[])
1550 const char *page;
1551 poptContext pc;
1552 struct poptOption long_options[] = {
1553 POPT_AUTOHELP
1554 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1555 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1556 POPT_COMMON_SAMBA
1557 POPT_TABLEEND
1559 TALLOC_CTX *frame = talloc_stackframe();
1561 fault_setup();
1562 umask(S_IWGRP | S_IWOTH);
1564 #if defined(HAVE_SET_AUTH_PARAMETERS)
1565 set_auth_parameters(argc, argv);
1566 #endif /* HAVE_SET_AUTH_PARAMETERS */
1568 /* just in case it goes wild ... */
1569 alarm(300);
1571 setlinebuf(stdout);
1573 /* we don't want any SIGPIPE messages */
1574 BlockSignals(True,SIGPIPE);
1576 debug_set_logfile("/dev/null");
1578 /* we don't want stderr screwing us up */
1579 close(2);
1580 open("/dev/null", O_WRONLY);
1581 setup_logging("swat", DEBUG_FILE);
1583 load_case_tables();
1585 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1587 /* Parse command line options */
1589 while(poptGetNextOpt(pc) != -1) { }
1591 poptFreeContext(pc);
1593 /* This should set a more apporiate log file */
1594 load_config(True);
1595 reopen_logs();
1596 load_interfaces();
1597 iNumNonAutoPrintServices = lp_numservices();
1598 if (pcap_cache_loaded(NULL)) {
1599 struct tevent_context *ev_ctx;
1600 struct messaging_context *msg_ctx;
1602 ev_ctx = s3_tevent_context_init(NULL);
1603 if (ev_ctx == NULL) {
1604 printf("s3_tevent_context_init() failed\n");
1605 return 0;
1607 msg_ctx = messaging_init(ev_ctx, ev_ctx);
1608 if (msg_ctx == NULL) {
1609 printf("messaging_init() failed\n");
1610 return 0;
1613 load_printers(ev_ctx, msg_ctx);
1615 talloc_free(ev_ctx);
1618 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1620 print_header();
1622 cgi_load_variables();
1624 if (!file_exist(get_dyn_CONFIGFILE())) {
1625 have_read_access = True;
1626 have_write_access = True;
1627 } else {
1628 /* check if the authenticated user has write access - if not then
1629 don't show write options */
1630 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1632 /* if the user doesn't have read access to smb.conf then
1633 don't let them view it */
1634 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1637 show_main_buttons();
1639 page = cgi_pathinfo();
1641 /* Root gets full functionality */
1642 if (have_read_access && strcmp(page, "globals")==0) {
1643 globals_page();
1644 } else if (have_read_access && strcmp(page,"shares")==0) {
1645 shares_page();
1646 } else if (have_read_access && strcmp(page,"printers")==0) {
1647 printers_page();
1648 } else if (have_read_access && strcmp(page,"status")==0) {
1649 status_page();
1650 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1651 viewconfig_page();
1652 } else if (strcmp(page,"passwd")==0) {
1653 passwd_page();
1654 } else if (have_read_access && strcmp(page,"wizard")==0) {
1655 wizard_page();
1656 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1657 wizard_params_page();
1658 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1659 rewritecfg_file();
1660 } else {
1661 welcome_page();
1664 print_footer();
1666 TALLOC_FREE(frame);
1667 return 0;
1670 /** @} **/