diff options
Diffstat (limited to 'source4/scripting/python')
| -rw-r--r-- | source4/scripting/python/misc.i | 1 | ||||
| -rw-r--r-- | source4/scripting/python/misc_wrap.c | 1 | ||||
| -rw-r--r-- | source4/scripting/python/modules.c | 3 | ||||
| -rw-r--r-- | source4/scripting/python/pyrpc.h | 2 | ||||
| -rw-r--r-- | source4/scripting/python/samba/getopt.py | 15 | ||||
| -rw-r--r-- | source4/scripting/python/samba/idmap.py | 73 | ||||
| -rw-r--r-- | source4/scripting/python/samba/provision.py | 156 | ||||
| -rw-r--r-- | source4/scripting/python/samba/samdb.py | 77 | ||||
| -rw-r--r-- | source4/scripting/python/samba/tests/dcerpc/unix.py | 30 | ||||
| -rw-r--r-- | source4/scripting/python/samba/tests/samdb.py | 1 | ||||
| -rw-r--r-- | source4/scripting/python/subunit/__init__.py | 2 | 
11 files changed, 243 insertions, 118 deletions
diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index a11b2fb825..e04e6a6906 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -25,6 +25,7 @@  #include "auth/credentials/credentials.h"  #include "dsdb/samdb/samdb.h"  #include "lib/ldb-samba/ldif_handlers.h" +#include "librpc/ndr/libndr.h"  %}  %import "stdint.i" diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index cf85e91e1e..579d1f379f 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -2533,6 +2533,7 @@ static swig_module_info swig_module = {swig_types, 27, 0, 0, 0, 0};  #include "auth/credentials/credentials.h"  #include "dsdb/samdb/samdb.h"  #include "lib/ldb-samba/ldif_handlers.h" +#include "librpc/ndr/libndr.h"  SWIGINTERN int diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index 2c10a35c60..08f3c1156c 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -34,6 +34,8 @@ extern void init_events(void);  extern void inituuid(void);  extern void init_net(void);  extern void initecho(void); +extern void initdfs(void); +extern void initdrsuapi(void);  extern void initwinreg(void);  extern void initepmapper(void);  extern void initinitshutdown(void); @@ -45,6 +47,7 @@ static void initdcerpc_security(void) {}  extern void initlsa(void);  extern void initsvcctl(void);  extern void initwkssvc(void); +extern void initunixinfo(void);  extern void init_libcli_nbt(void);  extern void init_libcli_smb(void); diff --git a/source4/scripting/python/pyrpc.h b/source4/scripting/python/pyrpc.h index 3a5d235cfc..f4d0f37c39 100644 --- a/source4/scripting/python/pyrpc.h +++ b/source4/scripting/python/pyrpc.h @@ -26,7 +26,7 @@  #define dom_sid2_Type dom_sid_Type  #define dom_sid28_Type dom_sid_Type  #define dom_sid2_Check dom_sid_Check -#define dom_sid28_Check dom_sid28_Check +#define dom_sid28_Check dom_sid_Check  /* This macro is only provided by Python >= 2.3 */  #ifndef PyAPI_DATA diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py index 088a5acf6f..82cb004b62 100644 --- a/source4/scripting/python/samba/getopt.py +++ b/source4/scripting/python/samba/getopt.py @@ -18,7 +18,7 @@  #  import optparse -from credentials import Credentials +from credentials import Credentials, AUTO_USE_KERBEROS, DONT_USE_KERBEROS, MUST_USE_KERBEROS  class SambaOptions(optparse.OptionGroup):      def __init__(self, parser): @@ -65,6 +65,9 @@ class CredentialsOptions(optparse.OptionGroup):                          help="Workgroup", callback=self._parse_workgroup)          self.add_option("-N", "--no-pass", action="store_true",                          help="Don't ask for a password") +        self.add_option("-k", "--kerberos", metavar="KERBEROS",  +                        action="callback", type=str, +                        help="Use Kerberos", callback=self._set_kerberos)          self.creds = Credentials()      def _parse_username(self, option, opt_str, arg, parser): @@ -76,11 +79,17 @@ class CredentialsOptions(optparse.OptionGroup):      def _set_password(self, option, opt_str, arg, parser):          self.creds.set_password(arg) +    def _set_kerberos(self, option, opt_str, arg, parser): +        if bool(arg) or arg.lower() == "yes": +            self.creds.set_kerberos_state(MUST_USE_KERBEROS) +        else: +            self.creds.set_kerberos_state(DONT_USE_KERBEROS) +      def _set_simple_bind_dn(self, option, opt_str, arg, parser):          self.creds.set_bind_dn(arg) -    def get_credentials(self): -        self.creds.guess() +    def get_credentials(self, lp): +        self.creds.guess(lp)          if not self.no_pass:              self.creds.set_cmdline_callbacks()          return self.creds diff --git a/source4/scripting/python/samba/idmap.py b/source4/scripting/python/samba/idmap.py new file mode 100644 index 0000000000..355565968a --- /dev/null +++ b/source4/scripting/python/samba/idmap.py @@ -0,0 +1,73 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) 2008 Kai Blin <kai@samba.org> +# +# +# 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/>. +# + +"""Convenience functions for using the idmap database.""" + +import samba +import ldb + +class IDmapDB(samba.Ldb): +    """The IDmap database.""" + +    # Mappings for ID_TYPE_UID, ID_TYPE_GID and ID_TYPE_BOTH +    TYPE_UID = 1 +    TYPE_GID = 2 +    TYPE_BOTH = 3 + +    def __init__(self, url=None, session_info=None, credentials=None, +                 modules_dir=None, lp=None): +        """Open the IDmap Database. + +        :param url: URL of the database. +        """ +        super(IDmapDB, self).__init__(session_info=session_info, credentials=credentials, +                                    modules_dir=modules_dir, lp=lp) +        if url: +            self.connect(url) + + +    def setup_name_mapping(self, sid, type, unixid): +        """Setup a mapping between a sam name and a unix name. + +        :param sid: SID of the NT-side of the mapping. +        :param unixname: Unix name to map to. +        """ +        type_string = "" +        if type == self.TYPE_UID: +            type_string = "ID_TYPE_UID" +        elif type == self.TYPE_GID: +            type_string = "ID_TYPE_GID" +        elif type == self.TYPE_BOTH: +            type_string = "ID_TYPE_BOTH" +        else: +            return + +        mod = """ +dn: CN=%s +xidNumber: %s +objectSid: %s +objectClass: sidMap +type: %s +cn: %s + +""" % (sid, unixid, sid, type_string, sid) +        self.add(self.parse_ldif(mod).next()[1]) + + diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d5e66d842c..6917aa1a54 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -28,13 +28,14 @@ import pwd  import grp  import time  import uuid, misc -from socket import gethostname, gethostbyname +import socket  import param  import registry  import samba  from auth import system_session  from samba import Ldb, substitute_var, valid_netbios_name, check_all_substituted  from samba.samdb import SamDB +from samba.idmap import IDmapDB  import security  import urllib  from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ @@ -267,7 +268,7 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole=                rootdn=None, domaindn=None, configdn=None, schemadn=None, sitename=None):      if hostname is None: -        hostname = gethostname().split(".")[0].lower() +        hostname = socket.gethostname().split(".")[0].lower()      netbiosname = hostname.upper()      if not valid_netbios_name(netbiosname): @@ -348,7 +349,7 @@ def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrol      if not os.path.exists(smbconf):          if hostname is None: -            hostname = gethostname().split(".")[0].lower() +            hostname = socket.gethostname().split(".")[0].lower()          if serverrole is None:              serverrole = "standalone" @@ -397,45 +398,30 @@ def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrol      return lp -def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users,  -                        wheel, backup): +def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, +                        users_gid, wheel_gid):      """setup reasonable name mappings for sam names to unix names. -     -    :param ldb: SamDB object. + +    :param samdb: SamDB object. +    :param idmap: IDmap db object.      :param sid: The domain sid.      :param domaindn: The domain DN. -    :param root: Name of the UNIX root user. -    :param nobody: Name of the UNIX nobody user. -    :param nogroup: Name of the unix nobody group. -    :param users: Name of the unix users group. -    :param wheel: Name of the wheel group (users that can become root). -    :param backup: Name of the backup group.""" +    :param root_uid: uid of the UNIX root user. +    :param nobody_uid: uid of the UNIX nobody user. +    :param users_gid: gid of the UNIX users group. +    :param wheel_gid: gid of the UNIX wheel group."""      # add some foreign sids if they are not present already -    ldb.add_foreign(domaindn, "S-1-5-7", "Anonymous") -    ldb.add_foreign(domaindn, "S-1-1-0", "World") -    ldb.add_foreign(domaindn, "S-1-5-2", "Network") -    ldb.add_foreign(domaindn, "S-1-5-18", "System") -    ldb.add_foreign(domaindn, "S-1-5-11", "Authenticated Users") - -    # some well known sids -    ldb.setup_name_mapping(domaindn, "S-1-5-7", nobody) -    ldb.setup_name_mapping(domaindn, "S-1-1-0", nogroup) -    ldb.setup_name_mapping(domaindn, "S-1-5-2", nogroup) -    ldb.setup_name_mapping(domaindn, "S-1-5-18", root) -    ldb.setup_name_mapping(domaindn, "S-1-5-11", users) -    ldb.setup_name_mapping(domaindn, "S-1-5-32-544", wheel) -    ldb.setup_name_mapping(domaindn, "S-1-5-32-545", users) -    ldb.setup_name_mapping(domaindn, "S-1-5-32-546", nogroup) -    ldb.setup_name_mapping(domaindn, "S-1-5-32-551", backup) - -    # and some well known domain rids -    ldb.setup_name_mapping(domaindn, sid + "-500", root) -    ldb.setup_name_mapping(domaindn, sid + "-518", wheel) -    ldb.setup_name_mapping(domaindn, sid + "-519", wheel) -    ldb.setup_name_mapping(domaindn, sid + "-512", wheel) -    ldb.setup_name_mapping(domaindn, sid + "-513", users) -    ldb.setup_name_mapping(domaindn, sid + "-520", wheel) +    samdb.add_foreign(domaindn, "S-1-5-7", "Anonymous") +    samdb.add_foreign(domaindn, "S-1-1-0", "World") +    samdb.add_foreign(domaindn, "S-1-5-2", "Network") +    samdb.add_foreign(domaindn, "S-1-5-18", "System") +    samdb.add_foreign(domaindn, "S-1-5-11", "Authenticated Users") + +    idmap.setup_name_mapping("S-1-5-7", idmap.TYPE_UID, nobody_uid) +    idmap.setup_name_mapping("S-1-5-32-544", idmap.TYPE_GID, wheel_gid) +    idmap.setup_name_mapping(sid + "-500", idmap.TYPE_UID, root_uid) +    idmap.setup_name_mapping(sid + "-513", idmap.TYPE_GID, users_gid)  def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,                              credentials, names, @@ -663,8 +649,8 @@ def setup_idmapdb(path, setup_path, session_info, credentials, lp):      if os.path.exists(path):          os.unlink(path) -    idmap_ldb = Ldb(path, session_info=session_info, credentials=credentials, -                    lp=lp) +    idmap_ldb = IDmapDB(path, session_info=session_info, +                        credentials=credentials, lp=lp)      idmap_ldb.erase()      idmap_ldb.load_ldif_file_add(setup_path("idmap_init.ldif")) @@ -695,13 +681,8 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname,  def setup_self_join(samdb, names,                      machinepass, dnspass,                       domainsid, invocationid, setup_path, -                    policyguid, hostguid=None): +                    policyguid):      """Join a host to its own domain.""" -    if hostguid is not None: -        hostguid_add = "objectGUID: %s" % hostguid -    else: -        hostguid_add = "" -      setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), {                 "CONFIGDN": names.configdn,                 "SCHEMADN": names.schemadn, @@ -714,7 +695,6 @@ def setup_self_join(samdb, names,                "DNSPASS_B64": b64encode(dnspass),                "REALM": names.realm,                "DOMAIN": names.domain, -              "HOSTGUID_ADD": hostguid_add,                "DNSDOMAIN": names.dnsdomain})      setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), {                 "POLICYGUID": policyguid, @@ -727,7 +707,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,                  names, message,                   domainsid, aci, domainguid, policyguid,                   fill, adminpass, krbtgtpass,  -                machinepass, hostguid, invocationid, dnspass, +                machinepass, invocationid, dnspass,                  serverrole, ldap_backend=None,                   ldap_backend_type=None):      """Setup a complete SAM Database. @@ -880,7 +860,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,                                  dnspass=dnspass,                                    machinepass=machinepass,                                   domainsid=domainsid, policyguid=policyguid, -                                hostguid=hostguid,                                   setup_path=setup_path)      #We want to setup the index last, as adds are faster unindexed @@ -901,8 +880,8 @@ FILL_DRS = "DRS"  def provision(setup_dir, message, session_info,                 credentials, smbconf=None, targetdir=None, samdb_fill=FILL_FULL, realm=None,                 rootdn=None, domaindn=None, schemadn=None, configdn=None, -              domain=None, hostname=None, hostip=None, domainsid=None,  -              hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None,  +              domain=None, hostname=None, hostip=None, hostip6=None,  +              domainsid=None, adminpass=None, krbtgtpass=None, domainguid=None,                 policyguid=None, invocationid=None, machinepass=None,                 dnspass=None, root=None, nobody=None, nogroup=None, users=None,                 wheel=None, backup=None, aci=None, serverrole=None,  @@ -931,18 +910,21 @@ def provision(setup_dir, message, session_info,      if dnspass is None:          dnspass = misc.random_password(12)      if root is None: -        root = findnss(pwd.getpwnam, ["root"])[0] +        root_uid = findnss(pwd.getpwnam, ["root"])[2] +    else: +        root_uid = findnss(pwd.getpwnam, [root])[2]      if nobody is None: -        nobody = findnss(pwd.getpwnam, ["nobody"])[0] -    if nogroup is None: -        nogroup = findnss(grp.getgrnam, ["nogroup", "nobody"])[0] +        nobody_uid = findnss(pwd.getpwnam, ["nobody"])[2] +    else: +        nobody_uid = findnss(pwd.getpwnam, [nobody])[2]      if users is None: -        users = findnss(grp.getgrnam, ["users", "guest", "other", "unknown",  -                        "usr"])[0] +        users_gid = findnss(grp.getgrnam, ["users"])[2] +    else: +        users_gid = findnss(grp.getgrnam, [users])[2]      if wheel is None: -        wheel = findnss(grp.getgrnam, ["wheel", "root", "staff", "adm"])[0] -    if backup is None: -        backup = findnss(grp.getgrnam, ["backup", "wheel", "root", "staff"])[0] +        wheel_gid = findnss(grp.getgrnam, ["wheel", "adm"])[2] +    else: +        wheel_gid = findnss(grp.getgrnam, [wheel])[2]      if aci is None:          aci = "# no aci for local ldb" @@ -955,7 +937,12 @@ def provision(setup_dir, message, session_info,      paths = provision_paths_from_lp(lp, names.dnsdomain)      if hostip is None: -        hostip = gethostbyname(names.hostname) +        hostip = socket.getaddrinfo(names.hostname, None, socket.AF_INET, socket.AI_CANONNAME, socket.IPPROTO_IP)[0][-1][0] + +    if hostip6 is None: +        try: +            hostip6 = socket.getaddrinfo(names.hostname, None, socket.AF_INET6, socket.AI_CANONNAME, socket.IPPROTO_IP)[0][-1][0] +        except socket.gaierror: pass      if serverrole is None:          serverrole = lp.get("server role") @@ -974,10 +961,6 @@ def provision(setup_dir, message, session_info,              # provision-backend will set this path suggested slapd command line / fedorads.inf              ldap_backend = "ldapi://" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") -    message("set DOMAIN SID: %s" % str(domainsid)) -    message("Provisioning for %s in realm %s" % (names.domain, realm)) -    message("Using administrator password: %s" % adminpass) -      # only install a new shares config db if there is none      if not os.path.exists(paths.shareconf):          message("Setting up share.ldb") @@ -1000,8 +983,8 @@ def provision(setup_dir, message, session_info,                        credentials=credentials, lp=lp)      message("Setting up idmap db") -    setup_idmapdb(paths.idmapdb, setup_path, session_info=session_info, -                  credentials=credentials, lp=lp) +    idmap = setup_idmapdb(paths.idmapdb, setup_path, session_info=session_info, +                          credentials=credentials, lp=lp)      samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info,                           credentials=credentials, lp=lp, names=names, @@ -1010,7 +993,7 @@ def provision(setup_dir, message, session_info,                          aci=aci, domainguid=domainguid, policyguid=policyguid,                           fill=samdb_fill,                           adminpass=adminpass, krbtgtpass=krbtgtpass, -                        hostguid=hostguid, invocationid=invocationid,  +                        invocationid=invocationid,                           machinepass=machinepass, dnspass=dnspass,                          serverrole=serverrole, ldap_backend=ldap_backend,                           ldap_backend_type=ldap_backend_type) @@ -1032,10 +1015,10 @@ def provision(setup_dir, message, session_info,                             machinepass=machinepass, dnsdomain=names.dnsdomain)      if samdb_fill == FILL_FULL: -        setup_name_mappings(samdb, str(domainsid), names.domaindn, root=root,  -                            nobody=nobody, nogroup=nogroup, wheel=wheel,  -                            users=users, backup=backup) -    +        setup_name_mappings(samdb, idmap, str(domainsid), names.domaindn, +                            root_uid=root_uid, nobody_uid=nobody_uid, +                            users_gid=users_gid, wheel_gid=wheel_gid) +          message("Setting up sam.ldb rootDSE marking as synchronized")          setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) @@ -1051,19 +1034,26 @@ def provision(setup_dir, message, session_info,                                         scope=SCOPE_SUBTREE)              assert isinstance(hostguid, str) -            message("Setting up DNS zone: %s" % names.dnsdomain)              create_zone_file(paths.dns, setup_path, samdb,  -                             hostname=names.hostname, hostip=hostip, dnsdomain=names.dnsdomain, +                             hostname=names.hostname, hostip=hostip, +                             hostip6=hostip6, dnsdomain=names.dnsdomain,                               domaindn=names.domaindn, dnspass=dnspass, realm=names.realm,                                domainguid=domainguid, hostguid=hostguid)              message("Please install the zone located in %s into your DNS server" % paths.dns) -    message("Setting up phpLDAPadmin configuration")      create_phpldapadmin_config(paths.phpldapadminconfig, setup_path,                                  ldapi_url)      message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) +    message("Once the above files are installed, your server will be ready to use") +    message("Server Type:    %s" % serverrole) +    message("Hostname:       %s" % names.hostname) +    message("NetBIOS Domain: %s" % names.domain) +    message("DNS Domain:     %s" % names.dnsdomain) +    message("DOMAIN SID:     %s" % str(domainsid)) +    message("Admin password: %s" % adminpass) +      result = ProvisionResult()      result.domaindn = domaindn      result.paths = paths @@ -1075,7 +1065,7 @@ def provision_become_dc(setup_dir=None,                          smbconf=None, targetdir=None, realm=None,                           rootdn=None, domaindn=None, schemadn=None, configdn=None,                          domain=None, hostname=None, domainsid=None,  -                        hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None,  +                        adminpass=None, krbtgtpass=None, domainguid=None,                           policyguid=None, invocationid=None, machinepass=None,                           dnspass=None, root=None, nobody=None, nogroup=None, users=None,                           wheel=None, backup=None, aci=None, serverrole=None,  @@ -1112,7 +1102,7 @@ def provision_backend(setup_dir=None, message=None,          return os.path.join(setup_dir, file)      if hostname is None: -        hostname = gethostname().split(".")[0].lower() +        hostname = socket.gethostname().split(".")[0].lower()      if root is None:          root = findnss(pwd.getpwnam, ["root"])[0] @@ -1245,7 +1235,7 @@ def create_phpldapadmin_config(path, setup_path, ldapi_uri):  def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn,  -                  hostip, hostname, dnspass, realm, domainguid, hostguid): +                  hostip, hostip6, hostname, dnspass, realm, domainguid, hostguid):      """Write out a DNS zone file, from the info in the current database.      :param path: Path of the new file. @@ -1253,7 +1243,8 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn,      :param samdb: SamDB object      :param dnsdomain: DNS Domain name      :param domaindn: DN of the Domain -    :param hostip: Local IP +    :param hostip: Local IPv4 IP +    :param hostip6: Local IPv6 IP      :param hostname: Local hostname      :param dnspass: Password for DNS      :param realm: Realm name @@ -1262,6 +1253,13 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn,      """      assert isinstance(domainguid, str) +    hostip6_base_line = "" +    hostip6_host_line = "" + +    if hostip6 is not None: +        hostip6_base_line = "			IN AAAA	" + hostip6 +        hostip6_host_line = hostname + "		IN AAAA	" + hostip6 +      setup_file(setup_path("provision.zone"), path, {              "DNSPASS_B64": b64encode(dnspass),              "HOSTNAME": hostname, @@ -1272,6 +1270,8 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn,              "DATESTRING": time.strftime("%Y%m%d%H"),              "DEFAULTSITE": DEFAULTSITE,              "HOSTGUID": hostguid, +            "HOSTIP6_BASE_LINE": hostip6_base_line, +            "HOSTIP6_HOST_LINE": hostip6_host_line,          })  def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 3c6bb23c02..bc3eef7879 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -53,34 +53,20 @@ description: %s          for msg in self.parse_ldif(add):              self.add(msg[1]) -    def setup_name_mapping(self, domaindn, sid, unixname): -        """Setup a mapping between a sam name and a unix name. -         -        :param domaindn: DN of the domain. -        :param sid: SID of the NT-side of the mapping. -        :param unixname: Unix name to map to. -        """ -        res = self.search(domaindn, ldb.SCOPE_SUBTREE,  -                         "objectSid=%s" % sid, ["dn"]) -        assert len(res) == 1, "Failed to find record for objectSid %s" % sid - -        mod = """ -dn: %s -changetype: modify -replace: unixName -unixName: %s -""" % (res[0].dn, unixname) -        self.modify(self.parse_ldif(mod).next()[1]) -      def enable_account(self, user_dn):          """Enable an account.          :param user_dn: Dn of the account to enable.          """ -        res = self.search(user_dn, SCOPE_ONELEVEL, None, ["userAccountControl"]) +        res = self.search(user_dn, ldb.SCOPE_BASE, None, ["userAccountControl"])          assert len(res) == 1 -        userAccountControl = res[0].userAccountControl -        userAccountControl = userAccountControl - 2 # remove disabled bit +        userAccountControl = res[0]["userAccountControl"][0] +        userAccountControl = int(userAccountControl) +        if (userAccountControl & 0x2): +            userAccountControl = userAccountControl & ~0x2 # remove disabled bit +        if (userAccountControl & 0x20): +            userAccountControl = userAccountControl & ~0x20 # remove 'no password required' bit +          mod = """  dn: %s  changetype: modify @@ -103,13 +89,9 @@ userAccountControl: %u          res = self.search("", scope=ldb.SCOPE_BASE,                             expression="(defaultNamingContext=*)",                             attrs=["defaultNamingContext"]) -        assert(len(res) == 1 and res[0].defaultNamingContext is not None) +        assert(len(res) == 1 and res[0]["defaultNamingContext"] is not None)          domain_dn = res[0]["defaultNamingContext"][0]          assert(domain_dn is not None) -        dom_users = self.searchone(basedn=domain_dn, attribute="dn",  -                                   expression="name=Domain Users") -        assert(dom_users is not None) -          user_dn = "CN=%s,CN=Users,%s" % (username, domain_dn)          # @@ -123,19 +105,44 @@ userAccountControl: %u              "sambaPassword": password,              "objectClass": "user"}) -        #  add the user to the users group as well -        modgroup = """ +        #  modify the userAccountControl to remove the disabled bit +        self.enable_account(user_dn) +        self.transaction_commit() + +    def setpassword(self, filter, password): +        """Set a password on a user record +         +        :param filter: LDAP filter to find the user (eg samccountname=name) +        :param password: Password for the user +        """ +        # connect to the sam  +        self.transaction_start() + +        # find the DNs for the domain +        res = self.search("", scope=ldb.SCOPE_BASE,  +                          expression="(defaultNamingContext=*)",  +                          attrs=["defaultNamingContext"]) +        assert(len(res) == 1 and res[0]["defaultNamingContext"] is not None) +        domain_dn = res[0]["defaultNamingContext"][0] +        assert(domain_dn is not None) + +        res = self.search(domain_dn, scope=ldb.SCOPE_SUBTREE,  +                          expression=filter, +                          attrs=[]) +        assert(len(res) == 1) +        user_dn = res[0].dn + +        setpw = """  dn: %s  changetype: modify -add: member -member: %s -""" % (dom_users, user_dn) - +replace: sambaPassword +sambaPassword: %s +""" % (user_dn, password) -        self.modify(modgroup) +        self.modify_ldif(setpw)          #  modify the userAccountControl to remove the disabled bit -        enable_account(self, user_dn) +        self.enable_account(user_dn)          self.transaction_commit()      def set_domain_sid(self, sid): diff --git a/source4/scripting/python/samba/tests/dcerpc/unix.py b/source4/scripting/python/samba/tests/dcerpc/unix.py new file mode 100644 index 0000000000..99c84c08da --- /dev/null +++ b/source4/scripting/python/samba/tests/dcerpc/unix.py @@ -0,0 +1,30 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008 +#    +# 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 unixinfo +import unittest +from samba.tests import get_loadparm + +class UnixinfoTests(unittest.TestCase): +    def setUp(self): +        self.conn = unixinfo.unixinfo("ncalrpc:", get_loadparm()) + +    def test_getpwuid(self): +        (count, infos) = self.conn.GetPWUid(1, [0]) +        self.assertEquals(1, len(infos)) diff --git a/source4/scripting/python/samba/tests/samdb.py b/source4/scripting/python/samba/tests/samdb.py index 40e56bebb5..3745dba6fc 100644 --- a/source4/scripting/python/samba/tests/samdb.py +++ b/source4/scripting/python/samba/tests/samdb.py @@ -38,6 +38,7 @@ class SamDBTestCase(TestCaseInTempDir):          policyguid = uuid.random()          setup_path = lambda x: os.path.join("setup", x)          creds = Credentials() +        creds.set_anonymous()          domainsid = security.random_sid()          hostguid = uuid.random()          path = os.path.join(self.tempdir, "samdb.ldb") diff --git a/source4/scripting/python/subunit/__init__.py b/source4/scripting/python/subunit/__init__.py index 3abfbf522e..ac3d0c3a40 100644 --- a/source4/scripting/python/subunit/__init__.py +++ b/source4/scripting/python/subunit/__init__.py @@ -5,7 +5,7 @@  #  #  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 2 of the License, or +#  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,  | 
