--- 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 #include +#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 +#include +#include +#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 +#include +#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 +#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));