1 # Unix SMB/CIFS implementation.
2 # Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 """Tests for samba.dcerpc.security."""
21 from samba
.dcerpc
import security
22 from samba
.security
import access_check
23 from samba
import ntstatus
24 from samba
import NTSTATUSError
27 class SecurityTokenTests(samba
.tests
.TestCase
):
31 self
.token
= security
.token()
33 def test_is_system(self
):
34 self
.assertFalse(self
.token
.is_system())
36 def test_is_anonymous(self
):
37 self
.assertFalse(self
.token
.is_anonymous())
39 def test_has_builtin_administrators(self
):
40 self
.assertFalse(self
.token
.has_builtin_administrators())
42 def test_has_nt_authenticated_users(self
):
43 self
.assertFalse(self
.token
.has_nt_authenticated_users())
45 def test_has_priv(self
):
46 self
.assertFalse(self
.token
.has_privilege(security
.SEC_PRIV_SHUTDOWN
))
48 def test_set_priv(self
):
49 self
.assertFalse(self
.token
.has_privilege(security
.SEC_PRIV_SHUTDOWN
))
50 self
.assertFalse(self
.token
.set_privilege(security
.SEC_PRIV_SHUTDOWN
))
51 self
.assertTrue(self
.token
.has_privilege(security
.SEC_PRIV_SHUTDOWN
))
54 class SecurityDescriptorTests(samba
.tests
.TestCase
):
58 self
.descriptor
= security
.descriptor()
60 def test_from_sddl(self
):
61 desc
= security
.descriptor
.from_sddl("O:AOG:DAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)",
62 security
.dom_sid("S-1-2-3"))
63 self
.assertEqual(desc
.group_sid
, security
.dom_sid('S-1-2-3-512'))
64 self
.assertEqual(desc
.owner_sid
, security
.dom_sid('S-1-5-32-548'))
65 self
.assertEqual(desc
.revision
, 1)
66 self
.assertEqual(desc
.sacl
, None)
67 self
.assertEqual(desc
.type, 0x8004)
69 def test_from_sddl_invalidsddl(self
):
70 self
.assertRaises(security
.SDDLValueError
, security
.descriptor
.from_sddl
, "foo",
71 security
.dom_sid("S-1-2-3"))
73 def test_from_sddl_invalidtype1(self
):
74 self
.assertRaises(TypeError, security
.descriptor
.from_sddl
, security
.dom_sid('S-1-2-3-512'),
75 security
.dom_sid("S-1-2-3"))
77 def test_from_sddl_invalidtype2(self
):
78 sddl
= "O:AOG:DAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)"
79 self
.assertRaises(TypeError, security
.descriptor
.from_sddl
, sddl
,
82 def test_as_sddl(self
):
83 text
= "O:AOG:DAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)"
84 dom
= security
.dom_sid("S-1-2-3")
85 desc1
= security
.descriptor
.from_sddl(text
, dom
)
86 desc2
= security
.descriptor
.from_sddl(desc1
.as_sddl(dom
), dom
)
87 self
.assertEqual(desc1
.group_sid
, desc2
.group_sid
)
88 self
.assertEqual(desc1
.owner_sid
, desc2
.owner_sid
)
89 self
.assertEqual(desc1
.sacl
, desc2
.sacl
)
90 self
.assertEqual(desc1
.type, desc2
.type)
92 def test_as_sddl_invalid(self
):
93 text
= "O:AOG:DAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)"
94 dom
= security
.dom_sid("S-1-2-3")
95 desc1
= security
.descriptor
.from_sddl(text
, dom
)
96 self
.assertRaises(TypeError, desc1
.as_sddl
, text
)
98 def test_as_sddl_no_domainsid(self
):
99 dom
= security
.dom_sid("S-1-2-3")
100 text
= "O:AOG:DAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)"
101 desc1
= security
.descriptor
.from_sddl(text
, dom
)
102 desc2
= security
.descriptor
.from_sddl(desc1
.as_sddl(), dom
)
103 self
.assertEqual(desc1
.group_sid
, desc2
.group_sid
)
104 self
.assertEqual(desc1
.owner_sid
, desc2
.owner_sid
)
105 self
.assertEqual(desc1
.sacl
, desc2
.sacl
)
106 self
.assertEqual(desc1
.type, desc2
.type)
108 def test_domsid_nodomsid_as_sddl(self
):
109 dom
= security
.dom_sid("S-1-2-3")
110 text
= "O:AOG:DAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)"
111 desc1
= security
.descriptor
.from_sddl(text
, dom
)
112 self
.assertNotEqual(desc1
.as_sddl(), desc1
.as_sddl(dom
))
114 def test_split(self
):
115 dom
= security
.dom_sid("S-1-0-7")
116 self
.assertEqual((security
.dom_sid("S-1-0"), 7), dom
.split())
119 class DomSidTests(samba
.tests
.TestCase
):
121 def test_parse_sid(self
):
122 sid
= security
.dom_sid("S-1-5-21")
123 self
.assertEqual("S-1-5-21", str(sid
))
125 def test_sid_equal(self
):
126 sid1
= security
.dom_sid("S-1-5-21")
127 sid2
= security
.dom_sid("S-1-5-21")
128 self
.assertEqual(sid1
, sid1
)
129 self
.assertEqual(sid1
, sid2
)
131 def test_random(self
):
132 sid
= security
.random_sid()
133 self
.assertTrue(str(sid
).startswith("S-1-5-21-"))
136 sid
= security
.random_sid()
137 self
.assertTrue(repr(sid
).startswith("dom_sid('S-1-5-21-"))
140 class PrivilegeTests(samba
.tests
.TestCase
):
142 def test_privilege_name(self
):
143 self
.assertEqual("SeShutdownPrivilege",
144 security
.privilege_name(security
.SEC_PRIV_SHUTDOWN
))
146 def test_privilege_id(self
):
147 self
.assertEqual(security
.SEC_PRIV_SHUTDOWN
,
148 security
.privilege_id("SeShutdownPrivilege"))
151 class CheckAccessTests(samba
.tests
.TestCase
):
153 def test_check_access(self
):
154 desc
= security
.descriptor
.from_sddl("O:AOG:DAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)",
155 security
.dom_sid("S-1-2-3"))
156 token
= security
.token()
158 self
.assertEqual(access_check(desc
, token
, 0), 0)
161 (security
.SEC_FLAG_SYSTEM_SECURITY
,
162 ntstatus
.NT_STATUS_PRIVILEGE_NOT_HELD
),
163 (security
.SEC_STD_READ_CONTROL
, ntstatus
.NT_STATUS_ACCESS_DENIED
)
166 for arg
, num
in params
:
168 result
= access_check(desc
, token
, arg
)
169 except Exception as e
:
170 self
.assertTrue(isinstance(e
, NTSTATUSError
))
171 e_num
, e_msg
= e
.args
172 self
.assertEqual(num
, e_num
)
177 class SecurityAceTests(samba
.tests
.TestCase
):
178 sddl
= "(OA;CIIO;RPWP;aaaaaaaa-1111-bbbb-2222-dddddddddddd;33333333-eeee-4444-ffff-555555555555;PS)"
179 sddl2
= "(OA;CIIO;RPWP;cccccccc-9999-ffff-8888-eeeeeeeeeeee;77777777-dddd-6666-bbbb-555555555555;PS)"
180 sddl3
= "(OA;CIIO;RPWP;aaaaaaaa-1111-bbbb-2222-dddddddddddd;77777777-dddd-6666-bbbb-555555555555;PS)"
181 sddl_uc
= "(OA;CIIO;RPWP;AAAAAAAA-1111-BBBB-2222-DDDDDDDDDDDD;33333333-EEEE-4444-FFFF-555555555555;PS)"
182 sddl_mc
= "(OA;CIIO;RPWP;AaAaAAAa-1111-BbBb-2222-DDddDDdDDDDD;33333333-EeeE-4444-FffF-555555555555;PS)"
183 sddl_sid
= "(OA;CIIO;RPWP;aaaaaaaa-1111-bbbb-2222-dddddddddddd;33333333-eeee-4444-ffff-555555555555;S-1-5-10)"
187 self
.dom
= security
.dom_sid("S-1-2-3")
189 def test_equality(self
):
190 ace
= security
.descriptor
.from_sddl("D:" + self
.sddl
, self
.dom
).dacl
.aces
[0]
191 ace2
= security
.descriptor
.from_sddl("D:" + self
.sddl2
, self
.dom
).dacl
.aces
[0]
192 ace3
= security
.descriptor
.from_sddl("D:" + self
.sddl3
, self
.dom
).dacl
.aces
[0]
193 ace_uc
= security
.descriptor
.from_sddl("D:" + self
.sddl_uc
, self
.dom
).dacl
.aces
[0]
194 ace_mc
= security
.descriptor
.from_sddl("D:" + self
.sddl_mc
, self
.dom
).dacl
.aces
[0]
195 ace_sid
= security
.descriptor
.from_sddl("D:" + self
.sddl_sid
, self
.dom
).dacl
.aces
[0]
196 self
.assertTrue(ace
== ace_uc
, "Case should not matter.")
197 self
.assertTrue(ace
== ace_mc
, "Case should not matter.")
198 self
.assertTrue(ace
!= ace2
, "Different ACEs should be unequal.")
199 self
.assertTrue(ace2
!= ace3
, "Different ACEs should be unequal.")
200 self
.assertTrue(ace
== ace_sid
, "Different ways of specifying SID should not matter.")
202 def test_as_sddl(self
):
203 ace
= security
.descriptor
.from_sddl("D:" + self
.sddl
, self
.dom
).dacl
.aces
[0]
204 ace_sddl
= ace
.as_sddl(self
.dom
)
205 # compare created SDDL with original one (we need to strip the parenthesis from the original
206 # since as_sddl does not create them)
207 self
.assertEqual(ace_sddl
, self
.sddl
[1:-1])
208 ace_new
= security
.descriptor
.from_sddl("D:(" + ace_sddl
+ ")", self
.dom
).dacl
.aces
[0]
209 self
.assertTrue(ace
== ace_new
, "Exporting ace as SDDl and reading back should result in same ACE.")