security - A working .NET example using SetEntriesInAcl interop in action -
does has working example of invoking setentriesinacl method in .net using p/invoke?
i keep getting error 87 when invoking , cannot doing wrong.
here definitions:
private enum fileaccessrights { file_read_data = 0x0001, } private enum accessmode { grant_access = 1, revoke_access = 4, } private enum inheritanceflags { no_inheritance = 0x0, } private enum trusteeform { trustee_is_sid = 0, } private enum trusteetype { trustee_is_user = 1, } private struct explicitaccess { public fileaccessrights accesspermissions; public accessmode accessmode; public inheritanceflags inheritance; public trustee trustee; } private struct trustee { public intptr multipletrustee; public int multipletrusteeoperation; public trusteeform trusteeform; public trusteetype trusteetype; [marshalas(unmanagedtype.lpwstr)] public string name; } [dllimport("advapi32.dll", setlasterror = true)] static extern int setentriesinacl(int countofexplicitentries, ref explicitaccess explicitentry, intptr oldacl, out intptr newacl); here how invoke it:
securityidentifier sid = getsid(); var ea = new explicitaccess { accesspermissions = fileaccessrights.file_read_data, accessmode = accessmode.grant_access, inheritance = inheritanceflags.no_inheritance, trustee = new trustee { trusteeform = trusteeform.trustee_is_sid, trusteetype = trusteetype.trustee_is_user, name = sid.value } }; intptr newacl; int res = setentriesinacl(1, ref ea, currentacl, out newacl); i keep getting error 87 (invalid parameter) , not know why.
thanks lot in advance samaritans out there.
edit1
i glad use new managed api changing acl, if shows me how if need modify acl of private key container associated certificate. unclear how use managed api in scenario.
i had same requirement via interop calls. found relevant answer searching here:
(different error code, same underlying reason failure) using setentriesinacl in c# : error 1332
it has ansi vs. unicode support , you'll need use correct charset on p-invoke method definition.
[dllimport("advapi32.dll", charset = charset.auto, setlasterror = true)] static extern uint setentriesinacl( int ccountofexplicitentries, ref explicit_access plistofexplicitentries, intptr oldacl, out intptr newacl); another thing ensure charset consistent struct , method definitions. in fact because our services run on servers support unicode character sets, changed charset charset.unicode across board.
also needed ensure unmanaged type marshalling string parameters matched unicode character set (i.e. wide-char types in c++/native example). below use unmanagedtype.lpwstr.
[structlayout(layoutkind.sequential, charset = charset.unicode)] internal struct trustee { public intptr multipletrustee; public multiple_trustee_operation multipletrusteeoperation; public trustee_form trusteeform; public trustee_type trusteetype; [marshalas(unmanagedtype.lpwstr)] public string name; } [dllimport("advapi32.dll", charset = charset.unicode, setlasterror = true)] internal static extern uint getnamedsecurityinfo( [marshalas(unmanagedtype.lpwstr)] string pobjectname, se_object_type objecttype, security_information securityinfo, out intptr psidowner, out intptr psidgroup, out intptr pdacl, out intptr psacl, out intptr psecuritydescriptor); (this working code setting permissions on share path might need):
public static void setreadonlysharepermissions(string servername, string sharename, string wellknowngroupname, dfssharepermission permissions) { intptr sidownerptr = intptr.zero; intptr groupownerptr = intptr.zero; intptr saclptr = intptr.zero; intptr olddacl = intptr.zero; intptr oldsecuritydescriptor = intptr.zero; string shareobjectname = $@"\\{servername}\{sharename}"; uint securityobjectqueryresult = netshareinterop.getnamedsecurityinfo( shareobjectname, netshareinterop.se_object_type.se_lmshare, netshareinterop.security_information.dacl_security_information, out sidownerptr, out groupownerptr, out olddacl, out saclptr, out oldsecuritydescriptor); if (securityobjectqueryresult != 0) { throw new win32exception((int)securityobjectqueryresult); } // default permissions = readonly uint shareaccesspermissions = (uint)netshareinterop.access_mask.share_access_read; switch (permissions) { case dfssharepermission.fullcontrol: shareaccesspermissions = (uint)netshareinterop.access_mask.share_access_full; break; case dfssharepermission.readwrite: shareaccesspermissions = (uint)netshareinterop.access_mask.share_access_write; break; } netshareinterop.explicit_access access = new netshareinterop.explicit_access() { accessmode = (uint)netshareinterop.access_mode.set_access, accesspermissions = shareaccesspermissions, inheritance = (uint)netshareinterop.access_inheritance.sub_containers_and_objects_inherit, trustee = new netshareinterop.trustee() { name = wellknowngroupname, trusteeform = netshareinterop.trustee_form.trustee_is_name, trusteetype = netshareinterop.trustee_type.trustee_is_well_known_group } }; intptr newdacl; int initializeaclentriesresult = netshareinterop.setentriesinacl(1, ref access, olddacl, out newdacl); if (initializeaclentriesresult != 0) { throw new win32exception(initializeaclentriesresult); } uint setsecurityresult = netshareinterop.setnamedsecurityinfo( shareobjectname, netshareinterop.se_object_type.se_lmshare, netshareinterop.security_information.dacl_security_information, intptr.zero, intptr.zero, newdacl, intptr.zero); if (setsecurityresult != 0) { throw new win32exception((int)setsecurityresult); } } (..and why make dig silly interop enum , struct definitions?)
internal static class netshareinterop { private const charset defaultcharset = charset.unicode; internal enum access_mode : uint { not_used_access = 0, grant_access, set_access, revoke_access, set_audit_success, set_audit_failure } internal enum access_mask : uint { generic_all = 0x10000000, //268435456, generic_read = 0x80000000, //2147483648l, generic_write = 0x40000000, //1073741824, generic_execute = 0x20000000, //536870912, standard_rights_read = 0x00020000, //131072 standard_rights_write = 0x00020000, share_access_read = 0x1200a9, // 1179817 share_access_write = 0x1301bf, // 1245631 share_access_full = 0x1f01ff // 2032127 } internal enum access_inheritance : uint { no_inheritance = 0, object_inherit_ace = 0x1, container_inherit_ace = 0x2, no_propagate_inherit_ace = 0x4, inherit_only_ace = 0x8, inherited_ace = 0x10, sub_objects_only_inherit = access_inheritance.object_inherit_ace | access_inheritance.inherit_only_ace, sub_containers_only_inherit = access_inheritance.container_inherit_ace | access_inheritance.inherit_only_ace, sub_containers_and_objects_inherit = access_inheritance.container_inherit_ace | access_inheritance.object_inherit_ace, } internal enum multiple_trustee_operation { no_multiple_trustee, trustee_is_impersonate } internal enum neterror : uint { nerr_success = 0, nerr_unknowndevdir = 0x00000844, nerr_redirectedpath = 0x00000845, nerr_duplicateshare = 0x00000846, nerr_netnamenotfound = 0x00000906, nerr_dfsnosuchvolume = 0x00000a66 } internal enum se_object_type { se_unknown_object_type = 0, se_file_object, se_service, se_printer, se_registry_key, se_lmshare, se_kernel_object, se_window_object, se_ds_object, se_ds_object_all, se_provider_defined_object, se_wmiguid_object, se_registry_wow64_32key } [flags] internal enum security_information : uint { owner_security_information = 0x00000001, group_security_information = 0x00000002, dacl_security_information = 0x00000004, sacl_security_information = 0x00000008, unprotected_sacl_security_information = 0x10000000, unprotected_dacl_security_information = 0x20000000, protected_sacl_security_information = 0x40000000, protected_dacl_security_information = 0x80000000 } internal enum share_type : uint { stype_disktree = 0, stype_printq = 1, stype_device = 2, stype_ipc = 3, stype_temporary = 0x40000000, stype_special = 0x80000000, } internal enum trustee_form { trustee_is_sid = 0, trustee_is_name, trustee_bad_form, trustee_is_objects_and_sid, trustee_is_objects_and_name } internal enum trustee_type { trustee_is_unknown = 0, trustee_is_user, trustee_is_group, trustee_is_domain, trustee_is_alias, trustee_is_well_known_group, trustee_is_deleted, trustee_is_invalid, trustee_is_computer } [structlayout(layoutkind.sequential, charset = defaultcharset)] internal struct share_info_502 { [marshalas(unmanagedtype.lpwstr)] public string shi502_netname; public share_type shi502_type; [marshalas(unmanagedtype.lpwstr)] public string shi502_remark; public int shi502_permissions; public int shi502_max_uses; public int shi502_current_uses; [marshalas(unmanagedtype.lpwstr)] public string shi502_path; [marshalas(unmanagedtype.lpwstr)] public string shi502_passwd; public int shi502_reserved; public intptr shi502_security_descriptor; } [structlayout(layoutkind.sequential, charset = defaultcharset)] internal struct explicit_access { public uint accesspermissions; public uint accessmode; public uint inheritance; public trustee trustee; } //platform independent (32 & 64 bit) - use pack = 0 both platforms. intptr works well. [structlayout(layoutkind.sequential, charset = defaultcharset)] internal struct trustee { public intptr multipletrustee; public multiple_trustee_operation multipletrusteeoperation; public trustee_form trusteeform; public trustee_type trusteetype; [marshalas(unmanagedtype.lpwstr)] public string name; } [dllimport("advapi32.dll", charset = defaultcharset, setlasterror = true)] internal static extern uint getnamedsecurityinfo( [marshalas(unmanagedtype.lpwstr)] string pobjectname, se_object_type objecttype, security_information securityinfo, out intptr psidowner, out intptr psidgroup, out intptr pdacl, out intptr psacl, out intptr psecuritydescriptor); [dllimport("netapi32.dll", charset = charset.auto, setlasterror = true)] internal static extern neterror netshareadd( [marshalas(unmanagedtype.lpwstr)] string strserver, int32 dwlevel, ref share_info_502 buf, out uint parm_err ); [dllimport("netapi32.dll", charset = defaultcharset, setlasterror = true)] internal static extern neterror netsharedel( [marshalas(unmanagedtype.lpwstr)] string strserver, [marshalas(unmanagedtype.lpwstr)] string strnetname, int reserved //must 0 ); [dllimport("advapi32.dll", charset = defaultcharset, setlasterror = true)] internal static extern uint setnamedsecurityinfo( [marshalas(unmanagedtype.lpwstr)] string pobjectname, se_object_type objecttype, security_information securityinfo, intptr psidowner, intptr psidgroup, intptr pdacl, intptr psacl); [dllimport("advapi32.dll", charset = defaultcharset, setlasterror = true)] internal static extern int setentriesinacl( int ccountofexplicitentries, ref explicit_access plistofexplicitentries, intptr oldacl, out intptr newacl); }
Comments
Post a Comment