mirror of
https://github.com/samba-team/samba.git
synced 2025-08-02 00:22:11 +03:00
r26088: Import some native-python python modules and move original python swig torture code to common python directory as well.
(This used to be commit cbf656ff05
)
This commit is contained in:
committed by
Stefan Metzmacher
parent
f2b9a9ae11
commit
39adc2418a
57
source4/scripting/python/samba/__init__.py
Normal file
57
source4/scripting/python/samba/__init__.py
Normal file
@ -0,0 +1,57 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# Unix SMB/CIFS implementation.
|
||||
# Copyright (C) Andrew Tridgell <tridge@samba.org> 2005
|
||||
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import os
|
||||
from misc import ldb_set_credentials
|
||||
|
||||
def Ldb(url, session_info=None, credentials=None, modules_dir=None):
|
||||
"""Open a Samba Ldb file.
|
||||
|
||||
This is different from a regular Ldb file in that the Samba-specific
|
||||
modules-dir is used by default and that credentials and session_info
|
||||
can be passed through (required by some modules).
|
||||
"""
|
||||
import ldb
|
||||
ret = ldb.Ldb()
|
||||
if modules_dir is None:
|
||||
modules_dir = os.path.join(os.getcwd(), "bin", "modules", "ldb")
|
||||
ret.set_modules_dir(modules_dir)
|
||||
def samba_debug(level,text):
|
||||
print "%d %s" % (level, text)
|
||||
ldb_set_opaque("credentials", credentials)
|
||||
ret.set_opaque("sessionInfo", session_info)
|
||||
#ret.set_debug(samba_debug)
|
||||
ret.connect(url)
|
||||
return ret
|
||||
|
||||
|
||||
def substitute_var(text, values):
|
||||
"""substitute strings of the form ${NAME} in str, replacing
|
||||
with substitutions from subobj.
|
||||
|
||||
:param text: Text in which to subsitute.
|
||||
:param values: Dictionary with keys and values.
|
||||
"""
|
||||
|
||||
for (name, value) in values.items():
|
||||
text = text.replace("${%s}" % name, value)
|
||||
|
||||
return text
|
||||
|
46
source4/scripting/python/samba/getopt.py
Normal file
46
source4/scripting/python/samba/getopt.py
Normal file
@ -0,0 +1,46 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# Samba-specific bits for optparse
|
||||
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import optparse
|
||||
from credentials import Credentials
|
||||
|
||||
class SambaOptions(optparse.OptionGroup):
|
||||
def __init__(self, parser):
|
||||
optparse.OptionGroup.__init__(self, parser, "Samba Common Options")
|
||||
self.add_option("--configfile", type="string", metavar="FILE",
|
||||
help="Configuration file")
|
||||
|
||||
|
||||
class VersionOptions(optparse.OptionGroup):
|
||||
def __init__(self, parser):
|
||||
optparse.OptionGroup.__init__(self, parser, "Version Options")
|
||||
|
||||
|
||||
class CredentialsOptions(optparse.OptionGroup):
|
||||
def __init__(self, parser):
|
||||
optparse.OptionGroup.__init__(self, parser, "Credentials Options")
|
||||
self.add_option("--simple-bind-dn", type="string", metavar="DN",
|
||||
help="DN to use for a simple bind")
|
||||
self.add_option("--password", type="string", metavar="PASSWORD",
|
||||
help="Password")
|
||||
|
||||
def get_credentials(self):
|
||||
creds = Credentials()
|
||||
# FIXME: Update
|
||||
return creds
|
753
source4/scripting/python/samba/samr.py
Normal file
753
source4/scripting/python/samba/samr.py
Normal file
@ -0,0 +1,753 @@
|
||||
import dcerpc
|
||||
|
||||
def sid_to_string(sid):
|
||||
"""Convert a Python dictionary SID to a string SID."""
|
||||
|
||||
result = 'S-%d' % sid.sid_rev_num
|
||||
|
||||
result = result + '-%u' % \
|
||||
(dcerpc.uint8_array_getitem(sid.id_auth, 5) +
|
||||
(dcerpc.uint8_array_getitem(sid.id_auth, 4) << 8) +
|
||||
(dcerpc.uint8_array_getitem(sid.id_auth, 3) << 16) +
|
||||
(dcerpc.uint8_array_getitem(sid.id_auth, 2) << 24))
|
||||
|
||||
for i in range(0, sid.num_auths):
|
||||
result = result + '-%u' % \
|
||||
dcerpc.uint32_array_getitem(sid.sub_auths, i)
|
||||
|
||||
return result
|
||||
|
||||
def string_to_sid(string):
|
||||
"""Convert a string SID to a Python dictionary SID. Throws a
|
||||
ValueError if the SID string was badly formed."""
|
||||
|
||||
if string[0] != 'S':
|
||||
raise ValueError('Bad SID format')
|
||||
|
||||
string = string[1:]
|
||||
|
||||
import re
|
||||
|
||||
match = re.match('-\d+', string)
|
||||
|
||||
if not match:
|
||||
raise ValueError('Bad SID format')
|
||||
|
||||
try:
|
||||
sid_rev_num = int(string[match.start()+1:match.end()])
|
||||
except ValueError:
|
||||
raise ValueError('Bad SID format')
|
||||
|
||||
string = string[match.end():]
|
||||
|
||||
match = re.match('-\d+', string)
|
||||
|
||||
if not match:
|
||||
raise ValueError('Bad SID format')
|
||||
|
||||
try:
|
||||
ia = int(string[match.start()+1:match.end()])
|
||||
except ValueError:
|
||||
raise ValueError('Bad SID format')
|
||||
|
||||
string = string[match.end():]
|
||||
|
||||
id_auth = [0, 0, (ia >> 24) & 0xff, (ia >> 16) & 0xff,
|
||||
(ia >> 8) & 0xff, ia & 0xff]
|
||||
|
||||
num_auths = 0
|
||||
sub_auths = []
|
||||
|
||||
while len(string):
|
||||
|
||||
match = re.match('-\d+', string)
|
||||
|
||||
if not match:
|
||||
raise ValueError('Bad SID format')
|
||||
|
||||
try:
|
||||
sa = int(string[match.start() + 1 : match.end()])
|
||||
except ValueError:
|
||||
raise ValueError('Bad SID format')
|
||||
|
||||
num_auths = num_auths + 1
|
||||
sub_auths.append(int(sa))
|
||||
|
||||
string = string[match.end():]
|
||||
|
||||
sid = dcerpc.dom_sid()
|
||||
sid.sid_rev_num = sid_rev_num
|
||||
sid.id_auth = dcerpc.new_uint8_array(6)
|
||||
for i in range(6):
|
||||
dcerpc.uint8_array_setitem(sid.id_auth, i, id_auth[i])
|
||||
sid.num_auths = num_auths
|
||||
sid.sub_auths = dcerpc.new_uint32_array(num_auths)
|
||||
for i in range(num_auths):
|
||||
dcerpc.uint32_array_setitem(sid.sub_auths, i, sub_auths[i])
|
||||
|
||||
return sid
|
||||
|
||||
def call_fn(fn, pipe, args):
|
||||
"""Wrap up a RPC call and throw an exception is an error was returned."""
|
||||
|
||||
result = fn(pipe, args);
|
||||
|
||||
if result & 0xc0000000L:
|
||||
raise dcerpc.NTSTATUS(result, dcerpc.nt_errstr(result));
|
||||
|
||||
return result;
|
||||
|
||||
class SamrHandle:
|
||||
|
||||
def __init__(self, pipe, handle):
|
||||
|
||||
self.pipe = pipe
|
||||
self.handle = handle
|
||||
|
||||
def __del__(self):
|
||||
|
||||
if self.handle is not None:
|
||||
self.Close()
|
||||
|
||||
def Close(self):
|
||||
|
||||
r = dcerpc.samr_Close()
|
||||
r.data_in.handle = self.handle
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_Close, self.pipe, r)
|
||||
|
||||
self.handle = None
|
||||
|
||||
def QuerySecurity(self, sec_info = 7):
|
||||
|
||||
r = dcerpc.samr_QuerySecurity()
|
||||
r.data_in.handle = self.handle
|
||||
r.data_in.sec_info = sec_info
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_QuerySecurity, self.pipe, r)
|
||||
|
||||
return r.data_out.sdbuf
|
||||
|
||||
def SetSecurity(self, sdbuf, sec_info = 7):
|
||||
|
||||
r = dcerpc.samr_SetSecurity()
|
||||
r.data_in.handle = self.handle
|
||||
r.data_in.sec_info = sec_info
|
||||
r.data_in.sdbuf = sdbuf
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_SetSecurity, self.pipe, r)
|
||||
|
||||
class ConnectHandle(SamrHandle):
|
||||
|
||||
def EnumDomains(self):
|
||||
|
||||
r = dcerpc.samr_EnumDomains()
|
||||
r.data_in.connect_handle = self.handle
|
||||
r.data_in.resume_handle = 0
|
||||
r.data_in.buf_size = -1
|
||||
|
||||
domains = []
|
||||
|
||||
while 1:
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_EnumDomains, self.pipe, r)
|
||||
|
||||
for i in range(r.data_out.sam.count):
|
||||
domains.append(dcerpc.samr_SamEntry_array_getitem(
|
||||
r.data_out.sam.entries, i).name.string)
|
||||
|
||||
# TODO: Handle more entries here
|
||||
|
||||
break
|
||||
|
||||
return domains
|
||||
|
||||
def LookupDomain(self, domain_name):
|
||||
|
||||
r = dcerpc.samr_LookupDomain()
|
||||
r.data_in.connect_handle = self.handle
|
||||
r.data_in.domain_name = dcerpc.samr_String()
|
||||
r.data_in.domain_name.string = domain_name
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_LookupDomain, self.pipe, r)
|
||||
|
||||
return sid_to_string(r.data_out.sid);
|
||||
|
||||
def OpenDomain(self, domain_sid, access_mask = 0x02000000):
|
||||
|
||||
r = dcerpc.samr_OpenDomain()
|
||||
r.data_in.connect_handle = self.handle
|
||||
r.data_in.access_mask = access_mask
|
||||
r.data_in.sid = string_to_sid(domain_sid)
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_OpenDomain, self.pipe, r)
|
||||
|
||||
return DomainHandle(self.pipe, r.data_out.domain_handle)
|
||||
|
||||
def Shutdown(self):
|
||||
|
||||
r = dcerpc.samr_Shutdown()
|
||||
r.data_in.connect_handle = self.handle
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_Shutdown, self.pipe, r)
|
||||
|
||||
def GetDomPwInfo(self, domain_name):
|
||||
|
||||
r = dcerpc.samr_GetDomPwInfo()
|
||||
r.data_in.domain_name = dcerpc.samr_String()
|
||||
r.data_in.domain_name.string = domain_name
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_GetDomPwInfo, self.pipe, r)
|
||||
|
||||
return r.data_out.info
|
||||
|
||||
|
||||
def SetBootKeyInformation(self, unknown1, unknown2, unknown3):
|
||||
|
||||
r = dcerpc.samr_GetBootKeyInformation()
|
||||
r.data_in.connect_handle = self.handle
|
||||
r.data_in.unknown1 = unknown1
|
||||
r.data_in.unknown2 = unknown2
|
||||
r.data_in.unknown3 = unknown3
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_SetBootKeyInformation, self.pipe, r)
|
||||
|
||||
class DomainHandle(SamrHandle):
|
||||
|
||||
def QueryDomainInfo(self, level = 2):
|
||||
|
||||
r = dcerpc.samr_QueryDomainInfo()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.level = level
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_QueryDomainInfo, self.pipe, r)
|
||||
|
||||
return getattr(r.data_out.info, 'info%d' % level)
|
||||
|
||||
def QueryDomainInfo2(self, level = 2):
|
||||
|
||||
r = dcerpc.samr_QueryDomainInfo2()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.level = level
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_QueryDomainInfo2, self.pipe, r)
|
||||
|
||||
return getattr(r.data_out.info, 'info%d' % level)
|
||||
|
||||
def SetDomainInfo(self, level, info):
|
||||
|
||||
r = dcerpc.samr_SetDomainInfo()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.level = level
|
||||
r.data_in.info = dcerpc.samr_DomainInfo()
|
||||
setattr(r.data_in.info, 'info%d' % level, info)
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_SetDomainInfo, self.pipe, r)
|
||||
|
||||
def EnumDomainGroups(self):
|
||||
|
||||
r = dcerpc.samr_EnumDomainGroups()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.resume_handle = 0
|
||||
r.data_in.max_size = 1000
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_EnumDomainGroups, self.pipe, r)
|
||||
|
||||
groups = []
|
||||
|
||||
if r.data_out.sam.entries:
|
||||
for i in range(r.data_out.sam.count):
|
||||
groups.append(dcerpc.samr_SamEntry_array_getitem(
|
||||
r.data_out.sam.entries, i).name.string)
|
||||
|
||||
return groups
|
||||
|
||||
def EnumDomainAliases(self):
|
||||
|
||||
r = dcerpc.samr_EnumDomainAliases()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.resume_handle = 0
|
||||
# acct_flags in SamrEnumerateAliasesInDomain has probably
|
||||
# no meaning so use 0xffffffff like W2K
|
||||
r.data_in.acct_flags = 0xffffffffL
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_EnumDomainAliases, self.pipe, r)
|
||||
|
||||
aliases = []
|
||||
|
||||
if r.data_out.sam.entries:
|
||||
for i in range(r.data_out.sam.count):
|
||||
aliases.append(dcerpc.samr_SamEntry_array_getitem(
|
||||
r.data_out.sam.entries, i).name.string)
|
||||
|
||||
return aliases
|
||||
|
||||
def EnumDomainUsers(self, user_account_flags = 16):
|
||||
|
||||
r = dcerpc.samr_EnumDomainUsers()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.resume_handle = 0
|
||||
r.data_in.acct_flags = user_account_flags
|
||||
r.data_in.max_size = 1000
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_EnumDomainUsers, self.pipe, r)
|
||||
|
||||
users = []
|
||||
|
||||
if r.data_out.sam.entries:
|
||||
for i in range(r.data_out.sam.count):
|
||||
users.append(dcerpc.samr_SamEntry_array_getitem(
|
||||
r.data_out.sam.entries, i).name.string)
|
||||
|
||||
return users
|
||||
|
||||
def CreateUser(self, account_name, access_mask = 0x02000000):
|
||||
|
||||
r = dcerpc.samr_CreateUser()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.account_name = dcerpc.samr_String()
|
||||
r.data_in.account_name.string = account_name
|
||||
r.data_in.access_mask = access_mask
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_CreateUser, self.pipe, r)
|
||||
|
||||
return (r.data_out.user_handle,
|
||||
dcerpc.uint32_array_getitem(r.data_out.rid, 0))
|
||||
|
||||
def CreateUser2(self, account_name, acct_flags = 0x00000010,
|
||||
access_mask = 0x02000000):
|
||||
|
||||
r = dcerpc.samr_CreateUser2()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.account_name = dcerpc.samr_String()
|
||||
r.data_in.account_name.string = account_name
|
||||
r.data_in.acct_flags = acct_flags
|
||||
r.data_in.access_mask = access_mask
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_CreateUser2, self.pipe, r)
|
||||
|
||||
return (r.data_out.user_handle,
|
||||
dcerpc.uint32_array_getitem(r.data_out.access_granted, 0),
|
||||
dcerpc.uint32_array_getitem(r.data_out.rid, 0))
|
||||
|
||||
def OpenUser(self, rid, access_mask = 0x02000000):
|
||||
|
||||
r = dcerpc.samr_OpenUser()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.access_mask = access_mask
|
||||
r.data_in.rid = rid
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_OpenUser, self.pipe, r)
|
||||
|
||||
return UserHandle(self.pipe, r.data_out.user_handle)
|
||||
|
||||
def OpenGroup(self, rid, access_mask = 0x02000000):
|
||||
|
||||
r = dcerpc.samr_OpenGroup()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.access_mask = access_mask
|
||||
r.data_in.rid = rid
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_OpenGroup, self.pipe, r)
|
||||
|
||||
return GroupHandle(self.pipe, r.data_out.group_handle)
|
||||
|
||||
def OpenAlias(self, rid, access_mask = 0x02000000):
|
||||
|
||||
r = dcerpc.samr_OpenAlias()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.access_mask = access_mask
|
||||
r.data_in.rid = rid
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_OpenAlias, self.pipe, r)
|
||||
|
||||
return AliasHandle(self.pipe, r.data_out.alias_handle)
|
||||
|
||||
def CreateDomAlias(self, alias_name, access_mask = 0x02000000):
|
||||
|
||||
r = dcerpc.samr_CreateDomAlias()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.alias_name = dcerpc.samr_String()
|
||||
r.data_in.alias_name.string = alias_name
|
||||
r.data_in.access_mask = access_mask
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_CreateDomAlias, self.pipe, r)
|
||||
|
||||
return (AliasHandle(self.pipe, r.data_out.alias_handle),
|
||||
r.data_out.rid)
|
||||
|
||||
def RidToSid(self, rid):
|
||||
|
||||
r = dcerpc.samr_RidToSid()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.rid = rid
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_RidToSid, self.pipe, r)
|
||||
|
||||
return sid_to_string(r.data_out.sid)
|
||||
|
||||
def RemoveMemberFromForeignDomain(self, sid):
|
||||
|
||||
r = dcerpc.samr_RemoveMemberFromForeignDomain()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.sid = sid
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_RemoveMemberFromForeignDomain, self.pipe, r)
|
||||
|
||||
def LookupNames(self, names):
|
||||
|
||||
r = dcerpc.samr_LookupNames()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.num_names = len(names)
|
||||
r.data_in.names = dcerpc.new_samr_String_array(len(names))
|
||||
|
||||
for i in range(len(names)):
|
||||
s = dcerpc.samr_String()
|
||||
s.string = names[i]
|
||||
dcerpc.samr_String_array_setitem(r.data_in.names, i, s)
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_LookupNames, self.pipe, r)
|
||||
|
||||
return ([dcerpc.uint32_array_getitem(r.data_out.rids.ids, i)
|
||||
for i in range(r.data_out.rids.count)],
|
||||
[dcerpc.uint32_array_getitem(r.data_out.types.ids, i)
|
||||
for i in range(r.data_out.types.count)])
|
||||
|
||||
def CreateDomainGroup(self, domain_name, access_mask = 0x02000000):
|
||||
|
||||
r = dcerpc.samr_CreateDomainGroup()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.name = dcerpc.samr_String()
|
||||
r.data_in.name.string = domain_name
|
||||
r.data_in.access_mask = access_mask
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_CreateDomainGroup, self.pipe, r)
|
||||
|
||||
def GetAliasMembership(self, sids):
|
||||
|
||||
r = dcerpc.samr_GetAliasMembership()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.sids = dcerpc.lsa_SidArray()
|
||||
r.data_in.sids.num_sids = len(sids)
|
||||
r.data_in.sids.sids = dcerpc.new_lsa_SidPtr_array(len(sids))
|
||||
|
||||
for i in range(len(sids)):
|
||||
s = dcerpc.lsa_SidPtr()
|
||||
s.sid = string_to_sid(sids[i])
|
||||
dcerpc.lsa_SidPtr_array_setitem(r.data_in.sids.sids, i, s)
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_GetAliasMembership, self.pipe, r)
|
||||
|
||||
return [r.ids[x] for x in range(r.count)]
|
||||
|
||||
def QueryDisplayInfo(self, level):
|
||||
|
||||
# TODO: Handle more data returns
|
||||
|
||||
r = dcerpc.samr_QueryDisplayInfo()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.level = level
|
||||
r.data_in.start_idx = 0
|
||||
r.data_in.max_entries = 1000
|
||||
r.data_in.buf_size = -1
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_QueryDisplayInfo, self.pipe, r)
|
||||
|
||||
# TODO: Return a mapping of the various samr_DispInfo
|
||||
# structures here.
|
||||
|
||||
return getattr(r.data_out.info, 'info%d' % level)
|
||||
|
||||
def QueryDisplayInfo2(self, level):
|
||||
|
||||
# TODO: Handle more data returns
|
||||
|
||||
r = dcerpc.samr_QueryDisplayInfo2()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.level = level
|
||||
r.data_in.start_idx = 0
|
||||
r.data_in.max_entries = 1000
|
||||
r.data_in.buf_size = -1
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_QueryDisplayInfo2, self.pipe, r)
|
||||
|
||||
# TODO: Return a mapping of the various samr_DispInfo
|
||||
# structures here.
|
||||
|
||||
return getattr(r.data_out.info, 'info%d' % level)
|
||||
|
||||
def QueryDisplayInfo3(self, level):
|
||||
|
||||
# TODO: Handle more data returns
|
||||
|
||||
r = dcerpc.samr_QueryDisplayInfo3()
|
||||
r.data_in.domain_handle = self.handle
|
||||
r.data_in.level = level
|
||||
r.data_in.start_idx = 0
|
||||
r.data_in.max_entries = 1000
|
||||
r.data_in.buf_size = -1
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_QueryDisplayInfo3, self.pipe, r)
|
||||
|
||||
# TODO: Return a mapping of the various samr_DispInfo
|
||||
# structures here.
|
||||
|
||||
return getattr(r.data_out.info, 'info%d' % level)
|
||||
|
||||
def GetBootKeyInformation(self):
|
||||
|
||||
r = dcerpc.samr_GetBootKeyInformation()
|
||||
r.data_in.domain_handle = self.handle
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_GetBootKeyInformation, self.pipe, r)
|
||||
|
||||
return r.data_out.unknown
|
||||
|
||||
def SetBootKeyInformation(self):
|
||||
|
||||
r = dcerpc.samr_GetBootKeyInformation()
|
||||
r.data_in.domain_handle = self.handle
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_GetBootKeyInformation, self.pipe, r)
|
||||
|
||||
def TestPrivateFunctionsDomain(self):
|
||||
|
||||
r = dcerpc.samr_TestPrivateFunctionsDomain()
|
||||
r.data_in.domain_handle = self.handle
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_TestPrivateFunctionsDomain, self.pipe, r)
|
||||
|
||||
class UserHandle(SamrHandle):
|
||||
|
||||
def DeleteUser(self):
|
||||
|
||||
r = dcerpc.samr_DeleteUser()
|
||||
r.data_in.user_handle = self.handle
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_DeleteUser, self.pipe, r)
|
||||
|
||||
self.handle = None
|
||||
|
||||
def GetUserPwInfo(self):
|
||||
|
||||
r = dcerpc.samr_GetUserPwInfo()
|
||||
r.data_in.user_handle = self.handle
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_GetUserPwInfo, self.pipe, r)
|
||||
|
||||
return r.data_out.info
|
||||
|
||||
def QueryUserInfo(self, level):
|
||||
|
||||
r = dcerpc.samr_QueryUserInfo()
|
||||
r.data_in.user_handle = self.handle
|
||||
r.data_in.level = level
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_QueryUserInfo, self.pipe, r)
|
||||
|
||||
return r.data_out.info
|
||||
|
||||
def QueryUserInfo2(self, level):
|
||||
|
||||
r = dcerpc.samr_QueryUserInfo2()
|
||||
r.data_in.user_handle = self.handle
|
||||
r.data_in.level = level
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_QueryUserInfo2, self.pipe, r)
|
||||
|
||||
return r.data_out.info
|
||||
|
||||
def GetGroupsForUser(self):
|
||||
|
||||
r = dcerpc.samr_GetGroupsForUser()
|
||||
r.data_in.user_handle = self.handle
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_GetGroupsForUser, self.pipe, r)
|
||||
|
||||
rid_types = [dcerpc.samr_RidType_array_getitem(r.data_out.rids.rid, x)
|
||||
for x in range(r.data_out.rids.count)]
|
||||
|
||||
return [(x.rid, x.type) for x in rid_types]
|
||||
|
||||
def TestPrivateFunctionsUser(self):
|
||||
|
||||
r = dcerpc.samr_TestPrivateFunctionsUser()
|
||||
r.data_in.user_handle = self.handle
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_TestPrivateFunctionsUser, self.pipe, r)
|
||||
|
||||
class GroupHandle(SamrHandle):
|
||||
|
||||
def QueryGroupInfo(self, level):
|
||||
|
||||
r = dcerpc.samr_QueryGroupInfo()
|
||||
r.data_in.group_handle = self.handle
|
||||
r.data_in.level = level
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_QueryGroupInfo, self.pipe, r)
|
||||
|
||||
return r.data_out.info
|
||||
|
||||
def SetGroupInfo(self, level, info):
|
||||
|
||||
r = dcerpc.samr_SetGroupInfo()
|
||||
r.data_in.group_handle = self.handle
|
||||
r.data_in.level = level
|
||||
r.data_in.info = info
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_SetGroupInfo, self.pipe, r)
|
||||
|
||||
def QueryGroupMember(self):
|
||||
|
||||
r = dcerpc.samr_QueryGroupMember()
|
||||
r.data_in.group_handle = self.handle
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_QueryGroupMember, self.pipe, r)
|
||||
|
||||
return [(dcerpc.uint32_array_getitem(r.data_out.rids.rids, x),
|
||||
dcerpc.uint32_array_getitem(r.data_out.rids.unknown, x))
|
||||
for x in range(r.data_out.rids.count)]
|
||||
|
||||
class AliasHandle(SamrHandle):
|
||||
|
||||
def DeleteDomAlias(self):
|
||||
|
||||
r = dcerpc.samr_DeleteDomAlias()
|
||||
r.data_in.alias_handle = self.handle
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_DeleteDomAlias, self.pipe, r)
|
||||
|
||||
self.handle = None
|
||||
|
||||
def QueryAliasInfo(self, level = 1):
|
||||
|
||||
r = dcerpc.samr_QueryAliasInfo()
|
||||
r.data_in.alias_handle = self.handle
|
||||
r.data_in.level = level
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_QueryAliasInfo, self.pipe, r)
|
||||
|
||||
return r.data_out.info
|
||||
|
||||
def SetAliasInfo(self, level, info):
|
||||
|
||||
r = dcerpc.samr_SetAliasInfo()
|
||||
r.data_in.alias_handle = self.handle
|
||||
r.data_in.level = level
|
||||
r.data_in.info = info
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_SetAliasInfo, self.pipe, r)
|
||||
|
||||
def AddAliasMember(self, sid):
|
||||
|
||||
r = dcerpc.samr_AddAliasMember()
|
||||
r.data_in.alias_handle = self.handle
|
||||
r.data_in.sid = string_to_sid(sid)
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_AddAliasMember, self.pipe, r)
|
||||
|
||||
def AddMultipleMembersToAlias(self, sids):
|
||||
|
||||
r = dcerpc.samr_AddMultipleMembersToAlias()
|
||||
r.data_in.alias_handle = self.handle
|
||||
r.data_in.sids = dcerpc.lsa_SidArray()
|
||||
r.data_in.sids.num_sids = len(sids)
|
||||
r.data_in.sids.sids = dcerpc.new_lsa_SidPtr_array(len(sids))
|
||||
|
||||
for i in range(len(sids)):
|
||||
s = dcerpc.lsa_SidPtr()
|
||||
s.sid = string_to_sid(sids[i])
|
||||
dcerpc.lsa_SidPtr_array_setitem(r.data_in.sids.sids, i, s)
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_AddMultipleMembersToAlias, self.pipe, r)
|
||||
|
||||
def GetMembersInAlias(self):
|
||||
|
||||
r = dcerpc.samr_GetMembersInAlias()
|
||||
r.data_in.alias_handle = self.handle
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_GetMembersInAlias, self.pipe, r)
|
||||
|
||||
return [
|
||||
sid_to_string(
|
||||
dcerpc.lsa_SidPtr_array_getitem(r.data_out.sids.sids, x).sid)
|
||||
for x in range(r.data_out.sids.num_sids)]
|
||||
|
||||
def Connect(pipe, access_mask = 0x02000000):
|
||||
|
||||
r = dcerpc.samr_Connect()
|
||||
r.data_in.system_name = dcerpc.new_uint16_array(1)
|
||||
dcerpc.uint16_array_setitem(r.data_in.system_name, 0, ord('\\'))
|
||||
r.data_in.access_mask = access_mask
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_Connect, pipe, r)
|
||||
|
||||
return ConnectHandle(pipe, r.data_out.connect_handle)
|
||||
|
||||
def Connect2(pipe, system_name = '', access_mask = 0x02000000):
|
||||
"""Connect to the SAMR pipe."""
|
||||
|
||||
r = dcerpc.samr_Connect2()
|
||||
r.data_in.system_name = system_name
|
||||
r.data_in.access_mask = access_mask
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_Connect2, pipe, r)
|
||||
|
||||
return ConnectHandle(pipe, r.data_out.connect_handle)
|
||||
|
||||
def Connect3(pipe, system_name = '', access_mask = 0x02000000):
|
||||
|
||||
r = dcerpc.samr_Connect3()
|
||||
r.data_in.system_name = system_name
|
||||
r.data_in.unknown = 0
|
||||
r.data_in.access_mask = access_mask
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_Connect3, pipe, r)
|
||||
|
||||
return ConnectHandle(pipe, r.data_out.connect_handle)
|
||||
|
||||
|
||||
def Connect4(pipe, system_name = '', access_mask = 0x02000000):
|
||||
|
||||
r = dcerpc.samr_Connect4()
|
||||
r.data_in.system_name = system_name
|
||||
r.data_in.unknown = 0
|
||||
r.data_in.access_mask = access_mask
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_Connect4, pipe, r)
|
||||
|
||||
return ConnectHandle(pipe, r.data_out.connect_handle)
|
||||
|
||||
def Connect5(pipe, system_name = '', access_mask = 0x02000000):
|
||||
|
||||
r = dcerpc.samr_Connect5()
|
||||
r.data_in.system_name = system_name
|
||||
r.data_in.access_mask = access_mask
|
||||
r.data_in.level = 1
|
||||
r.data_in.info = dcerpc.new_samr_ConnectInfo_array(1)
|
||||
r.data_in.info.unknown1 = 0
|
||||
r.data_in.info.unknown2 = 0
|
||||
|
||||
call_fn(dcerpc.dcerpc_samr_Connect5, pipe, r)
|
||||
|
||||
return ConnectHandle(pipe, r.data_out.connect_handle)
|
||||
|
||||
# AddGroupMember
|
||||
# DeleteDomainGroup
|
||||
# DeleteGroupMember
|
||||
# SetMemberAttributesofGroup
|
||||
# AddAliasMember
|
||||
# DeleteAliasMember
|
||||
# GetMembersinAlias
|
||||
# SetUserInfo
|
||||
# ChangePasswordUser
|
||||
# GetDisplayEnumerationIndex
|
||||
# RemoveMemberFromForeignDomain
|
||||
# GetDisplayEnumerationIndex2
|
||||
# RemoveMultipleMembersFromAlias
|
||||
# OemChangePasswordUser2
|
||||
# ChangePasswordUser2
|
||||
# SetUserInfo2
|
||||
# ChangePasswordUser3
|
||||
# SetDsrmPassword
|
||||
# ValidatePassword
|
51
source4/scripting/python/samba/torture/pytorture
Executable file
51
source4/scripting/python/samba/torture/pytorture
Executable file
@ -0,0 +1,51 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
from optparse import OptionParser
|
||||
|
||||
# Parse command line
|
||||
|
||||
parser = OptionParser()
|
||||
|
||||
parser.add_option("-b", "--binding", action="store", type="string",
|
||||
dest="binding")
|
||||
|
||||
parser.add_option("-d", "--domain", action="store", type="string",
|
||||
dest="domain")
|
||||
|
||||
parser.add_option("-u", "--username", action="store", type="string",
|
||||
dest="username")
|
||||
|
||||
parser.add_option("-p", "--password", action="store", type="string",
|
||||
dest="password")
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if not options.binding:
|
||||
parser.error('You must supply a binding string')
|
||||
|
||||
if not options.username or not options.password or not options.domain:
|
||||
parser.error('You must supply a domain, username and password')
|
||||
|
||||
binding = options.binding
|
||||
domain = options.domain
|
||||
username = options.username
|
||||
password = options.password
|
||||
|
||||
if len(args) == 0:
|
||||
parser.error('You must supply the name of a module to test')
|
||||
|
||||
# Import and test
|
||||
|
||||
for test in args:
|
||||
|
||||
try:
|
||||
module = __import__('torture_%s' % test)
|
||||
except ImportError:
|
||||
print 'No such module "%s"' % test
|
||||
sys.exit(1)
|
||||
|
||||
if not hasattr(module, 'runtests'):
|
||||
print 'Module "%s" does not have a runtests function' % test
|
||||
|
||||
module.runtests(binding, (domain, username, password))
|
437
source4/scripting/python/samba/torture/spoolss.py
Normal file
437
source4/scripting/python/samba/torture/spoolss.py
Normal file
@ -0,0 +1,437 @@
|
||||
import sys, string
|
||||
import dcerpc
|
||||
|
||||
|
||||
def ResizeBufferCall(fn, pipe, r):
|
||||
|
||||
r['buffer'] = None
|
||||
r['buf_size'] = 0
|
||||
|
||||
result = fn(pipe, r)
|
||||
|
||||
if result['result'] == dcerpc.WERR_INSUFFICIENT_BUFFER or \
|
||||
result['result'] == dcerpc.WERR_MORE_DATA:
|
||||
r['buffer'] = result['buf_size'] * '\x00'
|
||||
r['buf_size'] = result['buf_size']
|
||||
|
||||
result = fn(pipe, r)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def test_OpenPrinterEx(pipe, printer):
|
||||
|
||||
print 'spoolss_OpenPrinterEx(%s)' % printer
|
||||
|
||||
printername = '\\\\%s' % dcerpc.dcerpc_server_name(pipe)
|
||||
|
||||
if printer is not None:
|
||||
printername = printername + '\\%s' % printer
|
||||
|
||||
r = {}
|
||||
r['printername'] = printername
|
||||
r['datatype'] = None
|
||||
r['devmode_ctr'] = {}
|
||||
r['devmode_ctr']['size'] = 0
|
||||
r['devmode_ctr']['devmode'] = None
|
||||
r['access_mask'] = 0x02000000
|
||||
r['level'] = 1
|
||||
r['userlevel'] = {}
|
||||
r['userlevel']['level1'] = {}
|
||||
r['userlevel']['level1']['size'] = 0
|
||||
r['userlevel']['level1']['client'] = None
|
||||
r['userlevel']['level1']['user'] = None
|
||||
r['userlevel']['level1']['build'] = 1381
|
||||
r['userlevel']['level1']['major'] = 2
|
||||
r['userlevel']['level1']['minor'] = 0
|
||||
r['userlevel']['level1']['processor'] = 0
|
||||
|
||||
result = dcerpc.spoolss_OpenPrinterEx(pipe, r)
|
||||
|
||||
return result['handle']
|
||||
|
||||
|
||||
def test_ClosePrinter(pipe, handle):
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
|
||||
dcerpc.spoolss_ClosePrinter(pipe, r)
|
||||
|
||||
|
||||
def test_GetPrinter(pipe, handle):
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
|
||||
for level in [0, 1, 2, 3, 4, 5, 6, 7]:
|
||||
|
||||
print 'spoolss_GetPrinter(level = %d)' % level
|
||||
|
||||
r['level'] = level
|
||||
r['buffer'] = None
|
||||
r['buf_size'] = 0
|
||||
|
||||
result = ResizeBufferCall(dcerpc.spoolss_GetPrinter, pipe, r)
|
||||
|
||||
|
||||
def test_EnumForms(pipe, handle):
|
||||
|
||||
print 'spoolss_EnumForms()'
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
r['level'] = 1
|
||||
r['buffer'] = None
|
||||
r['buf_size'] = 0
|
||||
|
||||
result = ResizeBufferCall(dcerpc.spoolss_EnumForms, pipe, r)
|
||||
|
||||
forms = dcerpc.unmarshall_spoolss_FormInfo_array(
|
||||
result['buffer'], r['level'], result['count'])
|
||||
|
||||
for form in forms:
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
r['formname'] = form['info1']['formname']
|
||||
r['level'] = 1
|
||||
|
||||
result = ResizeBufferCall(dcerpc.spoolss_GetForm, pipe, r)
|
||||
|
||||
|
||||
def test_EnumPorts(pipe, handle):
|
||||
|
||||
print 'spoolss_EnumPorts()'
|
||||
|
||||
for level in [1, 2]:
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
r['servername'] = None
|
||||
r['level'] = level
|
||||
|
||||
result = ResizeBufferCall(dcerpc.spoolss_EnumPorts, pipe, r)
|
||||
|
||||
ports = dcerpc.unmarshall_spoolss_PortInfo_array(
|
||||
result['buffer'], r['level'], result['count'])
|
||||
|
||||
if level == 1:
|
||||
port_names = map(lambda x: x['info1']['port_name'], ports)
|
||||
|
||||
|
||||
def test_DeleteForm(pipe, handle, formname):
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
r['formname'] = formname
|
||||
|
||||
dcerpc.spoolss_DeleteForm(pipe, r)
|
||||
|
||||
|
||||
def test_GetForm(pipe, handle, formname):
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
r['formname'] = formname
|
||||
r['level'] = 1
|
||||
|
||||
result = ResizeBufferCall(dcerpc.spoolss_GetForm, pipe, r)
|
||||
|
||||
return result['info']['info1']
|
||||
|
||||
|
||||
def test_SetForm(pipe, handle, form):
|
||||
|
||||
print 'spoolss_SetForm()'
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
r['level'] = 1
|
||||
r['formname'] = form['info1']['formname']
|
||||
r['info'] = form
|
||||
|
||||
dcerpc.spoolss_SetForm(pipe, r)
|
||||
|
||||
newform = test_GetForm(pipe, handle, r['formname'])
|
||||
|
||||
if form['info1'] != newform:
|
||||
print 'SetForm: mismatch: %s != %s' % \
|
||||
(r['info']['info1'], f)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def test_AddForm(pipe, handle):
|
||||
|
||||
print 'spoolss_AddForm()'
|
||||
|
||||
formname = '__testform__'
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
r['level'] = 1
|
||||
r['info'] = {}
|
||||
r['info']['info1'] = {}
|
||||
r['info']['info1']['formname'] = formname
|
||||
r['info']['info1']['flags'] = 0x0002
|
||||
r['info']['info1']['width'] = 100
|
||||
r['info']['info1']['length'] = 100
|
||||
r['info']['info1']['left'] = 0
|
||||
r['info']['info1']['top'] = 1000
|
||||
r['info']['info1']['right'] = 2000
|
||||
r['info']['info1']['bottom'] = 3000
|
||||
|
||||
try:
|
||||
result = dcerpc.spoolss_AddForm(pipe, r)
|
||||
except dcerpc.WERROR, arg:
|
||||
if arg[0] == dcerpc.WERR_ALREADY_EXISTS:
|
||||
test_DeleteForm(pipe, handle, formname)
|
||||
result = dcerpc.spoolss_AddForm(pipe, r)
|
||||
|
||||
f = test_GetForm(pipe, handle, formname)
|
||||
|
||||
if r['info']['info1'] != f:
|
||||
print 'AddForm: mismatch: %s != %s' % \
|
||||
(r['info']['info1'], f)
|
||||
sys.exit(1)
|
||||
|
||||
r['formname'] = formname
|
||||
|
||||
test_SetForm(pipe, handle, r['info'])
|
||||
|
||||
test_DeleteForm(pipe, handle, formname)
|
||||
|
||||
|
||||
def test_EnumJobs(pipe, handle):
|
||||
|
||||
print 'spoolss_EnumJobs()'
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
r['firstjob'] = 0
|
||||
r['numjobs'] = 0xffffffff
|
||||
r['level'] = 1
|
||||
|
||||
result = ResizeBufferCall(dcerpc.spoolss_EnumJobs, pipe, r)
|
||||
|
||||
if result['buffer'] is None:
|
||||
return
|
||||
|
||||
jobs = dcerpc.unmarshall_spoolss_JobInfo_array(
|
||||
result['buffer'], r['level'], result['count'])
|
||||
|
||||
for job in jobs:
|
||||
|
||||
s = {}
|
||||
s['handle'] = handle
|
||||
s['job_id'] = job['info1']['job_id']
|
||||
s['level'] = 1
|
||||
|
||||
result = ResizeBufferCall(dcerpc.spoolss_GetJob, pipe, s)
|
||||
|
||||
if result['info'] != job:
|
||||
print 'EnumJobs: mismatch: %s != %s' % (result['info'], job)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
# TODO: AddJob, DeleteJob, ScheduleJob
|
||||
|
||||
|
||||
def test_EnumPrinterData(pipe, handle):
|
||||
|
||||
print 'test_EnumPrinterData()'
|
||||
|
||||
enum_index = 0
|
||||
|
||||
while 1:
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
r['enum_index'] = enum_index
|
||||
|
||||
r['value_offered'] = 0
|
||||
r['data_size'] = 0
|
||||
|
||||
result = dcerpc.spoolss_EnumPrinterData(pipe, r)
|
||||
|
||||
r['value_offered'] = result['value_needed']
|
||||
r['data_size'] = result['data_size']
|
||||
|
||||
result = dcerpc.spoolss_EnumPrinterData(pipe, r)
|
||||
|
||||
if result['result'] == dcerpc.WERR_NO_MORE_ITEMS:
|
||||
break
|
||||
|
||||
s = {}
|
||||
s['handle'] = handle
|
||||
s['value_name'] = result['value_name']
|
||||
|
||||
result2 = ResizeBufferCall(dcerpc.spoolss_GetPrinterData, pipe, s)
|
||||
|
||||
if result['buffer'][:result2['buf_size']] != result2['buffer']:
|
||||
print 'EnumPrinterData/GetPrinterData mismatch'
|
||||
sys.exit(1)
|
||||
|
||||
enum_index += 1
|
||||
|
||||
|
||||
def test_SetPrinterDataEx(pipe, handle):
|
||||
|
||||
valuename = '__printerdataextest__'
|
||||
data = '12345'
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
r['key_name'] = 'DsSpooler'
|
||||
r['value_name'] = valuename
|
||||
r['type'] = 3
|
||||
r['buffer'] = data
|
||||
r['buf_size'] = len(data)
|
||||
|
||||
result = dcerpc.spoolss_SetPrinterDataEx(pipe, r)
|
||||
|
||||
|
||||
def test_EnumPrinterDataEx(pipe, handle):
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
r['key_name'] = 'DsSpooler'
|
||||
r['buf_size'] = 0
|
||||
|
||||
result = dcerpc.spoolss_EnumPrinterDataEx(pipe, r)
|
||||
|
||||
if result['result'] == dcerpc.WERR_MORE_DATA:
|
||||
r['buf_size'] = result['buf_size']
|
||||
|
||||
result = dcerpc.spoolss_EnumPrinterDataEx(pipe, r)
|
||||
|
||||
# TODO: test spoolss_GetPrinterDataEx()
|
||||
|
||||
|
||||
def test_SetPrinterData(pipe, handle):
|
||||
|
||||
print 'testing spoolss_SetPrinterData()'
|
||||
|
||||
valuename = '__printerdatatest__'
|
||||
data = '12345'
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
r['value_name'] = valuename
|
||||
r['type'] = 3 # REG_BINARY
|
||||
r['buffer'] = data
|
||||
r['real_len'] = 5
|
||||
|
||||
dcerpc.spoolss_SetPrinterData(pipe, r)
|
||||
|
||||
s = {}
|
||||
s['handle'] = handle
|
||||
s['value_name'] = valuename
|
||||
|
||||
result = ResizeBufferCall(dcerpc.spoolss_GetPrinterData, pipe, r)
|
||||
|
||||
if result['buffer'] != data:
|
||||
print 'SetPrinterData: mismatch'
|
||||
sys.exit(1)
|
||||
|
||||
dcerpc.spoolss_DeletePrinterData(pipe, r)
|
||||
|
||||
|
||||
def test_EnumPrinters(pipe):
|
||||
|
||||
print 'testing spoolss_EnumPrinters()'
|
||||
|
||||
printer_names = None
|
||||
|
||||
r = {}
|
||||
r['flags'] = 0x02
|
||||
r['server'] = None
|
||||
|
||||
for level in [0, 1, 2, 4, 5]:
|
||||
|
||||
print 'test_EnumPrinters(level = %d)' % level
|
||||
|
||||
r['level'] = level
|
||||
|
||||
result = ResizeBufferCall(dcerpc.spoolss_EnumPrinters, pipe, r)
|
||||
|
||||
printers = dcerpc.unmarshall_spoolss_PrinterInfo_array(
|
||||
result['buffer'], r['level'], result['count'])
|
||||
|
||||
if level == 2:
|
||||
for p in printers:
|
||||
|
||||
# A nice check is for the specversion in the
|
||||
# devicemode. This has always been observed to be
|
||||
# 1025.
|
||||
|
||||
if p['info2']['devmode']['specversion'] != 1025:
|
||||
print 'test_EnumPrinters: specversion != 1025'
|
||||
sys.exit(1)
|
||||
|
||||
r['level'] = 1
|
||||
result = ResizeBufferCall(dcerpc.spoolss_EnumPrinters, pipe, r)
|
||||
|
||||
for printer in dcerpc.unmarshall_spoolss_PrinterInfo_array(
|
||||
result['buffer'], r['level'], result['count']):
|
||||
|
||||
if string.find(printer['info1']['name'], '\\\\') == 0:
|
||||
print 'Skipping remote printer %s' % printer['info1']['name']
|
||||
continue
|
||||
|
||||
printername = string.split(printer['info1']['name'], ',')[0]
|
||||
|
||||
handle = test_OpenPrinterEx(pipe, printername)
|
||||
|
||||
test_GetPrinter(pipe, handle)
|
||||
test_EnumPorts(pipe, handle)
|
||||
test_EnumForms(pipe, handle)
|
||||
test_AddForm(pipe, handle)
|
||||
test_EnumJobs(pipe, handle)
|
||||
test_EnumPrinterData(pipe, handle)
|
||||
test_EnumPrinterDataEx(pipe, handle)
|
||||
test_SetPrinterData(pipe, handle)
|
||||
# test_SetPrinterDataEx(pipe, handle)
|
||||
test_ClosePrinter(pipe, handle)
|
||||
|
||||
|
||||
def test_EnumPrinterDrivers(pipe):
|
||||
|
||||
print 'test spoolss_EnumPrinterDrivers()'
|
||||
|
||||
for level in [1, 2, 3]:
|
||||
|
||||
r = {}
|
||||
r['server'] = None
|
||||
r['environment'] = None
|
||||
r['level'] = level
|
||||
|
||||
result = ResizeBufferCall(dcerpc.spoolss_EnumPrinterDrivers, pipe, r)
|
||||
|
||||
drivers = dcerpc.unmarshall_spoolss_DriverInfo_array(
|
||||
result['buffer'], r['level'], result['count'])
|
||||
|
||||
if level == 1:
|
||||
driver_names = map(lambda x: x['info1']['driver_name'], drivers)
|
||||
|
||||
|
||||
def test_PrintServer(pipe):
|
||||
|
||||
handle = test_OpenPrinterEx(pipe, None)
|
||||
|
||||
# EnumForms and AddForm tests return WERR_BADFID here (??)
|
||||
|
||||
test_ClosePrinter(pipe, handle)
|
||||
|
||||
|
||||
def runtests(binding, domain, username, password):
|
||||
|
||||
print 'Testing SPOOLSS pipe'
|
||||
|
||||
pipe = dcerpc.pipe_connect(binding,
|
||||
dcerpc.DCERPC_SPOOLSS_UUID, dcerpc.DCERPC_SPOOLSS_VERSION,
|
||||
domain, username, password)
|
||||
|
||||
test_EnumPrinters(pipe)
|
||||
test_EnumPrinterDrivers(pipe)
|
||||
test_PrintServer(pipe)
|
221
source4/scripting/python/samba/torture/torture_samr.py
Executable file
221
source4/scripting/python/samba/torture/torture_samr.py
Executable file
@ -0,0 +1,221 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
import dcerpc, samr
|
||||
|
||||
def test_Connect(pipe):
|
||||
|
||||
handle = samr.Connect(pipe)
|
||||
handle = samr.Connect2(pipe)
|
||||
handle = samr.Connect3(pipe)
|
||||
handle = samr.Connect4(pipe)
|
||||
|
||||
# WIN2K3 only?
|
||||
|
||||
try:
|
||||
handle = samr.Connect5(pipe)
|
||||
except dcerpc.NTSTATUS, arg:
|
||||
if arg[0] != 0xc00000d2L: # NT_STATUS_NET_WRITE_FAULT
|
||||
raise
|
||||
|
||||
return handle
|
||||
|
||||
def test_UserHandle(user_handle):
|
||||
|
||||
# QuerySecurity()/SetSecurity()
|
||||
|
||||
user_handle.SetSecurity(user_handle.QuerySecurity())
|
||||
|
||||
# GetUserPwInfo()
|
||||
|
||||
user_handle.GetUserPwInfo()
|
||||
|
||||
# GetUserInfo()
|
||||
|
||||
for level in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 20,
|
||||
21, 23, 24, 25, 26]:
|
||||
|
||||
try:
|
||||
user_handle.QueryUserInfo(level)
|
||||
user_handle.QueryUserInfo2(level)
|
||||
except dcerpc.NTSTATUS, arg:
|
||||
if arg[0] != 0xc0000003L: # NT_STATUS_INVALID_INFO_CLASS
|
||||
raise
|
||||
|
||||
# GetGroupsForUser()
|
||||
|
||||
user_handle.GetGroupsForUser()
|
||||
|
||||
# TestPrivateFunctionsUser()
|
||||
|
||||
try:
|
||||
user_handle.TestPrivateFunctionsUser()
|
||||
except dcerpc.NTSTATUS, arg:
|
||||
if arg[0] != 0xC0000002L:
|
||||
raise
|
||||
|
||||
def test_GroupHandle(group_handle):
|
||||
|
||||
# QuerySecurity()/SetSecurity()
|
||||
|
||||
group_handle.SetSecurity(group_handle.QuerySecurity())
|
||||
|
||||
# QueryGroupInfo()
|
||||
|
||||
for level in [1, 2, 3, 4, 5]:
|
||||
info = group_handle.QueryGroupInfo(level)
|
||||
|
||||
# TODO: SetGroupinfo()
|
||||
|
||||
# QueryGroupMember()
|
||||
|
||||
group_handle.QueryGroupMember()
|
||||
|
||||
def test_AliasHandle(alias_handle):
|
||||
|
||||
# QuerySecurity()/SetSecurity()
|
||||
|
||||
alias_handle.SetSecurity(alias_handle.QuerySecurity())
|
||||
|
||||
print alias_handle.GetMembersInAlias()
|
||||
|
||||
def test_DomainHandle(name, sid, domain_handle):
|
||||
|
||||
print 'testing %s (%s)' % (name, sid)
|
||||
|
||||
# QuerySecurity()/SetSecurity()
|
||||
|
||||
domain_handle.SetSecurity(domain_handle.QuerySecurity())
|
||||
|
||||
# LookupNames(), none mapped
|
||||
|
||||
try:
|
||||
domain_handle.LookupNames(['xxNONAMExx'])
|
||||
except dcerpc.NTSTATUS, arg:
|
||||
if arg[0] != 0xc0000073L:
|
||||
raise dcerpc.NTSTATUS(arg)
|
||||
|
||||
# LookupNames(), some mapped
|
||||
|
||||
if name != 'Builtin':
|
||||
domain_handle.LookupNames(['Administrator', 'xxNONAMExx'])
|
||||
|
||||
# QueryDomainInfo()/SetDomainInfo()
|
||||
|
||||
levels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13]
|
||||
set_ok = [1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0]
|
||||
|
||||
for i in range(len(levels)):
|
||||
|
||||
info = domain_handle.QueryDomainInfo(level = levels[i])
|
||||
|
||||
try:
|
||||
domain_handle.SetDomainInfo(levels[i], info)
|
||||
except dcerpc.NTSTATUS, arg:
|
||||
if not (arg[0] == 0xc0000003L and not set_ok[i]):
|
||||
raise
|
||||
|
||||
# QueryDomainInfo2()
|
||||
|
||||
levels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13]
|
||||
|
||||
for i in range(len(levels)):
|
||||
domain_handle.QueryDomainInfo2(level = levels[i])
|
||||
|
||||
# EnumDomainUsers
|
||||
|
||||
print 'testing users'
|
||||
|
||||
users = domain_handle.EnumDomainUsers()
|
||||
rids = domain_handle.LookupNames(users)
|
||||
|
||||
for i in range(len(users)):
|
||||
test_UserHandle(domain_handle.OpenUser(rids[0][i]))
|
||||
|
||||
# QueryDisplayInfo
|
||||
|
||||
for i in [1, 2, 3, 4, 5]:
|
||||
domain_handle.QueryDisplayInfo(level = i)
|
||||
domain_handle.QueryDisplayInfo2(level = i)
|
||||
domain_handle.QueryDisplayInfo3(level = i)
|
||||
|
||||
# EnumDomainGroups
|
||||
|
||||
print 'testing groups'
|
||||
|
||||
groups = domain_handle.EnumDomainGroups()
|
||||
rids = domain_handle.LookupNames(groups)
|
||||
|
||||
for i in range(len(groups)):
|
||||
test_GroupHandle(domain_handle.OpenGroup(rids[0][i]))
|
||||
|
||||
# EnumDomainAliases
|
||||
|
||||
print 'testing aliases'
|
||||
|
||||
aliases = domain_handle.EnumDomainAliases()
|
||||
rids = domain_handle.LookupNames(aliases)
|
||||
|
||||
for i in range(len(aliases)):
|
||||
test_AliasHandle(domain_handle.OpenAlias(rids[0][i]))
|
||||
|
||||
# CreateUser
|
||||
# CreateUser2
|
||||
# CreateDomAlias
|
||||
# RidToSid
|
||||
# RemoveMemberFromForeignDomain
|
||||
# CreateDomainGroup
|
||||
# GetAliasMembership
|
||||
|
||||
# GetBootKeyInformation()
|
||||
|
||||
try:
|
||||
domain_handle.GetBootKeyInformation()
|
||||
except dcerpc.NTSTATUS, arg:
|
||||
pass
|
||||
|
||||
# TestPrivateFunctionsDomain()
|
||||
|
||||
try:
|
||||
domain_handle.TestPrivateFunctionsDomain()
|
||||
except dcerpc.NTSTATUS, arg:
|
||||
if arg[0] != 0xC0000002L:
|
||||
raise
|
||||
|
||||
def test_ConnectHandle(connect_handle):
|
||||
|
||||
print 'testing connect handle'
|
||||
|
||||
# QuerySecurity/SetSecurity
|
||||
|
||||
connect_handle.SetSecurity(connect_handle.QuerySecurity())
|
||||
|
||||
# Lookup bogus domain
|
||||
|
||||
try:
|
||||
connect_handle.LookupDomain('xxNODOMAINxx')
|
||||
except dcerpc.NTSTATUS, arg:
|
||||
if arg[0] != 0xC00000DFL: # NT_STATUS_NO_SUCH_DOMAIN
|
||||
raise
|
||||
|
||||
# Test all domains
|
||||
|
||||
for domain_name in connect_handle.EnumDomains():
|
||||
|
||||
connect_handle.GetDomPwInfo(domain_name)
|
||||
sid = connect_handle.LookupDomain(domain_name)
|
||||
domain_handle = connect_handle.OpenDomain(sid)
|
||||
|
||||
test_DomainHandle(domain_name, sid, domain_handle)
|
||||
|
||||
# TODO: Test Shutdown() function
|
||||
|
||||
def runtests(binding, creds):
|
||||
|
||||
print 'Testing SAMR pipe'
|
||||
|
||||
pipe = dcerpc.pipe_connect(binding,
|
||||
dcerpc.DCERPC_SAMR_UUID, int(dcerpc.DCERPC_SAMR_VERSION), creds)
|
||||
|
||||
handle = test_Connect(pipe)
|
||||
test_ConnectHandle(handle)
|
90
source4/scripting/python/samba/torture/torture_tdb.py
Executable file
90
source4/scripting/python/samba/torture/torture_tdb.py
Executable file
@ -0,0 +1,90 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys, os
|
||||
import Tdb
|
||||
|
||||
def fail(msg):
|
||||
print 'FAILED:', msg
|
||||
sys.exit(1)
|
||||
|
||||
tdb_file = '/tmp/torture_tdb.tdb'
|
||||
|
||||
# Create temporary tdb file
|
||||
|
||||
t = Tdb.Tdb(tdb_file, flags = Tdb.CLEAR_IF_FIRST)
|
||||
|
||||
# Check non-existent key throws KeyError exception
|
||||
|
||||
try:
|
||||
t['__none__']
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
fail('non-existent key did not throw KeyError')
|
||||
|
||||
# Check storing key
|
||||
|
||||
t['bar'] = '1234'
|
||||
if t['bar'] != '1234':
|
||||
fail('store key failed')
|
||||
|
||||
# Check key exists
|
||||
|
||||
if not t.has_key('bar'):
|
||||
fail('has_key() failed for existing key')
|
||||
|
||||
if t.has_key('__none__'):
|
||||
fail('has_key() succeeded for non-existent key')
|
||||
|
||||
# Delete key
|
||||
|
||||
try:
|
||||
del(t['__none__'])
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
fail('delete of non-existent key did not throw KeyError')
|
||||
|
||||
del t['bar']
|
||||
if t.has_key('bar'):
|
||||
fail('delete of existing key did not delete key')
|
||||
|
||||
# Clear all keys
|
||||
|
||||
t.clear()
|
||||
if len(t) != 0:
|
||||
fail('clear failed to remove all keys')
|
||||
|
||||
# Other dict functions
|
||||
|
||||
t['a'] = '1'
|
||||
t['ab'] = '12'
|
||||
t['abc'] = '123'
|
||||
|
||||
if len(t) != 3:
|
||||
fail('len method produced wrong value')
|
||||
|
||||
keys = t.keys()
|
||||
values = t.values()
|
||||
items = t.items()
|
||||
|
||||
if set(keys) != set(['a', 'ab', 'abc']):
|
||||
fail('keys method produced wrong values')
|
||||
|
||||
if set(values) != set(['1', '12', '123']):
|
||||
fail('values method produced wrong values')
|
||||
|
||||
if set(items) != set([('a', '1'), ('ab', '12'), ('abc', '123')]):
|
||||
fail('values method produced wrong values')
|
||||
|
||||
t.close()
|
||||
|
||||
# Re-open read-only
|
||||
|
||||
t = Tdb.Tdb(tdb_file, open_flags = os.O_RDONLY)
|
||||
t.keys()
|
||||
t.close()
|
||||
|
||||
# Clean up
|
||||
|
||||
os.unlink(tdb_file)
|
165
source4/scripting/python/samba/torture/winreg.py
Executable file
165
source4/scripting/python/samba/torture/winreg.py
Executable file
@ -0,0 +1,165 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys, dcerpc
|
||||
|
||||
def test_OpenHKLM(pipe):
|
||||
|
||||
r = {}
|
||||
r['unknown'] = {}
|
||||
r['unknown']['unknown0'] = 0x9038
|
||||
r['unknown']['unknown1'] = 0x0000
|
||||
r['access_required'] = 0x02000000
|
||||
|
||||
result = dcerpc.winreg_OpenHKLM(pipe, r)
|
||||
|
||||
return result['handle']
|
||||
|
||||
def test_QueryInfoKey(pipe, handle):
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
r['class'] = {}
|
||||
r['class']['name'] = None
|
||||
|
||||
return dcerpc.winreg_QueryInfoKey(pipe, r)
|
||||
|
||||
def test_CloseKey(pipe, handle):
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
|
||||
dcerpc.winreg_CloseKey(pipe, r)
|
||||
|
||||
def test_FlushKey(pipe, handle):
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
|
||||
dcerpc.winreg_FlushKey(pipe, r)
|
||||
|
||||
def test_GetVersion(pipe, handle):
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
|
||||
dcerpc.winreg_GetVersion(pipe, r)
|
||||
|
||||
def test_GetKeySecurity(pipe, handle):
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
r['unknown'] = 4
|
||||
r['size'] = None
|
||||
r['data'] = {}
|
||||
r['data']['max_len'] = 0
|
||||
r['data']['data'] = ''
|
||||
|
||||
result = dcerpc.winreg_GetKeySecurity(pipe, r)
|
||||
|
||||
print result
|
||||
|
||||
if result['result'] == dcerpc.WERR_INSUFFICIENT_BUFFER:
|
||||
r['size'] = {}
|
||||
r['size']['max_len'] = result['data']['max_len']
|
||||
r['size']['offset'] = 0
|
||||
r['size']['len'] = result['data']['max_len']
|
||||
|
||||
result = dcerpc.winreg_GetKeySecurity(pipe, r)
|
||||
|
||||
print result
|
||||
|
||||
sys.exit(1)
|
||||
|
||||
def test_Key(pipe, handle, name, depth = 0):
|
||||
|
||||
# Don't descend too far. Registries can be very deep.
|
||||
|
||||
if depth > 2:
|
||||
return
|
||||
|
||||
try:
|
||||
keyinfo = test_QueryInfoKey(pipe, handle)
|
||||
except dcerpc.WERROR, arg:
|
||||
if arg[0] == dcerpc.WERR_ACCESS_DENIED:
|
||||
return
|
||||
|
||||
test_GetVersion(pipe, handle)
|
||||
|
||||
test_FlushKey(pipe, handle)
|
||||
|
||||
test_GetKeySecurity(pipe, handle)
|
||||
|
||||
# Enumerate values in this key
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
r['name_in'] = {}
|
||||
r['name_in']['len'] = 0
|
||||
r['name_in']['max_len'] = (keyinfo['max_valnamelen'] + 1) * 2
|
||||
r['name_in']['buffer'] = {}
|
||||
r['name_in']['buffer']['max_len'] = keyinfo['max_valnamelen'] + 1
|
||||
r['name_in']['buffer']['offset'] = 0
|
||||
r['name_in']['buffer']['len'] = 0
|
||||
r['type'] = 0
|
||||
r['value_in'] = {}
|
||||
r['value_in']['max_len'] = keyinfo['max_valbufsize']
|
||||
r['value_in']['offset'] = 0
|
||||
r['value_in']['len'] = 0
|
||||
r['value_len1'] = keyinfo['max_valbufsize']
|
||||
r['value_len2'] = 0
|
||||
|
||||
for i in range(0, keyinfo['num_values']):
|
||||
|
||||
r['enum_index'] = i
|
||||
|
||||
dcerpc.winreg_EnumValue(pipe, r)
|
||||
|
||||
# Recursively test subkeys of this key
|
||||
|
||||
r = {}
|
||||
r['handle'] = handle
|
||||
r['key_name_len'] = 0
|
||||
r['unknown'] = 0x0414
|
||||
r['in_name'] = {}
|
||||
r['in_name']['unknown'] = 0x20a
|
||||
r['in_name']['key_name'] = {}
|
||||
r['in_name']['key_name']['name'] = None
|
||||
r['class'] = {}
|
||||
r['class']['name'] = None
|
||||
r['last_changed_time'] = {}
|
||||
r['last_changed_time']['low'] = 0
|
||||
r['last_changed_time']['high'] = 0
|
||||
|
||||
for i in range(0, keyinfo['num_subkeys']):
|
||||
|
||||
r['enum_index'] = i
|
||||
|
||||
subkey = dcerpc.winreg_EnumKey(pipe, r)
|
||||
|
||||
s = {}
|
||||
s['handle'] = handle
|
||||
s['keyname'] = {}
|
||||
s['keyname']['name'] = subkey['out_name']['name']
|
||||
s['unknown'] = 0
|
||||
s['access_mask'] = 0x02000000
|
||||
|
||||
result = dcerpc.winreg_OpenKey(pipe, s)
|
||||
|
||||
test_Key(pipe, result['handle'], name + '/' + s['keyname']['name'],
|
||||
depth + 1)
|
||||
|
||||
test_CloseKey(pipe, result['handle'])
|
||||
|
||||
# Enumerate values
|
||||
|
||||
def runtests(binding, domain, username, password):
|
||||
|
||||
print 'Testing WINREG pipe'
|
||||
|
||||
pipe = dcerpc.pipe_connect(binding,
|
||||
dcerpc.DCERPC_WINREG_UUID, dcerpc.DCERPC_WINREG_VERSION,
|
||||
domain, username, password)
|
||||
|
||||
handle = test_OpenHKLM(pipe)
|
||||
|
||||
test_Key(pipe, handle, 'HKLM')
|
Reference in New Issue
Block a user