Пример #1
0
int Condor_Auth_Kerberos :: authenticate(const char * /* remoteHost */, CondorError* /* errstack */, bool /*non_blocking*/)
{
    int status = 0;

	if ( mySock_->isClient() ) {
		// we are the client.
		// initialize everything if needed.
		if (init_kerberos_context() && init_server_info()) {
            
			if (isDaemon() || get_mySubSystem()->isDaemon() ) {
				status = init_daemon();
			} else {
				status = init_user();
			}
		} else {
			status = FALSE;
		}

		int message = (status == TRUE? KERBEROS_PROCEED : KERBEROS_ABORT);

		mySock_->encode();
		if (!mySock_->code(message) || !mySock_->end_of_message()) {
			status = FALSE;
		} else {
			if (message == KERBEROS_PROCEED) {
				// We are ready to go
				status = authenticate_client_kerberos();
			} else {
				status = FALSE;
			}
		}
	} else {
		// we are the server.
		int ready;
		mySock_->decode();
		if (!mySock_->code(ready) || !mySock_->end_of_message()) {
			status = FALSE;
		} else {
			if (ready == KERBEROS_PROCEED) {
				dprintf(D_SECURITY,"About to authenticate client using Kerberos\n" );
				// initialize everything if needed.
				if (init_kerberos_context() && init_server_info()) {
					status = authenticate_server_kerberos();
				} else {
					status = FALSE;
				}
			}
		}
	}

    return( status );
}
Пример #2
0
/*
 * listener_spawn is responsible for creating a Listener class
 * and launching the listener. It is provided as a means for
 * the C thread subsystem to launch the listener C++ object.
 */
void listener_spawn( thread_Settings *thread ) {
    Listener *theListener = NULL;

    // start up a listener
    theListener = new Listener( thread );
#ifndef WIN32
    // handling of daemon mode in non-win32 builds
    if ( isDaemon( thread ) ) {
        theListener->runAsDaemon("iperf",LOG_DAEMON);
    }
#endif

    // Start listening
    theListener->Run();
    DELETE_PTR( theListener );
}
Пример #3
0
/* -------------------------------------------------------------------
 * main()
 *      Entry point into Iperf
 *
 * sets up signal handlers
 * initialize global locks and conditions
 * parses settings from environment and command line
 * starts up server or client thread
 * waits for all threads to complete
 * ------------------------------------------------------------------- */
int main( int argc, char **argv ) {
#ifdef WIN32
    // Start winsock
    WSADATA wsaData;
    int rc;
#endif

    // Set SIGTERM and SIGINT to call our user interrupt function
    my_signal( SIGTERM, Sig_Interupt );
    my_signal( SIGINT,  Sig_Interupt );
#ifndef WIN32 // SIGALRM=14, _NSIG=3...
    my_signal( SIGALRM,  Sig_Interupt );
#endif

#ifndef WIN32
	// Ignore broken pipes
    signal(SIGPIPE,SIG_IGN);
#endif

#ifdef WIN32 
    // Start winsock
    rc = WSAStartup( 0x202, &wsaData );
    WARN_errno( rc == SOCKET_ERROR, "WSAStartup" );
    if (rc == SOCKET_ERROR)
        return 0;

    // Tell windows we want to handle our own signals
    SetConsoleCtrlHandler( sig_dispatcher, true );
#endif

    // Initialize global mutexes and conditions
    Condition_Initialize ( &ReportCond );
    Condition_Initialize ( &ReportDoneCond );
    Mutex_Initialize( &groupCond );
    Mutex_Initialize( &clients_mutex );

    // Initialize the thread subsystem
    thread_init( );

    // Initialize the interrupt handling thread to 0
    sThread = thread_zeroid();

    // perform any cleanup when quitting Iperf
    atexit( cleanup );

    // Allocate the "global" settings
    thread_Settings* ext_gSettings = new thread_Settings;

    // Initialize settings to defaults
    Settings_Initialize( ext_gSettings );
    // read settings from environment variables
    Settings_ParseEnvironment( ext_gSettings );
    // read settings from command-line parameters
    Settings_ParseCommandLine( argc, argv, ext_gSettings );

    // Check for either having specified client or server
    if ( ext_gSettings->mThreadMode == kMode_Client
         || ext_gSettings->mThreadMode == kMode_Listener ) {
#ifdef WIN32
        // Start the server as a daemon
        // Daemon mode for non-windows in handled
        // in the listener_spawn function
        if ( isDaemon( ext_gSettings ) ) {
            CmdInstallService(argc, argv);
            return 0;
        }

        // Remove the Windows service if requested
        if ( isRemoveService( ext_gSettings ) ) {
            // remove the service
            if ( CmdRemoveService() ) {
                fprintf(stderr, "IPerf Service is removed.\n");

                return 0;
            }
        }
#endif
        // initialize client(s)
        if ( ext_gSettings->mThreadMode == kMode_Client ) {
            client_init( ext_gSettings );
        }

#ifdef HAVE_THREAD
        // start up the reporter and client(s) or listener
        {
            thread_Settings *into = NULL;
            // Create the settings structure for the reporter thread
            Settings_Copy( ext_gSettings, &into );
            into->mThreadMode = kMode_Reporter;

            // Have the reporter launch the client or listener
            into->runNow = ext_gSettings;

            // Start all the threads that are ready to go
            thread_start( into );
        }
#else
        // No need to make a reporter thread because we don't have threads
        thread_start( ext_gSettings );
#endif
    } else {
        // neither server nor client mode was specified
        // print usage and exit

#ifdef WIN32
        // In Win32 we also attempt to start a previously defined service
        // Starting in 2.0 to restart a previously defined service
        // you must call iperf with "iperf -D" or using the environment variable
        SERVICE_TABLE_ENTRY dispatchTable[] =
        {
            { TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main},
            { NULL, NULL}
        };

        // Only attempt to start the service if "-D" was specified
        if ( !isDaemon(ext_gSettings) ||
             // starting the service by SCM, there is no arguments will be passed in.
             // the arguments will pass into Service_Main entry.
             !StartServiceCtrlDispatcher(dispatchTable) )
            // If the service failed to start then print usage
#endif
        fprintf( stderr, usage_short, argv[0], argv[0] );

        return 0;
    }

    // wait for other (client, server) threads to complete
    thread_joinall();

    // all done!
    return 0;
} // end main
Пример #4
0
/* -------------------------------------------------------------------
 * main()
 *      Entry point into Iperf
 *
 * sets up signal handlers
 * initialize global locks and conditions
 * parses settings from environment and command line
 * starts up server or client thread
 * waits for all threads to complete
 * ------------------------------------------------------------------- */
#ifdef __cplusplus
extern "C"
#endif /* __cplusplus */
int IPERF_MAIN( int argc, char **argv ) {
#ifdef NO_EXIT
    should_exit = 0;
#endif /* NO_EXIT */
#ifdef IPERF_DEBUG
    debug_init();
#endif /* IPERF_DEBUG */

#ifndef NO_INTERRUPTS
#ifdef WIN32
    setsigalrmfunc(call_sigalrm);
#endif /* WIN32 */

    // Set SIGTERM and SIGINT to call our user interrupt function
    my_signal( SIGTERM, Sig_Interupt );
    my_signal( SIGINT,  Sig_Interupt );
    my_signal( SIGALRM,  Sig_Interupt );

#ifndef WIN32
    // Ignore broken pipes
    signal(SIGPIPE,SIG_IGN);
#else
    // Start winsock
    WORD wVersionRequested;
    WSADATA wsaData;

    // Using MAKEWORD macro, Winsock version request 2.2
    wVersionRequested = MAKEWORD(2, 2);

    int rc = WSAStartup( wVersionRequested, &wsaData );
    WARN_errno( rc == SOCKET_ERROR, ( "WSAStartup failed.\n" ) );
	if (rc != 0) {
	    fprintf(stderr, "The Winsock DLL was not found!\n");
		return 1;
	}

    /*
     * Confirm that the WinSock DLL supports 2.2. Note that if the DLL supports
	 * versions greater than 2.2 in addition to 2.2, it will still return 2.2 in
	 * wVersion since that is the version we requested.
     */
    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2 ) {
        /* Tell the user that we could not find a usable WinSock DLL. */
        fprintf(stderr, "The DLL does not support the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion),HIBYTE(wsaData.wVersion));
        WSACleanup();
        return 1;
    }

    // Tell windows we want to handle our own signals
    SetConsoleCtrlHandler( sig_dispatcher, true );
#endif /* WIN32 */
#endif /* NO_INTERRUPTS */

    // Initialize global mutexes and conditions
    IPERF_DEBUGF( CONDITION_DEBUG | IPERF_DBG_TRACE, ( "Initializing report condition.\n" ) );
    Condition_Initialize ( &ReportCond );
    IPERF_DEBUGF( CONDITION_DEBUG | IPERF_DBG_TRACE, ( "Initializing report done condition.\n" ) );
    Condition_Initialize ( &ReportDoneCond );
    IPERF_DEBUGF( MUTEX_DEBUG | IPERF_DBG_TRACE, ( "Initializing group condition mutex.\n" ) );
    Mutex_Initialize( &groupCond );
    IPERF_DEBUGF( MUTEX_DEBUG | IPERF_DBG_TRACE, ( "Initializing clients mutex.\n" ) );
    Mutex_Initialize( &clients_mutex );

    // Initialize the thread subsystem
    IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Initializing the thread subsystem.\n" ) );
    thread_init( );

    // Initialize the interrupt handling thread to 0
    sThread = thread_zeroid();

#ifndef NO_EXIT
    // perform any cleanup when quitting Iperf
    atexit( cleanup );
#endif /* NO_EXIT */

    // Allocate the "global" settings
    thread_Settings *ext_gSettings = (thread_Settings*) malloc( sizeof( thread_Settings ) );
    FAIL( ext_gSettings == NULL, ( "Unable to allocate memory for thread_Settings ext_gSettings.\n" ), NULL );
    IPERF_DEBUGF( MEMALLOC_DEBUG, IPERF_MEMALLOC_MSG( ext_gSettings, sizeof( thread_Settings ) ) );

    // Initialize settings to defaults
    Settings_Initialize( ext_gSettings );
#ifndef NO_ENVIRONMENT
    // read settings from environment variables
    Settings_ParseEnvironment( ext_gSettings );
#endif /* NO_ENVIORNMENT */
    // read settings from command-line parameters
    Settings_ParseCommandLine( argc, argv, ext_gSettings );

#ifdef NO_EXIT
    if (should_exit) {
        IPERF_DEBUGF( MEMFREE_DEBUG | IPERF_DBG_TRACE, IPERF_MEMFREE_MSG( ext_gSettings ) );
        FREE_PTR( ext_gSettings );

        IPERF_DEBUGF( CONDITION_DEBUG | IPERF_DBG_TRACE, ( "Destroying report condition.\n" ) );
        Condition_Destroy( &ReportCond );
        IPERF_DEBUGF( CONDITION_DEBUG | IPERF_DBG_TRACE, ( "Destroying report done condition.\n" ) );
        Condition_Destroy( &ReportDoneCond );
        IPERF_DEBUGF( MUTEX_DEBUG | IPERF_DBG_TRACE, ( "Destroying group condition mutex.\n" ) );
        Mutex_Destroy( &groupCond );
        IPERF_DEBUGF( MUTEX_DEBUG | IPERF_DBG_TRACE, ( "Destroying clients mutex.\n" ) );
        Mutex_Destroy( &clients_mutex );

        return 0;
    }
#endif /* NO_EXIT */

    // Check for either having specified client or server
    if ( ext_gSettings->mThreadMode == kMode_Client 
         || ext_gSettings->mThreadMode == kMode_Listener ) {
#ifdef WIN32
#ifndef NO_DAEMON
        // Start the server as a daemon
        // Daemon mode for non-windows in handled
        // in the listener_spawn function
        if ( isDaemon( ext_gSettings ) ) {
            CmdInstallService(argc, argv);
            return 0;
        }
#endif /* NO_DAEMON */

#ifndef NO_SERVICE
        // Remove the Windows service if requested
        if ( isRemoveService( ext_gSettings ) ) {
            // remove the service
            if ( CmdRemoveService() ) {
                fprintf(stderr, "IPerf Service is removed.\n");
                return 0;
            }
        }
#endif /* NO_SERVICE */
#endif /* WIN32 */
        // initialize client(s)
        if ( ext_gSettings->mThreadMode == kMode_Client ) {
            IPERF_DEBUGF( CLIENT_DEBUG | LISTENER_DEBUG | IPERF_DBG_TRACE, ( "Initializing client(s)...\n" ) );
            client_init( ext_gSettings );
        }

#ifdef HAVE_THREAD
        // start up the reporter and client(s) or listener
        thread_Settings *into = NULL;
        // Create the settings structure for the reporter thread
        IPERF_DEBUGF( CLIENT_DEBUG | LISTENER_DEBUG | REPORTER_DEBUG | IPERF_DBG_TRACE, ( "Creating the settings structure for the reporter thread.\n" ) );
        Settings_Copy( ext_gSettings, &into );
        into->mThreadMode = kMode_Reporter;

        // Have the reporter launch the client or listener
        IPERF_DEBUGF( CLIENT_DEBUG | LISTENER_DEBUG | IPERF_DBG_TRACE, ( "Setting the reporter to launch the client or listener before launching itself.\n" ) );
        into->runNow = ext_gSettings;
        
        // Start all the threads that are ready to go
        IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Starting all the threads...\n" ) );
        thread_start( into );
#else
        // No need to make a reporter thread because we don't have threads
        IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Starting iperf in a single thread...\n" ) );
        thread_start( ext_gSettings );
#endif /* HAVE_THREAD */
    } else {
        // neither server nor client mode was specified
        // print usage and exit

#ifdef WIN32
        // In Win32 we also attempt to start a previously defined service
        // Starting in 2.0 to restart a previously defined service
        // you must call iperf with "iperf -D" or using the environment variable
        SERVICE_TABLE_ENTRY dispatchTable[] =
        {
            { TEXT((char *) SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main},
            { NULL, NULL}
        };

#ifndef NO_DAEMON
        // Only attempt to start the service if "-D" was specified
        if ( !isDaemon(ext_gSettings) ||
             // starting the service by SCM, there is no arguments will be passed in.
             // the arguments will pass into Service_Main entry.
             !StartServiceCtrlDispatcher(dispatchTable) )
            // If the service failed to start then print usage
#endif /* NO_DAEMON */
#endif /* WIN32 */
        fprintf( stderr, usage_short, argv[0], argv[0] );

        return 0;
    }

    // wait for other (client, server) threads to complete
//    IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Waiting for other (client, server) threads to complete...\n" ) );
//    thread_joinall();
    
#ifdef NO_EXIT
	/* We can't run the atexit function */
#ifdef WIN32
    // Shutdown Winsock
    WSACleanup();
#endif /* WIN32 */
    // clean up the list of clients
    Iperf_destroy ( &clients );

    // shutdown the thread subsystem
    IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Deinitializing the thread subsystem.\n" ) );

    IPERF_DEBUGF( CONDITION_DEBUG | IPERF_DBG_TRACE, ( "Destroying report condition.\n" ) );
    Condition_Destroy( &ReportCond );
    IPERF_DEBUGF( CONDITION_DEBUG | IPERF_DBG_TRACE, ( "Destroying report done condition.\n" ) );
    Condition_Destroy( &ReportDoneCond );
    IPERF_DEBUGF( MUTEX_DEBUG | IPERF_DBG_TRACE, ( "Destroying group condition mutex.\n" ) );
    Mutex_Destroy( &groupCond );
    IPERF_DEBUGF( MUTEX_DEBUG | IPERF_DBG_TRACE, ( "Destroying clients mutex.\n" ) );
    Mutex_Destroy( &clients_mutex );

#ifdef IPERF_DEBUG
    debug_init();
#endif /* IPERF_DEBUG */
#endif /* NO_EXIT */
	
    // all done!
    IPERF_DEBUGF( IPERF_DBG_TRACE | IPERF_DBG_STATE, ( "Done!\n" ) );
    return 0;
} // end main
Пример #5
0
int Condor_Auth_X509::authenticate_client_gss(CondorError* errstack)
{
    OM_uint32	major_status = 0;
    OM_uint32	minor_status = 0;
    int         status = 0;

    priv_state priv = PRIV_UNKNOWN;
    
    if (isDaemon()) {
        priv = set_root_priv();
    }
    
    char target_str[] = "GSI-NO-TARGET";
    major_status = globus_gss_assist_init_sec_context(&minor_status,
                                                      credential_handle,
                                                      &context_handle,
                                                      target_str,
                                                      GSS_C_MUTUAL_FLAG,
                                                      &ret_flags, 
                                                      &token_status,
                                                      relisock_gsi_get, 
                                                      (void *) mySock_,
                                                      relisock_gsi_put, 
                                                      (void *) mySock_
                                                      );
    
    if (isDaemon()) {
        set_priv(priv);
    }

    if (major_status != GSS_S_COMPLETE)	{
		if (major_status == 655360 && minor_status == 6) {
			errstack->pushf("GSI", GSI_ERR_AUTHENTICATION_FAILED,
				"Failed to authenticate.  Globus is reporting error (%u:%u).  "
				"This indicates that it was unable to find the issuer "
				"certificate for your credential", (unsigned)major_status, (unsigned)minor_status);
		} else if (major_status == 655360 && minor_status == 9) {
			errstack->pushf("GSI", GSI_ERR_AUTHENTICATION_FAILED,
				"Failed to authenticate.  Globus is reporting error (%u:%u).  "
				"This indicates that it was unable to verify the server's "
				"credential", (unsigned)major_status, (unsigned)minor_status);
		} else if (major_status == 655360 && minor_status == 11) {
			errstack->pushf("GSI", GSI_ERR_AUTHENTICATION_FAILED,
				"Failed to authenticate.  Globus is reporting error (%u:%u).  "
				"This indicates that it was unable verify the server's "
				"credentials because a signing policy file was not found or "
				"could not be read.", (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");
        // Following four lines of code is added to temporarily
        // resolve a bug (I belive so) in Globus's GSI code.
        // basically, if client calls init_sec_context with
        // mutual authentication and it returns with a mismatched
        // target principal, init_sec_context will return without
        // sending the server any token. The sever, therefore,
        // hangs on waiting for the token (or until the timeout
        // occurs). This code will force the server to break out
        // the loop.
        status = 0;
        mySock_->encode();
        mySock_->code(status);
        mySock_->end_of_message();
    }
    else {
        // Now, wait for final signal
        mySock_->decode();
        if (!mySock_->code(status) || !mySock_->end_of_message()) {
			errstack->push("GSI", GSI_ERR_COMMUNICATIONS_ERROR,
					"Failed to authenticate with server.  Unable to receive server status");
            dprintf(D_SECURITY, "Unable to receive final confirmation for GSI Authentication!\n");
        }
        if (status == 0) {
			errstack->push("GSI", GSI_ERR_AUTHENTICATION_FAILED,
				"Failed to get authorization from server.  Either the server "
				"does not trust your certificate, or you are not in the server's "
				"authorization file (grid-mapfile)");
            dprintf(D_SECURITY, "Server is unable to authorize my user name. Check the GRIDMAP file on the server side.\n");
            goto clear; 
        }

        char * server = get_server_info();

		// store the raw subject name for later mapping
		setAuthenticatedName(server);

		// Default to user name "gsi@unmapped".
		// Later on, if configured, we will invoke the callout in nameGssToLocal.
		setRemoteUser("gsi");
		setRemoteDomain( UNMAPPED_DOMAIN );

		// extract and store VOMS attributes
		if (param_boolean("USE_VOMS_ATTRIBUTES", true)) {

			// get the voms attributes from the peer
			globus_gsi_cred_handle_t peer_cred = context_handle->peer_cred_handle->cred_handle;

			char * voms_fqan = NULL;
			int voms_err = extract_VOMS_info(peer_cred, 1, NULL, NULL, &voms_fqan);
			if (!voms_err) {
				setFQAN(voms_fqan);
				free(voms_fqan);
			} else {
				// complain!
				dprintf(D_SECURITY, "ZKM: VOMS FQAN not present (error %i), ignoring.\n", voms_err);
			}
		}

        std::string fqh = get_full_hostname(mySock_->peer_addr());
        StringList * daemonNames = getDaemonList("GSI_DAEMON_NAME",fqh.c_str());

        // Now, let's see if the name is in the list, I am not using
        // anycase here, so if the host name and what we are looking for
        // are in different cases, then we will run into problems.
		if( daemonNames ) {
			status = daemonNames->contains_withwildcard(server) == TRUE? 1 : 0;

			if( !status ) {
				errstack->pushf("GSI", GSI_ERR_UNAUTHORIZED_SERVER,
								"Failed to authenticate because the subject '%s' is not currently trusted by you.  "
								"If it should be, add it to GSI_DAEMON_NAME or undefine GSI_DAEMON_NAME.", server);
				dprintf(D_SECURITY,
						"GSI_DAEMON_NAME is defined and the server %s is not specified in the GSI_DAEMON_NAME parameter\n",
						server);
			}
		}
		else {
			status = CheckServerName(fqh.c_str(),mySock_->peer_ip_str(),mySock_,errstack);
		}

        if (status) {
            dprintf(D_SECURITY, "valid GSS connection established to %s\n", server);            
        }

        mySock_->encode();
        if (!mySock_->code(status) || !mySock_->end_of_message()) {
			errstack->push("GSI", GSI_ERR_COMMUNICATIONS_ERROR,
					"Failed to authenticate with server.  Unable to send status");
            dprintf(D_SECURITY, "Unable to mutually authenticate with server!\n");
            status = 0;
        }

        delete [] server;
        delete daemonNames;
    }
 clear:
    return (status == 0) ? FALSE : TRUE;
}
Пример #6
0
int Condor_Auth_X509::authenticate_self_gss(CondorError* errstack)
{
    OM_uint32 major_status;
    OM_uint32 minor_status;
    char comment[1024];
    if ( credential_handle != GSS_C_NO_CREDENTIAL ) { // user already auth'd 
        dprintf( D_FULLDEBUG, "This process has a valid certificate & key\n" );
        return TRUE;
    }
    
    // ensure all env vars are in place, acquire cred will fail otherwise 
    
    //use gss-assist to verify user (not connection)
    //this method will prompt for password if private key is encrypted!
    int time = mySock_->timeout(60 * 5);  //allow user 5 min to type passwd
    
    priv_state priv = PRIV_UNKNOWN;
    
    //if ((!mySock_->isClient() && {
    if (isDaemon()) {
        priv = set_root_priv();
    }
    
    major_status = globus_gss_assist_acquire_cred(&minor_status,
                                                  GSS_C_BOTH, 
                                                  &credential_handle);
    if (major_status != GSS_S_COMPLETE) {
        major_status = globus_gss_assist_acquire_cred(&minor_status,
                                                      GSS_C_BOTH,
                                                      &credential_handle);
    }

    //if (!mySock_->isClient() || isDaemon()) {
    if (isDaemon()) {
        set_priv(priv);
    }
    
    mySock_->timeout(time); //put it back to what it was before
    
    if (major_status != GSS_S_COMPLETE)
	{
		if (major_status == 851968 && minor_status == 20) {
			errstack->pushf("GSI", GSI_ERR_NO_VALID_PROXY,
				"Failed to authenticate.  Globus is reporting error (%u:%u).  "
				"This indicates that you do not have a valid user proxy.  "
				"Run grid-proxy-init.", (unsigned)major_status, (unsigned)minor_status);
		} else if (major_status == 851968 && minor_status == 12) {
			errstack->pushf("GSI", GSI_ERR_NO_VALID_PROXY,
				"Failed to authenticate.  Globus is reporting error (%u:%u).  "
				"This indicates that your user proxy has expired.  "
				"Run grid-proxy-init.", (unsigned)major_status, (unsigned)minor_status);
		} else {
			errstack->pushf("GSI", GSI_ERR_ACQUIRING_SELF_CREDINTIAL_FAILED,
				"Failed to authenticate.  Globus is reporting error (%u:%u).  There is probably a problem with your credentials.  (Did you run grid-proxy-init?)", (unsigned)major_status, (unsigned)minor_status);
		}

        sprintf(comment,"authenticate_self_gss: acquiring self credentials failed. Please check your Condor configuration file if this is a server process. Or the user environment variable if this is a user process. \n");
        print_log( major_status,minor_status,0,comment); 
        credential_handle = GSS_C_NO_CREDENTIAL; 
        return FALSE;
	}
    
    dprintf( D_FULLDEBUG, "This process has a valid certificate & key\n" );
    return TRUE;
}