EditSecurity.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import os
  2. import win32com.server.policy
  3. import win32security, ntsecuritycon, win32con
  4. import pythoncom, win32api
  5. from win32com.authorization import authorization
  6. from ntsecuritycon import FILE_READ_ATTRIBUTES, FILE_READ_DATA, FILE_READ_EA, SYNCHRONIZE,\
  7. STANDARD_RIGHTS_READ, STANDARD_RIGHTS_WRITE, STANDARD_RIGHTS_EXECUTE, FILE_APPEND_DATA, \
  8. FILE_WRITE_ATTRIBUTES, FILE_WRITE_DATA, FILE_WRITE_EA, WRITE_OWNER, WRITE_DAC, READ_CONTROL, \
  9. SI_ADVANCED, SI_EDIT_AUDITS, SI_EDIT_PROPERTIES, SI_EDIT_ALL, SI_PAGE_TITLE, SI_RESET, \
  10. SI_ACCESS_SPECIFIC, SI_ACCESS_GENERAL, SI_ACCESS_CONTAINER, SI_ACCESS_PROPERTY, \
  11. FILE_ALL_ACCESS, FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, \
  12. OBJECT_INHERIT_ACE, CONTAINER_INHERIT_ACE, INHERIT_ONLY_ACE, \
  13. SI_PAGE_PERM, SI_PAGE_ADVPERM, SI_PAGE_AUDIT, SI_PAGE_OWNER, PSPCB_SI_INITDIALOG, \
  14. SI_CONTAINER
  15. from win32security import OBJECT_INHERIT_ACE, CONTAINER_INHERIT_ACE, INHERIT_ONLY_ACE
  16. from win32com.shell.shellcon import PSPCB_RELEASE, PSPCB_CREATE ## Msg parameter to PropertySheetPageCallback
  17. from pythoncom import IID_NULL
  18. class SecurityInformation(win32com.server.policy.DesignatedWrapPolicy):
  19. _com_interfaces_=[authorization.IID_ISecurityInformation]
  20. _public_methods_=['GetObjectInformation','GetSecurity','SetSecurity','GetAccessRights',
  21. 'GetInheritTypes','MapGeneric','PropertySheetPageCallback']
  22. def __init__(self, FileName):
  23. self.FileName=FileName
  24. self._wrap_(self)
  25. def GetObjectInformation(self):
  26. """Identifies object whose security will be modified, and determines options available
  27. to the end user"""
  28. flags=SI_ADVANCED|SI_EDIT_ALL|SI_PAGE_TITLE|SI_RESET
  29. if os.path.isdir(self.FileName):
  30. flags|=SI_CONTAINER
  31. hinstance=0 ## handle to module containing string resources
  32. servername='' ## name of authenticating server if not local machine
  33. objectname=os.path.split(self.FileName)[1]
  34. pagetitle='Python ACL Editor'
  35. if os.path.isdir(self.FileName):
  36. pagetitle+=' (dir)'
  37. else:
  38. pagetitle+=' (file)'
  39. objecttype=IID_NULL
  40. return flags, hinstance, servername, objectname, pagetitle, objecttype
  41. def GetSecurity(self, requestedinfo, bdefault):
  42. """Requests the existing permissions for object"""
  43. if bdefault:
  44. ## This is invoked if the 'Default' button is pressed (only present if SI_RESET is passed
  45. ## with the flags in GetObjectInfo). Passing an empty SD with a NULL Dacl
  46. ## should cause inherited ACL from parent dir or default dacl from user's token to be used
  47. return win32security.SECURITY_DESCRIPTOR()
  48. else:
  49. ## GetFileSecurity sometimes fails to return flags indicating that an ACE is inherited
  50. return win32security.GetNamedSecurityInfo(self.FileName, win32security.SE_FILE_OBJECT, requestedinfo)
  51. def SetSecurity(self, requestedinfo, sd):
  52. """Applies permissions to the object"""
  53. owner=sd.GetSecurityDescriptorOwner()
  54. group=sd.GetSecurityDescriptorGroup()
  55. dacl=sd.GetSecurityDescriptorDacl()
  56. sacl=sd.GetSecurityDescriptorSacl()
  57. win32security.SetNamedSecurityInfo(self.FileName, win32security.SE_FILE_OBJECT, requestedinfo,
  58. owner, group, dacl, sacl)
  59. ## should also handle recursive operations here
  60. def GetAccessRights(self, objecttype, flags):
  61. """Returns a tuple of (AccessRights, DefaultAccess), where AccessRights is a sequence of tuples representing
  62. SI_ACCESS structs, containing (guid, access mask, Name, flags). DefaultAccess indicates which of the
  63. AccessRights will be used initially when a new ACE is added (zero based).
  64. Flags can contain SI_ACCESS_SPECIFIC,SI_ACCESS_GENERAL,SI_ACCESS_CONTAINER,SI_ACCESS_PROPERTY,
  65. CONTAINER_INHERIT_ACE,INHERIT_ONLY_ACE,OBJECT_INHERIT_ACE
  66. """
  67. ## input flags: SI_ADVANCED,SI_EDIT_AUDITS,SI_EDIT_PROPERTIES indicating which property sheet is requesting the rights
  68. if (objecttype is not None) and (objecttype!=IID_NULL):
  69. ## Should not be true for file objects. Usually only used with DS objects that support security for
  70. ## their properties
  71. raise NotImplementedError("Object type is not supported")
  72. if os.path.isdir(self.FileName):
  73. file_append_data_desc='Create subfolders'
  74. file_write_data_desc='Create Files'
  75. else:
  76. file_append_data_desc='Append data'
  77. file_write_data_desc='Write data'
  78. accessrights=[(IID_NULL, FILE_GENERIC_READ, 'Generic read', SI_ACCESS_GENERAL|SI_ACCESS_SPECIFIC|OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
  79. (IID_NULL, FILE_GENERIC_WRITE, 'Generic write', SI_ACCESS_GENERAL|SI_ACCESS_SPECIFIC|OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
  80. (IID_NULL, win32con.DELETE, 'Delete', SI_ACCESS_SPECIFIC|OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
  81. (IID_NULL, WRITE_OWNER, 'Change owner', SI_ACCESS_SPECIFIC|OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
  82. (IID_NULL, READ_CONTROL,'Read Permissions', SI_ACCESS_SPECIFIC|OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
  83. (IID_NULL, WRITE_DAC, 'Change permissions', SI_ACCESS_SPECIFIC|OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
  84. (IID_NULL, FILE_APPEND_DATA, file_append_data_desc, SI_ACCESS_SPECIFIC|OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
  85. (IID_NULL, FILE_WRITE_DATA, file_write_data_desc, SI_ACCESS_SPECIFIC|OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)
  86. ]
  87. return (accessrights, 0)
  88. def MapGeneric(self, guid, aceflags, mask):
  89. """ Converts generic access rights to specific rights. This implementation uses standard file system rights,
  90. but you can map them any way that suits your application.
  91. """
  92. return win32security.MapGenericMask(mask, (FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, FILE_ALL_ACCESS))
  93. def GetInheritTypes(self):
  94. """Specifies which types of ACE inheritance are supported.
  95. Returns a sequence of tuples representing SI_INHERIT_TYPE structs, containing
  96. (object type guid, inheritance flags, display name). Guid is usually only used with
  97. Directory Service objects.
  98. """
  99. return ((IID_NULL, 0, 'Only current object'),
  100. (IID_NULL, OBJECT_INHERIT_ACE, 'Files inherit permissions'),
  101. (IID_NULL, CONTAINER_INHERIT_ACE, 'Sub Folders inherit permissions'),
  102. (IID_NULL, CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE, 'Files and subfolders'),
  103. )
  104. def PropertySheetPageCallback(self, hwnd, msg, pagetype):
  105. """Invoked each time a property sheet page is created or destroyed."""
  106. ## page types from SI_PAGE_TYPE enum: SI_PAGE_PERM SI_PAGE_ADVPERM SI_PAGE_AUDIT SI_PAGE_OWNER
  107. ## msg: PSPCB_CREATE, PSPCB_RELEASE, PSPCB_SI_INITDIALOG
  108. return None
  109. def EditSecurity(self, owner_hwnd=0):
  110. """Creates an ACL editor dialog based on parameters returned by interface methods"""
  111. isi=pythoncom.WrapObject(self, authorization.IID_ISecurityInformation, pythoncom.IID_IUnknown)
  112. authorization.EditSecurity(owner_hwnd, isi)
  113. ## folder permissions
  114. temp_dir=win32api.GetTempPath()
  115. dir_name=win32api.GetTempFileName(temp_dir,'isi')[0]
  116. print(dir_name)
  117. os.remove(dir_name)
  118. os.mkdir(dir_name)
  119. si=SecurityInformation(dir_name)
  120. si.EditSecurity()
  121. ## file permissions
  122. fname=win32api.GetTempFileName(dir_name,'isi')[0]
  123. si=SecurityInformation(fname)
  124. si.EditSecurity()