blob: 749cf03dbd36f09edb92230b5a1d228a378f5620 [file] [log] [blame]
/**************************************************************************
** ftpd.c
** Rumata@mg
** 13.6.1999
**
** Ermittlung der Zugriffsrechte aus den Userdaten.
**
** Dieses Objekt wird vom ftpimp aus aufgerufen, der wiederum vom master
** aufgerufen wird, um die Zugriffsrechte zu pruefen.
**
** Fuktionsweise:
** + Im Master wird vom UNIX-ftpd aus FtpAccess (/secure/master/network)
** aufgerufen.
** + Dieses ruft dann, sobald ein Zugriff erkannt wird
** QueryRead, QueryWrite oder QueryDir auf.
** + Diese fragen den Master, ob der Zugriff legal ist.
** + QueryDir liefert auch gleich das Ergebnis mit.
**
** Um ftp-zugriffe überwachen zu können, kann der ftpd eine liste der
** ueberwachten spieler liefern und deren Zugriffe auf dem FTP Kanal ausgeben.
**
** add( name, zeit ) - FTP Zugriffe des Spielers 'name' werden protokolliert.
** Nach 'zeit' wird dieser Zugriff automatisch beendet.
** Ist 'zeit' <= 0, wir auf ewig ueberwacht.
** sub( name ) - FTP Snoop fuer Spieler 'name' direkt aufheben.
** list() - Mapping der ueberwachten Spieler zurueckgeben.
**
** FILES:
** /secure/master/network.c
** /secure/ftpd.c
** /std/shells/filesys/ftpimp.c
** /secure/ARCH/ftpd.o
** /p/daemon/channeld.init
**
***************************************************************************/
#include "/secure/wizlevels.h"
#include "/sys/daemon.h"
#define FTPDSAVE "/secure/ARCH/ftpd"
#define FTPD_CH "FTP"
#define BBMASTER "/secure/bbmaster"
mapping monitored;
// Zu jedem Spielernamen wird vermerkt, wie lange die Ueberwachung dauern soll.
// Zahlen <= 0 bedeuten fuer immer.
nomask void create() {
if( clonep(this_object()) ) {
destruct( this_object() );
return;
}
seteuid( getuid() );
if( !restore_object(FTPDSAVE) )
monitored = ([]);
}
nomask int player_exists( string user ) {
user = lower_case(user);
if( !stringp( user ) || sizeof( user ) < 1 ) return 0;
return file_size( "/save/"+user[0..0]+"/"+user+".o" ) > 0;
}
nomask varargs int add( string user, int timeout ) {
if( !ARCH_SECURITY ) return -1;
if( !player_exists(user) ) return -2;
monitored[user] = timeout;
save_object( FTPDSAVE );
return 0;
}
nomask int sub( string user ) {
if( !ARCH_SECURITY ) return -1;
if( !player_exists(user) ) return -2;
monitored -= ([ user ]);
save_object( FTPDSAVE );
return 0;
}
nomask mixed list() {
if( !ARCH_SECURITY ) return -1;
return deep_copy(monitored);
}
#define NEWIMP "yes"
private object findFtpImpFor( string user ) {
#ifdef NEWIMP
return "/secure/impfetch"->impFor( lower_case(user) );
#else
object imp;
string fname;
user = lower_case( user );
fname = "/ftpimp:" + user;
imp = find_object( fname );
if( !objectp(imp) ) {
imp = clone_object( "secure/ftpimp" );
imp->SetUser(user);
rename_object( imp, fname );
}
return imp;
#endif
}
private nomask void msg( string user, string m ) {
int timeout;
object r;
if( !stringp(user) ) return;
m += "\n";
if( (r=find_player("rumata")) && user=="atamur" ) {
timeout = CHMASTER->send(FTPD_CH,findFtpImpFor(user), m );
tell_object( r, sprintf("%O\n", findFtpImpFor(user) ) );
}
BBMASTER->ftpbb(user,m);
if( !member(monitored,user) ) return;
timeout = monitored[user];
if( timeout > 0 && timeout < time() ) {
sub( user );
return;
}
CHMASTER->send(FTPD_CH,findFtpImpFor(user), m );
}
nomask int secure() {
return previous_object()==find_object(MASTER);
}
nomask mixed QueryRead( string user, string file ) {
if( !secure() ) return -1;
if( (IS_WIZARD(user) || file[0..4]=="/open")
&& file[0] == '/'
&& MASTER->valid_read(file, user, "read_file", 0)
) {
msg( user, "read " + file );
return "OK";
} else {
return "FAIL";
}
}
nomask mixed QueryWrite( string user, string file ) {
if( !secure() ) return -1;
if( file[0] == '/'
&& MASTER->valid_write( file, user, "write_file", 0)
) {
msg( user, "write " + file );
return "OK";
} else {
return "FAIL";
}
}
#define DBG(x) if(find_player("rumata")){tell_object(find_player("rumata"),"FTPD:"+x+"\n");}
//nomask mixed QueryDir( string user, string file ) {
// string reply;
// object imp;
//
// if( !secure() ) return -1;
// reply = QueryRead( user, file );
// if( reply=="FAIL" ) return -1;
//
// imp = findFtpImpFor( user );
// if( !objectp(imp) ) return -1; // should never happen
//
// return imp->GetDir( file );
//}
nomask mixed QueryDir( string user, string file ) {
if( !secure() ) return -1;
if( file[0] == '/'
&& MASTER->valid_read( file+"/*", user, "get_dir", 0))
return "OK";
else
return "FAIL";
}