]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Windows: cm_NameI Freelance Eval of Absolute Symlinks
authorJeffrey Altman <jaltman@your-file-system.com>
Sat, 15 Dec 2012 17:19:31 +0000 (12:19 -0500)
committerJeffrey Altman <jaltman@your-file-system.com>
Tue, 18 Dec 2012 06:28:20 +0000 (22:28 -0800)
In cm_NameI() it is possible that a symlink to an absolute path
is reached for which the component after the 'mountRoot' is not
present in the mountRoot directory.  If the mountRoot is the
Freelance root.volume then it is appropriate to attempt automatic
cell resolution.

Change-Id: I806c6d4332e5e7b76a9ce2d02977d0caef612e3c
Reviewed-on: http://gerrit.openafs.org/8763
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
Tested-by: Jeffrey Altman <jaltman@your-file-system.com>
src/WINNT/afsd/cm_vnodeops.c

index 48b9a5b5f1ffa781f8b3d4233f0c8c409eafe586..6044a788aa73968df2922a9e90fea8f9ea8eb3bd 100644 (file)
@@ -2045,12 +2045,53 @@ long cm_NameI(cm_scache_t *rootSCachep, clientchar_t *pathp, long flags,
                  */
                 *cp++ = 0;     /* add null termination */
                extraFlag = 0;
-               if ((flags & CM_FLAG_DIRSEARCH) && tc == 0)
-                   extraFlag = CM_FLAG_NOMOUNTCHASE;
-               code = cm_Lookup(tscp, component,
-                                 flags | extraFlag,
-                                 userp, reqp, &nscp);
 
+                if (tscp == cm_RootSCachep(userp, reqp)) {
+                    code = cm_Lookup(tscp, component, CM_FLAG_CHECKPATH, userp, reqp, &nscp);
+
+                    if ((code == CM_ERROR_NOSUCHPATH || code == CM_ERROR_NOSUCHFILE ||
+                         code == CM_ERROR_BPLUS_NOMATCH) &&
+                         tscp == cm_data.rootSCachep) {
+
+                        clientchar_t volref[AFSPATHMAX];
+
+                        if (wcschr(component, '%') != NULL || wcschr(component, '#') != NULL) {
+                            /*
+                             * A volume reference:  <cell>{%,#}<volume> -> @vol:<cell>{%,#}<volume>
+                             */
+                            cm_ClientStrCpyN(volref, AFSPATHMAX, _C(CM_PREFIX_VOL), CM_PREFIX_VOL_CCH);
+                            cm_ClientStrCat(volref, AFSPATHMAX, component);
+
+                            code = cm_EvaluateVolumeReference(volref, CM_FLAG_CHECKPATH, userp, reqp, &nscp);
+                        }
+#ifdef AFS_FREELANCE_CLIENT
+                        else if (tscp->fid.cell == AFS_FAKE_ROOT_CELL_ID && tscp->fid.volume == AFS_FAKE_ROOT_VOL_ID &&
+                                  tscp->fid.vnode == 1 && tscp->fid.unique == 1) {
+                            /*
+                             * If this is the Freelance volume root directory then treat unrecognized
+                             * names as cell names and attempt to find the appropriate "root.cell".
+                             */
+                            cm_ClientStrCpyN(volref, AFSPATHMAX, _C(CM_PREFIX_VOL), CM_PREFIX_VOL_CCH);
+                            if (component[0] == L'.') {
+                                cm_ClientStrCat(volref, AFSPATHMAX, &component[1]);
+                                cm_ClientStrCatN(volref, AFSPATHMAX, L"%", sizeof(WCHAR));
+                            } else {
+                                cm_ClientStrCat(volref, AFSPATHMAX, component);
+                                cm_ClientStrCatN(volref, AFSPATHMAX, L"#", sizeof(WCHAR));
+                            }
+                            cm_ClientStrCatN(volref, AFSPATHMAX, L"root.cell", 9 * sizeof(WCHAR));
+
+                            code = cm_EvaluateVolumeReference(volref, CM_FLAG_CHECKPATH, userp, reqp, &nscp);
+                        }
+#endif
+                    }
+                } else {
+                    if ((flags & CM_FLAG_DIRSEARCH) && tc == 0)
+                        extraFlag = CM_FLAG_NOMOUNTCHASE;
+                    code = cm_Lookup(tscp, component,
+                                     flags | extraFlag,
+                                     userp, reqp, &nscp);
+                }
                 if (code == 0) {
                     if (!cm_ClientStrCmp(component,_C("..")) ||
                         !cm_ClientStrCmp(component,_C("."))) {