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, |