s4:smbtorture: Fix samba3.smb.dir on btrfs
[samba4-gss.git] / python / samba / gp / gp_smb_conf_ext.py
blob3ef9cfdf2b4c4f39d6de8aca7281593950ca590f
1 # gp_smb_conf_ext smb.conf gpo policy
2 # Copyright (C) David Mulder <dmulder@suse.com> 2018
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/>.
17 import os, numbers
18 from samba.gp.gpclass import gp_pol_ext, gp_misc_applier
19 from tempfile import NamedTemporaryFile
20 from samba.gp.util.logging import log
22 def is_number(x):
23 return isinstance(x, numbers.Number) and \
24 type(x) != bool
26 class gp_smb_conf_ext(gp_pol_ext, gp_misc_applier):
27 def unapply(self, guid, attribute, val):
28 current = self.lp.get(attribute)
29 data = self.parse_value(val)
31 # Only overwrite the smb.conf setting if it hasn't been modified. It
32 # may have been modified by another GPO.
33 if 'new_val' not in data or \
34 self.lptype_to_string(current) == data['new_val']:
35 self.lp.set(attribute, self.regtype_to_lptype(data['old_val'],
36 current))
37 self.store_lp_smb_conf(self.lp)
38 log.info('smb.conf [global] was changed',
39 { attribute : str(data['old_val']) })
41 self.cache_remove_attribute(guid, attribute)
43 def apply(self, guid, attribute, val):
44 old_val = self.lp.get(attribute)
45 val = self.regtype_to_lptype(val, old_val)
47 self.lp.set(attribute, val)
48 self.store_lp_smb_conf(self.lp)
49 log.info('smb.conf [global] was changed', { attribute : str(val) })
51 data = self.generate_value(old_val=self.lptype_to_string(old_val),
52 new_val=self.lptype_to_string(val))
53 self.cache_add_attribute(guid, attribute, data)
55 def process_group_policy(self, deleted_gpo_list, changed_gpo_list):
56 pol_file = 'MACHINE/Registry.pol'
57 for guid, settings in deleted_gpo_list:
58 smb_conf = settings.get('smb.conf')
59 if smb_conf is None:
60 continue
61 for key, value in smb_conf.items():
62 self.unapply(guid, key, value)
64 for gpo in changed_gpo_list:
65 if gpo.file_sys_path:
66 section_name = 'Software\\Policies\\Samba\\smb_conf'
67 path = os.path.join(gpo.file_sys_path, pol_file)
68 pol_conf = self.parse(path)
69 if not pol_conf:
70 continue
71 attrs = []
72 for e in pol_conf.entries:
73 if not e.keyname.startswith(section_name):
74 continue
75 attrs.append(e.valuename)
76 self.apply(gpo.name, e.valuename, e.data)
78 # Cleanup settings which were removed from the policy
79 self.clean(gpo.name, keep=attrs)
81 def regtype_to_lptype(self, val, old_val):
82 if type(val) == bytes:
83 val = val.decode()
84 if is_number(val) and is_number(old_val):
85 val = str(val)
86 elif is_number(val) and type(old_val) == bool:
87 val = bool(val)
88 if type(val) == bool:
89 val = 'yes' if val else 'no'
90 return val
92 def store_lp_smb_conf(self, lp):
93 with NamedTemporaryFile(delete=False,
94 dir=os.path.dirname(lp.configfile)) as f:
95 lp.dump(False, f.name)
96 mode = os.stat(lp.configfile).st_mode
97 os.chmod(f.name, mode)
98 os.rename(f.name, lp.configfile)
100 def lptype_to_string(self, val):
101 if is_number(val):
102 val = str(val)
103 elif type(val) == bool:
104 val = 'yes' if val else 'no'
105 elif type(val) == list:
106 val = ' '.join(val)
107 return val
109 def __str__(self):
110 return "smb.conf"
112 def rsop(self, gpo):
113 output = {}
114 if gpo.file_sys_path:
115 section_name = 'Software\\Policies\\Samba\\smb_conf'
116 pol_file = 'MACHINE/Registry.pol'
117 path = os.path.join(gpo.file_sys_path, pol_file)
118 pol_conf = self.parse(path)
119 if not pol_conf:
120 return output
121 for e in pol_conf.entries:
122 if not e.keyname.startswith(section_name):
123 continue
124 if 'smb.conf' not in output.keys():
125 output['smb.conf'] = {}
126 output['smb.conf'][e.valuename] = e.data
127 return output