--- samba-2.2.1a/source/Makefile.in.old	Sun Jul  8 13:29:34 2001
+++ samba-2.2.1a/source/Makefile.in	Tue Jul 17 15:57:01 2001
@@ -8,5 +8,6 @@
 mandir=@mandir@
 sysconfdir=@sysconfdir@
 
-LIBS=@LIBS@
+OPENSSL_DIR=/oper/oper4/jvrobert/scratch/enc/openssl-0.9.6
+LIBS=-L/usr/lib/afs @LIBS@ -lkauth -lprot -lubik -lauth -lrxkad -lsys -ldes -lrx -llwp -lcom_err -laudit /usr/lib/afs/util.a -L$(OPENSSL_DIR) -lcrypto -lresolv
 LDAPLIBS=@LDAPLIBS@
@@ -83,3 +84,3 @@
 PASSWD_FLAGS = -DPASSWD_PROGRAM=\"$(PASSWD_PROGRAM)\" -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" -DTDB_PASSWD_FILE=\"$(TDB_PASSWD_FILE)\"
-FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx -I$(srcdir)/smbwrapper $(CPPFLAGS) -DLOGFILEBASE=\"$(LOGFILEBASE)\"
+FLAGS1 = $(CFLAGS) -I$(OPENSSL_DIR)/include -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx -I$(srcdir)/smbwrapper $(CPPFLAGS) -DLOGFILEBASE=\"$(LOGFILEBASE)\"
 FLAGS2 = -DCONFIGFILE=\"$(CONFIGFILE)\" -DLMHOSTSFILE=\"$(LMHOSTSFILE)\"
@@ -130,6 +131,7 @@
 RPC_SERVER_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o \
                  rpc_server/srv_lsa_hnd.o rpc_server/srv_netlog.o rpc_server/srv_netlog_nt.o \
                  rpc_server/srv_pipe_hnd.o rpc_server/srv_reg.o rpc_server/srv_reg_nt.o \
+				 rpc_server/srv_afstoken.o \
                  rpc_server/srv_samr.o rpc_server/srv_samr_nt.o rpc_server/srv_srvsvc.o rpc_server/srv_srvsvc_nt.o \
                  rpc_server/srv_util.o rpc_server/srv_wkssvc.o rpc_server/srv_wkssvc_nt.o \
                  rpc_server/srv_pipe.o rpc_server/srv_dfs.o rpc_server/srv_dfs_nt.o \
--- samba-2.2.1a/source/include/ntdomain.h.old	Thu Jul  5 19:01:26 2001
+++ samba-2.2.1a/source/include/ntdomain.h	Tue Jul 17 15:57:01 2001
@@ -295,6 +295,9 @@
 #include "rpc_wkssvc.h"
 #include "rpc_spoolss.h"
 #include "rpc_dfs.h"
+#ifdef WITH_AFS
+#include "rpc_afstoken.h"
+#endif
 #include "sids.h"
 
 #endif /* _NT_DOMAIN_H */
--- samba-2.2.1a/source/include/proto.h.old	Sun Jul  8 13:29:43 2001
+++ samba-2.2.1a/source/include/proto.h	Tue Jul 17 15:57:02 2001
@@ -3967,7 +3967,13 @@
 WERROR _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u);
 WERROR _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u,
                      DFS_R_DFS_GET_INFO *r_u);
 
+#ifdef WITH_AFS
+/* The following definitions come from rpc_server/srv_afstoken.c */
+BOOL api_afstoken_rpc(pipes_struct *p);
+BOOL afstoken_init();
+#endif /* WITH_AFS */
+
 /* The following definitions come from rpc_server/srv_lsa.c  */
 
 BOOL api_ntlsa_rpc(pipes_struct *p);
--- samba-2.2.1a/source/include/rpc_afstoken.h.old	Wed Dec 31 17:00:00 1969
+++ samba-2.2.1a/source/include/rpc_afstoken.h	Tue Jul 17 15:57:02 2001
@@ -0,0 +1,37 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   SMB parameters and setup
+   Copyright (C) Andrew Tridgell 1992-1997
+   Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+   Copyright (C) Paul Ashton 1997
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _RPC_AFSTOKEN_H /* _RPC_AFSTOKEN_H */
+#define _RPC_AFSTOKEN_H 
+
+/* afstoken pipe */
+/* Note: these are definied by the order in the dispatch table 
+   Note: in the files generated by the IDL (afstoken_s.c file, afstoken_table)
+*/
+#define AFSTOKEN_GETPUBLICKEY    0x00
+#define AFSTOKEN_GETAFSTOKEN     0x01
+#define AFSTOKEN_LISTAFSTOKENS   0x02
+#define AFSTOKEN_GETSERVICEVERSION      0x03
+#define AFSTOKEN_FORGETTOKEN	 0x04
+
+#endif /* _RPC_AFSTOKEN_H */
--- samba-2.2.1a/source/include/smb.h.old	Thu Jul  5 19:01:30 2001
+++ samba-2.2.1a/source/include/smb.h	Tue Jul 17 15:57:02 2001
@@ -302,6 +302,9 @@
 #define PIPE_LSARPC   "\\PIPE\\lsarpc"
 #define PIPE_SPOOLSS  "\\PIPE\\spoolss"
 #define PIPE_NETDFS   "\\PIPE\\netdfs"
+#ifdef WITH_AFS
+#define PIPE_AFSTOKEN "\\PIPE\\afstoken"
+#endif /* WITH_AFS */
 
 /* 64 bit time (100usec) since ????? - cifs6.txt, section 3.5, page 30 */
 typedef struct nttime_info
--- samba-2.2.1a/source/param/loadparm.c.old	Thu Jul  5 19:01:44 2001
+++ samba-2.2.1a/source/param/loadparm.c	Tue Jul 17 15:57:02 2001
@@ -228,6 +228,9 @@
 	BOOL sslReqServerCert;
 	BOOL sslCompatibility;
 #endif				/* WITH_SSL */
+#ifdef WITH_AFS
+	int afstokenKeyBits;
+#endif /* WITH_AFS */
 	BOOL bMsAddPrinterWizard;
 	BOOL bDNSproxy;
 	BOOL bWINSsupport;
@@ -755,6 +758,10 @@
 	{"ssl version", P_ENUM, P_GLOBAL, &Globals.sslVersion, NULL, enum_ssl_version, 0},
 	{"ssl compatibility", P_BOOL, P_GLOBAL, &Globals.sslCompatibility, NULL, NULL, 0},
 #endif /* WITH_SSL */
+#ifdef WITH_AFS
+	{"AFS Token Service Options", P_SEP, P_SEPARATOR},
+	{"afstoken service keybits",  P_INTEGER, P_GLOBAL, &Globals.afstokenKeyBits, NULL, NULL, 0},
+#endif /* WITH_AFS */
 
 	{"Logging Options", P_SEP, P_SEPARATOR},
 	{"log level",  P_INTEGER, P_GLOBAL, &DEBUGLEVEL_CLASS[DBGC_ALL], handle_debug_list, NULL, 0},
@@ -1418,6 +1425,10 @@
 	Globals.sslCompatibility = False;
 #endif /* WITH_SSL */
 
+#ifdef WITH_AFS
+	Globals.afstokenKeyBits = 768;
+#endif /* WITH_AFS */
+
 #ifdef WITH_LDAP_SAM
         string_set(&Globals.szLdapServer, "localhost");
         string_set(&Globals.szLdapSuffix, "");
@@ -1497,6 +1508,10 @@
 FN_GLOBAL_BOOL(lp_ssl_reqServerCert, &Globals.sslReqServerCert)
 FN_GLOBAL_BOOL(lp_ssl_compatibility, &Globals.sslCompatibility)
 #endif /* WITH_SSL */
+
+#ifdef WITH_AFS
+FN_GLOBAL_INTEGER(lp_afstoken_keybits, &Globals.afstokenKeyBits)
+#endif /* WITH_AFS */
 
 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
--- samba-2.2.1a/source/passdb/pass_check.c.old	Thu Jul  5 19:01:46 2001
+++ samba-2.2.1a/source/passdb/pass_check.c	Tue Jul 17 15:57:02 2001
@@ -33,8 +33,31 @@
 
 #ifdef WITH_AFS
 
+#define xdr_op BROKEN_AFS5
+#define xdrproc_t BROKEN_AFS6
+#define xdr_ops BROKEN_AFS7
+#define xdr_discrim BROKEN_AFS8
+#define XDR_ENCODE BROKEN_AFS9
+#define XDR_DECODE BROKEN_AFS10
+#define XDR_FREE BROKEN_AFS11
+#define XDR BROKEN_AFS12
+#define des_ks_struct BROKEN_AFS13
+#define des_key_schedule BROKEN_AFS14
+#define bit_64 BROKEN_AFS15
 #include <afs/stds.h>
 #include <afs/kautils.h>
+#undef xdr_op
+#undef xdrproc_t
+#undef xdr_ops
+#undef xdr_discrim
+#undef XDR_ENCODE
+#undef XDR_DECODE
+#undef XDR_FREE
+#undef XDR
+#undef des_ks_struct
+#undef des_key_schedule
+#undef bit_64
+
 
 /*******************************************************************
 check on AFS authentication
--- samba-2.2.1a/source/rpc_parse/parse_rpc.c.old	Mon Mar 12 14:09:53 2001
+++ samba-2.2.1a/source/rpc_parse/parse_rpc.c	Tue Jul 17 15:57:02 2001
@@ -132,6 +132,18 @@
         }, 0x03                             \
 }
 
+#ifdef WITH_AFS
+/* This is from the IDL file, and is in the output .c files as the GUID */
+#define SYNT_AFSTOKEN_V1					\
+{											\
+		{									\
+				0x328f6b2e, 0x3777, 0x4287,	\
+				{ 0xb9, 0x31, 0x9c, 0xdc,	\
+				  0xc5, 0x2c, 0x84, 0x0a }	\
+		}, 0x01								\
+}
+#endif /* WITH_AFS */
+
 struct pipe_id_info pipe_names [] =
 {
 	/* client pipe , abstract syntax , server pipe   , transfer syntax */
@@ -143,6 +155,9 @@
 	{ PIPE_WINREG  , SYNT_WINREG_V1  , PIPE_WINREG   , TRANS_SYNT_V2 },
 	{ PIPE_SPOOLSS , SYNT_SPOOLSS_V1 , PIPE_SPOOLSS  , TRANS_SYNT_V2 },
 	{ PIPE_NETDFS  , SYNT_NETDFS_V3  , PIPE_NETDFS   , TRANS_SYNT_V2 },
+#ifdef WITH_AFS
+	{ PIPE_AFSTOKEN, SYNT_AFSTOKEN_V1, PIPE_AFSTOKEN , TRANS_SYNT_V2 },
+#endif /* WITH_AFS */
 	{ NULL         , SYNT_NONE_V0    , NULL          , SYNT_NONE_V0  }
 };
 
--- samba-2.2.1a/source/rpc_server/srv_afstoken.c.old	Wed Dec 31 17:00:00 1969
+++ samba-2.2.1a/source/rpc_server/srv_afstoken.c	Tue Jul 17 15:57:03 2001
@@ -0,0 +1,589 @@
+#define OLD_NTDOMAIN 1
+/* 
+ *  Unix SMB/Netbios implementation.
+ *  Version 1.9.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Andrew Tridgell              1992-1997,
+ *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ *  Copyright (C) Paul Ashton                       1997.
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/bio.h>
+#include "includes.h"
+/* There's a conflict between AFS includes and OpenSSL includes some des structs */
+/* These effectively rename the AFS definitions */
+/* Another conflict with stupid AFS and rpc xdr headers */
+#define des_cblock BROKEN_AFS1
+#define des_ks_struct BROKEN_AFS2
+#define des_key_schedule BROKEN_AFS3
+#define bit_64 BROKEN_AFS4
+#define xdr_op BROKEN_AFS5
+#define xdrproc_t BROKEN_AFS6
+#define xdr_ops BROKEN_AFS7
+#define xdr_discrim BROKEN_AFS8
+#define XDR_ENCODE BROKEN_AFS9
+#define XDR_DECODE BROKEN_AFS10
+#define XDR_FREE BROKEN_AFS11
+#define XDR BROKEN_AFS12
+#include <afs/stds.h>
+#include <afs/kautils.h>
+#undef des_cblock
+#undef des_ks_struct
+#undef des_key_schedule
+#undef bit_64
+#undef xdr_op
+#undef xdrproc_t
+#undef xdr_ops
+#undef xdr_discrim
+#undef XDR_ENCODE
+#undef XDR_DECODE
+#undef XDR_FREE
+#undef XDR
+
+#ifdef SUNOS5
+#define SAVEME _FILE_OFFSET_BITS
+#undef _FILE_OFFSET_BITS
+#include <procfs.h>
+#define _FILE_OFFSET_BITS SAVEME
+#undef SAVEME
+#endif
+
+#define AFSTOKEN_VERSION 2
+
+
+/* AFS functions (from openafs, mostly) */
+struct tokenInfo {
+    struct ktc_token  token;
+    struct ktc_principal service;
+    struct ktc_principal client;
+    int deleted;
+};
+
+BOOL unlog_NormalizeCellNames(char **list, int size) {
+      char *newCellName, *lcstring();
+      unsigned index;
+      struct afsconf_dir *conf;
+      int code;
+      struct afsconf_cell cellinfo;
+
+      if(!(conf = afsconf_Open (AFSDIR_CLIENT_ETC_DIRPATH))) {
+          DEBUG(0, ("unlog_NormalizeCellNameS(): Cannot get cell configuration info!\n"));
+		  return False;
+      }
+
+      for(index = 0; index < size; index++, list++) {
+          newCellName = malloc(MAXKTCREALMLEN);
+          if(!newCellName) {
+          	DEBUG(0, ("unlog_NormalizeCellNameS(): malloc failed"));
+      		afsconf_Close (conf);
+			  return False;
+          }
+          
+          lcstring(newCellName,*list, MAXKTCREALMLEN);
+          code = afsconf_GetCellInfo(conf, newCellName, 0, &cellinfo);
+          if (code) {
+              if(code == AFSCONF_NOTFOUND) {
+                  DEBUG(0, ("unlog_NormalizeCellNameS() Unrecognized cell name %s\n", newCellName));
+              } else {
+                  DEBUG(0, ("unlog_NormalizeCellNameS() conf failed code %d\n", code));
+              }
+      		afsconf_Close (conf);
+			  return False;
+          }
+          
+          strncpy(newCellName, cellinfo.name, MAXKTCREALMLEN);
+          
+		  free(*list);
+          *list = newCellName;
+      }
+      afsconf_Close (conf);
+	  return True;
+}
+
+
+/* From unlog.c in AFS */
+unlog_ForgetCertainTokens(char **list, int listSize) {
+      unsigned count, index, index2, number;
+      afs_int32 code;
+      struct ktc_principal serviceName;
+      struct tokenInfo *tokenInfoP;
+
+	  if ( ! unlog_NormalizeCellNames(list, listSize)) {
+		  DEBUG(0, ("unlog_ForgetCertainTokens: normalize failed"));
+	  }
+      /* figure out how many tokens exist */
+      count = 0;
+	  number = 0;
+      do {
+          code = ktc_ListTokens(count, &count, &serviceName);
+		  if (! strcmp(serviceName.name, "afs")) {
+			  number++;
+		  }
+      } while(!code);
+
+      tokenInfoP = (struct tokenInfo *)malloc((sizeof(struct tokenInfo) *
+                                               number));
+      if(!tokenInfoP) {
+		  DEBUG(0, ("unlog_ForgetCertainTokens(): Malloc failed"));
+		  return 0;
+      }
+
+      for(code = index = index2 = 0; (!code) && (index2 < count); index++) {
+          code = ktc_ListTokens(index2, &index2, &(tokenInfoP+index)->service);
+		  if (strcmp((tokenInfoP+index)->service.name, "afs")) {
+			  index--; /* Probably never happen, but... */
+			  continue;
+		  }
+
+          if(!code) {
+              code = ktc_GetToken(&(tokenInfoP+index)->service,
+                                  &(tokenInfoP+index)->token,
+                                  sizeof(struct ktc_token),
+                                  &(tokenInfoP+index)->client);
+              
+              if(!code) {
+                  (tokenInfoP+index)->deleted =
+                      unlog_CheckUnlogList(list, listSize ,
+                                           &(tokenInfoP+index)->client);
+			  }
+
+          }
+      }
+
+      unlog_VerifyUnlog(list, listSize, tokenInfoP, number);
+	  DEBUG(3, ("unlog: unlogging all tokens"));
+      code = ktc_ForgetAllTokens();
+
+      if (code) {
+		  DEBUG(0, ("unlog_ForgetCertainTokens(): ktc_ForgetAllTokens() failed: %d", code));
+		  return 0;
+      }
+
+      for(code = index = 0; index < number ; index++) {
+          if(!((tokenInfoP+index)->deleted)) {
+              code = ktc_SetToken(&(tokenInfoP+index)->service,
+                                  &(tokenInfoP+index)->token,
+                                  &(tokenInfoP+index)->client, 0);
+              if(code) {
+                  DEBUG(0, ("unlog_ForgetCertainTokens(): Couldn't re-register token, code = %d\n", code));
+				  return 0;
+              }
+          }
+      }
+
+	  free(tokenInfoP);
+      return 1;
+}
+
+unlog_CheckUnlogList(char **list, int count, struct ktc_principal *principal) {
+      do {
+          if(strcmp(*list, principal->cell) == 0)
+              return 1;
+          list++;
+          --count;
+      } while(count);
+
+      return 0;
+}
+
+unlog_VerifyUnlog(char **cellList, int cellListSize, struct tokenInfo *tokenList, int tokenListSize) {
+      int index;
+
+      for(index = 0; index < cellListSize; index++) {
+          int index2;
+          int found;
+
+          for(found = index2 = 0; !found && index2 < tokenListSize; index2++)
+              found =
+                  strcmp(cellList[index], (tokenList+index2)->client.cell)==0;
+
+          if(!found)
+              DEBUG(0, ("unlog: Warning - no tokens held for cell %s\n",
+                      cellList[index]));
+      }
+}
+
+
+/* END AFS Functions */ 
+
+extern int DEBUGLEVEL;
+extern pstring global_myname;
+
+RSA *rsaKey = NULL;
+EVP_CIPHER *cipher = NULL;
+EVP_PKEY *evp_key = NULL;
+
+#define NUMCELLS 30
+
+/* Decrypt data in *data of length len, and return it in **out
+   **out should be free()'d when finished
+*/
+int decrypt_data(RSA *key, unsigned char *data, int len, unsigned char *ek, int ekl, unsigned char *iv, unsigned char **out) {
+	EVP_CIPHER_CTX ctx;
+	int outl;
+	int ret = 0;
+
+	*out = malloc(len + 2 * EVP_CIPHER_block_size(cipher));
+
+	if (EVP_OpenInit(&ctx, cipher, ek, ekl, iv, evp_key)) {
+		if (EVP_OpenUpdate(&ctx, *out, &outl, data, len)) {
+			if (EVP_OpenFinal(&ctx, (*out) + outl, &outl)) {
+				ret = 1;
+			}
+		}
+	}
+
+	return ret;
+}
+
+/* base64 encode data - you should free the return pointer */
+char *base64encode(unsigned char *data, int length) {
+	BIO *bio, *b1, *b2;
+	char *p, *ret;
+	long size;
+
+	b1 = BIO_new(BIO_f_base64());
+	bio = BIO_push(BIO_new(BIO_f_base64()), BIO_new(BIO_s_mem()));
+	BIO_write(bio, data, length);
+	BIO_flush(bio);
+	size = BIO_get_mem_data(bio, &p);
+
+	ret = malloc(size + 1);
+	ret[size] = '\0';
+	memcpy(ret, p, size);
+	BIO_free_all(bio);
+
+	return ret;
+}
+
+/* Initialize */
+BOOL afstoken_init() {
+#ifdef SUNOS5
+	char seed_file_name[1024];
+	int seed_fd;
+	struct pstatus seed;
+#endif
+	int bits = lp_afstoken_keybits();
+	DEBUG(1, ("afstoken_init: Initializing...\n"));
+	ERR_load_crypto_strings();
+	if (bits != 256 && bits != 512 && bits != 768 && bits != 1024 && bits != 2048) {
+		DEBUG(0, ("afstoken_init: %d is not a supported bitsize - try 256,512,768,1024, or 2048.  Defaulting to 768 bits.\n", bits));
+		bits = 768;
+	}
+	DEBUG(3, ("afstoken_init: Generating RSA key of %d bits...\n", bits));
+#ifdef SUNOS5
+#undef sprintf
+	sprintf(seed_file_name, "/proc/%d/status", getpid());
+	seed_fd = open(seed_file_name, O_RDONLY);
+	if (seed_fd == -1) {
+		DEBUG(0, ("afstoken_init: Error getting random data from %s."));
+	}
+	else {
+		if (read(seed_fd, &seed, sizeof(seed)) > 0) {
+			DEBUG(3, ("afstoken_init: Random number generator seeded."));
+		}
+		close(seed_fd);
+	}
+	RAND_seed(&seed, sizeof(seed));
+#define sprintf __ERROR__XX__NEVER_USE_SPRINTF__;
+#endif
+	rsaKey = RSA_generate_key(bits, RSA_F4, NULL, NULL);
+	if (rsaKey == NULL) {
+		DEBUG(0, ("afstoken_init: Error generating RSA key.\n"));
+		return False;
+	}
+	DEBUG(3, ("afstoken_init: Done generating key.\n"));
+
+	/* Initialize crypto stuff */
+	cipher = EVP_bf_cbc();
+	evp_key  = EVP_PKEY_new();
+	EVP_PKEY_assign_RSA(evp_key, rsaKey);
+	return True;
+}
+
+BOOL enum_tokens(char *buf, int size, pipes_struct *p) {
+	int cellNum = 0;
+	struct ktc_principal service, client;
+	struct ktc_token tok;
+	int i;
+	int offset = 0;
+
+	buf[0] = '\0';
+
+	for (i = 0; i < NUMCELLS && !ktc_ListTokens(cellNum, &cellNum, &service); i++) {
+		if (!ktc_GetToken(&service, &tok, sizeof(tok), &client)) {
+			DEBUG(3, ("enum_tokens: %d cell: %s name: %s instance: %s\n", i, client.cell, client.name, client.instance));
+			DEBUG(3, ("enum_tokens: SERVICE cell: %s name: %s instance: %s\n", service.cell, service.name, service.instance));
+			DEBUG(3, ("enum_tokens: start %d end %d\n", tok.startTime, tok.endTime));
+#undef sprintf
+			if ( ! strcmp(service.name, "afs") ) {
+				safe_strcat(buf + offset, client.cell, size - offset - 1);
+				offset += strlen(buf + offset) + 1;
+				buf[offset] = '\0';
+				safe_strcat(buf + offset, client.name, size - offset - 1);
+				offset += strlen(buf + offset) + 1;
+				buf[offset] = '\0';
+				sprintf(buf + offset, "%d", tok.endTime);
+				offset += strlen(buf + offset) + 2;
+				buf[offset-1] = '\0';
+				buf[offset] = '\0';
+			}
+#define sprintf __ERROR__XX__NEVER_USE_SPRINTF__;
+			if (offset >= size) {
+				DEBUG(0, ("AFS enum_tokens: insufficient buffer\n"));
+				return False;
+			}
+			buf[offset] = '\0';
+		}
+	}
+
+	return True;
+}
+
+static BOOL api_afstoken_getafstoken(pipes_struct *p)
+{
+	unsigned int retval = 0, len;
+	unsigned char *passdata, *ek, *iv, *password, *msg;
+	STRING2 user, cell;
+	prs_struct *rdata = &p->out_data.rdata;
+	prs_struct *indata = &p->in_data.data;
+	int pdl, ekl, ivl, msgl;
+
+	DEBUG(3, ("api_afstoken_getafstoken: Entering\n"));
+	/* read in user name and cell*/
+	smb_io_string2("user", &user, 1, indata, 0);
+	smb_io_string2("cell", &cell, 1, indata, 0);
+
+	DEBUG(3, ("api_afstoken_getafstoken: Request for user %s cell %s\n", user.buffer, cell.buffer));
+
+	/* read in encrypted password */
+
+	/* data */
+	prs_align(indata);
+	prs_uint32("passdata_len", indata, 0, &pdl);
+	prs_align(indata);
+	prs_uint32("passdata_len", indata, 0, &pdl);
+	prs_align(indata);
+	passdata = malloc(pdl);
+	prs_uint8s(False, "passdata", indata, 0, passdata, pdl);
+
+	/* read in encrypted symmetric key */
+	prs_align(indata);
+	prs_uint32("ek_len", indata, 0, &ekl);
+	prs_align(indata);
+	prs_uint32("ek_len", indata, 0, &ekl);
+	prs_align(indata);
+	ek = malloc(ekl);
+	prs_uint8s(False, "ek", indata, 0, ek, ekl);
+
+	/* read in IV */
+	prs_align(indata);
+	prs_uint32("iv_len", indata, 0, &ivl);
+	prs_align(indata);
+	prs_uint32("iv_len", indata, 0, &ivl);
+	prs_align(indata);
+	iv = malloc(ivl);
+	prs_uint8s(False, "iv", indata, 0, iv, ivl);
+
+	/* read in msg */
+	prs_align(indata);
+	prs_uint32("msgl", indata, 0, &msgl);
+	DEBUG(3, ("api_afstoken_getafstoken: msglen %d\n", msgl));
+	msg = malloc(msgl);
+	strncpy(msg, "Success.", msgl);
+
+	DEBUG(3, ("api_afstoken_getafstoken: read in encrypted password - decrypting.\n"));
+	if (decrypt_data(rsaKey, passdata, pdl, ek, ekl, iv, &password)) {
+		long password_expires = 0;
+		char *reason;
+		DEBUG(3, ("api_afstoken_getafstoken: password decrypted successfully.\n"));
+		if (ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION, user.buffer, (char *) 0,
+					cell.buffer, password, 0, &password_expires, 0, &reason) == 0) {
+			DEBUG(3, ("api_afstoken_getafstoken: got token for %s in cell %s\n",
+						user.buffer, cell.buffer));
+			retval = 1;
+        }
+        else {
+			DEBUG(3, ("api_afstoken_getafstoken: failed to authenticate %s: %s\n",
+						user.buffer, reason));
+				strncpy(msg, reason, msgl);
+				retval = 0;
+        }
+
+	}
+	else {
+		DEBUG(3, ("api_afstoken_getafstoken: failed to dencrypt password\n"));
+		strncpy(msg, "failed to decrypt password from client.", msgl);
+		retval = 0;
+	}
+	prs_align(rdata);
+	prs_uint32("msgl", rdata, 0, &msgl);
+	prs_align(rdata);
+	prs_uint8s(False, "key", rdata, 1, msg, msgl);
+	prs_align(rdata);
+	prs_uint32("retvalue", rdata, 0, &retval);
+
+	free(passdata);
+	free(ek);
+	free(password);
+	free(iv);
+	free(msg);
+
+	return True;
+}
+
+static BOOL api_afstoken_getpublickey(pipes_struct *p)
+{
+	/* retval is return value */
+	/* len is the actual public key length */
+	/* retsize is the buffer size we _always_ send regardless of key length */
+	unsigned int retval, len, retsize;
+	prs_struct *rdata = &p->out_data.rdata;
+	prs_struct *indata = &p->in_data.data;
+	unsigned char *out, *ptr;
+
+	if (rsaKey == NULL && ! afstoken_init()) {
+		DEBUG(0, ("api_afstoken_getpublickey: Unable to initialize RSA Key.\n"));
+		retval = 0;
+		len = 0;
+	}
+	else {
+		DEBUG(3, ("api_afstoken_getpublickey: Entering...\n"));
+		prs_uint32("buf_size", indata, 0, &retsize);
+		out = malloc(retsize);
+	
+		len = i2d_RSAPublicKey(rsaKey, NULL);
+		if (len > retsize) {
+			DEBUG(0, ("api_afstoken_getpublickey: Not enough buffer sent.\n"));
+			retval = 0;
+		}
+		else {
+			ptr = out;
+			len = i2d_RSAPublicKey(rsaKey, &ptr);
+			retval = 1;
+		}
+	}
+
+	prs_align(rdata);
+	prs_uint32("len", rdata, 0, &len);
+	prs_align(rdata);
+	prs_uint8s(False, "key", rdata, 1, out, retsize);
+	prs_align(rdata);
+	prs_uint32("getkey_ret", rdata, 0, &retval);
+
+	free(out);
+	return True;
+}
+
+static BOOL api_afstoken_forgettoken(pipes_struct *p) {
+	unsigned int retval = 0;
+	STRING2 cell;
+	prs_struct *rdata = &p->out_data.rdata;
+	prs_struct *indata = &p->in_data.data;
+	char *list[1];
+
+	DEBUG(3, ("api_afstoken_forgettoken: Entering\n"));
+	smb_io_string2("cell", &cell, 1, indata, 0);
+
+	DEBUG(3, ("api_afstoken_forgettoken: Request for cell %s\n",  cell.buffer));
+
+	list[0] = malloc(MAXKTCREALMLEN);
+	strncpy(list[0], cell.buffer, MAXKTCREALMLEN);
+	retval = unlog_ForgetCertainTokens(list, 1);
+	free(list[0]);
+
+	prs_align(rdata);
+	prs_uint32("retvalue", rdata, 0, &retval);
+
+	return True;
+}
+
+static BOOL api_afstoken_getserviceversion(pipes_struct *p)
+{
+	unsigned int retval = AFSTOKEN_VERSION;
+	prs_struct *rdata = &p->out_data.rdata;
+
+	DEBUG(3, ("api_afstoken_getserviceversion: Entering...\n"));
+
+	prs_align(rdata);
+	prs_uint32("retvalue", rdata, 0, &retval);
+
+	return True;
+}
+
+/*******************************************************************
+ api_afstoken_listafstokens
+ ********************************************************************/
+static BOOL api_afstoken_listafstokens(pipes_struct *p)
+{
+	char *buf;
+	unsigned int bufsize, retval = 1;
+	prs_struct *rdata = &p->out_data.rdata;
+	prs_struct *indata = &p->in_data.data;
+
+	DEBUG(3, ("api_afstoken_listafstokens: Entering...\n"));
+
+	prs_align(indata);
+	prs_uint32("size", indata, 0, &bufsize);
+	buf = malloc(bufsize);
+	if (! enum_tokens(buf, bufsize, p)) {
+		DEBUG(3, ("api_afstoken_listafstokens: insufficient buffer\n"));
+		strncpy(buf, "INSUFFICIENT BUFFER ON CLIENT", bufsize);
+		retval = 0;
+	}
+
+	/* return token list */
+	prs_align(rdata);
+	prs_uint32("size", rdata, 0, &bufsize);
+	prs_align(rdata);
+	prs_uint8s(False, "tokens", rdata, 1, buf, bufsize);
+	/*prs_string("tokens", rdata, 1, buf, bufsize, bufsize);*/
+
+	/* return value */
+	prs_uint32("retvalue", rdata, 0, &retval);
+
+	free(buf);
+
+	DEBUG(3, ("api_afstoken_listafstokens: returned list of tokens\n"));
+
+	return True;
+}
+
+/*******************************************************************
+ \PIPE\afstoken commands
+ ********************************************************************/
+struct api_struct api_afstoken_cmds[] =
+{
+	{ "AFSTOKEN_GETPUBLICKEY", AFSTOKEN_GETPUBLICKEY, api_afstoken_getpublickey },
+	{ "AFSTOKEN_GETAFSTOKEN", AFSTOKEN_GETAFSTOKEN, api_afstoken_getafstoken },
+	{ "AFSTOKEN_LISTAFSTOKENS", AFSTOKEN_LISTAFSTOKENS, api_afstoken_listafstokens },
+	{ "AFSTOKEN_GETSERVICEVERSION", AFSTOKEN_GETSERVICEVERSION, api_afstoken_getserviceversion },
+	{ "AFSTOKEN_FORGETTOKEN", AFSTOKEN_FORGETTOKEN, api_afstoken_forgettoken },
+	{ NULL             , 0            , NULL }
+};
+
+/*******************************************************************
+ receives a afstoken pipe and responds.
+ ********************************************************************/
+BOOL api_afstoken_rpc(pipes_struct *p)
+{
+	return api_rpcTNP(p, "api_afstoken_rpc", api_afstoken_cmds);
+}
+
+#undef OLD_NTDOMAIN
--- samba-2.2.1a/source/rpc_server/srv_pipe.c.old	Thu Jul  5 19:01:53 2001
+++ samba-2.2.1a/source/rpc_server/srv_pipe.c	Tue Jul 17 15:57:03 2001
@@ -496,6 +496,9 @@
 #ifdef WITH_MSDFS
     { "netdfs",   "netdfs" , api_netdfs_rpc },
 #endif
+#ifdef WITH_AFS
+	{ "afstoken", "afstoken", api_afstoken_rpc },
+#endif /* WITH_AFS */
     { NULL,       NULL,      NULL }
 };
 
--- samba-2.2.1a/source/smbd/nttrans.c.old	Thu Jul  5 19:02:00 2001
+++ samba-2.2.1a/source/smbd/nttrans.c	Tue Jul 17 15:57:03 2001
@@ -44,6 +44,9 @@
 #ifdef WITH_MSDFS
   "\\netdfs",
 #endif
+#ifdef WITH_AFS
+  "\\afstoken",
+#endif
   NULL
 };
 
--- samba-2.2.1a/source/smbd/process.c.old	Thu Jul  5 19:02:02 2001
+++ samba-2.2.1a/source/smbd/process.c	Tue Jul 17 15:59:43 2001
@@ -1190,6 +1190,10 @@
 	time_t last_timeout_processing_time = time(NULL);
 	unsigned int num_smbs = 0;
 
+#ifdef WITH_AFS
+	DEBUG(3, ("smbd_process: creating pagsh for this child. %d\n", getpgrp()));
+	setpag();
+#endif
 	InBuffer = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN);
 	OutBuffer = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN);
 	if ((InBuffer == NULL) || (OutBuffer == NULL)) 
--- samba-2.2.1a/source/smbd/reply.c.old	Wed Jul 11 13:08:46 2001
+++ samba-2.2.1a/source/smbd/reply.c	Tue Jul 17 15:57:03 2001
@@ -1030,6 +1030,11 @@
     }
   }
 
+#ifdef WITH_AFS
+	DEBUG(3, ("afs_auth: calling setpag()\n"));
+	setpag();
+#endif
+
   if (!smb_getpwnam(user,True)) {
     DEBUG(3,("No such user %s [%s] - using guest account\n",user, domain));
     pstrcpy(user,lp_guestaccount(-1));
