void _mark_thread_safe(int start_or_stop, int dologging, const char* descrip, const char* func, const char* file, int line) { mark_thread_func_t callback=0; const char* mode=0; #ifdef WIN32 char buf[40]; #endif switch (start_or_stop) { case 1: callback = start_callback; mode = "start"; break; case 2: callback = stop_callback; mode = "stop"; break; default: EXCEPT("unexpected mode: %d",start_or_stop); } if ( !callback ) { // nothing to do, we're done. return; } if (descrip == NULL) { descrip = "\0"; } #ifdef WIN32 strcpy(buf,"tid="); func = itoa(GetCurrentThreadId(), &buf[4], 10 ); #endif if ( dologging && IsDebugVerbose(D_THREADS)) { dprintf(D_THREADS,"Entering thread safe %s [%s] in %s:%d %s()\n", mode, descrip, my_local_basename(file), line, func); } (*callback)(); if ( dologging && IsDebugVerbose(D_THREADS)) { dprintf(D_THREADS,"Leaving thread safe %s [%s] in %s:%d %s()\n", mode, descrip, my_local_basename(file), line, func); } return; }
int Condor_Auth_Kerberos :: map_domain_name(const char * domain) { if (RealmMap == 0) { init_realm_mapping(); // it's okay if it returns false } // two cases, if domain is the same as the current uid domain, // then we are okay, other wise, see if we have a map if (RealmMap) { MyString from(domain), to; if (RealmMap->lookup(from, to) != -1) { if (IsFulldebug(D_SECURITY)) { dprintf (D_SECURITY, "KERBEROS: mapping realm %s to domain %s.\n", from.Value(), to.Value()); } setRemoteDomain(to.Value()); return TRUE; } else { // if the map exists, they must be listed. and they're NOT! return FALSE; } } // if there is no map, we just allow realm -> domain. if (IsDebugVerbose(D_SECURITY)) { dprintf (D_SECURITY, "KERBEROS: mapping realm %s to domain %s.\n", domain, domain); setRemoteDomain(domain); } return TRUE; }
/* Get the next n bytes from the message: * Copy the next 'size' bytes of the message to 'dta' * param: dta - buffer to which data will be copied * size - the number of bytes to be copied * return: the actual number of bytes copied, if success * -1, if failed * Notice: dta must be a pointer to object(>= size) */ int _condorInMsg::getn(char* dta, const int size) { int len, total = 0; if(!dta || passed + size > msgLen) { dprintf(D_NETWORK, "dta is NULL or more data than queued is requested\n"); return -1; } while(total != size) { len = size - total; if(len > curDir->dEntry[curPacket].dLen - curData) len = curDir->dEntry[curPacket].dLen - curData; memcpy(&dta[total], &(curDir->dEntry[curPacket].dGram[curData]), len); total += len; incrementCurData(len); } // of while(total..) if( IsDebugVerbose(D_NETWORK) ) { dprintf(D_NETWORK, "%d bytes read from UDP[size=%ld, passed=%d]\n", total, msgLen, passed); } return total; }
bool VMStarterInfo::updateUsageOfVM(void) { if( m_vm_pid == 0) { return false; } int proc_status = PROCAPI_OK; piPTR pi = NULL; if( ProcAPI::getProcInfo(m_vm_pid, pi, proc_status) == PROCAPI_SUCCESS ) { memcpy(&m_vm_alive_pinfo, pi, sizeof(struct procInfo)); if( IsDebugVerbose(D_LOAD) ) { dprintf(D_LOAD,"Usage of process[%d] for a VM is updated\n", m_vm_pid); dprintf(D_LOAD,"sys_time=%lu, user_time=%lu, image_size=%lu\n", pi->sys_time, pi->user_time, get_image_size(*pi)); } delete pi; return true; } if (pi) delete pi; return false; }
float sysapi_load_avg_raw(void) { float first, second, third; int mib[4]; struct loadavg load; size_t len; sysapi_internal_reconfig(); mib[0] = CTL_VM; mib[1] = VM_LOADAVG; len = sizeof(struct loadavg); sysctl(mib, 2, &load, &len, NULL, 0); first = (float)load.ldavg[0] / (float)load.fscale; second = (float)load.ldavg[1] / (float)load.fscale; third = (float)load.ldavg[2] / (float)load.fscale; if( IsDebugVerbose( D_LOAD ) ) { dprintf( D_LOAD, "Load avg: %.2f %.2f %.2f\n", first, second, third ); } return first; }
float sysapi_load_avg_raw(void) { float val; sysapi_internal_reconfig(); val = lookup_load_avg_via_uptime(); if( IsDebugVerbose( D_LOAD ) ) { dprintf( D_LOAD, "Load avg: %.2f\n", val ); } return val; }
float sysapi_load_avg_raw(void) { FILE *proc; struct utsname buf; int major, minor, patch; float short_avg, medium_avg, long_avg; sysapi_internal_reconfig(); // Obtain the kernel version so that we know what /proc looks like.. if( uname(&buf) < 0 ) return -1; sscanf(buf.release, "%d.%d.%d", &major, &minor, &patch); // /proc/loadavg looks like: // Kernel Version 2.0.0: // 0.03 0.03 0.09 2/42 15582 proc=safe_fopen_wrapper_follow("/proc/loadavg","r",0644); if(!proc) return -1; switch(major) { case 1: case 2: case 3: if (fscanf(proc, "%f %f %f", &short_avg, &medium_avg, &long_avg) != 3) { dprintf(D_ALWAYS, "Failed to fscanf 3 floats from /proc/loadavg\n"); fclose(proc); return -1; } break; default: dprintf(D_ALWAYS, "/proc format unknown for kernel version %d.%d.%d\n", major, minor, patch); fclose(proc); return -1; break; } fclose(proc); if( IsDebugVerbose( D_LOAD ) ) { dprintf( D_LOAD, "Load avg: %.2f %.2f %.2f\n", short_avg, medium_avg, long_avg ); } return short_avg; }
float Starter::percentCpuUsage( void ) { if (daemonCore->Get_Family_Usage(s_pid, s_usage, true) == FALSE) { EXCEPT( "Starter::percentCpuUsage(): Fatal error getting process " "info for the starter and decendents" ); } // In vm universe, there may be a process dealing with a VM. // Unfortunately, such a process is created by a specific // running daemon for virtual machine program(such as vmware-serverd). // So our Get_Family_Usage is unable to get usage for the process. // Here, we call a function in vm universe manager. // If this starter is for vm universe, s_usage will be updated. // Otherwise, s_usage will not change. if ( resmgr ) { resmgr->m_vmuniverse_mgr.getUsageForVM(s_pid, s_usage); // Now try to tack on details posted in the job ad because // hypervisors such as libvirt will spawn processes outside // of condor's perview. float fPercentCPU=0.0; int iNumCPUs=0; ClassAd * jobAd = s_claim->ad(); jobAd->LookupFloat(ATTR_JOB_VM_CPU_UTILIZATION, fPercentCPU); jobAd->LookupInteger(ATTR_JOB_VM_VCPUS, iNumCPUs); // computations outside take cores into account. fPercentCPU = fPercentCPU * iNumCPUs; dprintf( D_LOAD, "Starter::percentCpuUsage() adding VM Utilization %f\n",fPercentCPU); s_usage.percent_cpu += fPercentCPU; } if( IsDebugVerbose(D_LOAD) ) { dprintf(D_LOAD, "Starter::percentCpuUsage(): Percent CPU usage " "for the family of starter with pid %u is: %f\n", s_pid, s_usage.percent_cpu ); } return s_usage.percent_cpu; }
void VMStarterInfo::getUsageOfVM(ProcFamilyUsage &usage) { bool updated = updateUsageOfVM(); usage.user_cpu_time = m_vm_exited_pinfo.user_time + m_vm_alive_pinfo.user_time; usage.sys_cpu_time = m_vm_exited_pinfo.sys_time + m_vm_alive_pinfo.sys_time; if( updated ) { usage.percent_cpu = m_vm_alive_pinfo.cpuusage; }else usage.percent_cpu = 0; unsigned long exited_max_image = get_image_size(m_vm_exited_pinfo); unsigned long alive_max_image = get_image_size(m_vm_alive_pinfo); usage.max_image_size = (exited_max_image > alive_max_image ) ? exited_max_image : alive_max_image; if( updated ) { usage.total_image_size = m_vm_alive_pinfo.imgsize; usage.total_resident_set_size = m_vm_alive_pinfo.rssize; #if HAVE_PSS usage.total_proportional_set_size = m_vm_alive_pinfo.pssize; usage.total_proportional_set_size = m_vm_alive_pinfo.pssize_available; #endif }else { usage.total_image_size = 0; usage.total_resident_set_size = 0; #if HAVE_PSS usage.total_proportional_set_size = 0; usage.total_proportional_set_size = false; #endif } if( IsDebugVerbose(D_LOAD) ) { dprintf( D_LOAD, "VMStarterInfo::getUsageOfVM(): Percent CPU usage " "for VM process with pid %u is: %f\n", m_vm_pid, usage.percent_cpu ); } }
int Authentication::authenticate_inner( char *hostAddr, const char* auth_methods, CondorError* errstack, int timeout, bool non_blocking) { #if defined(SKIP_AUTHENTICATION) dprintf(D_ALWAYS, "Skipping....\n"); /* errstack->push ( "AUTHENTICATE", AUTHENTICATE_ERR_NOT_BUILT, "this condor was built with SKIP_AUTHENTICATION"); */ return 0; #else m_host_addr = hostAddr ? hostAddr : "(unknown)"; if (timeout > 0) { dprintf( D_SECURITY, "AUTHENTICATE: setting timeout for %s to %d.\n", m_host_addr.c_str(), timeout); m_auth_timeout_time = time(0) + timeout; } else { m_auth_timeout_time = 0; } if (IsDebugVerbose(D_SECURITY)) { if (m_host_addr.size()) { dprintf ( D_SECURITY, "AUTHENTICATE: in authenticate( addr == '%s', " "methods == '%s')\n", m_host_addr.c_str(), auth_methods); } else { dprintf ( D_SECURITY, "AUTHENTICATE: in authenticate( addr == NULL, " "methods == '%s')\n", auth_methods); } } m_methods_to_try = auth_methods; m_continue_handshake = false; m_continue_auth = false; auth_status = CAUTH_NONE; method_used = NULL; m_auth = NULL; return authenticate_continue(errstack, non_blocking); #endif }
bool _condorPacket :: set_encryption_id(const char * keyId) { // This should be for outpacket only! ASSERT(empty()); if (outgoingEncKeyId_) { if( curIndex > 0 ) { curIndex -= outgoingEidLen_; if (curIndex == SAFE_MSG_CRYPTO_HEADER_SIZE) { // empty header curIndex -= SAFE_MSG_CRYPTO_HEADER_SIZE; } ASSERT( curIndex >= 0 ); } free(outgoingEncKeyId_); outgoingEncKeyId_ = 0; outgoingEidLen_ = 0; } if (keyId) { outgoingEncKeyId_ = strdup(keyId); outgoingEidLen_ = strlen(outgoingEncKeyId_); if( IsDebugVerbose(D_SECURITY) ) { dprintf( D_SECURITY, "set_encryption_id: setting key length %d\n", outgoingEidLen_ ); } if ( curIndex == 0 ) { curIndex += SAFE_MSG_CRYPTO_HEADER_SIZE; } curIndex += outgoingEidLen_; } length = curIndex; return true; }
/* this function must return the same values as globus!!!! also, it must allocate memory the same: create a new string and write address into '*to'. */ int Condor_Auth_X509::condor_gss_assist_gridmap(const char * from, char ** to) { if (GridMap == 0) { ParseMapFile(); } if (GridMap) { MyString f(from), t; if (GridMap->lookup(f, t) != -1) { if (IsDebugVerbose(D_SECURITY)) { dprintf (D_SECURITY, "GSI: subject %s is mapped to user %s.\n", f.Value(), t.Value()); } *to = strdup(t.Value()); return GSS_S_COMPLETE; } else { // if the map exists, they must be listed. and they're NOT! return !GSS_S_COMPLETE; } } return !GSS_S_COMPLETE; }
/* Generic read/write wrappers for condor. These function emulate-ish the * read/write system calls under unix except that they are portable, use * a timeout, and make sure that all data is read or written. * * A few notes on the behavior differing from POSIX: * - These will never fail due to EINTR. * - If in non_blocking mode, there may be a short read or write returned. * - The corresponding POSIX functon returns 0 bytes read when the peer closed * the socket; these return -2. * - If zero bytes were read/written in non-blocking mode, this will return 0. This differs * from POSIX. * - Providing a zero-sized argument to this function will cause the program to abort(). * * Returns < 0 on failure. -1 = general error, -2 = peer closed socket */ int condor_read( char const *peer_description, SOCKET fd, char *buf, int sz, int timeout, int flags, bool non_blocking ) { Selector selector; int nr = 0, nro; unsigned int start_time=0, cur_time=0; char sinbuf[SINFUL_STRING_BUF_SIZE]; if( IsDebugLevel(D_NETWORK) ) { dprintf(D_NETWORK, "condor_read(fd=%d %s,,size=%d,timeout=%d,flags=%d,non_blocking=%d)\n", fd, not_null_peer_description(peer_description,fd,sinbuf), sz, timeout, flags, non_blocking); } /* PRE Conditions. */ ASSERT(fd >= 0); /* Need valid file descriptor */ ASSERT(buf != NULL); /* Need real memory to put data into */ ASSERT(sz > 0); /* Need legit size on buffer */ if (non_blocking) { #ifdef WIN32 unsigned long mode = 1; // nonblocking mode if (ioctlsocket(fd, FIONBIO, &mode) < 0) return -1; #else int fcntl_flags; if ( (fcntl_flags=fcntl(fd, F_GETFL)) < 0 ) return -1; // set nonblocking mode if ( ((fcntl_flags & O_NONBLOCK) == 0) && fcntl(fd, F_SETFL, fcntl_flags | O_NONBLOCK) == -1 ) return -1; #endif nr = -2; while (nr == -2 || (nr == -1 && errno == EINTR)) { nr = recv(fd, buf, sz, flags); } if ( nr <= 0 ) { int the_error; char const *the_errorstr; #ifdef WIN32 the_error = WSAGetLastError(); the_errorstr = ""; #else the_error = errno; the_errorstr = strerror(the_error); #endif if ( nr == 0 && !(flags & MSG_PEEK)) { nr = -2; dprintf( D_FULLDEBUG, "condor_read(): " "Socket closed when trying to read %d bytes from %s in non-blocking mode\n", sz, not_null_peer_description(peer_description,fd,sinbuf) ); } else if ( !errno_is_temporary(the_error) ) { dprintf( D_ALWAYS, "condor_read() failed: recv() %d bytes from %s " "returned %d, " "timeout=%d, errno=%d %s.\n", sz, not_null_peer_description(peer_description,fd,sinbuf), nr, timeout, the_error, the_errorstr ); } else { nr = 0; } } #ifdef WIN32 mode = 0; // reset blocking mode if (ioctlsocket(fd, FIONBIO, &mode) < 0) return -1; #else // reset flags to prior value if ( ((fcntl_flags & O_NONBLOCK) == 0) && (fcntl(fd, F_SETFL, fcntl_flags) == -1) ) return -1; #endif return nr; } selector.add_fd( fd, Selector::IO_READ ); if ( timeout > 0 ) { start_time = time(NULL); cur_time = start_time; } while( nr < sz ) { if( timeout > 0 ) { if( cur_time == 0 ) { cur_time = time(NULL); } // If it hasn't yet been longer then we said we would wait... if( start_time + timeout > cur_time ) { selector.set_timeout( (start_time + timeout) - cur_time ); } else { dprintf( D_ALWAYS, "condor_read(): timeout reading %d bytes from %s.\n", sz, not_null_peer_description(peer_description,fd,sinbuf) ); return -1; } cur_time = 0; if( IsDebugVerbose( D_NETWORK ) ) { dprintf(D_NETWORK, "condor_read(): fd=%d\n", fd); } selector.execute(); if( IsDebugVerbose( D_NETWORK ) ) { dprintf(D_NETWORK, "condor_read(): select returned %d\n", selector.select_retval()); } if ( selector.timed_out() ) { dprintf( D_ALWAYS, "condor_read(): timeout reading %d bytes from %s.\n", sz, not_null_peer_description(peer_description,fd,sinbuf) ); return -1; } else if ( selector.signalled() ) { continue; } else if ( !selector.has_ready() ) { int the_error; char const *the_errorstr; #ifdef WIN32 the_error = WSAGetLastError(); the_errorstr = ""; #else the_error = errno; the_errorstr = strerror(the_error); #endif dprintf( D_ALWAYS, "condor_read() failed: select() " "returns %d, reading %d bytes from %s (errno=%d %s).\n", selector.select_retval(), sz, not_null_peer_description(peer_description,fd,sinbuf), the_error, the_errorstr ); return -1; } } start_thread_safe("recv"); nro = recv(fd, &buf[nr], sz - nr, flags); // Save the error value before stop_thread_safe(), as that may // overwrite it. int the_error; #ifdef WIN32 the_error = WSAGetLastError(); #else the_error = errno; #endif stop_thread_safe("recv"); if( nro <= 0 ) { // If timeout > 0, and we made it here, then // we know we were woken by select(). Now, if // select() wakes up on a read fd, and then recv() // subsequently returns 0, that means that the // socket has been closed by our peer. // If timeout == 0, then recv() should have // blocked until 1 or more bytes arrived. // Thus no matter what, if nro==0, then the // socket must be closed. if ( nro == 0 ) { dprintf( D_FULLDEBUG, "condor_read(): " "Socket closed when trying to read %d bytes from %s\n", sz, not_null_peer_description(peer_description,fd,sinbuf) ); return -2; } char const *the_errorstr; #ifdef WIN32 the_errorstr = ""; #else the_errorstr = strerror(the_error); #endif if ( errno_is_temporary(the_error) ) { dprintf( D_FULLDEBUG, "condor_read(): " "recv() returned temporary error %d %s," "still trying to read from %s\n", the_error,the_errorstr, not_null_peer_description(peer_description,fd,sinbuf) ); continue; } dprintf( D_ALWAYS, "condor_read() failed: recv(fd=%d) returned %d, " "errno = %d %s, reading %d bytes from %s.\n", fd, nro, the_error, the_errorstr, sz, not_null_peer_description(peer_description,fd,sinbuf) ); if( the_error == ETIMEDOUT ) { if( timeout <= 0 ) { dprintf( D_ALWAYS, "condor_read(): read timeout during blocking read from %s\n", not_null_peer_description(peer_description,fd,sinbuf)); } else { int lapse = (int)(time(NULL)-start_time); dprintf( D_ALWAYS, "condor_read(): UNEXPECTED read timeout after %ds during non-blocking read from %s (desired timeout=%ds)\n", lapse, not_null_peer_description(peer_description,fd,sinbuf), timeout); } } return -1; } nr += nro; } /* Post Conditions */ ASSERT( nr == sz ); // we should have read *ALL* the data return nr; }
/* Get data from message up to the delimeter: * Copy data of the message to 'dta', starting from current position up to meeting 'delim' * @param: buf - buffer to which data will be copied * delim - the delimeter * @return: the number of bytes copied, if success * -1, if failed * * Notice: new character array will be allocated as needed and the space will be * deallocated at the time of the next call of this method, so 'buf' must be * a pointer to nothing and must not be deleted by caller */ int _condorInMsg::getPtr(void *&buf, char delim) { _condorDirPage *tempDir; int tempPkt, tempData; size_t n = 1; int size; tempDir = curDir; tempPkt = curPacket; tempData = curData; bool copy_needed = false; while(1) { char *msgbuf = &tempDir->dEntry[tempPkt].dGram[tempData]; size_t msgbufsize = tempDir->dEntry[tempPkt].dLen - tempData; char *delim_ptr = (char *)memchr(msgbuf,delim,msgbufsize); if( delim_ptr ) { n += delim_ptr - msgbuf; if( n == msgbufsize ) { // Need to copy the data in this case, because when // buffer is consumed by incrementCurData(), it will // be freed. copy_needed = true; } if( !copy_needed ) { // Special (common) case: the whole string is in one piece // so just return a pointer to it and skip the drudgery // of copying the bytes into another buffer. incrementCurData(n); buf = msgbuf; return n; } break; // found delim } copy_needed = true; // string spans multiple buffers n += msgbufsize; tempPkt++; tempData = 0; if(tempPkt >= SAFE_MSG_NO_OF_DIR_ENTRY) { if(!tempDir->nextDir) { return -1; } tempDir = tempDir->nextDir; tempPkt = 0; } else if(!tempDir->dEntry[tempPkt].dGram) { // was the last packet if( IsDebugVerbose(D_NETWORK) ) dprintf(D_NETWORK, "SafeMsg::getPtr: get to end & '%c' not found\n", delim); return -1; } } if( IsDebugVerbose(D_NETWORK) ) dprintf(D_NETWORK, "SafeMsg::_longMsg::getPtr: found delim = %c & length = %lu\n", delim, (unsigned long)n); if( n > tempBufLen ) { if(tempBuf) { free(tempBuf); } tempBuf = (char *)malloc(n); if(!tempBuf) { dprintf(D_ALWAYS, "getPtr, fail at malloc(%lu)\n", (unsigned long)n); tempBufLen = 0; return -1; } tempBufLen = n; } size = getn(tempBuf, n); buf = tempBuf; //cout << "\t\tInMsg::getPtr: " << (char *)buf << endl; return size; }
int Authentication::authenticate_continue( CondorError* errstack, bool non_blocking ) { // Check for continuations; int firm = -1; bool do_handshake = true; if (m_continue_handshake) { firm = handshake_continue(m_methods_to_try, non_blocking); if ( firm == -2 ) { dprintf(D_SECURITY, "AUTHENTICATE: handshake would still block\n"); return 2; } m_continue_handshake = false; do_handshake = false; } int auth_rc = 0; bool do_authenticate = true; if (m_continue_auth) { auth_rc = m_auth->authenticate_continue(errstack, non_blocking); if (auth_rc == 2 ) { dprintf(D_SECURITY, "AUTHENTICATE: auth would still block\n"); return 2; } m_continue_auth = false; do_authenticate = false; goto authenticate; } m_auth = NULL; while (auth_status == CAUTH_NONE ) { if (m_auth_timeout_time>0 && m_auth_timeout_time <= time(0)) { dprintf(D_SECURITY, "AUTHENTICATE: exceeded deadline %ld\n", m_auth_timeout_time); errstack->pushf( "AUTHENTICATE", AUTHENTICATE_ERR_TIMEOUT, "exceeded %ld deadline during authentication", m_auth_timeout_time ); break; } if (IsDebugVerbose(D_SECURITY)) { dprintf(D_SECURITY, "AUTHENTICATE: can still try these methods: %s\n", m_methods_to_try.c_str()); } if (do_handshake) { firm = handshake(m_methods_to_try, non_blocking); } do_handshake = true; if ( firm == -2 ) { dprintf(D_SECURITY, "AUTHENTICATE: handshake would block\n"); m_continue_handshake = true; return 2; } if ( firm < 0 ) { dprintf(D_ALWAYS, "AUTHENTICATE: handshake failed!\n"); errstack->push( "AUTHENTICATE", AUTHENTICATE_ERR_HANDSHAKE_FAILED, "Failure performing handshake" ); break; } m_method_name = ""; switch ( firm ) { #if defined(HAVE_EXT_GLOBUS) case CAUTH_GSI: m_auth = new Condor_Auth_X509(mySock); m_method_name = "GSI"; break; #endif /* HAVE_EXT_GLOBUS */ #ifdef HAVE_EXT_OPENSSL case CAUTH_SSL: m_auth = new Condor_Auth_SSL(mySock); m_method_name = "SSL"; break; #endif #if defined(HAVE_EXT_KRB5) case CAUTH_KERBEROS: m_auth = new Condor_Auth_Kerberos(mySock); m_method_name = "KERBEROS"; break; #endif #ifdef HAVE_EXT_OPENSSL // 3DES is the prequisite for passwd auth case CAUTH_PASSWORD: m_auth = new Condor_Auth_Passwd(mySock); m_method_name = "PASSWORD"; break; #endif #if defined(WIN32) case CAUTH_NTSSPI: m_auth = new Condor_Auth_SSPI(mySock); m_method_name = "NTSSPI"; break; #else case CAUTH_FILESYSTEM: m_auth = new Condor_Auth_FS(mySock); m_method_name = "FS"; break; case CAUTH_FILESYSTEM_REMOTE: m_auth = new Condor_Auth_FS(mySock, 1); m_method_name = "FS_REMOTE"; break; #endif /* !defined(WIN32) */ case CAUTH_CLAIMTOBE: m_auth = new Condor_Auth_Claim(mySock); m_method_name = "CLAIMTOBE"; break; case CAUTH_ANONYMOUS: m_auth = new Condor_Auth_Anonymous(mySock); m_method_name = "ANONYMOUS"; break; case CAUTH_NONE: dprintf(D_SECURITY|D_FULLDEBUG,"AUTHENTICATE: no available authentication methods succeeded!\n"); errstack->push("AUTHENTICATE", AUTHENTICATE_ERR_OUT_OF_METHODS, "Failed to authenticate with any method"); return 0; default: dprintf(D_ALWAYS,"AUTHENTICATE: unsupported method: %i, failing.\n", firm); errstack->pushf("AUTHENTICATE", AUTHENTICATE_ERR_OUT_OF_METHODS, "Failure. Unsupported method: %i", firm); return 0; } if (IsDebugVerbose(D_SECURITY)) { dprintf(D_SECURITY, "AUTHENTICATE: will try to use %d (%s)\n", firm, (m_method_name.size()?m_method_name.c_str():"?!?") ); } // We have just picked a new method, so we definitely want to // make this value true. We log a message only if we changed // it. if(!do_authenticate) { do_authenticate = true; if (IsDebugVerbose(D_SECURITY)) { dprintf(D_SECURITY, "AUTHENTICATE: forcing do_authenticate to true.\n"); } } //------------------------------------------ // Now authenticate //------------------------------------------ authenticate: // Re-check deadline as handshake could have taken awhile. if (m_auth_timeout_time>0 && m_auth_timeout_time <= time(0)) { dprintf(D_SECURITY, "AUTHENTICATE: exceeded deadline %ld\n", m_auth_timeout_time); errstack->pushf( "AUTHENTICATE", AUTHENTICATE_ERR_TIMEOUT, "exceeded %ld deadline during authentication", m_auth_timeout_time ); break; } if (IsDebugVerbose(D_SECURITY)) { dprintf (D_SECURITY, "AUTHENTICATE: do_authenticate is %i.\n", do_authenticate); } if (do_authenticate) { auth_rc = m_auth->authenticate(m_host_addr.c_str(), errstack, non_blocking); if (auth_rc == 2) { m_continue_auth = true; return 2; } } // check to see if the auth IP is the same as the socket IP if( auth_rc ) { char const *sockip = mySock->peer_ip_str(); char const *authip = m_auth->getRemoteHost() ; auth_rc = !sockip || !authip || !strcmp(sockip,authip); if (!auth_rc && !param_boolean( "DISABLE_AUTHENTICATION_IP_CHECK", false)) { errstack->pushf("AUTHENTICATE", AUTHENTICATE_ERR_METHOD_FAILED, "authenticated remote host does not match connection address (%s vs %s)", authip, sockip ); dprintf (D_ALWAYS, "AUTHENTICATE: ERROR: authenticated remot ehost does not match connection address (%s vs %s); configure DISABLE_AUTHENTICATION_IP_CHECK=TRUE if this check should be skipped\n",authip,sockip); } } if( !auth_rc ) { delete m_auth; m_auth = NULL; errstack->pushf("AUTHENTICATE", AUTHENTICATE_ERR_METHOD_FAILED, "Failed to authenticate using %s", m_method_name.c_str() ); //if authentication failed, try again after removing from client tries if ( mySock->isClient() ) { // need to remove this item from the MyString!! perhaps there is a // better way to do this... anyways, 'firm' is equal to the bit value // of a particular method, so we'll just convert each item in the list // and keep it if it's not that particular bit. StringList meth_iter( m_methods_to_try.c_str() ); meth_iter.rewind(); MyString new_list; char *tmp = NULL; while( (tmp = meth_iter.next()) ) { int that_bit = SecMan::getAuthBitmask( tmp ); // keep if this isn't the failed method. if (firm != that_bit) { // and of course, keep the comma's correct. if (new_list.Length() > 0) { new_list += ","; } new_list += tmp; } } // trust the copy constructor. :) m_methods_to_try = new_list; } dprintf(D_SECURITY,"AUTHENTICATE: method %d (%s) failed.\n", firm, (m_method_name.size()?m_method_name.c_str():"?!?")); } else { // authentication succeeded. store the object (we may call upon // its wrapper functions) and set the auth_status of this sock to // the bitmask method we used and the method_used to the string // name. (string name is obtained above because there is currently // no bitmask -> string map) authenticator_ = m_auth; m_auth = NULL; auth_status = authenticator_->getMode(); if (m_method_name.size()) { method_used = strdup(m_method_name.c_str()); } else { method_used = NULL; } } } return authenticate_finish(errstack); }
int Authentication::authenticate_finish(CondorError *errstack) { //if none of the methods succeeded, we fall thru to default "none" from above int retval = ( auth_status != CAUTH_NONE ); if (IsDebugVerbose(D_SECURITY)) { dprintf(D_SECURITY, "AUTHENTICATE: auth_status == %i (%s)\n", auth_status, (method_used?method_used:"?!?") ); } dprintf(D_SECURITY, "Authentication was a %s.\n", retval == 1 ? "Success" : "FAILURE" ); // at this point, all methods have set the raw authenticated name available // via getAuthenticatedName(). if(authenticator_) { dprintf (D_SECURITY, "ZKM: setting default map to %s\n", authenticator_->getRemoteFQU()?authenticator_->getRemoteFQU():"(null)"); } // check to see if CERTIFICATE_MAPFILE was defined. if so, use it. if // not, do nothing. the user and domain have been filled in by the // authentication method itself, so just leave that alone. char * cert_map_file = param("CERTIFICATE_MAPFILE"); bool use_mapfile = (cert_map_file != NULL); if (cert_map_file) { free(cert_map_file); cert_map_file = 0; } // if successful so far, invoke the security MapFile. the output of that // is the "canonical user". if that has an '@' sign, split it up on the // last '@' and set the user and domain. if there is more than one '@', // the user will contain the leftovers after the split and the domain // always has none. if (retval && use_mapfile) { const char * name_to_map = authenticator_->getAuthenticatedName(); if (name_to_map) { dprintf (D_SECURITY, "ZKM: name to map is '%s'\n", name_to_map); dprintf (D_SECURITY, "ZKM: pre-map: current user is '%s'\n", authenticator_->getRemoteUser()?authenticator_->getRemoteUser():"(null)"); dprintf (D_SECURITY, "ZKM: pre-map: current domain is '%s'\n", authenticator_->getRemoteDomain()?authenticator_->getRemoteDomain():"(null)"); map_authentication_name_to_canonical_name(auth_status, method_used, name_to_map); } else { dprintf (D_SECURITY, "ZKM: name to map is null, not mapping.\n"); } #if defined(HAVE_EXT_GLOBUS) } else if (auth_status == CAUTH_GSI ) { // Fall back to using the globus mapping mechanism. GSI is a bit unique in that // it may be horribly expensive - or cause a SEGFAULT - to do an authorization callout. // Hence, we delay it until after we apply a mapfile or, here, have no map file. // nameGssToLocal calls setRemoteFoo directly. const char * name_to_map = authenticator_->getAuthenticatedName(); if (name_to_map) { int retval = ((Condor_Auth_X509*)authenticator_)->nameGssToLocal(name_to_map); dprintf(D_SECURITY, "nameGssToLocal returned %s\n", retval ? "success" : "failure"); } else { dprintf (D_SECURITY, "ZKM: name to map is null, not calling GSI authorization.\n"); } #endif } // for now, let's be a bit more verbose and print this to D_SECURITY. // yeah, probably all of the log lines that start with ZKM: should be // updated. oh, i wish there were a D_ZKM, but alas, we're out of bits. if( authenticator_ ) { dprintf (D_SECURITY, "ZKM: post-map: current user is '%s'\n", authenticator_->getRemoteUser()?authenticator_->getRemoteUser():"(null)"); dprintf (D_SECURITY, "ZKM: post-map: current domain is '%s'\n", authenticator_->getRemoteDomain()?authenticator_->getRemoteDomain():"(null)"); dprintf (D_SECURITY, "ZKM: post-map: current FQU is '%s'\n", authenticator_->getRemoteFQU()?authenticator_->getRemoteFQU():"(null)"); } mySock->allow_one_empty_message(); #if !defined(SKIP_AUTHENTICATION) if (retval && retval != 2 && m_key != NULL) { // will always try to exchange key! // This is a hack for now, when we have only one authenticate method // this will be gone mySock->allow_empty_message_flag = FALSE; retval = exchangeKey(*m_key); if ( !retval ) { errstack->push("AUTHENTICATE",AUTHENTICATE_ERR_KEYEXCHANGE_FAILED, "Failed to securely exchange session key"); } dprintf(D_SECURITY, "AUTHENTICATE: Result of end of authenticate is %d.\n", retval); mySock->allow_one_empty_message(); } #endif return ( retval ); }
ClassAd* readJobAd( void ) { ClassAd* ad = NULL; bool is_stdin = false; bool read_something = false; ASSERT( job_ad_file ); if( job_ad_file[0] == '-' && job_ad_file[1] == '\0' ) { fp = stdin; is_stdin = true; } else { if (fp == NULL) { fp = safe_fopen_wrapper_follow( job_ad_file, "r" ); if( ! fp ) { EXCEPT( "Failed to open ClassAd file (%s): %s (errno %d)", job_ad_file, strerror(errno), errno ); } } } dprintf( D_FULLDEBUG, "Reading job ClassAd from %s\n", is_stdin ? "STDIN" : job_ad_file ); ad = new ClassAd; MyString line; while( line.readLine(fp) ) { read_something = true; line.chomp(); if( line[0] == '#' ) { dprintf( D_JOB, "IGNORING COMMENT: %s\n", line.Value() ); continue; } if( line == "***" ) { dprintf( D_JOB, "Saw ClassAd delimitor, stopping\n" ); break; } if( ! ad->Insert(line.Value()) ) { EXCEPT( "Failed to insert \"%s\" into ClassAd!", line.Value() ); } } if( ! read_something ) { EXCEPT( "reading ClassAd from (%s): file is empty", is_stdin ? "STDIN" : job_ad_file ); } if( IsDebugVerbose(D_JOB) ) { ad->dPrint( D_JOB ); } // For debugging, see if there's a special attribute in the // job ad that sends us into an infinite loop, waiting for // someone to attach with a debugger int shadow_should_wait = 0; ad->LookupInteger( ATTR_SHADOW_WAIT_FOR_DEBUG, shadow_should_wait ); if( shadow_should_wait ) { dprintf( D_ALWAYS, "Job requested shadow should wait for " "debugger with %s=%d, going into infinite loop\n", ATTR_SHADOW_WAIT_FOR_DEBUG, shadow_should_wait ); while( shadow_should_wait ) { } } return ad; }
// Timeout() is called when a select() time out. Returns number of seconds // until next timeout event, a 0 if there are no more events, or a -1 if // called while a handler is active (i.e. handler calls Timeout; // Timeout is not re-entrant). int TimerManager::Timeout(int * pNumFired /*= NULL*/, double * pruntime /*=NULL*/) { int result, timer_check_cntr; time_t now, time_sample; int num_fires = 0; // num of handlers called in this timeout if (pNumFired) *pNumFired = 0; if ( in_timeout != NULL ) { dprintf(D_DAEMONCORE,"DaemonCore Timeout() called and in_timeout is non-NULL\n"); if ( timer_list == NULL ) { result = 0; } else { result = (timer_list->when) - time(NULL); } if ( result < 0 ) { result = 0; } return(result); } dprintf( D_DAEMONCORE, "In DaemonCore Timeout()\n"); if (timer_list == NULL) { dprintf( D_DAEMONCORE, "Empty timer list, nothing to do\n" ); } time(&now); timer_check_cntr = 0; DumpTimerList(D_DAEMONCORE | D_FULLDEBUG); // loop until all handlers that should have been called by now or before // are invoked and renewed if periodic. Remember that NewTimer and CancelTimer // keep the timer_list happily sorted on "when" for us. We use "now" as a // variable so that if some of these handler functions run for a long time, // we do not sit in this loop forever. // we make certain we do not call more than "max_fires" handlers in a // single timeout --- this ensures that timers don't starve out the rest // of daemonCore if a timer handler resets itself to 0. while( (timer_list != NULL) && (timer_list->when <= now ) && (num_fires++ < MAX_FIRES_PER_TIMEOUT)) { // DumpTimerList(D_DAEMONCORE | D_FULLDEBUG); in_timeout = timer_list; // In some cases, resuming from a suspend can cause the system // clock to become temporarily skewed, causing crazy things to // happen with our timers (particularly for sending updates to // the collector). So, to correct for such skews, we routinely // check to make sure that 'now' is not in the future. timer_check_cntr++; // since time() is somewhat expensive, we // only check every 10 times we loop if ( timer_check_cntr > 10 ) { timer_check_cntr = 0; time(&time_sample); if (now > time_sample) { dprintf(D_ALWAYS, "DaemonCore: Clock skew detected " "(time=%ld; now=%ld). Resetting TimerManager's " "notion of 'now'\n", (long) time_sample, (long) now); now = time_sample; } } // Update curr_dataptr for GetDataPtr() curr_dataptr = &(in_timeout->data_ptr); // Initialize our flag so we know if ResetTimer was called. did_reset = false; did_cancel = false; // Log a message before calling handler, but only if // D_FULLDEBUG is also enabled. if (IsDebugVerbose(D_COMMAND)) { dprintf(D_COMMAND, "Calling Timer handler %d (%s)\n", in_timeout->id, in_timeout->event_descrip); } if( in_timeout->timeslice ) { in_timeout->timeslice->setStartTimeNow(); } // Now we call the registered handler. If we were told that the handler // is a c++ method, we call the handler from the c++ object referenced // by service*. If we were told the handler is a c function, we call // it and pass the service* as a parameter. if ( in_timeout->handlercpp ) { // typedef int (*TimerHandlercpp)() ((in_timeout->service)->*(in_timeout->handlercpp))(); } else { // typedef int (*TimerHandler)() (*(in_timeout->handler))(); } if( in_timeout->timeslice ) { in_timeout->timeslice->setFinishTimeNow(); } if (IsDebugVerbose(D_COMMAND)) { if( in_timeout->timeslice ) { dprintf(D_COMMAND, "Return from Timer handler %d (%s) - took %.3fs\n", in_timeout->id, in_timeout->event_descrip, in_timeout->timeslice->getLastDuration() ); } else { dprintf(D_COMMAND, "Return from Timer handler %d (%s)\n", in_timeout->id, in_timeout->event_descrip); } } if (pruntime) { *pruntime = daemonCore->dc_stats.AddRuntime(in_timeout->event_descrip, *pruntime); } // Make sure we didn't leak our priv state daemonCore->CheckPrivState(); // Clear curr_dataptr curr_dataptr = NULL; if ( did_cancel ) { // Timer was canceled inside its handler. All we need to do // is delete it. DeleteTimer( in_timeout ); } else if ( !did_reset ) { // here we remove the timer we just serviced, or renew it if it is // periodic. // If a new timer was added at a time in the past // (possible when resetting a timeslice timer), then // it may have landed before the timer we just processed, // meaning that we cannot assume prev==NULL in the call // to RemoveTimer() below. Timer *prev = NULL; ASSERT( GetTimer(in_timeout->id,&prev) == in_timeout ); RemoveTimer( in_timeout, prev ); if ( in_timeout->period > 0 || in_timeout->timeslice ) { in_timeout->period_started = time(NULL); in_timeout->when = in_timeout->period_started; if ( in_timeout->timeslice ) { in_timeout->when += in_timeout->timeslice->getTimeToNextRun(); } else { if( in_timeout->period == TIMER_NEVER ) { in_timeout->when = TIME_T_NEVER; } else { in_timeout->when += in_timeout->period; } } InsertTimer( in_timeout ); } else { // timer is not perodic; it is just a one-time event. we just called // the handler, so now just delete it. DeleteTimer( in_timeout ); } } } // end of while loop // set result to number of seconds until next event. get an update on the // time from time() in case the handlers we called above took significant time. if ( timer_list == NULL ) { // we set result to be -1 so that we do not busy poll. // a -1 return value will tell the DaemonCore:Driver to use select with // no timeout. result = -1; } else { result = (timer_list->when) - time(NULL); if (result < 0) result = 0; } dprintf( D_DAEMONCORE, "DaemonCore Timeout() Complete, returning %d \n",result); if (pNumFired) *pNumFired = num_fires; in_timeout = NULL; return(result); }
int Authentication::authenticate_inner( char *hostAddr, const char* auth_methods, CondorError* errstack, int timeout) { #if defined(SKIP_AUTHENTICATION) dprintf(D_ALWAYS, "Skipping....\n"); /* errstack->push ( "AUTHENTICATE", AUTHENTICATE_ERR_NOT_BUILT, "this condor was built with SKIP_AUTHENTICATION"); */ return 0; #else Condor_Auth_Base * auth = NULL; int auth_timeout_time = time(0) + timeout; if (IsDebugVerbose(D_SECURITY)) { if (hostAddr) { dprintf ( D_SECURITY, "AUTHENTICATE: in authenticate( addr == '%s', " "methods == '%s')\n", hostAddr, auth_methods); } else { dprintf ( D_SECURITY, "AUTHENTICATE: in authenticate( addr == NULL, " "methods == '%s')\n", auth_methods); } } MyString methods_to_try = auth_methods; auth_status = CAUTH_NONE; method_used = NULL; while (auth_status == CAUTH_NONE ) { if (timeout>0 && auth_timeout_time <= time(0)) { dprintf(D_SECURITY, "AUTHENTICATE: exceeded %ds timeout\n", timeout); errstack->pushf( "AUTHENTICATE", AUTHENTICATE_ERR_TIMEOUT, "exceeded %ds timeout during authentication", timeout ); break; } if (IsDebugVerbose(D_SECURITY)) { dprintf(D_SECURITY, "AUTHENTICATE: can still try these methods: %s\n", methods_to_try.Value()); } int firm = handshake(methods_to_try); if ( firm < 0 ) { dprintf(D_ALWAYS, "AUTHENTICATE: handshake failed!\n"); errstack->push( "AUTHENTICATE", AUTHENTICATE_ERR_HANDSHAKE_FAILED, "Failure performing handshake" ); break; } char* method_name = NULL; switch ( firm ) { #if defined(HAVE_EXT_GLOBUS) case CAUTH_GSI: auth = new Condor_Auth_X509(mySock); method_name = strdup("GSI"); break; #endif /* HAVE_EXT_GLOBUS */ #ifdef HAVE_EXT_OPENSSL case CAUTH_SSL: auth = new Condor_Auth_SSL(mySock); method_name = strdup("SSL"); break; #endif #if defined(HAVE_EXT_KRB5) case CAUTH_KERBEROS: auth = new Condor_Auth_Kerberos(mySock); method_name = strdup("KERBEROS"); break; #endif #ifdef HAVE_EXT_OPENSSL // 3DES is the prequisite for passwd auth case CAUTH_PASSWORD: auth = new Condor_Auth_Passwd(mySock); method_name = strdup("PASSWORD"); break; #endif #if defined(WIN32) case CAUTH_NTSSPI: auth = new Condor_Auth_SSPI(mySock); method_name = strdup("NTSSPI"); break; #else case CAUTH_FILESYSTEM: auth = new Condor_Auth_FS(mySock); method_name = strdup("FS"); break; case CAUTH_FILESYSTEM_REMOTE: auth = new Condor_Auth_FS(mySock, 1); method_name = strdup("FS_REMOTE"); break; #endif /* !defined(WIN32) */ case CAUTH_CLAIMTOBE: auth = new Condor_Auth_Claim(mySock); method_name = strdup("CLAIMTOBE"); break; case CAUTH_ANONYMOUS: auth = new Condor_Auth_Anonymous(mySock); method_name = strdup("ANONYMOUS"); break; case CAUTH_NONE: dprintf(D_SECURITY|D_FULLDEBUG,"AUTHENTICATE: no available authentication methods succeeded!\n"); errstack->push("AUTHENTICATE", AUTHENTICATE_ERR_OUT_OF_METHODS, "Failed to authenticate with any method"); return 0; default: dprintf(D_ALWAYS,"AUTHENTICATE: unsupported method: %i, failing.\n", firm); errstack->pushf("AUTHENTICATE", AUTHENTICATE_ERR_OUT_OF_METHODS, "Failure. Unsupported method: %i", firm); return 0; } if (IsDebugVerbose(D_SECURITY)) { dprintf(D_SECURITY, "AUTHENTICATE: will try to use %d (%s)\n", firm, (method_name?method_name:"?!?") ); } //------------------------------------------ // Now authenticate //------------------------------------------ bool auth_rc = auth->authenticate(hostAddr, errstack); // check to see if the auth IP is the same as the socket IP if( auth_rc ) { char const *sockip = mySock->peer_ip_str(); char const *authip = auth->getRemoteHost() ; auth_rc = !sockip || !authip || !strcmp(sockip,authip); if (!auth_rc && !param_boolean( "DISABLE_AUTHENTICATION_IP_CHECK", false)) { errstack->pushf("AUTHENTICATE", AUTHENTICATE_ERR_METHOD_FAILED, "authenticated remote host does not match connection address (%s vs %s)", authip, sockip ); dprintf (D_ALWAYS, "AUTHENTICATE: ERROR: authenticated remot ehost does not match connection address (%s vs %s); configure DISABLE_AUTHENTICATION_IP_CHECK=TRUE if this check should be skipped\n",authip,sockip); } } if( !auth_rc ) { delete auth; auth = NULL; errstack->pushf("AUTHENTICATE", AUTHENTICATE_ERR_METHOD_FAILED, "Failed to authenticate using %s", method_name ); //if authentication failed, try again after removing from client tries if ( mySock->isClient() ) { // need to remove this item from the MyString!! perhaps there is a // better way to do this... anyways, 'firm' is equal to the bit value // of a particular method, so we'll just convert each item in the list // and keep it if it's not that particular bit. StringList meth_iter( methods_to_try.Value() ); meth_iter.rewind(); MyString new_list; char *tmp = NULL; while( (tmp = meth_iter.next()) ) { int that_bit = SecMan::getAuthBitmask( tmp ); // keep if this isn't the failed method. if (firm != that_bit) { // and of course, keep the comma's correct. if (new_list.Length() > 0) { new_list += ","; } new_list += tmp; } } // trust the copy constructor. :) methods_to_try = new_list; } dprintf(D_SECURITY,"AUTHENTICATE: method %d (%s) failed.\n", firm, (method_name?method_name:"?!?")); } else { // authentication succeeded. store the object (we may call upon // its wrapper functions) and set the auth_status of this sock to // the bitmask method we used and the method_used to the string // name. (string name is obtained above because there is currently // no bitmask -> string map) authenticator_ = auth; auth_status = authenticator_->getMode(); if (method_name) { method_used = strdup(method_name); } else { method_used = NULL; } } free (method_name); } //if none of the methods succeeded, we fall thru to default "none" from above int retval = ( auth_status != CAUTH_NONE ); if (IsDebugVerbose(D_SECURITY)) { dprintf(D_SECURITY, "AUTHENTICATE: auth_status == %i (%s)\n", auth_status, (method_used?method_used:"?!?") ); } dprintf(D_SECURITY, "Authentication was a %s.\n", retval == 1 ? "Success" : "FAILURE" ); // at this point, all methods have set the raw authenticated name available // via getAuthenticatedName(). if(authenticator_) { dprintf (D_SECURITY, "ZKM: setting default map to %s\n", authenticator_->getRemoteFQU()?authenticator_->getRemoteFQU():"(null)"); } // check to see if CERTIFICATE_MAPFILE was defined. if so, use it. if // not, do nothing. the user and domain have been filled in by the // authentication method itself, so just leave that alone. char * cert_map_file = param("CERTIFICATE_MAPFILE"); bool use_mapfile = (cert_map_file != NULL); if (cert_map_file) { free(cert_map_file); cert_map_file = 0; } // if successful so far, invoke the security MapFile. the output of that // is the "canonical user". if that has an '@' sign, split it up on the // last '@' and set the user and domain. if there is more than one '@', // the user will contain the leftovers after the split and the domain // always has none. if (retval && use_mapfile) { const char * name_to_map = authenticator_->getAuthenticatedName(); if (name_to_map) { dprintf (D_SECURITY, "ZKM: name to map is '%s'\n", name_to_map); dprintf (D_SECURITY, "ZKM: pre-map: current user is '%s'\n", authenticator_->getRemoteUser()?authenticator_->getRemoteUser():"(null)"); dprintf (D_SECURITY, "ZKM: pre-map: current domain is '%s'\n", authenticator_->getRemoteDomain()?authenticator_->getRemoteDomain():"(null)"); map_authentication_name_to_canonical_name(auth_status, method_used, name_to_map); } else { dprintf (D_SECURITY, "ZKM: name to map is null, not mapping.\n"); } } // for now, let's be a bit more verbose and print this to D_SECURITY. // yeah, probably all of the log lines that start with ZKM: should be // updated. oh, i wish there were a D_ZKM, but alas, we're out of bits. if( authenticator_ ) { dprintf (D_SECURITY, "ZKM: post-map: current user is '%s'\n", authenticator_->getRemoteUser()?authenticator_->getRemoteUser():"(null)"); dprintf (D_SECURITY, "ZKM: post-map: current domain is '%s'\n", authenticator_->getRemoteDomain()?authenticator_->getRemoteDomain():"(null)"); dprintf (D_SECURITY, "ZKM: post-map: current FQU is '%s'\n", authenticator_->getRemoteFQU()?authenticator_->getRemoteFQU():"(null)"); } mySock->allow_one_empty_message(); return ( retval ); #endif /* SKIP_AUTHENTICATION */ }