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>
21 #include "afsd_init.h"
28 * The motivation for this whole module is that in transmitting tokens
29 * between applications and the AFS service, we must not send session keys
30 * in the clear. So the SetToken and GetToken pioctl's also do an RPC using
31 * packet privacy to transmit the session key. The pioctl() generates a UUID
32 * and sends it down, and the RPC sends down the same UUID, so that the service
33 * can match them up. A list of session keys, searched by UUID, is maintained.
36 extern void afsi_log(char *pattern, ...);
38 typedef struct tokenEvent {
41 struct tokenEvent *next;
44 tokenEvent_t *tokenEvents = NULL;
46 osi_mutex_t tokenEventLock;
48 EVENT_HANDLE rpc_ShutdownEvent = NULL;
51 * Add a new uuid and session key to the list.
53 void cm_RegisterNewTokenEvent(
57 tokenEvent_t *te = malloc(sizeof(tokenEvent_t));
59 memcpy(te->sessionKey, sessionKey, sizeof(te->sessionKey));
60 lock_ObtainMutex(&tokenEventLock);
61 te->next = tokenEvents;
63 lock_ReleaseMutex(&tokenEventLock);
67 * Find a uuid on the list. If it is there, copy the session key and
68 * destroy the entry, since it is only used once.
70 * Return TRUE if found, FALSE if not found
72 BOOL cm_FindTokenEvent(afs_uuid_t uuid, char sessionKey[8])
78 lock_ObtainMutex(&tokenEventLock);
82 if (UuidEqual((UUID *)&uuid, (UUID *)&te->uuid, &status)) {
84 lock_ReleaseMutex(&tokenEventLock);
85 memcpy(sessionKey, te->sessionKey,
86 sizeof(te->sessionKey));
93 lock_ReleaseMutex(&tokenEventLock);
98 * RPC manager entry point vector functions
101 long AFSRPC_SetToken(
103 unsigned char __RPC_FAR sessionKey[8])
105 cm_RegisterNewTokenEvent(uuid, sessionKey);
109 long AFSRPC_GetToken(
111 unsigned char __RPC_FAR sessionKey[8])
115 found = cm_FindTokenEvent(uuid, sessionKey);
122 void __RPC_FAR * __RPC_USER midl_user_allocate (size_t cBytes)
124 return ((void __RPC_FAR *) malloc(cBytes));
127 void __RPC_USER midl_user_free(void __RPC_FAR * p)
136 RPC_BINDING_VECTOR *ptrBindingVector = NULL;
137 BOOLEAN ifaceRegistered = FALSE;
138 BOOLEAN epRegistered = FALSE;
140 #ifdef NOOSIDEBUGSERVER /* Use All Protseqs already done in OSI */
142 status = RpcServerUseAllProtseqs(1, NULL);
143 if (status != RPC_S_OK) {
144 task = "Use All Protocol Sequences";
148 #endif /* NOOSIDEBUGSERVER */
150 status = RpcServerRegisterIf(afsrpc_v1_0_s_ifspec, NULL, NULL);
151 if (status != RPC_S_OK) {
152 task = "Register Interface";
155 ifaceRegistered = TRUE;
157 status = RpcServerInqBindings(&ptrBindingVector);
158 if (status != RPC_S_OK) {
159 task = "Inquire Bindings";
163 status = RpcServerRegisterAuthInfo(NULL, RPC_C_AUTHN_WINNT, NULL, NULL);
164 if (status != RPC_S_OK) {
165 task = "Register Authentication Info";
169 status = RpcEpRegister(afsrpc_v1_0_s_ifspec, ptrBindingVector,
170 NULL, "AFS session key interface");
171 if (status != RPC_S_OK) {
172 task = "Register Endpoints";
177 afsi_log("RPC server listening");
179 status = RpcServerListen(OSI_MAXRPCCALLS, OSI_MAXRPCCALLS, 0);
180 if (status != RPC_S_OK) {
181 task = "Server Listen";
186 (void) RpcEpUnregister(afsrpc_v1_0_s_ifspec, ptrBindingVector,
189 if (ptrBindingVector)
190 (void) RpcBindingVectorFree(&ptrBindingVector);
193 (void) RpcServerUnregisterIf(afsrpc_v1_0_s_ifspec, NULL, FALSE);
195 if (status != RPC_S_OK)
196 afsi_log("RPC problem, code %d for %s", status, task);
198 afsi_log("RPC shutdown");
200 if (rpc_ShutdownEvent != NULL)
201 thrd_SetEvent(rpc_ShutdownEvent);
207 LONG status = ERROR_SUCCESS;
209 ULONG listenThreadID = 0;
210 char * name = "afsd_rpc_ShutdownEvent";
212 lock_InitializeMutex(&tokenEventLock, "token event lock",
213 LOCK_HIERARCHY_TOKEN_EVENT_GLOBAL);
215 rpc_ShutdownEvent = thrd_CreateEvent(NULL, FALSE, FALSE, name);
216 if ( GetLastError() == ERROR_ALREADY_EXISTS )
217 afsi_log("Event Object Already Exists: %s", name);
219 listenThread = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)RpcListen,
220 0, 0, &listenThreadID);
222 if (listenThread == NULL) {
223 status = GetLastError();
225 CloseHandle(listenThread);
230 void RpcShutdown(void)
232 RpcMgmtStopServerListening(NULL);
234 if (rpc_ShutdownEvent != NULL) {
235 thrd_WaitForSingleObject_Event(rpc_ShutdownEvent, INFINITE);
236 CloseHandle(rpc_ShutdownEvent);