Revision: 23864 http://trac.macosforge.org/projects/launchd/changeset/23864 Author: dsorresso@apple.com Date: 2009-03-24 10:50:41 -0700 (Tue, 24 Mar 2009) Log Message: ----------- <rdar://problem/6682029> 10A295: rpc.statd launchd job submission succeeds but returns EACCES? Modified Paths: -------------- trunk/launchd/src/launchctl.c trunk/launchd/src/launchd_core_logic.c trunk/launchd/src/liblaunch.c Modified: trunk/launchd/src/launchctl.c =================================================================== --- trunk/launchd/src/launchctl.c 2009-03-18 01:41:53 UTC (rev 23863) +++ trunk/launchd/src/launchctl.c 2009-03-24 17:50:41 UTC (rev 23864) @@ -2410,6 +2410,8 @@ case ESRCH: fprintf(stderr, "%s: %s\n", lab4job, "Not loaded"); break; + case ENEEDAUTH: + fprintf(stderr, "%s: %s\n", lab4job, "Could not set security session"); default: fprintf(stderr, "%s: %s\n", lab4job, strerror(e)); case 0: Modified: trunk/launchd/src/launchd_core_logic.c =================================================================== --- trunk/launchd/src/launchd_core_logic.c 2009-03-18 01:41:53 UTC (rev 23863) +++ trunk/launchd/src/launchd_core_logic.c 2009-03-24 17:50:41 UTC (rev 23864) @@ -1562,6 +1562,10 @@ return NULL; } + /* Since jobs are effectively stalled until they get security sessions assigned + * to them, we may wish to reconsider this behavior of calling the job "enabled" + * as far as other jobs with the OtherJobEnabled KeepAlive criterion set. + */ job_dispatch_curious_jobs(j); return job_dispatch(j, false); } @@ -1576,7 +1580,7 @@ ja = alloca(c * sizeof(job_t)); for (i = 0; i < c; i++) { - if (likely(ja[i] = jobmgr_import2(root_jobmgr, launch_data_array_get_index(pload, i)))) { + if( (likely(ja[i] = jobmgr_import2(root_jobmgr, launch_data_array_get_index(pload, i)))) && errno != ENEEDAUTH ) { errno = 0; } launch_data_array_set_index(resp, launch_data_new_errno(errno), i); @@ -2251,6 +2255,7 @@ uuid_unparse(j->expected_audit_uuid, uuid_str); job_log(j, LOG_DEBUG, "Imported job. Waiting for session for UUID %s.", uuid_str); LIST_INSERT_HEAD(&s_needing_sessions, j, needing_session_sle); + errno = ENEEDAUTH; } else { job_log(j, LOG_DEBUG, "No security session specified."); j->audit_session = MACH_PORT_NULL; Modified: trunk/launchd/src/liblaunch.c =================================================================== --- trunk/launchd/src/liblaunch.c 2009-03-18 01:41:53 UTC (rev 23863) +++ trunk/launchd/src/liblaunch.c 2009-03-24 17:50:41 UTC (rev 23864) @@ -982,6 +982,10 @@ } pthread_once(&_lc_once, launch_client_init); + if (!_lc) { + errno = ENOTCONN; + return NULL; + } #if !TARGET_OS_EMBEDDED uuid_t uuid; @@ -1023,11 +1027,6 @@ } #endif - if (!_lc) { - errno = ENOTCONN; - return NULL; - } - pthread_mutex_lock(&_lc->mtx); if (d && launchd_msg_send(_lc->l, d) == -1) { @@ -1061,22 +1060,38 @@ out: #if !TARGET_OS_EMBEDDED if( !uuid_is_null(uuid) && resp && jobs_that_need_sessions > 0 ) { - mach_port_t session = MACH_PORT_NULL; - if( (launch_data_get_type(resp) == LAUNCH_DATA_ERRNO && launch_data_get_errno(resp) == 0) || launch_data_get_type(resp) == LAUNCH_DATA_ARRAY ) { - session = _audit_session_self(); + mach_port_t session_port = _audit_session_self(); + launch_data_type_t resp_type = launch_data_get_type(resp); + + bool set_session = false; + if( resp_type == LAUNCH_DATA_ERRNO ) { + set_session = ( launch_data_get_errno(resp) == ENEEDAUTH ); + } else if( resp_type == LAUNCH_DATA_ARRAY ) { + set_session = true; } - + kern_return_t kr = KERN_FAILURE; + if( set_session ) { + kr = vproc_mig_set_security_session(bootstrap_port, uuid, session_port); + } - /* If we can't get our own session, set the sessions for our recently-submitted jobs - * to MACH_PORT_NULL. - */ - kr = vproc_mig_set_security_session(bootstrap_port, uuid, session); - - if( kr != KERN_SUCCESS || session == MACH_PORT_NULL ) { - launch_data_set_errno(resp, EACCES); - _vproc_log_error(LOG_WARNING, "Could not set security session for recently submitted jobs!"); + if( kr == KERN_SUCCESS ) { + if( resp_type == LAUNCH_DATA_ERRNO ) { + launch_data_set_errno(resp, 0); + } else { + size_t i = 0; + for( i = 0; i < launch_data_array_get_count(resp); i++ ) { + launch_data_t ri = launch_data_array_get_index(resp, i); + + int recvd_err = 0; + if( launch_data_get_type(ri) == LAUNCH_DATA_ERRNO && (recvd_err = launch_data_get_errno(ri)) ) { + launch_data_set_errno(ri, recvd_err == ENEEDAUTH ? 0 : recvd_err); + } + } + } } + + mach_port_deallocate(mach_task_self(), session_port); } #endif