#include "krb.h"
#include "krb4int.h"
#include "autoconf.h"
#ifdef _WIN32
#include <errno.h>
typedef DWORD OSErr;
#define noErr 0
#define cKrbCredsDontExist 12001
#define cKrbSessDoesntExist 12002
#define memFullErr ENOMEM
#endif
#ifndef unix
#ifdef _AIX
#define unix
#endif
#endif
#ifdef unix
#include <stdio.h>
#include <errno.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#else
extern char *malloc (), *realloc ();
#endif
typedef int OSErr;
#define noErr 0
#define memFullErr ENOMEM
#endif
#include "memcache.h"
static int fNumSessions = 0;
static Session **fSessions = 0;
#ifndef _WIN32
#define change_cache()
#endif
#if defined (_WIN32) || defined (unix)
#define Handle char **
#define Size int
static OSErr memerror = noErr;
Handle
NewHandleSys(s)
int s;
{
Handle h;
h = (char **) malloc(sizeof(char *));
if (h == NULL) {
memerror = memFullErr;
return (NULL);
}
if (s > 0) {
*h = malloc(s);
if (*h == NULL) {
free(h);
memerror = memFullErr;
return (NULL);
}
}
else
*h = NULL;
memerror = noErr;
return h;
}
void
DisposHandle(h)
Handle h;
{
if (*h != NULL)
free(*h);
free(h);
}
void
SetHandleSize(h, s)
Handle h;
int s;
{
if (*h != NULL) {
if (s > 0) {
*h = realloc(*h, s);
if (*h == NULL) {
memerror = memFullErr;
return;
}
}
else {
free(*h);
*h = NULL;
}
}
else {
if (s > 0) {
*h = malloc(s);
if (*h == NULL) {
memerror = memFullErr;
return;
}
}
}
memerror = noErr;
}
OSErr
MemError()
{
return memerror;
}
#endif
#ifdef _WIN32
void
change_cache()
{
char fname[260];
static BOOL locked = FALSE;
if (fNumSessions > 0 && !locked) {
GetModuleFileName(get_lib_instance(), fname, sizeof(fname));
LoadLibrary(fname);
locked = TRUE;
}
else if (fNumSessions == 0 && locked) {
FreeLibrary(get_lib_instance());
locked = FALSE;
}
PostMessage(HWND_BROADCAST, krb_get_notification_message(), 0, 0);
}
unsigned int
krb_get_notification_message(void)
{
static UINT message = 0;
if (message == 0)
message = RegisterWindowMessage(WM_KERBEROS_CHANGED);
return message;
}
#endif
char uname[] = "Fixed User";
char uinstance[] = "Fixed Instance";
char urealm[] = "Fixed Realm";
static char curr_auth_uname [ANAME_SZ];
static char curr_auth_uinst [INST_SZ];
int KRB5_CALLCONV
in_tkt(pname,pinst)
char *pname;
char *pinst;
{
int retval;
strncpy (curr_auth_uname, pname, ANAME_SZ);
strncpy (curr_auth_uinst, pinst, INST_SZ);
krb_set_default_user (pname);
retval = dest_tkt();
if (!retval)
return retval;
else
return KSUCCESS;
}
int KRB5_CALLCONV
krb_in_tkt(pname, pinst, prealm)
char *pname;
char *pinst;
char *prealm;
{
return in_tkt(pname, pinst);
}
int KRB5_CALLCONV
dest_tkt()
{
OSErr err;
err = DeleteSession(uname, uinstance, urealm);
change_cache();
switch(err) {
case noErr:
return RET_OK;
case cKrbSessDoesntExist:
return RET_TKFIL;
default:
return KFAILURE;
}
}
int dest_all_tkts()
{
int i=0;
char name[ANAME_SZ], inst[INST_SZ], realm[REALM_SZ];
int ndeletes=0;
int err=0;
(void) GetNumSessions(&i);
if(!i) return RET_TKFIL;
for( ; i; i--) {
if(!GetNthSession(i, name, inst, realm)) {
if (err = DeleteSession(name, inst, realm))
break;
ndeletes++;
}
else {
err = KFAILURE;
break;
}
}
if (ndeletes > 0)
change_cache();
if (err)
return KFAILURE;
else
return KSUCCESS;
}
int KRB5_CALLCONV
krb_get_tf_realm (tktfile, lrealm)
char *tktfile;
char *lrealm;
{
return krb_get_tf_fullname(tktfile, (char*) 0, (char*) 0 , lrealm);
}
int KRB5_CALLCONV
krb_get_tf_fullname (tktfile, name, instance, realm)
char *tktfile;
char *name;
char *instance;
char *realm;
{
OSErr err;
err = GetNthCredentials(uname, uinstance, urealm, name,
instance, realm, 1);
if (err != noErr)
return NO_TKT_FIL;
if (name)
strcpy(name, curr_auth_uname);
if (instance)
strcpy(instance, curr_auth_uinst);
return KSUCCESS;
}
int KRB5_CALLCONV
krb_get_cred (service, instance, realm, c)
char *service;
char *instance;
char *realm;
CREDENTIALS *c;
{
strcpy(c->service, service);
strcpy(c->instance, instance);
strcpy(c->realm, realm);
switch(GetCredentials(uname, uinstance, urealm, c)) {
case noErr:
return KSUCCESS;
case cKrbCredsDontExist:
case cKrbSessDoesntExist:
return GC_NOTKT;
default:
return KFAILURE;
}
}
int
krb4int_save_credentials_addr(sname, sinst, srealm, session,
lifetime, kvno, ticket, issue_date, laddr)
char* sname;
char* sinst;
char* srealm;
C_Block session;
int lifetime;
int kvno;
KTEXT ticket;
KRB4_32 issue_date;
KRB_UINT32 laddr;
{
CREDENTIALS cr;
strcpy(cr.service, sname);
strcpy(cr.instance, sinst);
strcpy(cr.realm, srealm);
memcpy((void*)cr.session, (void*)session, sizeof(C_Block));
cr.lifetime = lifetime;
cr.kvno = kvno;
cr.ticket_st = *ticket;
cr.issue_date = issue_date;
strcpy(cr.pname, curr_auth_uname);
strcpy(cr.pinst, curr_auth_uinst);
if(AddCredentials(uname, uinstance, urealm, &cr)) return KFAILURE;
change_cache();
return KSUCCESS;
}
int KRB5_CALLCONV
krb_save_credentials(
char *name,
char *inst,
char *realm,
C_Block session,
int lifetime,
int kvno,
KTEXT ticket,
KRB4_32 issue_date)
{
return krb4int_save_credentials_addr(name, inst, realm, session,
lifetime, kvno, ticket,
issue_date, 0);
}
int
krb_delete_cred (sname, sinstance, srealm)
char *sname;
char *sinstance;
char *srealm;
{
if (DeleteCredentials (uname, uinstance, urealm, sname, sinstance, srealm))
return KFAILURE;
change_cache();
return KSUCCESS;
}
int
krb_get_nth_cred (sname, sinstance, srealm, n)
char *sname;
char *sinstance;
char *srealm;
int n;
{
if (GetNthCredentials(uname, uinstance, urealm, sname, sinstance, srealm, n))
return KFAILURE;
else
return KSUCCESS;
}
int
krb_get_num_cred ()
{
int n;
int s;
s = GetNumCredentials(uname, uinstance, urealm, &n);
if (s) return -1;
else return n;
}
OSErr GetNumSessions(n)
int *n;
{
*n = fNumSessions;
return 0;
}
OSErr
GetNthSession(n, name, instance, realm)
const int n;
char *name;
char *instance;
char *realm;
{
Session *sptr;
if(n > fNumSessions || !fSessions) return cKrbSessDoesntExist;
sptr = (*fSessions) + n-1;
if (name) strcpy(name, sptr->name);
if (instance) strcpy(instance, sptr->instance);
if (realm) strcpy(realm, sptr->realm);
return noErr;
}
OSErr DeleteSession(name, instance, realm)
const char *name;
const char *instance;
const char *realm;
{
int i;
Session *sptr;
Handle creds;
if(!fNumSessions || !fSessions) return cKrbSessDoesntExist;
sptr = *fSessions;
for(i = 0; i < fNumSessions; i++) {
if(!strcmp(sptr[i].name, name) &&
!strcmp(sptr[i].instance, instance) &&
!strcmp(sptr[i].realm, realm)) {
break;
}
}
if(i == fNumSessions) return cKrbSessDoesntExist;
fNumSessions--;
creds = (Handle) sptr[i].creds;
for( ; i < fNumSessions; i++) {
strcpy(sptr[i].name, sptr[i+1].name);
strcpy(sptr[i].instance, sptr[i+1].instance);
strcpy(sptr[i].realm, sptr[i+1].realm);
}
SetHandleSize((Handle) fSessions, fNumSessions * sizeof(Session));
if(creds) DisposHandle(creds);
return MemError();
}
OSErr GetCredentials(name, instance, realm, cr)
const char *name;
const char *instance;
const char *realm;
CREDENTIALS *cr;
{
int i;
Session *sptr;
CREDENTIALS *cptr;
if(!fNumSessions || !fSessions) return cKrbSessDoesntExist;
sptr = *fSessions;
for(i = 0; i < fNumSessions; i++) {
if(!strcmp(sptr[i].name, name) &&
!strcmp(sptr[i].instance, instance) &&
!strcmp(sptr[i].realm, realm)) {
break;
}
}
if(i == fNumSessions) return cKrbSessDoesntExist;
sptr = sptr + i;
if(!sptr->numcreds || !sptr->creds) return cKrbCredsDontExist;
cptr = *(sptr->creds);
for(i = 0; i < sptr->numcreds; i++) {
if(!strcmp(cptr[i].service, cr->service) &&
!strcmp(cptr[i].instance, cr->instance) &&
!strcmp(cptr[i].realm, cr->realm)) {
break;
}
}
if(i == sptr->numcreds) return cKrbCredsDontExist;
*cr = cptr[i];
return noErr;
}
OSErr AddCredentials(name, instance, realm, cr)
const char *name;
const char *instance;
const char *realm;
const CREDENTIALS *cr;
{
Session *sptr;
Handle creds;
int i, thesess;
CREDENTIALS *cptr;
if(!fSessions) {
fSessions = (Session**) NewHandleSys(0);
if(MemError()) return MemError();
fNumSessions = 0;
}
sptr = *fSessions;
for(thesess = 0; thesess < fNumSessions; thesess++) {
if(!strcmp(sptr[thesess].name, name) &&
!strcmp(sptr[thesess].instance, instance) &&
!strcmp(sptr[thesess].realm, realm)) {
break;
}
}
sptr = (*fSessions) + thesess;
if(thesess == fNumSessions) {
fNumSessions++;
SetHandleSize((Handle) fSessions, fNumSessions * sizeof(Session));
if(MemError()) return MemError();
sptr = (*fSessions) + thesess;
strcpy(sptr->name, (char *)name);
strcpy(sptr->instance, (char *)instance);
strcpy(sptr->realm, (char *)realm);
sptr->numcreds = 0;
sptr->creds = 0;
}
if(!sptr->numcreds || !sptr->creds) {
creds = NewHandleSys((Size) 0);
if(MemError()) return MemError();
sptr = (*fSessions) + thesess;
sptr->creds = (CREDENTIALS **)creds;
sptr->numcreds = 0;
}
cptr = *(sptr->creds);
for(i = 0; i < sptr->numcreds; i++) {
if(!strcmp(cptr[i].service, cr->service) &&
!strcmp(cptr[i].instance, cr->instance) &&
!strcmp(cptr[i].realm, cr->realm)) {
break;
}
}
if(i == sptr->numcreds) {
sptr->numcreds++;
SetHandleSize((Handle)sptr->creds, sptr->numcreds * sizeof(CREDENTIALS));
if(MemError()) return MemError();
sptr = (*fSessions) + thesess;
cptr = *(sptr->creds);
}
cptr[i] = *cr;
return noErr;
}
OSErr
DeleteCredentials (uname, uinst, urealm, sname, sinst, srealm)
const char *uname;
const char *uinst;
const char *urealm;
const char *sname;
const char *sinst;
const char *srealm;
{
int i;
Session *sptr;
CREDENTIALS *cptr;
if(!fNumSessions || !fSessions) return cKrbSessDoesntExist;
sptr = *fSessions;
for(i = 0; i < fNumSessions; i++) {
if(!strcmp(sptr[i].name, uname) &&
!strcmp(sptr[i].instance, uinstance) &&
!strcmp(sptr[i].realm, urealm)) {
break;
}
}
if(i == fNumSessions) return cKrbSessDoesntExist;
sptr = sptr + i;
if(!sptr->numcreds || !sptr->creds) return cKrbCredsDontExist;
cptr = *(sptr->creds);
for(i = 0; i < sptr->numcreds; i++) {
if(!strcmp(cptr[i].service, sname) &&
!strcmp(cptr[i].instance, sinst) &&
!strcmp(cptr[i].realm, srealm)) {
break;
}
}
if(i == sptr->numcreds) return cKrbCredsDontExist;
sptr->numcreds--;
for( ; i < sptr->numcreds; i++) {
cptr[i] = cptr[i+1];
}
SetHandleSize((Handle) sptr->creds, sptr->numcreds * sizeof(CREDENTIALS));
return MemError();
}
OSErr GetNumCredentials(name, instance, realm, n)
const char *name;
const char *instance;
const char *realm;
int *n;
{
int i;
Session *sptr;
if(!fNumSessions || !fSessions) {
*n = 0;
return cKrbSessDoesntExist;
}
sptr = *fSessions;
for(i = 0; i < fNumSessions; i++) {
if(!strcmp(sptr[i].name, name) &&
!strcmp(sptr[i].instance, instance) &&
!strcmp(sptr[i].realm, realm)) {
break;
}
}
if(i == fNumSessions) {
*n = 0;
return cKrbCredsDontExist;
}
*n = sptr[i].numcreds;
return noErr;
}
OSErr
GetNthCredentials(uname, uinstance, urealm, sname, sinst, srealm, n)
const char *uname;
const char *uinstance;
const char *urealm;
char *sname;
char *sinst;
char *srealm;
const int n;
{
int i;
Session *sptr;
CREDENTIALS *cptr;
if(!fNumSessions || !fSessions) return cKrbSessDoesntExist;
sptr = *fSessions;
for(i = 0; i < fNumSessions; i++) {
if(!strcmp(sptr[i].name, uname) &&
!strcmp(sptr[i].instance, uinstance) &&
!strcmp(sptr[i].realm, urealm)) {
break;
}
}
if(i == fNumSessions) return cKrbSessDoesntExist;
sptr = (*fSessions) + i;
if(n > sptr->numcreds || !sptr->creds) return cKrbCredsDontExist;
cptr = (*(sptr->creds)) + n-1;
if (sname)
strcpy(sname, cptr->service);
if (sinst)
strcpy(sinst, cptr->instance);
if (srealm)
strcpy(srealm, cptr->realm);
return noErr;
}