[launchd-changes] [23255] trunk/launchd/src

source_changes at macosforge.org source_changes at macosforge.org
Thu May 17 14:07:39 PDT 2007


Revision: 23255
          http://trac.macosforge.org/projects/launchd/changeset/23255
Author:   zarzycki at apple.com
Date:     2007-05-17 14:07:38 -0700 (Thu, 17 May 2007)

Log Message:
-----------
<rdar://problem/5171032> Leopard9A429: Cannot ssh into my machine

Modified Paths:
--------------
    trunk/launchd/src/launchctl.c
    trunk/launchd/src/launchd_core_logic.c
    trunk/launchd/src/liblaunch.c
    trunk/launchd/src/libvproc.c
    trunk/launchd/src/libvproc_internal.h
    trunk/launchd/src/libvproc_private.h

Modified: trunk/launchd/src/launchctl.c
===================================================================
--- trunk/launchd/src/launchctl.c	2007-05-14 18:32:48 UTC (rev 23254)
+++ trunk/launchd/src/launchctl.c	2007-05-17 21:07:38 UTC (rev 23255)
@@ -1929,7 +1929,7 @@
 }
 
 int
-list_cmd(int argc, char *const argv[] __attribute__((unused)))
+list_cmd(int argc, char *const argv[])
 {
 	launch_data_t resp, msg;
 	int r = 0;

Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c	2007-05-14 18:32:48 UTC (rev 23254)
+++ trunk/launchd/src/launchd_core_logic.c	2007-05-17 21:07:38 UTC (rev 23255)
@@ -244,7 +244,7 @@
 	unsigned int global_on_demand_cnt;
 	unsigned int hopefully_first_cnt;
 	unsigned int normal_active_cnt;
-	unsigned int sent_stop_to_normal_jobs:1, sent_stop_to_hopefully_last_jobs:1, shutting_down:1;
+	unsigned int sent_stop_to_normal_jobs:1, sent_stop_to_hopefully_last_jobs:1, shutting_down:1, session_initialized:1;
 	char name[0];
 };
 
@@ -258,6 +258,7 @@
 static void jobmgr_log_stray_children(jobmgr_t jm);
 static void jobmgr_remove(jobmgr_t jm);
 static void jobmgr_dispatch_all(jobmgr_t jm, bool newmounthack);
+static job_t jobmgr_init_session(jobmgr_t jm, const char *session_type, bool sflag);
 static job_t jobmgr_find_by_pid(jobmgr_t jm, pid_t p, bool create_anon);
 static job_t job_mig_intran2(jobmgr_t jm, mach_port_t mport, pid_t upid);
 static void job_export_all2(jobmgr_t jm, launch_data_t where);
@@ -3752,15 +3753,10 @@
 jobmgr_t 
 jobmgr_new(jobmgr_t jm, mach_port_t requestorport, mach_port_t transfer_port, bool sflag, const char *name)
 {
-	const char *bootstrap_tool[] = { "/bin/launchctl", "bootstrap", "-S", name, NULL, NULL };
 	mach_msg_size_t mxmsgsz;
 	job_t bootstrapper = NULL;
 	jobmgr_t jmr;
 
-	if (sflag) {
-		bootstrap_tool[4] = "-s";
-	}
-
 	launchd_assert(offsetof(struct jobmgr_s, kqjobmgr_callback) == 0);
 
 	if (jm && requestorport == MACH_PORT_NULL) {
@@ -3836,20 +3832,7 @@
 	}
 
 	if (name) {
-		char thelabel[1000];
-
-		snprintf(thelabel, sizeof(thelabel), "com.apple.launchctl.%s", name);
-		/* no name implies: bootstrap_subset() where creating a "bootstrapper" makes no sense */
-		bootstrapper = job_new(jmr, thelabel, NULL, bootstrap_tool);
-		if (jobmgr_assumes(jmr, bootstrapper != NULL) && (jm || getuid())) {
-			char buf[100];
-
-			/* <rdar://problem/5042202> launchd-201: can't ssh in with AFP OD account (hangs) */
-			snprintf(buf, sizeof(buf), "0x%X:0:0", getuid());
-			envitem_new(bootstrapper, "__CF_USER_TEXT_ENCODING", buf, false);
-			bootstrapper->weird_bootstrap = true;
-			jobmgr_assumes(jmr, job_setup_machport(bootstrapper));
-		}
+		bootstrapper = jobmgr_init_session(jmr, name, sflag);
 	}
 
 	if (!bootstrapper || !bootstrapper->weird_bootstrap) {
@@ -3873,6 +3856,30 @@
 	return NULL;
 }
 
+job_t
+jobmgr_init_session(jobmgr_t jm, const char *session_type, bool sflag)
+{
+	const char *bootstrap_tool[] = { "/bin/launchctl", "bootstrap", "-S", session_type, sflag ? "-s" : NULL, NULL };
+	char thelabel[1000];
+	job_t bootstrapper;
+
+	snprintf(thelabel, sizeof(thelabel), "com.apple.launchctl.%s", session_type);
+	bootstrapper = job_new(jm, thelabel, NULL, bootstrap_tool);
+	if (jobmgr_assumes(jm, bootstrapper != NULL) && (jm->parentmgr || getuid())) {
+		char buf[100];
+
+		/* <rdar://problem/5042202> launchd-201: can't ssh in with AFP OD account (hangs) */
+		snprintf(buf, sizeof(buf), "0x%X:0:0", getuid());
+		envitem_new(bootstrapper, "__CF_USER_TEXT_ENCODING", buf, false);
+		bootstrapper->weird_bootstrap = true;
+		jobmgr_assumes(jm, job_setup_machport(bootstrapper));
+	}
+
+	jm->session_initialized = true;
+
+	return bootstrapper;
+}
+
 jobmgr_t
 jobmgr_delete_anything_with_port(jobmgr_t jm, mach_port_t port)
 {
@@ -4871,20 +4878,19 @@
 		return BOOTSTRAP_NO_MEMORY;
 	}
 
+	job_log(j, LOG_DEBUG, "Looking up per user launchd for UID: %u", which_user);
+
+	runtime_get_caller_creds(&ldc);
+
 	if (getpid() != 1) {
+		job_log(j, LOG_ERR, "Only PID 1 supports per user launchd lookups.");
 		return BOOTSTRAP_NOT_PRIVILEGED;
 	}
 
-	runtime_get_caller_creds(&ldc);
-
 	if (ldc.euid || ldc.uid) {
 		which_user = ldc.euid ? ldc.euid : ldc.uid;
 	}
 
-	if (which_user == 0) {
-		return BOOTSTRAP_NOT_PRIVILEGED;
-	}
-
 	*up_cont = MACH_PORT_NULL;
 
 	LIST_FOREACH(ji, &root_jobmgr->jobs, sle) {
@@ -4907,6 +4913,8 @@
 		struct machservice *ms;
 		char lbuf[1024];
 
+		job_log(j, LOG_DEBUG, "Creating per user launchd job for UID: %u", which_user);
+
 		sprintf(lbuf, "com.apple.launchd.peruser.%u", which_user);
 
 		ji = job_new(root_jobmgr, lbuf, "/sbin/launchd", NULL);
@@ -4927,6 +4935,8 @@
 		ms->hide = true;
 
 		ji = job_dispatch(ji, false);
+	} else {
+		job_log(j, LOG_DEBUG, "Per user launchd job found for UID: %u", which_user);
 	}
 
 	if (job_assumes(j, ji != NULL)) {
@@ -5238,37 +5248,45 @@
 	mach_port_array_t l2l_ports = NULL;
 	mach_port_t reqport, rcvright;
 	kern_return_t kr = 1;
+	struct ldcred ldc;
 	jobmgr_t jmr = NULL;
-	job_t j2;
 
-	if (getuid() == 0) {
-		const char *bootstrap_tool[] = { "/bin/launchctl", "bootstrap", "-S", session_type, NULL };
-		char thelabel[1000];
-		job_t bootstrapper;
+	if (!launchd_assumes(j != NULL)) {
+		return BOOTSTRAP_NO_MEMORY;
+	}
 
-		snprintf(thelabel, sizeof(thelabel), "com.apple.launchctl.%s", session_type);
+	runtime_get_caller_creds(&ldc);
 
-		job_assumes(j, (j2 = job_mig_intran(target_subset)) != NULL);
-		j = j2;
+	if (target_subset == MACH_PORT_NULL) {
+		job_t j2;
+
+		if (j->mgr->session_initialized) {
+			job_log(j, LOG_ERR, "Tried to initialize an already setup session!");
+			kr = BOOTSTRAP_NOT_PRIVILEGED;
+			goto out;
+		}
+
 		jobmgr_log(j->mgr, LOG_DEBUG, "Renaming to: %s", session_type);
 		strcpy(j->mgr->name, session_type);
 
-		bootstrapper = job_new(j->mgr, thelabel, NULL, bootstrap_tool);
-		if (job_assumes(j, bootstrapper != NULL)) {
-			job_dispatch(bootstrapper, true);
+		if (job_assumes(j, (j2 = jobmgr_init_session(j->mgr, session_type, false)))) {
+			job_assumes(j, job_dispatch(j2, true));
 		}
 
 		kr = 0;
 		goto out;
-	}
+	} else if (job_mig_intran2(root_jobmgr, target_subset, ldc.pid)) {
+		job_log(j, LOG_ERR, "Moving a session to ourself is bogus.");
 
-	/* We call job_mig_intran2 because job_mig_intran logs on failure */
-	if (getpid() != 1 && job_mig_intran2(root_jobmgr, target_subset, getpid())) {
-		kr = 0;
+		kr = BOOTSTRAP_NOT_PRIVILEGED;
 		goto out;
 	}
 
-	if (!job_assumes(j, (kr = _vproc_grab_subset(target_subset, &reqport, &rcvright, &l2l_names, &l2l_name_cnt, &l2l_pids, &l2l_pid_cnt, &l2l_ports, &l2l_port_cnt)) == 0)) {
+	job_log(j, LOG_DEBUG, "Move subset attempt: 0x%x", target_subset);
+
+	kr = _vproc_grab_subset(target_subset, &reqport, &rcvright, &l2l_names, &l2l_name_cnt, &l2l_pids, &l2l_pid_cnt, &l2l_ports, &l2l_port_cnt);
+
+	if (!job_assumes(j, kr == 0)) {
 		goto out;
 	}
 
@@ -5308,7 +5326,9 @@
 	}
 
 	if (kr == 0) {
-		job_assumes(j, launchd_mport_deallocate(target_subset) == KERN_SUCCESS);
+		if (target_subset) {
+			job_assumes(j, launchd_mport_deallocate(target_subset) == KERN_SUCCESS);
+		}
 	} else if (jmr) {
 		jobmgr_shutdown(jmr);
 	}

Modified: trunk/launchd/src/liblaunch.c
===================================================================
--- trunk/launchd/src/liblaunch.c	2007-05-14 18:32:48 UTC (rev 23254)
+++ trunk/launchd/src/liblaunch.c	2007-05-17 21:07:38 UTC (rev 23255)
@@ -1204,7 +1204,7 @@
 void
 load_launchd_jobs_at_loginwindow_prompt(int flags __attribute__((unused)), ...)
 {
-	_vprocmgr_move_subset_to_user(geteuid() ? geteuid() : getuid(), "LoginWindow");
+	_vprocmgr_init("LoginWindow");
 }
 
 pid_t

Modified: trunk/launchd/src/libvproc.c
===================================================================
--- trunk/launchd/src/libvproc.c	2007-05-14 18:32:48 UTC (rev 23254)
+++ trunk/launchd/src/libvproc.c	2007-05-17 21:07:38 UTC (rev 23255)
@@ -30,6 +30,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <unistd.h>
+#include <syslog.h>
 
 #include "liblaunch_public.h"
 #include "liblaunch_private.h"
@@ -65,28 +66,70 @@
 }
 
 vproc_err_t
-_vprocmgr_move_subset_to_user(uid_t target_user, char *session_type)
+_vprocmgr_init(const char *session_type)
 {
+	if (vproc_mig_move_subset(bootstrap_port, MACH_PORT_NULL, (char *)session_type) == 0) {
+		return NULL;
+	}
+
+	return (vproc_err_t)_vprocmgr_init;
+}
+
+vproc_err_t
+_vprocmgr_move_subset_to_user(uid_t target_user, const char *session_type)
+{
 	launch_data_t output_obj;
 	kern_return_t kr = 1;
-	mach_port_t puc = 0, which_port = bootstrap_port;
+	mach_port_t puc = 0, rootbs = get_root_bootstrap_port();
 	bool is_bkgd = (strcmp(session_type, VPROCMGR_SESSION_BACKGROUND) == 0);
+	int64_t ldpid, lduid;
 
-	if (target_user && vproc_mig_lookup_per_user_context(get_root_bootstrap_port(), target_user, &puc) == 0) {
-		which_port = puc;
+	if (vproc_swap_integer(NULL, VPROC_GSK_MGR_PID, 0, &ldpid) != 0) {
+		return (vproc_err_t)_vprocmgr_move_subset_to_user;
 	}
 
+	if (vproc_swap_integer(NULL, VPROC_GSK_MGR_UID, 0, &lduid) != 0) {
+		return (vproc_err_t)_vprocmgr_move_subset_to_user;
+	}
+
+	if (target_user == 0) {
+		if (ldpid == 1 && rootbs != bootstrap_port) {
+			return _vprocmgr_init(session_type);
+		}
+
+		task_set_bootstrap_port(mach_task_self(), rootbs);
+		mach_port_deallocate(mach_task_self(), bootstrap_port);
+		bootstrap_port = rootbs;
+
+		return NULL;
+	}
+
+	if (ldpid != 1) {
+		if (lduid == getuid()) {
+			return NULL;
+		}
+		/*
+		 * Not all sessions can be moved.
+		 * We should clean up this mess someday.
+		 */
+		return (vproc_err_t)_vprocmgr_move_subset_to_user;
+	}
+
+	if (vproc_mig_lookup_per_user_context(rootbs, target_user, &puc) != 0) {
+		return (vproc_err_t)_vprocmgr_move_subset_to_user;
+	}
+
 	if (is_bkgd) {
 		kr = 0;
 	} else {
-		kr = vproc_mig_move_subset(which_port, bootstrap_port, session_type);
+		kr = vproc_mig_move_subset(puc, bootstrap_port, (char *)session_type);
 	}
 
-	if (puc && is_bkgd) {
+	if (is_bkgd) {
 		task_set_bootstrap_port(mach_task_self(), puc);
 		mach_port_deallocate(mach_task_self(), bootstrap_port);
 		bootstrap_port = puc;
-	} else if (puc) {
+	} else {
 		mach_port_deallocate(mach_task_self(), puc);
 	}
 
@@ -308,7 +351,9 @@
 
 	do {
 		if (previous_port) {
-			mach_port_deallocate(mach_task_self(), previous_port);
+			if (previous_port != bootstrap_port) {
+				mach_port_deallocate(mach_task_self(), previous_port);
+			}
 			previous_port = parent_port;
 		} else {
 			previous_port = bootstrap_port;

Modified: trunk/launchd/src/libvproc_internal.h
===================================================================
--- trunk/launchd/src/libvproc_internal.h	2007-05-14 18:32:48 UTC (rev 23254)
+++ trunk/launchd/src/libvproc_internal.h	2007-05-17 21:07:38 UTC (rev 23255)
@@ -39,6 +39,7 @@
 
 #pragma GCC visibility push(default)
 
+vproc_err_t _vprocmgr_init(const char *session_type);
 vproc_err_t _vproc_post_fork_ping(void);
 
 #define SPAWN_HAS_PATH			0x0001

Modified: trunk/launchd/src/libvproc_private.h
===================================================================
--- trunk/launchd/src/libvproc_private.h	2007-05-14 18:32:48 UTC (rev 23254)
+++ trunk/launchd/src/libvproc_private.h	2007-05-17 21:07:38 UTC (rev 23255)
@@ -63,7 +63,7 @@
 #define VPROCMGR_SESSION_STANDARDIO	"StandardIO"
 #define VPROCMGR_SESSION_SYSTEM		"System"
 
-vproc_err_t _vprocmgr_move_subset_to_user(uid_t target_user, char *session_type);
+vproc_err_t _vprocmgr_move_subset_to_user(uid_t target_user, const char *session_type);
 
 #pragma GCC visibility pop
 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/launchd-changes/attachments/20070517/540ff8ef/attachment.html


More information about the launchd-changes mailing list