b46aa261ec2c547f9e101eb28a64d04887f49c09
[samba.git] / source3 / web / swat.c
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
7    
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.
12    
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.
17    
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/>.
20 */
21
22 /**
23  * @defgroup swat SWAT - Samba Web Administration Tool
24  * @{ 
25  * @file swat.c
26  *
27  * @brief Samba Web Administration Tool.
28  **/
29
30 #include "includes.h"
31 #include "web/swat_proto.h"
32 #include "../lib/crypto/md5.h"
33
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;
39
40 /*
41  * Password Management Globals
42  */
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
56 #define _(x) lang_msg_rotate(talloc_tos(),x)
57
58 /****************************************************************************
59 ****************************************************************************/
60 static int enum_index(int value, const struct enum_list *enumlist)
61 {
62         int i;
63         for (i=0;enumlist[i].name;i++)
64                 if (value == enumlist[i].value) break;
65         return(i);
66 }
67
68 static char *fix_backslash(const char *str)
69 {
70         static char newstring[1024];
71         char *p = newstring;
72
73         while (*str) {
74                 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
75                 else *p++ = *str;
76                 ++str;
77         }
78         *p = '\0';
79         return newstring;
80 }
81
82 static const char *fix_quotes(TALLOC_CTX *ctx, const char *str)
83 {
84         char *newstring = NULL;
85         char *p = NULL;
86         size_t newstring_len;
87         int quote_len = strlen("&quot;");
88
89         /* Count the number of quotes. */
90         newstring_len = 1;
91         p = (char *) str;
92         while (*p) {
93                 if ( *p == '\"') {
94                         newstring_len += quote_len;
95                 } else {
96                         newstring_len++;
97                 }
98                 ++p;
99         }
100         newstring = TALLOC_ARRAY(ctx, char, newstring_len);
101         if (!newstring) {
102                 return "";
103         }
104         for (p = newstring; *str; str++) {
105                 if ( *str == '\"') {
106                         strncpy( p, "&quot;", quote_len);
107                         p += quote_len;
108                 } else {
109                         *p++ = *str;
110                 }
111         }
112         *p = '\0';
113         return newstring;
114 }
115
116 static char *stripspaceupper(const char *str)
117 {
118         static char newstring[1024];
119         char *p = newstring;
120
121         while (*str) {
122                 if (*str != ' ') *p++ = toupper_ascii(*str);
123                 ++str;
124         }
125         *p = '\0';
126         return newstring;
127 }
128
129 static char *make_parm_name(const char *label)
130 {
131         static char parmname[1024];
132         char *p = parmname;
133
134         while (*label) {
135                 if (*label == ' ') *p++ = '_';
136                 else *p++ = *label;
137                 ++label;
138         }
139         *p = '\0';
140         return parmname;
141 }
142
143 void get_xsrf_token(const char *username, const char *pass,
144                     const char *formname, char token_str[33])
145 {
146         struct MD5Context md5_ctx;
147         uint8_t token[16];
148         int i;
149
150         token_str[0] = '\0';
151         ZERO_STRUCT(md5_ctx);
152         MD5Init(&md5_ctx);
153
154         MD5Update(&md5_ctx, (uint8_t *)formname, strlen(formname));
155         if (username != NULL) {
156                 MD5Update(&md5_ctx, (uint8_t *)username, strlen(username));
157         }
158         if (pass != NULL) {
159                 MD5Update(&md5_ctx, (uint8_t *)pass, strlen(pass));
160         }
161
162         MD5Final(token, &md5_ctx);
163
164         for(i = 0; i < sizeof(token); i++) {
165                 char tmp[3];
166
167                 snprintf(tmp, sizeof(tmp), "%02x", token[i]);
168                 strncat(token_str, tmp, sizeof(tmp));
169         }
170 }
171
172 void print_xsrf_token(const char *username, const char *pass,
173                       const char *formname)
174 {
175         char token[33];
176
177         get_xsrf_token(username, pass, formname, token);
178         printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
179                XSRF_TOKEN, token);
180
181 }
182
183 bool verify_xsrf_token(const char *formname)
184 {
185         char expected[33];
186         const char *username = cgi_user_name();
187         const char *pass = cgi_user_pass();
188         const char *token = cgi_variable_nonull(XSRF_TOKEN);
189
190         get_xsrf_token(username, pass, formname, expected);
191         return (strncmp(expected, token, sizeof(expected)) == 0);
192 }
193
194
195 /****************************************************************************
196   include a lump of html in a page 
197 ****************************************************************************/
198 static int include_html(const char *fname)
199 {
200         int fd;
201         char buf[1024];
202         int ret;
203
204         fd = web_open(fname, O_RDONLY, 0);
205
206         if (fd == -1) {
207                 printf(_("ERROR: Can't open %s"), fname);
208                 printf("\n");
209                 return 0;
210         }
211
212         while ((ret = read(fd, buf, sizeof(buf))) > 0) {
213                 if (write(1, buf, ret) == -1) {
214                         break;
215                 }
216         }
217
218         close(fd);
219         return 1;
220 }
221
222 /****************************************************************************
223   start the page with standard stuff 
224 ****************************************************************************/
225 static void print_header(void)
226 {
227         if (!cgi_waspost()) {
228                 printf("Expires: 0\r\n");
229         }
230         printf("Content-type: text/html\r\n\r\n");
231
232         if (!include_html("include/header.html")) {
233                 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
234                 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
235         }
236 }
237
238 /* *******************************************************************
239    show parameter label with translated name in the following form
240    because showing original and translated label in one line looks
241    too long, and showing translated label only is unusable for
242    heavy users.
243    -------------------------------
244    HELP       security   [combo box][button]
245    SECURITY
246    -------------------------------
247    (capital words are translated by gettext.)
248    if no translation is available, then same form as original is
249    used.
250    "i18n_translated_parm" class is used to change the color of the
251    translated parameter with CSS.
252    **************************************************************** */
253 static const char *get_parm_translated(TALLOC_CTX *ctx,
254         const char* pAnchor, const char* pHelp, const char* pLabel)
255 {
256         const char *pTranslated = _(pLabel);
257         char *output;
258         if(strcmp(pLabel, pTranslated) != 0) {
259                 output = talloc_asprintf(ctx,
260                   "<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>",
261                    pAnchor, pHelp, pLabel, pTranslated);
262                 return output;
263         }
264         output = talloc_asprintf(ctx,
265           "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
266           pAnchor, pHelp, pLabel);
267         return output;
268 }
269 /****************************************************************************
270  finish off the page
271 ****************************************************************************/
272 static void print_footer(void)
273 {
274         if (!include_html("include/footer.html")) {
275                 printf("\n</BODY>\n</HTML>\n");
276         }
277 }
278
279 /****************************************************************************
280   display one editable parameter in a form
281 ****************************************************************************/
282 static void show_parameter(int snum, struct parm_struct *parm)
283 {
284         int i;
285         void *ptr = parm->ptr;
286         char *utf8_s1, *utf8_s2;
287         size_t converted_size;
288         TALLOC_CTX *ctx = talloc_stackframe();
289
290         if (parm->p_class == P_LOCAL && snum >= 0) {
291                 ptr = lp_local_ptr_by_snum(snum, ptr);
292         }
293
294         printf("<tr><td>%s</td><td>", get_parm_translated(ctx,
295                                 stripspaceupper(parm->label), _("Help"), parm->label));
296         switch (parm->type) {
297         case P_CHAR:
298                 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
299                        make_parm_name(parm->label), *(char *)ptr);
300                 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
301                         _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
302                 break;
303
304         case P_LIST:
305                 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
306                         make_parm_name(parm->label));
307                 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
308                         char **list = *(char ***)ptr;
309                         for (;*list;list++) {
310                                 /* enclose in HTML encoded quotes if the string contains a space */
311                                 if ( strchr_m(*list, ' ') ) {
312                                         push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
313                                         push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
314                                         printf("&quot;%s&quot;%s", utf8_s1, utf8_s2);
315                                 } else {
316                                         push_utf8_talloc(talloc_tos(), &utf8_s1, *list, &converted_size);
317                                         push_utf8_talloc(talloc_tos(), &utf8_s2, ((*(list+1))?", ":""), &converted_size);
318                                         printf("%s%s", utf8_s1, utf8_s2);
319                                 }
320                                 TALLOC_FREE(utf8_s1);
321                                 TALLOC_FREE(utf8_s2);
322                         }
323                 }
324                 printf("\">");
325                 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
326                         _("Set Default"), make_parm_name(parm->label));
327                 if (parm->def.lvalue) {
328                         char **list = (char **)(parm->def.lvalue);
329                         for (; *list; list++) {
330                                 /* enclose in HTML encoded quotes if the string contains a space */
331                                 if ( strchr_m(*list, ' ') )
332                                         printf("&quot;%s&quot;%s", *list, ((*(list+1))?", ":""));
333                                 else
334                                         printf("%s%s", *list, ((*(list+1))?", ":""));
335                         }
336                 }
337                 printf("\'\">");
338                 break;
339
340         case P_STRING:
341         case P_USTRING:
342                 push_utf8_talloc(talloc_tos(), &utf8_s1, *(char **)ptr, &converted_size);
343                 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
344                        make_parm_name(parm->label), fix_quotes(ctx, utf8_s1));
345                 TALLOC_FREE(utf8_s1);
346                 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
347                         _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
348                 break;
349
350         case P_BOOL:
351                 printf("<select name=\"parm_%s\">",make_parm_name(parm->label)); 
352                 printf("<option %s>Yes", (*(bool *)ptr)?"selected":"");
353                 printf("<option %s>No", (*(bool *)ptr)?"":"selected");
354                 printf("</select>");
355                 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
356                         _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?0:1);
357                 break;
358
359         case P_BOOLREV:
360                 printf("<select name=\"parm_%s\">",make_parm_name(parm->label)); 
361                 printf("<option %s>Yes", (*(bool *)ptr)?"":"selected");
362                 printf("<option %s>No", (*(bool *)ptr)?"selected":"");
363                 printf("</select>");
364                 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
365                         _("Set Default"), make_parm_name(parm->label),(bool)(parm->def.bvalue)?1:0);
366                 break;
367
368         case P_INTEGER:
369                 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
370                 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
371                         _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
372                 break;
373
374         case P_OCTAL: {
375                 char *o;
376                 o = octal_string(*(int *)ptr);
377                 printf("<input type=text size=8 name=\"parm_%s\" value=%s>",
378                        make_parm_name(parm->label), o);
379                 TALLOC_FREE(o);
380                 o = octal_string((int)(parm->def.ivalue));
381                 printf("<input type=button value=\"%s\" "
382                        "onClick=\"swatform.parm_%s.value=\'%s\'\">",
383                        _("Set Default"), make_parm_name(parm->label), o);
384                 TALLOC_FREE(o);
385                 break;
386         }
387
388         case P_ENUM:
389                 printf("<select name=\"parm_%s\">",make_parm_name(parm->label)); 
390                 for (i=0;parm->enum_list[i].name;i++) {
391                         if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
392                                 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
393                         }
394                 }
395                 printf("</select>");
396                 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
397                         _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
398                 break;
399         case P_SEP:
400                 break;
401         }
402         printf("</td></tr>\n");
403         TALLOC_FREE(ctx);
404 }
405
406 /****************************************************************************
407   display a set of parameters for a service 
408 ****************************************************************************/
409 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
410 {
411         int i = 0;
412         struct parm_struct *parm;
413         const char *heading = NULL;
414         const char *last_heading = NULL;
415
416         while ((parm = lp_next_parameter(snum, &i, allparameters))) {
417                 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
418                         continue;
419                 if (parm->p_class == P_SEPARATOR) {
420                         heading = parm->label;
421                         continue;
422                 }
423                 if (parm->flags & FLAG_HIDE) continue;
424                 if (snum >= 0) {
425                         if (printers & !(parm->flags & FLAG_PRINT)) continue;
426                         if (!printers & !(parm->flags & FLAG_SHARE)) continue;
427                 }
428
429                 if (!( parm_filter & FLAG_ADVANCED )) {
430                         if (!(parm->flags & FLAG_BASIC)) {
431                                         void *ptr = parm->ptr;
432
433                                 if (parm->p_class == P_LOCAL && snum >= 0) {
434                                         ptr = lp_local_ptr_by_snum(snum, ptr);
435                                 }
436
437                                 switch (parm->type) {
438                                 case P_CHAR:
439                                         if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
440                                         break;
441
442                                 case P_LIST:
443                                         if (!str_list_equal(*(const char ***)ptr, 
444                                                             (const char **)(parm->def.lvalue))) continue;
445                                         break;
446
447                                 case P_STRING:
448                                 case P_USTRING:
449                                         if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
450                                         break;
451
452                                 case P_BOOL:
453                                 case P_BOOLREV:
454                                         if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
455                                         break;
456
457                                 case P_INTEGER:
458                                 case P_OCTAL:
459                                         if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
460                                         break;
461
462
463                                 case P_ENUM:
464                                         if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
465                                         break;
466                                 case P_SEP:
467                                         continue;
468                                         }
469                         }
470                         if (printers && !(parm->flags & FLAG_PRINT)) continue;
471                 }
472
473                 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
474                 
475                 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
476                 
477                 if (heading && heading != last_heading) {
478                         printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
479                         last_heading = heading;
480                 }
481                 show_parameter(snum, parm);
482         }
483 }
484
485 /****************************************************************************
486   load the smb.conf file into loadparm.
487 ****************************************************************************/
488 static bool load_config(bool save_def)
489 {
490         return lp_load(get_dyn_CONFIGFILE(),False,save_def,False,True);
491 }
492
493 /****************************************************************************
494   write a config file 
495 ****************************************************************************/
496 static void write_config(FILE *f, bool show_defaults)
497 {
498         TALLOC_CTX *ctx = talloc_stackframe();
499
500         fprintf(f, "# Samba config file created using SWAT\n");
501         fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
502         fprintf(f, "# Date: %s\n\n", current_timestring(ctx, False));
503         
504         lp_dump(f, show_defaults, iNumNonAutoPrintServices);
505
506         TALLOC_FREE(ctx);
507 }
508
509 /****************************************************************************
510   save and reload the smb.conf config file 
511 ****************************************************************************/
512 static int save_reload(int snum)
513 {
514         FILE *f;
515         struct stat st;
516
517         f = sys_fopen(get_dyn_CONFIGFILE(),"w");
518         if (!f) {
519                 printf(_("failed to open %s for writing"), get_dyn_CONFIGFILE());
520                 printf("\n");
521                 return 0;
522         }
523
524         /* just in case they have used the buggy xinetd to create the file */
525         if (fstat(fileno(f), &st) == 0 &&
526             (st.st_mode & S_IWOTH)) {
527 #if defined HAVE_FCHMOD
528                 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
529 #else
530                 chmod(get_dyn_CONFIGFILE(), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
531 #endif
532         }
533
534         write_config(f, False);
535         if (snum >= 0)
536                 lp_dump_one(f, False, snum);
537         fclose(f);
538
539         lp_kill_all_services();
540
541         if (!load_config(False)) {
542                 printf(_("Can't reload %s"), get_dyn_CONFIGFILE());
543                 printf("\n");
544                 return 0;
545         }
546         iNumNonAutoPrintServices = lp_numservices();
547         pcap_cache_reload(&load_printers);
548
549         return 1;
550 }
551
552 /****************************************************************************
553   commit one parameter 
554 ****************************************************************************/
555 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
556 {
557         int i;
558         char *s;
559
560         if (snum < 0 && parm->p_class == P_LOCAL) {
561                 /* this handles the case where we are changing a local
562                    variable globally. We need to change the parameter in 
563                    all shares where it is currently set to the default */
564                 for (i=0;i<lp_numservices();i++) {
565                         s = lp_servicename(i);
566                         if (s && (*s) && lp_is_default(i, parm)) {
567                                 lp_do_parameter(i, parm->label, v);
568                         }
569                 }
570         }
571
572         lp_do_parameter(snum, parm->label, v);
573 }
574
575 /****************************************************************************
576   commit a set of parameters for a service 
577 ****************************************************************************/
578 static void commit_parameters(int snum)
579 {
580         int i = 0;
581         struct parm_struct *parm;
582         char *label;
583         const char *v;
584
585         while ((parm = lp_next_parameter(snum, &i, 1))) {
586                 if (asprintf(&label, "parm_%s", make_parm_name(parm->label)) > 0) {
587                         if ((v = cgi_variable(label)) != NULL) {
588                                 if (parm->flags & FLAG_HIDE)
589                                         continue;
590                                 commit_parameter(snum, parm, v);
591                         }
592                         SAFE_FREE(label);
593                 }
594         }
595 }
596
597 /****************************************************************************
598   spit out the html for a link with an image 
599 ****************************************************************************/
600 static void image_link(const char *name, const char *hlink, const char *src)
601 {
602         printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n", 
603                cgi_baseurl(), hlink, src, name);
604 }
605
606 /****************************************************************************
607   display the main navigation controls at the top of each page along
608   with a title 
609 ****************************************************************************/
610 static void show_main_buttons(void)
611 {
612         char *p;
613         
614         if ((p = cgi_user_name()) && strcmp(p, "root")) {
615                 printf(_("Logged in as <b>%s</b>"), p);
616                 printf("<p>\n");
617         }
618
619         image_link(_("Home"), "", "images/home.gif");
620         if (have_write_access) {
621                 image_link(_("Globals"), "globals", "images/globals.gif");
622                 image_link(_("Shares"), "shares", "images/shares.gif");
623                 image_link(_("Printers"), "printers", "images/printers.gif");
624                 image_link(_("Wizard"), "wizard", "images/wizard.gif");
625         }
626    /* root always gets all buttons, otherwise look for -P */
627         if ( have_write_access || (!passwd_only && have_read_access) ) {
628                 image_link(_("Status"), "status", "images/status.gif");
629                 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
630         }
631         image_link(_("Password Management"), "passwd", "images/passwd.gif");
632
633         printf("<HR>\n");
634 }
635
636 /****************************************************************************
637  * Handle Display/Edit Mode CGI
638  ****************************************************************************/
639 static void ViewModeBoxes(int mode)
640 {
641         printf("<p>%s:&nbsp;\n", _("Current View Is"));
642         printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
643         printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
644         printf("<br>%s:&nbsp;\n", _("Change View To"));
645         printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
646         printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
647         printf("</p><br>\n");
648 }
649
650 /****************************************************************************
651   display a welcome page  
652 ****************************************************************************/
653 static void welcome_page(void)
654 {
655         if (file_exist("help/welcome.html")) {
656                 include_html("help/welcome.html");
657         } else {
658                 include_html("help/welcome-no-samba-doc.html");
659         }
660 }
661
662 /****************************************************************************
663   display the current smb.conf  
664 ****************************************************************************/
665 static void viewconfig_page(void)
666 {
667         int full_view=0;
668         const char form_name[] = "viewconfig";
669
670         if (!verify_xsrf_token(form_name)) {
671                 goto output_page;
672         }
673
674         if (cgi_variable("full_view")) {
675                 full_view = 1;
676         }
677
678 output_page:
679         printf("<H2>%s</H2>\n", _("Current Config"));
680         printf("<form method=post>\n");
681         print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
682
683         if (full_view) {
684                 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
685         } else {
686                 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
687         }
688
689         printf("<p><pre>");
690         write_config(stdout, full_view);
691         printf("</pre>");
692         printf("</form>\n");
693 }
694
695 /****************************************************************************
696   second screen of the wizard ... Fetch Configuration Parameters
697 ****************************************************************************/
698 static void wizard_params_page(void)
699 {
700         unsigned int parm_filter = FLAG_WIZARD;
701         const char form_name[] = "wizard_params";
702
703         /* Here we first set and commit all the parameters that were selected
704            in the previous screen. */
705
706         printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
707
708         if (!verify_xsrf_token(form_name)) {
709                 goto output_page;
710         }
711
712         if (cgi_variable("Commit")) {
713                 commit_parameters(GLOBAL_SECTION_SNUM);
714                 save_reload(-1);
715         }
716
717 output_page:
718         printf("<form name=\"swatform\" method=post action=wizard_params>\n");
719         print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
720
721         if (have_write_access) {
722                 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
723         }
724
725         printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
726         printf("<p>\n");
727         
728         printf("<table>\n");
729         show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
730         printf("</table>\n");
731         printf("</form>\n");
732 }
733
734 /****************************************************************************
735   Utility to just rewrite the smb.conf file - effectively just cleans it up
736 ****************************************************************************/
737 static void rewritecfg_file(void)
738 {
739         commit_parameters(GLOBAL_SECTION_SNUM);
740         save_reload(-1);
741         printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
742 }
743
744 /****************************************************************************
745   wizard to create/modify the smb.conf file
746 ****************************************************************************/
747 static void wizard_page(void)
748 {
749         /* Set some variables to collect data from smb.conf */
750         int role = 0;
751         int winstype = 0;
752         int have_home = -1;
753         int HomeExpo = 0;
754         int SerType = 0;
755         const char form_name[] = "wizard";
756
757         if (!verify_xsrf_token(form_name)) {
758                 goto output_page;
759         }
760
761         if (cgi_variable("Rewrite")) {
762                 (void) rewritecfg_file();
763                 return;
764         }
765
766         if (cgi_variable("GetWizardParams")){
767                 (void) wizard_params_page();
768                 return;
769         }
770
771         if (cgi_variable("Commit")){
772                 SerType = atoi(cgi_variable_nonull("ServerType"));
773                 winstype = atoi(cgi_variable_nonull("WINSType"));
774                 have_home = lp_servicenumber(HOMES_NAME);
775                 HomeExpo = atoi(cgi_variable_nonull("HomeExpo"));
776
777                 /* Plain text passwords are too badly broken - use encrypted passwords only */
778                 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
779                 
780                 switch ( SerType ){
781                         case 0:
782                                 /* Stand-alone Server */
783                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
784                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
785                                 break;
786                         case 1:
787                                 /* Domain Member */
788                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
789                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
790                                 break;
791                         case 2:
792                                 /* Domain Controller */
793                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
794                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
795                                 break;
796                 }
797                 switch ( winstype ) {
798                         case 0:
799                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
800                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
801                                 break;
802                         case 1:
803                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
804                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
805                                 break;
806                         case 2:
807                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
808                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable_nonull("WINSAddr"));
809                                 break;
810                 }
811
812                 /* Have to create Homes share? */
813                 if ((HomeExpo == 1) && (have_home == -1)) {
814                         const char *unix_share = HOMES_NAME;
815
816                         load_config(False);
817                         lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
818                         have_home = lp_servicenumber(HOMES_NAME);
819                         lp_do_parameter( have_home, "read only", "No");
820                         lp_do_parameter( have_home, "valid users", "%S");
821                         lp_do_parameter( have_home, "browseable", "No");
822                         commit_parameters(have_home);
823                         save_reload(have_home);
824                 }
825
826                 /* Need to Delete Homes share? */
827                 if ((HomeExpo == 0) && (have_home != -1)) {
828                         lp_remove_service(have_home);
829                         have_home = -1;
830                 }
831
832                 commit_parameters(GLOBAL_SECTION_SNUM);
833                 save_reload(-1);
834         }
835         else
836         {
837                 /* Now determine smb.conf WINS settings */
838                 if (lp_wins_support())
839                         winstype = 1;
840                 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
841                         winstype = 2;
842
843                 /* Do we have a homes share? */
844                 have_home = lp_servicenumber(HOMES_NAME);
845         }
846         if ((winstype == 2) && lp_wins_support())
847                 winstype = 3;
848
849         role = lp_server_role();
850
851 output_page:
852         /* Here we go ... */
853         printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
854         printf("<form method=post action=wizard>\n");
855         print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
856
857         if (have_write_access) {
858                 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
859                 printf("%s", _("The same will happen if you press the commit button."));
860                 printf("<br><br>\n");
861                 printf("<center>");
862                 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
863                 printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
864                 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
865                 printf("</center>\n");
866         }
867
868         printf("<hr>");
869         printf("<center><table border=0>");
870         printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
871         printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
872         printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member")); 
873         printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
874         printf("</tr>\n");
875         if (role == ROLE_DOMAIN_BDC) {
876                 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
877         }
878         printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
879         printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
880         printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
881         printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
882         printf("</tr>\n");
883         printf("<tr><td></td><td></td><td></td><td>%s&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
884
885         /* Print out the list of wins servers */
886         if(lp_wins_server_list()) {
887                 int i;
888                 const char **wins_servers = lp_wins_server_list();
889                 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
890         }
891         
892         printf("\"></td></tr>\n");
893         if (winstype == 3) {
894                 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"));
895                 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
896         }
897         printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
898         printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
899         printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
900         printf("<td></td></tr>\n");
901         
902         /* Enable this when we are ready ....
903          * printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
904          * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
905          * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
906          * printf("<td></td></tr>\n");
907          */
908         
909         printf("</table></center>");
910         printf("<hr>");
911
912         printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
913         printf("</form>\n");
914 }
915
916
917 /****************************************************************************
918   display a globals editing page  
919 ****************************************************************************/
920 static void globals_page(void)
921 {
922         unsigned int parm_filter = FLAG_BASIC;
923         int mode = 0;
924
925         printf("<H2>%s</H2>\n", _("Global Parameters"));
926
927         if (cgi_variable("Commit")) {
928                 commit_parameters(GLOBAL_SECTION_SNUM);
929                 save_reload(-1);
930         }
931
932         if ( cgi_variable("ViewMode") )
933                 mode = atoi(cgi_variable_nonull("ViewMode"));
934         if ( cgi_variable("BasicMode"))
935                 mode = 0;
936         if ( cgi_variable("AdvMode"))
937                 mode = 1;
938
939         printf("<form name=\"swatform\" method=post action=globals>\n");
940
941         ViewModeBoxes( mode );
942         switch ( mode ) {
943                 case 0:
944                         parm_filter = FLAG_BASIC;
945                         break;
946                 case 1:
947                         parm_filter = FLAG_ADVANCED;
948                         break;
949         }
950         printf("<br>\n");
951         if (have_write_access) {
952                 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
953                         _("Commit Changes"));
954         }
955
956         printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", 
957                  _("Reset Values"));
958
959         printf("<p>\n");
960         printf("<table>\n");
961         show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
962         printf("</table>\n");
963         printf("</form>\n");
964 }
965
966 /****************************************************************************
967   display a shares editing page. share is in unix codepage, 
968 ****************************************************************************/
969 static void shares_page(void)
970 {
971         const char *share = cgi_variable("share");
972         char *s;
973         char *utf8_s;
974         int snum = -1;
975         int i;
976         int mode = 0;
977         unsigned int parm_filter = FLAG_BASIC;
978         size_t converted_size;
979
980         if (share)
981                 snum = lp_servicenumber(share);
982
983         printf("<H2>%s</H2>\n", _("Share Parameters"));
984
985         if (cgi_variable("Commit") && snum >= 0) {
986                 commit_parameters(snum);
987                 save_reload(-1);
988                 snum = lp_servicenumber(share);
989         }
990
991         if (cgi_variable("Delete") && snum >= 0) {
992                 lp_remove_service(snum);
993                 save_reload(-1);
994                 share = NULL;
995                 snum = -1;
996         }
997
998         if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
999                 snum = lp_servicenumber(share);
1000                 if (snum < 0) {
1001                         load_config(False);
1002                         lp_copy_service(GLOBAL_SECTION_SNUM, share);
1003                         snum = lp_servicenumber(share);
1004                         save_reload(snum);
1005                         snum = lp_servicenumber(share);
1006                 }
1007         }
1008
1009         printf("<FORM name=\"swatform\" method=post>\n");
1010
1011         printf("<table>\n");
1012
1013         if ( cgi_variable("ViewMode") )
1014                 mode = atoi(cgi_variable_nonull("ViewMode"));
1015         if ( cgi_variable("BasicMode"))
1016                 mode = 0;
1017         if ( cgi_variable("AdvMode"))
1018                 mode = 1;
1019
1020         ViewModeBoxes( mode );
1021         switch ( mode ) {
1022                 case 0:
1023                         parm_filter = FLAG_BASIC;
1024                         break;
1025                 case 1:
1026                         parm_filter = FLAG_ADVANCED;
1027                         break;
1028         }
1029         printf("<br><tr>\n");
1030         printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
1031         printf("<td><select name=share>\n");
1032         if (snum < 0)
1033                 printf("<option value=\" \"> \n");
1034         for (i=0;i<lp_numservices();i++) {
1035                 s = lp_servicename(i);
1036                 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
1037                         push_utf8_talloc(talloc_tos(), &utf8_s, s, &converted_size);
1038                         printf("<option %s value=\"%s\">%s\n", 
1039                                (share && strcmp(share,s)==0)?"SELECTED":"",
1040                                utf8_s, utf8_s);
1041                         TALLOC_FREE(utf8_s);
1042                 }
1043         }
1044         printf("</select></td>\n");
1045         if (have_write_access) {
1046                 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
1047         }
1048         printf("</tr>\n");
1049         printf("</table>");
1050         printf("<table>");
1051         if (have_write_access) {
1052                 printf("<tr>\n");
1053                 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
1054                 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1055         }
1056         printf("</table>");
1057
1058
1059         if (snum >= 0) {
1060                 if (have_write_access) {
1061                         printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1062                 }
1063
1064                 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1065                 printf("<p>\n");
1066         }
1067
1068         if (snum >= 0) {
1069                 printf("<table>\n");
1070                 show_parameters(snum, 1, parm_filter, 0);
1071                 printf("</table>\n");
1072         }
1073
1074         printf("</FORM>\n");
1075 }
1076
1077 /*************************************************************
1078 change a password either locally or remotely
1079 *************************************************************/
1080 static bool change_password(const char *remote_machine, const char *user_name, 
1081                             const char *old_passwd, const char *new_passwd, 
1082                                 int local_flags)
1083 {
1084         NTSTATUS ret;
1085         char *err_str = NULL;
1086         char *msg_str = NULL;
1087
1088         if (demo_mode) {
1089                 printf("%s\n<p>", _("password change in demo mode rejected"));
1090                 return False;
1091         }
1092         
1093         if (remote_machine != NULL) {
1094                 ret = remote_password_change(remote_machine, user_name,
1095                                              old_passwd, new_passwd, &err_str);
1096                 if (err_str != NULL)
1097                         printf("%s\n<p>", err_str);
1098                 SAFE_FREE(err_str);
1099                 return NT_STATUS_IS_OK(ret);
1100         }
1101
1102         if(!initialize_password_db(True, NULL)) {
1103                 printf("%s\n<p>", _("Can't setup password database vectors."));
1104                 return False;
1105         }
1106         
1107         ret = local_password_change(user_name, local_flags, new_passwd,
1108                                         &err_str, &msg_str);
1109
1110         if(msg_str)
1111                 printf("%s\n<p>", msg_str);
1112         if(err_str)
1113                 printf("%s\n<p>", err_str);
1114
1115         SAFE_FREE(msg_str);
1116         SAFE_FREE(err_str);
1117         return NT_STATUS_IS_OK(ret);
1118 }
1119
1120 /****************************************************************************
1121   do the stuff required to add or change a password 
1122 ****************************************************************************/
1123 static void chg_passwd(void)
1124 {
1125         const char *host;
1126         bool rslt;
1127         int local_flags = 0;
1128
1129         /* Make sure users name has been specified */
1130         if (strlen(cgi_variable_nonull(SWAT_USER)) == 0) {
1131                 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1132                 return;
1133         }
1134
1135         /*
1136          * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1137          * so if that's what we're doing, skip the rest of the checks
1138          */
1139         if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1140
1141                 /*
1142                  * If current user is not root, make sure old password has been specified 
1143                  * If REMOTE change, even root must provide old password 
1144                  */
1145                 if (((!am_root()) && (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0)) ||
1146                     ((cgi_variable(CHG_R_PASSWD_FLAG)) &&  (strlen( cgi_variable_nonull(OLD_PSWD)) <= 0))) {
1147                         printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1148                         return;
1149                 }
1150
1151                 /* If changing a users password on a remote hosts we have to know what host */
1152                 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable_nonull(RHOST)) <= 0)) {
1153                         printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1154                         return;
1155                 }
1156
1157                 /* Make sure new passwords have been specified */
1158                 if ((strlen( cgi_variable_nonull(NEW_PSWD)) <= 0) ||
1159                     (strlen( cgi_variable_nonull(NEW2_PSWD)) <= 0)) {
1160                         printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1161                         return;
1162                 }
1163
1164                 /* Make sure new passwords was typed correctly twice */
1165                 if (strcmp(cgi_variable_nonull(NEW_PSWD), cgi_variable_nonull(NEW2_PSWD)) != 0) {
1166                         printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1167                         return;
1168                 }
1169         }
1170
1171         if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1172                 host = cgi_variable(RHOST);
1173         } else if (am_root()) {
1174                 host = NULL;
1175         } else {
1176                 host = "127.0.0.1";
1177         }
1178
1179         /*
1180          * Set up the local flags.
1181          */
1182
1183         local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1184         local_flags |= (cgi_variable(ADD_USER_FLAG) ?  LOCAL_SET_PASSWORD : 0);
1185         local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1186         local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1187         local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1188         local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1189         
1190
1191         rslt = change_password(host,
1192                                cgi_variable_nonull(SWAT_USER),
1193                                cgi_variable_nonull(OLD_PSWD), cgi_variable_nonull(NEW_PSWD),
1194                                    local_flags);
1195
1196         if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1197                 printf("<p>");
1198                 if (rslt == True) {
1199                         printf("%s\n", _(" The passwd has been changed."));
1200                 } else {
1201                         printf("%s\n", _(" The passwd for has NOT been changed."));
1202                 }
1203         }
1204         
1205         return;
1206 }
1207
1208 /****************************************************************************
1209   display a password editing page  
1210 ****************************************************************************/
1211 static void passwd_page(void)
1212 {
1213         const char *new_name = cgi_user_name();
1214
1215         if (!new_name) new_name = "";
1216
1217         printf("<H2>%s</H2>\n", _("Server Password Management"));
1218
1219         printf("<FORM name=\"swatform\" method=post>\n");
1220
1221         printf("<table>\n");
1222
1223         /* 
1224          * Create all the dialog boxes for data collection
1225          */
1226         printf("<tr><td> %s : </td>\n", _("User Name"));
1227         printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1228         if (!am_root()) {
1229                 printf("<tr><td> %s : </td>\n", _("Old Password"));
1230                 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1231         }
1232         printf("<tr><td> %s : </td>\n", _("New Password"));
1233         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1234         printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1235         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1236         printf("</table>\n");
1237
1238         /*
1239          * Create all the control buttons for requesting action
1240          */
1241         printf("<input type=submit name=%s value=\"%s\">\n", 
1242                CHG_S_PASSWD_FLAG, _("Change Password"));
1243         if (demo_mode || am_root()) {
1244                 printf("<input type=submit name=%s value=\"%s\">\n",
1245                        ADD_USER_FLAG, _("Add New User"));
1246                 printf("<input type=submit name=%s value=\"%s\">\n",
1247                        DELETE_USER_FLAG, _("Delete User"));
1248                 printf("<input type=submit name=%s value=\"%s\">\n", 
1249                        DISABLE_USER_FLAG, _("Disable User"));
1250                 printf("<input type=submit name=%s value=\"%s\">\n", 
1251                        ENABLE_USER_FLAG, _("Enable User"));
1252         }
1253         printf("<p></FORM>\n");
1254
1255         /*
1256          * Do some work if change, add, disable or enable was
1257          * requested. It could be this is the first time through this
1258          * code, so there isn't anything to do.  */
1259         if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1260             (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1261                 chg_passwd();           
1262         }
1263
1264         printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1265
1266         printf("<FORM name=\"swatform\" method=post>\n");
1267
1268         printf("<table>\n");
1269
1270         /* 
1271          * Create all the dialog boxes for data collection
1272          */
1273         printf("<tr><td> %s : </td>\n", _("User Name"));
1274         printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1275         printf("<tr><td> %s : </td>\n", _("Old Password"));
1276         printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1277         printf("<tr><td> %s : </td>\n", _("New Password"));
1278         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1279         printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1280         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1281         printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1282         printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1283
1284         printf("</table>");
1285
1286         /*
1287          * Create all the control buttons for requesting action
1288          */
1289         printf("<input type=submit name=%s value=\"%s\">", 
1290                CHG_R_PASSWD_FLAG, _("Change Password"));
1291
1292         printf("<p></FORM>\n");
1293
1294         /*
1295          * Do some work if a request has been made to change the
1296          * password somewhere other than the server. It could be this
1297          * is the first time through this code, so there isn't
1298          * anything to do.  */
1299         if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1300                 chg_passwd();           
1301         }
1302
1303 }
1304
1305 /****************************************************************************
1306   display a printers editing page  
1307 ****************************************************************************/
1308 static void printers_page(void)
1309 {
1310         const char *share = cgi_variable("share");
1311         char *s;
1312         int snum=-1;
1313         int i;
1314         int mode = 0;
1315         unsigned int parm_filter = FLAG_BASIC;
1316
1317         if (share)
1318                 snum = lp_servicenumber(share);
1319
1320         printf("<H2>%s</H2>\n", _("Printer Parameters"));
1321  
1322         printf("<H3>%s</H3>\n", _("Important Note:"));
1323         printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1324         printf("%s",_("are autoloaded printers from "));
1325         printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1326         printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1327
1328         if (cgi_variable("Commit") && snum >= 0) {
1329                 commit_parameters(snum);
1330                 if (snum >= iNumNonAutoPrintServices)
1331                     save_reload(snum);
1332                 else
1333                     save_reload(-1);
1334                 snum = lp_servicenumber(share);
1335         }
1336
1337         if (cgi_variable("Delete") && snum >= 0) {
1338                 lp_remove_service(snum);
1339                 save_reload(-1);
1340                 share = NULL;
1341                 snum = -1;
1342         }
1343
1344         if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1345                 snum = lp_servicenumber(share);
1346                 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1347                         load_config(False);
1348                         lp_copy_service(GLOBAL_SECTION_SNUM, share);
1349                         snum = lp_servicenumber(share);
1350                         lp_do_parameter(snum, "print ok", "Yes");
1351                         save_reload(snum);
1352                         snum = lp_servicenumber(share);
1353                 }
1354         }
1355
1356         printf("<FORM name=\"swatform\" method=post>\n");
1357
1358         if ( cgi_variable("ViewMode") )
1359                 mode = atoi(cgi_variable_nonull("ViewMode"));
1360         if ( cgi_variable("BasicMode"))
1361                 mode = 0;
1362         if ( cgi_variable("AdvMode"))
1363                 mode = 1;
1364
1365         ViewModeBoxes( mode );
1366         switch ( mode ) {
1367                 case 0:
1368                         parm_filter = FLAG_BASIC;
1369                         break;
1370                 case 1:
1371                         parm_filter = FLAG_ADVANCED;
1372                         break;
1373         }
1374         printf("<table>\n");
1375         printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1376         printf("<td><select name=\"share\">\n");
1377         if (snum < 0 || !lp_print_ok(snum))
1378                 printf("<option value=\" \"> \n");
1379         for (i=0;i<lp_numservices();i++) {
1380                 s = lp_servicename(i);
1381                 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1382                     if (i >= iNumNonAutoPrintServices)
1383                         printf("<option %s value=\"%s\">[*]%s\n",
1384                                (share && strcmp(share,s)==0)?"SELECTED":"",
1385                                s, s);
1386                     else
1387                         printf("<option %s value=\"%s\">%s\n", 
1388                                (share && strcmp(share,s)==0)?"SELECTED":"",
1389                                s, s);
1390                 }
1391         }
1392         printf("</select></td>");
1393         if (have_write_access) {
1394                 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1395         }
1396         printf("</tr>");
1397         printf("</table>\n");
1398
1399         if (have_write_access) {
1400                 printf("<table>\n");
1401                 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1402                 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1403                 printf("</table>");
1404         }
1405
1406
1407         if (snum >= 0) {
1408                 if (have_write_access) {
1409                         printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1410                 }
1411                 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1412                 printf("<p>\n");
1413         }
1414
1415         if (snum >= 0) {
1416                 printf("<table>\n");
1417                 show_parameters(snum, 1, parm_filter, 1);
1418                 printf("</table>\n");
1419         }
1420         printf("</FORM>\n");
1421 }
1422
1423 /*
1424   when the _() translation macro is used there is no obvious place to free
1425   the resulting string and there is no easy way to give a static pointer.
1426   All we can do is rotate between some static buffers and hope a single d_printf()
1427   doesn't have more calls to _() than the number of buffers
1428 */
1429
1430 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1431 {
1432         const char *msgstr;
1433         const char *ret;
1434
1435         msgstr = lang_msg(msgid);
1436         if (!msgstr) {
1437                 return msgid;
1438         }
1439
1440         ret = talloc_strdup(ctx, msgstr);
1441
1442         lang_msg_free(msgstr);
1443         if (!ret) {
1444                 return msgid;
1445         }
1446
1447         return ret;
1448 }
1449
1450 /**
1451  * main function for SWAT.
1452  **/
1453  int main(int argc, char *argv[])
1454 {
1455         const char *page;
1456         poptContext pc;
1457         struct poptOption long_options[] = {
1458                 POPT_AUTOHELP
1459                 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1460                 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" }, 
1461                 POPT_COMMON_SAMBA
1462                 POPT_TABLEEND
1463         };
1464         TALLOC_CTX *frame = talloc_stackframe();
1465
1466         fault_setup(NULL);
1467         umask(S_IWGRP | S_IWOTH);
1468
1469 #if defined(HAVE_SET_AUTH_PARAMETERS)
1470         set_auth_parameters(argc, argv);
1471 #endif /* HAVE_SET_AUTH_PARAMETERS */
1472
1473         /* just in case it goes wild ... */
1474         alarm(300);
1475
1476         setlinebuf(stdout);
1477
1478         /* we don't want any SIGPIPE messages */
1479         BlockSignals(True,SIGPIPE);
1480
1481         dbf = x_fopen("/dev/null", O_WRONLY, 0);
1482         if (!dbf) dbf = x_stderr;
1483
1484         /* we don't want stderr screwing us up */
1485         close(2);
1486         open("/dev/null", O_WRONLY);
1487
1488         pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1489
1490         /* Parse command line options */
1491
1492         while(poptGetNextOpt(pc) != -1) { }
1493
1494         poptFreeContext(pc);
1495
1496         load_case_tables();
1497
1498         setup_logging(argv[0],False);
1499         load_config(True);
1500         load_interfaces();
1501         iNumNonAutoPrintServices = lp_numservices();
1502         pcap_cache_reload(&load_printers);
1503
1504         cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1505
1506         print_header();
1507
1508         cgi_load_variables();
1509
1510         if (!file_exist(get_dyn_CONFIGFILE())) {
1511                 have_read_access = True;
1512                 have_write_access = True;
1513         } else {
1514                 /* check if the authenticated user has write access - if not then
1515                    don't show write options */
1516                 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1517
1518                 /* if the user doesn't have read access to smb.conf then
1519                    don't let them view it */
1520                 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1521         }
1522
1523         show_main_buttons();
1524
1525         page = cgi_pathinfo();
1526
1527         /* Root gets full functionality */
1528         if (have_read_access && strcmp(page, "globals")==0) {
1529                 globals_page();
1530         } else if (have_read_access && strcmp(page,"shares")==0) {
1531                 shares_page();
1532         } else if (have_read_access && strcmp(page,"printers")==0) {
1533                 printers_page();
1534         } else if (have_read_access && strcmp(page,"status")==0) {
1535                 status_page();
1536         } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1537                 viewconfig_page();
1538         } else if (strcmp(page,"passwd")==0) {
1539                 passwd_page();
1540         } else if (have_read_access && strcmp(page,"wizard")==0) {
1541                 wizard_page();
1542         } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1543                 wizard_params_page();
1544         } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1545                 rewritecfg_file();
1546         } else {
1547                 welcome_page();
1548         }
1549
1550         print_footer();
1551
1552         TALLOC_FREE(frame);
1553         return 0;
1554 }
1555
1556 /** @} **/