1 | /*
|
---|
2 | File: MoreSecurity.h
|
---|
3 |
|
---|
4 | Contains: Security utilities.
|
---|
5 |
|
---|
6 | Written by: Quinn
|
---|
7 |
|
---|
8 | Copyright: Copyright (c) 2002 by Apple Computer, Inc., All Rights Reserved.
|
---|
9 |
|
---|
10 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
---|
11 | ("Apple") in consideration of your agreement to the following terms, and your
|
---|
12 | use, installation, modification or redistribution of this Apple software
|
---|
13 | constitutes acceptance of these terms. If you do not agree with these terms,
|
---|
14 | please do not use, install, modify or redistribute this Apple software.
|
---|
15 |
|
---|
16 | In consideration of your agreement to abide by the following terms, and subject
|
---|
17 | to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
|
---|
18 | copyrights in this original Apple software (the "Apple Software"), to use,
|
---|
19 | reproduce, modify and redistribute the Apple Software, with or without
|
---|
20 | modifications, in source and/or binary forms; provided that if you redistribute
|
---|
21 | the Apple Software in its entirety and without modifications, you must retain
|
---|
22 | this notice and the following text and disclaimers in all such redistributions of
|
---|
23 | the Apple Software. Neither the name, trademarks, service marks or logos of
|
---|
24 | Apple Computer, Inc. may be used to endorse or promote products derived from the
|
---|
25 | Apple Software without specific prior written permission from Apple. Except as
|
---|
26 | expressly stated in this notice, no other rights or licenses, express or implied,
|
---|
27 | are granted by Apple herein, including but not limited to any patent rights that
|
---|
28 | may be infringed by your derivative works or by other works in which the Apple
|
---|
29 | Software may be incorporated.
|
---|
30 |
|
---|
31 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
---|
32 | WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
---|
33 | WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
---|
34 | PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
---|
35 | COMBINATION WITH YOUR PRODUCTS.
|
---|
36 |
|
---|
37 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
---|
38 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
---|
39 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
---|
40 | ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
---|
41 | OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
---|
42 | (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
---|
43 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
---|
44 |
|
---|
45 | Change History (most recent first):
|
---|
46 |
|
---|
47 | $Log: MoreSecurity.h,v $
|
---|
48 | Revision 1.5 2003/01/20 07:58:32 eskimo1
|
---|
49 | Corrected some misspellings.
|
---|
50 |
|
---|
51 | Revision 1.4 2002/12/12 17:47:57 eskimo1
|
---|
52 | There should only be one point 5 in the "how to use" comment.
|
---|
53 |
|
---|
54 | Revision 1.3 2002/12/12 15:40:19 eskimo1
|
---|
55 | Eliminate MoreAuthCopyRightCFString because it makes no sense. A helper tool should always have the right name hard-wired into it, and hardwiring a C string is even easier than hardwiring a CFString.
|
---|
56 |
|
---|
57 | Revision 1.2 2002/11/25 16:42:29 eskimo1
|
---|
58 | Significant changes. Handle more edge cases better (for example, volumes with the "ignore permissions" flag turned on). Also brought MoreSecurity more into the CoreServices world.
|
---|
59 |
|
---|
60 | Revision 1.1 2002/11/09 00:08:40 eskimo1
|
---|
61 | First checked in. A module containing security helpers.
|
---|
62 |
|
---|
63 |
|
---|
64 | */
|
---|
65 |
|
---|
66 | #pragma once
|
---|
67 |
|
---|
68 | /////////////////////////////////////////////////////////////////
|
---|
69 |
|
---|
70 | // MoreIsBetter Setup
|
---|
71 |
|
---|
72 | #include "MoreSetup.h"
|
---|
73 |
|
---|
74 | #if !TARGET_RT_MAC_MACHO
|
---|
75 | #error MoreSecurity requires the use of Mach-O
|
---|
76 | #endif
|
---|
77 |
|
---|
78 | // System prototypes
|
---|
79 |
|
---|
80 | #include <Security/Security.h>
|
---|
81 | #include <CoreServices/CoreServices.h>
|
---|
82 |
|
---|
83 | /////////////////////////////////////////////////////////////////
|
---|
84 |
|
---|
85 | #ifdef __cplusplus
|
---|
86 | extern "C" {
|
---|
87 | #endif
|
---|
88 |
|
---|
89 | /////////////////////////////////////////////////////////////////
|
---|
90 | #pragma mark ***** UID Management
|
---|
91 |
|
---|
92 | // Basic utilities to manage your UIDs in setuid root programs.
|
---|
93 |
|
---|
94 | // RUID = real user id = ID of user who is running program
|
---|
95 | // EUID = effective user id = ID used to restrict privileged operations
|
---|
96 | // SUID = saved user id = extra ID to allow setuid programs to switch in and out of privileged mode
|
---|
97 |
|
---|
98 | extern int MoreSecPermanentlySetNonPrivilegedEUID(void);
|
---|
99 | // Relinquish privileges by setting RUID, EUID, and SUID
|
---|
100 | // to the RUID.
|
---|
101 |
|
---|
102 | extern int MoreSecTemporarilySetNonPrivilegedEUID(void);
|
---|
103 | // Set the EUID to the RUID, which means that subsequent
|
---|
104 | // code runs with a non-zero EUID. The process can
|
---|
105 | // still switch back to EUID when needed because the
|
---|
106 | // SUID is still 0.
|
---|
107 |
|
---|
108 | extern int MoreSecSetPrivilegedEUID(void);
|
---|
109 | // Set the EUID to 0. This is only possible if either
|
---|
110 | // the EUID is already 0 or the SUID is 0.
|
---|
111 |
|
---|
112 | // Typical Usage Patterns
|
---|
113 | // ----------------------
|
---|
114 | // #1 -- Do privileged operation and then drop privs
|
---|
115 | //
|
---|
116 | // DoPrivilegedStuff();
|
---|
117 | // MoreSecPermanentlySetNonPrivilegedEUID();
|
---|
118 | // DoNonPrivilegedStuff();
|
---|
119 | //
|
---|
120 | // #2 -- Switch in and out of privileged mode
|
---|
121 | //
|
---|
122 | // MoreSecTemporarilySetNonPrivilegedEUID();
|
---|
123 | // DoNonPrivilegedStuff();
|
---|
124 | // MoreSecSetPrivilegedEUID();
|
---|
125 | // DoPrivilegedStuff();
|
---|
126 | // ... repeat as necessary ...
|
---|
127 | // MoreSecPermanentlySetNonPrivilegedEUID();
|
---|
128 | // DoNonPrivilegedStuff();
|
---|
129 | //
|
---|
130 |
|
---|
131 | /////////////////////////////////////////////////////////////////
|
---|
132 | #pragma mark **** Environment Management
|
---|
133 |
|
---|
134 | // This is a utility routine to destroy any environment that you might have
|
---|
135 | // inherited from your parent. It's most useful in a setuid root program,
|
---|
136 | // which has to be careful that it doesn't rely on untrusted information
|
---|
137 | // that it inherited. Also useful for any privileged program which wants
|
---|
138 | // to execute a non-privileged program and ensure that no privileged
|
---|
139 | // information leaks to that program.
|
---|
140 |
|
---|
141 | // The following is a set of bit masks used for the whatToDubya parameter
|
---|
142 | // of the MoreSecDestroyInheritedEnvironment function.
|
---|
143 |
|
---|
144 | enum {
|
---|
145 | kMoreSecKeepNothingMask = 0x0000,
|
---|
146 |
|
---|
147 | kMoreSecKeepArg0Mask = 0x0001,
|
---|
148 | // if set, don't reset argv[0] to the real
|
---|
149 | // executable path
|
---|
150 | kMoreSecKeepEnvironmentMask = 0x0002,
|
---|
151 | // if set, don't clear environment
|
---|
152 | kMoreSecKeepStandardFilesMask = 0x0004,
|
---|
153 | // if set, don't close stdin, stdout, stderr
|
---|
154 | kMoreSecKeepOtherFilesMask = 0x0008,
|
---|
155 | // if set, don't close other file descriptors
|
---|
156 | kMoreSecKeepSignalsMask = 0x0010,
|
---|
157 | // if set, don't reset signals to default
|
---|
158 | kMoreSecKeepUmaskMask = 0x0020,
|
---|
159 | // if set, don't reset umask
|
---|
160 | kMoreSecKeepNiceMask = 0x0040,
|
---|
161 | // if set, don't reset process nice values
|
---|
162 | kMoreSecKeepResourceLimitsMask = 0x0080,
|
---|
163 | // if set, don't reset resource limits
|
---|
164 | kMoreSecKeepCurrentDirMask = 0x0100,
|
---|
165 | // if set, don't set CWD to "/"
|
---|
166 | kMoreSecKeepTimersMask = 0x0200,
|
---|
167 | // if set, don't reset all interval timers
|
---|
168 |
|
---|
169 | kMoreSecKeepEverythingMask = 0x03FF
|
---|
170 | };
|
---|
171 |
|
---|
172 | extern int MoreSecDestroyInheritedEnvironment(int whatToDubya, const char **argv);
|
---|
173 | // This function eliminates most of the environmental
|
---|
174 | // factors that you have inherited from your parent
|
---|
175 | // process. The function is intended for use by setuid
|
---|
176 | // root programs, who shouldn't trust any information
|
---|
177 | // supplied by a potentially malicious parent process.
|
---|
178 | //
|
---|
179 | // The whatToDubya parameter is a bit mask that
|
---|
180 | // specifies what environmental factors to *keep*. The
|
---|
181 | // most secure option is to pass kMoreSecKeepNothingMask
|
---|
182 | // (ie 0), which means you keep no environmental factors.
|
---|
183 | //
|
---|
184 | // The argv parameter allows the function to access argv
|
---|
185 | // without any special magic. You can pass NULL if you
|
---|
186 | // whatToDubya has kMoreSecKeepArg0Mask set, which
|
---|
187 | // indicates that you don't want to reset argv[0].
|
---|
188 | //
|
---|
189 | // The function returns a errno-style error. If it's
|
---|
190 | // non-zero you probably should err on the side of
|
---|
191 | // caution and refuse to start up.
|
---|
192 |
|
---|
193 | /////////////////////////////////////////////////////////////////
|
---|
194 | #pragma mark **** Helper Tool Big Picture
|
---|
195 |
|
---|
196 | // These utilities let you easily implement a setuid helper tool.
|
---|
197 | // This design is largely stolen from the DTS sample code "AuthSample",
|
---|
198 | // with refinements to cover more cases and allow easy code reuse.
|
---|
199 | //
|
---|
200 | // <http://developer.apple.com/samplecode/Sample_Code/Security/AuthSample.htm>
|
---|
201 | //
|
---|
202 | // To create a setuid root help tool, follow these simple instructions.
|
---|
203 | //
|
---|
204 | // 1. Define a request/response protocol based around CFDictionaries.
|
---|
205 | // This is as simple as defining the set of keys in the request
|
---|
206 | // that describe the operation you want to do, and the set of
|
---|
207 | // keys in the response that hold the results of those operations
|
---|
208 | // (if any).
|
---|
209 | //
|
---|
210 | // 2. Create a helper tool whose "main" function looks like:
|
---|
211 | //
|
---|
212 | // int main(int argc, const char *argv[])
|
---|
213 | // {
|
---|
214 | // int err;
|
---|
215 | // int result;
|
---|
216 | // AuthorizationRef auth;
|
---|
217 | //
|
---|
218 | // auth = MoreSecHelperToolCopyAuthRef();
|
---|
219 | //
|
---|
220 | // err = MoreSecDestroyInheritedEnvironment(kMoreSecKeepStandardFilesMask, argv);
|
---|
221 | // if (err == 0) {
|
---|
222 | // err = MoreUNIXIgnoreSIGPIPE();
|
---|
223 | // }
|
---|
224 | // if (err == 0) {
|
---|
225 | // err = MoreSecHelperToolMain(STDIN_FILENO, STDOUT_FILENO, auth, MyCommandProc, argc, argv);
|
---|
226 | // }
|
---|
227 | //
|
---|
228 | // return MoreSecErrorToHelperToolResult(err);
|
---|
229 | // }
|
---|
230 | //
|
---|
231 | // MyCommandProc is a callback that is executed when a request is
|
---|
232 | // passed to the tool. It can do privileged operations, such as
|
---|
233 | // committing changes to System Configuration framework. Its
|
---|
234 | // parameters are passed to it as a CFDictionary. It can pass results
|
---|
235 | // back to the application by creating a response dictionary.
|
---|
236 | //
|
---|
237 | // 3. Put the tool in the "MacOS" folder inside your application package.
|
---|
238 | // Decide on two tool names, one for the original template tool
|
---|
239 | // (for example, "HelperToolTemplate") and one for the working copy
|
---|
240 | // of the tool (for example, "HelperTool").
|
---|
241 | //
|
---|
242 | // 4. In your application, use MoreSecCopyHelperToolURLAndCheckBundled to find
|
---|
243 | // (or create) the working copy of your tool.
|
---|
244 | //
|
---|
245 | // err = MoreSecCopyHelperToolURLAndCheckBundled(CFBundleGetMainBundle(), CFSTR("HelperToolTemplate"),
|
---|
246 | // kApplicationSupportFolderType, CFSTR("My Application Name"), CFSTR("HelperTool"),
|
---|
247 | // &tool);
|
---|
248 | //
|
---|
249 | // The working copy of the helper tool will exist within the user's
|
---|
250 | // Application Support folder. See the description of
|
---|
251 | // MoreSecCopyHelperToolURLAndCheck[Bundled] for an explanation of this.
|
---|
252 | //
|
---|
253 | // 5. Then use MoreSecExecuteRequestInHelperTool to execute the tool, passing it
|
---|
254 | // a request dictionary. On success, you'll get back a response dictionary. Use
|
---|
255 | // MoreSecGetErrorFromResponse to extract the error result from your tool's
|
---|
256 | // MyCommandProc routine.
|
---|
257 | //
|
---|
258 | // 6. For extra credit, use AuthorizationCopyRights to have your tool
|
---|
259 | // be self-limiting, as described in the Authorization Services docs.
|
---|
260 | //
|
---|
261 | // <http://developer.apple.com/techpubs/macosx/CoreTechnologies/securityservices/authorizationservices/authservices.html>
|
---|
262 | //
|
---|
263 | // * * * *
|
---|
264 | //
|
---|
265 | // This complex design is required for a number of reasons.
|
---|
266 | //
|
---|
267 | // o The technique of using a self-limiting setuid root helper tool is
|
---|
268 | // recommended by Apple's security team.
|
---|
269 | //
|
---|
270 | // o You need to use a working helper tool and a backup helper tool
|
---|
271 | // because of the problems in the Mac OS X Finder. The problems
|
---|
272 | // are as follows:
|
---|
273 | //
|
---|
274 | // - In Mac OS X 10.0.x, the Finder will silently not copy the
|
---|
275 | // setuid root attribute of a helper program within your bundle.
|
---|
276 | //
|
---|
277 | // - In Mac OS X 10.1.x, the Finder will not copy the setuid root
|
---|
278 | // helper program within your bundle (and display a wacky error
|
---|
279 | // dialog).
|
---|
280 | //
|
---|
281 | // - In Mac OS X 10.2.x, the Finder will refuse to copy an application
|
---|
282 | // that contains a setuid root helper tool.
|
---|
283 | //
|
---|
284 | // o It's a general requirement that a Mac OS X application be
|
---|
285 | // self-contained, that is, it should be drag installable and not
|
---|
286 | // require the user to run an installer.
|
---|
287 | //
|
---|
288 | // o It's a general requirement that a Mac OS X application be runnable
|
---|
289 | // from a read-only volume (like a CD-ROM). Thus, you can't place
|
---|
290 | // the helper tool within the application bundle because copying it
|
---|
291 | // there would require the volume be writable.
|
---|
292 | //
|
---|
293 | // o Users can choose to ignore privileges on a particular volume
|
---|
294 | // by checking a checkbox in the Finder Get Info window. A setuid
|
---|
295 | // program on an volume that's ignoring privileges will not be
|
---|
296 | // effective (ie it won't run as EUID 0).
|
---|
297 | //
|
---|
298 | // By placing the setuid root helper tool within the Application Support
|
---|
299 | // folder, this code allows you to copy the application bundle from
|
---|
300 | // one disk to another without breaking it and without any weird error
|
---|
301 | // dialogs. In addition, you can copy the program to another machine
|
---|
302 | // entirely, and the only thing the user has to do is to reenter their
|
---|
303 | // admin password when they first run the application. Finally, the
|
---|
304 | // user's Application Support folder is typically inside their home
|
---|
305 | // directory, which is typically on the system volume, and thus is
|
---|
306 | // not ignoring privileges.
|
---|
307 |
|
---|
308 | /////////////////////////////////////////////////////////////////
|
---|
309 | #pragma mark **** Helper Tool Implementation
|
---|
310 |
|
---|
311 | // The following are special error codes used by the helper tool code.
|
---|
312 | // These error codes can be mapped to the helper tool return status
|
---|
313 | // (ie the result from main). For example, kMoreSecResultParamErr maps
|
---|
314 | // to a return status of 1, kMoreSecResultPrivilegesErr maps to 2,
|
---|
315 | // and so on.
|
---|
316 |
|
---|
317 | enum {
|
---|
318 | kMoreSecResultBase = 5360,
|
---|
319 |
|
---|
320 | kMoreSecResultParamErr = 5361,
|
---|
321 | kMoreSecResultPrivilegesErr = 5362,
|
---|
322 | kMoreSecResultCanceledErr = 5363,
|
---|
323 | kMoreSecResultInternalErrorErr = 5364,
|
---|
324 |
|
---|
325 | kMoreSecFirstResultErr = kMoreSecResultParamErr,
|
---|
326 | kMoreSecLastResultErr = kMoreSecResultInternalErrorErr
|
---|
327 |
|
---|
328 | // other errors defined below
|
---|
329 | };
|
---|
330 |
|
---|
331 | extern int MoreSecErrorToHelperToolResult(int errNum);
|
---|
332 | // A function to map an errno/OSStatus to a helper tool return
|
---|
333 | // status. The MoreSec error codes are mapped as described
|
---|
334 | // above, and there is a minimal amount of mapping of other
|
---|
335 | // OSStatus values to those codes.
|
---|
336 |
|
---|
337 | extern int MoreSecHelperToolResultToError(int toolResult);
|
---|
338 | // This function maps a helper tool status to the corresponding
|
---|
339 | // errno/OSStatus value.
|
---|
340 |
|
---|
341 | extern AuthorizationRef MoreSecHelperToolCopyAuthRef(void);
|
---|
342 | // When started by AuthorizationExecuteWithPrivileges, a helper tool
|
---|
343 | // gets some important parameters via its environment. However,
|
---|
344 | // a helper tool is *supposed* to blow away its environment
|
---|
345 | // (using MoreSecDestroyInheritedEnvironment) to minimise security
|
---|
346 | // risks. This routine allows the tool to recover the parameters
|
---|
347 | // supplied by AuthorizationExecuteWithPrivileges before it
|
---|
348 | // calls MoreSecDestroyInheritedEnvironment to destroy the environment.
|
---|
349 | //
|
---|
350 | // IMPORTANT: It's quite normal for this routine to return NULL.
|
---|
351 | // You should just pass the result straight to MoreSecHelperToolMain.
|
---|
352 |
|
---|
353 | typedef OSStatus (*MoreSecCommandProc)(AuthorizationRef auth,
|
---|
354 | CFDictionaryRef request, CFDictionaryRef *response);
|
---|
355 | // This is a callback type, called by MoreSecHelperToolMain to
|
---|
356 | // actually execute commands.
|
---|
357 | //
|
---|
358 | // auth will not be NULL
|
---|
359 | // request will not be NULL
|
---|
360 | // response will not be NULL
|
---|
361 | // *response will be NULL
|
---|
362 | //
|
---|
363 | // The EUID will be set to the RUID, while the SUID will be 0.
|
---|
364 | // If you need to do a privileged operation, you should
|
---|
365 | // temporarily set the EUID to 0 via MoreSecSetPrivilegedEUID,
|
---|
366 | // and set it back whenh you're done via MoreSecTemporarilySetNonPrivilegedEUID.
|
---|
367 | //
|
---|
368 | // If you don't need to return anything other than a function
|
---|
369 | // result to your client, you don't need to mess with response.
|
---|
370 | // MoreSecHelperToolMain will create a dictionary containing
|
---|
371 | // your function result and pass that back to the client.
|
---|
372 | // Even if you do return a dictionary in *response,
|
---|
373 | // MoreSecHelperToolMain will still put your function result into the
|
---|
374 | // kMoreSecErrorNumberKey key unless you've set up that key yourself.
|
---|
375 | //
|
---|
376 | // If you want to self-limit the capabilities of your helper tool,
|
---|
377 | // you might consider using AuthorizationCopyRights to make sure
|
---|
378 | // that the user has authorization to do specific operations.
|
---|
379 | //
|
---|
380 | // If you do create a response, it must be it must be flattenable via
|
---|
381 | // the CFPropertyList APIs.
|
---|
382 |
|
---|
383 | extern int MoreSecHelperToolMain(int fdIn, int fdOut, AuthorizationRef auth,
|
---|
384 | MoreSecCommandProc commandProc, int argc, const char *argv[]);
|
---|
385 | // This function is the helper tool half of MoreSecExecuteRequestInHelperTool.
|
---|
386 | // It's designed to be called directly from your helper tool's "main" function,
|
---|
387 | // and to implement the entire tool, calling commandProc to handle the specific
|
---|
388 | // command.
|
---|
389 | //
|
---|
390 | // IMPORTANT: Contrary to the usual rules, this routine disposes of
|
---|
391 | // auth before returning. This makes sense when you consider the
|
---|
392 | // standard "main" function, described above.
|
---|
393 | //
|
---|
394 | // fdIn must be non-negative, typically you pass in STDIN_FILENO
|
---|
395 | // fdOut must be non-negative, typically you pass in STDOUT_FILENO
|
---|
396 | // auth may be NULL, typically you just pass in the result of MoreSecHelperToolCopyAuthRef
|
---|
397 | // commandProc must not be NULL
|
---|
398 | // argc must be 1 or 2, depending on whether the tool is running in self-repair mode,
|
---|
399 | // typically you just pass in the argc that was supplied to main
|
---|
400 | // argv must not be NULL, typically you just pass in the value that was supplied to main
|
---|
401 |
|
---|
402 | /////////////////////////////////////////////////////////////////
|
---|
403 | #pragma mark **** Calling Helper Tool
|
---|
404 |
|
---|
405 | enum {
|
---|
406 | kMoreSecIgnoringPrivsInFolderErr = 5370
|
---|
407 | };
|
---|
408 |
|
---|
409 | extern OSStatus MoreSecIsFolderIgnoringPrivileges(const FSRef *folder, Boolean *ignoringPrivs);
|
---|
410 | // Determines whether the specified folder is on a volume that's
|
---|
411 | // ignoring privileges (as per the "Ignore ownership on this volume"
|
---|
412 | // checkbox in the Finder's Get Info dialog). There is a real API to
|
---|
413 | // do this but it's currently private. I've filed a request to get
|
---|
414 | // this made public [3061192]. Until that's done, I use a workaround
|
---|
415 | // that involves creating a temporary file within the folder and
|
---|
416 | // seeing if I can manipulate its permissions. For this workaround to
|
---|
417 | // work the folder must be read/write accessible.
|
---|
418 | //
|
---|
419 | // folder must not be NULL; folder must reference a folder
|
---|
420 | // ignoringPrivs must not be NULL;
|
---|
421 | // on success, *ignoringPrivs is true if the volume on which the folder
|
---|
422 | // resides is ignoring privileges; on error, *ignoringPrivs is undefined
|
---|
423 |
|
---|
424 | extern OSStatus MoreSecCopyHelperToolURLAndCheck(CFURLRef templateTool,
|
---|
425 | OSType folder, CFStringRef subFolderName, CFStringRef toolName,
|
---|
426 | CFURLRef *tool, Boolean *toolFound);
|
---|
427 | // This routine returns a CFURL to your helper tool. This CFURL typically
|
---|
428 | // points to a working copy of the tool inside the Application Support
|
---|
429 | // folder. This routine confirms that the tool exists and is valid in that
|
---|
430 | // location. If that check fails, it restores the tool from the template.
|
---|
431 | // Thus, the tool pointed to by the returned CFURL will be a valid copy of the
|
---|
432 | // template tool specified by templateTool.
|
---|
433 | //
|
---|
434 | // templateTool must not be NULL; the tool referenced by templateTool
|
---|
435 | // must exist; templateTool is a reference to your original helper tool;
|
---|
436 | // if your template tool is bundled within your application package, you might
|
---|
437 | // want to use the MoreSecCopyHelperToolURLAndCheckBundled wrapper routine
|
---|
438 | // (see below)
|
---|
439 | //
|
---|
440 | // folder is a Folder Manager folder selector; typically you pass kApplicationSupportFolderType
|
---|
441 | //
|
---|
442 | // subFolderName is the name of an optional sub-folder within the
|
---|
443 | // folder specified above; if this is not NULL, the returned URL
|
---|
444 | // points to within the named folder; if it is NULL, the URL points
|
---|
445 | // directly within the Folder Manager folder; if you don't want to
|
---|
446 | // pass NULL, you typically use the name of your application
|
---|
447 | //
|
---|
448 | // toolName is the name of the helper tool itself
|
---|
449 | //
|
---|
450 | // tool must not be NULL; *tool must be NULL; on success, *tool
|
---|
451 | // is a newly created CFURL that you must release; on error, *tool
|
---|
452 | // will be NULL
|
---|
453 | //
|
---|
454 | // On current systems, the returned URL will point to one of the
|
---|
455 | // following if the tool already exists.
|
---|
456 | //
|
---|
457 | // ~/Library/Application Support/<subFolderName>/<toolName>
|
---|
458 | // /Library/Application Support/<subFolderName>/<toolName>
|
---|
459 | // /Network/Library/Application Support/<subFolderName>/<toolName>
|
---|
460 | // /System/Library/Application Support/<subFolderName>/<toolName>
|
---|
461 | //
|
---|
462 | // If the tool doesn't already exist, a copy will be made in:
|
---|
463 | //
|
---|
464 | // ~/Library/Application Support/<subFolderName>/<toolName>
|
---|
465 | //
|
---|
466 | // and that URL will be return.d
|
---|
467 | //
|
---|
468 | // In all cases, you can treat <subFolderName> as the empty string
|
---|
469 | // if subFolderName is NULL.
|
---|
470 | //
|
---|
471 | // An error result of kMoreSecIgnoringPrivsInFolderErr means that
|
---|
472 | // the helper tool could not be created because the folder is
|
---|
473 | // on a volume that's ignoring privileges.
|
---|
474 | //
|
---|
475 | // IMPORTANT:
|
---|
476 | // When create the helper tool from the template tool, this only copies the
|
---|
477 | // data fork of the tool. If you the helper tool needs to access resources,
|
---|
478 | // you should either pass those resources in the request dictionary or
|
---|
479 | // pass it the URL of your bundle in the request dictionary.
|
---|
480 | //
|
---|
481 | // Note:
|
---|
482 | // This does not verify any tool checksum or digital signature,
|
---|
483 | // for the reasons outlined in the comment "Notes on Code Signing"
|
---|
484 | // (in "MoreSecurity.c").
|
---|
485 |
|
---|
486 | extern OSStatus MoreSecCopyHelperToolURLAndCheckBundled(CFBundleRef inBundle, CFStringRef templateToolName,
|
---|
487 | OSType folder, CFStringRef subFolderName, CFStringRef toolName,
|
---|
488 | CFURLRef *tool, Boolean *toolFound);
|
---|
489 | // Finds (or creates) a helper tool in a bundled application.
|
---|
490 | // inBundle and templateToolName describe the location of the template
|
---|
491 | // tool. folder, subFolderName, and toolName describe the location of the
|
---|
492 | // working copy of the tool.
|
---|
493 | //
|
---|
494 | // This routine is a simple composition of CFBundleCopyAuxiliaryExecutableURL and
|
---|
495 | // MoreSecCopyHelperToolURLAndCheck.
|
---|
496 | //
|
---|
497 | // inBundle must not be NULL; typically you just pass in CFBundleGetMainBundle()
|
---|
498 | //
|
---|
499 | // templateToolName must not be NULL; the tool must exist within the executable
|
---|
500 | // folder of inBundle
|
---|
501 | //
|
---|
502 | // See MoreSecCopyHelperToolURLAndCheck for a full description of the folder,
|
---|
503 | // subFolderName, and toolName parameters. Typically you pass
|
---|
504 | // kApplicationSupportFolderType for folder and your application name for
|
---|
505 | // subFolderName.
|
---|
506 | //
|
---|
507 | // tool must not be NULL; *tool must be NULL; on success, *tool will be
|
---|
508 | // a URL to the helper tool; on error, *tool will be NULL
|
---|
509 |
|
---|
510 | extern OSStatus MoreSecExecuteRequestInHelperTool(CFURLRef helperTool, AuthorizationRef auth,
|
---|
511 | CFDictionaryRef request, CFDictionaryRef *response);
|
---|
512 | // Executes a privileged request in a helper tool. helperTool is
|
---|
513 | // a reference to the helper tool to run. You typically gets its value
|
---|
514 | // using MoreSecCopyHelperToolURLAndCheckBundled, although it's passed in as a
|
---|
515 | // parameter to allow flexibility.
|
---|
516 | //
|
---|
517 | // auth is your application's connection to Authorization Services.
|
---|
518 | // It's likely that you've used this connection to pre-authorization
|
---|
519 | // this operation, as described in the Authorization Services docs.
|
---|
520 | //
|
---|
521 | // <http://developer.apple.com/techpubs/macosx/CoreTechnologies/securityservices/authorizationservices/authservices.html>
|
---|
522 | //
|
---|
523 | // request specifies what you want the helper tool to do. Its
|
---|
524 | // contents are not interpreted by MoreSecExecuteRequestInHelperTool,
|
---|
525 | // however, it must be flattenable via the CFPropertyList APIs.
|
---|
526 | //
|
---|
527 | // response is the reply from the helper tool. It is not interpreted
|
---|
528 | // by MoreSecExecuteRequestInHelperTool other than to add a key
|
---|
529 | // (kMoreSecErrorNumberKey) which contains the error from the
|
---|
530 | // helper tool's commandProc.
|
---|
531 | //
|
---|
532 | // helperTool must not be NULL
|
---|
533 | // auth must not be NULL
|
---|
534 | // request must not be NULL
|
---|
535 | // response must not be NULL
|
---|
536 | // *response must be NULL
|
---|
537 |
|
---|
538 | extern OSStatus MoreSecGetErrorFromResponse(CFDictionaryRef response);
|
---|
539 | // this function returns the error stored in a helper tool
|
---|
540 | // response obtained via MoreSecExecuteRequestInHelperTool.
|
---|
541 | //
|
---|
542 | // response must not be NULL
|
---|
543 |
|
---|
544 | #define kMoreSecErrorNumberKey CFSTR("com.apple.dts.MoreIsBetter.MoreSec.ErrorNumber") // CFNumberRef, OSStatus
|
---|
545 | // The dictionary key where the helper tool error is stored.
|
---|
546 |
|
---|
547 | #ifdef __cplusplus
|
---|
548 | }
|
---|
549 | #endif
|
---|