attachment upload
authorDerrickBrashear <DerrickBrashear@web>
Tue, 29 Jun 2010 21:35:32 +0000 (14:35 -0700)
committerOpenAFS Wiki <ikiwiki@openafs.org>
Tue, 29 Jun 2010 21:35:32 +0000 (14:35 -0700)
AFSLore/SMBtoAFS/samba-2.2.7-afstoken.patch [new file with mode: 0644]

diff --git a/AFSLore/SMBtoAFS/samba-2.2.7-afstoken.patch b/AFSLore/SMBtoAFS/samba-2.2.7-afstoken.patch
new file mode 100644 (file)
index 0000000..64742fb
--- /dev/null
@@ -0,0 +1,856 @@
+--- 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));