PEP8: fix E128: continuation line under-indented for visual indent
[samba.git] / python / samba / tests / samba_tool / group.py
1 # Unix SMB/CIFS implementation.
2 # Copyright (C) Michael Adam 2012
3 #
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.
8 #
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.
13 #
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/>.
16 #
17
18 import os
19 import time
20 import ldb
21 from samba.tests.samba_tool.base import SambaToolCmdTest
22 from samba import (
23         nttime2unix,
24         dsdb
25         )
26
27 class GroupCmdTestCase(SambaToolCmdTest):
28     """Tests for samba-tool group subcommands"""
29     groups = []
30     samdb = None
31
32     def setUp(self):
33         super(GroupCmdTestCase, self).setUp()
34         self.samdb = self.getSamDB("-H", "ldap://%s" % os.environ["DC_SERVER"],
35                                    "-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"]))
36         self.groups = []
37         self.groups.append(self._randomGroup({"name": "testgroup1"}))
38         self.groups.append(self._randomGroup({"name": "testgroup2"}))
39         self.groups.append(self._randomGroup({"name": "testgroup3"}))
40         self.groups.append(self._randomGroup({"name": "testgroup4"}))
41
42         # setup the 4 groups and ensure they are correct
43         for group in self.groups:
44             (result, out, err) = self._create_group(group)
45
46             self.assertCmdSuccess(result, out, err)
47             self.assertEquals(err, "", "There shouldn't be any error message")
48             self.assertIn("Added group %s" % group["name"], out)
49
50             found = self._find_group(group["name"])
51
52             self.assertIsNotNone(found)
53
54             self.assertEquals("%s" % found.get("name"), group["name"])
55             self.assertEquals("%s" % found.get("description"), group["description"])
56
57     def tearDown(self):
58         super(GroupCmdTestCase, self).tearDown()
59         # clean up all the left over groups, just in case
60         for group in self.groups:
61             if self._find_group(group["name"]):
62                 self.runsubcmd("group", "delete", group["name"])
63
64
65     def test_newgroup(self):
66         """This tests the "group add" and "group delete" commands"""
67         # try to add all the groups again, this should fail
68         for group in self.groups:
69             (result, out, err) = self._create_group(group)
70             self.assertCmdFail(result, "Succeeded to create existing group")
71             self.assertIn("LDAP error 68 LDAP_ENTRY_ALREADY_EXISTS", err)
72
73         # try to delete all the groups we just added
74         for group in self.groups:
75             (result, out, err) = self.runsubcmd("group", "delete", group["name"])
76             self.assertCmdSuccess(result, out, err,
77                                   "Failed to delete group '%s'" % group["name"])
78             found = self._find_group(group["name"])
79             self.assertIsNone(found,
80                               "Deleted group '%s' still exists" % group["name"])
81
82         # test adding groups
83         for group in self.groups:
84             (result, out, err) =  self.runsubcmd("group", "add", group["name"],
85                                                  "--description=%s" % group["description"],
86                                                  "-H", "ldap://%s" % os.environ["DC_SERVER"],
87                                                  "-U%s%%%s" % (os.environ["DC_USERNAME"],
88                                                                os.environ["DC_PASSWORD"]))
89
90             self.assertCmdSuccess(result, out, err)
91             self.assertEquals(err,"","There shouldn't be any error message")
92             self.assertIn("Added group %s" % group["name"], out)
93
94             found = self._find_group(group["name"])
95
96             self.assertEquals("%s" % found.get("samaccountname"),
97                               "%s" % group["name"])
98
99
100     def test_list(self):
101         (result, out, err) = self.runsubcmd("group", "list",
102                                             "-H", "ldap://%s" % os.environ["DC_SERVER"],
103                                             "-U%s%%%s" % (os.environ["DC_USERNAME"],
104                                                           os.environ["DC_PASSWORD"]))
105         self.assertCmdSuccess(result, out, err, "Error running list")
106
107         search_filter = "(objectClass=group)"
108
109         grouplist = self.samdb.search(base=self.samdb.domain_dn(),
110                                       scope=ldb.SCOPE_SUBTREE,
111                                       expression=search_filter,
112                                       attrs=["samaccountname"])
113
114         self.assertTrue(len(grouplist) > 0, "no groups found in samdb")
115
116         for groupobj in grouplist:
117             name = groupobj.get("samaccountname", idx=0)
118             found = self.assertMatch(out, name,
119                                      "group '%s' not found" % name)
120
121     def test_listmembers(self):
122         (result, out, err) = self.runsubcmd("group", "listmembers", "Domain Users",
123                                             "-H", "ldap://%s" % os.environ["DC_SERVER"],
124                                             "-U%s%%%s" % (os.environ["DC_USERNAME"],
125                                                           os.environ["DC_PASSWORD"]))
126         self.assertCmdSuccess(result, out, err, "Error running listmembers")
127
128         search_filter = "(|(primaryGroupID=513)(memberOf=CN=Domain Users,CN=Users,%s))" % self.samdb.domain_dn()
129
130         grouplist = self.samdb.search(base=self.samdb.domain_dn(),
131                                       scope=ldb.SCOPE_SUBTREE,
132                                       expression=search_filter,
133                                       attrs=["samAccountName"])
134
135         self.assertTrue(len(grouplist) > 0, "no groups found in samdb")
136
137         for groupobj in grouplist:
138             name = groupobj.get("samAccountName", idx=0)
139             found = self.assertMatch(out, name, "group '%s' not found" % name)
140
141     def test_move(self):
142         full_ou_dn = str(self.samdb.normalize_dn_in_domain("OU=movetest"))
143         (result, out, err) =  self.runsubcmd("ou", "create", full_ou_dn)
144         self.assertCmdSuccess(result, out, err)
145         self.assertEquals(err, "", "There shouldn't be any error message")
146         self.assertIn('Created ou "%s"' % full_ou_dn, out)
147
148         for group in self.groups:
149             (result, out, err) = self.runsubcmd(
150                 "group", "move", group["name"], full_ou_dn)
151             self.assertCmdSuccess(result, out, err, "Error running move")
152             self.assertIn('Moved group "%s" into "%s"' %
153                           (group["name"], full_ou_dn), out)
154
155         # Should fail as groups objects are in OU
156         (result, out, err) =  self.runsubcmd("ou", "delete", full_ou_dn)
157         self.assertCmdFail(result)
158         self.assertIn(("subtree_delete: Unable to delete a non-leaf node "
159                        "(it has %d children)!") % len(self.groups), err)
160
161         for group in self.groups:
162             new_dn = "CN=Users,%s" % self.samdb.domain_dn()
163             (result, out, err) = self.runsubcmd(
164                 "group", "move", group["name"], new_dn)
165             self.assertCmdSuccess(result, out, err, "Error running move")
166             self.assertIn('Moved group "%s" into "%s"' %
167                           (group["name"], new_dn), out)
168
169         (result, out, err) = self.runsubcmd("ou", "delete", full_ou_dn)
170         self.assertCmdSuccess(result, out, err,
171                               "Failed to delete ou '%s'" % full_ou_dn)
172
173     def test_show(self):
174         """Assert that we can show a group correctly."""
175         (result, out, err) = self.runsubcmd("group", "show", "Domain Users",
176                                             "-H", "ldap://%s" % os.environ["DC_SERVER"],
177                                             "-U%s%%%s" % (os.environ["DC_USERNAME"],
178                                                           os.environ["DC_PASSWORD"]))
179         self.assertCmdSuccess(result, out, err)
180         self.assertEquals(err,"","Shouldn't be any error messages")
181         self.assertIn("dn: CN=Domain Users,CN=Users,DC=samba,DC=example,DC=com", out)
182
183     def _randomGroup(self, base={}):
184         """create a group with random attribute values, you can specify base attributes"""
185         group = {
186             "name": self.randomName(),
187             "description": self.randomName(count=100),
188         }
189         group.update(base)
190         return group
191
192     def _create_group(self, group):
193         return self.runsubcmd("group", "add", group["name"],
194                               "--description=%s" % group["description"],
195                               "-H", "ldap://%s" % os.environ["DC_SERVER"],
196                               "-U%s%%%s" % (os.environ["DC_USERNAME"],
197                                             os.environ["DC_PASSWORD"]))
198
199     def _find_group(self, name):
200         search_filter = ("(&(sAMAccountName=%s)(objectCategory=%s,%s))" %
201                          (ldb.binary_encode(name),
202                           "CN=Group,CN=Schema,CN=Configuration",
203                           self.samdb.domain_dn()))
204         grouplist = self.samdb.search(base=self.samdb.domain_dn(),
205                                       scope=ldb.SCOPE_SUBTREE,
206                                       expression=search_filter,
207                                       attrs=[])
208         if grouplist:
209             return grouplist[0]
210         else:
211             return None