int agent_starter( ReliSock * s ) { ReliSock* stream = (ReliSock*)s; char *subsys = NULL; stream->decode(); if( ! stream->code(subsys) || ! stream->end_of_message() ) { dprintf( D_ALWAYS, "Can't read subsystem name\n" ); free( subsys ); return FALSE; } dprintf ( D_ALWAYS, "Starting agent '%s'\n", subsys ); if( strcasecmp(subsys, "fetch_log") == 0 ) { free (subsys); return handle_agent_fetch_log( stream ); } // default: free (subsys); dprintf( D_ALWAYS, "WARNING: unrecognized agent name\n" ); return FALSE; }
/* Takes sinful address of startd and sends it the given cmd, along with the capability and an end_of_message. */ int send_cmd_to_startd(char *sin_host, char *capability, int cmd) { ReliSock* sock = NULL; Daemon startd (DT_STARTD, sin_host, NULL); if (!(sock = (ReliSock*)startd.startCommand(cmd, Stream::reli_sock, 20))) { dprintf( D_ALWAYS, "Can't connect to startd at %s\n", sin_host ); return -1; } // send the capability ClaimIdParser idp( capability ); dprintf(D_FULLDEBUG, "send capability %s\n", idp.publicClaimId() ); if(!sock->code(capability)){ dprintf( D_ALWAYS, "sock->code(%s) failed.\n", idp.publicClaimId() ); delete sock; return -3; } // send end of message if( !sock->end_of_message() ) { dprintf( D_ALWAYS, "end_of_message failed\n" ); delete sock; return -4; } dprintf( D_FULLDEBUG, "Sent command %d to startd at %s with cap %s\n", cmd, sin_host, idp.publicClaimId() ); delete sock; return 0; }
DCStarter::X509UpdateStatus DCStarter::delegateX509Proxy( const char * filename, time_t expiration_time, char const *sec_session_id, time_t *result_expiration_time) { ReliSock rsock; rsock.timeout(60); if( ! rsock.connect(_addr) ) { dprintf(D_ALWAYS, "DCStarter::delegateX509Proxy: " "Failed to connect to starter %s\n", _addr); return XUS_Error; } CondorError errstack; if( ! startCommand(DELEGATE_GSI_CRED_STARTER, &rsock, 0, &errstack, NULL, false, sec_session_id) ) { dprintf( D_ALWAYS, "DCStarter::delegateX509Proxy: " "Failed send command to the starter: %s\n", errstack.getFullText().c_str()); return XUS_Error; } // Send the gsi proxy filesize_t file_size = 0; // will receive the size of the file if ( rsock.put_x509_delegation(&file_size,filename,expiration_time,result_expiration_time) < 0 ) { dprintf(D_ALWAYS, "DCStarter::delegateX509Proxy " "failed to delegate proxy file %s (size=%ld)\n", filename, (long int)file_size); return XUS_Error; } // Fetch the result rsock.decode(); int reply = 0; rsock.code(reply); rsock.end_of_message(); switch(reply) { case 0: return XUS_Error; case 1: return XUS_Okay; case 2: return XUS_Declined; } dprintf(D_ALWAYS, "DCStarter::delegateX509Proxy: " "remote side returned unknown code %d. Treating " "as an error.\n", reply); return XUS_Error; }
// specific command function - sends local daemon's version and state over // the socket bool AbstractReplicatorStateMachine::versionAndStateCommand(ReliSock& socket) { if( ! versionCommand( socket ) ) { return false; } int stateAsInteger = int( m_state ); if( ! socket.code( stateAsInteger ) /*|| ! socket.end_of_message( )*/ ) { dprintf( D_NETWORK, "AbstractReplicatorStateMachine::versionAndStateCommand " "unable to code the state or eom%d\n", m_state ); return false; } dprintf( D_ALWAYS, "AbstractReplicatorStateMachine::versionAndStateCommand " "sent command successfully\n" ); return true; }
/* Function : transferFileCommand * Return value: TRANSFERER_TRUE - upon success, * TRANSFERER_FALSE - upon failure * Description : sends a transfer command to the remote replication daemon, * which creates a uploading 'condor_transferer' process * Notes : sends to the replication daemon a port number, on which it * will be listening to the files uploading requests */ int DownloadReplicaTransferer::transferFileCommand( ) { char* temporaryDaemonSinfulString = const_cast<char*>( m_daemonSinfulString.Value( ) ); dprintf( D_ALWAYS, "DownloadReplicaTransferer::transferFileCommand " "to %s started\n", temporaryDaemonSinfulString ); Daemon daemon( DT_ANY, temporaryDaemonSinfulString ); ReliSock temporarySocket; // no retries after 'm_connectionTimeout' seconds of unsuccessful connection temporarySocket.timeout( m_connectionTimeout ); temporarySocket.doNotEnforceMinimalCONNECT_TIMEOUT( ); if( ! temporarySocket.connect( temporaryDaemonSinfulString, 0, false ) ) { dprintf( D_NETWORK, "DownloadReplicaTransferer::transferFileCommand " "unable to connect to %s, reason: %s\n", temporaryDaemonSinfulString, strerror( errno ) ); temporarySocket.close( ); return TRANSFERER_FALSE; } if( ! daemon.startCommand( REPLICATION_TRANSFER_FILE, &temporarySocket, m_connectionTimeout ) ) { dprintf( D_COMMAND, "DownloadReplicaTransferer::transferFileCommand " "unable to start command to addr %s\n", temporaryDaemonSinfulString ); temporarySocket.close( ); return TRANSFERER_FALSE; } MyString sinfulString; // find and bind port of the socket, to which the uploading // 'condor_transferer' process will send the important files ReliSock listeningSocket; listeningSocket.timeout( m_maxTransferLifetime / 2); //listeningSocket.timeout( ACCEPT_TIMEOUT ); //listeningSocket.timeout( m_connectionTimeout ); // this setting is practically unnecessary, since we do not connect to // remote sockets with 'listeningSocket' listeningSocket.doNotEnforceMinimalCONNECT_TIMEOUT( ); if( ! listeningSocket.bind( FALSE ) || ! listeningSocket.listen( ) ) { temporarySocket.close( ); listeningSocket.close( ); return TRANSFERER_FALSE; } sinfulString = listeningSocket.get_sinful_public(); // after the socket for the downloading/uploading process is occupied, // its number is sent to the remote replication daemon char* temporarySinfulString = const_cast<char*>( sinfulString.Value( ) ); if( ! temporarySocket.code( temporarySinfulString ) || ! temporarySocket.end_of_message( ) ) { dprintf( D_NETWORK, "DownloadReplicaTransferer::transferFileCommand " "unable to code the sinful string %s\n", temporarySinfulString ); temporarySocket.close( ); listeningSocket.close( ); return TRANSFERER_FALSE; } else { dprintf( D_ALWAYS, "DownloadReplicaTransferer::transferFileCommand " "sinful string %s coded successfully\n", temporarySinfulString ); } temporarySocket.close( ); m_socket = listeningSocket.accept( ); // m_socket->set_timeout_multiplier( 1 ); m_socket->timeout( INT_MAX ); //m_connectionTimeout ); m_socket->doNotEnforceMinimalCONNECT_TIMEOUT( ); listeningSocket.close( ); dprintf( D_ALWAYS, "DownloadReplicaTransferer::transferFileCommand " "sent transfer command successfully and accepted " "request on port no. %d\n", m_socket->get_port( ) ); return TRANSFERER_TRUE; }
bool DCSchedd::spoolJobFiles(int JobAdsArrayLen, ClassAd* JobAdsArray[], CondorError * errstack) { int reply; int i; ReliSock rsock; bool use_new_command = true; if ( version() ) { CondorVersionInfo vi( version() ); if ( vi.built_since_version(6,7,7) ) { use_new_command = true; } else { use_new_command = false; } } // // // // // // // // // On the wire protocol // // // // // // // // rsock.timeout(20); // years of research... :) if( ! rsock.connect(_addr) ) { std::string errmsg; formatstr(errmsg, "Failed to connect to schedd (%s)", _addr); dprintf( D_ALWAYS, "DCSchedd::spoolJobFiles: %s\n", errmsg.c_str() ); if( errstack ) { errstack->push( "DCSchedd::spoolJobFiles",CEDAR_ERR_CONNECT_FAILED, errmsg.c_str() ); } return false; } if ( use_new_command ) { if( ! startCommand(SPOOL_JOB_FILES_WITH_PERMS, (Sock*)&rsock, 0, errstack) ) { dprintf( D_ALWAYS, "DCSchedd::spoolJobFiles: " "Failed to send command (SPOOL_JOB_FILES_WITH_PERMS) " "to the schedd (%s)\n", _addr ); return false; } } else { if( ! startCommand(SPOOL_JOB_FILES, (Sock*)&rsock, 0, errstack) ) { dprintf( D_ALWAYS, "DCSchedd::spoolJobFiles: " "Failed to send command (SPOOL_JOB_FILES) " "to the schedd (%s)\n", _addr ); return false; } } // First, if we're not already authenticated, force that now. if (!forceAuthentication( &rsock, errstack )) { dprintf( D_ALWAYS, "DCSchedd: authentication failure: %s\n", errstack ? errstack->getFullText().c_str() : "" ); return false; } rsock.encode(); // Send our version if using the new command if ( use_new_command ) { // Need to use a named variable, else the wrong version of // code() is called. char *my_version = strdup( CondorVersion() ); if ( !rsock.code(my_version) ) { dprintf(D_ALWAYS,"DCSchedd:spoolJobFiles: " "Can't send version string to the schedd\n"); free( my_version ); return false; } free( my_version ); } // Send the number of jobs if ( !rsock.code(JobAdsArrayLen) ) { dprintf(D_ALWAYS,"DCSchedd:spoolJobFiles: " "Can't send JobAdsArrayLen to the schedd\n"); return false; } if( !rsock.end_of_message() ) { std::string errmsg; formatstr(errmsg, "Can't send initial message (version + count) to schedd (%s)", _addr); dprintf(D_ALWAYS,"DCSchedd:spoolJobFiles: %s\n", errmsg.c_str()); if( errstack ) { errstack->push( "DCSchedd::spoolJobFiles", CEDAR_ERR_EOM_FAILED, errmsg.c_str()); } return false; } // Now, put the job ids onto the wire PROC_ID jobid; for (i=0; i<JobAdsArrayLen; i++) { if (!JobAdsArray[i]->LookupInteger(ATTR_CLUSTER_ID,jobid.cluster)) { dprintf(D_ALWAYS,"DCSchedd:spoolJobFiles: " "Job ad %d did not have a cluster id\n",i); return false; } if (!JobAdsArray[i]->LookupInteger(ATTR_PROC_ID,jobid.proc)) { dprintf(D_ALWAYS,"DCSchedd:spoolJobFiles: " "Job ad %d did not have a proc id\n",i); return false; } rsock.code(jobid); } if( !rsock.end_of_message() ) { std::string errmsg; formatstr(errmsg, "Failed while sending job ids to schedd (%s)", _addr); dprintf(D_ALWAYS,"DCSchedd:spoolJobFiles: %s\n", errmsg.c_str()); if( errstack ) { errstack->push( "DCSchedd::spoolJobFiles", CEDAR_ERR_EOM_FAILED, errmsg.c_str()); } return false; } // Now send all the files via the file transfer object for (i=0; i<JobAdsArrayLen; i++) { FileTransfer ftrans; if ( !ftrans.SimpleInit(JobAdsArray[i], false, false, &rsock, PRIV_UNKNOWN, false, true) ) { if( errstack ) { int cluster = -1, proc = -1; if(JobAdsArray[i]) { JobAdsArray[i]->LookupInteger(ATTR_CLUSTER_ID,cluster); JobAdsArray[i]->LookupInteger(ATTR_PROC_ID,proc); } errstack->pushf( "DCSchedd::spoolJobFiles", FILETRANSFER_INIT_FAILED, "File transfer initialization failed for target job %d.%d", cluster, proc ); } return false; } if ( use_new_command ) { ftrans.setPeerVersion( version() ); } if ( !ftrans.UploadFiles(true,false) ) { if( errstack ) { FileTransfer::FileTransferInfo ft_info = ftrans.GetInfo(); int cluster = -1, proc = -1; if(JobAdsArray[i]) { JobAdsArray[i]->LookupInteger(ATTR_CLUSTER_ID,cluster); JobAdsArray[i]->LookupInteger(ATTR_PROC_ID,proc); } errstack->pushf( "DCSchedd::spoolJobFiles", FILETRANSFER_UPLOAD_FAILED, "File transfer failed for target job %d.%d: %s", cluster, proc, ft_info.error_desc.Value() ); } return false; } } rsock.end_of_message(); rsock.decode(); reply = 0; rsock.code(reply); rsock.end_of_message(); if ( reply == 1 ) return true; else return false; }
bool DCSchedd::receiveJobSandbox(const char* constraint, CondorError * errstack, int * numdone /*=0*/) { if(numdone) { *numdone = 0; } ExprTree *tree = NULL; const char *lhstr; int reply; int i; ReliSock rsock; int JobAdsArrayLen; bool use_new_command = true; if ( version() ) { CondorVersionInfo vi( version() ); if ( vi.built_since_version(6,7,7) ) { use_new_command = true; } else { use_new_command = false; } } // // // // // // // // // On the wire protocol // // // // // // // // rsock.timeout(20); // years of research... :) if( ! rsock.connect(_addr) ) { dprintf( D_ALWAYS, "DCSchedd::receiveJobSandbox: " "Failed to connect to schedd (%s)\n", _addr ); return false; } if ( use_new_command ) { if( ! startCommand(TRANSFER_DATA_WITH_PERMS, (Sock*)&rsock, 0, errstack) ) { dprintf( D_ALWAYS, "DCSchedd::receiveJobSandbox: " "Failed to send command (TRANSFER_DATA_WITH_PERMS) " "to the schedd\n" ); return false; } } else { if( ! startCommand(TRANSFER_DATA, (Sock*)&rsock, 0, errstack) ) { dprintf( D_ALWAYS, "DCSchedd::receiveJobSandbox: " "Failed to send command (TRANSFER_DATA) " "to the schedd\n" ); return false; } } // First, if we're not already authenticated, force that now. if (!forceAuthentication( &rsock, errstack )) { dprintf( D_ALWAYS, "DCSchedd::receiveJobSandbox: authentication failure: %s\n", errstack ? errstack->getFullText().c_str() : "" ); return false; } rsock.encode(); // Send our version if using the new command if ( use_new_command ) { // Need to use a named variable, else the wrong version of // code() is called. char *my_version = strdup( CondorVersion() ); if ( !rsock.code(my_version) ) { dprintf(D_ALWAYS,"DCSchedd:receiveJobSandbox: " "Can't send version string to the schedd\n"); free( my_version ); return false; } free( my_version ); } // Send the constraint char * nc_constraint = strdup( constraint ); // de-const if ( !rsock.code(nc_constraint) ) { free( nc_constraint ); dprintf(D_ALWAYS,"DCSchedd:receiveJobSandbox: " "Can't send JobAdsArrayLen to the schedd\n"); return false; } free( nc_constraint ); if ( !rsock.end_of_message() ) { std::string errmsg; formatstr(errmsg, "Can't send initial message (version + constraint) to schedd (%s)", _addr); dprintf(D_ALWAYS,"DCSchedd::receiveJobSandbox: %s\n", errmsg.c_str()); if( errstack ) { errstack->push( "DCSchedd::receiveJobSandbox", CEDAR_ERR_EOM_FAILED, errmsg.c_str()); } return false; } // Now, read how many jobs matched the constraint. rsock.decode(); if ( !rsock.code(JobAdsArrayLen) ) { std::string errmsg; formatstr(errmsg, "Can't receive JobAdsArrayLen from the schedd (%s)", _addr); dprintf(D_ALWAYS,"DCSchedd::receiveJobSandbox: %s\n", errmsg.c_str()); if( errstack ) { errstack->push( "DCSchedd::receiveJobSandbox", CEDAR_ERR_GET_FAILED, errmsg.c_str()); } return false; } rsock.end_of_message(); dprintf(D_FULLDEBUG,"DCSchedd:receiveJobSandbox: " "%d jobs matched my constraint (%s)\n", JobAdsArrayLen, constraint); // Now read all the files via the file transfer object for (i=0; i<JobAdsArrayLen; i++) { FileTransfer ftrans; ClassAd job; // grab job ClassAd if ( !getClassAd(&rsock, job) ) { std::string errmsg; formatstr(errmsg, "Can't receive job ad %d from the schedd", i); dprintf(D_ALWAYS, "DCSchedd::receiveJobSandbox: %s\n", errmsg.c_str()); if( errstack ) { errstack->push( "DCSchedd::receiveJobSandbox", CEDAR_ERR_GET_FAILED, errmsg.c_str()); } return false; } rsock.end_of_message(); // translate the job ad by replacing the // saved SUBMIT_ attributes job.ResetExpr(); while( job.NextExpr(lhstr, tree) ) { if ( lhstr && strncasecmp("SUBMIT_",lhstr,7)==0 ) { // this attr name starts with SUBMIT_ // compute new lhs (strip off the SUBMIT_) const char *new_attr_name = strchr(lhstr,'_'); ExprTree * pTree; ASSERT(new_attr_name); new_attr_name++; // insert attribute pTree = tree->Copy(); job.Insert(new_attr_name, pTree, false); } } // while next expr if ( !ftrans.SimpleInit(&job,false,false,&rsock) ) { if( errstack ) { int cluster = -1, proc = -1; job.LookupInteger(ATTR_CLUSTER_ID,cluster); job.LookupInteger(ATTR_PROC_ID,proc); errstack->pushf( "DCSchedd::receiveJobSandbox", FILETRANSFER_INIT_FAILED, "File transfer initialization failed for target job %d.%d", cluster, proc ); } return false; } // We want files to be copied to their final places, so apply // any filename remaps when downloading. if ( !ftrans.InitDownloadFilenameRemaps(&job) ) { return false; } if ( use_new_command ) { ftrans.setPeerVersion( version() ); } if ( !ftrans.DownloadFiles() ) { if( errstack ) { FileTransfer::FileTransferInfo ft_info = ftrans.GetInfo(); int cluster = -1, proc = -1; job.LookupInteger(ATTR_CLUSTER_ID,cluster); job.LookupInteger(ATTR_PROC_ID,proc); errstack->pushf( "DCSchedd::receiveJobSandbox", FILETRANSFER_DOWNLOAD_FAILED, "File transfer failed for target job %d.%d: %s", cluster, proc, ft_info.error_desc.Value() ); } return false; } } rsock.end_of_message(); rsock.encode(); reply = OK; rsock.code(reply); rsock.end_of_message(); if(numdone) { *numdone = JobAdsArrayLen; } return true; }
ClassAd* DCSchedd::actOnJobs( JobAction action, const char* constraint, StringList* ids, const char* reason, const char* reason_attr, const char* reason_code, const char* reason_code_attr, action_result_type_t result_type, bool notify_scheduler, CondorError * errstack ) { char* tmp = NULL; char buf[512]; int size, reply; ReliSock rsock; // // // // // // // // // Construct the ad we want to send // // // // // // // // ClassAd cmd_ad; sprintf( buf, "%s = %d", ATTR_JOB_ACTION, action ); cmd_ad.Insert( buf ); sprintf( buf, "%s = %d", ATTR_ACTION_RESULT_TYPE, (int)result_type ); cmd_ad.Insert( buf ); sprintf( buf, "%s = %s", ATTR_NOTIFY_JOB_SCHEDULER, notify_scheduler ? "True" : "False" ); cmd_ad.Insert( buf ); if( constraint ) { if( ids ) { // This is a programming error, not a run-time one EXCEPT( "DCSchedd::actOnJobs has both constraint and ids!" ); } size = strlen(constraint) + strlen(ATTR_ACTION_CONSTRAINT) + 4; tmp = (char*) malloc( size*sizeof(char) ); if( !tmp ) { EXCEPT( "Out of memory!" ); } sprintf( tmp, "%s = %s", ATTR_ACTION_CONSTRAINT, constraint ); if( ! cmd_ad.Insert(tmp) ) { dprintf( D_ALWAYS, "DCSchedd::actOnJobs: " "Can't insert constraint (%s) into ClassAd!\n", constraint ); free( tmp ); return NULL; } free( tmp ); tmp = NULL; } else if( ids ) { char* action_ids = ids->print_to_string(); if ( action_ids ) { size = strlen(action_ids) + strlen(ATTR_ACTION_IDS) + 7; tmp = (char*) malloc( size*sizeof(char) ); if( !tmp ) { EXCEPT( "Out of memory!" ); } sprintf( tmp, "%s = \"%s\"", ATTR_ACTION_IDS, action_ids ); cmd_ad.Insert( tmp ); free( tmp ); tmp = NULL; free(action_ids); action_ids = NULL; } } else { EXCEPT( "DCSchedd::actOnJobs called without constraint or ids" ); } if( reason_attr && reason ) { size = strlen(reason_attr) + strlen(reason) + 7; tmp = (char*) malloc( size*sizeof(char) ); if( !tmp ) { EXCEPT( "Out of memory!" ); } sprintf( tmp, "%s = \"%s\"", reason_attr, reason ); cmd_ad.Insert( tmp ); free( tmp ); tmp = NULL; } if( reason_code_attr && reason_code ) { cmd_ad.AssignExpr(reason_code_attr,reason_code); } // // // // // // // // // On the wire protocol // // // // // // // // rsock.timeout(20); // years of research... :) if( ! rsock.connect(_addr) ) { dprintf( D_ALWAYS, "DCSchedd::actOnJobs: " "Failed to connect to schedd (%s)\n", _addr ); return NULL; } if( ! startCommand(ACT_ON_JOBS, (Sock*)&rsock, 0, errstack) ) { dprintf( D_ALWAYS, "DCSchedd::actOnJobs: " "Failed to send command (ACT_ON_JOBS) to the schedd\n" ); return NULL; } // First, if we're not already authenticated, force that now. if (!forceAuthentication( &rsock, errstack )) { dprintf( D_ALWAYS, "DCSchedd: authentication failure: %s\n", errstack->getFullText().c_str() ); return NULL; } // Now, put the command classad on the wire if( ! (putClassAd(&rsock, cmd_ad) && rsock.end_of_message()) ) { dprintf( D_ALWAYS, "DCSchedd:actOnJobs: Can't send classad\n" ); return NULL; } // Next, we need to read the reply from the schedd if things // are ok and it's going to go forward. If the schedd can't // read our reply to this ClassAd, it assumes we got killed // and it should abort its transaction rsock.decode(); ClassAd* result_ad = new ClassAd(); if( ! (getClassAd(&rsock, *result_ad) && rsock.end_of_message()) ) { dprintf( D_ALWAYS, "DCSchedd:actOnJobs: " "Can't read response ad from %s\n", _addr ); delete( result_ad ); return NULL; } // If the action totally failed, the schedd will already have // aborted the transaction and closed up shop, so there's no // reason trying to continue. However, we still want to // return the result ad we got back so that our caller can // figure out what went wrong. reply = FALSE; result_ad->LookupInteger( ATTR_ACTION_RESULT, reply ); if( reply != OK ) { dprintf( D_ALWAYS, "DCSchedd:actOnJobs: Action failed\n" ); return result_ad; } // Tell the schedd we're still here and ready to go rsock.encode(); int answer = OK; if( ! (rsock.code(answer) && rsock.end_of_message()) ) { dprintf( D_ALWAYS, "DCSchedd:actOnJobs: Can't send reply\n" ); delete( result_ad ); return NULL; } // finally, make sure the schedd didn't blow up trying to // commit these changes to the job queue... rsock.decode(); if( ! (rsock.code(reply) && rsock.end_of_message()) ) { dprintf( D_ALWAYS, "DCSchedd:actOnJobs: " "Can't read confirmation from %s\n", _addr ); delete( result_ad ); return NULL; } return result_ad; }
static bool _requestVMRegister(char *addr) { char *buffer = NULL; Daemon hstartd(DT_STARTD, addr); //Using TCP ReliSock ssock; ssock.timeout( VM_SOCKET_TIMEOUT ); ssock.encode(); if( !ssock.connect(addr) ) { dprintf( D_FULLDEBUG, "Failed to connect to host startd(%s)\n", addr); return FALSE; } if( !hstartd.startCommand(VM_REGISTER, &ssock) ) { dprintf( D_FULLDEBUG, "Failed to send VM_REGISTER command to host startd(%s)\n", addr); return FALSE; } // Send <IP address:port> of virtual machine buffer = strdup(daemonCore->InfoCommandSinfulString()); ASSERT(buffer); if ( !ssock.code(buffer) ) { dprintf( D_FULLDEBUG, "Failed to send VM_REGISTER command's arguments to " "host startd %s: %s\n", addr, buffer ); free(buffer); return FALSE; } if( !ssock.end_of_message() ) { dprintf( D_FULLDEBUG, "Failed to send EOM to host startd %s\n", addr ); free(buffer); return FALSE; } free(buffer); //Now, read permission information ssock.timeout( VM_SOCKET_TIMEOUT ); ssock.decode(); int permission = 0; ssock.code(permission); if( !ssock.end_of_message() ) { dprintf( D_FULLDEBUG, "Failed to receive EOM from host startd(%s)\n", addr ); return FALSE; } if( permission > 0 ) { // Since now this virtual machine can be used for Condor if( vmregister ) { if( vmregister->vm_usable == 0 ) { vmregister->vm_usable = 1; if( resmgr ) { resmgr->eval_and_update_all(); } } } }else { // For now this virtual machine can't be used for Condor if( vmregister ) { if( vmregister->vm_usable == 1 ) { vmregister->vm_usable = 0; if( resmgr ) { resmgr->eval_and_update_all(); } } } } return TRUE; }
int rm_cred_handler(Service * /*service*/, int /*i*/, Stream *stream) { char * name = NULL; int rtnVal = FALSE; int rc; bool found_cred; CredentialWrapper * cred_wrapper = NULL; char * owner = NULL; const char * user; ReliSock * socket = (ReliSock*)stream; if (!socket->triedAuthentication()) { CondorError errstack; if( ! SecMan::authenticate_sock(socket, READ, &errstack) ) { dprintf (D_ALWAYS, "Unable to authenticate, qutting\n"); goto EXIT; } } socket->decode(); if (!socket->code(name)) { dprintf (D_ALWAYS, "Error receiving credential name\n"); goto EXIT; } user = socket->getFullyQualifiedUser(); dprintf (D_ALWAYS, "Authenticated as %s\n", user); if (strchr (name, ':')) { // The name is of the form user:name // This better be a super-user! // TODO: Check super-user's list // Owner is the first part owner = strdup (name); char * pColon = strchr (owner, ':'); *pColon = '\0'; // Name is the second part sprintf (name, "%s", (char*)(pColon+sizeof(char))); if (strcmp (owner, user) != 0) { dprintf (D_ALWAYS, "Requesting another user's (%s) credential %s\n", owner, name); if (!isSuperUser (user)) { dprintf (D_ALWAYS, "User %s is NOT super user, request DENIED\n", user); goto EXIT; } else { dprintf (D_FULLDEBUG, "User %s is super user, request GRANTED\n", user); } } } else { owner = strdup (user); } dprintf (D_ALWAYS, "Attempting to delete cred %s for user %s\n", name, owner); found_cred=false; credentials.Rewind(); while (credentials.Next(cred_wrapper)) { if (cred_wrapper->cred->GetType() == X509_CREDENTIAL_TYPE) { if ((strcmp(cred_wrapper->cred->GetName(), name) == 0) && (strcmp(cred_wrapper->cred->GetOwner(), owner) == 0)) { credentials.DeleteCurrent(); found_cred=true; break; // found it } } } if (found_cred) { priv_state priv = set_root_priv(); // Remove credential data unlink (cred_wrapper->GetStorageName()); // Save the metadata list SaveCredentialList(); set_priv(priv); delete cred_wrapper; dprintf (D_ALWAYS, "Removed credential %s for owner %s\n", name, owner); } else { dprintf (D_ALWAYS, "Unable to remove credential %s:%s (not found)\n", owner, name); } free (owner); socket->encode(); rc = (found_cred)?CREDD_SUCCESS:CREDD_CREDENTIAL_NOT_FOUND; socket->code(rc); rtnVal = TRUE; EXIT: if (name != NULL) { free (name); } return rtnVal; }
int query_cred_handler(Service * /*service*/, int /*i*/, Stream *stream) { classad::ClassAdUnParser unparser; std::string adbuffer; char * request = NULL; int rtnVal = FALSE; int length; CredentialWrapper * cred = NULL; SimpleList <Credential*> result_list; ReliSock * socket = (ReliSock*)stream; const char * user; if (!socket->triedAuthentication()) { CondorError errstack; if( ! SecMan::authenticate_sock(socket, READ, &errstack) ) { dprintf (D_ALWAYS, "Unable to authenticate, qutting\n"); goto EXIT; } } user = socket->getFullyQualifiedUser(); dprintf (D_ALWAYS, "Authenticated as %s\n", user); socket->decode(); if (!socket->code(request)) { dprintf (D_ALWAYS, "Error receiving request\n"); goto EXIT; } if ((request != NULL) && (strcmp (request, "*") == 0)) { if (!isSuperUser (user)) { dprintf (D_ALWAYS, "User %s is NOT super user, request DENIED\n", user); goto EXIT; } } // Find credentials for this user credentials.Rewind(); while (credentials.Next(cred)) { if (cred->cred->GetType() == X509_CREDENTIAL_TYPE) { if (strcmp(cred->cred->GetOwner(), user) == 0) { result_list.Append (cred->cred); } } } socket->encode(); length = result_list.Length(); dprintf (D_FULLDEBUG, "User has %d credentials\n", length); socket->code (length); Credential * _cred; result_list.Rewind(); while (result_list.Next(_cred)) { classad::ClassAd * _temp = cred->GetMetadata(); unparser.Unparse(adbuffer,_temp); char * classad_str = strdup(adbuffer.c_str()); socket->code (classad_str); free (classad_str); delete _temp; } rtnVal = TRUE; EXIT: if (request != NULL) { free (request); } return rtnVal; }
int get_cred_handler(Service * /*service*/, int /*i*/, Stream *stream) { char * name = NULL; int rtnVal = FALSE; bool found_cred=false; CredentialWrapper * cred = NULL; char * owner = NULL; const char * user = NULL; void * data = NULL; ReliSock * socket = (ReliSock*)stream; // Authenticate if (!socket->triedAuthentication()) { CondorError errstack; if( ! SecMan::authenticate_sock(socket, READ, &errstack) ) { dprintf (D_ALWAYS, "Unable to authenticate, qutting\n"); goto EXIT; } } socket->decode(); if (!socket->code(name)) { dprintf (D_ALWAYS, "Error receiving credential name\n"); goto EXIT; } user = socket->getFullyQualifiedUser(); dprintf (D_ALWAYS, "Authenticated as %s\n", user); if (strchr (name, ':')) { // The name is of the form user:name // This better be a super-user! // TODO: Check super-user's list // Owner is the first part owner = strdup (name); char * pColon = strchr (owner, ':'); *pColon = '\0'; // Name is the second part sprintf (name, "%s", (char*)(pColon+sizeof(char))); if (strcmp (owner, user) != 0) { dprintf (D_ALWAYS, "Requesting another user's (%s) credential %s\n", owner, name); if (!isSuperUser (user)) { dprintf (D_ALWAYS, "User %s is NOT super user, request DENIED\n", user); goto EXIT; } else { dprintf (D_FULLDEBUG, "User %s is super user, request GRANTED\n", user); } } } else { owner = strdup (user); } dprintf (D_ALWAYS, "sending cred %s for user %s\n", name, owner); credentials.Rewind(); while (credentials.Next(cred)) { if (cred->cred->GetType() == X509_CREDENTIAL_TYPE) { if ((strcmp(cred->cred->GetName(), name) == 0) && (strcmp(cred->cred->GetOwner(), owner) == 0)) { found_cred=true; break; // found it } } } socket->encode(); if (found_cred) { dprintf (D_FULLDEBUG, "Found cred %s\n", cred->GetStorageName()); int data_size; int rc = LoadData (cred->GetStorageName(), data, data_size); dprintf (D_FULLDEBUG, "Credential::LoadData returned %d\n", rc); if (rc == 0) { goto EXIT; } socket->code (data_size); socket->code_bytes (data, data_size); dprintf (D_ALWAYS, "Credential name %s for owner %s returned to user %s\n", name, owner, user); } else { dprintf (D_ALWAYS, "Cannot find cred %s\n", name); int rc = CREDD_CREDENTIAL_NOT_FOUND; socket->code (rc); } rtnVal = TRUE; EXIT: if ( name != NULL) { free (name); } if ( owner != NULL) { free (owner); } if ( data != NULL) { free (data); } return rtnVal; }
void send_command(const ClassAdWrapper & ad, DaemonCommands dc, const std::string &target="") { std::string addr; if (!ad.EvaluateAttrString(ATTR_MY_ADDRESS, addr)) { PyErr_SetString(PyExc_ValueError, "Address not available in location ClassAd."); throw_error_already_set(); } std::string ad_type_str; if (!ad.EvaluateAttrString(ATTR_MY_TYPE, ad_type_str)) { PyErr_SetString(PyExc_ValueError, "Daemon type not available in location ClassAd."); throw_error_already_set(); } int ad_type = AdTypeFromString(ad_type_str.c_str()); if (ad_type == NO_AD) { PyErr_SetString(PyExc_ValueError, "Unknown ad type."); throw_error_already_set(); } daemon_t d_type; switch (ad_type) { case MASTER_AD: d_type = DT_MASTER; break; case STARTD_AD: d_type = DT_STARTD; break; case SCHEDD_AD: d_type = DT_SCHEDD; break; case NEGOTIATOR_AD: d_type = DT_NEGOTIATOR; break; case COLLECTOR_AD: d_type = DT_COLLECTOR; break; default: PyErr_SetString(PyExc_ValueError, "Unknown daemon type."); throw_error_already_set(); } ClassAd ad_copy; ad_copy.CopyFrom(ad); Daemon d(&ad_copy, d_type, NULL); if (!d.locate()) { PyErr_SetString(PyExc_RuntimeError, "Unable to locate daemon."); throw_error_already_set(); } ReliSock sock; if (!sock.connect(d.addr())) { PyErr_SetString(PyExc_RuntimeError, "Unable to connect to the remote daemon"); throw_error_already_set(); } if (!d.startCommand(dc, &sock, 0, NULL)) { PyErr_SetString(PyExc_RuntimeError, "Failed to start command."); throw_error_already_set(); } if (target.size()) { std::vector<unsigned char> target_cstr; target_cstr.reserve(target.size()+1); memcpy(&target_cstr[0], target.c_str(), target.size()+1); if (!sock.code(&target_cstr[0])) { PyErr_SetString(PyExc_RuntimeError, "Failed to send target."); throw_error_already_set(); } if (!sock.end_of_message()) { PyErr_SetString(PyExc_RuntimeError, "Failed to send end-of-message."); throw_error_already_set(); } } sock.close(); }
SharedPortState::HandlerResult SharedPortState::HandleResp(Stream *&s) { // The following final ACK appears to be necessary on Mac OS X // 10.5.8 (not sure of others). It does not appear to be // necessary on any version of linux that I have tried. The // observed problem that this solves is random failures where // the endpoint sees the passed socket close right away. It // would be nice not to have an ACK, because then the whole // PassSocket() protocol would be non-blocking. Since the // protocol is blocking with this ACK, it means we could // temporarily deadlock if the endpoint we are passing the // socket to is blocking on us on some other channel. If // this becomes a problem, we can at least make the ACK only // happen on platforms that need it. This protocol is always // just local to the machine, so need to worry about keeping // it compatible between different platforms. ReliSock *sock = static_cast<ReliSock*>(s); sock->decode(); int status = 0; bool result; bool read_would_block = false; { BlockingModeGuard guard(sock, m_non_blocking); result = sock->code(status); if ( m_non_blocking ) { read_would_block = sock->clear_read_block_flag(); } } if (read_would_block) { if (sock->deadline_expired()) { dprintf(D_ALWAYS, "SharedPortClient - server response deadline has passed for %s%s\n", m_sock_name.c_str(), m_requested_by.c_str()); return FAILED; } dprintf(D_ALWAYS, "SharedPortClient read would block; waiting for result for SHARED_PORT_PASS_FD to %s%s.\n", m_sock_name.c_str(), m_requested_by.c_str()); return WAIT; } if( !result || !sock->end_of_message() ) { dprintf(D_ALWAYS, "SharedPortClient: failed to receive result for SHARED_PORT_PASS_FD to %s%s: %s\n", m_sock_name.c_str(), m_requested_by.c_str(), strerror(errno)); return FAILED; } if( status != 0 ) { dprintf(D_ALWAYS, "SharedPortClient: received failure response for SHARED_PORT_PASS_FD to %s%s\n", m_sock_name.c_str(), m_requested_by.c_str()); return FAILED; } dprintf(D_FULLDEBUG, "SharedPortClient: passed socket to %s%s\n", m_sock_name.c_str(), m_requested_by.c_str()); return DONE; }
int main( int argc, char *argv[] ) { char *machine_name = 0; char *log_name = 0; char *pool=0; int i; daemon_t type = DT_MASTER; myDistro->Init( argc, argv ); config(); for( i=1; i<argc; i++ ) { if(!strcmp(argv[i],"-help")) { usage(argv[0]); exit(0); } else if(!strcmp(argv[i],"-pool")) { i++; if(!argv[i]) { fprintf(stderr,"-pool requires an argument.\n\n"); usage(argv[0]); exit(1); } pool = argv[i]; } else if(!strcmp(argv[i],"-version")) { version(); exit(0); } else if(!strcmp(argv[i],"-debug")) { dprintf_set_tool_debug("TOOL", 0); } else if(argv[i][0]=='-') { type = stringToDaemonType(&argv[i][1]); if( type == DT_NONE || type == DT_DAGMAN) { usage(argv[0]); exit(1); } } else if(argv[i][0]!='-') { if(!machine_name) { machine_name = argv[i]; } else if(!log_name) { log_name = argv[i]; } else { fprintf(stderr,"Extra argument: %s\n\n",argv[i]); usage(argv[0]); exit(1); } } else { usage(argv[0]); exit(1); } } if( !machine_name || !log_name ) { usage(argv[0]); exit(1); } Daemon *daemon; ReliSock *sock; if (pool) { DCCollector col( pool ); if( ! col.addr() ) { fprintf( stderr, "Error: %s\n", col.error() ); exit(1); } daemon = new Daemon( type, machine_name, col.addr() ); } else { daemon = new Daemon( type, machine_name ); } dprintf(D_FULLDEBUG,"Locating daemon process on %s...\n",machine_name); if(!daemon->locate()) { fprintf(stderr,"Couldn't locate daemon on %s: %s\n",machine_name,daemon->error()); exit(1); } dprintf(D_FULLDEBUG,"Daemon %s is %s\n",daemon->hostname(),daemon->addr()); sock = (ReliSock*)daemon->startCommand( DC_FETCH_LOG, Sock::reli_sock); if(!sock) { fprintf(stderr,"couldn't connect to daemon %s at %s\n",daemon->hostname(),daemon->addr()); return 1; } int commandType = DC_FETCH_LOG_TYPE_PLAIN; if ((strcmp(log_name, "HISTORY") == 0) || (strcmp(log_name, "STARTD_HISTORY") == 0)) { commandType = DC_FETCH_LOG_TYPE_HISTORY; } if ((strcmp(log_name, "STARTD.PER_JOB_HISTORY_DIR") == 0) || (strcmp(log_name, "STARTD.PER_JOB_HISTORY_DIR") == 0)) { commandType = DC_FETCH_LOG_TYPE_HISTORY_DIR; } sock->put( commandType ); sock->put( log_name ); sock->end_of_message(); if (commandType == DC_FETCH_LOG_TYPE_HISTORY_DIR) { return handleHistoryDir(sock); } int result = -1; int exitcode = 1; const char *reason=NULL; filesize_t filesize; sock->decode(); sock->code(result); switch(result) { case -1: reason = "permission denied"; break; case DC_FETCH_LOG_RESULT_SUCCESS: result = sock->get_file(&filesize,1,0); if(result>=0) { exitcode = 0; } else { reason = "connection lost"; } break; case DC_FETCH_LOG_RESULT_NO_NAME: reason = "no log file by that name"; break; case DC_FETCH_LOG_RESULT_CANT_OPEN: reason = "server was unable to access it"; break; case DC_FETCH_LOG_RESULT_BAD_TYPE: reason = "server can't provide that type of log"; break; default: reason = "unknown error"; break; } if(exitcode!=0) { fprintf(stderr,"Couldn't fetch log: %s.\n",reason); } return exitcode; }
int part_send_job( int test_starter, char *host, int &reason, char *capability, char * /*schedd*/, PROC *proc, int &sd1, int &sd2, char **name) { int reply; ReliSock *sock = NULL; StartdRec stRec; PORTS ports; bool done = false; int retry_delay = 3; int num_retries = 0; // make sure we have the job classad InitJobAd(proc->id.cluster, proc->id.proc); while( !done ) { Daemon startd(DT_STARTD, host, NULL); if (!(sock = (ReliSock*)startd.startCommand ( ACTIVATE_CLAIM, Stream::reli_sock, 90))) { dprintf( D_ALWAYS, "startCommand(ACTIVATE_CLAIM) to startd failed\n"); goto returnfailure; } // Send the capability ClaimIdParser idp( capability ); dprintf(D_FULLDEBUG, "send capability %s\n", idp.publicClaimId() ); if( !sock->put_secret(capability) ) { dprintf( D_ALWAYS, "sock->put(\"%s\") failed\n",idp.publicClaimId()); goto returnfailure; } // Send the starter number if( test_starter ) { dprintf( D_ALWAYS, "Requesting Alternate Starter %d\n", test_starter ); } else { dprintf( D_ALWAYS, "Requesting Primary Starter\n" ); } if( !sock->code(test_starter) ) { dprintf( D_ALWAYS, "sock->code(%d) failed\n", test_starter ); goto returnfailure; } // Send the job info if( !JobAd->put(*sock) ) { dprintf( D_ALWAYS, "failed to send job ad\n" ); goto returnfailure; } if( !sock->end_of_message() ) { dprintf( D_ALWAYS, "failed to send message to startd\n" ); goto returnfailure; } // We're done sending. Now, get the reply. sock->decode(); if( !sock->code(reply) || !sock->end_of_message() ) { dprintf( D_ALWAYS, "failed to receive reply from startd\n" ); goto returnfailure; } switch( reply ) { case OK: dprintf( D_ALWAYS, "Shadow: Request to run a job was ACCEPTED\n" ); done = true; break; case NOT_OK: dprintf( D_ALWAYS, "Shadow: Request to run a job was REFUSED\n"); goto returnfailure; break; case CONDOR_TRY_AGAIN: num_retries++; dprintf( D_ALWAYS, "Shadow: Request to run a job was TEMPORARILY REFUSED\n" ); if( num_retries > 20 ) { dprintf( D_ALWAYS, "Shadow: Too many retries, giving up.\n" ); goto returnfailure; } delete sock; dprintf( D_ALWAYS, "Shadow: will try again in %d seconds\n", retry_delay ); sleep( retry_delay ); break; default: dprintf(D_ALWAYS,"Unknown reply from startd for command ACTIVATE_CLAIM\n"); dprintf(D_ALWAYS,"Shadow: Request to run a job was REFUSED\n"); goto returnfailure; break; } } /* start flock : dhruba */ sock->decode(); memset( &stRec, '\0', sizeof(stRec) ); if( !sock->code(stRec) || !sock->end_of_message() ) { dprintf(D_ALWAYS, "Can't read reply from startd.\n"); goto returnfailure; } ports = stRec.ports; if( stRec.ip_addr ) { host = stRec.server_name; if(name) { *name = strdup(stRec.server_name); } dprintf(D_FULLDEBUG, "host = %s inet_addr = 0x%x port1 = %d port2 = %d\n", host, stRec.ip_addr,ports.port1, ports.port2 ); } else { dprintf(D_FULLDEBUG, "host = %s port1 = %d port2 = %d\n", host, ports.port1, ports.port2 ); } if( ports.port1 == 0 ) { dprintf( D_ALWAYS, "Shadow: Request to run a job on %s was REFUSED\n", host ); goto returnfailure; } /* end flock ; dhruba */ // We don't use the server_name in the StartdRec, because our // DNS query may fail or may give us the wrong IP address // (either because it's stale or because we're talking to a // machine with multiple network interfaces). Sadly, we can't // use the ip_addr either, because the startd doesn't send it in // the correct byte ordering on little-endian machines. So, we // grab the IP address from the ReliSock, since we konw the // startd always uses the same IP address for all of its // communication. char sinfulstring[SINFUL_STRING_BUF_SIZE]; generate_sinful(sinfulstring, SINFUL_STRING_BUF_SIZE, sock->peer_ip_str(), ports.port1); if( (sd1 = do_connect(sinfulstring, (char *)0, (u_short)ports.port1)) < 0 ) { dprintf( D_ALWAYS, "failed to connect to scheduler on %s\n", sinfulstring ); goto returnfailure; } generate_sinful(sinfulstring, SINFUL_STRING_BUF_SIZE, sock->peer_ip_str(), ports.port2); if( (sd2 = do_connect(sinfulstring, (char *)0, (u_short)ports.port2)) < 0 ) { dprintf( D_ALWAYS, "failed to connect to scheduler on %s\n", sinfulstring ); close(sd1); goto returnfailure; } delete sock; sock = NULL; if ( stRec.server_name ) { free( stRec.server_name ); } return 0; returnfailure: reason = JOB_NOT_STARTED; delete sock; return -1; }
int store_cred_handler(Service * /*service*/, int /*i*/, Stream *stream) { void * data = NULL; int rtnVal = FALSE; int rc; char * temp_file_name = NULL; bool found_cred; CredentialWrapper * temp_cred = NULL; int data_size = -1; classad::ClassAd * _classad = NULL; classad::ClassAd classad; std::string classad_cstr; char * classad_str = NULL; classad::ClassAdParser parser; ReliSock * socket = (ReliSock*)stream; const char * user = NULL; CredentialWrapper * cred_wrapper = NULL; if (!socket->triedAuthentication()) { CondorError errstack; if( ! SecMan::authenticate_sock(socket, WRITE, &errstack) ) { dprintf (D_ALWAYS, "Unable to authenticate, qutting\n"); goto EXIT; } } user = socket->getFullyQualifiedUser(); dprintf (D_FULLDEBUG, "Request by: %s, %s\n", socket->getOwner(), user); socket->decode(); if (!socket->code (classad_str)) { dprintf (D_ALWAYS, "Error receiving credential metadata\n"); goto EXIT; } classad_cstr = classad_str; free (classad_str); _classad = parser.ParseClassAd(classad_cstr); if (!_classad) { dprintf (D_ALWAYS, "Error: invalid credential metadata %s\n", classad_cstr.c_str()); goto EXIT; } classad = *_classad; delete _classad; int type; if (!classad.EvaluateAttrInt ("Type", type)) { dprintf (D_ALWAYS, "Missing Type attribute in classad!\n"); goto EXIT; } if (type == X509_CREDENTIAL_TYPE) { cred_wrapper = new X509CredentialWrapper (classad); dprintf (D_ALWAYS, "Name=%s Size=%d\n", cred_wrapper->cred->GetName(), cred_wrapper->cred->GetDataSize()); } else { dprintf (D_ALWAYS, "Unsupported credential type %d\n", type); goto EXIT; } cred_wrapper->cred->SetOrigOwner (socket->getOwner()); // original remote uname cred_wrapper->cred->SetOwner (user); // mapped uname // Receive credential data data_size = cred_wrapper->cred->GetDataSize(); if (data_size > MAX_CRED_DATA_SIZE) { dprintf (D_ALWAYS, "ERROR: Credential data size %d > maximum allowed (%d)\n", data_size, MAX_CRED_DATA_SIZE); goto EXIT; } data = malloc (data_size); if (data == NULL) { EXCEPT("Out of memory. Aborting."); } if (!socket->code_bytes(data,data_size)) { dprintf (D_ALWAYS, "Error receiving credential data\n"); goto EXIT; } cred_wrapper->cred->SetData (data, data_size); // Check whether credential under this name already exists found_cred=false; credentials.Rewind(); while (credentials.Next(temp_cred)) { if ((strcmp(cred_wrapper->cred->GetName(), temp_cred->cred->GetName()) == 0) && (strcmp(cred_wrapper->cred->GetOwner(), temp_cred->cred->GetOwner()) == 0)) { found_cred=true; break; // found it } } if (found_cred) { dprintf (D_ALWAYS, "Credential %s for owner %s already exists!\n", cred_wrapper->cred->GetName(), cred_wrapper->cred->GetOwner()); socket->encode(); int rcred=CREDD_ERROR_CREDENTIAL_ALREADY_EXISTS; socket->code(rcred); goto EXIT; } // Write data to a file temp_file_name = dircat (cred_store_dir, "credXXXXXX"); condor_mkstemp (temp_file_name); cred_wrapper->SetStorageName (temp_file_name); init_user_id_from_FQN (user); if (!StoreData(temp_file_name,data,data_size)) { socket->encode(); int rcred = CREDD_UNABLE_TO_STORE; socket->code(rcred); goto EXIT; } ((X509CredentialWrapper*)cred_wrapper)->cred->SetRealExpirationTime ( x509_proxy_expiration_time(temp_file_name)); // Write metadata to a file credentials.Append (cred_wrapper); SaveCredentialList(); // Write response to the client socket->encode(); rc = CREDD_SUCCESS; socket->code(rc); dprintf( D_ALWAYS, "Credential name %s owner %s successfully stored\n", cred_wrapper->cred->GetName(), cred_wrapper->cred->GetOwner() ); if (type == X509_CREDENTIAL_TYPE) { ((X509Credential*)cred_wrapper->cred)->display( D_FULLDEBUG ); } rtnVal = TRUE; EXIT: if ( data != NULL ) { free (data); } if ( temp_file_name != NULL ) { delete [] temp_file_name; } if ( cred_wrapper != NULL) { delete cred_wrapper; } return rtnVal; }
void send_command(const ClassAdWrapper & ad, DaemonCommands dc, const std::string &target="") { std::string addr; if (!ad.EvaluateAttrString(ATTR_MY_ADDRESS, addr)) { PyErr_SetString(PyExc_ValueError, "Address not available in location ClassAd."); throw_error_already_set(); } std::string ad_type_str; if (!ad.EvaluateAttrString(ATTR_MY_TYPE, ad_type_str)) { PyErr_SetString(PyExc_ValueError, "Daemon type not available in location ClassAd."); throw_error_already_set(); } int ad_type = AdTypeFromString(ad_type_str.c_str()); if (ad_type == NO_AD) { printf("ad type %s.\n", ad_type_str.c_str()); PyErr_SetString(PyExc_ValueError, "Unknown ad type."); throw_error_already_set(); } daemon_t d_type; switch (ad_type) { case MASTER_AD: d_type = DT_MASTER; break; case STARTD_AD: d_type = DT_STARTD; break; case SCHEDD_AD: d_type = DT_SCHEDD; break; case NEGOTIATOR_AD: d_type = DT_NEGOTIATOR; break; case COLLECTOR_AD: d_type = DT_COLLECTOR; break; default: d_type = DT_NONE; PyErr_SetString(PyExc_ValueError, "Unknown daemon type."); throw_error_already_set(); } ClassAd ad_copy; ad_copy.CopyFrom(ad); Daemon d(&ad_copy, d_type, NULL); bool result; { condor::ModuleLock ml; result = !d.locate(); } if (result) { PyErr_SetString(PyExc_RuntimeError, "Unable to locate daemon."); throw_error_already_set(); } ReliSock sock; { condor::ModuleLock ml; result = !sock.connect(d.addr()); } if (result) { PyErr_SetString(PyExc_RuntimeError, "Unable to connect to the remote daemon"); throw_error_already_set(); } { condor::ModuleLock ml; result = !d.startCommand(dc, &sock, 0, NULL); } if (result) { PyErr_SetString(PyExc_RuntimeError, "Failed to start command."); throw_error_already_set(); } if (target.size()) { std::string target_to_send = target; if (!sock.code(target_to_send)) { PyErr_SetString(PyExc_RuntimeError, "Failed to send target."); throw_error_already_set(); } if (!sock.end_of_message()) { PyErr_SetString(PyExc_RuntimeError, "Failed to send end-of-message."); throw_error_already_set(); } } sock.close(); }
bool DCSchedd::delegateGSIcredential(const int cluster, const int proc, const char* path_to_proxy_file, time_t expiration_time, time_t *result_expiration_time, CondorError * errstack) { int reply; ReliSock rsock; // check the parameters if ( cluster < 1 || proc < 0 || !path_to_proxy_file || !errstack ) { dprintf(D_FULLDEBUG,"DCSchedd::delegateGSIcredential: bad parameters\n"); return false; } // connect to the schedd, send the DELEGATE_GSI_CRED_SCHEDD command rsock.timeout(20); // years of research... :) if( ! rsock.connect(_addr) ) { dprintf( D_ALWAYS, "DCSchedd::delegateGSIcredential: " "Failed to connect to schedd (%s)\n", _addr ); return false; } if( ! startCommand(DELEGATE_GSI_CRED_SCHEDD, (Sock*)&rsock, 0, errstack) ) { dprintf( D_ALWAYS, "DCSchedd::delegateGSIcredential: " "Failed send command to the schedd: %s\n", errstack->getFullText().c_str()); return false; } // If we're not already authenticated, force that now. if (!forceAuthentication( &rsock, errstack )) { dprintf( D_ALWAYS, "DCSchedd::delegateGSIcredential authentication failure: %s\n", errstack->getFullText().c_str() ); return false; } // Send the job id rsock.encode(); PROC_ID jobid; jobid.cluster = cluster; jobid.proc = proc; if ( !rsock.code(jobid) || !rsock.end_of_message() ) { dprintf(D_ALWAYS,"DCSchedd::delegateGSIcredential: " "Can't send jobid to the schedd\n"); return false; } // Delegate the gsi proxy filesize_t file_size = 0; // will receive the size of the file if ( rsock.put_x509_delegation(&file_size,path_to_proxy_file,expiration_time,result_expiration_time) < 0 ) { dprintf(D_ALWAYS, "DCSchedd::delegateGSIcredential " "failed to send proxy file %s\n", path_to_proxy_file); return false; } // Fetch the result rsock.decode(); reply = 0; rsock.code(reply); rsock.end_of_message(); if ( reply == 1 ) return true; else return false; }
int DCStartd::delegateX509Proxy( const char* proxy, time_t expiration_time, time_t *result_expiration_time ) { dprintf( D_FULLDEBUG, "Entering DCStartd::delegateX509Proxy()\n" ); setCmdStr( "delegateX509Proxy" ); if( ! claim_id ) { newError( CA_INVALID_REQUEST, "DCStartd::delegateX509Proxy: Called with NULL claim_id" ); return CONDOR_ERROR; } // if this claim is associated with a security session ClaimIdParser cidp(claim_id); // // 1) begin the DELEGATE_GSI_CRED_STARTD command // ReliSock* tmp = (ReliSock*)startCommand( DELEGATE_GSI_CRED_STARTD, Stream::reli_sock, 20, NULL, NULL, false, cidp.secSessionId() ); if( ! tmp ) { newError( CA_COMMUNICATION_ERROR, "DCStartd::delegateX509Proxy: Failed to send command DELEGATE_GSI_CRED_STARTD to the startd" ); return CONDOR_ERROR; } // // 2) get reply from startd - OK means continue, NOT_OK means // don't bother (the startd doesn't require a delegated // proxy // tmp->decode(); int reply; if( !tmp->code(reply) ) { newError( CA_COMMUNICATION_ERROR, "DCStartd::delegateX509Proxy: failed to receive reply from startd (1)" ); delete tmp; return CONDOR_ERROR; } if ( !tmp->end_of_message() ) { newError( CA_COMMUNICATION_ERROR, "DCStartd::delegateX509Proxy: end of message error from startd (1)" ); delete tmp; return CONDOR_ERROR; } if( reply == NOT_OK ) { delete tmp; return NOT_OK; } // // 3) send over the claim id and delegate (or copy) the given proxy // tmp->encode(); int use_delegation = param_boolean( "DELEGATE_JOB_GSI_CREDENTIALS", true ) ? 1 : 0; if( !tmp->code( claim_id ) ) { newError( CA_COMMUNICATION_ERROR, "DCStartd::delegateX509Proxy: Failed to send claim id to the startd" ); delete tmp; return CONDOR_ERROR; } if ( !tmp->code( use_delegation ) ) { newError( CA_COMMUNICATION_ERROR, "DCStartd::delegateX509Proxy: Failed to send use_delegation flag to the startd" ); delete tmp; return CONDOR_ERROR; } int rv; filesize_t dont_care; if( use_delegation ) { rv = tmp->put_x509_delegation( &dont_care, proxy, expiration_time, result_expiration_time ); } else { dprintf( D_FULLDEBUG, "DELEGATE_JOB_GSI_CREDENTIALS is False; using direct copy\n"); if( ! tmp->get_encryption() ) { newError( CA_COMMUNICATION_ERROR, "DCStartd::delegateX509Proxy: Cannot copy: channel does not have encryption enabled" ); delete tmp; return CONDOR_ERROR; } rv = tmp->put_file( &dont_care, proxy ); } if( rv == -1 ) { newError( CA_FAILURE, "DCStartd::delegateX509Proxy: Failed to delegate proxy" ); delete tmp; return CONDOR_ERROR; } if ( !tmp->end_of_message() ) { newError( CA_FAILURE, "DCStartd::delegateX509Proxy: end of message error to startd" ); delete tmp; return CONDOR_ERROR; } // command successfully sent; now get the reply tmp->decode(); if( !tmp->code(reply) ) { newError( CA_COMMUNICATION_ERROR, "DCStartd::delegateX509Proxy: failed to receive reply from startd (2)" ); delete tmp; return CONDOR_ERROR; } if ( !tmp->end_of_message() ) { newError( CA_COMMUNICATION_ERROR, "DCStartd::delegateX509Proxy: end of message error from startd (2)" ); delete tmp; return CONDOR_ERROR; } delete tmp; dprintf( D_FULLDEBUG, "DCStartd::delegateX509Proxy: successfully sent command, reply is: %d\n", reply ); return reply; }
void VMRegister::requestHostClassAds(void) { // find host startd daemon if( !m_vm_host_daemon ) m_vm_host_daemon = vmapi_findDaemon( m_vm_host_name, DT_STARTD); if( !m_vm_host_daemon ) { dprintf( D_FULLDEBUG, "Can't find host(%s) Startd daemon\n", m_vm_host_name ); return; } ClassAd query_ad; query_ad.SetMyTypeName(QUERY_ADTYPE); query_ad.SetTargetTypeName(STARTD_ADTYPE); query_ad.Assign(ATTR_REQUIREMENTS, true); char *addr = m_vm_host_daemon->addr(); Daemon hstartd(DT_STARTD, addr); ReliSock ssock; ssock.timeout( VM_SOCKET_TIMEOUT ); ssock.encode(); if( !ssock.connect(addr) ) { dprintf( D_FULLDEBUG, "Failed to connect to host startd(%s)\n to get host classAd", addr); return; } if(!hstartd.startCommand( QUERY_STARTD_ADS, &ssock )) { dprintf( D_FULLDEBUG, "Failed to send QUERY_STARTD_ADS command to host startd(%s)\n", addr); return; } if( !query_ad.put(ssock) ) { dprintf(D_FULLDEBUG, "Failed to send query Ad to host startd(%s)\n", addr); } if( !ssock.end_of_message() ) { dprintf(D_FULLDEBUG, "Failed to send query EOM to host startd(%s)\n", addr); } // Read host classAds ssock.timeout( VM_SOCKET_TIMEOUT ); ssock.decode(); int more = 1, num_ads = 0; ClassAdList adList; ClassAd *ad; while (more) { if( !ssock.code(more) ) { ssock.end_of_message(); return; } if(more) { ad = new ClassAd; if( !ad->initFromStream(ssock) ) { ssock.end_of_message(); delete ad; return; } adList.Insert(ad); num_ads++; } } ssock.end_of_message(); dprintf(D_FULLDEBUG, "Got %d classAds from host\n", num_ads); // Although we can get more than one classAd from host machine, // we use only the first one classAd adList.Rewind(); ad = adList.Next(); #if !defined(WANT_OLD_CLASSADS) ad->AddTargetRefs( TargetJobAttrs ); #endif // Get each Attribute from the classAd // added "HOST_" in front of each Attribute name const char *name; ExprTree *expr; ad->ResetExpr(); while( ad->NextExpr(name, expr) ) { MyString attr; attr += "HOST_"; attr += name; // Insert or Update an attribute to host_classAd in a VMRegister object ExprTree * pTree = expr->Copy(); host_classad->Insert(attr.Value(), pTree, true); } }