1 # vgp_openssh_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/>.
19 from io
import BytesIO
20 from samba
.gp
.gpclass
import gp_xml_ext
, gp_file_applier
21 from samba
.common
import get_bytes
24 ### autogenerated by samba
26 # This file is generated by the vgp_openssh_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 # For each key value pair in sshd_config, the first obtained value will be
35 # used. We must insert config files in reverse, so that the last applied policy
37 def select_next_conf(directory
):
38 configs
= [re
.match(r
'(\d+)', f
) for f
in os
.listdir(directory
)]
39 conf_ids
= [int(m
.group(1)) for m
in configs
if m
]
40 conf_ids
.append(9000000000) # The starting node
41 conf_id
= min(conf_ids
)-1
42 return os
.path
.join(directory
, '%010d_gp.conf' % conf_id
)
44 class vgp_openssh_ext(gp_xml_ext
, gp_file_applier
):
46 return 'VGP/Unix Settings/OpenSSH'
48 def process_group_policy(self
, deleted_gpo_list
, changed_gpo_list
,
49 cfg_dir
='/etc/ssh/sshd_config.d'):
50 for guid
, settings
in deleted_gpo_list
:
51 if str(self
) in settings
:
52 for attribute
, sshd_config
in settings
[str(self
)].items():
53 self
.unapply(guid
, attribute
, sshd_config
)
55 for gpo
in changed_gpo_list
:
57 xml
= 'MACHINE/VGP/VTLA/SshCfg/SshD/manifest.xml'
58 path
= os
.path
.join(gpo
.file_sys_path
, xml
)
59 xml_conf
= self
.parse(path
)
62 policy
= xml_conf
.find('policysetting')
63 data
= policy
.find('data')
64 configfile
= data
.find('configfile')
65 for configsection
in configfile
.findall('configsection'):
66 if configsection
.find('sectionname').text
:
69 for kv
in configsection
.findall('keyvaluepair'):
70 settings
[kv
.find('key')] = kv
.find('value')
72 for k
, v
in settings
.items():
73 raw
.write(b
'%s %s\n' %
74 (get_bytes(k
.text
), get_bytes(v
.text
)))
75 # Each GPO applies only one set of OpenSSH settings, in a
76 # single file, so the attribute does not need uniqueness.
77 attribute
= self
.generate_attribute(gpo
.name
)
78 # The value hash is generated from the raw data we will
79 # write to the OpenSSH settings file, ensuring any changes
80 # to this GPO will cause the file to be rewritten.
81 value_hash
= self
.generate_value_hash(raw
.getvalue())
82 if not os
.path
.isdir(cfg_dir
):
83 os
.mkdir(cfg_dir
, 0o640)
84 def applier_func(cfg_dir
, raw
):
85 filename
= select_next_conf(cfg_dir
)
86 f
= open(filename
, 'wb')
88 f
.write(raw
.getvalue())
89 os
.chmod(filename
, 0o640)
92 self
.apply(gpo
.name
, attribute
, value_hash
, applier_func
,
99 xml
= 'MACHINE/VGP/VTLA/SshCfg/SshD/manifest.xml'
100 path
= os
.path
.join(gpo
.file_sys_path
, xml
)
101 xml_conf
= self
.parse(path
)
104 policy
= xml_conf
.find('policysetting')
105 data
= policy
.find('data')
106 configfile
= data
.find('configfile')
107 for configsection
in configfile
.findall('configsection'):
108 if configsection
.find('sectionname').text
:
110 for kv
in configsection
.findall('keyvaluepair'):
111 if str(self
) not in output
.keys():
112 output
[str(self
)] = {}
113 output
[str(self
)][kv
.find('key').text
] = \
114 kv
.find('value').text