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 <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 {
45 struct tokenEvent *next;
48 tokenEvent_t *tokenEvents = NULL;
50 osi_mutex_t tokenEventLock;
52 EVENT_HANDLE rpc_ShutdownEvent = NULL;
55 * Add a new uuid and session key to the list.
57 void cm_RegisterNewTokenEvent(
61 tokenEvent_t *te = malloc(sizeof(tokenEvent_t));
63 memcpy(te->sessionKey, sessionKey, sizeof(te->sessionKey));
64 lock_ObtainMutex(&tokenEventLock);
65 te->next = tokenEvents;
67 lock_ReleaseMutex(&tokenEventLock);
71 * Find a uuid on the list. If it is there, copy the session key and
72 * destroy the entry, since it is only used once.
74 * Return TRUE if found, FALSE if not found
76 BOOL cm_FindTokenEvent(afs_uuid_t uuid, char sessionKey[8])
82 lock_ObtainMutex(&tokenEventLock);
86 if (UuidEqual((UUID *)&uuid, (UUID *)&te->uuid, &status)) {
88 lock_ReleaseMutex(&tokenEventLock);
89 memcpy(sessionKey, te->sessionKey,
90 sizeof(te->sessionKey));
97 lock_ReleaseMutex(&tokenEventLock);
102 * RPC manager entry point vector functions
105 long AFSRPC_SetToken(
107 unsigned char __RPC_FAR sessionKey[8])
109 cm_RegisterNewTokenEvent(uuid, sessionKey);
113 long AFSRPC_GetToken(
115 unsigned char __RPC_FAR sessionKey[8])
119 found = cm_FindTokenEvent(uuid, sessionKey);
126 void __RPC_FAR * __RPC_USER midl_user_allocate (size_t cBytes)
128 return ((void __RPC_FAR *) malloc(cBytes));
131 void __RPC_USER midl_user_free(void __RPC_FAR * p)
140 RPC_BINDING_VECTOR *ptrBindingVector = NULL;
141 BOOLEAN ifaceRegistered = FALSE;
142 BOOLEAN epRegistered = FALSE;
144 #ifdef NOOSIDEBUGSERVER /* Use All Protseqs already done in OSI */
146 status = RpcServerUseAllProtseqs(1, NULL);
147 if (status != RPC_S_OK) {
148 task = "Use All Protocol Sequences";
152 #endif /* NOOSIDEBUGSERVER */
154 status = RpcServerRegisterIf(afsrpc_v1_0_s_ifspec, NULL, NULL);
155 if (status != RPC_S_OK) {
156 task = "Register Interface";
159 ifaceRegistered = TRUE;
161 status = RpcServerInqBindings(&ptrBindingVector);
162 if (status != RPC_S_OK) {
163 task = "Inquire Bindings";
167 status = RpcServerRegisterAuthInfo(NULL, RPC_C_AUTHN_WINNT, NULL, NULL);
168 if (status != RPC_S_OK) {
169 task = "Register Authentication Info";
173 status = RpcEpRegister(afsrpc_v1_0_s_ifspec, ptrBindingVector,
174 NULL, "AFS session key interface");
175 if (status != RPC_S_OK) {
176 task = "Register Endpoints";
181 afsi_log("RPC server listening");
183 status = RpcServerListen(OSI_MAXRPCCALLS, OSI_MAXRPCCALLS, 0);
184 if (status != RPC_S_OK) {
185 task = "Server Listen";
190 (void) RpcEpUnregister(afsrpc_v1_0_s_ifspec, ptrBindingVector,
193 if (ptrBindingVector)
194 (void) RpcBindingVectorFree(&ptrBindingVector);
197 (void) RpcServerUnregisterIf(afsrpc_v1_0_s_ifspec, NULL, FALSE);
199 if (status != RPC_S_OK)
200 afsi_log("RPC problem, code %d for %s", status, task);
202 afsi_log("RPC shutdown");
204 if (rpc_ShutdownEvent != NULL)
205 thrd_SetEvent(rpc_ShutdownEvent);
211 LONG status = ERROR_SUCCESS;
213 ULONG listenThreadID = 0;
214 char * name = "afsd_rpc_ShutdownEvent";
216 lock_InitializeMutex(&tokenEventLock, "token event lock");
218 rpc_ShutdownEvent = thrd_CreateEvent(NULL, FALSE, FALSE, name);
219 if ( GetLastError() == ERROR_ALREADY_EXISTS )
220 afsi_log("Event Object Already Exists: %s", name);
222 listenThread = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)RpcListen,
223 0, 0, &listenThreadID);
225 if (listenThread == NULL) {
226 status = GetLastError();
228 CloseHandle(listenThread);
233 void RpcShutdown(void)
235 RpcMgmtStopServerListening(NULL);
237 if (rpc_ShutdownEvent != NULL) {
238 thrd_WaitForSingleObject_Event(rpc_ShutdownEvent, INFINITE);
239 CloseHandle(rpc_ShutdownEvent);