VERSION: Bump version number up to 4.0.4.
[samba.git] / source4 / scripting / python / samba / __init__.py
index bd7628993ebe85931f7b7eddae99d6da4ddd25ae..cd2a309fc0aea445139081ec4e2117fd1b95bea0 100644 (file)
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-
 # Unix SMB/CIFS implementation.
 # Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008
 #
@@ -26,24 +24,32 @@ __docformat__ = "restructuredText"
 
 import os
 import sys
+import samba.param
 
-def in_source_tree():
-    """Check whether the script is being run from the source dir. """
-    return os.path.exists("%s/../../../selftest/skip" % os.path.dirname(__file__))
 
+def source_tree_topdir():
+    """Return the top level source directory."""
+    paths = ["../../..", "../../../.."]
+    for p in paths:
+        topdir = os.path.normpath(os.path.join(os.path.dirname(__file__), p))
+        if os.path.exists(os.path.join(topdir, 'source4')):
+            return topdir
+    raise RuntimeError("unable to find top level source directory")
 
-# When running, in-tree, make sure bin/python is in the PYTHONPATH
-if in_source_tree():
-    srcdir = "%s/../../.." % os.path.dirname(__file__)
-    sys.path.append("%s/bin/python" % srcdir)
-    default_ldb_modules_dir = "%s/bin/modules/ldb" % srcdir
-else:
-    default_ldb_modules_dir = None
+
+def in_source_tree():
+    """Return True if we are running from within the samba source tree"""
+    try:
+        topdir = source_tree_topdir()
+    except RuntimeError:
+        return False
+    return True
 
 
 import ldb
 from samba._ldb import Ldb as _Ldb
 
+
 class Ldb(_Ldb):
     """Simple Samba-specific LDB subclass that takes care
     of setting up the modules dir, credentials pointers, etc.
@@ -72,10 +78,8 @@ class Ldb(_Ldb):
 
         if modules_dir is not None:
             self.set_modules_dir(modules_dir)
-        elif default_ldb_modules_dir is not None:
-            self.set_modules_dir(default_ldb_modules_dir)
-        elif lp is not None:
-            self.set_modules_dir(os.path.join(lp.get("modules dir"), "ldb"))
+        else:
+            self.set_modules_dir(os.path.join(samba.param.modules_dir(), "ldb"))
 
         if session_info is not None:
             self.set_session_info(session_info)
@@ -101,7 +105,7 @@ class Ldb(_Ldb):
         # Allow admins to force non-sync ldb for all databases
         if lp is not None:
             nosync_p = lp.get("nosync", "ldb")
-            if nosync_p is not None and nosync_p == True:
+            if nosync_p is not None and nosync_p:
                 flags |= ldb.FLG_NOSYNC
 
         self.set_create_perms(0600)
@@ -163,7 +167,8 @@ class Ldb(_Ldb):
         # Try to delete user/computer accounts to allow deletion of groups
         self.erase_users_computers(basedn)
 
-        # Delete the 'visible' records, and the invisble 'deleted' records (if this DB supports it)
+        # Delete the 'visible' records, and the invisble 'deleted' records (if
+        # this DB supports it)
         for msg in self.search(basedn, ldb.SCOPE_SUBTREE,
                        "(&(|(objectclass=*)(distinguishedName=*))(!(distinguishedName=@BASEINFO)))",
                        [], controls=["show_deleted:0", "show_recycled:0"]):
@@ -175,7 +180,8 @@ class Ldb(_Ldb):
                     raise
 
         res = self.search(basedn, ldb.SCOPE_SUBTREE,
-            "(&(|(objectclass=*)(distinguishedName=*))(!(distinguishedName=@BASEINFO)))", [], controls=["show_deleted:0", "show_recycled:0"])
+            "(&(|(objectclass=*)(distinguishedName=*))(!(distinguishedName=@BASEINFO)))",
+            [], controls=["show_deleted:0", "show_recycled:0"])
         assert len(res) == 0
 
         # delete the specials
@@ -292,18 +298,40 @@ def setup_file(template, fname, subst_vars=None):
     finally:
         f.close()
 
+MAX_NETBIOS_NAME_LEN = 15
+def is_valid_netbios_char(c):
+    return (c.isalnum() or c in " !#$%&'()-.@^_{}~")
+
 
 def valid_netbios_name(name):
     """Check whether a name is valid as a NetBIOS name. """
     # See crh's book (1.4.1.1)
-    if len(name) > 15:
+    if len(name) > MAX_NETBIOS_NAME_LEN:
         return False
     for x in name:
-        if not x.isalnum() and not x in " !#$%&'()-.@^_{}~":
+        if not is_valid_netbios_char(x):
             return False
     return True
 
 
+def import_bundled_package(modulename, location):
+    """Import the bundled version of a package.
+
+    :note: This should only be called if the system version of the package
+        is not adequate.
+
+    :param modulename: Module name to import
+    :param location: Location to add to sys.path (can be relative to
+        ${srcdir}/lib)
+    """
+    if in_source_tree():
+        sys.path.insert(0, os.path.join(source_tree_topdir(), "lib", location))
+        sys.modules[modulename] = __import__(modulename)
+    else:
+        sys.modules[modulename] = __import__(
+            "samba.external.%s" % modulename, fromlist=["samba.external"])
+
+
 def ensure_external_module(modulename, location):
     """Add a location to sys.path if an external dependency can't be found.
 
@@ -314,16 +342,14 @@ def ensure_external_module(modulename, location):
     try:
         __import__(modulename)
     except ImportError:
-        if in_source_tree():
-            sys.path.insert(0,
-                os.path.join(os.path.dirname(__file__),
-                             "../../../../lib", location))
-            __import__(modulename)
-        else:
-            sys.modules[modulename] = __import__(
-                "samba.external.%s" % modulename, fromlist=["samba.external"])
+        import_bundled_package(modulename, location)
+
+
+def dn_from_dns_name(dnsdomain):
+    """return a DN from a DNS name domain/forest root"""
+    return "DC=" + ",DC=".join(dnsdomain.split("."))
 
-from samba import _glue
+import _glue
 version = _glue.version
 interface_ips = _glue.interface_ips
 set_debug_level = _glue.set_debug_level
@@ -333,3 +359,5 @@ nttime2string = _glue.nttime2string
 nttime2unix = _glue.nttime2unix
 unix2nttime = _glue.unix2nttime
 generate_random_password = _glue.generate_random_password
+strcasecmp_m = _glue.strcasecmp_m
+strstr_m = _glue.strstr_m