From 882a97985726eadbf1be7e936e08be8ce2712cce Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Tue, 7 Dec 2004 12:41:15 +0000 Subject: [PATCH 1/1] winnotes-20041207 update text files for StoreAnsiFilenames. ==================== This delta was composed from multiple commits as part of the CVS->Git migration. The checkin message with each commit was inconsistent. The following are the additional commit messages. ==================== Allow users to choose to store file names in AFS using ANSI code pages instead of OEM code pages. --- doc/txt/winnotes/afs-changes-since-1.2.txt | 12 ++ doc/txt/winnotes/afs-install-notes.txt | 49 +++++ doc/txt/winnotes/registry.txt | 18 +- src/WINNT/afsd/afsd_init.c | 87 ++++++--- src/WINNT/afsd/afslogon.c | 5 +- src/WINNT/afsd/smb.c | 57 ++++-- src/WINNT/afsd/smb.h | 285 ++++++++++++++--------------- src/WINNT/afsd/smb3.c | 62 +++++-- 8 files changed, 369 insertions(+), 206 deletions(-) diff --git a/doc/txt/winnotes/afs-changes-since-1.2.txt b/doc/txt/winnotes/afs-changes-since-1.2.txt index e9e8c06..4facd2f 100644 --- a/doc/txt/winnotes/afs-changes-since-1.2.txt +++ b/doc/txt/winnotes/afs-changes-since-1.2.txt @@ -1,4 +1,16 @@ Since 1.3.74: + * Added a new registry value, "StoreAnsiFilenames", which can be used + to force the use of ANSI character sets instead of OEM Code Pages. + This feature is useful when users require the ability to create + filenames with 8-bit characters and need to access the files from + both Latin-1 based Unix systems as well as from Windows. + + Activation of this feature will prevent access to files stored with + 8-bit OEM characters. + + * Shutdown all SMB threads in a synchronized manner when stopping the + service. + * There is currently a maximum cache size of 1.3GB. The limit is imposed by the largest contiguous block of unused memory within the 2GB process space which can be assigned to the memory mapped file. Unfortunately, diff --git a/doc/txt/winnotes/afs-install-notes.txt b/doc/txt/winnotes/afs-install-notes.txt index 38a7b3a..91eaae6 100644 --- a/doc/txt/winnotes/afs-install-notes.txt +++ b/doc/txt/winnotes/afs-install-notes.txt @@ -416,6 +416,55 @@ specify a cache size greater then 700MB will result in the automatic disabling of the signature check. +29. OpenAFS for Windows implements an SMB server which is used as a +gateway to the AFS filesystem. Because of the use of SMB, Windows +stores all files into AFS using the OEM code pages such as CP437 (United +States) or CP850 (Western Europe). These code pages are incompatible +with the ISO Latin-1 character set typically used as a default on Unix +systems in both the United States and Western Europe. Filenames stored +by OpenAFS for Windows are therefore unreadable on Unix systems if they +include any of the following characters: + + [Ç] 128 08/00 200 80 C cedilla + [ü] 129 08/01 201 81 u diaeresis + [é] 130 08/02 202 82 e acute + [â] 131 08/03 203 83 a circumflex + [ä] 132 08/04 204 84 a diaeresis + [à] 133 08/05 205 85 a grave + [å] 134 08/06 206 86 a ring + [ç] 135 08/07 207 87 c cedilla + [ê] 136 08/08 210 88 e circumflex + [ë] 137 08/09 211 89 e diaeresis + [è] 138 08/10 212 8A e grave + [ï] 139 08/11 213 8B i diaeresis + [î] 140 08/12 214 8C i circumflex + [ì] 141 08/13 215 8D i grave + [Ä] 142 08/14 216 8E A diaeresis + [Å] 143 08/15 217 8F A ring + [É] 144 09/00 220 90 E acute + [æ] 145 09/01 221 91 ae diphthong + [Æ] 146 09/02 222 92 AE diphthong + [ô] 147 09/03 223 93 o circumflex + [ö] 148 09/04 224 94 o diaeresis + [ò] 149 09/05 225 95 o grave + [û] 150 09/06 226 96 u circumflex + [ù] 151 09/07 227 97 u grave + [ÿ] 152 09/08 230 98 y diaeresis + [Ö] 153 09/09 231 99 O diaeresis + [Ü] 154 09/10 232 9A U diaeresis + [ø] 155 09/11 233 9B o slash + [£] 156 09/12 234 9C Pound sterling sign + [Ø] 157 09/13 235 9D O slash + [×] 158 09/14 236 9E Multiplication sign + [ƒ] 159 09/15 237 9F Florin sign + +As of 1.3.75, a new registry value, HKLM\SOFTWARE\OpenAFS\Client +"StoreAnsiFilenames" can be set to instruct OpenAFS for Windows to store +filenames using the ANSI Code Page instead of the OEM Code Page. The ANSI +Code Page is a compatible superset of Latin-1. This setting is not the +default setting because making this change would prevent OpenAFS for Windows +from being able to access filenames containing the above characters. + ------------------------------------------------------------------------ Reporting Bugs: diff --git a/doc/txt/winnotes/registry.txt b/doc/txt/winnotes/registry.txt index 064455d..f7cab8d 100644 --- a/doc/txt/winnotes/registry.txt +++ b/doc/txt/winnotes/registry.txt @@ -450,7 +450,7 @@ Default : 0x1 Value : IoctlDebug -Type : REG_DEBUG +Type : REG_DWORD Default : 0x0 This value can be used to debug the cause of pioctl() failures. @@ -460,6 +460,22 @@ Default : 0x0 pioctl() call is failing. +Value : StoreAnsiFilenames +Type : REG_DWORD +Default : 0x0 + + This value can be used to force the AFS Client Service to + store filenames using the Windows system's ANSI character set + instead of the OEM Code Page character set which has traditionally + been used by SMB file systems. + + Note: The use of ANSI characters will render access to files + with 8-bit OEM file names unaccessible from Windows. This option + is of use primarily when you wish to allow file names produced + on Windows to be accessible from Latin-1 Unix systems and vice + versa. + + 2.1 Domain specific configuration keys for the Network Provider --------------------------------------------------------------- diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index 9509f55..ae625b8 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include @@ -37,6 +39,8 @@ extern afs_int32 cryptall; char AFSConfigKeyName[] = "SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters"; +char OpenAFSConfigKeyName[] = + "SOFTWARE\\OpenAFS\\Client"; osi_log_t *afsd_logp; @@ -99,6 +103,33 @@ HANDLE afsi_file; int cm_dnsEnabled = 1; #endif + +static int afsi_log_useTimestamp = 1; + +void +afsi_log(char *pattern, ...) +{ + char s[256], t[100], d[100], u[512]; + DWORD zilch; + va_list ap; + va_start(ap, pattern); + + StringCbVPrintfA(s, sizeof(s), pattern, ap); + if ( afsi_log_useTimestamp ) { + GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, t, sizeof(t)); + GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, d, sizeof(d)); + StringCbPrintfA(u, sizeof(u), "%s %s: %s\n", d, t, s); + if (afsi_file != INVALID_HANDLE_VALUE) + WriteFile(afsi_file, u, strlen(u), &zilch, NULL); +#ifdef NOTSERVICE + printf("%s", u); +#endif + } else { + if (afsi_file != INVALID_HANDLE_VALUE) + WriteFile(afsi_file, s, strlen(s), &zilch, NULL); + } +} + extern initUpperCaseTable(); void afsd_initUpperCaseTable() { @@ -162,32 +193,20 @@ afsi_start() WriteFile(afsi_file, p, strlen(p), &zilch, NULL); WriteFile(afsi_file, path, strlen(path), &zilch, NULL); WriteFile(afsi_file, "\n", 1, &zilch, NULL); -} - -static int afsi_log_useTimestamp = 1; - -void -afsi_log(char *pattern, ...) -{ - char s[256], t[100], d[100], u[512]; - DWORD zilch; - va_list ap; - va_start(ap, pattern); - StringCbVPrintfA(s, sizeof(s), pattern, ap); - if ( afsi_log_useTimestamp ) { - GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, t, sizeof(t)); - GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, d, sizeof(d)); - StringCbPrintfA(u, sizeof(u), "%s %s: %s\n", d, t, s); - if (afsi_file != INVALID_HANDLE_VALUE) - WriteFile(afsi_file, u, strlen(u), &zilch, NULL); -#ifdef NOTSERVICE - printf("%s", u); -#endif - } else { - if (afsi_file != INVALID_HANDLE_VALUE) - WriteFile(afsi_file, s, strlen(s), &zilch, NULL); - } + /* Initialize C RTL Code Page conversion functions */ + /* All of the path info obtained from the SMB client is in the OEM code page */ + afsi_log("OEM Code Page = %d", GetOEMCP()); + afsi_log("locale = %s", setlocale(LC_ALL,NULL)); +#ifdef COMMENT + /* Two things to look into. First, should mbstowcs() be performing + * character set translations from OEM to Unicode in smb3.c; + * Second, do we need to set this translation in each function + * due to multi-threading. + */ + afsi_log("locale -> %s", setlocale(LC_ALL, ".OCP")); + afsi_log("_setmbcp = %d -> %d", _setmbcp(_MB_CP_OEM), _getmbcp()); +#endif /* COMMENT */ } /* @@ -1019,11 +1038,27 @@ int afsd_InitDaemons(char **reasonP) int afsd_InitSMB(char **reasonP, void *aMBfunc) { + HKEY parmKey; + DWORD dummyLen; + DWORD dwValue; + DWORD code; + + code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, OpenAFSConfigKeyName, + 0, KEY_QUERY_VALUE, &parmKey); + if (code == ERROR_SUCCESS) { + dummyLen = sizeof(DWORD); + code = RegQueryValueEx(parmKey, "StoreAnsiFilenames", NULL, NULL, + (BYTE *) &dwValue, &dummyLen); + if (code == ERROR_SUCCESS) + smb_StoreAnsiFilenames = dwValue ? 1 : 0; + RegCloseKey (parmKey); + } + /* Do this last so that we don't handle requests before init is done. * Here we initialize the SMB listener. */ smb_Init(afsd_logp, cm_NetbiosName, smb_UseV3, LANadapter, numSvThreads, aMBfunc); - afsi_log("smb_Init"); + afsi_log("smb_Init complete"); return 0; } diff --git a/src/WINNT/afsd/afslogon.c b/src/WINNT/afsd/afslogon.c index 7f6b4e1..0446fb4 100644 --- a/src/WINNT/afsd/afslogon.c +++ b/src/WINNT/afsd/afslogon.c @@ -550,10 +550,6 @@ UnicodeStringToANSI(UNICODE_STRING uInputString, LPSTR lpszOutputString, int nOu GetCPInfo(CP_ACP, &CodePageInfo); - if (CodePageInfo.MaxCharSize > 1) - // Only supporting non-Unicode strings - return FALSE; - if (uInputString.Buffer && ((LPBYTE) uInputString.Buffer)[1] == '\0') { // Looks like unicode, better translate it @@ -565,6 +561,7 @@ UnicodeStringToANSI(UNICODE_STRING uInputString, LPSTR lpszOutputString, int nOu } else lpszOutputString[0] = '\0'; + return FALSE; } // UnicodeStringToANSI diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index 60a45ad..093ef02 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -51,6 +51,8 @@ int smbShutdownFlag = 0; int smb_LogoffTokenTransfer; time_t smb_LogoffTransferTimeout; +int smb_StoreAnsiFilenames = 0; + DWORD last_msg_time = 0; long ongoingOps = 0; @@ -1653,7 +1655,7 @@ void smb_GCDirSearches(int isV3) int i; victimCount = 0; /* how many have we got so far */ - for(tp = smb_lastDirSearchp; tp; tp=prevp) { + for (tp = smb_lastDirSearchp; tp; tp=prevp) { /* we'll move tp from queue, so * do this early. */ @@ -2998,6 +3000,8 @@ long smb_ReceiveCoreTreeConnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * /* parse input parameters */ tp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(tp, &tp); + if (smb_StoreAnsiFilenames) + OemToChar(pathp,pathp); passwordp = smb_ParseASCIIBlock(tp, &tp); tp = strrchr(pathp, '\\'); if (!tp) @@ -3174,6 +3178,8 @@ long smb_ReceiveCoreSearchVolume(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t tp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(tp, (char **) &tp); osi_assert(pathp != NULL); + if (smb_StoreAnsiFilenames) + OemToChar(pathp,pathp); statBlockp = smb_ParseVblBlock(tp, (char **) &tp, &statLen); osi_assert(statBlockp != NULL); if (statLen == 0) { @@ -3355,6 +3361,8 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou tp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(tp, &tp); + if (smb_StoreAnsiFilenames) + OemToChar(pathp,pathp); inCookiep = smb_ParseVblBlock(tp, &tp, &dataLength); /* bail out if request looks bad */ @@ -3657,7 +3665,7 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou * attributes */ /* no hidden files */ - if(smb_hideDotFiles && !(dsp->attribute & SMB_ATTR_HIDDEN) && smb_IsDotFile(actualName)) + if (smb_hideDotFiles && !(dsp->attribute & SMB_ATTR_HIDDEN) && smb_IsDotFile(actualName)) goto nextEntry; if (!(dsp->attribute & SMB_ATTR_DIRECTORY)) /* no directories */ @@ -3726,6 +3734,8 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou * never hurts to be sure. */ strncpy(op, actualName, 13); + if (smb_StoreAnsiFilenames) + CharToOem(op, op); /* Uppercase if requested by client */ if ((((smb_t *)inp)->flg2 & 1) == 0) @@ -3809,12 +3819,12 @@ long smb_ReceiveCoreCheckPath(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou pathp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(pathp, NULL); + if (!pathp) + return CM_ERROR_BADFD; + if (smb_StoreAnsiFilenames) + OemToChar(pathp,pathp); osi_Log1(smb_logp, "SMB receive check path %s", osi_LogSaveString(smb_logp, pathp)); - - if (!pathp) { - return CM_ERROR_BADFD; - } rootScp = cm_rootSCachep; @@ -3881,11 +3891,11 @@ long smb_ReceiveCoreSetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack pathp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(pathp, NULL); - - if (!pathp) { + if (!pathp) return CM_ERROR_BADSMB; - } - + if (smb_StoreAnsiFilenames) + OemToChar(pathp,pathp); + osi_Log2(smb_logp, "SMB receive setfile attributes time %d, attr 0x%x", dosTime, attribute); @@ -3979,13 +3989,14 @@ long smb_ReceiveCoreGetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack pathp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(pathp, NULL); - - if (!pathp) { + if (!pathp) return CM_ERROR_BADSMB; - } if (*pathp == 0) /* null path */ pathp = "\\"; + else + if (smb_StoreAnsiFilenames) + OemToChar(pathp,pathp); osi_Log1(smb_logp, "SMB receive getfile attributes path %s", osi_LogSaveString(smb_logp, pathp)); @@ -4139,6 +4150,8 @@ long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) pathp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(pathp, NULL); + if (smb_StoreAnsiFilenames) + OemToChar(pathp,pathp); osi_Log1(smb_logp, "SMB receive open file [%s]", osi_LogSaveString(smb_logp, pathp)); @@ -4324,6 +4337,8 @@ long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) tp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(tp, &tp); + if (smb_StoreAnsiFilenames) + OemToChar(pathp,pathp); osi_Log1(smb_logp, "SMB receive unlink %s", osi_LogSaveString(smb_logp, pathp)); @@ -4745,7 +4760,11 @@ smb_ReceiveCoreRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) tp = smb_GetSMBData(inp, NULL); oldPathp = smb_ParseASCIIBlock(tp, &tp); + if (smb_StoreAnsiFilenames) + OemToChar(oldPathp,oldPathp); newPathp = smb_ParseASCIIBlock(tp, &tp); + if (smb_StoreAnsiFilenames) + OemToChar(newPathp,newPathp); osi_Log2(smb_logp, "smb rename [%s] to [%s]", osi_LogSaveString(smb_logp, oldPathp), @@ -4822,6 +4841,8 @@ long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou tp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(tp, &tp); + if (smb_StoreAnsiFilenames) + OemToChar(pathp,pathp); spacep = inp->spacep; smb_StripLastComponent(spacep->data, &lastNamep, pathp); @@ -5843,6 +5864,8 @@ long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp tp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(tp, &tp); + if (smb_StoreAnsiFilenames) + OemToChar(pathp,pathp); if (strcmp(pathp, "\\") == 0) return CM_ERROR_EXISTS; @@ -5957,6 +5980,8 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) tp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(tp, &tp); + if (smb_StoreAnsiFilenames) + OemToChar(pathp,pathp); spacep = inp->spacep; smb_StripLastComponent(spacep->data, &lastNamep, pathp); @@ -5981,8 +6006,10 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* otherwise, scp points to the parent directory. Do a lookup, and * truncate the file if we find it, otherwise we create the file. */ - if (!lastNamep) lastNamep = pathp; - else lastNamep++; + if (!lastNamep) + lastNamep = pathp; + else + lastNamep++; if (!smb_IsLegalFilename(lastNamep)) return CM_ERROR_BADNTFILENAME; diff --git a/src/WINNT/afsd/smb.h b/src/WINNT/afsd/smb.h index e742bcf..81ec7b1 100644 --- a/src/WINNT/afsd/smb.h +++ b/src/WINNT/afsd/smb.h @@ -18,21 +18,21 @@ /* basic core protocol SMB structure */ typedef struct smb { - unsigned char id[4]; - unsigned char com; - unsigned char rcls; - unsigned char reh; - unsigned char errLow; - unsigned char errHigh; - unsigned char reb; - unsigned short flg2; - unsigned short res[6]; - unsigned short tid; - unsigned short pid; - unsigned short uid; - unsigned short mid; - unsigned char wct; - unsigned char vdata[1]; + unsigned char id[4]; + unsigned char com; + unsigned char rcls; + unsigned char reh; + unsigned char errLow; + unsigned char errHigh; + unsigned char reb; + unsigned short flg2; + unsigned short res[6]; + unsigned short tid; + unsigned short pid; + unsigned short uid; + unsigned short mid; + unsigned char wct; + unsigned char vdata[1]; } smb_t; /* more defines */ @@ -94,23 +94,23 @@ typedef struct smb { */ #define SMB_PACKETMAGIC 0x7436353 /* magic # for packets */ typedef struct smb_packet { - char data[SMB_PACKETSIZE]; - struct smb_packet *nextp; /* in free list, or whatever */ - long magic; - cm_space_t *spacep; /* use this for stripping last component */ - NCB *ncbp; /* use this for sending */ - struct smb_vc *vcp; - unsigned long resumeCode; - unsigned short inCount; - unsigned short fid; /* for calls bundled with openAndX */ - unsigned char *wctp; - unsigned char inCom; - unsigned char oddByte; - unsigned short ncb_length; - unsigned char flags; + char data[SMB_PACKETSIZE]; + struct smb_packet *nextp; /* in free list, or whatever */ + long magic; + cm_space_t *spacep; /* use this for stripping last component */ + NCB *ncbp; /* use this for sending */ + struct smb_vc *vcp; + unsigned long resumeCode; + unsigned short inCount; + unsigned short fid; /* for calls bundled with openAndX */ + unsigned char *wctp; + unsigned char inCom; + unsigned char oddByte; + unsigned short ncb_length; + unsigned char flags; #ifdef DJGPP - dos_ptr dos_pkt; - unsigned int dos_pkt_sel; + dos_ptr dos_pkt; + unsigned int dos_pkt_sel; #endif /* DJGPP */ } smb_packet_t; @@ -122,13 +122,13 @@ typedef struct smb_packet { /* a structure for making Netbios calls; locked by smb_globalLock */ #define SMB_NCBMAGIC 0x2334344 typedef struct myncb { - NCB ncb; /* ncb to use */ - struct myncb *nextp; /* when on free list */ - long magic; + NCB ncb; /* ncb to use */ + struct myncb *nextp; /* when on free list */ + long magic; #ifdef DJGPP - dos_ptr dos_ncb; - smb_packet_t *orig_pkt; - unsigned int dos_ncb_sel; + dos_ptr dos_ncb; + smb_packet_t *orig_pkt; + unsigned int dos_ncb_sel; #endif /* DJGPP */ } smb_ncb_t; @@ -140,28 +140,27 @@ typedef struct myncb { /* one per virtual circuit */ typedef struct smb_vc { - struct smb_vc *nextp; /* not used */ - unsigned long refCount; /* the reference count */ - long flags; /* the flags, if any; locked by mx */ + struct smb_vc *nextp; /* not used */ + unsigned long refCount; /* the reference count */ + long flags; /* the flags, if any; locked by mx */ osi_mutex_t mx; /* the mutex */ - long vcID; /* VC id */ - unsigned short lsn; /* the NCB LSN associated with this */ - unsigned short uidCounter; /* session ID counter */ - unsigned short tidCounter; /* tree ID counter */ - unsigned short fidCounter; /* file handle ID counter */ + long vcID; /* VC id */ + unsigned short lsn; /* the NCB LSN associated with this */ + unsigned short uidCounter; /* session ID counter */ + unsigned short tidCounter; /* tree ID counter */ + unsigned short fidCounter; /* file handle ID counter */ struct smb_tid *tidsp; /* the first child in the tid list */ - struct smb_user *usersp; /* the first child in the user session list */ + struct smb_user *usersp; /* the first child in the user session list */ struct smb_fid *fidsp; /* the first child in the open file list */ - struct smb_user *justLoggedOut; /* ready for profile upload? */ - time_t logoffTime; /* tick count when logged off */ - /*struct cm_user *logonDLLUser; /* integrated logon user */ - unsigned char errorCount; + struct smb_user *justLoggedOut; /* ready for profile upload? */ + time_t logoffTime; /* tick count when logged off */ + unsigned char errorCount; char rname[17]; - int lana; - char encKey[MSV1_0_CHALLENGE_LENGTH]; /* MSV1_0_CHALLENGE_LENGTH is 8 */ - void * secCtx; /* security context when negotiating SMB extended auth - * valid when SMB_VCFLAG_AUTH_IN_PROGRESS is set - */ + int lana; + char encKey[MSV1_0_CHALLENGE_LENGTH]; /* MSV1_0_CHALLENGE_LENGTH is 8 */ + void * secCtx; /* security context when negotiating SMB extended auth + * valid when SMB_VCFLAG_AUTH_IN_PROGRESS is set + */ } smb_vc_t; /* have we negotiated ... */ @@ -176,23 +175,23 @@ typedef struct smb_vc { /* one per user session */ typedef struct smb_user { - struct smb_user *nextp; /* next sibling */ - unsigned long refCount; /* ref count */ - long flags; /* flags; locked by mx */ - osi_mutex_t mx; - long userID; /* the session identifier */ - struct smb_vc *vcp; /* back ptr to virtual circuit */ - struct smb_username *unp; /* user name struct */ + struct smb_user *nextp; /* next sibling */ + unsigned long refCount; /* ref count */ + long flags; /* flags; locked by mx */ + osi_mutex_t mx; + long userID; /* the session identifier */ + struct smb_vc *vcp; /* back ptr to virtual circuit */ + struct smb_username *unp; /* user name struct */ } smb_user_t; typedef struct smb_username { - struct smb_username *nextp; /* next sibling */ - unsigned long refCount; /* ref count */ - long flags; /* flags; locked by mx */ - osi_mutex_t mx; - struct cm_user *userp; /* CM user structure */ - char *name; /* user name */ - char *machine; /* machine name */ + struct smb_username *nextp; /* next sibling */ + unsigned long refCount; /* ref count */ + long flags; /* flags; locked by mx */ + osi_mutex_t mx; + struct cm_user *userp; /* CM user structure */ + char *name; /* user name */ + char *machine; /* machine name */ } smb_username_t; #define SMB_USERFLAG_DELETE 1 /* delete struct when ref count zero */ @@ -201,15 +200,15 @@ typedef struct smb_username { /* one per tree-connect */ typedef struct smb_tid { - struct smb_tid *nextp; /* next sibling */ - unsigned long refCount; - long flags; - osi_mutex_t mx; /* for non-tree-related stuff */ - unsigned short tid; /* the tid */ - struct smb_vc *vcp; /* back ptr */ - struct cm_user *userp; /* user logged in at the + struct smb_tid *nextp; /* next sibling */ + unsigned long refCount; + long flags; + osi_mutex_t mx; /* for non-tree-related stuff */ + unsigned short tid; /* the tid */ + struct smb_vc *vcp; /* back ptr */ + struct cm_user *userp; /* user logged in at the * tree connect level (base) */ - char *pathname; /* pathname derived from sharename */ + char *pathname; /* pathname derived from sharename */ } smb_tid_t; #define SMB_TIDFLAG_DELETE 1 /* delete struct when ref count zero */ @@ -217,40 +216,39 @@ typedef struct smb_tid { /* one per process ID */ typedef struct smb_pid { - struct smb_pid *nextp; /* next sibling */ - unsigned long refCount; - long flags; - osi_mutex_t mx; /* for non-tree-related stuff */ - unsigned short pid; /* the pid */ - struct smb_tid *tidp; /* back ptr */ + struct smb_pid *nextp; /* next sibling */ + unsigned long refCount; + long flags; + osi_mutex_t mx; /* for non-tree-related stuff */ + unsigned short pid; /* the pid */ + struct smb_tid *tidp; /* back ptr */ } smb_pid_t; /* ioctl parameter, while being assembled and/or processed */ typedef struct smb_ioctl { - /* input side */ - char *inDatap; /* ioctl func's current position + /* input side */ + char *inDatap; /* ioctl func's current position * in input parameter block */ - char *inAllocp; /* allocated input parameter block */ - long inCopied; /* # of input bytes copied in so far + char *inAllocp; /* allocated input parameter block */ + long inCopied; /* # of input bytes copied in so far * by write calls */ - cm_space_t *prefix; /* prefix for subst drives */ - char *tidPathp; /* Pathname associated with Tree ID */ - - /* output side */ - char *outDatap; /* output results assembled so far */ - char *outAllocp; /* output results assembled so far */ - long outCopied; /* # of output bytes copied back so far - * by read calls */ + cm_space_t *prefix; /* prefix for subst drives */ + char *tidPathp; /* Pathname associated with Tree ID */ + + /* output side */ + char *outDatap; /* output results assembled so far */ + char *outAllocp; /* output results assembled so far */ + long outCopied; /* # of output bytes copied back so far + * by read calls */ - /* flags */ - long flags; + /* flags */ + long flags; - /* fid pointer */ - struct smb_fid *fidp; - - /* uid pointer */ - smb_user_t *uidp; + /* fid pointer */ + struct smb_fid *fidp; + /* uid pointer */ + smb_user_t *uidp; } smb_ioctl_t; /* flags for smb_ioctl_t */ @@ -259,27 +257,27 @@ typedef struct smb_ioctl { /* one per file ID; these are really file descriptors */ typedef struct smb_fid { - osi_queue_t q; - unsigned long refCount; - unsigned long flags; - osi_mutex_t mx; /* for non-tree-related stuff */ - unsigned short fid; /* the file ID */ - struct smb_vc *vcp; /* back ptr */ - struct cm_scache *scp; /* scache of open file */ - long offset; /* our file pointer */ - smb_ioctl_t *ioctlp; /* ptr to ioctl structure */ + osi_queue_t q; + unsigned long refCount; + unsigned long flags; + osi_mutex_t mx; /* for non-tree-related stuff */ + unsigned short fid; /* the file ID */ + struct smb_vc *vcp; /* back ptr */ + struct cm_scache *scp; /* scache of open file */ + long offset; /* our file pointer */ + smb_ioctl_t *ioctlp; /* ptr to ioctl structure */ /* Under NT, we may need to know the * parent directory and pathname used * to open the file, either to delete * the file on close, or to do a * change notification */ - struct cm_scache *NTopen_dscp; /* parent directory (NT) */ - char *NTopen_pathp; /* path used in open (NT) */ - char *NTopen_wholepathp; /* entire path, not just last name */ - int curr_chunk; /* chunk being read */ - int prev_chunk; /* previous chunk read */ - int raw_writers; /* pending async raw writes */ - EVENT_HANDLE raw_write_event; /* signal this when raw_writers zero */ + struct cm_scache *NTopen_dscp; /* parent directory (NT) */ + char *NTopen_pathp; /* path used in open (NT) */ + char *NTopen_wholepathp; /* entire path, not just last name */ + int curr_chunk; /* chunk being read */ + int prev_chunk; /* previous chunk read */ + int raw_writers; /* pending async raw writes */ + EVENT_HANDLE raw_write_event; /* signal this when raw_writers zero */ } smb_fid_t; #define SMB_FID_OPENREAD 1 /* open for reading */ @@ -311,17 +309,17 @@ typedef struct smb_fid { /* for tracking in-progress directory searches */ typedef struct smb_dirSearch { - osi_queue_t q; /* queue of all outstanding cookies */ - osi_mutex_t mx; /* just in case the caller screws up */ - unsigned long refCount; /* reference count */ - long cookie; /* value returned to the caller */ - struct cm_scache *scp; /* vnode of the dir we're searching */ - time_t lastTime; /* last time we used this */ - long flags; /* flags (see below); + osi_queue_t q; /* queue of all outstanding cookies */ + osi_mutex_t mx; /* just in case the caller screws up */ + unsigned long refCount; /* reference count */ + long cookie; /* value returned to the caller */ + struct cm_scache *scp; /* vnode of the dir we're searching */ + time_t lastTime; /* last time we used this */ + long flags; /* flags (see below); * locked by smb_globalLock */ - unsigned short attribute; /* search attribute + unsigned short attribute; /* search attribute * (used for extended protocol) */ - char mask[256]; /* search mask for V3 */ + char mask[256]; /* search mask for V3 */ } smb_dirSearch_t; #define SMB_DIRSEARCH_DELETE 1 /* delete struct when ref count zero */ @@ -331,11 +329,11 @@ typedef struct smb_dirSearch { /* type for patching directory listings */ typedef struct smb_dirListPatch { - osi_queue_t q; - char *dptr; /* ptr to attr, time, data, sizel, sizeh */ - long flags; /* flags. See below */ - cm_fid_t fid; - cm_dirEntry_t *dep; /* temp */ + osi_queue_t q; + char *dptr; /* ptr to attr, time, data, sizel, sizeh */ + long flags; /* flags. See below */ + cm_fid_t fid; + cm_dirEntry_t *dep; /* temp */ } smb_dirListPatch_t; /* dirListPatch Flags */ @@ -346,12 +344,12 @@ typedef struct smb_dirListPatch { /* waiting lock list elements */ typedef struct smb_waitingLock { - osi_queue_t q; - smb_vc_t *vcp; - smb_packet_t *inp; - smb_packet_t *outp; - time_t timeRemaining; - void *lockp; + osi_queue_t q; + smb_vc_t *vcp; + smb_packet_t *inp; + smb_packet_t *outp; + time_t timeRemaining; + void *lockp; } smb_waitingLock_t; extern smb_waitingLock_t *smb_allWaitingLocks; @@ -359,8 +357,8 @@ extern smb_waitingLock_t *smb_allWaitingLocks; typedef long (smb_proc_t)(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp); typedef struct smb_dispatch { - smb_proc_t *procp; /* proc to call */ - int flags; /* flags describing function */ + smb_proc_t *procp; /* proc to call */ + int flags; /* flags describing function */ } smb_dispatch_t; #define SMB_DISPATCHFLAG_CHAINED 1 /* this is an _AND_X function */ @@ -492,6 +490,7 @@ extern time_t smb_LogoffTransferTimeout; extern int smb_maxVCPerServer; /* max # of VCs per server */ extern int smb_maxMpxRequests; /* max # of mpx requests */ +extern int smb_StoreAnsiFilenames; extern int smb_hideDotFiles; extern unsigned int smb_IsDotFile(char *lastComp); @@ -515,12 +514,12 @@ extern LSA_STRING smb_lsaLogonOrigin; /* used for getting a challenge for SMB auth */ typedef struct _MSV1_0_LM20_CHALLENGE_REQUEST { - MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType; + MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType; } MSV1_0_LM20_CHALLENGE_REQUEST, *PMSV1_0_LM20_CHALLENGE_REQUEST; typedef struct _MSV1_0_LM20_CHALLENGE_RESPONSE { - MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType; - UCHAR ChallengeToClient[MSV1_0_CHALLENGE_LENGTH]; + MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType; + UCHAR ChallengeToClient[MSV1_0_CHALLENGE_LENGTH]; } MSV1_0_LM20_CHALLENGE_RESPONSE, *PMSV1_0_LM20_CHALLENGE_RESPONSE; /**/ diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index f03270c..4bf92a6 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -936,6 +936,8 @@ long smb_ReceiveV3TreeConnectX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *o tp = smb_GetSMBData(inp, NULL); passwordp = smb_ParseString(tp, &tp); pathp = smb_ParseString(tp, &tp); + if (smb_StoreAnsiFilenames) + OemToChar(pathp,pathp); servicep = smb_ParseString(tp, &tp); tp = strrchr(pathp, '\\'); @@ -1202,7 +1204,7 @@ void smb_SendTran2Packet(smb_vc_t *vcp, smb_tran2Packet_t *t2p, smb_packet_t *tp smb_SetSMBParm(tp, 7, dataOffset); /* offset of data */ smb_SetSMBParm(tp, 8, 0); /* data displacement */ smb_SetSMBParm(tp, 9, 0); /* low: setup word count * - * high: resvd */ + * high: resvd */ datap = smb_GetSMBData(tp, NULL); *datap++ = 0; /* we rounded to even */ @@ -2036,7 +2038,9 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) if (attributes & 1) initialModeBits &= ~0222; pathp = (char *) (&p->parmsp[14]); - + if (smb_StoreAnsiFilenames) + OemToChar(pathp,pathp); + outp = smb_GetTran2ResponsePacket(vcp, p, op, 40, 0); spacep = cm_GetSpace(); @@ -3578,6 +3582,8 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t dsp = smb_NewDirSearch(1); dsp->attribute = attribute; pathp = ((char *) p->parmsp) + 12; /* points to path */ + if (smb_StoreAnsiFilenames) + OemToChar(pathp,pathp); nextCookie = 0; maskp = strrchr(pathp, '\\'); if (maskp == NULL) @@ -3974,11 +3980,15 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t else *((u_long *)(op + 60)) = onbytes; strcpy(origOp+ohbytes, dep->name); + if (smb_StoreAnsiFilenames) + CharToOem(origOp+ohbytes, origOp+ohbytes); /* Short name if requested and needed */ if (infoLevel == 0x104) { if (NeedShortName) { strcpy(op + 70, shortName); + if (smb_StoreAnsiFilenames) + CharToOem(op + 70, op + 70); *(op + 68) = shortNameEnd - shortName; } } @@ -3996,7 +4006,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t /* now we emit the attribute. This is tricky, since * we need to really stat the file to find out what * type of entry we've got. Right now, we're copying - * out data from * a buffer, while holding the scp + * out data from a buffer, while holding the scp * locked, so it isn't really convenient to stat * something now. We'll put in a place holder * now, and make a second pass before returning this @@ -4208,6 +4218,8 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) if (attributes & 1) initialModeBits &= ~0222; pathp = smb_GetSMBData(inp, NULL); + if (smb_StoreAnsiFilenames) + OemToChar(pathp,pathp); spacep = inp->spacep; smb_StripLastComponent(spacep->data, &lastNamep, pathp); @@ -4851,6 +4863,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) realPathp = malloc(nameLength+1); memcpy(realPathp, pathp, nameLength); realPathp[nameLength] = 0; + if (smb_StoreAnsiFilenames) + OemToChar(realPathp,realPathp); spacep = inp->spacep; smb_StripLastComponent(spacep->data, &lastNamep, realPathp); @@ -5472,6 +5486,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out realPathp = malloc(nameLength+1); memcpy(realPathp, pathp, nameLength); realPathp[nameLength] = 0; + if (smb_StoreAnsiFilenames) + OemToChar(realPathp,realPathp); spacep = cm_GetSpace(); smb_StripLastComponent(spacep->data, &lastNamep, realPathp); @@ -5978,16 +5994,16 @@ long smb_ReceiveNTTranNotifyChange(smb_vc_t *vcp, smb_packet_t *inp, unsigned char nullSecurityDesc[36] = { 0x01, /* security descriptor revision */ 0x00, /* reserved, should be zero */ - 0x00, 0x80, /* security descriptor control; - * 0x8000 : self-relative format */ + 0x00, 0x80, /* security descriptor control; + * 0x8000 : self-relative format */ 0x14, 0x00, 0x00, 0x00, /* offset of owner SID */ 0x1c, 0x00, 0x00, 0x00, /* offset of group SID */ 0x00, 0x00, 0x00, 0x00, /* offset of DACL would go here */ 0x00, 0x00, 0x00, 0x00, /* offset of SACL would go here */ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* "null SID" owner SID */ + /* "null SID" owner SID */ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - /* "null SID" group SID */ + /* "null SID" group SID */ }; long smb_ReceiveNTTranQuerySecurityDesc(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) @@ -6214,6 +6230,7 @@ void smb_NotifyChange(DWORD action, DWORD notifyFilter, smb_SetSMBDataLength(watch, parmCount + 1); if (parmCount != 0) { + char * p; outData = smb_GetSMBData(watch, NULL); outData++; /* round to get to parmOffset */ oldOutData = outData; @@ -6223,7 +6240,11 @@ void smb_NotifyChange(DWORD action, DWORD notifyFilter, /* Action */ *((DWORD *)outData) = nameLen*2; outData += 4; /* File Name Length */ - mbstowcs((WCHAR *)outData, filename, nameLen); + p = strdup(filename); + if (smb_StoreAnsiFilenames) + CharToOem(p,p); + mbstowcs((WCHAR *)outData, p, nameLen); + free(p); /* File Name */ if (twoEntries) { outData = oldOutData + oldParmCount; @@ -6233,8 +6254,11 @@ void smb_NotifyChange(DWORD action, DWORD notifyFilter, /* Action */ *((DWORD *)outData) = otherNameLen*2; outData += 4; /* File Name Length */ - mbstowcs((WCHAR *)outData, otherFilename, - otherNameLen); /* File Name */ + p = strdup(otherFilename); + if (smb_StoreAnsiFilenames) + CharToOem(p,p); + mbstowcs((WCHAR *)outData, p, otherNameLen); /* File Name */ + free(p); } } @@ -6346,7 +6370,7 @@ long smb_ReceiveNTCancel(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveNTRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *oldname, *newname; + char *oldPathp, *newPathp; long code = 0; cm_user_t *userp; char * tp; @@ -6362,18 +6386,22 @@ long smb_ReceiveNTRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } tp = smb_GetSMBData(inp, NULL); - oldname = smb_ParseASCIIBlock(tp, &tp); - newname = smb_ParseASCIIBlock(tp, &tp); + oldPathp = smb_ParseASCIIBlock(tp, &tp); + if (smb_StoreAnsiFilenames) + OemToChar(oldPathp,oldPathp); + newPathp = smb_ParseASCIIBlock(tp, &tp); + if (smb_StoreAnsiFilenames) + OemToChar(newPathp,newPathp); osi_Log3(smb_logp, "NTRename for [%s]->[%s] type [%s]", - osi_LogSaveString(smb_logp, oldname), - osi_LogSaveString(smb_logp, newname), + osi_LogSaveString(smb_logp, oldPathp), + osi_LogSaveString(smb_logp, newPathp), ((rename_type==RENAME_FLAG_RENAME)?"rename":"hardlink")); if (rename_type == RENAME_FLAG_RENAME) { - code = smb_Rename(vcp,inp,oldname,newname,attrs); + code = smb_Rename(vcp,inp,oldPathp,newPathp,attrs); } else { /* RENAME_FLAG_HARD_LINK */ - code = smb_Link(vcp,inp,oldname,newname); + code = smb_Link(vcp,inp,oldPathp,newPathp); } return code; } -- 1.9.4