windows-misc-20050722
[openafs.git] / src / WINNT / afsd / smb3.c
index 451532c..389449b 100644 (file)
@@ -583,7 +583,7 @@ long smb_AuthenticateUserLM(smb_vc_t *vcp, char * accountName, char * primaryDom
                         &quotaLimits,
                         &ntsEx);
 
-    if (nts != STATUS_SUCCESS)
+    if (nts != STATUS_SUCCESS || ntsEx != STATUS_SUCCESS)
         osi_Log2(smb_logp,"LsaLogonUser failure: nts %u ntsEx %u",
                   nts, ntsEx);
 
@@ -2065,7 +2065,7 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op)
     smb_fid_t *fidp;
     int attributes;
     char *lastNamep;
-    time_t dosTime;
+    afs_uint32 dosTime;
     int openFun;
     int trunc;
     int openMode;
@@ -2602,7 +2602,7 @@ long cm_GetShortName(char *pathp, cm_user_t *userp, cm_req_t *reqp,
 long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx)
 {
     smb_tran2Packet_t *outp;
-    time_t dosTime;
+    afs_uint32 dosTime;
     FILETIME ft;
     unsigned short infoLevel;
     int nbytesRequired;
@@ -3054,8 +3054,7 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet
         if (LargeIntegerNotEqualToZero(*((LARGE_INTEGER *)&lastMod)) && 
              lastMod.dwLowDateTime != -1 && lastMod.dwHighDateTime != -1) {
             attr.mask |= CM_ATTRMASK_CLIENTMODTIME;
-            smb_UnixTimeFromLargeSearchTime(&attr.clientModTime,
-                                             &lastMod);
+            smb_UnixTimeFromLargeSearchTime(&attr.clientModTime, &lastMod);
             fidp->flags |= SMB_FID_MTIMESETDONE;
         }
                
@@ -3297,7 +3296,7 @@ smb_ApplyV3DirListPatches(cm_scache_t *dscp,
     cm_scache_t *scp;
     cm_scache_t *targetScp;                    /* target if scp is a symlink */
     char *dptr;
-    time_t dosTime;
+    afs_uint32 dosTime;
     FILETIME ft;
     int shortTemp;
     unsigned short attr;
@@ -4499,7 +4498,7 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     smb_fid_t *fidp;
     int attributes;
     char *lastNamep;
-    time_t dosTime;
+    afs_uint32 dosTime;
     int openFun;
     int trunc;
     int openMode;
@@ -4784,6 +4783,15 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     return 0;
 }       
 
+/* The file locking code is incomplete and that which is implemented in cm_Lock()
+ * is broken.  What exists functions only because it is rarely if ever called.
+ * The tests activated by FULL_LOCKS_ONLY ensure that cm_Lock() is only called
+ * if the lock covers the entire file.  Therefore, RXAFS_SetLock is only called 
+ * rarely.   That means that AFS locks are ignored by Windows clients.
+ * When cm_Lock is re-written, undefine or better yet remove, the FULL_LOCKS_ONLY
+ * code.
+ */
+#define FULL_LOCKS_ONLY
 long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
 {
     cm_req_t req;
@@ -4808,6 +4816,7 @@ long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
 
     fidp = smb_FindFID(vcp, fid, 0);
     if (!fidp || (fidp->flags & SMB_FID_IOCTL)) {
+        osi_Log0(smb_logp, "smb_ReceiveV3Locking BadFD");
         return CM_ERROR_BADFD;
     }
     /* set inp->fid so that later read calls in same msg can find fid */
@@ -4822,8 +4831,10 @@ long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
                       CM_SCACHESYNC_NEEDCALLBACK
                         | CM_SCACHESYNC_GETSTATUS
                         | CM_SCACHESYNC_LOCK);
-    if (code) 
+    if (code) {
+        osi_Log1(smb_logp, "smb_ReceiveV3Locking SyncOp failure code 0x%x", code);
         goto doneSync;
+    }
 
     LockType = smb_GetSMBParm(inp, 3) & 0xff;
     Timeout = (smb_GetSMBParm(inp, 5) << 16) + smb_GetSMBParm(inp, 4);
@@ -4833,7 +4844,7 @@ long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     op = smb_GetSMBData(inp, NULL);
 
     for (i=0; i<NumberOfUnlocks; i++) {
-        if (LockType & 0x10) {
+        if (LockType & LOCKING_ANDX_LARGE_FILES) {
             /* Large Files */
             LOffset.HighPart = *((LONG *)(op + 4));
             LOffset.LowPart = *((DWORD *)(op + 8));
@@ -4849,8 +4860,13 @@ long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
             LLength.LowPart = *((DWORD *)(op + 6));
             op += 10;
         }
-        if (LargeIntegerNotEqualToZero(LOffset))
+#ifdef FULL_LOCKS_ONLY
+        if (LargeIntegerNotEqualToZero(LOffset)) {
+            osi_Log2(smb_logp, "smb_ReceiveV3Locking Unlock %d offset 0x%x != Zero",
+                     i, (long)LOffset.QuadPart);
             continue;
+        }
+#endif /* FULL_LOCKS_ONLY */
         /* Do not check length -- length check done in cm_Unlock */
 
         code = cm_Unlock(scp, LockType, LOffset, LLength, userp, &req);
@@ -4858,7 +4874,7 @@ long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     }       
 
     for (i=0; i<NumberOfLocks; i++) {
-        if (LockType & 0x10) {
+        if (LockType & LOCKING_ANDX_LARGE_FILES) {
             /* Large Files */
             LOffset.HighPart = *((LONG *)(op + 4));
             LOffset.LowPart = *((DWORD *)(op + 8));
@@ -4874,11 +4890,18 @@ long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
             LLength.LowPart = *((DWORD *)(op + 6));
             op += 10;
         }
-        if (LargeIntegerNotEqualToZero(LOffset))
+#ifdef FULL_LOCKS_ONLY
+        if (LargeIntegerNotEqualToZero(LOffset)) {
+            osi_Log2(smb_logp, "smb_ReceiveV3Locking Lock %d offset 0x%x != Zero",
+                     i, (long)LOffset.QuadPart);
             continue;
-        if (LargeIntegerLessThan(LOffset, scp->length))
+        }
+        if (LargeIntegerLessThan(LOffset, scp->length)) {
+            osi_Log3(smb_logp, "smb_ReceiveV3Locking Unlock %d offset 0x%x < 0x%x",
+                     i, (long)LOffset.QuadPart, (long)scp->length.QuadPart);
             continue;
-
+        }
+#endif /* FULL_LOCKS_ONLY */
         code = cm_Lock(scp, LockType, LOffset, LLength, Timeout,
                         userp, &req, &lockp);
         if (code == CM_ERROR_WOULDBLOCK && Timeout != 0) {
@@ -4897,13 +4920,19 @@ long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
             lock_ReleaseWrite(&smb_globalLock);
             /* don't send reply immediately */
             outp->flags |= SMB_PACKETFLAG_NOSEND;
+            osi_Log1(smb_logp, "smb_ReceiveV3Locking WaitingLock created 0x%x",
+                     (long) waitingLock);
+            continue;
         }
-        if (code) 
+        if (code) {
+            osi_Log1(smb_logp, "smb_ReceiveV3Locking cm_Lock failure code 0x%x", code);
             break;
+        }
     }           
 
     if (code) {
         /* release any locks acquired before the failure */
+        osi_Log0(smb_logp, "smb_ReceiveV3Locking - failure; should be releasing locks but don't!!!!");
     }
     else
         smb_SetSMBDataLength(outp, 0);
@@ -4923,7 +4952,7 @@ long smb_ReceiveV3GetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *
     smb_fid_t *fidp;
     cm_scache_t *scp;
     long code = 0;
-    time_t searchTime;
+    afs_uint32 searchTime;
     cm_user_t *userp;
     cm_req_t req;
 
@@ -4985,7 +5014,7 @@ long smb_ReceiveV3SetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *
     smb_fid_t *fidp;
     cm_scache_t *scp;
     long code = 0;
-    time_t searchTime;
+    afs_uint32 searchTime;
     time_t unixTime;
     cm_user_t *userp;
     cm_attr_t attrs;
@@ -5115,6 +5144,23 @@ long smb_ReceiveV3ReadX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
 #define  FILE_OVERWRITE        4       // (open & truncate, but do not create)
 #define  FILE_OVERWRITE_IF 5   // (open & truncate, or create)
 
+/* Flags field */
+#define REQUEST_OPLOCK 2
+#define REQUEST_BATCH_OPLOCK 4
+#define OPEN_DIRECTORY 8
+#define EXTENDED_RESPONSE_REQUIRED 0x10
+
+/* CreateOptions field. */
+#define FILE_DIRECTORY_FILE       0x0001
+#define FILE_WRITE_THROUGH        0x0002
+#define FILE_SEQUENTIAL_ONLY      0x0004
+#define FILE_NON_DIRECTORY_FILE   0x0040
+#define FILE_NO_EA_KNOWLEDGE      0x0200
+#define FILE_EIGHT_DOT_THREE_ONLY 0x0400
+#define FILE_RANDOM_ACCESS        0x0800
+#define FILE_DELETE_ON_CLOSE      0x1000
+#define FILE_OPEN_BY_FILE_ID      0x2000
+
 long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
 {
     char *pathp, *realPathp;
@@ -5132,6 +5178,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     unsigned int requestOpLock;
     unsigned int requestBatchOpLock;
     unsigned int mustBeDir;
+    unsigned int extendedRespRequired;
     unsigned int treeCreate;
     int realDirFlag;
     unsigned int desiredAccess;
@@ -5166,9 +5213,10 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     nameLength = smb_GetSMBOffsetParm(inp, 2, 1);
     flags = smb_GetSMBOffsetParm(inp, 3, 1)
         | (smb_GetSMBOffsetParm(inp, 4, 1) << 16);
-    requestOpLock = flags & 0x02;
-    requestBatchOpLock = flags & 0x04;
-    mustBeDir = flags & 0x08;
+    requestOpLock = flags & REQUEST_OPLOCK;
+    requestBatchOpLock = flags & REQUEST_BATCH_OPLOCK;
+    mustBeDir = flags & OPEN_DIRECTORY;
+    extendedRespRequired = flags & EXTENDED_RESPONSE_REQUIRED;
 
     /*
      * Why all of a sudden 32-bit FID?
@@ -5189,9 +5237,9 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     /* mustBeDir is never set; createOptions directory bit seems to be
      * more important
      */
-    if (createOptions & 1)
+    if (createOptions & FILE_DIRECTORY_FILE)
         realDirFlag = 1;
-    else if (createOptions & 0x40)
+    else if (createOptions & FILE_NON_DIRECTORY_FILE)
         realDirFlag = 0;
     else
         realDirFlag = -1;
@@ -5310,6 +5358,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
         fidflags |= SMB_FID_OPENREAD;
     if (desiredAccess & AFS_ACCESS_WRITE)
         fidflags |= SMB_FID_OPENWRITE;
+    if (createOptions & FILE_DELETE_ON_CLOSE)
+        fidflags |= SMB_FID_DELONCLOSE;
 
     code = 0;
 
@@ -5418,7 +5468,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
                 }
             } while (dscp == NULL && code == 0);
         } else
-                       code = 0;
+            code = 0;
 
         /* we might have scp and we might have dscp */
 
@@ -5454,8 +5504,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
         if (!smb_IsLegalFilename(lastNamep)) {
             if (scp)
                 cm_ReleaseSCache(scp);
-                       if (dscp)
-            cm_ReleaseSCache(dscp);
+            if (dscp)
+                cm_ReleaseSCache(dscp);
             cm_ReleaseUser(userp);
             free(realPathp);
             return CM_ERROR_BADNTFILENAME;
@@ -5474,7 +5524,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
                                  userp, &req, &scp);
             }
             if (code && code != CM_ERROR_NOSUCHFILE) {
-                cm_ReleaseSCache(dscp);
+                if (dscp)
+                    cm_ReleaseSCache(dscp);
                 cm_ReleaseUser(userp);
                 free(realPathp);
                 return code;
@@ -5497,7 +5548,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
             /* oops, file shouldn't be there */
             if (dscp)
                 cm_ReleaseSCache(dscp);
-            cm_ReleaseSCache(scp);
+            if (scp)
+                cm_ReleaseSCache(scp);
             cm_ReleaseUser(userp);
             free(realPathp);
             return CM_ERROR_EXISTS;
@@ -5535,7 +5587,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
         if (code) {
             if (dscp)
                 cm_ReleaseSCache(dscp);
-            cm_ReleaseSCache(scp);
+            if (scp)
+                cm_ReleaseSCache(scp);
             cm_ReleaseUser(userp);
             free(realPathp);
             return code;
@@ -5544,8 +5597,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
         /* don't create if not found */
         if (dscp)
             cm_ReleaseSCache(dscp);
-               if (scp)
-                       cm_ReleaseSCache(scp);
+        if (scp)
+            cm_ReleaseSCache(scp);
         cm_ReleaseUser(userp);
         free(realPathp);
         return CM_ERROR_NOSUCHFILE;
@@ -5718,7 +5771,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     /* (only applies to single component case) */
     if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) {
         cm_ReleaseSCache(scp);
-        cm_ReleaseSCache(dscp);
+        if (dscp)
+            cm_ReleaseSCache(dscp);
         cm_ReleaseUser(userp);
         free(realPathp);
         return CM_ERROR_NOTDIR;
@@ -5847,10 +5901,10 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
     lparmp = (ULONG *) parmp;
 
     flags = lparmp[0];
-    requestOpLock = flags & 0x02;
-    requestBatchOpLock = flags & 0x04;
-    mustBeDir = flags & 0x08;
-    extendedRespRequired = flags & 0x10;
+    requestOpLock = flags & REQUEST_OPLOCK;
+    requestBatchOpLock = flags & REQUEST_BATCH_OPLOCK;
+    mustBeDir = flags & OPEN_DIRECTORY;
+    extendedRespRequired = flags & EXTENDED_RESPONSE_REQUIRED;
 
     /*
      * Why all of a sudden 32-bit FID?
@@ -5883,9 +5937,9 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
     /* mustBeDir is never set; createOptions directory bit seems to be
      * more important
      */
-    if (createOptions & 1)
+    if (createOptions & FILE_DIRECTORY_FILE)
         realDirFlag = 1;
-    else if (createOptions & 0x40)
+    else if (createOptions & FILE_NON_DIRECTORY_FILE)
         realDirFlag = 0;
     else
         realDirFlag = -1;
@@ -5967,6 +6021,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
         fidflags |= SMB_FID_OPENREAD;
     if (desiredAccess & AFS_ACCESS_WRITE)
         fidflags |= SMB_FID_OPENWRITE;
+    if (createOptions & FILE_DELETE_ON_CLOSE)
+        fidflags |= SMB_FID_DELONCLOSE;
 
     dscp = NULL;
     code = 0;
@@ -6093,7 +6149,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
         code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp,
                                &req);
         if (code) {     
-            if (dscp) cm_ReleaseSCache(dscp);
+            if (dscp) 
+                cm_ReleaseSCache(dscp);
             cm_ReleaseSCache(scp);
             cm_ReleaseUser(userp);
             free(realPathp);
@@ -6102,7 +6159,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
 
         if (createDisp == FILE_CREATE) {
             /* oops, file shouldn't be there */
-            if (dscp) cm_ReleaseSCache(dscp);
+            if (dscp) 
+                cm_ReleaseSCache(dscp);
             cm_ReleaseSCache(scp);
             cm_ReleaseUser(userp);
             free(realPathp);
@@ -6138,7 +6196,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
     }
     else if (createDisp == FILE_OPEN || createDisp == FILE_OVERWRITE) {
         /* don't create if not found */
-        if (dscp) cm_ReleaseSCache(dscp);
+        if (dscp) 
+            cm_ReleaseSCache(dscp);
         cm_ReleaseUser(userp);
         free(realPathp);
         return CM_ERROR_NOSUCHFILE;
@@ -6220,7 +6279,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
 
     if (code) {
         /* something went wrong creating or truncating the file */
-        if (scp) cm_ReleaseSCache(scp);
+        if (scp) 
+            cm_ReleaseSCache(scp);
         cm_ReleaseUser(userp);
         free(realPathp);
         return code;
@@ -6279,7 +6339,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
     fidp->NTopen_wholepathp = realPathp;
 
     /* we don't need this any longer */
-    if (dscp) cm_ReleaseSCache(dscp);
+    if (dscp) 
+        cm_ReleaseSCache(dscp);
 
     cm_Open(scp, 0, userp);