mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2026-10-13 00:42:03 -05:00
support more DateTime attributes in LDAP searches in IPA API
LDAPSearch class constructs a filter from a set of attributes and their values passed in by the command. During this construction process a limited set of attributes gets converted to a special form, the rest is simply taken as a string and escaped according to LDAP rules. This means DateTime class would simply be converted to string using str(DateTime) and that uses default formatting method. For LDAP we need to apply a specific formatting method instead. Following LDAP attributes now handled as datetime.datetime: ( 1.3.6.1.4.1.5322.21.2.5 NAME 'krbLastAdminUnlock' EQUALITY generalizedTimeMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE) ( 2.16.840.1.113719.1.301.4.6.1 NAME 'krbPrincipalExpiration' EQUALITY generalizedTimeMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE) ( 2.16.840.1.113719.1.301.4.37.1 NAME 'krbPasswordExpiration' EQUALITY generalizedTimeMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE) ( 2.16.840.1.113719.1.301.4.45.1 NAME 'krbLastPwdChange' EQUALITY generalizedTimeMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE) ( 2.16.840.1.113719.1.301.4.48.1 NAME 'krbLastSuccessfulAuth' EQUALITY generalizedTimeMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE) ( 2.16.840.1.113719.1.301.4.49.1 NAME 'krbLastFailedAuth' EQUALITY generalizedTimeMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE) ( 2.16.840.1.113730.3.8.16.1.3 NAME 'ipatokenNotBefore' DESC 'Token validity date' EQUALITY generalizedTimeMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-ORIGIN 'IPA OTP') ( 2.16.840.1.113730.3.8.16.1.4 NAME 'ipatokenNotAfter' DESC 'Token expiration date' EQUALITY generalizedTimeMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE X-ORIGIN 'IPA OTP') Fixes: https://pagure.io/freeipa/issue/9395 Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com> Reviewed-By: Antonio Torres <antorres@redhat.com>
This commit is contained in:
1 parent
d5ae5e1884
commit
ef955c9015
2 files changed
+40
-5
No files matched your search
+17
-5
@@ -23,7 +23,7 @@ import binascii
|
||||
import errno
|
||||
import logging
|
||||
import time
|
||||
import datetime
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
from copy import deepcopy
|
||||
import contextlib
|
||||
@@ -689,11 +689,12 @@ class LDAPClient:
|
||||
'1.3.6.1.4.1.1466.115.121.1.10' : bytes, # Certificate Pair
|
||||
'1.3.6.1.4.1.1466.115.121.1.12' : DN, # Distinguished Name
|
||||
'1.3.6.1.4.1.1466.115.121.1.23' : bytes, # Fax
|
||||
'1.3.6.1.4.1.1466.115.121.1.24' : datetime.datetime,
|
||||
'1.3.6.1.4.1.1466.115.121.1.24' : datetime, # GeneralizedTime
|
||||
'1.3.6.1.4.1.1466.115.121.1.28' : bytes, # JPEG
|
||||
'1.3.6.1.4.1.1466.115.121.1.40' : bytes, # OctetString (same as Binary)
|
||||
'1.3.6.1.4.1.1466.115.121.1.49' : bytes, # Supported Algorithm
|
||||
'1.3.6.1.4.1.1466.115.121.1.51' : bytes, # Teletext Terminal Identifier
|
||||
'1.3.6.1.4.1.5322.21.2.5' : datetime, # krbLastAdminUnlock
|
||||
|
||||
'2.16.840.1.113730.3.8.3.3' : DN, # enrolledBy
|
||||
'2.16.840.1.113730.3.8.3.18' : DN, # managedBy
|
||||
@@ -706,16 +707,23 @@ class LDAPClient:
|
||||
'2.16.840.1.113730.3.8.7.1' : DN, # memberAllowCmd
|
||||
'2.16.840.1.113730.3.8.7.2' : DN, # memberDenyCmd
|
||||
|
||||
'2.16.840.1.113719.1.301.4.6.1' : datetime, # krbPrincipalExpiration
|
||||
'2.16.840.1.113719.1.301.4.14.1' : DN, # krbRealmReferences
|
||||
'2.16.840.1.113719.1.301.4.17.1' : DN, # krbKdcServers
|
||||
'2.16.840.1.113719.1.301.4.18.1' : DN, # krbPwdServers
|
||||
'2.16.840.1.113719.1.301.4.26.1' : DN, # krbPrincipalReferences
|
||||
'2.16.840.1.113719.1.301.4.29.1' : DN, # krbAdmServers
|
||||
'2.16.840.1.113719.1.301.4.36.1' : DN, # krbPwdPolicyReference
|
||||
'2.16.840.1.113719.1.301.4.37.1' : datetime, # krbPasswordExpiration
|
||||
'2.16.840.1.113719.1.301.4.40.1' : DN, # krbTicketPolicyReference
|
||||
'2.16.840.1.113719.1.301.4.41.1' : DN, # krbSubTrees
|
||||
'2.16.840.1.113719.1.301.4.45.1' : datetime, # krbLastPwdChange
|
||||
'2.16.840.1.113719.1.301.4.48.1' : datetime, # krbLastSuccessfulAuth
|
||||
'2.16.840.1.113719.1.301.4.49.1' : datetime, # krbLastFailedAuth
|
||||
'2.16.840.1.113719.1.301.4.52.1' : DN, # krbObjectReferences
|
||||
'2.16.840.1.113719.1.301.4.53.1' : DN, # krbPrincContainerRef
|
||||
'2.16.840.1.113730.3.8.16.1.3' : datetime, # ipatokenNotBefore
|
||||
'2.16.840.1.113730.3.8.16.1.4' : datetime, # ipatokenNotAfter
|
||||
}
|
||||
|
||||
# In most cases we lookup the syntax from the schema returned by
|
||||
@@ -990,7 +998,7 @@ class LDAPClient:
|
||||
# key in dict must be str not bytes
|
||||
dct = dict((k, self.encode(v)) for k, v in val.items())
|
||||
return dct
|
||||
elif isinstance(val, datetime.datetime):
|
||||
elif isinstance(val, datetime):
|
||||
return val.strftime(LDAP_GENERALIZED_TIME_FORMAT).encode('utf-8')
|
||||
elif isinstance(val, crypto_x509.Certificate):
|
||||
return val.public_bytes(x509.Encoding.DER)
|
||||
@@ -1012,8 +1020,8 @@ class LDAPClient:
|
||||
return val.decode('utf-8')
|
||||
elif target_type is bool:
|
||||
return val.decode('utf-8') == 'TRUE'
|
||||
elif target_type is datetime.datetime:
|
||||
return datetime.datetime.strptime(
|
||||
elif target_type is datetime:
|
||||
return datetime.strptime(
|
||||
val.decode('utf-8'), LDAP_GENERALIZED_TIME_FORMAT)
|
||||
elif target_type is DNSName:
|
||||
return DNSName.from_text(val.decode('utf-8'))
|
||||
@@ -1372,6 +1380,10 @@ class LDAPClient:
|
||||
# value[-2:0] is empty string for the initial '\\'
|
||||
value = u'\\'.join(
|
||||
value[i:i+2] for i in six.moves.range(-2, len(value), 2))
|
||||
elif isinstance(value, datetime):
|
||||
value = value.strftime(
|
||||
LDAP_GENERALIZED_TIME_FORMAT)
|
||||
value = ldap.filter.escape_filter_chars(value)
|
||||
else:
|
||||
value = str(value)
|
||||
value = ldap.filter.escape_filter_chars(value)
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
import os
|
||||
import sys
|
||||
|
||||
@@ -140,6 +141,28 @@ class test_ldap:
|
||||
cert = entry_attrs.get('usercertificate')[0]
|
||||
assert cert.serial_number is not None
|
||||
|
||||
def test_generalized_time(self):
|
||||
"""
|
||||
Test that LDAP generalized time is converted to/from datetime
|
||||
"""
|
||||
self.conn = ldap2(api)
|
||||
try:
|
||||
self.conn.connect(autobind=True)
|
||||
except errors.ACIError:
|
||||
pytest.skip("Only executed as root")
|
||||
if not api.Backend.rpcclient.isconnected():
|
||||
api.Backend.rpcclient.connect()
|
||||
newdate = datetime.now() + timedelta(days=365)
|
||||
lastdate = api.Backend.ldap2.encode(newdate).decode('utf-8')
|
||||
api.Command["user_mod"](
|
||||
"admin",
|
||||
**dict(setattr=("krbprincipalexpiration=%s" % lastdate))
|
||||
)
|
||||
result = api.Command["user_find"](
|
||||
**dict(krbprincipalexpiration=lastdate)
|
||||
)
|
||||
assert result['count'] == 1
|
||||
|
||||
|
||||
@pytest.mark.tier0
|
||||
@pytest.mark.needs_ipaapi
|
||||
|
||||
Reference in new issue
Block a user