From d9c409437d443a95ddefede0db91f7639de5e183 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 13 Dec 2004 14:03:55 +0000 Subject: [PATCH] windows-smb-and-symlinks-20041213 Fix bug in automatic symlink generation for freelance root.afs. do not create symlinks if cell resolution fails Update SMB files to use preprocessor symbols for InfoLevel constants. --- src/WINNT/afsd/cm_vnodeops.c | 11 +-- src/WINNT/afsd/smb.c | 14 ++-- src/WINNT/afsd/smb.h | 82 ++++++++++++++++------ src/WINNT/afsd/smb3.c | 129 +++++++++++++++++++++++------------ src/WINNT/afsd/smb3.h | 74 ++++++++++---------- 5 files changed, 198 insertions(+), 112 deletions(-) diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 9267a2a31..b936b444c 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -1021,12 +1021,13 @@ long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, cm_user_t *us code = cm_FreelanceAddMount(namep, &fullname[1], "root.cell.", 1, &rock.fid); } } else { - if (cm_GetCell_Gen(namep, fullname, CM_FLAG_CREATE)) + if (cm_GetCell_Gen(namep, fullname, CM_FLAG_CREATE)) { found = 1; - if ( stricmp(namep, fullname) ) - code = cm_FreelanceAddSymlink(namep, fullname, &rock.fid); - else - code = cm_FreelanceAddMount(namep, fullname, "root.cell.", 0, &rock.fid); + if ( stricmp(namep, fullname) ) + code = cm_FreelanceAddSymlink(namep, fullname, &rock.fid); + else + code = cm_FreelanceAddMount(namep, fullname, "root.cell.", 0, &rock.fid); + } } if (!found || code < 0) { /* add mount point failed, so give up */ if (flags & CM_FLAG_CHECKPATH) diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index 093ef0289..573b9745c 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -2118,7 +2118,7 @@ void smb_FormatResponsePacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *op op->inCom = inSmbp->com; } outp->reb = 0x80; /* SERVER_RESP */ - outp->flg2 = 0x1; /* KNOWS_LONG_NAMES */ + outp->flg2 = SMB_FLAGS2_KNOWS_LONG_NAMES; /* copy fields in generic packet area */ op->wctp = &outp->wct; @@ -2764,8 +2764,12 @@ long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) * 32-bit error codes * * and NT Find * * and NT SMB's * - * and raw mode */ + * and raw mode + * and DFS */ caps = NTNEGOTIATE_CAPABILITY_NTSTATUS | +#ifdef DFS_SUPPORT + NTNEGOTIATE_CAPABILITY_DFS | +#endif NTNEGOTIATE_CAPABILITY_NTFIND | NTNEGOTIATE_CAPABILITY_RAWMODE | NTNEGOTIATE_CAPABILITY_NTSMB; @@ -3372,7 +3376,7 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou /* We can handle long names */ if (vcp->flags & SMB_VCFLAG_USENT) - ((smb_t *)outp)->flg2 |= 0x40; /* IS_LONG_NAME */ + ((smb_t *)outp)->flg2 |= SMB_FLAGS2_IS_LONG_NAME; /* make sure we got a whole search status */ if (dataLength < 21) { @@ -3738,7 +3742,7 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou CharToOem(op, op); /* Uppercase if requested by client */ - if ((((smb_t *)inp)->flg2 & 1) == 0) + if ((((smb_t *)inp)->flg2 & SMB_FLAGS2_KNOWS_LONG_NAMES) == 0) _strupr(op); op += 13; @@ -6382,7 +6386,7 @@ void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, smbp->reh = (unsigned char) ((NTStatus >> 8) & 0xff); smbp->errLow = (unsigned char) ((NTStatus >> 16) & 0xff); smbp->errHigh = (unsigned char) ((NTStatus >> 24) & 0xff); - smbp->flg2 |= 0x4000; + smbp->flg2 |= SMB_FLAGS2_ERR_STATUS; break; } else { diff --git a/src/WINNT/afsd/smb.h b/src/WINNT/afsd/smb.h index 81ec7b155..4774e397b 100644 --- a/src/WINNT/afsd/smb.h +++ b/src/WINNT/afsd/smb.h @@ -35,6 +35,41 @@ typedef struct smb { unsigned char vdata[1]; } smb_t; +/* flg2 values */ + +#define SMB_FLAGS2_KNOWS_LONG_NAMES 0x0001 +#define SMB_FLAGS2_KNOWS_EAS 0x0002 +#define SMB_FLAGS2_SECURITY_SIGNATURE 0x0004 +#define SMB_FLAGS2_RESERVED1 0x0008 +#define SMB_FLAGS2_IS_LONG_NAME 0x0040 +#define SMB_FLAGS2_EXT_SEC 0x0800 +#define SMB_FLAGS2_DFS 0x1000 +#define SMB_FLAGS2_PAGING_IO 0x2000 +#define SMB_FLAGS2_ERR_STATUS 0x4000 +#define SMB_FLAGS2_UNICODE 0x8000 + +/* Information Levels */ +#define SMB_INFO_STANDARD 1 +#define SMB_INFO_QUERY_EA_SIZE 2 +#define SMB_INFO_QUERY_EAS_FROM_LIST 3 +#define SMB_INFO_QUERY_ALL_EAS 4 +#define SMB_INFO_IS_NAME_VALID 6 + +#define SMB_QUERY_FILE_BASIC_INFO 0x101 +#define SMB_QUERY_FILE_STANDARD_INFO 0x102 +#define SMB_QUERY_FILE_EA_INFO 0x103 +#define SMB_QUERY_FILE_NAME_INFO 0x104 +#define SMB_QUERY_FILE_ALL_INFO 0x107 +#define SMB_QUERY_FILE_ALT_NAME_INFO 0x108 +#define SMB_QUERY_FILE_STREAM_INFO 0x109 +#define SMB_QUERY_FILE_COMPRESSION_INFO 0x10B +#define SMB_QUERY_FILE_UNIX_BASIC 0x200 +#define SMB_QUERY_FILE_UNIX_LINK 0x201 + +#define SMB_SET_FILE_UNIX_BASIC 0x200 +#define SMB_SET_FILE_UNIX_LINK 0x201 +#define SMB_SET_FILE_UNIX_HLINK 0x203 + /* more defines */ #define SMB_NOPCODES 256 /* # of opcodes in the dispatch table */ @@ -59,20 +94,20 @@ typedef struct smb { #define NEGOTIATE_SECURITY_SIGNATURES_REQUIRED 0x08 /* Capabilities */ -#define NTNEGOTIATE_CAPABILITY_RAWMODE 0x00000001L -#define NTNEGOTIATE_CAPABILITY_MPXMODE 0x00000002L -#define NTNEGOTIATE_CAPABILITY_UNICODE 0x00000004L -#define NTNEGOTIATE_CAPABILITY_LARGEFILES 0x00000008L -#define NTNEGOTIATE_CAPABILITY_NTSMB 0x00000010L -#define NTNEGOTIATE_CAPABILITY_RPCAPI 0x00000020L -#define NTNEGOTIATE_CAPABILITY_NTSTATUS 0x00000040L -#define NTNEGOTIATE_CAPABILITY_LEVEL_II_OPLOCKS 0x00000080L +#define NTNEGOTIATE_CAPABILITY_RAWMODE 0x00000001L +#define NTNEGOTIATE_CAPABILITY_MPXMODE 0x00000002L +#define NTNEGOTIATE_CAPABILITY_UNICODE 0x00000004L +#define NTNEGOTIATE_CAPABILITY_LARGEFILES 0x00000008L +#define NTNEGOTIATE_CAPABILITY_NTSMB 0x00000010L +#define NTNEGOTIATE_CAPABILITY_RPCAPI 0x00000020L +#define NTNEGOTIATE_CAPABILITY_NTSTATUS 0x00000040L +#define NTNEGOTIATE_CAPABILITY_LEVEL_II_OPLOCKS 0x00000080L #define NTNEGOTIATE_CAPABILITY_LOCK_AND_READ 0x00000100L -#define NTNEGOTIATE_CAPABILITY_NTFIND 0x00000200L -#define NTNEGOTIATE_CAPABILITY_DFS 0x00001000L +#define NTNEGOTIATE_CAPABILITY_NTFIND 0x00000200L +#define NTNEGOTIATE_CAPABILITY_DFS 0x00001000L #define NTNEGOTIATE_CAPABILITY_NT_INFO_PASSTHRU 0x00002000L #define NTNEGOTIATE_CAPABILITY_BULK_TRANSFER 0x20000000L -#define NTNEGOTIATE_CAPABILITY_COMPRESSED 0x40000000L +#define NTNEGOTIATE_CAPABILITY_COMPRESSED 0x40000000L #define NTNEGOTIATE_CAPABILITY_EXTENDED_SECURITY 0x80000000L /* a packet structure for receiving SMB messages; locked by smb_globalLock. @@ -296,16 +331,23 @@ typedef struct smb_fid { #define SMB_FID_NTOPEN 0x100 /* have dscp and pathp */ /* - * SMB file attributes + * SMB file attributes (32-bit) */ -#define SMB_ATTR_ARCHIVE 0x20 -#define SMB_ATTR_COMPRESSED 0x800 /* file or dir is compressed */ -#define SMB_ATTR_NORMAL 0x80 /* normal file. Only valid if used alone */ -#define SMB_ATTR_HIDDEN 0x2 /* hidden file for the purpose of dir listings */ -#define SMB_ATTR_READONLY 0x1 -#define SMB_ATTR_TEMPORARY 0x100 -#define SMB_ATTR_DIRECTORY 0x10 -#define SMB_ATTR_SYSTEM 0x4 +#define SMB_ATTR_READONLY 0x0001 +#define SMB_ATTR_HIDDEN 0x0002 /* hidden file for the purpose of dir listings */ +#define SMB_ATTR_SYSTEM 0x0004 +#define SMB_ATTR_VOLUMEID 0x0008 /* obsolete */ +#define SMB_ATTR_DIRECTORY 0x0010 +#define SMB_ATTR_ARCHIVE 0x0020 +#define SMB_ATTR_DEVICE 0x0040 +#define SMB_ATTR_NORMAL 0x0080 /* normal file. Only valid if used alone */ +#define SMB_ATTR_TEMPORARY 0x0100 +#define SMB_ATTR_SPARSE_FILE 0x0200 +#define SMB_ATTR_REPARSE_POINT 0x0400 +#define SMB_ATTR_COMPRESSED 0x0800 /* file or dir is compressed */ +#define SMB_ATTR_OFFLINE 0x1000 +#define SMB_ATTR_NOT_CONTENT_INDEXED 0x2000 +#define SMB_ATTR_ENCRYPTED 0x4000 /* for tracking in-progress directory searches */ typedef struct smb_dirSearch { diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index 4bf92a663..9266d3773 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -914,6 +914,7 @@ long smb_ReceiveV3UserLogoffX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou } #define SMB_SUPPORT_SEARCH_BITS 0x0001 +#define SMB_SHARE_IS_IN_DFS 0x0002 long smb_ReceiveV3TreeConnectX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { @@ -967,7 +968,7 @@ long smb_ReceiveV3TreeConnectX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *o tidp = smb_FindTID(vcp, newTid, SMB_FLAG_CREATE); - if(!ipc) { + if (!ipc) { uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0); shareFound = smb_FindShare(vcp, uidp, shareName, &sharePath); if (uidp) @@ -980,7 +981,11 @@ long smb_ReceiveV3TreeConnectX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *o if (vcp->flags & SMB_VCFLAG_USENT) { int policy = smb_FindShareCSCPolicy(shareName); - smb_SetSMBParm(outp, 2, SMB_SUPPORT_SEARCH_BITS | (policy << 2)); + smb_SetSMBParm(outp, 2, SMB_SUPPORT_SEARCH_BITS | +#ifdef DFS_SUPPORT + SMB_SHARE_IS_IN_DFS | +#endif + (policy << 2)); } } else { smb_SetSMBParm(outp, 2, 0); @@ -990,7 +995,8 @@ long smb_ReceiveV3TreeConnectX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *o lock_ObtainMutex(&tidp->mx); tidp->userp = userp; tidp->pathname = sharePath; - if(ipc) tidp->flags |= SMB_TIDFLAG_IPC; + if (ipc) + tidp->flags |= SMB_TIDFLAG_IPC; lock_ReleaseMutex(&tidp->mx); smb_ReleaseTID(tidp); @@ -998,6 +1004,7 @@ long smb_ReceiveV3TreeConnectX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *o ((smb_t *)inp)->tid = newTid; tp = smb_GetSMBData(outp, NULL); if (!ipc) { + /* XXX - why is this a drive letter? - jaltman */ *tp++ = 'A'; *tp++ = ':'; *tp++ = 0; @@ -1135,7 +1142,7 @@ void smb_SendTran2Error(smb_vc_t *vcp, smb_tran2Packet_t *t2p, /* We can handle long names */ if (vcp->flags & SMB_VCFLAG_USENT) - smbp->flg2 |= 0x40; /* IS_LONG_NAME */ + smbp->flg2 |= SMB_FLAGS2_IS_LONG_NAME; /* now copy important fields from the tran 2 packet */ smbp->com = t2p->com; @@ -1149,7 +1156,7 @@ void smb_SendTran2Error(smb_vc_t *vcp, smb_tran2Packet_t *t2p, smbp->reh = (unsigned char) ((NTStatus >> 8) & 0xff); smbp->errLow = (unsigned char) ((NTStatus >> 16) & 0xff); smbp->errHigh = (unsigned char) ((NTStatus >> 24) & 0xff); - smbp->flg2 |= 0x4000; + smbp->flg2 |= SMB_FLAGS2_ERR_STATUS; } else { smbp->rcls = errClass; @@ -1175,7 +1182,7 @@ void smb_SendTran2Packet(smb_vc_t *vcp, smb_tran2Packet_t *t2p, smb_packet_t *tp /* We can handle long names */ if (vcp->flags & SMB_VCFLAG_USENT) - smbp->flg2 |= 0x40; /* IS_LONG_NAME */ + smbp->flg2 |= SMB_FLAGS2_IS_LONG_NAME; /* now copy important fields from the tran 2 packet */ smbp->com = t2p->com; @@ -1600,9 +1607,9 @@ long smb_ReceiveRAPNetShareGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_pack if (infoLevel == 0) totalData = sizeof(smb_rap_share_info_0_t); - else if(infoLevel == 1) + else if(infoLevel == SMB_INFO_STANDARD) totalData = sizeof(smb_rap_share_info_1_t) + 1; /* + empty string */ - else if(infoLevel == 2) + else if(infoLevel == SMB_INFO_QUERY_EA_SIZE) totalData = sizeof(smb_rap_share_info_2_t) + 2; /* + two empty strings */ else return CM_ERROR_INVAL; @@ -1652,7 +1659,7 @@ long smb_ReceiveRAPNetShareGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_pack smb_rap_share_info_0_t * info = (smb_rap_share_info_0_t *) outp->datap; strncpy(info->shi0_netname, shareName, sizeof(info->shi0_netname)-1); info->shi0_netname[sizeof(info->shi0_netname)-1] = 0; - } else if(infoLevel == 1) { + } else if(infoLevel == SMB_INFO_STANDARD) { smb_rap_share_info_1_t * info = (smb_rap_share_info_1_t *) outp->datap; strncpy(info->shi1_netname, shareName, sizeof(info->shi1_netname)-1); info->shi1_netname[sizeof(info->shi1_netname)-1] = 0; @@ -1826,7 +1833,7 @@ long smb_ReceiveRAPNetServerGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_pac info0 = (smb_rap_server_info_0_t *) outp->datap; cstrp = (char *) (info0 + 1); strcpy(info0->sv0_name, "AFS"); - } else { /* infoLevel == 1 */ + } else { /* infoLevel == SMB_INFO_STANDARD */ info1 = (smb_rap_server_info_1_t *) outp->datap; cstrp = (char *) (info1 + 1); strcpy(info1->sv1_name, "AFS"); @@ -2348,6 +2355,8 @@ long smb_ReceiveTran2QFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t * 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; } @@ -2520,13 +2529,20 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t cm_InitReq(&req); infoLevel = p->parmsp[0]; - if (infoLevel == 6) nbytesRequired = 0; - else if (infoLevel == 1) nbytesRequired = 22; - else if (infoLevel == 2) nbytesRequired = 26; - else if (infoLevel == 0x101) nbytesRequired = 40; - else if (infoLevel == 0x102) nbytesRequired = 24; - else if (infoLevel == 0x103) nbytesRequired = 4; - else if (infoLevel == 0x108) nbytesRequired = 30; + 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) + 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_ALT_NAME_INFO) + nbytesRequired = 30; else { osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", p->opcode, infoLevel); @@ -2548,7 +2564,7 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t * the syntax, so we just OK things now. In particular, we're *not* * being asked to verify anything about the state of any parent dirs. */ - if (infoLevel == 6) { + if (infoLevel == SMB_INFO_IS_NAME_VALID) { smb_SendTran2Packet(vcp, outp, opx); smb_FreeTran2Packet(outp); return 0; @@ -2583,7 +2599,7 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t * yet been evaluated and for directories that haven't yet been * fetched. */ - if (infoLevel == 0x101) { + if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) { spacep = cm_GetSpace(); smb_StripLastComponent(spacep->data, &lastComp, (char *)(&p->parmsp[3])); @@ -2659,7 +2675,7 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t goto done; } - if (infoLevel == 1 || infoLevel == 2) { + 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 */ @@ -2669,7 +2685,7 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t attributes = smb_Attributes(scp); *((u_short *)op) = attributes; op += 2; /* attributes */ } - else if (infoLevel == 0x101) { + 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 */ @@ -2679,7 +2695,7 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *((u_long *)op) = extAttributes; op += 4; /* extended attribs */ *((u_long *)op) = 0; op += 4; /* don't know what this is */ } - else if (infoLevel == 0x102) { + 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; @@ -2688,12 +2704,12 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op++ = (scp->fileType == CM_SCACHETYPE_DIRECTORY ? 1 : 0); *op++ = 0; } - else if (infoLevel == 0x103) { + else if (infoLevel == SMB_QUERY_FILE_EA_INFO) { memset(op, 0, 4); op += 4; /* EA size */ } /* now, if we are being asked about extended attrs, return a 0 size */ - if (infoLevel == 2) { + if (infoLevel == SMB_INFO_QUERY_EA_SIZE) { *((u_long *)op) = 0; op += 4; } @@ -2744,10 +2760,14 @@ long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t } infoLevel = p->parmsp[1]; - if (infoLevel == 0x101) nbytesRequired = 40; - else if (infoLevel == 0x102) nbytesRequired = 24; - else if (infoLevel == 0x103) nbytesRequired = 4; - else if (infoLevel == 0x104) nbytesRequired = 6; + 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); @@ -2783,7 +2803,7 @@ long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t * Marshall the output data. */ op = outp->datap; - if (infoLevel == 0x101) { + 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 */ @@ -2793,7 +2813,7 @@ long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *((u_long *)op) = attributes; op += 4; *((u_long *)op) = 0; op += 4; } - else if (infoLevel == 0x102) { + 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; @@ -2802,10 +2822,10 @@ long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op++ = 0; *op++ = 0; } - else if (infoLevel == 0x103) { + else if (infoLevel == SMB_QUERY_FILE_EA_INFO) { *((u_long *)op) = 0; op += 4; } - else if (infoLevel == 0x104) { + else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) { unsigned long len; char *name; @@ -2864,12 +2884,12 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet return 0; } - if (infoLevel == 0x102 && !(fidp->flags & SMB_FID_OPENDELETE)) { + if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO && !(fidp->flags & SMB_FID_OPENDELETE)) { smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS); smb_ReleaseFID(fidp); return 0; } - if ((infoLevel == 0x103 || infoLevel == 0x104) + if ((infoLevel == SMB_QUERY_FILE_EA_INFO || infoLevel == SMB_QUERY_FILE_NAME_INFO) && !(fidp->flags & SMB_FID_OPENWRITE)) { smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS); smb_ReleaseFID(fidp); @@ -2892,7 +2912,7 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet scp = fidp->scp; - if (infoLevel == 0x101) { + if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) { FILETIME lastMod; unsigned int attribute; cm_attr_t attr; @@ -2948,7 +2968,7 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet else code = 0; } - else if (infoLevel == 0x103 || infoLevel == 0x104) { + 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; @@ -2957,7 +2977,7 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet attr.length.HighPart = size.HighPart; code = cm_SetAttr(scp, &attr, userp, &req); } - else if (infoLevel == 0x102) { + else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) { if (*((char *)(p->datap))) { code = cm_CheckNTDelete(fidp->NTopen_dscp, scp, userp, &req); @@ -3027,6 +3047,16 @@ smb_ReceiveTran2SessionSetup(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t * long smb_ReceiveTran2GetDFSReferral(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { + /* This is a UNICODE only request (bit15 of Flags2) */ + /* The TID must be IPC$ */ + + /* The documentation for the Flags response field is contradictory */ + + /* Use Version 1 Referral Element Format */ + /* ServerType = 0; indicates the next server should be queried for the file */ + /* ReferralFlags = 0x01; PathConsumed characters should be stripped */ + /* Node = UnicodeString of UNC path of the next share name */ + osi_Log0(smb_logp,"ReceiveTran2GetDFSReferral - NOT_SUPPORTED"); return CM_ERROR_BADOP; } @@ -3034,6 +3064,15 @@ smb_ReceiveTran2GetDFSReferral(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t long smb_ReceiveTran2ReportDFSInconsistency(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { + /* This is a UNICODE only request (bit15 of Flags2) */ + + /* There is nothing we can do about this operation. The client is going to + * tell us that there is a Version 1 Referral Element for which there is a DFS Error. + * Unfortunately, there is really nothing we can do about it other then log it + * somewhere. Even then I don't think there is anything for us to do. + * So let's return an error value. + */ + osi_Log0(smb_logp,"ReceiveTran2ReportDFSInconsistency - NOT_SUPPORTED"); return CM_ERROR_BADOP; } @@ -3893,7 +3932,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t /* Need 8.3 name? */ NeedShortName = 0; - if (infoLevel == 0x104 + if (infoLevel == SMB_QUERY_FILE_NAME_INFO && dep->fid.vnode != 0 && !cm_Is8Dot3(dep->name)) { cm_Gen8Dot3Name(dep, shortName, &shortNameEnd); @@ -3933,12 +3972,12 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t /* standard dir entry stuff */ if (infoLevel < 0x101) ohbytes = 23; /* pre-NT */ - else if (infoLevel == 0x103) + else if (infoLevel == SMB_QUERY_FILE_EA_INFO) ohbytes = 12; /* NT names only */ else ohbytes = 64; /* NT */ - if (infoLevel == 0x104) + if (infoLevel == SMB_QUERY_FILE_NAME_INFO) ohbytes += 26; /* Short name & length */ if (searchFlags & 4) { @@ -3975,7 +4014,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t if (infoLevel <= 0x101) *(origOp + ohbytes - 1) = (unsigned char) onbytes; - else if (infoLevel == 0x103) + else if (infoLevel == SMB_QUERY_FILE_EA_INFO) *((u_long *)(op + 8)) = onbytes; else *((u_long *)(op + 60)) = onbytes; @@ -3984,7 +4023,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t CharToOem(origOp+ohbytes, origOp+ohbytes); /* Short name if requested and needed */ - if (infoLevel == 0x104) { + if (infoLevel == SMB_QUERY_FILE_NAME_INFO) { if (NeedShortName) { strcpy(op + 70, shortName); if (smb_StoreAnsiFilenames) @@ -6084,7 +6123,7 @@ long smb_ReceiveNTTransact(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* We can handle long names */ if (vcp->flags & SMB_VCFLAG_USENT) - ((smb_t *)outp)->flg2 |= 0x40; /* IS_LONG_NAME */ + ((smb_t *)outp)->flg2 |= SMB_FLAGS2_IS_LONG_NAME; switch (function) { case 6: @@ -6275,7 +6314,7 @@ void smb_NotifyChange(DWORD action, DWORD notifyFilter, ((smb_t *) watch)->errLow = 0; ((smb_t *) watch)->errHigh = 0; /* Set NT Status codes flag */ - ((smb_t *) watch)->flg2 |= 0x4000; + ((smb_t *) watch)->flg2 |= SMB_FLAGS2_ERR_STATUS; } smb_SendPacket(vcp, watch); @@ -6344,7 +6383,7 @@ long smb_ReceiveNTCancel(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) ((smb_t *)watch)->reh = 0x1; ((smb_t *)watch)->errLow = 0; ((smb_t *)watch)->errHigh = 0xC0; - ((smb_t *)watch)->flg2 |= 0x4000; + ((smb_t *)watch)->flg2 |= SMB_FLAGS2_ERR_STATUS; smb_SendPacket(vcp, watch); if (watch->vcp) smb_ReleaseVC(watch->vcp); diff --git a/src/WINNT/afsd/smb3.h b/src/WINNT/afsd/smb3.h index 99f5ca580..6b795665b 100644 --- a/src/WINNT/afsd/smb3.h +++ b/src/WINNT/afsd/smb3.h @@ -41,45 +41,45 @@ typedef struct smb_tran2Dispatch { } smb_tran2Dispatch_t; typedef struct smb_tran2QFSInfo { - union { + union { #pragma pack(push, 2) - struct { - long FSID; /* file system ID */ - long sectorsPerAllocUnit; - long totalAllocUnits; /* on the disk */ - long availAllocUnits; /* free blocks */ - unsigned short bytesPerSector; /* bytes per sector */ - } allocInfo; + struct { + long FSID; /* file system ID */ + long sectorsPerAllocUnit; + long totalAllocUnits; /* on the disk */ + long availAllocUnits; /* free blocks */ + unsigned short bytesPerSector; /* bytes per sector */ + } allocInfo; #pragma pack(pop) - struct { - 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 */ - long vsn; /* volume serial number */ - 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 */ - long sectorsPerAllocUnit; - long bytesPerSector; /* bytes per sector */ - } FSsizeInfo; - struct { - long devType; /* device type */ - long characteristics; - } FSdeviceInfo; - struct { - long attributes; - long maxCompLength; /* max path component length */ - long FSnameLength; /* length of file system name */ - char FSname[12]; - } FSattributeInfo; - } u; + struct { + 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 */ + long vsn; /* volume serial number */ + 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 */ + long sectorsPerAllocUnit; + long bytesPerSector; /* bytes per sector */ + } FSsizeInfo; + struct { + long devType; /* device type */ + long characteristics; + } FSdeviceInfo; + struct { + long attributes; + long maxCompLength; /* max path component length */ + long FSnameLength; /* length of file system name */ + char FSname[12]; + } FSattributeInfo; + } u; } smb_tran2QFSInfo_t; /* more than enough opcodes for today, anyway */ -- 2.39.5