/* proxy_valid_right_now() this function is used in this object to determine if glexec should actually be invoked. glexec will always fail with an expired proxy, and there is overhead in invoking it. */ int GLExecPrivSepHelper::proxy_valid_right_now() { int result = TRUE; /* Note that set_user_priv is a no-op if condor is running as non-root (the "usual" mode for invoking glexec) */ priv_state priv_saved = set_user_priv(); if (!m_proxy) { dprintf(D_FULLDEBUG, "GLExecPrivSepHelper::proxy_valid_right_now: no proxy defined\n"); result = FALSE; } else { time_t expiration_time = x509_proxy_expiration_time(m_proxy); time_t now = time(NULL); if (expiration_time == -1) { dprintf(D_FULLDEBUG, "GLExecPrivSepHelper::proxy_valid_right_now: Globus error when getting proxy %s expiration: %s.\n", m_proxy, x509_error_string()); result = FALSE; } else if (expiration_time < now) { dprintf(D_FULLDEBUG, "GLExecPrivSepHelper::proxy_valid_right_now: proxy %s expired %ld seconds ago!\n", m_proxy, now - expiration_time); result = FALSE; } } set_priv(priv_saved); return result; }
// This function is called // periodically to check for updated proxies. It can be called earlier // if a proxy is about to expire. void CheckProxies() { int now = time(NULL); int next_check = CheckProxies_interval + now; ProxySubject *curr_subject; dprintf( D_FULLDEBUG, "Checking proxies\n" ); SubjectsByName.startIterations(); while ( SubjectsByName.iterate( curr_subject ) != 0 ) { Proxy *curr_proxy; Proxy *new_master = curr_subject->master_proxy; curr_subject->proxies.Rewind(); while ( curr_subject->proxies.Next( curr_proxy ) != false ) { int new_expiration = x509_proxy_expiration_time( curr_proxy->proxy_filename ); // Check whether to renew the proxy (need to check all myproxy entries) if (!curr_proxy->myproxy_entries.IsEmpty()) { curr_proxy->myproxy_entries.Rewind(); MyProxyEntry * myProxyEntry=NULL; while (curr_proxy->myproxy_entries.Next (myProxyEntry) != false ) { if (new_expiration <= now + (myProxyEntry->refresh_threshold*60)) { dprintf (D_FULLDEBUG, "About to RefreshProxyThruMyProxy() for %s\n", curr_proxy->proxy_filename); RefreshProxyThruMyProxy (curr_proxy); break; } } } curr_proxy->near_expired = (curr_proxy->expiration_time - now) <= minProxy_time; if ( new_expiration > curr_proxy->expiration_time ) { curr_proxy->expiration_time = new_expiration; curr_proxy->near_expired = (curr_proxy->expiration_time - now) <= minProxy_time; Callback cb; curr_proxy->m_callbacks.Rewind(); while ( curr_proxy->m_callbacks.Next( cb ) ) { ((cb.m_data)->*(cb.m_func_ptr))(); } if ( curr_proxy->expiration_time > new_master->expiration_time ) { new_master = curr_proxy; } } else if ( curr_proxy->near_expired ) { Callback cb; curr_proxy->m_callbacks.Rewind(); while ( curr_proxy->m_callbacks.Next( cb ) ) { ((cb.m_data)->*(cb.m_func_ptr))(); } } if ( curr_proxy->expiration_time - minProxy_time < next_check && !curr_proxy->near_expired ) { next_check = curr_proxy->expiration_time - minProxy_time; } } if ( new_master != curr_subject->master_proxy ) { SetMasterProxy( curr_subject->master_proxy, new_master ); } } // next_check is the absolute time of the next check, convert it to // a relative time (from now) daemonCore->Reset_Timer( CheckProxies_tid, next_check - now ); }
Condor_Auth_X509::CondorAuthX509Retval Condor_Auth_X509::authenticate_server_gss(CondorError* errstack, bool non_blocking) { OM_uint32 major_status = GSS_S_COMPLETE; OM_uint32 minor_status = 0; OM_uint32 time_req; gss_buffer_desc output_token_desc = GSS_C_EMPTY_BUFFER; gss_buffer_t output_token = &output_token_desc; gss_buffer_desc input_token_desc; gss_buffer_t input_token; if ( !m_globusActivated ) { errstack->push("GSI", GSI_ERR_AUTHENTICATION_FAILED, "Failed to load Globus libraries."); return Fail; } m_state = GSSAuth; do { if (non_blocking && !mySock_->readReady()) { dprintf(D_NETWORK, "Returning to DC as read would block.\n"); return WouldBlock; } input_token_desc.length = 0; input_token_desc.value = NULL; input_token = &input_token_desc; if ((token_status = relisock_gsi_get( mySock_, &input_token->value, &input_token->length)) != 0) { major_status = GSS_S_DEFECTIVE_TOKEN | GSS_S_CALL_INACCESSIBLE_READ; break; } dprintf(D_NETWORK, "gss_assist_accept_sec_context(1):inlen:%lu\n", static_cast<unsigned long>(input_token->length)); major_status = (*gss_accept_sec_context_ptr)( &minor_status, &context_handle, credential_handle, input_token, GSS_C_NO_CHANNEL_BINDINGS, &m_client_name, NULL, output_token, &ret_flags, &time_req, NULL); dprintf(D_NETWORK, "gss_assist_accept_sec_context(2)" "maj:%8.8x:min:%8.8x:ret:%8.8x " "outlen:%lu:context:%p\n", (unsigned int) major_status, (unsigned int) minor_status, (unsigned int) ret_flags, output_token->length, context_handle); if (output_token->length != 0) { if ((token_status = relisock_gsi_put( mySock_, output_token->value, output_token->length)) != 0) { major_status = GSS_S_DEFECTIVE_TOKEN | GSS_S_CALL_INACCESSIBLE_WRITE; } (*gss_release_buffer_ptr)(&minor_status, output_token); } if (GSS_ERROR(major_status)) { if (context_handle != GSS_C_NO_CONTEXT) { (*gss_delete_sec_context_ptr)(&minor_status, &context_handle, GSS_C_NO_BUFFER); } break; } if (input_token->length >0) { free(input_token->value); input_token->length = 0; } } while (major_status & GSS_S_CONTINUE_NEEDED); if (input_token->length >0) { free(input_token->value); input_token->length = 0; } m_status = 0; if ( (major_status != GSS_S_COMPLETE)) { if (major_status == 655360) { errstack->pushf("GSI", GSI_ERR_AUTHENTICATION_FAILED, "COMMON Failed to authenticate (%u:%u)", (unsigned)major_status, (unsigned)minor_status); } else { errstack->pushf("GSI", GSI_ERR_AUTHENTICATION_FAILED, "Failed to authenticate. Globus is reporting error (%u:%u)", (unsigned)major_status, (unsigned)minor_status); } print_log(major_status,minor_status,token_status, "Condor GSI authentication failure" ); } else { gss_buffer_desc tmp_buffer_desc = GSS_C_EMPTY_BUFFER; gss_buffer_t tmp_buffer = &tmp_buffer_desc; char * gss_name = NULL; major_status = (*gss_display_name_ptr)(&minor_status, m_client_name, tmp_buffer, NULL); if (major_status == GSS_S_COMPLETE) { gss_name = (char *)malloc(tmp_buffer->length+1); if (gss_name) { memcpy(gss_name, tmp_buffer->value, tmp_buffer->length); gss_name[tmp_buffer->length] = '\0'; } else { errstack->pushf("GSI", GSI_ERR_AUTHENTICATION_FAILED, "Unable to allocate buffer"); major_status = GSS_S_FAILURE; } } else { errstack->pushf("GSI", GSI_ERR_AUTHENTICATION_FAILED, "Unable to determine remote client name. Globus is reporting error (%u:%u)", (unsigned)major_status, (unsigned)minor_status); } (*gss_release_buffer_ptr)(&minor_status, tmp_buffer); classad::ClassAd ad; // store the raw subject name for later mapping if (gss_name) { setAuthenticatedName(gss_name); ad.InsertAttr(ATTR_X509_USER_PROXY_SUBJECT, gss_name); free(gss_name); } setRemoteUser("gsi"); setRemoteDomain( UNMAPPED_DOMAIN ); // get handle to cred so we can extract other attributes globus_gsi_cred_handle_t peer_cred = context_handle->peer_cred_handle->cred_handle; time_t expiration = x509_proxy_expiration_time(peer_cred); if (expiration != -1) { ad.InsertAttr(ATTR_X509_USER_PROXY_EXPIRATION, expiration); } char *email_name = x509_proxy_email(peer_cred); if (email_name) { ad.InsertAttr(ATTR_X509_USER_PROXY_EMAIL, email_name); free(email_name); } if (param_boolean("USE_VOMS_ATTRIBUTES", true)) { // get the voms attributes from the peer char * voname = NULL; char * firstfqan = NULL; char * voms_fqan = NULL; int voms_err = extract_VOMS_info(peer_cred, 1, &voname, &firstfqan, &voms_fqan); if (!voms_err) { setFQAN(voms_fqan); if (voms_fqan) {ad.InsertAttr(ATTR_X509_USER_PROXY_FQAN, voms_fqan);} free(voms_fqan); if (firstfqan) {ad.InsertAttr(ATTR_X509_USER_PROXY_FIRST_FQAN, firstfqan);} free(firstfqan); if (voname) {ad.InsertAttr(ATTR_X509_USER_PROXY_VONAME, voname);} free(voname); } else { // complain! dprintf(D_SECURITY, "ZKM: VOMS FQAN not present (error %i), ignoring.\n", voms_err); } } mySock_->setPolicyAd(ad); // XXX FIXME ZKM // i am making failure to be mapped a non-fatal error at this point. m_status = (major_status == GSS_S_COMPLETE); mySock_->encode(); if (!mySock_->code(m_status) || !mySock_->end_of_message()) { errstack->push("GSI", GSI_ERR_COMMUNICATIONS_ERROR, "Failed to authenticate with client. Unable to send status"); dprintf(D_SECURITY, "Unable to send final confirmation\n"); m_status = 0; } } m_state = GetClientPost; return (m_status == 0) ? Fail : Continue; }
// An entity (e.g. GlobusJob, GlobusResource object) should call this // function when it wants to use a proxy and have it managed by // ProxyManager. job_ad contains attributes related to the proxy to be // used. error allows the function to return an error message if proxy // acquisition fails. notify_tid is a timer id that // will be signalled when something interesting happens with the proxy // (it's about to expire or has been refreshed). A Proxy struct will be // returned. When the Proxy is no longer needed, ReleaseProxy() should be // called with it. If no notifications are desired, give a // negative number for notify_tid or omit it. Note the the Proxy returned // is a shared data-structure and shouldn't be delete'd or modified by // the caller. // If AcquireProxy() encounters an error, it will store an error message // in the error parameter and return NULL. If the job ad doesn't contain // any proxy-related attributes, AcquireProxy() will store the empty // string in the error parameter and return NULL. Proxy * AcquireProxy( const ClassAd *job_ad, std::string &error, TimerHandlercpp func_ptr, Service *data ) { if ( proxymanager_initialized == false ) { error = "Internal Error: ProxyManager not initialized"; return NULL; } int expire_time; Proxy *proxy = NULL; ProxySubject *proxy_subject = NULL; char *subject_name = NULL; char *fqan = NULL; char *email = NULL; char *first_fqan = NULL; std::string proxy_path; std::string owner; char *param_str = NULL; bool has_voms_attrs = false; if ( job_ad->LookupString( ATTR_OWNER, owner ) ) { std::string param_name; formatstr( param_name, "JOB_PROXY_OVERRIDE_FILE_%s", owner.c_str() ); param_str = param( param_name.c_str() ); } if ( param_str == NULL ) { param_str = param( "JOB_PROXY_OVERRIDE_FILE" ); } if ( param_str ) { proxy_path = param_str; free( param_str ); } else if ( job_ad->LookupString( ATTR_X509_USER_PROXY, proxy_path ) == 0 ) { // Special handling for "use best proxy" job_ad->LookupString( ATTR_X509_USER_PROXY_FQAN, &fqan ); job_ad->LookupString( ATTR_X509_USER_PROXY_FIRST_FQAN, &first_fqan ); job_ad->LookupString( ATTR_X509_USER_PROXY_SUBJECT, &subject_name ); job_ad->LookupString( ATTR_X509_USER_PROXY_EMAIL, &email ); if ( subject_name ) { if ( fqan == NULL ) { fqan = strdup( subject_name ); } else { has_voms_attrs = true; } if ( SubjectsByName.lookup( HashKey(fqan), proxy_subject ) != 0 ) { // We don't know about this proxy subject yet, // create a new ProxySubject and fill it out std::string tmp; proxy_subject = new ProxySubject; proxy_subject->subject_name = strdup( subject_name ); if (email) proxy_subject->email = strdup( email ); else proxy_subject->email = NULL; proxy_subject->fqan = fqan ? strdup( fqan ) : NULL; proxy_subject->first_fqan = first_fqan ? strdup( first_fqan ) : NULL; proxy_subject->has_voms_attrs = has_voms_attrs; // Create a master proxy for our new ProxySubject Proxy *new_master = new Proxy; new_master->id = next_proxy_id++; formatstr( tmp, "%s/master_proxy.%d", masterProxyDirectory, new_master->id ); new_master->proxy_filename = strdup( tmp.c_str() ); new_master->num_references = 0; new_master->subject = proxy_subject; //SetMasterProxy( new_master, proxy ); new_master->expiration_time = -1; new_master->near_expired = true; ProxiesByFilename.insert( HashKey(new_master->proxy_filename), new_master ); proxy_subject->master_proxy = new_master; SubjectsByName.insert(HashKey(proxy_subject->fqan), proxy_subject); } // Now that we have a proxy_subject, return it's master proxy proxy = proxy_subject->master_proxy; proxy->num_references++; if ( func_ptr ) { Callback cb; cb.m_func_ptr = func_ptr; cb.m_data = data; if ( proxy->m_callbacks.IsMember( cb ) == false ) { proxy->m_callbacks.Append( cb ); } } free( subject_name ); if ( email ) free( email ); free( fqan ); free( first_fqan ); return proxy; } free( subject_name ); free( email ); free( fqan ); free( first_fqan ); //sprintf( error, "%s is not set in the job ad", ATTR_X509_USER_PROXY ); error = ""; return NULL; } // If Condor-C submitted the job, the proxy_path is relative to the // spool directory. For the purposes of this function, extend the // proxy path with the ATTR_JOB_IWD if (proxy_path[0] != DIR_DELIM_CHAR) { std::string iwd; job_ad->LookupString(ATTR_JOB_IWD, iwd); if (!iwd.empty()) { std::stringstream ss; ss << iwd << DIR_DELIM_CHAR << proxy_path; proxy_path = ss.str(); } } if ( ProxiesByFilename.lookup( HashKey(proxy_path.c_str()), proxy ) == 0 ) { // We already know about this proxy, // use the existing Proxy struct proxy->num_references++; if ( func_ptr ) { Callback cb; cb.m_func_ptr = func_ptr; cb.m_data = data; if ( proxy->m_callbacks.IsMember( cb ) == false ) { proxy->m_callbacks.Append( cb ); } } return proxy; } else { // We don't know about this proxy yet, // find the proxy's expiration time and subject name expire_time = x509_proxy_expiration_time( proxy_path.c_str() ); if ( expire_time < 0 ) { dprintf( D_ALWAYS, "Failed to get expiration time of proxy %s\n", proxy_path.c_str() ); error = "Failed to get expiration time of proxy"; return NULL; } subject_name = x509_proxy_identity_name( proxy_path.c_str() ); if ( subject_name == NULL ) { dprintf( D_ALWAYS, "Failed to get identity of proxy %s\n", proxy_path.c_str() ); error = "Failed to get identity of proxy"; return NULL; } email = x509_proxy_email( proxy_path.c_str() ); fqan = NULL; #if defined(HAVE_EXT_GLOBUS) int rc = extract_VOMS_info_from_file( proxy_path.c_str(), 0, NULL, &first_fqan, &fqan ); if ( rc != 0 && rc != 1 ) { dprintf( D_ALWAYS, "Failed to get voms info of proxy %s\n", proxy_path.c_str() ); error = "Failed to get voms info of proxy"; free( subject_name ); free( email ); return NULL; } #endif if ( fqan ) { has_voms_attrs = true; } else { fqan = strdup( subject_name ); } // Create a Proxy struct for our new proxy and populate it proxy = new Proxy; proxy->proxy_filename = strdup(proxy_path.c_str()); proxy->num_references = 1; proxy->expiration_time = expire_time; proxy->near_expired = (expire_time - time(NULL)) <= minProxy_time; proxy->id = next_proxy_id++; if ( func_ptr ) { Callback cb; cb.m_func_ptr = func_ptr; cb.m_data = data; if ( proxy->m_callbacks.IsMember( cb ) == false ) { proxy->m_callbacks.Append( cb ); } } ProxiesByFilename.insert(HashKey(proxy_path.c_str()), proxy); if ( SubjectsByName.lookup( HashKey(fqan), proxy_subject ) != 0 ) { // We don't know about this proxy subject yet, // create a new ProxySubject and fill it out std::string tmp; proxy_subject = new ProxySubject; proxy_subject->subject_name = strdup( subject_name ); proxy_subject->email = email ? strdup( email ) : NULL; proxy_subject->fqan = strdup( fqan ); proxy_subject->first_fqan = first_fqan ? strdup( first_fqan ) : NULL; proxy_subject->has_voms_attrs = true; // Create a master proxy for our new ProxySubject Proxy *new_master = new Proxy; new_master->id = next_proxy_id++; formatstr( tmp, "%s/master_proxy.%d", masterProxyDirectory, new_master->id ); new_master->proxy_filename = strdup( tmp.c_str() ); new_master->num_references = 0; new_master->subject = proxy_subject; SetMasterProxy( new_master, proxy ); ProxiesByFilename.insert( HashKey(new_master->proxy_filename), new_master ); proxy_subject->master_proxy = new_master; SubjectsByName.insert(HashKey(proxy_subject->fqan), proxy_subject); } proxy_subject->proxies.Append( proxy ); proxy->subject = proxy_subject; // If the new Proxy is longer-lived than the current master proxy for // this subject, copy it for the new master. if ( proxy->expiration_time > proxy_subject->master_proxy->expiration_time ) { SetMasterProxy( proxy_subject->master_proxy, proxy ); } free( subject_name ); free( email ); free( fqan ); free( first_fqan ); } // MyProxy crap std::string buff; if ( job_ad->LookupString( ATTR_MYPROXY_HOST_NAME, buff ) ) { int cluster; int proc; ASSERT( job_ad->LookupInteger( ATTR_CLUSTER_ID, cluster ) ); ASSERT( job_ad->LookupInteger( ATTR_PROC_ID, proc ) ); MyProxyEntry * myProxyEntry =new MyProxyEntry(); myProxyEntry->last_invoked_time=0; myProxyEntry->get_delegation_pid=FALSE; myProxyEntry->get_delegation_err_fd=-1; myProxyEntry->get_delegation_err_filename=NULL; myProxyEntry->myproxy_server_dn=NULL; myProxyEntry->myproxy_password=NULL; myProxyEntry->myproxy_credential_name=NULL; myProxyEntry->myproxy_host=strdup(buff.c_str()); myProxyEntry->cluster_id = cluster; myProxyEntry->proc_id = proc; // Get optional MYPROXY_SERVER_DN attribute if (job_ad->LookupString (ATTR_MYPROXY_SERVER_DN, buff)) { myProxyEntry->myproxy_server_dn=strdup(buff.c_str()); } if (job_ad->LookupString (ATTR_MYPROXY_CRED_NAME, buff)) { myProxyEntry->myproxy_credential_name=strdup(buff.c_str()); } if (job_ad->LookupInteger (ATTR_MYPROXY_REFRESH_THRESHOLD, myProxyEntry->refresh_threshold)) { //myProxyEntry->refresh_threshold=atoi(buff); // In minutes dprintf (D_FULLDEBUG, "MyProxy Refresh Threshold %d\n",myProxyEntry->refresh_threshold); } else { myProxyEntry->refresh_threshold = 4*60; // default 4 hrs dprintf (D_FULLDEBUG, "MyProxy Refresh Threshold %d (default)\n",myProxyEntry->refresh_threshold); } if (job_ad->LookupInteger (ATTR_MYPROXY_NEW_PROXY_LIFETIME, myProxyEntry->new_proxy_lifetime)) { //myProxyEntry->new_proxy_lifetime=atoi(buff); // In hours dprintf (D_FULLDEBUG, "MyProxy New Proxy Lifetime %d\n",myProxyEntry->new_proxy_lifetime); } else { myProxyEntry->new_proxy_lifetime = 12; // default 12 hrs dprintf (D_FULLDEBUG, "MyProxy New Proxy Lifetime %d (default)\n",myProxyEntry->new_proxy_lifetime); } dprintf (D_FULLDEBUG, "Adding new MyProxy entry for proxy %s : host=%s, cred name=%s\n", proxy->proxy_filename, myProxyEntry->myproxy_host, (myProxyEntry->myproxy_credential_name!=NULL)?(myProxyEntry->myproxy_credential_name):"<default>"); proxy->myproxy_entries.Prepend (myProxyEntry); // Add at the top of the list, so it'll be used first // See if we already have a MyProxy entry for the given host/credential name /*int found = FALSE; MyProxyEntry * currentMyProxyEntry = NULL; jobProxy->myproxy_entries.Rewind(); while (jobProxy->myproxy_entries.Next (currentMyProxyEntry)) { if (strcmp (currentMyProxyEntry->myproxy_host, myProxyEntry->myproxy_host)) { continue; } if (myProxyEntry->myproxy_credential_name == NULL || myProxyEntry->myproxy_credential_name == NULL) { if (myProxyEntry->myproxy_credential_name != NULL || myProxyEntry->myproxy_credential_name != NULL) { // One credential name is NULL, the other is not continue; } } else { if (strcmp (currentMyProxyEntry->myproxy_credential_name, myProxyEntry->myproxy_credential_name)) { // credential names non-null and not-equal continue; } } // If we've gotten this far, we've got a match found = TRUE; break; } //... If we don't, insert it if (!found) { dprintf (D_FULLDEBUG, "Adding new MyProxy entry for proxy %s : host=%s, cred name=%s\n", jobProxy->proxy_filename, myProxyEntry->myproxy_host, (myProxyEntry->myproxy_credential_name!=NULL)?(myProxyEntry->myproxy_credential_name):"<default>"); jobProxy->myproxy_entries.Append (myProxyEntry); } else { // No need to insert this delete myProxyEntry; }*/ } return proxy; }
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; }