1 # vgp_access_ext samba group 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
19 from hashlib
import blake2b
20 from tempfile
import NamedTemporaryFile
21 from samba
.common
import get_bytes
24 ### autogenerated by samba
26 # This file is generated by the vgp_access_ext Group Policy
27 # Client Side Extension. To modify the contents of this file,
28 # modify the appropriate Group Policy objects which apply
29 # to this machine. DO NOT MODIFY THIS FILE DIRECTLY.
34 # Access files in /etc/security/access.d are read in the order of the system
35 # locale. Here we number the conf files to ensure they are read in the correct
37 def select_next_conf(directory
):
38 configs
= [re
.match(r
'(\d+)', f
) for f
in os
.listdir(directory
)]
39 return max([int(m
.group(1)) for m
in configs
if m
]+[0])+1
41 class vgp_access_ext(gp_xml_ext
):
43 return 'VGP/Unix Settings/Host Access'
45 def process_group_policy(self
, deleted_gpo_list
, changed_gpo_list
,
46 access
='/etc/security/access.d'):
47 for guid
, settings
in deleted_gpo_list
:
48 self
.gp_db
.set_guid(guid
)
49 if str(self
) in settings
:
50 for attribute
, access_file
in settings
[str(self
)].items():
51 if os
.path
.exists(access_file
):
52 os
.unlink(access_file
)
53 self
.gp_db
.delete(str(self
), attribute
)
56 for gpo
in changed_gpo_list
:
58 self
.gp_db
.set_guid(gpo
.name
)
59 allow
= 'MACHINE/VGP/VTLA/VAS/HostAccessControl/Allow/manifest.xml'
60 path
= os
.path
.join(gpo
.file_sys_path
, allow
)
61 allow_conf
= self
.parse(path
)
62 deny
= 'MACHINE/VGP/VTLA/VAS/HostAccessControl/Deny/manifest.xml'
63 path
= os
.path
.join(gpo
.file_sys_path
, deny
)
64 deny_conf
= self
.parse(path
)
67 policy
= allow_conf
.find('policysetting')
68 data
= policy
.find('data')
69 for listelement
in data
.findall('listelement'):
70 adobject
= listelement
.find('adobject')
71 name
= adobject
.find('name').text
72 domain
= adobject
.find('domain').text
73 entries
.append('+:%s\\%s:ALL' % (domain
, name
))
75 policy
= deny_conf
.find('policysetting')
76 data
= policy
.find('data')
77 for listelement
in data
.findall('listelement'):
78 adobject
= listelement
.find('adobject')
79 name
= adobject
.find('name').text
80 domain
= adobject
.find('domain').text
81 entries
.append('-:%s\\%s:ALL' % (domain
, name
))
84 conf_id
= select_next_conf(access
)
85 access_file
= os
.path
.join(access
, '%010d_gp.conf' % conf_id
)
86 access_contents
= '\n'.join(entries
)
87 attribute
= blake2b(get_bytes(access_contents
)).hexdigest()
88 old_val
= self
.gp_db
.retrieve(str(self
), attribute
)
89 if old_val
is not None:
91 if not os
.path
.isdir(access
):
92 os
.mkdir(access
, 0o644)
93 with
NamedTemporaryFile(delete
=False, dir=access
) as f
:
94 with
open(f
.name
, 'w') as w
:
96 w
.write(access_contents
)
97 os
.chmod(f
.name
, 0o644)
98 os
.rename(f
.name
, access_file
)
99 self
.gp_db
.store(str(self
), attribute
, access_file
)
104 if gpo
.file_sys_path
:
105 self
.gp_db
.set_guid(gpo
.name
)
106 allow
= 'MACHINE/VGP/VTLA/VAS/HostAccessControl/Allow/manifest.xml'
107 path
= os
.path
.join(gpo
.file_sys_path
, allow
)
108 allow_conf
= self
.parse(path
)
109 deny
= 'MACHINE/VGP/VTLA/VAS/HostAccessControl/Deny/manifest.xml'
110 path
= os
.path
.join(gpo
.file_sys_path
, deny
)
111 deny_conf
= self
.parse(path
)
114 policy
= allow_conf
.find('policysetting')
115 data
= policy
.find('data')
116 for listelement
in data
.findall('listelement'):
117 adobject
= listelement
.find('adobject')
118 name
= adobject
.find('name').text
119 domain
= adobject
.find('domain').text
120 if str(self
) not in output
.keys():
121 output
[str(self
)] = []
122 output
[str(self
)].append('+:%s\\%s:ALL' % (name
, domain
))
124 policy
= deny_conf
.find('policysetting')
125 data
= policy
.find('data')
126 for listelement
in data
.findall('listelement'):
127 adobject
= listelement
.find('adobject')
128 name
= adobject
.find('name').text
129 domain
= adobject
.find('domain').text
130 if str(self
) not in output
.keys():
131 output
[str(self
)] = []
132 output
[str(self
)].append('-:%s\\%s:ALL' % (name
, domain
))