使用c#

时间:2019-08-29 12:55:19

标签: c# permissions shared-directory

是否可以为每个用户设置不同的用户和不同的权限?

在代码的以下部分中,我可以为运行该应用程序的用户设置权限级别“读取-读写” ...它创建一个共享文件夹,并为运行该应用程序的用户设置权限。效果很好。

        try
        {
            //Create a ManagementClass object
            ManagementClass managementClass = new ManagementClass("Win32_Share");

            // Create ManagementBaseObjects for in and out parameters
            ManagementBaseObject inParams = managementClass.GetMethodParameters("Create");

            ManagementBaseObject outParams;

            // Set the input parameters
            inParams["Description"] = Description;
            inParams["Name"] = ShareName;
            inParams["Path"] = FolderPath;

            // Another Type:
            // DISK_DRIVE = 0x0
            // PRINT_QUEUE = 0x1
            // DEVICE = 0x2
            // IPC = 0x3
            // DISK_DRIVE_ADMIN = 0x80000000
            // PRINT_QUEUE_ADMIN = 0x80000001
            // DEVICE_ADMIN = 0x80000002
            // IPC_ADMIN = 0x8000003
            inParams["Type"] = 0x0; // Disk Drive

            inParams["MaximumAllowed"] = 2;
            inParams["Password"] = null;

            string accountToAccess = WindowsIdentity.GetCurrent().Name.Split('\\').Last();

            NTAccount NTAccount = new NTAccount(accountToAccess);
            SecurityIdentifier sid = (SecurityIdentifier)NTAccount.Translate(typeof(SecurityIdentifier));
            byte[] sidArray = new byte[sid.BinaryLength];
            sid.GetBinaryForm(sidArray, 0);

            ManagementObject trustee = new ManagementClass("Win32_Trustee");
            trustee["Domain"] = null;
            trustee["Name"] = accountToAccess;
            trustee["SID"] = sidArray;

            ManagementObject dacl = new ManagementClass("Win32_Ace");
            // 1179817 - read    //1245631 - modify     2032127 - full
            dacl["AccessMask"] = 2032127;
            dacl["AceFlags"] = 3;
            dacl["AceType"] = 0;
            dacl["Trustee"] = trustee;

            ManagementObject securityDescriptor = new ManagementClass("Win32_SecurityDescriptor");
            securityDescriptor["ControlFlags"] = 4; //SE_DACL_PRESENT 
            securityDescriptor["DACL"] = new object[] { dacl };

            inParams["Access"] = securityDescriptor;

            // Invoke the "create" method on the ManagementClass object
            outParams = managementClass.InvokeMethod("Create", inParams, null);

            // Check to see if the method invocation was successful
            var result = (uint)(outParams.Properties["ReturnValue"].Value);
            switch (result)
            {
                case 0:
                    log.Info("Folder successfuly shared.");
                    break;
                case 2:
                    throw new Exception("Access Denied");
                case 8:
                    throw new Exception("Unknown Failure");
                case 9:
                    throw new Exception("Invalid Name");
                case 10:
                    throw new Exception("Invalid Level");
                case 21:
                    throw new Exception("Invalid Parameter");
                case 22:
                    throw new Exception("Duplicate Share");
                case 23:
                    throw new Exception("Redirected Path");
                case 24:
                    throw new Exception("Unknown Device or Directory");
                case 25:
                    throw new Exception("Net Name Not Found");
                default:
                    throw new Exception("Folder cannot be shared.");
            }



        }
        catch (Exception ex)
        {
            log.Warn($"Failed to create Shared Folders with error: '{ex.GetErrorMessage()}'", ex);
            throw;
        }

但是,如果我想设置多个具有多个权限的用户,如何修改此代码?

例如

user1的完全访问权限 user2只读

更新 我找到了解决方案,

    private static ManagementObject GetManagementObject(string name, Permission permission)
    {
        NTAccount NTAccount = new NTAccount(name);
        SecurityIdentifier sid = (SecurityIdentifier)NTAccount.Translate(typeof(SecurityIdentifier));
        byte[] sidArray = new byte[sid.BinaryLength];
        sid.GetBinaryForm(sidArray, 0);

        ManagementObject trustee = new ManagementClass("Win32_Trustee");
        trustee["Domain"] = null;
        trustee["Name"] = name;
        trustee["SID"] = sidArray;

        ManagementObject dacl = new ManagementClass("Win32_Ace");
        dacl["AccessMask"] = (int)permission;
        dacl["AceFlags"] = 3;
        dacl["AceType"] = 0;
        dacl["Trustee"] = trustee;

        return dacl;
    }

    public static void CreateOrUpdateSharedFolder(ILog log, string FolderPath, string ShareName, string Description, string RWUsers, string ROUsers)
    {
        try
        {
            int result = -1; 
            List<object> users = new List<object>();

            foreach (string PWUser in RWUsers?.Split(','))
                if (!StringHelper.IsNullOrEmptyOrWhiteSpace(PWUser))
                    users.Add(GetManagementObject(PWUser, Permission.Full));

            foreach (string ROUser in ROUsers?.Split(','))
                if (!StringHelper.IsNullOrEmptyOrWhiteSpace(ROUser))
                    users.Add(GetManagementObject(ROUser, Permission.Read));

            ManagementObject securityDescriptor = new ManagementClass("Win32_SecurityDescriptor");

            securityDescriptor["ControlFlags"] = 4; //SE_DACL_PRESENT 

            securityDescriptor["DACL"] = users.ToArray();
            //Create a ManagementClass object
            ManagementClass managementClass = new ManagementClass("Win32_Share");


            if (Directory.Exists($@"\\{Environment.MachineName}\{ShareName}"))
            {

                ManagementObject outParams = new ManagementObject($"{managementClass.Path}.Name='{ShareName}'");

                result = (int)outParams.InvokeMethod("SetShareInfo", new object[] { Int32.MaxValue, Description, securityDescriptor });

            }
            else
            {      
                // Create ManagementBaseObjects for in and out parameters
                ManagementBaseObject inParams = managementClass.GetMethodParameters("Create");                    

                // Set the input parameters
                inParams["Description"] = Description;
                inParams["Name"] = ShareName;
                inParams["Path"] = FolderPath;

                // Another Type:
                // DISK_DRIVE = 0x0
                // PRINT_QUEUE = 0x1
                // DEVICE = 0x2
                // IPC = 0x3
                // DISK_DRIVE_ADMIN = 0x80000000
                // PRINT_QUEUE_ADMIN = 0x80000001
                // DEVICE_ADMIN = 0x80000002
                // IPC_ADMIN = 0x8000003
                inParams["Type"] = 0x0; // Disk Drive

                inParams["MaximumAllowed"] = 2;

                inParams["Password"] = null;

                inParams["Access"] = securityDescriptor;

                // Invoke the "create" method on the ManagementClass object
                ManagementBaseObject outParams = managementClass.InvokeMethod("Create", inParams, null);

                // Check to see if the method invocation was successful
                result = (int)(outParams.Properties["ReturnValue"].Value);

            }

            switch (result)
            {
                case 0:
                    log.Info($"Folder {FolderPath} created/updated successfuly!");
                    break;
                case 2:
                    throw new Exception("Access Denied");
                case 8:
                    throw new Exception("Unknown Failure");
                case 9:
                    throw new Exception("Invalid Name");
                case 10:
                    throw new Exception("Invalid Level");
                case 21:
                    throw new Exception("Invalid Parameter");
                case 22:
                    throw new Exception("Duplicate Share");
                case 23:
                    throw new Exception("Redirected Path");
                case 24:
                    throw new Exception("Unknown Device or Directory");
                case 25:
                    throw new Exception("Net Name Not Found");
                default:
                    throw new Exception("Other.");
            }
        }
        catch (Exception ex)
        {
            log.Warn($"Failed to create or update Shared Folder: '{ShareName}' with error: '{ex.GetErrorMessage()}'", ex);
            throw;
        }
    }
enter code here

0 个答案:

没有答案