00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <signal.h>
00034 #include <unistd.h>
00035 #include <grp.h>
00036 #include <pwd.h>
00037
00038 #include <iostream>
00039 #include <fstream>
00040 #include <cstdlib>
00041
00042 using std::cout ;
00043 using std::cerr ;
00044 using std::endl ;
00045 using std::ios ;
00046 using std::ofstream ;
00047
00048 #include "config.h"
00049
00050 #include "ServerApp.h"
00051 #include "ServerExitConditions.h"
00052 #include "TheBESKeys.h"
00053 #include "SocketListener.h"
00054 #include "TcpSocket.h"
00055 #include "UnixSocket.h"
00056 #include "BESServerHandler.h"
00057 #include "BESError.h"
00058 #include "PPTServer.h"
00059 #include "BESMemoryManager.h"
00060 #include "BESDebug.h"
00061 #include "BESServerUtils.h"
00062
00063 #include "BESDefaultModule.h"
00064 #include "BESDefaultCommands.h"
00065
00066 ServerApp::ServerApp()
00067 : BESModuleApp(),
00068 _portVal( 0 ),
00069 _gotPort( false ),
00070 _unixSocket( "" ),
00071 _secure( false ),
00072 _mypid( 0 ),
00073 _ts( 0 ),
00074 _us( 0 ),
00075 _ps( 0 )
00076 {
00077 _mypid = getpid() ;
00078 }
00079
00080 ServerApp::~ServerApp()
00081 {
00082 }
00083
00084 void
00085 ServerApp::signalTerminate( int sig )
00086 {
00087 if( sig == SIGTERM )
00088 {
00089 BESApp::TheApplication()->terminate( sig ) ;
00090 exit( SERVER_EXIT_NORMAL_SHUTDOWN ) ;
00091 }
00092 }
00093
00094 void
00095 ServerApp::signalInterrupt( int sig )
00096 {
00097 if( sig == SIGINT )
00098 {
00099 BESApp::TheApplication()->terminate( sig ) ;
00100 exit( SERVER_EXIT_NORMAL_SHUTDOWN ) ;
00101 }
00102 }
00103
00104 void
00105 ServerApp::signalRestart( int sig )
00106 {
00107 if( sig == SIGUSR1 )
00108 {
00109 BESApp::TheApplication()->terminate( sig ) ;
00110 exit( SERVER_EXIT_RESTART ) ;
00111 }
00112 }
00113
00114 void
00115 ServerApp::set_group_id()
00116 {
00117 #if !defined(OS2) && !defined(TPF)
00118
00119
00120
00121
00122
00123 BESDEBUG( "server", "ServerApp: Setting group id ... " )
00124 bool found = false ;
00125 string key = "BES.Group" ;
00126 string group_str = TheBESKeys::TheKeys()->get_key( key, found ) ;
00127 if( !found || group_str.empty() )
00128 {
00129 BESDEBUG( "server", "FAILED" << endl ) ;
00130 cerr << "FAILED: Group not specified in BES configuration file"
00131 << endl ;
00132 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00133 }
00134 BESDEBUG( "server", "to " << group_str << " ... " )
00135
00136 gid_t new_gid = 0 ;
00137 if( group_str[0] == '#' )
00138 {
00139
00140 const char *group_c = group_str.c_str() ;
00141 group_c++ ;
00142 new_gid = atoi( group_c ) ;
00143 }
00144 else
00145 {
00146
00147 struct group *ent ;
00148 ent = getgrnam( group_str.c_str() ) ;
00149 if( !ent )
00150 {
00151 BESDEBUG( "server", "FAILED" << endl ) ;
00152 cerr << "FAILED: Group " << group_str << " does not exist" << endl ;
00153 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00154 }
00155 new_gid = ent->gr_gid ;
00156 }
00157
00158 if( new_gid < 1 )
00159 {
00160 BESDEBUG( "server", "FAILED" << endl ) ;
00161 cerr << "FAILED: Group id " << new_gid
00162 << " not a valid group id for BES" << endl ;
00163 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00164 }
00165
00166 BESDEBUG( "server", "to id " << new_gid << " ... " )
00167 if( setgid( new_gid ) == -1 )
00168 {
00169 BESDEBUG( "server", "FAILED" << endl ) ;
00170 cerr << "FAILED: unable to set the group id to " << new_gid << endl ;
00171 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00172 }
00173
00174 BESDEBUG( "server", "OK" << endl ) ;
00175 #else
00176 BESDEBUG( "server", "ServerApp: Groups not supported in this OS" )
00177 #endif
00178 }
00179
00180 void
00181 ServerApp::set_user_id()
00182 {
00183 BESDEBUG( "server", "ServerApp: Setting user id ... " )
00184
00185
00186
00187
00188
00189 bool found = false ;
00190 string key = "BES.User" ;
00191 string user_str = TheBESKeys::TheKeys()->get_key( key, found ) ;
00192 if( !found || user_str.empty() )
00193 {
00194 BESDEBUG( "server", "FAILED" << endl ) ;
00195 cerr << "FAILED: User not specified in BES configuration file"
00196 << endl ;
00197 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00198 }
00199 BESDEBUG( "server", "to " << user_str << " ... " )
00200
00201 uid_t new_id = 0 ;
00202 if( user_str[0] == '#' )
00203 {
00204 const char *user_str_c = user_str.c_str() ;
00205 user_str_c++ ;
00206 new_id = atoi( user_str_c ) ;
00207 }
00208 else
00209 {
00210 struct passwd *ent ;
00211 ent = getpwnam( user_str.c_str() ) ;
00212 if( !ent )
00213 {
00214 BESDEBUG( "server", "FAILED" << endl ) ;
00215 cerr << "FAILED: Bad user name specified: "
00216 << user_str << endl ;
00217 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00218 }
00219 new_id = ent->pw_uid ;
00220 }
00221
00222
00223 if( !new_id )
00224 {
00225 BESDEBUG( "server", "FAILED" << endl ) ;
00226 cerr << "FAILED: BES can not run as root" << endl ;
00227 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00228 }
00229
00230 BESDEBUG( "server", "to " << new_id << " ... " )
00231 if( setuid( new_id ) == -1 )
00232 {
00233 BESDEBUG( "server", "FAILED" << endl ) ;
00234 cerr << "FAILED: Unable to set user id to "
00235 << new_id << endl ;
00236 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00237 }
00238 }
00239
00240 int
00241 ServerApp::initialize( int argc, char **argv )
00242 {
00243 uid_t curr_euid = geteuid() ;
00244 #ifndef BES_DEVELOPER
00245
00246 if( curr_euid )
00247 {
00248 cerr << "FAILED: Must be root to run BES" << endl ;
00249 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00250 }
00251 #else
00252 cerr << "Developer Mode: not testing if BES is run by root" << endl ;
00253 #endif
00254
00255 int c = 0 ;
00256 bool needhelp = false ;
00257 string dashi ;
00258 string dashc ;
00259
00260
00261
00262 while( ( c = getopt( argc, argv, "hvsd:c:p:u:i:r:" ) ) != EOF )
00263 {
00264 switch( c )
00265 {
00266 case 'i':
00267 dashi = optarg ;
00268 break ;
00269 case 'c':
00270 dashc = optarg ;
00271 break ;
00272 case 'r':
00273 break ;
00274 case 'p':
00275 _portVal = atoi( optarg ) ;
00276 _gotPort = true ;
00277 break ;
00278 case 'u':
00279 _unixSocket = optarg ;
00280 break ;
00281 case 'd':
00282 BESDebug::SetUp( optarg ) ;
00283 break ;
00284 case 'v':
00285 BESServerUtils::show_version( BESApp::TheApplication()->appName() ) ;
00286 break ;
00287 case 's':
00288 _secure = true ;
00289 break ;
00290 case 'h':
00291 case '?':
00292 default:
00293 needhelp = true ;
00294 break ;
00295 }
00296 }
00297
00298
00299
00300 if( !dashc.empty() )
00301 {
00302 TheBESKeys::ConfigFile = dashc ;
00303 }
00304
00305
00306
00307
00308 if( dashc.empty() && !dashi.empty() )
00309 {
00310 if( dashi[dashi.length()-1] != '/' )
00311 {
00312 dashi += '/' ;
00313 }
00314 string conf_file = dashi + "etc/bes/bes.conf" ;
00315 TheBESKeys::ConfigFile = conf_file ;
00316 }
00317
00318 bool found = false ;
00319 string port_key = "BES.ServerPort" ;
00320 if( !_gotPort )
00321 {
00322 string sPort = TheBESKeys::TheKeys()->get_key( port_key, found ) ;
00323 if( found )
00324 {
00325 _portVal = atoi( sPort.c_str() ) ;
00326 if( _portVal != 0 )
00327 {
00328 _gotPort = true ;
00329 }
00330 }
00331 }
00332
00333 found = false ;
00334 string socket_key = "BES.ServerUnixSocket" ;
00335 if( _unixSocket == "" )
00336 {
00337 _unixSocket = TheBESKeys::TheKeys()->get_key( socket_key, found ) ;
00338 }
00339
00340 if( !_gotPort && _unixSocket == "" )
00341 {
00342 cout << endl << "Must specify either a tcp port"
00343 << " or a unix socket or both" << endl ;
00344 cout << "Please specify on the command line with"
00345 << " -p <port> -u <unix_socket> "
00346 << endl
00347 << "Or specify in the bes configuration file with "
00348 << port_key << " and/or " << socket_key
00349 << endl << endl ;
00350 BESServerUtils::show_usage( BESApp::TheApplication()->appName() ) ;
00351 }
00352
00353 found = false ;
00354 if( _secure == false )
00355 {
00356 string key = "BES.ServerSecure" ;
00357 string isSecure = TheBESKeys::TheKeys()->get_key( key, found ) ;
00358 if( isSecure == "Yes" || isSecure == "YES" || isSecure == "yes" )
00359 {
00360 _secure = true ;
00361 }
00362 }
00363
00364 BESDEBUG( "server", "ServerApp: Registering signal SIGTERM ... " )
00365 if( signal( SIGTERM, signalTerminate ) == SIG_ERR )
00366 {
00367 BESDEBUG( "server", "FAILED" << endl ) ;
00368 cerr << "FAILED: Can not register SIGTERM signal handler" << endl ;
00369 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00370 }
00371 BESDEBUG( "server", "OK" << endl ) ;
00372
00373 BESDEBUG( "server", "ServerApp: Registering signal SIGINT ... " )
00374 if( signal( SIGINT, signalInterrupt ) == SIG_ERR )
00375 {
00376 BESDEBUG( "server", "FAILED" << endl ) ;
00377 cerr << "FAILED: Can not register SIGINT signal handler" << endl ;
00378 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00379 }
00380 BESDEBUG( "server", "OK" << endl ) ;
00381
00382 BESDEBUG( "server", "ServerApp: Registering signal SIGUSR1 ... " )
00383 if( signal( SIGUSR1, signalRestart ) == SIG_ERR )
00384 {
00385 BESDEBUG( "server", "FAILED" << endl ) ;
00386 cerr << "FAILED: Can not register SIGUSR1 signal handler" << endl ;
00387 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00388 }
00389 BESDEBUG( "server", "OK" << endl ) ;
00390
00391 BESDEBUG( "server", "ServerApp: initializing default module ... " )
00392 BESDefaultModule::initialize( argc, argv ) ;
00393 BESDEBUG( "server", "OK" << endl ) ;
00394
00395 BESDEBUG( "server", "ServerApp: initializing default commands ... " )
00396 BESDefaultCommands::initialize( argc, argv ) ;
00397 BESDEBUG( "server", "OK" << endl ) ;
00398
00399 int ret = BESModuleApp::initialize( argc, argv ) ;
00400
00401 BESDEBUG( "server", "ServerApp: initialized settings:" << *this ) ;
00402
00403 if( needhelp )
00404 {
00405 BESServerUtils::show_usage( BESApp::TheApplication()->appName() ) ;
00406 }
00407
00408 if( curr_euid == 0 )
00409 {
00410
00411
00412
00413 #ifdef BES_DEVELOPER
00414 cerr << "Developer Mode: Running as root - setting group and user ids"
00415 << endl ;
00416 #endif
00417 set_group_id() ;
00418 set_user_id() ;
00419 }
00420 else
00421 {
00422 cerr << "Developer Mode: Not setting group or user ids" << endl ;
00423 }
00424
00425 return ret ;
00426 }
00427
00428 int
00429 ServerApp::run()
00430 {
00431 try
00432 {
00433 BESDEBUG( "server", "ServerApp: initializing memory pool ... " )
00434 BESMemoryManager::initialize_memory_pool() ;
00435 BESDEBUG( "server", "OK" << endl ) ;
00436
00437 SocketListener listener ;
00438
00439 if( _portVal )
00440 {
00441 _ts = new TcpSocket( _portVal ) ;
00442 listener.listen( _ts ) ;
00443 BESDEBUG( "server", "ServerApp: listening on port (" << _portVal << ")" << endl )
00444 }
00445
00446 if( !_unixSocket.empty() )
00447 {
00448 _us = new UnixSocket( _unixSocket ) ;
00449 listener.listen( _us ) ;
00450 BESDEBUG( "server", "ServerApp: listening on unix socket (" << _unixSocket << ")" << endl )
00451 }
00452
00453 BESServerHandler handler ;
00454
00455 _ps = new PPTServer( &handler, &listener, _secure ) ;
00456 _ps->initConnection() ;
00457 }
00458 catch( BESError &se )
00459 {
00460 cerr << se.get_message() << endl ;
00461 return 1 ;
00462 }
00463 catch( ... )
00464 {
00465 cerr << "caught unknown exception" << endl ;
00466 return 1 ;
00467 }
00468
00469 return 0 ;
00470 }
00471
00472 int
00473 ServerApp::terminate( int sig )
00474 {
00475 pid_t apppid = getpid() ;
00476 if( apppid == _mypid )
00477 {
00478 if( _ps )
00479 {
00480 _ps->closeConnection() ;
00481 delete _ps ;
00482 }
00483 if( _ts )
00484 {
00485 _ts->close() ;
00486 delete _ts ;
00487 }
00488 if( _us )
00489 {
00490 _us->close() ;
00491 delete _us ;
00492 }
00493
00494 BESDEBUG( "server", "ServerApp: terminating default module ... " )
00495 BESDefaultModule::terminate( ) ;
00496 BESDEBUG( "server", "OK" << endl ) ;
00497
00498 BESDEBUG( "server", "ServerApp: terminating default commands ... " )
00499 BESDefaultCommands::terminate( ) ;
00500 BESDEBUG( "server", "OK" << endl ) ;
00501
00502 BESModuleApp::terminate( sig ) ;
00503 }
00504 return sig ;
00505 }
00506
00513 void
00514 ServerApp::dump( ostream &strm ) const
00515 {
00516 strm << BESIndent::LMarg << "ServerApp::dump - ("
00517 << (void *)this << ")" << endl ;
00518 BESIndent::Indent() ;
00519 strm << BESIndent::LMarg << "got port? " << _gotPort << endl ;
00520 strm << BESIndent::LMarg << "port: " << _portVal << endl ;
00521 strm << BESIndent::LMarg << "unix socket: " << _unixSocket << endl ;
00522 strm << BESIndent::LMarg << "is secure? " << _secure << endl ;
00523 strm << BESIndent::LMarg << "pid: " << _mypid << endl ;
00524 if( _ts )
00525 {
00526 strm << BESIndent::LMarg << "tcp socket:" << endl ;
00527 BESIndent::Indent() ;
00528 _ts->dump( strm ) ;
00529 BESIndent::UnIndent() ;
00530 }
00531 else
00532 {
00533 strm << BESIndent::LMarg << "tcp socket: null" << endl ;
00534 }
00535 if( _us )
00536 {
00537 strm << BESIndent::LMarg << "unix socket:" << endl ;
00538 BESIndent::Indent() ;
00539 _us->dump( strm ) ;
00540 BESIndent::UnIndent() ;
00541 }
00542 else
00543 {
00544 strm << BESIndent::LMarg << "unix socket: null" << endl ;
00545 }
00546 if( _ps )
00547 {
00548 strm << BESIndent::LMarg << "ppt server:" << endl ;
00549 BESIndent::Indent() ;
00550 _ps->dump( strm ) ;
00551 BESIndent::UnIndent() ;
00552 }
00553 else
00554 {
00555 strm << BESIndent::LMarg << "ppt server: null" << endl ;
00556 }
00557 BESModuleApp::dump( strm ) ;
00558 BESIndent::UnIndent() ;
00559 }
00560
00561 int
00562 main( int argc, char **argv )
00563 {
00564 try
00565 {
00566 ServerApp app ;
00567 return app.main( argc, argv ) ;
00568 }
00569 catch( BESError &e )
00570 {
00571 cerr << "Caught unhandled exception: " << endl ;
00572 cerr << e.get_message() << endl ;
00573 return 1 ;
00574 }
00575 catch( ... )
00576 {
00577 cerr << "Caught unhandled, unknown exception" << endl ;
00578 return 1 ;
00579 }
00580 return 0 ;
00581 }
00582