web2ldap  1.7.7
About: web2ldap is a full-featured web-based LDAPv3 client.
  Fossies Dox: web2ldap-1.7.7.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

samba.py
Go to the documentation of this file.
1# -*- coding: ascii -*-
2"""
3web2ldap plugin classes for Samba 3
4"""
5
6import string
7import re
8from typing import Dict
9
10import ldap0
11import ldap0.filter
12
13from ..schema.syntaxes import (
14 DirectoryString,
15 SelectList,
16 SecondsSinceEpoch,
17 IA5String,
18 DynamicValueSelectList,
19 syntax_registry,
20)
21from .activedirectory import LogonHours
22
23
24syntax_registry.reg_at(
25 SecondsSinceEpoch.oid, [
26 '1.3.6.1.4.1.7165.2.1.3', # pwdLastSet
27 '1.3.6.1.4.1.7165.2.1.5', # logonTime
28 '1.3.6.1.4.1.7165.2.1.6', # logoffTime
29 '1.3.6.1.4.1.7165.2.1.7', # kickoffTime
30 '1.3.6.1.4.1.7165.2.1.8', # pwdCanChange
31 '1.3.6.1.4.1.7165.2.1.9', # pwdMustChange
32 '1.3.6.1.4.1.7165.2.1.27', # sambaPwdLastSet
33 '1.3.6.1.4.1.7165.2.1.28', # sambaPwdCanChange
34 '1.3.6.1.4.1.7165.2.1.29', # sambaPwdMustChange
35 '1.3.6.1.4.1.7165.2.1.30', # sambaLogonTime
36 '1.3.6.1.4.1.7165.2.1.31', # sambaLogoffTime
37 '1.3.6.1.4.1.7165.2.1.32', # sambaKickoffTime
38 ]
39)
40
41
42syntax_registry.reg_at(
43 LogonHours.oid, [
44 '1.3.6.1.4.1.7165.2.1.55', # sambaLogonHours
45 ]
46)
47
48
50 oid: str = 'SambaAcctFlags-oid'
51 desc: str = 'Samba 3 account flags'
52 input_pattern: str = r'^\[[NDHTUMWSLXI ]{0,16}\]$'
53 pattern = re.compile(input_pattern)
54 flags_dict = {
55 'N': '<b>N</b>o password.',
56 'D': '<b>D</b>isabled.',
57 'H': '<b>H</b>omedir required.',
58 'T': '<b>T</b>emp account.',
59 'U': '<b>U</b>ser account (normal)',
60 'M': '<b>M</b>NS logon user account.',
61 'W': '<b>W</b>orkstation account.',
62 'S': '<b>S</b>erver account.',
63 'L': '<b>L</b>ocked account.',
64 'X': 'No <b>X</b>piry on password',
65 'I': '<b>I</b>nterdomain trust account.',
66 }
67
68 def display(self, vidx, links) -> str:
69 flags = self.av_u[1:-1] # trim brackets
70 table_rows = [
71 '<tr><td>%s</td><td>%s</td></tr>\n' % ({True:'*', False:''}[f in flags], d)
72 for f, d in self.flags_dict.items()
73 ]
74 return '<pre>%s</pre><table>\n%s\n</table>\n' % (
75 self._app.form.s2d(self.av_u),
76 ''.join(table_rows)
77 )
78
79syntax_registry.reg_at(
80 SambaAcctFlags.oid, [
81 '1.3.6.1.4.1.7165.2.1.26', # sambaAcctFlags
82 '1.3.6.1.4.1.7165.2.1.4', # acctFlags
83 ]
84)
85
86
88 oid: str = 'SambaSID-oid'
89 desc: str = 'Samba SID (SDDL syntax)'
90 input_pattern: str = r'^S(-[0-9]+)+$'
91 pattern = re.compile(input_pattern)
92
93 def _search_domain_entry(self, domain_name):
94 if domain_name:
95 domain_filter = '(&(objectClass=sambaDomain)(sambaDomainName=%s))' % (
96 ldap0.filter.escape_str(domain_name)
97 )
98 else:
99 domain_filter = '(objectClass=sambaDomain)'
100 try:
101 ldap_result = self._app.ls.l.search_s(
102 self._app.naming_context.encode(self._app.ls.charset),
103 ldap0.SCOPE_SUBTREE,
104 domain_filter,
105 attrlist=['sambaSID', 'sambaDomainName'],
106 sizelimit=2
107 )
108 except ldap0.NO_SUCH_OBJECT:
109 return None
110 else:
111 if len(ldap_result) != 1:
112 return None
113 try:
114 _, domain_entry = ldap_result[0].entry_as
115 except (KeyError, IndexError):
116 return None
117 return domain_entry
118
120 try:
121 primary_group_sid = self._entry['sambaPrimaryGroupSID'][0]
122 except (KeyError, IndexError):
123 domain_name = self._entry.get('sambaDomainName', [None])[0]
124 domain_entry = self._search_domain_entry(domain_name)
125 if domain_entry is None:
126 domain_sid = None
127 else:
128 domain_sid = domain_entry.get('sambaSID', [None])[0]
129 else:
130 domain_sid = primary_group_sid.rsplit('-', 1)[0]
131 return domain_sid
132
133 def form_value(self) -> str:
134 ocs = self._entry.object_class_oid_set()
135 result = IA5String.form_value(self)
136 if result:
137 return result
138 domain_sid = self._get_domain_sid()
139 if domain_sid is not None:
140 try:
141 if 'sambaSamAccount' in ocs and 'posixAccount' in ocs:
142 uid_number = int(self._entry['uidNumber'][0])
143 result = '-'.join((
144 self._get_domain_sid(),
145 str(2*uid_number+1000)
146 ))
147 elif 'sambaGroupMapping' in ocs and 'posixGroup' in ocs:
148 gid_number = int(self._entry['gidNumber'][0])
149 result = '-'.join((
150 self._get_domain_sid(),
151 str(2*gid_number+1001)
152 ))
153 except (IndexError, KeyError, ValueError):
154 pass
155 return result
156
157syntax_registry.reg_at(
158 SambaSID.oid, [
159 '1.3.6.1.4.1.7165.2.1.20', # sambaSID
160 ]
161)
162
163
165 oid: str = 'SambaForceLogoff-oid'
166 desc: str = 'Disconnect Users outside logon hours (default: -1 => off, 0 => on)'
167 attr_value_dict: Dict[str, str] = {
168 '': '',
169 '0': 'on',
170 '-1': 'off',
171 }
172
173syntax_registry.reg_at(
174 SambaForceLogoff.oid, [
175 '1.3.6.1.4.1.7165.2.1.66', # sambaForceLogoff
176 ]
177)
178
180 oid: str = 'SambaLogonToChgPwd-oid'
181 desc: str = 'Force Users to logon for password change (default: 0 => off, 2 => on)'
182 attr_value_dict: Dict[str, str] = {
183 '': '',
184 '0': 'off',
185 '2': 'on',
186 }
187
188syntax_registry.reg_at(
189 SambaLogonToChgPwd.oid, [
190 '1.3.6.1.4.1.7165.2.1.60', # sambaLogonToChgPwd
191 ]
192)
193
195 oid: str = 'SambaGroupType-oid'
196 desc: str = 'Samba group type'
197 attr_value_dict: Dict[str, str] = {
198 '': '',
199 '2': 'Domain Group',
200 '4': 'Local Group (Alias)',
201 '5': 'Built-in Group (well-known)',
202 }
203
204syntax_registry.reg_at(
205 SambaGroupType.oid, [
206 '1.3.6.1.4.1.7165.2.1.19', # sambaGroupType
207 ]
208)
209
210
212 oid: str = 'ReferencedSID-oid'
213 desc: str = 'SID which points to another object'
214 ldap_url = 'ldap:///_?sambaSID,cn?sub?'
215
216syntax_registry.reg_at(
217 ReferencedSID.oid, [
218 '1.3.6.1.4.1.7165.2.1.51', # sambaSIDList
219 ]
220)
221
222
224 oid: str = 'SambaGroupSID-oid'
225 desc: str = 'SID which points to Samba group object'
226 ldap_url = 'ldap:///_?sambaSID,cn?sub?(objectClass=sambaGroupMapping)'
227
228syntax_registry.reg_at(
229 SambaGroupSID.oid, [
230 '1.3.6.1.4.1.7165.2.1.23', # sambaPrimaryGroupSID
231 ]
232)
233
234
236 oid: str = 'SambaDomainName-oid'
237 desc: str = 'Name of Samba domain'
238 ldap_url = 'ldap:///_?sambaDomainName,sambaDomainName?sub?(objectClass=sambaDomain)'
239
240syntax_registry.reg_at(
241 SambaDomainName.oid, [
242 '1.3.6.1.4.1.7165.2.1.38', # sambaDomainName
243 ]
244)
245
246
247syntax_registry.reg_at(
248 DirectoryString.oid, [
249 '1.3.6.1.4.1.7165.2.1.38', # sambaDomainName
250 ],
251 structural_oc_oids=[
252 '1.3.6.1.4.1.7165.2.2.5', # sambaDomain
253 ],
254)
255
256
258 oid: str = 'SambaHomeDrive-oid'
259 desc: str = 'Samba home drive letter'
260 attr_value_dict: Dict[str, str] = {
261 driveletter: driveletter
262 for driveletter in [
263 '%s:' % letter
264 for letter in string.ascii_lowercase.upper()
265 ]
266 }
267
268syntax_registry.reg_at(
269 SambaHomeDrive.oid, [
270 '1.3.6.1.4.1.7165.2.1.33', # sambaHomeDrive
271 ]
272)
273
274
275# Register all syntax classes in this module
276syntax_registry.reg_syntaxes(__name__)
str display(self, vidx, links)
Definition: samba.py:68
def _search_domain_entry(self, domain_name)
Definition: samba.py:93