smb-symlink-to-vnovnode-attribute-20081017
authorJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 18 Oct 2008 18:01:07 +0000 (18:01 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 18 Oct 2008 18:01:07 +0000 (18:01 +0000)
LICENSE MIT

When reporting the attribute of a directory name which happens to be
a symlink object to a file that cannot be accessed or does not exist,
use the target name to guess the type of the object.  If it has an
extension, consider it a file, otherwise report it as a directory.

src/WINNT/afsd/NTMakefile
src/WINNT/afsd/cm_utils.c
src/WINNT/afsd/cm_utils.h
src/WINNT/afsd/smb.c
src/WINNT/afsd/smb3.c

index 7345556..22c55f9 100644 (file)
@@ -376,7 +376,7 @@ AFSD_SDKLIBS =\
         secur32.lib \
         ole32.lib \
         oleaut32.lib \
-        iphlpapi.lib shell32.lib
+        iphlpapi.lib shell32.lib shlwapi.lib
 
 AFSD_EXELIBS =\
        $(DESTDIR)\lib\libosi.lib \
index 89e8c9b..f8fbab5 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <errno.h>
 #include <windows.h>
+#include <shlwapi.h>
 #include <winsock2.h>
 #ifndef EWOULDBLOCK
 #define EWOULDBLOCK             WSAEWOULDBLOCK
@@ -747,3 +748,14 @@ int cm_MatchMask(clientchar_t *namep, clientchar_t *maskp, int flags)
     return retval;
 }
 
+BOOL
+cm_TargetPerceivedAsDirectory(const fschar_t *target)
+{
+    char        * ext;
+
+    ext = PathFindExtension(target);
+    if (!ext[0])
+        return TRUE;
+
+    return FALSE;
+}
index bca414e..b852902 100644 (file)
@@ -81,4 +81,6 @@ extern void cm_Gen8Dot3NameIntW(const clientchar_t* longname, cm_dirFid_t * pfid
 
 extern int cm_MatchMask(clientchar_t *namep, clientchar_t *maskp, int flags);
 
+extern BOOL cm_TargetPerceivedAsDirectory(const fschar_t *target);
+
 #endif /*  __CM_UTILS_H_ENV__ */
index 63642e1..a1fb9f2 100644 (file)
@@ -4380,17 +4380,22 @@ smb_ApplyDirListPatches(cm_scache_t * dscp, smb_dirListPatch_t **dirPatchespp,
             switch (scp->fileType) {
             case CM_SCACHETYPE_DIRECTORY:
             case CM_SCACHETYPE_MOUNTPOINT:
-            case CM_SCACHETYPE_SYMLINK:
             case CM_SCACHETYPE_INVALID:
                 attr = SMB_ATTR_DIRECTORY;
                 break;
+            case CM_SCACHETYPE_SYMLINK:
+                if (cm_TargetPerceivedAsDirectory(scp->mountPointStringp))
+                    attr = SMB_ATTR_DIRECTORY;
+                else
+                    attr = SMB_ATTR_NORMAL;
+                break;
             default:
                 /* if we get here we either have a normal file
                 * or we have a file for which we have never 
                 * received status info.  In this case, we can
                 * check the even/odd value of the entry's vnode.
-                * even means it is to be treated as a directory
-                * and odd means it is to be treated as a file.
+                * odd means it is to be treated as a directory
+                * and even means it is to be treated as a file.
                 */
                 if (mustFake && (scp->fid.vnode & 0x1))
                     attr = SMB_ATTR_DIRECTORY;
@@ -5315,21 +5320,7 @@ long smb_ReceiveCoreGetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack
 
     cm_SyncOpDone(newScp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
 
-#ifdef undef
-    /* use smb_Attributes instead.   Also the fact that a file is 
-     * in a readonly volume doesn't mean it shojuld be marked as RO 
-     */
-    if (newScp->fileType == CM_SCACHETYPE_DIRECTORY ||
-        newScp->fileType == CM_SCACHETYPE_MOUNTPOINT ||
-       newScp->fileType == CM_SCACHETYPE_INVALID)
-        attrs = SMB_ATTR_DIRECTORY;
-    else
-        attrs = 0;
-    if ((newScp->unixModeBits & 0222) == 0 || (newScp->flags & CM_SCACHEFLAG_RO))
-        attrs |= SMB_ATTR_READONLY;    /* turn on read-only flag */
-#else
     attrs = smb_Attributes(newScp);
-#endif
 
     smb_SetSMBParm(outp, 0, attrs);
         
index 7c8a317..ca9588e 100644 (file)
@@ -4128,17 +4128,22 @@ smb_ApplyV3DirListPatches(cm_scache_t *dscp, smb_dirListPatch_t **dirPatchespp,
                 switch (scp->fileType) {
                 case CM_SCACHETYPE_DIRECTORY:
                 case CM_SCACHETYPE_MOUNTPOINT:
-                case CM_SCACHETYPE_SYMLINK:
                 case CM_SCACHETYPE_INVALID:
                     fa->extFileAttributes = SMB_ATTR_DIRECTORY;
                     break;
+                case CM_SCACHETYPE_SYMLINK:
+                    if (cm_TargetPerceivedAsDirectory(scp->mountPointStringp))
+                        fa->extFileAttributes = SMB_ATTR_DIRECTORY;
+                    else
+                        fa->extFileAttributes = SMB_ATTR_NORMAL;
+                    break;
                 default:
                     /* if we get here we either have a normal file
                      * or we have a file for which we have never 
                      * received status info.  In this case, we can
                      * check the even/odd value of the entry's vnode.
-                     * even means it is to be treated as a directory
-                     * and odd means it is to be treated as a file.
+                     * odd means it is to be treated as a directory
+                     * and even means it is to be treated as a file.
                      */
                     if (mustFake && (scp->fid.vnode & 0x1))
                         fa->extFileAttributes = SMB_ATTR_DIRECTORY;
@@ -4163,10 +4168,15 @@ smb_ApplyV3DirListPatches(cm_scache_t *dscp, smb_dirListPatch_t **dirPatchespp,
                 switch (scp->fileType) {
                 case CM_SCACHETYPE_DIRECTORY:
                 case CM_SCACHETYPE_MOUNTPOINT:
-                case CM_SCACHETYPE_SYMLINK:
                 case CM_SCACHETYPE_INVALID:
                     fa->attributes = SMB_ATTR_DIRECTORY;
                     break;
+                case CM_SCACHETYPE_SYMLINK:
+                    if (cm_TargetPerceivedAsDirectory(scp->mountPointStringp))
+                        fa->attributes = SMB_ATTR_DIRECTORY;
+                    else
+                        fa->attributes = SMB_ATTR_NORMAL;
+                    break;
                 default:
                     /* if we get here we either have a normal file
                      * or we have a file for which we have never 
@@ -4233,7 +4243,9 @@ smb_ApplyV3DirListPatches(cm_scache_t *dscp, smb_dirListPatch_t **dirPatchespp,
 
             /* Copy attributes */
             lattr = smb_ExtAttributes(scp);
-            if (code == CM_ERROR_NOSUCHPATH && scp->fileType == CM_SCACHETYPE_SYMLINK ||
+            if ((code == CM_ERROR_NOSUCHPATH && 
+                (scp->fileType == CM_SCACHETYPE_SYMLINK && 
+                cm_TargetPerceivedAsDirectory(scp->mountPointStringp))) ||
                 code == CM_ERROR_PATH_NOT_COVERED && scp->fileType == CM_SCACHETYPE_DFSLINK) {
                 if (lattr == SMB_ATTR_NORMAL)
                     lattr = SMB_ATTR_DIRECTORY;