#include <afsconfig.h>
#include <afs/param.h>
+#include <afs/stds.h>
+#include <roken.h>
-#include <afs/stds.h>
-#include <stdio.h>
-#include <afs/pthread_glock.h>
-#include <sys/types.h>
#include <ctype.h>
-#include <sys/stat.h>
-#include <signal.h>
-#include <errno.h>
+
+#include <afs/pthread_glock.h>
#include <rpc.h>
#include <afs/smb_iocons.h>
#include <afs/pioctl_nt.h>
static char AFSGlobalKTCMutexName[] = "Global\\AFS_KTC_Mutex";
static char AFSKTCMutexName[] = "AFS_KTC_Mutex";
+#define MAXPIOCTLTOKENLEN \
+(3*sizeof(afs_int32)+MAXKTCTICKETLEN+sizeof(struct ClearToken)+MAXKTCREALMLEN)
+
/*
* Support for RPC's to send and receive session keys
*
void __RPC_FAR *__RPC_USER
midl_user_allocate(size_t cBytes)
{
- return ((void __RPC_FAR *)malloc(cBytes));
+ return malloc(cBytes);
}
void __RPC_USER
tp += sizeof(uuid);
len += sizeof(uuid);
-#ifndef AFS_WIN95_ENV
ktcMutex = CreateMutex(NULL, TRUE, AFSGlobalKTCMutexName);
if (ktcMutex == NULL)
- return KTC_PIOCTLFAIL;
+ return KTC_TOKEN_MUTEX_FAIL;
if (GetLastError() == ERROR_ALREADY_EXISTS) {
if (WaitForSingleObject(ktcMutex, INFINITE) != WAIT_OBJECT_0) {
CloseHandle(ktcMutex);
- return KTC_PIOCTLFAIL;
+ return KTC_TOKEN_MUTEX_FAIL;
}
}
strcpy(rpcErr, "RPC failure in AFS gateway");
else
DceErrorInqText(status, rpcErr);
- if (status == RPC_S_SERVER_UNAVAILABLE ||
+
+ ReleaseMutex(ktcMutex);
+ CloseHandle(ktcMutex);
+
+ if (status == RPC_S_SERVER_UNAVAILABLE ||
status == EPT_S_NOT_REGISTERED) {
- ReleaseMutex(ktcMutex);
- CloseHandle(ktcMutex);
return KTC_NOCMRPC;
} else {
- ReleaseMutex(ktcMutex);
- CloseHandle(ktcMutex);
return KTC_RPC;
}
}
-#endif /* AFS_WIN95_ENV */
/* set up for pioctl */
iob.in = tbuffer;
code = pioctl(0, VIOCSETTOK, &iob, 0);
-#ifndef AFS_WIN95_ENV
ReleaseMutex(ktcMutex);
CloseHandle(ktcMutex);
-#endif /* AFS_WIN95_ENV */
if (code) {
if (code == -1) {
{
struct ViceIoctl iob;
char tbuffer[TBUFFERSIZE];
- int len;
+ size_t len;
char *tp, *cp;
char *ticketP;
int ticketLen, temp;
iob.out = tbuffer;
iob.out_size = sizeof(tbuffer);
-#ifndef AFS_WIN95_ENV
ktcMutex = CreateMutex(NULL, TRUE, AFSGlobalKTCMutexName);
if (ktcMutex == NULL)
- return KTC_PIOCTLFAIL;
+ return KTC_TOKEN_MUTEX_FAIL;
if (GetLastError() == ERROR_ALREADY_EXISTS) {
if (WaitForSingleObject(ktcMutex, INFINITE) != WAIT_OBJECT_0) {
CloseHandle(ktcMutex);
- return KTC_PIOCTLFAIL;
+ return KTC_TOKEN_MUTEX_FAIL;
}
}
-#endif /* AFS_WIN95_ENV */
code = pioctl(0, VIOCNEWGETTOK, &iob, 0);
if (code) {
-#ifndef AFS_WIN95_ENV
ReleaseMutex(ktcMutex);
CloseHandle(ktcMutex);
-#endif /* AFS_WIN95_ENV */
+
if (code == -1) {
if (errno == ESRCH)
return KTC_NOCELL;
} else
return KTC_PIOCTLFAIL;
}
-#ifndef AFS_WIN95_ENV
- /* get rid of RPC for win95 build */
+
/* RPC to receive session key */
status = receive_key(uuid, token->sessionKey.data);
CloseHandle(ktcMutex);
if (status != RPC_S_OK) {
- if (status == 1)
- strcpy(rpcErr, "RPC failure in AFS gateway");
- else
- DceErrorInqText(status, rpcErr);
- if (status == RPC_S_SERVER_UNAVAILABLE
- || status == EPT_S_NOT_REGISTERED)
- return KTC_NOCMRPC;
- else
- return KTC_RPC;
+ if (status == 1)
+ strcpy(rpcErr, "RPC failure in AFS gateway");
+ else
+ DceErrorInqText(status, rpcErr);
+
+ if (status == RPC_S_SERVER_UNAVAILABLE ||
+ status == EPT_S_NOT_REGISTERED)
+ return KTC_NOCMRPC;
+ else
+ return KTC_RPC;
}
-#endif /* AFS_WIN95_ENV */
cp = tbuffer;
*/
int
ktc_GetTokenEx(char *cellName, struct ktc_setTokenData **tokenSet) {
- return KTC_PIOCTLFAIL;
+ struct ViceIoctl iob;
+ char tbuffer[MAXPIOCTLTOKENLEN];
+ char *tp;
+ afs_int32 code;
+ XDR xdrs;
+ HANDLE ktcMutex = NULL;
+
+ tp = tbuffer;
+
+ /* If we have a cellName, write it out here */
+ if (cellName) {
+ memcpy(tp, cellName, strlen(cellName) +1);
+ tp += strlen(cellName)+1;
+ }
+
+ iob.in = tbuffer;
+ iob.in_size = tp - tbuffer;
+ iob.out = tbuffer;
+ iob.out_size = sizeof(tbuffer);
+
+ ktcMutex = CreateMutex(NULL, TRUE, AFSGlobalKTCMutexName);
+ if (ktcMutex == NULL)
+ return KTC_TOKEN_MUTEX_FAIL;
+ if (GetLastError() == ERROR_ALREADY_EXISTS) {
+ if (WaitForSingleObject(ktcMutex, INFINITE) != WAIT_OBJECT_0) {
+ CloseHandle(ktcMutex);
+ return KTC_TOKEN_MUTEX_FAIL;
+ }
+ }
+
+#if 0
+ code = pioctl(0, VIOC_GETTOK2, &iob, 0);
+#else
+ code = -1; /* not yet implemented */
+ errno = EINVAL;
+#endif
+
+ ReleaseMutex(ktcMutex);
+ CloseHandle(ktcMutex);
+
+ /* If we can't use the new pioctl, the fall back to the old one. We then
+ * need to convert the rxkad token we get back into the new format
+ */
+ if (code == -1 && errno == EINVAL) {
+ struct ktc_principal server;
+ struct ktc_principal client;
+ struct ktc_tokenUnion token;
+ struct ktc_token *ktcToken; /* too huge for the stack */
+
+ memset(&server, 0, sizeof(server));
+ ktcToken = malloc(sizeof(struct ktc_token));
+ if (ktcToken == NULL)
+ return ENOMEM;
+ memset(ktcToken, 0, sizeof(struct ktc_token));
+
+ strcpy(server.name, "afs");
+ strcpy(server.cell, cellName);
+ code = ktc_GetToken(&server, ktcToken, sizeof(struct ktc_token),
+ &client);
+ if (code == 0) {
+ *tokenSet = token_buildTokenJar(cellName);
+ token.at_type = AFSTOKEN_UNION_KAD;
+ token.ktc_tokenUnion_u.at_kad.rk_kvno = ktcToken->kvno;
+ memcpy(token.ktc_tokenUnion_u.at_kad.rk_key,
+ ktcToken->sessionKey.data, 8);
+
+ token.ktc_tokenUnion_u.at_kad.rk_begintime = ktcToken->startTime;
+ token.ktc_tokenUnion_u.at_kad.rk_endtime = ktcToken->endTime;
+ token.ktc_tokenUnion_u.at_kad.rk_ticket.rk_ticket_len
+ = ktcToken->ticketLen;
+ token.ktc_tokenUnion_u.at_kad.rk_ticket.rk_ticket_val
+ = ktcToken->ticket;
+
+ token_addToken(*tokenSet, &token);
+
+ memset(ktcToken, 0, sizeof(struct ktc_token));
+ }
+ free(ktcToken);
+ return code;
+ }
+ if (code)
+ return KTC_PIOCTLFAIL;
+
+ *tokenSet = malloc(sizeof(struct ktc_setTokenData));
+ if (*tokenSet == NULL)
+ return ENOMEM;
+ memset(*tokenSet, 0, sizeof(struct ktc_setTokenData));
+
+ xdrmem_create(&xdrs, iob.out, iob.out_size, XDR_DECODE);
+ if (!xdr_ktc_setTokenData(&xdrs, *tokenSet)) {
+ free(*tokenSet);
+ *tokenSet = NULL;
+ xdr_destroy(&xdrs);
+ return EINVAL;
+ }
+ xdr_destroy(&xdrs);
+ return 0;
}
int
int code;
HANDLE ktcMutex = NULL;
-#ifndef AFS_WIN95_ENV
ktcMutex = CreateMutex(NULL, TRUE, AFSGlobalKTCMutexName);
if (ktcMutex == NULL)
- return KTC_PIOCTLFAIL;
+ return KTC_TOKEN_MUTEX_FAIL;
if (GetLastError() == ERROR_ALREADY_EXISTS) {
if (WaitForSingleObject(ktcMutex, INFINITE) != WAIT_OBJECT_0) {
CloseHandle(ktcMutex);
- return KTC_PIOCTLFAIL;
+ return KTC_TOKEN_MUTEX_FAIL;
}
}
-#endif /* AFS_WIN95_ENV */
tp = tbuffer;
code = pioctl(0, VIOCGETTOK, &iob, 0);
-#ifndef AFS_WIN95_ENV
ReleaseMutex(ktcMutex);
CloseHandle(ktcMutex);
-#endif /* AFS_WIN95_ENV */
if (code) {
if (code == -1) {
if (strcmp(server->name, "afs")) {
return ForgetOneLocalToken(server);
}
-#ifndef AFS_WIN95_ENV
ktcMutex = CreateMutex(NULL, TRUE, AFSGlobalKTCMutexName);
if (ktcMutex == NULL)
- return KTC_PIOCTLFAIL;
+ return KTC_TOKEN_MUTEX_FAIL;
if (GetLastError() == ERROR_ALREADY_EXISTS) {
if (WaitForSingleObject(ktcMutex, INFINITE) != WAIT_OBJECT_0) {
CloseHandle(ktcMutex);
- return KTC_PIOCTLFAIL;
+ return KTC_TOKEN_MUTEX_FAIL;
}
}
-#endif /* AFS_WIN95_ENV */
tp = tbuffer;
iob.out_size = sizeof(tbuffer);
code = pioctl(0, VIOCDELTOK, &iob, 0);
-#ifndef AFS_WIN95_ENV
ReleaseMutex(ktcMutex);
CloseHandle(ktcMutex);
-#endif /* AFS_WIN95_ENV */
+
if (code) {
if (code == -1) {
if (errno == ESRCH)
(void)ForgetLocalTokens();
-#ifndef AFS_WIN95_ENV
ktcMutex = CreateMutex(NULL, TRUE, AFSGlobalKTCMutexName);
if (ktcMutex == NULL)
- return KTC_PIOCTLFAIL;
+ return KTC_TOKEN_MUTEX_FAIL;
if (GetLastError() == ERROR_ALREADY_EXISTS) {
if (WaitForSingleObject(ktcMutex, INFINITE) != WAIT_OBJECT_0) {
CloseHandle(ktcMutex);
- return KTC_PIOCTLFAIL;
+ return KTC_TOKEN_MUTEX_FAIL;
}
}
-#endif /* AFS_WIN95_ENV */
/* do pioctl */
iob.in = tbuffer;
iob.out_size = sizeof(tbuffer);
code = pioctl(0, VIOCDELALLTOK, &iob, 0);
-#ifndef AFS_WIN95_ENV
ReleaseMutex(ktcMutex);
CloseHandle(ktcMutex);
-#endif /* AFS_WIN95_ENV */
+
if (code) {
if (code == -1) {
if (errno == ENODEV)
int
ktc_ListTokensEx(int prevIndex, int *newIndex, char **cellName) {
+ struct ViceIoctl iob;
+ char tbuffer[MAXPIOCTLTOKENLEN];
+ afs_int32 code;
+ afs_int32 index;
+ struct ktc_setTokenData tokenSet;
+ XDR xdrs;
+ HANDLE ktcMutex = NULL;
+
+ memset(&tokenSet, 0, sizeof(tokenSet));
+
*cellName = NULL;
+ *newIndex = prevIndex;
+
+ index = prevIndex;
+
+ while (index<100) { /* Safety, incase of pioctl failure */
+ memset(tbuffer, 0, sizeof(tbuffer));
+ iob.in = tbuffer;
+ memcpy(tbuffer, &index, sizeof(afs_int32));
+ iob.in_size = sizeof(afs_int32);
+ iob.out = tbuffer;
+ iob.out_size = sizeof(tbuffer);
+
+#if 0
+ code = pioctl(0, VIOC_GETTOK2, &iob, 0);
+#else
+ code = -1; /* not yet implemented */
+ errno = EINVAL;
+#endif
+
+ /* Can't use new pioctl, so must use old one */
+ if (code == -1 && errno == EINVAL) {
+ struct ktc_principal server;
+
+ code = ktc_ListTokens(index, newIndex, &server);
+ if (code == 0)
+ *cellName = strdup(server.cell);
+ return code;
+ }
+
+ if (code == 0) {
+ /* Got a token from the pioctl. Now we throw it away,
+ * so we can return just a cellname. This is rather wasteful,
+ * but it's what the old API does. Ho hum. */
+
+ xdrmem_create(&xdrs, iob.out, iob.out_size, XDR_DECODE);
+ if (!xdr_ktc_setTokenData(&xdrs, &tokenSet)) {
+ xdr_destroy(&xdrs);
+ return EINVAL;
+ }
+ xdr_destroy(&xdrs);
+ *cellName = strdup(tokenSet.cell);
+ xdr_free((xdrproc_t)xdr_ktc_setTokenData, &tokenSet);
+ *newIndex = index + 1;
+ return 0;
+ }
+ index++;
+ }
return KTC_PIOCTLFAIL;
}