r3590: Add some more commands to rpcclient from a patch by jbm. Add
[samba.git] / source4 / scripting / swig / rpcclient
1 #!/usr/bin/python
2
3 import sys, os, string
4 from cmd import Cmd
5 from optparse import OptionParser
6 from pprint import pprint
7
8 import dcerpc, samr
9
10 class rpcclient(Cmd):
11
12     prompt = 'rpcclient$ '
13
14     def __init__(self, binding, domain, username, password):
15         Cmd.__init__(self)
16         self.binding = binding
17         self.domain = domain
18         self.username = username
19         self.password = password
20
21     def emptyline(self):
22
23         # Default for empty line is to repeat last command - yuck
24
25         pass
26
27     def onecmd(self, line):
28
29         # Override the onecmd() method so we can trap error returns
30
31         try:
32             Cmd.onecmd(self, line)
33         except dcerpc.NTSTATUS, arg:
34             print 'The command returned an error: %s' % arg[1]
35             
36     # Command handlers
37
38     def do_help(self, line):
39         """Displays on-line help for rpcclient commands."""
40         Cmd.do_help(self, line)
41
42     def do_shell(self, line):
43
44         status = os.system(line)
45
46         if os.WIFEXITED(status):
47             if os.WEXITSTATUS(status) != 0:
48                 print 'Command exited with code %d' % os.WEXITSTATUS(status)
49         else:
50             print 'Command exited with signal %d' % os.WTERMSIG(status)
51             
52     def do_EOF(self, line):
53         """Exits rpcclient."""
54         print
55         sys.exit(0)
56
57     # SAMR pipe commands
58
59     def do_SamrEnumDomains(self, line):
60         """Enumerate domain names."""
61         
62         usage = 'usage: SamrEnumDomains'
63
64         if line != '':
65             print usage
66             return
67
68         pipe = dcerpc.pipe_connect(
69             self.binding,
70             dcerpc.DCERPC_SAMR_UUID, dcerpc.DCERPC_SAMR_VERSION,
71             self.domain, self.username, self.password)
72
73         connect_handle = samr.Connect(pipe)
74
75         for i in connect_handle.EnumDomains():
76             print i
77
78     def do_SamrLookupDomain(self, line):
79         """Return the SID for a domain."""
80
81         usage = 'SamrLookupDomain DOMAIN'
82
83         parser = OptionParser(usage)
84         options, args = parser.parse_args(string.split(line))
85
86         if len(args) != 1:
87             print 'usage:', usage
88             return
89
90         pipe = dcerpc.pipe_connect(
91             self.binding,
92             dcerpc.DCERPC_SAMR_UUID, dcerpc.DCERPC_SAMR_VERSION,
93             self.domain, self.username, self.password)
94
95         connect_handle = samr.Connect(pipe)
96
97         print connect_handle.LookupDomain(args[0])
98
99     def do_SamrQueryDomInfo(self, line):
100         """Return information about a domain designated by its SID."""
101
102         usage = 'SamrQueryDomInfo DOMAIN_SID [info_level]'
103
104         parser = OptionParser(usage)
105         options, args = parser.parse_args(string.split(line))
106
107         if (len(args) == 0) or (len(args) > 2):
108             print 'usage:', usage
109             return
110
111         pipe = dcerpc.pipe_connect(
112             self.binding,
113             dcerpc.DCERPC_SAMR_UUID, dcerpc.DCERPC_SAMR_VERSION,
114             self.domain, self.username, self.password)
115
116         connect_handle = samr.Connect(pipe)
117         domain_handle = connect_handle.OpenDomain(args[0])
118
119         if (len(args) == 2):
120             result = domain_handle.QueryDomainInfo(int(args[1]))
121         else:
122             result = domain_handle.QueryDomainInfo()
123
124         pprint(result['info'])
125
126     def do_SamrQueryDomInfo2(self, line):
127         """Return information about a domain designated by its SID. (Windows 2000 and >)"""
128
129         usage = 'SamrQueryDomInfo2 DOMAIN_SID [info_level] (Windows 2000 and >)'
130         parser = OptionParser(usage)
131         options, args = parser.parse_args(string.split(line))
132
133         if (len(args) == 0) or (len(args) > 2):
134             print 'usage:', usage
135             return
136
137         pipe = dcerpc.pipe_connect(
138             self.binding,
139             dcerpc.DCERPC_SAMR_UUID, dcerpc.DCERPC_SAMR_VERSION,
140             self.domain, self.username, self.password)
141
142         connect_handle = samr.Connect(pipe)
143         domain_handle = connect_handle.OpenDomain(args[0])
144
145         if (len(args) == 2):
146             result = domain_handle.QueryDomainInfo2(int(args[1]))
147         else:
148             result = domain_handle.QueryDomainInfo2()
149
150         pprint(result['info'])
151
152     def do_SamrEnumDomainGroups(self, line):
153         """Return the list of groups of a domain designated by its SID."""
154
155         usage = 'SamrEnumDomainGroups DOMAIN_SID'
156
157         parser = OptionParser(usage)
158         options, args = parser.parse_args(string.split(line))
159
160         if len(args) != 1:
161             print 'usage:', usage
162             return
163
164         pipe = dcerpc.pipe_connect(
165             self.binding,
166             dcerpc.DCERPC_SAMR_UUID, dcerpc.DCERPC_SAMR_VERSION,
167             self.domain, self.username, self.password)
168
169         connect_handle = samr.Connect(pipe)     
170         domain_handle = connect_handle.OpenDomain(args[0])
171
172         result = domain_handle.EnumDomainGroups()
173
174         for r in result['sam']['entries']:
175             print r['name']['name']
176
177     def do_SamrEnumDomainAliases(self, line):
178         """Return the list of aliases (local groups) of a domain designated by its SID."""
179
180         usage = 'SamrEnumDomainAliases DOMAIN_SID'
181
182         parser = OptionParser(usage)
183         options, args = parser.parse_args(string.split(line))
184
185         if len(args) != 1:
186             print 'usage:', usage
187             return
188
189         pipe = dcerpc.pipe_connect(
190             self.binding,
191             dcerpc.DCERPC_SAMR_UUID, dcerpc.DCERPC_SAMR_VERSION,
192             self.domain, self.username, self.password)
193
194         connect_handle = samr.Connect(pipe)
195         domain_handle = connect_handle.OpenDomain(args[0])
196
197         result = domain_handle.EnumDomainAliases()
198
199         for r in result['sam']['entries']:
200             print r['name']['name']
201
202     def do_SamrEnumDomainUsers(self, line):
203         """Return the list of users of a domain designated by its SID."""
204
205         usage = 'SamrEnumDomainUsers DOMAIN_SID [user_account_flags]'
206
207         parser = OptionParser(usage)
208         options, args = parser.parse_args(string.split(line))
209
210         if (len(args) == 0) or (len(args) > 2):
211             print 'usage:', usage
212             return
213
214         pipe = dcerpc.pipe_connect(
215             self.binding,
216             dcerpc.DCERPC_SAMR_UUID, dcerpc.DCERPC_SAMR_VERSION,
217             self.domain, self.username, self.password)
218
219         connect_handle = samr.Connect(pipe)
220         domain_handle = connect_handle.OpenDomain(args[0])
221
222         if (len(args) == 2):
223             result = domain_handle.EnumDomainUsers(int(args[1]))
224         else:
225             result = domain_handle.EnumDomainUsers()
226
227         for r in result['sam']['entries']:
228             print r['name']['name']
229
230 if __name__ == '__main__':
231
232     # Parse command line
233
234     usage = 'rpcclient BINDING [options]'
235
236     if len(sys.argv) == 1:
237         print usage
238         sys.exit(1)
239
240     binding = sys.argv[1]
241     del(sys.argv[1])
242
243     if string.find(binding, ':') == -1:
244         binding = 'ncacn_np:' + binding
245
246     parser = OptionParser(usage)
247
248     parser.add_option('-U', '--username', action='store', type='string',
249                       help='Use given credentials when connecting',
250                       metavar='DOMAIN\\username%password',
251                       dest='username')
252
253     parser.add_option('-c', '--command', action='store', type='string',
254                       help='Execute COMMAND', dest='command')
255
256     options, args = parser.parse_args()
257
258     # Break --username up into domain, usernamd and password
259
260     if not options.username:
261         options.username = '%'
262
263     domain = ''
264     if string.find(options.username, '\\') != -1:
265         domain, options.username = string.split(options.username, '\\')
266
267     password = ''
268     if string.find(options.username, '%') != -1:
269         options.username, password  = string.split(options.username, '%')
270
271     username = options.username
272
273     # Run command loop
274
275     c = rpcclient(binding, domain, username, password)
276
277     if options.command:
278         c.onecmd(options.command)
279         sys.exit(0)
280
281     while 1:
282         try:
283             c.cmdloop()
284         except KeyboardInterrupt:
285             print 'KeyboardInterrupt'