s3 swat: Add XSRF protection to printer page
[Samba.git] / source3 / web / swat.c
blob995bc15ca2cc592fe35210fe79449f7680d3c2df
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"
40 static int demo_mode = False;
41 static int passwd_only = False;
42 static bool have_write_access = False;
43 static bool have_read_access = False;
44 static int iNumNonAutoPrintServices = 0;
47 * Password Management Globals
49 #define SWAT_USER "username"
50 #define OLD_PSWD "old_passwd"
51 #define NEW_PSWD "new_passwd"
52 #define NEW2_PSWD "new2_passwd"
53 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
54 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
55 #define ADD_USER_FLAG "add_user_flag"
56 #define DELETE_USER_FLAG "delete_user_flag"
57 #define DISABLE_USER_FLAG "disable_user_flag"
58 #define ENABLE_USER_FLAG "enable_user_flag"
59 #define RHOST "remote_host"
60 #define XSRF_TOKEN "xsrf"
62 #define _(x) lang_msg_rotate(talloc_tos(),x)
64 /****************************************************************************
65 ****************************************************************************/
66 static int enum_index(int value, const struct enum_list *enumlist)
68 int i;
69 for (i=0;enumlist[i].name;i++)
70 if (value == enumlist[i].value) break;
71 return(i);
74 static char *fix_backslash(const char *str)
76 static char newstring[1024];
77 char *p = newstring;
79 while (*str) {
80 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
81 else *p++ = *str;
82 ++str;
84 *p = '\0';
85 return newstring;
88 static const char *fix_quotes(TALLOC_CTX *ctx, const char *str)
90 char *newstring = NULL;
91 char *p = NULL;
92 size_t newstring_len;
93 int quote_len = strlen("&quot;");
95 /* Count the number of quotes. */
96 newstring_len = 1;
97 p = (char *) str;
98 while (*p) {
99 if ( *p == '\"') {
100 newstring_len += quote_len;
101 } else {
102 newstring_len++;
104 ++p;
106 newstring = TALLOC_ARRAY(ctx, char, newstring_len);
107 if (!newstring) {
108 return "";
110 for (p = newstring; *str; str++) {
111 if ( *str == '\"') {
112 strncpy( p, "&quot;", quote_len);
113 p += quote_len;
114 } else {
115 *p++ = *str;
118 *p = '\0';
119 return newstring;
122 static char *stripspaceupper(const char *str)
124 static char newstring[1024];
125 char *p = newstring;
127 while (*str) {
128 if (*str != ' ') *p++ = toupper_m(*str);
129 ++str;
131 *p = '\0';
132 return newstring;
135 static char *make_parm_name(const char *label)
137 static char parmname[1024];
138 char *p = parmname;
140 while (*label) {
141 if (*label == ' ') *p++ = '_';
142 else *p++ = *label;
143 ++label;
145 *p = '\0';
146 return parmname;
149 void get_xsrf_token(const char *username, const char *pass,
150 const char *formname, char token_str[33])
152 struct MD5Context md5_ctx;
153 uint8_t token[16];
154 int i;
156 token_str[0] = '\0';
157 ZERO_STRUCT(md5_ctx);
158 MD5Init(&md5_ctx);
160 MD5Update(&md5_ctx, (uint8_t *)formname, strlen(formname));
161 if (username != NULL) {
162 MD5Update(&md5_ctx, (uint8_t *)username, strlen(username));
164 if (pass != NULL) {
165 MD5Update(&md5_ctx, (uint8_t *)pass, strlen(pass));
168 MD5Final(token, &md5_ctx);
170 for(i = 0; i < sizeof(token); i++) {
171 char tmp[3];
173 snprintf(tmp, sizeof(tmp), "%02x", token[i]);
174 strncat(token_str, tmp, sizeof(tmp));
178 void print_xsrf_token(const char *username, const char *pass,
179 const char *formname)
181 char token[33];
183 get_xsrf_token(username, pass, formname, token);
184 printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
185 XSRF_TOKEN, token);
189 bool verify_xsrf_token(const char *formname)
191 char expected[33];
192 const char *username = cgi_user_name();
193 const char *pass = cgi_user_pass();
194 const char *token = cgi_variable_nonull(XSRF_TOKEN);
196 get_xsrf_token(username, pass, formname, expected);
197 return (strncmp(expected, token, sizeof(expected)) == 0);
201 /****************************************************************************
202 include a lump of html in a page
203 ****************************************************************************/
204 static int include_html(const char *fname)
206 int fd;
207 char buf[1024];
208 int ret;
210 fd = web_open(fname, O_RDONLY, 0);
212 if (fd == -1) {
213 printf(_("ERROR: Can't open %s"), fname);
214 printf("\n");
215 return 0;
218 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
219 if (write(1, buf, ret) == -1) {
220 break;
224 close(fd);
225 return 1;
228 /****************************************************************************
229 start the page with standard stuff
230 ****************************************************************************/
231 static void print_header(void)
233 if (!cgi_waspost()) {
234 printf("Expires: 0\r\n");
236 printf("Content-type: text/html\r\n\r\n");
238 if (!include_html("include/header.html")) {
239 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
240 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
244 /* *******************************************************************
245 show parameter label with translated name in the following form
246 because showing original and translated label in one line looks
247 too long, and showing translated label only is unusable for
248 heavy users.
249 -------------------------------
250 HELP security [combo box][button]
251 SECURITY
252 -------------------------------
253 (capital words are translated by gettext.)
254 if no translation is available, then same form as original is
255 used.
256 "i18n_translated_parm" class is used to change the color of the
257 translated parameter with CSS.
258 **************************************************************** */
259 static const char *get_parm_translated(TALLOC_CTX *ctx,
260 const char* pAnchor, const char* pHelp, const char* pLabel)
262 const char *pTranslated = _(pLabel);
263 char *output;
264 if(strcmp(pLabel, pTranslated) != 0) {
265 output = talloc_asprintf(ctx,
266 "<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>",
267 pAnchor, pHelp, pLabel, pTranslated);
268 return output;
270 output = talloc_asprintf(ctx,
271 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
272 pAnchor, pHelp, pLabel);
273 return output;
275 /****************************************************************************
276 finish off the page
277 ****************************************************************************/
278 static void print_footer(void)
280 if (!include_html("include/footer.html")) {
281 printf("\n</BODY>\n</HTML>\n");
285 /****************************************************************************
286 display one editable parameter in a form
287 ****************************************************************************/
288 static void show_parameter(int snum, struct parm_struct *parm)
290 int i;
291 void *ptr = parm->ptr;
292 char *utf8_s1, *utf8_s2;
293 size_t converted_size;
294 TALLOC_CTX *ctx = talloc_stackframe();
296 if (parm->p_class == P_LOCAL && snum >= 0) {
297 ptr = lp_local_ptr_by_snum(snum, ptr);
300 printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
301 stripspaceupper(parm->label), _("Help"), parm->label));
302 switch (parm->type) {
303 case P_CHAR:
304 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
305 make_parm_name(parm->label), *(char *)ptr);
306 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
307 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
308 break;
310 case P_LIST:
311 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
312 make_parm_name(parm->label));
313 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
314 char **list = *(char ***)ptr;
315 for (;*list;list++) {
316 /* enclose in HTML encoded quotes if the string contains a space */
317 if ( strchr_m(*list, ' ') ) {
318 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
319 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
320 printf("&quot;%s&quot;%s", utf8_s1, utf8_s2);
321 } else {
322 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
323 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
324 printf("%s%s", utf8_s1, utf8_s2);
326 TALLOC_FREE(utf8_s1);
327 TALLOC_FREE(utf8_s2);
330 printf("\">");
331 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
332 _("Set Default"), make_parm_name(parm->label));
333 if (parm->def.lvalue) {
334 char **list = (char **)(parm->def.lvalue);
335 for (; *list; list++) {
336 /* enclose in HTML encoded quotes if the string contains a space */
337 if ( strchr_m(*list, ' ') )
338 printf("&quot;%s&quot;%s", *list, ((*(list+1))?", ":""));
339 else
340 printf("%s%s", *list, ((*(list+1))?", ":""));
343 printf("\'\">");
344 break;
346 case P_STRING:
347 case P_USTRING:
348 push_utf8_talloc(talloc_tos(), &utf8_s1, *(char **)ptr, &converted_size);
349 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
350 make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
351 TALLOC_FREE(utf8_s1);
352 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
353 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
354 break;
356 case P_BOOL:
357 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
358 printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
359 printf("<option %s>No", (*(bool *)ptr)?"":"selected");
360 printf("</select>");
361 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
362 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
363 break;
365 case P_BOOLREV:
366 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
367 printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
368 printf("<option %s>No", (*(bool *)ptr)?"selected":"");
369 printf("</select>");
370 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
371 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
372 break;
374 case P_INTEGER:
375 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
376 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
377 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
378 break;
380 case P_OCTAL: {
381 char *o;
382 o = octal_string(*(int *)ptr);
383 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
384 make_parm_name(parm->label), o);
385 TALLOC_FREE(o);
386 o = octal_string((int)(parm->def.ivalue));
387 printf("<input type=button value=\"%s\" "
388 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
389 _("Set Default"), make_parm_name(parm->label), o);
390 TALLOC_FREE(o);
391 break;
394 case P_ENUM:
395 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
396 for (i=0;parm->enum_list[i].name;i++) {
397 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
398 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
401 printf("</select>");
402 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
403 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
404 break;
405 case P_SEP:
406 break;
408 printf("</td></tr>\n");
409 TALLOC_FREE(ctx);
412 /****************************************************************************
413 display a set of parameters for a service
414 ****************************************************************************/
415 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
417 int i = 0;
418 struct parm_struct *parm;
419 const char *heading = NULL;
420 const char *last_heading = NULL;
422 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
423 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
424 continue;
425 if (parm->p_class == P_SEPARATOR) {
426 heading = parm->label;
427 continue;
429 if (parm->flags & FLAG_HIDE) continue;
430 if (snum >= 0) {
431 if (printers & !(parm->flags & FLAG_PRINT)) continue;
432 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
435 if (!( parm_filter & FLAG_ADVANCED )) {
436 if (!(parm->flags & FLAG_BASIC)) {
437 void *ptr = parm->ptr;
439 if (parm->p_class == P_LOCAL && snum >= 0) {
440 ptr = lp_local_ptr_by_snum(snum, ptr);
443 switch (parm->type) {
444 case P_CHAR:
445 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
446 break;
448 case P_LIST:
449 if (!str_list_equal(*(const char ***)ptr,
450 (const char **)(parm->def.lvalue))) continue;
451 break;
453 case P_STRING:
454 case P_USTRING:
455 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
456 break;
458 case P_BOOL:
459 case P_BOOLREV:
460 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
461 break;
463 case P_INTEGER:
464 case P_OCTAL:
465 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
466 break;
469 case P_ENUM:
470 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
471 break;
472 case P_SEP:
473 continue;
476 if (printers && !(parm->flags & FLAG_PRINT)) continue;
479 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
481 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
483 if (heading && heading != last_heading) {
484 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
485 last_heading = heading;
487 show_parameter(snum, parm);
491 /****************************************************************************
492 load the smb.conf file into loadparm.
493 ****************************************************************************/
494 static bool load_config(bool save_def)
496 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
499 /****************************************************************************
500 write a config file
501 ****************************************************************************/
502 static void write_config(FILE *f, bool show_defaults)
504 TALLOC_CTX *ctx = talloc_stackframe();
506 fprintf(f, "# Samba config file created using SWAT\n");
507 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
508 fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
510 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
512 TALLOC_FREE(ctx);
515 /****************************************************************************
516 save and reload the smb.conf config file
517 ****************************************************************************/
518 static int save_reload(int snum)
520 FILE *f;
521 struct stat st;
523 f = sys_fopen(get_dyn_CONFIGFILE(),"w");
524 if (!f) {
525 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
526 printf("\n");
527 return 0;
530 /* just in case they have used the buggy xinetd to create the file */
531 if (fstat(fileno(f), &st) == 0 &&
532 (st.st_mode & S_IWOTH)) {
533 #if defined HAVE_FCHMOD
534 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
535 #else
536 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
537 #endif
540 write_config(f, False);
541 if (snum >= 0)
542 lp_dump_one(f, False, snum);
543 fclose(f);
545 lp_kill_all_services();
547 if (!load_config(False)) {
548 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
549 printf("\n");
550 return 0;
552 iNumNonAutoPrintServices = lp_numservices();
553 if (pcap_cache_loaded()) {
554 load_printers(server_event_context(),
555 server_messaging_context());
558 return 1;
561 /****************************************************************************
562 commit one parameter
563 ****************************************************************************/
564 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
566 int i;
567 char *s;
569 if (snum < 0 && parm->p_class == P_LOCAL) {
570 /* this handles the case where we are changing a local
571 variable globally. We need to change the parameter in
572 all shares where it is currently set to the default */
573 for (i=0;i<lp_numservices();i++) {
574 s = lp_servicename(i);
575 if (s && (*s) && lp_is_default(i, parm)) {
576 lp_do_parameter(i, parm->label, v);
581 lp_do_parameter(snum, parm->label, v);
584 /****************************************************************************
585 commit a set of parameters for a service
586 ****************************************************************************/
587 static void commit_parameters(int snum)
589 int i = 0;
590 struct parm_struct *parm;
591 char *label;
592 const char *v;
594 while ((parm = lp_next_parameter(snum, &i, 1))) {
595 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
596 if ((v = cgi_variable(label)) != NULL) {
597 if (parm->flags & FLAG_HIDE)
598 continue;
599 commit_parameter(snum, parm, v);
601 SAFE_FREE(label);
606 /****************************************************************************
607 spit out the html for a link with an image
608 ****************************************************************************/
609 static void image_link(const char *name, const char *hlink, const char *src)
611 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
612 cgi_baseurl(), hlink, src, name);
615 /****************************************************************************
616 display the main navigation controls at the top of each page along
617 with a title
618 ****************************************************************************/
619 static void show_main_buttons(void)
621 char *p;
623 if ((p = cgi_user_name()) && strcmp(p, "root")) {
624 printf(_("Logged in as <b>%s</b>"), p);
625 printf("<p>\n");
628 image_link(_("Home"), "", "images/home.gif");
629 if (have_write_access) {
630 image_link(_("Globals"), "globals", "images/globals.gif");
631 image_link(_("Shares"), "shares", "images/shares.gif");
632 image_link(_("Printers"), "printers", "images/printers.gif");
633 image_link(_("Wizard"), "wizard", "images/wizard.gif");
635 /* root always gets all buttons, otherwise look for -P */
636 if ( have_write_access || (!passwd_only && have_read_access) ) {
637 image_link(_("Status"), "status", "images/status.gif");
638 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
640 image_link(_("Password Management"), "passwd", "images/passwd.gif");
642 printf("<HR>\n");
645 /****************************************************************************
646 * Handle Display/Edit Mode CGI
647 ****************************************************************************/
648 static void ViewModeBoxes(int mode)
650 printf("<p>%s:&nbsp;\n", _("Current View Is"));
651 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
652 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
653 printf("<br>%s:&nbsp;\n", _("Change View To"));
654 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
655 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
656 printf("</p><br>\n");
659 /****************************************************************************
660 display a welcome page
661 ****************************************************************************/
662 static void welcome_page(void)
664 if (file_exist("help/welcome.html")) {
665 include_html("help/welcome.html");
666 } else {
667 include_html("help/welcome-no-samba-doc.html");
671 /****************************************************************************
672 display the current smb.conf
673 ****************************************************************************/
674 static void viewconfig_page(void)
676 int full_view=0;
677 const char form_name[] = "viewconfig";
679 if (!verify_xsrf_token(form_name)) {
680 goto output_page;
683 if (cgi_variable("full_view")) {
684 full_view = 1;
687 output_page:
688 printf("<H2>%s</H2>\n", _("Current Config"));
689 printf("<form method=post>\n");
690 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
692 if (full_view) {
693 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
694 } else {
695 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
698 printf("<p><pre>");
699 write_config(stdout, full_view);
700 printf("</pre>");
701 printf("</form>\n");
704 /****************************************************************************
705 second screen of the wizard ... Fetch Configuration Parameters
706 ****************************************************************************/
707 static void wizard_params_page(void)
709 unsigned int parm_filter = FLAG_WIZARD;
710 const char form_name[] = "wizard_params";
712 /* Here we first set and commit all the parameters that were selected
713 in the previous screen. */
715 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
717 if (!verify_xsrf_token(form_name)) {
718 goto output_page;
721 if (cgi_variable("Commit")) {
722 commit_parameters(GLOBAL_SECTION_SNUM);
723 save_reload(-1);
726 output_page:
727 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
728 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
730 if (have_write_access) {
731 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
734 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
735 printf("<p>\n");
737 printf("<table>\n");
738 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
739 printf("</table>\n");
740 printf("</form>\n");
743 /****************************************************************************
744 Utility to just rewrite the smb.conf file - effectively just cleans it up
745 ****************************************************************************/
746 static void rewritecfg_file(void)
748 commit_parameters(GLOBAL_SECTION_SNUM);
749 save_reload(-1);
750 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
753 /****************************************************************************
754 wizard to create/modify the smb.conf file
755 ****************************************************************************/
756 static void wizard_page(void)
758 /* Set some variables to collect data from smb.conf */
759 int role = 0;
760 int winstype = 0;
761 int have_home = -1;
762 int HomeExpo = 0;
763 int SerType = 0;
764 const char form_name[] = "wizard";
766 if (!verify_xsrf_token(form_name)) {
767 goto output_page;
770 if (cgi_variable("Rewrite")) {
771 (void) rewritecfg_file();
772 return;
775 if (cgi_variable("GetWizardParams")){
776 (void) wizard_params_page();
777 return;
780 if (cgi_variable("Commit")){
781 SerType = atoi(cgi_variable_nonull("ServerType"));
782 winstype = atoi(cgi_variable_nonull("WINSType"));
783 have_home = lp_servicenumber(HOMES_NAME);
784 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
786 /* Plain text passwords are too badly broken - use encrypted passwords only */
787 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
789 switch ( SerType ){
790 case 0:
791 /* Stand-alone Server */
792 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
793 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
794 break;
795 case 1:
796 /* Domain Member */
797 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
798 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
799 break;
800 case 2:
801 /* Domain Controller */
802 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
803 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
804 break;
806 switch ( winstype ) {
807 case 0:
808 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
809 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
810 break;
811 case 1:
812 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
813 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
814 break;
815 case 2:
816 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
817 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
818 break;
821 /* Have to create Homes share? */
822 if ((HomeExpo == 1) && (have_home == -1)) {
823 const char *unix_share = HOMES_NAME;
825 load_config(False);
826 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
827 have_home = lp_servicenumber(HOMES_NAME);
828 lp_do_parameter( have_home, "read only", "No");
829 lp_do_parameter( have_home, "valid users", "%S");
830 lp_do_parameter( have_home, "browseable", "No");
831 commit_parameters(have_home);
832 save_reload(have_home);
835 /* Need to Delete Homes share? */
836 if ((HomeExpo == 0) && (have_home != -1)) {
837 lp_remove_service(have_home);
838 have_home = -1;
841 commit_parameters(GLOBAL_SECTION_SNUM);
842 save_reload(-1);
844 else
846 /* Now determine smb.conf WINS settings */
847 if (lp_wins_support())
848 winstype = 1;
849 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
850 winstype = 2;
852 /* Do we have a homes share? */
853 have_home = lp_servicenumber(HOMES_NAME);
855 if ((winstype == 2) && lp_wins_support())
856 winstype = 3;
858 role = lp_server_role();
860 output_page:
861 /* Here we go ... */
862 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
863 printf("<form method=post action=wizard>\n");
864 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
866 if (have_write_access) {
867 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
868 printf("%s", _("The same will happen if you press the commit button."));
869 printf("<br><br>\n");
870 printf("<center>");
871 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
872 printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
873 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
874 printf("</center>\n");
877 printf("<hr>");
878 printf("<center><table border=0>");
879 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
880 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
881 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
882 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
883 printf("</tr>\n");
884 if (role == ROLE_DOMAIN_BDC) {
885 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
887 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
888 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
889 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
890 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
891 printf("</tr>\n");
892 printf("<tr><td></td><td></td><td></td><td>%s&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
894 /* Print out the list of wins servers */
895 if(lp_wins_server_list()) {
896 int i;
897 const char **wins_servers = lp_wins_server_list();
898 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
901 printf("\"></td></tr>\n");
902 if (winstype == 3) {
903 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"));
904 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
906 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
907 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
908 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
909 printf("<td></td></tr>\n");
911 /* Enable this when we are ready ....
912 * printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
913 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
914 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
915 * printf("<td></td></tr>\n");
918 printf("</table></center>");
919 printf("<hr>");
921 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
922 printf("</form>\n");
926 /****************************************************************************
927 display a globals editing page
928 ****************************************************************************/
929 static void globals_page(void)
931 unsigned int parm_filter = FLAG_BASIC;
932 int mode = 0;
933 const char form_name[] = "globals";
935 printf("<H2>%s</H2>\n", _("Global Parameters"));
937 if (!verify_xsrf_token(form_name)) {
938 goto output_page;
941 if (cgi_variable("Commit")) {
942 commit_parameters(GLOBAL_SECTION_SNUM);
943 save_reload(-1);
946 if ( cgi_variable("ViewMode") )
947 mode = atoi(cgi_variable_nonull("ViewMode"));
948 if ( cgi_variable("BasicMode"))
949 mode = 0;
950 if ( cgi_variable("AdvMode"))
951 mode = 1;
953 output_page:
954 printf("<form name=\"swatform\" method=post action=globals>\n");
955 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
957 ViewModeBoxes( mode );
958 switch ( mode ) {
959 case 0:
960 parm_filter = FLAG_BASIC;
961 break;
962 case 1:
963 parm_filter = FLAG_ADVANCED;
964 break;
966 printf("<br>\n");
967 if (have_write_access) {
968 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
969 _("Commit Changes"));
972 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
973 _("Reset Values"));
975 printf("<p>\n");
976 printf("<table>\n");
977 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
978 printf("</table>\n");
979 printf("</form>\n");
982 /****************************************************************************
983 display a shares editing page. share is in unix codepage,
984 ****************************************************************************/
985 static void shares_page(void)
987 const char *share = cgi_variable("share");
988 char *s;
989 char *utf8_s;
990 int snum = -1;
991 int i;
992 int mode = 0;
993 unsigned int parm_filter = FLAG_BASIC;
994 size_t converted_size;
995 const char form_name[] = "shares";
997 printf("<H2>%s</H2>\n", _("Share Parameters"));
999 if (!verify_xsrf_token(form_name)) {
1000 goto output_page;
1003 if (share)
1004 snum = lp_servicenumber(share);
1007 if (cgi_variable("Commit") && snum >= 0) {
1008 commit_parameters(snum);
1009 save_reload(-1);
1010 snum = lp_servicenumber(share);
1013 if (cgi_variable("Delete") && snum >= 0) {
1014 lp_remove_service(snum);
1015 save_reload(-1);
1016 share = NULL;
1017 snum = -1;
1020 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1021 snum = lp_servicenumber(share);
1022 if (snum < 0) {
1023 load_config(False);
1024 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1025 snum = lp_servicenumber(share);
1026 save_reload(snum);
1027 snum = lp_servicenumber(share);
1031 if ( cgi_variable("ViewMode") )
1032 mode = atoi(cgi_variable_nonull("ViewMode"));
1033 if ( cgi_variable("BasicMode"))
1034 mode = 0;
1035 if ( cgi_variable("AdvMode"))
1036 mode = 1;
1038 output_page:
1039 printf("<FORM name=\"swatform\" method=post>\n");
1040 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1042 printf("<table>\n");
1044 ViewModeBoxes( mode );
1045 switch ( mode ) {
1046 case 0:
1047 parm_filter = FLAG_BASIC;
1048 break;
1049 case 1:
1050 parm_filter = FLAG_ADVANCED;
1051 break;
1053 printf("<br><tr>\n");
1054 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1055 printf("<td><select name=share>\n");
1056 if (snum < 0)
1057 printf("<option value=\" \"> \n");
1058 for (i=0;i<lp_numservices();i++) {
1059 s = lp_servicename(i);
1060 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
1061 push_utf8_talloc(talloc_tos(), &utf8_s, s, &converted_size);
1062 printf("<option %s value=\"%s\">%s\n",
1063 (share && strcmp(share,s)==0)?"SELECTED":"",
1064 utf8_s, utf8_s);
1065 TALLOC_FREE(utf8_s);
1068 printf("</select></td>\n");
1069 if (have_write_access) {
1070 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1072 printf("</tr>\n");
1073 printf("</table>");
1074 printf("<table>");
1075 if (have_write_access) {
1076 printf("<tr>\n");
1077 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1078 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1080 printf("</table>");
1083 if (snum >= 0) {
1084 if (have_write_access) {
1085 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1088 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1089 printf("<p>\n");
1092 if (snum >= 0) {
1093 printf("<table>\n");
1094 show_parameters(snum, 1, parm_filter, 0);
1095 printf("</table>\n");
1098 printf("</FORM>\n");
1101 /*************************************************************
1102 change a password either locally or remotely
1103 *************************************************************/
1104 static bool change_password(const char *remote_machine, const char *user_name,
1105 const char *old_passwd, const char *new_passwd,
1106 int local_flags)
1108 NTSTATUS ret;
1109 char *err_str = NULL;
1110 char *msg_str = NULL;
1112 if (demo_mode) {
1113 printf("%s\n<p>", _("password change in demo mode rejected"));
1114 return False;
1117 if (remote_machine != NULL) {
1118 ret = remote_password_change(remote_machine, user_name,
1119 old_passwd, new_passwd, &err_str);
1120 if (err_str != NULL)
1121 printf("%s\n<p>", err_str);
1122 SAFE_FREE(err_str);
1123 return NT_STATUS_IS_OK(ret);
1126 if(!initialize_password_db(True, NULL)) {
1127 printf("%s\n<p>", _("Can't setup password database vectors."));
1128 return False;
1131 ret = local_password_change(user_name, local_flags, new_passwd,
1132 &err_str, &msg_str);
1134 if(msg_str)
1135 printf("%s\n<p>", msg_str);
1136 if(err_str)
1137 printf("%s\n<p>", err_str);
1139 SAFE_FREE(msg_str);
1140 SAFE_FREE(err_str);
1141 return NT_STATUS_IS_OK(ret);
1144 /****************************************************************************
1145 do the stuff required to add or change a password
1146 ****************************************************************************/
1147 static void chg_passwd(void)
1149 const char *host;
1150 bool rslt;
1151 int local_flags = 0;
1153 /* Make sure users name has been specified */
1154 if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1155 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1156 return;
1160 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1161 * so if that's what we're doing, skip the rest of the checks
1163 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1166 * If current user is not root, make sure old password has been specified
1167 * If REMOTE change, even root must provide old password
1169 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1170 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1171 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1172 return;
1175 /* If changing a users password on a remote hosts we have to know what host */
1176 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1177 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1178 return;
1181 /* Make sure new passwords have been specified */
1182 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1183 (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1184 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1185 return;
1188 /* Make sure new passwords was typed correctly twice */
1189 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1190 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1191 return;
1195 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1196 host = cgi_variable(RHOST);
1197 } else if (am_root()) {
1198 host = NULL;
1199 } else {
1200 host = "127.0.0.1";
1204 * Set up the local flags.
1207 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1208 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1209 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1210 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1211 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1212 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1214 rslt = change_password(host,
1215 cgi_variable_nonull(SWAT_USER),
1216 cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1217 local_flags);
1219 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1220 printf("<p>");
1221 if (rslt == True) {
1222 printf("%s\n", _(" The passwd has been changed."));
1223 } else {
1224 printf("%s\n", _(" The passwd has NOT been changed."));
1228 return;
1231 /****************************************************************************
1232 display a password editing page
1233 ****************************************************************************/
1234 static void passwd_page(void)
1236 const char *new_name = cgi_user_name();
1237 const char passwd_form[] = "passwd";
1238 const char rpasswd_form[] = "rpasswd";
1240 if (!new_name) new_name = "";
1242 printf("<H2>%s</H2>\n", _("Server Password Management"));
1244 printf("<FORM name=\"swatform\" method=post>\n");
1245 print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form);
1247 printf("<table>\n");
1250 * Create all the dialog boxes for data collection
1252 printf("<tr><td> %s : </td>\n", _("User Name"));
1253 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1254 if (!am_root()) {
1255 printf("<tr><td> %s : </td>\n", _("Old Password"));
1256 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1258 printf("<tr><td> %s : </td>\n", _("New Password"));
1259 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1260 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1261 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1262 printf("</table>\n");
1265 * Create all the control buttons for requesting action
1267 printf("<input type=submit name=%s value=\"%s\">\n",
1268 CHG_S_PASSWD_FLAG, _("Change Password"));
1269 if (demo_mode || am_root()) {
1270 printf("<input type=submit name=%s value=\"%s\">\n",
1271 ADD_USER_FLAG, _("Add New User"));
1272 printf("<input type=submit name=%s value=\"%s\">\n",
1273 DELETE_USER_FLAG, _("Delete User"));
1274 printf("<input type=submit name=%s value=\"%s\">\n",
1275 DISABLE_USER_FLAG, _("Disable User"));
1276 printf("<input type=submit name=%s value=\"%s\">\n",
1277 ENABLE_USER_FLAG, _("Enable User"));
1279 printf("<p></FORM>\n");
1282 * Do some work if change, add, disable or enable was
1283 * requested. It could be this is the first time through this
1284 * code, so there isn't anything to do. */
1285 if (verify_xsrf_token(passwd_form) &&
1286 ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1287 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG)))) {
1288 chg_passwd();
1291 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1293 printf("<FORM name=\"swatform\" method=post>\n");
1294 print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form);
1296 printf("<table>\n");
1299 * Create all the dialog boxes for data collection
1301 printf("<tr><td> %s : </td>\n", _("User Name"));
1302 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1303 printf("<tr><td> %s : </td>\n", _("Old Password"));
1304 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1305 printf("<tr><td> %s : </td>\n", _("New Password"));
1306 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1307 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1308 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1309 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1310 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1312 printf("</table>");
1315 * Create all the control buttons for requesting action
1317 printf("<input type=submit name=%s value=\"%s\">",
1318 CHG_R_PASSWD_FLAG, _("Change Password"));
1320 printf("<p></FORM>\n");
1323 * Do some work if a request has been made to change the
1324 * password somewhere other than the server. It could be this
1325 * is the first time through this code, so there isn't
1326 * anything to do. */
1327 if (verify_xsrf_token(passwd_form) && cgi_variable(CHG_R_PASSWD_FLAG)) {
1328 chg_passwd();
1333 /****************************************************************************
1334 display a printers editing page
1335 ****************************************************************************/
1336 static void printers_page(void)
1338 const char *share = cgi_variable("share");
1339 char *s;
1340 int snum=-1;
1341 int i;
1342 int mode = 0;
1343 unsigned int parm_filter = FLAG_BASIC;
1344 const char form_name[] = "printers";
1346 if (!verify_xsrf_token(form_name)) {
1347 goto output_page;
1350 if (share)
1351 snum = lp_servicenumber(share);
1353 if (cgi_variable("Commit") && snum >= 0) {
1354 commit_parameters(snum);
1355 if (snum >= iNumNonAutoPrintServices)
1356 save_reload(snum);
1357 else
1358 save_reload(-1);
1359 snum = lp_servicenumber(share);
1362 if (cgi_variable("Delete") && snum >= 0) {
1363 lp_remove_service(snum);
1364 save_reload(-1);
1365 share = NULL;
1366 snum = -1;
1369 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1370 snum = lp_servicenumber(share);
1371 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1372 load_config(False);
1373 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1374 snum = lp_servicenumber(share);
1375 lp_do_parameter(snum, "print ok", "Yes");
1376 save_reload(snum);
1377 snum = lp_servicenumber(share);
1381 if ( cgi_variable("ViewMode") )
1382 mode = atoi(cgi_variable_nonull("ViewMode"));
1383 if ( cgi_variable("BasicMode"))
1384 mode = 0;
1385 if ( cgi_variable("AdvMode"))
1386 mode = 1;
1388 output_page:
1389 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1391 printf("<H3>%s</H3>\n", _("Important Note:"));
1392 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1393 printf("%s",_("are autoloaded printers from "));
1394 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1395 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1398 printf("<FORM name=\"swatform\" method=post>\n");
1399 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1401 ViewModeBoxes( mode );
1402 switch ( mode ) {
1403 case 0:
1404 parm_filter = FLAG_BASIC;
1405 break;
1406 case 1:
1407 parm_filter = FLAG_ADVANCED;
1408 break;
1410 printf("<table>\n");
1411 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1412 printf("<td><select name=\"share\">\n");
1413 if (snum < 0 || !lp_print_ok(snum))
1414 printf("<option value=\" \"> \n");
1415 for (i=0;i<lp_numservices();i++) {
1416 s = lp_servicename(i);
1417 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1418 if (i >= iNumNonAutoPrintServices)
1419 printf("<option %s value=\"%s\">[*]%s\n",
1420 (share && strcmp(share,s)==0)?"SELECTED":"",
1421 s, s);
1422 else
1423 printf("<option %s value=\"%s\">%s\n",
1424 (share && strcmp(share,s)==0)?"SELECTED":"",
1425 s, s);
1428 printf("</select></td>");
1429 if (have_write_access) {
1430 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1432 printf("</tr>");
1433 printf("</table>\n");
1435 if (have_write_access) {
1436 printf("<table>\n");
1437 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1438 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1439 printf("</table>");
1443 if (snum >= 0) {
1444 if (have_write_access) {
1445 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1447 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1448 printf("<p>\n");
1451 if (snum >= 0) {
1452 printf("<table>\n");
1453 show_parameters(snum, 1, parm_filter, 1);
1454 printf("</table>\n");
1456 printf("</FORM>\n");
1460 when the _() translation macro is used there is no obvious place to free
1461 the resulting string and there is no easy way to give a static pointer.
1462 All we can do is rotate between some static buffers and hope a single d_printf()
1463 doesn't have more calls to _() than the number of buffers
1466 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1468 const char *msgstr;
1469 const char *ret;
1471 msgstr = lang_msg(msgid);
1472 if (!msgstr) {
1473 return msgid;
1476 ret = talloc_strdup(ctx, msgstr);
1478 lang_msg_free(msgstr);
1479 if (!ret) {
1480 return msgid;
1483 return ret;
1487 * main function for SWAT.
1489 int main(int argc, char *argv[])
1491 const char *page;
1492 poptContext pc;
1493 struct poptOption long_options[] = {
1494 POPT_AUTOHELP
1495 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1496 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1497 POPT_COMMON_SAMBA
1498 POPT_TABLEEND
1500 TALLOC_CTX *frame = talloc_stackframe();
1502 fault_setup(NULL);
1503 umask(S_IWGRP | S_IWOTH);
1505 #if defined(HAVE_SET_AUTH_PARAMETERS)
1506 set_auth_parameters(argc, argv);
1507 #endif /* HAVE_SET_AUTH_PARAMETERS */
1509 /* just in case it goes wild ... */
1510 alarm(300);
1512 setlinebuf(stdout);
1514 /* we don't want any SIGPIPE messages */
1515 BlockSignals(True,SIGPIPE);
1517 debug_set_logfile("/dev/null");
1519 /* we don't want stderr screwing us up */
1520 close(2);
1521 open("/dev/null", O_WRONLY);
1522 setup_logging("swat", DEBUG_FILE);
1524 load_case_tables();
1526 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1528 /* Parse command line options */
1530 while(poptGetNextOpt(pc) != -1) { }
1532 poptFreeContext(pc);
1534 /* This should set a more apporiate log file */
1535 load_config(True);
1536 reopen_logs();
1537 load_interfaces();
1538 iNumNonAutoPrintServices = lp_numservices();
1539 if (pcap_cache_loaded()) {
1540 load_printers(server_event_context(),
1541 server_messaging_context());
1544 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1546 print_header();
1548 cgi_load_variables();
1550 if (!file_exist(get_dyn_CONFIGFILE())) {
1551 have_read_access = True;
1552 have_write_access = True;
1553 } else {
1554 /* check if the authenticated user has write access - if not then
1555 don't show write options */
1556 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1558 /* if the user doesn't have read access to smb.conf then
1559 don't let them view it */
1560 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1563 show_main_buttons();
1565 page = cgi_pathinfo();
1567 /* Root gets full functionality */
1568 if (have_read_access && strcmp(page, "globals")==0) {
1569 globals_page();
1570 } else if (have_read_access && strcmp(page,"shares")==0) {
1571 shares_page();
1572 } else if (have_read_access && strcmp(page,"printers")==0) {
1573 printers_page();
1574 } else if (have_read_access && strcmp(page,"status")==0) {
1575 status_page();
1576 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1577 viewconfig_page();
1578 } else if (strcmp(page,"passwd")==0) {
1579 passwd_page();
1580 } else if (have_read_access && strcmp(page,"wizard")==0) {
1581 wizard_page();
1582 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1583 wizard_params_page();
1584 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1585 rewritecfg_file();
1586 } else {
1587 welcome_page();
1590 print_footer();
1592 TALLOC_FREE(frame);
1593 return 0;
1596 /** @} **/