问题
I have a situation where I need to confirm that I am able to get write access to a particular folder on the network. So firstly I check is the user or one of the groups it is part of (domain groups) one of the identities in the access rules. If that is not the case then I need to go through and check all the local groups on the remote machine, to see if my user or one of the user's groups is a member of the local groups on the machine. For example on this particular machine I am a member of BUILTIN\Administrators, which means I do have write access to the given folder. However I am not clear how to get that local group from the remote machine to check if I have write access.
In the code below, when I try and use GroupPrincipal.FindByIdentity, it gives an exception "The binding handle is invalid." I'm not clear what is invalid. If I just try and verify my username and password (a domain username), by using ctx.ValidateCredentials(UserName, Password), it gives exactly the same error.
If I give the machine name as just "pvr-pc", it says it cannot find the name on the network, but "\\pvr-pc" does get past that problem fine.
The same code correctly discovers that I one of the groups I am part of is a group in BUILTIN\Administrators on my local machine, so it's something about the network access that is the problem.
Does anyone have any ideas what I've done wrong?
The code looks like this:
using (WindowsIdentity identity = GetUserIdentity())
{
if (identity != null)
{
try
{
FileInfo fi = new FileInfo(@"\\pvr-pc\c\installers\");
AuthorizationRuleCollection acl = fi.GetAccessControl().GetAccessRules
(true, true, typeof (SecurityIdentifier));
var rules = acl.Cast<FileSystemAccessRule>();
List<string> sids = new List<string>();
sids.Add(identity.User.Value);
sids.AddRange(identity.Groups.Select(identityReference => identityReference.Value));
// check for a direct user match
var matches = from r in rules where sids.Contains(r.IdentityReference.Value) select r;
foreach (FileSystemAccessRule accessRule in matches)
{
// apply rules
}
foreach (FileSystemAccessRule rule in rules)
{
// if it is built in, try and get the group
var groupDetail = rule.IdentityReference.Translate(typeof (NTAccount));
if (!groupDetail.Value.StartsWith("BUILTIN\\")) continue;
PrincipalContext ctx = new PrincipalContext(ContextType.Machine, @"\\pvr-pc", null,
ContextOptions.Negotiate, UserName, Password);
GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Sid,
rule.IdentityReference.Value);
if (grp != null)
{
//// find out if we are a member of the group
var isInGroup = (from g in grp.GetMembers(true)
where sids.Contains(g.Sid.ToString())
select g).Any();
if (isInGroup)
{
// apply rules
}
}
}
}
catch (Exception ex)
{
}
Thanks, Stefan
回答1:
Would it not be easier to simply read or write to the folder and then catch the Exception; then inform the user s/he has no access.
来源:https://stackoverflow.com/questions/11463353/getting-file-permissions-across-the-network