PEP8: fix E303: too many blank lines (2)
[nivanova/samba-autobuild/.git] / python / samba / netcmd / delegation.py
1 # delegation management
2 #
3 # Copyright Matthieu Patou mat@samba.org 2010
4 # Copyright Stefan Metzmacher metze@samba.org 2011
5 # Copyright Bjoern Baumbach bb@sernet.de 2011
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20
21 import samba.getopt as options
22 import ldb
23 from samba import provision
24 from samba import dsdb
25 from samba.samdb import SamDB
26 from samba.auth import system_session
27 from samba.netcmd.common import _get_user_realm_domain
28 from samba.netcmd import (
29     Command,
30     CommandError,
31     SuperCommand,
32     Option
33 )
34
35
36 class cmd_delegation_show(Command):
37     """Show the delegation setting of an account."""
38
39     synopsis = "%prog <accountname> [options]"
40
41     takes_optiongroups = {
42         "sambaopts": options.SambaOptions,
43         "credopts": options.CredentialsOptions,
44         "versionopts": options.VersionOptions,
45     }
46
47     takes_options = [
48         Option("-H", "--URL", help="LDB URL for database or target server", type=str,
49                metavar="URL", dest="H"),
50     ]
51
52     takes_args = ["accountname"]
53
54     def run(self, accountname, H=None, credopts=None, sambaopts=None, versionopts=None):
55         lp = sambaopts.get_loadparm()
56         creds = credopts.get_credentials(lp)
57         paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
58
59         if H == None:
60             path = paths.samdb
61         else:
62             path = H
63
64         sam = SamDB(path, session_info=system_session(),
65                     credentials=creds, lp=lp)
66         # TODO once I understand how, use the domain info to naildown
67         # to the correct domain
68         (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
69
70         res = sam.search(expression="sAMAccountName=%s" %
71                          ldb.binary_encode(cleanedaccount),
72                          scope=ldb.SCOPE_SUBTREE,
73                          attrs=["userAccountControl", "msDS-AllowedToDelegateTo"])
74         if len(res) == 0:
75             raise CommandError("Unable to find account name '%s'" % accountname)
76         assert(len(res) == 1)
77
78         uac = int(res[0].get("userAccountControl")[0])
79         allowed = res[0].get("msDS-AllowedToDelegateTo")
80
81         self.outf.write("Account-DN: %s\n" % str(res[0].dn))
82         self.outf.write("UF_TRUSTED_FOR_DELEGATION: %s\n"
83                         % bool(uac & dsdb.UF_TRUSTED_FOR_DELEGATION))
84         self.outf.write("UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION: %s\n" %
85                         bool(uac & dsdb.UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION))
86
87         if allowed is not None:
88             for a in allowed:
89                 self.outf.write("msDS-AllowedToDelegateTo: %s\n" % a)
90
91
92 class cmd_delegation_for_any_service(Command):
93     """Set/unset UF_TRUSTED_FOR_DELEGATION for an account."""
94
95     synopsis = "%prog <accountname> [(on|off)] [options]"
96
97     takes_optiongroups = {
98         "sambaopts": options.SambaOptions,
99         "credopts": options.CredentialsOptions,
100         "versionopts": options.VersionOptions,
101     }
102
103     takes_options = [
104         Option("-H", "--URL", help="LDB URL for database or target server", type=str,
105                metavar="URL", dest="H"),
106     ]
107
108     takes_args = ["accountname", "onoff"]
109
110     def run(self, accountname, onoff, H=None, credopts=None, sambaopts=None,
111             versionopts=None):
112
113         on = False
114         if onoff == "on":
115             on = True
116         elif onoff == "off":
117             on = False
118         else:
119             raise CommandError("invalid argument: '%s' (choose from 'on', 'off')" % onoff)
120
121         lp = sambaopts.get_loadparm()
122         creds = credopts.get_credentials(lp)
123         paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
124         if H == None:
125             path = paths.samdb
126         else:
127             path = H
128
129         sam = SamDB(path, session_info=system_session(),
130                     credentials=creds, lp=lp)
131         # TODO once I understand how, use the domain info to naildown
132         # to the correct domain
133         (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
134
135         search_filter = "sAMAccountName=%s" % ldb.binary_encode(cleanedaccount)
136         flag = dsdb.UF_TRUSTED_FOR_DELEGATION
137         try:
138             sam.toggle_userAccountFlags(search_filter, flag,
139                                         flags_str="Trusted-for-Delegation",
140                                         on=on, strict=True)
141         except Exception as err:
142             raise CommandError(err)
143
144
145 class cmd_delegation_for_any_protocol(Command):
146     """Set/unset UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION (S4U2Proxy) for an account."""
147
148     synopsis = "%prog <accountname> [(on|off)] [options]"
149
150     takes_optiongroups = {
151         "sambaopts": options.SambaOptions,
152         "credopts": options.CredentialsOptions,
153         "versionopts": options.VersionOptions,
154     }
155
156     takes_options = [
157         Option("-H", "--URL", help="LDB URL for database or target server", type=str,
158                metavar="URL", dest="H"),
159     ]
160
161     takes_args = ["accountname", "onoff"]
162
163     def run(self, accountname, onoff, H=None, credopts=None, sambaopts=None,
164             versionopts=None):
165
166         on = False
167         if onoff == "on":
168             on = True
169         elif onoff == "off":
170             on = False
171         else:
172             raise CommandError("invalid argument: '%s' (choose from 'on', 'off')" % onoff)
173
174         lp = sambaopts.get_loadparm()
175         creds = credopts.get_credentials(lp, fallback_machine=True)
176         paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
177         if H == None:
178             path = paths.samdb
179         else:
180             path = H
181
182         sam = SamDB(path, session_info=system_session(),
183                     credentials=creds, lp=lp)
184         # TODO once I understand how, use the domain info to naildown
185         # to the correct domain
186         (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
187
188         search_filter = "sAMAccountName=%s" % ldb.binary_encode(cleanedaccount)
189         flag = dsdb.UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION
190         try:
191             sam.toggle_userAccountFlags(search_filter, flag,
192                                         flags_str="Trusted-to-Authenticate-for-Delegation",
193                                         on=on, strict=True)
194         except Exception as err:
195             raise CommandError(err)
196
197
198 class cmd_delegation_add_service(Command):
199     """Add a service principal as msDS-AllowedToDelegateTo."""
200
201     synopsis = "%prog <accountname> <principal> [options]"
202
203     takes_optiongroups = {
204         "sambaopts": options.SambaOptions,
205         "credopts": options.CredentialsOptions,
206         "versionopts": options.VersionOptions,
207     }
208
209     takes_options = [
210         Option("-H", "--URL", help="LDB URL for database or target server", type=str,
211                metavar="URL", dest="H"),
212     ]
213
214     takes_args = ["accountname", "principal"]
215
216     def run(self, accountname, principal, H=None, credopts=None, sambaopts=None,
217             versionopts=None):
218
219         lp = sambaopts.get_loadparm()
220         creds = credopts.get_credentials(lp)
221         paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
222         if H == None:
223             path = paths.samdb
224         else:
225             path = H
226
227         sam = SamDB(path, session_info=system_session(),
228                     credentials=creds, lp=lp)
229         # TODO once I understand how, use the domain info to naildown
230         # to the correct domain
231         (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
232
233         res = sam.search(expression="sAMAccountName=%s" %
234                          ldb.binary_encode(cleanedaccount),
235                          scope=ldb.SCOPE_SUBTREE,
236                          attrs=["msDS-AllowedToDelegateTo"])
237         if len(res) == 0:
238             raise CommandError("Unable to find account name '%s'" % accountname)
239         assert(len(res) == 1)
240
241         msg = ldb.Message()
242         msg.dn = res[0].dn
243         msg["msDS-AllowedToDelegateTo"] = ldb.MessageElement([principal],
244                                                              ldb.FLAG_MOD_ADD,
245                                                              "msDS-AllowedToDelegateTo")
246         try:
247             sam.modify(msg)
248         except Exception as err:
249             raise CommandError(err)
250
251
252 class cmd_delegation_del_service(Command):
253     """Delete a service principal as msDS-AllowedToDelegateTo."""
254
255     synopsis = "%prog <accountname> <principal> [options]"
256
257     takes_optiongroups = {
258         "sambaopts": options.SambaOptions,
259         "credopts": options.CredentialsOptions,
260         "versionopts": options.VersionOptions,
261     }
262
263     takes_options = [
264         Option("-H", "--URL", help="LDB URL for database or target server", type=str,
265                metavar="URL", dest="H"),
266     ]
267
268     takes_args = ["accountname", "principal"]
269
270     def run(self, accountname, principal, H=None, credopts=None, sambaopts=None,
271             versionopts=None):
272
273         lp = sambaopts.get_loadparm()
274         creds = credopts.get_credentials(lp)
275         paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
276         if H == None:
277             path = paths.samdb
278         else:
279             path = H
280
281         sam = SamDB(path, session_info=system_session(),
282                     credentials=creds, lp=lp)
283         # TODO once I understand how, use the domain info to naildown
284         # to the correct domain
285         (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
286
287         res = sam.search(expression="sAMAccountName=%s" %
288                          ldb.binary_encode(cleanedaccount),
289                          scope=ldb.SCOPE_SUBTREE,
290                          attrs=["msDS-AllowedToDelegateTo"])
291         if len(res) == 0:
292             raise CommandError("Unable to find account name '%s'" % accountname)
293         assert(len(res) == 1)
294
295         msg = ldb.Message()
296         msg.dn = res[0].dn
297         msg["msDS-AllowedToDelegateTo"] = ldb.MessageElement([principal],
298                                                              ldb.FLAG_MOD_DELETE,
299                                                              "msDS-AllowedToDelegateTo")
300         try:
301             sam.modify(msg)
302         except Exception as err:
303             raise CommandError(err)
304
305
306 class cmd_delegation(SuperCommand):
307     """Delegation management."""
308
309     subcommands = {}
310     subcommands["show"] = cmd_delegation_show()
311     subcommands["for-any-service"] = cmd_delegation_for_any_service()
312     subcommands["for-any-protocol"] = cmd_delegation_for_any_protocol()
313     subcommands["add-service"] = cmd_delegation_add_service()
314     subcommands["del-service"] = cmd_delegation_del_service()