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]
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 run(self, value, H=None, credopts=None, sambaopts=None, versionopts=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = samdb.domain_dn() object_dn = "%s,%s" % (self.objectdn, domain_dn) # Create the modification m = ldb.Message() m.dn = ldb.Dn(samdb, object_dn) m[self.attribute] = ldb.MessageElement(value, ldb.FLAG_MOD_REPLACE, self.attribute) samdb.modify(m) self.outf.write("set %s: %s\n" % (self.attribute, value))
def run(self, sambaopts=None, credopts=None, versionopts=None, H=None, full_dn=False): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = ldb.Dn(samdb, samdb.domain_dn()) res = samdb.search(domain_dn, scope=ldb.SCOPE_SUBTREE, expression="(objectClass=organizationalUnit)", attrs=[]) if (len(res) == 0): return for msg in sorted(res, key=attrgetter('dn')): if not full_dn: msg.dn.remove_base_components(len(domain_dn)) self.outf.write("%s\n" % str(msg.dn))
def run(self, sambaopts=None, credopts=None, versionopts=None, H=None, base_dn=None, full_dn=False): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) filter = "(sAMAccountType=%u)" % (dsdb.ATYPE_WORKSTATION_TRUST) search_dn = samdb.domain_dn() if base_dn: search_dn = samdb.normalize_dn_in_domain(base_dn) res = samdb.search(search_dn, scope=ldb.SCOPE_SUBTREE, expression=filter, attrs=["samaccountname"]) if (len(res) == 0): return for msg in res: if full_dn: self.outf.write("%s\n" % msg.get("dn")) continue self.outf.write("%s\n" % msg.get("samaccountname", idx=0))
def run(self, computername, credopts=None, sambaopts=None, versionopts=None, H=None, computer_attrs=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) attrs = None if computer_attrs: attrs = computer_attrs.split(",") samaccountname = computername if not computername.endswith('$'): samaccountname = "%s$" % computername filter = ("(&(sAMAccountType=%d)(sAMAccountName=%s))" % (dsdb.ATYPE_WORKSTATION_TRUST, ldb.binary_encode(samaccountname))) domaindn = samdb.domain_dn() try: res = samdb.search(base=domaindn, expression=filter, scope=ldb.SCOPE_SUBTREE, attrs=attrs) computer_dn = res[0].dn except IndexError: raise CommandError('Unable to find computer "%s"' % samaccountname) for msg in res: computer_ldif = common.get_ldif_for_editor(samdb, msg) self.outf.write(computer_ldif)
class MatchRulesTests(samba.tests.TestCase): def setUp(self): super(MatchRulesTests, self).setUp() self.lp = lp self.ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp) self.base_dn = self.ldb.domain_dn() self.ou = "OU=pid%s,%s" % (os.getpid(), self.base_dn) self.ou_users = "OU=users,%s" % self.ou self.ou_groups = "OU=groups,%s" % self.ou self.ou_computers = "OU=computers,%s" % self.ou self.n_groups = 1 try: for i in range(self.n_groups): delete_force(self.ldb, "cn=g%d,%s" % (i + 1, self.ou_groups)) delete_force(self.ldb, "cn=u%d,%s" % (i + 1, self.ou_users)) delete_force(self.ldb, "cn=c1,%s" % self.ou_computers) delete_force(self.ldb, "cn=c2,%s" % self.ou_computers) delete_force(self.ldb, "cn=c3,%s" % self.ou_computers) delete_force(self.ldb, self.ou_users) delete_force(self.ldb, self.ou_groups) delete_force(self.ldb, self.ou_computers) delete_force(self.ldb, "OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou) delete_force(self.ldb, "OU=o3,OU=o2,OU=o1,%s" % self.ou) delete_force(self.ldb, "OU=o2,OU=o1,%s" % self.ou) delete_force(self.ldb, "OU=o1,%s" % self.ou) delete_force(self.ldb, "CN=e2,%s" % self.ou) delete_force(self.ldb, "CN=e1,%s" % self.ou) delete_force(self.ldb, self.ou) except Exception, e: print e try: # Add a organizational unit to create objects self.ldb.add({ "dn": self.ou, "objectclass": "organizationalUnit"}) # Create OU for users and groups self.ldb.add({ "dn": self.ou_users, "objectclass": "organizationalUnit"}) self.ldb.add({ "dn": self.ou_groups, "objectclass": "organizationalUnit"}) self.ldb.add({ "dn": self.ou_computers, "objectclass": "organizationalUnit"}) # Add groups for i in range(self.n_groups): self.ldb.add({ "dn": "cn=g%d,%s" % (i + 1, self.ou_groups), "objectclass": "group" }) except Exception, e: print e
def run(self, H=None, credopts=None, sambaopts=None, versionopts=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = samdb.domain_dn() forest_dn = samba.dn_from_dns_name(samdb.forest_dns_name()) infrastructure_dn = "CN=Infrastructure," + domain_dn naming_dn = "CN=Partitions,%s" % samdb.get_config_basedn() schema_dn = samdb.get_schema_basedn() rid_dn = "CN=RID Manager$,CN=System," + domain_dn domaindns_dn = "CN=Infrastructure,DC=DomainDnsZones," + domain_dn forestdns_dn = "CN=Infrastructure,DC=ForestDnsZones," + forest_dn masters = [(schema_dn, "schema", "SchemaMasterRole"), (infrastructure_dn, "infrastructure", "InfrastructureMasterRole"), (rid_dn, "rid", "RidAllocationMasterRole"), (domain_dn, "pdc", "PdcEmulationMasterRole"), (naming_dn, "naming", "DomainNamingMasterRole"), (domaindns_dn, "domaindns", "DomainDnsZonesMasterRole"), (forestdns_dn, "forestdns", "ForestDnsZonesMasterRole"), ] for master in masters: (dn, short_name, long_name) = master try: master = get_fsmo_roleowner(samdb, dn, short_name) if master is not None: self.message("%s owner: %s" % (long_name, str(master))) else: self.message("%s has no current owner" % (long_name)) except CommandError as e: self.message("%s: * %s" % (long_name, e.message))
def run(self, groupname, credopts=None, sambaopts=None, versionopts=None, H=None, group_attrs=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) attrs = None if group_attrs: attrs = group_attrs.split(",") filter = ("(&(objectCategory=group)(sAMAccountName=%s))" % ldb.binary_encode(groupname)) domaindn = samdb.domain_dn() try: res = samdb.search(base=domaindn, expression=filter, scope=ldb.SCOPE_SUBTREE, attrs=attrs) user_dn = res[0].dn except IndexError: raise CommandError('Unable to find group "%s"' % (groupname)) for msg in res: group_ldif = common.get_ldif_for_editor(samdb, msg) self.outf.write(group_ldif)
def run(self, groupname, credopts=None, sambaopts=None, versionopts=None, H=None, group_attrs=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) attrs = None if group_attrs: attrs = group_attrs.split(",") filter = ("(&(sAMAccountType=%d)(sAMAccountName=%s))" % ( ATYPE_SECURITY_GLOBAL_GROUP, ldb.binary_encode(groupname))) domaindn = samdb.domain_dn() try: res = samdb.search(base=domaindn, expression=filter, scope=ldb.SCOPE_SUBTREE, attrs=attrs) user_dn = res[0].dn except IndexError: raise CommandError('Unable to find group "%s"' % (groupname)) for msg in res: user_ldif = samdb.write_ldif(msg, ldb.CHANGETYPE_NONE) self.outf.write(user_ldif)
def run(self, H=None, credopts=None, sambaopts=None, versionopts=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = samdb.domain_dn() forest_dn = samba.dn_from_dns_name(samdb.forest_dns_name()) infrastructure_dn = "CN=Infrastructure," + domain_dn naming_dn = "CN=Partitions,%s" % samdb.get_config_basedn() schema_dn = samdb.get_schema_basedn() rid_dn = "CN=RID Manager$,CN=System," + domain_dn domaindns_dn = "CN=Infrastructure,DC=DomainDnsZones," + domain_dn forestdns_dn = "CN=Infrastructure,DC=ForestDnsZones," + forest_dn masters = [(schema_dn, "schema", "SchemaMasterRole"), (infrastructure_dn, "infrastructure", "InfrastructureMasterRole"), (rid_dn, "rid", "RidAllocationMasterRole"), (domain_dn, "pdc", "PdcEmulationMasterRole"), (naming_dn, "naming", "DomainNamingMasterRole"), (domaindns_dn, "domaindns", "DomainDnsZonesMasterRole"), (forestdns_dn, "forestdns", "ForestDnsZonesMasterRole"), ] for master in masters: (dn, short_name, long_name) = master try: master = get_fsmo_roleowner(samdb, dn, short_name) if master is not None: self.message("%s owner: %s" % (long_name, str(master))) else: self.message("%s has no current owner" % (long_name)) except CommandError, e: self.message("%s: * %s" % (long_name, e.message))
def run(self, H=None, credopts=None, sambaopts=None, versionopts=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = samdb.domain_dn() object_dn = "%s,%s" % (self.objectdn, domain_dn) # Show all the settings we know how to set in the forest object! res = samdb.search(base=object_dn, scope=ldb.SCOPE_BASE, attrs=self.attributes) # Now we just display these attributes. The value is that # we make them a bit prettier and human accessible. # There should only be one response! res_object = res[0] self.outf.write("Settings for %s\n" % object_dn) for attr in self.attributes: try: self.outf.write("%s: %s\n" % (attr, res_object[attr][0])) except KeyError: self.outf.write("%s: <NO VALUE>\n" % attr)
def run(self, sambaopts=None, credopts=None, versionopts=None, H=None, base_dn=None, full_dn=False): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) search_dn = samdb.domain_dn() if base_dn: search_dn = samdb.normalize_dn_in_domain(base_dn) res = samdb.search(search_dn, scope=ldb.SCOPE_SUBTREE, expression="(objectClass=contact)", attrs=["name"]) if (len(res) == 0): return if full_dn: for msg in sorted(res, key=attrgetter('dn')): self.outf.write("%s\n" % msg.dn) return for msg in res: contact_name = msg.get("name", idx=0) self.outf.write("%s\n" % contact_name)
def run(self, H=None, credopts=None, sambaopts=None, versionopts=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = samdb.domain_dn() forest_dn = samba.dn_from_dns_name(samdb.forest_dns_name()) infrastructure_dn = "CN=Infrastructure," + domain_dn naming_dn = "CN=Partitions,%s" % samdb.get_config_basedn() schema_dn = samdb.get_schema_basedn() rid_dn = "CN=RID Manager$,CN=System," + domain_dn domaindns_dn = "CN=Infrastructure,DC=DomainDnsZones," + domain_dn forestdns_dn = "CN=Infrastructure,DC=ForestDnsZones," + forest_dn infrastructureMaster = get_fsmo_roleowner(samdb, infrastructure_dn) pdcEmulator = get_fsmo_roleowner(samdb, domain_dn) namingMaster = get_fsmo_roleowner(samdb, naming_dn) schemaMaster = get_fsmo_roleowner(samdb, schema_dn) ridMaster = get_fsmo_roleowner(samdb, rid_dn) domaindnszonesMaster = get_fsmo_roleowner(samdb, domaindns_dn) forestdnszonesMaster = get_fsmo_roleowner(samdb, forestdns_dn) self.message("SchemaMasterRole owner: " + schemaMaster) self.message("InfrastructureMasterRole owner: " + infrastructureMaster) self.message("RidAllocationMasterRole owner: " + ridMaster) self.message("PdcEmulationMasterRole owner: " + pdcEmulator) self.message("DomainNamingMasterRole owner: " + namingMaster) self.message("DomainDnsZonesMasterRole owner: " + domaindnszonesMaster) self.message("ForestDnsZonesMasterRole owner: " + forestdnszonesMaster)
class DirsyncBaseTests(samba.tests.TestCase): def setUp(self): super(DirsyncBaseTests, self).setUp() self.ldb_admin = SamDB(ldapshost, credentials=creds, session_info=system_session(lp), lp=lp) self.base_dn = self.ldb_admin.domain_dn() self.domain_sid = security.dom_sid(self.ldb_admin.get_domain_sid()) self.user_pass = samba.generate_random_password(12, 16) self.configuration_dn = self.ldb_admin.get_config_basedn( ).get_linearized() self.sd_utils = sd_utils.SDUtils(self.ldb_admin) # used for anonymous login print("baseDN: %s" % self.base_dn) def get_user_dn(self, name): return "CN=%s,CN=Users,%s" % (name, self.base_dn) def get_ldb_connection(self, target_username, target_password): creds_tmp = Credentials() creds_tmp.set_username(target_username) creds_tmp.set_password(target_password) creds_tmp.set_domain(creds.get_domain()) creds_tmp.set_realm(creds.get_realm()) creds_tmp.set_workstation(creds.get_workstation()) creds_tmp.set_gensec_features(creds_tmp.get_gensec_features() | gensec.FEATURE_SEAL) creds_tmp.set_kerberos_state( DONT_USE_KERBEROS) # kinit is too expensive to use in a tight loop ldb_target = SamDB(url=ldaphost, credentials=creds_tmp, lp=lp) return ldb_target
def main(): lp = LoadParm() lp.load_default() print("\nLoaded loadparm:") print(" samdb_url: ", lp.samdb_url()) print(" server_role: ", lp.server_role()) creds = Credentials() creds.guess(lp) print("\nCredentials:") creds.set_kerberos_state(MUST_USE_KERBEROS) # If MUST_USE_KERBEROS and we have no ticket, yields this error: # "Failed to connect to 'ldap://dc1' with backend 'ldap': LDAP client internal error: NT_STATUS_INVALID_PARAMETER" # Local #samdb = SamDB(lp=lp) # Remote samdb = SamDB(lp=lp, url='ldap://dc1', credentials=creds) print("\nOpened SAM DB:") print(" domain_dn: ", samdb.domain_dn()) print(" domain_dns_name:", samdb.domain_dns_name()) for q in sys.argv[1:]: query(samdb, q)
def test_1000_binds(self): for x in range(1, 1000): samdb = SamDB(host, credentials=creds, session_info=system_session(self.lp), lp=self.lp) samdb.search(base=samdb.domain_dn(), scope=SCOPE_BASE, attrs=["*"])
class BaseDeleteTests(samba.tests.TestCase): def GUID_string(self, guid): return self.ldb.schema_format_value("objectGUID", guid) def setUp(self): super(BaseDeleteTests, self).setUp() self.ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp) self.base_dn = self.ldb.domain_dn() self.configuration_dn = self.ldb.get_config_basedn().get_linearized() def search_guid(self, guid): print("SEARCH by GUID %s" % self.GUID_string(guid)) res = self.ldb.search(base="<GUID=%s>" % self.GUID_string(guid), scope=SCOPE_BASE, controls=["show_deleted:1"]) self.assertEquals(len(res), 1) return res[0] def search_dn(self, dn): print("SEARCH by DN %s" % dn) res = self.ldb.search(expression="(objectClass=*)", base=dn, scope=SCOPE_BASE, controls=["show_deleted:1"]) self.assertEquals(len(res), 1) return res[0]
def run(self, computername, new_ou_dn, credopts=None, sambaopts=None, versionopts=None, H=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = ldb.Dn(samdb, samdb.domain_dn()) samaccountname = computername if not computername.endswith('$'): samaccountname = "%s$" % computername filter = ("(&(sAMAccountName=%s)(sAMAccountType=%u))" % (ldb.binary_encode(samaccountname), dsdb.ATYPE_WORKSTATION_TRUST)) try: res = samdb.search(base=domain_dn, expression=filter, scope=ldb.SCOPE_SUBTREE) computer_dn = res[0].dn except IndexError: raise CommandError('Unable to find computer "%s"' % (computername)) full_new_ou_dn = ldb.Dn(samdb, new_ou_dn) if not full_new_ou_dn.is_child_of(domain_dn): full_new_ou_dn.add_base(domain_dn) new_computer_dn = ldb.Dn(samdb, str(computer_dn)) new_computer_dn.remove_base_components(len(computer_dn)-1) new_computer_dn.add_base(full_new_ou_dn) try: samdb.rename(computer_dn, new_computer_dn) except Exception as e: raise CommandError('Failed to move computer "%s"' % computername, e) self.outf.write('Moved computer "%s" to "%s"\n' % (computername, new_ou_dn))
def run(self, computername, credopts=None, sambaopts=None, versionopts=None, H=None, computer_attrs=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) attrs = None if computer_attrs: attrs = computer_attrs.split(",") samaccountname = computername if not computername.endswith('$'): samaccountname = "%s$" % computername filter = ("(&(sAMAccountType=%d)(sAMAccountName=%s))" % (dsdb.ATYPE_WORKSTATION_TRUST, ldb.binary_encode(samaccountname))) domaindn = samdb.domain_dn() try: res = samdb.search(base=domaindn, expression=filter, scope=ldb.SCOPE_SUBTREE, attrs=attrs) computer_dn = res[0].dn except IndexError: raise CommandError('Unable to find computer "%s"' % samaccountname) for msg in res: computer_ldif = samdb.write_ldif(msg, ldb.CHANGETYPE_NONE) self.outf.write(computer_ldif)
def run(self, groupname, new_parent_dn, credopts=None, sambaopts=None, versionopts=None, H=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = ldb.Dn(samdb, samdb.domain_dn()) filter = ("(&(sAMAccountName=%s)(objectClass=group))" % groupname) try: res = samdb.search(base=domain_dn, expression=filter, scope=ldb.SCOPE_SUBTREE) group_dn = res[0].dn except IndexError: raise CommandError('Unable to find group "%s"' % (groupname)) try: full_new_parent_dn = samdb.normalize_dn_in_domain(new_parent_dn) except Exception as e: raise CommandError('Invalid new_parent_dn "%s": %s' % (new_parent_dn, e.message)) full_new_group_dn = ldb.Dn(samdb, str(group_dn)) full_new_group_dn.remove_base_components(len(group_dn)-1) full_new_group_dn.add_base(full_new_parent_dn) try: samdb.rename(group_dn, full_new_group_dn) except Exception as e: raise CommandError('Failed to move group "%s"' % groupname, e) self.outf.write('Moved group "%s" into "%s"\n' % (groupname, full_new_parent_dn))
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)
class DirsyncBaseTests(samba.tests.TestCase): def setUp(self): super(DirsyncBaseTests, self).setUp() self.ldb_admin = SamDB(ldapshost, credentials=creds, session_info=system_session(lp), lp=lp) self.base_dn = self.ldb_admin.domain_dn() self.domain_sid = security.dom_sid(self.ldb_admin.get_domain_sid()) self.user_pass = samba.generate_random_password(12, 16) self.configuration_dn = self.ldb_admin.get_config_basedn().get_linearized() self.sd_utils = sd_utils.SDUtils(self.ldb_admin) #used for anonymous login print("baseDN: %s" % self.base_dn) def get_user_dn(self, name): return "CN=%s,CN=Users,%s" % (name, self.base_dn) def get_ldb_connection(self, target_username, target_password): creds_tmp = Credentials() creds_tmp.set_username(target_username) creds_tmp.set_password(target_password) creds_tmp.set_domain(creds.get_domain()) creds_tmp.set_realm(creds.get_realm()) creds_tmp.set_workstation(creds.get_workstation()) creds_tmp.set_gensec_features(creds_tmp.get_gensec_features() | gensec.FEATURE_SEAL) creds_tmp.set_kerberos_state(DONT_USE_KERBEROS) # kinit is too expensive to use in a tight loop ldb_target = SamDB(url=ldaphost, credentials=creds_tmp, lp=lp) return ldb_target
def run(self, subcommand, H=None, min_pwd_age=None, max_pwd_age=None, quiet=False, complexity=None, store_plaintext=None, history_length=None, min_pwd_length=None, credopts=None, sambaopts=None, versionopts=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = samdb.domain_dn() res = samdb.search(domain_dn, scope=ldb.SCOPE_BASE, attrs=["pwdProperties", "pwdHistoryLength", "minPwdLength", "minPwdAge", "maxPwdAge"]) assert(len(res) == 1) try: pwd_props = int(res[0]["pwdProperties"][0]) pwd_hist_len = int(res[0]["pwdHistoryLength"][0]) cur_min_pwd_len = int(res[0]["minPwdLength"][0]) # ticks -> days cur_min_pwd_age = int(abs(int(res[0]["minPwdAge"][0])) / (1e7 * 60 * 60 * 24)) if int(res[0]["maxPwdAge"][0]) == -0x8000000000000000: cur_max_pwd_age = 0 else: cur_max_pwd_age = int(abs(int(res[0]["maxPwdAge"][0])) / (1e7 * 60 * 60 * 24)) except Exception, e: raise CommandError("Could not retrieve password properties!", e)
class BaseDeleteTests(samba.tests.TestCase): def GUID_string(self, guid): return self.ldb.schema_format_value("objectGUID", guid) def setUp(self): super(BaseDeleteTests, self).setUp() self.ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp) self.base_dn = self.ldb.domain_dn() self.configuration_dn = self.ldb.get_config_basedn().get_linearized() def search_guid(self, guid): print "SEARCH by GUID {0!s}".format(self.GUID_string(guid)) res = self.ldb.search(base="<GUID={0!s}>".format(self.GUID_string(guid)), scope=SCOPE_BASE, controls=["show_deleted:1"]) self.assertEquals(len(res), 1) return res[0] def search_dn(self,dn): print "SEARCH by DN {0!s}".format(dn) res = self.ldb.search(expression="(objectClass=*)", base=dn, scope=SCOPE_BASE, controls=["show_deleted:1"]) self.assertEquals(len(res), 1) return res[0]
def run(self, computername, new_ou_dn, credopts=None, sambaopts=None, versionopts=None, H=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = ldb.Dn(samdb, samdb.domain_dn()) samaccountname = computername if not computername.endswith('$'): samaccountname = "%s$" % computername filter = ("(&(sAMAccountName=%s)(sAMAccountType=%u))" % (ldb.binary_encode(samaccountname), dsdb.ATYPE_WORKSTATION_TRUST)) try: res = samdb.search(base=domain_dn, expression=filter, scope=ldb.SCOPE_SUBTREE) computer_dn = res[0].dn except IndexError: raise CommandError('Unable to find computer "%s"' % (computername)) full_new_ou_dn = ldb.Dn(samdb, new_ou_dn) if not full_new_ou_dn.is_child_of(domain_dn): full_new_ou_dn.add_base(domain_dn) new_computer_dn = ldb.Dn(samdb, str(computer_dn)) new_computer_dn.remove_base_components(len(computer_dn) -1) new_computer_dn.add_base(full_new_ou_dn) try: samdb.rename(computer_dn, new_computer_dn) except Exception as e: raise CommandError('Failed to move computer "%s"' % computername, e) self.outf.write('Moved computer "%s" to "%s"\n' % (computername, new_ou_dn))
def run(self, groupname, credopts=None, sambaopts=None, versionopts=None, H=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) filter = ("(&(sAMAccountName=%s)(objectClass=group))" % groupname) try: res = samdb.search(base=samdb.domain_dn(), scope=ldb.SCOPE_SUBTREE, expression=filter, attrs=["dn"]) group_dn = res[0].dn except IndexError: raise CommandError('Unable to find group "%s"' % (groupname)) try: samdb.delete(group_dn) except Exception as e: # FIXME: catch more specific exception raise CommandError('Failed to remove group "%s"' % groupname, e) self.outf.write("Deleted group %s\n" % groupname)
def run(self, old_ou_dn, new_ou_dn, credopts=None, sambaopts=None, versionopts=None, H=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = ldb.Dn(samdb, samdb.domain_dn()) try: full_old_ou_dn = samdb.normalize_dn_in_domain(old_ou_dn) except Exception as e: raise CommandError('Invalid old_ou_dn "%s": %s' % (old_ou_dn, e)) try: full_new_ou_dn = samdb.normalize_dn_in_domain(new_ou_dn) except Exception as e: raise CommandError('Invalid new_ou_dn "%s": %s' % (new_ou_dn, e)) try: res = samdb.search(base=full_old_ou_dn, expression="(objectclass=organizationalUnit)", scope=ldb.SCOPE_BASE, attrs=[]) if len(res) == 0: self.outf.write('Unable to find ou "%s"\n' % old_ou_dn) return samdb.rename(full_old_ou_dn, full_new_ou_dn) except Exception as e: raise CommandError('Failed to rename ou "%s"' % full_old_ou_dn, e) self.outf.write('Renamed ou "%s" to "%s"\n' % (full_old_ou_dn, full_new_ou_dn))
def run(self, groupname, credopts=None, sambaopts=None, versionopts=None, H=None, group_attrs=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) attrs = None if group_attrs: attrs = group_attrs.split(",") filter = ("(&(sAMAccountType=%d)(sAMAccountName=%s))" % (ATYPE_SECURITY_GLOBAL_GROUP, ldb.binary_encode(groupname))) domaindn = samdb.domain_dn() try: res = samdb.search(base=domaindn, expression=filter, scope=ldb.SCOPE_SUBTREE, attrs=attrs) user_dn = res[0].dn except IndexError: raise CommandError('Unable to find group "%s"' % (groupname)) for msg in res: user_ldif = samdb.write_ldif(msg, ldb.CHANGETYPE_NONE) self.outf.write(user_ldif)
def run(self, groupname, new_parent_dn, credopts=None, sambaopts=None, versionopts=None, H=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = ldb.Dn(samdb, samdb.domain_dn()) filter = ("(&(sAMAccountName=%s)(objectClass=group))" % groupname) try: res = samdb.search(base=domain_dn, expression=filter, scope=ldb.SCOPE_SUBTREE) group_dn = res[0].dn except IndexError: raise CommandError('Unable to find group "%s"' % (groupname)) try: full_new_parent_dn = samdb.normalize_dn_in_domain(new_parent_dn) except Exception as e: raise CommandError('Invalid new_parent_dn "%s": %s' % (new_parent_dn, e.message)) full_new_group_dn = ldb.Dn(samdb, str(group_dn)) full_new_group_dn.remove_base_components(len(group_dn) - 1) full_new_group_dn.add_base(full_new_parent_dn) try: samdb.rename(group_dn, full_new_group_dn) except Exception as e: raise CommandError('Failed to move group "%s"' % groupname, e) self.outf.write('Moved group "%s" into "%s"\n' % (groupname, full_new_parent_dn))
def run(self, groupname, gidnumber, credopts=None, sambaopts=None, versionopts=None, H=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domaindn = samdb.domain_dn() # Check group exists and doesn't have a gidNumber filter = "(samaccountname={})".format(ldb.binary_encode(groupname)) res = samdb.search(domaindn, scope=ldb.SCOPE_SUBTREE, expression=filter) if (len(res) == 0): raise CommandError("Unable to find group '{}'".format(groupname)) group_dn = res[0].dn if "gidNumber" in res[0]: raise CommandError("Group {} is a Unix group.".format(groupname)) # Check if supplied gidnumber isn't already being used filter = "(&(objectClass=group)(gidNumber={}))".format(gidnumber) res = samdb.search(domaindn, scope=ldb.SCOPE_SUBTREE, expression=filter) if (len(res) != 0): raise CommandError('gidNumber {} already used.'.format(gidnumber)) if not lp.get("idmap_ldb:use rfc2307"): self.outf.write("You are setting a Unix/RFC2307 GID. " "You may want to set 'idmap_ldb:use rfc2307 = Yes'" " in smb.conf to use the attributes for " "XID/SID-mapping.\n") group_mod = """ dn: {0} changetype: modify add: gidNumber gidNumber: {1} """.format(group_dn, gidnumber) try: samdb.modify_ldif(group_mod) except ldb.LdbError as e: raise CommandError("Failed to modify group '{0}': {1}".format( groupname, e)) self.outf.write("Modified Group '{}' successfully\n".format(groupname))
def run(self, sambaopts=None, credopts=None, versionopts=None, H=None, verbose=False, base_dn=None, full_dn=False): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) attrs=["samaccountname"] if verbose: attrs += ["grouptype", "member"] domain_dn = samdb.domain_dn() if base_dn: domain_dn = samdb.normalize_dn_in_domain(base_dn) res = samdb.search(domain_dn, scope=ldb.SCOPE_SUBTREE, expression=("(objectClass=group)"), attrs=attrs) if (len(res) == 0): return if verbose: self.outf.write("Group Name Group Type Group Scope Members\n") self.outf.write("--------------------------------------------------------------------------------\n") for msg in res: self.outf.write("%-44s" % msg.get("samaccountname", idx=0)) hgtype = hex(int("%s" % msg["grouptype"]) & 0x00000000FFFFFFFF) if (hgtype == hex(int(security_group.get("Builtin")))): self.outf.write("Security Builtin ") elif (hgtype == hex(int(security_group.get("Domain")))): self.outf.write("Security Domain ") elif (hgtype == hex(int(security_group.get("Global")))): self.outf.write("Security Global ") elif (hgtype == hex(int(security_group.get("Universal")))): self.outf.write("Security Universal") elif (hgtype == hex(int(distribution_group.get("Global")))): self.outf.write("Distribution Global ") elif (hgtype == hex(int(distribution_group.get("Domain")))): self.outf.write("Distribution Domain ") elif (hgtype == hex(int(distribution_group.get("Universal")))): self.outf.write("Distribution Universal") else: self.outf.write(" ") num_members = len(msg.get("member", default=[])) self.outf.write(" %6u\n" % num_members) else: for msg in res: if full_dn: self.outf.write("%s\n" % msg.get("dn")) continue self.outf.write("%s\n" % msg.get("samaccountname", idx=0))
class ManyLDAPTest(samba.tests.TestCase): def setUp(self): super(ManyLDAPTest, self).setUp() self.ldb = SamDB(url, credentials=creds, session_info=system_session(lp), lp=lp) self.base_dn = self.ldb.domain_dn() self.OU_NAME_MANY = "many_ou" + format(random.randint(0, 99999), "05") self.ou_dn = ldb.Dn( self.ldb, "ou=" + self.OU_NAME_MANY + "," + str(self.base_dn)) samba.tests.delete_force(self.ldb, self.ou_dn, controls=['tree_delete:1']) self.ldb.add({ "dn": self.ou_dn, "objectclass": "organizationalUnit", "ou": self.OU_NAME_MANY }) for x in range(2000): ou_name = self.OU_NAME_MANY + str(x) self.ldb.add({ "dn": "ou=" + ou_name + "," + str(self.ou_dn), "objectclass": "organizationalUnit", "ou": ou_name }) def tearDown(self): samba.tests.delete_force(self.ldb, self.ou_dn, controls=['tree_delete:1']) def test_unindexed_iterator_search(self): """Testing a search for all the OUs. Needed to test that more that IOV_MAX responses can be returned """ if not url.startswith("ldap"): self.fail(msg="This test is only valid on ldap") count = 0 msg1 = None search1 = self.ldb.search_iterator( base=self.ou_dn, expression="(ou=" + self.OU_NAME_MANY + "*)", scope=ldb.SCOPE_SUBTREE, attrs=["objectGUID", "samAccountName"]) for reply in search1: self.assertIsInstance(reply, ldb.Message) count += 1 res1 = search1.result() # Check we got everything self.assertEqual(count, 2001)
def run(self, groupname, credopts=None, sambaopts=None, versionopts=None, H=None, editor=None): from . import common lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) filter = ("(&(sAMAccountName=%s)(objectClass=group))" % groupname) domaindn = samdb.domain_dn() try: res = samdb.search(base=domaindn, expression=filter, scope=ldb.SCOPE_SUBTREE) group_dn = res[0].dn except IndexError: raise CommandError('Unable to find group "%s"' % (groupname)) if len(res) != 1: raise CommandError('Invalid number of results: for "%s": %d' % ((groupname), len(res))) msg = res[0] result_ldif = common.get_ldif_for_editor(samdb, msg) if editor is None: editor = os.environ.get('EDITOR') if editor is None: editor = 'vi' with tempfile.NamedTemporaryFile(suffix=".tmp") as t_file: t_file.write(get_bytes(result_ldif)) t_file.flush() try: check_call([editor, t_file.name]) except CalledProcessError as e: raise CalledProcessError("ERROR: ", e) with open(t_file.name) as edited_file: edited_message = edited_file.read() msgs_edited = samdb.parse_ldif(edited_message) msg_edited = next(msgs_edited)[1] res_msg_diff = samdb.msg_diff(msg, msg_edited) if len(res_msg_diff) == 0: self.outf.write("Nothing to do\n") return try: samdb.modify(res_msg_diff) except Exception as e: raise CommandError("Failed to modify group '%s': " % groupname, e) self.outf.write("Modified group '%s' successfully\n" % groupname)
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))
def conectar(self): lp = param.LoadParm() badge = Credentials() badge.guess(lp) badge.set_username(self.username) badge.set_password(self.password) cx = SamDB(url='ldap://localhost', lp=lp, credentials=badge) self.domain = cx.domain_dn() return cx
class SitesBaseTests(samba.tests.TestCase): def setUp(self): super(SitesBaseTests, self).setUp() self.ldb = SamDB(ldaphost, credentials=creds, session_info=system_session(lp), lp=lp) self.base_dn = self.ldb.domain_dn() self.domain_sid = security.dom_sid(self.ldb.get_domain_sid()) self.configuration_dn = self.ldb.get_config_basedn().get_linearized() def get_user_dn(self, name): return "CN=%s,CN=Users,%s" % (name, self.base_dn)
def run(self, ou_dn, credopts=None, sambaopts=None, versionopts=None, H=None, force_subtree_delete=False): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = ldb.Dn(samdb, samdb.domain_dn()) try: full_ou_dn = samdb.normalize_dn_in_domain(ou_dn) except Exception, e: raise CommandError('Invalid ou_dn "%s": %s' % (ou_dn, e.message))
def run(self, computername, credopts=None, sambaopts=None, versionopts=None, H=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) samaccountname = computername if not computername.endswith('$'): samaccountname = "%s$" % computername filter = ( "(&(sAMAccountName=%s)(sAMAccountType=%u))" % (ldb.binary_encode(samaccountname), dsdb.ATYPE_WORKSTATION_TRUST)) try: res = samdb.search(base=samdb.domain_dn(), scope=ldb.SCOPE_SUBTREE, expression=filter, attrs=["userAccountControl", "dNSHostName"]) computer_dn = res[0].dn computer_ac = int(res[0]["userAccountControl"][0]) if "dNSHostName" in res[0]: computer_dns_host_name = res[0]["dNSHostName"][0] else: computer_dns_host_name = None except IndexError: raise CommandError('Unable to find computer "%s"' % computername) computer_is_workstation = (computer_ac & dsdb.UF_WORKSTATION_TRUST_ACCOUNT) if not computer_is_workstation: raise CommandError( 'Failed to remove computer "%s": ' 'Computer is not a workstation - removal denied' % computername) try: samdb.delete(computer_dn) if computer_dns_host_name: remove_dns_references(samdb, self.get_logger(), computer_dns_host_name, ignore_no_name=True) except Exception as e: raise CommandError( 'Failed to remove computer "%s"' % samaccountname, e) self.outf.write("Deleted computer %s\n" % computername)
def run(self, contactname, sambaopts=None, credopts=None, versionopts=None, H=None, contact_attrs=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) base_dn = samdb.domain_dn() scope = ldb.SCOPE_SUBTREE attrs = None if contact_attrs: attrs = contact_attrs.split(",") filter = ("(&(objectClass=contact)(name=%s))" % ldb.binary_encode(contactname)) if contactname.upper().startswith("CN="): # contact is specified by DN filter = "(objectClass=contact)" scope = ldb.SCOPE_BASE try: base_dn = samdb.normalize_dn_in_domain(contactname) except Exception as e: raise CommandError('Invalid dn "%s": %s' % (contactname, e)) try: res = samdb.search(base=base_dn, expression=filter, scope=scope, attrs=attrs) contact_dn = res[0].dn except IndexError: raise CommandError('Unable to find contact "%s"' % (contactname)) if len(res) > 1: for msg in sorted(res, key=attrgetter('dn')): self.outf.write("found: %s\n" % msg.dn) raise CommandError("Multiple results for contact '%s'\n" "Please specify the contact's DN" % contactname) for msg in res: contact_ldif = common.get_ldif_for_editor(samdb, msg) self.outf.write(contact_ldif)
class SitesBaseTests(samba.tests.TestCase): def setUp(self): super(SitesBaseTests, self).setUp() self.ldb = SamDB(ldaphost, credentials=creds, session_info=system_session(lp), lp=lp) self.base_dn = self.ldb.domain_dn() self.domain_sid = security.dom_sid(self.ldb.get_domain_sid()) self.configuration_dn = self.ldb.get_config_basedn().get_linearized() def get_user_dn(self, name): return "CN={0!s},CN=Users,{1!s}".format(name, self.base_dn)
def run(self, sambaopts=None, credopts=None, versionopts=None, H=None, verbose=False): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = samdb.domain_dn() res = samdb.search(domain_dn, scope=ldb.SCOPE_SUBTREE, expression=("(objectClass=group)"), attrs=["samaccountname", "grouptype"]) if (len(res) == 0): return if verbose: self.outf.write( "Group Name Group Type Group Scope\n" ) self.outf.write( "-----------------------------------------------------------------------------\n" ) for msg in res: self.outf.write("%-44s" % msg.get("samaccountname", idx=0)) hgtype = hex(int("%s" % msg["grouptype"]) & 0x00000000FFFFFFFF) if (hgtype == hex(int(security_group.get("Builtin")))): self.outf.write("Security Builtin\n") elif (hgtype == hex(int(security_group.get("Domain")))): self.outf.write("Security Domain\n") elif (hgtype == hex(int(security_group.get("Global")))): self.outf.write("Security Global\n") elif (hgtype == hex(int(security_group.get("Universal")))): self.outf.write("Security Universal\n") elif (hgtype == hex(int(distribution_group.get("Global")))): self.outf.write("Distribution Global\n") elif (hgtype == hex(int(distribution_group.get("Domain")))): self.outf.write("Distribution Domain\n") elif (hgtype == hex(int(distribution_group.get("Universal")))): self.outf.write("Distribution Universal\n") else: self.outf.write("\n") else: for msg in res: self.outf.write("%s\n" % msg.get("samaccountname", idx=0))
def run(self, use_ntvfs=False, use_s3fs=False, credopts=None, sambaopts=None, versionopts=None): lp = sambaopts.get_loadparm() path = lp.private_path("secrets.ldb") creds = credopts.get_credentials(lp) creds.set_kerberos_state(DONT_USE_KERBEROS) logger = self.get_logger() netlogon = lp.get("path", "netlogon") sysvol = lp.get("path", "sysvol") try: samdb = SamDB(session_info=system_session(), lp=lp) except Exception as e: raise CommandError("Unable to open samdb:", e) if not use_ntvfs and not use_s3fs: use_ntvfs = "smb" in lp.get("server services") elif use_s3fs: use_ntvfs = False domain_sid = security.dom_sid(samdb.domain_sid) s3conf = s3param.get_context() s3conf.load(lp.configfile) # ensure we are using the right samba_dsdb passdb backend, no matter what s3conf.set("passdb backend", "samba_dsdb:%s" % samdb.url) LA_sid = security.dom_sid(str(domain_sid) +"-"+str(security.DOMAIN_RID_ADMINISTRATOR)) BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) s4_passdb = passdb.PDB(s3conf.get("passdb backend")) # These assertions correct for current ad_dc selftest # configuration. When other environments have a broad range of # groups mapped via passdb, we can relax some of these checks (LA_uid,LA_type) = s4_passdb.sid_to_id(LA_sid) if (LA_type != idmap.ID_TYPE_UID and LA_type != idmap.ID_TYPE_BOTH): raise CommandError("SID %s is not mapped to a UID" % LA_sid) (BA_gid,BA_type) = s4_passdb.sid_to_id(BA_sid) if (BA_type != idmap.ID_TYPE_GID and BA_type != idmap.ID_TYPE_BOTH): raise CommandError("SID %s is not mapped to a GID" % BA_sid) if use_ntvfs: logger.warning("Please note that POSIX permissions have NOT been changed, only the stored NT ACL") provision.setsysvolacl(samdb, netlogon, sysvol, LA_uid, BA_gid, domain_sid, lp.get("realm").lower(), samdb.domain_dn(), lp, use_ntvfs=use_ntvfs)
def run(self, groupname, credopts=None, sambaopts=None, versionopts=None, H=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) try: samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) search_filter = "(&(objectClass=group)(samaccountname=%s))" % groupname res = samdb.search(samdb.domain_dn(), scope=ldb.SCOPE_SUBTREE, expression=(search_filter), attrs=["objectSid"]) if (len(res) != 1): return group_dn = res[0].get('dn', idx=0) object_sid = res[0].get('objectSid', idx=0) object_sid = ndr_unpack(security.dom_sid, object_sid) (group_dom_sid, rid) = object_sid.split() search_filter = "(|(primaryGroupID=%s)(memberOf=%s))" % (rid, group_dn) res = samdb.search(samdb.domain_dn(), scope=ldb.SCOPE_SUBTREE, expression=(search_filter), attrs=["samAccountName", "cn"]) if (len(res) == 0): return for msg in res: member_name = msg.get("samAccountName", idx=0) if member_name is None: member_name = msg.get("cn", idx=0) self.outf.write("%s\n" % member_name) except Exception as e: raise CommandError('Failed to list members of "%s" group ' % groupname, e)
def run(self, sambaopts=None, credopts=None, versionopts=None, H=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = samdb.domain_dn() res = samdb.search(domain_dn, scope=ldb.SCOPE_SUBTREE, expression=("(&(objectClass=user)(userAccountControl:{0!s}:={1:d}))".format(ldb.OID_COMPARATOR_AND, dsdb.UF_NORMAL_ACCOUNT)), attrs=["samaccountname"]) if (len(res) == 0): return for msg in res: self.outf.write("{0!s}\n".format(msg.get("samaccountname", idx=0)))
def run(self, sambaopts=None, credopts=None, versionopts=None, H=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = samdb.domain_dn() res = samdb.search(domain_dn, scope=ldb.SCOPE_SUBTREE, expression=("(objectClass=group)"), attrs=["samaccountname"]) if (len(res) == 0): return for msg in res: self.outf.write("%s\n" % msg.get("samaccountname", idx=0))
class LATests(samba.tests.TestCase): def setUp(self): super(LATests, self).setUp() self.samdb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp) self.base_dn = self.samdb.domain_dn() self.ou = "OU=la,%s" % self.base_dn if opts.delete_in_setup: try: self.samdb.delete(self.ou, ['tree_delete:1']) except ldb.LdbError, e: print "tried deleting %s, got error %s" % (self.ou, e) self.samdb.add({'objectclass': 'organizationalUnit', 'dn': self.ou})
class EncryptedSecretsTests(TestCase): def setUp(self): super(EncryptedSecretsTests, self).setUp() self.lp = samba.tests.env_loadparm() self.creds = Credentials() self.session = system_session() self.creds.guess(self.lp) self.session = system_session() self.ldb = SamDB(session_info=self.session, credentials=self.creds, lp=self.lp) def test_encrypted_secrets(self): """Test that secret attributes are stored encrypted on disk""" basedn = self.ldb.domain_dn() backend_filename = "%s.ldb" % basedn.upper() backend_subpath = os.path.join("sam.ldb.d", backend_filename) backend_path = self.lp.private_path(backend_subpath) backenddb = ldb.Ldb("ldb://" + backend_path, flags=ldb.FLG_DONT_CREATE_DB) dn = "CN=Administrator,CN=Users,%s" % basedn res = backenddb.search(scope=ldb.SCOPE_BASE, base=dn, attrs=["unicodePwd"]) self.assertIs(True, len(res) > 0) obj = res[0] blob = obj["unicodePwd"][0] self.assertTrue(len(blob) > 30) # Now verify that the header contains the correct magic value. encrypted = ndr_unpack(drsblobs.EncryptedSecret, blob) magic = 0xca5caded self.assertEquals(magic, encrypted.header.magic) def test_required_features(self): """Test that databases are provisioned with encryptedSecrets as a required feature """ res = self.ldb.search(scope=ldb.SCOPE_BASE, base="@SAMBA_DSDB", attrs=["requiredFeatures"]) self.assertTrue(len(res) > 0) self.assertTrue("requiredFeatures" in res[0]) required_features = res[0]["requiredFeatures"] self.assertTrue("encryptedSecrets" in required_features)
def run(self, computername, credopts=None, sambaopts=None, versionopts=None, H=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) samaccountname = computername if not computername.endswith('$'): samaccountname = "%s$" % computername filter = ("(&(sAMAccountName=%s)(sAMAccountType=%u))" % (ldb.binary_encode(samaccountname), dsdb.ATYPE_WORKSTATION_TRUST)) try: res = samdb.search(base=samdb.domain_dn(), scope=ldb.SCOPE_SUBTREE, expression=filter, attrs=["userAccountControl", "dNSHostName"]) computer_dn = res[0].dn computer_ac = int(res[0]["userAccountControl"][0]) if "dNSHostName" in res[0]: computer_dns_host_name = res[0]["dNSHostName"][0] else: computer_dns_host_name = None except IndexError: raise CommandError('Unable to find computer "%s"' % computername) computer_is_workstation = ( computer_ac & dsdb.UF_WORKSTATION_TRUST_ACCOUNT) if computer_is_workstation == False: raise CommandError('Failed to remove computer "%s": ' 'Computer is not a workstation - removal denied' % computername) try: samdb.delete(computer_dn) if computer_dns_host_name: remove_dns_references( samdb, self.get_logger(), computer_dns_host_name, ignore_no_name=True) except Exception as e: raise CommandError('Failed to remove computer "%s"' % samaccountname, e) self.outf.write("Deleted computer %s\n" % computername)
def run(self, value, H=None, credopts=None, sambaopts=None, versionopts=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = samdb.domain_dn() object_dn = "%s,%s" % (self.objectdn, domain_dn) # Create the modification m = ldb.Message() m.dn = ldb.Dn(samdb, object_dn) m[self.attribute] = ldb.MessageElement( value, ldb.FLAG_MOD_REPLACE, self.attribute) samdb.modify(m) self.outf.write("set %s: %s\n" % (self.attribute, value))
def run(self, sambaopts=None, credopts=None, versionopts=None, H=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) filter = "(sAMAccountType=%u)" % (dsdb.ATYPE_WORKSTATION_TRUST) domain_dn = samdb.domain_dn() res = samdb.search(domain_dn, scope=ldb.SCOPE_SUBTREE, expression=filter, attrs=["samaccountname"]) if (len(res) == 0): return for msg in res: self.outf.write("%s\n" % msg.get("samaccountname", idx=0))
def run(self, H=None, credopts=None, sambaopts=None, versionopts=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = samdb.domain_dn() self.infrastructure_dn = "CN=Infrastructure," + domain_dn self.naming_dn = "CN=Partitions,%s" % samdb.get_config_basedn() self.schema_dn = samdb.get_schema_basedn() self.rid_dn = "CN=RID Manager$,CN=System," + domain_dn res = samdb.search(self.infrastructure_dn, scope=ldb.SCOPE_BASE, attrs=["fSMORoleOwner"]) assert len(res) == 1 self.infrastructureMaster = res[0]["fSMORoleOwner"][0] res = samdb.search(domain_dn, scope=ldb.SCOPE_BASE, attrs=["fSMORoleOwner"]) assert len(res) == 1 self.pdcEmulator = res[0]["fSMORoleOwner"][0] res = samdb.search(self.naming_dn, scope=ldb.SCOPE_BASE, attrs=["fSMORoleOwner"]) assert len(res) == 1 self.namingMaster = res[0]["fSMORoleOwner"][0] res = samdb.search(self.schema_dn, scope=ldb.SCOPE_BASE, attrs=["fSMORoleOwner"]) assert len(res) == 1 self.schemaMaster = res[0]["fSMORoleOwner"][0] res = samdb.search(self.rid_dn, scope=ldb.SCOPE_BASE, attrs=["fSMORoleOwner"]) assert len(res) == 1 self.ridMaster = res[0]["fSMORoleOwner"][0] self.message("InfrastructureMasterRole owner: " + self.infrastructureMaster) self.message("RidAllocationMasterRole owner: " + self.ridMaster) self.message("PdcEmulationMasterRole owner: " + self.pdcEmulator) self.message("DomainNamingMasterRole owner: " + self.namingMaster) self.message("SchemaMasterRole owner: " + self.schemaMaster)
def run(self, sambaopts=None, credopts=None, versionopts=None, H=None, verbose=False): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = samdb.domain_dn() res = samdb.search( domain_dn, scope=ldb.SCOPE_SUBTREE, expression=("(objectClass=group)"), attrs=["samaccountname", "grouptype"], ) if len(res) == 0: return if verbose: self.outf.write("Group Name Group Type Group Scope\n") self.outf.write("-----------------------------------------------------------------------------\n") for msg in res: self.outf.write("%-44s" % msg.get("samaccountname", idx=0)) hgtype = hex(int("%s" % msg["grouptype"]) & 0x00000000FFFFFFFF) if hgtype == hex(int(security_group.get("Builtin"))): self.outf.write("Security Builtin\n") elif hgtype == hex(int(security_group.get("Domain"))): self.outf.write("Security Domain\n") elif hgtype == hex(int(security_group.get("Global"))): self.outf.write("Security Global\n") elif hgtype == hex(int(security_group.get("Universal"))): self.outf.write("Security Universal\n") elif hgtype == hex(int(distribution_group.get("Global"))): self.outf.write("Distribution Global\n") elif hgtype == hex(int(distribution_group.get("Domain"))): self.outf.write("Distribution Domain\n") elif hgtype == hex(int(distribution_group.get("Universal"))): self.outf.write("Distribution Universal\n") else: self.outf.write("\n") else: for msg in res: self.outf.write("%s\n" % msg.get("samaccountname", idx=0))
def run(self, credopts=None, sambaopts=None, versionopts=None): lp = sambaopts.get_loadparm() path = lp.private_path("secrets.ldb") creds = credopts.get_credentials(lp) creds.set_kerberos_state(DONT_USE_KERBEROS) logger = self.get_logger() netlogon = lp.get("path", "netlogon") sysvol = lp.get("path", "sysvol") try: samdb = SamDB(session_info=system_session(), lp=lp) except Exception as e: raise CommandError("Unable to open samdb:", e) domain_sid = security.dom_sid(samdb.domain_sid) provision.checksysvolacl(samdb, netlogon, sysvol, domain_sid, lp.get("realm").lower(), samdb.domain_dn(), lp)
def run(self, psoname, user_or_group, H=None, credopts=None, sambaopts=None, versionopts=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) pso_dn = "CN=%s,%s" % (psoname, pso_container(samdb)) # sanity-check the PSO exists check_pso_valid(samdb, pso_dn, psoname) # lookup the user/group by account-name to gets its DN search_filter = "(sAMAccountName=%s)" % user_or_group res = samdb.search(samdb.domain_dn(), scope=ldb.SCOPE_SUBTREE, expression=search_filter) if len(res) == 0: raise CommandError("The specified user or group '%s' was not found" % user_or_group) # modify the PSO to apply to the user/group specified target_dn = str(res[0].dn) m = ldb.Message() m.dn = ldb.Dn(samdb, pso_dn) m["msDS-PSOAppliesTo"] = ldb.MessageElement(target_dn, ldb.FLAG_MOD_ADD, "msDS-PSOAppliesTo") try: samdb.modify(m) except ldb.LdbError as e: (num, msg) = e.args # most likely error - PSO already applies to that user/group if num == ldb.ERR_ATTRIBUTE_OR_VALUE_EXISTS: raise CommandError("PSO '%s' already applies to '%s'" % (psoname, user_or_group)) else: raise CommandError("Failed to update PSO '%s': %s" %(psoname, msg)) self.message("PSO '%s' applied to '%s'" %(psoname, user_or_group))
def _load_samba_environment(): """Load the samba configuration vars from smb.conf and the sam.db. """ params = samba.param.LoadParm() params.load_default() netbiosname = params.get("netbios name") hostname = netbiosname.lower() dnsdomain = params.get("realm") dnsdomain = dnsdomain.lower() samdb_ldb = SamDB(url=params.samdb_url(), lp=params) domaindn = samdb_ldb.domain_dn() rootdn = domaindn configdn = "CN=Configuration," + rootdn firstorg = FIRST_ORGANIZATION firstou = FIRST_ORGANIZATION_UNIT sam_environ = {"samdb_ldb": samdb_ldb, "private_dir": params.get("private dir"), "domaindn": domaindn, "oc_user_basedn": "CN=%s,CN=%s,CN=%s,%s" \ % (firstou, firstorg, netbiosname, domaindn), "firstorgdn": ("CN=%s,CN=Microsoft Exchange,CN=Services,%s" % (firstorg, configdn)), "legacyserverdn": ("/o=%s/ou=%s/cn=Configuration/cn=Servers" "/cn=%s" % (firstorg, firstou, netbiosname)), "hostname": hostname, "dnsdomain": dnsdomain} # OpenChange dispatcher DB names return sam_environ