Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

git init failed in case of user have access to a directory but not have "List Directory" access to some of the parent directories of that directory #598

Closed
skvoboo opened this issue Jan 14, 2016 · 2 comments

Comments

@skvoboo
Copy link

skvoboo commented Jan 14, 2016

OS/Git version

C:\inetpub\wwwroot>git version
git version 2.7.0.windows.1

C:\inetpub\wwwroot>ver
Microsoft Windows [Version 6.3.9600]

Steps to reproduce

  1. Create user
  2. Allow full access control on C:\inetpub\wwwroot directory for created user
  3. Deny List Directory permission (this folder only) on C:\inetpub directory for created user
  4. Login to server by created user and execute:
C:\Users\user1>cd C:\inetpub\wwwroot
C:\inetpub\wwwroot>git init
fatal: unable to get current working directory: No error

Root cause
mingw_getcwd function in compat\mingw.c file uses GetLongPathNameW WinAPI function, GetLongPathName may fail when it is unable to query the parent directory of a path component to determine the long name for that component.

Proposed solution
Get handle of current directory and use GetFinalPathNameByHandleW function to get long path.

The solution proposed for Windows Server 2008/Windows Vista or high.

Patch

 char *mingw_getcwd(char *pointer, int len)
 {
-   int i;
    wchar_t cwd[MAX_PATH], wpointer[MAX_PATH];
+   DECLARE_PROC_ADDR(kernel32.dll, DWORD, GetFinalPathNameByHandleW,
+             HANDLE, LPWSTR, DWORD, DWORD);
    DWORD ret = GetCurrentDirectoryW(ARRAY_SIZE(cwd), cwd);

    if (ret < 0 || ret >= ARRAY_SIZE(cwd))
        return NULL;
-   ret = GetLongPathNameW(cwd, wpointer, ARRAY_SIZE(wpointer));
-   if (!ret || ret >= ARRAY_SIZE(wpointer))
+
+   if (INIT_PROC_ADDR(GetFinalPathNameByHandleW)) {
+       HANDLE hnd = CreateFileW(cwd, 0,
+           FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
+           OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+       if (hnd == INVALID_HANDLE_VALUE)
+           return NULL;
+       ret = GetFinalPathNameByHandleW(hnd, wpointer, ARRAY_SIZE(wpointer), 0);
+       CloseHandle(hnd);
+   } else {
+       ret = GetLongPathNameW(cwd, wpointer, ARRAY_SIZE(wpointer));
+   }
+
+   if (!ret || ret >= ARRAY_SIZE(wpointer))
        return NULL;
-   if (xwcstoutf(pointer, wpointer, len) < 0)
+   if (xwcstoutf(pointer, normalize_ntpath(wpointer), len) < 0)
        return NULL;
-   for (i = 0; pointer[i]; i++)
-       if (pointer[i] == '\\')
-           pointer[i] = '/';
    return pointer;
 }
@skvoboo skvoboo changed the title git init failed in case of user have access to a directory but not have "List Directory" access to some of the parent directories of that directory: unable to get current working directory git init failed in case of user have access to a directory but not have "List Directory" access to some of the parent directories of that directory Jan 14, 2016
@dscho
Copy link
Member

dscho commented Jan 14, 2016

@skvoboo could you turn that into a real Pull Request (with a nice commit message), please?

@dscho
Copy link
Member

dscho commented Feb 1, 2016

Fixed via #606.

@dscho dscho closed this as completed Feb 1, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants