2 * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
28 #include <security_utilities/logging.h>
29 #include <security_utilities/debugging.h>
30 #include <security_agent_client/sa_request.h>
31 #include <security_agent_client/utils.h>
32 #include <bsm/audit.h>
33 #include <bootstrap_priv.h>
37 #include <sys/types.h>
38 #include <sys/sysctl.h>
42 static pthread_once_t agent_cred_init
= PTHREAD_ONCE_INIT
;
43 static gid_t agent_gid
= 92;
44 static uid_t agent_uid
= 92;
46 void initialize_agent_creds()
48 struct passwd
*agentUser
= getpwnam("securityagent");
51 agent_uid
= agentUser
->pw_uid
;
52 agent_gid
= agentUser
->pw_gid
;
57 AuthHostInstance::AuthHostInstance(Session
&session
, AuthHostType host
) :
60 secdebug("authhost", "authhost born (%p)", this);
62 session
.addReference(*this);
63 if (host
== securityAgent
)
64 pthread_once(&agent_cred_init
, initialize_agent_creds
);
67 AuthHostInstance::~AuthHostInstance()
69 secdebug("authhost", "authhost died (%p)", this);
72 Session
&AuthHostInstance::session() const
74 return referent
<Session
>();
77 bool AuthHostInstance::inDarkWake()
79 return session().server().inDarkWake();
83 AuthHostInstance::childAction()
85 // switch to desired session
86 CommonCriteria::AuditInfo
&audit
= this->session().auditInfo();
87 audit
.get(audit
.sessionId());
89 //this->session().auditInfo().set();
91 // Setup the environment for the SecurityAgent
96 // close down any files that might have been open at this point
97 int maxDescriptors
= getdtablesize ();
100 int devnull
= open(_PATH_DEVNULL
, O_RDWR
, 0);
101 if (devnull
>= 0) for (i
= 0; i
< 3; ++i
)
106 for (i
= 3; i
< maxDescriptors
; ++i
)
111 // construct path to SecurityAgent
112 char agentExecutable
[PATH_MAX
+ 1];
113 const char *path
= getenv("SECURITYAGENT");
115 path
= "/System/Library/CoreServices/SecurityAgent.app";
116 secdebug("adhoc", "hostType = %d", mHostType
);
118 if ((mHostType
== userAuthHost
) || (mHostType
== privilegedAuthHost
))
120 snprintf(agentExecutable
, sizeof(agentExecutable
), "%s/Contents/Resources/authorizationhost", path
);
121 secdebug("AuthHostInstance", "execl(%s)", agentExecutable
);
122 execl(agentExecutable
, agentExecutable
, NULL
);
126 snprintf(agentExecutable
, sizeof(agentExecutable
), "%s/Contents/MacOS/SecurityAgent", path
);
128 pid_t pid
= getpid();
130 sysctlbyname("vfs.generic.noremotehang", NULL
, NULL
, &pid
, sizeof(pid
)))
131 syslog(LOG_ERR
, "Failed to set vfs.generic.noremotehang for pid(%d)", pid
);
133 setgroups(1, &agent_gid
);
137 secdebug("AuthHostInstance", "execl(%s) as user (%d,%d)", agentExecutable
, agent_uid
, agent_gid
);
138 execl(agentExecutable
, agentExecutable
, NULL
);
141 secdebug("AuthHostInstance", "execl failed, errno=%d", errno
);
142 // Unconditional suicide follows.
146 // @@@ these definitions and the logic in lookup() should move into
148 #define SECURITYAGENT_BOOTSTRAP_NAME_BASE "com.apple.SecurityAgent"
149 #define AUTHORIZATIONHOST_BOOTSTRAP_NAME_BASE "com.apple.authorizationhost"
152 AuthHostInstance::lookup(SessionId jobId
)
154 StLock
<Mutex
> _(*this);
156 mach_port_t pluginhostPort
= MACH_PORT_NULL
;
157 kern_return_t result
;
158 const char *serviceName
;
159 /* PR-7483709 const */ uuid_t instanceId
= UUID_INITIALIZER_FROM_SESSIONID(jobId
);
162 if ((mHostType
== securityAgent
)) {
163 if (!(session().attributes() & sessionHasGraphicAccess
))
164 CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION
);
166 CssmError::throwMe(CSSM_ERRCODE_IN_DARK_WAKE
);
169 if (mHostType
== securityAgent
)
170 serviceName
= SECURITYAGENT_BOOTSTRAP_NAME_BASE
;
172 serviceName
= AUTHORIZATIONHOST_BOOTSTRAP_NAME_BASE
;
174 secdebug("AuthHostInstance", "looking up %s instance %s", serviceName
,
175 uuid_to_string(instanceId
, s
)); // XXX/gh debugging
176 if ((result
= bootstrap_look_up3(bootstrap_port
, serviceName
,
177 &pluginhostPort
, 0, instanceId
, BOOTSTRAP_SPECIFIC_INSTANCE
)) != KERN_SUCCESS
) {
179 Syslog::error("error %d looking up %s instance %s", result
, serviceName
,
180 uuid_to_string(instanceId
, s
));
182 secdebug("AuthHostInstance", "port = %x", (unsigned int)pluginhostPort
);
184 return pluginhostPort
;
187 Port
AuthHostInstance::activate()
189 StLock
<Mutex
> _(*this);
190 if (state() != alive
)
192 if ((mHostType
== securityAgent
)) {
193 if (!(session().attributes() & sessionHasGraphicAccess
))
194 CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION
);
196 CssmError::throwMe(CSSM_ERRCODE_IN_DARK_WAKE
);
200 switch (ServerChild::state()) {
202 secdebug("AuthHostInstance", "%p (pid %d) has launched", this, pid());
205 secdebug("AuthHostInstance", "%p (pid %d) failed on startup", this, pid());
213 CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION
);
215 return servicePort();