3 * aklog auth plugin, Taken from rot13 with guidance from NullAuthPlugin
4 * Copyright (c) 2010 Your File System Inc. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <sys/kauth.h>
33 #include <Security/AuthorizationTags.h>
34 #include <Security/AuthorizationPlugin.h>
35 #include <DirectoryService/DirectoryService.h>
37 typedef struct PluginRef
39 const AuthorizationCallbacks *callbacks;
42 typedef struct MechanismRef
44 const PluginRef *plugin;
45 AuthorizationEngineRef engine;
49 static OSStatus do_aklog(char *cell)
52 * The first draft used aklog source inline. In an rxgk
53 * universe, that code should be encapsulated in a library
54 * we call. In this version we simply fork aklog.
55 * This function should be replaced with calls to a "libaklog"
60 asprintf(&aklogCmd, "/usr/bin/aklog %s", cell);
62 return system(aklogCmd);
67 return system("/usr/bin/aklog");
70 static OSStatus invokeAklog(MechanismRef *mechanism)
72 AuthorizationContextFlags contextFlags;
73 const AuthorizationValue *value;
78 /* a list of context values appears in the Null sample plugin */
79 status = mechanism->plugin->callbacks->GetContextValue(mechanism->engine,
84 /* This and the group are strings. I don't know why. */
86 uid = atoi(value->data);
90 status = mechanism->plugin->callbacks->GetContextValue(mechanism->engine,
91 kDS1AttrPrimaryGroupID,
95 gid = atoi(value->data);
99 /* in a PAGless universe, this trick works */
100 status = pthread_setugid_np(uid, gid);
102 status = do_aklog(mechanism->mechanismArg);
103 pthread_setugid_np(KAUTH_UID_NONE, KAUTH_GID_NONE);
109 mechanism->plugin->callbacks->SetResult(mechanism->engine,
110 kAuthorizationResultAllow);
113 return errAuthorizationSuccess;
116 return errAuthorizationInternal;
119 static OSStatus pluginDestroy(AuthorizationPluginRef inPlugin)
121 /* seems to not be called. can't do cleanup? */
122 PluginRef *plugin = (PluginRef *)inPlugin;
127 static OSStatus mechanismCreate(AuthorizationPluginRef inPlugin,
128 AuthorizationEngineRef inEngine,
129 AuthorizationMechanismId mechanismId,
130 AuthorizationMechanismRef *outMechanism)
132 const PluginRef *plugin = (const PluginRef *)inPlugin;
134 MechanismRef *mechanism = calloc(1, sizeof(MechanismRef));
136 mechanism->plugin = plugin;
137 mechanism->engine = inEngine;
139 * consider supporting a variant which backgrounds aklog and returns
140 * success where tokens are desired but not critical.
142 mechanism->mechanismArg = strdup(mechanismId);
144 *outMechanism = mechanism;
150 static OSStatus mechanismInvoke(AuthorizationMechanismRef inMechanism)
152 MechanismRef *mechanism = (MechanismRef *)inMechanism;
155 status = invokeAklog(mechanism);
157 return errAuthorizationInternal;
160 return mechanism->plugin->callbacks->SetResult(mechanism->engine, kAuthorizationResultAllow);
165 * Since a authorization result is provided within invoke, we don't have to
166 * cancel a long(er) term operation that might have been spawned.
167 * A timeout could be done here.
169 static OSStatus mechanismDeactivate(AuthorizationMechanismRef inMechanism)
175 static OSStatus mechanismDestroy(AuthorizationMechanismRef inMechanism)
177 MechanismRef *mechanism = (MechanismRef *)inMechanism;
178 free(mechanism->mechanismArg);
185 AuthorizationPluginInterface pluginInterface =
187 kAuthorizationPluginInterfaceVersion, /* UInt32 version; */
197 * Entry point for all plugins. Plugin and the host loading it exchange interfaces.
198 * Normally you'd allocate resources shared amongst all mechanisms here.
199 * When a plugin is created it may not necessarily be used, so be conservative
201 OSStatus AuthorizationPluginCreate(const AuthorizationCallbacks *callbacks,
202 AuthorizationPluginRef *outPlugin,
203 const AuthorizationPluginInterface **outPluginInterface)
205 PluginRef *plugin = calloc(1, sizeof(PluginRef));
207 plugin->callbacks = callbacks;
208 *outPlugin = (AuthorizationPluginRef) plugin;
209 *outPluginInterface = &pluginInterface;