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 "BESXMLDefaultCommands.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 ... " << endl )
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 << " ... " << endl )
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 << " ... " << endl )
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" << endl )
00177 #endif
00178 }
00179
00180 void
00181 ServerApp::set_user_id()
00182 {
00183 BESDEBUG( "server", "ServerApp: Setting user id ... " << endl )
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 << " ... " << endl )
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 cannot run as root" << endl ;
00227 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00228 }
00229
00230 BESDEBUG( "server", "to " << new_id << " ... " << endl )
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 ... " << endl )
00365 if( signal( SIGTERM, signalTerminate ) == SIG_ERR )
00366 {
00367 BESDEBUG( "server", "FAILED" << endl ) ;
00368 cerr << "FAILED: cannot 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 ... " << endl )
00374 if( signal( SIGINT, signalInterrupt ) == SIG_ERR )
00375 {
00376 BESDEBUG( "server", "FAILED" << endl ) ;
00377 cerr << "FAILED: cannot 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 ... " << endl )
00383 if( signal( SIGUSR1, signalRestart ) == SIG_ERR )
00384 {
00385 BESDEBUG( "server", "FAILED" << endl ) ;
00386 cerr << "FAILED: cannot 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 ... " << endl )
00392 BESDefaultModule::initialize( argc, argv ) ;
00393 BESDEBUG( "server", "OK" << endl ) ;
00394
00395 BESDEBUG( "server", "ServerApp: initializing default commands ... " << endl )
00396 BESXMLDefaultCommands::initialize( argc, argv ) ;
00397 BESDEBUG( "server", "OK" << endl ) ;
00398
00399 BESDebug::Register( "server" ) ;
00400 BESDebug::Register( "ppt" ) ;
00401
00402 int ret = BESModuleApp::initialize( argc, argv ) ;
00403
00404 BESDEBUG( "server", "ServerApp: initialized settings:" << *this )
00405
00406 if( needhelp )
00407 {
00408 BESServerUtils::show_usage( BESApp::TheApplication()->appName() ) ;
00409 }
00410
00411 if( curr_euid == 0 )
00412 {
00413
00414
00415
00416 #ifdef BES_DEVELOPER
00417 cerr << "Developer Mode: Running as root - setting group and user ids"
00418 << endl ;
00419 #endif
00420 set_group_id() ;
00421 set_user_id() ;
00422 }
00423 else
00424 {
00425 cerr << "Developer Mode: Not setting group or user ids" << endl ;
00426 }
00427
00428 return ret ;
00429 }
00430
00431 int
00432 ServerApp::run()
00433 {
00434 try
00435 {
00436 BESDEBUG( "server", "ServerApp: initializing memory pool ... " << endl )
00437 BESMemoryManager::initialize_memory_pool() ;
00438 BESDEBUG( "server", "OK" << endl ) ;
00439
00440 SocketListener listener ;
00441
00442 if( _portVal )
00443 {
00444 _ts = new TcpSocket( _portVal ) ;
00445 listener.listen( _ts ) ;
00446 BESDEBUG( "server", "ServerApp: listening on port (" << _portVal << ")" << endl )
00447 }
00448
00449 if( !_unixSocket.empty() )
00450 {
00451 _us = new UnixSocket( _unixSocket ) ;
00452 listener.listen( _us ) ;
00453 BESDEBUG( "server", "ServerApp: listening on unix socket (" << _unixSocket << ")" << endl )
00454 }
00455
00456 BESServerHandler handler ;
00457
00458 _ps = new PPTServer( &handler, &listener, _secure ) ;
00459 _ps->initConnection() ;
00460 }
00461 catch( BESError &se )
00462 {
00463 cerr << se.get_message() << endl ;
00464 return 1 ;
00465 }
00466 catch( ... )
00467 {
00468 cerr << "caught unknown exception" << endl ;
00469 return 1 ;
00470 }
00471
00472 return 0 ;
00473 }
00474
00475 int
00476 ServerApp::terminate( int sig )
00477 {
00478 pid_t apppid = getpid() ;
00479 if( apppid == _mypid )
00480 {
00481 if( _ps )
00482 {
00483 _ps->closeConnection() ;
00484 delete _ps ;
00485 }
00486 if( _ts )
00487 {
00488 _ts->close() ;
00489 delete _ts ;
00490 }
00491 if( _us )
00492 {
00493 _us->close() ;
00494 delete _us ;
00495 }
00496
00497 BESDEBUG( "server", "ServerApp: terminating default module ... " << endl )
00498 BESDefaultModule::terminate( ) ;
00499 BESDEBUG( "server", "OK" << endl ) ;
00500
00501 BESDEBUG( "server", "ServerApp: terminating default commands ... " << endl )
00502 BESXMLDefaultCommands::terminate( ) ;
00503 BESDEBUG( "server", "OK" << endl ) ;
00504
00505 BESModuleApp::terminate( sig ) ;
00506 }
00507 return sig ;
00508 }
00509
00516 void
00517 ServerApp::dump( ostream &strm ) const
00518 {
00519 strm << BESIndent::LMarg << "ServerApp::dump - ("
00520 << (void *)this << ")" << endl ;
00521 BESIndent::Indent() ;
00522 strm << BESIndent::LMarg << "got port? " << _gotPort << endl ;
00523 strm << BESIndent::LMarg << "port: " << _portVal << endl ;
00524 strm << BESIndent::LMarg << "unix socket: " << _unixSocket << endl ;
00525 strm << BESIndent::LMarg << "is secure? " << _secure << endl ;
00526 strm << BESIndent::LMarg << "pid: " << _mypid << endl ;
00527 if( _ts )
00528 {
00529 strm << BESIndent::LMarg << "tcp socket:" << endl ;
00530 BESIndent::Indent() ;
00531 _ts->dump( strm ) ;
00532 BESIndent::UnIndent() ;
00533 }
00534 else
00535 {
00536 strm << BESIndent::LMarg << "tcp socket: null" << endl ;
00537 }
00538 if( _us )
00539 {
00540 strm << BESIndent::LMarg << "unix socket:" << endl ;
00541 BESIndent::Indent() ;
00542 _us->dump( strm ) ;
00543 BESIndent::UnIndent() ;
00544 }
00545 else
00546 {
00547 strm << BESIndent::LMarg << "unix socket: null" << endl ;
00548 }
00549 if( _ps )
00550 {
00551 strm << BESIndent::LMarg << "ppt server:" << endl ;
00552 BESIndent::Indent() ;
00553 _ps->dump( strm ) ;
00554 BESIndent::UnIndent() ;
00555 }
00556 else
00557 {
00558 strm << BESIndent::LMarg << "ppt server: null" << endl ;
00559 }
00560 BESModuleApp::dump( strm ) ;
00561 BESIndent::UnIndent() ;
00562 }
00563
00564 int
00565 main( int argc, char **argv )
00566 {
00567 try
00568 {
00569 ServerApp app ;
00570 return app.main( argc, argv ) ;
00571 }
00572 catch( BESError &e )
00573 {
00574 cerr << "Caught unhandled exception: " << endl ;
00575 cerr << e.get_message() << endl ;
00576 return 1 ;
00577 }
00578 catch( ... )
00579 {
00580 cerr << "Caught unhandled, unknown exception" << endl ;
00581 return 1 ;
00582 }
00583 return 0 ;
00584 }
00585