Esempio n. 1
0
int
set_owner_egid()
{
	if( !OwnerIdsInited ) {
		dprintf( D_ALWAYS,
				 "set_owner_egid() called when OwnerIds not inited!\n" );
		return -1;
	}
	
		// Now, call our caching version of initgroups with the 
		// right username so the user can access files belonging
		// to any group (s)he is a member of.  If we did not call
		// initgroups here, the user could only access files
		// belonging to his/her default group, and might be left
		// with access to the groups that root belongs to, which 
		// is a serious security problem.
	if( OwnerName ) {
		errno = 0;
		if(!(pcache()->init_groups(OwnerName)) ) {
			dprintf( D_ALWAYS, 
					 "set_owner_egid - ERROR: initgroups(%s, %d) failed, "
					 "errno: %s\n", OwnerName, OwnerGid, strerror(errno) );
		}			
	}
	return SET_EFFECTIVE_GID(UserGid);
}
Esempio n. 2
0
int
init_user_ids_implementation( const char username[], int is_quiet )
{
	int					scm;
	uid_t 				usr_uid;
	gid_t				usr_gid;

		// So if we are not root, trying to use any user id is bogus
		// since the OS will disallow it.  So if we are not running as
		// root, may as well just set the user id to be the real id.
	
	// For setuid-root
	// -jaeyoung 05/22/07
	//if ( get_my_uid() != ROOT ) {
	if ( !can_switch_ids() ) {
		return set_user_ids_implementation( get_my_uid(), get_my_gid(),
										NULL, is_quiet ); 
	}

	/*
	** N.B. if we are using the yellow pages, system calls which are
	** not supported by either remote system calls or file descriptor
	** mapping will occur.  Thus we must be in LOCAL/UNRECORDED mode here.
	*/
	scm = SetSyscalls( SYS_LOCAL | SYS_UNRECORDED );

	if( ! strcasecmp(username, "nobody") ) {
			// There's so much special logic for user nobody that it's
			// all in a seperate function now.
		return init_nobody_ids( is_quiet );
	}

	if( !(pcache()->get_user_uid(username, usr_uid)) ||
	 	!(pcache()->get_user_gid(username, usr_gid)) ) {
		if( ! is_quiet ) {
			dprintf( D_ALWAYS, "%s not in passwd file\n", username );
		}
		(void)endpwent();
		(void)SetSyscalls( scm );
		return FALSE;
	}
	(void)endpwent();
	(void)SetSyscalls( scm );
	return set_user_ids_implementation( usr_uid, usr_gid, username, is_quiet ); 
}
Esempio n. 3
0
const char*
get_real_username( void )
{
	if( ! RealUserName ) {
		uid_t my_uid = getuid();
		if ( !(pcache()->get_user_name( my_uid, RealUserName)) ) {
			char buf[64];
			sprintf( buf, "uid %d", (int)my_uid );
			RealUserName = strdup( buf );
		}
	}
	return RealUserName;
}
Esempio n. 4
0
static int
set_user_ids_implementation( uid_t uid, gid_t gid, const char *username, 
							 int is_quiet ) 
{
	if( uid == 0 || gid == 0 ) {
			// NOTE: we want this dprintf() even if we're in quiet
			// mode, since we should *never* be allowing this.
		dprintf( D_ALWAYS, "ERROR: Attempt to initialize user_priv " 
				 "with root privileges rejected\n" );
		return FALSE;
	}
		// So if we are not root, trying to use any user id is bogus
		// since the OS will disallow it.  So if we are not running as
		// root, may as well just set the user id to be the real id.
	// For setuid-root
	// -jaeyoung 05/22/07
	//if ( get_my_uid() != ROOT ) {
	if ( !can_switch_ids() ) {
		uid = get_my_uid();
		gid = get_my_gid();
	}

	if( UserIdsInited && UserUid != uid && !is_quiet ) {
		dprintf( D_ALWAYS, 
				 "warning: setting UserUid to %d, was %d previously\n",
				 uid, UserUid );
	}
	UserUid = uid;
	UserGid = gid;
	UserIdsInited = TRUE;

	// find the user login name for this uid.  note we should not
	// EXCEPT or log an error if we do not find it; it is OK for the
	// user not to be in the passwd file for a so-called SOFT_UID_DOMAIN.
	if( UserName ) {
		free( UserName );
	}

	if ( !username ) {

		if ( !(pcache()->get_user_name( UserUid, UserName )) ) {
			UserName = NULL;
		}
	} else {
		UserName = strdup( username );
	}
	return TRUE;
}
Esempio n. 5
0
bool
SpooledJobFiles::chownSpoolDirectoryToCondor(ClassAd const *job_ad)
{
	bool result = true;

#ifndef WIN32
	std::string sandbox;
	int cluster=-1,proc=-1;

	job_ad->LookupInteger(ATTR_CLUSTER_ID,cluster);
	job_ad->LookupInteger(ATTR_PROC_ID,proc);

	getJobSpoolPath(cluster, proc, sandbox);

	uid_t src_uid = 0;
	uid_t dst_uid = get_condor_uid();
	gid_t dst_gid = get_condor_gid();

	MyString jobOwner;
	job_ad->LookupString( ATTR_OWNER, jobOwner );

	passwd_cache* p_cache = pcache();
	if( p_cache->get_user_uid( jobOwner.Value(), src_uid ) ) {
		if( ! recursive_chown(sandbox.c_str(), src_uid,
							  dst_uid, dst_gid, true) )
		{
			dprintf( D_FULLDEBUG, "(%d.%d) Failed to chown %s from "
					 "%d to %d.%d.  User may run into permissions "
					 "problems when fetching sandbox.\n", 
					 cluster, proc, sandbox.c_str(),
					 src_uid, dst_uid, dst_gid );
			result = false;
		}
	} else {
		dprintf( D_ALWAYS, "(%d.%d) Failed to find UID and GID "
				 "for user %s.  Cannot chown \"%s\".  User may "
				 "run into permissions problems when fetching "
				 "job sandbox.\n", cluster, proc, jobOwner.Value(),
				 sandbox.c_str() );
		result = false;
	}

#endif

	return result;
}
Esempio n. 6
0
int
set_condor_rgid()
{
	if( !CondorIdsInited ) {
		init_condor_ids();
	}

	if( CondorUserName ) {
		errno = 0;
		if(!(pcache()->init_groups(CondorUserName)) ) {
			dprintf( D_ALWAYS, 
					 "set_condor_rgid - ERROR: initgroups(%s) failed, "
					 "errno: %s\n", CondorUserName, strerror(errno) );
		}                       
	}

	return SET_REAL_GID(CondorGid);
}
Esempio n. 7
0
int
set_file_owner_ids( uid_t uid, gid_t gid )
{
	if( OwnerIdsInited && OwnerUid != uid  ) {
		dprintf( D_ALWAYS, 
				 "warning: setting OwnerUid to %d, was %d previosly\n",
				 (int)uid, (int)OwnerUid );
	}
	OwnerUid = uid;
	OwnerGid = gid;
	OwnerIdsInited = TRUE;

	// find the user login name for this uid.  note we should not
	// EXCEPT or log an error if we do not find it; it is OK for the
	// user not to be in the passwd file...
	if( OwnerName ) {
		free( OwnerName );
	}
	if ( !(pcache()->get_user_name( OwnerUid, OwnerName )) ) {
		OwnerName = NULL;
	}
	return TRUE;
}
Esempio n. 8
0
bool
VMGahpServer::startUp(Env *job_env, const char *workingdir, int nice_inc, FamilyInfo *family_info)
{
    //check if we already have spawned a vmgahp server
    if( m_vmgahp_pid > 0 ) {
        //vmgahp is already running
        return true;
    }

    if( !m_job_ad ) {
        start_err_msg = "No JobAd in VMGahpServer::startUp()";
        dprintf(D_ALWAYS,"%s\n", start_err_msg.Value());
        return false;
    }

    MyString JobName;
    if( m_vmgahp_server.IsEmpty() ) {
        start_err_msg = "No path for vmgahp in VMGahpServer::startUp()";
        dprintf(D_ALWAYS,"%s\n", start_err_msg.Value());
        return false;
    }

    JobName = m_vmgahp_server;

    // Create two pairs of pipes which we will use to
    int stdin_pipefds[2];
    int stdout_pipefds[2];
    int stderr_pipefds[2];

    if(!daemonCore->Create_Pipe(stdin_pipefds,
                                true, // read end registerable
                                false, // write end not registerable
                                false, // read end blocking
                                false // write end blocking
                               )) {
        start_err_msg = "unable to create pipe to stdin of VM gahp";
        dprintf(D_ALWAYS,"%s\n", start_err_msg.Value());
        return false;
    }
    if(!daemonCore->Create_Pipe(stdout_pipefds,
                                true,  //read end registerable
                                false, // write end not registerable
                                false, // read end blocking
                                false // write end blocking
                               )) {
        // blocking read
        start_err_msg = "unable to create pipe to stdout of VM gahp";
        dprintf(D_ALWAYS,"%s\n", start_err_msg.Value());
        return false;
    }
    if( m_include_gahp_log ) {
        if(!daemonCore->Create_Pipe(stderr_pipefds,
                                    true,  // read end registerable
                                    false, // write end not registerable
                                    true,  // read end non-blocking
                                    true  // write end non-blocking
                                   )) {
            // nonblocking read
            start_err_msg = "unable to create pipe to stderr of VM gahp";
            dprintf(D_ALWAYS,"%s\n", start_err_msg.Value());
            return false;
        }
    }

    int io_redirect[3];
    io_redirect[0] = stdin_pipefds[0];	//stdin gets read side of in pipe
    io_redirect[1] = stdout_pipefds[1];	//stdout gets write side of out pipe
    if( m_include_gahp_log ) {
        io_redirect[2] = stderr_pipefds[1];	//stderr gets write side of err pipe
    } else {
        int null_fd = safe_open_wrapper_follow(NULL_FILE, O_WRONLY | O_APPEND, 0666);
        if( null_fd < 0 ) {
            start_err_msg = "unable to open null file for stderr of VM gahp";
            dprintf(D_ALWAYS,"Failed to open '%s':%s (errno %d)\n",
                    NULL_FILE, strerror(errno), errno);
            return false;
        }
        io_redirect[2] = null_fd;
    }

    // Set Arguments
    ArgList vmgahp_args;

    vmgahp_args.SetArgV1SyntaxToCurrentPlatform();
    vmgahp_args.AppendArg(m_vmgahp_server.Value());

    // Add daemonCore options
    vmgahp_args.AppendArg("-f");
    if( m_include_gahp_log ) {
        vmgahp_args.AppendArg("-t");
    }
    vmgahp_args.AppendArg("-M");
    vmgahp_args.AppendArg(VMGAHP_STANDALONE_MODE);

    MyString args_string;
    vmgahp_args.GetArgsStringForDisplay(&args_string, 1);
    dprintf( D_ALWAYS, "About to exec %s %s\n", JobName.Value(),
             args_string.Value() );

#if !defined(WIN32)
    uid_t vmgahp_user_uid = (uid_t) -1;
    gid_t vmgahp_user_gid = (gid_t) -1;

    if( can_switch_ids() ) {
        // Condor runs as root
        vmgahp_user_uid = get_user_uid();
        vmgahp_user_gid = get_user_gid();
    }
    else if (Starter->condorPrivSepHelper() != NULL) {
        vmgahp_user_uid = Starter->condorPrivSepHelper()->get_uid();
        char* user_name;
        if (!pcache()->get_user_name(vmgahp_user_uid, user_name)) {
            EXCEPT("unable to get user name for UID %u", vmgahp_user_uid);
        }
        if (!pcache()->get_user_ids(user_name,
                                    vmgahp_user_uid,
                                    vmgahp_user_gid))
        {
            EXCEPT("unable to get GID for UID %u", vmgahp_user_uid);
        }
        free(user_name);
    }
    else {
        // vmgahp may have setuid-root (e.g. vmgahp for Xen)
        vmgahp_user_uid = get_condor_uid();
        vmgahp_user_gid = get_condor_gid();
    }

    // Setup vmgahp user uid/gid
    if( vmgahp_user_uid > 0 ) {
        if( vmgahp_user_gid <= 0 ) {
            vmgahp_user_gid = vmgahp_user_uid;
        }

        MyString tmp_str;
        tmp_str.sprintf("%d", (int)vmgahp_user_uid);
        job_env->SetEnv("VMGAHP_USER_UID", tmp_str.Value());
        tmp_str.sprintf("%d", (int)vmgahp_user_gid);
        job_env->SetEnv("VMGAHP_USER_GID", tmp_str.Value());
    }
#endif

    job_env->SetEnv("VMGAHP_VMTYPE", m_vm_type.Value());
    job_env->SetEnv("VMGAHP_WORKING_DIR", workingdir);

    // Grab the full environment back out of the Env object
    if(IsFulldebug(D_FULLDEBUG)) {
        MyString env_str;
        job_env->getDelimitedStringForDisplay(&env_str);
        dprintf(D_FULLDEBUG, "Env = %s\n", env_str.Value());
    }

    priv_state vmgahp_priv = PRIV_ROOT;
#if defined(WIN32)
    // 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.
    // -jaeyoung 06/15/07
    if( strcasecmp(m_vm_type.Value(), CONDOR_VM_UNIVERSE_VMWARE ) == MATCH ) {
        vmgahp_priv = PRIV_UNKNOWN;
    }
#endif

    m_vmgahp_pid = daemonCore->Create_Process(
                       JobName.Value(), //Name of executable
                       vmgahp_args,	//Args
                       vmgahp_priv, 	//Priv state
                       1, 		//id for our registered reaper
                       FALSE, 		//do not want a command port
                       job_env, 	//env
                       workingdir,	//cwd
                       family_info,		//family_info
                       NULL, 		//network sockets to inherit
                       io_redirect,	//redirect stdin/out/err
                       NULL,
                       nice_inc
                   );

    //NOTE: Create_Process() saves the errno for us if it is an
    //"interesting" error.
    char const *create_process_error = NULL;
    if(m_vmgahp_pid == FALSE && errno) create_process_error = strerror(errno);

    // Now that the VMGAHP server is running, close the sides of
    // the pipes we gave away to the server, and stash the ones
    // we want to keep in an object data member.
    daemonCore->Close_Pipe(io_redirect[0]);
    daemonCore->Close_Pipe(io_redirect[1]);
    if( m_include_gahp_log ) {
        daemonCore->Close_Pipe(io_redirect[2]);
    } else {
        close(io_redirect[2]);
    }

    if ( m_vmgahp_pid == FALSE ) {
        m_vmgahp_pid = -1;
        start_err_msg = "Failed to start vm-gahp server";
        dprintf(D_ALWAYS, "%s (%s)\n", start_err_msg.Value(),
                m_vmgahp_server.Value());
        if(create_process_error) {
            MyString err_msg = "Failed to execute '";
            err_msg += m_vmgahp_server.Value(),
                       err_msg += "'";
            if(!args_string.IsEmpty()) {
                err_msg += " with arguments ";
                err_msg += args_string.Value();
            }
            err_msg += ": ";
            err_msg += create_process_error;
            dprintf(D_ALWAYS, "Failed to start vmgahp server (%s)\n",
                    err_msg.Value());
        }
        return false;
    }

    dprintf(D_ALWAYS, "VMGAHP server pid=%d\n", m_vmgahp_pid);

    m_vmgahp_writefd = stdin_pipefds[1];
    m_vmgahp_readfd = stdout_pipefds[0];
    if( m_include_gahp_log ) {
        m_vmgahp_errorfd = stderr_pipefds[0];
    }

    // Now initialization is done
    m_is_initialized = true;

    // print initial stderr messages from vmgahp
    printSystemErrorMsg();

    // Read the initial greeting from the vm-gahp, which is the version
    if( command_version() == false ) {
        start_err_msg = "Internal vmgahp server error";
        dprintf(D_ALWAYS,"Failed to read vmgahp server version\n");
        printSystemErrorMsg();
        cleanup();
        return false;
    }

    dprintf(D_FULLDEBUG,"VMGAHP server version: %s\n", m_vmgahp_version.Value());

    // Now see what commands this server supports.
    if( command_commands() == false ) {
        start_err_msg = "Internal vmgahp server error";
        dprintf(D_ALWAYS,"Failed to read supported commands from vmgahp server\n");
        printSystemErrorMsg();
        cleanup();
        return false;
    }

    // Now see what virtual machine types this server supports
    if( command_support_vms() == false ) {
        start_err_msg = "Internal vmgahp server error";
        dprintf(D_ALWAYS,"Failed to read supported vm types from vmgahp server\n");
        printSystemErrorMsg();
        cleanup();
        return false;
    }

    int result = -1;
    if( m_include_gahp_log ) {
        result = daemonCore->Register_Pipe(m_vmgahp_errorfd,
                                           "m_vmgahp_errorfd",
                                           static_cast<PipeHandlercpp>(&VMGahpServer::err_pipe_ready),
                                           "VMGahpServer::err_pipe_ready",this);

        if( result == -1 ) {
            dprintf(D_ALWAYS,"Failed to register vmgahp stderr pipe\n");
            if(m_stderr_tid != -1) {
                daemonCore->Cancel_Timer(m_stderr_tid);
                m_stderr_tid = -1;
            }
            m_stderr_tid = daemonCore->Register_Timer(2,
                           2, (TimerHandlercpp)&VMGahpServer::err_pipe_ready,
                           "VMGahpServer::err_pipe_ready",this);
            if( m_stderr_tid == -1 ) {
                start_err_msg = "Internal vmgahp server error";
                dprintf(D_ALWAYS,"Failed to register stderr timer\n");
                printSystemErrorMsg();
                cleanup();
                return false;
            }
        }
    }

    // try to turn on vmgahp async notification mode
    if  ( !command_async_mode_on() ) {
        // not supported, set a poll interval
        m_is_async_mode = false;
        setPollInterval(m_pollInterval);
    } else {
        // command worked... register the pipe and stop polling
        result = daemonCore->Register_Pipe(m_vmgahp_readfd,
                                           "m_vmgahp_readfd",
                                           static_cast<PipeHandlercpp>(&VMGahpServer::pipe_ready),
                                           "VMGahpServer::pipe_ready",this);
        if( result == -1 ) {
            // failed to register the pipe for some reason; fall
            // back on polling (yuck).
            dprintf(D_ALWAYS,"Failed to register vmgahp Read pipe\n");
            m_is_async_mode = false;
            setPollInterval(m_pollInterval);
        } else {
            // pipe is registered.  stop polling.
            setPollInterval(0);
            m_is_async_mode = true;
        }
    }

    return true;
}
Esempio n. 9
0
void
init_condor_ids()
{
	int scm;
	bool result;
	char* env_val = NULL;
	char* config_val = NULL;
	char* val = NULL;
	uid_t envCondorUid = INT_MAX;
	gid_t envCondorGid = INT_MAX;

        /*
        ** N.B. if we are using the yellow pages, system calls which are
        ** not supported by either remote system calls or file descriptor
        ** mapping will occur.  Thus we must be in LOCAL/UNRECORDED mode here.
        */
	scm = SetSyscalls( SYS_LOCAL | SYS_UNRECORDED );

	uid_t MyUid = get_my_uid();
	gid_t MyGid = get_my_gid();
	
		/* if either of the following get_user_*() functions fail,
		 * the default is INT_MAX */
	RealCondorUid = INT_MAX;
	RealCondorGid = INT_MAX;
	pcache()->get_user_uid( myDistro->Get(), RealCondorUid );
	pcache()->get_user_gid( myDistro->Get(), RealCondorGid );

	const char	*envName = EnvGetName( ENV_UG_IDS ); 
	if( (env_val = getenv(envName)) ) {
		val = env_val;
	} else if( (config_val = param_without_default(envName)) ) {
		// I had to change this to param_without_default because there's no way
		// to put a default value of condor.condor in the default value table.
		// In the future, there should be a way to call a function to find out
		// the default value for a parameter, but for now this should work.
		val = config_val;
	}
	if( val ) {  
		if( sscanf(val, "%d.%d", &envCondorUid, &envCondorGid) != 2 ) {
			fprintf( stderr, "ERROR: badly formed value in %s ", envName );
			fprintf( stderr, "%s variable (%s).\n",
					 env_val ? "environment" : "config file", val );
			fprintf( stderr, "Please set %s to ", envName );
			fprintf( stderr, "the '.' seperated uid, gid pair that\n" );
			fprintf( stderr, "should be used by %s.\n", myDistro->Get() );
			exit(1);
		}
		if( CondorUserName != NULL ) {
			free( CondorUserName );
			CondorUserName = NULL;
		}
		result = pcache()->get_user_name( envCondorUid, CondorUserName );

		if( ! result ) {

				/* failure to get username */

			fprintf( stderr, "ERROR: the uid specified in %s ", envName );
			fprintf( stderr, "%s variable (%d)\n", 
					 env_val ? "environment" : "config file", envCondorUid );
			fprintf(stderr, "does not exist in your password information.\n" );
			fprintf(stderr, "Please set %s to ", envName);
			fprintf(stderr, "the '.' seperated uid, gid pair that\n");
			fprintf(stderr, "should be used by %s.\n", myDistro->Get() );
			exit(1);
		}
	}
	if( config_val ) {
		free( config_val );
		config_val = NULL;
		val = NULL;
	}

	/* If we're root, set the Condor Uid and Gid to the value
	   specified in the "CONDOR_IDS" environment variable */
	if( can_switch_ids() ) {
		const char	*enviName = EnvGetName( ENV_UG_IDS ); 
		if( envCondorUid != INT_MAX ) {	
			/* CONDOR_IDS are set, use what it said */
				CondorUid = envCondorUid;
				CondorGid = envCondorGid;
		} else {
			/* No CONDOR_IDS set, use condor.condor */
			if( RealCondorUid != INT_MAX ) {
				CondorUid = RealCondorUid;
				CondorGid = RealCondorGid;
				if( CondorUserName != NULL ) {
					free( CondorUserName );
					CondorUserName = NULL;
				}
				CondorUserName = strdup( myDistro->Get() );
				if (CondorUserName == NULL) {
					EXCEPT("Out of memory. Aborting.");
				}
			} else {
				fprintf( stderr,
						 "Can't find \"%s\" in the password file and "
						 "%s not defined in %s_config or as an "
						 "environment variable.\n", myDistro->Get(),
						 enviName, myDistro->Get() );
				exit(1);
			}
		}
			/* We'd like to dprintf() here, but we can't.  Since this 
			   function is called from the initial time we try to
			   enter Condor priv, if we dprintf() here, we'll still be
			   in root priv when we service this dprintf(), and we'll
			   have major problems.  -Derek Wright 12/21/98 */
			/* dprintf(D_PRIV, "running as root; privilege switching in effect\n"); */
	} else {
		/* Non-root.  Set the CondorUid/Gid to our current uid/gid */
		CondorUid = MyUid;
		CondorGid = MyGid;
		if( CondorUserName != NULL ) {
			free( CondorUserName );
			CondorUserName = NULL;
		}
		result = pcache()->get_user_name( CondorUid, CondorUserName );
		if( !result ) {
			/* Cannot find an entry in the passwd file for this uid */
			CondorUserName = strdup("Unknown");
			if (CondorUserName == NULL) {
				EXCEPT("Out of memory. Aborting.");
			}
		}

		/* If CONDOR_IDS environment variable is set, and set to the same uid
		   that we are running as, then behave as if the daemons are running
		   as user "condor" -- i.e. allow any user to submit jobs to these daemons,
		   not just the user running the daemons.
		*/
		if ( MyUid == envCondorUid ) {
			RealCondorUid = MyUid;
			RealCondorGid = MyGid;
		}
	}
	
	(void)endpwent();
	(void)SetSyscalls( scm );
	
	CondorIdsInited = TRUE;
}
Esempio n. 10
0
void
clear_passwd_cache() {
	pcache()->reset();
}
Esempio n. 11
0
/*
  Initialize the correct uid/gid for user "nobody".  Most of the
  special-case logic for this code came from
  condor_starter.V5/starter_common.C: determine_user_ids()
*/
int
init_nobody_ids( int is_quiet )
{
	bool result;

	/* WARNING: We're initializing the nobody uid/gid's to 0!
	   That's a big no-no, so make sure that if we somehow don't
	   manage to find a valid nobody uid/gid, that we immediately
	   return FALSE and fail out. 

	   Unfortunately, there is no value you can set a uid_t/gid_t
	   to that indicates an uninitialized or invalid value. In the
	   case of this function however, we know that no matter what,
	   the nobody user should NEVER be 0, so it serves well for
	   this purpose.
	 */

	uid_t nobody_uid = 0;
	gid_t nobody_gid = 0;

	result = ( 	(pcache()->get_user_uid("nobody", nobody_uid)) &&
	   			(pcache()->get_user_gid("nobody", nobody_gid)) );

	if (! result ) {


#ifdef HPUX
		// the HPUX9 release does not have a default entry for nobody,
		// so we'll help condor admins out a bit here...
		nobody_uid = 59999;
		nobody_gid = 59999;
#else
		if( ! is_quiet ) {
			dprintf( D_ALWAYS, 
					 "Can't find UID for \"nobody\" in passwd file\n" );
		}
		return FALSE;
#endif
	} 

#ifdef HPUX
	// HPUX9 has a bug in that getpwnam("nobody") always returns
	// a gid of 60001, no matter what the group file (or NIS) says!
	// on top of that, legal UID/GIDs must be -1<x<60000, so unless we
	// patch here, we will generate an EXCEPT later when we try a
	// setgid().  -Todd Tannenbaum, 3/95
	if( (nobody_uid > 59999) || (nobody_uid <= 0) ) {
		nobody_uid = 59999;
	}
	if( (nobody_gid > 59999) || (nobody_gid <= 0) ) {
		nobody_gid = 59999;
	}
#endif

	/* WARNING: At the top of this function, we initialized 
	   nobody_uid and nobody_gid to 0, so if for some terrible 
	   reason we haven't set them to a valid nobody uid/gid
	   by this point, we need to fail immediately. */

	if ( nobody_uid == 0 || nobody_gid == 0 ) {
		return FALSE;
	}

		// Now we know what the uid/gid for nobody should *really* be,
		// so we can actually initialize this as the "user" priv.
	return set_user_ids_implementation( (uid_t)nobody_uid,
										(gid_t)nobody_gid, "nobody",
										is_quiet );
}
Esempio n. 12
0
static bool
createJobSpoolDirectory(ClassAd const *job_ad,priv_state desired_priv_state,char const *spool_path)
{
	int cluster=-1,proc=-1;

	job_ad->LookupInteger(ATTR_CLUSTER_ID,cluster);
	job_ad->LookupInteger(ATTR_PROC_ID,proc);

#ifndef WIN32
	uid_t spool_path_uid;
#endif

	StatInfo si( spool_path );
	if( si.Error() == SINoFile ) {
		if(!mkdir_and_parents_if_needed(spool_path,0755,PRIV_CONDOR) )
		{
			dprintf( D_ALWAYS,
					 "Failed to create spool directory for job %d.%d: "
					 "mkdir(%s): %s (errno %d)\n",
					 cluster, proc, spool_path, strerror(errno), errno );
			return false;
		}
#ifndef WIN32
		spool_path_uid = get_condor_uid();
#endif
	} else { 
#ifndef WIN32
			// spool_path already exists, check owner
		spool_path_uid = si.GetOwner();
#endif
	}

	if( !can_switch_ids() ||
		desired_priv_state == PRIV_UNKNOWN ||
		desired_priv_state == PRIV_CONDOR )
	{
		return true; // no need/desire for chowning
	}

	ASSERT( desired_priv_state == PRIV_USER );

#ifndef WIN32

	MyString owner;
	job_ad->LookupString( ATTR_OWNER, owner );

	uid_t src_uid = get_condor_uid();
	uid_t dst_uid;
	gid_t dst_gid;
	passwd_cache* p_cache = pcache();
	if( !p_cache->get_user_ids(owner.Value(), dst_uid, dst_gid) ) {
		dprintf( D_ALWAYS, "(%d.%d) Failed to find UID and GID for "
				 "user %s. Cannot chown %s to user.\n",
				 cluster, proc, owner.Value(), spool_path );
		return false;
	}

	if( (spool_path_uid != dst_uid) && 
		!recursive_chown(spool_path,src_uid,dst_uid,dst_gid,true) )
	{
		dprintf( D_ALWAYS, "(%d.%d) Failed to chown %s from %d to %d.%d.\n",
				 cluster, proc, spool_path, src_uid, dst_uid, dst_gid );
		return false;
	}

#else	/* WIN32 */

	MyString owner;
	job_ad->LookupString(ATTR_OWNER, owner);

	MyString nt_domain;
	job_ad->LookupString(ATTR_NT_DOMAIN, nt_domain);

	if(!recursive_chown(spool_path, owner.Value(), nt_domain.Value()))
	{
		dprintf( D_ALWAYS, "(%d.%d) Failed to chown %s from to %d\\%d.\n",
		         cluster, proc, spool_path,
				 nt_domain.Value(), owner.Value() );
		return false;
	}
#endif

	return true;  // All happy paths lead here
}