mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
r2555: Start of a rpcclient type program.
This commit is contained in:
parent
74d7bc1948
commit
c9d6827312
154
source/scripting/swig/rpcclient
Executable file
154
source/scripting/swig/rpcclient
Executable file
@ -0,0 +1,154 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys, os, string
|
||||
from cmd import Cmd
|
||||
from optparse import OptionParser
|
||||
|
||||
|
||||
import dcerpc, samr
|
||||
|
||||
class rpcclient(Cmd):
|
||||
|
||||
prompt = 'rpcclient$ '
|
||||
|
||||
def __init__(self, binding, domain, username, password):
|
||||
Cmd.__init__(self)
|
||||
self.binding = binding
|
||||
self.domain = domain
|
||||
self.username = username
|
||||
self.password = password
|
||||
|
||||
def emptyline(self):
|
||||
|
||||
# Default for empty line is to repeat last command - yuck
|
||||
|
||||
pass
|
||||
|
||||
def onecmd(self, line):
|
||||
|
||||
# Override the onecmd() method so we can trap error returns
|
||||
|
||||
try:
|
||||
Cmd.onecmd(self, line)
|
||||
except dcerpc.NTSTATUS, arg:
|
||||
print 'The command returned an error: %s' % arg[1]
|
||||
|
||||
# Command handlers
|
||||
|
||||
def do_help(self, line):
|
||||
"""Displays on-line help for rpcclient commands."""
|
||||
Cmd.do_help(self, line)
|
||||
|
||||
def do_shell(self, line):
|
||||
|
||||
status = os.system(line)
|
||||
|
||||
if os.WIFEXITED(status):
|
||||
if os.WEXITSTATUS(status) != 0:
|
||||
print 'Command exited with code %d' % os.WEXITSTATUS(status)
|
||||
else:
|
||||
print 'Command exited with signal %d' % os.WTERMSIG(status)
|
||||
|
||||
def do_EOF(self, line):
|
||||
"""Exits rpcclient."""
|
||||
print
|
||||
sys.exit(0)
|
||||
|
||||
# SAMR pipe commands
|
||||
|
||||
def do_SamrEnumDomains(self, line):
|
||||
"""Enumerate domain names."""
|
||||
|
||||
usage = 'usage: SamrEnumDomains'
|
||||
|
||||
if line != '':
|
||||
print usage
|
||||
return
|
||||
|
||||
pipe = dcerpc.pipe_connect(
|
||||
self.binding,
|
||||
dcerpc.DCERPC_SAMR_UUID, dcerpc.DCERPC_SAMR_VERSION,
|
||||
self.domain, self.username, self.password)
|
||||
|
||||
connect_handle = samr.Connect(pipe)
|
||||
|
||||
for i in connect_handle.EnumDomains():
|
||||
print i
|
||||
|
||||
def do_SamrLookupDomain(self, line):
|
||||
"""Return the SID for a domain."""
|
||||
|
||||
usage = 'SamrLookupDomain DOMAIN'
|
||||
|
||||
parser = OptionParser(usage)
|
||||
options, args = parser.parse_args(string.split(line))
|
||||
|
||||
if len(args) != 1:
|
||||
print 'usage:', usage
|
||||
return
|
||||
|
||||
pipe = dcerpc.pipe_connect(
|
||||
self.binding,
|
||||
dcerpc.DCERPC_SAMR_UUID, dcerpc.DCERPC_SAMR_VERSION,
|
||||
self.domain, self.username, self.password)
|
||||
|
||||
connect_handle = samr.Connect(pipe)
|
||||
|
||||
print connect_handle.LookupDomain(args[0])
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# Parse command line
|
||||
|
||||
usage = 'rpcclient BINDING [options]'
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
print usage
|
||||
sys.exit(1)
|
||||
|
||||
binding = sys.argv[1]
|
||||
del(sys.argv[1])
|
||||
|
||||
if string.find(binding, ':') == -1:
|
||||
binding = 'ncacn_np:' + binding
|
||||
|
||||
parser = OptionParser(usage)
|
||||
|
||||
parser.add_option('-U', '--username', action='store', type='string',
|
||||
help='Use given credentials when connecting',
|
||||
metavar='DOMAIN\\username%password',
|
||||
dest='username')
|
||||
|
||||
parser.add_option('-c', '--command', action='store', type='string',
|
||||
help='Execute COMMAND', dest='command')
|
||||
|
||||
options, args = parser.parse_args()
|
||||
|
||||
# Break --username up into domain, usernamd and password
|
||||
|
||||
if not options.username:
|
||||
options.username = '%'
|
||||
|
||||
domain = ''
|
||||
if string.find(options.username, '\\') != -1:
|
||||
domain, options.username = string.split(options.username, '\\')
|
||||
|
||||
password = ''
|
||||
if string.find(options.username, '%') != -1:
|
||||
options.username, password = string.split(options.username, '%')
|
||||
|
||||
username = options.username
|
||||
|
||||
# Run command loop
|
||||
|
||||
c = rpcclient(binding, domain, username, password)
|
||||
|
||||
if options.command:
|
||||
c.onecmd(options.command)
|
||||
sys.exit(0)
|
||||
|
||||
while 1:
|
||||
try:
|
||||
c.cmdloop()
|
||||
except KeyboardInterrupt:
|
||||
print 'KeyboardInterrupt'
|
165
source/scripting/swig/samr.py
Normal file
165
source/scripting/swig/samr.py
Normal file
@ -0,0 +1,165 @@
|
||||
import dcerpc
|
||||
|
||||
def sid_to_string(sid):
|
||||
"""Convert a Python dictionary SID to a string SID."""
|
||||
|
||||
result = 'S-%d' % sid['sid_rev_num']
|
||||
|
||||
ia = sid['id_auth']
|
||||
|
||||
result = result + '-%u' % (ia[5] + (ia[4] << 8) + (ia[3] << 16) + \
|
||||
(ia[2] << 24))
|
||||
|
||||
for i in range(0, sid['num_auths']):
|
||||
result = result + '-%u' % 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():]
|
||||
|
||||
print map(type, sub_auths)
|
||||
|
||||
return {'sid_rev_num': sid_rev_num, 'id_auth': id_auth,
|
||||
'num_auths': num_auths, 'sub_auths': sub_auths}
|
||||
|
||||
class SamrHandle:
|
||||
|
||||
def __init__(self, pipe, handle):
|
||||
|
||||
self.pipe = pipe
|
||||
self.handle = handle
|
||||
|
||||
def __del__(self):
|
||||
|
||||
r = {}
|
||||
r['handle'] = self.handle
|
||||
|
||||
dcerpc.samr_Close(self.pipe, r)
|
||||
|
||||
class ConnectHandle(SamrHandle):
|
||||
|
||||
def EnumDomains(self):
|
||||
|
||||
r = {}
|
||||
r['connect_handle'] = self.handle
|
||||
r['resume_handle'] = 0
|
||||
r['buf_size'] = -1
|
||||
|
||||
domains = []
|
||||
|
||||
while 1:
|
||||
|
||||
result = dcerpc.samr_EnumDomains(self.pipe, r)
|
||||
|
||||
domains = domains + result['sam']['entries']
|
||||
|
||||
if result['result'] == dcerpc.STATUS_MORE_ENTRIES:
|
||||
r['resume_handle'] = result['resume_handle']
|
||||
continue
|
||||
|
||||
break
|
||||
|
||||
return map(lambda x: x['name']['name'], domains)
|
||||
|
||||
def LookupDomain(self, domain_name):
|
||||
|
||||
r = {}
|
||||
r['connect_handle'] = self.handle
|
||||
r['domain'] = {}
|
||||
r['domain']['name_len'] = 0
|
||||
r['domain']['name_size'] = 0
|
||||
r['domain']['name'] = domain_name
|
||||
|
||||
result = dcerpc.samr_LookupDomain(self.pipe, r)
|
||||
|
||||
return sid_to_string(result['sid'])
|
||||
|
||||
def OpenDomain(self, domain_sid, access_mask = 0x02000000):
|
||||
|
||||
r = {}
|
||||
r['connect_handle'] = self.handle
|
||||
r['access_mask'] = access_mask
|
||||
r['sid'] = string_to_sid(domain_sid)
|
||||
|
||||
result = dcerpc.samr_OpenDomain(self.pipe, r)
|
||||
|
||||
return DomainHandle(pipe, result['domain_handle'])
|
||||
|
||||
class DomainHandle(SamrHandle):
|
||||
|
||||
def QueryDomainInfo(self, level = 2):
|
||||
|
||||
r = {}
|
||||
r['domain_handle'] = self.domain_handle
|
||||
r['level'] = level
|
||||
|
||||
result = dcerpc.samr_QueryDomainInfo(pipe, r)
|
||||
|
||||
return result
|
||||
|
||||
def Connect(pipe, system_name = None, access_mask = 0x02000000):
|
||||
"""Connect to the SAMR pipe."""
|
||||
|
||||
r = {}
|
||||
r['system_name'] = system_name
|
||||
r['access_mask'] = access_mask
|
||||
|
||||
result = dcerpc.samr_Connect2(pipe, r)
|
||||
|
||||
return ConnectHandle(pipe, result['connect_handle'])
|
Loading…
Reference in New Issue
Block a user