[SCM] Samba Shared Repository - branch master updated

Jelmer Vernooij jelmer at samba.org
Sat Jun 19 17:33:33 MDT 2010


The branch, master has been updated
       via  1d86414... samdb: Fix formatting, move get_oid_from_attid from Ldb to SamDB.
       via  b481820... s4-python: Remove trivial function, replace by dictionary.
       via  e55c012... make test modules for net group set of commands and modification to the newuser to include additional parameters
       via  214133f... Modifications extending functionality of newuser cmd and new net group set of commands for group related operations on ldb
       via  c58c0c2... Modifications extending functionality of newuser cmd and new net group set of commands for group related operations on ldb
      from  38a26f7... s4 upgradeprovision: Make grouped commit / rollback more resistant to unexpected problems

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 1d86414eb022bd8c4d86bdab094a06f43e4eb10c
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Sun Jun 20 01:28:39 2010 +0200

    samdb: Fix formatting, move get_oid_from_attid from Ldb to SamDB.

commit b48182007c53faebb0a57cefb5e1923a3bef5851
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Sun Jun 20 01:26:23 2010 +0200

    s4-python: Remove trivial function, replace by dictionary.

commit e55c012accef40a9e07f8a9e67d54afd18ba2a7e
Author: Lukasz Zalewski <lukas at eecs.qmul.ac.uk>
Date:   Sun Jun 13 11:02:44 2010 +0100

    make test modules for net group set of commands and modification to the newuser to include additional parameters
    
    Signed-off-by: Jelmer Vernooij <jelmer at samba.org>

commit 214133fbec27c4ed42bb8c527e1365a321de0fbf
Author: Lukasz Zalewski <lukas at eecs.qmul.ac.uk>
Date:   Tue Jun 8 20:33:56 2010 +0100

    Modifications extending functionality of newuser cmd and new net group set of commands for group related operations on ldb
    
    Signed-off-by: Jelmer Vernooij <jelmer at samba.org>

commit c58c0c2129b1df7b5eeb984bed4a09f2ecdfc2b1
Author: Lukasz Zalewski <lukas at eecs.qmul.ac.uk>
Date:   Mon Jun 7 17:10:28 2010 +0100

    Modifications extending functionality of newuser cmd and new net group set of commands for group related operations on ldb
    
    Signed-off-by: Jelmer Vernooij <jelmer at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source4/scripting/bin/upgradeprovision            |   15 +-
 source4/scripting/python/samba/__init__.py        |    3 -
 source4/scripting/python/samba/misc.py            |   33 ---
 source4/scripting/python/samba/netcmd/__init__.py |    2 +
 source4/scripting/python/samba/netcmd/group.py    |  193 +++++++++++++++++
 source4/scripting/python/samba/netcmd/newuser.py  |   35 +++-
 source4/scripting/python/samba/samdb.py           |  233 +++++++++++++++++++-
 source4/scripting/python/samba/tests/dsdb.py      |    6 +-
 source4/selftest/tests.sh                         |    3 +-
 source4/setup/tests/blackbox_group.sh             |   73 +++++++
 source4/setup/tests/blackbox_newuser.sh           |   10 +-
 11 files changed, 547 insertions(+), 59 deletions(-)
 delete mode 100644 source4/scripting/python/samba/misc.py
 create mode 100644 source4/scripting/python/samba/netcmd/group.py
 create mode 100755 source4/setup/tests/blackbox_group.sh


Changeset truncated at 500 lines:

diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision
index a478856..242d040 100755
--- a/source4/scripting/bin/upgradeprovision
+++ b/source4/scripting/bin/upgradeprovision
@@ -22,6 +22,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
+import ldb
 import logging
 import optparse
 import os
@@ -41,7 +42,6 @@ from ldb import (SCOPE_SUBTREE, SCOPE_BASE,
                 FLAG_MOD_REPLACE, FLAG_MOD_ADD, FLAG_MOD_DELETE,
                 MessageElement, Message, Dn)
 from samba import param
-from samba.misc import messageEltFlagToString
 from samba.provision import (find_setup_dir, get_domain_descriptor,
                             get_config_descriptor, secretsdb_self_join,
                             ProvisioningError, getLastProvisionUSN,
@@ -683,6 +683,13 @@ def handle_links(samdb, att, basedn, dn, value, ref_value, delta):
     else:
         delta.remove(att)
 
+
+msg_elt_flag_strs = {
+    ldb.FLAG_MOD_ADD: "MOD_ADD",
+    ldb.FLAG_MOD_REPLACE: "MOD_REPLACE",
+    ldb.FLAG_MOD_DELETE: "MOD_DELETE" }
+
+
 def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid):
     """ This function updates the object that are already present in the
         provision
@@ -857,11 +864,11 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid):
                             if opts.debugchange or opts.debugall:
                                 try:
                                     dump_denied_change(dn, att,
-                                        messageEltFlagToString(msgElt.flags()),
+                                        msg_elt_flag_strs[msgElt.flags()],
                                         current[0][att], reference[0][att])
                                 except KeyError:
                                     dump_denied_change(dn, att,
-                                        messageEltFlagToString(msgElt.flags()),
+                                        msg_elt_flag_strs[msgElt.flags()],
                                         current[0][att], None)
                             delta.remove(att)
                         continue
@@ -881,6 +888,7 @@ def update_present(ref_samdb, samdb, basedn, listPresent, usns, invocationid):
             samdb.modify(delta)
     return changed
 
+
 def update_partition(ref_samdb, samdb, basedn, names, schema, provisionUSNs):
     """Check differences between the reference provision and the upgraded one.
 
@@ -960,7 +968,6 @@ def update_partition(ref_samdb, samdb, basedn, names, schema, provisionUSNs):
         return 0
 
 
-
 def check_updated_sd(ref_sam, cur_sam, names):
     """Check if the security descriptor in the upgraded provision are the same
        as the reference
diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py
index c9bb59e..8f5ff83 100644
--- a/source4/scripting/python/samba/__init__.py
+++ b/source4/scripting/python/samba/__init__.py
@@ -280,9 +280,6 @@ class Ldb(_Ldb):
     def set_schema_from_ldif(self, pf, df):
         dsdb.dsdb_set_schema_from_ldif(self, pf, df)
 
-    def get_oid_from_attid(self, attid):
-        return dsdb.dsdb_get_oid_from_attid(self, attid)
-
     def set_schema_from_ldb(self, ldb):
         dsdb.dsdb_set_schema_from_ldb(self, ldb)
 
diff --git a/source4/scripting/python/samba/misc.py b/source4/scripting/python/samba/misc.py
deleted file mode 100644
index 0089751..0000000
--- a/source4/scripting/python/samba/misc.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/python
-
-# Unix SMB/CIFS implementation.
-# Copyright (C) Matthieu Patou 2010 <mat at matws.net>
-#
-#
-# This program 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; either version 3 of the License, or
-# (at your option) any later version.
-#
-# 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/>.
-#
-
-"""Misc helper functions"""
-
-__docformat__ = "restructuredText"
-
-import ldb
-
-def messageEltFlagToString(flag):
-    if flag == ldb.FLAG_MOD_ADD:
-        return "MOD_ADD"
-    elif flag == ldb.FLAG_MOD_REPLACE:
-        return "MOD_REPLACE"
-    elif flag == ldb.FLAG_MOD_DELETE:
-        return "MOD_DELETE"
diff --git a/source4/scripting/python/samba/netcmd/__init__.py b/source4/scripting/python/samba/netcmd/__init__.py
index 3deaec3..f51e21a 100644
--- a/source4/scripting/python/samba/netcmd/__init__.py
+++ b/source4/scripting/python/samba/netcmd/__init__.py
@@ -160,3 +160,5 @@ from samba.netcmd.vampire import cmd_vampire
 commands["vampire"] = cmd_vampire()
 from samba.netcmd.machinepw import cmd_machinepw
 commands["machinepw"] = cmd_machinepw()
+from samba.netcmd.group import cmd_group
+commands["group"] = cmd_group()
diff --git a/source4/scripting/python/samba/netcmd/group.py b/source4/scripting/python/samba/netcmd/group.py
new file mode 100644
index 0000000..41506bb
--- /dev/null
+++ b/source4/scripting/python/samba/netcmd/group.py
@@ -0,0 +1,193 @@
+#!/usr/bin/python
+#
+# Adds a new user to a Samba4 server
+# Copyright Jelmer Vernooij 2008
+#
+# Based on the original in EJS:
+# Copyright Andrew Tridgell 2005
+#
+# This program 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; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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 samba.getopt as options
+from samba.netcmd import Command, SuperCommand, CommandError, Option
+import ldb
+
+from getpass import getpass
+from samba.auth import system_session
+from samba.samdb import SamDB
+from samba.dsdb import (
+    GTYPE_SECURITY_DOMAIN_LOCAL_GROUP,
+    GTYPE_SECURITY_GLOBAL_GROUP,
+    GTYPE_SECURITY_UNIVERSAL_GROUP,
+    GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP,
+    GTYPE_DISTRIBUTION_GLOBAL_GROUP,
+    GTYPE_DISTRIBUTION_UNIVERSAL_GROUP,
+)
+
+security_group = dict({"Domain": GTYPE_SECURITY_DOMAIN_LOCAL_GROUP, "Global": GTYPE_SECURITY_GLOBAL_GROUP, "Universal": GTYPE_SECURITY_UNIVERSAL_GROUP})
+distribution_group = dict({"Domain": GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP, "Global": GTYPE_DISTRIBUTION_GLOBAL_GROUP, "Universal": GTYPE_DISTRIBUTION_UNIVERSAL_GROUP})
+
+
+class cmd_group_add(Command):
+    """Creates a new group"""
+
+    synopsis = "%prog group add [options] <groupname>"
+
+    takes_optiongroups = {
+        "sambaopts": options.SambaOptions,
+        "versionopts": options.VersionOptions,
+        "credopts": options.CredentialsOptions,
+    }
+
+    takes_options = [
+        Option("-H", help="LDB URL for database or target server", type=str),
+        Option("--groupou",
+	   help="Alternative location (without domainDN counterpart) to default CN=Users in which new user object will be created",
+	   type=str),
+        Option("--group-scope", type="choice", choices=["Domain", "Global", "Universal"],
+            help="Group scope (Domain | Global | Universal)"),
+        Option("--group-type", type="choice", choices=["Security", "Distribution"],
+            help="Group type (Security | Distribution)"),
+        Option("--description", help="Group's description", type=str),
+        Option("--mail-address", help="Group's email address", type=str),
+        Option("--notes", help="Groups's notes", type=str),
+    ]
+
+    takes_args = ["groupname"]
+
+    def run(self, groupname, credopts=None, sambaopts=None,
+            versionopts=None, H=None, groupou=None, group_scope=None,
+            group_type=None, description=None, mail_address=None, notes=None):
+
+        if (group_type or "Security") == "Security":
+              gtype = security_group.get(group_scope, GTYPE_SECURITY_GLOBAL_GROUP)
+        else:
+              gtype = distribution_group.get(group_scope, GTYPE_DISTRIBUTION_GLOBAL_GROUP)
+
+        lp = sambaopts.get_loadparm()
+        creds = credopts.get_credentials(lp)
+
+        try:
+            samdb = SamDB(url=H, session_info=system_session(),
+                          credentials=creds, lp=lp)
+            samdb.newgroup(groupname, groupou=groupou, grouptype = gtype,
+                          description=description, mailaddress=mail_address, notes=notes)
+        except ldb.LdbError, (num, msg):
+            raise CommandError('Failed to create group "%s" : %s' % (
+                groupname, msg))
+
+
+class cmd_group_delete(Command):
+    """Delete a group"""
+
+    synopsis = "%prog group delete <groupname>"
+
+    takes_optiongroups = {
+        "sambaopts": options.SambaOptions,
+        "versionopts": options.VersionOptions,
+        "credopts": options.CredentialsOptions,
+    }
+
+    takes_options = [
+        Option("-H", help="LDB URL for database or target server", type=str),
+    ]
+
+    takes_args = ["groupname"]
+
+    def run(self, groupname, credopts=None, sambaopts=None, versionopts=None, H=None):
+
+        lp = sambaopts.get_loadparm()
+        creds = credopts.get_credentials(lp)
+
+        try:
+            samdb = SamDB(url=H, session_info=system_session(),
+                          credentials=creds, lp=lp)
+            samdb.deletegroup(groupname)
+        except ldb.LdbError, (num, msg):
+            raise CommandError('Failed to remove group "%s": %s' % (
+                groupname , msg))
+
+
+class cmd_group_add_members(Command):
+    """Add (comma-separated list of) group members"""
+
+    synopsis = "%prog group addmembers <groupname> <listofmembers>"
+
+    takes_optiongroups = {
+        "sambaopts": options.SambaOptions,
+        "versionopts": options.VersionOptions,
+        "credopts": options.CredentialsOptions,
+    }
+
+    takes_options = [
+        Option("-H", help="LDB URL for database or target server", type=str),
+    ]
+
+    takes_args = ["groupname", "listofmembers"]
+
+    def run(self, groupname, listofmembers, credopts=None, sambaopts=None,
+            versionopts=None, H=None):
+
+        lp = sambaopts.get_loadparm()
+        creds = credopts.get_credentials(lp)
+
+        try:
+            samdb = SamDB(url=H, session_info=system_session(),
+                          credentials=creds, lp=lp)
+            samdb.add_remove_group_members(groupname, listofmembers, add_members_operation=True)
+        except ldb.LdbError, (num, msg):
+            raise CommandError('Failed to add members "%s" to group "%s": %s' % (
+                listofmembers, groupname , msg))
+
+
+class cmd_group_remove_members(Command):
+    """Remove (comma-separated list of) group members"""
+
+    synopsis = "%prog group removemembers <groupname> <listofmembers>"
+
+    takes_optiongroups = {
+        "sambaopts": options.SambaOptions,
+        "versionopts": options.VersionOptions,
+        "credopts": options.CredentialsOptions,
+    }
+
+    takes_options = [
+        Option("-H", help="LDB URL for database or target server", type=str),
+    ]
+
+    takes_args = ["groupname", "listofmembers"]
+
+    def run(self, groupname, listofmembers, credopts=None, sambaopts=None,
+            versionopts=None, H=None):
+
+        lp = sambaopts.get_loadparm()
+        creds = credopts.get_credentials(lp)
+
+        try:
+            samdb = SamDB(url=H, session_info=system_session(),
+                          credentials=creds, lp=lp)
+            samdb.add_remove_group_members(groupname, listofmembers, add_members_operation=False)
+        except ldb.LdbError, (num, msg):
+            raise CommandError('Failed to remove members "%s" from group "%s": %s' % (
+                listofmembers, groupname , msg))
+
+
+class cmd_group(SuperCommand):
+    """Group management"""
+
+    subcommands = {}
+    subcommands["add"] = cmd_group_add()
+    subcommands["delete"] = cmd_group_delete()
+    subcommands["addmembers"] = cmd_group_add_members()
+    subcommands["removemembers"] = cmd_group_remove_members()
diff --git a/source4/scripting/python/samba/netcmd/newuser.py b/source4/scripting/python/samba/netcmd/newuser.py
index bb5537a..982b75f 100644
--- a/source4/scripting/python/samba/netcmd/newuser.py
+++ b/source4/scripting/python/samba/netcmd/newuser.py
@@ -43,12 +43,38 @@ class cmd_newuser(Command):
         Option("--must-change-at-next-login",
             help="Force password to be changed on next login",
             action="store_true"),
+        Option("--use-username-as-cn",
+            help="Force use of username as user's CN",
+            action="store_true"),
+	Option("--userou",
+	   help="Alternative location (without domainDN counterpart) to default CN=Users in which new user object will be created",
+	   type=str),
+        Option("--surname", help="User's surname", type=str),
+        Option("--given-name", help="User's given name", type=str),
+        Option("--initials", help="User's initials", type=str),
+        Option("--profile-path", help="User's profile path", type=str),
+        Option("--script-path", help="User's logon script path", type=str),
+        Option("--home-drive", help="User's home drive letter", type=str),
+        Option("--home-directory", help="User's home directory path", type=str),
+        Option("--job-title", help="User's job title", type=str),
+        Option("--department", help="User's department", type=str),
+        Option("--company", help="User's company", type=str),
+        Option("--description", help="User's description", type=str),
+        Option("--mail-address", help="User's email address", type=str),
+        Option("--internet-address", help="User's home page", type=str),
+        Option("--telephone-number", help="User's phone number", type=str),
+        Option("--physical-delivery-office", help="User's office location", type=str),
     ]
 
     takes_args = ["username", "password?"]
 
     def run(self, username, password=None, credopts=None, sambaopts=None,
-            versionopts=None, H=None, must_change_at_next_login=None):
+            versionopts=None, H=None, must_change_at_next_login=None,
+            use_username_as_cn=None, userou=None, surname=None, given_name=None, initials=None,
+            profile_path=None, script_path=None, home_drive=None, home_directory=None,
+            job_title=None, department=None, company=None, description=None,
+            mail_address=None, internet_address=None, telephone_number=None, physical_delivery_office=None):
+
         if password is None:
             password = getpass("New Password: ")
 
@@ -59,7 +85,12 @@ class cmd_newuser(Command):
             samdb = SamDB(url=H, session_info=system_session(),
                           credentials=creds, lp=lp)
             samdb.newuser(username, password,
-                          force_password_change_at_next_login_req=must_change_at_next_login)
+                          force_password_change_at_next_login_req=must_change_at_next_login,
+                          useusernameascn=use_username_as_cn, userou=userou, surname=surname, givenname=given_name, initials=initials,
+                          profilepath=profile_path, homedrive=home_drive, scriptpath=script_path, homedirectory=home_directory,
+                          jobtitle=job_title, department=department, company=company, description=description,
+                          mailaddress=mail_address, internetaddress=internet_address,
+                          telephonenumber=telephone_number, physicaldeliveryoffice=physical_delivery_office)
         except ldb.LdbError, (num, msg):
             raise CommandError('Failed to create user "%s" : %s' % (
                 username, msg))
diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py
index 4af330b..a47db96 100644
--- a/source4/scripting/python/samba/samdb.py
+++ b/source4/scripting/python/samba/samdb.py
@@ -1,7 +1,7 @@
 #!/usr/bin/python
 
 # Unix SMB/CIFS implementation.
-# Copyright (C) Jelmer Vernooij <jelmer at samba.org> 2007-2008
+# Copyright (C) Jelmer Vernooij <jelmer at samba.org> 2007-2010
 # Copyright (C) Matthias Dieter Wallnoefer 2009
 #
 # Based on the original in EJS:
@@ -26,8 +26,6 @@
 import dsdb
 import samba
 import ldb
-from samba.idmap import IDmapDB
-import pwd
 import time
 import base64
 
@@ -112,23 +110,231 @@ pwdLastSet: 0
 """ % (user_dn)
         self.modify_ldif(mod)
 
+    def newgroup(self, groupname, groupou=None, grouptype=None,
+                 description=None, mailaddress=None, notes=None):
+        """Adds a new group with additional parameters
+
+        :param groupname: Name of the new group
+        :param grouptype: Type of the new group
+        :param description: Description of the new group
+        :param mailaddress: Email address of the new group
+        :param notes: Notes of the new group
+        """
+
+        group_dn = "CN=%s,%s,%s" % (groupname, (groupou or "CN=Users"), self.domain_dn())
+
+        # The new user record. Note the reliance on the SAMLDB module which
+        # fills in the default informations
+        ldbmessage = {"dn": group_dn,
+            "sAMAccountName": groupname,
+            "objectClass": "group"}
+
+        if grouptype is not None:
+            ldbmessage["groupType"] = "%d" % ((grouptype)-2**32)
+
+        if description is not None:
+            ldbmessage["description"] = description
+
+        if mailaddress is not None:
+            ldbmessage["mail"] = mailaddress
+
+        if notes is not None:
+            ldbmessage["info"] = notes
+
+        self.transaction_start()
+        try:
+            self.add(ldbmessage)
+        except:
+            self.transaction_cancel()
+            raise
+        else:
+            self.transaction_commit()
+
+    def deletegroup (self, groupname):
+        """Deletes a group
+
+        :param groupname: Name of the target group
+        """
+
+        groupfilter = "(&(sAMAccountName=%s)(objectCategory=%s,%s))" % (groupname, "CN=Group,CN=Schema,CN=Configuration", self.domain_dn())
+        self.transaction_start()
+        try:
+            targetgroup = self.search(base=self.domain_dn(), scope=ldb.SCOPE_SUBTREE,
+                               expression=groupfilter, attrs=[])
+            if len(targetgroup) == 0:
+                print('Unable to find group "%s"' % (groupname or expression))
+                raise
+            assert(len(targetgroup) == 1)
+
+            self.delete (targetgroup[0].dn);
+
+        except:
+            self.transaction_cancel()
+            raise
+        else:
+            self.transaction_commit()
+
+    def add_remove_group_members (self, groupname, listofmembers,
+                                  add_members_operation=True):
+        """Adds or removes group members
+
+        :param groupname: Name of the target group
+        :param listofmembers: Comma-separated list of group members
+        :param add_members_operation: Defines if its an add or remove operation
+        """
+
+        groupfilter = "(&(sAMAccountName=%s)(objectCategory=%s,%s))" % (groupname, "CN=Group,CN=Schema,CN=Configuration", self.domain_dn())
+        groupmembers = listofmembers.split(',')
+
+        self.transaction_start()
+        try:
+            targetgroup = self.search(base=self.domain_dn(), scope=ldb.SCOPE_SUBTREE,
+                               expression=groupfilter, attrs=['member'])
+            if len(targetgroup) == 0:
+                print('Unable to find group "%s"' % (groupname or expression))
+                raise
+            assert(len(targetgroup) == 1)
+
+            modified = False
+
+            addtargettogroup = """
+dn: %s
+changetype: modify


-- 
Samba Shared Repository


More information about the samba-cvs mailing list