ctdb: Save a few lines with talloc_zero()
[samba4-gss.git] / python / samba / gp / gp_sec_ext.py
blob39b9cdced83c5ca3e86f9f144079eafbd58c6ac4
1 # gp_sec_ext kdc gpo policy
2 # Copyright (C) Luke Morrison <luc785@.hotmail.com> 2013
3 # Copyright (C) David Mulder <dmulder@suse.com> 2018
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 import os.path
19 from samba.gp.gpclass import gp_inf_ext
20 from samba.auth import system_session
21 from samba.common import get_string
22 try:
23 from ldb import LdbError
24 from samba.samdb import SamDB
25 except ImportError:
26 pass
27 from samba.gp.util.logging import log
29 def mins_to_hours(val):
30 return '%d' % (int(val) / 60)
32 def days_to_hours(val):
33 return '%d' % (int(val) * 24)
35 def days2rel_nttime(val):
36 seconds = 60
37 minutes = 60
38 hours = 24
39 sam_add = 10000000
40 val = int(val)
41 return str(-(val * seconds * minutes * hours * sam_add))
43 class gp_krb_ext(gp_inf_ext):
44 apply_map = { 'MaxTicketAge': 'kdc:user_ticket_lifetime',
45 'MaxServiceAge': 'kdc:service_ticket_lifetime',
46 'MaxRenewAge': 'kdc:renewal_lifetime' }
47 def process_group_policy(self, deleted_gpo_list, changed_gpo_list):
48 if self.lp.get('server role') != 'active directory domain controller':
49 return
50 inf_file = 'MACHINE/Microsoft/Windows NT/SecEdit/GptTmpl.inf'
51 for guid, settings in deleted_gpo_list:
52 self.gp_db.set_guid(guid)
53 for section in settings.keys():
54 if section == str(self):
55 for att, value in settings[section].items():
56 self.set_kdc_tdb(att, value)
57 self.gp_db.delete(section, att)
58 self.gp_db.commit()
60 for gpo in changed_gpo_list:
61 if gpo.file_sys_path:
62 self.gp_db.set_guid(gpo.name)
63 path = os.path.join(gpo.file_sys_path, inf_file)
64 inf_conf = self.parse(path)
65 if not inf_conf:
66 continue
67 for section in inf_conf.sections():
68 if section == str(self):
69 for key, value in inf_conf.items(section):
70 if key not in gp_krb_ext.apply_map:
71 continue
72 att = gp_krb_ext.apply_map[key]
73 value_func = self.mapper().get(att)
74 self.set_kdc_tdb(att, value_func(value))
75 self.gp_db.commit()
77 def set_kdc_tdb(self, attribute, val):
78 old_val = self.gp_db.gpostore.get(attribute)
79 log.info('%s was changed from %s to %s' % (attribute, old_val, val))
80 if val is not None:
81 self.gp_db.gpostore.store(attribute, get_string(val))
82 self.gp_db.store(str(self), attribute, get_string(old_val)
83 if old_val else None)
84 else:
85 self.gp_db.gpostore.delete(attribute)
86 self.gp_db.delete(str(self), attribute)
88 def mapper(self):
89 return {'kdc:user_ticket_lifetime': lambda val: val,
90 'kdc:service_ticket_lifetime': mins_to_hours,
91 'kdc:renewal_lifetime': days_to_hours,
94 def __str__(self):
95 return 'Kerberos Policy'
97 def rsop(self, gpo):
98 output = {}
99 if self.lp.get('server role') != 'active directory domain controller':
100 return output
101 inf_file = 'MACHINE/Microsoft/Windows NT/SecEdit/GptTmpl.inf'
102 if gpo.file_sys_path:
103 path = os.path.join(gpo.file_sys_path, inf_file)
104 inf_conf = self.parse(path)
105 if not inf_conf:
106 return output
107 if str(self) in inf_conf.sections():
108 section = str(self)
109 output[section] = {k: v for k, v in inf_conf.items(section)
110 if gp_krb_ext.apply_map.get(k)}
111 return output
114 class gp_access_ext(gp_inf_ext):
115 """This class takes the .inf file parameter (essentially a GPO file mapped
116 to a GUID), hashmaps it to the Samba parameter, which then uses an ldb
117 object to update the parameter to Samba4. Not registry oriented whatsoever.
120 def load_ldb(self):
121 try:
122 self.ldb = SamDB(self.lp.samdb_url(),
123 session_info=system_session(),
124 credentials=self.creds,
125 lp=self.lp)
126 except (NameError, LdbError):
127 raise Exception('Failed to load SamDB for assigning Group Policy')
129 apply_map = { 'MinimumPasswordAge': 'minPwdAge',
130 'MaximumPasswordAge': 'maxPwdAge',
131 'MinimumPasswordLength': 'minPwdLength',
132 'PasswordComplexity': 'pwdProperties' }
133 def process_group_policy(self, deleted_gpo_list, changed_gpo_list):
134 if self.lp.get('server role') != 'active directory domain controller':
135 return
136 self.load_ldb()
137 inf_file = 'MACHINE/Microsoft/Windows NT/SecEdit/GptTmpl.inf'
138 for guid, settings in deleted_gpo_list:
139 self.gp_db.set_guid(guid)
140 for section in settings.keys():
141 if section == str(self):
142 for att, value in settings[section].items():
143 update_samba, _ = self.mapper().get(att)
144 update_samba(att, value)
145 self.gp_db.delete(section, att)
146 self.gp_db.commit()
148 for gpo in changed_gpo_list:
149 if gpo.file_sys_path:
150 self.gp_db.set_guid(gpo.name)
151 path = os.path.join(gpo.file_sys_path, inf_file)
152 inf_conf = self.parse(path)
153 if not inf_conf:
154 continue
155 for section in inf_conf.sections():
156 if section == str(self):
157 for key, value in inf_conf.items(section):
158 if key not in gp_access_ext.apply_map:
159 continue
160 att = gp_access_ext.apply_map[key]
161 (update_samba, value_func) = self.mapper().get(att)
162 update_samba(att, value_func(value))
163 self.gp_db.commit()
165 def ch_minPwdAge(self, attribute, val):
166 old_val = self.ldb.get_minPwdAge()
167 log.info('KDC Minimum Password age was changed from %s to %s'
168 % (old_val, val))
169 self.gp_db.store(str(self), attribute, str(old_val))
170 self.ldb.set_minPwdAge(val)
172 def ch_maxPwdAge(self, attribute, val):
173 old_val = self.ldb.get_maxPwdAge()
174 log.info('KDC Maximum Password age was changed from %s to %s'
175 % (old_val, val))
176 self.gp_db.store(str(self), attribute, str(old_val))
177 self.ldb.set_maxPwdAge(val)
179 def ch_minPwdLength(self, attribute, val):
180 old_val = self.ldb.get_minPwdLength()
181 log.info('KDC Minimum Password length was changed from %s to %s'
182 % (old_val, val))
183 self.gp_db.store(str(self), attribute, str(old_val))
184 self.ldb.set_minPwdLength(val)
186 def ch_pwdProperties(self, attribute, val):
187 old_val = self.ldb.get_pwdProperties()
188 log.info('KDC Password Properties were changed from %s to %s'
189 % (old_val, val))
190 self.gp_db.store(str(self), attribute, str(old_val))
191 self.ldb.set_pwdProperties(val)
193 def mapper(self):
194 """ldap value : samba setter"""
195 return {"minPwdAge": (self.ch_minPwdAge, days2rel_nttime),
196 "maxPwdAge": (self.ch_maxPwdAge, days2rel_nttime),
197 # Could be none, but I like the method assignment in
198 # update_samba
199 "minPwdLength": (self.ch_minPwdLength, lambda val: val),
200 "pwdProperties": (self.ch_pwdProperties, lambda val: val),
204 def __str__(self):
205 return 'System Access'
207 def rsop(self, gpo):
208 output = {}
209 if self.lp.get('server role') != 'active directory domain controller':
210 return output
211 inf_file = 'MACHINE/Microsoft/Windows NT/SecEdit/GptTmpl.inf'
212 if gpo.file_sys_path:
213 path = os.path.join(gpo.file_sys_path, inf_file)
214 inf_conf = self.parse(path)
215 if not inf_conf:
216 return output
217 if str(self) in inf_conf.sections():
218 section = str(self)
219 output[section] = {k: v for k, v in inf_conf.items(section)
220 if gp_access_ext.apply_map.get(k)}
221 return output