<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Michael V. O'Brien &#187; Cocoa</title>
	<atom:link href="http://michaelobrien.info/blog/category/cocoa/feed/" rel="self" type="application/rss+xml" />
	<link>http://michaelobrien.info/blog</link>
	<description></description>
	<lastBuildDate>Wed, 27 Jan 2010 04:46:55 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>AuthorizationExecuteWithPrivileges: A Simple Example</title>
		<link>http://michaelobrien.info/blog/2009/07/authorizationexecutewithprivileges-a-simple-example/</link>
		<comments>http://michaelobrien.info/blog/2009/07/authorizationexecutewithprivileges-a-simple-example/#comments</comments>
		<pubDate>Mon, 20 Jul 2009 01:26:40 +0000</pubDate>
		<dc:creator>michael</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[osx]]></category>

		<guid isPermaLink="false">http://michaelobrien.info/blog/?p=51</guid>
		<description><![CDATA[Introduction
I didn&#8217;t find Apple&#8217;s documentation to be completely clear on how to grant an Mac OS X application authorization to run system-level commands.  The best solution and only solution I could find was to use the function AuthorizationExecuteWithPrivileges.  I wrote two simple Xcode projects, OSXSimpleAuth and OSXSlightlyBetterAuth, for OS X Leopard (10.5) to [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>I didn&#8217;t find Apple&#8217;s documentation to be completely clear on how to grant an Mac OS X application authorization to run system-level commands.  The best solution and only solution I could find was to use the function <code>AuthorizationExecuteWithPrivileges</code>.  I wrote two simple Xcode projects, <a href="http://github.com/notbrien/OSXSimpleAuth">OSXSimpleAuth</a> and <a href="http://github.com/notbrien/OSXSlightlyBetterAuth">OSXSlightlyBetterAuth</a>, for OS X Leopard (10.5) to demonstrate its use, and I hope it will help others get something working quickly and gain a basic understanding, so they can concentrate on adding more robust functionality.</p>
<h3>Simple Example</h3>
<p>A simple example of how to use <code>AuthorizationExecuteWithPrivileges</code> is as follows:</p>
<ol>
<li>Create a Authorization Reference (<code>AuthorizationCreate</code>)</li>
<li>Run your tool with the authorization reference (<code>AuthorizationExecuteWithPrivileges</code>)</li>
</ol>
<p>For this example, <a href="http://github.com/notbrien/OSXSimpleAuth">OSXSimpleAuth</a>, I created a Foundation Tool and added the Security framework to it.</p>
<pre class="code">
<span class="comment-delimiter">// </span><span class="comment">Create authorization reference</span>
<span class="type">AuthorizationRef</span> <span class="variable-name">authorizationRef</span>;
<span class="type">OSStatus</span> <span class="variable-name">status</span>;
status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment,
                             kAuthorizationFlagDefaults, &amp;authorizationRef);

<span class="comment-delimiter">// </span><span class="comment">Run the tool using the authorization reference</span>
<span class="type">char</span> *<span class="variable-name">tool</span> = <span class="string">"/sbin/dmesg"</span>;
<span class="type">char</span> *<span class="variable-name">args</span>[] = {NULL};
<span class="type">FILE</span> *<span class="variable-name">pipe</span> = NULL;
status = AuthorizationExecuteWithPrivileges(authorizationRef, tool,
                                            kAuthorizationFlagDefaults, args, &amp;pipe);
</pre>
<h3>Slightly Better Example</h3>
<p>A slightly better example that uses more options to run <code>AuthorizationExecuteWithPrivileges</code> and has links to some explanations from Apple&#8217;s documentation can be found in <a href="http://github.com/notbrien/OSXSlightlyBetterAuth">OSXSlightlyBetterAuth</a>.</p>
<pre class="code">
<span class="comment-delimiter">// </span><span class="comment">Create authorization reference
</span><span class="type">OSStatus</span> <span class="variable-name">status</span>;
<span class="type">AuthorizationRef</span> <span class="variable-name">authorizationRef</span>;

<span class="comment-delimiter">// </span><span class="comment">AuthorizationCreate and pass NULL as the initial
</span><span class="comment-delimiter">// </span><span class="comment">AuthorizationRights set so that the AuthorizationRef gets created
</span><span class="comment-delimiter">// </span><span class="comment">successfully, and then later call AuthorizationCopyRights to
</span><span class="comment-delimiter">// </span><span class="comment">determine or extend the allowable rights.
</span><span class="comment-delimiter">// </span><span class="comment">http://developer.apple.com/qa/qa2001/qa1172.html
</span>status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment,
                             kAuthorizationFlagDefaults, &amp;authorizationRef);
<span class="keyword">if</span> (status != errAuthorizationSuccess)
    NSLog(@<span class="string">"Error Creating Initial Authorization: %d"</span>, status);

<span class="comment-delimiter">// </span><span class="comment">kAuthorizationRightExecute == "system.privilege.admin"
</span><span class="type">AuthorizationItem</span> <span class="variable-name">right</span> = {kAuthorizationRightExecute, 0, NULL, 0};
<span class="type">AuthorizationRights</span> <span class="variable-name">rights</span> = {1, &amp;right};
<span class="type">AuthorizationFlags</span> <span class="variable-name">flags</span> = kAuthorizationFlagDefaults |
                           kAuthorizationFlagInteractionAllowed |
                           kAuthorizationFlagPreAuthorize |
                           kAuthorizationFlagExtendRights;

<span class="comment-delimiter">// </span><span class="comment">Call AuthorizationCopyRights to determine or extend the allowable rights.
</span>status = AuthorizationCopyRights(authorizationRef, &amp;rights, NULL, flags, NULL);
<span class="keyword">if</span> (status != errAuthorizationSuccess)
    NSLog(@<span class="string">"Copy Rights Unsuccessful: %d"</span>, status);

NSLog(@<span class="string">"\n\n** %@ **\n\n"</span>, @<span class="string">"This command should work."</span>);
<span class="type">char</span> *<span class="variable-name">tool</span> = <span class="string">"/sbin/dmesg"</span>;
<span class="type">char</span> *<span class="variable-name">args</span>[] = {NULL};
<span class="type">FILE</span> *<span class="variable-name">pipe</span> = NULL;

status = AuthorizationExecuteWithPrivileges(authorizationRef, tool,
                                            kAuthorizationFlagDefaults, args, &amp;pipe);
<span class="keyword">if</span> (status != errAuthorizationSuccess)
    NSLog(@<span class="string">"Error: %d"</span>, status);

<span class="comment-delimiter">// </span><span class="comment">The only way to guarantee that a credential acquired when you
</span><span class="comment-delimiter">// </span><span class="comment">request a right is not shared with other authorization instances is
</span><span class="comment-delimiter">// </span><span class="comment">to destroy the credential.  To do so, call the AuthorizationFree
</span><span class="comment-delimiter">// </span><span class="comment">function with the flag kAuthorizationFlagDestroyRights.
</span><span class="comment-delimiter">// </span><span class="comment">http://developer.apple.com/documentation/Security/Conceptual/authorization_concepts/02authconcepts/chapter_2_section_7.html
</span>status = AuthorizationFree(authorizationRef, kAuthorizationFlagDestroyRights);
</pre>
<p>Notice the &#8220;Right&#8221; label in the authorization dialog box screenshot.  The <code>AuthorizationItem</code> was set with &#8220;system.privilege.admin&#8221; via the <code>kAuthorizationRightExecute</code> constant.</p>
<p><img src="/static/images/blog/osx_auth_dialog.png"></p>
<h3>Conclusion</h3>
<p>Apple recommends only using <code>AuthorizationExecuteWithPrivileges</code> in two cases.  One is to create an installer.  The other is to repair your helper tool by setting the setuid bit.  The helper tool is supposed to encapsulate the root privileged portion of the code. Be aware that I didn&#8217;t do this in the examples.  Go to the <a href="http://github.com/notbrien/OSXSimpleAuth">OSXSimpleAuth project page</a> and the <a href="http://github.com/notbrien/OSXSlightlyBetterAuth">OSXSlightlyBetterAuth project page</a> to download the example Xcode projects.</p>
]]></content:encoded>
			<wfw:commentRss>http://michaelobrien.info/blog/2009/07/authorizationexecutewithprivileges-a-simple-example/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
