2 KClient.c -- Application library for KClient
4 © Copyright 1994,1995 by Cornell University
6 Initial coding 8/94 by Peter Bosanko.
10 #include "krbdriver.h"
17 #include "kcglue_des.h"
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"
25 /* Forward Declarations */
27 OSErr KClientSendMessage(short msg, void *parm);
28 OSErr KClientSetPassword( KClientSessionInfo *session, char *password );
29 krbHiParmBlock *KClientSessionKind( KClientSessionInfo *session, KClientRec **kcRec );
30 OSErr _KClientVersion( StringPtr driver, short *majorVersion, short *minorVersion, char *versionString );
33 * call into des ecb_encrypt
35 /* created by n3liw+@cmu.edu to support SASL, need to be able to specify checksum */
36 int KClient_des_ecb_encrypt(KClientSessionInfo *session,des_cblock v1,des_cblock v2,int do_encrypt)
38 KClientKey sessionKey;
39 Key_schedule schedule;
41 int rc=KClientGetSessionKey(session,&sessionKey);
44 rc=kcglue_des_key_sched(&sessionKey,schedule);
47 kcglue_des_ecb_encrypt(v1,v2,schedule,do_encrypt);
52 * call into des pcbc_encrypt
54 /* created by n3liw+@cmu.edu to support SASL, need to be able to specify checksum */
55 int KClient_des_pcbc_encrypt(KClientSessionInfo *session,des_cblock v1,des_cblock v2,long len,int do_encrypt)
57 KClientKey sessionKey;
58 Key_schedule schedule;
60 int rc=KClientGetSessionKey(session,&sessionKey);
63 rc=kcglue_des_key_sched(&sessionKey,schedule);
66 kcglue_des_pcbc_encrypt(v1,v2,len,schedule,&sessionKey,do_encrypt);
70 /*---------------------------------------------------------------------------------------------------*/
71 OSErr KClientSendMessage(short msg, void *parm)
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 ***************************************************/
83 OSErr err = OpenDriver(KCLIENTDRIVER,&refNum);
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));
92 (void) PBControlImmed( &aPBR );
94 err = aPBR.cntrlParam.ioResult;
98 /*---------------------------------------------------------------------------------------------------*/
99 krbHiParmBlock *KClientSessionKind( KClientSessionInfo *session, KClientRec **kcRec )
101 if (KC_SESSION->tag==NEW_KCLIENT_TAG) {
102 /* Newer driver, use newer session record */
114 /*---------------------------------------------------------------------------------------------------*/
115 OSErr KClientSetPassword( KClientSessionInfo *session, char *password )
118 krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
121 return KClientSendMessage(cKrbSetPassword,PICK_PARM);
124 /*---------------------------------------------------------------------------------------------------*/
125 OSErr KClientNewSession(KClientSessionInfo *session, unsigned long lAddr,unsigned short lPort,unsigned long fAddr,unsigned short fPort)
129 err = KClientSendMessage(cKrbNewClientSession,KC_SESSION);
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;
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;
148 /*---------------------------------------------------------------------------------------------------*/
149 OSErr KClientDisposeSession(KClientSessionInfo *session)
152 (void) KClientSessionKind(session,&kcRec);
155 return KClientSendMessage(cKrbDisposeSession,session);
160 /*---------------------------------------------------------------------------------------------------*/
162 * modified by n3liw+@cmu.edu to support SASL, need to be able to specify checksum
164 OSErr KClientGetTicketForService(KClientSessionInfo *session, char *service,void *buf,unsigned long *buflen)
166 return KClientGetTicketForServiceFull(session,service,buf,buflen,0);
173 * store the passed long in network byte order
175 static char *put_long(char *dst,long aval)
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
194 * int authenticator length
201 * byte GMT microseconds/5
203 * ] encrypted in session key
206 /*---------------------------------------------------------------------------------------------------*/
208 * created by n3liw+@cmu.edu to support SASL, need to be able to specify checksum
210 OSErr KClientGetTicketForServiceFull(KClientSessionInfo *session, char *service,void *buf,unsigned long *buflen,long cks)
219 krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
221 pb->service = service;
222 pb->buf = (char *) buf;
223 pb->buflen = *buflen;
225 err = KClientSendMessage(cKrbGetTicketForService,PICK_PARM);
226 *buflen = pb->buflen;
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.
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;
243 err=KClient_des_pcbc_encrypt(session,(unsigned char *)p,(unsigned char *)wbuf,auth_len,0);
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*/
256 err=KClient_des_pcbc_encrypt(session,(unsigned char *)wbuf,(unsigned char *)wbuf,auth_len,1);
257 memcpy(p,wbuf,auth_len);
261 /*---------------------------------------------------------------------------------------------------*/
262 OSErr KClientLogin( KClientSessionInfo *session, KClientKey *privateKey )
266 krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
268 pb->service = (char *) privateKey; /* pointer to private key in first 4 bytes */
269 err = KClientSendMessage(cKrbLogin,PICK_PARM);
273 /*---------------------------------------------------------------------------------------------------*/
274 OSErr KClientSetPrompt( KClientSessionInfo *session, char *prompt )
277 (void) KClientSessionKind(session,&kcRec);
280 kcRec->prompt = prompt;
281 else return cKrbBadSelector;
286 /*---------------------------------------------------------------------------------------------------*/
287 OSErr KClientPasswordLogin( KClientSessionInfo *session, char *password, KClientKey *privateKey )
291 if ( ( err = KClientSetPassword(session,password) ) != noErr )
294 return KClientLogin(session,privateKey);
297 /*---------------------------------------------------------------------------------------------------*/
298 OSErr KClientPasswordToKey( char *password, KClientKey *privateKey )
304 if ( (err = OpenDriver(KCLIENTDRIVER,&refNum)) != noErr)
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;
314 (void) PBControl( &aPBR, false );
315 return aPBR.cntrlParam.ioResult;
318 /*---------------------------------------------------------------------------------------------------*/
319 OSErr KClientKeyLogin( KClientSessionInfo *session, KClientKey *privateKey )
323 err = KClientSendMessage(cKrbSetKey,privateKey);
326 return KClientLogin(session,privateKey);
329 /*---------------------------------------------------------------------------------------------------*/
330 OSErr KClientLogout( )
334 return KClientSendMessage(cKrbDeleteAllSessions, &cpb);
337 /*---------------------------------------------------------------------------------------------------*/
338 short KClientStatus( )
343 (void) KClientGetUserName(user);
345 return KClientLoggedIn;
346 return KClientNotLoggedIn;
349 /*---------------------------------------------------------------------------------------------------*/
350 OSErr _KClientVersion( StringPtr driver, short *majorVersion, short *minorVersion, char *versionString )
356 if ( (err = OpenDriver(driver,&refNum)) != noErr)
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;
365 (void) PBControl( &aPBR, false );
366 err = aPBR.cntrlParam.ioResult;
368 /* For pre-2.0, do some detective work */
369 if (err==cKrbBadSelector) {
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) {
377 *((long *)versionString) = '1.1\0';
382 *((long *)versionString) = '1.0\0';
387 *majorVersion = aPBR.cntrlParam.csParam[0];
388 *minorVersion = aPBR.cntrlParam.csParam[1];
394 /*---------------------------------------------------------------------------------------------------*/
395 OSErr KClientVersion( short *majorVersion, short *minorVersion, char *versionString )
397 return _KClientVersion(KCLIENTDRIVER,majorVersion,minorVersion,versionString);
400 /*---------------------------------------------------------------------------------------------------*/
401 OSErr KClientGetUserName(char *user)
404 KClientSessionInfo s,*session = &s;
407 OLD_KC_PB->user = user;
408 err = KClientSendMessage(cKrbGetUserName,session);
412 /*---------------------------------------------------------------------------------------------------*/
413 OSErr KClientGetSessionUserName(KClientSessionInfo *session, char *user, short nameType )
417 krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
420 kcRec->nameType = nameType;
421 err = KClientSendMessage(cKrbGetSessionUserName,PICK_PARM);
425 /*---------------------------------------------------------------------------------------------------*/
426 OSErr KClientSetUserName(char *user)
429 KClientSessionInfo s,*session = &s;
432 OLD_KC_PB->user = user;
433 err = KClientSendMessage(cKrbSetUserName,session);
437 /*---------------------------------------------------------------------------------------------------*/
438 OSErr KClientCacheInitialTicket(KClientSessionInfo *session, char *service)
442 krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
444 pb->service = service;
445 err = KClientSendMessage(cKrbCacheInitialTicket,PICK_PARM);
449 /*---------------------------------------------------------------------------------------------------*/
450 OSErr KClientGetSessionKey(KClientSessionInfo *session, KClientKey *sessionKey)
453 krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
455 /* Not logged in and no server context */
456 if ((!kcRec || !kcRec->serverContext) && KClientStatus()==KClientNotLoggedIn)
457 return cKrbNotLoggedIn;
459 BlockMove(&(pb->sessionKey),sessionKey,sizeof(KClientKey));
463 /*---------------------------------------------------------------------------------------------------*/
464 OSErr KClientMakeSendAuth(KClientSessionInfo *session, char *service,void *buf,unsigned long *buflen,long checksum, char *applicationVersion)
468 krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
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;
479 /*---------------------------------------------------------------------------------------------------*/
480 OSErr KClientVerifyReplyTicket(KClientSessionInfo *session, void *buf,unsigned long *buflen )
484 krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
486 pb->buf = (char *) buf;
487 pb->buflen = *buflen;
488 err = KClientSendMessage(cKrbCheckServiceResponse,PICK_PARM);
489 *buflen = pb->buflen;
493 /*---------------------------------------------------------------------------------------------------*/
494 OSErr KClientEncrypt(KClientSessionInfo *session, void *buf,unsigned long buflen,void *encryptBuf,unsigned long *encryptLength)
498 krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
500 pb->buf = (char *) buf;
502 pb->encryptBuf = (char *) encryptBuf;
503 err = KClientSendMessage(cKrbEncrypt,PICK_PARM);
504 *encryptLength = pb->encryptLength;
508 /*---------------------------------------------------------------------------------------------------*/
509 OSErr KClientDecrypt(KClientSessionInfo *session, void *buf,unsigned long buflen,
510 unsigned long *decryptOffset,unsigned long *decryptLength)
514 krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
516 pb->buf = (char *) buf;
518 err = KClientSendMessage(cKrbDecrypt,PICK_PARM);
519 *decryptOffset = pb->decryptOffset;
520 *decryptLength = pb->decryptLength;
524 /*---------------------------------------------------------------------------------------------------*/
525 void KClientErrorText(OSErr err, char *text)
531 if ( (oerr = OpenDriver(KCLIENTDRIVER,&refNum)) != noErr)
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;
541 (void) PBControl( &aPBR, false );
543 /* In case driver is old, at least return something */
544 if (aPBR.cntrlParam.ioResult==cKrbBadSelector) {
545 BlockMove("Kerberos error",text,15);
549 /*---------------------------------------------------------------------------------------------------*/
550 /* Kerberized Server routines */
551 /*---------------------------------------------------------------------------------------------------*/
552 OSErr KServerNewSession( KClientSessionInfo *session, char *service,unsigned long lAddr,
553 unsigned short lPort,unsigned long fAddr,unsigned short fPort)
557 KC_PB->service = service;
559 err = KClientSendMessage(cKrbNewServerSession,KC_SESSION);
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;
573 /*---------------------------------------------------------------------------------------------------*/
574 OSErr KServerVerifyTicket( KClientSessionInfo *session, void *buf, char *filename )
577 KC_PB->buf = (char *) buf;
578 KC_SESSION->filename = filename;
580 err = KClientSendMessage(cKrbServerVerifyTicket,KC_SESSION);
584 /*---------------------------------------------------------------------------------------------------*/
585 OSErr KServerGetReplyTicket( KClientSessionInfo *session, void *buf, unsigned long *buflen )
589 krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
591 pb->buf = (char *) buf;
592 pb->buflen = *buflen;
594 err = KClientSendMessage(cKrbServerGetReplyTkt,PICK_PARM);
597 *buflen = pb->buflen;
601 /*---------------------------------------------------------------------------------------------------*/
602 OSErr KServerAddKey( KClientSessionInfo *session, KClientKey *privateKey, char *service, long version, char *filename )
610 krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
613 return cKrbBadSelector; /* old driver */
615 KC_SESSION->filename = filename;
616 KC_PB->service = service;
619 /* No service, build from scratch, prompt the user */
621 /* Get the user to log in, using service principle and password */
623 err = KClientLogin( session, &key );
626 err = KClientGetUserName(srv);
629 /* Get a service ticket for the service so that we can obtain key version number */
630 err = KClientGetTicketForService(session, srv,tkt,&len);
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 */
638 KC_SESSION->keyVersion = version;
639 BlockMove(privateKey,KC_SESSION->serverKey,8);
640 KC_PB->service = service;
643 return KClientSendMessage(cKrbAddServiceKey,session);
647 /*---------------------------------------------------------------------------------------------------*/
648 OSErr KServerGetKey( KClientSessionInfo *session, KClientKey *privateKey,char *service, long version, char *filename )
652 krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
655 return cKrbBadSelector; /* old driver */
657 KC_SESSION->keyVersion = version;
658 KC_SESSION->filename = filename;
659 KC_PB->service = service;
661 err = KClientSendMessage(cKrbGetServiceKey,KC_SESSION);
664 BlockMove(KC_SESSION->serverKey,privateKey,8);
668 /*---------------------------------------------------------------------------------------------------*/
669 OSErr KServerGetSessionTimeRemaining( KClientSessionInfo *session, long *seconds )
673 krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
675 err = KClientSendMessage(cKrbGetSessionTimeRemaining,PICK_PARM);
676 *seconds = pb->checksum;
680 /*---------------------------------------------------------------------------------------------------*/
681 /* Configuration routines */
682 /*---------------------------------------------------------------------------------------------------*/
683 OSErr KClientGetLocalRealm( char *realm )
687 return KClientSendMessage(cKrbGetLocalRealm,&pb);
690 /*---------------------------------------------------------------------------------------------------*/
691 OSErr KClientSetLocalRealm( char *realm )
695 return KClientSendMessage(cKrbSetLocalRealm,&pb);
698 /*---------------------------------------------------------------------------------------------------*/
699 OSErr KClientGetRealm( char *host, char *realm )
704 return KClientSendMessage(cKrbGetRealm,&pb);
707 /*---------------------------------------------------------------------------------------------------*/
708 OSErr KClientAddRealmMap( char *host, char *realm )
713 return KClientSendMessage(cKrbAddRealmMap,&pb);
716 /*---------------------------------------------------------------------------------------------------*/
717 OSErr KClientDeleteRealmMap( char *host )
721 return KClientSendMessage(cKrbDeleteRealmMap,&pb);
724 /*---------------------------------------------------------------------------------------------------*/
725 OSErr KClientGetNthRealmMap( long n, char *host, char *realm )
731 return KClientSendMessage(cKrbGetNthRealmMap,&pb);
734 /*---------------------------------------------------------------------------------------------------*/
735 OSErr KClientGetNthServer( long n, char *host, char *realm, Boolean admin )
742 pb.admin = (long) admin;
743 return KClientSendMessage(cKrbGetNthServer,&pb);
746 /*---------------------------------------------------------------------------------------------------*/
747 OSErr KClientAddServerMap( char *host, char *realm, Boolean admin )
752 pb.admin = admin ? 1 : 0;
753 return KClientSendMessage(cKrbAddServerMap,&pb);
756 /*---------------------------------------------------------------------------------------------------*/
757 OSErr KClientDeleteServerMap( char *host, char *realm )
762 return KClientSendMessage(cKrbDeleteServerMap,&pb);
765 /*---------------------------------------------------------------------------------------------------*/
766 OSErr KClientGetNthServerMap( long n, char *host, char *realm, Boolean *admin )
774 pb.adminReturn = &ladmin;
776 err = KClientSendMessage(cKrbGetNthServerMap,&pb);
777 *admin = (ladmin==1);
781 /*---------------------------------------------------------------------------------------------------*/
782 OSErr KClientGetNthServerPort( long n, short *port )
787 err = KClientSendMessage(cKrbGetNthServerPort,&pb);
792 /*---------------------------------------------------------------------------------------------------*/
793 OSErr KClientSetNthServerPort( long n, short port )
798 return KClientSendMessage(cKrbSetNthServerPort,&pb);
801 /*---------------------------------------------------------------------------------------------------*/
802 OSErr KClientGetNumSessions( long *n )
806 return KClientSendMessage(cKrbGetNumSessions,&pb);
809 /*---------------------------------------------------------------------------------------------------*/
810 OSErr KClientGetNthSession( long n, char *name, char *instance, char *realm )
815 pb.uInstance = instance;
817 return KClientSendMessage(cKrbGetNthSession,&pb);
820 /*---------------------------------------------------------------------------------------------------*/
821 OSErr KClientDeleteSession( char *name, char *instance, char *realm )
825 pb.uInstance = instance;
827 return KClientSendMessage(cKrbDeleteSession,&pb);
830 /*---------------------------------------------------------------------------------------------------*/
831 OSErr KClientGetCredentials( char *name, char *instance, char *realm, CREDENTIALS *cred )
835 pb.uInstance = instance;
838 return KClientSendMessage(cKrbGetCredentials,&pb);
841 /*---------------------------------------------------------------------------------------------------*/
842 OSErr KClientAddCredentials( char *name, char *instance, char *realm, CREDENTIALS *cred )
846 pb.uInstance = instance;
849 return KClientSendMessage(cKrbAddCredentials,&pb);
852 /*---------------------------------------------------------------------------------------------------*/
853 OSErr KClientDeleteCredentials( char *name, char *instance, char *realm,
854 char *sname, char *sinstance, char *srealm )
858 pb.uInstance = instance;
861 pb.sInstance = sinstance;
863 return KClientSendMessage(cKrbDeleteCredentials,&pb);
866 /*---------------------------------------------------------------------------------------------------*/
867 OSErr KClientGetNumCredentials( long *n, char *name, char *instance, char *realm )
871 pb.uInstance = instance;
874 return KClientSendMessage(cKrbGetNumCredentials,&pb);
877 /*---------------------------------------------------------------------------------------------------*/
878 OSErr KClientGetNthCredential( long n, char *name, char *instance, char *realm,
879 char *sname, char *sinstance, char *srealm )
883 pb.uInstance = instance;
886 pb.sInstance = sinstance;
889 return KClientSendMessage(cKrbGetNthCredentials,&pb);
892 /*---------------------------------------------------------------------------------------------------*/
893 OSErr KClientAddSpecial( char *service, char *name )
898 return KClientSendMessage(cKrbAddSpecial,&pb);
901 /*---------------------------------------------------------------------------------------------------*/
902 OSErr KClientDeleteSpecial( char *service )
906 return KClientSendMessage(cKrbDeleteSpecial,&pb);
909 /*---------------------------------------------------------------------------------------------------*/
910 OSErr KClientGetNumSpecials( long *n )
914 return KClientSendMessage(cKrbGetNumSpecials,&pb);
917 /*---------------------------------------------------------------------------------------------------*/
918 OSErr KClientGetNthSpecial( long n, char *name, char *service )
924 return KClientSendMessage(cKrbGetNthSpecial,&pb);
927 /*---------------------------------------------------------------------------------------------------*/
928 OSErr KClientSetOption( short option, void *value )
931 pb.uName = (char *) value;
933 return KClientSendMessage(cKrbSetOption,&pb);
936 /*---------------------------------------------------------------------------------------------------*/
937 OSErr KClientGetOption( short option, void *value )
940 pb.uName = (char *) value;
942 return KClientSendMessage(cKrbGetOption,&pb);