def get_machine_sec_channel_type(self, host): return fetch_uint32( self.db, get_bytes("SECRETS/MACHINE_SEC_CHANNEL_TYPE/%s" % host))
def get_machine_password(self, host): return self.db.get(get_bytes("SECRETS/MACHINE_PASSWORD/%s" % host))
def get_ldap_bind_pw(self, host): return self.db.get(get_bytes("SECRETS/LDAP_BIND_PW/%s" % host))
def get_afs_keyfile(self, host): return self.db.get(get_bytes("SECRETS/AFS_KEYFILE/%s" % host))
def run(self, contactname, sambaopts=None, credopts=None, versionopts=None, H=None, editor=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 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, scope=scope, expression=filter) 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 full DN" % contactname) for msg in res: 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 contact '%s': " % contactname, e) self.outf.write("Modified contact '%s' successfully\n" % contactname)
def run(self, computername, credopts=None, sambaopts=None, versionopts=None, H=None, editor=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 = ( "(&(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) computer_dn = res[0].dn except IndexError: raise CommandError('Unable to find computer "%s"' % (computername)) if len(res) != 1: raise CommandError('Invalid number of results: for "%s": %d' % ((computername), 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 computer '%s': " % computername, e) self.outf.write("Modified computer '%s' successfully\n" % computername)
def delete(self, key): self.log.delete(get_bytes(key))
def generalize_xml(self, root, out_file, global_entities): entities = [] # Locate all user_id and all ACLs user_ids = root.findall('.//*[@user_id="TRUE"]') user_ids.sort(key=lambda x: x.tag) for elem in user_ids: old_text = elem.text if old_text is None or old_text == '': continue if old_text in global_entities: elem.text = global_entities[old_text] entities.append((elem.text, old_text)) else: elem.text = self.new_xml_entity(old_text, ENTITY_USER_ID) entities.append((elem.text, old_text)) global_entities.update([(old_text, elem.text)]) acls = root.findall('.//*[@acl="TRUE"]') acls.sort(key=lambda x: x.tag) for elem in acls: old_text = elem.text if old_text is None or old_text == '': continue if old_text in global_entities: elem.text = global_entities[old_text] entities.append((elem.text, old_text)) else: elem.text = self.new_xml_entity(old_text, ENTITY_SDDL_ACL) entities.append((elem.text, old_text)) global_entities.update([(old_text, elem.text)]) share_paths = root.findall('.//*[@network_path="TRUE"]') share_paths.sort(key=lambda x: x.tag) for elem in share_paths: old_text = elem.text if old_text is None or old_text == '': continue stripped = old_text.lstrip('\\') file_server = stripped.split('\\')[0] server_index = old_text.find(file_server) remaining = old_text[server_index + len(file_server):] old_text = old_text[:server_index] + file_server if old_text in global_entities: elem.text = global_entities[old_text] + remaining to_put = global_entities[old_text] entities.append((to_put, old_text)) else: to_put = self.new_xml_entity(old_text, ENTITY_NETWORK_PATH) elem.text = to_put + remaining entities.append((to_put, old_text)) global_entities.update([(old_text, to_put)]) # Call any file specific customization of entities # (which appear in any subclasses). entities.extend(self.custom_entities(root, global_entities)) output_xml = tostring(root) for ent in entities: entb = get_bytes(ent[0]) output_xml = output_xml.replace(entb.replace(b'&', b'&'), entb) with open(out_file, 'wb') as f: f.write(output_xml) return entities
def store(self, key, val): self.log.store(get_bytes(key), get_bytes(val))
def get_gplog(self, user): return gp_log(user, self, self.log.get(get_bytes(user)))
def get(self, key): return self.log.get(get_bytes(key))
def get_int(self, key): try: return int(self.log.get(get_bytes(key))) except TypeError: return None
def test_setpassword(self): for user in self.users: newpasswd = self.random_password(16) (result, out, err) = self.runsubcmd( "user", "setpassword", user["name"], "--newpassword=%s" % newpasswd, "-H", "ldap://%s" % os.environ["DC_SERVER"], "-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"])) self.assertCmdSuccess(result, out, err, "Ensure setpassword runs") self.assertEqual(err, "", "setpassword with url") self.assertMatch(out, "Changed password OK", "setpassword with url") attributes = "sAMAccountName,unicodePwd,supplementalCredentials,virtualClearTextUTF8,virtualClearTextUTF16,virtualSSHA,virtualSambaGPG" (result, out, err) = self.runsubcmd("user", "syncpasswords", "--cache-ldb-initialize", "--attributes=%s" % attributes, "--decrypt-samba-gpg") self.assertCmdSuccess( result, out, err, "Ensure syncpasswords --cache-ldb-initialize runs") self.assertEqual(err, "", "getpassword without url") cache_attrs = { "objectClass": { "value": "userSyncPasswords" }, "samdbUrl": {}, "dirsyncFilter": {}, "dirsyncAttribute": {}, "dirsyncControl": { "value": "dirsync:1:0:0" }, "passwordAttribute": {}, "decryptSambaGPG": {}, "currentTime": {}, } for a in cache_attrs.keys(): v = cache_attrs[a].get("value", "") self.assertMatch( out, "%s: %s" % (a, v), "syncpasswords --cache-ldb-initialize: %s: %s out[%s]" % (a, v, out)) (result, out, err) = self.runsubcmd("user", "syncpasswords", "--no-wait") self.assertCmdSuccess(result, out, err, "Ensure syncpasswords --no-wait runs") self.assertEqual(err, "", "syncpasswords --no-wait") self.assertMatch( out, "dirsync_loop(): results 0", "syncpasswords --no-wait: 'dirsync_loop(): results 0': out[%s]" % (out)) for user in self.users: self.assertMatch( out, "sAMAccountName: %s" % (user["name"]), "syncpasswords --no-wait: 'sAMAccountName': %s out[%s]" % (user["name"], out)) for user in self.users: newpasswd = self.random_password(16) creds = credentials.Credentials() creds.set_anonymous() creds.set_password(newpasswd) nthash = creds.get_nt_hash() unicodePwd = base64.b64encode(creds.get_nt_hash()).decode('utf8') virtualClearTextUTF8 = base64.b64encode( get_bytes(newpasswd)).decode('utf8') virtualClearTextUTF16 = base64.b64encode( get_string(newpasswd).encode('utf-16-le')).decode('utf8') (result, out, err) = self.runsubcmd("user", "setpassword", user["name"], "--newpassword=%s" % newpasswd) self.assertCmdSuccess(result, out, err, "Ensure setpassword runs") self.assertEqual(err, "", "setpassword without url") self.assertMatch(out, "Changed password OK", "setpassword without url") (result, out, err) = self.runsubcmd("user", "syncpasswords", "--no-wait") self.assertCmdSuccess(result, out, err, "Ensure syncpasswords --no-wait runs") self.assertEqual(err, "", "syncpasswords --no-wait") self.assertMatch( out, "dirsync_loop(): results 0", "syncpasswords --no-wait: 'dirsync_loop(): results 0': out[%s]" % (out)) self.assertMatch( out, "sAMAccountName: %s" % (user["name"]), "syncpasswords --no-wait: 'sAMAccountName': %s out[%s]" % (user["name"], out)) self.assertMatch( out, "# unicodePwd::: REDACTED SECRET ATTRIBUTE", "getpassword '# unicodePwd::: REDACTED SECRET ATTRIBUTE': out[%s]" % out) self.assertMatch(out, "unicodePwd:: %s" % unicodePwd, "getpassword unicodePwd: out[%s]" % out) self.assertMatch( out, "# supplementalCredentials::: REDACTED SECRET ATTRIBUTE", "getpassword '# supplementalCredentials::: REDACTED SECRET ATTRIBUTE': out[%s]" % out) self.assertMatch( out, "supplementalCredentials:: ", "getpassword supplementalCredentials: out[%s]" % out) if "virtualSambaGPG:: " in out: self.assertMatch( out, "virtualClearTextUTF8:: %s" % virtualClearTextUTF8, "getpassword virtualClearTextUTF8: out[%s]" % out) self.assertMatch( out, "virtualClearTextUTF16:: %s" % virtualClearTextUTF16, "getpassword virtualClearTextUTF16: out[%s]" % out) self.assertMatch(out, "virtualSSHA: ", "getpassword virtualSSHA: out[%s]" % out) (result, out, err) = self.runsubcmd("user", "getpassword", user["name"], "--attributes=%s" % attributes, "--decrypt-samba-gpg") self.assertCmdSuccess(result, out, err, "Ensure getpassword runs") self.assertEqual(err, "", "getpassword without url") self.assertMatch(out, "Got password OK", "getpassword without url") self.assertMatch( out, "sAMAccountName: %s" % (user["name"]), "getpassword: '******': %s out[%s]" % (user["name"], out)) self.assertMatch(out, "unicodePwd:: %s" % unicodePwd, "getpassword unicodePwd: out[%s]" % out) self.assertMatch( out, "supplementalCredentials:: ", "getpassword supplementalCredentials: out[%s]" % out) self._verify_supplementalCredentials( out.replace("\nGot password OK\n", "")) if "virtualSambaGPG:: " in out: self.assertMatch( out, "virtualClearTextUTF8:: %s" % virtualClearTextUTF8, "getpassword virtualClearTextUTF8: out[%s]" % out) self.assertMatch( out, "virtualClearTextUTF16:: %s" % virtualClearTextUTF16, "getpassword virtualClearTextUTF16: out[%s]" % out) self.assertMatch(out, "virtualSSHA: ", "getpassword virtualSSHA: out[%s]" % out) for user in self.users: newpasswd = self.random_password(16) (result, out, err) = self.runsubcmd( "user", "setpassword", user["name"], "--newpassword=%s" % newpasswd, "--must-change-at-next-login", "-H", "ldap://%s" % os.environ["DC_SERVER"], "-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"])) self.assertCmdSuccess(result, out, err, "Ensure setpassword runs") self.assertEqual(err, "", "setpassword with forced change") self.assertMatch(out, "Changed password OK", "setpassword with forced change")