~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/web/cgi.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
   some simple CGI helper routines
3
 
   Copyright (C) Andrew Tridgell 1997-1998
4
 
   
5
 
   This program is free software; you can redistribute it and/or modify
6
 
   it under the terms of the GNU General Public License as published by
7
 
   the Free Software Foundation; either version 2 of the License, or
8
 
   (at your option) any later version.
9
 
   
10
 
   This program is distributed in the hope that it will be useful,
11
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
   GNU General Public License for more details.
14
 
   
15
 
   You should have received a copy of the GNU General Public License
16
 
   along with this program; if not, write to the Free Software
17
 
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
 
*/
19
 
 
20
 
 
21
 
#include "includes.h"
22
 
#include "web/swat_proto.h"
23
 
 
24
 
#define MAX_VARIABLES 10000
25
 
 
26
 
/* set the expiry on fixed pages */
27
 
#define EXPIRY_TIME (60*60*24*7)
28
 
 
29
 
#ifdef DEBUG_COMMENTS
30
 
extern void print_title(char *fmt, ...);
31
 
#endif
32
 
 
33
 
struct cgi_var {
34
 
        char *name;
35
 
        char *value;
36
 
};
37
 
 
38
 
static struct cgi_var variables[MAX_VARIABLES];
39
 
static int num_variables;
40
 
static int content_length;
41
 
static int request_post;
42
 
static char *query_string;
43
 
static const char *baseurl;
44
 
static char *pathinfo;
45
 
static char *C_user;
46
 
static BOOL inetd_server;
47
 
static BOOL got_request;
48
 
 
49
 
static char *grab_line(FILE *f, int *cl)
50
 
{
51
 
        char *ret = NULL;
52
 
        int i = 0;
53
 
        int len = 0;
54
 
 
55
 
        while ((*cl)) {
56
 
                int c;
57
 
        
58
 
                if (i == len) {
59
 
                        char *ret2;
60
 
                        if (len == 0) len = 1024;
61
 
                        else len *= 2;
62
 
                        ret2 = (char *)SMB_REALLOC_KEEP_OLD_ON_ERROR(ret, len);
63
 
                        if (!ret2) return ret;
64
 
                        ret = ret2;
65
 
                }
66
 
        
67
 
                c = fgetc(f);
68
 
                (*cl)--;
69
 
 
70
 
                if (c == EOF) {
71
 
                        (*cl) = 0;
72
 
                        break;
73
 
                }
74
 
                
75
 
                if (c == '\r') continue;
76
 
 
77
 
                if (strchr_m("\n&", c)) break;
78
 
 
79
 
                ret[i++] = c;
80
 
 
81
 
        }
82
 
        
83
 
 
84
 
        ret[i] = 0;
85
 
        return ret;
86
 
}
87
 
 
88
 
/**
89
 
 URL encoded strings can have a '+', which should be replaced with a space
90
 
 
91
 
 (This was in rfc1738_unescape(), but that broke the squid helper)
92
 
**/
93
 
 
94
 
static void plus_to_space_unescape(char *buf)
95
 
{
96
 
        char *p=buf;
97
 
 
98
 
        while ((p=strchr_m(p,'+')))
99
 
                *p = ' ';
100
 
}
101
 
 
102
 
/***************************************************************************
103
 
  load all the variables passed to the CGI program. May have multiple variables
104
 
  with the same name and the same or different values. Takes a file parameter
105
 
  for simulating CGI invocation eg loading saved preferences.
106
 
  ***************************************************************************/
107
 
void cgi_load_variables(void)
108
 
{
109
 
        static char *line;
110
 
        char *p, *s, *tok;
111
 
        int len, i;
112
 
        FILE *f = stdin;
113
 
 
114
 
#ifdef DEBUG_COMMENTS
115
 
        char dummy[100]="";
116
 
        print_title(dummy);
117
 
        d_printf("<!== Start dump in cgi_load_variables() %s ==>\n",__FILE__);
118
 
#endif
119
 
 
120
 
        if (!content_length) {
121
 
                p = getenv("CONTENT_LENGTH");
122
 
                len = p?atoi(p):0;
123
 
        } else {
124
 
                len = content_length;
125
 
        }
126
 
 
127
 
 
128
 
        if (len > 0 && 
129
 
            (request_post ||
130
 
             ((s=getenv("REQUEST_METHOD")) && 
131
 
              strequal(s,"POST")))) {
132
 
                while (len && (line=grab_line(f, &len))) {
133
 
                        p = strchr_m(line,'=');
134
 
                        if (!p) continue;
135
 
                        
136
 
                        *p = 0;
137
 
                        
138
 
                        variables[num_variables].name = SMB_STRDUP(line);
139
 
                        variables[num_variables].value = SMB_STRDUP(p+1);
140
 
 
141
 
                        SAFE_FREE(line);
142
 
                        
143
 
                        if (!variables[num_variables].name || 
144
 
                            !variables[num_variables].value)
145
 
                                continue;
146
 
 
147
 
                        plus_to_space_unescape(variables[num_variables].value);
148
 
                        rfc1738_unescape(variables[num_variables].value);
149
 
                        plus_to_space_unescape(variables[num_variables].name);
150
 
                        rfc1738_unescape(variables[num_variables].name);
151
 
 
152
 
#ifdef DEBUG_COMMENTS
153
 
                        printf("<!== POST var %s has value \"%s\"  ==>\n",
154
 
                               variables[num_variables].name,
155
 
                               variables[num_variables].value);
156
 
#endif
157
 
                        
158
 
                        num_variables++;
159
 
                        if (num_variables == MAX_VARIABLES) break;
160
 
                }
161
 
        }
162
 
 
163
 
        fclose(stdin);
164
 
        open("/dev/null", O_RDWR);
165
 
 
166
 
        if ((s=query_string) || (s=getenv("QUERY_STRING"))) {
167
 
                for (tok=strtok(s,"&;");tok;tok=strtok(NULL,"&;")) {
168
 
                        p = strchr_m(tok,'=');
169
 
                        if (!p) continue;
170
 
                        
171
 
                        *p = 0;
172
 
                        
173
 
                        variables[num_variables].name = SMB_STRDUP(tok);
174
 
                        variables[num_variables].value = SMB_STRDUP(p+1);
175
 
 
176
 
                        if (!variables[num_variables].name || 
177
 
                            !variables[num_variables].value)
178
 
                                continue;
179
 
 
180
 
                        plus_to_space_unescape(variables[num_variables].value);
181
 
                        rfc1738_unescape(variables[num_variables].value);
182
 
                        plus_to_space_unescape(variables[num_variables].name);
183
 
                        rfc1738_unescape(variables[num_variables].name);
184
 
 
185
 
#ifdef DEBUG_COMMENTS
186
 
                        printf("<!== Commandline var %s has value \"%s\"  ==>\n",
187
 
                               variables[num_variables].name,
188
 
                               variables[num_variables].value);
189
 
#endif                                          
190
 
                        num_variables++;
191
 
                        if (num_variables == MAX_VARIABLES) break;
192
 
                }
193
 
 
194
 
        }
195
 
#ifdef DEBUG_COMMENTS
196
 
        printf("<!== End dump in cgi_load_variables() ==>\n");   
197
 
#endif
198
 
 
199
 
        /* variables from the client are in UTF-8 - convert them
200
 
           to our internal unix charset before use */
201
 
        for (i=0;i<num_variables;i++) {
202
 
                pstring dest;
203
 
 
204
 
                convert_string(CH_UTF8, CH_UNIX, 
205
 
                               variables[i].name, -1, 
206
 
                               dest, sizeof(dest), True);
207
 
                free(variables[i].name);
208
 
                variables[i].name = SMB_STRDUP(dest);
209
 
 
210
 
                convert_string(CH_UTF8, CH_UNIX, 
211
 
                               variables[i].value, -1,
212
 
                               dest, sizeof(dest), True);
213
 
                free(variables[i].value);
214
 
                variables[i].value = SMB_STRDUP(dest);
215
 
        }
216
 
}
217
 
 
218
 
 
219
 
/***************************************************************************
220
 
  find a variable passed via CGI
221
 
  Doesn't quite do what you think in the case of POST text variables, because
222
 
  if they exist they might have a value of "" or even " ", depending on the 
223
 
  browser. Also doesn't allow for variables[] containing multiple variables
224
 
  with the same name and the same or different values.
225
 
  ***************************************************************************/
226
 
 
227
 
const char *cgi_variable(const char *name)
228
 
{
229
 
        int i;
230
 
 
231
 
        for (i=0;i<num_variables;i++)
232
 
                if (strcmp(variables[i].name, name) == 0)
233
 
                        return variables[i].value;
234
 
        return NULL;
235
 
}
236
 
 
237
 
/***************************************************************************
238
 
 Version of the above that can't return a NULL pointer.
239
 
***************************************************************************/
240
 
 
241
 
const char *cgi_variable_nonull(const char *name)
242
 
{
243
 
        const char *var = cgi_variable(name);
244
 
        if (var) {
245
 
                return var;
246
 
        } else {
247
 
                return "";
248
 
        }
249
 
}
250
 
 
251
 
/***************************************************************************
252
 
tell a browser about a fatal error in the http processing
253
 
  ***************************************************************************/
254
 
static void cgi_setup_error(const char *err, const char *header, const char *info)
255
 
{
256
 
        if (!got_request) {
257
 
                /* damn browsers don't like getting cut off before they give a request */
258
 
                char line[1024];
259
 
                while (fgets(line, sizeof(line)-1, stdin)) {
260
 
                        if (strnequal(line,"GET ", 4) || 
261
 
                            strnequal(line,"POST ", 5) ||
262
 
                            strnequal(line,"PUT ", 4)) {
263
 
                                break;
264
 
                        }
265
 
                }
266
 
        }
267
 
 
268
 
        d_printf("HTTP/1.0 %s\r\n%sConnection: close\r\nContent-Type: text/html\r\n\r\n<HTML><HEAD><TITLE>%s</TITLE></HEAD><BODY><H1>%s</H1>%s<p></BODY></HTML>\r\n\r\n", err, header, err, err, info);
269
 
        fclose(stdin);
270
 
        fclose(stdout);
271
 
        exit(0);
272
 
}
273
 
 
274
 
 
275
 
/***************************************************************************
276
 
tell a browser about a fatal authentication error
277
 
  ***************************************************************************/
278
 
static void cgi_auth_error(void)
279
 
{
280
 
        if (inetd_server) {
281
 
                cgi_setup_error("401 Authorization Required", 
282
 
                                "WWW-Authenticate: Basic realm=\"SWAT\"\r\n",
283
 
                                "You must be authenticated to use this service");
284
 
        } else {
285
 
                printf("Content-Type: text/html\r\n");
286
 
 
287
 
                printf("\r\n<HTML><HEAD><TITLE>SWAT</TITLE></HEAD>\n");
288
 
                printf("<BODY><H1>Installation Error</H1>\n");
289
 
                printf("SWAT must be installed via inetd. It cannot be run as a CGI script<p>\n");
290
 
                printf("</BODY></HTML>\r\n");
291
 
        }
292
 
        exit(0);
293
 
}
294
 
 
295
 
/***************************************************************************
296
 
authenticate when we are running as a CGI
297
 
  ***************************************************************************/
298
 
static void cgi_web_auth(void)
299
 
{
300
 
        const char *user = getenv("REMOTE_USER");
301
 
        struct passwd *pwd;
302
 
        const char *head = "Content-Type: text/html\r\n\r\n<HTML><BODY><H1>SWAT installation Error</H1>\n";
303
 
        const char *tail = "</BODY></HTML>\r\n";
304
 
 
305
 
        if (!user) {
306
 
                printf("%sREMOTE_USER not set. Not authenticated by web server.<br>%s\n",
307
 
                       head, tail);
308
 
                exit(0);
309
 
        }
310
 
 
311
 
        pwd = getpwnam_alloc(NULL, user);
312
 
        if (!pwd) {
313
 
                printf("%sCannot find user %s<br>%s\n", head, user, tail);
314
 
                exit(0);
315
 
        }
316
 
 
317
 
        setuid(0);
318
 
        setuid(pwd->pw_uid);
319
 
        if (geteuid() != pwd->pw_uid || getuid() != pwd->pw_uid) {
320
 
                printf("%sFailed to become user %s - uid=%d/%d<br>%s\n", 
321
 
                       head, user, (int)geteuid(), (int)getuid(), tail);
322
 
                exit(0);
323
 
        }
324
 
        TALLOC_FREE(pwd);
325
 
}
326
 
 
327
 
 
328
 
/***************************************************************************
329
 
handle a http authentication line
330
 
  ***************************************************************************/
331
 
static BOOL cgi_handle_authorization(char *line)
332
 
{
333
 
        char *p;
334
 
        fstring user, user_pass;
335
 
        struct passwd *pass = NULL;
336
 
 
337
 
        if (!strnequal(line,"Basic ", 6)) {
338
 
                goto err;
339
 
        }
340
 
        line += 6;
341
 
        while (line[0] == ' ') line++;
342
 
        base64_decode_inplace(line);
343
 
        if (!(p=strchr_m(line,':'))) {
344
 
                /*
345
 
                 * Always give the same error so a cracker
346
 
                 * cannot tell why we fail.
347
 
                 */
348
 
                goto err;
349
 
        }
350
 
        *p = 0;
351
 
 
352
 
        convert_string(CH_UTF8, CH_UNIX, 
353
 
                       line, -1, 
354
 
                       user, sizeof(user), True);
355
 
 
356
 
        convert_string(CH_UTF8, CH_UNIX, 
357
 
                       p+1, -1, 
358
 
                       user_pass, sizeof(user_pass), True);
359
 
 
360
 
        /*
361
 
         * Try and get the user from the UNIX password file.
362
 
         */
363
 
        
364
 
        pass = getpwnam_alloc(NULL, user);
365
 
        
366
 
        /*
367
 
         * Validate the password they have given.
368
 
         */
369
 
        
370
 
        if NT_STATUS_IS_OK(pass_check(pass, user, user_pass, 
371
 
                      strlen(user_pass), NULL, False)) {
372
 
                
373
 
                if (pass) {
374
 
                        /*
375
 
                         * Password was ok.
376
 
                         */
377
 
                        
378
 
                        if ( initgroups(pass->pw_name, pass->pw_gid) != 0 )
379
 
                                goto err;
380
 
 
381
 
                        become_user_permanently(pass->pw_uid, pass->pw_gid);
382
 
                        
383
 
                        /* Save the users name */
384
 
                        C_user = SMB_STRDUP(user);
385
 
                        TALLOC_FREE(pass);
386
 
                        return True;
387
 
                }
388
 
        }
389
 
        
390
 
err:
391
 
        cgi_setup_error("401 Bad Authorization", 
392
 
                        "WWW-Authenticate: Basic realm=\"SWAT\"\r\n",
393
 
                        "username or password incorrect");
394
 
 
395
 
        TALLOC_FREE(pass);
396
 
        return False;
397
 
}
398
 
 
399
 
/***************************************************************************
400
 
is this root?
401
 
  ***************************************************************************/
402
 
BOOL am_root(void)
403
 
{
404
 
        if (geteuid() == 0) {
405
 
                return( True);
406
 
        } else {
407
 
                return( False);
408
 
        }
409
 
}
410
 
 
411
 
/***************************************************************************
412
 
return a ptr to the users name
413
 
  ***************************************************************************/
414
 
char *cgi_user_name(void)
415
 
{
416
 
        return(C_user);
417
 
}
418
 
 
419
 
 
420
 
/***************************************************************************
421
 
handle a file download
422
 
  ***************************************************************************/
423
 
static void cgi_download(char *file)
424
 
{
425
 
        SMB_STRUCT_STAT st;
426
 
        char buf[1024];
427
 
        int fd, l, i;
428
 
        char *p;
429
 
        char *lang;
430
 
 
431
 
        /* sanitise the filename */
432
 
        for (i=0;file[i];i++) {
433
 
                if (!isalnum((int)file[i]) && !strchr_m("/.-_", file[i])) {
434
 
                        cgi_setup_error("404 File Not Found","",
435
 
                                        "Illegal character in filename");
436
 
                }
437
 
        }
438
 
 
439
 
        if (sys_stat(file, &st) != 0) 
440
 
        {
441
 
                cgi_setup_error("404 File Not Found","",
442
 
                                "The requested file was not found");
443
 
        }
444
 
 
445
 
        if (S_ISDIR(st.st_mode))
446
 
        {
447
 
                snprintf(buf, sizeof(buf), "%s/index.html", file);
448
 
                if (!file_exist(buf, &st) || !S_ISREG(st.st_mode))
449
 
                {
450
 
                        cgi_setup_error("404 File Not Found","",
451
 
                                        "The requested file was not found");
452
 
                }
453
 
        }
454
 
        else if (S_ISREG(st.st_mode))
455
 
        {
456
 
                snprintf(buf, sizeof(buf), "%s", file);
457
 
        }
458
 
        else
459
 
        {
460
 
                cgi_setup_error("404 File Not Found","",
461
 
                                "The requested file was not found");
462
 
        }
463
 
 
464
 
        fd = web_open(buf,O_RDONLY,0);
465
 
        if (fd == -1) {
466
 
                cgi_setup_error("404 File Not Found","",
467
 
                                "The requested file was not found");
468
 
        }
469
 
        printf("HTTP/1.0 200 OK\r\n");
470
 
        if ((p=strrchr_m(buf, '.'))) {
471
 
                if (strcmp(p,".gif")==0) {
472
 
                        printf("Content-Type: image/gif\r\n");
473
 
                } else if (strcmp(p,".jpg")==0) {
474
 
                        printf("Content-Type: image/jpeg\r\n");
475
 
                } else if (strcmp(p,".png")==0) {
476
 
                        printf("Content-Type: image/png\r\n");
477
 
                } else if (strcmp(p,".css")==0) {
478
 
                        printf("Content-Type: text/css\r\n");
479
 
                } else if (strcmp(p,".txt")==0) {
480
 
                        printf("Content-Type: text/plain\r\n");
481
 
                } else {
482
 
                        printf("Content-Type: text/html\r\n");
483
 
                }
484
 
        }
485
 
        printf("Expires: %s\r\n", http_timestring(time(NULL)+EXPIRY_TIME));
486
 
 
487
 
        lang = lang_tdb_current();
488
 
        if (lang) {
489
 
                printf("Content-Language: %s\r\n", lang);
490
 
        }
491
 
 
492
 
        printf("Content-Length: %d\r\n\r\n", (int)st.st_size);
493
 
        while ((l=read(fd,buf,sizeof(buf)))>0) {
494
 
                fwrite(buf, 1, l, stdout);
495
 
        }
496
 
        close(fd);
497
 
        exit(0);
498
 
}
499
 
 
500
 
 
501
 
 
502
 
 
503
 
/**
504
 
 * @brief Setup the CGI framework.
505
 
 *
506
 
 * Setup the cgi framework, handling the possibility that this program
507
 
 * is either run as a true CGI program with a gateway to a web server, or
508
 
 * is itself a mini web server.
509
 
 **/
510
 
void cgi_setup(const char *rootdir, int auth_required)
511
 
{
512
 
        BOOL authenticated = False;
513
 
        char line[1024];
514
 
        char *url=NULL;
515
 
        char *p;
516
 
        char *lang;
517
 
 
518
 
        if (chdir(rootdir)) {
519
 
                cgi_setup_error("500 Server Error", "",
520
 
                                "chdir failed - the server is not configured correctly");
521
 
        }
522
 
 
523
 
        /* Handle the possibility we might be running as non-root */
524
 
        sec_init();
525
 
 
526
 
        if ((lang=getenv("HTTP_ACCEPT_LANGUAGE"))) {
527
 
                /* if running as a cgi program */
528
 
                web_set_lang(lang);
529
 
        }
530
 
 
531
 
        /* maybe we are running under a web server */
532
 
        if (getenv("CONTENT_LENGTH") || getenv("REQUEST_METHOD")) {
533
 
                if (auth_required) {
534
 
                        cgi_web_auth();
535
 
                }
536
 
                return;
537
 
        }
538
 
 
539
 
        inetd_server = True;
540
 
 
541
 
        if (!check_access(1, lp_hostsallow(-1), lp_hostsdeny(-1))) {
542
 
                cgi_setup_error("403 Forbidden", "",
543
 
                                "Samba is configured to deny access from this client\n<br>Check your \"hosts allow\" and \"hosts deny\" options in smb.conf ");
544
 
        }
545
 
 
546
 
        /* we are a mini-web server. We need to read the request from stdin
547
 
           and handle authentication etc */
548
 
        while (fgets(line, sizeof(line)-1, stdin)) {
549
 
                if (line[0] == '\r' || line[0] == '\n') break;
550
 
                if (strnequal(line,"GET ", 4)) {
551
 
                        got_request = True;
552
 
                        url = SMB_STRDUP(&line[4]);
553
 
                } else if (strnequal(line,"POST ", 5)) {
554
 
                        got_request = True;
555
 
                        request_post = 1;
556
 
                        url = SMB_STRDUP(&line[5]);
557
 
                } else if (strnequal(line,"PUT ", 4)) {
558
 
                        got_request = True;
559
 
                        cgi_setup_error("400 Bad Request", "",
560
 
                                        "This server does not accept PUT requests");
561
 
                } else if (strnequal(line,"Authorization: ", 15)) {
562
 
                        authenticated = cgi_handle_authorization(&line[15]);
563
 
                } else if (strnequal(line,"Content-Length: ", 16)) {
564
 
                        content_length = atoi(&line[16]);
565
 
                } else if (strnequal(line,"Accept-Language: ", 17)) {
566
 
                        web_set_lang(&line[17]);
567
 
                }
568
 
                /* ignore all other requests! */
569
 
        }
570
 
 
571
 
        if (auth_required && !authenticated) {
572
 
                cgi_auth_error();
573
 
        }
574
 
 
575
 
        if (!url) {
576
 
                cgi_setup_error("400 Bad Request", "",
577
 
                                "You must specify a GET or POST request");
578
 
        }
579
 
 
580
 
        /* trim the URL */
581
 
        if ((p = strchr_m(url,' ')) || (p=strchr_m(url,'\t'))) {
582
 
                *p = 0;
583
 
        }
584
 
        while (*url && strchr_m("\r\n",url[strlen(url)-1])) {
585
 
                url[strlen(url)-1] = 0;
586
 
        }
587
 
 
588
 
        /* anything following a ? in the URL is part of the query string */
589
 
        if ((p=strchr_m(url,'?'))) {
590
 
                query_string = p+1;
591
 
                *p = 0;
592
 
        }
593
 
 
594
 
        string_sub(url, "/swat/", "", 0);
595
 
 
596
 
        if (url[0] != '/' && strstr(url,"..")==0) {
597
 
                cgi_download(url);
598
 
        }
599
 
 
600
 
        printf("HTTP/1.0 200 OK\r\nConnection: close\r\n");
601
 
        printf("Date: %s\r\n", http_timestring(time(NULL)));
602
 
        baseurl = "";
603
 
        pathinfo = url+1;
604
 
}
605
 
 
606
 
 
607
 
/***************************************************************************
608
 
return the current pages URL
609
 
  ***************************************************************************/
610
 
const char *cgi_baseurl(void)
611
 
{
612
 
        if (inetd_server) {
613
 
                return baseurl;
614
 
        }
615
 
        return getenv("SCRIPT_NAME");
616
 
}
617
 
 
618
 
/***************************************************************************
619
 
return the current pages path info
620
 
  ***************************************************************************/
621
 
const char *cgi_pathinfo(void)
622
 
{
623
 
        char *r;
624
 
        if (inetd_server) {
625
 
                return pathinfo;
626
 
        }
627
 
        r = getenv("PATH_INFO");
628
 
        if (!r) return "";
629
 
        if (*r == '/') r++;
630
 
        return r;
631
 
}
632
 
 
633
 
/***************************************************************************
634
 
return the hostname of the client
635
 
  ***************************************************************************/
636
 
char *cgi_remote_host(void)
637
 
{
638
 
        if (inetd_server) {
639
 
                return get_peer_name(1,False);
640
 
        }
641
 
        return getenv("REMOTE_HOST");
642
 
}
643
 
 
644
 
/***************************************************************************
645
 
return the hostname of the client
646
 
  ***************************************************************************/
647
 
char *cgi_remote_addr(void)
648
 
{
649
 
        if (inetd_server) {
650
 
                return get_peer_addr(1);
651
 
        }
652
 
        return getenv("REMOTE_ADDR");
653
 
}
654
 
 
655
 
 
656
 
/***************************************************************************
657
 
return True if the request was a POST
658
 
  ***************************************************************************/
659
 
BOOL cgi_waspost(void)
660
 
{
661
 
        if (inetd_server) {
662
 
                return request_post;
663
 
        }
664
 
        return strequal(getenv("REQUEST_METHOD"), "POST");
665
 
}