def force_drs_replication(source_dc=None,
                          destination_dc=None,
                          partition_dn=None,
                          direction="in"):
    if not package_installed('univention-samba4'):
        print(
            'force_drs_replication(): skip, univention-samba4 not installed.')
        return
    if not source_dc:
        source_dc = get_available_s4connector_dc()
        if not source_dc:
            return 1

    if not destination_dc:
        destination_dc = socket.gethostname()

    if destination_dc == source_dc:
        return

    if not partition_dn:
        lp = LoadParm()
        lp.load('/etc/samba/smb.conf')
        samdb = SamDB("tdb://%s" % lp.private_path("sam.ldb"),
                      session_info=system_session(lp),
                      lp=lp)
        partition_dn = str(samdb.domain_dn())
        print("USING partition_dn:", partition_dn)

    if direction == "in":
        cmd = ("/usr/bin/samba-tool", "drs", "replicate", destination_dc,
               source_dc, partition_dn)
    else:
        cmd = ("/usr/bin/samba-tool", "drs", "replicate", source_dc,
               destination_dc, partition_dn)
    return subprocess.call(cmd)
def _wait_for_drs_replication(ldap_filter, attrs=None, base=None, scope=ldb.SCOPE_SUBTREE, lp=None, timeout=360, delta_t=1, verbose=True, should_exist=True, controls=None):
	# type: (str, Union[List[str], None, str], Optional[str], int, Optional[LoadParm], int, int, bool, bool, Optional[List[str]]) -> None
	if not package_installed('univention-samba4'):
		if package_installed('univention-samba'):
			time.sleep(15)
			print('Sleeping 15 seconds as a workaround for http://forge.univention.org/bugzilla/show_bug.cgi?id=52145')
		elif verbose:
			print('wait_for_drs_replication(): skip, univention-samba4 not installed.')
		return
	if not attrs:
		attrs = ['dn']
	elif not isinstance(attrs, list):
		attrs = [attrs]

	if not lp:
		lp = LoadParm()
		lp.load('/etc/samba/smb.conf')
	samdb = SamDB("tdb://%s" % lp.private_path("sam.ldb"), session_info=system_session(lp), lp=lp)
	if not controls:
		controls = ["domain_scope:0"]
	if base is None:
		ucr = config_registry.ConfigRegistry()
		ucr.load()
		base = ucr['samba4/ldap/base']
	else:
		if len(ldap.dn.str2dn(base)[0]) > 1:
			if verbose:
				print('wait_for_drs_replication(): skip, multiple RDNs are not supported')
			return
	if not base:
		if verbose:
			print('wait_for_drs_replication(): skip, no samba domain found')
		return

	if verbose:
		print("Waiting for DRS replication, filter: %r, base: %r, scope: %r, should_exist: %r" % (ldap_filter, base, scope, should_exist), end=' ')
	t = t0 = time.time()
	while t < t0 + timeout:
		try:
			res = samdb.search(base=base, scope=scope, expression=ldap_filter, attrs=attrs, controls=controls)
			if bool(res) is bool(should_exist):
				if verbose:
					print("\nDRS replication took %d seconds" % (t - t0, ))
				return  # res
		except ldb.LdbError as exc:
			(_num, msg) = exc.args
			if _num == ldb.ERR_INVALID_DN_SYNTAX:
				raise
			if _num == ldb.ERR_NO_SUCH_OBJECT and not should_exist:
				if verbose:
					print("\nDRS replication took %d seconds" % (t - t0, ))
				return
			print("Error during samdb.search: %s" % (msg, ))

		print('.', end=' ')
		time.sleep(delta_t)
		t = time.time()
	raise DRSReplicationFailed("DRS replication for filter: %r failed due to timeout after %d sec." % (ldap_filter, t - t0))
Ejemplo n.º 3
0
class SambaOCHelper(object):
    def __init__(self):
        self.samba_lp = LoadParm()
        self.samba_lp.set('debug level', '0')
        self.samba_lp.load_default()
        url = self.samba_lp.get('dcerpc_mapiproxy:samdb_url') or \
            self.samba_lp.private_path("sam.ldb")
        self.samdb = SamDB(url=url,
                           lp=self.samba_lp,
                           session_info=system_session())
        self.conn = self._open_mysql_connection()

    def _open_mysql_connection(self):
        connection_string = self.samba_lp.get('mapiproxy:openchangedb')
        if not connection_string:
            raise Exception(
                "Not found mapiproxy:openchangedb on samba configuration")
        # mysql://openchange:password@localhost/openchange
        m = re.search(
            r'(?P<scheme>.+)://(?P<user>.+):(?P<pass>.+)@(?P<host>.+)/(?P<db>.+)',
            connection_string)
        if not m:
            raise Exception("Unable to parse mapiproxy:openchangedb: %s" %
                            connection_string)
        group_dict = m.groupdict()
        if group_dict['scheme'] != 'mysql':
            raise Exception(
                "mapiproxy:openchangedb should start with mysql:// (we got %s)",
                group_dict['scheme'])

        conn = MySQLdb.connect(host=group_dict['host'],
                               user=group_dict['user'],
                               passwd=group_dict['pass'],
                               db=group_dict['db'])
        conn.autocommit(True)
        return conn

    def invalid_user(self, username):
        ret = self.samdb.search(base=self.samdb.domain_dn(),
                                scope=ldb.SCOPE_SUBTREE,
                                expression="(sAMAccountName=%s)" %
                                ldb.binary_encode(username))
        return len(ret) != 1

    def find_email_of(self, username):
        ret = self.samdb.search(base=self.samdb.domain_dn(),
                                scope=ldb.SCOPE_SUBTREE,
                                attrs=["mail"],
                                expression="(sAMAccountName=%s)" %
                                ldb.binary_encode(username))
        return ret[0]["mail"][0]

    def active_openchange_users(self):
        c = self.conn.cursor()
        c.execute("SELECT name FROM mailboxes")
        return sorted([row[0] for row in c.fetchall()])
def wait_for_drs_replication(ldap_filter, attrs=None, base=None, scope=ldb.SCOPE_SUBTREE, lp=None, timeout=360, delta_t=1, verbose=True, should_exist=True, controls=None):
	if not package_installed('univention-samba4'):
		if verbose:
			print('wait_for_drs_replication(): skip, univention-samba4 not installed.')
		return
	if not lp:
		lp = LoadParm()
		lp.load('/etc/samba/smb.conf')
	if not attrs:
		attrs = ['dn']
	elif not isinstance(attrs, list):
		attrs = [attrs]

	samdb = SamDB("tdb://%s" % lp.private_path("sam.ldb"), session_info=system_session(lp), lp=lp)
	if not controls:
		controls = ["domain_scope:0"]
	if base is None:
		base = samdb.domain_dn()
	else:
		if len(ldap.dn.str2dn(base)[0]) > 1:
			if verbose:
				print('wait_for_drs_replication(): skip, multiple RDNs are not supported')
			return
	if not base or base == 'None':
		if verbose:
			print('wait_for_drs_replication(): skip, no samba domain found')
		return

	if verbose:
		print("Waiting for DRS replication, filter: %r, base: %r, scope: %r, should_exist: %r" % (ldap_filter, base, scope, should_exist), end=' ')
	t = t0 = time.time()
	while t < t0 + timeout:
		try:
			res = samdb.search(base=base, scope=scope, expression=ldap_filter, attrs=attrs, controls=controls)
			if res and should_exist:
				if verbose:
					print("\nDRS replication took %d seconds" % (t - t0, ))
				return res
			if not res and not should_exist:
				if verbose:
					print("\nDRS replication took %d seconds" % (t - t0, ))
				return res
		except ldb.LdbError as exc:
			(_num, msg) = exc.args
			if _num == ldb.ERR_INVALID_DN_SYNTAX:
				raise
			if _num == ldb.ERR_NO_SUCH_OBJECT and not should_exist:
				if verbose:
					print("\nDRS replication took %d seconds" % (t - t0, ))
				return
			print("Error during samdb.search: %s" % (msg, ))

		print('.', end=' ')
		time.sleep(delta_t)
		t = time.time()
	raise DRSReplicationFailed("DRS replication for filter: %r failed due to timeout after %d sec." % (ldap_filter, t - t0))
Ejemplo n.º 5
0
class SambaOCHelper(object):
    def __init__(self):
        self.samba_lp = LoadParm()
        self.samba_lp.set('debug level', '0')
        self.samba_lp.load_default()
        url = self.samba_lp.get('dcerpc_mapiproxy:samdb_url') or \
            self.samba_lp.private_path("sam.ldb")
        self.samdb = SamDB(url=url,
                           lp=self.samba_lp,
                           session_info=system_session())
        self.conn = self._open_mysql_connection()

    def _open_mysql_connection(self):
        connection_string = self.samba_lp.get('mapiproxy:openchangedb')
        if not connection_string:
            raise Exception("Not found mapiproxy:openchangedb on samba configuration")
        # mysql://openchange:password@localhost/openchange
        m = re.search(r'(?P<scheme>.+)://(?P<user>.+):(?P<pass>.+)@(?P<host>.+)/(?P<db>.+)',
                      connection_string)
        if not m:
            raise Exception("Unable to parse mapiproxy:openchangedb: %s" %
                            connection_string)
        group_dict = m.groupdict()
        if group_dict['scheme'] != 'mysql':
            raise Exception("mapiproxy:openchangedb should start with mysql:// (we got %s)",
                            group_dict['scheme'])

        conn = MySQLdb.connect(host=group_dict['host'], user=group_dict['user'],
                               passwd=group_dict['pass'], db=group_dict['db'])
        conn.autocommit(True)
        return conn

    def invalid_user(self, username):
        ret = self.samdb.search(base=self.samdb.domain_dn(),
                                scope=ldb.SCOPE_SUBTREE,
                                expression="(sAMAccountName=%s)" % ldb.binary_encode(username))
        return len(ret) != 1

    def find_email_of(self, username):
        ret = self.samdb.search(base=self.samdb.domain_dn(),
                                scope=ldb.SCOPE_SUBTREE, attrs=["mail"],
                                expression="(sAMAccountName=%s)" % ldb.binary_encode(username))
        return ret[0]["mail"][0]

    def active_openchange_users(self):
        c = self.conn.cursor()
        c.execute("SELECT name FROM mailboxes")
        return sorted([row[0] for row in c.fetchall()])

    def get_indexing_cache(self):
        memcached_server = self.samba_lp.get('mapistore:indexing_cache')
        if not memcached_server:
            return "127.0.0.1:11211"
        # This should has a format like: --SERVER=11.22.33.44:11211
        return memcached_server.split('=')[1]
Ejemplo n.º 6
0
def wait_for_drs_replication(ldap_filter,
                             attrs=None,
                             base=None,
                             scope=ldb.SCOPE_SUBTREE,
                             lp=None,
                             timeout=360,
                             delta_t=1,
                             verbose=True):
    if not package_installed('univention-samba4'):
        if verbose:
            print 'wait_for_drs_replication(): skip, univention-samba4 not installed.'
        return
    if not lp:
        lp = LoadParm()
        lp.load('/etc/samba/smb.conf')
    if not attrs:
        attrs = ['dn']
    elif not isinstance(attrs, list):
        attrs = [attrs]

    samdb = SamDB("tdb://%s" % lp.private_path("sam.ldb"),
                  session_info=system_session(lp),
                  lp=lp)
    controls = ["domain_scope:0"]
    if base is None:
        base = samdb.domain_dn()
    if not base or base == 'None':
        if verbose:
            print 'wait_for_drs_replication(): skip, no samba domain found'
        return

    if verbose:
        print "Waiting for DRS replication, filter: '%s'" % (ldap_filter, ),
    t = t0 = time.time()
    while t < t0 + timeout:
        try:
            res = samdb.search(base=base,
                               scope=scope,
                               expression=ldap_filter,
                               attrs=attrs,
                               controls=controls)
            if res:
                if verbose:
                    print "\nDRS replication took %d seconds" % (t - t0, )
                return res
        except ldb.LdbError as (_num, msg):
            print "Error during samdb.search: %s" % (msg, )

        print '.',
        time.sleep(delta_t)
        t = time.time()
Ejemplo n.º 7
0
class SambaOCHelper(object):
    def __init__(self):
        self.samba_lp = LoadParm()
        self.samba_lp.set("debug level", "0")
        self.samba_lp.load_default()
        url = self.samba_lp.get("dcerpc_mapiproxy:samdb_url") or self.samba_lp.private_path("sam.ldb")
        self.samdb = SamDB(url=url, lp=self.samba_lp, session_info=system_session())
        self.conn = self._open_mysql_connection()

    def _open_mysql_connection(self):
        connection_string = self.samba_lp.get("mapiproxy:openchangedb")
        if not connection_string:
            raise Exception("Not found mapiproxy:openchangedb on samba configuration")
        # mysql://openchange:password@localhost/openchange
        m = re.search(r"(?P<scheme>.+)://(?P<user>.+):(?P<pass>.+)@(?P<host>.+)/(?P<db>.+)", connection_string)
        if not m:
            raise Exception("Unable to parse mapiproxy:openchangedb: %s" % connection_string)
        group_dict = m.groupdict()
        if group_dict["scheme"] != "mysql":
            raise Exception("mapiproxy:openchangedb should start with mysql:// (we got %s)", group_dict["scheme"])

        conn = MySQLdb.connect(
            host=group_dict["host"], user=group_dict["user"], passwd=group_dict["pass"], db=group_dict["db"]
        )
        conn.autocommit(True)
        return conn

    def invalid_user(self, username):
        ret = self.samdb.search(
            base=self.samdb.domain_dn(),
            scope=ldb.SCOPE_SUBTREE,
            expression="(sAMAccountName=%s)" % ldb.binary_encode(username),
        )
        return len(ret) != 1

    def find_email_of(self, username):
        ret = self.samdb.search(
            base=self.samdb.domain_dn(),
            scope=ldb.SCOPE_SUBTREE,
            attrs=["mail"],
            expression="(sAMAccountName=%s)" % ldb.binary_encode(username),
        )
        return ret[0]["mail"][0]

    def active_openchange_users(self):
        c = self.conn.cursor()
        c.execute("SELECT name FROM mailboxes")
        return sorted([row[0] for row in c.fetchall()])
Ejemplo n.º 8
0
    def get_samba_sam_ldb_path(self):
        """
		Returns the 'sam.ldb' path using samba conf or defaults.
		"""
        print(
            "\nObtaining the Samba configuration to determine Samba private path"
        )
        smb_conf_path = getenv("SMB_CONF_PATH")
        SambaLP = LoadParm()

        if smb_conf_path:
            SambaLP.load(smb_conf_path)
        else:
            SambaLP.load_default()

        return SambaLP.private_path('sam.ldb')
Ejemplo n.º 9
0
    def apply(cls, cur, **kwargs):
        # Mimetise what mapistore_interface.c (mapistore_init) does
        # to get the mapping path
        if 'lp' in kwargs:
            mapping_path = kwargs['lp'].private_path("mapistore")
        else:
            lp = LoadParm()
            lp.load_default()
            mapping_path = lp.private_path("mapistore")

        if mapping_path is None:
            return

        cur.execute("START TRANSACTION")
        try:
            # Get all mailboxes
            cur.execute("SELECT name FROM mailboxes")
            for row in cur.fetchall():
                username = row[0]
                path = "{0}/{1}/replica_mapping.tdb".format(
                    mapping_path, username)
                try:
                    tdb_file = tdb.Tdb(path, 0, tdb.DEFAULT, os.O_RDONLY)
                    for k in tdb_file.iterkeys():
                        # Check if the key is an integer
                        try:
                            repl_id = int(k, base=16)
                            cls._insert_map(cur, username, repl_id,
                                            tdb_file[k])
                        except ValueError:
                            # Cannot convert to int, so no repl_id
                            continue
                except IOError:
                    # Cannot read any replica mapping
                    continue

            cur.execute("COMMIT")
        except Exception as e:
            print("Error migrating TDB files into the database {}, rollback".
                  format(e),
                  file=sys.stderr)
            cur.execute("ROLLBACK")
            raise
Ejemplo n.º 10
0
    def apply(cls, cur, **kwargs):
        # Mimetise what mapistore_interface.c (mapistore_init) does
        # to get the mapping path
        if 'lp' in kwargs:
            mapping_path = kwargs['lp'].private_path("mapistore")
        else:
            lp = LoadParm()
            lp.load_default()
            mapping_path = lp.private_path("mapistore")

        if mapping_path is None:
            return

        cur.execute("START TRANSACTION")
        try:
            # Get all mailboxes
            cur.execute("SELECT name FROM mailboxes")
            for row in cur.fetchall():
                username = row[0]
                path = "{0}/{1}/replica_mapping.tdb".format(mapping_path, username)
                try:
                    tdb_file = tdb.Tdb(path, 0, tdb.DEFAULT, os.O_RDONLY)
                    for k in tdb_file.iterkeys():
                        # Check if the key is an integer
                        try:
                            repl_id = int(k, base=16)
                            cls._insert_map(cur, username, repl_id, tdb_file[k])
                        except ValueError:
                            # Cannot convert to int, so no repl_id
                            continue
                except IOError:
                    # Cannot read any replica mapping
                    continue

            cur.execute("COMMIT")
        except Exception as e:
            print("Error migrating TDB files into the database {}, rollback".format(e), file=sys.stderr)
            cur.execute("ROLLBACK")
            raise
Ejemplo n.º 11
0
class SambaOCHelper(object):
    def __init__(self):
        self.samba_lp = LoadParm()
        self.samba_lp.set('debug level', '0')
        self.samba_lp.load_default()
        self.next_fmid = None
        url = self.samba_lp.get('dcerpc_mapiproxy:samdb_url') or \
            self.samba_lp.private_path("sam.ldb")
        self.samdb = SamDB(url=url,
                           lp=self.samba_lp,
                           session_info=system_session())
        self.conn = self._open_mysql_connection()

    def _open_mysql_connection(self):
        connection_string = self.samba_lp.get('mapiproxy:openchangedb')
        if not connection_string:
            raise Exception("Not found mapiproxy:openchangedb on samba configuration")
        # mysql://openchange:password@localhost/openchange
        m = re.search(r'(?P<scheme>.+)://(?P<user>.+):(?P<pass>.+)@(?P<host>.+)/(?P<db>.+)',
                      connection_string)
        if not m:
            raise Exception("Unable to parse mapiproxy:openchangedb: %s" %
                            connection_string)
        group_dict = m.groupdict()
        if group_dict['scheme'] != 'mysql':
            raise Exception("mapiproxy:openchangedb should start with mysql:// (we got %s)",
                            group_dict['scheme'])

        conn = MySQLdb.connect(host=group_dict['host'], user=group_dict['user'],
                               passwd=group_dict['pass'], db=group_dict['db'])
        conn.autocommit(True)
        return conn

    def invalid_user(self, username):
        ret = self.samdb.search(base=self.samdb.domain_dn(),
                                scope=ldb.SCOPE_SUBTREE,
                                expression="(sAMAccountName=%s)" % ldb.binary_encode(username))
        return len(ret) != 1

    def find_email_of(self, username):
        ret = self.samdb.search(base=self.samdb.domain_dn(),
                                scope=ldb.SCOPE_SUBTREE, attrs=["mail"],
                                expression="(sAMAccountName=%s)" % ldb.binary_encode(username))
        return ret[0]["mail"][0]

    def active_openchange_users(self):
        c = self.conn.cursor()
        c.execute("SELECT name FROM mailboxes")
        return sorted([row[0] for row in c.fetchall()])

    def allocate_fmids(self, count, username):
        if self.next_fmid is None:
            c = self.conn.cursor()
            c.execute("SELECT next_fmid FROM mapistore_indexes WHERE username = '******'" % username)
            self.next_fmid = c.fetchone()[0]
        if self.next_fmid is not None:
            self.next_fmid = int(self.next_fmid) + count

        return (int(self.next_fmid) - count, self.next_fmid)

    def create_indexes(self, username):
        c = self.conn.cursor()
        c.execute("INSERT INTO mapistore_indexes (username,next_fmid) VALUES('%s','1024')" % (username))
        return

    def commit_start(self):
        self.conn.autocommit(False)

    def insert_indexing(self, username, fmid, url):
        c = self.conn.cursor()
        
        c.execute("INSERT INTO mapistore_indexing (username,fmid,url,soft_deleted) VALUES('%s','%s','%s', '0')" % (username, str(fmid), url))

    def update_indexes(self, count, username):
        c = self.conn.cursor()
        updated_number = int(count) + int(self.next_fmid)
        print "Updating next_fmid to %s" % str(updated_number)
        c.execute("UPDATE mapistore_indexes SET next_fmid='%s' WHERE username='******'" % (str(updated_number), username))

    def commit_end(self):
        c = self.conn.cursor()
        self.conn.commit()
        c.close()
        self.conn.autocommit(True)