1997-09-11 06:17:16 +04:00
/*
some simple CGI helper routines
1998-01-22 16:27:43 +03:00
Copyright ( C ) Andrew Tridgell 1997 - 1998
1997-09-11 06:17:16 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
1998-03-10 07:56:58 +03:00
# include "includes.h"
# include "smb.h"
1997-09-11 06:17:16 +04:00
1997-11-22 10:51:23 +03:00
# define MAX_VARIABLES 10000
1998-03-10 07:56:58 +03:00
/* set the expiry on fixed pages */
# define EXPIRY_TIME (60*60*24*7)
1997-11-22 10:51:23 +03:00
# ifdef DEBUG_COMMENTS
extern void print_title ( char * fmt , . . . ) ;
# endif
1997-09-11 06:17:16 +04:00
struct var {
char * name ;
char * value ;
} ;
static struct var variables [ MAX_VARIABLES ] ;
static int num_variables ;
1997-11-22 10:51:23 +03:00
static int content_length ;
static int request_post ;
static char * query_string ;
1998-03-08 17:14:49 +03:00
static char * baseurl ;
1998-03-14 07:13:24 +03:00
static char * pathinfo ;
1998-11-12 00:37:44 +03:00
static char * C_user ;
1998-11-14 05:10:55 +03:00
static BOOL inetd_server ;
1998-11-21 04:41:14 +03:00
static BOOL got_request ;
1997-11-22 10:51:23 +03:00
static void unescape ( char * buf )
{
char * p = buf ;
2001-07-04 11:36:09 +04:00
while ( ( p = strchr_m ( p , ' + ' ) ) )
1997-11-22 10:51:23 +03:00
* p = ' ' ;
p = buf ;
2001-07-04 11:36:09 +04:00
while ( p & & * p & & ( p = strchr_m ( p , ' % ' ) ) ) {
1997-11-22 10:51:23 +03:00
int c1 = p [ 1 ] ;
int c2 = p [ 2 ] ;
if ( c1 > = ' 0 ' & & c1 < = ' 9 ' )
c1 = c1 - ' 0 ' ;
else if ( c1 > = ' A ' & & c1 < = ' F ' )
c1 = 10 + c1 - ' A ' ;
else if ( c1 > = ' a ' & & c1 < = ' f ' )
c1 = 10 + c1 - ' a ' ;
else { p + + ; continue ; }
if ( c2 > = ' 0 ' & & c2 < = ' 9 ' )
c2 = c2 - ' 0 ' ;
else if ( c2 > = ' A ' & & c2 < = ' F ' )
c2 = 10 + c2 - ' A ' ;
else if ( c2 > = ' a ' & & c2 < = ' f ' )
c2 = 10 + c2 - ' a ' ;
else { p + + ; continue ; }
* p = ( c1 < < 4 ) | c2 ;
memcpy ( p + 1 , p + 3 , strlen ( p + 3 ) + 1 ) ;
p + + ;
}
}
1997-09-11 06:17:16 +04:00
1997-11-22 10:51:23 +03:00
static char * grab_line ( FILE * f , int * cl )
1997-09-11 06:17:16 +04:00
{
2001-08-08 20:54:16 +04:00
char * ret = NULL ;
1997-09-11 06:17:16 +04:00
int i = 0 ;
2001-08-12 13:18:31 +04:00
int len = 0 ;
1997-11-22 10:51:23 +03:00
1997-09-11 06:17:16 +04:00
while ( ( * cl ) ) {
2001-08-08 20:54:16 +04:00
int c ;
if ( i = = len ) {
char * ret2 ;
if ( len = = 0 ) len = 1024 ;
else len * = 2 ;
2001-08-12 13:18:31 +04:00
ret2 = ( char * ) Realloc ( ret , len ) ;
2001-08-08 20:54:16 +04:00
if ( ! ret2 ) return ret ;
ret = ret2 ;
}
c = fgetc ( f ) ;
1997-09-11 06:17:16 +04:00
( * cl ) - - ;
if ( c = = EOF ) {
( * cl ) = 0 ;
break ;
}
if ( c = = ' \r ' ) continue ;
2001-07-04 11:36:09 +04:00
if ( strchr_m ( " \n & " , c ) ) break ;
1997-09-11 06:17:16 +04:00
1997-11-22 10:51:23 +03:00
ret [ i + + ] = c ;
1997-09-11 06:17:16 +04:00
}
1997-11-22 10:51:23 +03:00
ret [ i ] = 0 ;
return ret ;
1997-09-11 06:17:16 +04:00
}
/***************************************************************************
1997-11-22 10:51:23 +03:00
load all the variables passed to the CGI program . May have multiple variables
with the same name and the same or different values . Takes a file parameter
for simulating CGI invocation eg loading saved preferences .
1997-09-11 06:17:16 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-09-24 08:49:14 +04:00
void cgi_load_variables ( void )
1997-09-11 06:17:16 +04:00
{
1997-11-22 10:51:23 +03:00
static char * line ;
char * p , * s , * tok ;
2001-09-24 08:49:14 +04:00
int len , i ;
FILE * f = stdin ;
1997-09-11 06:17:16 +04:00
1997-11-22 10:51:23 +03:00
# ifdef DEBUG_COMMENTS
char dummy [ 100 ] = " " ;
print_title ( dummy ) ;
2001-10-14 16:10:29 +04:00
d_printf ( " <!== Start dump in cgi_load_variables() %s ==> \n " , __FILE__ ) ;
1997-11-22 10:51:23 +03:00
# endif
1997-09-11 06:17:16 +04:00
2001-09-24 08:49:14 +04:00
if ( ! content_length ) {
p = getenv ( " CONTENT_LENGTH " ) ;
len = p ? atoi ( p ) : 0 ;
1997-11-22 10:51:23 +03:00
} else {
2001-09-24 08:49:14 +04:00
len = content_length ;
1997-11-22 10:51:23 +03:00
}
1997-09-11 06:17:16 +04:00
1997-11-22 10:51:23 +03:00
if ( len > 0 & &
2001-09-24 08:49:14 +04:00
( request_post | |
1997-11-22 10:51:23 +03:00
( ( s = getenv ( " REQUEST_METHOD " ) ) & &
strcasecmp ( s , " POST " ) = = 0 ) ) ) {
while ( len & & ( line = grab_line ( f , & len ) ) ) {
2001-07-04 11:36:09 +04:00
p = strchr_m ( line , ' = ' ) ;
1997-11-22 10:51:23 +03:00
if ( ! p ) continue ;
* p = 0 ;
variables [ num_variables ] . name = strdup ( line ) ;
variables [ num_variables ] . value = strdup ( p + 1 ) ;
1997-09-11 06:17:16 +04:00
2001-09-17 15:48:29 +04:00
SAFE_FREE ( line ) ;
1997-11-22 10:51:23 +03:00
if ( ! variables [ num_variables ] . name | |
! variables [ num_variables ] . value )
continue ;
1997-09-11 06:17:16 +04:00
1997-11-22 10:51:23 +03:00
unescape ( variables [ num_variables ] . value ) ;
unescape ( variables [ num_variables ] . name ) ;
1997-09-11 06:17:16 +04:00
1997-11-22 10:51:23 +03:00
# ifdef DEBUG_COMMENTS
printf ( " <!== POST var %s has value \" %s \" ==> \n " ,
variables [ num_variables ] . name ,
variables [ num_variables ] . value ) ;
1997-09-11 06:17:16 +04:00
# endif
1997-11-22 10:51:23 +03:00
num_variables + + ;
if ( num_variables = = MAX_VARIABLES ) break ;
}
}
1997-09-11 06:17:16 +04:00
fclose ( stdin ) ;
2000-04-11 11:14:12 +04:00
open ( " /dev/null " , O_RDWR ) ;
1997-11-22 10:51:23 +03:00
if ( ( s = query_string ) | | ( s = getenv ( " QUERY_STRING " ) ) ) {
for ( tok = strtok ( s , " &; " ) ; tok ; tok = strtok ( NULL , " &; " ) ) {
2001-07-04 11:36:09 +04:00
p = strchr_m ( tok , ' = ' ) ;
1997-11-22 10:51:23 +03:00
if ( ! p ) continue ;
* p = 0 ;
variables [ num_variables ] . name = strdup ( tok ) ;
variables [ num_variables ] . value = strdup ( p + 1 ) ;
if ( ! variables [ num_variables ] . name | |
! variables [ num_variables ] . value )
continue ;
unescape ( variables [ num_variables ] . value ) ;
unescape ( variables [ num_variables ] . name ) ;
# ifdef DEBUG_COMMENTS
printf ( " <!== Commandline var %s has value \" %s \" ==> \n " ,
variables [ num_variables ] . name ,
variables [ num_variables ] . value ) ;
# endif
num_variables + + ;
if ( num_variables = = MAX_VARIABLES ) break ;
}
}
# ifdef DEBUG_COMMENTS
printf ( " <!== End dump in cgi_load_variables() ==> \n " ) ;
# endif
2001-09-24 08:49:14 +04:00
/* variables from the client are in display charset - convert them
to our internal charset before use */
for ( i = 0 ; i < num_variables ; i + + ) {
pstring dest ;
convert_string ( CH_DISPLAY , CH_UNIX ,
2001-09-24 10:24:14 +04:00
variables [ i ] . name , - 1 ,
2001-09-24 08:49:14 +04:00
dest , sizeof ( dest ) ) ;
free ( variables [ i ] . name ) ;
variables [ i ] . name = strdup ( dest ) ;
convert_string ( CH_DISPLAY , CH_UNIX ,
2001-09-24 10:24:14 +04:00
variables [ i ] . value , - 1 ,
2001-09-24 08:49:14 +04:00
dest , sizeof ( dest ) ) ;
free ( variables [ i ] . value ) ;
variables [ i ] . value = strdup ( dest ) ;
}
1997-09-11 06:17:16 +04:00
}
/***************************************************************************
find a variable passed via CGI
1997-11-22 10:51:23 +03:00
Doesn ' t quite do what you think in the case of POST text variables , because
if they exist they might have a value of " " or even " " , depending on the
browser . Also doesn ' t allow for variables [ ] containing multiple variables
with the same name and the same or different values .
1997-09-11 06:17:16 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
char * cgi_variable ( char * name )
{
int i ;
for ( i = 0 ; i < num_variables ; i + + )
if ( strcmp ( variables [ i ] . name , name ) = = 0 )
return variables [ i ] . value ;
return NULL ;
}
1997-11-22 10:51:23 +03:00
/***************************************************************************
tell a browser about a fatal error in the http processing
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void cgi_setup_error ( char * err , char * header , char * info )
{
1998-11-21 04:41:14 +03:00
if ( ! got_request ) {
/* damn browsers don't like getting cut off before they give a request */
char line [ 1024 ] ;
while ( fgets ( line , sizeof ( line ) - 1 , stdin ) ) {
if ( strncasecmp ( line , " GET " , 4 ) = = 0 | |
strncasecmp ( line , " POST " , 5 ) = = 0 | |
strncasecmp ( line , " PUT " , 4 ) = = 0 ) {
break ;
}
}
}
2001-10-14 16:10:29 +04:00
d_printf ( " HTTP/1.0 %s \r \n %sConnection: close \r \n Content-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 ) ;
1998-11-21 04:41:14 +03:00
fclose ( stdin ) ;
fclose ( stdout ) ;
1997-11-22 10:51:23 +03:00
exit ( 0 ) ;
}
1998-11-14 05:10:55 +03:00
/***************************************************************************
tell a browser about a fatal authentication error
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void cgi_auth_error ( void )
{
if ( inetd_server ) {
cgi_setup_error ( " 401 Authorization Required " ,
" WWW-Authenticate: Basic realm= \" SWAT \" \r \n " ,
" You must be authenticated to use this service " ) ;
} else {
printf ( " Content-Type: text/html \r \n " ) ;
printf ( " \r \n <HTML><HEAD><TITLE>SWAT</TITLE></HEAD> \n " ) ;
printf ( " <BODY><H1>Installation Error</H1> \n " ) ;
printf ( " SWAT must be installed via inetd. It cannot be run as a CGI script<p> \n " ) ;
printf ( " </BODY></HTML> \r \n " ) ;
}
exit ( 0 ) ;
}
2001-05-17 15:45:58 +04:00
/***************************************************************************
authenticate when we are running as a CGI
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void cgi_web_auth ( void )
{
char * user = getenv ( " REMOTE_USER " ) ;
struct passwd * pwd ;
char * head = " Content-Type: text/html \r \n \r \n <HTML><BODY><H1>SWAT installation Error</H1> \n " ;
char * tail = " </BODY></HTML> \r \n " ;
if ( ! user ) {
printf ( " %sREMOTE_USER not set. Not authenticated by web server.<br>%s \n " ,
head , tail ) ;
exit ( 0 ) ;
}
pwd = getpwnam ( user ) ;
if ( ! pwd ) {
printf ( " %sCannot find user %s<br>%s \n " , head , user , tail ) ;
exit ( 0 ) ;
}
setuid ( 0 ) ;
setuid ( pwd - > pw_uid ) ;
if ( geteuid ( ) ! = pwd - > pw_uid | | getuid ( ) ! = pwd - > pw_uid ) {
printf ( " %sFailed to become user %s - uid=%d/%d<br>%s \n " ,
head , user , ( int ) geteuid ( ) , ( int ) getuid ( ) , tail ) ;
exit ( 0 ) ;
}
}
1998-11-14 05:10:55 +03:00
1997-11-22 10:51:23 +03:00
/***************************************************************************
decode a base64 string in - place - simple and slow algorithm
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void base64_decode ( char * s )
{
char * b64 = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ " ;
1998-09-01 10:01:19 +04:00
int bit_offset , byte_offset , idx , i , n ;
1997-11-22 10:51:23 +03:00
unsigned char * d = ( unsigned char * ) s ;
char * p ;
1998-09-01 10:01:19 +04:00
n = i = 0 ;
1997-11-22 10:51:23 +03:00
2001-07-04 11:36:09 +04:00
while ( * s & & ( p = strchr_m ( b64 , * s ) ) ) {
1997-11-22 10:51:23 +03:00
idx = ( int ) ( p - b64 ) ;
byte_offset = ( i * 6 ) / 8 ;
bit_offset = ( i * 6 ) % 8 ;
d [ byte_offset ] & = ~ ( ( 1 < < ( 8 - bit_offset ) ) - 1 ) ;
if ( bit_offset < 3 ) {
d [ byte_offset ] | = ( idx < < ( 2 - bit_offset ) ) ;
1998-09-01 10:01:19 +04:00
n = byte_offset + 1 ;
1997-11-22 10:51:23 +03:00
} else {
d [ byte_offset ] | = ( idx > > ( bit_offset - 2 ) ) ;
d [ byte_offset + 1 ] = 0 ;
d [ byte_offset + 1 ] | = ( idx < < ( 8 - ( bit_offset - 2 ) ) ) & 0xFF ;
1998-09-01 10:01:19 +04:00
n = byte_offset + 2 ;
1997-11-22 10:51:23 +03:00
}
s + + ; i + + ;
}
1998-09-01 10:01:19 +04:00
/* null terminate */
d [ n ] = 0 ;
1997-11-22 10:51:23 +03:00
}
/***************************************************************************
handle a http authentication line
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-11-12 06:06:00 +03:00
static BOOL cgi_handle_authorization ( char * line )
1997-11-22 10:51:23 +03:00
{
1998-11-12 06:06:00 +03:00
char * p , * user , * user_pass ;
1999-12-13 16:27:58 +03:00
struct passwd * pass = NULL ;
1997-11-22 10:51:23 +03:00
if ( strncasecmp ( line , " Basic " , 6 ) ) {
2000-11-01 22:43:53 +03:00
goto err ;
1997-11-22 10:51:23 +03:00
}
line + = 6 ;
while ( line [ 0 ] = = ' ' ) line + + ;
base64_decode ( line ) ;
2001-07-04 11:36:09 +04:00
if ( ! ( p = strchr_m ( line , ' : ' ) ) ) {
1998-11-12 06:06:00 +03:00
/*
* Always give the same error so a cracker
* cannot tell why we fail .
*/
2000-11-01 22:43:53 +03:00
goto err ;
1997-11-22 10:51:23 +03:00
}
* p = 0 ;
user = line ;
1998-11-12 06:06:00 +03:00
user_pass = p + 1 ;
2001-09-19 09:26:11 +04:00
1998-11-12 06:06:00 +03:00
/*
* Try and get the user from the UNIX password file .
*/
2001-09-19 09:26:11 +04:00
pass = sys_getpwnam ( user ) ;
1998-11-12 06:06:00 +03:00
/*
* Validate the password they have given .
*/
2001-09-19 09:26:11 +04:00
2001-09-20 17:15:35 +04:00
if NT_STATUS_IS_OK ( pass_check ( pass , user , user_pass ,
2001-09-19 09:26:11 +04:00
strlen ( user_pass ) , NULL , False ) ) {
if ( pass ) {
1998-11-12 06:06:00 +03:00
/*
2001-09-19 09:26:11 +04:00
* Password was ok .
1998-11-12 06:06:00 +03:00
*/
2001-09-19 09:26:11 +04:00
2001-09-20 17:15:35 +04:00
become_user_permanently ( pass - > pw_uid , pass - > pw_gid ) ;
2001-09-19 09:26:11 +04:00
/* Save the users name */
C_user = strdup ( user ) ;
return True ;
1998-11-12 06:06:00 +03:00
}
}
2001-09-19 09:26:11 +04:00
err :
2000-11-01 22:43:53 +03:00
cgi_setup_error ( " 401 Bad Authorization " , " " ,
" username or password incorrect " ) ;
return False ;
1997-11-22 10:51:23 +03:00
}
1998-11-12 00:37:44 +03:00
/***************************************************************************
is this root ?
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-11-12 02:47:03 +03:00
BOOL am_root ( void )
1998-11-12 00:37:44 +03:00
{
1998-11-12 06:06:00 +03:00
if ( geteuid ( ) = = 0 ) {
1998-11-12 00:37:44 +03:00
return ( True ) ;
} else {
return ( False ) ;
}
}
/***************************************************************************
return a ptr to the users name
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-11-14 05:10:55 +03:00
char * cgi_user_name ( void )
1998-11-12 00:37:44 +03:00
{
return ( C_user ) ;
}
1997-11-22 10:51:23 +03:00
/***************************************************************************
handle a file download
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void cgi_download ( char * file )
{
1998-09-02 00:11:54 +04:00
SMB_STRUCT_STAT st ;
1997-11-22 10:51:23 +03:00
char buf [ 1024 ] ;
1997-11-23 05:42:22 +03:00
int fd , l , i ;
1997-11-22 10:51:23 +03:00
char * p ;
2001-10-14 16:10:29 +04:00
char * lang ;
1997-11-22 10:51:23 +03:00
1997-11-23 05:42:22 +03:00
/* sanitise the filename */
for ( i = 0 ; file [ i ] ; i + + ) {
2001-07-04 11:36:09 +04:00
if ( ! isalnum ( ( int ) file [ i ] ) & & ! strchr_m ( " /.-_ " , file [ i ] ) ) {
1997-11-23 05:42:22 +03:00
cgi_setup_error ( " 404 File Not Found " , " " ,
" Illegal character in filename " ) ;
}
}
1997-11-22 10:51:23 +03:00
if ( ! file_exist ( file , & st ) ) {
cgi_setup_error ( " 404 File Not Found " , " " ,
" The requested file was not found " ) ;
}
2001-10-14 16:10:29 +04:00
fd = web_open ( file , O_RDONLY , 0 ) ;
1997-11-22 10:51:23 +03:00
if ( fd = = - 1 ) {
cgi_setup_error ( " 404 File Not Found " , " " ,
" The requested file was not found " ) ;
}
1998-10-26 13:55:29 +03:00
printf ( " HTTP/1.0 200 OK \r \n " ) ;
2001-07-04 11:36:09 +04:00
if ( ( p = strrchr_m ( file , ' . ' ) ) ) {
1998-03-10 07:56:58 +03:00
if ( strcmp ( p , " .gif " ) = = 0 ) {
1997-11-22 10:51:23 +03:00
printf ( " Content-Type: image/gif \r \n " ) ;
1998-03-10 07:56:58 +03:00
} else if ( strcmp ( p , " .jpg " ) = = 0 ) {
printf ( " Content-Type: image/jpeg \r \n " ) ;
2000-09-01 06:06:20 +04:00
} else if ( strcmp ( p , " .txt " ) = = 0 ) {
printf ( " Content-Type: text/plain \r \n " ) ;
1997-11-22 10:51:23 +03:00
} else {
printf ( " Content-Type: text/html \r \n " ) ;
}
}
1998-03-10 07:56:58 +03:00
printf ( " Expires: %s \r \n " , http_timestring ( time ( NULL ) + EXPIRY_TIME ) ) ;
2001-10-14 16:10:29 +04:00
lang = lang_tdb_current ( ) ;
if ( lang ) {
printf ( " Content-Language: %s \r \n " , lang ) ;
}
1997-11-22 10:51:23 +03:00
printf ( " Content-Length: %d \r \n \r \n " , ( int ) st . st_size ) ;
while ( ( l = read ( fd , buf , sizeof ( buf ) ) ) > 0 ) {
fwrite ( buf , 1 , l , stdout ) ;
}
close ( fd ) ;
exit ( 0 ) ;
}
2001-05-17 15:45:58 +04:00
2001-11-19 05:48:23 +03:00
/**
* @ brief Setup the CGI framework .
*
* Setup the cgi framework , handling the possibility that this program
* is either run as a true CGI program with a gateway to a web server , or
* is itself a mini web server .
* */
void cgi_setup ( const char * rootdir , int auth_required )
1997-11-22 10:51:23 +03:00
{
1998-11-12 06:06:00 +03:00
BOOL authenticated = False ;
1997-11-22 10:51:23 +03:00
char line [ 1024 ] ;
char * url = NULL ;
char * p ;
2001-10-14 16:10:29 +04:00
char * lang ;
1997-11-22 10:51:23 +03:00
if ( chdir ( rootdir ) ) {
cgi_setup_error ( " 400 Server Error " , " " ,
" chdir failed - the server is not configured correctly " ) ;
}
2001-09-20 17:15:35 +04:00
/* Handle the possability we might be running as non-root */
sec_init ( ) ;
2001-10-14 16:10:29 +04:00
if ( ( lang = getenv ( " HTTP_ACCEPT_LANGUAGE " ) ) ) {
/* if running as a cgi program */
web_set_lang ( lang ) ;
}
2001-09-24 19:55:09 +04:00
1998-11-14 05:10:55 +03:00
/* maybe we are running under a web server */
1997-11-22 10:51:23 +03:00
if ( getenv ( " CONTENT_LENGTH " ) | | getenv ( " REQUEST_METHOD " ) ) {
1998-11-14 05:10:55 +03:00
if ( auth_required ) {
2001-05-17 15:45:58 +04:00
cgi_web_auth ( ) ;
1998-11-12 00:37:44 +03:00
}
1997-11-22 10:51:23 +03:00
return ;
}
1998-11-14 05:10:55 +03:00
inetd_server = True ;
1998-11-21 04:41:14 +03:00
if ( ! check_access ( 1 , lp_hostsallow ( - 1 ) , lp_hostsdeny ( - 1 ) ) ) {
cgi_setup_error ( " 400 Server Error " , " " ,
" Samba is configured to deny access from this client \n <br>Check your \" hosts allow \" and \" hosts deny \" options in smb.conf " ) ;
}
1997-11-22 10:51:23 +03:00
/* we are a mini-web server. We need to read the request from stdin
and handle authentication etc */
while ( fgets ( line , sizeof ( line ) - 1 , stdin ) ) {
if ( line [ 0 ] = = ' \r ' | | line [ 0 ] = = ' \n ' ) break ;
if ( strncasecmp ( line , " GET " , 4 ) = = 0 ) {
1998-11-21 04:41:14 +03:00
got_request = True ;
1997-11-22 10:51:23 +03:00
url = strdup ( & line [ 4 ] ) ;
} else if ( strncasecmp ( line , " POST " , 5 ) = = 0 ) {
1998-11-21 04:41:14 +03:00
got_request = True ;
1997-11-22 10:51:23 +03:00
request_post = 1 ;
url = strdup ( & line [ 5 ] ) ;
} else if ( strncasecmp ( line , " PUT " , 4 ) = = 0 ) {
1998-11-21 04:41:14 +03:00
got_request = True ;
1997-11-22 10:51:23 +03:00
cgi_setup_error ( " 400 Bad Request " , " " ,
" This server does not accept PUT requests " ) ;
} else if ( strncasecmp ( line , " Authorization: " , 15 ) = = 0 ) {
authenticated = cgi_handle_authorization ( & line [ 15 ] ) ;
} else if ( strncasecmp ( line , " Content-Length: " , 16 ) = = 0 ) {
content_length = atoi ( & line [ 16 ] ) ;
2001-09-24 19:55:09 +04:00
} else if ( strncasecmp ( line , " Accept-Language: " , 17 ) = = 0 ) {
2001-10-14 16:10:29 +04:00
web_set_lang ( & line [ 17 ] ) ;
1997-11-22 10:51:23 +03:00
}
/* ignore all other requests! */
}
1998-03-08 17:31:50 +03:00
if ( auth_required & & ! authenticated ) {
1998-11-14 05:10:55 +03:00
cgi_auth_error ( ) ;
1997-11-22 10:51:23 +03:00
}
if ( ! url ) {
cgi_setup_error ( " 400 Bad Request " , " " ,
" You must specify a GET or POST request " ) ;
}
/* trim the URL */
2001-07-04 11:36:09 +04:00
if ( ( p = strchr_m ( url , ' ' ) ) | | ( p = strchr_m ( url , ' \t ' ) ) ) {
1997-11-22 10:51:23 +03:00
* p = 0 ;
}
2001-07-04 11:36:09 +04:00
while ( * url & & strchr_m ( " \r \n " , url [ strlen ( url ) - 1 ] ) ) {
1997-11-22 10:51:23 +03:00
url [ strlen ( url ) - 1 ] = 0 ;
}
/* anything following a ? in the URL is part of the query string */
2001-07-04 11:36:09 +04:00
if ( ( p = strchr_m ( url , ' ? ' ) ) ) {
1997-11-22 10:51:23 +03:00
query_string = p + 1 ;
* p = 0 ;
}
1999-12-13 16:27:58 +03:00
string_sub ( url , " /swat/ " , " " , 0 ) ;
1998-09-02 06:02:30 +04:00
1999-12-13 16:27:58 +03:00
if ( url [ 0 ] ! = ' / ' & & strstr ( url , " .. " ) = = 0 & & file_exist ( url , NULL ) ) {
1998-09-02 06:02:30 +04:00
cgi_download ( url ) ;
1997-11-22 10:51:23 +03:00
}
1998-10-26 13:55:29 +03:00
printf ( " HTTP/1.0 200 OK \r \n Connection: close \r \n " ) ;
1998-03-10 07:56:58 +03:00
printf ( " Date: %s \r \n " , http_timestring ( time ( NULL ) ) ) ;
1998-03-14 07:13:24 +03:00
baseurl = " " ;
pathinfo = url + 1 ;
1997-11-22 10:51:23 +03:00
}
1997-11-23 05:42:22 +03:00
1998-03-08 17:14:49 +03:00
/***************************************************************************
return the current pages URL
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
char * cgi_baseurl ( void )
{
1998-11-14 05:10:55 +03:00
if ( inetd_server ) {
1998-03-14 07:13:24 +03:00
return baseurl ;
}
return getenv ( " SCRIPT_NAME " ) ;
1998-03-08 17:14:49 +03:00
}
1998-03-14 07:13:24 +03:00
/***************************************************************************
return the current pages path info
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
char * cgi_pathinfo ( void )
{
char * r ;
1998-11-14 05:10:55 +03:00
if ( inetd_server ) {
1998-03-14 07:13:24 +03:00
return pathinfo ;
}
r = getenv ( " PATH_INFO " ) ;
if ( ! r ) return " " ;
if ( * r = = ' / ' ) r + + ;
return r ;
}
1998-03-17 15:31:43 +03:00
/***************************************************************************
return the hostname of the client
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
char * cgi_remote_host ( void )
{
1998-11-14 05:10:55 +03:00
if ( inetd_server ) {
2000-04-11 17:55:53 +04:00
return get_socket_name ( 1 ) ;
1998-03-17 15:31:43 +03:00
}
return getenv ( " REMOTE_HOST " ) ;
}
/***************************************************************************
return the hostname of the client
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
char * cgi_remote_addr ( void )
{
1998-11-14 05:10:55 +03:00
if ( inetd_server ) {
2000-04-11 17:55:53 +04:00
return get_socket_addr ( 1 ) ;
1998-03-17 15:31:43 +03:00
}
return getenv ( " REMOTE_ADDR " ) ;
}
1998-03-18 10:33:11 +03:00
/***************************************************************************
return True if the request was a POST
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL cgi_waspost ( void )
{
1998-11-14 05:10:55 +03:00
if ( inetd_server ) {
1998-03-18 10:33:11 +03:00
return request_post ;
}
return strequal ( getenv ( " REQUEST_METHOD " ) , " POST " ) ;
}