URL: https://github.com/SSSD/sssd/pull/373
Author: lslebodn
 Title: #373: intg: Add sanity tests for pysss_nss_idmap
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/373/head:pr373
git checkout pr373
From 6d9097a5213ac3eaa23fcddd63379eff3bd7462a Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lsleb...@redhat.com>
Date: Wed, 6 Sep 2017 14:13:00 +0200
Subject: [PATCH 1/7] intg: Fix pep8 warnings in config.py template

intg/bld/src/tests/intg/config.py:5:7: E221 multiple spaces before operator
intg/bld/src/tests/intg/config.py:6:11: E221 multiple spaces before operator
intg/bld/src/tests/intg/config.py:7:15: E221 multiple spaces before operator
intg/bld/src/tests/intg/config.py:8:12: E221 multiple spaces before operator
intg/bld/src/tests/intg/config.py:9:10: E221 multiple spaces before operator
intg/bld/src/tests/intg/config.py:10:8: E221 multiple spaces before operator
intg/bld/src/tests/intg/config.py:11:9: E221 multiple spaces before operator
intg/bld/src/tests/intg/config.py:12:13: E221 multiple spaces before operator
intg/bld/src/tests/intg/config.py:13:9: E221 multiple spaces before operator
intg/bld/src/tests/intg/config.py:14:12: E221 multiple spaces before operator
intg/bld/src/tests/intg/config.py:15:11: E221 multiple spaces before operator
intg/bld/src/tests/intg/config.py:16:13: E221 multiple spaces before operator
intg/bld/src/tests/intg/config.py:17:12: E221 multiple spaces before operator
intg/bld/src/tests/intg/config.py:18:13: E221 multiple spaces before operator
intg/bld/src/tests/intg/config.py:20:11: E221 multiple spaces before operator
intg/bld/src/tests/intg/config.py:21:7: E221 multiple spaces before operator
intg/bld/src/tests/intg/config.py:22:11: E221 multiple spaces before operator
intg/bld/src/tests/intg/config.py:23:7: E221 multiple spaces before operator

pep8 will prevent reformatting in case of added new options
e.g. 53a4219e2f51cd0443931aa931505bf0b4bf5a45
---
 src/tests/intg/config.py.m4 | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/tests/intg/config.py.m4 b/src/tests/intg/config.py.m4
index bfbbf030f..20f9ec17a 100644
--- a/src/tests/intg/config.py.m4
+++ b/src/tests/intg/config.py.m4
@@ -2,18 +2,18 @@
 Build configuration variables.
 """
 
-PREFIX                  = "prefix"
-SYSCONFDIR              = "sysconfdir"
-NSS_MODULE_DIR          = PREFIX + "/lib"
-SSSDCONFDIR             = SYSCONFDIR + "/sssd"
-CONF_PATH               = SSSDCONFDIR + "/sssd.conf"
-DB_PATH                 = "dbpath"
-PID_PATH                = "pidpath"
-PIDFILE_PATH            = PID_PATH + "/sssd.pid"
-LOG_PATH                = "logpath"
-MCACHE_PATH             = "mcpath"
-SECDB_PATH              = "secdbpath"
-LIBEXEC_PATH            = "libexecpath"
-RUNSTATEDIR             = "runstatedir"
-ABS_BUILDDIR            = "abs_builddir"
+PREFIX = "prefix"
+SYSCONFDIR = "sysconfdir"
+NSS_MODULE_DIR = PREFIX + "/lib"
+SSSDCONFDIR = SYSCONFDIR + "/sssd"
+CONF_PATH = SSSDCONFDIR + "/sssd.conf"
+DB_PATH = "dbpath"
+PID_PATH = "pidpath"
+PIDFILE_PATH = PID_PATH + "/sssd.pid"
+LOG_PATH = "logpath"
+MCACHE_PATH = "mcpath"
+SECDB_PATH = "secdbpath"
+LIBEXEC_PATH = "libexecpath"
+RUNSTATEDIR = "runstatedir"
+ABS_BUILDDIR = "abs_builddir"
 SESSION_RECORDING_SHELL = "session_recording_shell"

From ec2b744599813418a3c380ddab96f4e9e2a480ba Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lsleb...@redhat.com>
Date: Sat, 21 May 2016 22:44:08 +0200
Subject: [PATCH 2/7] intg: Let python paths be configurable

It will allow to prefer locally built python modules
in integration tests.
---
 src/tests/intg/Makefile.am  | 4 ++++
 src/tests/intg/config.py.m4 | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/src/tests/intg/Makefile.am b/src/tests/intg/Makefile.am
index abf6237fc..d25d94466 100644
--- a/src/tests/intg/Makefile.am
+++ b/src/tests/intg/Makefile.am
@@ -44,6 +44,10 @@ config.py: config.py.m4
 	   -D "runstatedir=\`$(runstatedir)'" \
 	   -D "abs_builddir=\`$(abs_builddir)'" \
 	   -D "session_recording_shell=\`$(session_recording_shell)'" \
+	   -D "py2execdir=\`$(py2execdir)'" \
+	   -D "py3execdir=\`$(py3execdir)'" \
+	   -D "python2dir=\`$(python2dir)'" \
+	   -D "python3dir=\`$(python3dir)'" \
 	   $< > $@
 
 root:
diff --git a/src/tests/intg/config.py.m4 b/src/tests/intg/config.py.m4
index 20f9ec17a..6e011b692 100644
--- a/src/tests/intg/config.py.m4
+++ b/src/tests/intg/config.py.m4
@@ -17,3 +17,7 @@ LIBEXEC_PATH = "libexecpath"
 RUNSTATEDIR = "runstatedir"
 ABS_BUILDDIR = "abs_builddir"
 SESSION_RECORDING_SHELL = "session_recording_shell"
+PY2EXECDIR = "py2execdir"
+PY2DIR = "python2dir"
+PY3EXECDIR = "py3execdir"
+PY3DIR = "python3dir"

From dfd3cd50e12832b5f9143a333e664070363b8049 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lsleb...@redhat.com>
Date: Wed, 18 May 2016 21:00:27 +0200
Subject: [PATCH 3/7] intg: prevent "TypeError: must be type, not classobj"

http://stackoverflow.com/questions/9698614/super-raises-typeerror-must-be-type-not-classobj-for-new-style-class

========================== ERRORS ===========================
_______ ERROR at setup of test_regression_ticket2163 ________
Traceback (most recent call last):
  File "src/tests/intg/test_pysss_nss_idmap.py", line 48, in ad_inst
    instance.teardown()
  File "src/tests/intg/ds_openldap.py", line 371, in teardown
    super(FakeAD, self).teardown()
TypeError: super() argument 1 must be type, not classobj
---
 src/tests/intg/ds.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tests/intg/ds.py b/src/tests/intg/ds.py
index 66cb8875d..faf664ce0 100644
--- a/src/tests/intg/ds.py
+++ b/src/tests/intg/ds.py
@@ -20,7 +20,7 @@
 import ldap
 
 
-class DS:
+class DS(object):
     """Abstract directory server instance."""
 
     def __init__(self, dir, port, base_dn, admin_rdn, admin_pw):

From 8cb476fb06f7cc05e755f2bad79c86a94d3d9191 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lsleb...@redhat.com>
Date: Wed, 6 Sep 2017 14:27:06 +0200
Subject: [PATCH 4/7] intg: Prefer locally built python modules

Patch prepends path to sssd python modules; so we will be
able to import them without any issue and they will be preferred over
system modules.

sh$[/tmp/sssd-intg.3gb4hzpn/var/log/sssd] python2
Python 2.7.13 (default, Aug 16 2017, 12:56:26)
[GCC 7.1.1 20170802 (Red Hat 7.1.1-7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import SSSDConfig
>>> print(SSSDConfig.__file__)
/tmp/sssd-intg.3gb4hzpn/lib/python2.7/site-packages/SSSDConfig/__init__.pyc
>>> import pyhbac
>>> print(pyhbac.__file__)
/tmp/sssd-intg.3gb4hzpn/lib64/python2.7/site-packages/pyhbac.so
---
 src/tests/intg/Makefile.am |  1 +
 src/tests/intg/__init__.py | 13 +++++++++++++
 2 files changed, 14 insertions(+)
 create mode 100644 src/tests/intg/__init__.py

diff --git a/src/tests/intg/Makefile.am b/src/tests/intg/Makefile.am
index d25d94466..9d2fe36b7 100644
--- a/src/tests/intg/Makefile.am
+++ b/src/tests/intg/Makefile.am
@@ -1,4 +1,5 @@
 dist_noinst_DATA = \
+    __init__.py \
     config.py.m4 \
     util.py \
     sssd_nss.py \
diff --git a/src/tests/intg/__init__.py b/src/tests/intg/__init__.py
new file mode 100644
index 000000000..542f4d13c
--- /dev/null
+++ b/src/tests/intg/__init__.py
@@ -0,0 +1,13 @@
+import sys
+import config
+
+if sys.version_info[0] > 2:
+    LOCAL_PYEXECDIR = config.PY3EXECDIR
+    LOCAL_PYDIR = config.PY3DIR
+else:
+    LOCAL_PYEXECDIR = config.PY2EXECDIR
+    LOCAL_PYDIR = config.PY2DIR
+
+for path in [LOCAL_PYEXECDIR, LOCAL_PYDIR]:
+    if path not in sys.path:
+        sys.path.insert(0, path)

From 4b293cc8f3463e44f8a93d445325701a3ebb1ad1 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lsleb...@redhat.com>
Date: Wed, 6 Sep 2017 14:54:44 +0200
Subject: [PATCH 5/7] ds_openldap: Extract functionality to protected methods

---
 src/tests/intg/ds_openldap.py | 51 ++++++++++++++++++++++++-------------------
 1 file changed, 28 insertions(+), 23 deletions(-)

diff --git a/src/tests/intg/ds_openldap.py b/src/tests/intg/ds_openldap.py
index 6a074c947..b7e0eb6c4 100644
--- a/src/tests/intg/ds_openldap.py
+++ b/src/tests/intg/ds_openldap.py
@@ -185,26 +185,10 @@ def _setup_config(self):
         db_config_file.write(db_config)
         db_config_file.close()
 
-    def setup(self):
-        """Setup the instance."""
-        ldapi_socket = self.run_dir + "/ldapi"
-        ldapi_url = "ldapi://" + url_quote(ldapi_socket, "")
-        url_list = ldapi_url + " " + self.ldap_url
-
-        os.makedirs(self.conf_slapd_d_dir)
-        os.makedirs(self.run_dir)
-        os.makedirs(self.data_dir)
-
-        #
-        # Setup initial configuration
-        #
-        self._setup_config()
-
-        #
-        # Start the daemon
-        #
+    def _start_daemon(self):
+        """Start the instance."""
         if subprocess.call(["slapd", "-F", self.conf_slapd_d_dir,
-                            "-h", url_list]) != 0:
+                            "-h", self.url_list]) != 0:
             raise Exception("Failed to start slapd")
 
         #
@@ -213,7 +197,7 @@ def setup(self):
         attempt = 0
         while True:
             try:
-                ldap_conn = ldap.initialize(ldapi_url)
+                ldap_conn = ldap.initialize(self.ldapi_url)
                 ldap_conn.simple_bind_s(self.admin_rdn + ",cn=config",
                                         self.admin_pw)
                 ldap_conn.unbind_s()
@@ -228,6 +212,23 @@ def setup(self):
                 raise Exception("Failed to start slapd")
             time.sleep(1)
 
+    def setup(self):
+        """Setup the instance."""
+        ldapi_socket = self.run_dir + "/ldapi"
+        self.ldapi_url = "ldapi://" + url_quote(ldapi_socket, "")
+        self.url_list = self.ldapi_url + " " + self.ldap_url
+
+        os.makedirs(self.conf_slapd_d_dir)
+        os.makedirs(self.run_dir)
+        os.makedirs(self.data_dir)
+
+        #
+        # Setup initial configuration
+        #
+        self._setup_config()
+
+        self._start_daemon()
+
         #
         # Relax requirement of member attribute presence in groupOfNames
         #
@@ -243,7 +244,7 @@ def setup(self):
              b"STRUCTURAL MUST ( cn ) MAY ( member $ businessCategory $ "
              b"seeAlso $ owner $ ou $ o $ description ) )"),
         ]
-        ldap_conn = ldap.initialize(ldapi_url)
+        ldap_conn = ldap.initialize(self.ldapi_url)
         ldap_conn.simple_bind_s(self.admin_rdn + ",cn=config", self.admin_pw)
         ldap_conn.modify_s("cn={0}core,cn=schema,cn=config", modlist)
         ldap_conn.unbind_s()
@@ -266,8 +267,8 @@ def setup(self):
             ])
         ldap_conn.unbind_s()
 
-    def teardown(self):
-        """Teardown the instance."""
+    def _stop_daemon(self):
+        """Stop the instance."""
         # Wait for slapd to stop
         try:
             pid_file = open(self.pid_path, "r")
@@ -285,5 +286,9 @@ def teardown(self):
             if e.errno != errno.ENOENT:
                 raise
 
+    def teardown(self):
+        """Teardown the instance."""
+        self._stop_daemon()
+
         for path in (self.conf_slapd_d_dir, self.run_dir, self.data_dir):
             shutil.rmtree(path, True)

From 75f9b1d5f3039959f781e3eb1d82f3ff6d877ef7 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lsleb...@redhat.com>
Date: Wed, 6 Sep 2017 15:09:50 +0200
Subject: [PATCH 6/7] intg: Create FakeAD class based on openldap

FakeAD is openldap with ldif schema which allows to load static data
from real AD. Instance of class will also contain some predefined
users/groups which can be used for basic sanity testing in sssd of AD features.
---
 src/tests/intg/Makefile.am         |   2 +
 src/tests/intg/data/ad_data.ldif   | 815 +++++++++++++++++++++++++++++++++++++
 src/tests/intg/data/ad_schema.ldif |  42 ++
 src/tests/intg/ds_openldap.py      |  77 ++++
 4 files changed, 936 insertions(+)
 create mode 100644 src/tests/intg/data/ad_data.ldif
 create mode 100644 src/tests/intg/data/ad_schema.ldif

diff --git a/src/tests/intg/Makefile.am b/src/tests/intg/Makefile.am
index 9d2fe36b7..eb157693d 100644
--- a/src/tests/intg/Makefile.am
+++ b/src/tests/intg/Makefile.am
@@ -31,6 +31,8 @@ dist_noinst_DATA = \
     kdc.py \
     krb5utils.py \
     test_kcm.py \
+    data/ad_data.ldif \
+    data/ad_schema.ldif \
     $(NULL)
 
 config.py: config.py.m4
diff --git a/src/tests/intg/data/ad_data.ldif b/src/tests/intg/data/ad_data.ldif
new file mode 100644
index 000000000..0d2ec444c
--- /dev/null
+++ b/src/tests/intg/data/ad_data.ldif
@@ -0,0 +1,815 @@
+dn: cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: container
+cn: Users
+description: Default container for upgraded user accounts
+distinguishedName: cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923233930.0Z
+whenChanged: 20140923233930.0Z
+uSNCreated: 5696
+uSNChanged: 5696
+showInAdvancedViewOnly: FALSE
+name: Users
+objectGUID:: 6Gd2SrsmeEiT3Hmh/5hTqw==
+systemFlags: -1946157056
+objectCategory: cn=Container,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=CHILD1$,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: user
+cn: CHILD1$
+distinguishedName: cn=CHILD1$,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923224256.0Z
+whenChanged: 20160423221800.0Z
+uSNCreated: 20732
+uSNChanged: 2181674
+name: CHILD1$
+objectGUID:: ACE60RcYu0iZv4CMYPK+eg==
+userAccountControl: 2080
+badPwdCount: 0
+codePage: 0
+countryCode: 0
+badPasswordTime: 0
+lastLogoff: 0
+lastLogon: 0
+pwdLastSet: 131059234804699243
+primaryGroupID: 513
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8EUAQAAA==
+accountExpires: 9223372036854775807
+logonCount: 0
+sAMAccountName: CHILD1$
+sAMAccountType: 805306370
+objectCategory: cn=Person,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=krbtgt,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: user
+cn: krbtgt
+description: Key Distribution Center Service Account
+distinguishedName: cn=krbtgt,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923234018.0Z
+whenChanged: 20140923185530.0Z
+uSNCreated: 12324
+memberOf: cn=Denied ROdc Password Replication Group,cn=Users,dc=example,dc=com
+uSNChanged: 12723
+showInAdvancedViewOnly: TRUE
+name: krbtgt
+objectGUID:: F/Yrx8X81ESM6t14mMxcxA==
+userAccountControl: 514
+badPwdCount: 0
+codePage: 0
+countryCode: 0
+badPasswordTime: 0
+lastLogoff: 0
+lastLogon: 0
+pwdLastSet: 130559892182968750
+primaryGroupID: 513
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8E9gEAAA==
+adminCount: 1
+accountExpires: 9223372036854775807
+logonCount: 0
+sAMAccountName: krbtgt
+sAMAccountType: 805306368
+servicePrincipalName: kadmin/changepw
+objectCategory: cn=Person,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 20140923185530.0Z
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=Domain Computers,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: Domain Computers
+description: All workstations and servers joined to the domain
+distinguishedName: cn=Domain Computers,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923234018.0Z
+whenChanged: 20140923234018.0Z
+uSNCreated: 12330
+uSNChanged: 12332
+name: Domain Computers
+objectGUID:: 09VIVs7CDkOMTnLtMkZMUA==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8EAwIAAA==
+sAMAccountName: Domain Computers
+sAMAccountType: 268435456
+groupType: -2147483646
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=Domain Controllers,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: Domain Controllers
+description: All domain controllers in the domain
+distinguishedName: cn=Domain Controllers,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923234018.0Z
+whenChanged: 20140923185530.0Z
+uSNCreated: 12333
+memberOf: cn=Denied ROdc Password Replication Group,cn=Users,dc=example,dc=com
+uSNChanged: 12726
+name: Domain Controllers
+objectGUID:: a6OG+FLmnECf3fAe0a8o6w==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8EBAIAAA==
+adminCount: 1
+sAMAccountName: Domain Controllers
+sAMAccountType: 268435456
+groupType: -2147483646
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 20140923185530.0Z
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=Schema Admins,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: Schema Admins
+description: Designated administrators of the schema
+member: cn=Administrator,cn=Users,dc=example,dc=com
+distinguishedName: cn=Schema Admins,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923234018.0Z
+whenChanged: 20140923185530.0Z
+uSNCreated: 12336
+memberOf: cn=Denied ROdc Password Replication Group,cn=Users,dc=example,dc=com
+uSNChanged: 12708
+name: Schema Admins
+objectGUID:: ONs7cn0OF0uEip0yMnLv2Q==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8EBgIAAA==
+adminCount: 1
+sAMAccountName: Schema Admins
+sAMAccountType: 268435456
+groupType: -2147483640
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 20140923185530.0Z
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=Enterprise Admins,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: Enterprise Admins
+description: Designated administrators of the enterprise
+member: cn=Administrator,cn=Users,dc=example,dc=com
+distinguishedName: cn=Enterprise Admins,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923234018.0Z
+whenChanged: 20140923185530.0Z
+uSNCreated: 12339
+memberOf: cn=Denied ROdc Password Replication Group,cn=Users,dc=example,dc=com
+memberOf: cn=Administrators,cn=Builtin,dc=example,dc=com
+uSNChanged: 12712
+name: Enterprise Admins
+objectGUID:: rD6jEoiL8U6huv7c/OJPwg==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8EBwIAAA==
+adminCount: 1
+sAMAccountName: Enterprise Admins
+sAMAccountType: 268435456
+groupType: -2147483640
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 20140923185530.0Z
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=Cert Publishers,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: Cert Publishers
+description: Members of this group are permitted to publish certificates to the directory
+member: cn=PLUTO,OU=Domain Controllers,dc=example,dc=com
+distinguishedName: cn=Cert Publishers,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923234018.0Z
+whenChanged: 20140923191508.0Z
+uSNCreated: 12342
+memberOf: cn=Denied ROdc Password Replication Group,cn=Users,dc=example,dc=com
+uSNChanged: 12749
+name: Cert Publishers
+objectGUID:: zWTUMdl6tEWA1J0QnPLkRQ==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8EBQIAAA==
+sAMAccountName: Cert Publishers
+sAMAccountType: 536870912
+groupType: -2147483644
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=Domain Admins,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: Domain Admins
+description: Designated administrators of the domain
+member: cn=Administrator,cn=Users,dc=example,dc=com
+distinguishedName: cn=Domain Admins,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923234018.0Z
+whenChanged: 20140923185530.0Z
+uSNCreated: 12345
+memberOf: cn=Denied ROdc Password Replication Group,cn=Users,dc=example,dc=com
+memberOf: cn=Administrators,cn=Builtin,dc=example,dc=com
+uSNChanged: 12711
+name: Domain Admins
+objectGUID:: YxI+YLrC3UeNNsmMnXGTlg==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8EAAIAAA==
+adminCount: 1
+sAMAccountName: Domain Admins
+sAMAccountType: 268435456
+groupType: -2147483646
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 20140923185530.0Z
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=Domain Users,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: Domain Users
+description: All domain users
+distinguishedName: cn=Domain Users,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923234018.0Z
+whenChanged: 20150202222731.0Z
+uSNCreated: 12348
+memberOf: cn=Users,cn=Builtin,dc=example,dc=com
+uSNChanged: 213433
+name: Domain Users
+objectGUID:: JRHvlJXoU0+LOYXs3vESow==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8EAQIAAA==
+sAMAccountName: Domain Users
+sAMAccountType: 268435456
+groupType: -2147483646
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 16010101000000.0Z
+msSFU30NisDomain: example
+gidNumber: 100000
+
+dn: cn=Domain Guests,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: Domain Guests
+description: All domain guests
+distinguishedName: cn=Domain Guests,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923234018.0Z
+whenChanged: 20140923234018.0Z
+uSNCreated: 12351
+memberOf: cn=Guests,cn=Builtin,dc=example,dc=com
+uSNChanged: 12353
+name: Domain Guests
+objectGUID:: Rx/t/vuPwUGOMoprY1KFog==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8EAgIAAA==
+sAMAccountName: Domain Guests
+sAMAccountType: 268435456
+groupType: -2147483646
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=Group Policy Creator Owners,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: Group Policy Creator Owners
+description: Members in this group can modify group policy for the domain
+member: cn=Administrator,cn=Users,dc=example,dc=com
+distinguishedName: cn=Group Policy Creator Owners,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923234018.0Z
+whenChanged: 20140923234018.0Z
+uSNCreated: 12354
+memberOf: cn=Denied ROdc Password Replication Group,cn=Users,dc=example,dc=com
+uSNChanged: 12391
+name: Group Policy Creator Owners
+objectGUID:: V3HfwcWfZ0yv1br3tRP6bA==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8ECAIAAA==
+sAMAccountName: Group Policy Creator Owners
+sAMAccountType: 268435456
+groupType: -2147483646
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=RAS and IAS Servers,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: RAS and IAS Servers
+description: Servers in this group can access remote access properties of users
+distinguishedName: cn=RAS and IAS Servers,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923234018.0Z
+whenChanged: 20140923234018.0Z
+uSNCreated: 12357
+uSNChanged: 12359
+name: RAS and IAS Servers
+objectGUID:: PHyDebZK7UKVG9HG+mT8ng==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8EKQIAAA==
+sAMAccountName: RAS and IAS Servers
+sAMAccountType: 536870912
+groupType: -2147483644
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=Allowed ROdc Password Replication Group,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: Allowed ROdc Password Replication Group
+description: Members in this group can have their passwords replicated to all read-only domain controllers in the domain
+distinguishedName: cn=Allowed ROdc Password Replication Group,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923234018.0Z
+whenChanged: 20140923234018.0Z
+uSNCreated: 12402
+uSNChanged: 12404
+name: Allowed ROdc Password Replication Group
+objectGUID:: pKN3Txn0SUenHm8Z58ZQYA==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8EOwIAAA==
+sAMAccountName: Allowed ROdc Password Replication Group
+sAMAccountType: 536870912
+groupType: -2147483644
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=Denied ROdc Password Replication Group,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: Denied ROdc Password Replication Group
+description: Members in this group cannot have their passwords replicated to any read-only domain controllers in the domain
+member: cn=Read-only Domain Controllers,cn=Users,dc=example,dc=com
+member: cn=Group Policy Creator Owners,cn=Users,dc=example,dc=com
+member: cn=Domain Admins,cn=Users,dc=example,dc=com
+member: cn=Cert Publishers,cn=Users,dc=example,dc=com
+member: cn=Enterprise Admins,cn=Users,dc=example,dc=com
+member: cn=Schema Admins,cn=Users,dc=example,dc=com
+member: cn=Domain Controllers,cn=Users,dc=example,dc=com
+member: cn=krbtgt,cn=Users,dc=example,dc=com
+distinguishedName: cn=Denied ROdc Password Replication Group,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923234018.0Z
+whenChanged: 20140923234018.0Z
+uSNCreated: 12405
+uSNChanged: 12433
+name: Denied ROdc Password Replication Group
+objectGUID:: OoOtLxLbXUSdCGKeGvzc7Q==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8EPAIAAA==
+sAMAccountName: Denied ROdc Password Replication Group
+sAMAccountType: 536870912
+groupType: -2147483644
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=Read-only Domain Controllers,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: Read-only Domain Controllers
+description: Members of this group are Read-Only Domain Controllers in the domain
+distinguishedName: cn=Read-only Domain Controllers,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923234018.0Z
+whenChanged: 20140923185530.0Z
+uSNCreated: 12419
+memberOf: cn=Denied ROdc Password Replication Group,cn=Users,dc=example,dc=com
+uSNChanged: 12725
+name: Read-only Domain Controllers
+objectGUID:: GoeeiCJ87UqBN3C9MhqQ3w==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8ECQIAAA==
+adminCount: 1
+sAMAccountName: Read-only Domain Controllers
+sAMAccountType: 268435456
+groupType: -2147483646
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 20140923185530.0Z
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=Enterprise Read-only Domain Controllers,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: Enterprise Read-only Domain Controllers
+description: Members of this group are Read-Only Domain Controllers in the enterprise
+distinguishedName: cn=Enterprise Read-only Domain Controllers,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923234018.0Z
+whenChanged: 20140923234018.0Z
+uSNCreated: 12429
+uSNChanged: 12431
+name: Enterprise Read-only Domain Controllers
+objectGUID:: qHRH+tAgFUy7660VnrFpTA==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8E8gEAAA==
+sAMAccountName: Enterprise Read-only Domain Controllers
+sAMAccountType: 268435456
+groupType: -2147483640
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=DnsAdmins,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: DnsAdmins
+description: DNS Administrators Group
+distinguishedName: cn=DnsAdmins,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923234058.0Z
+whenChanged: 20140923234058.0Z
+uSNCreated: 12459
+uSNChanged: 12461
+name: DnsAdmins
+objectGUID:: w4cyv6dWNEGQao3mL5RpTA==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8ETQQAAA==
+sAMAccountName: DnsAdmins
+sAMAccountType: 536870912
+groupType: -2147483644
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=DnsUpdateProxy,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: DnsUpdateProxy
+description: DNS clients who are permitted to perform dynamic updates on behalf of some other clients (such as DHCP servers).
+distinguishedName: cn=DnsUpdateProxy,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923234058.0Z
+whenChanged: 20140923234058.0Z
+uSNCreated: 12464
+uSNChanged: 12464
+name: DnsUpdateProxy
+objectGUID:: LMyHGT2RuEG+IGrGL80qMg==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8ETgQAAA==
+sAMAccountName: DnsUpdateProxy
+sAMAccountType: 268435456
+groupType: -2147483646
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=user1_dom1-19661,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: user
+cn: user1_dom1-19661
+givenName: user1_dom1-19661
+distinguishedName: cn=user1_dom1-19661,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20160517121016.0Z
+whenChanged: 20160517121017.0Z
+displayName: user1_dom1-19661
+uSNCreated: 2223663
+memberOf: cn=group1_dom1-19661,cn=Users,dc=example,dc=com
+uSNChanged: 2223667
+name: user1_dom1-19661
+objectGUID:: qyJVkvQrRUyig6rpPsXNUw==
+userAccountControl: 512
+badPwdCount: 0
+codePage: 0
+countryCode: 0
+badPasswordTime: 0
+lastLogoff: 0
+lastLogon: 0
+pwdLastSet: 131079606172284326
+primaryGroupID: 513
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8EeUMBAA==
+accountExpires: 0
+logonCount: 0
+sAMAccountName: user1_dom1-19661
+sAMAccountType: 805306368
+userPrincipalName: user1_dom1-19...@example.com
+objectCategory: cn=Person,cn=Schema,cn=Configuration,dc=example,dc=com
+dSCorePropagationData: 16010101000000.0Z
+uid: user1_dom1-19661
+msSFU30Name: user1_dom1-19661
+
+dn: cn=group1_dom1-19661,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: group1_dom1-19661
+member: cn=user1_dom1-19661,cn=Users,dc=example,dc=com
+distinguishedName: cn=group1_dom1-19661,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20160517121017.0Z
+whenChanged: 20160517121018.0Z
+uSNCreated: 2223669
+uSNChanged: 2223673
+name: group1_dom1-19661
+objectGUID:: 8BulXIrOCkmlc6HgV+PAvw==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8EekMBAA==
+sAMAccountName: group1_dom1-19661
+sAMAccountType: 268435456
+groupType: -2147483640
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=user2_dom1-19661,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: user
+cn: user2_dom1-19661
+givenName: user2_dom1-19661
+distinguishedName: cn=user2_dom1-19661,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20160517121018.0Z
+whenChanged: 20160517121019.0Z
+displayName: user2_dom1-19661
+uSNCreated: 2223676
+memberOf: cn=group2_dom2-19661,cn=Users,dc=example_tree,dc=com
+uSNChanged: 2223680
+name: user2_dom1-19661
+objectGUID:: YSnhUKGpFUC+SqxUvvXugA==
+userAccountControl: 512
+badPwdCount: 0
+codePage: 0
+countryCode: 0
+badPasswordTime: 0
+lastLogoff: 0
+lastLogon: 0
+pwdLastSet: 131079606188221826
+primaryGroupID: 513
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8Ee0MBAA==
+accountExpires: 0
+logonCount: 0
+sAMAccountName: user2_dom1-19661
+sAMAccountType: 805306368
+userPrincipalName: user2_dom1-19...@example.com
+objectCategory: cn=Person,cn=Schema,cn=Configuration,dc=example,dc=com
+dSCorePropagationData: 16010101000000.0Z
+uid: user2_dom1-19661
+msSFU30Name: user2_dom1-19661
+
+dn: cn=group3_dom1-19661,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: group3_dom1-19661
+member: cn=user3_dom3-19661,cn=Users,dc=child1,dc=example,dc=com
+distinguishedName: cn=group3_dom1-19661,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20160517121145.0Z
+whenChanged: 20160517121146.0Z
+uSNCreated: 2223750
+uSNChanged: 2223754
+name: group3_dom1-19661
+objectGUID:: 7bIPzON/JEKmGsVlRmhU3g==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8EfEMBAA==
+sAMAccountName: group3_dom1-19661
+sAMAccountType: 268435456
+groupType: -2147483640
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=TelnetClients,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: TelnetClients
+distinguishedName: cn=TelnetClients,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923184913.0Z
+whenChanged: 20140923184913.0Z
+uSNCreated: 12704
+uSNChanged: 12706
+name: TelnetClients
+objectGUID:: pen22ZTevU2Rb+8+krexQA==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8ETwQAAA==
+sAMAccountName: TelnetClients
+sAMAccountType: 536870912
+groupType: -2147483644
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=SSSDAD_TREE$,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: user
+cn: SSSDAD_TREE$
+distinguishedName: cn=SSSDAD_TREE$,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20141002150546.0Z
+whenChanged: 20160504032042.0Z
+uSNCreated: 31148
+uSNChanged: 2196300
+name: SSSDAD_TREE$
+objectGUID:: SYm5qEjtH0SySg5aQw6XNA==
+userAccountControl: 2080
+badPwdCount: 0
+codePage: 0
+countryCode: 0
+badPasswordTime: 0
+lastLogoff: 0
+lastLogon: 0
+pwdLastSet: 131068056421414345
+primaryGroupID: 513
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8EUQQAAA==
+accountExpires: 9223372036854775807
+logonCount: 0
+sAMAccountName: SSSDAD_TREE$
+sAMAccountType: 805306370
+objectCategory: cn=Person,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=user1_dom1-17775,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: user
+cn: user1_dom1-17775
+givenName: user1_dom1-17775
+distinguishedName: cn=user1_dom1-17775,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20160517104141.0Z
+whenChanged: 20160517105245.0Z
+displayName: user1_dom1-17775
+uSNCreated: 2220148
+memberOf: cn=group1_dom1-17775,cn=Users,dc=example,dc=com
+uSNChanged: 2220869
+name: user1_dom1-17775
+objectGUID:: dCwgefPZTEaA5Gq7fuH9eQ==
+userAccountControl: 512
+badPwdCount: 0
+codePage: 0
+countryCode: 0
+badPasswordTime: 0
+lastLogoff: 0
+lastLogon: 131079562057827406
+pwdLastSet: 131079557906733656
+primaryGroupID: 513
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8ESUMBAA==
+accountExpires: 0
+logonCount: 46
+sAMAccountName: user1_dom1-17775
+sAMAccountType: 805306368
+userPrincipalName: user1_dom1-17...@example.com
+objectCategory: cn=Person,cn=Schema,cn=Configuration,dc=example,dc=com
+dSCorePropagationData: 16010101000000.0Z
+lastLogonTimestamp: 131079557817046156
+uid: user1_dom1-17775
+msSFU30Name: user1_dom1-17775
+
+dn: cn=group1_dom1-17775,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: group1_dom1-17775
+member: cn=user1_dom1-17775,cn=Users,dc=example,dc=com
+distinguishedName: cn=group1_dom1-17775,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20160517104143.0Z
+whenChanged: 20160517104143.0Z
+uSNCreated: 2220154
+uSNChanged: 2220158
+name: group1_dom1-17775
+objectGUID:: UfJpBGL6gE2d5hqzqNlRGQ==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8ESkMBAA==
+sAMAccountName: group1_dom1-17775
+sAMAccountType: 268435456
+groupType: -2147483640
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=user2_dom1-17775,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: user
+cn: user2_dom1-17775
+givenName: user2_dom1-17775
+distinguishedName: cn=user2_dom1-17775,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20160517104143.0Z
+whenChanged: 20160517105302.0Z
+displayName: user2_dom1-17775
+uSNCreated: 2220161
+memberOf: cn=group2_dom2-17775,cn=Users,dc=example_tree,dc=com
+uSNChanged: 2220886
+name: user2_dom1-17775
+objectGUID:: r22lHyI8Y0eMVzeTH2dzoQ==
+userAccountControl: 512
+badPwdCount: 0
+codePage: 0
+countryCode: 0
+badPasswordTime: 0
+lastLogoff: 0
+lastLogon: 131079561237671156
+pwdLastSet: 131079553041264906
+primaryGroupID: 513
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8ES0MBAA==
+accountExpires: 0
+logonCount: 14
+sAMAccountName: user2_dom1-17775
+sAMAccountType: 805306368
+userPrincipalName: user2_dom1-17...@example.com
+objectCategory: cn=Person,cn=Schema,cn=Configuration,dc=example,dc=com
+dSCorePropagationData: 16010101000000.0Z
+lastLogonTimestamp: 131079559824702406
+uid: user2_dom1-17775
+msSFU30Name: user2_dom1-17775
+
+dn: cn=group3_dom1-17775,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: group
+cn: group3_dom1-17775
+member: cn=user3_dom3-17775,cn=Users,dc=child1,dc=example,dc=com
+distinguishedName: cn=group3_dom1-17775,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20160517104312.0Z
+whenChanged: 20160517104312.0Z
+uSNCreated: 2220239
+uSNChanged: 2220243
+name: group3_dom1-17775
+objectGUID:: jkkwGJCVb0K4OCjHZVDmdQ==
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8ETEMBAA==
+sAMAccountName: group3_dom1-17775
+sAMAccountType: 268435456
+groupType: -2147483640
+objectCategory: cn=Group,cn=Schema,cn=Configuration,dc=example,dc=com
+dSCorePropagationData: 16010101000000.0Z
+
+dn: cn=Administrator,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: user
+cn: Administrator
+description: Built-in account for administering the computer/domain
+distinguishedName: cn=Administrator,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923233931.0Z
+whenChanged: 20160510092815.0Z
+uSNCreated: 8196
+memberOf: cn=Group Policy Creator Owners,cn=Users,dc=example,dc=com
+memberOf: cn=Domain Admins,cn=Users,dc=example,dc=com
+memberOf: cn=Enterprise Admins,cn=Users,dc=example,dc=com
+memberOf: cn=Schema Admins,cn=Users,dc=example,dc=com
+memberOf: cn=Administrators,cn=Builtin,dc=example,dc=com
+uSNChanged: 2204950
+name: Administrator
+objectGUID:: QeHMqu/QPEyjJ+KQEqcKFw==
+userAccountControl: 66048
+badPwdCount: 0
+codePage: 0
+countryCode: 0
+badPasswordTime: 131074379403763791
+lastLogoff: 0
+lastLogon: 131079606125409326
+logonHours:: ////////////////////////////
+pwdLastSet: 130553133586093750
+primaryGroupID: 513
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8E9AEAAA==
+adminCount: 1
+accountExpires: 0
+logonCount: 7477
+sAMAccountName: Administrator
+sAMAccountType: 805306368
+objectCategory: cn=Person,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 20140923185530.0Z
+dSCorePropagationData: 16010101000000.0Z
+lastLogonTimestamp: 131073460951421705
+
+dn: cn=Guest,cn=Users,dc=example,dc=com
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: user
+cn: Guest
+description: Built-in account for guest access to the computer/domain
+distinguishedName: cn=Guest,cn=Users,dc=example,dc=com
+instanceType: 4
+whenCreated: 20140923233931.0Z
+whenChanged: 20140923233931.0Z
+uSNCreated: 8197
+memberOf: cn=Guests,cn=Builtin,dc=example,dc=com
+uSNChanged: 8197
+name: Guest
+objectGUID:: pZVy9Q6Eh02XuYDEXDE9Cg==
+userAccountControl: 66082
+badPwdCount: 0
+codePage: 0
+countryCode: 0
+badPasswordTime: 0
+lastLogoff: 0
+lastLogon: 0
+pwdLastSet: 0
+primaryGroupID: 514
+objectSid:: AQUAAAAAAAUVAAAADcfLTVzC66zo0l8E9QEAAA==
+accountExpires: 9223372036854775807
+logonCount: 0
+sAMAccountName: Guest
+sAMAccountType: 805306368
+objectCategory: cn=Person,cn=Schema,cn=Configuration,dc=example,dc=com
+isCriticalSystemObject: TRUE
+dSCorePropagationData: 16010101000000.0Z
diff --git a/src/tests/intg/data/ad_schema.ldif b/src/tests/intg/data/ad_schema.ldif
new file mode 100644
index 000000000..1e4b777a2
--- /dev/null
+++ b/src/tests/intg/data/ad_schema.ldif
@@ -0,0 +1,42 @@
+dn: cn=ad,cn=schema,cn=config
+objectClass: olcSchemaConfig
+cn: ad
+structuralObjectClass: olcSchemaConfig
+olcAttributeTypes: {0}( 1.2.840.113556.1.4.750 NAME 'groupType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )
+olcAttributeTypes: {1}( 1.2.840.113556.1.4.221 NAME 'sAMAccountName' EQUALITY caseExactMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )
+olcAttributeTypes: {2}( 1.2.840.113556.1.4.35 NAME 'employeeID' EQUALITY integerMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )
+olcAttributeTypes: {3}( 1.2.840.113556.1.2.1 NAME 'instanceType' EQUALITY integerMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )
+olcAttributeTypes: {4}( 1.2.840.113556.1.4.782 NAME 'objectCategory' EQUALITY caseExactMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )
+olcAttributeTypes: {5}( 1.2.840.113556.1.2.2 NAME 'whenCreated' EQUALITY caseExactMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )
+olcAttributeTypes: {6}( 1.2.840.113556.1.2.3 NAME 'whenChanged' EQUALITY caseExactMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )
+olcAttributeTypes: {7}( 1.2.840.113556.1.2.19 NAME 'uSNCreated' EQUALITY integerMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )
+olcAttributeTypes: {8}( 1.2.840.113556.1.2.120 NAME 'uSNChanged' EQUALITY integerMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )
+olcAttributeTypes: {9}( 1.2.840.113556.1.2.169 NAME 'showInAdvancedViewOnly' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
+olcAttributeTypes: {10}( 1.2.840.113556.1.4.2 NAME 'objectGUID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE)
+olcAttributeTypes: {11}( 1.2.840.113556.1.4.375 NAME 'systemFlags' EQUALITY integerMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )
+olcAttributeTypes: {12}( 1.2.840.113556.1.4.868 NAME 'isCriticalSystemObject' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
+olcAttributeTypes: {13}( 1.2.840.113556.1.4.1357 NAME 'dSCorePropagationData' EQUALITY caseExactMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
+olcAttributeTypes: {14}( 1.2.840.113556.1.4.8 NAME 'userAccountControl' EQUALITY integerMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )
+olcAttributeTypes: {15}( 1.2.840.113556.1.4.12 NAME 'badPwdCount' EQUALITY integerMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )
+olcAttributeTypes: {16}( 1.2.840.113556.1.4.146 NAME 'objectSid' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE)
+olcAttributeTypes: {17}( 1.2.840.113556.1.2.102 NAME 'memberOf' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
+olcAttributeTypes: {18}( 1.2.840.113556.1.4.16 NAME 'codePage' EQUALITY integerMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )
+olcAttributeTypes: {19}( 1.2.840.113556.1.4.302 NAME 'sAMAccountType' EQUALITY integerMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )
+olcAttributeTypes: {20}( 1.2.840.113556.1.4.150 NAME 'adminCount' EQUALITY integerMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )
+olcAttributeTypes: {21}( 1.2.840.113556.1.4.25 NAME 'countryCode' EQUALITY integerMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )
+olcAttributeTypes: {22}( 1.2.840.113556.1.4.49 NAME 'badPasswordTime' EQUALITY caseExactMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )
+olcAttributeTypes: {23}( 1.2.840.113556.1.6.18.1.339 NAME 'msSFU30NisDomain' EQUALITY caseExactMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )
+olcAttributeTypes: {24}( 1.2.840.113556.1.4.51 NAME 'lastLogoff' EQUALITY integerMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )
+olcAttributeTypes: {25}( 1.2.840.113556.1.4.52 NAME 'lastLogon' EQUALITY integerMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )
+olcAttributeTypes: {26}( 1.2.840.113556.1.4.96 NAME 'pwdLastSet' EQUALITY numericStringMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.36' SINGLE-VALUE )
+olcAttributeTypes: {27}( 1.2.840.113556.1.4.64 NAME 'logonHours' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE)
+olcAttributeTypes: {28}( 1.2.840.113556.1.4.98 NAME 'primaryGroupID' EQUALITY integerMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )
+olcAttributeTypes: {29}( 1.2.840.113556.1.4.159 NAME 'accountExpires' EQUALITY numericStringMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.36' SINGLE-VALUE )
+olcAttributeTypes: {30}( 1.2.840.113556.1.4.169 NAME 'logonCount' EQUALITY integerMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )
+olcAttributeTypes: {31}( 1.2.840.113556.1.4.771 NAME 'servicePrincipalName' EQUALITY caseExactMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )
+olcAttributeTypes: {31}( 1.2.840.113556.1.4.656 NAME 'userPrincipalName' EQUALITY caseExactMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )
+olcAttributeTypes: {32}( 1.2.840.113556.1.6.18.1.309 NAME 'msSFU30Name' EQUALITY caseExactMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )
+olcAttributeTypes: {33}( 1.2.840.113556.1.4.1696 NAME 'lastLogonTimestamp' EQUALITY numericStringMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.36' SINGLE-VALUE )
+olcObjectClasses: {1}( 1.2.840.113556.1.5.9 NAME 'user' DESC 'a user' SUP organizationalPerson STRUCTURAL MUST ( cn $ objectSid $ instanceType $ sAMAccountName $ objectCategory ) MAY ( userPassword $ description $ distinguishedName $ name $ userAccountControl $ badPwdCount $ memberOf $ codePage $ sAMAccountType $ adminCount $ countryCode $ dSCorePropagationData $ whenCreated $ whenChanged $ uSNCreated $ uSNChanged $ badPasswordTime $ msSFU30NisDomain $ lastLogoff $ lastLogon $ objectGUID $ pwdLastSet $ logonCount $ logonHours $ primaryGroupID $ accountExpires $ isCriticalSystemObject $ servicePrincipalName $ userPrincipalName $ msSFU30Name $ lastLogonTimestamp $ showInAdvancedViewOnly $ givenName $ displayName $ uid ) )
+olcObjectClasses: {2}( 1.2.840.113556.1.5.8 NAME 'group' DESC 'a group of users' SUP top STRUCTURAL MUST ( groupType $ cn $ objectSid $ instanceType $ sAMAccountName $ objectCategory ) MAY ( member $ description $ distinguishedName $ name $ memberOf $ sAMAccountType $ adminCount $ dSCorePropagationData $ whenCreated $ whenChanged $ uSNCreated $ uSNChanged $ msSFU30NisDomain $ objectGUID $ isCriticalSystemObject $ gidNumber ) )
+olcObjectClasses: {3}( 1.2.840.113556.1.3.23 NAME 'container' DESC 'asdasd' SUP top STRUCTURAL MUST ( cn $ instanceType $ objectCategory ) MAY ( whenCreated $ whenChanged $ uSNCreated $ uSNChanged $ showInAdvancedViewOnly $ objectGUID $ systemFlags $ isCriticalSystemObject $ dSCorePropagationData $ description $ distinguishedName $ name ) )
diff --git a/src/tests/intg/ds_openldap.py b/src/tests/intg/ds_openldap.py
index b7e0eb6c4..842ff9108 100644
--- a/src/tests/intg/ds_openldap.py
+++ b/src/tests/intg/ds_openldap.py
@@ -3,6 +3,7 @@
 #
 # Copyright (c) 2015 Red Hat, Inc.
 # Author: Nikolai Kondrashov <nikolai.kondras...@redhat.com>
+# Author: Lukas Slebodnik <lsleb...@redhat.com>
 #
 # This is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -292,3 +293,79 @@ def teardown(self):
 
         for path in (self.conf_slapd_d_dir, self.run_dir, self.data_dir):
             shutil.rmtree(path, True)
+
+
+class FakeAD(DSOpenLDAP):
+    """Fake Active Directory based on OpenLDAP directory server."""
+
+    def _setup_config(self):
+        """Setup the instance initial configuration."""
+
+        # Import ad schema
+        subprocess.check_call(
+            ["slapadd", "-F", self.conf_slapd_d_dir, "-b", "cn=config",
+             "-l", "data/ad_schema.ldif"],
+        )
+
+    def setup(self):
+        """Setup the instance."""
+        ldapi_socket = self.run_dir + "/ldapi"
+        self.ldapi_url = "ldapi://" + url_quote(ldapi_socket, "")
+        self.url_list = self.ldapi_url + " " + self.ldap_url
+
+        os.makedirs(self.conf_slapd_d_dir)
+        os.makedirs(self.run_dir)
+        os.makedirs(self.data_dir)
+
+        super(FakeAD, self)._setup_config()
+        self._setup_config()
+
+        # Start the daemon
+        super(FakeAD, self)._start_daemon()
+
+        # Relax requirement of surname attribute presence in person
+        modlist = [
+            (ldap.MOD_DELETE, "olcObjectClasses",
+             b"{4}( 2.5.6.6 NAME 'person' DESC 'RFC2256: a person' SUP top "
+             b"STRUCTURAL MUST ( sn $ cn ) MAY ( userPassword $ "
+             b"telephoneNumber $ seeAlso $ description ) )"),
+            (ldap.MOD_ADD, "olcObjectClasses",
+             b"{4}( 2.5.6.6 NAME 'person' DESC 'RFC2256: a person' SUP top "
+             b"STRUCTURAL MUST ( cn ) MAY ( sn $ userPassword $ "
+             b"telephoneNumber $ seeAlso $ description ) )"),
+        ]
+        ldap_conn = ldap.initialize(self.ldapi_url)
+        ldap_conn.simple_bind_s(self.admin_rdn + ",cn=config", self.admin_pw)
+        ldap_conn.modify_s("cn={0}core,cn=schema,cn=config", modlist)
+        ldap_conn.unbind_s()
+
+        # restart daemon for reloading schema
+        super(FakeAD, self)._stop_daemon()
+        super(FakeAD, self)._start_daemon()
+
+        # Add data
+        ldap_conn = ldap.initialize(self.ldap_url)
+        ldap_conn.simple_bind_s(self.admin_dn, self.admin_pw)
+        ldap_conn.add_s(self.base_dn, [
+            ("objectClass", [b"dcObject", b"organization"]),
+            ("o", b"Example Company"),
+        ])
+        ldap_conn.add_s("cn=Manager," + self.base_dn, [
+            ("objectClass", b"organizationalRole"),
+        ])
+        for ou in ("Users", "Groups", "Netgroups", "Services", "Policies"):
+            ldap_conn.add_s("ou=" + ou + "," + self.base_dn, [
+                ("objectClass", [b"top", b"organizationalUnit"]),
+            ])
+        ldap_conn.unbind_s()
+
+        # import data from real AD
+        subprocess.check_call(
+            ["ldapadd", "-x", "-w", self.admin_pw, "-D",
+             self.admin_dn, "-H", self.ldap_url,
+             "-f", "data/ad_data.ldif"],
+        )
+
+    def teardown(self):
+        """Teardown the instance."""
+        super(FakeAD, self).teardown()

From 96421d7ec8a271f5f73199530da798c291e0a3f9 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lsleb...@redhat.com>
Date: Wed, 6 Sep 2017 15:14:31 +0200
Subject: [PATCH 7/7] intg: Add sanity tests for pysss_nss_idmap

---
 src/tests/intg/Makefile.am             |   1 +
 src/tests/intg/test_pysss_nss_idmap.py | 269 +++++++++++++++++++++++++++++++++
 2 files changed, 270 insertions(+)
 create mode 100644 src/tests/intg/test_pysss_nss_idmap.py

diff --git a/src/tests/intg/Makefile.am b/src/tests/intg/Makefile.am
index eb157693d..f7796c5c7 100644
--- a/src/tests/intg/Makefile.am
+++ b/src/tests/intg/Makefile.am
@@ -33,6 +33,7 @@ dist_noinst_DATA = \
     test_kcm.py \
     data/ad_data.ldif \
     data/ad_schema.ldif \
+    test_pysss_nss_idmap.py \
     $(NULL)
 
 config.py: config.py.m4
diff --git a/src/tests/intg/test_pysss_nss_idmap.py b/src/tests/intg/test_pysss_nss_idmap.py
new file mode 100644
index 000000000..aed2a8cf9
--- /dev/null
+++ b/src/tests/intg/test_pysss_nss_idmap.py
@@ -0,0 +1,269 @@
+#
+# LDAP integration test
+#
+# Copyright (c) 2017 Red Hat, Inc.
+# Author: Lukas Slebodnik <lsleb...@redhat.com>
+#
+# This is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 only
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+import os
+import stat
+import pwd
+import grp
+import signal
+import subprocess
+import time
+import pytest
+import ldb
+import pysss_nss_idmap
+
+import config
+import ds_openldap
+
+from .util import unindent
+
+LDAP_BASE_DN = "dc=example,dc=com"
+
+
+@pytest.fixture(scope="module")
+def ad_inst(request):
+    """Fake AD server instance fixture"""
+    instance = ds_openldap.FakeAD(
+        config.PREFIX, 10389, LDAP_BASE_DN,
+        "cn=admin", "Secret123"
+    )
+
+    try:
+        instance.setup()
+    except:
+        instance.teardown()
+        raise
+    request.addfinalizer(instance.teardown)
+    return instance
+
+
+@pytest.fixture(scope="module")
+def ldap_conn(request, ad_inst):
+    """LDAP server connection fixture"""
+    ldap_conn = ad_inst.bind()
+    ldap_conn.ad_inst = ad_inst
+    request.addfinalizer(ldap_conn.unbind_s)
+    return ldap_conn
+
+
+def format_basic_conf(ldap_conn):
+    """Format a basic SSSD configuration"""
+    return unindent("""\
+        [sssd]
+        domains = FakeAD
+        services = nss
+
+        [nss]
+
+        [pam]
+
+        [domain/FakeAD]
+        ldap_search_base = {ldap_conn.ad_inst.base_dn}
+        ldap_referrals = false
+
+        id_provider = ldap
+        auth_provider = ldap
+        chpass_provider = ldap
+        access_provider = ldap
+
+        ldap_uri = {ldap_conn.ad_inst.ldap_url}
+        ldap_default_bind_dn = {ldap_conn.ad_inst.admin_dn}
+        ldap_default_authtok_type = password
+        ldap_default_authtok = {ldap_conn.ad_inst.admin_pw}
+
+        ldap_schema = ad
+        ldap_id_mapping = true
+        ldap_idmap_default_domain_sid = S-1-5-21-1305200397-2901131868-73388776
+        case_sensitive = False
+    """).format(**locals())
+
+
+def create_conf_file(contents):
+    """Create sssd.conf with specified contents"""
+    conf = open(config.CONF_PATH, "w")
+    conf.write(contents)
+    conf.close()
+    os.chmod(config.CONF_PATH, stat.S_IRUSR | stat.S_IWUSR)
+
+
+def create_conf_fixture(request, contents):
+    """
+    Create sssd.conf with specified contents and add teardown for removing it
+    """
+    create_conf_file(contents)
+
+    def cleanup_conf_file():
+        """Remove sssd.conf, if it exists"""
+        if os.path.lexists(config.CONF_PATH):
+            os.unlink(config.CONF_PATH)
+
+    request.addfinalizer(cleanup_conf_file)
+
+
+def create_sssd_process():
+    """Start the SSSD process"""
+    if subprocess.call(["sssd", "-D", "-f"]) != 0:
+        raise Exception("sssd start failed")
+
+
+def cleanup_sssd_process():
+    """Stop the SSSD process and remove its state"""
+    try:
+        with open(config.PIDFILE_PATH, "r") as pid_file:
+            pid = int(pid_file.read())
+        os.kill(pid, signal.SIGTERM)
+        while True:
+            try:
+                os.kill(pid, signal.SIGCONT)
+            except:
+                break
+            time.sleep(1)
+    except:
+        pass
+    for path in os.listdir(config.DB_PATH):
+        os.unlink(config.DB_PATH + "/" + path)
+    for path in os.listdir(config.MCACHE_PATH):
+        os.unlink(config.MCACHE_PATH + "/" + path)
+
+
+def create_sssd_fixture(request):
+    """Start SSSD and add teardown for stopping it and removing its state"""
+    create_sssd_process()
+    request.addfinalizer(cleanup_sssd_process)
+
+
+def sysdb_sed_domainid(domain_name, doamin_id):
+    sssd_cache = "{0}/cache_{1}.ldb".format(config.DB_PATH, domain_name)
+    domain_ldb = ldb.Ldb(sssd_cache)
+
+    msg = ldb.Message()
+    msg.dn = ldb.Dn(domain_ldb, "cn=sysdb")
+    msg["cn"] = "sysdb"
+    msg["description"] = "base object"
+    msg["version"] = "0.17"
+    domain_ldb.add(msg)
+
+    # Set domainID for fake AD domain
+    msg = ldb.Message()
+    msg.dn = ldb.Dn(domain_ldb, "cn={0},cn=sysdb".format(domain_name))
+    msg["cn"] = domain_name
+    msg["domainID"] = doamin_id
+    msg["distinguishedName"] = "cn={0},cn=sysdb".format(domain_name)
+    domain_ldb.add(msg)
+
+    msg = ldb.Message()
+    msg.dn = ldb.Dn(domain_ldb, "@ATTRIBUTES")
+    msg["distinguishedName"] = "@ATTRIBUTES"
+    for attr in ['cn', 'dc', 'dn', 'objectclass', 'originalDN',
+                 'userPrincipalName']:
+        msg[attr] = "CASE_INSENSITIVE"
+    domain_ldb.add(msg)
+
+    msg = ldb.Message()
+    msg.dn = ldb.Dn(domain_ldb, "@INDEXLIST")
+    msg["distinguishedName"] = "@INDEXLIST"
+    msg["@IDXONE"] = "1"
+    for attr in ['cn', 'objectclass', 'member', 'memberof', 'name',
+                 'uidNumber', 'gidNumber', 'lastUpdate', 'dataExpireTimestamp',
+                 'originalDN', 'nameAlias', 'servicePort', 'serviceProtocol',
+                 'sudoUser', 'sshKnownHostsExpire', 'objectSIDString']:
+        msg["@IDXATTR"] = attr
+    domain_ldb.add(msg)
+
+    msg = ldb.Message()
+    msg.dn = ldb.Dn(domain_ldb, "@MODULES")
+    msg["distinguishedName"] = "@MODULES"
+    msg["@LIST"] = "asq,memberof"
+    domain_ldb.add(msg)
+
+
+@pytest.fixture
+def simple_ad(request, ldap_conn):
+    conf = format_basic_conf(ldap_conn)
+    sysdb_sed_domainid("FakeAD", "S-1-5-21-1305200397-2901131868-73388776")
+
+    create_conf_fixture(request, conf)
+    create_sssd_fixture(request)
+    return None
+
+
+def test_user_operations(ldap_conn, simple_ad):
+    user = 'user1_dom1-19661'
+    user_id = pwd.getpwnam(user).pw_uid
+    user_sid = 'S-1-5-21-1305200397-2901131868-73388776-82809'
+
+    output = pysss_nss_idmap.getsidbyname(user)[user]
+    assert output[pysss_nss_idmap.TYPE_KEY] == pysss_nss_idmap.ID_USER
+    assert output[pysss_nss_idmap.SID_KEY] == user_sid
+
+    output = pysss_nss_idmap.getsidbyid(user_id)[user_id]
+    assert output[pysss_nss_idmap.TYPE_KEY] == pysss_nss_idmap.ID_USER
+    assert output[pysss_nss_idmap.SID_KEY] == user_sid
+
+    output = pysss_nss_idmap.getidbysid(user_sid)[user_sid]
+    assert output[pysss_nss_idmap.TYPE_KEY] == pysss_nss_idmap.ID_USER
+    assert output[pysss_nss_idmap.ID_KEY] == user_id
+
+    output = pysss_nss_idmap.getnamebysid(user_sid)[user_sid]
+    assert output[pysss_nss_idmap.TYPE_KEY] == pysss_nss_idmap.ID_USER
+    assert output[pysss_nss_idmap.NAME_KEY] == user
+
+
+def test_group_operations(ldap_conn, simple_ad):
+    group = 'group3_dom1-17775'
+    group_id = grp.getgrnam(group).gr_gid
+    group_sid = 'S-1-5-21-1305200397-2901131868-73388776-82764'
+
+    output = pysss_nss_idmap.getsidbyname(group)[group]
+    assert output[pysss_nss_idmap.TYPE_KEY] == pysss_nss_idmap.ID_GROUP
+    assert output[pysss_nss_idmap.SID_KEY] == group_sid
+
+    output = pysss_nss_idmap.getsidbyid(group_id)[group_id]
+    assert output[pysss_nss_idmap.TYPE_KEY] == pysss_nss_idmap.ID_GROUP
+    assert output[pysss_nss_idmap.SID_KEY] == group_sid
+
+    output = pysss_nss_idmap.getidbysid(group_sid)[group_sid]
+    assert output[pysss_nss_idmap.TYPE_KEY] == pysss_nss_idmap.ID_GROUP
+    assert output[pysss_nss_idmap.ID_KEY] == group_id
+
+    output = pysss_nss_idmap.getnamebysid(group_sid)[group_sid]
+    assert output[pysss_nss_idmap.TYPE_KEY] == pysss_nss_idmap.ID_GROUP
+    assert output[pysss_nss_idmap.NAME_KEY] == group
+
+
+def test_case_insensitive(ldap_conn, simple_ad):
+    # resolve group and also member of this group
+    group = 'Domain Users'
+    group_id = grp.getgrnam(group).gr_gid
+    group_sid = 'S-1-5-21-1305200397-2901131868-73388776-513'
+
+    output = pysss_nss_idmap.getsidbyname(group)[group]
+    assert output[pysss_nss_idmap.TYPE_KEY] == pysss_nss_idmap.ID_GROUP
+    assert output[pysss_nss_idmap.SID_KEY] == group_sid
+
+    output = pysss_nss_idmap.getsidbyid(group_id)[group_id]
+    assert output[pysss_nss_idmap.TYPE_KEY] == pysss_nss_idmap.ID_GROUP
+    assert output[pysss_nss_idmap.SID_KEY] == group_sid
+
+    output = pysss_nss_idmap.getidbysid(group_sid)[group_sid]
+    assert output[pysss_nss_idmap.TYPE_KEY] == pysss_nss_idmap.ID_GROUP
+    assert output[pysss_nss_idmap.ID_KEY] == group_id
+
+    output = pysss_nss_idmap.getnamebysid(group_sid)[group_sid]
+    assert output[pysss_nss_idmap.TYPE_KEY] == pysss_nss_idmap.ID_GROUP
+    assert output[pysss_nss_idmap.NAME_KEY] == group.lower()
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org

Reply via email to