Issue:
I am following the microsoft reference in order to set directory permissions on a network share.
Despite the Intellicode not showing any issue, I receive the following error as soon as a function is called which contains dirInfo.GetAccessControl();
System.MissingMethodException: 'Method not found: 'System.Security.AccessControl.DirectorySecurity System.IO.DirectoryInfo.GetAccessControl()'.'
The function to execute is as follows:
public static void SetFullPermission(string path, string domainAccount)
{
NTAccount ntaccount = new NTAccount("my_domain", domainAccount);
var ds = new DirectorySecurity();
DirectoryInfo dirInfo = new DirectoryInfo(path);
ds = dirInfo.GetAccessControl();
ds.AddAccessRule(new FileSystemAccessRule(ntaccount, FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));
ds.SetAccessRuleProtection(true, false); // disable inheritance and clear any inherited permissions
dirInfo.SetAccessControl(ds);
}
As soon as I uncomment the line var ds = new DirectorySecurity();
the code gets executed but no permissions are set.
Code reference
For reference, the following code might be useful. The calling code looks like the following:
System.Net.NetworkCredential cred = new System.Net.NetworkCredential("my_admin",pwd);
using (new NetworkConnection(@"\\my_fileserver\Data\Home", cred))
{
string path = $@"\\my_fileserver\Data\Home\testuserfolder";
string domainName = "my_domain";
string userNameToCreate = "testuser";
Directory.CreateDirectory(path);
SetFullPermission(path, userNameToCreate);
}
The code which calls SetFullPermission
utilizes a class found in How to provide user name and password when connecting to a network share because my normal account has no permissions on the network drive.
The class NewNetworkConnection()
is as follows:
using System;
using System.ComponentModel;
using System.Net;
using System.Runtime.InteropServices;
namespace FileInterface
{
public class NetworkConnection : IDisposable
{
string _networkName;
public NetworkConnection(string networkName,
NetworkCredential credentials)
{
_networkName = networkName;
var netResource = new NetResource()
{
Scope = ResourceScope.GlobalNetwork,
ResourceType = ResourceType.Disk,
DisplayType = ResourceDisplaytype.Share,
RemoteName = networkName
};
var userName = string.IsNullOrEmpty(credentials.Domain)
? credentials.UserName
: string.Format(@"{0}\{1}", credentials.Domain, credentials.UserName);
var result = WNetAddConnection2(
netResource,
credentials.Password,
userName,
0);
if (result != 0)
{
throw new Win32Exception(result);
}
}
~NetworkConnection()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
WNetCancelConnection2(_networkName, 0, true);
}
[DllImport("mpr.dll")]
private static extern int WNetAddConnection2(NetResource netResource,
string password, string username, int flags);
[DllImport("mpr.dll")]
private static extern int WNetCancelConnection2(string name, int flags,
bool force);
}
[StructLayout(LayoutKind.Sequential)]
public class NetResource
{
public ResourceScope Scope;
public ResourceType ResourceType;
public ResourceDisplaytype DisplayType;
public int Usage;
public string LocalName;
public string RemoteName;
public string Comment;
public string Provider;
}
public enum ResourceScope : int
{
Connected = 1,
GlobalNetwork,
Remembered,
Recent,
Context
};
public enum ResourceType : int
{
Any = 0,
Disk = 1,
Print = 2,
Reserved = 8,
}
public enum ResourceDisplaytype : int
{
Generic = 0x0,
Domain = 0x01,
Server = 0x02,
Share = 0x03,
File = 0x04,
Group = 0x05,
Network = 0x06,
Root = 0x07,
Shareadmin = 0x08,
Directory = 0x09,
Tree = 0x0a,
Ndscontainer = 0x0b
}
}
Solution reference
The following solution information might be important:
- The solution has a main project
Ticketing solution
targeting.NET Core
- The project where the issues code relies in is a
.NET Framework
class library targeting.NET framework 4.8
The reason for the different framework targets is that some code requires the one framework, other code or reference might only work with the other.