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

Fix ownership when cloning elevated #1829

Merged
merged 1 commit into from
Feb 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions GVFS/GVFS.Common/FileSystem/IPlatformFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ public interface IPlatformFileSystem
bool TryCreateDirectoryWithAdminAndUserModifyPermissions(string directoryPath, out string error);
bool TryCreateOrUpdateDirectoryToAdminModifyPermissions(ITracer tracer, string directoryPath, out string error);
bool IsFileSystemSupported(string path, out string error);
void EnsureDirectoryIsOwnedByCurrentUser(string workingDirectoryRoot);
}
}
2 changes: 1 addition & 1 deletion GVFS/GVFS.Common/GVFSEnlistment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ public bool TryCreateEnlistmentSubFolders()
{
try
{
Directory.CreateDirectory(this.WorkingDirectoryRoot);
GVFSPlatform.Instance.FileSystem.EnsureDirectoryIsOwnedByCurrentUser(this.WorkingDirectoryRoot);
this.CreateHiddenDirectory(this.DotGVFSRoot);
}
catch (IOException)
Expand Down
28 changes: 28 additions & 0 deletions GVFS/GVFS.Platform.Windows/WindowsFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,34 @@ public bool IsFileSystemSupported(string path, out string error)
return true;
}

/// <summary>
/// On Windows, if the current user is elevated, the owner of the directory will be the Administrators group by default.
/// This runs afoul of the git "dubious ownership" check, which can fail if either the .git directory or the working directory
/// are not owned by the current user.
///
/// At the moment git for windows does not consider a non-elevated admin to be the owner of a directory owned by the Administrators group,
/// though a fix is in progress in the microsoft fork of git. Libgit2(sharp) also does not have this fix.
///
/// Also, even if the fix were in place, automount would still fail because it runs under SYSTEM account.
///
/// This method ensures that the directory is owned by the current user (which is verified to work for SYSTEM account for automount).
/// </summary>
public void EnsureDirectoryIsOwnedByCurrentUser(string directoryPath)
{
// Ensure directory exists, inheriting all other ACLS
Directory.CreateDirectory(directoryPath);
// If the user is currently elevated, the owner of the directory will be the Administrators group.
DirectorySecurity directorySecurity = Directory.GetAccessControl(directoryPath);
IdentityReference directoryOwner = directorySecurity.GetOwner(typeof(SecurityIdentifier));
SecurityIdentifier administratorsSid = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);
if (directoryOwner == administratorsSid)
{
WindowsIdentity currentUser = WindowsIdentity.GetCurrent();
directorySecurity.SetOwner(currentUser.User);
Directory.SetAccessControl(directoryPath, directorySecurity);
}
}

private class NativeFileReader
{
private const uint GenericRead = 0x80000000;
Expand Down
5 changes: 5 additions & 0 deletions GVFS/GVFS.UnitTests/Mock/FileSystem/MockPlatformFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,10 @@ public bool IsFileSystemSupported(string path, out string error)
error = null;
return true;
}

public void EnsureDirectoryIsOwnedByCurrentUser(string workingDirectoryRoot)
{
throw new NotSupportedException();
}
}
}
11 changes: 11 additions & 0 deletions GVFS/GVFS/CommandLine/CloneVerb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,17 @@ private Result TryInitRepo(ITracer tracer, GitRefs refs, Enlistment enlistmentTo
return new Result(error);
}

try
{
GVFSPlatform.Instance.FileSystem.EnsureDirectoryIsOwnedByCurrentUser(enlistmentToInit.DotGitRoot);
}
catch (IOException e)
{
string error = string.Format("Could not ensure .git directory is owned by current user: {0}", e.Message);
tracer.RelatedError(error);
return new Result(error);
}

GitProcess.Result remoteAddResult = new GitProcess(enlistmentToInit).RemoteAdd("origin", enlistmentToInit.RepoUrl);
if (remoteAddResult.ExitCodeIsFailure)
{
Expand Down