[condor: 2/31] Added the glexec-as-root patch.

Brian Bockelman bbockelm at fedoraproject.org
Fri Mar 8 01:19:47 UTC 2013


commit 4c2db811c7f18fe1ed00ce9f37364cdde967367c
Author: Brian Bockelman <bbockelm at cse.unl.edu>
Date:   Fri Sep 30 15:45:34 2011 -0500

    Added the glexec-as-root patch.

 condor_glexec_as_root_v3.patch |  217 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 217 insertions(+), 0 deletions(-)
---
diff --git a/condor_glexec_as_root_v3.patch b/condor_glexec_as_root_v3.patch
new file mode 100644
index 0000000..2dc2db4
--- /dev/null
+++ b/condor_glexec_as_root_v3.patch
@@ -0,0 +1,217 @@
+diff --git a/src/condor_starter.V6.1/glexec_privsep_helper.linux.cpp b/src/condor_starter.V6.1/glexec_privsep_helper.linux.cpp
+index 0856c8f..42d02d2 100644
+--- a/src/condor_starter.V6.1/glexec_privsep_helper.linux.cpp
++++ b/src/condor_starter.V6.1/glexec_privsep_helper.linux.cpp
+@@ -54,20 +54,31 @@ GLExecPrivSepHelper::~GLExecPrivSepHelper()
+ int
+ GLExecPrivSepHelper::proxy_valid_right_now()
+ {
++
++	int result = TRUE;
++		/* Note that set_user_priv is a no-op if condor is running as
++		   non-root (the "usual" mode for invoking glexec) */
++	priv_state priv_saved = set_user_priv();
+ 	if (!m_proxy) {
+ 		dprintf(D_FULLDEBUG, "GLExecPrivSepHelper::proxy_valid_right_now: no proxy defined\n");
+-		return FALSE;
++		result = FALSE;
+ 	} else {
++
+ 		time_t expiration_time = x509_proxy_expiration_time(m_proxy);
+ 		time_t now = time(NULL);
+ 
+-		if (expiration_time < now) {
+-			dprintf(D_FULLDEBUG, "GLExecPrivSepHelper::proxy_valid_right_now: proxy %s already expired!\n", m_proxy);
+-			return FALSE;
++		if (expiration_time == -1) {
++			dprintf(D_FULLDEBUG, "GLExecPrivSepHelper::proxy_valid_right_now: Globus error when getting proxy %s expiration: %s.\n", m_proxy, x509_error_string());
++			result = FALSE;
++		} else if (expiration_time < now) {
++			dprintf(D_FULLDEBUG, "GLExecPrivSepHelper::proxy_valid_right_now: proxy %s expired %ld seconds ago!\n", m_proxy, now - expiration_time);
++			result = FALSE;
+ 		}
+ 	}
+ 
+-	return TRUE;
++	set_priv(priv_saved);
++
++	return result;
+ }
+ 
+ 
+@@ -79,17 +90,27 @@ GLExecPrivSepHelper::run_script(ArgList& args,MyString &error_desc)
+ 		return -1;
+ 	}
+ 
++		/* Note that set_user_priv is a no-op if condor is running as
++		   non-root (the "usual" mode for invoking glexec) */
++	priv_state priv_saved = set_user_priv();
+ 	FILE* fp = my_popen(args, "r", TRUE);
++	set_priv(priv_saved);
+ 	if (fp == NULL) {
+ 		dprintf(D_ALWAYS,
+ 		        "GLExecPrivSepHelper::run_script: "
+-		            "my_popen failure on %s\n",
+-		        args.GetArg(0));
++		            "my_popen failure on %s: errno=%d (%s)\n",
++		        args.GetArg(0),
++			errno,
++			strerror(errno));
+ 		return -1;
+ 	}
+ 	MyString str;
+ 	while (str.readLine(fp, true));
++
++	priv_saved = set_user_priv();
+ 	int ret = my_pclose(fp);
++	set_priv(priv_saved);
++
+ 	if (ret != 0) {
+ 		str.trim();
+ 		dprintf(D_ALWAYS,
+@@ -320,17 +341,28 @@ GLExecPrivSepHelper::create_process(const char* path,
+ 
+ 	glexec_env.MergeFrom(env);
+ 
+-	if( glexec_env.GetEnv("X509_USER_PROXY",user_proxy) &&
+-	    (condor_proxy = getenv("X509_USER_PROXY")) )
++	if( glexec_env.GetEnv("X509_USER_PROXY",user_proxy))
+ 	{
+-		// glexec versions >= 0.7.0 may use X509_USER_PROXY to
+-		// authenticate to the mapping service.  We are expected to
+-		// set this to the glidein (aka pilot) proxy rather than the
+-		// end-user proxy when invoking glexec.  Since we are invoking
+-		// glexec with the job environment (see comment above), we
+-		// must treat X509_USER_PROXY specially.
+-
+-		glexec_env.SetEnv("X509_USER_PROXY",condor_proxy);
++		if ((condor_proxy = getenv("X509_USER_PROXY"))) {
++			// glexec versions >= 0.7.0 may use X509_USER_PROXY to
++			// authenticate to the mapping service.  We are expected to
++			// set this to the glidein (aka pilot) proxy rather than the
++			// end-user proxy when invoking glexec.  Since we are invoking
++			// glexec with the job environment (see comment above), we
++			// must treat X509_USER_PROXY specially.
++
++			glexec_env.SetEnv("X509_USER_PROXY",condor_proxy);
++		}
++		// We set the target proxy environment variable to point at
++                // the user proxy.  Without it, newer versions of glexec will
++                // create a proxy in /tmp and not clean it up.  When the glexec
++                // exec's to the target process, there will be a fresh copy
++                // of the proxy (not delegation).
++                // Note Condor will copy the proxy into into the user's sandbox,
++                // and this will get clobbered when the job actually launches.
++                // When Condor runs proxy-update, the proxy will get overwritten
++                // twice - first by glexec, then by Condor.
++		glexec_env.SetEnv("GLEXEC_TARGET_PROXY", user_proxy);
+ 	}
+ 
+ 	int pid = daemonCore->Create_Process(m_run_script.Value(),
+diff --git a/src/condor_utils/my_popen.cpp b/src/condor_utils/my_popen.cpp
+index f0018c7..3206f91 100644
+--- a/src/condor_utils/my_popen.cpp
++++ b/src/condor_utils/my_popen.cpp
+@@ -270,6 +270,7 @@ my_system(const char *cmd)
+ // UNIX versions of my_popen(v) & my_pclose 
+ //////////////////////////////////////////////////////////////////////////
+ 
++#include <fcntl.h> // for O_CLOEXEC
+ #include <grp.h> // for setgroups
+ 
+ static int	READ_END = 0;
+@@ -282,7 +283,7 @@ my_popenv_impl( const char *const args[],
+                 uid_t privsep_uid,
+ 				Env *env_ptr = 0)
+ {
+-	int	pipe_d[2];
++	int	pipe_d[2], pipe_d2[2];
+ 	int	parent_reads;
+ 	uid_t	euid;
+ 	gid_t	egid;
+@@ -312,6 +313,32 @@ my_popenv_impl( const char *const args[],
+ 		}
+ 	}
+ 
++		/* Create a pipe to detect execv failures */
++	if ( pipe(pipe_d2) < 0) {
++		dprintf(D_ALWAYS, "my_popenv: Failed to create the pre-exec pipe, "
++				"errno=%d (%s)\n", errno, strerror(errno));
++		close(pipe_d[0]);
++		close(pipe_d[1]);
++		return NULL;
++	}
++	int fd_flags;
++	if ((fd_flags = fcntl(pipe_d2[1], F_GETFD, NULL)) == -1) {
++		dprintf(D_ALWAYS, "my_popenv: Failed to get fd flags: errno=%d (%s)\n", errno, strerror(errno));
++		close( pipe_d[0] );
++		close( pipe_d[1] );
++		close( pipe_d2[0] );
++		close( pipe_d2[1] );
++		return NULL;
++	}
++	if (fcntl(pipe_d2[1], F_SETFD, fd_flags | FD_CLOEXEC) == -1) {
++		dprintf(D_ALWAYS, "my_popenv: Failed to set new fd flags: errno=%d (%s)\n", errno, strerror(errno));
++		close( pipe_d[0] );
++		close( pipe_d[1] );
++		close( pipe_d2[0] );
++		close( pipe_d2[1] );
++		return NULL;
++	}
++
+ 		/* Create a new process */
+ 	if( (pid=fork()) < 0 ) {
+ 		dprintf(D_ALWAYS, "my_popenv: Failed to fork child, errno=%d (%s)\n",
+@@ -319,11 +346,14 @@ my_popenv_impl( const char *const args[],
+ 			/* Clean up file descriptors */
+ 		close( pipe_d[0] );
+ 		close( pipe_d[1] );
++		close( pipe_d2[0] );
++		close( pipe_d2[1] );
+ 		return NULL;
+ 	}
+ 
+ 		/* The child */
+ 	if( pid == 0 ) {
++		close(pipe_d2[0]);
+ 
+ 		if( parent_reads ) {
+ 				/* Close stdin, dup pipe to stdout */
+@@ -394,10 +424,36 @@ my_popenv_impl( const char *const args[],
+ 			execvp(cmd.Value(), const_cast<char *const*>(args) );
+ 		}
+ 
+-		_exit( ENOEXEC );		/* This isn't safe ... */
++			/* If we get here, inform the parent of our errno */
++		char result_buf[10];
++		int len = snprintf(result_buf, 10, "%d", errno);
++		write(pipe_d2[1], result_buf, len);
++
++		_exit( errno );
+ 	}
+ 
+ 		/* The parent */
++		/* First, wait until the exec is called - determine status */
++	close(pipe_d2[1]);
++	int exit_code;
++	FILE *fh;
++	if ((fh = fdopen(pipe_d2[0], "r")) == NULL) {
++		dprintf(D_ALWAYS, "my_popenv: Failed to reopen file descriptor as file handle: errno=%d (%s)", errno, strerror(errno));
++		close(pipe_d2[0]);
++		close(pipe_d[0]);
++		close(pipe_d[1]);
++		return NULL;
++	}
++		/* Handle case where exec fails */
++	if (fscanf(fh, "%d", &exit_code) == 1) {
++		fclose(fh);
++		close(pipe_d[0]);
++		close(pipe_d[1]);
++		errno = exit_code;
++		return NULL;
++	}
++	fclose(fh);
++
+ 	if( parent_reads ) {
+ 		close( pipe_d[WRITE_END] );
+ 		retp = fdopen(pipe_d[READ_END],mode);


More information about the scm-commits mailing list