python/samba/netcmd/schema.py: add schema show_oc for attribute
authorWilliam Brown <william@blackhats.net.au>
Sun, 29 Apr 2018 01:28:42 +0000 (13:28 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 29 May 2018 03:34:08 +0000 (05:34 +0200)
Often administrators need to add a specific attribute to an object, but
it may not be possible with the objectClasses present. This tool allows
searching "what objectclasses must or may?" take an attribute to help hint
to an administrator what objectclasses can be added to objects to achieve
the changes they want.

Signed-off-by: William Brown <william@blackhats.net.au>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
docs-xml/manpages/samba-tool.8.xml
python/samba/netcmd/schema.py
python/samba/tests/samba_tool/schema.py

index 19c18645171d9d64337a2963648b534038e33d92..f785e53ae73c8e800911085cd473ab81e50b4b58 100644 (file)
        <para>Display an attribute schema definition.</para>
 </refsect3>
 
+<refsect3>
+       <title>schema attribute show_oc <replaceable>attribute</replaceable> [options]</title>
+       <para>Show objectclasses that MAY or MUST contain this attribute.</para>
+</refsect3>
+
 <refsect3>
        <title>schema objectclass show <replaceable>objectclass</replaceable> [options]</title>
        <para>Display an objectclass schema definition.</para>
index dbefe7999cb25481014425e8e2406f79cc670ed5..8b92b10a6f0e89ed12fd65bdd76ea3dbed1c65c9 100644 (file)
@@ -202,6 +202,55 @@ class cmd_schema_attribute_show(Command):
         user_ldif = samdb.write_ldif(res[0], ldb.CHANGETYPE_NONE)
         self.outf.write(user_ldif)
 
+class cmd_schema_attribute_show_oc(Command):
+    """Show what objectclasses MAY or MUST contain an attribute.
+
+    This is useful to determine "if I need uid, what objectclasses could be
+    applied to achieve this."
+    """
+    synopsis = "%prog attribute [options]"
+
+    takes_optiongroups = {
+        "sambaopts": options.SambaOptions,
+        "versionopts": options.VersionOptions,
+        "credopts": options.CredentialsOptions,
+        }
+
+    takes_options = [
+        Option("-H", "--URL", help="LDB URL for database or target server",
+                type=str, metavar="URL", dest="H"),
+        ]
+
+    takes_args = ["attribute"]
+
+    def run(self, attribute, H=None, credopts=None, sambaopts=None, versionopts=None):
+        lp = sambaopts.get_loadparm()
+        creds = credopts.get_credentials(lp)
+
+        samdb = SamDB(url=H, session_info=system_session(),
+            credentials=creds, lp=lp)
+
+        schema_dn = samdb.schema_dn()
+
+        may_filt = '(&(objectClass=classSchema)' \
+         '(|(mayContain={0})(systemMayContain={0})))'.format(attribute)
+        must_filt = '(&(objectClass=classSchema)' \
+         '(|(mustContain={0})(systemMustContain={0})))'.format(attribute)
+
+        may_res = samdb.search(base=schema_dn, scope=ldb.SCOPE_SUBTREE,
+                           expression=may_filt, attrs=['cn'])
+        must_res = samdb.search(base=schema_dn, scope=ldb.SCOPE_SUBTREE,
+                           expression=must_filt, attrs=['cn'])
+
+        self.outf.write('--- MAY contain ---\n')
+        for msg in may_res:
+            self.outf.write('%s\n' % msg['cn'][0])
+
+        self.outf.write('--- MUST contain ---\n')
+        for msg in must_res:
+            self.outf.write('%s\n' % msg['cn'][0])
+
+
 class cmd_schema_objectclass_show(Command):
     """Show details about an objectClass from the schema.
 
@@ -248,6 +297,7 @@ class cmd_schema_attribute(SuperCommand):
     subcommands = {}
     subcommands["modify"] = cmd_schema_attribute_modify()
     subcommands["show"] = cmd_schema_attribute_show()
+    subcommands["show_oc"] = cmd_schema_attribute_show_oc()
 
 class cmd_schema_objectclass(SuperCommand):
     """Query and manage objectclasses in the schema partition."""
index 373ae16aad97e397d4fee2db438e1065a5dee5a3..c719b1c9c0e3f1050a51cf20843ca660b55c8ed1 100644 (file)
@@ -77,6 +77,16 @@ class SchemaCmdTestCase(SambaToolCmdTest):
 
         self.assertCmdSuccess(result, out, err)
 
+    def test_show_oc_attribute(self):
+        """Tests that we can modify searchFlags of an attribute"""
+        (result, out, err) = self.runsubcmd("schema", "attribute",
+                              "show_oc", "cn",
+                              "-H", "ldap://%s" % os.environ["DC_SERVER"],
+                              "-U%s%%%s" % (os.environ["DC_USERNAME"],
+                                            os.environ["DC_PASSWORD"]))
+
+        self.assertCmdSuccess(result, out, err)
+
     def test_display_objectclass(self):
         """Tests that we can display schema objectclasses"""
         (result, out, err) = self.runsubcmd("schema", "objectclass",