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
.gp
.gpclass
import gp_xml_ext
, check_safe_path
, gp_file_applier
19 from tempfile
import NamedTemporaryFile
20 from shutil
import copyfile
, move
21 from samba
.gp
.util
.logging
import log
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 def source_file_change(fname
):
62 if os
.path
.exists(fname
):
63 return b
'%d' % os
.stat(fname
).st_ctime
65 class vgp_files_ext(gp_xml_ext
, gp_file_applier
):
67 return 'VGP/Unix Settings/Files'
69 def process_group_policy(self
, deleted_gpo_list
, changed_gpo_list
):
70 for guid
, settings
in deleted_gpo_list
:
71 if str(self
) in settings
:
72 for attribute
, _
in settings
[str(self
)].items():
73 self
.unapply(guid
, attribute
, attribute
)
75 for gpo
in changed_gpo_list
:
77 xml
= 'MACHINE/VGP/VTLA/Unix/Files/manifest.xml'
78 path
= os
.path
.join(gpo
.file_sys_path
, xml
)
79 xml_conf
= self
.parse(path
)
82 policy
= xml_conf
.find('policysetting')
83 data
= policy
.find('data')
84 for entry
in data
.findall('file_properties'):
85 local_path
= self
.lp
.cache_path('gpo_cache')
86 source
= entry
.find('source').text
87 source_file
= os
.path
.join(local_path
,
88 os
.path
.dirname(check_safe_path(path
)).upper(),
90 if not os
.path
.exists(source_file
):
91 log
.warn('Source file does not exist', source_file
)
93 target
= entry
.find('target').text
94 user
= entry
.find('user').text
95 group
= entry
.find('group').text
96 mode
= calc_mode(entry
)
98 # The attribute is simply the target file.
100 # The value hash is generated from the source file last
101 # change stamp, the user, the group, and the mode, ensuring
102 # any changes to this GPO will cause the file to be
104 value_hash
= self
.generate_value_hash(
105 source_file_change(source_file
),
106 user
, group
, b
'%d' % mode
)
107 def applier_func(source_file
, target
, user
, group
, mode
):
108 with
NamedTemporaryFile(dir=os
.path
.dirname(target
),
110 copyfile(source_file
, f
.name
)
111 os
.chown(f
.name
, pwd
.getpwnam(user
).pw_uid
,
112 grp
.getgrnam(group
).gr_gid
)
113 os
.chmod(f
.name
, mode
)
116 self
.apply(gpo
.name
, attribute
, value_hash
, applier_func
,
117 source_file
, target
, user
, group
, mode
)
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
)