Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/web/swat.c

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