2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
25 #include "afsd_init.h"
32 * The motivation for this whole module is that in transmitting tokens
33 * between applications and the AFS service, we must not send session keys
34 * in the clear. So the SetToken and GetToken pioctl's also do an RPC using
35 * packet privacy to transmit the session key. The pioctl() generates a UUID
36 * and sends it down, and the RPC sends down the same UUID, so that the service
37 * can match them up. A list of session keys, searched by UUID, is maintained.
40 extern void afsi_log(char *pattern, ...);
42 typedef struct tokenEvent {
43 clientchar_t *SidString;
46 struct tokenEvent *next;
49 tokenEvent_t *tokenEvents = NULL;
51 osi_mutex_t tokenEventLock;
53 EVENT_HANDLE rpc_ShutdownEvent = NULL;
56 * Add a new uuid and session key to the list.
58 void cm_RegisterNewTokenEvent(
61 clientchar_t *SidString)
63 tokenEvent_t *te = malloc(sizeof(tokenEvent_t));
64 te->SidString = SidString;
66 memcpy(te->sessionKey, sessionKey, sizeof(te->sessionKey));
67 lock_ObtainMutex(&tokenEventLock);
68 te->next = tokenEvents;
70 lock_ReleaseMutex(&tokenEventLock);
74 * Find a uuid on the list. If it is there, copy the session key and
75 * destroy the entry, since it is only used once.
77 * Return TRUE if found, FALSE if not found
79 BOOL cm_FindTokenEvent(afs_uuid_t uuid, char sessionKey[8], clientchar_t **SidString)
85 lock_ObtainMutex(&tokenEventLock);
89 if (UuidEqual((UUID *)&uuid, (UUID *)&te->uuid, &status)) {
91 lock_ReleaseMutex(&tokenEventLock);
92 memcpy(sessionKey, te->sessionKey,
93 sizeof(te->sessionKey));
95 *SidString = te->SidString;
97 LocalFree(te->SidString);
104 lock_ReleaseMutex(&tokenEventLock);
109 * RPC manager entry point vector functions
112 long AFSRPC_SetToken(
114 unsigned char __RPC_FAR sessionKey[8])
116 clientchar_t *secSidString = 0;
118 if (RpcImpersonateClient(0) == RPC_S_OK) {
123 TOKEN_STATISTICS tokenStats;
125 if (!OpenThreadToken( GetCurrentThread(), TOKEN_READ, FALSE, &hToken)) {
126 gle = GetLastError();
130 if (!GetTokenInformation( hToken, TokenStatistics, &tokenStats, sizeof(tokenStats), &retlen)) {
131 gle = GetLastError();
135 if (!smb_GetUserSID( hToken, &pSid))
138 if (!ConvertSidToStringSidW(pSid, &secSidString))
143 CloseHandle( hToken);
148 cm_RegisterNewTokenEvent(uuid, sessionKey, secSidString);
153 long AFSRPC_GetToken(
155 unsigned char __RPC_FAR sessionKey[8])
159 found = cm_FindTokenEvent(uuid, sessionKey, NULL);
166 void __RPC_FAR * __RPC_USER midl_user_allocate (size_t cBytes)
168 return ((void __RPC_FAR *) calloc(cBytes, 1));
171 void __RPC_USER midl_user_free(void __RPC_FAR * p)
180 RPC_BINDING_VECTOR *ptrBindingVector = NULL;
181 BOOLEAN ifaceRegistered = FALSE;
182 BOOLEAN epRegistered = FALSE;
184 #ifdef NOOSIDEBUGSERVER /* Use All Protseqs already done in OSI */
186 status = RpcServerUseAllProtseqs(1, NULL);
187 if (status != RPC_S_OK) {
188 task = "Use All Protocol Sequences";
192 #endif /* NOOSIDEBUGSERVER */
194 status = RpcServerRegisterIf(afsrpc_v1_0_s_ifspec, NULL, NULL);
195 if (status != RPC_S_OK) {
196 task = "Register Interface";
199 ifaceRegistered = TRUE;
201 status = RpcServerInqBindings(&ptrBindingVector);
202 if (status != RPC_S_OK) {
203 task = "Inquire Bindings";
207 status = RpcServerRegisterAuthInfo(NULL, RPC_C_AUTHN_WINNT, NULL, NULL);
208 if (status != RPC_S_OK) {
209 task = "Register Authentication Info";
213 status = RpcEpRegister(afsrpc_v1_0_s_ifspec, ptrBindingVector,
214 NULL, "AFS session key interface");
215 if (status != RPC_S_OK) {
216 task = "Register Endpoints";
221 afsi_log("RPC server listening");
223 status = RpcServerListen(OSI_MAXRPCCALLS, OSI_MAXRPCCALLS, 0);
224 if (status != RPC_S_OK) {
225 task = "Server Listen";
230 (void) RpcEpUnregister(afsrpc_v1_0_s_ifspec, ptrBindingVector,
233 if (ptrBindingVector)
234 (void) RpcBindingVectorFree(&ptrBindingVector);
237 (void) RpcServerUnregisterIf(afsrpc_v1_0_s_ifspec, NULL, FALSE);
239 if (status != RPC_S_OK)
240 afsi_log("RPC problem, code %d for %s", status, task);
242 afsi_log("RPC shutdown");
244 if (rpc_ShutdownEvent != NULL)
245 thrd_SetEvent(rpc_ShutdownEvent);
251 LONG status = ERROR_SUCCESS;
253 ULONG listenThreadID = 0;
254 char * name = "afsd_rpc_ShutdownEvent";
256 lock_InitializeMutex(&tokenEventLock, "token event lock",
257 LOCK_HIERARCHY_TOKEN_EVENT_GLOBAL);
259 rpc_ShutdownEvent = thrd_CreateEvent(NULL, FALSE, FALSE, name);
260 if ( GetLastError() == ERROR_ALREADY_EXISTS )
261 afsi_log("Event Object Already Exists: %s", name);
263 listenThread = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)RpcListen,
264 0, 0, &listenThreadID);
266 if (listenThread == NULL) {
267 status = GetLastError();
269 CloseHandle(listenThread);
274 void RpcShutdown(void)
276 RpcMgmtStopServerListening(NULL);
278 if (rpc_ShutdownEvent != NULL) {
279 thrd_WaitForSingleObject_Event(rpc_ShutdownEvent, INFINITE);
280 CloseHandle(rpc_ShutdownEvent);