Index: openafs/src/WINNT/afsd/NTMakefile diff -c openafs/src/WINNT/afsd/NTMakefile:1.46.2.2 openafs/src/WINNT/afsd/NTMakefile:1.46.2.3 *** openafs/src/WINNT/afsd/NTMakefile:1.46.2.2 Tue Jul 4 02:28:23 2006 --- openafs/src/WINNT/afsd/NTMakefile Mon Jul 24 10:13:16 2006 *************** *** 246,252 **** ole32.lib \ adsiid.lib \ activeds.lib \ ! userenv.lib $(LOGON_DLLFILE): $(LOGON_DLLOBJS) $(LOGON_DLLLIBS) $(DLLGUILINK) $(LOGONLINKFLAGS) -def:afslogon.def $(LOGON_DLLSDKLIBS) --- 246,253 ---- ole32.lib \ adsiid.lib \ activeds.lib \ ! user32.lib \ ! userenv.lib $(LOGON_DLLFILE): $(LOGON_DLLOBJS) $(LOGON_DLLLIBS) $(DLLGUILINK) $(LOGONLINKFLAGS) -def:afslogon.def $(LOGON_DLLSDKLIBS) *************** *** 371,377 **** # afscpcc.exe $(EXEDIR)\afscpcc.exe: $(OUT)\afscpcc.obj $(OUT)\afscpcc.res $(LOGON_DLLLIBS) ! $(EXECONLINK) dnsapi.lib mpr.lib iphlpapi.lib $(_VC_MANIFEST_EMBED_EXE) $(EXEPREP) --- 372,378 ---- # afscpcc.exe $(EXEDIR)\afscpcc.exe: $(OUT)\afscpcc.obj $(OUT)\afscpcc.res $(LOGON_DLLLIBS) ! $(EXECONLINK) dnsapi.lib mpr.lib iphlpapi.lib userenv.lib $(_VC_MANIFEST_EMBED_EXE) $(EXEPREP) Index: openafs/src/WINNT/afsd/afscpcc.c diff -c openafs/src/WINNT/afsd/afscpcc.c:1.1 openafs/src/WINNT/afsd/afscpcc.c:1.1.6.1 *** openafs/src/WINNT/afsd/afscpcc.c:1.1 Sun May 29 23:52:01 2005 --- openafs/src/WINNT/afsd/afscpcc.c Mon Jul 24 10:13:16 2006 *************** *** 1,5 **** /* ! * Copyright 2005, Secure Endpoints Inc. * All Rights Reserved. * * This software has been released under the terms of the MIT License. --- 1,5 ---- /* ! * Copyright 2005,2006 Secure Endpoints Inc. * All Rights Reserved. * * This software has been released under the terms of the MIT License. *************** *** 15,21 **** KFW_initialize(); ! return KFW_AFS_copy_system_file_to_default_cache(argv[1]); } --- 15,21 ---- KFW_initialize(); ! return KFW_AFS_copy_file_cache_to_default_cache(argv[1]); } Index: openafs/src/WINNT/afsd/afsd_service.c diff -c openafs/src/WINNT/afsd/afsd_service.c:1.52.4.1 openafs/src/WINNT/afsd/afsd_service.c:1.52.4.3 *** openafs/src/WINNT/afsd/afsd_service.c:1.52.4.1 Thu Jun 1 11:36:39 2006 --- openafs/src/WINNT/afsd/afsd_service.c Thu Jul 20 17:46:18 2006 *************** *** 37,46 **** HANDLE hAFSDWorkerThread[WORKER_THREADS]; #endif ! /* for the IFS version, set the event DoTerminate, on which all ! worker threads wait. they will exit, and then everything else ! can uninitialize. */ ! HANDLE WaitToTerminate, DoTerminate; int GlobalStatus; --- 37,43 ---- HANDLE hAFSDWorkerThread[WORKER_THREADS]; #endif ! HANDLE WaitToTerminate; int GlobalStatus; *************** *** 59,64 **** --- 56,65 ---- */ static void afsd_notifier(char *msgp, char *filep, long line) { + #ifdef AFSIFS + int i; + #endif + if (filep) LogEvent(EVENTLOG_ERROR_TYPE, MSG_SERVICE_ERROR_STOP_WITH_MSG_AND_LOCATION, filep, line, msgp); *************** *** 85,94 **** DebugBreak(); #endif - #ifndef AFSIFS SetEvent(WaitToTerminate); ! #else ! SetEvent(DoTerminate); WaitForMultipleObjects(WORKER_THREADS, hAFSDWorkerThread, TRUE, INFINITE); for (i = 0; i < WORKER_THREADS; i++) CloseHandle(hAFSDWorkerThread[i]); --- 86,93 ---- DebugBreak(); #endif SetEvent(WaitToTerminate); ! #ifdef AFSIFS WaitForMultipleObjects(WORKER_THREADS, hAFSDWorkerThread, TRUE, INFINITE); for (i = 0; i < WORKER_THREADS; i++) CloseHandle(hAFSDWorkerThread[i]); *************** *** 197,207 **** } doneTrace: - #ifndef AFSIFS SetEvent(WaitToTerminate); - #else - SetEvent(DoTerminate); - #endif break; case SERVICE_CONTROL_INTERROGATE: --- 196,202 ---- *************** *** 269,279 **** } doneTrace: - #ifndef AFSIFS SetEvent(WaitToTerminate); - #else - SetEvent(DoTerminate); - #endif dwRet = NO_ERROR; break; --- 264,270 ---- *************** *** 384,390 **** --- 375,383 ---- #define MAX_RETRIES 30 static void MountGlobalDrives(void) { + #ifndef AFSIFS char szAfsPath[_MAX_PATH]; + #endif char szDriveToMapTo[5]; DWORD dwResult; char szKeyName[256]; *************** *** 450,465 **** static void DismountGlobalDrives() { char szAfsPath[_MAX_PATH]; char szDriveToMapTo[5]; - DWORD dwResult; - char szKeyName[256]; - HKEY hKey; - DWORD dwIndex = 0; DWORD dwDriveSize; DWORD dwSubMountSize; char szSubMount[256]; DWORD dwType; sprintf(szKeyName, "%s\\GlobalAutoMapper", AFSREG_CLT_SVC_PARAM_SUBKEY); --- 443,460 ---- static void DismountGlobalDrives() { + #ifndef AFSIFS char szAfsPath[_MAX_PATH]; char szDriveToMapTo[5]; DWORD dwDriveSize; DWORD dwSubMountSize; char szSubMount[256]; DWORD dwType; + #endif + DWORD dwResult; + char szKeyName[256]; + HKEY hKey; + DWORD dwIndex = 0; sprintf(szKeyName, "%s\\GlobalAutoMapper", AFSREG_CLT_SVC_PARAM_SUBKEY); *************** *** 467,473 **** if (dwResult != ERROR_SUCCESS) return; ! #ifndef AFSIFS while (1) { dwDriveSize = sizeof(szDriveToMapTo); dwSubMountSize = sizeof(szSubMount); --- 462,470 ---- if (dwResult != ERROR_SUCCESS) return; ! #ifdef AFSIFS ! /* FIXFIX: implement */ ! #else while (1) { dwDriveSize = sizeof(szDriveToMapTo); dwSubMountSize = sizeof(szSubMount); *************** *** 487,494 **** afsi_log("Disconnect from GlobalAutoMap of %s to %s %s", szDriveToMapTo, szSubMount, dwResult ? "succeeded" : "failed"); } - #else - /* FIXFIX: implement */ #endif RegCloseKey(hKey); --- 484,489 ---- *************** *** 1033,1038 **** --- 1028,1036 ---- #endif /* JUMP */ HMODULE hHookDll; HMODULE hAdvApi32; + #ifdef AFSIFS + int cnt; + #endif #ifdef _DEBUG _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF /*| _CRTDBG_CHECK_ALWAYS_DF*/ | *************** *** 1050,1061 **** if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", TEXT("afsd_service_WaitToTerminate")); - #ifdef AFSIFS - DoTerminate = CreateEvent(NULL, TRUE, FALSE, TEXT("afsd_service_DoTerminate")); - if ( GetLastError() == ERROR_ALREADY_EXISTS ) - afsi_log("Event Object Already Exists: %s", TEXT("afsd_service_DoTerminate")); - #endif - #ifndef NOTSERVICE hAdvApi32 = LoadLibrary("advapi32.dll"); if (hAdvApi32 == NULL) --- 1048,1053 ---- *************** *** 1467,1477 **** printf("Hit to terminate OpenAFS Client Service\n"); getchar(); - #ifndef AFSIFS SetEvent(WaitToTerminate); ! #else ! SetEvent(DoTerminate); ! dc_release_hooks(); #endif } } --- 1459,1467 ---- printf("Hit to terminate OpenAFS Client Service\n"); getchar(); SetEvent(WaitToTerminate); ! #ifdef AFSIFS ! dc_release_hooks(); #endif } } Index: openafs/src/WINNT/afsd/afsdifs.c diff -c openafs/src/WINNT/afsd/afsdifs.c:1.5 openafs/src/WINNT/afsd/afsdifs.c:1.5.4.1 *** openafs/src/WINNT/afsd/afsdifs.c:1.5 Sun Jan 15 03:04:59 2006 --- openafs/src/WINNT/afsd/afsdifs.c Thu Jul 20 17:46:18 2006 *************** *** 83,91 **** CRITICAL_SECTION mapLock, scp_list_lock; - /* an event set by the controlling program to cause worker threads to terminate */ - extern HANDLE DoTerminate; - scp_status_t *scp_list_head = NULL; --- 83,88 ---- *************** *** 404,410 **** /****************************/ /* upcalls */ /****************************/ ! uc_namei(WCHAR *name, ULONG *fid) /* performs name<->fid mapping, and enters it into table */ { char *buffer; /* we support semi-infinite path lengths */ long code; --- 401,407 ---- /****************************/ /* upcalls */ /****************************/ ! long uc_namei(WCHAR *name, ULONG *fid) /* performs name<->fid mapping, and enters it into table */ { char *buffer; /* we support semi-infinite path lengths */ long code; *************** *** 472,478 **** /* this should only be called right after open, so we do not need to stat file. * we only check the server's restrictions. sharing violations are handled in the * kernel. the access mode we grant sticks with the file_object until its death. */ ! uc_check_access(ULONG fid, ULONG access, ULONG *granted) { ULONG afs_acc, afs_gr; cm_scache_t *scp; --- 469,475 ---- /* this should only be called right after open, so we do not need to stat file. * we only check the server's restrictions. sharing violations are handled in the * kernel. the access mode we grant sticks with the file_object until its death. */ ! long uc_check_access(ULONG fid, ULONG access, ULONG *granted) { ULONG afs_acc, afs_gr; cm_scache_t *scp; *************** *** 537,543 **** return 0; } ! uc_create(WCHAR *name, ULONG attribs, LARGE_INTEGER alloc, ULONG access, ULONG *granted, ULONG *fid) { char *buffer; /* we support semi-infinite path lengths */ long code; --- 534,540 ---- return 0; } ! long uc_create(WCHAR *name, ULONG attribs, LARGE_INTEGER alloc, ULONG access, ULONG *granted, ULONG *fid) { char *buffer; /* we support semi-infinite path lengths */ long code; *************** *** 610,616 **** /* this does not fill the attribs member completely. additional flags must be added in the kernel, such as read-only. */ ! uc_stat(ULONG fid, ULONG *attribs, LARGE_INTEGER *size, LARGE_INTEGER *creation, LARGE_INTEGER *access, LARGE_INTEGER *change, LARGE_INTEGER *written) { cm_scache_t *scp; --- 607,613 ---- /* this does not fill the attribs member completely. additional flags must be added in the kernel, such as read-only. */ ! long uc_stat(ULONG fid, ULONG *attribs, LARGE_INTEGER *size, LARGE_INTEGER *creation, LARGE_INTEGER *access, LARGE_INTEGER *change, LARGE_INTEGER *written) { cm_scache_t *scp; *************** *** 640,646 **** } /* set atime, mtime, etc. */ ! uc_setinfo(ULONG fid, ULONG attribs, LARGE_INTEGER creation, LARGE_INTEGER access, LARGE_INTEGER change, LARGE_INTEGER written) { return IFSL_GENERIC_FAILURE; --- 637,643 ---- } /* set atime, mtime, etc. */ ! long uc_setinfo(ULONG fid, ULONG attribs, LARGE_INTEGER creation, LARGE_INTEGER access, LARGE_INTEGER change, LARGE_INTEGER written) { return IFSL_GENERIC_FAILURE; *************** *** 722,728 **** /* FIXFIX: this does not catch all overquota errors, because the file * is not necessarily written to the server when this returns. */ /* write data to a file */ ! uc_write(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *written, char *data) { ULONG code; cm_scache_t *scp; --- 719,725 ---- /* FIXFIX: this does not catch all overquota errors, because the file * is not necessarily written to the server when this returns. */ /* write data to a file */ ! long uc_write(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *written, char *data) { ULONG code; cm_scache_t *scp; *************** *** 739,751 **** return 0; } ! uc_rename(ULONG fid, WCHAR *curr, WCHAR *new_dir, WCHAR *new_name, ULONG *new_fid) { int code; cm_req_t req; char *curdir, *curfile, *newdir, *newfile; cm_scache_t *dscp1, *dscp2, *scp; char b1[MAX_PATH], b2[MAX_PATH], b3[MAX_PATH]; code = !(scp = ifs_FindScp(fid)); if (!code) --- 736,749 ---- return 0; } ! long uc_rename(ULONG fid, WCHAR *curr, WCHAR *new_dir, WCHAR *new_name, ULONG *new_fid) { int code; cm_req_t req; char *curdir, *curfile, *newdir, *newfile; cm_scache_t *dscp1, *dscp2, *scp; char b1[MAX_PATH], b2[MAX_PATH], b3[MAX_PATH]; + wchar_t b3_w[MAX_PATH]; code = !(scp = ifs_FindScp(fid)); if (!code) *************** *** 778,785 **** { strcat(b3, "\\"); strcat(b3, b2); ! // TODO: Must convert b3 to type WCHAR* ! uc_namei(b3, new_fid); } else { --- 776,783 ---- { strcat(b3, "\\"); strcat(b3, b2); ! mbstowcs(b3_w, b3, MAX_PATH); ! uc_namei(b3_w, new_fid); } else { *************** *** 904,910 **** ULONG code; char buffer[2048]; cm_req_t req; ! cm_scache_t *scp, *child_scp; readdir_context_t context; LARGE_INTEGER cookie; --- 902,908 ---- ULONG code; char buffer[2048]; cm_req_t req; ! cm_scache_t *scp; readdir_context_t context; LARGE_INTEGER cookie; *************** *** 947,953 **** return code; } ! uc_close(ULONG fid) { cm_scache_t *scp; cm_req_t req; --- 945,951 ---- return code; } ! long uc_close(ULONG fid) { cm_scache_t *scp; cm_req_t req; *************** *** 988,994 **** return 0; } ! uc_unlink(WCHAR *name) { char buffer[2048]; long code; --- 986,992 ---- return 0; } ! long uc_unlink(WCHAR *name) { char buffer[2048]; long code; *************** *** 1020,1026 **** } ! int uc_ioctl_write(ULONG length, char *data, ULONG_PTR *key) { smb_ioctl_t *iop; --- 1018,1024 ---- } ! long uc_ioctl_write(ULONG length, char *data, ULONG_PTR *key) { smb_ioctl_t *iop; *************** *** 1035,1045 **** return 0; } ! int uc_ioctl_read(ULONG_PTR key, ULONG *length, char *data) { smb_ioctl_t *iop; ! iop = key; osi_assert(iop); cm_HoldUser(userp); --- 1033,1043 ---- return 0; } ! long uc_ioctl_read(ULONG_PTR key, ULONG *length, char *data) { smb_ioctl_t *iop; ! iop = (smb_ioctl_t *)key; osi_assert(iop); cm_HoldUser(userp); *************** *** 1130,1137 **** while (1) { /* just check if the event is already signalled, do not wait */ ! if (WaitForSingleObject(DoTerminate, 0) == WAIT_OBJECT_0) ! break; /* read request... */ st = ReadFile(pipe, bufIn, TRANSFER_BUF_SIZE, &lenIn, NULL); --- 1128,1135 ---- while (1) { /* just check if the event is already signalled, do not wait */ ! if (WaitForSingleObject(WaitToTerminate, 0) == WAIT_OBJECT_0) ! break; /* read request... */ st = ReadFile(pipe, bufIn, TRANSFER_BUF_SIZE, &lenIn, NULL); Index: openafs/src/WINNT/afsd/afskfw-int.h diff -c openafs/src/WINNT/afsd/afskfw-int.h:1.3 openafs/src/WINNT/afsd/afskfw-int.h:1.3.14.1 *** openafs/src/WINNT/afsd/afskfw-int.h:1.3 Thu Jul 22 18:41:27 2004 --- openafs/src/WINNT/afsd/afskfw-int.h Mon Jul 24 10:13:17 2006 *************** *** 1,5 **** /* ! * Copyright (c) 2003 SkyRope, LLC * All rights reserved. * * Redistribution and use in source and binary forms, with or without --- 1,6 ---- /* ! * Copyright (c) 2004, 2005, 2006 Secure Endpoints Inc. ! * Copyright (c) 2003 SkyRope, LLC * All rights reserved. * * Redistribution and use in source and binary forms, with or without *************** *** 103,108 **** --- 104,110 ---- #define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */ #define LSA_CCNAME "MSLSA:" + #ifndef KTC_ERROR #define KTC_ERROR 11862784L #define KTC_TOOBIG 11862785L #define KTC_INVAL 11862786L *************** *** 111,116 **** --- 113,119 ---- #define KTC_NOPIOCTL 11862789L #define KTC_NOCELL 11862790L #define KTC_NOCM 11862791L + #endif /* User Query data structures and functions */ Index: openafs/src/WINNT/afsd/afskfw.c diff -c openafs/src/WINNT/afsd/afskfw.c:1.28.4.1 openafs/src/WINNT/afsd/afskfw.c:1.28.4.3 *** openafs/src/WINNT/afsd/afskfw.c:1.28.4.1 Sun Jul 2 21:03:13 2006 --- openafs/src/WINNT/afsd/afskfw.c Wed Jul 26 08:51:21 2006 *************** *** 1,5 **** /* ! * Copyright (c) 2004, 2005 Secure Endpoints Inc. * Copyright (c) 2003 SkyRope, LLC * All rights reserved. * --- 1,5 ---- /* ! * Copyright (c) 2004, 2005, 2006 Secure Endpoints Inc. * Copyright (c) 2003 SkyRope, LLC * All rights reserved. * *************** *** 60,65 **** --- 60,68 ---- #undef USE_KRB4 #include "afskfw-int.h" #include "afskfw.h" + #include + #include + #include #include #include *************** *** 3492,3510 **** return success; } void KFW_AFS_copy_cache_to_system_file(char * user, char * szLogonId) { ! char filename[256]; DWORD count; ! char cachename[264] = "FILE:"; krb5_context ctx = 0; krb5_error_code code; krb5_principal princ = 0; krb5_ccache cc = 0; krb5_ccache ncc = 0; ! if (!pkrb5_init_context) return; count = GetEnvironmentVariable("TEMP", filename, sizeof(filename)); --- 3495,3637 ---- return success; } + int + KFW_AFS_set_file_cache_dacl(char *filename, HANDLE hUserToken) + { + // SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_SID_AUTHORITY; + PSID pSystemSID = NULL; + DWORD SystemSIDlength = 0, UserSIDlength = 0; + PACL ccacheACL = NULL; + DWORD ccacheACLlength = 0; + PTOKEN_USER pTokenUser = NULL; + DWORD retLen; + DWORD gle; + int ret = 0; + + if (!filename) { + return 1; + } + + /* Get System SID */ + if (!ConvertStringSidToSid("S-1-5-18", &pSystemSID)) { + ret = 1; + goto cleanup; + } + + /* Create ACL */ + SystemSIDlength = GetLengthSid(pSystemSID); + ccacheACLlength = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + + SystemSIDlength - sizeof(DWORD); + + if (hUserToken) { + if (!GetTokenInformation(hUserToken, TokenUser, NULL, 0, &retLen)) + { + if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) { + pTokenUser = (PTOKEN_USER) LocalAlloc(LPTR, retLen); + + GetTokenInformation(hUserToken, TokenUser, pTokenUser, retLen, &retLen); + } + } + + if (pTokenUser) { + UserSIDlength = GetLengthSid(pTokenUser->User.Sid); + + ccacheACLlength += sizeof(ACCESS_ALLOWED_ACE) + UserSIDlength + - sizeof(DWORD); + } + } + + ccacheACL = (PACL) LocalAlloc(LPTR, ccacheACLlength); + if (!ccacheACL) { + ret = 1; + goto cleanup; + } + InitializeAcl(ccacheACL, ccacheACLlength, ACL_REVISION); + AddAccessAllowedAceEx(ccacheACL, ACL_REVISION, 0, + STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, + pSystemSID); + if (pTokenUser) { + AddAccessAllowedAceEx(ccacheACL, ACL_REVISION, 0, + STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, + pTokenUser->User.Sid); + if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT, + DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, + NULL, + NULL, + ccacheACL, + NULL)) { + gle = GetLastError(); + if (gle != ERROR_NO_TOKEN) + ret = 1; + } + if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT, + OWNER_SECURITY_INFORMATION, + pTokenUser->User.Sid, + NULL, + NULL, + NULL)) { + gle = GetLastError(); + if (gle != ERROR_NO_TOKEN) + ret = 1; + } + } else { + if (!SetNamedSecurityInfo( filename, SE_FILE_OBJECT, + DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, + NULL, + NULL, + ccacheACL, + NULL)) { + gle = GetLastError(); + if (gle != ERROR_NO_TOKEN) + ret = 1; + } + } + + cleanup: + if (pSystemSID) + LocalFree(pSystemSID); + if (pTokenUser) + LocalFree(pTokenUser); + if (ccacheACL) + LocalFree(ccacheACL); + return ret; + } + + int + KFW_AFS_obtain_user_temp_directory(HANDLE hUserToken, char *newfilename, int size) + { + int retval = 0; + DWORD dwSize = size-1; /* leave room for nul */ + DWORD dwLen = 0; + + if (!hUserToken || !newfilename || size <= 0) + return; + + *newfilename = '\0'; + + dwLen = ExpandEnvironmentStringsForUser(hUserToken, "%TEMP%", newfilename, dwSize); + if ( !dwLen || dwLen > dwSize ) + dwLen = ExpandEnvironmentStringsForUser(hUserToken, "%TMP%", newfilename, dwSize); + if ( !dwLen || dwLen > dwSize ) + return 1; + + newfilename[dwSize] = '\0'; + return 0; + } + void KFW_AFS_copy_cache_to_system_file(char * user, char * szLogonId) { ! char filename[MAX_PATH] = ""; DWORD count; ! char cachename[MAX_PATH + 8] = "FILE:"; krb5_context ctx = 0; krb5_error_code code; krb5_principal princ = 0; krb5_ccache cc = 0; krb5_ccache ncc = 0; ! if (!pkrb5_init_context || !user || !szLogonId) return; count = GetEnvironmentVariable("TEMP", filename, sizeof(filename)); *************** *** 3537,3542 **** --- 3664,3672 ---- code = pkrb5_cc_initialize(ctx, ncc, princ); if (code) goto cleanup; + code = KFW_AFS_set_file_cache_dacl(filename, NULL); + if (code) goto cleanup; + code = pkrb5_cc_copy_creds(ctx,cc,ncc); cleanup: *************** *** 3558,3566 **** } int ! KFW_AFS_copy_system_file_to_default_cache(char * filename) { ! char cachename[264] = "FILE:"; krb5_context ctx = 0; krb5_error_code code; krb5_principal princ = 0; --- 3688,3696 ---- } int ! KFW_AFS_copy_file_cache_to_default_cache(char * filename) { ! char cachename[MAX_PATH + 8] = "FILE:"; krb5_context ctx = 0; krb5_error_code code; krb5_principal princ = 0; *************** *** 3568,3577 **** krb5_ccache ncc = 0; int retval = 1; ! if (!pkrb5_init_context) return 1; ! if ( strlen(filename) + 6 > sizeof(cachename) ) return 1; strcat(cachename, filename); --- 3698,3707 ---- krb5_ccache ncc = 0; int retval = 1; ! if (!pkrb5_init_context || !filename) return 1; ! if ( strlen(filename) + sizeof("FILE:") > sizeof(cachename) ) return 1; strcat(cachename, filename); Index: openafs/src/WINNT/afsd/afskfw.h diff -c openafs/src/WINNT/afsd/afskfw.h:1.4.4.1 openafs/src/WINNT/afsd/afskfw.h:1.4.4.2 *** openafs/src/WINNT/afsd/afskfw.h:1.4.4.1 Sun Jul 2 21:03:13 2006 --- openafs/src/WINNT/afsd/afskfw.h Mon Jul 24 10:13:17 2006 *************** *** 1,5 **** /* ! * Copyright (c) 2003 SkyRope, LLC * All rights reserved. * * Redistribution and use in source and binary forms, with or without --- 1,6 ---- /* ! * Copyright (c) 2004, 2005, 2006 Secure Endpoints Inc. ! * Copyright (c) 2003 SkyRope, LLC * All rights reserved. * * Redistribution and use in source and binary forms, with or without *************** *** 62,67 **** --- 63,72 ---- int KFW_AFS_get_cellconfig(char *, struct afsconf_cell *, char *); void KFW_import_windows_lsa(void); BOOL KFW_AFS_get_lsa_principal(char *, DWORD *); + int KFW_AFS_set_file_cache_dacl(char *filename, HANDLE hUserToken); + int KFW_AFS_obtain_user_temp_directory(HANDLE hUserToken, char *newfilename, int size); + int KFW_AFS_copy_file_cache_to_default_cache(char * filename); + /* These functions are only to be used in the afslogon.dll */ void KFW_AFS_copy_cache_to_system_file(char *, char *); Index: openafs/src/WINNT/afsd/afslogon.c diff -c openafs/src/WINNT/afsd/afslogon.c:1.45.2.1 openafs/src/WINNT/afsd/afslogon.c:1.45.2.3 *** openafs/src/WINNT/afsd/afslogon.c:1.45.2.1 Sun Jul 2 21:03:13 2006 --- openafs/src/WINNT/afsd/afslogon.c Wed Jul 26 08:51:21 2006 *************** *** 670,677 **** lpszOutputString[min(uInputString.Length/2,nOutStringLen-1)] = '\0'; return TRUE; } ! else ! lpszOutputString[0] = '\0'; return FALSE; } // UnicodeStringToANSI --- 670,677 ---- lpszOutputString[min(uInputString.Length/2,nOutStringLen-1)] = '\0'; return TRUE; } ! ! lpszOutputString[0] = '\0'; return FALSE; } // UnicodeStringToANSI *************** *** 750,758 **** /* Convert from Unicode to ANSI */ /*TODO: Use SecureZeroMemory to erase passwords */ ! UnicodeStringToANSI(IL->UserName, uname, MAX_USERNAME_LENGTH); ! UnicodeStringToANSI(IL->Password, password, MAX_PASSWORD_LENGTH); ! UnicodeStringToANSI(IL->LogonDomainName, logonDomain, MAX_DOMAIN_LENGTH); /* Make sure AD-DOMANS sent from login that is sent to us is striped */ ctemp = strchr(uname, '@'); --- 750,759 ---- /* Convert from Unicode to ANSI */ /*TODO: Use SecureZeroMemory to erase passwords */ ! if (!UnicodeStringToANSI(IL->UserName, uname, MAX_USERNAME_LENGTH) || ! !UnicodeStringToANSI(IL->Password, password, MAX_PASSWORD_LENGTH) || ! !UnicodeStringToANSI(IL->LogonDomainName, logonDomain, MAX_DOMAIN_LENGTH)) ! return 0; /* Make sure AD-DOMANS sent from login that is sent to us is striped */ ctemp = strchr(uname, '@'); *************** *** 1294,1303 **** char szPath[MAX_PATH] = ""; char szLogonId[128] = ""; DWORD count; ! char filename[256]; ! char commandline[512]; STARTUPINFO startupinfo; PROCESS_INFORMATION procinfo; LUID LogonId = {0, 0}; PSECURITY_LOGON_SESSION_DATA pLogonSessionData = NULL; --- 1295,1306 ---- char szPath[MAX_PATH] = ""; char szLogonId[128] = ""; DWORD count; ! char filename[MAX_PATH] = ""; ! char newfilename[MAX_PATH] = ""; ! char commandline[MAX_PATH+256] = ""; STARTUPINFO startupinfo; PROCESS_INFORMATION procinfo; + HANDLE hf = INVALID_HANDLE_VALUE; LUID LogonId = {0, 0}; PSECURITY_LOGON_SESSION_DATA pLogonSessionData = NULL; *************** *** 1327,1340 **** GetWindowsDirectory(filename, sizeof(filename)); } ! if ( strlen(filename) + strlen(szLogonId) + 2 <= sizeof(filename) ) { ! strcat(filename, "\\"); ! strcat(filename, szLogonId); ! sprintf(commandline, "afscpcc.exe \"%s\"", filename); ! GetStartupInfo(&startupinfo); ! if (CreateProcessAsUser( pInfo->hToken, "afscpcc.exe", commandline, NULL, --- 1330,1385 ---- GetWindowsDirectory(filename, sizeof(filename)); } ! count = GetEnvironmentVariable("TEMP", filename, sizeof(filename)); ! if ( count > sizeof(filename) || count == 0 ) { ! GetWindowsDirectory(filename, sizeof(filename)); ! } ! ! if ( strlen(filename) + strlen(szLogonId) + 2 > sizeof(filename) ) { ! DebugEvent0("KFW_Logon_Event - filename too long"); ! return; ! } ! strcat(filename, "\\"); ! strcat(filename, szLogonId); ! hf = CreateFile(filename, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, ! FILE_ATTRIBUTE_NORMAL, NULL); ! if (hf == INVALID_HANDLE_VALUE) { ! DebugEvent0("KFW_Logon_Event - file cannot be opened"); ! return; ! } ! CloseHandle(hf); ! ! if (KFW_AFS_set_file_cache_dacl(filename, pInfo->hToken)) { ! DebugEvent0("KFW_Logon_Event - unable to set dacl"); ! DeleteFile(filename); ! return; ! } ! ! if (KFW_AFS_obtain_user_temp_directory(pInfo->hToken, newfilename, sizeof(newfilename))) { ! DebugEvent0("KFW_Logon_Event - unable to obtain temp directory"); ! return; ! } ! ! if ( strlen(newfilename) + strlen(szLogonId) + 2 > sizeof(newfilename) ) { ! DebugEvent0("KFW_Logon_Event - new filename too long"); ! return; ! } ! ! strcat(newfilename, "\\"); ! strcat(newfilename, szLogonId); ! ! if (!MoveFileEx(filename, newfilename, ! MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) { ! DebugEvent("KFW_Logon_Event - MoveFileEx failed GLE = 0x%x", GetLastError()); ! return; ! } ! ! sprintf(commandline, "afscpcc.exe \"%s\"", newfilename); ! ! GetStartupInfo(&startupinfo); ! if (CreateProcessAsUser( pInfo->hToken, "afscpcc.exe", commandline, NULL, *************** *** 1345,1356 **** NULL, &startupinfo, &procinfo)) ! { ! WaitForSingleObject(procinfo.hProcess, 30000); ! CloseHandle(procinfo.hThread); ! CloseHandle(procinfo.hProcess); ! } } DeleteFile(filename); --- 1390,1404 ---- NULL, &startupinfo, &procinfo)) ! { ! DebugEvent("KFW_Logon_Event - CommandLine %s", commandline); ! WaitForSingleObject(procinfo.hProcess, 30000); ! ! CloseHandle(procinfo.hThread); ! CloseHandle(procinfo.hProcess); ! } else { ! DebugEvent0("KFW_Logon_Event - CreateProcessFailed"); } DeleteFile(filename); Index: openafs/src/WINNT/afsd/cm_conn.c diff -c openafs/src/WINNT/afsd/cm_conn.c:1.49.2.3 openafs/src/WINNT/afsd/cm_conn.c:1.49.2.4 *** openafs/src/WINNT/afsd/cm_conn.c:1.49.2.3 Tue Jun 27 11:40:33 2006 --- openafs/src/WINNT/afsd/cm_conn.c Mon Jul 10 15:27:30 2006 *************** *** 47,53 **** HKEY parmKey; if (osi_Once(&once)) { ! lock_InitializeRWLock(&cm_connLock, "connection global lock"); /* keisa - read timeout value for lanmanworkstation service. * jaltman - as per --- 47,53 ---- HKEY parmKey; if (osi_Once(&once)) { ! lock_InitializeRWLock(&cm_connLock, "connection global lock"); /* keisa - read timeout value for lanmanworkstation service. * jaltman - as per *************** *** 56,84 **** * I believe that the default should not be short. Instead, we should wait until * RX times out before reporting a timeout to the SMB client. */ ! code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, LANMAN_WKS_PARAM_KEY, ! 0, KEY_QUERY_VALUE, &parmKey); ! if (code == ERROR_SUCCESS) { ! DWORD dummyLen = sizeof(sessTimeout); ! code = RegQueryValueEx(parmKey, LANMAN_WKS_SESSION_TIMEOUT, NULL, NULL, ! (BYTE *) &sessTimeout, &dummyLen); ! if (code == ERROR_SUCCESS) { - afsi_log("lanmanworkstation : SessTimeout %d", sessTimeout); RDRtimeout = sessTimeout; ! if ( ConnDeadtimeout < RDRtimeout + 15 ) { ! ConnDeadtimeout = RDRtimeout + 15; ! afsi_log("ConnDeadTimeout increased to %d", ConnDeadtimeout); ! } ! if ( HardDeadtimeout < 2 * ConnDeadtimeout ) { ! HardDeadtimeout = 2 * ConnDeadtimeout; ! afsi_log("HardDeadTimeout increased to %d", HardDeadtimeout); ! } ! } } ! osi_EndOnce(&once); } } --- 56,85 ---- * I believe that the default should not be short. Instead, we should wait until * RX times out before reporting a timeout to the SMB client. */ ! code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, LANMAN_WKS_PARAM_KEY, ! 0, KEY_QUERY_VALUE, &parmKey); ! if (code == ERROR_SUCCESS) { ! DWORD dummyLen = sizeof(sessTimeout); ! code = RegQueryValueEx(parmKey, LANMAN_WKS_SESSION_TIMEOUT, NULL, NULL, ! (BYTE *) &sessTimeout, &dummyLen); ! if (code == ERROR_SUCCESS) { RDRtimeout = sessTimeout; ! } } ! afsi_log("lanmanworkstation : SessTimeout %d", sessTimeout); ! if ( ConnDeadtimeout < RDRtimeout + 15 ) { ! ConnDeadtimeout = RDRtimeout + 15; ! afsi_log("ConnDeadTimeout increased to %d", ConnDeadtimeout); ! } ! if ( HardDeadtimeout < 2 * ConnDeadtimeout ) { ! HardDeadtimeout = 2 * ConnDeadtimeout; ! afsi_log("HardDeadTimeout increased to %d", HardDeadtimeout); ! } ! ! osi_EndOnce(&once); } } *************** *** 181,187 **** if (reqp->flags & CM_REQ_NORETRY) goto out; ! /* if timeout - check that it did not exceed the SMB timeout * and retry */ /* timeleft - get if from reqp the same way as cmXonnByMServers does */ --- 182,188 ---- if (reqp->flags & CM_REQ_NORETRY) goto out; ! /* if timeout - check that it did not exceed the HardDead timeout * and retry */ /* timeleft - get if from reqp the same way as cmXonnByMServers does */ *************** *** 193,199 **** #endif /* leave 5 seconds margin for sleep */ ! timeLeft = RDRtimeout - timeUsed; if (errorCode == CM_ERROR_TIMEDOUT) { if (timeLeft > 5 ) { --- 194,200 ---- #endif /* leave 5 seconds margin for sleep */ ! timeLeft = HardDeadtimeout - timeUsed; if (errorCode == CM_ERROR_TIMEDOUT) { if (timeLeft > 5 ) { Index: openafs/src/WINNT/afsd/cm_daemon.c diff -c openafs/src/WINNT/afsd/cm_daemon.c:1.16.4.2 openafs/src/WINNT/afsd/cm_daemon.c:1.16.4.3 *** openafs/src/WINNT/afsd/cm_daemon.c:1.16.4.2 Sat Jun 24 16:41:54 2006 --- openafs/src/WINNT/afsd/cm_daemon.c Wed Jul 26 09:04:08 2006 *************** *** 278,287 **** lastTokenCacheCheck = now - cm_daemonTokenCheckInterval/2 + (rand() % cm_daemonTokenCheckInterval); while (daemon_ShutdownFlag == 0) { - thrd_Sleep(30 * 1000); /* sleep 30 seconds */ - if (daemon_ShutdownFlag == 1) - return; - if (configureFirewall) { /* Open Microsoft Firewall to allow in port 7001 */ switch (icf_CheckAndAddAFSPorts(AFS_PORTSET_CLIENT)) { --- 278,283 ---- *************** *** 364,369 **** --- 360,369 ---- SetEvent(WaitToTerminate); } } + + thrd_Sleep(30 * 1000); /* sleep 30 seconds */ + if (daemon_ShutdownFlag == 1) + return; } } Index: openafs/src/WINNT/afsd/cm_ioctl.c diff -c openafs/src/WINNT/afsd/cm_ioctl.c:1.73.2.3 openafs/src/WINNT/afsd/cm_ioctl.c:1.73.2.4 *** openafs/src/WINNT/afsd/cm_ioctl.c:1.73.2.3 Tue Jun 27 18:53:42 2006 --- openafs/src/WINNT/afsd/cm_ioctl.c Thu Jul 20 17:46:19 2006 *************** *** 216,229 **** cm_scache_t **scpp) { long code; cm_scache_t *substRootp; - char * relativePath = ioctlp->inDatap; - #ifdef AFSIFS - char * absRoot[MAX_PATH]; - long length; - wchar_t absRoot_w[MAX_PATH]; - HANDLE rootDir; #endif osi_Log1(afsd_logp, "cm_ParseIoctlPath %s", osi_LogSaveString(afsd_logp,relativePath)); /* This is usually the file name, but for StatMountPoint it is the path. */ --- 216,226 ---- cm_scache_t **scpp) { long code; + #ifndef AFSIFS cm_scache_t *substRootp; #endif + char * relativePath = ioctlp->inDatap; + osi_Log1(afsd_logp, "cm_ParseIoctlPath %s", osi_LogSaveString(afsd_logp,relativePath)); /* This is usually the file name, but for StatMountPoint it is the path. */ *************** *** 237,262 **** #ifdef AFSIFS /* we have passed the whole path, including the afs prefix. ! when the pioctl call is made, we perform an ioctl to afsrdr ! and it returns the correct (full) path. therefore, there is ! no drive letter, and the path is absolute. */ code = cm_NameI(cm_data.rootSCachep, relativePath, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, "", reqp, scpp); if (code) return code; ! ! /* # of bytes of path */ ! code = strlen(ioctlp->inDatap) + 1; ! ioctlp->inDatap += code; ! ! /* This is usually nothing, but for StatMountPoint it is the file name. */ ! TranslateExtendedChars(ioctlp->inDatap); ! ! return 0; ! #endif /* AFSIFS */ ! if (relativePath[0] == relativePath[1] && relativePath[1] == '\\' && !_strnicmp(cm_NetbiosName,relativePath+2,strlen(cm_NetbiosName))) --- 234,249 ---- #ifdef AFSIFS /* we have passed the whole path, including the afs prefix. ! when the pioctl call is made, we perform an ioctl to afsrdr ! and it returns the correct (full) path. therefore, there is ! no drive letter, and the path is absolute. */ code = cm_NameI(cm_data.rootSCachep, relativePath, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, "", reqp, scpp); if (code) return code; ! #else /* AFSIFS */ if (relativePath[0] == relativePath[1] && relativePath[1] == '\\' && !_strnicmp(cm_NetbiosName,relativePath+2,strlen(cm_NetbiosName))) *************** *** 336,341 **** --- 323,329 ---- if (code) return code; } + #endif /* AFSIFS */ /* # of bytes of path */ code = (long)strlen(ioctlp->inDatap) + 1; *************** *** 2001,2007 **** --- 1989,1997 ---- afs_uuid_t uuid; int flags; char sessionKey[8]; + #ifndef AFSIFS char *smbname; + #endif int release_userp = 0; char * wdir = NULL; *************** *** 2048,2054 **** uname = tp; tp += strlen(tp) + 1; ! #ifndef AFSIFS /* no SMB username, so we cannot log based on this */ if (flags & PIOCTL_LOGON) { /* SMB user name with which to associate tokens */ smbname = tp; --- 2038,2044 ---- uname = tp; tp += strlen(tp) + 1; ! #ifndef AFSIFS /* no SMB username, so we cannot logon based on this */ if (flags & PIOCTL_LOGON) { /* SMB user name with which to associate tokens */ smbname = tp; *************** *** 2058,2064 **** tp += strlen(tp) + 1; } else { osi_Log1(smb_logp,"cm_IoctlSetToken for user [%s]", ! osi_LogSaveString(smb_logp,uname)); } #endif --- 2048,2054 ---- tp += strlen(tp) + 1; } else { osi_Log1(smb_logp,"cm_IoctlSetToken for user [%s]", ! osi_LogSaveString(smb_logp, uname)); } #endif *************** *** 2073,2083 **** --- 2063,2075 ---- osi_Log0(smb_logp,"cm_IoctlSetToken - no name specified"); } + #ifndef AFSIFS if (flags & PIOCTL_LOGON) { userp = smb_FindCMUserByName(smbname, ioctlp->fidp->vcp->rname, SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON); release_userp = 1; } + #endif /* AFSIFS */ /* store the token */ lock_ObtainMutex(&userp->mx); Index: openafs/src/WINNT/afsd/cm_memmap.c diff -c openafs/src/WINNT/afsd/cm_memmap.c:1.7 openafs/src/WINNT/afsd/cm_memmap.c:1.7.2.1 *** openafs/src/WINNT/afsd/cm_memmap.c:1.7 Mon Feb 6 02:06:34 2006 --- openafs/src/WINNT/afsd/cm_memmap.c Mon Jul 24 10:13:17 2006 *************** *** 161,167 **** psa = GlobalAlloc(GMEM_FIXED, sizeof(SECURITY_ATTRIBUTES)); psa->nLength = sizeof(SECURITY_ATTRIBUTES); psa->lpSecurityDescriptor = psd; ! psa->bInheritHandle = TRUE; return psa; } --- 161,167 ---- psa = GlobalAlloc(GMEM_FIXED, sizeof(SECURITY_ATTRIBUTES)); psa->nLength = sizeof(SECURITY_ATTRIBUTES); psa->lpSecurityDescriptor = psd; ! psa->bInheritHandle = FALSE; return psa; } Index: openafs/src/WINNT/afsd/cm_scache.c diff -c openafs/src/WINNT/afsd/cm_scache.c:1.35.2.12 openafs/src/WINNT/afsd/cm_scache.c:1.35.2.13 *** openafs/src/WINNT/afsd/cm_scache.c:1.35.2.12 Wed Jun 28 11:01:21 2006 --- openafs/src/WINNT/afsd/cm_scache.c Thu Jul 27 22:10:15 2006 *************** *** 1080,1091 **** /* ensure that the buffer isn't already in the I/O list */ for(qdp = scp->bufReadsp; qdp; qdp = (osi_queueData_t *) osi_QNext(&qdp->q)) { tbufp = osi_GetQData(qdp); ! if (tbufp == bufp) break; } ! osi_assert(qdp != NULL); ! osi_assert(osi_GetQData(qdp) == bufp); ! osi_QRemove((osi_queue_t **) &scp->bufReadsp, &qdp->q); ! osi_QDFree(qdp); if (bufp) { bufp->cmFlags &= ~(CM_BUF_CMFETCHING | CM_BUF_CMFULLYFETCHED); if (bufp->flags & CM_BUF_WAITING) { --- 1080,1092 ---- /* ensure that the buffer isn't already in the I/O list */ for(qdp = scp->bufReadsp; qdp; qdp = (osi_queueData_t *) osi_QNext(&qdp->q)) { tbufp = osi_GetQData(qdp); ! if (tbufp == bufp) ! break; } ! if (qdp) { ! osi_QRemove((osi_queue_t **) &scp->bufReadsp, &qdp->q); ! osi_QDFree(qdp); ! } if (bufp) { bufp->cmFlags &= ~(CM_BUF_CMFETCHING | CM_BUF_CMFULLYFETCHED); if (bufp->flags & CM_BUF_WAITING) { *************** *** 1101,1112 **** /* ensure that the buffer isn't already in the I/O list */ for(qdp = scp->bufWritesp; qdp; qdp = (osi_queueData_t *) osi_QNext(&qdp->q)) { tbufp = osi_GetQData(qdp); ! if (tbufp == bufp) break; } ! osi_assert(qdp != NULL); ! osi_assert(osi_GetQData(qdp) == bufp); ! osi_QRemove((osi_queue_t **) &scp->bufWritesp, &qdp->q); ! osi_QDFree(qdp); if (bufp) { bufp->cmFlags &= ~CM_BUF_CMSTORING; if (bufp->flags & CM_BUF_WAITING) { --- 1102,1114 ---- /* ensure that the buffer isn't already in the I/O list */ for(qdp = scp->bufWritesp; qdp; qdp = (osi_queueData_t *) osi_QNext(&qdp->q)) { tbufp = osi_GetQData(qdp); ! if (tbufp == bufp) ! break; } ! if (qdp) { ! osi_QRemove((osi_queue_t **) &scp->bufWritesp, &qdp->q); ! osi_QDFree(qdp); ! } if (bufp) { bufp->cmFlags &= ~CM_BUF_CMSTORING; if (bufp->flags & CM_BUF_WAITING) { Index: openafs/src/WINNT/afsd/cm_vnodeops.c diff -c openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.8 openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.9 *** openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.8 Wed Jun 28 11:01:21 2006 --- openafs/src/WINNT/afsd/cm_vnodeops.c Thu Jul 20 17:46:19 2006 *************** *** 664,673 **** } #ifdef AFSIFS ! /* for the IFS version, we bulkstat the dirents because this ! routine is used in place of smb_ReceiveCoreSearchDir. our ! other option is to modify smb_ReceiveCoreSearchDir itself, ! but this seems to be the proper use for cm_ApplyDir. */ lock_ObtainMutex(&scp->mx); if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 && (scp->bulkStatProgress.QuadPart <= thyper.QuadPart)) --- 664,673 ---- } #ifdef AFSIFS ! /* for the IFS version, we bulkstat the dirents because this ! routine is used in place of smb_ReceiveCoreSearchDir. our ! other option is to modify smb_ReceiveCoreSearchDir itself, ! but this seems to be the proper use for cm_ApplyDir. */ lock_ObtainMutex(&scp->mx); if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 && (scp->bulkStatProgress.QuadPart <= thyper.QuadPart)) Index: openafs/src/WINNT/afsd/fs.c diff -c openafs/src/WINNT/afsd/fs.c:1.32.4.1 openafs/src/WINNT/afsd/fs.c:1.32.4.2 *** openafs/src/WINNT/afsd/fs.c:1.32.4.1 Tue Jun 27 18:19:35 2006 --- openafs/src/WINNT/afsd/fs.c Fri Jul 28 09:38:13 2006 *************** *** 2280,2286 **** { afs_int32 code; struct ViceIoctl blob; ! afs_int32 parms[MAXGCSIZE]; memset(parms, 0, sizeof(parms)); blob.in = NULL; --- 2280,2286 ---- { afs_int32 code; struct ViceIoctl blob; ! afs_uint64 parms[MAXGCSIZE]; memset(parms, 0, sizeof(parms)); blob.in = NULL; Index: openafs/src/WINNT/afsd/smb.c diff -c openafs/src/WINNT/afsd/smb.c:1.118.2.11 openafs/src/WINNT/afsd/smb.c:1.118.2.16 *** openafs/src/WINNT/afsd/smb.c:1.118.2.11 Tue Jul 4 18:43:24 2006 --- openafs/src/WINNT/afsd/smb.c Mon Jul 31 11:51:38 2006 *************** *** 415,439 **** default: return "unknown SMB op-2"; case 0: ! return "S(00)CreateFile"; case 1: ! return "S(01)FindFirst"; case 2: ! return "S(02)FindNext"; /* FindNext */ case 3: return "S(03)QueryFileSystem_ReceiveTran2QFSInfo"; case 4: ! return "S(04)??"; case 5: ! return "S(05)QueryFileInfo_ReceiveTran2QPathInfo"; case 6: ! return "S(06)SetFileInfo_ReceiveTran2SetPathInfo"; case 7: ! return "S(07)SetInfoHandle_ReceiveTran2QFileInfo"; case 8: ! return "S(08)??_ReceiveTran2SetFileInfo"; case 9: ! return "S(09)??_ReceiveTran2FSCTL"; case 10: return "S(0a)_ReceiveTran2IOCTL"; case 11: --- 415,439 ---- default: return "unknown SMB op-2"; case 0: ! return "S(00)CreateFile_ReceiveTran2Open"; case 1: ! return "S(01)FindFirst_ReceiveTran2SearchDir"; case 2: ! return "S(02)FindNext_ReceiveTran2SearchDir"; /* FindNext */ case 3: return "S(03)QueryFileSystem_ReceiveTran2QFSInfo"; case 4: ! return "S(04)SetFileSystem_ReceiveTran2SetFSInfo"; case 5: ! return "S(05)QueryPathInfo_ReceiveTran2QPathInfo"; case 6: ! return "S(06)SetPathInfo_ReceiveTran2SetPathInfo"; case 7: ! return "S(07)QueryFileInfo_ReceiveTran2QFileInfo"; case 8: ! return "S(08)SetFileInfo_ReceiveTran2SetFileInfo"; case 9: ! return "S(09)_ReceiveTran2FSCTL"; case 10: return "S(0a)_ReceiveTran2IOCTL"; case 11: *************** *** 444,449 **** --- 444,451 ---- return "S(0d)_ReceiveTran2CreateDirectory"; case 14: return "S(0e)_ReceiveTran2SessionSetup"; + case 15: + return "S(0f)_QueryFileSystemInformationFid"; case 16: return "S(10)_ReceiveTran2GetDfsReferral"; case 17: *************** *** 1505,1510 **** --- 1507,1531 ---- return fidp; } + smb_fid_t *smb_FindFIDByScache(smb_vc_t *vcp, cm_scache_t * scp) + { + smb_fid_t *fidp = NULL; + int newFid = 0; + + if (!scp) + return NULL; + + lock_ObtainWrite(&smb_rctLock); + for(fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q)) { + if (scp == fidp->scp) { + fidp->refCount++; + break; + } + } + lock_ReleaseWrite(&smb_rctLock); + return fidp; + } + void smb_HoldFIDNoLock(smb_fid_t *fidp) { fidp->refCount++; *************** *** 2336,2341 **** --- 2357,2388 ---- } /* return the parm'th parameter in the smbp packet */ + unsigned int smb_GetSMBParmLong(smb_packet_t *smbp, int parm) + { + int parmCount; + unsigned char *parmDatap; + + parmCount = *smbp->wctp; + + if (parm + 1 >= parmCount) { + char s[100]; + + sprintf(s, "Bad SMB param %d out of %d, ncb len %d", + parm, parmCount, smbp->ncb_length); + osi_Log3(smb_logp,"Bad SMB param %d out of %d, ncb len %d", + parm, parmCount, smbp->ncb_length); + #ifndef DJGPP + LogEvent(EVENTLOG_ERROR_TYPE, MSG_BAD_SMB_PARAM, + __FILE__, __LINE__, parm, parmCount, smbp->ncb_length); + #endif /* !DJGPP */ + osi_panic(s, __FILE__, __LINE__); + } + parmDatap = smbp->wctp + (2*parm) + 1; + + return parmDatap[0] + (parmDatap[1] << 8) + (parmDatap[2] << 16) + (parmDatap[3] << 24); + } + + /* return the parm'th parameter in the smbp packet */ unsigned int smb_GetSMBOffsetParm(smb_packet_t *smbp, int parm, int offset) { int parmCount; *************** *** 2386,2392 **** *parmDatap++ = parmValue & 0xff; *parmDatap++ = (parmValue>>8) & 0xff; *parmDatap++ = (parmValue>>16) & 0xff; ! *parmDatap++ = (parmValue>>24) & 0xff; } void smb_SetSMBParmDouble(smb_packet_t *smbp, int slot, char *parmValuep) --- 2433,2439 ---- *parmDatap++ = parmValue & 0xff; *parmDatap++ = (parmValue>>8) & 0xff; *parmDatap++ = (parmValue>>16) & 0xff; ! *parmDatap = (parmValue>>24) & 0xff; } void smb_SetSMBParmDouble(smb_packet_t *smbp, int slot, char *parmValuep) *************** *** 3188,3198 **** } lock_ObtainMutex(&vcp->mx); if (VistaProtoIndex != -1) { protoIndex = VistaProtoIndex; vcp->flags |= (SMB_VCFLAG_USENT | SMB_VCFLAG_USEV3); ! } ! if (NTProtoIndex != -1) { protoIndex = NTProtoIndex; vcp->flags |= (SMB_VCFLAG_USENT | SMB_VCFLAG_USEV3); } --- 3235,3247 ---- } lock_ObtainMutex(&vcp->mx); + #if 0 if (VistaProtoIndex != -1) { protoIndex = VistaProtoIndex; vcp->flags |= (SMB_VCFLAG_USENT | SMB_VCFLAG_USEV3); ! } else ! #endif ! if (NTProtoIndex != -1) { protoIndex = NTProtoIndex; vcp->flags |= (SMB_VCFLAG_USENT | SMB_VCFLAG_USEV3); } *************** *** 3209,3215 **** if (protoIndex == -1) return CM_ERROR_INVAL; ! else if (NTProtoIndex != -1) { smb_SetSMBParm(outp, 0, protoIndex); if (smb_authType != SMB_AUTH_NONE) { smb_SetSMBParmByte(outp, 1, --- 3258,3264 ---- if (protoIndex == -1) return CM_ERROR_INVAL; ! else if (VistaProtoIndex != 1 || NTProtoIndex != -1) { smb_SetSMBParm(outp, 0, protoIndex); if (smb_authType != SMB_AUTH_NONE) { smb_SetSMBParmByte(outp, 1, *************** *** 4655,4666 **** attr.mask |= CM_ATTRMASK_CLIENTMODTIME; smb_UnixTimeFromDosUTime(&attr.clientModTime, dosTime); } ! if ((newScp->unixModeBits & 0222) && (attribute & 1) != 0) { /* we're told to make a writable file read-only */ attr.unixModeBits = newScp->unixModeBits & ~0222; attr.mask |= CM_ATTRMASK_UNIXMODEBITS; } ! else if ((newScp->unixModeBits & 0222) == 0 && (attribute & 1) == 0) { /* we're told to make a read-only file writable */ attr.unixModeBits = newScp->unixModeBits | 0222; attr.mask |= CM_ATTRMASK_UNIXMODEBITS; --- 4704,4715 ---- attr.mask |= CM_ATTRMASK_CLIENTMODTIME; smb_UnixTimeFromDosUTime(&attr.clientModTime, dosTime); } ! if ((newScp->unixModeBits & 0222) && (attribute & SMB_ATTR_READONLY) != 0) { /* we're told to make a writable file read-only */ attr.unixModeBits = newScp->unixModeBits & ~0222; attr.mask |= CM_ATTRMASK_UNIXMODEBITS; } ! else if ((newScp->unixModeBits & 0222) == 0 && (attribute & SMB_ATTR_READONLY) == 0) { /* we're told to make a read-only file writable */ attr.unixModeBits = newScp->unixModeBits | 0222; attr.mask |= CM_ATTRMASK_UNIXMODEBITS; *************** *** 6388,6396 **** long smb_ReceiveCoreWrite(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - osi_hyper_t offset; - long count, written = 0, total_written = 0; unsigned short fd; unsigned pid; smb_fid_t *fidp; long code = 0; --- 6437,6447 ---- long smb_ReceiveCoreWrite(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { unsigned short fd; + unsigned short count; + osi_hyper_t offset; + unsigned short hint; + long written = 0, total_written = 0; unsigned pid; smb_fid_t *fidp; long code = 0; *************** *** 6402,6408 **** fd = smb_GetSMBParm(inp, 0); count = smb_GetSMBParm(inp, 1); offset.HighPart = 0; /* too bad */ ! offset.LowPart = smb_GetSMBParm(inp, 2) | (smb_GetSMBParm(inp, 3) << 16); op = smb_GetSMBData(inp, NULL); op = smb_ParseDataBlock(op, NULL, &inDataBlockCount); --- 6453,6460 ---- fd = smb_GetSMBParm(inp, 0); count = smb_GetSMBParm(inp, 1); offset.HighPart = 0; /* too bad */ ! offset.LowPart = smb_GetSMBParmLong(inp, 2); ! hint = smb_GetSMBParm(inp, 4); op = smb_GetSMBData(inp, NULL); op = smb_ParseDataBlock(op, NULL, &inDataBlockCount); *************** *** 6412,6448 **** fd = smb_ChainFID(fd, inp); fidp = smb_FindFID(vcp, fd, 0); ! if (!fidp) return CM_ERROR_BADFD; lock_ObtainMutex(&fidp->mx); if (fidp->flags & SMB_FID_IOCTL) { lock_ReleaseMutex(&fidp->mx); code = smb_IoctlWrite(fidp, vcp, inp, outp); smb_ReleaseFID(fidp); return code; } lock_ReleaseMutex(&fidp->mx); userp = smb_GetUserFromVCP(vcp, inp); - /* special case: 0 bytes transferred means truncate to this position */ - if (count == 0) { - cm_req_t req; - - cm_InitReq(&req); - - truncAttr.mask = CM_ATTRMASK_LENGTH; - truncAttr.length.LowPart = offset.LowPart; - truncAttr.length.HighPart = 0; - lock_ObtainMutex(&fidp->mx); - code = cm_SetAttr(fidp->scp, &truncAttr, userp, &req); - fidp->flags |= SMB_FID_LENGTHSETDONE; - lock_ReleaseMutex(&fidp->mx); - smb_SetSMBParm(outp, 0, /* count */ 0); - smb_SetSMBDataLength(outp, 0); - goto done; - } - { cm_key_t key; LARGE_INTEGER LOffset; --- 6464,6485 ---- fd = smb_ChainFID(fd, inp); fidp = smb_FindFID(vcp, fd, 0); ! if (!fidp) { ! osi_Log0(smb_logp, "smb_ReceiveCoreWrite fid not found"); return CM_ERROR_BADFD; + } lock_ObtainMutex(&fidp->mx); if (fidp->flags & SMB_FID_IOCTL) { lock_ReleaseMutex(&fidp->mx); code = smb_IoctlWrite(fidp, vcp, inp, outp); smb_ReleaseFID(fidp); + osi_Log1(smb_logp, "smb_ReceiveCoreWrite ioctl code 0x%x", code); return code; } lock_ReleaseMutex(&fidp->mx); userp = smb_GetUserFromVCP(vcp, inp); { cm_key_t key; LARGE_INTEGER LOffset; *************** *** 6460,6467 **** code = cm_LockCheckWrite(fidp->scp, LOffset, LLength, key); lock_ReleaseMutex(&fidp->scp->mx); ! if (code) goto done; } /* --- 6497,6526 ---- code = cm_LockCheckWrite(fidp->scp, LOffset, LLength, key); lock_ReleaseMutex(&fidp->scp->mx); ! if (code) { ! osi_Log1(smb_logp, "smb_ReceiveCoreWrite lock check failure 0x%x", code); goto done; + } + } + + /* special case: 0 bytes transferred means truncate to this position */ + if (count == 0) { + cm_req_t req; + + osi_Log1(smb_logp, "smb_ReceiveCoreWrite truncation to length 0x%x", offset.LowPart); + + cm_InitReq(&req); + + truncAttr.mask = CM_ATTRMASK_LENGTH; + truncAttr.length.LowPart = offset.LowPart; + truncAttr.length.HighPart = 0; + lock_ObtainMutex(&fidp->mx); + code = cm_SetAttr(fidp->scp, &truncAttr, userp, &req); + fidp->flags |= SMB_FID_LENGTHSETDONE; + lock_ReleaseMutex(&fidp->mx); + smb_SetSMBParm(outp, 0, 0 /* count */); + smb_SetSMBDataLength(outp, 0); + goto done; } /* *************** *** 6498,6507 **** --- 6557,6571 ---- written = 0; } + osi_Log2(smb_logp, "smb_ReceiveCoreWrite total written 0x%x code 0x%x", + total_written, code); + /* set the packet data length to 3 bytes for the data block header, * plus the size of the data. */ smb_SetSMBParm(outp, 0, total_written); + smb_SetSMBParmLong(outp, 1, offset.LowPart); + smb_SetSMBParm(outp, 3, hint); smb_SetSMBDataLength(outp, 0); done: *************** *** 7009,7015 **** /* compute initial mode bits based on read-only flag in attributes */ initialModeBits = 0666; ! if (attributes & 1) initialModeBits &= ~0222; tp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(tp, &tp); --- 7073,7080 ---- /* compute initial mode bits based on read-only flag in attributes */ initialModeBits = 0666; ! if (attributes & SMB_ATTR_READONLY) ! initialModeBits &= ~0222; tp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(tp, &tp); *************** *** 8734,8739 **** --- 8799,8805 ---- smb_tran2DispatchTable[12].procp = smb_ReceiveTran2FindNotifyNext; smb_tran2DispatchTable[13].procp = smb_ReceiveTran2CreateDirectory; smb_tran2DispatchTable[14].procp = smb_ReceiveTran2SessionSetup; + smb_tran2DispatchTable[15].procp = smb_ReceiveTran2QFSInfoFid; smb_tran2DispatchTable[16].procp = smb_ReceiveTran2GetDFSReferral; smb_tran2DispatchTable[17].procp = smb_ReceiveTran2ReportDFSInconsistency; Index: openafs/src/WINNT/afsd/smb.h diff -c openafs/src/WINNT/afsd/smb.h:1.41.2.4 openafs/src/WINNT/afsd/smb.h:1.41.2.7 *** openafs/src/WINNT/afsd/smb.h:1.41.2.4 Tue Jul 4 18:43:24 2006 --- openafs/src/WINNT/afsd/smb.h Fri Jul 28 09:38:13 2006 *************** *** 83,92 **** --- 83,113 ---- #define SMB_QUERY_FILE_UNIX_LINK 0x201 #define SMB_INFO_PASSTHROUGH 0x1000 + #define SMB_SET_FILE_BASIC_INFO 0x101 + #define SMB_SET_FILE_DISPOSITION_INFO 0x102 + #define SMB_SET_FILE_ALLOCATION_INFO 0x103 + #define SMB_SET_FILE_END_OF_FILE_INFO 0x104 #define SMB_SET_FILE_UNIX_BASIC 0x200 #define SMB_SET_FILE_UNIX_LINK 0x201 #define SMB_SET_FILE_UNIX_HLINK 0x203 + #define SMB_INFO_ALLOCATION 1 + #define SMB_INFO_VOLUME 2 + #define SMB_QUERY_FS_LABEL_INFO 0x101 + #define SMB_QUERY_FS_VOLUME_INFO 0x102 + #define SMB_QUERY_FS_SIZE_INFO 0x103 + #define SMB_QUERY_FS_DEVICE_INFO 0x104 + #define SMB_QUERY_FS_ATTRIBUTE_INFO 0x105 + #define SMB_QUERY_FS_QUOTA_INFO 0x106 + #define SMB_QUERY_FS_CONTROL_INFO 0x107 + #define SMB_INFO_UNIX 0x200 + #define SMB_INFO_MACOS 0x301 + + #define SMB_FIND_FILE_DIRECTORY_INFO 0x101 + #define SMB_FIND_FILE_FULL_DIRECTORY_INFO 0x102 + #define SMB_FIND_FILE_NAMES_INFO 0x103 + #define SMB_FIND_FILE_BOTH_DIRECTORY_INFO 0x104 + /* more defines */ #define SMB_NOPCODES 256 /* # of opcodes in the dispatch table */ *************** *** 386,392 **** #define SMB_FID_QLOCK_PID 0 /* ! * SMB file attributes (32-bit) */ #define SMB_ATTR_READONLY 0x0001 #define SMB_ATTR_HIDDEN 0x0002 /* hidden file for the purpose of dir listings */ --- 407,413 ---- #define SMB_FID_QLOCK_PID 0 /* ! * SMB file attributes (16-bit) */ #define SMB_ATTR_READONLY 0x0001 #define SMB_ATTR_HIDDEN 0x0002 /* hidden file for the purpose of dir listings */ *************** *** 395,400 **** --- 416,423 ---- #define SMB_ATTR_DIRECTORY 0x0010 #define SMB_ATTR_ARCHIVE 0x0020 #define SMB_ATTR_DEVICE 0x0040 + + /* the following are Extended File Attributes (32-bit) */ #define SMB_ATTR_NORMAL 0x0080 /* normal file. Only valid if used alone */ #define SMB_ATTR_TEMPORARY 0x0100 #define SMB_ATTR_SPARSE_FILE 0x0200 /* used with dfs links */ *************** *** 403,408 **** --- 426,438 ---- #define SMB_ATTR_OFFLINE 0x1000 #define SMB_ATTR_NOT_CONTENT_INDEXED 0x2000 #define SMB_ATTR_ENCRYPTED 0x4000 + #define SMB_ATTR_POSIX_SEMANTICS 0x01000000 + #define SMB_ATTR_BACKUP_SEMANTICS 0x02000000 + #define SMB_ATTR_DELETE_ON_CLOSE 0x04000000 + #define SMB_ATTR_SEQUENTIAL_SCAN 0x08000000 + #define SMB_ATTR_RANDOM_ACCESS 0x10000000 + #define SMB_ATTR_NO_BUFFERING 0x20000000 + #define SMB_ATTR_WRITE_THROUGH 0x80000000 #define LOCKING_ANDX_SHARED_LOCK 0x01 /* Read-only lock */ #define LOCKING_ANDX_OPLOCK_RELEASE 0x02 /* Oplock break notification */ *************** *** 545,550 **** --- 575,582 ---- extern smb_fid_t *smb_FindFID(smb_vc_t *vcp, unsigned short fid, int flags); + extern smb_fid_t *smb_FindFIDByScache(smb_vc_t *vcp, cm_scache_t * scp); + extern void smb_HoldFIDNoLock(smb_fid_t *fidp); extern void smb_ReleaseFID(smb_fid_t *fidp); *************** *** 576,581 **** --- 608,615 ---- extern unsigned int smb_GetSMBParm(smb_packet_t *smbp, int parm); + extern unsigned int smb_GetSMBParmLong(smb_packet_t *smbp, int parm); + extern unsigned int smb_GetSMBOffsetParm(smb_packet_t *smbp, int parm, int offset); extern void smb_SetSMBParm(smb_packet_t *smbp, int slot, unsigned int parmValue); *************** *** 672,681 **** extern int smb_ChainFID(int fid, smb_packet_t *inp); - extern smb_fid_t *smb_FindFID(smb_vc_t *vcp, unsigned short fid, int flags); - - extern void smb_ReleaseFID(smb_fid_t *fidp); - extern unsigned char *smb_ParseDataBlock(unsigned char *inp, char **chainpp, int *lengthp); extern unsigned char *smb_ParseASCIIBlock(unsigned char *inp, char **chainpp); --- 706,711 ---- Index: openafs/src/WINNT/afsd/smb3.c diff -c openafs/src/WINNT/afsd/smb3.c:1.95.2.11 openafs/src/WINNT/afsd/smb3.c:1.95.2.14 *** openafs/src/WINNT/afsd/smb3.c:1.95.2.11 Tue Jul 4 18:43:24 2006 --- openafs/src/WINNT/afsd/smb3.c Fri Jul 28 09:38:13 2006 *************** *** 2092,2098 **** /* compute initial mode bits based on read-only flag in attributes */ initialModeBits = 0666; ! if (attributes & 1) initialModeBits &= ~0222; pathp = (char *) (&p->parmsp[14]); --- 2092,2098 ---- /* compute initial mode bits based on read-only flag in attributes */ initialModeBits = 0666; ! if (attributes & SMB_ATTR_READONLY) initialModeBits &= ~0222; pathp = (char *) (&p->parmsp[14]); *************** *** 2433,2465 **** return CM_ERROR_BADOP; } long smb_ReceiveTran2QFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { smb_tran2Packet_t *outp; smb_tran2QFSInfo_t qi; int responseSize; ! osi_hyper_t temp; ! static char FSname[6] = {'A', 0, 'F', 0, 'S', 0}; osi_Log1(smb_logp, "T2 QFSInfo type 0x%x", p->parmsp[0]); switch (p->parmsp[0]) { ! case 1: responseSize = sizeof(qi.u.allocInfo); break; ! case 2: responseSize = sizeof(qi.u.volumeInfo); break; ! break; ! case 0x102: responseSize = sizeof(qi.u.FSvolumeInfo); break; ! case 0x103: responseSize = sizeof(qi.u.FSsizeInfo); break; ! case 0x104: responseSize = sizeof(qi.u.FSdeviceInfo); break; ! case 0x105: responseSize = sizeof(qi.u.FSattributeInfo); break; ! case 0x200: /* CIFS Unix Info */ ! case 0x301: /* Mac FS Info */ default: ! return CM_ERROR_INVAL; } outp = smb_GetTran2ResponsePacket(vcp, p, op, 0, responseSize); switch (p->parmsp[0]) { ! case 1: /* alloc info */ qi.u.allocInfo.FSID = 0; qi.u.allocInfo.sectorsPerAllocUnit = 1; --- 2433,2487 ---- return CM_ERROR_BADOP; } + long smb_ReceiveTran2QFSInfoFid(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) + { + unsigned short fid; + unsigned short infolevel; + + infolevel = p->parmsp[0]; + fid = p->parmsp[1]; + osi_Log2(smb_logp, "T2 QFSInfoFid InfoLevel 0x%x fid 0x%x - NOT_SUPPORTED", infolevel, fid); + + return CM_ERROR_BADOP; + } + long smb_ReceiveTran2QFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { smb_tran2Packet_t *outp; smb_tran2QFSInfo_t qi; int responseSize; ! static char FSname[8] = {'A', 0, 'F', 0, 'S', 0, 0, 0}; osi_Log1(smb_logp, "T2 QFSInfo type 0x%x", p->parmsp[0]); switch (p->parmsp[0]) { ! case SMB_INFO_ALLOCATION: ! responseSize = sizeof(qi.u.allocInfo); ! break; ! case SMB_INFO_VOLUME: ! responseSize = sizeof(qi.u.volumeInfo); ! break; ! case SMB_QUERY_FS_VOLUME_INFO: ! responseSize = sizeof(qi.u.FSvolumeInfo); ! break; ! case SMB_QUERY_FS_SIZE_INFO: ! responseSize = sizeof(qi.u.FSsizeInfo); ! break; ! case SMB_QUERY_FS_DEVICE_INFO: ! responseSize = sizeof(qi.u.FSdeviceInfo); ! break; ! case SMB_QUERY_FS_ATTRIBUTE_INFO: ! responseSize = sizeof(qi.u.FSattributeInfo); ! break; ! case SMB_INFO_UNIX: /* CIFS Unix Info */ ! case SMB_INFO_MACOS: /* Mac FS Info */ default: ! return CM_ERROR_BADOP; } outp = smb_GetTran2ResponsePacket(vcp, p, op, 0, responseSize); switch (p->parmsp[0]) { ! case SMB_INFO_ALLOCATION: /* alloc info */ qi.u.allocInfo.FSID = 0; qi.u.allocInfo.sectorsPerAllocUnit = 1; *************** *** 2468,2474 **** qi.u.allocInfo.bytesPerSector = 1024; break; ! case 2: /* volume info */ qi.u.volumeInfo.vsn = 1234; qi.u.volumeInfo.vnCount = 4; --- 2490,2496 ---- qi.u.allocInfo.bytesPerSector = 1024; break; ! case SMB_INFO_VOLUME: /* volume info */ qi.u.volumeInfo.vsn = 1234; qi.u.volumeInfo.vnCount = 4; *************** *** 2477,2521 **** memcpy(qi.u.volumeInfo.label, "AFS", 4); break; ! case 0x102: /* FS volume info */ ! memset((char *)&qi.u.FSvolumeInfo.vct, 0, sizeof(FILETIME)); qi.u.FSvolumeInfo.vsn = 1234; qi.u.FSvolumeInfo.vnCount = 8; ! memcpy(qi.u.FSvolumeInfo.label, "A\0F\0S\0\0", 8); break; ! case 0x103: /* FS size info */ ! temp.HighPart = 0; ! temp.LowPart = 0x7fffffff; ! qi.u.FSsizeInfo.totalAllocUnits = temp; ! temp.LowPart = 0x3fffffff; ! qi.u.FSsizeInfo.availAllocUnits = temp; qi.u.FSsizeInfo.sectorsPerAllocUnit = 1; qi.u.FSsizeInfo.bytesPerSector = 1024; break; ! case 0x104: /* FS device info */ ! qi.u.FSdeviceInfo.devType = 0; /* don't have a number */ qi.u.FSdeviceInfo.characteristics = 0x50; /* remote, virtual */ break; ! case 0x105: /* FS attribute info */ /* attributes, defined in WINNT.H: * FILE_CASE_SENSITIVE_SEARCH 0x1 * FILE_CASE_PRESERVED_NAMES 0x2 * 0x4000 * If bit 0x4000 is not set, Windows 95 thinks * we can't handle long (non-8.3) names, * despite our protestations to the contrary. */ qi.u.FSattributeInfo.attributes = 0x4003; ! qi.u.FSattributeInfo.maxCompLength = 255; ! qi.u.FSattributeInfo.FSnameLength = 6; ! memcpy(qi.u.FSattributeInfo.FSname, FSname, 6); break; } --- 2499,2543 ---- memcpy(qi.u.volumeInfo.label, "AFS", 4); break; ! case SMB_QUERY_FS_VOLUME_INFO: /* FS volume info */ ! memset((char *)&qi.u.FSvolumeInfo.vct, 0, 4); qi.u.FSvolumeInfo.vsn = 1234; qi.u.FSvolumeInfo.vnCount = 8; ! memcpy(qi.u.FSvolumeInfo.label, "A\0F\0S\0\0\0", 8); break; ! case SMB_QUERY_FS_SIZE_INFO: /* FS size info */ ! qi.u.FSsizeInfo.totalAllocUnits.HighPart = 0; ! qi.u.FSsizeInfo.totalAllocUnits.LowPart= 0x7fffffff; ! qi.u.FSsizeInfo.availAllocUnits.HighPart = 0; ! qi.u.FSsizeInfo.availAllocUnits.LowPart= 0x3fffffff; qi.u.FSsizeInfo.sectorsPerAllocUnit = 1; qi.u.FSsizeInfo.bytesPerSector = 1024; break; ! case SMB_QUERY_FS_DEVICE_INFO: /* FS device info */ ! qi.u.FSdeviceInfo.devType = 0x14; /* network file system */ qi.u.FSdeviceInfo.characteristics = 0x50; /* remote, virtual */ break; ! case SMB_QUERY_FS_ATTRIBUTE_INFO: /* FS attribute info */ /* attributes, defined in WINNT.H: * FILE_CASE_SENSITIVE_SEARCH 0x1 * FILE_CASE_PRESERVED_NAMES 0x2 + * FILE_VOLUME_QUOTAS 0x10 * 0x4000 * If bit 0x4000 is not set, Windows 95 thinks * we can't handle long (non-8.3) names, * despite our protestations to the contrary. */ qi.u.FSattributeInfo.attributes = 0x4003; ! qi.u.FSattributeInfo.maxCompLength = MAX_PATH; ! qi.u.FSattributeInfo.FSnameLength = sizeof(FSname); ! memcpy(qi.u.FSattributeInfo.FSname, FSname, sizeof(FSname)); break; } *************** *** 2618,2624 **** afs_uint32 dosTime; FILETIME ft; unsigned short infoLevel; ! int nbytesRequired; unsigned short attributes; unsigned long extAttributes; char shortName[13]; --- 2640,2647 ---- afs_uint32 dosTime; FILETIME ft; unsigned short infoLevel; ! smb_tran2QPathInfo_t qpi; ! int responseSize; unsigned short attributes; unsigned long extAttributes; char shortName[13]; *************** *** 2626,2633 **** cm_user_t *userp; cm_space_t *spacep; cm_scache_t *scp, *dscp; long code = 0; - char *op; char *pathp; char *tidPathp; char *lastComp; --- 2649,2656 ---- cm_user_t *userp; cm_space_t *spacep; cm_scache_t *scp, *dscp; + int delonclose = 0; long code = 0; char *pathp; char *tidPathp; char *lastComp; *************** *** 2637,2679 **** infoLevel = p->parmsp[0]; if (infoLevel == SMB_INFO_IS_NAME_VALID) ! nbytesRequired = 0; else if (infoLevel == SMB_INFO_STANDARD) ! nbytesRequired = 22; else if (infoLevel == SMB_INFO_QUERY_EA_SIZE) ! nbytesRequired = 26; ! else if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) { ! #ifdef COMMENT ! nbytesRequired = 40; ! #else ! nbytesRequired = 34; ! #endif ! } ! else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) { ! #ifdef COMMENT ! nbytesRequired = 24; ! #else ! nbytesRequired = 22; ! #endif ! } ! else if (infoLevel == SMB_QUERY_FILE_EA_INFO) ! nbytesRequired = 4; ! #if 0 else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) ! nbytesRequired = ???; else if (infoLevel == SMB_QUERY_FILE_ALL_INFO) ! nbytesRequired = ???; ! #endif else if (infoLevel == SMB_QUERY_FILE_ALT_NAME_INFO) ! nbytesRequired = 30; else { osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", p->opcode, infoLevel); - #ifdef COMMENT - smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL); - #else smb_SendTran2Error(vcp, p, opx, CM_ERROR_BADOP); - #endif return 0; } --- 2660,2686 ---- infoLevel = p->parmsp[0]; if (infoLevel == SMB_INFO_IS_NAME_VALID) ! responseSize = 0; else if (infoLevel == SMB_INFO_STANDARD) ! responseSize = sizeof(qpi.u.QPstandardInfo); else if (infoLevel == SMB_INFO_QUERY_EA_SIZE) ! responseSize = sizeof(qpi.u.QPeaSizeInfo); ! else if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) ! responseSize = sizeof(qpi.u.QPfileBasicInfo); ! else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) ! responseSize = sizeof(qpi.u.QPfileStandardInfo); ! else if (infoLevel == SMB_QUERY_FILE_EA_INFO) ! responseSize = sizeof(qpi.u.QPfileEaInfo); else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) ! responseSize = sizeof(qpi.u.QPfileNameInfo); else if (infoLevel == SMB_QUERY_FILE_ALL_INFO) ! responseSize = sizeof(qpi.u.QPfileAllInfo); else if (infoLevel == SMB_QUERY_FILE_ALT_NAME_INFO) ! responseSize = sizeof(qpi.u.QPfileAltNameInfo); else { osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", p->opcode, infoLevel); smb_SendTran2Error(vcp, p, opx, CM_ERROR_BADOP); return 0; } *************** *** 2683,2695 **** osi_Log2(smb_logp, "T2 QPathInfo type 0x%x path %s", infoLevel, osi_LogSaveString(smb_logp, pathp)); ! outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, nbytesRequired); if (infoLevel > 0x100) outp->totalParms = 2; else outp->totalParms = 0; ! outp->totalData = nbytesRequired; /* now, if we're at infoLevel 6, we're only being asked to check * the syntax, so we just OK things now. In particular, we're *not* --- 2690,2702 ---- osi_Log2(smb_logp, "T2 QPathInfo type 0x%x path %s", infoLevel, osi_LogSaveString(smb_logp, pathp)); ! outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, responseSize); if (infoLevel > 0x100) outp->totalParms = 2; else outp->totalParms = 0; ! outp->totalData = responseSize; /* now, if we're at infoLevel 6, we're only being asked to check * the syntax, so we just OK things now. In particular, we're *not* *************** *** 2809,2817 **** /* now we have the status in the cache entry, and everything is locked. * Marshall the output data. */ - op = outp->datap; /* for info level 108, figure out short name */ ! if (infoLevel == 0x108) { code = cm_GetShortName(pathp, userp, &req, tidPathp, scp->fid.vnode, shortName, (size_t *) &len); --- 2816,2823 ---- /* now we have the status in the cache entry, and everything is locked. * Marshall the output data. */ /* for info level 108, figure out short name */ ! if (infoLevel == SMB_QUERY_FILE_ALT_NAME_INFO) { code = cm_GetShortName(pathp, userp, &req, tidPathp, scp->fid.vnode, shortName, (size_t *) &len); *************** *** 2819,2898 **** goto done; } ! op = outp->datap; ! *((u_long *)op) = len * 2; op += 4; ! mbstowcs((unsigned short *)op, shortName, len); ! op += (len * 2); goto done; } ! if (infoLevel == SMB_INFO_STANDARD || infoLevel == SMB_INFO_QUERY_EA_SIZE) { smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime); ! *((u_long *)op) = dosTime; op += 4; /* creation time */ ! *((u_long *)op) = dosTime; op += 4; /* access time */ ! *((u_long *)op) = dosTime; op += 4; /* write time */ ! *((u_long *)op) = scp->length.LowPart; op += 4; /* length */ ! *((u_long *)op) = scp->length.LowPart; op += 4; /* alloc size */ attributes = smb_Attributes(scp); ! *((u_short *)op) = attributes; op += 2; /* attributes */ ! ! /* now, if we are being asked about extended attrs, return a 0 size */ ! if (infoLevel == SMB_INFO_QUERY_EA_SIZE) { ! *((u_long *)op) = 0; op += 4; ! } } else if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) { smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); ! *((FILETIME *)op) = ft; op += 8; /* creation time */ ! *((FILETIME *)op) = ft; op += 8; /* last access time */ ! *((FILETIME *)op) = ft; op += 8; /* last write time */ ! *((FILETIME *)op) = ft; op += 8; /* last change time */ extAttributes = smb_ExtAttributes(scp); ! #ifdef COMMENT ! *((u_long *)op) = extAttributes; op += 4; /* extended attribs */ ! *((u_long *)op) = 0; op += 4; /* don't know what this is */ ! #else ! /* The CIFS Specs say */ ! *((u_short *)op) = extAttributes; op += 2; /* extended attributes */ ! #endif } else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) { ! *((LARGE_INTEGER *)op) = scp->length; op += 8; /* alloc size */ ! *((LARGE_INTEGER *)op) = scp->length; op += 8; /* EOF */ ! *((u_long *)op) = scp->linkCount; op += 4; /* Link count */ ! *op++ = 0; /* Delete Pending */ ! *op++ = ((scp->fileType == CM_SCACHETYPE_DIRECTORY || ! scp->fileType == CM_SCACHETYPE_MOUNTPOINT || ! scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0); ! #ifdef COMMENT ! *op++ = 0; ! *op++ = 0; ! #endif } else if (infoLevel == SMB_QUERY_FILE_EA_INFO) { ! memset(op, 0, 4); op += 4; /* EA size */ } - - /* send and free the packets */ done: lock_ReleaseMutex(&scp->mx); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); ! if (code == 0) ! smb_SendTran2Packet(vcp, outp, opx); ! else smb_SendTran2Error(vcp, p, opx, code); smb_FreeTran2Packet(outp); return 0; } ! long smb_ReceiveTran2SetPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { osi_Log0(smb_logp,"ReceiveTran2SetPathInfo - NOT_SUPPORTED"); return CM_ERROR_BADOP; } long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx) --- 2825,3151 ---- goto done; } ! qpi.u.QPfileAltNameInfo.fileNameLength = (len + 1) * 2; ! mbstowcs((unsigned short *)qpi.u.QPfileAltNameInfo.fileName, shortName, len + 1); goto done; } ! else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) { ! len = strlen(lastComp); ! qpi.u.QPfileNameInfo.fileNameLength = (len + 1) * 2; ! mbstowcs((unsigned short *)qpi.u.QPfileNameInfo.fileName, lastComp, len + 1); ! ! goto done; ! } ! else if (infoLevel == SMB_INFO_STANDARD || infoLevel == SMB_INFO_QUERY_EA_SIZE) { smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime); ! qpi.u.QPstandardInfo.creationDateTime = dosTime; ! qpi.u.QPstandardInfo.lastAccessDateTime = dosTime; ! qpi.u.QPstandardInfo.lastWriteDateTime = dosTime; ! qpi.u.QPstandardInfo.dataSize = scp->length.LowPart; ! qpi.u.QPstandardInfo.allocationSize = scp->length.LowPart; attributes = smb_Attributes(scp); ! qpi.u.QPstandardInfo.attributes = attributes; ! qpi.u.QPstandardInfo.eaSize = 0; } else if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) { smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); ! qpi.u.QPfileBasicInfo.creationTime = ft; ! qpi.u.QPfileBasicInfo.lastAccessTime = ft; ! qpi.u.QPfileBasicInfo.lastWriteTime = ft; ! qpi.u.QPfileBasicInfo.changeTime = ft; extAttributes = smb_ExtAttributes(scp); ! qpi.u.QPfileBasicInfo.attributes = extAttributes; ! qpi.u.QPfileBasicInfo.reserved = 0; } else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) { ! smb_fid_t *fidp = smb_FindFIDByScache(vcp, scp); ! if (fidp) { ! lock_ObtainMutex(&fidp->mx); ! delonclose = fidp->flags & SMB_FID_DELONCLOSE; ! lock_ReleaseMutex(&fidp->mx); ! smb_ReleaseFID(fidp); ! } ! ! qpi.u.QPfileStandardInfo.allocationSize = scp->length; ! qpi.u.QPfileStandardInfo.endOfFile = scp->length; ! qpi.u.QPfileStandardInfo.numberOfLinks = scp->linkCount; ! qpi.u.QPfileStandardInfo.deletePending = (delonclose ? 1 : 0); ! qpi.u.QPfileStandardInfo.directory = ! ((scp->fileType == CM_SCACHETYPE_DIRECTORY || ! scp->fileType == CM_SCACHETYPE_MOUNTPOINT || ! scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0); ! qpi.u.QPfileStandardInfo.reserved = 0; } else if (infoLevel == SMB_QUERY_FILE_EA_INFO) { ! qpi.u.QPfileEaInfo.eaSize = 0; ! } ! else if (infoLevel == SMB_QUERY_FILE_ALL_INFO) { ! smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); ! qpi.u.QPfileAllInfo.creationTime = ft; ! qpi.u.QPfileAllInfo.lastAccessTime = ft; ! qpi.u.QPfileAllInfo.lastWriteTime = ft; ! qpi.u.QPfileAllInfo.changeTime = ft; ! extAttributes = smb_ExtAttributes(scp); ! qpi.u.QPfileAllInfo.attributes = extAttributes; ! qpi.u.QPfileAllInfo.allocationSize = scp->length; ! qpi.u.QPfileAllInfo.endOfFile = scp->length; ! qpi.u.QPfileAllInfo.numberOfLinks = scp->linkCount; ! qpi.u.QPfileAllInfo.deletePending = 0; ! qpi.u.QPfileAllInfo.directory = ! ((scp->fileType == CM_SCACHETYPE_DIRECTORY || ! scp->fileType == CM_SCACHETYPE_MOUNTPOINT || ! scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0); ! qpi.u.QPfileAllInfo.indexNumber.HighPart = scp->fid.cell; ! qpi.u.QPfileAllInfo.indexNumber.LowPart = scp->fid.volume; ! qpi.u.QPfileAllInfo.eaSize = 0; ! qpi.u.QPfileAllInfo.accessFlags = 0; ! qpi.u.QPfileAllInfo.indexNumber2.HighPart = scp->fid.vnode; ! qpi.u.QPfileAllInfo.indexNumber2.LowPart = scp->fid.unique; ! qpi.u.QPfileAllInfo.currentByteOffset.HighPart = 0; ! qpi.u.QPfileAllInfo.currentByteOffset.LowPart = 0; ! qpi.u.QPfileAllInfo.mode = 0; ! qpi.u.QPfileAllInfo.alignmentRequirement = 0; ! len = strlen(lastComp); ! qpi.u.QPfileAllInfo.fileNameLength = (len + 1) * 2; ! mbstowcs((unsigned short *)qpi.u.QPfileAllInfo.fileName, lastComp, len + 1); } /* send and free the packets */ done: lock_ReleaseMutex(&scp->mx); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); ! if (code == 0) { ! memcpy(outp->datap, &qpi, responseSize); ! smb_SendTran2Packet(vcp, outp, opx); ! } else { smb_SendTran2Error(vcp, p, opx, code); + } smb_FreeTran2Packet(outp); return 0; } ! long smb_ReceiveTran2SetPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx) { + #if 0 osi_Log0(smb_logp,"ReceiveTran2SetPathInfo - NOT_SUPPORTED"); return CM_ERROR_BADOP; + #else + long code = 0; + smb_fid_t *fidp; + unsigned short infoLevel; + char * pathp; + smb_tran2Packet_t *outp; + smb_tran2QPathInfo_t *spi; + cm_user_t *userp; + cm_scache_t *scp, *dscp; + cm_req_t req; + cm_space_t *spacep; + char *tidPathp; + char *lastComp; + + cm_InitReq(&req); + + infoLevel = p->parmsp[0]; + osi_Log1(smb_logp,"ReceiveTran2SetPathInfo type 0x%x", infoLevel); + if (infoLevel != SMB_INFO_STANDARD && + infoLevel != SMB_INFO_QUERY_EA_SIZE && + infoLevel != SMB_INFO_QUERY_ALL_EAS) { + osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", + p->opcode, infoLevel); + smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL); + return 0; + } + + pathp = (char *)(&p->parmsp[3]); + if (smb_StoreAnsiFilenames) + OemToChar(pathp,pathp); + osi_Log2(smb_logp, "T2 SetPathInfo infolevel 0x%x path %s", infoLevel, + osi_LogSaveString(smb_logp, pathp)); + + userp = smb_GetTran2User(vcp, p); + if (!userp) { + osi_Log1(smb_logp,"ReceiveTran2SetPathInfo unable to resolve user [%d]", p->uid); + code = CM_ERROR_BADSMB; + goto done; + } + + code = smb_LookupTIDPath(vcp, p->tid, &tidPathp); + if (code == CM_ERROR_TIDIPC) { + /* Attempt to use a TID allocated for IPC. The client + * is probably looking for DCE RPC end points which we + * don't support OR it could be looking to make a DFS + * referral request. + */ + osi_Log0(smb_logp, "Tran2Open received IPC TID"); + cm_ReleaseUser(userp); + return CM_ERROR_NOSUCHPATH; + } + + /* + * XXX Strange hack XXX + * + * As of Patch 7 (13 January 98), we are having the following problem: + * In NT Explorer 4.0, whenever we click on a directory, AFS gets + * requests to look up "desktop.ini" in all the subdirectories. + * This can cause zillions of timeouts looking up non-existent cells + * and volumes, especially in the top-level directory. + * + * We have not found any way to avoid this or work around it except + * to explicitly ignore the requests for mount points that haven't + * yet been evaluated and for directories that haven't yet been + * fetched. + */ + if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) { + spacep = cm_GetSpace(); + smb_StripLastComponent(spacep->data, &lastComp, pathp); + #ifndef SPECIAL_FOLDERS + /* Make sure that lastComp is not NULL */ + if (lastComp) { + if (stricmp(lastComp, "\\desktop.ini") == 0) { + code = cm_NameI(cm_data.rootSCachep, spacep->data, + CM_FLAG_CASEFOLD + | CM_FLAG_DIRSEARCH + | CM_FLAG_FOLLOW, + userp, tidPathp, &req, &dscp); + if (code == 0) { + #ifdef DFS_SUPPORT + if (dscp->fileType == CM_SCACHETYPE_DFSLINK) { + if ( WANTS_DFS_PATHNAMES(p) ) + code = CM_ERROR_PATH_NOT_COVERED; + else + code = CM_ERROR_BADSHARENAME; + } else + #endif /* DFS_SUPPORT */ + if (dscp->fileType == CM_SCACHETYPE_MOUNTPOINT && !dscp->mountRootFid.volume) + code = CM_ERROR_NOSUCHFILE; + else if (dscp->fileType == CM_SCACHETYPE_DIRECTORY) { + cm_buf_t *bp = buf_Find(dscp, &hzero); + if (bp) + buf_Release(bp); + else + code = CM_ERROR_NOSUCHFILE; + } + cm_ReleaseSCache(dscp); + if (code) { + cm_FreeSpace(spacep); + cm_ReleaseUser(userp); + smb_SendTran2Error(vcp, p, opx, code); + return 0; + } + } + } + } + #endif /* SPECIAL_FOLDERS */ + + cm_FreeSpace(spacep); + } + + /* now do namei and stat, and copy out the info */ + code = cm_NameI(cm_data.rootSCachep, pathp, + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp); + if (code) { + cm_ReleaseUser(userp); + smb_SendTran2Error(vcp, p, opx, code); + return 0; + } + + fidp = smb_FindFIDByScache(vcp, scp); + if (!fidp) { + cm_ReleaseUser(userp); + cm_ReleaseSCache(scp); + smb_SendTran2Error(vcp, p, opx, code); + return 0; + } + + lock_ObtainMutex(&fidp->mx); + if (!(fidp->flags & SMB_FID_OPENWRITE)) { + lock_ReleaseMutex(&fidp->mx); + smb_ReleaseFID(fidp); + cm_ReleaseUser(userp); + cm_ReleaseSCache(scp); + smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOACCESS); + return 0; + } + lock_ReleaseMutex(&fidp->mx); + + outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, 0); + + outp->totalParms = 2; + outp->totalData = 0; + + spi = (smb_tran2QPathInfo_t *)p->datap; + if (infoLevel == SMB_INFO_STANDARD || infoLevel == SMB_INFO_QUERY_EA_SIZE) { + cm_attr_t attr; + + /* lock the vnode with a callback; we need the current status + * to determine what the new status is, in some cases. + */ + lock_ObtainMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_GETSTATUS + | CM_SCACHESYNC_NEEDCALLBACK); + lock_ReleaseMutex(&scp->mx); + if (code) { + goto done; + } + + lock_ObtainMutex(&fidp->mx); + lock_ObtainMutex(&scp->mx); + + /* prepare for setattr call */ + attr.mask = CM_ATTRMASK_LENGTH; + attr.length.LowPart = spi->u.QPstandardInfo.dataSize; + attr.length.HighPart = 0; + + if (spi->u.QPstandardInfo.lastWriteDateTime != 0) { + smb_UnixTimeFromSearchTime(&attr.clientModTime, spi->u.QPstandardInfo.lastWriteDateTime); + attr.mask |= CM_ATTRMASK_CLIENTMODTIME; + fidp->flags |= SMB_FID_MTIMESETDONE; + } + + if (spi->u.QPstandardInfo.attributes != 0) { + if ((scp->unixModeBits & 0222) + && (spi->u.QPstandardInfo.attributes & SMB_ATTR_READONLY) != 0) { + /* make a writable file read-only */ + attr.mask |= CM_ATTRMASK_UNIXMODEBITS; + attr.unixModeBits = scp->unixModeBits & ~0222; + } + else if ((scp->unixModeBits & 0222) == 0 + && (spi->u.QPstandardInfo.attributes & SMB_ATTR_READONLY) == 0) { + /* make a read-only file writable */ + attr.mask |= CM_ATTRMASK_UNIXMODEBITS; + attr.unixModeBits = scp->unixModeBits | 0222; + } + } + lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&fidp->mx); + + /* call setattr */ + if (attr.mask) + code = cm_SetAttr(scp, &attr, userp, &req); + else + code = 0; + } + else if (infoLevel == SMB_INFO_QUERY_ALL_EAS) { + /* we don't support EAs */ + code = CM_ERROR_INVAL; + } + + done: + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); + if (code == 0) + smb_SendTran2Packet(vcp, outp, opx); + else + smb_SendTran2Error(vcp, p, opx, code); + smb_FreeTran2Packet(outp); + + return 0; + #endif } long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx) *************** *** 2901,2913 **** FILETIME ft; unsigned long attributes; unsigned short infoLevel; ! int nbytesRequired; unsigned short fid; int delonclose = 0; cm_user_t *userp; smb_fid_t *fidp; cm_scache_t *scp; ! char *op; long code = 0; cm_req_t req; --- 3154,3166 ---- FILETIME ft; unsigned long attributes; unsigned short infoLevel; ! int responseSize; unsigned short fid; int delonclose = 0; cm_user_t *userp; smb_fid_t *fidp; cm_scache_t *scp; ! smb_tran2QFileInfo_t qfi; long code = 0; cm_req_t req; *************** *** 2923,2951 **** infoLevel = p->parmsp[1]; if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) ! nbytesRequired = 40; else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) ! nbytesRequired = 24; else if (infoLevel == SMB_QUERY_FILE_EA_INFO) ! nbytesRequired = 4; else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) ! nbytesRequired = 6; else { osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", p->opcode, infoLevel); ! smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL); smb_ReleaseFID(fidp); return 0; } osi_Log2(smb_logp, "T2 QFileInfo type 0x%x fid %d", infoLevel, fid); ! outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, nbytesRequired); if (infoLevel > 0x100) outp->totalParms = 2; else outp->totalParms = 0; ! outp->totalData = nbytesRequired; userp = smb_GetTran2User(vcp, p); if (!userp) { --- 3176,3204 ---- infoLevel = p->parmsp[1]; if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) ! responseSize = sizeof(qfi.u.QFbasicInfo); else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) ! responseSize = sizeof(qfi.u.QFstandardInfo); else if (infoLevel == SMB_QUERY_FILE_EA_INFO) ! responseSize = sizeof(qfi.u.QFeaInfo); else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) ! responseSize = sizeof(qfi.u.QFfileNameInfo); else { osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", p->opcode, infoLevel); ! smb_SendTran2Error(vcp, p, opx, CM_ERROR_BADOP); smb_ReleaseFID(fidp); return 0; } osi_Log2(smb_logp, "T2 QFileInfo type 0x%x fid %d", infoLevel, fid); ! outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, responseSize); if (infoLevel > 0x100) outp->totalParms = 2; else outp->totalParms = 0; ! outp->totalData = responseSize; userp = smb_GetTran2User(vcp, p); if (!userp) { *************** *** 2968,2997 **** /* now we have the status in the cache entry, and everything is locked. * Marshall the output data. */ - op = outp->datap; if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) { smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); ! *((FILETIME *)op) = ft; op += 8; /* creation time */ ! *((FILETIME *)op) = ft; op += 8; /* last access time */ ! *((FILETIME *)op) = ft; op += 8; /* last write time */ ! *((FILETIME *)op) = ft; op += 8; /* last change time */ attributes = smb_ExtAttributes(scp); ! *((u_long *)op) = attributes; op += 4; ! *((u_long *)op) = 0; op += 4; } else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) { ! *((LARGE_INTEGER *)op) = scp->length; op += 8; /* alloc size */ ! *((LARGE_INTEGER *)op) = scp->length; op += 8; /* EOF */ ! *((u_long *)op) = scp->linkCount; op += 4; /* Link count */ ! *op++ = (delonclose ? 1 : 0); /* Delete Pending */ ! *op++ = ((scp->fileType == CM_SCACHETYPE_DIRECTORY || ! scp->fileType == CM_SCACHETYPE_MOUNTPOINT || ! scp->fileType == CM_SCACHETYPE_INVALID)? 1 : 0); ! *op++ = 0; ! *op++ = 0; } else if (infoLevel == SMB_QUERY_FILE_EA_INFO) { ! *((u_long *)op) = 0; op += 4; } else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) { unsigned long len; --- 3221,3247 ---- /* now we have the status in the cache entry, and everything is locked. * Marshall the output data. */ if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) { smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); ! qfi.u.QFbasicInfo.creationTime = ft; ! qfi.u.QFbasicInfo.lastAccessTime = ft; ! qfi.u.QFbasicInfo.lastWriteTime = ft; ! qfi.u.QFbasicInfo.lastChangeTime = ft; attributes = smb_ExtAttributes(scp); ! qfi.u.QFbasicInfo.attributes = attributes; } else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) { ! qfi.u.QFstandardInfo.allocationSize = scp->length; ! qfi.u.QFstandardInfo.endOfFile = scp->length; ! qfi.u.QFstandardInfo.numberOfLinks = scp->linkCount; ! qfi.u.QFstandardInfo.deletePending = (delonclose ? 1 : 0); ! qfi.u.QFstandardInfo.directory = ! ((scp->fileType == CM_SCACHETYPE_DIRECTORY || ! scp->fileType == CM_SCACHETYPE_MOUNTPOINT || ! scp->fileType == CM_SCACHETYPE_INVALID)? 1 : 0); } else if (infoLevel == SMB_QUERY_FILE_EA_INFO) { ! qfi.u.QFeaInfo.eaSize = 0; } else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) { unsigned long len; *************** *** 3006,3014 **** name = "\\"; /* probably can't happen */ lock_ReleaseMutex(&fidp->mx); len = (unsigned long)strlen(name); ! outp->totalData = (len*2) + 4; /* this is actually what we want to return */ ! *((u_long *)op) = len * 2; op += 4; ! mbstowcs((unsigned short *)op, name, len); op += (len * 2); } /* send and free the packets */ --- 3256,3264 ---- name = "\\"; /* probably can't happen */ lock_ReleaseMutex(&fidp->mx); len = (unsigned long)strlen(name); ! outp->totalData = ((len+1)*2) + 4; /* this is actually what we want to return */ ! qfi.u.QFfileNameInfo.fileNameLength = (len + 1) * 2; ! mbstowcs((unsigned short *)qfi.u.QFfileNameInfo.fileName, name, len + 1); } /* send and free the packets */ *************** *** 3017,3032 **** cm_ReleaseSCache(scp); cm_ReleaseUser(userp); smb_ReleaseFID(fidp); ! if (code == 0) smb_SendTran2Packet(vcp, outp, opx); ! else smb_SendTran2Error(vcp, p, opx, code); smb_FreeTran2Packet(outp); return 0; } ! long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { long code = 0; unsigned short fid; --- 3267,3284 ---- cm_ReleaseSCache(scp); cm_ReleaseUser(userp); smb_ReleaseFID(fidp); ! if (code == 0) { ! memcpy(outp->datap, &qfi, responseSize); smb_SendTran2Packet(vcp, outp, opx); ! } else { smb_SendTran2Error(vcp, p, opx, code); + } smb_FreeTran2Packet(outp); return 0; } ! long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx) { long code = 0; unsigned short fid; *************** *** 3043,3074 **** fidp = smb_FindFID(vcp, fid, 0); if (fidp == NULL) { ! smb_SendTran2Error(vcp, p, op, CM_ERROR_BADFD); return 0; } infoLevel = p->parmsp[1]; osi_Log2(smb_logp,"ReceiveTran2SetFileInfo type 0x%x fid %d", infoLevel, fid); ! if (infoLevel > 0x104 || infoLevel < 0x101) { osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", p->opcode, infoLevel); ! smb_SendTran2Error(vcp, p, op, CM_ERROR_INVAL); smb_ReleaseFID(fidp); return 0; } lock_ObtainMutex(&fidp->mx); ! if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO && !(fidp->flags & SMB_FID_OPENDELETE)) { lock_ReleaseMutex(&fidp->mx); smb_ReleaseFID(fidp); ! smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS); return 0; } ! if ((infoLevel == SMB_QUERY_FILE_EA_INFO || infoLevel == SMB_QUERY_FILE_NAME_INFO) && !(fidp->flags & SMB_FID_OPENWRITE)) { lock_ReleaseMutex(&fidp->mx); smb_ReleaseFID(fidp); ! smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS); return 0; } --- 3295,3327 ---- fidp = smb_FindFID(vcp, fid, 0); if (fidp == NULL) { ! smb_SendTran2Error(vcp, p, opx, CM_ERROR_BADFD); return 0; } infoLevel = p->parmsp[1]; osi_Log2(smb_logp,"ReceiveTran2SetFileInfo type 0x%x fid %d", infoLevel, fid); ! if (infoLevel > SMB_SET_FILE_END_OF_FILE_INFO || infoLevel < SMB_SET_FILE_BASIC_INFO) { osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", p->opcode, infoLevel); ! smb_SendTran2Error(vcp, p, opx, CM_ERROR_BADOP); smb_ReleaseFID(fidp); return 0; } lock_ObtainMutex(&fidp->mx); ! if (infoLevel == SMB_SET_FILE_DISPOSITION_INFO && !(fidp->flags & SMB_FID_OPENDELETE)) { lock_ReleaseMutex(&fidp->mx); smb_ReleaseFID(fidp); ! smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOACCESS); return 0; } ! if ((infoLevel == SMB_SET_FILE_ALLOCATION_INFO || ! infoLevel == SMB_SET_FILE_END_OF_FILE_INFO) && !(fidp->flags & SMB_FID_OPENWRITE)) { lock_ReleaseMutex(&fidp->mx); smb_ReleaseFID(fidp); ! smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOACCESS); return 0; } *************** *** 3076,3084 **** cm_HoldSCache(scp); lock_ReleaseMutex(&fidp->mx); ! osi_Log1(smb_logp, "T2 SFileInfo type 0x%x", infoLevel); ! ! outp = smb_GetTran2ResponsePacket(vcp, p, op, 2, 0); outp->totalParms = 2; outp->totalData = 0; --- 3329,3335 ---- cm_HoldSCache(scp); lock_ReleaseMutex(&fidp->mx); ! outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, 0); outp->totalParms = 2; outp->totalData = 0; *************** *** 3090,3101 **** goto done; } ! if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) { FILETIME lastMod; unsigned int attribute; cm_attr_t attr; ! /* lock the vnode with a callback; we need the current status * to determine what the new status is, in some cases. */ lock_ObtainMutex(&scp->mx); --- 3341,3355 ---- goto done; } ! if (infoLevel == SMB_SET_FILE_BASIC_INFO) { FILETIME lastMod; unsigned int attribute; cm_attr_t attr; + smb_tran2QFileInfo_t *sfi; ! sfi = (smb_tran2QFileInfo_t *)p->datap; ! ! /* lock the vnode with a callback; we need the current status * to determine what the new status is, in some cases. */ lock_ObtainMutex(&scp->mx); *************** *** 3103,3111 **** CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); lock_ReleaseMutex(&scp->mx); ! if (code) { goto done; - } lock_ObtainMutex(&fidp->mx); lock_ObtainMutex(&scp->mx); --- 3357,3364 ---- CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); lock_ReleaseMutex(&scp->mx); ! if (code) goto done; lock_ObtainMutex(&fidp->mx); lock_ObtainMutex(&scp->mx); *************** *** 3113,3119 **** /* prepare for setattr call */ attr.mask = 0; ! lastMod = *((FILETIME *)(p->datap + 16)); /* when called as result of move a b, lastMod is (-1, -1). * If the check for -1 is not present, timestamp * of the resulting file will be 1969 (-1) --- 3366,3372 ---- /* prepare for setattr call */ attr.mask = 0; ! lastMod = sfi->u.QFbasicInfo.lastWriteTime; /* when called as result of move a b, lastMod is (-1, -1). * If the check for -1 is not present, timestamp * of the resulting file will be 1969 (-1) *************** *** 3125,3140 **** fidp->flags |= SMB_FID_MTIMESETDONE; } ! attribute = *((u_long *)(p->datap + 32)); if (attribute != 0) { if ((scp->unixModeBits & 0222) ! && (attribute & 1) != 0) { /* make a writable file read-only */ attr.mask |= CM_ATTRMASK_UNIXMODEBITS; attr.unixModeBits = scp->unixModeBits & ~0222; } else if ((scp->unixModeBits & 0222) == 0 ! && (attribute & 1) == 0) { /* make a read-only file writable */ attr.mask |= CM_ATTRMASK_UNIXMODEBITS; attr.unixModeBits = scp->unixModeBits | 0222; --- 3378,3393 ---- fidp->flags |= SMB_FID_MTIMESETDONE; } ! attribute = sfi->u.QFbasicInfo.attributes; if (attribute != 0) { if ((scp->unixModeBits & 0222) ! && (attribute & SMB_ATTR_READONLY) != 0) { /* make a writable file read-only */ attr.mask |= CM_ATTRMASK_UNIXMODEBITS; attr.unixModeBits = scp->unixModeBits & ~0222; } else if ((scp->unixModeBits & 0222) == 0 ! && (attribute & SMB_ATTR_READONLY) == 0) { /* make a read-only file writable */ attr.mask |= CM_ATTRMASK_UNIXMODEBITS; attr.unixModeBits = scp->unixModeBits | 0222; *************** *** 3148,3165 **** code = cm_SetAttr(scp, &attr, userp, &req); else code = 0; ! } ! else if (infoLevel == SMB_QUERY_FILE_EA_INFO || infoLevel == SMB_QUERY_FILE_NAME_INFO) { ! LARGE_INTEGER size = *((LARGE_INTEGER *)(p->datap)); ! cm_attr_t attr; ! ! attr.mask = CM_ATTRMASK_LENGTH; ! attr.length.LowPart = size.LowPart; ! attr.length.HighPart = size.HighPart; ! code = cm_SetAttr(scp, &attr, userp, &req); ! } ! else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) { ! if (*((char *)(p->datap))) { code = cm_CheckNTDelete(fidp->NTopen_dscp, scp, userp, &req); if (code == 0) { --- 3401,3409 ---- code = cm_SetAttr(scp, &attr, userp, &req); else code = 0; ! } ! else if (infoLevel == SMB_SET_FILE_DISPOSITION_INFO) { ! if (*((char *)(p->datap))) { /* File is Deleted */ code = cm_CheckNTDelete(fidp->NTopen_dscp, scp, userp, &req); if (code == 0) { *************** *** 3175,3189 **** lock_ReleaseMutex(&fidp->mx); } } done: cm_ReleaseSCache(scp); cm_ReleaseUser(userp); smb_ReleaseFID(fidp); if (code == 0) ! smb_SendTran2Packet(vcp, outp, op); else ! smb_SendTran2Error(vcp, p, op, code); smb_FreeTran2Packet(outp); return 0; --- 3419,3451 ---- lock_ReleaseMutex(&fidp->mx); } } + else if (infoLevel == SMB_SET_FILE_ALLOCATION_INFO) { + LARGE_INTEGER size = *((LARGE_INTEGER *)(p->datap)); + cm_attr_t attr; + + attr.mask = CM_ATTRMASK_LENGTH; + attr.length.LowPart = size.LowPart; + attr.length.HighPart = size.HighPart; + code = cm_SetAttr(scp, &attr, userp, &req); + } + else if (infoLevel == SMB_SET_FILE_END_OF_FILE_INFO) { + unsigned short size = *((unsigned short *)(p->datap)); + cm_attr_t attr; + + attr.mask = CM_ATTRMASK_LENGTH; + attr.length.HighPart = 0; + attr.length.LowPart = size; + code = cm_SetAttr(scp, &attr, userp, &req); + } done: cm_ReleaseSCache(scp); cm_ReleaseUser(userp); smb_ReleaseFID(fidp); if (code == 0) ! smb_SendTran2Packet(vcp, outp, opx); else ! smb_SendTran2Error(vcp, p, opx, code); smb_FreeTran2Packet(outp); return 0; *************** *** 3393,3399 **** /* Plug in fake timestamps. A time stamp of 0 causes 'invalid parameter' errors in the client. */ ! if (infoLevel >= 0x101) { /* 1969-12-31 23:59:59 +00 */ ft.dwHighDateTime = 0x19DB200; ft.dwLowDateTime = 0x5BB78980; --- 3655,3661 ---- /* Plug in fake timestamps. A time stamp of 0 causes 'invalid parameter' errors in the client. */ ! if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) { /* 1969-12-31 23:59:59 +00 */ ft.dwHighDateTime = 0x19DB200; ft.dwLowDateTime = 0x5BB78980; *************** *** 3483,3489 **** dptr = patchp->dptr; ! if (infoLevel >= 0x101) { /* get filetime */ smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); --- 3745,3751 ---- dptr = patchp->dptr; ! if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) { /* get filetime */ smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); *************** *** 3912,3917 **** --- 4174,4180 ---- int fileType; cm_fid_t fid; cm_req_t req; + char * s; cm_InitReq(&req); *************** *** 3956,3969 **** starPattern = 1; /* assume, since required a Find Next */ } osi_Log4(smb_logp, ! "T2 search dir attr 0x%x, info level %d, max count %d, flags 0x%x", attribute, infoLevel, maxCount, searchFlags); osi_Log3(smb_logp, "...T2 search op %d, id %d, nextCookie 0x%x", p->opcode, dsp->cookie, nextCookie); ! if (infoLevel >= 0x101) searchFlags &= ~4; /* no resume keys */ dirListPatchesp = NULL; --- 4219,4260 ---- starPattern = 1; /* assume, since required a Find Next */ } + switch ( infoLevel ) { + case SMB_INFO_STANDARD: + s = "InfoStandard"; + break; + case SMB_INFO_QUERY_EA_SIZE: + s = "InfoQueryEaSize"; + break; + case SMB_INFO_QUERY_EAS_FROM_LIST: + s = "InfoQueryEasFromList"; + break; + case SMB_FIND_FILE_DIRECTORY_INFO: + s = "FindFileDirectoryInfo"; + break; + case SMB_FIND_FILE_FULL_DIRECTORY_INFO: + s = "FindFileFullDirectoryInfo"; + break; + case SMB_FIND_FILE_NAMES_INFO: + s = "FindFileNamesInfo"; + break; + case SMB_FIND_FILE_BOTH_DIRECTORY_INFO: + s = "FindFileBothDirectoryInfo"; + break; + default: + s = "unknownInfoLevel"; + } + + osi_Log1(smb_logp, "T2 search dir info level: %s", s); + osi_Log4(smb_logp, ! "T2 search dir attr 0x%x, info level 0x%x, max count %d, flags 0x%x", attribute, infoLevel, maxCount, searchFlags); osi_Log3(smb_logp, "...T2 search op %d, id %d, nextCookie 0x%x", p->opcode, dsp->cookie, nextCookie); ! if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) searchFlags &= ~4; /* no resume keys */ dirListPatchesp = NULL; *************** *** 4267,4273 **** /* Need 8.3 name? */ NeedShortName = 0; ! if (infoLevel == SMB_QUERY_FILE_NAME_INFO && dep->fid.vnode != 0 && !cm_Is8Dot3(dep->name)) { cm_Gen8Dot3Name(dep, shortName, &shortNameEnd); --- 4558,4564 ---- /* Need 8.3 name? */ NeedShortName = 0; ! if (infoLevel == SMB_FIND_FILE_BOTH_DIRECTORY_INFO && dep->fid.vnode != 0 && !cm_Is8Dot3(dep->name)) { cm_Gen8Dot3Name(dep, shortName, &shortNameEnd); *************** *** 4316,4336 **** /* standard dir entry stuff */ if (infoLevel < 0x101) ohbytes = 23; /* pre-NT */ ! else if (infoLevel == SMB_QUERY_FILE_EA_INFO) ohbytes = 12; /* NT names only */ else ohbytes = 64; /* NT */ ! if (infoLevel == SMB_QUERY_FILE_NAME_INFO) ohbytes += 26; /* Short name & length */ if (searchFlags & 4) { ohbytes += 4; /* if resume key required */ } ! if (infoLevel != 1 ! && infoLevel != 0x101 ! && infoLevel != 0x103) ohbytes += 4; /* EASIZE */ /* add header to name & term. null */ --- 4607,4627 ---- /* standard dir entry stuff */ if (infoLevel < 0x101) ohbytes = 23; /* pre-NT */ ! else if (infoLevel == SMB_FIND_FILE_NAMES_INFO) ohbytes = 12; /* NT names only */ else ohbytes = 64; /* NT */ ! if (infoLevel == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) ohbytes += 26; /* Short name & length */ if (searchFlags & 4) { ohbytes += 4; /* if resume key required */ } ! if (infoLevel != SMB_INFO_STANDARD ! && infoLevel != SMB_FIND_FILE_DIRECTORY_INFO ! && infoLevel != SMB_FIND_FILE_NAMES_INFO) ohbytes += 4; /* EASIZE */ /* add header to name & term. null */ *************** *** 4342,4348 **** * about an * overflow when we pad things out below). * That's the reason for the alignment arithmetic below. */ ! if (infoLevel >= 0x101) align = (4 - (orbytes & 3)) & 3; else align = 0; --- 4633,4639 ---- * about an * overflow when we pad things out below). * That's the reason for the alignment arithmetic below. */ ! if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) align = (4 - (orbytes & 3)) & 3; else align = 0; *************** *** 4359,4367 **** /* First zero everything else */ memset(origOp, 0, ohbytes); ! if (infoLevel <= 0x101) *(origOp + ohbytes - 1) = (unsigned char) onbytes; ! else if (infoLevel == SMB_QUERY_FILE_EA_INFO) *((u_long *)(op + 8)) = onbytes; else *((u_long *)(op + 60)) = onbytes; --- 4650,4658 ---- /* First zero everything else */ memset(origOp, 0, ohbytes); ! if (infoLevel <= SMB_FIND_FILE_DIRECTORY_INFO) *(origOp + ohbytes - 1) = (unsigned char) onbytes; ! else if (infoLevel == SMB_FIND_FILE_NAMES_INFO) *((u_long *)(op + 8)) = onbytes; else *((u_long *)(op + 60)) = onbytes; *************** *** 4370,4376 **** CharToOem(origOp+ohbytes, origOp+ohbytes); /* Short name if requested and needed */ ! if (infoLevel == SMB_QUERY_FILE_NAME_INFO) { if (NeedShortName) { strcpy(op + 70, shortName); if (smb_StoreAnsiFilenames) --- 4661,4667 ---- CharToOem(origOp+ohbytes, origOp+ohbytes); /* Short name if requested and needed */ ! if (infoLevel == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { if (NeedShortName) { strcpy(op + 70, shortName); if (smb_StoreAnsiFilenames) *************** *** 4383,4389 **** returnedNames++; /* NextEntryOffset and FileIndex */ ! if (infoLevel >= 101) { int entryOffset = orbytes + align; *((u_long *)op) = entryOffset; *((u_long *)(op+4)) = nextEntryCookie; --- 4674,4680 ---- returnedNames++; /* NextEntryOffset and FileIndex */ ! if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) { int entryOffset = orbytes + align; *((u_long *)op) = entryOffset; *((u_long *)(op+4)) = nextEntryCookie; *************** *** 4402,4413 **** * later. The replay will happen at a time when it is * safe to unlock the directory. */ ! if (infoLevel != 0x103) { curPatchp = malloc(sizeof(*curPatchp)); osi_QAdd((osi_queue_t **) &dirListPatchesp, &curPatchp->q); curPatchp->dptr = op; ! if (infoLevel >= 0x101) curPatchp->dptr += 8; if (smb_hideDotFiles && smb_IsDotFile(dep->name)) { --- 4693,4704 ---- * later. The replay will happen at a time when it is * safe to unlock the directory. */ ! if (infoLevel != SMB_FIND_FILE_NAMES_INFO) { curPatchp = malloc(sizeof(*curPatchp)); osi_QAdd((osi_queue_t **) &dirListPatchesp, &curPatchp->q); curPatchp->dptr = op; ! if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) curPatchp->dptr += 8; if (smb_hideDotFiles && smb_IsDotFile(dep->name)) { *************** *** 4603,4609 **** /* compute initial mode bits based on read-only flag in attributes */ initialModeBits = 0666; ! if (attributes & 1) initialModeBits &= ~0222; pathp = smb_GetSMBData(inp, NULL); if (smb_StoreAnsiFilenames) --- 4894,4901 ---- /* compute initial mode bits based on read-only flag in attributes */ initialModeBits = 0666; ! if (attributes & SMB_ATTR_READONLY) ! initialModeBits &= ~0222; pathp = smb_GetSMBData(inp, NULL); if (smb_StoreAnsiFilenames) *************** *** 6437,6443 **** * extended attributes */ initialModeBits = 0666; ! if (extAttributes & 1) initialModeBits &= ~0222; pathp = parmp + (13 * sizeof(ULONG)) + sizeof(UCHAR); --- 6729,6735 ---- * extended attributes */ initialModeBits = 0666; ! if (extAttributes & SMB_ATTR_READONLY) initialModeBits &= ~0222; pathp = parmp + (13 * sizeof(ULONG)) + sizeof(UCHAR); Index: openafs/src/WINNT/afsd/smb3.h diff -c openafs/src/WINNT/afsd/smb3.h:1.12.2.1 openafs/src/WINNT/afsd/smb3.h:1.12.2.3 *** openafs/src/WINNT/afsd/smb3.h:1.12.2.1 Sat Jun 24 16:41:55 2006 --- openafs/src/WINNT/afsd/smb3.h Fri Jul 28 09:38:14 2006 *************** *** 52,71 **** } allocInfo; #pragma pack(pop) struct { ! unsigned long vsn; /* volume serial number */ ! char vnCount; /* count of chars in label, incl null */ ! char label[12]; /* pad out with nulls */ } volumeInfo; struct { ! FILETIME vct; /* volume creation time */ unsigned long vsn; /* volume serial number */ unsigned long vnCount; /* length of volume label in bytes */ char res[2]; /* reserved */ char label[10]; /* volume label */ } FSvolumeInfo; struct { ! osi_hyper_t totalAllocUnits; /* on the disk */ ! osi_hyper_t availAllocUnits; /* free blocks */ unsigned long sectorsPerAllocUnit; unsigned long bytesPerSector; /* bytes per sector */ } FSsizeInfo; --- 52,71 ---- } allocInfo; #pragma pack(pop) struct { ! unsigned long vsn; /* volume serial number */ ! char vnCount; /* count of chars in label, incl null */ ! char label[12]; /* pad out with nulls */ } volumeInfo; struct { ! FILETIME vct; /* volume creation time */ unsigned long vsn; /* volume serial number */ unsigned long vnCount; /* length of volume label in bytes */ char res[2]; /* reserved */ char label[10]; /* volume label */ } FSvolumeInfo; struct { ! LARGE_INTEGER totalAllocUnits; /* on the disk */ ! LARGE_INTEGER availAllocUnits; /* free blocks */ unsigned long sectorsPerAllocUnit; unsigned long bytesPerSector; /* bytes per sector */ } FSsizeInfo; *************** *** 82,87 **** --- 82,211 ---- } u; } smb_tran2QFSInfo_t; + typedef struct { + union { + struct { + unsigned long creationDateTime; /* SMB_DATE / SMB_TIME */ + unsigned long lastAccessDateTime; /* SMB_DATE / SMB_TIME */ + unsigned long lastWriteDateTime; /* SMB_DATE / SMB_TIME */ + unsigned long dataSize; + unsigned long allocationSize; + unsigned short attributes; + unsigned long eaSize; + } QPstandardInfo; + struct { + unsigned long creationDateTime; /* SMB_DATE / SMB_TIME */ + unsigned long lastAccessDateTime; /* SMB_DATE / SMB_TIME */ + unsigned long lastWriteDateTime; /* SMB_DATE / SMB_TIME */ + unsigned long dataSize; + unsigned long allocationSize; + unsigned short attributes; + unsigned long eaSize; + } QPeaSizeInfo; + struct { + unsigned short maxDataCount; + unsigned short eaErrorOffset; + unsigned long listLength; + unsigned char eaList[128]; + } QPeasFromListInfo; + struct { + unsigned short maxDataCount; + unsigned short eaErrorOffset; + unsigned long listLength; + unsigned char eaList[128]; + } QPallEasInfo; + struct { + FILETIME creationTime; + FILETIME lastAccessTime; + FILETIME lastWriteTime; + FILETIME changeTime; + unsigned long attributes; + unsigned long reserved; + } QPfileBasicInfo; + struct { + LARGE_INTEGER allocationSize; + LARGE_INTEGER endOfFile; + unsigned long numberOfLinks; + unsigned char deletePending; + unsigned char directory; + unsigned short reserved; + } QPfileStandardInfo; + struct { + unsigned long eaSize; + } QPfileEaInfo; + struct { + unsigned long fileNameLength; + unsigned char fileName[512]; + } QPfileNameInfo; + struct { + FILETIME creationTime; + FILETIME lastAccessTime; + FILETIME lastWriteTime; + FILETIME changeTime; + unsigned long attributes; + LARGE_INTEGER allocationSize; + LARGE_INTEGER endOfFile; + unsigned long numberOfLinks; + unsigned char deletePending; + unsigned char directory; + LARGE_INTEGER indexNumber; + unsigned long eaSize; + unsigned long accessFlags; + LARGE_INTEGER indexNumber2; + LARGE_INTEGER currentByteOffset; + unsigned long mode; + unsigned long alignmentRequirement; + unsigned long fileNameLength; + unsigned char fileName[512]; + } QPfileAllInfo; + struct { + unsigned long fileNameLength; + unsigned char fileName[512]; + } QPfileAltNameInfo; + struct { + unsigned long nextEntryOffset; + unsigned long streamNameLength; + LARGE_INTEGER streamSize; + LARGE_INTEGER streamAllocationSize; + unsigned char fileName[512]; + } QPfileStreamInfo; + struct { + LARGE_INTEGER compressedFileSize; + unsigned short compressionFormat; + unsigned char compressionUnitShift; + unsigned char chuckShift; + unsigned char clusterShift; + unsigned char reserved[3]; + } QPfileCompressionInfo; + } u; + } smb_tran2QPathInfo_t; + + typedef struct { + union { + struct { + FILETIME creationTime; + FILETIME lastAccessTime; + FILETIME lastWriteTime; + FILETIME lastChangeTime; + unsigned long attributes; + } QFbasicInfo; + struct { + LARGE_INTEGER allocationSize; + LARGE_INTEGER endOfFile; + unsigned long numberOfLinks; + unsigned char deletePending; + unsigned char directory; + } QFstandardInfo; + struct { + unsigned long eaSize; + } QFeaInfo; + struct { + unsigned long fileNameLength; + unsigned char fileName[512]; + } QFfileNameInfo; + } u; + } smb_tran2QFileInfo_t; + /* more than enough opcodes for today, anyway */ #define SMB_TRAN2_NOPCODES 20 *************** *** 125,130 **** --- 249,257 ---- extern long smb_ReceiveTran2SetFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp); + extern long smb_ReceiveTran2QFSInfoFid(smb_vc_t *vcp, smb_tran2Packet_t *p, + smb_packet_t *outp); + extern long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp); Index: openafs/src/WINNT/afsd/smb_iocons.h diff -c openafs/src/WINNT/afsd/smb_iocons.h:1.10.4.1 openafs/src/WINNT/afsd/smb_iocons.h:1.10.4.2 *** openafs/src/WINNT/afsd/smb_iocons.h:1.10.4.1 Tue Jun 27 18:19:35 2006 --- openafs/src/WINNT/afsd/smb_iocons.h Thu Jul 20 17:46:19 2006 *************** *** 43,49 **** #define CM_IOCTLCACHEPARMS 16 typedef struct cm_cacheParms { ! long parms[CM_IOCTLCACHEPARMS]; } cm_cacheParms_t; /* set cell flags */ --- 43,49 ---- #define CM_IOCTLCACHEPARMS 16 typedef struct cm_cacheParms { ! afs_uint64 parms[CM_IOCTLCACHEPARMS]; } cm_cacheParms_t; /* set cell flags */ Index: openafs/src/WINNT/afsd/smb_ioctl.c diff -c openafs/src/WINNT/afsd/smb_ioctl.c:1.25.2.2 openafs/src/WINNT/afsd/smb_ioctl.c:1.25.2.3 *** openafs/src/WINNT/afsd/smb_ioctl.c:1.25.2.2 Tue Jun 27 18:19:35 2006 --- openafs/src/WINNT/afsd/smb_ioctl.c Thu Jul 20 17:46:19 2006 *************** *** 138,148 **** return CM_ERROR_TOOBIG; /* check for no such proc */ ! if (fidp->flags & SMB_FID_IOCTL) ! procp = smb_ioctlProcsp[opcode]; ! else ! procp = NULL; ! if (procp == NULL) return CM_ERROR_BADOP; --- 138,144 ---- return CM_ERROR_TOOBIG; /* check for no such proc */ ! procp = smb_ioctlProcsp[opcode]; if (procp == NULL) return CM_ERROR_BADOP; Index: openafs/src/WINNT/afsrdr/afsrdr.c diff -c openafs/src/WINNT/afsrdr/afsrdr.c:1.3 openafs/src/WINNT/afsrdr/afsrdr.c:1.3.4.2 *** openafs/src/WINNT/afsrdr/afsrdr.c:1.3 Thu Aug 4 12:32:39 2005 --- openafs/src/WINNT/afsrdr/afsrdr.c Thu Jul 20 17:46:21 2006 *************** *** 298,304 **** } StringCbCatN(str, len, IrpSp->FileObject->FileName.Buffer, IrpSp->FileObject->FileName.Length); ! /* request to open heirarchical parent of specified path */ /* remove last path component */ if (IrpSp->Flags & SL_OPEN_TARGET_DIRECTORY) { --- 298,304 ---- } StringCbCatN(str, len, IrpSp->FileObject->FileName.Buffer, IrpSp->FileObject->FileName.Length); ! /* request to open hierarchical parent of specified path */ /* remove last path component */ if (IrpSp->Flags & SL_OPEN_TARGET_DIRECTORY) { *************** *** 1655,1660 **** --- 1655,1661 ---- SYNC_FAIL(STATUS_UNSUCCESSFUL); } + long dc_break_callback(ULONG fid) { afs_fcb_t *fcb; *************** *** 1699,1707 **** return 0; } ! dc_release_hooks() { KeSetEvent(&comExt->cancelEvent, 0, FALSE); } /********************************************************** --- 1700,1710 ---- return 0; } ! long ! dc_release_hooks(void) { KeSetEvent(&comExt->cancelEvent, 0, FALSE); + return 0; } /********************************************************** Index: openafs/src/WINNT/afsrdr/ifs_rpc.c diff -c openafs/src/WINNT/afsrdr/ifs_rpc.c:1.3 openafs/src/WINNT/afsrdr/ifs_rpc.c:1.3.4.2 *** openafs/src/WINNT/afsrdr/ifs_rpc.c:1.3 Thu Aug 4 12:32:39 2005 --- openafs/src/WINNT/afsrdr/ifs_rpc.c Thu Jul 20 17:46:21 2006 *************** *** 241,247 **** { ULONG size; rpc_t *rpc; - ULONG status; size = sizeof(rpc_t) + 2*RPC_BUF_SIZE; rpc = malloc(size); --- 241,246 ---- *************** *** 268,277 **** rpc_transact(rpc_t *rpc) { - HANDLE hf; - int ret; ULONG header_len; ! DWORD err, read = 0; if (!rpc) return IFSL_GENERIC_FAILURE; --- 267,274 ---- rpc_transact(rpc_t *rpc) { ULONG header_len; ! DWORD read = 0; if (!rpc) return IFSL_GENERIC_FAILURE; *************** *** 286,291 **** --- 283,289 ---- /* upcall stubs */ #ifdef RPC_KERN + long uc_namei(WCHAR *name, ULONG *fid) { rpc_t *rpc; *************** *** 317,322 **** --- 315,321 ---- return status; } + long uc_check_access(ULONG fid, ULONG access, ULONG *granted) { rpc_t *rpc; *************** *** 345,350 **** --- 344,350 ---- return status; } + long uc_create(WCHAR *name, ULONG attribs, LARGE_INTEGER alloc, ULONG access, ULONG *granted, ULONG *fid) { rpc_t *rpc; *************** *** 375,380 **** --- 375,381 ---- return status; } + long uc_stat(ULONG fid, ULONG *attribs, LARGE_INTEGER *size, LARGE_INTEGER *creation, LARGE_INTEGER *access, LARGE_INTEGER *change, LARGE_INTEGER *written) { rpc_t *rpc; *************** *** 407,412 **** --- 408,414 ---- return status; } + long uc_setinfo(ULONG fid, ULONG attribs, LARGE_INTEGER creation, LARGE_INTEGER access, LARGE_INTEGER change, LARGE_INTEGER written) { rpc_t *rpc; *************** *** 439,444 **** --- 441,447 ---- return status; } + long uc_trunc(ULONG fid, LARGE_INTEGER size) { rpc_t *rpc; *************** *** 466,471 **** --- 469,475 ---- return status; } + long uc_read(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *read, char *data) { rpc_t *rpc; *************** *** 495,500 **** --- 499,505 ---- return status; } + long uc_write(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *written, char *data) { rpc_t *rpc; *************** *** 524,529 **** --- 529,535 ---- return status; } + long uc_readdir(ULONG fid, LARGE_INTEGER cookie_in, WCHAR *filter, ULONG *count, char *data, ULONG *len) { rpc_t *rpc; *************** *** 555,560 **** --- 561,567 ---- return status; } + long uc_close(ULONG fid) { rpc_t *rpc; *************** *** 581,586 **** --- 588,594 ---- return status; } + long uc_unlink(WCHAR *name) { rpc_t *rpc; *************** *** 607,612 **** --- 615,621 ---- return status; } + long uc_ioctl_write(ULONG length, char *data, ULONG *key) { rpc_t *rpc; *************** *** 634,639 **** --- 643,649 ---- return status; } + long uc_ioctl_read(ULONG key, ULONG *length, char *data) { rpc_t *rpc; *************** *** 661,666 **** --- 671,677 ---- return status; } + long uc_rename(ULONG fid, WCHAR *curr, WCHAR *new_dir, WCHAR *new_name, ULONG *new_fid) { rpc_t *rpc; *************** *** 691,696 **** --- 702,708 ---- return status; } + long uc_flush(ULONG fid) { rpc_t *rpc; *************** *** 721,727 **** /* downcall stubs */ #ifndef RPC_KERN ! dc_break_callback(ULONG fid) { rpc_t *rpc; ULONG status; --- 733,739 ---- /* downcall stubs */ #ifndef RPC_KERN ! long dc_break_callback(ULONG fid) { rpc_t *rpc; ULONG status; *************** *** 742,748 **** return status; } ! dc_release_hooks() { rpc_t *rpc; ULONG status; --- 754,760 ---- return status; } ! long dc_release_hooks(void) { rpc_t *rpc; ULONG status; *************** *** 1225,1231 **** break; case RPC_UNLINK: { - ULONG fid, unlink; rpc_unmarshal_wstr(rpc, name); status = uc_unlink(name); rpc_marshal_long(rpc, status); --- 1237,1242 ---- Index: openafs/src/WINNT/afsrdr/ifs_rpc.h diff -c openafs/src/WINNT/afsrdr/ifs_rpc.h:1.3 openafs/src/WINNT/afsrdr/ifs_rpc.h:1.3.4.1 *** openafs/src/WINNT/afsrdr/ifs_rpc.h:1.3 Thu Aug 4 12:32:39 2005 --- openafs/src/WINNT/afsrdr/ifs_rpc.h Thu Jul 2