1/*
2 * Copyright (c) 2000-2001,2003-2004 Apple Computer, Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25//
26// Exectest - privileged-execution test driver
27//
28#include <Security/Authorization.h>
29#include <unistd.h>
30#include <stdlib.h>
31
32
33void doLoopback(int argc, char *argv[]);
34
35
36int main(int argc, char **argv)
37{
38	const char *path = "/usr/bin/id";
39	bool writeToPipe = false;
40	bool loopback = false;
41
42	int arg;
43	extern char *optarg;
44	extern int optind;
45	while ((arg = getopt(argc, argv, "f:lLw")) != -1) {
46		switch (arg) {
47		case 'f':
48			path = optarg;
49			break;
50		case 'l':
51			loopback = true;
52			break;
53		case 'L':
54			doLoopback(argc, argv);
55			exit(0);
56		case 'w':
57			writeToPipe = true;
58			break;
59		case '?':
60			exit(2);
61		}
62	}
63
64	AuthorizationItem right = { "system.privilege.admin", 0, NULL, 0 };
65	AuthorizationRights rights = { 1, &right };
66
67	AuthorizationRef auth;
68	if (OSStatus error = AuthorizationCreate(&rights, NULL /*env*/,
69		kAuthorizationFlagInteractionAllowed |
70		kAuthorizationFlagExtendRights |
71		kAuthorizationFlagPreAuthorize,
72		&auth)) {
73		printf("create error %ld\n", error);
74		exit(1);
75	}
76
77	if (loopback) {
78		path = argv[0];
79		argv[--optind] = "-L";	// backing over existing array element
80	}
81
82	FILE *f;
83	if (OSStatus error = AuthorizationExecuteWithPrivileges(auth,
84		path, 0, argv + optind, &f)) {
85		printf("exec error %ld\n", error);
86		exit(1);
87	}
88	printf("--- execute successful ---\n");
89	if (writeToPipe) {
90		char buffer[1024];
91		while (fgets(buffer, sizeof(buffer), stdin))
92			fprintf(f, "%s", buffer);
93	} else {
94		char buffer[1024];
95		while (fgets(buffer, sizeof(buffer), f))
96			printf("%s", buffer);
97	}
98	printf("--- end of output ---\n");
99	exit(0);
100}
101
102
103void doLoopback(int argc, char *argv[])
104{
105	// general status
106	printf("Authorization Execution Loopback Test\n");
107	printf("Invoked as");
108	for (int n = 0; argv[n]; n++)
109		printf(" %s", argv[n]);
110	printf("\n");
111
112	// recover the authorization handle
113	AuthorizationRef auth;
114	if (OSStatus err = AuthorizationCopyPrivilegedReference(&auth, 0)) {
115		printf("Cannot recover AuthorizationRef: error=%ld\n", err);
116		exit(1);
117	}
118
119	printf("AuthorizationRef recovered.\n");
120}
121