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
>();
78 AuthHostInstance::childAction()
80 // switch to desired session
81 CommonCriteria::AuditInfo
&audit
= this->session().auditInfo();
82 audit
.get(audit
.sessionId());
84 //this->session().auditInfo().set();
86 // Setup the environment for the SecurityAgent
91 // close down any files that might have been open at this point
92 int maxDescriptors
= getdtablesize ();
95 int devnull
= open(_PATH_DEVNULL
, O_RDWR
, 0);
96 if (devnull
>= 0) for (i
= 0; i
< 3; ++i
)
101 for (i
= 3; i
< maxDescriptors
; ++i
)
106 // construct path to SecurityAgent
107 char agentExecutable
[PATH_MAX
+ 1];
108 const char *path
= getenv("SECURITYAGENT");
110 path
= "/System/Library/CoreServices/SecurityAgent.app";
111 secdebug("adhoc", "hostType = %d", mHostType
);
113 if ((mHostType
== userAuthHost
) || (mHostType
== privilegedAuthHost
))
115 snprintf(agentExecutable
, sizeof(agentExecutable
), "%s/Contents/Resources/authorizationhost", path
);
116 secdebug("AuthHostInstance", "execl(%s)", agentExecutable
);
117 execl(agentExecutable
, agentExecutable
, NULL
);
121 snprintf(agentExecutable
, sizeof(agentExecutable
), "%s/Contents/MacOS/SecurityAgent", path
);
123 pid_t pid
= getpid();
125 sysctlbyname("vfs.generic.noremotehang", NULL
, NULL
, &pid
, sizeof(pid
)))
126 syslog(LOG_ERR
, "Failed to set vfs.generic.noremotehang for pid(%d)", pid
);
128 setgroups(1, &agent_gid
);
132 secdebug("AuthHostInstance", "execl(%s) as user (%d,%d)", agentExecutable
, agent_uid
, agent_gid
);
133 execl(agentExecutable
, agentExecutable
, NULL
);
136 secdebug("AuthHostInstance", "execl failed, errno=%d", errno
);
137 // Unconditional suicide follows.
141 // @@@ these definitions and the logic in lookup() should move into
143 #define SECURITYAGENT_BOOTSTRAP_NAME_BASE "com.apple.SecurityAgent"
144 #define AUTHORIZATIONHOST_BOOTSTRAP_NAME_BASE "com.apple.authorizationhost"
147 AuthHostInstance::lookup(SessionId jobId
)
149 StLock
<Mutex
> _(*this);
151 mach_port_t pluginhostPort
= MACH_PORT_NULL
;
152 kern_return_t result
;
153 const char *serviceName
;
154 /* PR-7483709 const */ uuid_t instanceId
= UUID_INITIALIZER_FROM_SESSIONID(jobId
);
157 if ((mHostType
== securityAgent
) &&
158 !(session().attributes() & sessionHasGraphicAccess
))
159 CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION
);
161 if (mHostType
== securityAgent
)
162 serviceName
= SECURITYAGENT_BOOTSTRAP_NAME_BASE
;
164 serviceName
= AUTHORIZATIONHOST_BOOTSTRAP_NAME_BASE
;
166 secdebug("AuthHostInstance", "looking up %s instance %s", serviceName
,
167 uuid_to_string(instanceId
, s
)); // XXX/gh debugging
168 if ((result
= bootstrap_look_up3(bootstrap_port
, serviceName
,
169 &pluginhostPort
, 0, instanceId
, BOOTSTRAP_SPECIFIC_INSTANCE
)) != KERN_SUCCESS
) {
171 Syslog::error("error %d looking up %s instance %s", result
, serviceName
,
172 uuid_to_string(instanceId
, s
));
174 secdebug("AuthHostInstance", "port = %x", (unsigned int)pluginhostPort
);
176 return pluginhostPort
;
179 Port
AuthHostInstance::activate()
181 StLock
<Mutex
> _(*this);
182 if (state() != alive
)
184 if ((mHostType
== securityAgent
) &&
185 !(session().attributes() & sessionHasGraphicAccess
))
186 CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION
);
189 switch (ServerChild::state()) {
191 secdebug("AuthHostInstance", "%p (pid %d) has launched", this, pid());
194 secdebug("AuthHostInstance", "%p (pid %d) failed on startup", this, pid());
202 CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION
);
204 return servicePort();