1 # common functions for samba-tool python commands
3 # Copyright Andrew Tridgell 2010
4 # Copyright Giampaolo Lauria 2011 <lauria2@yahoo.com>
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 from samba
.dcerpc
import nbt
22 from samba
.net
import Net
23 from samba
.netcmd
import CommandError
27 # In MS AD, setting a timeout to '(never)' corresponds to this value
28 NEVER_TIMESTAMP
= int(-0x8000000000000000)
31 def _get_user_realm_domain(user
, sam
=None):
32 r
""" get the realm or the domain and the base user
38 A SamDB object can also be passed in to check
39 our domain or realm against the obtained ones.
42 m
= re
.match(r
"(\w+)\\(\w+$)", user
)
48 our_domain
= sam
.domain_netbios_name()
49 if domain
.lower() != our_domain
.lower():
50 raise CommandError(f
"Given domain '{domain}' does not match "
51 f
"our domain '{our_domain}'!")
53 return (baseuser
.lower(), "", domain
.upper())
56 m
= re
.match(r
"(\w+)@(\w+)", user
)
62 our_realm
= sam
.domain_dns_name()
63 our_realm_initial
= our_realm
.split('.', 1)[0]
64 if realm
.lower() != our_realm_initial
.lower():
65 raise CommandError(f
"Given realm '{realm}' does not match our "
66 f
"realm '{our_realm}'!")
68 return (baseuser
.lower(), realm
.upper(), "")
71 def netcmd_dnsname(lp
):
72 """return the full DNS name of our own host. Used as a default
73 for hostname when running status queries"""
74 return lp
.get('netbios name').lower() + "." + lp
.get('realm').lower()
77 def netcmd_finddc(lp
, creds
, realm
=None):
78 """Return domain-name of a writable/ldap-capable DC for the default
79 domain (parameter "realm" in smb.conf) unless another realm has been
80 specified as argument"""
81 net
= Net(creds
=creds
, lp
=lp
)
83 realm
= lp
.get('realm')
84 cldap_ret
= net
.finddc(domain
=realm
,
85 flags
=nbt
.NBT_SERVER_LDAP | nbt
.NBT_SERVER_DS | nbt
.NBT_SERVER_WRITABLE
)
86 return cldap_ret
.pdc_dns_name
89 def netcmd_get_domain_infos_via_cldap(lp
, creds
, address
=None):
90 """Return domain information (CLDAP record) of the ldap-capable
91 DC with the specified address"""
92 net
= Net(creds
=creds
, lp
=lp
)
93 cldap_ret
= net
.finddc(address
=address
,
94 flags
=nbt
.NBT_SERVER_LDAP | nbt
.NBT_SERVER_DS
)
97 def is_printable_attr_val(val
):
100 # The value must be convertible to a string value.
106 # Characters of the Unicode Character Category "C" ("Other") are
107 # supposed to be not printable. The category "C" includes control
108 # characters, format specifier and others.
110 if unicodedata
.category(c
)[0] == 'C':
115 def get_ldif_for_editor(samdb
, msg
):
117 # Copy the given message, because we do not
118 # want to modify the original message.
129 if is_printable_attr_val(v
):
134 m
[k
].set_flags(ldb
.FLAG_FORCE_NO_BASE64_LDIF
)
136 result_ldif
= samdb
.write_ldif(m
, ldb
.CHANGETYPE_NONE
)
141 def timestamp_to_mins(timestamp_str
):
142 """Converts a timestamp in -100 nanosecond units to minutes"""
143 # treat a timestamp of 'never' the same as zero (this should work OK for
144 # most settings, and it displays better than trying to convert
145 # -0x8000000000000000 to minutes)
146 if int(timestamp_str
) == NEVER_TIMESTAMP
:
149 return abs(int(timestamp_str
)) / (1e7
* 60)
152 def timestamp_to_days(timestamp_str
):
153 """Converts a timestamp in -100 nanosecond units to days"""
154 return timestamp_to_mins(timestamp_str
) / (60 * 24)
157 def attr_default(msg
, attrname
, default
):
158 """get an attribute from a ldap msg with a default"""
160 return msg
[attrname
][0]