Skip to content

Commit 2b6bf5d

Browse files
authored
Merge pull request #1831 from microsoft/milestones/m253
[Release] Milestone M253
2 parents 9603246 + 0d6f8bb commit 2b6bf5d

File tree

9 files changed

+46
-34
lines changed

9 files changed

+46
-34
lines changed

GVFS/GVFS.Common/FileSystem/IPlatformFileSystem.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ public interface IPlatformFileSystem
1818
bool TryCreateDirectoryWithAdminAndUserModifyPermissions(string directoryPath, out string error);
1919
bool TryCreateOrUpdateDirectoryToAdminModifyPermissions(ITracer tracer, string directoryPath, out string error);
2020
bool IsFileSystemSupported(string path, out string error);
21+
void EnsureDirectoryIsOwnedByCurrentUser(string workingDirectoryRoot);
2122
}
2223
}

GVFS/GVFS.Common/GVFSEnlistment.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ public bool TryCreateEnlistmentSubFolders()
217217
{
218218
try
219219
{
220-
Directory.CreateDirectory(this.WorkingDirectoryRoot);
220+
GVFSPlatform.Instance.FileSystem.EnsureDirectoryIsOwnedByCurrentUser(this.WorkingDirectoryRoot);
221221
this.CreateHiddenDirectory(this.DotGVFSRoot);
222222
}
223223
catch (IOException)

GVFS/GVFS.Common/GVFSPlatform.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,6 @@ public static void Register(GVFSPlatform platform)
8787
public abstract bool TryGetGVFSHooksVersion(out string hooksVersion, out string error);
8888
public abstract bool TryInstallGitCommandHooks(GVFSContext context, string executingDirectory, string hookName, string commandHookPath, out string errorMessage);
8989

90-
public abstract bool TryVerifyAuthenticodeSignature(string path, out string subject, out string issuer, out string error);
91-
9290
public abstract Dictionary<string, string> GetPhysicalDiskInfo(string path, bool sizeStatsOnly);
9391

9492
public abstract bool IsConsoleOutputRedirectedToFile();

GVFS/GVFS.Platform.Windows/GVFS.Platform.Windows.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
<PackageReference Include="Microsoft.Database.Collections.Generic" Version="1.9.4" />
1515
<PackageReference Include="Microsoft.Database.Isam" Version="1.9.4" />
1616
<PackageReference Include="Microsoft.Windows.ProjFS" Version="1.1.19156.1" />
17-
<PackageReference Include="System.Management.Automation.dll" Version="10.0.10586.0" />
1817
</ItemGroup>
1918

2019
<ItemGroup>

GVFS/GVFS.Platform.Windows/WindowsFileSystem.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,34 @@ public bool IsFileSystemSupported(string path, out string error)
272272
return true;
273273
}
274274

275+
/// <summary>
276+
/// On Windows, if the current user is elevated, the owner of the directory will be the Administrators group by default.
277+
/// This runs afoul of the git "dubious ownership" check, which can fail if either the .git directory or the working directory
278+
/// are not owned by the current user.
279+
///
280+
/// 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,
281+
/// though a fix is in progress in the microsoft fork of git. Libgit2(sharp) also does not have this fix.
282+
///
283+
/// Also, even if the fix were in place, automount would still fail because it runs under SYSTEM account.
284+
///
285+
/// This method ensures that the directory is owned by the current user (which is verified to work for SYSTEM account for automount).
286+
/// </summary>
287+
public void EnsureDirectoryIsOwnedByCurrentUser(string directoryPath)
288+
{
289+
// Ensure directory exists, inheriting all other ACLS
290+
Directory.CreateDirectory(directoryPath);
291+
// If the user is currently elevated, the owner of the directory will be the Administrators group.
292+
DirectorySecurity directorySecurity = Directory.GetAccessControl(directoryPath);
293+
IdentityReference directoryOwner = directorySecurity.GetOwner(typeof(SecurityIdentifier));
294+
SecurityIdentifier administratorsSid = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);
295+
if (directoryOwner == administratorsSid)
296+
{
297+
WindowsIdentity currentUser = WindowsIdentity.GetCurrent();
298+
directorySecurity.SetOwner(currentUser.User);
299+
Directory.SetAccessControl(directoryPath, directorySecurity);
300+
}
301+
}
302+
275303
private class NativeFileReader
276304
{
277305
private const uint GenericRead = 0x80000000;

GVFS/GVFS.Platform.Windows/WindowsPlatform.cs

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
using System.IO;
1212
using System.IO.Pipes;
1313
using System.Linq;
14-
using System.Management.Automation;
1514
using System.Security.AccessControl;
1615
using System.Security.Principal;
1716
using System.ServiceProcess;
@@ -294,30 +293,6 @@ public override bool TryInstallGitCommandHooks(GVFSContext context, string execu
294293
return true;
295294
}
296295

297-
public override bool TryVerifyAuthenticodeSignature(string path, out string subject, out string issuer, out string error)
298-
{
299-
using (PowerShell powershell = PowerShell.Create())
300-
{
301-
powershell.AddScript($"Get-AuthenticodeSignature -FilePath {path}");
302-
303-
Collection<PSObject> results = powershell.Invoke();
304-
if (powershell.HadErrors || results.Count <= 0)
305-
{
306-
subject = null;
307-
issuer = null;
308-
error = $"Powershell Get-AuthenticodeSignature failed, could not verify authenticode for {path}.";
309-
return false;
310-
}
311-
312-
Signature signature = results[0].BaseObject as Signature;
313-
bool isValid = signature.Status == SignatureStatus.Valid;
314-
subject = signature.SignerCertificate.SubjectName.Name;
315-
issuer = signature.SignerCertificate.IssuerName.Name;
316-
error = isValid == false ? signature.StatusMessage : null;
317-
return isValid;
318-
}
319-
}
320-
321296
public override string GetCurrentUser()
322297
{
323298
WindowsIdentity identity = WindowsIdentity.GetCurrent();

GVFS/GVFS.UnitTests/Mock/Common/MockPlatform.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,6 @@ public override bool TryInstallGitCommandHooks(GVFSContext context, string execu
5959
throw new NotSupportedException();
6060
}
6161

62-
public override bool TryVerifyAuthenticodeSignature(string path, out string subject, out string issuer, out string error)
63-
{
64-
throw new NotImplementedException();
65-
}
66-
6762
public override string GetNamedPipeName(string enlistmentRoot)
6863
{
6964
return "GVFS_Mock_PipeName";

GVFS/GVFS.UnitTests/Mock/FileSystem/MockPlatformFileSystem.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,10 @@ public bool IsFileSystemSupported(string path, out string error)
7070
error = null;
7171
return true;
7272
}
73+
74+
public void EnsureDirectoryIsOwnedByCurrentUser(string workingDirectoryRoot)
75+
{
76+
throw new NotSupportedException();
77+
}
7378
}
7479
}

GVFS/GVFS/CommandLine/CloneVerb.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,17 @@ private Result TryInitRepo(ITracer tracer, GitRefs refs, Enlistment enlistmentTo
716716
return new Result(error);
717717
}
718718

719+
try
720+
{
721+
GVFSPlatform.Instance.FileSystem.EnsureDirectoryIsOwnedByCurrentUser(enlistmentToInit.DotGitRoot);
722+
}
723+
catch (IOException e)
724+
{
725+
string error = string.Format("Could not ensure .git directory is owned by current user: {0}", e.Message);
726+
tracer.RelatedError(error);
727+
return new Result(error);
728+
}
729+
719730
GitProcess.Result remoteAddResult = new GitProcess(enlistmentToInit).RemoteAdd("origin", enlistmentToInit.RepoUrl);
720731
if (remoteAddResult.ExitCodeIsFailure)
721732
{

0 commit comments

Comments
 (0)