summaryrefslogtreecommitdiff
path: root/source4/scripting
diff options
context:
space:
mode:
Diffstat (limited to 'source4/scripting')
-rwxr-xr-xsource4/scripting/bin/minschema.py579
-rwxr-xr-xsource4/scripting/bin/subunitrun5
-rw-r--r--source4/scripting/ejs/config.mk29
-rw-r--r--source4/scripting/ejs/smbcalls_samba3.c501
-rw-r--r--source4/scripting/ejs/smbscript.c2
-rw-r--r--source4/scripting/libjs/provision.js4
-rw-r--r--source4/scripting/python/config.m48
-rw-r--r--source4/scripting/python/config.mk2
-rw-r--r--source4/scripting/python/samba/provision.py54
-rw-r--r--source4/scripting/python/samba/samdb.py8
-rw-r--r--source4/scripting/python/samba/tests/__init__.py6
-rw-r--r--source4/scripting/python/samba/tests/dcerpc/registry.py4
-rw-r--r--source4/scripting/python/samba/tests/dcerpc/rpcecho.py5
-rw-r--r--source4/scripting/python/samba/tests/dcerpc/sam.py3
-rw-r--r--source4/scripting/python/samba/tests/provision.py5
-rw-r--r--source4/scripting/python/samba/tests/samdb.py55
-rw-r--r--source4/scripting/python/samba/tests/upgrade.py19
-rw-r--r--source4/scripting/python/samba/upgrade.py6
-rw-r--r--source4/scripting/python/subunit/__init__.py6
19 files changed, 727 insertions, 574 deletions
diff --git a/source4/scripting/bin/minschema.py b/source4/scripting/bin/minschema.py
new file mode 100755
index 0000000000..fb9d7b05aa
--- /dev/null
+++ b/source4/scripting/bin/minschema.py
@@ -0,0 +1,579 @@
+#!/usr/bin/python
+#
+# work out the minimal schema for a set of objectclasses
+#
+
+import optparse
+import samba
+from samba import getopt as options
+import sys
+
+parser = optparse.OptionParser("minschema <URL> <classfile>")
+sambaopts = options.SambaOptions(parser)
+parser.add_option_group(sambaopts)
+credopts = options.CredentialsOptions(parser)
+parser.add_option_group(credopts)
+parser.add_option_group(options.VersionOptions(parser))
+parser.add_option("--verbose", help="Be verbose", action="store_true")
+parser.add_option("--dump-classes", action="store_true")
+parser.add_option("--dump-attributes", action="store_true")
+parser.add_option("--dump-subschema", action="store_true")
+parser.add_option("--dump-subschema-auto", action="store_true")
+
+opts, args = parser.parse_args()
+opts.dump_all = True
+
+if opts.dump_classes:
+ opts.dump_all = False
+if opts.dump_attributes:
+ opts.dump_all = False
+if opts.dump_subschema:
+ opts.dump_all = False
+if opts.dump_subschema_auto:
+ opts.dump_all = False
+ opts.dump_subschema = True
+if opts.dump_all:
+ opts.dump_classes = True
+ opts.dump_attributes = True
+ opts.dump_subschema = True
+ opts.dump_subschema_auto = True
+
+if len(args) != 2:
+ parser.print_usage()
+ sys.exit(1)
+
+(url, classfile) = args
+
+creds = credopts.get_credentials()
+ldb = Ldb(url, credentials=creds)
+
+objectclasses = []
+attributes = []
+
+objectclasses_expanded = set()
+
+# the attributes we need for objectclasses
+class_attrs = ["objectClass",
+ "subClassOf",
+ "governsID",
+ "possSuperiors",
+ "possibleInferiors",
+ "mayContain",
+ "mustContain",
+ "auxiliaryClass",
+ "rDNAttID",
+ "showInAdvancedViewOnly",
+ "adminDisplayName",
+ "adminDescription",
+ "objectClassCategory",
+ "lDAPDisplayName",
+ "schemaIDGUID",
+ "systemOnly",
+ "systemPossSuperiors",
+ "systemMayContain",
+ "systemMustContain",
+ "systemAuxiliaryClass",
+ "defaultSecurityDescriptor",
+ "systemFlags",
+ "defaultHidingValue",
+ "objectCategory",
+ "defaultObjectCategory",
+
+ # this attributes are not used by w2k3
+ "schemaFlagsEx",
+ "msDs-IntId",
+ "msDs-Schema-Extensions",
+ "classDisplayName",
+ "isDefunct"]
+
+attrib_attrs = ["objectClass",
+ "attributeID",
+ "attributeSyntax",
+ "isSingleValued",
+ "rangeLower",
+ "rangeUpper",
+ "mAPIID",
+ "linkID",
+ "showInAdvancedViewOnly",
+ "adminDisplayName",
+ "oMObjectClass",
+ "adminDescription",
+ "oMSyntax",
+ "searchFlags",
+ "extendedCharsAllowed",
+ "lDAPDisplayName",
+ "schemaIDGUID",
+ "attributeSecurityGUID",
+ "systemOnly",
+ "systemFlags",
+ "isMemberOfPartialAttributeSet",
+ "objectCategory",
+
+ # this attributes are not used by w2k3
+ "schemaFlagsEx",
+ "msDs-IntId",
+ "msDs-Schema-Extensions",
+ "classDisplayName",
+ "isEphemeral",
+ "isDefunct"]
+
+#
+# notes:
+#
+# objectClassCategory
+# 1: structural
+# 2: abstract
+# 3: auxiliary
+
+#
+# print only if verbose is set
+#
+def dprintf(text):
+ if verbose is not None:
+ print text
+
+def get_object_cn(ldb, name):
+ attrs = ["cn"]
+
+ res = ldb.search("(ldapDisplayName=%s)" % name, rootDse["schemaNamingContext"], ldb.SCOPE_SUBTREE, attrs)
+ assert len(res) == 1
+
+ return res[0]["cn"]
+
+class Objectclass:
+ def __init__(self, ldb, name):
+ """create an objectclass object"""
+ self.name = name
+ self.cn = get_object_cn(ldb, name)
+
+
+class Attribute:
+ def __init__(self, ldb, name):
+ """create an attribute object"""
+ self.name = name
+ self.cn = get_object_cn(ldb, name)
+
+
+syntaxmap = dict()
+
+syntaxmap['2.5.5.1'] = '1.3.6.1.4.1.1466.115.121.1.12'
+syntaxmap['2.5.5.2'] = '1.3.6.1.4.1.1466.115.121.1.38'
+syntaxmap['2.5.5.3'] = '1.2.840.113556.1.4.1362'
+syntaxmap['2.5.5.4'] = '1.2.840.113556.1.4.905'
+syntaxmap['2.5.5.5'] = '1.3.6.1.4.1.1466.115.121.1.26'
+syntaxmap['2.5.5.6'] = '1.3.6.1.4.1.1466.115.121.1.36'
+syntaxmap['2.5.5.7'] = '1.2.840.113556.1.4.903'
+syntaxmap['2.5.5.8'] = '1.3.6.1.4.1.1466.115.121.1.7'
+syntaxmap['2.5.5.9'] = '1.3.6.1.4.1.1466.115.121.1.27'
+syntaxmap['2.5.5.10'] = '1.3.6.1.4.1.1466.115.121.1.40'
+syntaxmap['2.5.5.11'] = '1.3.6.1.4.1.1466.115.121.1.24'
+syntaxmap['2.5.5.12'] = '1.3.6.1.4.1.1466.115.121.1.15'
+syntaxmap['2.5.5.13'] = '1.3.6.1.4.1.1466.115.121.1.43'
+syntaxmap['2.5.5.14'] = '1.2.840.113556.1.4.904'
+syntaxmap['2.5.5.15'] = '1.2.840.113556.1.4.907'
+syntaxmap['2.5.5.16'] = '1.2.840.113556.1.4.906'
+syntaxmap['2.5.5.17'] = '1.3.6.1.4.1.1466.115.121.1.40'
+
+
+def map_attribute_syntax(s):
+ """map some attribute syntaxes from some apparently MS specific
+ syntaxes to the standard syntaxes"""
+ if syntaxmap.has_key(s):
+ return syntaxmap[s]
+ return s
+
+
+def fix_dn(dn):
+ """fix a string DN to use ${SCHEMADN}"""
+ return dn.replace(rootDse["schemaNamingContext"], "${SCHEMADN}")
+
+
+def write_ldif_one(o, attrs):
+ """dump an object as ldif"""
+ print "dn: CN=%s,${SCHEMADN}\n" % o["cn"]
+ for a in attrs:
+ if not o.has_key(a):
+ continue
+ # special case for oMObjectClass, which is a binary object
+ if a == "oMObjectClass":
+ print "%s:: %s\n" % (a, o[a])
+ continue
+ v = o[a]
+ if isinstance(v, str):
+ v = [v]
+ for j in v:
+ print "%s: %s\n" % (a, fix_dn(j))
+ print "\n"
+
+def write_ldif(o, attrs):
+ """dump an array of objects as ldif"""
+ for i in o:
+ write_ldif_one(i, attrs)
+
+
+def create_testdn(exampleDN):
+ """create a testDN based an an example DN
+ the idea is to ensure we obey any structural rules"""
+ a = exampleDN.split(",")
+ a[0] = "CN=TestDN"
+ return ",".join(a)
+
+
+def find_objectclass_properties(ldb, o):
+ """the properties of an objectclass"""
+ res = ldb.search(
+ expression="(ldapDisplayName=%s)" % o.name,
+ basedn=rootDse["schemaNamingContext"], scope=ldb.SCOPE_SUBTREE, attrs=class_attrs)
+ assert(len(res) == 1)
+ msg = res[0]
+ for a in msg:
+ o[a] = msg[a]
+
+def find_attribute_properties(ldb, o):
+ """find the properties of an attribute"""
+ res = ldb.search(
+ expression="(ldapDisplayName=%s)" % o.name,
+ basedn=rootDse["schemaNamingContext"], scope=ldb.SCOPE_SUBTREE,
+ attrs=attrib_attrs)
+ assert(len(res) == 1)
+ msg = res[0]
+ for a in msg:
+ # special case for oMObjectClass, which is a binary object
+ if a == "oMObjectClass":
+ o[a] = ldb.encode(msg[a])
+ continue
+ o[a] = msg[a]
+
+
+def find_objectclass_auto(ldb, o):
+ """find the auto-created properties of an objectclass. Only works for
+ classes that can be created using just a DN and the objectclass"""
+ if not o.has_key("exampleDN"):
+ return
+ testdn = create_testdn(o.exampleDN)
+
+ print "testdn is '%s'\n" % testdn
+
+ ldif = "dn: " + testdn
+ ldif += "\nobjectClass: " + o.name
+ try:
+ ldb.add(ldif)
+ except LdbError, e:
+ print "error adding %s: %s\n" % (o.name, e)
+ print "%s\n" % ldif
+ return
+
+ res = ldb.search("", testdn, ldb.SCOPE_BASE)
+ ldb.delete(testdn)
+
+ for a in res.msgs[0]:
+ attributes[a].autocreate = True
+
+
+def expand_objectclass(ldb, o):
+ """look at auxiliary information from a class to intuit the existance of
+ more classes needed for a minimal schema"""
+ attrs = ["auxiliaryClass", "systemAuxiliaryClass",
+ "possSuperiors", "systemPossSuperiors",
+ "subClassOf"]
+ res = ldb.search(
+ expression="(&(objectClass=classSchema)(ldapDisplayName=%s))" % o.name,
+ basedn=rootDse["schemaNamingContext"], scope=ldb.SCOPE_SUBTREE,
+ attrs=attrs)
+ print "Expanding class %s\n" % o.name
+ assert(len(res) == 1)
+ msg = res[0]
+ for a in attrs:
+ if not msg.has_key(aname):
+ continue
+ list = msg[aname]
+ if isinstance(list, str):
+ list = [msg[aname]]
+ for name in list:
+ if not objectclasses.has_key(name):
+ print "Found new objectclass '%s'\n" % name
+ objectclasses[name] = Objectclass(ldb, name)
+
+
+def add_objectclass_attributes(ldb, objectclass):
+ """add the must and may attributes from an objectclass to the full list
+ of attributes"""
+ attrs = ["mustContain", "systemMustContain",
+ "mayContain", "systemMayContain"]
+ for aname in attrs:
+ if not objectclass.has_key(aname):
+ continue
+ alist = objectclass[aname]
+ if isinstance(alist, str):
+ alist = [alist]
+ for a in alist:
+ if not attributes.has_key(a):
+ attributes[a] = Attribute(ldb, a)
+
+
+def walk_dn(ldb, dn):
+ """process an individual record, working out what attributes it has"""
+ # get a list of all possible attributes for this object
+ attrs = ["allowedAttributes"]
+ try:
+ res = ldb.search("objectClass=*", dn, ldb.SCOPE_BASE, attrs)
+ except LdbError, e:
+ print "Unable to fetch allowedAttributes for '%s' - %r\n" % (dn, e)
+ return
+ allattrs = res[0]["allowedAttributes"]
+ try:
+ res = ldb.search("objectClass=*", dn, ldb.SCOPE_BASE, allattrs)
+ except LdbError, e:
+ print "Unable to fetch all attributes for '%s' - %s\n" % (dn, e)
+ return
+ msg = res[0]
+ for a in msg:
+ if not attributes.has_key(a):
+ attributes[a] = Attribute(ldb, a)
+
+def walk_naming_context(ldb, namingContext):
+ """walk a naming context, looking for all records"""
+ try:
+ res = ldb.search("objectClass=*", namingContext, ldb.SCOPE_DEFAULT,
+ ["objectClass"])
+ except LdbError, e:
+ print "Unable to fetch objectClasses for '%s' - %s\n" % (namingContext, e)
+ return
+ for msg in res:
+ msg = res.msgs[r]["objectClass"]
+ for objectClass in msg:
+ if not objectclasses.has_key(objectClass):
+ objectclasses[objectClass] = Objectclass(ldb, objectClass)
+ objectclasses[objectClass].exampleDN = res.msgs[r]["dn"]
+ walk_dn(ldb, res.msgs[r].dn)
+
+def trim_objectclass_attributes(ldb, objectclass):
+ """trim the may attributes for an objectClass"""
+ # trim possibleInferiors,
+ # include only the classes we extracted
+ if objectclass.has_key("possibleInferiors"):
+ possinf = objectclass["possibleInferiors"]
+ newpossinf = []
+ if isinstance(possinf, str):
+ possinf = [possinf]
+ for x in possinf:
+ if objectclasses.has_key(x):
+ newpossinf[n] = x
+ n+=1
+ objectclass["possibleInferiors"] = newpossinf
+
+ # trim systemMayContain,
+ # remove duplicates
+ if objectclass.has_key("systemMayContain"):
+ sysmay = objectclass["systemMayContain"]
+ newsysmay = []
+ if isinstance(sysmay, str):
+ sysmay = [sysmay]
+ for x in sysmay:
+ if not x in newsysmay:
+ newsysmay.append(x)
+ objectclass["systemMayContain"] = newsysmay
+
+ # trim mayContain,
+ # remove duplicates
+ if not objectclass.has_key("mayContain"):
+ may = objectclass["mayContain"]
+ newmay = []
+ if isinstance(may, str):
+ may = [may]
+ for x in may:
+ if not x in newmay:
+ newmay.append(x)
+ objectclass["mayContain"] = newmay
+
+def build_objectclass(ldb, name):
+ """load the basic attributes of an objectClass"""
+ attrs = ["name"]
+ try:
+ res = ldb.search(
+ expression="(&(objectClass=classSchema)(ldapDisplayName=%s))" % name,
+ basedn=rootDse["schemaNamingContext"], scope=ldb.SCOPE_SUBTREE,
+ attrs=attrs)
+ except LdbError, e:
+ print "unknown class '%s'\n" % name
+ return None
+ if len(res) == 0:
+ print "unknown class '%s'\n" % name
+ return None
+ return Objectclass(ldb, name)
+
+def attribute_list(objectclass, attr1, attr2):
+ """form a coalesced attribute list"""
+ a1 = objectclass[attr1]
+ a2 = objectclass[attr2]
+ if isinstance(a1, str):
+ a1 = [a1]
+ if isinstance(a2, str):
+ a2 = [a2]
+ return a1 + a2
+
+def aggregate_list(name, list):
+ """write out a list in aggregate form"""
+ if list is None:
+ return
+ print "%s ( %s )" % (name, "$ ".join(list))
+
+def write_aggregate_objectclass(objectclass):
+ """write the aggregate record for an objectclass"""
+ print "objectClasses: ( %s NAME '%s' " % (objectclass.governsID, objectclass.name)
+ if not objectclass.has_key('subClassOf'):
+ print "SUP %s " % objectclass['subClassOf']
+ if objectclass.objectClassCategory == 1:
+ print "STRUCTURAL "
+ elif objectclass.objectClassCategory == 2:
+ print "ABSTRACT "
+ elif objectclass.objectClassCategory == 3:
+ print "AUXILIARY "
+
+ list = attribute_list(objectclass, "systemMustContain", "mustContain")
+ aggregate_list("MUST", list)
+
+ list = attribute_list(objectclass, "systemMayContain", "mayContain")
+ aggregate_list("MAY", list)
+
+ print ")\n"
+
+
+def write_aggregate_ditcontentrule(objectclass):
+ """write the aggregate record for an ditcontentrule"""
+ list = attribute_list(objectclass, "auxiliaryClass", "systemAuxiliaryClass")
+ if list is None:
+ return
+
+ print "dITContentRules: ( %s NAME '%s' " % (objectclass.governsID, objectclass.name)
+
+ aggregate_list("AUX", list)
+
+ may_list = None
+ must_list = None
+
+ for c in list:
+ list2 = attribute_list(objectclasses[c],
+ "mayContain", "systemMayContain")
+ may_list = may_list + list2
+ list2 = attribute_list(objectclasses[c],
+ "mustContain", "systemMustContain")
+ must_list = must_list + list2
+
+ aggregate_list("MUST", must_list)
+ aggregate_list("MAY", may_list)
+
+ print ")\n"
+
+def write_aggregate_attribute(attrib):
+ """write the aggregate record for an attribute"""
+ print "attributeTypes: ( %s NAME '%s' SYNTAX '%s' " % (
+ attrib.attributeID, attrib.name,
+ map_attribute_syntax(attrib.attributeSyntax))
+ if attrib['isSingleValued'] == "TRUE":
+ print "SINGLE-VALUE "
+ if attrib['systemOnly'] == "TRUE":
+ print "NO-USER-MODIFICATION "
+
+ print ")\n"
+
+
+def write_aggregate():
+ """write the aggregate record"""
+ print "dn: CN=Aggregate,${SCHEMADN}\n"
+ print """objectClass: top
+objectClass: subSchema
+objectCategory: CN=SubSchema,${SCHEMADN}
+"""
+ if not opts.dump_subschema_auto:
+ return
+
+ for objectclass in objectclasses:
+ write_aggregate_objectclass(objectclass)
+ for attr in attributes:
+ write_aggregate_attribute(attr)
+ for objectclass in objectclasses:
+ write_aggregate_ditcontentrule(objectclass)
+
+def load_list(file):
+ """load a list from a file"""
+ return open(file, 'r').splitlines()
+
+# get the rootDSE
+res = ldb.search("", "", ldb.SCOPE_BASE)
+rootDse = res[0]
+
+# load the list of classes we are interested in
+classes = load_list(classfile)
+for classname in classes:
+ objectclass = build_objectclass(ldb, classname)
+ if objectclass is not None:
+ objectclasses[classname] = objectclass
+
+
+#
+# expand the objectclass list as needed
+#
+expanded = 0
+
+# so EJS do not have while nor the break statement
+# cannot find any other way than doing more loops
+# than necessary to recursively expand all classes
+#
+for inf in range(500):
+ for n in objectclasses:
+ if not n in objectclasses_expanded:
+ expand_objectclass(ldb, objectclasses[i])
+ objectclasses_expanded.add(n)
+
+#
+# find objectclass properties
+#
+for objectclass in objectclasses:
+ find_objectclass_properties(ldb, objectclass)
+
+
+#
+# form the full list of attributes
+#
+for objectclass in objectclasses:
+ add_objectclass_attributes(ldb, objectclass)
+
+# and attribute properties
+for attr in attributes:
+ find_attribute_properties(ldb, attr)
+
+#
+# trim the 'may' attribute lists to those really needed
+#
+for objectclass in objectclasses:
+ trim_objectclass_attributes(ldb, objectclass)
+
+#
+# dump an ldif form of the attributes and objectclasses
+#
+if opts.dump_attributes:
+ write_ldif(attributes, attrib_attrs)
+if opts.dump_classes:
+ write_ldif(objectclasses, class_attrs)
+if opts.dump_subschema:
+ write_aggregate()
+
+if not opts.verbose:
+ sys.exit(0)
+
+#
+# dump list of objectclasses
+#
+print "objectClasses:\n"
+for objectclass in objectclasses:
+ print "\t%s\n" % objectclass
+
+print "attributes:\n"
+for attr in attributes:
+ print "\t%s\n" % attr
+
+print "autocreated attributes:\n"
+for attr in attributes:
+ if attr.autocreate:
+ print "\t%s\n" % i
diff --git a/source4/scripting/bin/subunitrun b/source4/scripting/bin/subunitrun
index 7142abed85..11ac426589 100755
--- a/source4/scripting/bin/subunitrun
+++ b/source4/scripting/bin/subunitrun
@@ -21,6 +21,5 @@ from subunit import SubunitTestRunner
import sys
from unittest import TestProgram
-program = TestProgram(module=None, argv=sys.argv,
- testRunner=SubunitTestRunner())
-program.runTests()
+runner = SubunitTestRunner()
+TestProgram(module=None, argv=sys.argv, testRunner=runner)
diff --git a/source4/scripting/ejs/config.mk b/source4/scripting/ejs/config.mk
index 656ecdae16..c1f07367fb 100644
--- a/source4/scripting/ejs/config.mk
+++ b/source4/scripting/ejs/config.mk
@@ -4,13 +4,13 @@ OBJ_FILES = \
[MODULE::smbcalls_config]
OBJ_FILES = smbcalls_config.o
-OUTPUT_TYPE = INTEGRATED
+OUTPUT_TYPE = MERGED_OBJ
SUBSYSTEM = smbcalls
INIT_FUNCTION = smb_setup_ejs_config
[MODULE::smbcalls_ldb]
OBJ_FILES = smbcalls_ldb.o
-OUTPUT_TYPE = INTEGRATED
+OUTPUT_TYPE = MERGED_OBJ
SUBSYSTEM = smbcalls
INIT_FUNCTION = smb_setup_ejs_ldb
PRIVATE_DEPENDENCIES = LIBLDB SAMDB LIBNDR
@@ -18,45 +18,38 @@ PRIVATE_DEPENDENCIES = LIBLDB SAMDB LIBNDR
[MODULE::smbcalls_reg]
OBJ_FILES = smbcalls_reg.o
SUBSYSTEM = smbcalls
-OUTPUT_TYPE = INTEGRATED
+OUTPUT_TYPE = MERGED_OBJ
INIT_FUNCTION = smb_setup_ejs_reg
PRIVATE_DEPENDENCIES = registry SAMDB LIBNDR
[MODULE::smbcalls_nbt]
OBJ_FILES = smbcalls_nbt.o
SUBSYSTEM = smbcalls
-OUTPUT_TYPE = INTEGRATED
+OUTPUT_TYPE = MERGED_OBJ
INIT_FUNCTION = smb_setup_ejs_nbt
-[MODULE::smbcalls_samba3]
-OBJ_FILES = smbcalls_samba3.o
-SUBSYSTEM = smbcalls
-OUTPUT_TYPE = INTEGRATED
-INIT_FUNCTION = smb_setup_ejs_samba3
-PRIVATE_DEPENDENCIES = LIBSAMBA3
-
[MODULE::smbcalls_rand]
OBJ_FILES = smbcalls_rand.o
SUBSYSTEM = smbcalls
-OUTPUT_TYPE = INTEGRATED
+OUTPUT_TYPE = MERGED_OBJ
INIT_FUNCTION = smb_setup_ejs_random
[MODULE::smbcalls_nss]
OBJ_FILES = smbcalls_nss.o
SUBSYSTEM = smbcalls
-OUTPUT_TYPE = INTEGRATED
+OUTPUT_TYPE = MERGED_OBJ
INIT_FUNCTION = smb_setup_ejs_nss
PRIVATE_DEPENDENCIES = NSS_WRAPPER
[MODULE::smbcalls_data]
OBJ_FILES = smbcalls_data.o
SUBSYSTEM = smbcalls
-OUTPUT_TYPE = INTEGRATED
+OUTPUT_TYPE = MERGED_OBJ
INIT_FUNCTION = smb_setup_ejs_datablob
[MODULE::smbcalls_auth]
OBJ_FILES = smbcalls_auth.o
-OUTPUT_TYPE = INTEGRATED
+OUTPUT_TYPE = MERGED_OBJ
SUBSYSTEM = smbcalls
INIT_FUNCTION = smb_setup_ejs_auth
PRIVATE_DEPENDENCIES = auth
@@ -64,16 +57,16 @@ PRIVATE_DEPENDENCIES = auth
[MODULE::smbcalls_string]
OBJ_FILES = smbcalls_string.o
SUBSYSTEM = smbcalls
-OUTPUT_TYPE = INTEGRATED
+OUTPUT_TYPE = MERGED_OBJ
INIT_FUNCTION = smb_setup_ejs_string
[MODULE::smbcalls_sys]
OBJ_FILES = smbcalls_sys.o
SUBSYSTEM = smbcalls
-OUTPUT_TYPE = INTEGRATED
+OUTPUT_TYPE = MERGED_OBJ
INIT_FUNCTION = smb_setup_ejs_system
-include ejsnet/config.mk
+mkinclude ejsnet/config.mk
[SUBSYSTEM::smbcalls]
PRIVATE_PROTO_HEADER = proto.h
diff --git a/source4/scripting/ejs/smbcalls_samba3.c b/source4/scripting/ejs/smbcalls_samba3.c
deleted file mode 100644
index 36ec2a54e4..0000000000
--- a/source4/scripting/ejs/smbcalls_samba3.c
+++ /dev/null
@@ -1,501 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- provide hooks into smbd C calls from ejs scripts
-
- Copyright (C) Jelmer Vernooij 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/>.
-*/
-
-#include "includes.h"
-#include "scripting/ejs/smbcalls.h"
-#include "lib/appweb/ejs/ejs.h"
-#include "lib/samba3/samba3.h"
-#include "libcli/security/security.h"
-#include "librpc/gen_ndr/ndr_misc.h"
-#include "system/network.h"
-
-
-static struct MprVar mprRegistry(struct samba3_regdb *reg)
-{
- struct MprVar mpv = mprObject("registry"), ks, vs, k, v;
- int i, j;
-
- ks = mprArray("array");
-
- for (i = 0; i < reg->key_count; i++) {
- k = mprObject("regkey");
-
- mprSetVar(&k, "name", mprString(reg->keys[i].name));
-
- vs = mprArray("array");
-
- for (j = 0; j < reg->keys[i].value_count; j++) {
- v = mprObject("regval");
-
- mprSetVar(&v, "name", mprString(reg->keys[i].values[j].name));
- mprSetVar(&v, "type", mprCreateIntegerVar(reg->keys[i].values[j].type));
- mprSetVar(&v, "data", mprDataBlob(reg->keys[i].values[j].data));
-
- mprAddArray(&vs, j, v);
- }
-
- mprSetVar(&k, "values", vs);
-
- mprAddArray(&ks, i, k);
- }
-
- if (i == 0) {
- mprSetVar(&ks, "length", mprCreateIntegerVar(i));
- }
-
- mprSetVar(&mpv, "keys", ks);
-
- return mpv;
-}
-
-static struct MprVar mprPolicy(struct samba3_policy *pol)
-{
- struct MprVar mpv = mprObject("policy");
-
- mprSetVar(&mpv, "min_password_length", mprCreateIntegerVar(pol->min_password_length));
- mprSetVar(&mpv, "password_history", mprCreateIntegerVar(pol->password_history));
- mprSetVar(&mpv, "user_must_logon_to_change_password", mprCreateIntegerVar(pol->user_must_logon_to_change_password));
- mprSetVar(&mpv, "maximum_password_age", mprCreateIntegerVar(pol->maximum_password_age));
- mprSetVar(&mpv, "minimum_password_age", mprCreateIntegerVar(pol->minimum_password_age));
- mprSetVar(&mpv, "lockout_duration", mprCreateIntegerVar(pol->lockout_duration));
- mprSetVar(&mpv, "reset_count_minutes", mprCreateIntegerVar(pol->reset_count_minutes));
- mprSetVar(&mpv, "bad_lockout_minutes", mprCreateIntegerVar(pol->bad_lockout_minutes));
- mprSetVar(&mpv, "disconnect_time", mprCreateIntegerVar(pol->disconnect_time));
- mprSetVar(&mpv, "refuse_machine_password_change", mprCreateIntegerVar(pol->refuse_machine_password_change));
-
- return mpv;
-}
-
-static struct MprVar mprIdmapDb(struct samba3_idmapdb *db)
-{
- struct MprVar mpv = mprObject("idmapdb"), mps, mp;
- int i;
-
- mprSetVar(&mpv, "user_hwm", mprCreateIntegerVar(db->user_hwm));
- mprSetVar(&mpv, "group_hwm", mprCreateIntegerVar(db->group_hwm));
-
- mps = mprArray("array");
-
- for (i = 0; i < db->mapping_count; i++) {
- char *tmp;
- mp = mprObject("idmap");
-
- mprSetVar(&mp, "IDMAP_GROUP", mprCreateIntegerVar(IDMAP_GROUP));
- mprSetVar(&mp, "IDMAP_USER", mprCreateIntegerVar(IDMAP_USER));
- mprSetVar(&mp, "type", mprCreateIntegerVar(db->mappings[i].type));
- mprSetVar(&mp, "unix_id", mprCreateIntegerVar(db->mappings[i].unix_id));
-
- tmp = dom_sid_string(NULL, db->mappings[i].sid);
- mprSetVar(&mp, "sid", mprString(tmp));
- talloc_free(tmp);
-
- mprAddArray(&mps, i, mp);
- }
-
- if (i == 0) {
- mprSetVar(&mpv, "length", mprCreateIntegerVar(i));
- }
-
-
- mprSetVar(&mpv, "mappings", mps);
-
- return mpv;
-}
-
-static struct MprVar mprGroupMappings(struct samba3_groupdb *db)
-{
- struct MprVar mpv = mprArray("array"), g;
- int i;
-
- for (i = 0; i < db->groupmap_count; i++) {
- char *tmp;
- g = mprObject("group");
-
- mprSetVar(&g, "gid", mprCreateIntegerVar(db->groupmappings[i].gid));
-
- tmp = dom_sid_string(NULL, db->groupmappings[i].sid);
- mprSetVar(&g, "sid", mprString(tmp));
- talloc_free(tmp);
-
- mprSetVar(&g, "sid_name_use", mprCreateIntegerVar(db->groupmappings[i].sid_name_use));
- mprSetVar(&g, "nt_name", mprString(db->groupmappings[i].nt_name));
- mprSetVar(&g, "comment", mprString(db->groupmappings[i].comment));
-
- mprAddArray(&mpv, i, g);
- }
-
- if (i == 0) {
- mprSetVar(&mpv, "length", mprCreateIntegerVar(i));
- }
-
-
- return mpv;
-}
-
-static struct MprVar mprAliases(struct samba3_groupdb *db)
-{
- struct MprVar mpv = mprObject("array"), a, am;
- int i, j;
-
- for (i = 0; i < db->alias_count; i++) {
- char *tmp;
- a = mprObject("alias");
-
- tmp = dom_sid_string(NULL, db->aliases[i].sid);
- mprSetVar(&a, "sid", mprString(tmp));
- talloc_free(tmp);
-
- am = mprArray("array");
-
- for (j = 0; j < db->aliases[i].member_count; j++) {
- tmp = dom_sid_string(NULL, db->aliases[i].members[j]);
- mprAddArray(&am, j, mprString(tmp));
- talloc_free(tmp);
- }
-
- mprSetVar(&a, "members", am);
- }
-
- if (i == 0) {
- mprSetVar(&mpv, "length", mprCreateIntegerVar(i));
- }
-
- return mpv;
-}
-
-static struct MprVar mprDomainSecrets(struct samba3_domainsecrets *ds)
-{
- struct MprVar v, e = mprObject("domainsecrets");
- char *tmp;
- DATA_BLOB blob;
-
- mprSetVar(&e, "name", mprString(ds->name));
-
- tmp = dom_sid_string(NULL, &ds->sid);
- mprSetVar(&e, "sid", mprString(tmp));
- talloc_free(tmp);
-
- tmp = GUID_string(NULL, &ds->guid);
- mprSetVar(&e, "guid", mprString(tmp));
- talloc_free(tmp);
-
- mprSetVar(&e, "plaintext_pw", mprString(ds->plaintext_pw));
-
- mprSetVar(&e, "last_change_time", mprCreateIntegerVar(ds->last_change_time));
- mprSetVar(&e, "sec_channel_type", mprCreateIntegerVar(ds->sec_channel_type));
-
- v = mprObject("hash_pw");
-
- blob.data = ds->hash_pw.hash;
- blob.length = 16;
- mprSetVar(&v, "hash", mprDataBlob(blob));
-
- mprSetVar(&v, "mod_time", mprCreateIntegerVar(ds->hash_pw.mod_time));
-
- mprSetVar(&e, "hash_pw", v);
-
- return e;
-}
-
-static struct MprVar mprSecrets(struct samba3_secrets *sec)
-{
- struct MprVar mpv = mprObject("samba3_secrets"), es, e;
- int i;
-
- es = mprArray("array");
-
- for (i = 0; i < sec->ldappw_count; i++) {
- e = mprObject("ldappw");
-
- mprSetVar(&e, "dn", mprString(sec->ldappws[i].dn));
- mprSetVar(&e, "password", mprString(sec->ldappws[i].password));
-
- mprAddArray(&es, i, e);
- }
-
- mprSetVar(&mpv, "ldappws", es);
-
- es = mprArray("array");
-
- for (i = 0; i < sec->domain_count; i++) {
- mprAddArray(&es, i, mprDomainSecrets(&sec->domains[i]));
- }
-
- if (i == 0) {
- mprSetVar(&es, "length", mprCreateIntegerVar(i));
- }
-
- mprSetVar(&mpv, "domains", es);
-
- es = mprArray("trusted_domains");
-
- for (i = 0; i < sec->trusted_domain_count; i++) {
- struct MprVar ns;
- char *tmp;
- int j;
- e = mprObject("trusted_domain");
-
- ns = mprArray("array");
-
- for (j = 0; j < sec->trusted_domains[i].uni_name_len; j++) {
- mprAddArray(&ns, j, mprString(sec->trusted_domains[i].uni_name[j]));
- }
-
- mprSetVar(&e, "uni_name", ns);
-
- mprSetVar(&e, "pass", mprString(sec->trusted_domains[i].pass));
- mprSetVar(&e, "mod_time", mprCreateIntegerVar(sec->trusted_domains[i].mod_time));
-
- tmp = dom_sid_string(NULL, &sec->trusted_domains[i].domain_sid);
- mprSetVar(&e, "domains_sid", mprString(tmp));
- talloc_free(tmp);
-
- mprAddArray(&es, i, e);
- }
-
- if (i == 0) {
- mprSetVar(&es, "length", mprCreateIntegerVar(i));
- }
-
- mprSetVar(&mpv, "trusted_domains", es);
-
- es = mprArray("array");
-
- for (i = 0; i < sec->afs_keyfile_count; i++) {
- struct MprVar ks;
- int j;
- e = mprObject("afs_keyfile");
-
- mprSetVar(&e, "cell", mprString(sec->afs_keyfiles[i].cell));
-
- ks = mprArray("array");
-
- for (j = 0; j < 8; j++) {
- struct MprVar k = mprObject("entry");
- DATA_BLOB blob;
-
- mprSetVar(&k, "kvno", mprCreateIntegerVar(sec->afs_keyfiles[i].entry[j].kvno));
- blob.data = (uint8_t*)sec->afs_keyfiles[i].entry[j].key;
- blob.length = 8;
- mprSetVar(&k, "key", mprDataBlob(blob));
-
- mprAddArray(&ks, j, k);
- }
-
- mprSetVar(&e, "entry", ks);
-
- mprSetVar(&e, "nkeys", mprCreateIntegerVar(sec->afs_keyfiles[i].nkeys));
-
- mprAddArray(&es, i, e);
- }
-
- if (i == 0) {
- mprSetVar(&es, "length", mprCreateIntegerVar(i));
- }
-
- mprSetVar(&mpv, "afs_keyfiles", es);
-
- mprSetVar(&mpv, "ipc_cred", mprCredentials(sec->ipc_cred));
-
- return mpv;
-}
-
-static struct MprVar mprShares(struct samba3 *samba3)
-{
- struct MprVar mpv = mprArray("array"), s;
- int i;
-
- for (i = 0; i < samba3->share_count; i++) {
- s = mprObject("share");
-
- mprSetVar(&s, "name", mprString(samba3->shares[i].name));
-
- /* FIXME: secdesc */
-
- mprAddArray(&mpv, i, s);
- }
-
- if (i == 0) {
- mprSetVar(&mpv, "length", mprCreateIntegerVar(i));
- }
-
- return mpv;
-}
-
-static struct MprVar mprSamAccounts(struct samba3 *samba3)
-{
- struct MprVar mpv = mprArray("array"), m;
- int i;
-
- for (i = 0; i < samba3->samaccount_count; i++) {
- struct samba3_samaccount *a = &samba3->samaccounts[i];
- DATA_BLOB blob;
-
- m = mprObject("samba3_samaccount");
-
- mprSetVar(&m, "logon_time", mprCreateIntegerVar(a->logon_time));
- mprSetVar(&m, "logoff_time", mprCreateIntegerVar(a->logoff_time));
- mprSetVar(&m, "kickoff_time", mprCreateIntegerVar(a->kickoff_time));
- mprSetVar(&m, "bad_password_time", mprCreateIntegerVar(a->bad_password_time));
- mprSetVar(&m, "pass_last_set_time", mprCreateIntegerVar(a->pass_last_set_time));
- mprSetVar(&m, "pass_can_change_time", mprCreateIntegerVar(a->pass_can_change_time));
- mprSetVar(&m, "pass_must_change_time", mprCreateIntegerVar(a->pass_must_change_time));
- mprSetVar(&m, "user_rid", mprCreateIntegerVar(a->user_rid));
- mprSetVar(&m, "group_rid", mprCreateIntegerVar(a->group_rid));
- mprSetVar(&m, "acct_ctrl", mprCreateIntegerVar(a->acct_ctrl));
- mprSetVar(&m, "logon_divs", mprCreateIntegerVar(a->logon_divs));
- mprSetVar(&m, "bad_password_count", mprCreateIntegerVar(a->bad_password_count));
- mprSetVar(&m, "logon_count", mprCreateIntegerVar(a->logon_count));
- mprSetVar(&m, "username", mprString(a->username));
- mprSetVar(&m, "domain", mprString(a->domain));
- mprSetVar(&m, "nt_username", mprString(a->nt_username));
- mprSetVar(&m, "dir_drive", mprString(a->dir_drive));
- mprSetVar(&m, "munged_dial", mprString(a->munged_dial));
- mprSetVar(&m, "fullname", mprString(a->fullname));
- mprSetVar(&m, "homedir", mprString(a->homedir));
- mprSetVar(&m, "logon_script", mprString(a->logon_script));
- mprSetVar(&m, "profile_path", mprString(a->profile_path));
- mprSetVar(&m, "acct_desc", mprString(a->acct_desc));
- mprSetVar(&m, "workstations", mprString(a->workstations));
- blob.length = 16;
- blob.data = a->lm_pw.hash;
- mprSetVar(&m, "lm_pw", mprDataBlob(blob));
- blob.data = a->nt_pw.hash;
- mprSetVar(&m, "nt_pw", mprDataBlob(blob));
-
- mprAddArray(&mpv, i, m);
- }
-
- if (i == 0) {
- mprSetVar(&mpv, "length", mprCreateIntegerVar(i));
- }
-
- return mpv;
-}
-
-static struct MprVar mprWinsEntries(struct samba3 *samba3)
-{
- struct MprVar mpv = mprArray("array");
- int i, j;
-
- for (i = 0; i < samba3->winsdb_count; i++) {
- struct MprVar w = mprObject("wins_entry"), ips;
-
- mprSetVar(&w, "name", mprString(samba3->winsdb_entries[i].name));
- mprSetVar(&w, "nb_flags", mprCreateIntegerVar(samba3->winsdb_entries[i].nb_flags));
- mprSetVar(&w, "type", mprCreateIntegerVar(samba3->winsdb_entries[i].type));
- mprSetVar(&w, "ttl", mprCreateIntegerVar(samba3->winsdb_entries[i].ttl));
-
- ips = mprObject("array");
-
- for (j = 0; j < samba3->winsdb_entries[i].ip_count; j++) {
- const char *addr;
- addr = inet_ntoa(samba3->winsdb_entries[i].ips[j]);
- mprAddArray(&ips, j, mprString(addr));
- }
-
- mprSetVar(&w, "ips", ips);
-
- mprAddArray(&mpv, i, w);
- }
-
- if (i == 0) {
- mprSetVar(&mpv, "length", mprCreateIntegerVar(i));
- }
-
- return mpv;
-}
-
-static int ejs_find_domainsecrets(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct samba3 *samba3 = NULL;
- struct samba3_domainsecrets *sec;
-
- if (argc < 1) {
- ejsSetErrorMsg(eid, "find_domainsecrets invalid arguments");
- return -1;
- }
-
- samba3 = (struct samba3 *)mprGetThisPtr(eid, "samba3");
- mprAssert(samba3);
- sec = samba3_find_domainsecrets(samba3, mprToString(argv[0]));
-
- if (sec == NULL) {
- mpr_Return(eid, mprCreateUndefinedVar());
- } else {
- mpr_Return(eid, mprDomainSecrets(sec));
- }
-
- return 0;
-}
-
-/*
- initialise samba3 ejs subsystem
-
- samba3 = samba3_read(libdir,smbconf)
-*/
-static int ejs_samba3_read(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct MprVar mpv = mprObject("samba3");
- struct samba3 *samba3;
- NTSTATUS status;
-
- if (argc < 2) {
- ejsSetErrorMsg(eid, "samba3_read invalid arguments");
- return -1;
- }
-
- status = samba3_read(mprToString(argv[0]), mprToString(argv[1]), mprMemCtx(), &samba3);
-
- if (NT_STATUS_IS_ERR(status)) {
- ejsSetErrorMsg(eid, "samba3_read: error");
- return -1;
- }
-
- mprAssert(samba3);
-
- mprSetPtrChild(&mpv, "samba3", samba3);
- mprSetVar(&mpv, "winsentries", mprWinsEntries(samba3));
- mprSetVar(&mpv, "samaccounts", mprSamAccounts(samba3));
- mprSetVar(&mpv, "shares", mprShares(samba3));
- mprSetVar(&mpv, "secrets", mprSecrets(&samba3->secrets));
- mprSetVar(&mpv, "groupmappings", mprGroupMappings(&samba3->group));
- mprSetVar(&mpv, "aliases", mprAliases(&samba3->group));
- mprSetVar(&mpv, "idmapdb", mprIdmapDb(&samba3->idmap));
- mprSetVar(&mpv, "policy", mprPolicy(&samba3->policy));
- mprSetVar(&mpv, "registry", mprRegistry(&samba3->registry));
- mprSetVar(&mpv, "configuration", mprParam(samba3->configuration));
- mprSetCFunction(&mpv, "find_domainsecrets", ejs_find_domainsecrets);
-
- mpr_Return(eid, mpv);
-
- return 0;
-}
-
-
-/*
- setup C functions that be called from ejs
-*/
-NTSTATUS smb_setup_ejs_samba3(void)
-{
- ejsDefineCFunction(-1, "samba3_read", ejs_samba3_read, NULL, MPR_VAR_SCRIPT_HANDLE);
- return NT_STATUS_OK;
-}
diff --git a/source4/scripting/ejs/smbscript.c b/source4/scripting/ejs/smbscript.c
index a4f2e1cd43..9ed4aa490f 100644
--- a/source4/scripting/ejs/smbscript.c
+++ b/source4/scripting/ejs/smbscript.c
@@ -61,8 +61,6 @@ int main(int argc, const char **argv)
lp_load(lp_ctx, dyn_CONFIGFILE);
}
- ldb_global_init();
-
gensec_init(lp_ctx);
mprSetCtx(mem_ctx);
diff --git a/source4/scripting/libjs/provision.js b/source4/scripting/libjs/provision.js
index e71498010c..dc9eae8e72 100644
--- a/source4/scripting/libjs/provision.js
+++ b/source4/scripting/libjs/provision.js
@@ -1124,7 +1124,7 @@ unixName: %s
sambaPassword: %s
objectClass: user
",
- user_dn, username, dom_users,
+ user_dn, username,
unixname, password);
/*
add the user to the users group as well
@@ -1134,7 +1134,7 @@ dn: %s
changetype: modify
add: member
member: %s
-",
+",
dom_users, user_dn);
diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4
index e4a34ece1e..2142cd9abd 100644
--- a/source4/scripting/python/config.m4
+++ b/source4/scripting/python/config.m4
@@ -54,7 +54,7 @@ fi
if test x$PYTHON != x
then
- DISTUTILS_CFLAGS=`$PYTHON -c "from distutils import sysconfig; print '-I%s -I%s %s' % (sysconfig.get_python_inc(), sysconfig.get_python_inc(plat_specific=True), sysconfig.get_config_var('CFLAGS'))"`
+ DISTUTILS_CFLAGS=`$PYTHON -c "from distutils import sysconfig; print '-I%s -I%s %s' % (sysconfig.get_python_inc(), sysconfig.get_python_inc(plat_specific=1), sysconfig.get_config_var('CFLAGS'))"`
DISTUTILS_LDFLAGS=`$PYTHON -c "from distutils import sysconfig; print '%s %s -lpython%s -L%s' % (sysconfig.get_config_var('LIBS'), sysconfig.get_config_var('SYSLIBS'), sysconfig.get_config_var('VERSION'), sysconfig.get_config_var('LIBPL'))"`
TRY_LINK_PYTHON($DISTUTILS_LDFLAGS, $DISTUTILS_CFLAGS)
fi
@@ -66,12 +66,8 @@ if test $working_python = yes; then
SMB_ENABLE(EXT_LIB_PYTHON,YES)
SMB_ENABLE(smbpython,YES)
SMB_ENABLE(LIBPYTHON,YES)
- dnl AC_DEFINE(HAVE_WORKING_PYTHON, 1, [Whether we have working python support])
AC_MSG_RESULT([yes])
else
- SMB_ENABLE(EXT_LIB_PYTHON,NO)
- SMB_ENABLE(LIBPYTHONyy,NO)
- SMB_ENABLE(smbpython,NO)
- AC_MSG_RESULT([no])
+ AC_MSG_ERROR([Python not found. Please install Python 2.x and its development headers/libraries.])
fi
diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk
index 450da0e90a..b15e1fcda7 100644
--- a/source4/scripting/python/config.mk
+++ b/source4/scripting/python/config.mk
@@ -33,7 +33,7 @@ pythonmods:: $(PYTHON_DSOS) $(PYTHON_PYS)
PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py bin/python/tdb.py bin/python/security.py bin/python/events.py bin/python/net.py
pydoctor:: pythonmods
- LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --make-html --docformat=restructuredtext --add-package scripting/python/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES))
+ LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --project-name=Samba --make-html --docformat=restructuredtext --add-package scripting/python/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES))
installpython:: pythonmods
@$(SHELL) $(srcdir)/script/installpython.sh \
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index 7dd564fae1..3e88b68509 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -271,20 +271,19 @@ def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users,
def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
credentials, configdn, schemadn, domaindn,
hostname, netbiosname, dnsdomain, realm,
- rootdn, serverrole, ldap_backend=None,
+ rootdn, serverrole, sitename, ldap_backend=None,
ldap_backend_type=None, erase=False):
"""Setup the partitions for the SAM database.
Alternatively, provision() may call this, and then populate the database.
:param erase: Remove the existing data present in the database.
- :param
:note: This will wipe the Sam Database!
:note: This function always removes the local SAM LDB file. The erase
- parameter controls whether to erase the existing data, which
- may not be stored locally but in LDAP.
+ parameter controls whether to erase the existing data, which
+ may not be stored locally but in LDAP.
"""
assert session_info is not None
@@ -333,13 +332,12 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
schemadn_ldb = "schema.ldb"
if ldap_backend is not None:
schema_ldb = ldap_backend
-
schemadn_ldb = ldap_backend
if ldap_backend_type == "fedora-ds":
- backend_modules = ["nsuniqueid","paged_searches"]
+ backend_modules = ["nsuniqueid", "paged_searches"]
elif ldap_backend_type == "openldap":
- backend_modules = ["normalise","entryuuid","paged_searches"]
+ backend_modules = ["normalise", "entryuuid", "paged_searches"]
elif serverrole == "domain controller":
backend_modules = ["repl_meta_data"]
else:
@@ -380,7 +378,8 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
message("Setting up sam.ldb rootDSE")
setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname,
- dnsdomain, realm, rootdn, configdn, netbiosname)
+ dnsdomain, realm, rootdn, configdn, netbiosname,
+ sitename)
if erase:
message("Erasing data from partitions")
@@ -474,18 +473,18 @@ def setup_registry(path, setup_path, session_info, credentials, lp):
def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname,
- dnsdomain, realm, rootdn, configdn, netbiosname):
+ dnsdomain, realm, rootdn, configdn, netbiosname,
+ sitename):
"""Setup the SamDB rootdse.
:param samdb: Sam Database handle
:param setup_path: Obtain setup path
- ...
"""
setup_add_ldif(samdb, setup_path("provision_rootdse_add.ldif"), {
"SCHEMADN": schemadn,
"NETBIOSNAME": netbiosname,
"DNSDOMAIN": dnsdomain,
- "DEFAULTSITE": DEFAULTSITE,
+ "DEFAULTSITE": sitename,
"REALM": realm,
"DNSNAME": "%s.%s" % (hostname, dnsdomain),
"DOMAINDN": domaindn,
@@ -498,7 +497,7 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname,
def setup_self_join(samdb, configdn, schemadn, domaindn,
netbiosname, hostname, dnsdomain, machinepass, dnspass,
realm, domainname, domainsid, invocationid, setup_path,
- policyguid, hostguid=None):
+ policyguid, sitename, hostguid=None):
"""Join a host to its own domain."""
if hostguid is not None:
hostguid_add = "objectGUID: %s" % hostguid
@@ -511,7 +510,7 @@ def setup_self_join(samdb, configdn, schemadn, domaindn,
"DOMAINDN": domaindn,
"INVOCATIONID": invocationid,
"NETBIOSNAME": netbiosname,
- "DEFAULTSITE": DEFAULTSITE,
+ "DEFAULTSITE": sitename,
"DNSNAME": "%s.%s" % (hostname, dnsdomain),
"MACHINEPASS_B64": b64encode(machinepass),
"DNSPASS_B64": b64encode(dnspass),
@@ -532,12 +531,15 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
domainsid, aci, domainguid, policyguid,
domainname, fill, adminpass, krbtgtpass,
machinepass, hostguid, invocationid, dnspass,
- serverrole, ldap_backend=None, ldap_backend_type=None):
+ serverrole, sitename, ldap_backend=None,
+ ldap_backend_type=None):
"""Setup a complete SAM Database.
:note: This will wipe the main SAM database file!
"""
+ assert serverrole in ("domain controller", "member server")
+
# Also wipes the database
setup_samdb_partitions(path, setup_path, schemadn=schemadn, configdn=configdn,
domaindn=domaindn, message=message, lp=lp,
@@ -545,7 +547,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
hostname=hostname, netbiosname=netbiosname,
dnsdomain=dnsdomain, realm=realm, rootdn=rootdn,
ldap_backend=ldap_backend, serverrole=serverrole,
- ldap_backend_type=ldap_backend_type, erase=erase)
+ ldap_backend_type=ldap_backend_type, erase=erase,
+ sitename=sitename)
samdb = SamDB(path, session_info=session_info,
credentials=credentials, lp=lp)
@@ -563,7 +566,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
if lp.get("server role") == "domain controller":
samdb.set_invocation_id(invocationid)
- load_schema(setup_path, samdb, schemadn, netbiosname, configdn)
+ load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename)
samdb.transaction_start()
@@ -585,7 +588,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
"DOMAINSID": str(domainsid),
"SCHEMADN": schemadn,
"NETBIOSNAME": netbiosname,
- "DEFAULTSITE": DEFAULTSITE,
+ "DEFAULTSITE": sitename,
"CONFIGDN": configdn,
"POLICYGUID": policyguid,
"DOMAINDN": domaindn,
@@ -615,7 +618,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
setup_path("provision_schema_basedn_modify.ldif"), {
"SCHEMADN": schemadn,
"NETBIOSNAME": netbiosname,
- "DEFAULTSITE": DEFAULTSITE,
+ "DEFAULTSITE": sitename,
"CONFIGDN": configdn,
})
@@ -630,7 +633,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
setup_add_ldif(samdb, setup_path("provision_configuration.ldif"), {
"CONFIGDN": configdn,
"NETBIOSNAME": netbiosname,
- "DEFAULTSITE": DEFAULTSITE,
+ "DEFAULTSITE": sitename,
"DNSDOMAIN": dnsdomain,
"DOMAIN": domainname,
"SCHEMADN": schemadn,
@@ -657,7 +660,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
setup_add_ldif(samdb, setup_path("provision.ldif"), {
"DOMAINDN": domaindn,
"NETBIOSNAME": netbiosname,
- "DEFAULTSITE": DEFAULTSITE,
+ "DEFAULTSITE": sitename,
"CONFIGDN": configdn,
})
@@ -680,7 +683,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
machinepass=machinepass, domainname=domainname,
domainsid=domainsid, policyguid=policyguid,
hostname=hostname, hostguid=hostguid,
- setup_path=setup_path)
+ setup_path=setup_path, sitename=sitename)
#We want to setup the index last, as adds are faster unindexed
message("Setting up sam.ldb index")
@@ -692,6 +695,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
samdb.transaction_commit()
return samdb
+
FILL_FULL = "FULL"
FILL_NT4SYNC = "NT4SYNC"
FILL_DRS = "DRS"
@@ -703,7 +707,7 @@ def provision(lp, setup_dir, message, paths, session_info,
policyguid=None, invocationid=None, machinepass=None,
dnspass=None, root=None, nobody=None, nogroup=None, users=None,
wheel=None, backup=None, aci=None, serverrole=None, erase=False,
- ldap_backend=None, ldap_backend_type=None):
+ ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE):
"""Provision samba4
:note: caution, this wipes all existing data!
@@ -852,7 +856,7 @@ def provision(lp, setup_dir, message, paths, session_info,
hostguid=hostguid, invocationid=invocationid,
machinepass=machinepass, dnspass=dnspass,
serverrole=serverrole, ldap_backend=ldap_backend,
- ldap_backend_type=ldap_backend_type)
+ ldap_backend_type=ldap_backend_type, sitename=sitename)
if lp.get("server role") == "domain controller":
policy_path = os.path.join(paths.sysvol, dnsdomain, "Policies",
@@ -946,7 +950,7 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn,
})
-def load_schema(setup_path, samdb, schemadn, netbiosname, configdn):
+def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename):
"""Load schema for the SamDB.
:param samdb: Load a schema into a SamDB.
@@ -963,7 +967,7 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn):
"SCHEMADN": schemadn,
"NETBIOSNAME": netbiosname,
"CONFIGDN": configdn,
- "DEFAULTSITE": DEFAULTSITE
+ "DEFAULTSITE":sitename
})
samdb.attach_schema_from_ldif(head_data, schema_data)
diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py
index c11fabf553..3c6bb23c02 100644
--- a/source4/scripting/python/samba/samdb.py
+++ b/source4/scripting/python/samba/samdb.py
@@ -100,12 +100,14 @@ userAccountControl: %u
self.transaction_start()
# find the DNs for the domain and the domain users group
- res = self.search("", SCOPE_BASE, "defaultNamingContext=*",
- ["defaultNamingContext"])
+ 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)
- dom_users = self.searchone(basedn=domain_dn, attribute="dn", expression="name=Domain Users")
+ 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)
diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py
index 9402002674..c8673d3fae 100644
--- a/source4/scripting/python/samba/tests/__init__.py
+++ b/source4/scripting/python/samba/tests/__init__.py
@@ -84,3 +84,9 @@ class LdbExtensionTests(TestCaseInTempDir):
del l
os.unlink(path)
+
+def get_loadparm():
+ import param
+ lp = param.LoadParm()
+ lp.load(os.getenv("SMB_CONF_PATH"))
+ return lp
diff --git a/source4/scripting/python/samba/tests/dcerpc/registry.py b/source4/scripting/python/samba/tests/dcerpc/registry.py
index f3f0b0fb1a..147acc5098 100644
--- a/source4/scripting/python/samba/tests/dcerpc/registry.py
+++ b/source4/scripting/python/samba/tests/dcerpc/registry.py
@@ -20,11 +20,11 @@
import winreg
from param import LoadParm
import unittest
+from samba.tests import get_loadparm
class WinregTests(unittest.TestCase):
def setUp(self):
- lp_ctx = LoadParm()
- lp_ctx.load("st/client/client.conf")
+ lp_ctx = get_loadparm()
self.conn = winreg.winreg("ncalrpc:", lp_ctx)
def get_hklm(self):
diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py
index 52c2bb8c72..8c1a8bec71 100644
--- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py
+++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py
@@ -18,13 +18,12 @@
#
import echo
-from param import LoadParm
import unittest
+from samba.tests import get_loadparm
class RpcEchoTests(unittest.TestCase):
def setUp(self):
- lp_ctx = LoadParm()
- lp_ctx.load("st/client/client.conf")
+ lp_ctx = get_loadparm()
self.conn = echo.rpcecho("ncalrpc:", lp_ctx)
def test_addone(self):
diff --git a/source4/scripting/python/samba/tests/dcerpc/sam.py b/source4/scripting/python/samba/tests/dcerpc/sam.py
index 50caaf2348..96348f2f69 100644
--- a/source4/scripting/python/samba/tests/dcerpc/sam.py
+++ b/source4/scripting/python/samba/tests/dcerpc/sam.py
@@ -19,10 +19,11 @@
import samr
import unittest
+from samba.tests import get_loadparm
class SamrTests(unittest.TestCase):
def setUp(self):
- self.conn = samr.samr("ncalrpc:", "st/client/client.conf")
+ self.conn = samr.samr("ncalrpc:", get_loadparm())
def test_connect5(self):
(level, info, handle) = self.conn.Connect5(None, 0, 1, samr.ConnectInfo1())
diff --git a/source4/scripting/python/samba/tests/provision.py b/source4/scripting/python/samba/tests/provision.py
index eb49f7af83..514582cbe4 100644
--- a/source4/scripting/python/samba/tests/provision.py
+++ b/source4/scripting/python/samba/tests/provision.py
@@ -24,8 +24,7 @@ from ldb import Dn
import param
import unittest
-lp = param.LoadParm()
-lp.load("st/dc/etc/smb.conf")
+lp = samba.tests.get_loadparm()
setup_dir = "setup"
def setup_path(file):
@@ -33,6 +32,8 @@ def setup_path(file):
class ProvisionTestCase(samba.tests.TestCaseInTempDir):
+ """Some simple tests for individual functions in the provisioning code.
+ """
def test_setup_secretsdb(self):
path = os.path.join(self.tempdir, "secrets.ldb")
ldb = setup_secretsdb(path, setup_path, None, None, lp=lp)
diff --git a/source4/scripting/python/samba/tests/samdb.py b/source4/scripting/python/samba/tests/samdb.py
new file mode 100644
index 0000000000..40e56bebb5
--- /dev/null
+++ b/source4/scripting/python/samba/tests/samdb.py
@@ -0,0 +1,55 @@
+#!/usr/bin/python
+
+# Unix SMB/CIFS implementation. Tests for SamDB
+# 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/>.
+#
+from auth import system_session
+from credentials import Credentials
+import os
+from samba.provision import setup_samdb
+from samba.samdb import SamDB
+from samba.tests import get_loadparm, TestCaseInTempDir
+import security
+from unittest import TestCase
+import uuid
+
+class SamDBTestCase(TestCaseInTempDir):
+ def setUp(self):
+ super(SamDBTestCase, self).setUp()
+ invocationid = uuid.random()
+ domaindn = "DC=COM,DC=EXAMPLE"
+ self.domaindn = domaindn
+ configdn = "CN=Configuration," + domaindn
+ schemadn = "CN=Schema," + configdn
+ domainguid = uuid.random()
+ policyguid = uuid.random()
+ setup_path = lambda x: os.path.join("setup", x)
+ creds = Credentials()
+ domainsid = security.random_sid()
+ hostguid = uuid.random()
+ path = os.path.join(self.tempdir, "samdb.ldb")
+ self.samdb = setup_samdb(path, setup_path, system_session(), creds,
+ get_loadparm(), schemadn, configdn,
+ self.domaindn, "example.com", "EXAMPLE.COM",
+ "FOO", lambda x: None, "foo", domaindn,
+ False, domainsid, "# no aci", domainguid,
+ policyguid, "EXAMPLE", True, "secret",
+ "secret", "secret", hostguid, invocationid,
+ "secret", "domain controller")
+
+ def test_add_foreign(self):
+ self.samdb.add_foreign(self.domaindn, "S-1-5-7", "Somedescription")
+
diff --git a/source4/scripting/python/samba/tests/upgrade.py b/source4/scripting/python/samba/tests/upgrade.py
index ddafa00691..4dc86ace8a 100644
--- a/source4/scripting/python/samba/tests/upgrade.py
+++ b/source4/scripting/python/samba/tests/upgrade.py
@@ -17,6 +17,21 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-import samba.upgrade
-from unittest import TestCase
+from samba import Ldb
+from samba.upgrade import import_wins
+from samba.tests import LdbTestCase
+class WinsUpgradeTests(LdbTestCase):
+ def test_upgrade(self):
+ winsdb = {
+ "FOO#20": (200, ["127.0.0.1", "127.0.0.2"], 0x60)
+ }
+ import_wins(self.ldb, winsdb)
+
+ self.assertEquals(['name=FOO,type=0x20'],
+ [str(m.dn) for m in self.ldb.search(expression="(objectClass=winsRecord)")])
+
+ def test_version(self):
+ import_wins(self.ldb, {})
+ self.assertEquals("VERSION",
+ self.ldb.search(expression="(objectClass=winsMaxVersion)")[0]["cn"])
diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py
index b332bb89ae..01b62ff984 100644
--- a/source4/scripting/python/samba/upgrade.py
+++ b/source4/scripting/python/samba/upgrade.py
@@ -10,6 +10,7 @@
from provision import findnss, provision, FILL_DRS
import grp
import ldb
+import time
import pwd
import uuid
import registry
@@ -17,6 +18,7 @@ from samba import Ldb
from samba.samdb import SamDB
def import_sam_policy(samldb, samba3_policy, domaindn):
+ """Import a Samba 3 policy database."""
samldb.modify_ldif("""
dn: %s
changetype: modify
@@ -162,7 +164,6 @@ def import_wins(samba4_winsdb, samba3_winsdb):
:param samba3_winsdb: WINS database to import from
"""
version_id = 0
- import time
for (name, (ttl, ips, nb_flags)) in samba3_winsdb.items():
version_id+=1
@@ -201,7 +202,8 @@ def import_wins(samba4_winsdb, samba3_winsdb):
"versionID": str(version_id),
"address": ips})
- samba4_winsdb.add({"dn": "CN=VERSION",
+ samba4_winsdb.add({"dn": "cn=VERSION",
+ "cn": "VERSION",
"objectClass": "winsMaxVersion",
"maxVersion": str(version_id)})
diff --git a/source4/scripting/python/subunit/__init__.py b/source4/scripting/python/subunit/__init__.py
index 4d3434a3ea..3abfbf522e 100644
--- a/source4/scripting/python/subunit/__init__.py
+++ b/source4/scripting/python/subunit/__init__.py
@@ -209,7 +209,7 @@ class TestProtocolClient(unittest.TestResult):
"""A class that looks like a TestResult and informs a TestProtocolServer."""
def __init__(self, stream):
- unittest.TestResult.__init__(self)
+ super(TestProtocolClient, self).__init__()
self._stream = stream
def addError(self, test, error):
@@ -218,6 +218,7 @@ class TestProtocolClient(unittest.TestResult):
for line in self._exc_info_to_string(error, test).splitlines():
self._stream.write("%s\n" % line)
self._stream.write("]\n")
+ super(TestProtocolClient, self).addError(test, error)
def addFailure(self, test, error):
"""Report a failure in test test."""
@@ -225,14 +226,17 @@ class TestProtocolClient(unittest.TestResult):
for line in self._exc_info_to_string(error, test).splitlines():
self._stream.write("%s\n" % line)
self._stream.write("]\n")
+ super(TestProtocolClient, self).addFailure(test, error)
def addSuccess(self, test):
"""Report a success in a test."""
self._stream.write("successful: %s\n" % (test.shortDescription() or str(test)))
+ super(TestProtocolClient, self).addSuccess(test)
def startTest(self, test):
"""Mark a test as starting its test run."""
self._stream.write("test: %s\n" % (test.shortDescription() or str(test)))
+ super(TestProtocolClient, self).startTest(test)
def RemoteError(description=""):