1/*
2	KClient.c -- Application library for KClient
3
4	� Copyright 1994,1995 by Cornell University
5
6	Initial coding 8/94 by Peter Bosanko.
7*/
8
9#ifndef _KrbDriver_
10#include "krbdriver.h"
11#endif
12
13#ifndef _DEVICES_
14#include	<Devices.h>
15#endif
16
17#include "kcglue_des.h"
18
19#define KC_SESSION ((KClientRec *)session)
20#define KC_PB (&(((KClientRec *)session)->hiParm))
21#define OLD_KC_PB ((krbHiParmBlock *)session)
22#define PICK_PARM (kcRec ? (void*) kcRec : (void*) pb)
23#define KCLIENTDRIVER "\p.Kerberos"
24
25/* Forward Declarations */
26
27OSErr KClientSendMessage(short msg, void *parm);
28OSErr KClientSetPassword(  KClientSessionInfo *session, char *password  );
29krbHiParmBlock *KClientSessionKind(  KClientSessionInfo *session, KClientRec **kcRec );
30OSErr _KClientVersion( StringPtr driver, short *majorVersion, short *minorVersion, char *versionString );
31
32/*
33 * call into des ecb_encrypt
34 */
35/* created by n3liw+@cmu.edu to support SASL, need to be able to specify checksum */
36int KClient_des_ecb_encrypt(KClientSessionInfo  *session,des_cblock v1,des_cblock v2,int do_encrypt)
37{
38	KClientKey sessionKey;
39	Key_schedule schedule;
40
41	int rc=KClientGetSessionKey(session,&sessionKey);
42	if(rc!=0)
43		return rc;
44	rc=kcglue_des_key_sched(&sessionKey,schedule);
45	if(rc!=0)
46		return rc;
47	kcglue_des_ecb_encrypt(v1,v2,schedule,do_encrypt);
48	return rc;
49}
50
51/*
52 * call into des pcbc_encrypt
53 */
54/* created by n3liw+@cmu.edu to support SASL, need to be able to specify checksum */
55int KClient_des_pcbc_encrypt(KClientSessionInfo  *session,des_cblock v1,des_cblock v2,long len,int do_encrypt)
56{
57	KClientKey sessionKey;
58	Key_schedule schedule;
59
60	int rc=KClientGetSessionKey(session,&sessionKey);
61	if(rc!=0)
62		return rc;
63	rc=kcglue_des_key_sched(&sessionKey,schedule);
64	if(rc!=0)
65		return rc;
66	kcglue_des_pcbc_encrypt(v1,v2,len,schedule,&sessionKey,do_encrypt);
67	return rc;
68}
69
70/*---------------------------------------------------------------------------------------------------*/
71OSErr KClientSendMessage(short msg, void *parm)
72{
73	ParamBlockRec aPBR;
74	short refNum = 0;
75
76/**************************************************
77	OK to "open" driver everytime because driver
78	just returns if it's already open.
79	This saves us from having to pass around refNum
80	or store it in a global.
81***************************************************/
82
83	OSErr err = OpenDriver(KCLIENTDRIVER,&refNum);
84	if (err) return err;
85
86	aPBR.cntrlParam.ioCompletion = nil;
87	aPBR.cntrlParam.ioVRefNum = 0;
88	aPBR.cntrlParam.ioCRefNum = refNum;
89	aPBR.cntrlParam.csCode = msg;
90	BlockMove(&parm,aPBR.cntrlParam.csParam,sizeof(parm));
91
92	(void) PBControlImmed( &aPBR );
93
94	err = aPBR.cntrlParam.ioResult;
95	return err;
96}
97
98/*---------------------------------------------------------------------------------------------------*/
99krbHiParmBlock *KClientSessionKind(  KClientSessionInfo *session, KClientRec **kcRec )
100{
101	if (KC_SESSION->tag==NEW_KCLIENT_TAG) {
102		/* Newer driver, use newer session record */
103		if (kcRec)
104			*kcRec 		= KC_SESSION;
105		return KC_PB;
106	}
107	else {
108		if (kcRec)
109			*kcRec 		= NULL;
110		return OLD_KC_PB;
111	}
112}
113
114/*---------------------------------------------------------------------------------------------------*/
115OSErr KClientSetPassword(  KClientSessionInfo *session, char *password  )
116{
117	KClientRec *kcRec;
118	krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
119
120	pb->user = password;
121	return KClientSendMessage(cKrbSetPassword,PICK_PARM);
122}
123
124/*---------------------------------------------------------------------------------------------------*/
125OSErr KClientNewSession(KClientSessionInfo *session, unsigned long lAddr,unsigned short lPort,unsigned long fAddr,unsigned short fPort)
126{
127	OSErr err;
128
129	err = KClientSendMessage(cKrbNewClientSession,KC_SESSION);
130
131	if (err==cKrbBadSelector) {
132		/* old driver, so initialize by hand */
133		short i,e = sizeof(KClientSessionInfo) / sizeof(long);
134		long *s = (long *) session;
135		for (i=0;i<e;i++) *s++ = 0;
136		err = noErr;
137	}
138
139	KC_SESSION->libVersion		= 2;
140	KC_PB->lAddr 				= lAddr;
141	KC_PB->lPort 				= lPort;
142	KC_PB->fAddr 				= fAddr;
143	KC_PB->fPort 				= fPort;
144
145	return err;
146}
147
148/*---------------------------------------------------------------------------------------------------*/
149OSErr KClientDisposeSession(KClientSessionInfo *session)
150{
151	KClientRec *kcRec;
152	(void) KClientSessionKind(session,&kcRec);
153
154	if (kcRec)
155		return KClientSendMessage(cKrbDisposeSession,session);
156
157	return noErr;
158}
159
160/*---------------------------------------------------------------------------------------------------*/
161/*
162 * modified by n3liw+@cmu.edu to support SASL, need to be able to specify checksum
163 */
164OSErr KClientGetTicketForService(KClientSessionInfo *session, char *service,void *buf,unsigned long *buflen)
165{
166	return KClientGetTicketForServiceFull(session,service,buf,buflen,0);
167}
168
169#include <stdio.h>
170#include <string.h>
171
172/*
173 * store the passed long in network byte order
174 */
175static char *put_long(char *dst,long aval)
176{
177	*dst++=aval>>24;
178	*dst++=aval>>16;
179	*dst++=aval>>8;
180	*dst++=aval;
181	return dst;
182}
183
184/*
185 * - int = 1 byte
186 * - long = 4 bytes
187 * long length of all the following [kclientism]
188 * ticket format, from reading mk_req.c
189 * int KRB_PROT_VERSION
190 * int AUTH_MSG_APPL_REQUEST
191 * int key version numbner
192 * string realm
193 * int ticket length
194 * int authenticator length
195 * ticket
196 * authenticator [
197 *   string name
198 *   string instance
199 *   string realm
200 *   long checksum
201 *   byte GMT microseconds/5
202 *   int GMT time
203 * ] encrypted in session key
204 */
205
206/*---------------------------------------------------------------------------------------------------*/
207/*
208 * created by n3liw+@cmu.edu to support SASL, need to be able to specify checksum
209 */
210OSErr KClientGetTicketForServiceFull(KClientSessionInfo *session, char *service,void *buf,unsigned long *buflen,long cks)
211{
212	char *p=(char *)buf;
213	long tkt_len;
214	long auth_len;
215	char wbuf[1500];
216
217	OSErr err;
218	KClientRec *kcRec;
219	krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
220
221	pb->service = service;
222	pb->buf = (char *) buf;
223	pb->buflen = *buflen;
224	pb->checksum = cks;
225	err = KClientSendMessage(cKrbGetTicketForService,PICK_PARM);
226	*buflen = pb->buflen;
227	if(err!=0)
228		return err;
229	/*
230	 * if checksum is zero, buth kclientman and kclient will correctly get the ticket
231	 * if checksum is non zero, then kclientman will have incorrectly encoded 0 in the checksum
232	 * field of the authenticator, kclient will have encoded the correct checksum...
233	 * rather than check the underlying authentication package (kclient vs kclientman)
234	 * we will go ahead and decrypt the authenticator and fix the checksum.  this is unessary but
235	 * harmless for kclient.
236     */
237	if(cks==0)
238		return 0;
239	p+=4+3+strlen(p+7)+1; /*4 byte kclient len, vers,req, kvno*/
240	tkt_len= (*p++)&0x0ff;
241	auth_len= (*p++)&0x0ff;
242	p+=tkt_len;
243	err=KClient_des_pcbc_encrypt(session,(unsigned char *)p,(unsigned char *)wbuf,auth_len,0);
244	if(err!=0)
245		return err;
246	{
247		char *w=wbuf;
248		/* printf("name='%s'\n",w); */
249		w+=strlen(w)+1;	/*skip name */
250		/* printf("instance='%s'\n",w); */
251		w+=strlen(w)+1;	/*skip instance */
252		/* printf("realm='%s'\n",w); */
253		w+=strlen(w)+1; /*realm*/
254		w=put_long(w,cks);
255	}
256	err=KClient_des_pcbc_encrypt(session,(unsigned char *)wbuf,(unsigned char *)wbuf,auth_len,1);
257	memcpy(p,wbuf,auth_len);
258	return err;
259}
260
261/*---------------------------------------------------------------------------------------------------*/
262OSErr KClientLogin(  KClientSessionInfo *session, KClientKey *privateKey )
263{
264	OSErr err;
265	KClientRec *kcRec;
266	krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
267
268	pb->service = (char *) privateKey; /* pointer to private key in first 4 bytes */
269	err = KClientSendMessage(cKrbLogin,PICK_PARM);
270	return err;
271}
272
273/*---------------------------------------------------------------------------------------------------*/
274OSErr KClientSetPrompt(  KClientSessionInfo *session, char *prompt )
275{
276	KClientRec *kcRec;
277	(void) KClientSessionKind(session,&kcRec);
278
279	if (kcRec)
280		kcRec->prompt = prompt;
281	else return cKrbBadSelector;
282
283	return noErr;
284}
285
286/*---------------------------------------------------------------------------------------------------*/
287OSErr KClientPasswordLogin(  KClientSessionInfo *session, char *password, KClientKey *privateKey )
288{
289	OSErr err;
290
291	if ( ( err = KClientSetPassword(session,password) ) != noErr )
292		 return err;
293
294	return KClientLogin(session,privateKey);
295}
296
297/*---------------------------------------------------------------------------------------------------*/
298OSErr KClientPasswordToKey( char *password, KClientKey *privateKey )
299{
300	ParamBlockRec aPBR;
301	short refNum;
302	OSErr err;
303
304	if ( (err = OpenDriver(KCLIENTDRIVER,&refNum)) != noErr)
305		return err;
306
307	aPBR.cntrlParam.ioCompletion = nil;
308	aPBR.cntrlParam.ioVRefNum = 0;
309	aPBR.cntrlParam.ioCRefNum = refNum;
310	aPBR.cntrlParam.csCode = cKrbPasswordToKey;
311	((long *)aPBR.cntrlParam.csParam)[0] = (long)password;
312	((long *)aPBR.cntrlParam.csParam)[1] = (long)privateKey;
313
314	(void) PBControl( &aPBR, false );
315	return aPBR.cntrlParam.ioResult;
316}
317
318/*---------------------------------------------------------------------------------------------------*/
319OSErr KClientKeyLogin( KClientSessionInfo *session, KClientKey *privateKey )
320{
321	OSErr err;
322
323	err = KClientSendMessage(cKrbSetKey,privateKey);
324	if (err) return err;
325
326	return KClientLogin(session,privateKey);
327}
328
329/*---------------------------------------------------------------------------------------------------*/
330OSErr KClientLogout( )
331{
332	krbHiParmBlock	cpb;
333
334	return KClientSendMessage(cKrbDeleteAllSessions, &cpb);
335}
336
337/*---------------------------------------------------------------------------------------------------*/
338short KClientStatus( )
339{
340	char user[40];
341
342	user[0] = '\0';
343	(void) KClientGetUserName(user);
344	if (*user != 0)
345		return KClientLoggedIn;
346	return KClientNotLoggedIn;
347}
348
349/*---------------------------------------------------------------------------------------------------*/
350OSErr _KClientVersion( StringPtr driver, short *majorVersion, short *minorVersion, char *versionString )
351{
352	ParamBlockRec aPBR;
353	short refNum;
354	OSErr err;
355
356	if ( (err = OpenDriver(driver,&refNum)) != noErr)
357		return err;
358
359	aPBR.cntrlParam.ioCompletion = nil;
360	aPBR.cntrlParam.ioVRefNum = 0;
361	aPBR.cntrlParam.ioCRefNum = refNum;
362	aPBR.cntrlParam.csCode = cKrbDriverVersion;
363	((long *)aPBR.cntrlParam.csParam)[1] = (long)versionString;
364
365	(void) PBControl( &aPBR, false );
366	err = aPBR.cntrlParam.ioResult;
367
368	/* For pre-2.0, do some detective work */
369	if (err==cKrbBadSelector) {
370		*majorVersion = 1;
371		aPBR.cntrlParam.csCode = cKrbGetDesPointers;
372		((long *)aPBR.cntrlParam.csParam)[1] = 11; /* so it doesn't return anything */
373		(void) PBControl( &aPBR, false );
374		if (aPBR.cntrlParam.ioResult==cKrbOldDriver) {
375			*minorVersion = 1;
376			if (versionString)
377				*((long *)versionString) = '1.1\0';
378		}
379		else {
380			*minorVersion = 0;
381			if (versionString)
382				*((long *)versionString) = '1.0\0';
383		}
384		err = 0;
385	}
386	else {
387		*majorVersion = aPBR.cntrlParam.csParam[0];
388		*minorVersion = aPBR.cntrlParam.csParam[1];
389	}
390
391	return err;
392}
393
394/*---------------------------------------------------------------------------------------------------*/
395OSErr KClientVersion( short *majorVersion, short *minorVersion, char *versionString )
396{
397	return _KClientVersion(KCLIENTDRIVER,majorVersion,minorVersion,versionString);
398}
399
400/*---------------------------------------------------------------------------------------------------*/
401OSErr KClientGetUserName(char *user)
402{
403	OSErr err;
404	KClientSessionInfo s,*session = &s;
405
406	KC_SESSION->tag = 0;
407	OLD_KC_PB->user = user;
408	err = KClientSendMessage(cKrbGetUserName,session);
409	return err;
410}
411
412/*---------------------------------------------------------------------------------------------------*/
413OSErr KClientGetSessionUserName(KClientSessionInfo *session, char *user, short nameType )
414{
415	OSErr err;
416	KClientRec *kcRec;
417	krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
418
419	pb->user = user;
420	kcRec->nameType = nameType;
421	err = KClientSendMessage(cKrbGetSessionUserName,PICK_PARM);
422	return err;
423}
424
425/*---------------------------------------------------------------------------------------------------*/
426OSErr KClientSetUserName(char *user)
427{
428	OSErr err;
429	KClientSessionInfo s,*session = &s;
430
431	KC_SESSION->tag = 0;
432	OLD_KC_PB->user = user;
433	err = KClientSendMessage(cKrbSetUserName,session);
434	return err;
435}
436
437/*---------------------------------------------------------------------------------------------------*/
438OSErr KClientCacheInitialTicket(KClientSessionInfo *session, char *service)
439{
440	OSErr err;
441	KClientRec *kcRec;
442	krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
443
444	pb->service = service;
445	err = KClientSendMessage(cKrbCacheInitialTicket,PICK_PARM);
446	return err;
447}
448
449/*---------------------------------------------------------------------------------------------------*/
450OSErr KClientGetSessionKey(KClientSessionInfo *session, KClientKey *sessionKey)
451{
452	KClientRec *kcRec;
453	krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
454
455	/* Not logged in and no server context */
456	if ((!kcRec || !kcRec->serverContext) && KClientStatus()==KClientNotLoggedIn)
457		return cKrbNotLoggedIn;
458
459	BlockMove(&(pb->sessionKey),sessionKey,sizeof(KClientKey));
460	return 0;
461}
462
463/*---------------------------------------------------------------------------------------------------*/
464OSErr KClientMakeSendAuth(KClientSessionInfo *session, char *service,void *buf,unsigned long *buflen,long checksum, char *applicationVersion)
465{
466	OSErr err;
467	KClientRec *kcRec;
468	krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
469
470	pb->service = service;
471	pb->buf = (char *) buf;
472	pb->buflen = *buflen;
473	pb->checksum = checksum;
474	pb->applicationVersion = applicationVersion;
475	err = KClientSendMessage(cKrbGetAuthForService,PICK_PARM);
476	*buflen = pb->buflen;
477	return err;
478}
479/*---------------------------------------------------------------------------------------------------*/
480OSErr KClientVerifyReplyTicket(KClientSessionInfo *session, void *buf,unsigned long *buflen )
481{
482	OSErr err;
483	KClientRec *kcRec;
484	krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
485
486	pb->buf = (char *) buf;
487	pb->buflen = *buflen;
488	err = KClientSendMessage(cKrbCheckServiceResponse,PICK_PARM);
489	*buflen = pb->buflen;
490	return err;
491}
492
493/*---------------------------------------------------------------------------------------------------*/
494OSErr KClientEncrypt(KClientSessionInfo *session, void *buf,unsigned long buflen,void *encryptBuf,unsigned long *encryptLength)
495{
496	OSErr err;
497	KClientRec *kcRec;
498	krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
499
500	pb->buf = (char *) buf;
501	pb->buflen = buflen;
502	pb->encryptBuf = (char *) encryptBuf;
503	err = KClientSendMessage(cKrbEncrypt,PICK_PARM);
504	*encryptLength = pb->encryptLength;
505	return err;
506}
507
508/*---------------------------------------------------------------------------------------------------*/
509OSErr KClientDecrypt(KClientSessionInfo *session, void *buf,unsigned long buflen,
510					unsigned long *decryptOffset,unsigned long *decryptLength)
511{
512	OSErr err;
513	KClientRec *kcRec;
514	krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
515
516	pb->buf = (char *) buf;
517	pb->buflen = buflen;
518	err = KClientSendMessage(cKrbDecrypt,PICK_PARM);
519	*decryptOffset = pb->decryptOffset;
520	*decryptLength = pb->decryptLength;
521	return err;
522}
523
524/*---------------------------------------------------------------------------------------------------*/
525void KClientErrorText(OSErr err, char *text)
526{
527	ParamBlockRec aPBR;
528	short refNum;
529	OSErr oerr;
530
531	if ( (oerr = OpenDriver(KCLIENTDRIVER,&refNum)) != noErr)
532		return;
533
534	aPBR.cntrlParam.ioCompletion = nil;
535	aPBR.cntrlParam.ioVRefNum = 0;
536	aPBR.cntrlParam.ioCRefNum = refNum;
537	aPBR.cntrlParam.csCode = cKrbGetErrorText;
538	((long *)aPBR.cntrlParam.csParam)[0] = (long)err;
539	((long *)aPBR.cntrlParam.csParam)[1] = (long)text;
540
541	(void) PBControl( &aPBR, false );
542
543	/* In case driver is old, at least return something */
544	if (aPBR.cntrlParam.ioResult==cKrbBadSelector) {
545		BlockMove("Kerberos error",text,15);
546	}
547}
548
549/*---------------------------------------------------------------------------------------------------*/
550/* Kerberized Server routines                                                                        */
551/*---------------------------------------------------------------------------------------------------*/
552OSErr KServerNewSession( KClientSessionInfo *session, char *service,unsigned long lAddr,
553						unsigned short lPort,unsigned long fAddr,unsigned short fPort)
554{
555	OSErr err;
556
557	KC_PB->service 				= service;
558
559	err = KClientSendMessage(cKrbNewServerSession,KC_SESSION);
560
561	if (err)
562		return err;
563
564	KC_SESSION->libVersion		= 2;
565	KC_PB->lAddr 				= lAddr;
566	KC_PB->lPort 				= lPort;
567	KC_PB->fAddr 				= fAddr;
568	KC_PB->fPort 				= fPort;
569
570	return err;
571}
572
573/*---------------------------------------------------------------------------------------------------*/
574OSErr KServerVerifyTicket( KClientSessionInfo *session, void *buf, char *filename )
575{
576	OSErr err;
577	KC_PB->buf = (char *) buf;
578	KC_SESSION->filename = filename;
579
580	err = KClientSendMessage(cKrbServerVerifyTicket,KC_SESSION);
581	return err;
582}
583
584/*---------------------------------------------------------------------------------------------------*/
585OSErr KServerGetReplyTicket( KClientSessionInfo *session, void *buf, unsigned long *buflen )
586{
587	OSErr err;
588	KClientRec *kcRec;
589	krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
590
591	pb->buf 		= (char *) buf;
592	pb->buflen 	= *buflen;
593
594	err = KClientSendMessage(cKrbServerGetReplyTkt,PICK_PARM);
595	if (err) return err;
596
597	*buflen = pb->buflen;
598	return noErr;
599}
600
601/*---------------------------------------------------------------------------------------------------*/
602OSErr KServerAddKey( KClientSessionInfo *session, KClientKey *privateKey, char *service, long version, char *filename )
603{
604	OSErr err;
605	KClientKey key;
606	char srv[128];
607	char tkt[1250];
608	unsigned long len;
609	KClientRec *kcRec;
610	krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
611
612	if (!kcRec)
613		return cKrbBadSelector;	/* old driver */
614
615	KC_SESSION->filename 	= filename;
616	KC_PB->service 			= service;
617
618	if (!service) {
619		/* No service, build from scratch, prompt the user */
620
621		/* Get the user to log in, using service principle and password */
622		KClientLogout();
623		err = KClientLogin( session, &key );
624		if (err) return err;
625
626		err = KClientGetUserName(srv);
627		if (err) return err;
628
629		/* Get a service ticket for the service so that we can obtain key version number */
630		err = KClientGetTicketForService(session, srv,tkt,&len);
631		if (err) return err;
632
633		KC_PB->service = srv;
634		BlockMove(&key,KC_SESSION->serverKey,8);
635		KC_SESSION->keyVersion 	= tkt[6];		/* tkt contains private key's version in the seventh byte */
636	}
637	else {
638		KC_SESSION->keyVersion 	= version;
639		BlockMove(privateKey,KC_SESSION->serverKey,8);
640		KC_PB->service 		= service;
641	}
642
643	return KClientSendMessage(cKrbAddServiceKey,session);
644
645}
646
647/*---------------------------------------------------------------------------------------------------*/
648OSErr KServerGetKey( KClientSessionInfo *session, KClientKey *privateKey,char *service, long version, char *filename )
649{
650	OSErr err;
651	KClientRec *kcRec;
652	krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
653
654	if (!kcRec)
655		return cKrbBadSelector;	/* old driver */
656
657	KC_SESSION->keyVersion 	= version;
658	KC_SESSION->filename 	= filename;
659	KC_PB->service 			= service;
660
661	err = KClientSendMessage(cKrbGetServiceKey,KC_SESSION);
662	if (err) return err;
663
664	BlockMove(KC_SESSION->serverKey,privateKey,8);
665	return noErr;
666}
667
668/*---------------------------------------------------------------------------------------------------*/
669OSErr KServerGetSessionTimeRemaining( KClientSessionInfo *session, long *seconds )
670{
671	OSErr err;
672	KClientRec *kcRec;
673	krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
674
675	err = KClientSendMessage(cKrbGetSessionTimeRemaining,PICK_PARM);
676	*seconds = pb->checksum;
677	return err;
678}
679
680/*---------------------------------------------------------------------------------------------------*/
681/* Configuration routines                                                                            */
682/*---------------------------------------------------------------------------------------------------*/
683OSErr KClientGetLocalRealm( char *realm )
684{
685	krbParmBlock pb;
686	pb.uRealm = realm;
687	return KClientSendMessage(cKrbGetLocalRealm,&pb);
688}
689
690/*---------------------------------------------------------------------------------------------------*/
691OSErr KClientSetLocalRealm( char *realm )
692{
693	krbParmBlock pb;
694	pb.uRealm = realm;
695	return KClientSendMessage(cKrbSetLocalRealm,&pb);
696}
697
698/*---------------------------------------------------------------------------------------------------*/
699OSErr KClientGetRealm( char *host, char *realm )
700{
701	krbParmBlock pb;
702	pb.uRealm = realm;
703	pb.host = host;
704	return KClientSendMessage(cKrbGetRealm,&pb);
705}
706
707/*---------------------------------------------------------------------------------------------------*/
708OSErr KClientAddRealmMap( char *host, char *realm )
709{
710	krbParmBlock pb;
711	pb.uRealm = realm;
712	pb.host = host;
713	return KClientSendMessage(cKrbAddRealmMap,&pb);
714}
715
716/*---------------------------------------------------------------------------------------------------*/
717OSErr KClientDeleteRealmMap( char *host )
718{
719	krbParmBlock pb;
720	pb.host = host;
721	return KClientSendMessage(cKrbDeleteRealmMap,&pb);
722}
723
724/*---------------------------------------------------------------------------------------------------*/
725OSErr KClientGetNthRealmMap( long n, char *host, char *realm )
726{
727	krbParmBlock pb;
728	pb.host = host;
729	pb.uRealm = realm;
730	pb.itemNumber = &n;
731	return KClientSendMessage(cKrbGetNthRealmMap,&pb);
732}
733
734/*---------------------------------------------------------------------------------------------------*/
735OSErr KClientGetNthServer( long n, char *host, char *realm, Boolean admin )
736{
737	krbParmBlock pb;
738
739	pb.host = host;
740	pb.uRealm = realm;
741	pb.itemNumber = &n;
742	pb.admin = (long) admin;
743	return KClientSendMessage(cKrbGetNthServer,&pb);
744}
745
746/*---------------------------------------------------------------------------------------------------*/
747OSErr KClientAddServerMap( char *host, char *realm, Boolean admin )
748{
749	krbParmBlock pb;
750	pb.uRealm = realm;
751	pb.host = host;
752	pb.admin = admin ? 1 : 0;
753	return KClientSendMessage(cKrbAddServerMap,&pb);
754}
755
756/*---------------------------------------------------------------------------------------------------*/
757OSErr KClientDeleteServerMap( char *host, char *realm )
758{
759	krbParmBlock pb;
760	pb.uRealm = realm;
761	pb.host = host;
762	return KClientSendMessage(cKrbDeleteServerMap,&pb);
763}
764
765/*---------------------------------------------------------------------------------------------------*/
766OSErr KClientGetNthServerMap( long n, char *host, char *realm, Boolean *admin )
767{
768	OSErr err;
769	long ladmin;
770	krbParmBlock pb;
771
772	pb.uRealm = realm;
773	pb.host = host;
774	pb.adminReturn = &ladmin;
775	pb.itemNumber = &n;
776	err = KClientSendMessage(cKrbGetNthServerMap,&pb);
777	*admin = (ladmin==1);
778	return err;
779}
780
781/*---------------------------------------------------------------------------------------------------*/
782OSErr KClientGetNthServerPort( long n, short *port )
783{
784	OSErr err;
785	krbParmBlock pb;
786	pb.itemNumber = &n;
787	err = KClientSendMessage(cKrbGetNthServerPort,&pb);
788	*port = pb.port;
789	return err;
790}
791
792/*---------------------------------------------------------------------------------------------------*/
793OSErr KClientSetNthServerPort( long n, short port )
794{
795	krbParmBlock pb;
796	pb.itemNumber = &n;
797	pb.port = port;
798	return KClientSendMessage(cKrbSetNthServerPort,&pb);
799}
800
801/*---------------------------------------------------------------------------------------------------*/
802OSErr KClientGetNumSessions( long *n )
803{
804	krbParmBlock pb;
805	pb.itemNumber = n;
806	return KClientSendMessage(cKrbGetNumSessions,&pb);
807}
808
809/*---------------------------------------------------------------------------------------------------*/
810OSErr KClientGetNthSession( long n, char *name, char *instance, char *realm )
811{
812	krbParmBlock pb;
813	pb.itemNumber = &n;
814	pb.uName = name;
815	pb.uInstance = instance;
816	pb.uRealm = realm;
817	return KClientSendMessage(cKrbGetNthSession,&pb);
818}
819
820/*---------------------------------------------------------------------------------------------------*/
821OSErr KClientDeleteSession( char *name, char *instance, char *realm )
822{
823	krbParmBlock pb;
824	pb.uName = name;
825	pb.uInstance = instance;
826	pb.uRealm = realm;
827	return KClientSendMessage(cKrbDeleteSession,&pb);
828}
829
830/*---------------------------------------------------------------------------------------------------*/
831OSErr KClientGetCredentials( char *name, char *instance, char *realm, CREDENTIALS *cred )
832{
833	krbParmBlock pb;
834	pb.uName = name;
835	pb.uInstance = instance;
836	pb.uRealm = realm;
837	pb.cred = cred;
838	return KClientSendMessage(cKrbGetCredentials,&pb);
839}
840
841/*---------------------------------------------------------------------------------------------------*/
842OSErr KClientAddCredentials( char *name, char *instance, char *realm, CREDENTIALS *cred )
843{
844	krbParmBlock pb;
845	pb.uName = name;
846	pb.uInstance = instance;
847	pb.uRealm = realm;
848	pb.cred = cred;
849	return KClientSendMessage(cKrbAddCredentials,&pb);
850}
851
852/*---------------------------------------------------------------------------------------------------*/
853OSErr KClientDeleteCredentials( char *name, char *instance, char *realm,
854								char *sname, char *sinstance, char *srealm )
855{
856	krbParmBlock pb;
857	pb.uName = name;
858	pb.uInstance = instance;
859	pb.uRealm = realm;
860	pb.sName = sname;
861	pb.sInstance = sinstance;
862	pb.sRealm = srealm;
863	return KClientSendMessage(cKrbDeleteCredentials,&pb);
864}
865
866/*---------------------------------------------------------------------------------------------------*/
867OSErr KClientGetNumCredentials( long *n, char *name, char *instance, char *realm )
868{
869	krbParmBlock pb;
870	pb.uName = name;
871	pb.uInstance = instance;
872	pb.uRealm = realm;
873	pb.itemNumber = n;
874	return KClientSendMessage(cKrbGetNumCredentials,&pb);
875}
876
877/*---------------------------------------------------------------------------------------------------*/
878OSErr KClientGetNthCredential( long n, char *name, char *instance, char *realm,
879								char *sname, char *sinstance, char *srealm )
880{
881	krbParmBlock pb;
882	pb.uName = name;
883	pb.uInstance = instance;
884	pb.uRealm = realm;
885	pb.sName = sname;
886	pb.sInstance = sinstance;
887	pb.sRealm = srealm;
888	pb.itemNumber = &n;
889	return KClientSendMessage(cKrbGetNthCredentials,&pb);
890}
891
892/*---------------------------------------------------------------------------------------------------*/
893OSErr KClientAddSpecial( char *service, char *name )
894{
895	krbParmBlock pb;
896	pb.uName = name;
897	pb.sName = service;
898	return KClientSendMessage(cKrbAddSpecial,&pb);
899}
900
901/*---------------------------------------------------------------------------------------------------*/
902OSErr KClientDeleteSpecial( char *service )
903{
904	krbParmBlock pb;
905	pb.sName = service;
906	return KClientSendMessage(cKrbDeleteSpecial,&pb);
907}
908
909/*---------------------------------------------------------------------------------------------------*/
910OSErr KClientGetNumSpecials( long *n )
911{
912	krbParmBlock pb;
913	pb.itemNumber = n;
914	return KClientSendMessage(cKrbGetNumSpecials,&pb);
915}
916
917/*---------------------------------------------------------------------------------------------------*/
918OSErr KClientGetNthSpecial( long n, char *name, char *service )
919{
920	krbParmBlock pb;
921	pb.uName = name;
922	pb.sName = service;
923	pb.itemNumber = &n;
924	return KClientSendMessage(cKrbGetNthSpecial,&pb);
925}
926
927/*---------------------------------------------------------------------------------------------------*/
928OSErr KClientSetOption( short option, void *value )
929{
930	krbParmBlock pb;
931	pb.uName = (char *) value;
932	pb.port = option;
933	return KClientSendMessage(cKrbSetOption,&pb);
934}
935
936/*---------------------------------------------------------------------------------------------------*/
937OSErr KClientGetOption( short option, void *value )
938{
939	krbParmBlock pb;
940	pb.uName = (char *) value;
941	pb.port = option;
942	return KClientSendMessage(cKrbGetOption,&pb);
943}
944
945