예제 #1
0
void 
initialize_uids(void)
{
#if defined(WIN32)
#include "my_username.h"

	char *name = NULL;
	char *domain = NULL;

	name = my_username();
	domain = my_domainname();

	caller_name = name;
	job_user_name = name;

	if ( !init_user_ids(name, domain ) ) {
		// shouldn't happen - we always can get our own token
		vmprintf(D_ALWAYS, "Could not initialize user_priv with our own token!\n");
	}

	vmprintf(D_ALWAYS, "Initialize Uids: caller=%s@%s, job user=%s@%s\n", 
			caller_name.Value(), domain, job_user_name.Value(), domain);

	if( name ) {
		free(name);
	}
	if( domain ) {
		free(domain);
	}
	return;
#else
	// init_user_ids was called in main_pre_dc_init()
	vmprintf(D_ALWAYS, "Initial UID/GUID=%d/%d, EUID/EGUID=%d/%d, "
			"Condor UID/GID=%d,%d\n", (int)getuid(), (int)getuid(), 
			(int)geteuid(), (int)getegid(), 
			(int)get_condor_uid(), (int)get_condor_gid());

	vmprintf(D_ALWAYS, "Initialize Uids: caller=%s, job user=%s\n", 
			caller_name.Value(), job_user_name.Value());
	
	return;
#endif
}
예제 #2
0
Qmgr_connection *
ConnectQ(const char *qmgr_location, int timeout, bool read_only, CondorError* errstack, const char *effective_owner, const char* schedd_version_str )
{
	int		rval, ok;
	int cmd = read_only ? QMGMT_READ_CMD : QMGMT_WRITE_CMD;

		// do we already have a connection active?
	if( qmgmt_sock ) {
			// yes; reject new connection (we can only handle one at a time)
		return( NULL );
	}

	// set up the error handling so it will clean up automatically on
	// return.  also allow them to specify their own stack.
	CondorError  our_errstack;
	CondorError* errstack_select = &our_errstack;
	if (errstack) {
		errstack_select = errstack;
	}

    // no connection active as of now; create a new one
	Daemon d( DT_SCHEDD, qmgr_location );
	if( ! d.locate() ) {
		ok = FALSE;
		if( qmgr_location ) {
			dprintf( D_ALWAYS, "Can't find address of queue manager %s\n", 
					 qmgr_location );
		} else {
			dprintf( D_ALWAYS, "Can't find address of local queue manager\n" );
		}
	} else { 
			// QMGMT_WRITE_CMD didn't exist before 7.5.0, so use QMGMT_READ_CMD
			// when talking to older schedds
		if( cmd == QMGMT_WRITE_CMD ) {
			if( !schedd_version_str ) schedd_version_str = d.version();
			if( !schedd_version_str ) {
					// Some day when we don't care about compatibility with
					// things from before 7.5.0, we could stop defaulting
					// to QMGMT_READ_CMD here.
				cmd = QMGMT_READ_CMD;
			}
			else {
				CondorVersionInfo ver_info(schedd_version_str);
				if( !ver_info.built_since_version(7,5,0) ) {
					cmd = QMGMT_READ_CMD;
				}
			}
		}

		qmgmt_sock = (ReliSock*) d.startCommand( cmd,
												 Stream::reli_sock,
												 timeout,
												 errstack_select);
		ok = qmgmt_sock != NULL;
		if( !ok && !errstack) {
			dprintf(D_ALWAYS, "Can't connect to queue manager: %s\n",
					errstack_select->getFullText().c_str() );
		}
	}

	if( !ok ) {
		if( qmgmt_sock ) delete qmgmt_sock;
		qmgmt_sock = NULL;
		return 0;
	}

		// If security negotiation is turned off and we are using WRITE_CMD,
		// then we must force authentication now, before trying to initialize
		// the connection, because this command is registered with
		// force_authentication=true on the server side.
	if( cmd == QMGMT_WRITE_CMD && !qmgmt_sock->triedAuthentication()) {
		if( !SecMan::authenticate_sock(qmgmt_sock, CLIENT_PERM, errstack_select ) )
		{
			delete qmgmt_sock;
			qmgmt_sock = NULL;
			if (!errstack) {
				dprintf( D_ALWAYS, "Authentication Error: %s\n",
						 errstack_select->getFullText().c_str() );
			}
			return 0;
		}
	}

    // This could be a problem
	char *username = my_username();
	char *domain = my_domainname();

	if ( !username ) {
		dprintf(D_FULLDEBUG,"Failure getting my_username()\n");
		delete qmgmt_sock;
		qmgmt_sock = NULL;
		if (domain) free(domain);
		return( 0 );
	}

	/* Get the schedd to handle Q ops. */

    /* Get rid of all the code below */

    if (read_only || !qmgmt_sock->triedAuthentication()) {
        if ( read_only ) {
            rval = InitializeReadOnlyConnection( username );
        } else {
            rval = InitializeConnection( username, domain );
        }

		if (username) {
			free(username);
			username = NULL;
		}
		if (domain) {
			free(domain);
			domain = NULL;
		}

        if (rval < 0) {
            delete qmgmt_sock;
            qmgmt_sock = NULL;
            return 0;
        }

        if ( !read_only ) {
            if (!SecMan::authenticate_sock(qmgmt_sock, CLIENT_PERM, errstack_select)) {
                delete qmgmt_sock;
                qmgmt_sock = NULL;
				if (!errstack) {
					dprintf( D_ALWAYS, "Authentication Error: %s\n",
							 errstack_select->getFullText().c_str() );
				}
                return 0;
            }
        }
    }

	if (username) free(username);
	if (domain) free(domain);

	if( effective_owner && *effective_owner ) {
		if( QmgmtSetEffectiveOwner( effective_owner ) != 0 ) {
			if( errstack ) {
				errstack->pushf(
					"Qmgmt",SCHEDD_ERR_SET_EFFECTIVE_OWNER_FAILED,
					"SetEffectiveOwner(%s) failed with errno=%d: %s.",
					effective_owner, errno, strerror(errno) );
			}
			else {
				dprintf( D_ALWAYS,
						 "SetEffectiveOwner(%s) failed with errno=%d: %s.\n",
						 effective_owner, errno, strerror(errno) );
			}
			delete qmgmt_sock;
			qmgmt_sock = NULL;
			return 0;
		}
	}

	return &connection;
}
예제 #3
0
bool
JobInfoCommunicator::initUserPrivWindows( void )
{
    // Win32
    // taken origionally from OsProc::StartJob.  Here we create the
    // user and initialize user_priv.

    // By default, assume execute login may be shared by other processes.
    setExecuteAccountIsDedicated( NULL );

    // we support running the job as other users if the user
    // is specifed in the config file, and the account's password
    // is properly stored in our credential stash.

    char *name = NULL;
    char *domain = NULL;
    bool init_priv_succeeded = true;
    bool run_as_owner = allowRunAsOwner( false, false );

    // TODO..
    // Currently vmgahp for VMware VM universe can't run as user on Windows.
    // It seems like a bug of VMware. VMware command line tool such as "vmrun"
    // requires Administrator privilege.
    // So here we set name and domain with my_username and my_domainname
    // -jaeyoung 06/15/07
    if( job_universe == CONDOR_UNIVERSE_VM ) {
#if 0
        // If "VM_UNIV_NOBODY_USER" is defined in Condor configuration file,
        // wee will use it.
        char *vm_jobs_as = param("VM_UNIV_NOBODY_USER");
        if (vm_jobs_as) {
            getDomainAndName(vm_jobs_as, domain, name);
            /*
             * name and domain are now just pointers into vm_jobs_as
             * buffer.  copy these values into their own buffer so we
             * deallocate below.
             */
            if ( name ) {
                name = strdup(name);
            }
            if ( domain ) {
                domain = strdup(domain);
            }
            free(vm_jobs_as);
        }
#endif
        MyString vm_type;
        job_ad->LookupString(ATTR_JOB_VM_TYPE, vm_type);

        if( strcasecmp(vm_type.Value(), CONDOR_VM_UNIVERSE_VMWARE) == MATCH ) {
            name = my_username();
            domain = my_domainname();
        }
    }

    if( !name ) {
        if ( run_as_owner ) {
            job_ad->LookupString(ATTR_OWNER,&name);
            job_ad->LookupString(ATTR_NT_DOMAIN,&domain);
        }
    }

    if ( !name ) {
        char slot_user[255];
        MyString slotName = "";
        slotName = Starter->getMySlotName();

        slotName.upper_case();
        sprintf(slot_user, "%s_USER", slotName);
        char *run_jobs_as = param(slot_user);
        if (run_jobs_as) {
            getDomainAndName(run_jobs_as, domain, name);
            /*
             * name and domain are now just pointers into run_jobs_as
             * buffer.  copy these values into their own buffer so we
             * deallocate below.
             */
            if ( name ) {
                name = strdup(name);
            }
            if ( domain ) {
                domain = strdup(domain);
            }
            free(run_jobs_as);
        }
    }

    if ( name ) {

        if (!init_user_ids(name, domain)) {

            dprintf(D_ALWAYS, "Could not initialize user_priv as \"%s\\%s\".\n"
                    "\tMake sure this account's password is securely stored "
                    "with condor_store_cred.\n", domain, name );
            init_priv_succeeded = false;
        }
        else {
            MyString login_name;
            joinDomainAndName(name, domain, login_name);
            if( checkDedicatedExecuteAccounts( login_name.Value() ) ) {
                setExecuteAccountIsDedicated( login_name.Value() );
            }
        }

    } else if ( !can_switch_ids() ) {
        char *u = my_username();
        char *d = my_domainname();

        if ( !init_user_ids(u, d) ) {
            // shouldn't happen - we always can get our own token
            dprintf(D_ALWAYS, "Could not initialize user_priv with our own token!\n");
            init_priv_succeeded = false;
        }
        free(u);
        free(d);
    } else if( init_user_ids("nobody", ".") ) {
        // just init a new nobody user; dynuser handles the rest.
        // the "." means Local Machine to LogonUser

        setExecuteAccountIsDedicated( get_user_loginname() );
    }
    else {

        dprintf( D_ALWAYS, "ERROR: Could not initialize user_priv "
                 "as \"nobody\"\n" );
        init_priv_succeeded = false;

    }

    if ( name ) free(name);
    if ( domain ) free(domain);

    user_priv_is_initialized = init_priv_succeeded;
    return init_priv_succeeded;
}
예제 #4
0
int
init_user_ids(const char username[], const char domain[]) 
{
	int retval = 0;

	if (!username || !domain) {
		dprintf(D_ALWAYS, "WARNING: init_user_ids() called with"
			   " NULL arguments!\n");
	   	return 0;
   	}

	// we have to be very careful calling dprintf in this function, because dprintf
	// will try and _set_priv to root and then back to what it was.  so we need to
	// make sure that our global variables are always in a state where that doesn't
	// except.

	// TJ:2010: Can't do this here, UserIdsInited must never be true 
	// while CurrUserHandle is NULL or dprintf will EXCEPT.
	// UserIdsInited = true;
	
	// see if we already have a user handle for the requested user.
	// if so, just return 1. 
	// TODO: cache multiple user handles to save time.

	dprintf(D_FULLDEBUG, "init_user_ids: want user '%s@%s', "
			"current is '%s@%s'\n",
		username, domain, UserLoginName, UserDomainName);
	
	if ( CurrUserHandle = cached_tokens.getToken(username, domain)) {
		UserIdsInited = true; // do this before we call dprintf
		// when we uninit_user_ids we can end up CurrUserHandle in the cache
		// but UserLoginName and UserDomainName not set, if that happens
		// we need to set them here.
		if ( ! UserLoginName) UserLoginName = strdup(username);
		if ( ! UserDomainName) UserDomainName = strdup(domain);
		dprintf(D_FULLDEBUG, "init_user_ids: Already have handle for %s@%s,"
			" so returning.\n", username, domain);
		return 1;
	} else {
		char* myusr = my_username();
		char* mydom = my_domainname();

		// we cleared CurrUserHandle, so we aren't inited.
		UserIdsInited = false;

		// see if our calling thread matches the user and domain
		// we want a token for. This happens if we're submit for example.
		if ( strcmp( myusr, username ) == 0 &&
			 strcasecmp( mydom, domain ) == 0 ) { // domain is case insensitive

			dprintf(D_FULLDEBUG, "init_user_ids: Calling thread has token "
					"we want, so returning.\n");
			CurrUserHandle = my_usertoken();
			if (CurrUserHandle) {
				UserIdsInited = true;
			} else {
				dprintf(D_FULLDEBUG, "init_user_ids: handle is null!\n");
			}
			
			if (UserLoginName) {
				free(UserLoginName);
				UserLoginName = NULL;
			}
			if (UserDomainName) {
				free(UserDomainName);
				UserDomainName = NULL;
			}
			
			// these are strdup'ed, so we can just stash their pointers
			UserLoginName = myusr;
			UserDomainName = mydom;

			// don't forget to drop it in the cache too
			cached_tokens.storeToken(UserLoginName, UserDomainName,
				   		CurrUserHandle);
			return 1;
		}
	}

	// at this point UserIdsInited should be false.
	ASSERT( ! UserIdsInited);

	// anything beyond this requires user switching
	if (!can_switch_ids()) {
		dprintf(D_ALWAYS, "init_user_ids: failed because user switching is disabled\n");
		return 0;
	}

	if ( strcmp(username,"nobody") != 0 ) {
		// here we call routines to deal with passwords. Hopefully we're
		// running as LocalSystem here, otherwise we can't get at the 
		// password stash.
		lsa_mgr lsaMan;
		char pw[255];
		char user[255];
		char dom[255];
		wchar_t w_fullname[255];
		wchar_t *w_pw;
		bool got_password = false;
		bool got_password_from_credd = false;

		// these should probably be snprintfs
		swprintf(w_fullname, L"%S@%S", username, domain);
		sprintf(user, "%s", username);
		sprintf(dom, "%s", domain);
		
		// make sure we're SYSTEM when we do this
		w_pw = lsaMan.query(w_fullname);
		if ( w_pw ) {
			// copy password into a char buffer
			sprintf(pw, "%S", w_pw);			
			// we don't need the wide char pw anymore, so clean it up
			SecureZeroMemory(w_pw, wcslen(w_pw)*sizeof(wchar_t));
			delete[](w_pw);
			w_pw = NULL;

			// now that we got a password, see if it is good.
			retval = LogonUser(
				user,						// user name
				dom,						// domain or server - local for now
				pw,							// password
				LOGON32_LOGON_INTERACTIVE,	// type of logon operation. 
											// LOGON_BATCH doesn't seem to work right here.
				LOGON32_PROVIDER_DEFAULT,	// logon provider
				&CurrUserHandle				// receive tokens handle
			);
			
			if ( !retval ) {
				dprintf(D_FULLDEBUG,"Locally stored credential for %s@%s is stale\n",
					user,dom);
				// Set handle to NULL to make certain we recall LogonUser again below
				CurrUserHandle = NULL;	
			} else {
				got_password = true;	// so we don't bother going to a credd
			}
		}

		// if we don't have the password from our local stash, try to fetch
		// it from a credd. this tiny function is in a separate file so
        // that we don't pull in all of daemon core when we link to the utils library.

		char *credd_host = param("CREDD_HOST");
		if (credd_host && got_password==false) {
#if 1
           got_password = get_password_from_credd(
              credd_host,
              username,
              domain,
              pw,
              sizeof(pw));
           got_password_from_credd = got_password;
#else
			dprintf(D_FULLDEBUG, "trying to fetch password from credd: %s\n", credd_host);
			Daemon credd(DT_CREDD);
			Sock * credd_sock = credd.startCommand(CREDD_GET_PASSWD,Stream::reli_sock,10);
			if ( credd_sock ) {
				credd_sock->put((char*)username);	// send user
				credd_sock->put((char*)domain);		// send domain
				credd_sock->end_of_message();
				credd_sock->decode();
				pw[0] = '\0';
				int my_stupid_sizeof_int_for_damn_cedar = sizeof(pw);
				char *my_buffer = pw;
				if ( credd_sock->code(my_buffer,my_stupid_sizeof_int_for_damn_cedar) && pw[0] ) {
					got_password = true;
					got_password_from_credd = true;
				} else {
					dprintf(D_FULLDEBUG,
							"credd (%s) did not have info for %s@%s\n",
							credd_host, username,domain);
				}
				delete credd_sock;
				credd_sock = NULL;
			} else {
				dprintf(D_FULLDEBUG,"Failed to contact credd %s: %s\n",
					credd_host,credd.error() ? credd.error() : "");
			}
#endif
		}
		if (credd_host) free(credd_host);

		if ( ! got_password ) {
			dprintf(D_ALWAYS, "ERROR: Could not locate valid credential for user "
				"'%s@%s'\n", username, domain);
			return 0;
		} else {
			dprintf(D_FULLDEBUG, "Found credential for user '%s'\n", username);

			// If we have not yet called LogonUser, then CurrUserHandle is NULL,
			// and we need to call it here.
			if ( CurrUserHandle == NULL ) {
				retval = LogonUser(
					user,						// user name
					dom,						// domain or server - local for now
					pw,							// password
					LOGON32_LOGON_INTERACTIVE,	// type of logon operation. 
												// LOGON_BATCH doesn't seem to work right here.
					LOGON32_PROVIDER_DEFAULT,	// logon provider
					&CurrUserHandle				// receive tokens handle
				);
			} else {
				// we already have a good user handle from calling LogonUser to check to
				// see if our stashed credential was stale or not, so set retval to success
				retval = 1;	// LogonUser returns nonzero value on success
			}

			dprintf(D_FULLDEBUG, "LogonUser completed.\n");

			if (UserLoginName) {
				free(UserLoginName);
				UserDomainName = NULL;
			}
			if (UserDomainName) {
				free(UserDomainName);
				UserDomainName = NULL;
			}
			UserLoginName = strdup(username);
			UserDomainName = strdup(domain);

			if ( !retval ) {
				dprintf(D_ALWAYS, "init_user_ids: LogonUser failed with NT Status %ld\n", 
					GetLastError());
				retval =  0;	// return of 0 means FAILURE
			} else {
				// stash the new token in our cache
				cached_tokens.storeToken(UserLoginName, UserDomainName,
					   	CurrUserHandle);
				UserIdsInited = true;

				// if we got the password from the credd, and the admin wants passwords stashed
				// locally on this machine, then do it.
				if ( got_password_from_credd &&
                     param_boolean("CREDD_CACHE_LOCALLY",false) ) {
                    cache_credd_locally(username, domain, pw);
                }
				
				retval = 1;	// return of 1 means SUCCESS
			}

			// clear pw from memory
			SecureZeroMemory(pw, 255);

			return retval;
		}
		
	} else {
		///
		// Here's where we use a nobody account
		//
		
		dprintf(D_FULLDEBUG, "Using dynamic user account.\n");

		myDynuser->reset();
		// at this point, we know we want a user nobody, so
		// generate a dynamic user and stash the handle

				
		if ( !myDynuser->init_user() ) {
			// This is indicative of a serious problem.
			EXCEPT("Failed to create a user nobody");
		}
		
		if (UserLoginName) {
			free(UserLoginName);
			UserDomainName = NULL;
		}
		if (UserDomainName) {
			free(UserDomainName);
			UserDomainName = NULL;
		}

		UserLoginName = strdup( myDynuser->get_accountname() );
		UserDomainName = strdup( "." );

		// we created a new user, now just stash the token
		CurrUserHandle = myDynuser->get_token();

		// drop the handle in our cache too
		cached_tokens.storeToken(UserLoginName, UserDomainName,
			   		CurrUserHandle);
		UserIdsInited = true;
		return 1;
	}
}
예제 #5
0
int 
Condor_Auth_SSPI::sspi_server_auth(CredHandle& cred,CtxtHandle& srvCtx)
{
    int rc;
    SecPkgInfo *secPackInfo;
    int it_worked = FALSE;		// assume failure
    
    dprintf(D_FULLDEBUG, "sspi_server_auth() entered\n" );
    
    rc = (pf->QuerySecurityPackageInfo)( "NTLM", &secPackInfo );
    
    TimeStamp useBefore;
    
    rc = (pf->AcquireCredentialsHandle)( NULL, "NTLM", SECPKG_CRED_INBOUND,
                                         NULL, NULL, NULL, NULL, &cred, &useBefore );
    
    // input and output buffers
    SecBufferDesc obd, ibd;
    SecBuffer ob, ib;
    
    DWORD ctxAttr;
    
    bool haveContext = false;
    
    while ( 1 )
	{
            // prepare to get the server's response
            ibd.ulVersion = SECBUFFER_VERSION;
            ibd.cBuffers = 1;
            ibd.pBuffers = &ib; // just one buffer
            ib.BufferType = SECBUFFER_TOKEN; // preping a token here
            
            // receive the client's POD
            ib.pvBuffer = NULL;
            mySock_->decode();
            if ( !mySock_->code(ib.cbBuffer) ||
                 !mySock_->end_of_message() ||
                 !(ib.pvBuffer = LocalAlloc( 0, ib.cbBuffer )) ||
                 !mySock_->get_bytes((char *) ib.pvBuffer, ib.cbBuffer) ||
                 !mySock_->end_of_message() )
		{
                    dprintf(D_ALWAYS,
                            "ERROR sspi_server_auth() failed to received client POD\n");
                    if ( ib.pvBuffer ) {
                        LocalFree( ib.pvBuffer );
                        ib.pvBuffer = NULL;
                    }
                    (pf->FreeContextBuffer)( secPackInfo );			
                    return 0;
		}
            
            // by now we have an input buffer
            
            obd.ulVersion = SECBUFFER_VERSION;
            obd.cBuffers = 1;
            obd.pBuffers = &ob; // just one buffer
            ob.BufferType = SECBUFFER_TOKEN; // preping a token here
            ob.cbBuffer = secPackInfo->cbMaxToken;
            ob.pvBuffer = LocalAlloc( 0, ob.cbBuffer );
            
            rc = (pf->AcceptSecurityContext)( &cred, 
                                              haveContext? &srvCtx: NULL,
                                              &ibd, 
                                              0, 
                                              SECURITY_NATIVE_DREP, 
                                              &srvCtx, &obd, &ctxAttr,
                                              &useBefore );
            
            if ( ib.pvBuffer != NULL )
		{
                    LocalFree( ib.pvBuffer );
                    ib.pvBuffer = NULL;
		}
            
            if ( rc == SEC_I_COMPLETE_AND_CONTINUE || rc == SEC_I_COMPLETE_NEEDED )
		{
                    if ( pf->CompleteAuthToken != NULL ) // only if implemented
                        (pf->CompleteAuthToken)( &srvCtx, &obd );
                    if ( rc == SEC_I_COMPLETE_NEEDED )
                        rc = SEC_E_OK;
                    else if ( rc == SEC_I_COMPLETE_AND_CONTINUE )
                        rc = SEC_I_CONTINUE_NEEDED;
		}
            
            // send the output buffer off to the server
            if ( ob.cbBuffer != 0 )
		{
                    mySock_->encode();
                    if ( !mySock_->code(ob.cbBuffer) ||
                         !mySock_->end_of_message() ||
                         !mySock_->put_bytes( (const char *) ob.pvBuffer, ob.cbBuffer ) ||
                         !mySock_->end_of_message() ) 
			{
                            dprintf(D_ALWAYS,
                                    "ERROR sspi_server_auth() failed to send output blob\n");
                            LocalFree( ob.pvBuffer );
                            ob.pvBuffer = NULL;
                            (pf->FreeContextBuffer)( secPackInfo );			
                            return 0;
			}
		}
            LocalFree( ob.pvBuffer );
            ob.pvBuffer = NULL;
            
            if ( rc != SEC_I_CONTINUE_NEEDED )
                break;
            
            haveContext = true;
            
            // loop back for another round
            dprintf(D_FULLDEBUG,"sspi_server_auth() looping\n");
	}
    
    // we arrive here as soon as InitializeSecurityContext()
    // returns != SEC_I_CONTINUE_NEEDED.
    
    if ( rc != SEC_E_OK ) {
        dprintf( D_ALWAYS,"sspi_server_auth(): Oops! ASC() returned %d!\n", 
                 rc );
    }
    
    // now we try to use the context to Impersonate and thereby get the login
    rc = (pf->ImpersonateSecurityContext)( &srvCtx );

	char buf[256];
	char *dom = NULL;
	DWORD bufsiz = sizeof buf;

    if ( rc != SEC_E_OK ) {
        dprintf( D_ALWAYS,
                 "sspi_server_auth(): Failed to impersonate (returns %d)!\n",
					 rc );
    } else {

		// PLEASE READ: We're now running in the context of the
		// client we're impersonating. This means dprintf()'ing is
		// OFF LIMITS until we RevertSecurityContext(), since the
		// dprintf() will likely fail because the client 
		// probably will not have write access to the log file.

        GetUserName( buf, &bufsiz );
		dom = my_domainname();

		// revert as soon as possible.
	   	(pf->RevertSecurityContext)( &srvCtx );

		// Ok, safe to dprintf() now...

		it_worked = TRUE;

		setRemoteUser(buf);
		setRemoteDomain(dom);

		// set authenticated name used for mapping
		MyString auth_name;
		auth_name = buf;
		if(dom) {
			auth_name += "@";
			auth_name += dom;
		}
		setAuthenticatedName(auth_name.Value());

		dprintf( D_FULLDEBUG, "sspi_server_auth(): user name is: \"%s\"\n", buf );
		if (dom) {
			dprintf( D_FULLDEBUG, "sspi_server_auth(): domain name is: \"%s\"\n", dom);
			free(dom);
		}
    }

    (pf->FreeContextBuffer)( secPackInfo );

    dprintf( D_FULLDEBUG,"sspi_server_auth() exiting\n" );

    // return success (1) or failure (0) 
	return it_worked;
}
예제 #6
0
int main(int argc, char *argv[]) {

    MyString my_full_name;
    const char *full_name;
    char* pw = NULL;
    struct StoreCredOptions options;
    int result = FAILURE_ABORTED;
    bool pool_password_arg = false;
    bool pool_password_delete = false;
    Daemon *daemon = NULL;
    char *credd_host;

    MyName = condor_basename(argv[0]);

    // load up configuration file
    myDistro->Init( argc, argv );
    config();

    if (!parseCommandLine(&options, argc, argv)) {
        goto cleanup;
    }

    // if -h was given, just print usage
    if (options.help || (options.mode == 0)) {
        usage();
        goto cleanup;
    }

#if !defined(WIN32)
    // if the -f argument was given, we just want to prompt for a password
    // and write it to a file (in our weirdo XORed format)
    //
    if (options.password_file != NULL) {
        if (options.pw[0] == '\0') {
            pw = get_password();
            printf("\n");
        }
        else {
            pw = strnewp(options.pw);
            SecureZeroMemory(options.pw, MAX_PASSWORD_LENGTH + 1);
        }
        result = write_password_file(options.password_file, pw);
        SecureZeroMemory(pw, strlen(pw));
        if (result != SUCCESS) {
            fprintf(stderr,
                    "error writing password file: %s\n",
                    options.password_file);
        }
        goto cleanup;
    }
#endif

    // determine the username to use
    if ( strcmp(options.username, "") == 0 ) {
        // default to current user and domain
        char* my_name = my_username();
        char* my_domain = my_domainname();

        my_full_name.formatstr("%s@%s", my_name, my_domain);
        if ( my_name) {
            free(my_name);
        }
        if ( my_domain) {
            free(my_domain);
        }
        my_name = my_domain = NULL;
    } else if (strcmp(options.username, POOL_PASSWORD_USERNAME) == 0) {
#if !defined(WIN32)
        // we don't support querying the pool password on UNIX
        // (since it is not possible to do so through the
        //  STORE_POOL_CRED command)
        if (options.mode == QUERY_MODE) {
            fprintf(stderr, "Querying the pool password is not supported.\n");
            goto cleanup;
        }
#endif
        // append the correct domain name if we're using the pool pass
        // we first try POOL_PASSWORD_DOMAIN, then UID_DOMAIN
        pool_password_arg = true;
        char *domain;
        if ((domain = param("SEC_PASSWORD_DOMAIN")) == NULL) {
            if ((domain = param("UID_DOMAIN")) == NULL) {
                fprintf(stderr, "ERROR: could not domain for pool password\n");
                goto cleanup;
            }
        }
        my_full_name.formatstr(POOL_PASSWORD_USERNAME "@%s", domain);
        free(domain);
    } else {
        // username was specified on the command line
        my_full_name += options.username;
    }
    full_name = my_full_name.Value();
    printf("Account: %s\n\n", full_name);

    // determine where to direct our command
    daemon = NULL;
    credd_host = NULL;
    if (options.daemonname != NULL) {
        if (pool_password_arg && (options.mode != QUERY_MODE)) {
            // daemon named on command line; go to master for pool password
            //printf("sending command to master: %s\n", options.daemonname);
            daemon = new Daemon(DT_MASTER, options.daemonname);
        }
        else {
            // daemon named on command line; go to schedd for user password
            //printf("sending command to schedd: %s\n", options.daemonname);
            daemon = new Daemon(DT_SCHEDD, options.daemonname);
        }
    }
    else if (!pool_password_arg && ((credd_host = param("CREDD_HOST")) != NULL)) {
        // no daemon given, use credd for user passwords if CREDD_HOST is defined
        // (otherwise, we use the local schedd)
        //printf("sending command to CREDD: %s\n", credd_host);
        daemon = new Daemon(DT_CREDD);
    }
    else {
        //printf("sending command to local daemon\n");
    }

    // flag the case where we're deleting the pool password
    if (pool_password_arg && (options.mode == DELETE_MODE)) {
        pool_password_delete = true;
    }

    switch (options.mode) {
    case ADD_MODE:
    case DELETE_MODE:
        if (!pool_password_delete) {
            if ( strcmp(options.pw, "") == 0 ) {
                // get password from the user.
                pw = get_password();
                printf("\n\n");
            } else {
                // got the passwd from the command line.
                pw = strnewp(options.pw);
                SecureZeroMemory(options.pw, MAX_PASSWORD_LENGTH);
            }
        }
        if ( pw || pool_password_delete) {
            result = store_cred(full_name, pw, options.mode, daemon);
            if ((result == FAILURE_NOT_SECURE) && goAheadAnyways()) {
                // if user is ok with it, send the password in the clear
                result = store_cred(full_name, pw, options.mode, daemon, true);
            }
            if (pw) {
                SecureZeroMemory(pw, strlen(pw));
                delete[] pw;
            }
        }
        break;
    case QUERY_MODE:
        result = queryCredential(full_name, daemon);
        break;
#if defined(WIN32)
    case CONFIG_MODE:
        return interactive();
        break;
#endif
    default:
        fprintf(stderr, "Internal error\n");
        goto cleanup;
    }

    // output result of operation
    switch (result) {
    case SUCCESS:
        if (options.mode == QUERY_MODE) {
            printf("A credential is stored and is valid.\n");
        }
        else {
            printf("Operation succeeded.\n");
        }
        break;

    case FAILURE:
        printf("Operation failed.\n");
        if (pool_password_arg && (options.mode != QUERY_MODE)) {
            printf("    Make sure you have CONFIG access to the target Master.\n");
        }
        else {
            printf("    Make sure your ALLOW_WRITE setting includes this host.\n");
        }
        break;

    case FAILURE_BAD_PASSWORD:
        if (options.mode == QUERY_MODE) {
            printf("A credential is stored, but it is invalid. "
                   "Run 'condor_store_cred add' again.\n");
        }
        else {
            printf("Operation failed: bad password.\n");
        }
        break;

    case FAILURE_NOT_FOUND:
        if (options.mode == QUERY_MODE) {
            printf("No credential is stored.\n");
        }
        else {
            printf("Operation failed: username not found.\n");
        }
        break;

    case FAILURE_NOT_SECURE:
    case FAILURE_ABORTED:
        printf("Operation aborted.\n");
        break;

    case FAILURE_NOT_SUPPORTED:
        printf("Operation failed.\n"
               "    The target daemon is not running as SYSTEM.\n");
        break;

    default:
        fprintf(stderr, "Operation failed: unknown error code\n");
    }

cleanup:
    if (options.daemonname) {
        delete[] options.daemonname;
    }
    if (daemon) {
        delete daemon;
    }

    if ( result == SUCCESS ) {
        return 0;
    } else {
        return 1;
    }
}