Revision: 23255 http://trac.macosforge.org/projects/launchd/changeset/23255 Author: zarzycki@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
participants (1)
-
source_changes@macosforge.org