s3 swat: Add time component to XSRF token
[Samba.git] / source3 / web / swat.c
blob259b833e85f82ccf9c984b9fe70df6f70f4cc3e5
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"
32 #include "../lib/crypto/md5.h"
34 static int demo_mode = False;
35 static int passwd_only = False;
36 static bool have_write_access = False;
37 static bool have_read_access = False;
38 static int iNumNonAutoPrintServices = 0;
41 * Password Management Globals
43 #define SWAT_USER "username"
44 #define OLD_PSWD "old_passwd"
45 #define NEW_PSWD "new_passwd"
46 #define NEW2_PSWD "new2_passwd"
47 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
48 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
49 #define ADD_USER_FLAG "add_user_flag"
50 #define DELETE_USER_FLAG "delete_user_flag"
51 #define DISABLE_USER_FLAG "disable_user_flag"
52 #define ENABLE_USER_FLAG "enable_user_flag"
53 #define RHOST "remote_host"
54 #define XSRF_TOKEN "xsrf"
55 #define XSRF_TIME "xsrf_time"
56 #define XSRF_TIMEOUT 300
58 #define _(x) lang_msg_rotate(talloc_tos(),x)
60 /****************************************************************************
61 ****************************************************************************/
62 static int enum_index(int value, const struct enum_list *enumlist)
64 int i;
65 for (i=0;enumlist[i].name;i++)
66 if (value == enumlist[i].value) break;
67 return(i);
70 static char *fix_backslash(const char *str)
72 static char newstring[1024];
73 char *p = newstring;
75 while (*str) {
76 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
77 else *p++ = *str;
78 ++str;
80 *p = '\0';
81 return newstring;
84 static const char *fix_quotes(TALLOC_CTX *ctx, const char *str)
86 char *newstring = NULL;
87 char *p = NULL;
88 size_t newstring_len;
89 int quote_len = strlen("&quot;");
91 /* Count the number of quotes. */
92 newstring_len = 1;
93 p = (char *) str;
94 while (*p) {
95 if ( *p == '\"') {
96 newstring_len += quote_len;
97 } else {
98 newstring_len++;
100 ++p;
102 newstring = TALLOC_ARRAY(ctx, char, newstring_len);
103 if (!newstring) {
104 return "";
106 for (p = newstring; *str; str++) {
107 if ( *str == '\"') {
108 strncpy( p, "&quot;", quote_len);
109 p += quote_len;
110 } else {
111 *p++ = *str;
114 *p = '\0';
115 return newstring;
118 static char *stripspaceupper(const char *str)
120 static char newstring[1024];
121 char *p = newstring;
123 while (*str) {
124 if (*str != ' ') *p++ = toupper_ascii(*str);
125 ++str;
127 *p = '\0';
128 return newstring;
131 static char *make_parm_name(const char *label)
133 static char parmname[1024];
134 char *p = parmname;
136 while (*label) {
137 if (*label == ' ') *p++ = '_';
138 else *p++ = *label;
139 ++label;
141 *p = '\0';
142 return parmname;
145 void get_xsrf_token(const char *username, const char *pass,
146 const char *formname, time_t xsrf_time, char token_str[33])
148 struct MD5Context md5_ctx;
149 uint8_t token[16];
150 int i;
152 token_str[0] = '\0';
153 ZERO_STRUCT(md5_ctx);
154 MD5Init(&md5_ctx);
156 MD5Update(&md5_ctx, (uint8_t *)formname, strlen(formname));
157 MD5Update(&md5_ctx, (uint8_t *)&xsrf_time, sizeof(time_t));
158 if (username != NULL) {
159 MD5Update(&md5_ctx, (uint8_t *)username, strlen(username));
161 if (pass != NULL) {
162 MD5Update(&md5_ctx, (uint8_t *)pass, strlen(pass));
165 MD5Final(token, &md5_ctx);
167 for(i = 0; i < sizeof(token); i++) {
168 char tmp[3];
170 snprintf(tmp, sizeof(tmp), "%02x", token[i]);
171 strncat(token_str, tmp, sizeof(tmp));
175 void print_xsrf_token(const char *username, const char *pass,
176 const char *formname)
178 char token[33];
179 time_t xsrf_time = time(NULL);
181 get_xsrf_token(username, pass, formname, xsrf_time, token);
182 printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
183 XSRF_TOKEN, token);
184 printf("<input type=\"hidden\" name=\"%s\" value=\"%lld\">\n",
185 XSRF_TIME, (long long int)xsrf_time);
188 bool verify_xsrf_token(const char *formname)
190 char expected[33];
191 const char *username = cgi_user_name();
192 const char *pass = cgi_user_pass();
193 const char *token = cgi_variable_nonull(XSRF_TOKEN);
194 const char *time_str = cgi_variable_nonull(XSRF_TIME);
195 time_t xsrf_time = 0;
196 time_t now = time(NULL);
198 if (sizeof(time_t) == sizeof(int)) {
199 xsrf_time = atoi(time_str);
200 } else if (sizeof(time_t) == sizeof(long)) {
201 xsrf_time = atol(time_str);
202 } else if (sizeof(time_t) == sizeof(long long)) {
203 xsrf_time = atoll(time_str);
206 if (abs(now - xsrf_time) > XSRF_TIMEOUT) {
207 return false;
210 get_xsrf_token(username, pass, formname, xsrf_time, expected);
211 return (strncmp(expected, token, sizeof(expected)) == 0);
215 /****************************************************************************
216 include a lump of html in a page
217 ****************************************************************************/
218 static int include_html(const char *fname)
220 int fd;
221 char buf[1024];
222 int ret;
224 fd = web_open(fname, O_RDONLY, 0);
226 if (fd == -1) {
227 printf(_("ERROR: Can't open %s"), fname);
228 printf("\n");
229 return 0;
232 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
233 if (write(1, buf, ret) == -1) {
234 break;
238 close(fd);
239 return 1;
242 /****************************************************************************
243 start the page with standard stuff
244 ****************************************************************************/
245 static void print_header(void)
247 if (!cgi_waspost()) {
248 printf("Expires: 0\r\n");
250 printf("Content-type: text/html\r\n\r\n");
252 if (!include_html("include/header.html")) {
253 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
254 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
258 /* *******************************************************************
259 show parameter label with translated name in the following form
260 because showing original and translated label in one line looks
261 too long, and showing translated label only is unusable for
262 heavy users.
263 -------------------------------
264 HELP security [combo box][button]
265 SECURITY
266 -------------------------------
267 (capital words are translated by gettext.)
268 if no translation is available, then same form as original is
269 used.
270 "i18n_translated_parm" class is used to change the color of the
271 translated parameter with CSS.
272 **************************************************************** */
273 static const char *get_parm_translated(TALLOC_CTX *ctx,
274 const char* pAnchor, const char* pHelp, const char* pLabel)
276 const char *pTranslated = _(pLabel);
277 char *output;
278 if(strcmp(pLabel, pTranslated) != 0) {
279 output = talloc_asprintf(ctx,
280 "<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>",
281 pAnchor, pHelp, pLabel, pTranslated);
282 return output;
284 output = talloc_asprintf(ctx,
285 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
286 pAnchor, pHelp, pLabel);
287 return output;
289 /****************************************************************************
290 finish off the page
291 ****************************************************************************/
292 static void print_footer(void)
294 if (!include_html("include/footer.html")) {
295 printf("\n</BODY>\n</HTML>\n");
299 /****************************************************************************
300 display one editable parameter in a form
301 ****************************************************************************/
302 static void show_parameter(int snum, struct parm_struct *parm)
304 int i;
305 void *ptr = parm->ptr;
306 char *utf8_s1, *utf8_s2;
307 size_t converted_size;
308 TALLOC_CTX *ctx = talloc_stackframe();
310 if (parm->p_class == P_LOCAL && snum >= 0) {
311 ptr = lp_local_ptr_by_snum(snum, ptr);
314 printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
315 stripspaceupper(parm->label), _("Help"), parm->label));
316 switch (parm->type) {
317 case P_CHAR:
318 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
319 make_parm_name(parm->label), *(char *)ptr);
320 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
321 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
322 break;
324 case P_LIST:
325 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
326 make_parm_name(parm->label));
327 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
328 char **list = *(char ***)ptr;
329 for (;*list;list++) {
330 /* enclose in HTML encoded quotes if the string contains a space */
331 if ( strchr_m(*list, ' ') ) {
332 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
333 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
334 printf("&quot;%s&quot;%s", utf8_s1, utf8_s2);
335 } else {
336 push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
337 push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
338 printf("%s%s", utf8_s1, utf8_s2);
340 TALLOC_FREE(utf8_s1);
341 TALLOC_FREE(utf8_s2);
344 printf("\">");
345 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
346 _("Set Default"), make_parm_name(parm->label));
347 if (parm->def.lvalue) {
348 char **list = (char **)(parm->def.lvalue);
349 for (; *list; list++) {
350 /* enclose in HTML encoded quotes if the string contains a space */
351 if ( strchr_m(*list, ' ') )
352 printf("&quot;%s&quot;%s", *list, ((*(list+1))?", ":""));
353 else
354 printf("%s%s", *list, ((*(list+1))?", ":""));
357 printf("\'\">");
358 break;
360 case P_STRING:
361 case P_USTRING:
362 push_utf8_talloc(talloc_tos(), &utf8_s1, *(char **)ptr, &converted_size);
363 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
364 make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
365 TALLOC_FREE(utf8_s1);
366 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
367 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
368 break;
370 case P_BOOL:
371 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
372 printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
373 printf("<option %s>No", (*(bool *)ptr)?"":"selected");
374 printf("</select>");
375 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
376 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
377 break;
379 case P_BOOLREV:
380 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
381 printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
382 printf("<option %s>No", (*(bool *)ptr)?"selected":"");
383 printf("</select>");
384 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
385 _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
386 break;
388 case P_INTEGER:
389 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
390 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
391 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
392 break;
394 case P_OCTAL: {
395 char *o;
396 o = octal_string(*(int *)ptr);
397 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
398 make_parm_name(parm->label), o);
399 TALLOC_FREE(o);
400 o = octal_string((int)(parm->def.ivalue));
401 printf("<input type=button value=\"%s\" "
402 "onClick=\"swatform.parm_%s.value=\'%s\'\">",
403 _("Set Default"), make_parm_name(parm->label), o);
404 TALLOC_FREE(o);
405 break;
408 case P_ENUM:
409 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
410 for (i=0;parm->enum_list[i].name;i++) {
411 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
412 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
415 printf("</select>");
416 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
417 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
418 break;
419 case P_SEP:
420 break;
422 printf("</td></tr>\n");
423 TALLOC_FREE(ctx);
426 /****************************************************************************
427 display a set of parameters for a service
428 ****************************************************************************/
429 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
431 int i = 0;
432 struct parm_struct *parm;
433 const char *heading = NULL;
434 const char *last_heading = NULL;
436 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
437 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
438 continue;
439 if (parm->p_class == P_SEPARATOR) {
440 heading = parm->label;
441 continue;
443 if (parm->flags & FLAG_HIDE) continue;
444 if (snum >= 0) {
445 if (printers & !(parm->flags & FLAG_PRINT)) continue;
446 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
449 if (!( parm_filter & FLAG_ADVANCED )) {
450 if (!(parm->flags & FLAG_BASIC)) {
451 void *ptr = parm->ptr;
453 if (parm->p_class == P_LOCAL && snum >= 0) {
454 ptr = lp_local_ptr_by_snum(snum, ptr);
457 switch (parm->type) {
458 case P_CHAR:
459 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
460 break;
462 case P_LIST:
463 if (!str_list_equal(*(const char ***)ptr,
464 (const char **)(parm->def.lvalue))) continue;
465 break;
467 case P_STRING:
468 case P_USTRING:
469 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
470 break;
472 case P_BOOL:
473 case P_BOOLREV:
474 if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
475 break;
477 case P_INTEGER:
478 case P_OCTAL:
479 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
480 break;
483 case P_ENUM:
484 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
485 break;
486 case P_SEP:
487 continue;
490 if (printers && !(parm->flags & FLAG_PRINT)) continue;
493 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
495 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
497 if (heading && heading != last_heading) {
498 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
499 last_heading = heading;
501 show_parameter(snum, parm);
505 /****************************************************************************
506 load the smb.conf file into loadparm.
507 ****************************************************************************/
508 static bool load_config(bool save_def)
510 return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
513 /****************************************************************************
514 write a config file
515 ****************************************************************************/
516 static void write_config(FILE *f, bool show_defaults)
518 TALLOC_CTX *ctx = talloc_stackframe();
520 fprintf(f, "# Samba config file created using SWAT\n");
521 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
522 fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
524 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
526 TALLOC_FREE(ctx);
529 /****************************************************************************
530 save and reload the smb.conf config file
531 ****************************************************************************/
532 static int save_reload(int snum)
534 FILE *f;
535 struct stat st;
537 f = sys_fopen(get_dyn_CONFIGFILE(),"w");
538 if (!f) {
539 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
540 printf("\n");
541 return 0;
544 /* just in case they have used the buggy xinetd to create the file */
545 if (fstat(fileno(f), &st) == 0 &&
546 (st.st_mode & S_IWOTH)) {
547 #if defined HAVE_FCHMOD
548 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
549 #else
550 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
551 #endif
554 write_config(f, False);
555 if (snum >= 0)
556 lp_dump_one(f, False, snum);
557 fclose(f);
559 lp_kill_all_services();
561 if (!load_config(False)) {
562 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
563 printf("\n");
564 return 0;
566 iNumNonAutoPrintServices = lp_numservices();
567 pcap_cache_reload(&load_printers);
569 return 1;
572 /****************************************************************************
573 commit one parameter
574 ****************************************************************************/
575 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
577 int i;
578 char *s;
580 if (snum < 0 && parm->p_class == P_LOCAL) {
581 /* this handles the case where we are changing a local
582 variable globally. We need to change the parameter in
583 all shares where it is currently set to the default */
584 for (i=0;i<lp_numservices();i++) {
585 s = lp_servicename(i);
586 if (s && (*s) && lp_is_default(i, parm)) {
587 lp_do_parameter(i, parm->label, v);
592 lp_do_parameter(snum, parm->label, v);
595 /****************************************************************************
596 commit a set of parameters for a service
597 ****************************************************************************/
598 static void commit_parameters(int snum)
600 int i = 0;
601 struct parm_struct *parm;
602 char *label;
603 const char *v;
605 while ((parm = lp_next_parameter(snum, &i, 1))) {
606 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
607 if ((v = cgi_variable(label)) != NULL) {
608 if (parm->flags & FLAG_HIDE)
609 continue;
610 commit_parameter(snum, parm, v);
612 SAFE_FREE(label);
617 /****************************************************************************
618 spit out the html for a link with an image
619 ****************************************************************************/
620 static void image_link(const char *name, const char *hlink, const char *src)
622 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
623 cgi_baseurl(), hlink, src, name);
626 /****************************************************************************
627 display the main navigation controls at the top of each page along
628 with a title
629 ****************************************************************************/
630 static void show_main_buttons(void)
632 char *p;
634 if ((p = cgi_user_name()) && strcmp(p, "root")) {
635 printf(_("Logged in as <b>%s</b>"), p);
636 printf("<p>\n");
639 image_link(_("Home"), "", "images/home.gif");
640 if (have_write_access) {
641 image_link(_("Globals"), "globals", "images/globals.gif");
642 image_link(_("Shares"), "shares", "images/shares.gif");
643 image_link(_("Printers"), "printers", "images/printers.gif");
644 image_link(_("Wizard"), "wizard", "images/wizard.gif");
646 /* root always gets all buttons, otherwise look for -P */
647 if ( have_write_access || (!passwd_only && have_read_access) ) {
648 image_link(_("Status"), "status", "images/status.gif");
649 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
651 image_link(_("Password Management"), "passwd", "images/passwd.gif");
653 printf("<HR>\n");
656 /****************************************************************************
657 * Handle Display/Edit Mode CGI
658 ****************************************************************************/
659 static void ViewModeBoxes(int mode)
661 printf("<p>%s:&nbsp;\n", _("Current View Is"));
662 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
663 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
664 printf("<br>%s:&nbsp;\n", _("Change View To"));
665 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
666 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
667 printf("</p><br>\n");
670 /****************************************************************************
671 display a welcome page
672 ****************************************************************************/
673 static void welcome_page(void)
675 if (file_exist("help/welcome.html")) {
676 include_html("help/welcome.html");
677 } else {
678 include_html("help/welcome-no-samba-doc.html");
682 /****************************************************************************
683 display the current smb.conf
684 ****************************************************************************/
685 static void viewconfig_page(void)
687 int full_view=0;
688 const char form_name[] = "viewconfig";
690 if (!verify_xsrf_token(form_name)) {
691 goto output_page;
694 if (cgi_variable("full_view")) {
695 full_view = 1;
698 output_page:
699 printf("<H2>%s</H2>\n", _("Current Config"));
700 printf("<form method=post>\n");
701 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
703 if (full_view) {
704 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
705 } else {
706 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
709 printf("<p><pre>");
710 write_config(stdout, full_view);
711 printf("</pre>");
712 printf("</form>\n");
715 /****************************************************************************
716 second screen of the wizard ... Fetch Configuration Parameters
717 ****************************************************************************/
718 static void wizard_params_page(void)
720 unsigned int parm_filter = FLAG_WIZARD;
721 const char form_name[] = "wizard_params";
723 /* Here we first set and commit all the parameters that were selected
724 in the previous screen. */
726 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
728 if (!verify_xsrf_token(form_name)) {
729 goto output_page;
732 if (cgi_variable("Commit")) {
733 commit_parameters(GLOBAL_SECTION_SNUM);
734 save_reload(-1);
737 output_page:
738 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
739 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
741 if (have_write_access) {
742 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
745 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
746 printf("<p>\n");
748 printf("<table>\n");
749 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
750 printf("</table>\n");
751 printf("</form>\n");
754 /****************************************************************************
755 Utility to just rewrite the smb.conf file - effectively just cleans it up
756 ****************************************************************************/
757 static void rewritecfg_file(void)
759 commit_parameters(GLOBAL_SECTION_SNUM);
760 save_reload(-1);
761 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
764 /****************************************************************************
765 wizard to create/modify the smb.conf file
766 ****************************************************************************/
767 static void wizard_page(void)
769 /* Set some variables to collect data from smb.conf */
770 int role = 0;
771 int winstype = 0;
772 int have_home = -1;
773 int HomeExpo = 0;
774 int SerType = 0;
775 const char form_name[] = "wizard";
777 if (!verify_xsrf_token(form_name)) {
778 goto output_page;
781 if (cgi_variable("Rewrite")) {
782 (void) rewritecfg_file();
783 return;
786 if (cgi_variable("GetWizardParams")){
787 (void) wizard_params_page();
788 return;
791 if (cgi_variable("Commit")){
792 SerType = atoi(cgi_variable_nonull("ServerType"));
793 winstype = atoi(cgi_variable_nonull("WINSType"));
794 have_home = lp_servicenumber(HOMES_NAME);
795 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
797 /* Plain text passwords are too badly broken - use encrypted passwords only */
798 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
800 switch ( SerType ){
801 case 0:
802 /* Stand-alone Server */
803 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
804 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
805 break;
806 case 1:
807 /* Domain Member */
808 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
809 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
810 break;
811 case 2:
812 /* Domain Controller */
813 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
814 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
815 break;
817 switch ( winstype ) {
818 case 0:
819 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
820 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
821 break;
822 case 1:
823 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
824 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
825 break;
826 case 2:
827 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
828 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
829 break;
832 /* Have to create Homes share? */
833 if ((HomeExpo == 1) && (have_home == -1)) {
834 const char *unix_share = HOMES_NAME;
836 load_config(False);
837 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
838 have_home = lp_servicenumber(HOMES_NAME);
839 lp_do_parameter( have_home, "read only", "No");
840 lp_do_parameter( have_home, "valid users", "%S");
841 lp_do_parameter( have_home, "browseable", "No");
842 commit_parameters(have_home);
843 save_reload(have_home);
846 /* Need to Delete Homes share? */
847 if ((HomeExpo == 0) && (have_home != -1)) {
848 lp_remove_service(have_home);
849 have_home = -1;
852 commit_parameters(GLOBAL_SECTION_SNUM);
853 save_reload(-1);
855 else
857 /* Now determine smb.conf WINS settings */
858 if (lp_wins_support())
859 winstype = 1;
860 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
861 winstype = 2;
863 /* Do we have a homes share? */
864 have_home = lp_servicenumber(HOMES_NAME);
866 if ((winstype == 2) && lp_wins_support())
867 winstype = 3;
869 role = lp_server_role();
871 output_page:
872 /* Here we go ... */
873 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
874 printf("<form method=post action=wizard>\n");
875 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
877 if (have_write_access) {
878 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
879 printf("%s", _("The same will happen if you press the commit button."));
880 printf("<br><br>\n");
881 printf("<center>");
882 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
883 printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
884 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
885 printf("</center>\n");
888 printf("<hr>");
889 printf("<center><table border=0>");
890 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
891 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
892 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
893 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
894 printf("</tr>\n");
895 if (role == ROLE_DOMAIN_BDC) {
896 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
898 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
899 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
900 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
901 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
902 printf("</tr>\n");
903 printf("<tr><td></td><td></td><td></td><td>%s&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
905 /* Print out the list of wins servers */
906 if(lp_wins_server_list()) {
907 int i;
908 const char **wins_servers = lp_wins_server_list();
909 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
912 printf("\"></td></tr>\n");
913 if (winstype == 3) {
914 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"));
915 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
917 printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
918 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
919 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
920 printf("<td></td></tr>\n");
922 /* Enable this when we are ready ....
923 * printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
924 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
925 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
926 * printf("<td></td></tr>\n");
929 printf("</table></center>");
930 printf("<hr>");
932 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
933 printf("</form>\n");
937 /****************************************************************************
938 display a globals editing page
939 ****************************************************************************/
940 static void globals_page(void)
942 unsigned int parm_filter = FLAG_BASIC;
943 int mode = 0;
944 const char form_name[] = "globals";
946 printf("<H2>%s</H2>\n", _("Global Parameters"));
948 if (!verify_xsrf_token(form_name)) {
949 goto output_page;
952 if (cgi_variable("Commit")) {
953 commit_parameters(GLOBAL_SECTION_SNUM);
954 save_reload(-1);
957 if ( cgi_variable("ViewMode") )
958 mode = atoi(cgi_variable_nonull("ViewMode"));
959 if ( cgi_variable("BasicMode"))
960 mode = 0;
961 if ( cgi_variable("AdvMode"))
962 mode = 1;
964 output_page:
965 printf("<form name=\"swatform\" method=post action=globals>\n");
966 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
968 ViewModeBoxes( mode );
969 switch ( mode ) {
970 case 0:
971 parm_filter = FLAG_BASIC;
972 break;
973 case 1:
974 parm_filter = FLAG_ADVANCED;
975 break;
977 printf("<br>\n");
978 if (have_write_access) {
979 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
980 _("Commit Changes"));
983 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
984 _("Reset Values"));
986 printf("<p>\n");
987 printf("<table>\n");
988 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
989 printf("</table>\n");
990 printf("</form>\n");
993 /****************************************************************************
994 display a shares editing page. share is in unix codepage,
995 ****************************************************************************/
996 static void shares_page(void)
998 const char *share = cgi_variable("share");
999 char *s;
1000 char *utf8_s;
1001 int snum = -1;
1002 int i;
1003 int mode = 0;
1004 unsigned int parm_filter = FLAG_BASIC;
1005 size_t converted_size;
1006 const char form_name[] = "shares";
1008 printf("<H2>%s</H2>\n", _("Share Parameters"));
1010 if (!verify_xsrf_token(form_name)) {
1011 goto output_page;
1014 if (share)
1015 snum = lp_servicenumber(share);
1018 if (cgi_variable("Commit") && snum >= 0) {
1019 commit_parameters(snum);
1020 save_reload(-1);
1021 snum = lp_servicenumber(share);
1024 if (cgi_variable("Delete") && snum >= 0) {
1025 lp_remove_service(snum);
1026 save_reload(-1);
1027 share = NULL;
1028 snum = -1;
1031 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1032 snum = lp_servicenumber(share);
1033 if (snum < 0) {
1034 load_config(False);
1035 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1036 snum = lp_servicenumber(share);
1037 save_reload(snum);
1038 snum = lp_servicenumber(share);
1042 if ( cgi_variable("ViewMode") )
1043 mode = atoi(cgi_variable_nonull("ViewMode"));
1044 if ( cgi_variable("BasicMode"))
1045 mode = 0;
1046 if ( cgi_variable("AdvMode"))
1047 mode = 1;
1049 output_page:
1050 printf("<FORM name=\"swatform\" method=post>\n");
1051 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1053 printf("<table>\n");
1055 ViewModeBoxes( mode );
1056 switch ( mode ) {
1057 case 0:
1058 parm_filter = FLAG_BASIC;
1059 break;
1060 case 1:
1061 parm_filter = FLAG_ADVANCED;
1062 break;
1064 printf("<br><tr>\n");
1065 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1066 printf("<td><select name=share>\n");
1067 if (snum < 0)
1068 printf("<option value=\" \"> \n");
1069 for (i=0;i<lp_numservices();i++) {
1070 s = lp_servicename(i);
1071 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
1072 push_utf8_talloc(talloc_tos(), &utf8_s, s, &converted_size);
1073 printf("<option %s value=\"%s\">%s\n",
1074 (share && strcmp(share,s)==0)?"SELECTED":"",
1075 utf8_s, utf8_s);
1076 TALLOC_FREE(utf8_s);
1079 printf("</select></td>\n");
1080 if (have_write_access) {
1081 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1083 printf("</tr>\n");
1084 printf("</table>");
1085 printf("<table>");
1086 if (have_write_access) {
1087 printf("<tr>\n");
1088 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1089 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1091 printf("</table>");
1094 if (snum >= 0) {
1095 if (have_write_access) {
1096 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1099 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1100 printf("<p>\n");
1103 if (snum >= 0) {
1104 printf("<table>\n");
1105 show_parameters(snum, 1, parm_filter, 0);
1106 printf("</table>\n");
1109 printf("</FORM>\n");
1112 /*************************************************************
1113 change a password either locally or remotely
1114 *************************************************************/
1115 static bool change_password(const char *remote_machine, const char *user_name,
1116 const char *old_passwd, const char *new_passwd,
1117 int local_flags)
1119 NTSTATUS ret;
1120 char *err_str = NULL;
1121 char *msg_str = NULL;
1123 if (demo_mode) {
1124 printf("%s\n<p>", _("password change in demo mode rejected"));
1125 return False;
1128 if (remote_machine != NULL) {
1129 ret = remote_password_change(remote_machine, user_name,
1130 old_passwd, new_passwd, &err_str);
1131 if (err_str != NULL)
1132 printf("%s\n<p>", err_str);
1133 SAFE_FREE(err_str);
1134 return NT_STATUS_IS_OK(ret);
1137 if(!initialize_password_db(True, NULL)) {
1138 printf("%s\n<p>", _("Can't setup password database vectors."));
1139 return False;
1142 ret = local_password_change(user_name, local_flags, new_passwd,
1143 &err_str, &msg_str);
1145 if(msg_str)
1146 printf("%s\n<p>", msg_str);
1147 if(err_str)
1148 printf("%s\n<p>", err_str);
1150 SAFE_FREE(msg_str);
1151 SAFE_FREE(err_str);
1152 return NT_STATUS_IS_OK(ret);
1155 /****************************************************************************
1156 do the stuff required to add or change a password
1157 ****************************************************************************/
1158 static void chg_passwd(void)
1160 const char *host;
1161 bool rslt;
1162 int local_flags = 0;
1164 /* Make sure users name has been specified */
1165 if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1166 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1167 return;
1171 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1172 * so if that's what we're doing, skip the rest of the checks
1174 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1177 * If current user is not root, make sure old password has been specified
1178 * If REMOTE change, even root must provide old password
1180 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1181 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1182 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1183 return;
1186 /* If changing a users password on a remote hosts we have to know what host */
1187 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1188 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1189 return;
1192 /* Make sure new passwords have been specified */
1193 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1194 (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1195 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1196 return;
1199 /* Make sure new passwords was typed correctly twice */
1200 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1201 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1202 return;
1206 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1207 host = cgi_variable(RHOST);
1208 } else if (am_root()) {
1209 host = NULL;
1210 } else {
1211 host = "127.0.0.1";
1215 * Set up the local flags.
1218 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1219 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1220 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1221 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1222 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1223 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1226 rslt = change_password(host,
1227 cgi_variable_nonull(SWAT_USER),
1228 cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1229 local_flags);
1231 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1232 printf("<p>");
1233 if (rslt == True) {
1234 printf("%s\n", _(" The passwd has been changed."));
1235 } else {
1236 printf("%s\n", _(" The passwd for has NOT been changed."));
1240 return;
1243 /****************************************************************************
1244 display a password editing page
1245 ****************************************************************************/
1246 static void passwd_page(void)
1248 const char *new_name = cgi_user_name();
1249 const char passwd_form[] = "passwd";
1250 const char rpasswd_form[] = "rpasswd";
1252 if (!new_name) new_name = "";
1254 printf("<H2>%s</H2>\n", _("Server Password Management"));
1256 printf("<FORM name=\"swatform\" method=post>\n");
1257 print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form);
1259 printf("<table>\n");
1262 * Create all the dialog boxes for data collection
1264 printf("<tr><td> %s : </td>\n", _("User Name"));
1265 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1266 if (!am_root()) {
1267 printf("<tr><td> %s : </td>\n", _("Old Password"));
1268 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1270 printf("<tr><td> %s : </td>\n", _("New Password"));
1271 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1272 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1273 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1274 printf("</table>\n");
1277 * Create all the control buttons for requesting action
1279 printf("<input type=submit name=%s value=\"%s\">\n",
1280 CHG_S_PASSWD_FLAG, _("Change Password"));
1281 if (demo_mode || am_root()) {
1282 printf("<input type=submit name=%s value=\"%s\">\n",
1283 ADD_USER_FLAG, _("Add New User"));
1284 printf("<input type=submit name=%s value=\"%s\">\n",
1285 DELETE_USER_FLAG, _("Delete User"));
1286 printf("<input type=submit name=%s value=\"%s\">\n",
1287 DISABLE_USER_FLAG, _("Disable User"));
1288 printf("<input type=submit name=%s value=\"%s\">\n",
1289 ENABLE_USER_FLAG, _("Enable User"));
1291 printf("<p></FORM>\n");
1294 * Do some work if change, add, disable or enable was
1295 * requested. It could be this is the first time through this
1296 * code, so there isn't anything to do. */
1297 if (verify_xsrf_token(passwd_form) &&
1298 ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1299 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG)))) {
1300 chg_passwd();
1303 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1305 printf("<FORM name=\"swatform\" method=post>\n");
1306 print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form);
1308 printf("<table>\n");
1311 * Create all the dialog boxes for data collection
1313 printf("<tr><td> %s : </td>\n", _("User Name"));
1314 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1315 printf("<tr><td> %s : </td>\n", _("Old Password"));
1316 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1317 printf("<tr><td> %s : </td>\n", _("New Password"));
1318 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1319 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1320 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1321 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1322 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1324 printf("</table>");
1327 * Create all the control buttons for requesting action
1329 printf("<input type=submit name=%s value=\"%s\">",
1330 CHG_R_PASSWD_FLAG, _("Change Password"));
1332 printf("<p></FORM>\n");
1335 * Do some work if a request has been made to change the
1336 * password somewhere other than the server. It could be this
1337 * is the first time through this code, so there isn't
1338 * anything to do. */
1339 if (verify_xsrf_token(passwd_form) && cgi_variable(CHG_R_PASSWD_FLAG)) {
1340 chg_passwd();
1345 /****************************************************************************
1346 display a printers editing page
1347 ****************************************************************************/
1348 static void printers_page(void)
1350 const char *share = cgi_variable("share");
1351 char *s;
1352 int snum=-1;
1353 int i;
1354 int mode = 0;
1355 unsigned int parm_filter = FLAG_BASIC;
1356 const char form_name[] = "printers";
1358 if (!verify_xsrf_token(form_name)) {
1359 goto output_page;
1362 if (share)
1363 snum = lp_servicenumber(share);
1365 if (cgi_variable("Commit") && snum >= 0) {
1366 commit_parameters(snum);
1367 if (snum >= iNumNonAutoPrintServices)
1368 save_reload(snum);
1369 else
1370 save_reload(-1);
1371 snum = lp_servicenumber(share);
1374 if (cgi_variable("Delete") && snum >= 0) {
1375 lp_remove_service(snum);
1376 save_reload(-1);
1377 share = NULL;
1378 snum = -1;
1381 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1382 snum = lp_servicenumber(share);
1383 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1384 load_config(False);
1385 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1386 snum = lp_servicenumber(share);
1387 lp_do_parameter(snum, "print ok", "Yes");
1388 save_reload(snum);
1389 snum = lp_servicenumber(share);
1393 if ( cgi_variable("ViewMode") )
1394 mode = atoi(cgi_variable_nonull("ViewMode"));
1395 if ( cgi_variable("BasicMode"))
1396 mode = 0;
1397 if ( cgi_variable("AdvMode"))
1398 mode = 1;
1400 output_page:
1401 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1403 printf("<H3>%s</H3>\n", _("Important Note:"));
1404 printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1405 printf("%s",_("are autoloaded printers from "));
1406 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1407 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1410 printf("<FORM name=\"swatform\" method=post>\n");
1411 print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
1413 ViewModeBoxes( mode );
1414 switch ( mode ) {
1415 case 0:
1416 parm_filter = FLAG_BASIC;
1417 break;
1418 case 1:
1419 parm_filter = FLAG_ADVANCED;
1420 break;
1422 printf("<table>\n");
1423 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1424 printf("<td><select name=\"share\">\n");
1425 if (snum < 0 || !lp_print_ok(snum))
1426 printf("<option value=\" \"> \n");
1427 for (i=0;i<lp_numservices();i++) {
1428 s = lp_servicename(i);
1429 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1430 if (i >= iNumNonAutoPrintServices)
1431 printf("<option %s value=\"%s\">[*]%s\n",
1432 (share && strcmp(share,s)==0)?"SELECTED":"",
1433 s, s);
1434 else
1435 printf("<option %s value=\"%s\">%s\n",
1436 (share && strcmp(share,s)==0)?"SELECTED":"",
1437 s, s);
1440 printf("</select></td>");
1441 if (have_write_access) {
1442 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1444 printf("</tr>");
1445 printf("</table>\n");
1447 if (have_write_access) {
1448 printf("<table>\n");
1449 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1450 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1451 printf("</table>");
1455 if (snum >= 0) {
1456 if (have_write_access) {
1457 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1459 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1460 printf("<p>\n");
1463 if (snum >= 0) {
1464 printf("<table>\n");
1465 show_parameters(snum, 1, parm_filter, 1);
1466 printf("</table>\n");
1468 printf("</FORM>\n");
1472 when the _() translation macro is used there is no obvious place to free
1473 the resulting string and there is no easy way to give a static pointer.
1474 All we can do is rotate between some static buffers and hope a single d_printf()
1475 doesn't have more calls to _() than the number of buffers
1478 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1480 const char *msgstr;
1481 const char *ret;
1483 msgstr = lang_msg(msgid);
1484 if (!msgstr) {
1485 return msgid;
1488 ret = talloc_strdup(ctx, msgstr);
1490 lang_msg_free(msgstr);
1491 if (!ret) {
1492 return msgid;
1495 return ret;
1499 * main function for SWAT.
1501 int main(int argc, char *argv[])
1503 const char *page;
1504 poptContext pc;
1505 struct poptOption long_options[] = {
1506 POPT_AUTOHELP
1507 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1508 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1509 POPT_COMMON_SAMBA
1510 POPT_TABLEEND
1512 TALLOC_CTX *frame = talloc_stackframe();
1514 fault_setup(NULL);
1515 umask(S_IWGRP | S_IWOTH);
1517 #if defined(HAVE_SET_AUTH_PARAMETERS)
1518 set_auth_parameters(argc, argv);
1519 #endif /* HAVE_SET_AUTH_PARAMETERS */
1521 /* just in case it goes wild ... */
1522 alarm(300);
1524 setlinebuf(stdout);
1526 /* we don't want any SIGPIPE messages */
1527 BlockSignals(True,SIGPIPE);
1529 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1530 if (!dbf) dbf = x_stderr;
1532 /* we don't want stderr screwing us up */
1533 close(2);
1534 open("/dev/null", O_WRONLY);
1536 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1538 /* Parse command line options */
1540 while(poptGetNextOpt(pc) != -1) { }
1542 poptFreeContext(pc);
1544 load_case_tables();
1546 setup_logging(argv[0],False);
1547 load_config(True);
1548 load_interfaces();
1549 iNumNonAutoPrintServices = lp_numservices();
1550 pcap_cache_reload(&load_printers);
1552 cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1554 print_header();
1556 cgi_load_variables();
1558 if (!file_exist(get_dyn_CONFIGFILE())) {
1559 have_read_access = True;
1560 have_write_access = True;
1561 } else {
1562 /* check if the authenticated user has write access - if not then
1563 don't show write options */
1564 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1566 /* if the user doesn't have read access to smb.conf then
1567 don't let them view it */
1568 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1571 show_main_buttons();
1573 page = cgi_pathinfo();
1575 /* Root gets full functionality */
1576 if (have_read_access && strcmp(page, "globals")==0) {
1577 globals_page();
1578 } else if (have_read_access && strcmp(page,"shares")==0) {
1579 shares_page();
1580 } else if (have_read_access && strcmp(page,"printers")==0) {
1581 printers_page();
1582 } else if (have_read_access && strcmp(page,"status")==0) {
1583 status_page();
1584 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1585 viewconfig_page();
1586 } else if (strcmp(page,"passwd")==0) {
1587 passwd_page();
1588 } else if (have_read_access && strcmp(page,"wizard")==0) {
1589 wizard_page();
1590 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1591 wizard_params_page();
1592 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1593 rewritecfg_file();
1594 } else {
1595 welcome_page();
1598 print_footer();
1600 TALLOC_FREE(frame);
1601 return 0;
1604 /** @} **/