1 # vgp_files_ext samba gpo policy
2 # Copyright (C) David Mulder <dmulder@suse.com> 2020
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 from samba
.gpclass
import gp_xml_ext
, check_safe_path
19 from tempfile
import NamedTemporaryFile
20 from shutil
import copyfile
, move
21 from hashlib
import blake2b
25 for permissions
in entry
.findall('permissions'):
26 ptype
= permissions
.get('type')
28 if permissions
.find('read') is not None:
30 if permissions
.find('write') is not None:
32 if permissions
.find('execute') is not None:
34 elif ptype
== 'group':
35 if permissions
.find('read') is not None:
37 if permissions
.find('write') is not None:
39 if permissions
.find('execute') is not None:
41 elif ptype
== 'other':
42 if permissions
.find('read') is not None:
44 if permissions
.find('write') is not None:
46 if permissions
.find('execute') is not None:
50 def stat_from_mode(mode
):
52 for i
in range(6, -1, -3):
53 mask
= {0o4: 'r', 0o2: 'w', 0o1: 'x'}
61 class vgp_files_ext(gp_xml_ext
):
63 return 'VGP/Unix Settings/Files'
65 def process_group_policy(self
, deleted_gpo_list
, changed_gpo_list
):
66 for guid
, settings
in deleted_gpo_list
:
67 self
.gp_db
.set_guid(guid
)
68 if str(self
) in settings
:
69 for attribute
, _
in settings
[str(self
)].items():
70 if os
.path
.exists(attribute
):
72 self
.gp_db
.delete(str(self
), attribute
)
75 for gpo
in changed_gpo_list
:
77 self
.gp_db
.set_guid(gpo
.name
)
78 xml
= 'MACHINE/VGP/VTLA/Unix/Files/manifest.xml'
79 path
= os
.path
.join(gpo
.file_sys_path
, xml
)
80 xml_conf
= self
.parse(path
)
83 policy
= xml_conf
.find('policysetting')
84 data
= policy
.find('data')
85 for entry
in data
.findall('file_properties'):
86 local_path
= self
.lp
.cache_path('gpo_cache')
87 source
= entry
.find('source').text
88 source_file
= os
.path
.join(local_path
,
89 os
.path
.dirname(check_safe_path(path
)).upper(),
91 if not os
.path
.exists(source_file
):
92 self
.logger
.warn('Source file "%s" does not exist'
96 blake2b(open(source_file
, 'rb').read()).hexdigest()
97 target
= entry
.find('target').text
98 user
= entry
.find('user').text
99 group
= entry
.find('group').text
100 mode
= calc_mode(entry
)
101 value
= '%s:%s:%s:%d' % (source_hash
, user
, group
, mode
)
102 old_val
= self
.gp_db
.retrieve(str(self
), target
)
105 if os
.path
.exists(target
):
106 self
.logger
.warn('Target file "%s" already exists'
109 with
NamedTemporaryFile(dir=os
.path
.dirname(target
),
111 copyfile(source_file
, f
.name
)
112 os
.chown(f
.name
, pwd
.getpwnam(user
).pw_uid
,
113 grp
.getgrnam(group
).gr_gid
)
114 os
.chmod(f
.name
, mode
)
116 self
.gp_db
.store(str(self
), target
, value
)
121 xml
= 'MACHINE/VGP/VTLA/Unix/Files/manifest.xml'
122 if gpo
.file_sys_path
:
123 path
= os
.path
.join(gpo
.file_sys_path
, xml
)
124 xml_conf
= self
.parse(path
)
127 policy
= xml_conf
.find('policysetting')
128 data
= policy
.find('data')
129 for entry
in data
.findall('file_properties'):
130 source
= entry
.find('source').text
131 target
= entry
.find('target').text
132 user
= entry
.find('user').text
133 group
= entry
.find('group').text
134 mode
= calc_mode(entry
)
135 p
= '%s\t%s\t%s\t%s -> %s' % \
136 (stat_from_mode(mode
), user
, group
, target
, source
)
137 if str(self
) not in output
.keys():
138 output
[str(self
)] = []
139 output
[str(self
)].append(p
)