]> git.saurik.com Git - apple/securityd.git/blobdiff - src/authhost.cpp
securityd-55199.3.tar.gz
[apple/securityd.git] / src / authhost.cpp
index a35edf12817e40c7619077851b3db8fd7c940e57..049b04f0ff984b4956b4d342d74b7292e13b5b79 100644 (file)
 #include <fcntl.h>
 #include "authhost.h"
 #include "server.h"
+#include <security_utilities/logging.h>
+#include <security_utilities/debugging.h>
+#include <security_agent_client/sa_request.h>
+#include <security_agent_client/utils.h>
+#include <bsm/audit.h>
+#include <bootstrap_priv.h>
 
 #include <grp.h>
 #include <pwd.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <syslog.h>
+#include <pthread.h>
 
+static pthread_once_t agent_cred_init = PTHREAD_ONCE_INIT; 
+static gid_t agent_gid = 92;
+static uid_t agent_uid = 92;
 
+void initialize_agent_creds()
+{
+    struct passwd *agentUser = getpwnam("securityagent");
+    if (agentUser)
+    {
+        agent_uid = agentUser->pw_uid;
+        agent_gid = agentUser->pw_gid;
+        endpwent();
+    }
+}
+  
 AuthHostInstance::AuthHostInstance(Session &session, AuthHostType host) :
        mHostType(host)
 {
        secdebug("authhost", "authhost born (%p)", this);
        referent(session);
        session.addReference(*this);
+    if (host == securityAgent)
+        pthread_once(&agent_cred_init, initialize_agent_creds); 
 }
 
 AuthHostInstance::~AuthHostInstance()
 { 
        secdebug("authhost", "authhost died (%p)", this);
-       
-       // clean up
-       servicePort ().destroy ();
 }
 
 Session &AuthHostInstance::session() const
@@ -51,9 +74,20 @@ Session &AuthHostInstance::session() const
        return referent<Session>();
 }
 
+bool AuthHostInstance::inDarkWake()
+{
+       return session().server().inDarkWake();
+}
+
 void
 AuthHostInstance::childAction()
 {
+       // switch to desired session
+       CommonCriteria::AuditInfo &audit = this->session().auditInfo();
+       audit.get(audit.sessionId());
+       audit.set();
+       //this->session().auditInfo().set();
+
        // Setup the environment for the SecurityAgent
        unsetenv("USER");
        unsetenv("LOGNAME");
@@ -79,11 +113,11 @@ AuthHostInstance::childAction()
        const char *path = getenv("SECURITYAGENT");
        if (!path)
                path = "/System/Library/CoreServices/SecurityAgent.app";
+       secdebug("adhoc", "hostType = %d", mHostType);
 
        if ((mHostType == userAuthHost) || (mHostType == privilegedAuthHost))
        {
                snprintf(agentExecutable, sizeof(agentExecutable), "%s/Contents/Resources/authorizationhost", path);
-       
                secdebug("AuthHostInstance", "execl(%s)", agentExecutable);
                execl(agentExecutable, agentExecutable, NULL);
        }
@@ -91,69 +125,76 @@ AuthHostInstance::childAction()
        {
                snprintf(agentExecutable, sizeof(agentExecutable), "%s/Contents/MacOS/SecurityAgent", path);
 
-               struct group *agentGroup = getgrnam("securityagent");
-               gid_t agentGID = static_cast<gid_t>(-2);
-               if (agentGroup)
-               {
-                       agentGID = agentGroup->gr_gid;
-                       endgrent();
-               }
+               pid_t pid = getpid();
+               if ((pid <= 0) ||
+            sysctlbyname("vfs.generic.noremotehang", NULL, NULL, &pid, sizeof(pid)))
+                               syslog(LOG_ERR, "Failed to set vfs.generic.noremotehang for pid(%d)", pid);
 
-               struct passwd *agentUser = getpwnam("securityagent");
-               uid_t agentUID = static_cast<uid_t>(-2);
-               if (agentUser)
-               {
-                       agentUID = agentUser->pw_uid;
-                       endpwent();
-               }
+               setgroups(1, &agent_gid);
+               setgid(agent_gid);
+               setuid(agent_uid);
 
-               setuid(agentUID);
-               setgid(agentGID);
-       
-               CFRef<CFDataRef> userPrefs(session().copyUserPrefs());
-               
-               FILE *mbox = tmpfile();
-               
-               if (userPrefs && mbox)
-               {
-                       if (fwrite(CFDataGetBytePtr(userPrefs), CFDataGetLength(userPrefs), 1, mbox) != 1)
-                               fclose(mbox);
-                       else
-                       {
-                               char mboxFdString[20];
-                               fflush(mbox);
-                               if ((int)sizeof(mboxFdString) > snprintf(mboxFdString, sizeof(mboxFdString), "%d", fileno(mbox)))
-                                       setenv("SECURITYAGENT_USERPREFS_FD", mboxFdString, 1);
-                       }
-               }
-               
-               secdebug("AuthHostInstance", "execl(%s) as user (%d,%d)", agentExecutable, agentUID, agentGID);
+               secdebug("AuthHostInstance", "execl(%s) as user (%d,%d)", agentExecutable, agent_uid, agent_gid);
                execl(agentExecutable, agentExecutable, NULL);
        }
 
        secdebug("AuthHostInstance", "execl failed, errno=%d", errno);
        // Unconditional suicide follows.
-       // See comments below on why we can't use abort()
-#if 1
        _exit(1);
-#else
-       // NOTE: OS X abort() is implemented as kill(getuid()), which fails
-       // for a setuid-root process that has setuid'd. Go back to root to die...
-       setuid(0);
-       abort();
-#endif
 }
 
-Port
-AuthHostInstance::activate()
+// @@@  these definitions and the logic in lookup() should move into 
+// libsecurity_agent
+#define SECURITYAGENT_BOOTSTRAP_NAME_BASE       "com.apple.SecurityAgent"
+#define AUTHORIZATIONHOST_BOOTSTRAP_NAME_BASE   "com.apple.authorizationhost"
+
+mach_port_t
+AuthHostInstance::lookup(SessionId jobId)
+{
+    StLock<Mutex> _(*this);
+    
+    mach_port_t pluginhostPort = MACH_PORT_NULL;
+    kern_return_t result;
+    const char *serviceName;
+    /* PR-7483709 const */ uuid_t instanceId = UUID_INITIALIZER_FROM_SESSIONID(jobId);
+    uuid_string_t s;
+
+    if ((mHostType == securityAgent)) {
+       if (!(session().attributes() & sessionHasGraphicAccess))
+           CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION);
+       if (inDarkWake())
+           CssmError::throwMe(CSSM_ERRCODE_IN_DARK_WAKE);
+    }
+    
+    if (mHostType == securityAgent)
+       serviceName = SECURITYAGENT_BOOTSTRAP_NAME_BASE;
+    else
+       serviceName = AUTHORIZATIONHOST_BOOTSTRAP_NAME_BASE;
+
+    secdebug("AuthHostInstance", "looking up %s instance %s", serviceName,
+      uuid_to_string(instanceId, s)); // XXX/gh  debugging
+    if ((result = bootstrap_look_up3(bootstrap_port, serviceName,
+      &pluginhostPort, 0, instanceId, BOOTSTRAP_SPECIFIC_INSTANCE)) != KERN_SUCCESS) {
+
+        Syslog::error("error %d looking up %s instance %s", result, serviceName,
+         uuid_to_string(instanceId, s));
+    } else
+       secdebug("AuthHostInstance", "port = %x", (unsigned int)pluginhostPort);
+
+    return pluginhostPort;
+}
+
+Port AuthHostInstance::activate()
 {
        StLock<Mutex> _(*this);
        if (state() != alive)
        {
-               if (!(session().attributes() & sessionHasGraphicAccess))
+               if ((mHostType == securityAgent)) {
+                   if (!(session().attributes() & sessionHasGraphicAccess))
                        CssmError::throwMe(CSSM_ERRCODE_NO_USER_INTERACTION);
-
-               Security::MachPlusPlus::StBootstrap bootSaver(session().bootstrapPort());
+                   if (inDarkWake())
+                       CssmError::throwMe(CSSM_ERRCODE_IN_DARK_WAKE);
+               }
 
                fork();
                switch (ServerChild::state()) {