]> git.saurik.com Git - apple/security.git/blobdiff - SecurityServer/Authorization/trampolineClient.cpp
Security-222.tar.gz
[apple/security.git] / SecurityServer / Authorization / trampolineClient.cpp
diff --git a/SecurityServer/Authorization/trampolineClient.cpp b/SecurityServer/Authorization/trampolineClient.cpp
deleted file mode 100644 (file)
index b17aebe..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- * 
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- * 
- * This Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
- * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
- * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
- * specific language governing rights and limitations under the License.
- */
-
-
-//
-// trampolineClient - Authorization trampoline client-side implementation
-//
-#include <sys/types.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <Security/Authorization.h>
-#include <Security/debugging.h>
-
-//
-// Where is the trampoline itself?
-//
-#if !defined(TRAMPOLINE)
-# define TRAMPOLINE "/System/Library/CoreServices/AuthorizationTrampoline" /* fallback */
-#endif
-
-
-//
-// A few names for clarity's sake
-//
-enum {
-       READ = 0,               // read end of standard UNIX pipe
-       WRITE = 1               // write end of standard UNIX pipe
-};
-
-
-//
-// Local (static) functions
-//
-static const char **argVector(const char *trampoline,
-       const char *tool, const char *commFd,
-       char *const *arguments);
-
-
-//
-// The public client API function.
-//
-OSStatus AuthorizationExecuteWithPrivileges(AuthorizationRef authorization,
-       const char *pathToTool,
-       unsigned long flags,
-       char *const *arguments,
-       FILE **communicationsPipe)
-{
-       // flags are currently reserved
-       if (flags != 0)
-               return errAuthorizationInvalidFlags;
-
-       // externalize the authorization
-       AuthorizationExternalForm extForm;
-       if (OSStatus err = AuthorizationMakeExternalForm(authorization, &extForm))
-               return err;
-
-    // create the mailbox file
-    FILE *mbox = tmpfile();
-    if (!mbox)
-        return errAuthorizationInternal;
-    if (fwrite(&extForm, sizeof(extForm), 1, mbox) != 1) {
-        fclose(mbox);
-        return errAuthorizationInternal;
-    }
-    fflush(mbox);
-    
-    // make text representation of the temp-file descriptor
-    char mboxFdText[20];
-    snprintf(mboxFdText, sizeof(mboxFdText), "auth %d", fileno(mbox));
-    
-       // make a notifier pipe
-       int notify[2];
-       if (pipe(notify)) {
-        fclose(mbox);
-               return errAuthorizationToolExecuteFailure;
-    }
-
-       // make the communications pipe if requested
-       int comm[2];
-       if (communicationsPipe && socketpair(AF_UNIX, SOCK_STREAM, 0, comm)) {
-               close(notify[READ]); close(notify[WRITE]);
-        fclose(mbox);
-               return errAuthorizationToolExecuteFailure;
-       }
-
-       // do the standard forking tango...
-       int delay = 1;
-       for (int n = 5;; n--, delay *= 2) {
-               switch (fork()) {
-               case -1:        // error
-                       if (errno == EAGAIN) {
-                               // potentially recoverable resource shortage
-                               if (n > 0) {
-                                       secdebug("authexec", "resource shortage (EAGAIN), delaying %d seconds", delay);
-                                       sleep(delay);
-                                       continue;
-                               }
-                       }
-                       secdebug("authexec", "fork failed (errno=%d)", errno);
-                       close(notify[READ]); close(notify[WRITE]);
-                       return errAuthorizationToolExecuteFailure;
-
-               default:        // parent
-                       // close foreign side of pipes
-                       close(notify[WRITE]);
-                       if (communicationsPipe)
-                               close(comm[WRITE]);
-                
-            // close mailbox file (child has it open now)
-            fclose(mbox);
-                       
-                       // get status notification from child
-                       OSStatus status;
-                       secdebug("authexec", "parent waiting for status");
-                       switch (IFDEBUG(ssize_t rc =) read(notify[READ], &status, sizeof(status))) {
-                       default:                                // weird result of read: post error
-                               secdebug("authexec", "unexpected read return value %ld", long(rc));
-                               status = errAuthorizationToolEnvironmentError;
-                               // fall through
-                       case sizeof(status):    // read succeeded: child reported an error
-                               secdebug("authexec", "parent received status=%ld", status);
-                               close(notify[READ]);
-                               if (communicationsPipe) { close(comm[READ]); close(comm[WRITE]); }
-                               return status;
-                       case 0:                                 // end of file: exec succeeded
-                               close(notify[READ]);
-                               if (communicationsPipe)
-                                       *communicationsPipe = fdopen(comm[READ], "r+");
-                               secdebug("authexec", "parent resumes (no error)");
-                               return noErr;
-                       }
-
-               case 0:         // child
-                       // close foreign side of pipes
-                       close(notify[READ]);
-                       if (communicationsPipe)
-                               close(comm[READ]);
-                       
-                       // fd 1 (stdout) holds the notify write end
-                       dup2(notify[WRITE], 1);
-                       close(notify[WRITE]);
-                       
-                       // fd 0 (stdin) holds either the comm-link write-end or /dev/null
-                       if (communicationsPipe) {
-                               dup2(comm[WRITE], 0);
-                               close(comm[WRITE]);
-                       } else {
-                               close(0);
-                               open("/dev/null", O_RDWR);
-                       }
-                       
-                       // where is the trampoline?
-#if defined(NDEBUG)
-                       const char *trampoline = TRAMPOLINE;
-#else //!NDEBUG
-                       const char *trampoline = getenv("AUTHORIZATIONTRAMPOLINE");
-                       if (!trampoline)
-                               trampoline = TRAMPOLINE;
-#endif //NDEBUG
-
-                       // okay, execute the trampoline
-                       secdebug("authexec", "child exec(%s:%s)",
-                               trampoline, pathToTool);
-                       if (const char **argv = argVector(trampoline, pathToTool, mboxFdText, arguments))
-                               execv(trampoline, (char *const*)argv);
-                       secdebug("authexec", "trampoline exec failed (errno=%d)", errno);
-
-                       // execute failed - tell the parent
-                       {
-                               OSStatus error = errAuthorizationToolExecuteFailure;
-                               write(1, &error, sizeof(error));
-                               _exit(1);
-                       }
-               }
-       }
-}
-
-
-//
-// Build an argv vector
-//
-static const char **argVector(const char *trampoline, const char *pathToTool,
-       const char *mboxFdText, char *const *arguments)
-{
-       int length = 0;
-       if (arguments) {
-               for (char *const *p = arguments; *p; p++)
-                       length++;
-       }
-       if (const char **args = (const char **)malloc(sizeof(const char *) * (length + 4))) {
-               args[0] = trampoline;
-               args[1] = pathToTool;
-               args[2] = mboxFdText;
-               if (arguments)
-                       for (int n = 0; arguments[n]; n++)
-                               args[n + 3] = arguments[n];
-               args[length + 3] = NULL;
-               return args;
-       }
-       return NULL;
-}