diff --git a/smart.cmake b/smart.cmake index b16fd43..68d43a6 100755 --- a/smart.cmake +++ b/smart.cmake @@ -1,12 +1,13 @@ #!/usr/bin/perl -# + +# # SMArT -# -# Main program file -# -# Copyright 2001 Wilmer van der Gaast -# -# +# +# Main web frontend +# +# Copyright 2001 Wilmer van der Gaast (lintux@lintux.cx) +# +# # 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 @@ -25,288 +26,295 @@ $redirected = 0; -$server_id = 'Server: SMArT/Perl/@MARS_NWE_VERSION@'; +$smart_version = '@MARS_NWE_VERSION@'; +$server_id = 'Server: SMArT/Perl/' . $smart_version; -do( '@MARS_NWE_INSTALL_FULL_CONFDIR@/smart.conf' ) - or die "Could not load @MARS_NWE_INSTALL_FULL_CONFDIR@/smart.conf: $@ $!"; - -close( STDERR ); -open( STDERR, '>>' . $smart_log_path ) - or die "Could not open $smart_log_path: $!"; +if( ! do('@MARS_NWE_INSTALL_FULL_CONFDIR@/smart.conf') ) +{ + die "Could not load @MARS_NWE_INSTALL_FULL_CONFDIR@/smart.conf: $@ $!"; +} $ENV{HOME} = '@MARS_NWE_INSTALL_FULL_CONFDIR@'; $smart_libexec_dir = '@MARS_NWE_INSTALL_FULL_LIBEXECDIR@'; $smart_libexec_dir =~ s#/*$##; +close( STDERR ); +open( STDERR, '>>' . $smart_log_path ) or die "Could not open $smart_log_path: $!"; +select( STDERR ); $| = 1; +select( STDOUT ); $| = 1; + +sub log_timestamp() +{ + my @t = localtime( time() ); + return sprintf( + '%04d-%02d-%02d %02d:%02d:%02d', + $t[5] + 1900, $t[4] + 1, $t[3], + $t[2], $t[1], $t[0] + ); +} + +sub log_msg( $$ ) +{ + my( $level, $msg ) = @_; + print STDERR '[' . log_timestamp() . '] [' . $level . '] [SMArT ' . $smart_version . '] ' . $msg . "\n"; +} + +sub log_info( $ ) +{ + log_msg( 'INFO', $_[0] ); +} + +sub log_error( $ ) +{ + log_msg( 'ERROR', $_[0] ); +} + +log_info( 'starting' ); +log_info( 'loaded configuration from ' . '@MARS_NWE_INSTALL_FULL_CONFDIR@/smart.conf' ); + $l = ; +if( ! defined( $l ) ) +{ + log_error( 'no request line received on stdin' ); + exit( 1 ); +} $l =~ s/[\n\r]//g; +log_info( 'request: ' . $l ); + @c = split( ' ', $l ); -if( scalar( @c ) > 2 ) -{ - while( keys( %h ) < 15 ) # Who would ever want to send more headers??? - { - $l = ; - $l =~ s/[\n\r]//g; - if( $l eq '' ) - { last; } - $n = $l; - $n =~ s/:[^:]*$//g; - $v = $l; - $v =~ s/^[^:]*://g; - $h{$n} = $v; - } -} - -$c[0] = uc( $c[0] ); - -if( $h{Authorization} eq '' ) - { error( 401 ); } -else -{ - @s = split( ' ', $h{Authorization} ); - if( $s[0] ne 'Basic' or length( $h{Authorization} ) > 80 ) # We can't be too careful, can we... - { error( 401 ); } - else - { - $s[1] =~ tr#A-Za-z0-9+/##cd; - $s[1] =~ tr#A-Za-z0-9+/# -_#; - $s[1] = pack( 'c', 32 + 0.75 * length( $s[1] ) ) . $s[1]; - $s[1] = unpack( 'u', $s[1] ); - $s[1] =~ s/[\r\n]//g; - @l = split( ':', $s[1] ); - if( $l[0] ne 'root' ) - { error( 401 ); } - else - { if( $x = system( $smart_check_login, @l ) ) - { error( 401 ); } } - } -} - -if( $c[0] ne 'GET' ) -{ - error( 501 ); -} - -@p = split( '\?', $c[1] ); $cc = $c[1]; -$cc =~ s/[^\?]*\?//; -$c = substr( shift( @p ), 1 ); -@p = split( '&', $p[0] ); -foreach $p ( @p ) -{ - $n = $p; - $n =~ s/=.*//; - $v = $p; - $v =~ s/.*=//; - $v =~ s/\+/ /g; - $v =~ s/%([0-9A-F][0-9A-F])/pack('c',hex($1))/gie; - $p{$n} = $v; -} -@c = split( '/', $c ); +@c = split( '/', $c[1] ); +shift( @c ); -if( $c[0] eq 'apply' ) +sub error( $ ) { - do( $smart_libexec_dir . '/readconfig.pl' ); - do( $smart_libexec_dir . '/apply.pl' ); - handle_request(); - exit; -} -elsif( $c[0] eq 'settings' ) -{ - do( $smart_libexec_dir . '/readconfig.pl' ); -} + my( $e ) = @_; -drop_root(); + log_error( 'HTTP error ' . $e . ' for request ' . $cc ); -if( $c[0] eq '' ) -{ - print < - -SMArT - - - - - + +

Error $e

+ EOF - exit; -} -elsif( $c[0] eq 'static' ) -{ - do( $smart_libexec_dir . '/static.pl' ); -} -elsif( $c[0] eq 'settings' ) -{ - do( $smart_libexec_dir . '/settings.pl' ); -} -else -{ - error( 500 ); -} - -handle_request(); -exit; - -########################################## -##### END OF MAIN PROCEDURES FOLLOW ##### -########################################## - -sub error( $ ) -{ - if( $_[0] eq '401' ) - { - print < $d[0], uid => $d[2] } ); - } - return( sort( { $a->{"name"} cmp $b->{"name"} } @c ) ); -} - -sub unix_grouplist() -{ - my( @c, @d, %e ); - - while( @d = getgrent ) - { - unshift( @c, { name => $d[0], gid => $d[2] } ); - } - return( sort( { $a->{"name"} cmp $b->{"name"} } @c ) ); + exit; } sub redirect( $ ) { - if( $redirected != 0 ) - { return( 0 ); } - $redirected = 1; - print < ); - close( SFILE ); - - $line =~ s/\/.*//; - return( $line ); -} - -sub get_bindery_password -{ - open( SFILE, '<' . $smart_nwclient_path ); - chomp( $line = ); - close( SFILE ); - - $line =~ s/.* //; - return( $line ); -} - -sub read_property_string -{ - my @x = split( "\n", `nwbpvalues -c -o $_[0] -t $_[1] -p $_[2] -S $server` ); - my( $i, $s ); - - $i = 5; - while( hex( $x[$i] ) > 0 ) + if( $> == 0 ) + { + my $uid = getpwnam( $nonroot_user ); + if( ! defined( $uid ) ) { - $s .= pack( 'c', hex( $x[$i] ) ); - $i ++; + log_error( 'could not resolve non-root user ' . $nonroot_user ); + error( 500 ); } - - return( $s ); + $> = $uid; + } } -sub read_property_list +sub get_server() { - my @x = split( "\n", `nwbpvalues -c -o $_[0] -t $_[1] -p $_[2] -S $server` ); - my( $i, @l ); - - $i = 6; - while( $x[$i] ne '' ) - { - unshift( @l, $x[$i] ); - $i += 2; - } - - return( @l ); + open( SFILE, '<' . $smart_nwclient_path ) or do { + log_error( 'could not open ' . $smart_nwclient_path . ': ' . $! ); + return ''; + }; + chomp( $line = ); + close( SFILE ); + + $line =~ s/\/.*//; + return( $line ); } -sub write_property_string +sub get_bindery_password() { - open( FILE, '|' . 'nwbpset -S ' . $server ); - print FILE < ); + close( SFILE ); + + $line =~ s/.* //; + return( $line ); +} + +sub unix_userlist() +{ + my( @l, @r, $u ); + open( FILE, ' ) + { + chomp; + @l = split( /:/ ); + $u = {}; + $u->{name} = $l[0]; + $u->{uid} = $l[2]; + push( @r, $u ); + } + close( FILE ); + return( @r ); +} + +sub unix_grouplist() +{ + my( @l, @r, $u ); + open( FILE, ' ) + { + chomp; + @l = split( /:/ ); + $u = {}; + $u->{name} = $l[0]; + $u->{gid} = $l[2]; + push( @r, $u ); + } + close( FILE ); + return( @r ); +} + +sub write_property_string( $$$$$ ) +{ + my( $obj, $type, $prop, $seg, $len, $str ) = @_; + + open( FILE, '|' . 'nwbpset -S ' . get_server() ) or return; + print FILE < = getpwnam( $nonroot_user ); + my( $obj, $type, $prop ) = @_; + my( @l, $s ); + + open( FILE, 'nwbpvalues -S ' . get_server() . ' -o ' . $obj . ' -t ' . $type . ' -p ' . $prop . ' |' ) or return ''; + @l = ; + close( FILE ); + + $s = join( '', @l ); + $s =~ s/[\r\n]+$//g; + return( $s ); +} + +sub authenticate() +{ + my( @h, $auth, @l, $x ); + + while( $l = ) + { + $l =~ s/[\n\r]//g; + last if $l eq ''; + push( @h, $l ); + } + + ($auth) = grep( /^Authorization: /i, @h ); + if( $auth eq '' ) + { + print <