s3:web/swat: use strtoll() instead of atoi/atol/atoll
[Samba.git] / source / web / swat.c
blobbc2497f9bbffdacbe4100bd911f8b3708ad0774a
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 "web/swat_proto.h"
33 static int demo_mode = False;
34 static int passwd_only = False;
35 static bool have_write_access = False;
36 static bool have_read_access = False;
37 static int iNumNonAutoPrintServices = 0;
40 * Password Management Globals
42 #define SWAT_USER "username"
43 #define OLD_PSWD "old_passwd"
44 #define NEW_PSWD "new_passwd"
45 #define NEW2_PSWD "new2_passwd"
46 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
47 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
48 #define ADD_USER_FLAG "add_user_flag"
49 #define DELETE_USER_FLAG "delete_user_flag"
50 #define DISABLE_USER_FLAG "disable_user_flag"
51 #define ENABLE_USER_FLAG "enable_user_flag"
52 #define RHOST "remote_host"
53 #define XSRF_TOKEN "xsrf"
54 #define XSRF_TIME "xsrf_time"
55 #define XSRF_TIMEOUT 300
57 #define _(x) lang_msg_rotate(talloc_tos(),x)
59 /****************************************************************************
60 ****************************************************************************/
61 static int enum_index(int value, const struct enum_list *enumlist)
63 int i;
64 for (i=0;enumlist[i].name;i++)
65 if (value == enumlist[i].value) break;
66 return(i);
69 static char *fix_backslash(const char *str)
71 static char newstring[1024];
72 char *p = newstring;
74 while (*str) {
75 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
76 else *p++ = *str;
77 ++str;
79 *p = '\0';
80 return newstring;
83 static const char *fix_quotes(TALLOC_CTX *ctx, const char *str)
85 char *newstring = NULL;
86 char *p = NULL;
87 size_t newstring_len;
88 int quote_len = strlen("&quot;");
90 /* Count the number of quotes. */
91 newstring_len = 1;
92 p = (char *) str;
93 while (*p) {
94 if ( *p == '\"') {
95 newstring_len += quote_len;
96 } else {
97 newstring_len++;
99 ++p;
101 newstring = TALLOC_ARRAY(ctx, char, newstring_len);
102 if (!newstring) {
103 return "";
105 for (p = newstring; *str; str++) {
106 if ( *str == '\"') {
107 strncpy( p, "&quot;", quote_len);
108 p += quote_len;
109 } else {
110 *p++ = *str;
113 *p = '\0';
114 return newstring;
117 static char *stripspaceupper(const char *str)
119 static char newstring[1024];
120 char *p = newstring;
122 while (*str) {
123 if (*str != ' ') *p++ = toupper_ascii(*str);
124 ++str;
126 *p = '\0';
127 return newstring;
130 static char *make_parm_name(const char *label)
132 static char parmname[1024];
133 char *p = parmname;
135 while (*label) {
136 if (*label == ' ') *p++ = '_';
137 else *p++ = *label;
138 ++label;
140 *p = '\0';
141 return parmname;
144 void get_xsrf_token(const char *username, const char *pass,
145 const char *formname, time_t xsrf_time, char token_str[33])
147 struct MD5Context md5_ctx;
148 uint8_t token[16];
149 int i;
151 token_str[0] = '\0';
152 ZERO_STRUCT(md5_ctx);
153 MD5Init(&md5_ctx);
155 MD5Update(&md5_ctx, (uint8_t *)formname, strlen(formname));
156 MD5Update(&md5_ctx, (uint8_t *)&xsrf_time, sizeof(time_t));
157 if (username != NULL) {
158 MD5Update(&md5_ctx, (uint8_t *)username, strlen(username));
160 if (pass != NULL) {
161 MD5Update(&md5_ctx, (uint8_t *)pass, strlen(pass));
164 MD5Final(token, &md5_ctx);
166 for(i = 0; i < sizeof(token); i++) {
167 char tmp[3];
169 snprintf(tmp, sizeof(tmp), "%02x", token[i]);
170 strncat(token_str, tmp, sizeof(tmp));
174 void print_xsrf_token(const char *username, const char *pass,
175 const char *formname)
177 char token[33];
178 time_t xsrf_time = time(NULL);
180 get_xsrf_token(username, pass, formname, xsrf_time, token);
181 printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
182 XSRF_TOKEN, token);
183 printf("<input type=\"hidden\" name=\"%s\" value=\"%lld\">\n",
184 XSRF_TIME, (long long int)xsrf_time);
187 bool verify_xsrf_token(const char *formname)
189 char expected[33];
190 const char *username = cgi_user_name();
191 const char *pass = cgi_user_pass();
192 const char *token = cgi_variable_nonull(XSRF_TOKEN);
193 const char *time_str = cgi_variable_nonull(XSRF_TIME);
194 char *p = NULL;
195 long long xsrf_time_ll = 0;
196 time_t xsrf_time = 0;
197 time_t now = time(NULL);
199 errno = 0;
200 xsrf_time_ll = strtoll(time_str, &p, 10);
201 if (errno != 0) {
202 return false;
204 if (p == NULL) {
205 return false;
207 if (PTR_DIFF(p, time_str) > strlen(time_str)) {
208 return false;
210 if (xsrf_time_ll > _TYPE_MAXIMUM(time_t)) {
211 return false;
213 if (xsrf_time_ll < _TYPE_MINIMUM(time_t)) {
214 return false;
216 xsrf_time = xsrf_time_ll;
218 if (abs(now - xsrf_time) > XSRF_TIMEOUT) {
219 return false;
222 get_xsrf_token(username, pass, formname, xsrf_time, expected);
223 return (strncmp(expected, token, sizeof(expected)) == 0);
227 /****************************************************************************
228 include a lump of html in a page
229 ****************************************************************************/
230 static int include_html(const char *fname)
232 int fd;
233 char buf[1024];
234 int ret;
236 fd = web_open(fname, O_RDONLY, 0);
238 if (fd == -1) {
239 printf(_("ERROR: Can't open %s"), fname);
240 printf("\n");
241 return 0;
244 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
245 if (write(1, buf, ret) == -1) {
246 break;
250 close(fd);
251 return 1;
254 /****************************************************************************
255 start the page with standard stuff
256 ****************************************************************************/
257 static void print_header(void)
259 if (!cgi_waspost()) {
260 printf("Expires: 0\r\n");
262 printf("Content-type: text/html\r\n\r\n");
264 if (!include_html("include/header.html")) {
265 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
266 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
270 /* *******************************************************************
271 show parameter label with translated name in the following form
272 because showing original and translated label in one line looks
273 too long, and showing translated label only is unusable for
274 heavy users.
275 -------------------------------
276 HELP security [combo box][button]
277 SECURITY
278 -------------------------------
279 (capital words are translated by gettext.)
280 if no translation is available, then same form as original is
281 used.
282 "i18n_translated_parm" class is used to change the color of the
283 translated parameter with CSS.
284 **************************************************************** */
285 static const char *get_parm_translated(TALLOC_CTX *ctx,
286 const char* pAnchor, const char* pHelp, const char* pLabel)
288 const char *pTranslated = _(pLabel);
289 char *output;
290 if(strcmp(pLabel, pTranslated) != 0) {
291 output = talloc_asprintf(ctx,
292 "<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>",
293 pAnchor, pHelp, pLabel, pTranslated);
294 return output;
296 output = talloc_asprintf(ctx,
297 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
298 pAnchor, pHelp, pLabel);
299 return output;
301 /****************************************************************************
302 finish off the page
303 ****************************************************************************/
304 static void print_footer(void)
306 if (!include_html("include/footer.html")) {
307 printf("\n</BODY>\n</HTML>\n");
311 /****************************************************************************
312 display one editable parameter in a form
313 ****************************************************************************/
314 static void show_parameter(int snum, struct parm_struct *parm)
316 int i;
317 void *ptr = parm->ptr;
318 char *utf8_s1, *utf8_s2;
319 size_t converted_size;
320 TALLOC_CTX *ctx = talloc_stackframe();
322 if (parm->p_class == P_LOCAL && snum >= 0) {
323 ptr = lp_local_ptr(snum, ptr);
326 printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
327 stripspaceupper(parm->label), _("Help"), parm->label));
328 switch (parm->type) {
329 case P_CHAR:
330 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
331 make_parm_name(parm->label), *(char *)ptr);
332 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
333 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
334 break;
336 case P_LIST:
337 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
338 make_parm_name(parm->label));
339 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
340 char **list = *(char ***)ptr;
341 for (;*list;list++) {
342 /* enclose in HTML encoded quotes if the string contains a space */
343 if ( strchr_m(*list, ' ') ) {
344 push_utf8_allocate(&utf8_s1, *list, &converted_size);
345 push_utf8_allocate(&utf8_s2, ((*(list+1))?", ":""), &converted_size);
346 printf("&quot;%s&quot;%s", utf8_s1, utf8_s2);
347 } else {
348 push_utf8_allocate(&utf8_s1, *list, &converted_size);
349 push_utf8_allocate(&utf8_s2, ((*(list+1))?", ":""), &converted_size);
350 printf("%s%s", utf8_s1, utf8_s2);
352 SAFE_FREE(utf8_s1);
353 SAFE_FREE(utf8_s2);
356 printf("\">");
357 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
358 _("Set Default"), make_parm_name(parm->label));
359 if (parm->def.lvalue) {
360 char **list = (char **)(parm->def.lvalue);
361 for (; *list; list++) {
362 /* enclose in HTML encoded quotes if the string contains a space */
363 if ( strchr_m(*list, ' ') )
364 printf("&quot;%s&quot;%s", *list, ((*(list+1))?", ":""));
365 else
366 printf("%s%s", *list, ((*(list+1))?", ":""));
369 printf("\'\">");
370 break;
372 case P_STRING:
373 case P_USTRING:
374 push_utf8_allocate(&utf8_s1, *(char **)ptr, &converted_size);
375 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
376 make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
377 SAFE_FREE(utf8_s1);
378 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
379 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
380 break;
382 case P_BOOL:
383 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
384 printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
385 printf("<option %s>No", (*(bool *)ptr)?"":"selected");
386 printf("</select>");
387 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
388 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
389 break;
391 case P_BOOLREV:
392 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
393 printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
394 printf("<option %s>No", (*(bool *)ptr)?"selected":"");
395 printf("</select>");
396 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
397 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
398 break;
400 case P_INTEGER:
401 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
402 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
403 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
404 break;
406 case P_OCTAL: {
407 char *o;
408 o = octal_string(*(int *)ptr);
409 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
410 make_parm_name(parm->label), o);
411 TALLOC_FREE(o);
412 o = octal_string((int)(parm->def.ivalue));
413 printf("<input type=button value=\"%s\" "
414 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
415 _("Set Default"), make_parm_name(parm->label), o);
416 TALLOC_FREE(o);
417 break;
420 case P_ENUM:
421 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
422 for (i=0;parm->enum_list[i].name;i++) {
423 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
424 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
427 printf("</select>");
428 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
429 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
430 break;
431 case P_SEP:
432 break;
434 printf("</td></tr>\n");
435 TALLOC_FREE(ctx);
438 /****************************************************************************
439 display a set of parameters for a service
440 ****************************************************************************/
441 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
443 int i = 0;
444 struct parm_struct *parm;
445 const char *heading = NULL;
446 const char *last_heading = NULL;
448 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
449 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
450 continue;
451 if (parm->p_class == P_SEPARATOR) {
452 heading = parm->label;
453 continue;
455 if (parm->flags & FLAG_HIDE) continue;
456 if (snum >= 0) {
457 if (printers & !(parm->flags & FLAG_PRINT)) continue;
458 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
461 if (!( parm_filter & FLAG_ADVANCED )) {
462 if (!(parm->flags & FLAG_BASIC)) {
463 void *ptr = parm->ptr;
465 if (parm->p_class == P_LOCAL && snum >= 0) {
466 ptr = lp_local_ptr(snum, ptr);
469 switch (parm->type) {
470 case P_CHAR:
471 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
472 break;
474 case P_LIST:
475 if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
476 break;
478 case P_STRING:
479 case P_USTRING:
480 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
481 break;
483 case P_BOOL:
484 case P_BOOLREV:
485 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
486 break;
488 case P_INTEGER:
489 case P_OCTAL:
490 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
491 break;
494 case P_ENUM:
495 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
496 break;
497 case P_SEP:
498 continue;
501 if (printers && !(parm->flags & FLAG_PRINT)) continue;
504 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
506 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
508 if (heading && heading != last_heading) {
509 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
510 last_heading = heading;
512 show_parameter(snum, parm);
516 /****************************************************************************
517 load the smb.conf file into loadparm.
518 ****************************************************************************/
519 static bool load_config(bool save_def)
521 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
524 /****************************************************************************
525 write a config file
526 ****************************************************************************/
527 static void write_config(FILE *f, bool show_defaults)
529 TALLOC_CTX *ctx = talloc_stackframe();
531 fprintf(f, "# Samba config file created using SWAT\n");
532 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
533 fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
535 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
537 TALLOC_FREE(ctx);
540 /****************************************************************************
541 save and reload the smb.conf config file
542 ****************************************************************************/
543 static int save_reload(int snum)
545 FILE *f;
546 struct stat st;
548 f = sys_fopen(get_dyn_CONFIGFILE(),"w");
549 if (!f) {
550 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
551 printf("\n");
552 return 0;
555 /* just in case they have used the buggy xinetd to create the file */
556 if (fstat(fileno(f), &st) == 0 &&
557 (st.st_mode & S_IWOTH)) {
558 #if defined HAVE_FCHMOD
559 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
560 #else
561 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
562 #endif
565 write_config(f, False);
566 if (snum >= 0)
567 lp_dump_one(f, False, snum);
568 fclose(f);
570 lp_kill_all_services();
572 if (!load_config(False)) {
573 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
574 printf("\n");
575 return 0;
577 iNumNonAutoPrintServices = lp_numservices();
578 load_printers();
580 return 1;
583 /****************************************************************************
584 commit one parameter
585 ****************************************************************************/
586 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
588 int i;
589 char *s;
591 if (snum < 0 && parm->p_class == P_LOCAL) {
592 /* this handles the case where we are changing a local
593 variable globally. We need to change the parameter in
594 all shares where it is currently set to the default */
595 for (i=0;i<lp_numservices();i++) {
596 s = lp_servicename(i);
597 if (s && (*s) && lp_is_default(i, parm)) {
598 lp_do_parameter(i, parm->label, v);
603 lp_do_parameter(snum, parm->label, v);
606 /****************************************************************************
607 commit a set of parameters for a service
608 ****************************************************************************/
609 static void commit_parameters(int snum)
611 int i = 0;
612 struct parm_struct *parm;
613 char *label;
614 const char *v;
616 while ((parm = lp_next_parameter(snum, &i, 1))) {
617 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
618 if ((v = cgi_variable(label)) != NULL) {
619 if (parm->flags & FLAG_HIDE)
620 continue;
621 commit_parameter(snum, parm, v);
623 SAFE_FREE(label);
628 /****************************************************************************
629 spit out the html for a link with an image
630 ****************************************************************************/
631 static void image_link(const char *name, const char *hlink, const char *src)
633 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
634 cgi_baseurl(), hlink, src, name);
637 /****************************************************************************
638 display the main navigation controls at the top of each page along
639 with a title
640 ****************************************************************************/
641 static void show_main_buttons(void)
643 char *p;
645 if ((p = cgi_user_name()) && strcmp(p, "root")) {
646 printf(_("Logged in as <b>%s</b>"), p);
647 printf("<p>\n");
650 image_link(_("Home"), "", "images/home.gif");
651 if (have_write_access) {
652 image_link(_("Globals"), "globals", "images/globals.gif");
653 image_link(_("Shares"), "shares", "images/shares.gif");
654 image_link(_("Printers"), "printers", "images/printers.gif");
655 image_link(_("Wizard"), "wizard", "images/wizard.gif");
657 /* root always gets all buttons, otherwise look for -P */
658 if ( have_write_access || (!passwd_only && have_read_access) ) {
659 image_link(_("Status"), "status", "images/status.gif");
660 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
662 image_link(_("Password Management"), "passwd", "images/passwd.gif");
664 printf("<HR>\n");
667 /****************************************************************************
668 * Handle Display/Edit Mode CGI
669 ****************************************************************************/
670 static void ViewModeBoxes(int mode)
672 printf("<p>%s:&nbsp;\n", _("Current View Is"));
673 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
674 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
675 printf("<br>%s:&nbsp;\n", _("Change View To"));
676 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
677 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
678 printf("</p><br>\n");
681 /****************************************************************************
682 display a welcome page
683 ****************************************************************************/
684 static void welcome_page(void)
686 if (file_exist("help/welcome.html", NULL)) {
687 include_html("help/welcome.html");
688 } else {
689 include_html("help/welcome-no-samba-doc.html");
693 /****************************************************************************
694 display the current smb.conf
695 ****************************************************************************/
696 static void viewconfig_page(void)
698 int full_view=0;
699 const char form_name[] = "viewconfig";
701 if (!verify_xsrf_token(form_name)) {
702 goto output_page;
705 if (cgi_variable("full_view")) {
706 full_view = 1;
709 output_page:
710 printf("<H2>%s</H2>\n", _("Current Config"));
711 printf("<form method=post>\n");
712 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
714 if (full_view) {
715 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
716 } else {
717 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
720 printf("<p><pre>");
721 write_config(stdout, full_view);
722 printf("</pre>");
723 printf("</form>\n");
726 /****************************************************************************
727 second screen of the wizard ... Fetch Configuration Parameters
728 ****************************************************************************/
729 static void wizard_params_page(void)
731 unsigned int parm_filter = FLAG_WIZARD;
732 const char form_name[] = "wizard_params";
734 /* Here we first set and commit all the parameters that were selected
735 in the previous screen. */
737 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
739 if (!verify_xsrf_token(form_name)) {
740 goto output_page;
743 if (cgi_variable("Commit")) {
744 commit_parameters(GLOBAL_SECTION_SNUM);
745 save_reload(0);
748 output_page:
749 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
750 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
752 if (have_write_access) {
753 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
756 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
757 printf("<p>\n");
759 printf("<table>\n");
760 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
761 printf("</table>\n");
762 printf("</form>\n");
765 /****************************************************************************
766 Utility to just rewrite the smb.conf file - effectively just cleans it up
767 ****************************************************************************/
768 static void rewritecfg_file(void)
770 commit_parameters(GLOBAL_SECTION_SNUM);
771 save_reload(0);
772 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
775 /****************************************************************************
776 wizard to create/modify the smb.conf file
777 ****************************************************************************/
778 static void wizard_page(void)
780 /* Set some variables to collect data from smb.conf */
781 int role = 0;
782 int winstype = 0;
783 int have_home = -1;
784 int HomeExpo = 0;
785 int SerType = 0;
786 const char form_name[] = "wizard";
788 if (!verify_xsrf_token(form_name)) {
789 goto output_page;
792 if (cgi_variable("Rewrite")) {
793 (void) rewritecfg_file();
794 return;
797 if (cgi_variable("GetWizardParams")){
798 (void) wizard_params_page();
799 return;
802 if (cgi_variable("Commit")){
803 SerType = atoi(cgi_variable_nonull("ServerType"));
804 winstype = atoi(cgi_variable_nonull("WINSType"));
805 have_home = lp_servicenumber(HOMES_NAME);
806 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
808 /* Plain text passwords are too badly broken - use encrypted passwords only */
809 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
811 switch ( SerType ){
812 case 0:
813 /* Stand-alone Server */
814 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
815 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
816 break;
817 case 1:
818 /* Domain Member */
819 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
820 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
821 break;
822 case 2:
823 /* Domain Controller */
824 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
825 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
826 break;
828 switch ( winstype ) {
829 case 0:
830 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
831 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
832 break;
833 case 1:
834 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
835 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
836 break;
837 case 2:
838 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
839 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
840 break;
843 /* Have to create Homes share? */
844 if ((HomeExpo == 1) && (have_home == -1)) {
845 const char *unix_share = HOMES_NAME;
847 load_config(False);
848 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
849 have_home = lp_servicenumber(HOMES_NAME);
850 lp_do_parameter( have_home, "read only", "No");
851 lp_do_parameter( have_home, "valid users", "%S");
852 lp_do_parameter( have_home, "browseable", "No");
853 commit_parameters(have_home);
854 save_reload(have_home);
857 /* Need to Delete Homes share? */
858 if ((HomeExpo == 0) && (have_home != -1)) {
859 lp_remove_service(have_home);
860 have_home = -1;
863 commit_parameters(GLOBAL_SECTION_SNUM);
864 save_reload(0);
866 else
868 /* Now determine smb.conf WINS settings */
869 if (lp_wins_support())
870 winstype = 1;
871 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
872 winstype = 2;
874 /* Do we have a homes share? */
875 have_home = lp_servicenumber(HOMES_NAME);
877 if ((winstype == 2) && lp_wins_support())
878 winstype = 3;
880 role = lp_server_role();
882 output_page:
883 /* Here we go ... */
884 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
885 printf("<form method=post action=wizard>\n");
886 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
888 if (have_write_access) {
889 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
890 printf("%s", _("The same will happen if you press the commit button."));
891 printf("<br><br>\n");
892 printf("<center>");
893 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
894 printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
895 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
896 printf("</center>\n");
899 printf("<hr>");
900 printf("<center><table border=0>");
901 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
902 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
903 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
904 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
905 printf("</tr>\n");
906 if (role == ROLE_DOMAIN_BDC) {
907 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
909 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
910 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
911 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
912 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
913 printf("</tr>\n");
914 printf("<tr><td></td><td></td><td></td><td>%s&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
916 /* Print out the list of wins servers */
917 if(lp_wins_server_list()) {
918 int i;
919 const char **wins_servers = lp_wins_server_list();
920 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
923 printf("\"></td></tr>\n");
924 if (winstype == 3) {
925 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"));
926 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
928 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
929 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
930 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
931 printf("<td></td></tr>\n");
933 /* Enable this when we are ready ....
934 * printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
935 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
936 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
937 * printf("<td></td></tr>\n");
940 printf("</table></center>");
941 printf("<hr>");
943 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
944 printf("</form>\n");
948 /****************************************************************************
949 display a globals editing page
950 ****************************************************************************/
951 static void globals_page(void)
953 unsigned int parm_filter = FLAG_BASIC;
954 int mode = 0;
955 const char form_name[] = "globals";
957 printf("<H2>%s</H2>\n", _("Global Parameters"));
959 if (!verify_xsrf_token(form_name)) {
960 goto output_page;
963 if (cgi_variable("Commit")) {
964 commit_parameters(GLOBAL_SECTION_SNUM);
965 save_reload(0);
968 if ( cgi_variable("ViewMode") )
969 mode = atoi(cgi_variable_nonull("ViewMode"));
970 if ( cgi_variable("BasicMode"))
971 mode = 0;
972 if ( cgi_variable("AdvMode"))
973 mode = 1;
975 output_page:
976 printf("<form name=\"swatform\" method=post action=globals>\n");
977 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
979 ViewModeBoxes( mode );
980 switch ( mode ) {
981 case 0:
982 parm_filter = FLAG_BASIC;
983 break;
984 case 1:
985 parm_filter = FLAG_ADVANCED;
986 break;
988 printf("<br>\n");
989 if (have_write_access) {
990 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
991 _("Commit Changes"));
994 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
995 _("Reset Values"));
997 printf("<p>\n");
998 printf("<table>\n");
999 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
1000 printf("</table>\n");
1001 printf("</form>\n");
1004 /****************************************************************************
1005 display a shares editing page. share is in unix codepage,
1006 ****************************************************************************/
1007 static void shares_page(void)
1009 const char *share = cgi_variable("share");
1010 char *s;
1011 char *utf8_s;
1012 int snum = -1;
1013 int i;
1014 int mode = 0;
1015 unsigned int parm_filter = FLAG_BASIC;
1016 size_t converted_size;
1017 const char form_name[] = "shares";
1019 printf("<H2>%s</H2>\n", _("Share Parameters"));
1021 if (!verify_xsrf_token(form_name)) {
1022 goto output_page;
1025 if (share)
1026 snum = lp_servicenumber(share);
1029 if (cgi_variable("Commit") && snum >= 0) {
1030 commit_parameters(snum);
1031 save_reload(0);
1032 snum = lp_servicenumber(share);
1035 if (cgi_variable("Delete") && snum >= 0) {
1036 lp_remove_service(snum);
1037 save_reload(0);
1038 share = NULL;
1039 snum = -1;
1042 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1043 snum = lp_servicenumber(share);
1044 if (snum < 0) {
1045 load_config(False);
1046 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1047 snum = lp_servicenumber(share);
1048 save_reload(snum);
1049 snum = lp_servicenumber(share);
1053 if ( cgi_variable("ViewMode") )
1054 mode = atoi(cgi_variable_nonull("ViewMode"));
1055 if ( cgi_variable("BasicMode"))
1056 mode = 0;
1057 if ( cgi_variable("AdvMode"))
1058 mode = 1;
1060 output_page:
1061 printf("<FORM name=\"swatform\" method=post>\n");
1062 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1064 printf("<table>\n");
1066 ViewModeBoxes( mode );
1067 switch ( mode ) {
1068 case 0:
1069 parm_filter = FLAG_BASIC;
1070 break;
1071 case 1:
1072 parm_filter = FLAG_ADVANCED;
1073 break;
1075 printf("<br><tr>\n");
1076 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1077 printf("<td><select name=share>\n");
1078 if (snum < 0)
1079 printf("<option value=\" \"> \n");
1080 for (i=0;i<lp_numservices();i++) {
1081 s = lp_servicename(i);
1082 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
1083 push_utf8_allocate(&utf8_s, s, &converted_size);
1084 printf("<option %s value=\"%s\">%s\n",
1085 (share && strcmp(share,s)==0)?"SELECTED":"",
1086 utf8_s, utf8_s);
1087 SAFE_FREE(utf8_s);
1090 printf("</select></td>\n");
1091 if (have_write_access) {
1092 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1094 printf("</tr>\n");
1095 printf("</table>");
1096 printf("<table>");
1097 if (have_write_access) {
1098 printf("<tr>\n");
1099 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1100 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1102 printf("</table>");
1105 if (snum >= 0) {
1106 if (have_write_access) {
1107 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1110 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1111 printf("<p>\n");
1114 if (snum >= 0) {
1115 printf("<table>\n");
1116 show_parameters(snum, 1, parm_filter, 0);
1117 printf("</table>\n");
1120 printf("</FORM>\n");
1123 /*************************************************************
1124 change a password either locally or remotely
1125 *************************************************************/
1126 static bool change_password(const char *remote_machine, const char *user_name,
1127 const char *old_passwd, const char *new_passwd,
1128 int local_flags)
1130 NTSTATUS ret;
1131 char *err_str = NULL;
1132 char *msg_str = NULL;
1134 if (demo_mode) {
1135 printf("%s\n<p>", _("password change in demo mode rejected"));
1136 return False;
1139 if (remote_machine != NULL) {
1140 ret = remote_password_change(remote_machine, user_name,
1141 old_passwd, new_passwd, &err_str);
1142 if (err_str != NULL)
1143 printf("%s\n<p>", err_str);
1144 SAFE_FREE(err_str);
1145 return NT_STATUS_IS_OK(ret);
1148 if(!initialize_password_db(True, NULL)) {
1149 printf("%s\n<p>", _("Can't setup password database vectors."));
1150 return False;
1153 ret = local_password_change(user_name, local_flags, new_passwd,
1154 &err_str, &msg_str);
1156 if(msg_str)
1157 printf("%s\n<p>", msg_str);
1158 if(err_str)
1159 printf("%s\n<p>", err_str);
1161 SAFE_FREE(msg_str);
1162 SAFE_FREE(err_str);
1163 return NT_STATUS_IS_OK(ret);
1166 /****************************************************************************
1167 do the stuff required to add or change a password
1168 ****************************************************************************/
1169 static void chg_passwd(void)
1171 const char *host;
1172 bool rslt;
1173 int local_flags = 0;
1175 /* Make sure users name has been specified */
1176 if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1177 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1178 return;
1182 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1183 * so if that's what we're doing, skip the rest of the checks
1185 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1188 * If current user is not root, make sure old password has been specified
1189 * If REMOTE change, even root must provide old password
1191 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1192 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1193 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1194 return;
1197 /* If changing a users password on a remote hosts we have to know what host */
1198 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1199 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1200 return;
1203 /* Make sure new passwords have been specified */
1204 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1205 (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1206 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1207 return;
1210 /* Make sure new passwords was typed correctly twice */
1211 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1212 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1213 return;
1217 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1218 host = cgi_variable(RHOST);
1219 } else if (am_root()) {
1220 host = NULL;
1221 } else {
1222 host = "127.0.0.1";
1226 * Set up the local flags.
1229 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1230 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1231 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1232 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1233 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1234 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1237 rslt = change_password(host,
1238 cgi_variable_nonull(SWAT_USER),
1239 cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1240 local_flags);
1242 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1243 printf("<p>");
1244 if (rslt == True) {
1245 printf("%s\n", _(" The passwd has been changed."));
1246 } else {
1247 printf("%s\n", _(" The passwd has NOT been changed."));
1251 return;
1254 /****************************************************************************
1255 display a password editing page
1256 ****************************************************************************/
1257 static void passwd_page(void)
1259 const char *new_name = cgi_user_name();
1260 const char passwd_form[] = "passwd";
1261 const char rpasswd_form[] = "rpasswd";
1263 if (!new_name) new_name = "";
1265 printf("<H2>%s</H2>\n", _("Server Password Management"));
1267 printf("<FORM name=\"swatform\" method=post>\n");
1268 print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form);
1270 printf("<table>\n");
1273 * Create all the dialog boxes for data collection
1275 printf("<tr><td> %s : </td>\n", _("User Name"));
1276 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1277 if (!am_root()) {
1278 printf("<tr><td> %s : </td>\n", _("Old Password"));
1279 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1281 printf("<tr><td> %s : </td>\n", _("New Password"));
1282 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1283 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1284 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1285 printf("</table>\n");
1288 * Create all the control buttons for requesting action
1290 printf("<input type=submit name=%s value=\"%s\">\n",
1291 CHG_S_PASSWD_FLAG, _("Change Password"));
1292 if (demo_mode || am_root()) {
1293 printf("<input type=submit name=%s value=\"%s\">\n",
1294 ADD_USER_FLAG, _("Add New User"));
1295 printf("<input type=submit name=%s value=\"%s\">\n",
1296 DELETE_USER_FLAG, _("Delete User"));
1297 printf("<input type=submit name=%s value=\"%s\">\n",
1298 DISABLE_USER_FLAG, _("Disable User"));
1299 printf("<input type=submit name=%s value=\"%s\">\n",
1300 ENABLE_USER_FLAG, _("Enable User"));
1302 printf("<p></FORM>\n");
1305 * Do some work if change, add, disable or enable was
1306 * requested. It could be this is the first time through this
1307 * code, so there isn't anything to do. */
1308 if (verify_xsrf_token(passwd_form) &&
1309 ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1310 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG)))) {
1311 chg_passwd();
1314 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1316 printf("<FORM name=\"swatform\" method=post>\n");
1317 print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form);
1319 printf("<table>\n");
1322 * Create all the dialog boxes for data collection
1324 printf("<tr><td> %s : </td>\n", _("User Name"));
1325 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1326 printf("<tr><td> %s : </td>\n", _("Old Password"));
1327 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1328 printf("<tr><td> %s : </td>\n", _("New Password"));
1329 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1330 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1331 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1332 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1333 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1335 printf("</table>");
1338 * Create all the control buttons for requesting action
1340 printf("<input type=submit name=%s value=\"%s\">",
1341 CHG_R_PASSWD_FLAG, _("Change Password"));
1343 printf("<p></FORM>\n");
1346 * Do some work if a request has been made to change the
1347 * password somewhere other than the server. It could be this
1348 * is the first time through this code, so there isn't
1349 * anything to do. */
1350 if (verify_xsrf_token(passwd_form) && cgi_variable(CHG_R_PASSWD_FLAG)) {
1351 chg_passwd();
1356 /****************************************************************************
1357 display a printers editing page
1358 ****************************************************************************/
1359 static void printers_page(void)
1361 const char *share = cgi_variable("share");
1362 char *s;
1363 int snum=-1;
1364 int i;
1365 int mode = 0;
1366 unsigned int parm_filter = FLAG_BASIC;
1367 const char form_name[] = "printers";
1369 if (!verify_xsrf_token(form_name)) {
1370 goto output_page;
1373 if (share)
1374 snum = lp_servicenumber(share);
1376 if (cgi_variable("Commit") && snum >= 0) {
1377 commit_parameters(snum);
1378 if (snum >= iNumNonAutoPrintServices)
1379 save_reload(snum);
1380 else
1381 save_reload(0);
1382 snum = lp_servicenumber(share);
1385 if (cgi_variable("Delete") && snum >= 0) {
1386 lp_remove_service(snum);
1387 save_reload(0);
1388 share = NULL;
1389 snum = -1;
1392 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1393 snum = lp_servicenumber(share);
1394 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1395 load_config(False);
1396 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1397 snum = lp_servicenumber(share);
1398 lp_do_parameter(snum, "print ok", "Yes");
1399 save_reload(snum);
1400 snum = lp_servicenumber(share);
1404 if ( cgi_variable("ViewMode") )
1405 mode = atoi(cgi_variable_nonull("ViewMode"));
1406 if ( cgi_variable("BasicMode"))
1407 mode = 0;
1408 if ( cgi_variable("AdvMode"))
1409 mode = 1;
1411 output_page:
1412 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1414 printf("<H3>%s</H3>\n", _("Important Note:"));
1415 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1416 printf("%s",_("are autoloaded printers from "));
1417 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1418 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1421 printf("<FORM name=\"swatform\" method=post>\n");
1422 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1424 ViewModeBoxes( mode );
1425 switch ( mode ) {
1426 case 0:
1427 parm_filter = FLAG_BASIC;
1428 break;
1429 case 1:
1430 parm_filter = FLAG_ADVANCED;
1431 break;
1433 printf("<table>\n");
1434 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1435 printf("<td><select name=\"share\">\n");
1436 if (snum < 0 || !lp_print_ok(snum))
1437 printf("<option value=\" \"> \n");
1438 for (i=0;i<lp_numservices();i++) {
1439 s = lp_servicename(i);
1440 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1441 if (i >= iNumNonAutoPrintServices)
1442 printf("<option %s value=\"%s\">[*]%s\n",
1443 (share && strcmp(share,s)==0)?"SELECTED":"",
1444 s, s);
1445 else
1446 printf("<option %s value=\"%s\">%s\n",
1447 (share && strcmp(share,s)==0)?"SELECTED":"",
1448 s, s);
1451 printf("</select></td>");
1452 if (have_write_access) {
1453 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1455 printf("</tr>");
1456 printf("</table>\n");
1458 if (have_write_access) {
1459 printf("<table>\n");
1460 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1461 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1462 printf("</table>");
1466 if (snum >= 0) {
1467 if (have_write_access) {
1468 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1470 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1471 printf("<p>\n");
1474 if (snum >= 0) {
1475 printf("<table>\n");
1476 show_parameters(snum, 1, parm_filter, 1);
1477 printf("</table>\n");
1479 printf("</FORM>\n");
1483 when the _() translation macro is used there is no obvious place to free
1484 the resulting string and there is no easy way to give a static pointer.
1485 All we can do is rotate between some static buffers and hope a single d_printf()
1486 doesn't have more calls to _() than the number of buffers
1489 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1491 const char *msgstr;
1492 const char *ret;
1494 msgstr = lang_msg(msgid);
1495 if (!msgstr) {
1496 return msgid;
1499 ret = talloc_strdup(ctx, msgstr);
1501 lang_msg_free(msgstr);
1502 if (!ret) {
1503 return msgid;
1506 return ret;
1510 * main function for SWAT.
1512 int main(int argc, char *argv[])
1514 const char *page;
1515 poptContext pc;
1516 struct poptOption long_options[] = {
1517 POPT_AUTOHELP
1518 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1519 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1520 POPT_COMMON_SAMBA
1521 POPT_TABLEEND
1523 TALLOC_CTX *frame = talloc_stackframe();
1525 fault_setup(NULL);
1526 umask(S_IWGRP | S_IWOTH);
1528 #if defined(HAVE_SET_AUTH_PARAMETERS)
1529 set_auth_parameters(argc, argv);
1530 #endif /* HAVE_SET_AUTH_PARAMETERS */
1532 /* just in case it goes wild ... */
1533 alarm(300);
1535 setlinebuf(stdout);
1537 /* we don't want any SIGPIPE messages */
1538 BlockSignals(True,SIGPIPE);
1540 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1541 if (!dbf) dbf = x_stderr;
1543 /* we don't want stderr screwing us up */
1544 close(2);
1545 open("/dev/null", O_WRONLY);
1547 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1549 /* Parse command line options */
1551 while(poptGetNextOpt(pc) != -1) { }
1553 poptFreeContext(pc);
1555 load_case_tables();
1557 setup_logging(argv[0],False);
1558 load_config(True);
1559 load_interfaces();
1560 iNumNonAutoPrintServices = lp_numservices();
1561 load_printers();
1563 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1565 print_header();
1567 cgi_load_variables();
1569 if (!file_exist(get_dyn_CONFIGFILE(), NULL)) {
1570 have_read_access = True;
1571 have_write_access = True;
1572 } else {
1573 /* check if the authenticated user has write access - if not then
1574 don't show write options */
1575 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1577 /* if the user doesn't have read access to smb.conf then
1578 don't let them view it */
1579 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1582 show_main_buttons();
1584 page = cgi_pathinfo();
1586 /* Root gets full functionality */
1587 if (have_read_access && strcmp(page, "globals")==0) {
1588 globals_page();
1589 } else if (have_read_access && strcmp(page,"shares")==0) {
1590 shares_page();
1591 } else if (have_read_access && strcmp(page,"printers")==0) {
1592 printers_page();
1593 } else if (have_read_access && strcmp(page,"status")==0) {
1594 status_page();
1595 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1596 viewconfig_page();
1597 } else if (strcmp(page,"passwd")==0) {
1598 passwd_page();
1599 } else if (have_read_access && strcmp(page,"wizard")==0) {
1600 wizard_page();
1601 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1602 wizard_params_page();
1603 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1604 rewritecfg_file();
1605 } else {
1606 welcome_page();
1609 print_footer();
1611 TALLOC_FREE(frame);
1612 return 0;
1615 /** @} **/