source: trunk/python/pyregfi/winsec.py @ 257

Last change on this file since 257 was 257, checked in by tim, 13 years ago

documentation fixes/additions

File size: 6.0 KB
Line 
1#!/usr/bin/env python
2
3## @package pyregfi.winsec
4# Low-level data structures for winsec library
5#
6
7import sys
8import os
9import uuid
10import ctypes
11import ctypes.util
12from ctypes import *
13from .structures import regfi
14
15is_win32 = hasattr(ctypes, 'windll')
16WINSEC_MAX_SUBAUTHS = 15
17
18if is_win32:
19    libc = cdll.msvcrt
20else:
21    libc = cdll.LoadLibrary("libc.so.6")
22
23class WINSEC_UUID(Structure):
24    pass
25
26class WINSEC_DOM_SID(Structure):
27    pass
28
29class WINSEC_ACE(Structure):
30    pass
31
32class WINSEC_ACL(Structure):
33    pass
34
35class WINSEC_DESC(Structure):
36    pass
37
38WINSEC_UUID._fields_ = [('time_low', c_uint32),
39                        ('time_mid', c_uint16),
40                        ('time_hi_and_version', c_uint16),
41                        ('clock_seq', c_uint8*2),
42                        ('node', c_uint8*6),
43                        ]
44
45WINSEC_DOM_SID._fields_ = [('sid_rev_num', c_uint8),
46                           ('num_auths', c_uint8),
47                           ('id_auths', c_uint8*6),
48                           ('sub_auths', c_uint32*WINSEC_MAX_SUBAUTHS),
49                           ]
50
51WINSEC_ACE._fields_ = [('type', c_uint8),
52                       ('flags', c_uint8),
53                       ('size', c_uint16),
54                       ('access_mask', c_uint32),
55                       ('obj_flags', c_uint32),
56                       ('obj_guid', POINTER(WINSEC_UUID)),
57                       ('inh_guid', POINTER(WINSEC_UUID)),
58                       ('trustee', POINTER(WINSEC_DOM_SID)),
59                       ]
60
61WINSEC_ACL._fields_ = [('revision', c_uint16),
62                       ('size', c_uint16),
63                       ('num_aces', c_uint32),
64                       ('aces', POINTER(POINTER(WINSEC_ACE))),
65                       ]
66
67WINSEC_DESC._fields_ = [('revision', c_uint8),
68                        ('sbz1', c_uint8),
69                        ('control', c_uint16),
70                        ('off_owner_sid', c_uint32),
71                        ('off_grp_sid', c_uint32),
72                        ('off_sacl', c_uint32),
73                        ('off_dacl', c_uint32),
74                        ('owner_sid', POINTER(WINSEC_DOM_SID)),
75                        ('grp_sid', POINTER(WINSEC_DOM_SID)),
76                        ('sacl', POINTER(WINSEC_ACL)),
77                        ('dacl', POINTER(WINSEC_ACL)),
78                        ]
79regfi.winsec_sid2str.argtypes = [POINTER(WINSEC_DOM_SID)]
80regfi.winsec_sid2str.restype = POINTER(c_char)
81
82
83def _guid2uuid(guid):
84    if not guid:
85        return None
86    return uuid.UUID(fields=(guid.contents.time_low,
87                             guid.contents.time_mid,
88                             guid.contents.time_hi_and_version,
89                             guid.contents.clock_seq[0],
90                             guid.contents.clock_seq[1],
91                             guid.contents.node[0]<<40
92                             ^ guid.contents.node[1]<<32
93                             ^ guid.contents.node[2]<<24
94                             ^ guid.contents.node[3]<<16
95                             ^ guid.contents.node[4]<<8
96                             ^ guid.contents.node[5]))
97
98## Represents a Microsoft access control entry, which are elements of access
99#  control lists.  For more information, see:
100#    http://msdn.microsoft.com/en-us/library/aa374868%28v=vs.85%29.aspx
101#
102#  @note
103#  This interface is subject to change
104class ACE(object):
105    ## The type of entry as an integer
106    type = 1234
107   
108    ## The flags as an integer
109    flags = 0x1234
110
111    ## The access mask/permissions as an integer
112    access_mask = 0x1234
113
114    ## The trustee's SID as a string
115    trustee = "S-1-2..."
116   
117    ## The object GUID as a Python UUID
118    # May be None
119    object = uuid.UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
120
121    ## The inherited object GUID as a Python UUID
122    # May be None
123    inherited_object = uuid.UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
124
125    def __init__(self, ace):
126        # Just copy all of the values out so we don't need to manage memory
127        self.object = _guid2uuid(ace.obj_guid)
128        self.inherited_object = _guid2uuid(ace.inh_guid)
129
130        c_str = regfi.winsec_sid2str(ace.trustee)
131        self.trustee = ctypes.cast(c_str, c_char_p).value.decode('utf-8', 'replace')
132        libc.free(c_str)
133
134        self.type = int(ace.type)
135        self.flags = int(ace.flags)
136        self.access_mask = int(ace.access_mask)
137
138
139## A Microsoft security descriptor
140# For more information, see:
141#   http://msdn.microsoft.com/en-us/library/aa379563%28v=vs.85%29.aspx
142#
143class SecurityDescriptor(object):
144    ## The security descriptor's owner SID, as a string
145    owner = "S-1-2-..."
146
147    ## The security descriptor's group SID, as a string
148    group = "S-1-2-..."
149
150    ## The system access control list represented as a list of @ref ACE objects.
151    #
152    # Is set to None if a sacl isn't defined
153    sacl = []
154
155    ## The discretionary access control list represented as a list of @ref ACE objects
156    #
157    # Is set to None if a dacl isn't defined
158    dacl = []
159
160    def __init__(self, sec_desc):
161        c_str = regfi.winsec_sid2str(sec_desc.owner_sid)
162        self.owner = ctypes.cast(c_str, c_char_p).value.decode('utf-8', 'replace')
163        libc.free(c_str)
164       
165        c_str = regfi.winsec_sid2str(sec_desc.grp_sid)
166        self.group = ctypes.cast(c_str, c_char_p).value.decode('utf-8', 'replace')
167        libc.free(c_str)
168
169        self.sacl = None
170        if sec_desc.sacl:
171            self.sacl = []
172            for i in range(0,sec_desc.sacl.contents.num_aces):
173                self.sacl.append(ACE(sec_desc.sacl.contents.aces[i].contents))
174
175        self.dacl = None
176        if sec_desc.dacl:
177            self.dacl = []
178            for i in range(0,sec_desc.dacl.contents.num_aces):
179                self.dacl.append(ACE(sec_desc.dacl.contents.aces[i].contents))
180
181
182# Free class objects used for documentation
183del ACE.type,ACE.flags,ACE.access_mask,ACE.object,ACE.inherited_object
184del SecurityDescriptor.owner,SecurityDescriptor.group,SecurityDescriptor.sacl,SecurityDescriptor.dacl
Note: See TracBrowser for help on using the repository browser.