s3-torture: run_locktest2(): replace cli_lock() with cli_lock32()
[Samba/gebeck_regimport.git] / source4 / samba_tool / samba_tool.c
blobce2294442035e9cbc293b547cdffb67e71cd14c4
1 /*
2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
4 Copyright (C) 2001 Steve French (sfrench@us.ibm.com)
5 Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com)
6 Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
7 Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
8 Copyright (C) 2004 Stefan Metzmacher (metze@samba.org)
9 Copyright (C) 2009 Jelmer Vernooij (jelmer@samba.org)
11 Largely rewritten by metze in August 2004
13 Originally written by Steve and Jim. Largely rewritten by tridge in
14 November 2001.
16 Reworked again by abartlet in December 2001
18 This program is free software; you can redistribute it and/or modify
19 it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 3 of the License, or
21 (at your option) any later version.
23 This program is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 GNU General Public License for more details.
28 You should have received a copy of the GNU General Public License
29 along with this program. If not, see <http://www.gnu.org/licenses/>.
32 /*****************************************************/
33 /* */
34 /* Distributed SMB/CIFS Server Management Utility */
35 /* */
36 /* The intent was to make the syntax similar */
37 /* to the NET utility (first developed in DOS */
38 /* with additional interesting & useful functions */
39 /* added in later SMB server network operating */
40 /* systems). */
41 /* */
42 /*****************************************************/
44 #include <Python.h>
45 #include "includes.h"
46 #include "samba_tool/samba_tool.h"
47 #include "lib/cmdline/popt_common.h"
48 #include <ldb.h>
49 #include "librpc/rpc/dcerpc.h"
50 #include "param/param.h"
51 #include "lib/events/events.h"
52 #include "auth/credentials/credentials.h"
53 #include "scripting/python/modules.h"
55 /* There's no Py_ssize_t in 2.4, apparently */
56 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
57 typedef int Py_ssize_t;
58 #endif
60 static PyObject *py_tuple_from_argv(int argc, const char *argv[])
62 PyObject *l;
63 Py_ssize_t i;
65 l = PyTuple_New(argc);
66 if (l == NULL) {
67 return NULL;
70 for (i = 0; i < argc; i++) {
71 PyTuple_SetItem(l, i, PyString_FromString(argv[i]));
74 return l;
77 static int py_call_with_string_args(PyObject *self, const char *method, int argc, const char *argv[])
79 PyObject *ret, *args, *py_method;
81 args = py_tuple_from_argv(argc, argv);
82 if (args == NULL) {
83 PyErr_Print();
84 return 1;
87 py_method = PyObject_GetAttrString(self, method);
88 if (py_method == NULL) {
89 PyErr_Print();
90 return 1;
93 ret = PyObject_CallObject(py_method, args);
95 Py_DECREF(args);
97 if (ret == NULL) {
98 PyErr_Print();
99 return 1;
102 if (ret == Py_None) {
103 return 0;
104 } else if (PyInt_Check(ret)) {
105 return PyInt_AsLong(ret);
106 } else {
107 fprintf(stderr, "Function return value type unexpected.\n");
108 return -1;
112 static PyObject *py_commands(void)
114 PyObject *netcmd_module, *py_cmds;
115 netcmd_module = PyImport_ImportModule("samba.netcmd");
116 if (netcmd_module == NULL) {
117 PyErr_Print();
118 return NULL;
121 py_cmds = PyObject_GetAttrString(netcmd_module, "commands");
122 if (py_cmds == NULL) {
123 PyErr_Print();
124 return NULL;
127 if (!PyDict_Check(py_cmds)) {
128 d_printf("Python net commands is not a dictionary\n");
129 return NULL;
132 return py_cmds;
136 run a function from a function table. If not found then
137 call the specified usage function
139 int net_run_function(struct net_context *ctx,
140 int argc, const char **argv,
141 const struct net_functable *functable,
142 int (*usage_fn)(struct net_context *ctx, int argc, const char **argv))
144 int i;
146 if (argc == 0) {
147 return usage_fn(ctx, argc, argv);
149 } else if (argc == 1 && strequal(argv[0], "help")) {
150 return net_help(ctx, functable);
153 for (i=0; functable[i].name; i++) {
154 if (strcasecmp_m(argv[0], functable[i].name) == 0)
155 return functable[i].fn(ctx, argc-1, argv+1);
158 d_printf("No command: '%s'\n", argv[0]);
159 return usage_fn(ctx, argc, argv);
163 run a usage function from a function table. If not found then fail
165 int net_run_usage(struct net_context *ctx,
166 int argc, const char **argv,
167 const struct net_functable *functable)
169 int i;
170 PyObject *py_cmds, *py_cmd;
172 for (i=0; functable[i].name; i++) {
173 if (strcasecmp_m(argv[0], functable[i].name) == 0)
174 if (functable[i].usage) {
175 return functable[i].usage(ctx, argc-1, argv+1);
179 py_cmds = py_commands();
180 if (py_cmds == NULL) {
181 return 1;
184 py_cmd = PyDict_GetItemString(py_cmds, argv[0]);
185 if (py_cmd != NULL) {
186 return py_call_with_string_args(py_cmd, "usage", argc-1,
187 argv+1);
190 d_printf("No usage information for command: %s\n", argv[0]);
192 return 1;
196 /* main function table */
197 static const struct net_functable net_functable[] = {
198 {"password", "Changes/Sets the password on a user account [server connection needed]\n", net_password, net_password_usage},
199 {"samdump", "dump the sam of a domain\n", net_samdump, net_samdump_usage},
200 {"samsync", "synchronise into the local ldb the sam of an NT4 domain\n", net_samsync_ldb, net_samsync_ldb_usage},
201 {"gpo", "Administer group policies\n", net_gpo, net_gpo_usage},
202 {NULL, NULL, NULL, NULL}
205 static int net_help_builtin(const struct net_functable *ftable)
207 int i = 0;
208 const char *name = ftable[i].name;
209 const char *desc = ftable[i].desc;
211 while (name && desc) {
212 if (strlen(name) > 7) {
213 d_printf("\t%s\t%s", name, desc);
214 } else {
215 d_printf("\t%s\t\t%s", name, desc);
217 name = ftable[++i].name;
218 desc = ftable[i].desc;
220 return 0;
223 static int net_help_python(void)
225 PyObject *py_cmds;
226 PyObject *key, *value;
227 Py_ssize_t pos = 0;
229 py_cmds = py_commands();
230 if (py_cmds == NULL) {
231 return 1;
234 while (PyDict_Next(py_cmds, &pos, &key, &value)) {
235 char *name, *desc;
236 PyObject *py_desc;
237 if (!PyString_Check(key)) {
238 d_printf("Command name not a string\n");
239 return 1;
241 name = PyString_AsString(key);
242 py_desc = PyObject_GetAttrString(value, "description");
243 if (py_desc == NULL) {
244 PyErr_Print();
245 return 1;
247 if (!PyString_Check(py_desc)) {
248 d_printf("Command description for %s not a string\n",
249 name);
250 return 1;
252 desc = PyString_AsString(py_desc);
253 if (strlen(name) > 7) {
254 d_printf("\t%s\t%s\n", name, desc);
255 } else {
256 d_printf("\t%s\t\t%s\n", name, desc);
259 return 0;
262 int net_help(struct net_context *ctx, const struct net_functable *ftable)
264 d_printf("Available commands:\n");
265 net_help_builtin(ftable);
266 net_help_python();
267 return 0;
270 static int net_usage(struct net_context *ctx, int argc, const char **argv)
272 d_printf("Usage:\n");
273 d_printf("samba-tool <command> [options]\n");
274 net_help(ctx, net_functable);
275 return -1;
278 /****************************************************************************
279 main program
280 ****************************************************************************/
281 static int binary_net(int argc, const char **argv)
283 int opt,i;
284 int rc;
285 int argc_new;
286 PyObject *py_cmds, *py_cmd;
287 const char **argv_new;
288 struct tevent_context *ev;
289 struct net_context *ctx = NULL;
290 poptContext pc;
291 struct poptOption long_options[] = {
292 POPT_AUTOHELP
293 POPT_COMMON_SAMBA
294 POPT_COMMON_CONNECTION
295 POPT_COMMON_CREDENTIALS
296 POPT_COMMON_VERSION
297 { NULL }
300 setlinebuf(stdout);
302 dcerpc_init();
304 ev = s4_event_context_init(NULL);
305 if (!ev) {
306 d_printf("Failed to create an event context\n");
307 exit(1);
309 Py_Initialize();
310 PySys_SetArgv(argc, discard_const_p(char *, argv));
311 py_update_path(); /* Put the Samba path at the start of sys.path */
313 py_cmds = py_commands();
314 if (py_cmds == NULL) {
315 return 1;
318 for (i=1; i<argc; i++) {
319 if (argv[i][0] != '-') {
320 py_cmd = PyDict_GetItemString(py_cmds, argv[i]);
321 if (py_cmd != NULL) {
322 rc = py_call_with_string_args(py_cmd, "_run",
323 argc-1, argv+1);
324 talloc_free(ev);
325 return rc;
330 pc = poptGetContext("net", argc, (const char **) argv, long_options,
331 POPT_CONTEXT_KEEP_FIRST);
333 while((opt = poptGetNextOpt(pc)) != -1) {
334 switch (opt) {
335 default:
336 d_printf("Invalid option %s: %s\n",
337 poptBadOption(pc, 0), poptStrerror(opt));
338 net_usage(ctx, argc, argv);
339 exit(1);
343 argv_new = (const char **)poptGetArgs(pc);
345 argc_new = argc;
346 for (i=0; i<argc; i++) {
347 if (argv_new[i] == NULL) {
348 argc_new = i;
349 break;
353 if (argc_new < 2) {
354 return net_usage(ctx, argc, argv);
358 ctx = talloc(ev, struct net_context);
359 if (!ctx) {
360 d_printf("Failed to talloc a net_context\n");
361 exit(1);
364 ZERO_STRUCTP(ctx);
365 ctx->lp_ctx = cmdline_lp_ctx;
366 ctx->credentials = cmdline_credentials;
367 ctx->event_ctx = ev;
371 rc = net_run_function(ctx, argc_new-1, argv_new+1, net_functable,
372 net_usage);
374 if (rc != 0) {
375 DEBUG(0,("return code = %d\n", rc));
378 talloc_free(ev);
379 return rc;
382 int main(int argc, const char **argv)
384 return binary_net(argc, argv);