net: Make arguments available to python commands as sys.argv.
[Samba/eduardoll.git] / source4 / utils / net / net.c
blob68fee9709ff7391aaf52668b1df29dcc8f28f583
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 "includes.h"
45 #include "utils/net/net.h"
46 #include "lib/cmdline/popt_common.h"
47 #include "lib/ldb/include/ldb.h"
48 #include "librpc/rpc/dcerpc.h"
49 #include "param/param.h"
50 #include "lib/events/events.h"
51 #include "auth/credentials/credentials.h"
52 #include <Python.h>
53 #include "scripting/python/modules.h"
55 static PyObject *py_tuple_from_argv(int argc, const char *argv[])
57 PyObject *l;
58 Py_ssize_t i;
60 l = PyTuple_New(argc);
61 if (l == NULL) {
62 return NULL;
65 for (i = 0; i < argc; i++) {
66 PyTuple_SetItem(l, i, PyString_FromString(argv[i]));
69 return l;
72 static int py_call_with_string_args(PyObject *self, const char *method, int argc, const char *argv[])
74 PyObject *ret, *args, *py_method;
76 args = py_tuple_from_argv(argc, argv);
77 if (args == NULL) {
78 PyErr_Print();
79 return 1;
82 py_method = PyObject_GetAttrString(self, method);
83 if (py_method == NULL) {
84 PyErr_Print();
85 return 1;
88 ret = PyObject_CallObject(py_method, args);
90 Py_DECREF(args);
92 if (ret == NULL) {
93 PyErr_Print();
94 return 1;
97 return PyInt_AsLong(ret);
100 static PyObject *py_commands(void)
102 PyObject *netcmd_module, *py_cmds;
103 netcmd_module = PyImport_ImportModule("samba.netcmd");
104 if (netcmd_module == NULL) {
105 PyErr_Print();
106 return NULL;
109 py_cmds = PyObject_GetAttrString(netcmd_module, "commands");
110 if (py_cmds == NULL) {
111 PyErr_Print();
112 return NULL;
115 if (!PyDict_Check(py_cmds)) {
116 d_printf("Python net commands is not a dictionary\n");
117 return NULL;
120 return py_cmds;
124 run a function from a function table. If not found then
125 call the specified usage function
127 int net_run_function(struct net_context *ctx,
128 int argc, const char **argv,
129 const struct net_functable *functable,
130 int (*usage_fn)(struct net_context *ctx, int argc, const char **argv))
132 int i;
134 if (argc == 0) {
135 return usage_fn(ctx, argc, argv);
137 } else if (argc == 1 && strequal(argv[0], "help")) {
138 return net_help(ctx, functable);
141 for (i=0; functable[i].name; i++) {
142 if (strcasecmp_m(argv[0], functable[i].name) == 0)
143 return functable[i].fn(ctx, argc-1, argv+1);
146 d_printf("No command: %s\n", argv[0]);
147 return usage_fn(ctx, argc, argv);
151 run a usage function from a function table. If not found then fail
153 int net_run_usage(struct net_context *ctx,
154 int argc, const char **argv,
155 const struct net_functable *functable)
157 int i;
158 PyObject *py_cmds, *py_cmd;
160 for (i=0; functable[i].name; i++) {
161 if (strcasecmp_m(argv[0], functable[i].name) == 0)
162 if (functable[i].usage) {
163 return functable[i].usage(ctx, argc-1, argv+1);
167 py_cmds = py_commands();
168 if (py_cmds == NULL) {
169 return 1;
172 py_cmd = PyDict_GetItemString(py_cmds, argv[0]);
173 if (py_cmd != NULL) {
174 return py_call_with_string_args(py_cmd, "usage", argc-1,
175 argv+1);
178 d_printf("No usage information for command: %s\n", argv[0]);
180 return 1;
184 /* main function table */
185 static const struct net_functable net_functable[] = {
186 {"password", "change password\n", net_password, net_password_usage},
187 {"time", "get remote server's time\n", net_time, net_time_usage},
188 {"join", "join a domain\n", net_join, net_join_usage},
189 {"samdump", "dump the sam of a domain\n", net_samdump, net_samdump_usage},
190 {"export", "dump the sam of this domain\n", net_export, net_export_usage},
191 {"vampire", "join and syncronise an AD domain onto the local server\n", net_vampire, net_vampire_usage},
192 {"samsync", "synchronise into the local ldb the sam of an NT4 domain\n", net_samsync_ldb, net_samsync_ldb_usage},
193 {"user", "manage user accounts\n", net_user, net_user_usage},
194 {"machinepw", "Get a machine password out of our SAM\n", net_machinepw, net_machinepw_usage},
195 {NULL, NULL, NULL, NULL}
198 static int net_help_builtin(const struct net_functable *ftable)
200 int i = 0;
201 const char *name = ftable[i].name;
202 const char *desc = ftable[i].desc;
204 while (name && desc) {
205 if (strlen(name) > 7) {
206 d_printf("\t%s\t%s", name, desc);
207 } else {
208 d_printf("\t%s\t\t%s", name, desc);
210 name = ftable[++i].name;
211 desc = ftable[i].desc;
213 return 0;
216 static int net_help_python(void)
218 PyObject *py_cmds;
219 PyObject *key, *value;
220 Py_ssize_t pos = 0;
222 py_cmds = py_commands();
223 if (py_cmds == NULL) {
224 return 1;
227 while (PyDict_Next(py_cmds, &pos, &key, &value)) {
228 char *name, *desc;
229 PyObject *py_desc;
230 if (!PyString_Check(key)) {
231 d_printf("Command name not a string\n");
232 return 1;
234 name = PyString_AsString(key);
235 py_desc = PyObject_GetAttrString(value, "description");
236 if (py_desc == NULL) {
237 PyErr_Print();
238 return 1;
240 if (!PyString_Check(py_desc)) {
241 d_printf("Command description for %s not a string\n",
242 name);
243 return 1;
245 desc = PyString_AsString(py_desc);
246 if (strlen(name) > 7) {
247 d_printf("\t%s\t%s\n", name, desc);
248 } else {
249 d_printf("\t%s\t\t%s\n", name, desc);
252 return 0;
255 int net_help(struct net_context *ctx, const struct net_functable *ftable)
257 d_printf("Available commands:\n");
258 net_help_builtin(ftable);
259 net_help_python();
260 return 0;
263 static int net_usage(struct net_context *ctx, int argc, const char **argv)
265 d_printf("Usage:\n");
266 d_printf("net <command> [options]\n");
267 d_printf("Type 'net help' for all available commands\n");
268 return 0;
271 /****************************************************************************
272 main program
273 ****************************************************************************/
274 static int binary_net(int argc, const char **argv)
276 int opt,i;
277 int rc;
278 int argc_new;
279 PyObject *py_cmds, *py_cmd;
280 const char **argv_new;
281 struct tevent_context *ev;
282 struct net_context *ctx = NULL;
283 poptContext pc;
284 struct poptOption long_options[] = {
285 POPT_AUTOHELP
286 POPT_COMMON_SAMBA
287 POPT_COMMON_CONNECTION
288 POPT_COMMON_CREDENTIALS
289 POPT_COMMON_VERSION
290 { NULL }
293 setlinebuf(stdout);
295 pc = poptGetContext("net", argc, (const char **) argv, long_options,
296 POPT_CONTEXT_KEEP_FIRST);
298 while((opt = poptGetNextOpt(pc)) != -1) {
299 switch (opt) {
300 default:
301 d_printf("Invalid option %s: %s\n",
302 poptBadOption(pc, 0), poptStrerror(opt));
303 net_usage(ctx, argc, argv);
304 exit(1);
308 argv_new = (const char **)poptGetArgs(pc);
310 argc_new = argc;
311 for (i=0; i<argc; i++) {
312 if (argv_new[i] == NULL) {
313 argc_new = i;
314 break;
318 if (argc_new < 2) {
319 return net_usage(ctx, argc, argv);
322 dcerpc_init(cmdline_lp_ctx);
324 ev = s4_event_context_init(NULL);
325 if (!ev) {
326 d_printf("Failed to create an event context\n");
327 exit(1);
329 ctx = talloc(ev, struct net_context);
330 if (!ctx) {
331 d_printf("Failed to talloc a net_context\n");
332 exit(1);
335 ZERO_STRUCTP(ctx);
336 ctx->lp_ctx = cmdline_lp_ctx;
337 ctx->credentials = cmdline_credentials;
338 ctx->event_ctx = ev;
340 py_load_samba_modules();
341 Py_Initialize();
342 PySys_SetArgv(argc, argv);
343 py_update_path("bin"); /* FIXME: Can't assume this is always the case */
345 py_cmds = py_commands();
346 if (py_cmds == NULL) {
347 return 1;
350 py_cmd = PyDict_GetItemString(py_cmds, argv_new[1]);
351 if (py_cmd != NULL) {
352 rc = py_call_with_string_args(py_cmd, "_run",
353 argc-1, argv+1);
354 talloc_free(ev);
355 return rc;
358 rc = net_run_function(ctx, argc_new-1, argv_new+1, net_functable,
359 net_usage);
361 if (rc != 0) {
362 DEBUG(0,("return code = %d\n", rc));
365 talloc_free(ev);
366 return rc;
369 int main(int argc, const char **argv)
371 return binary_net(argc, argv);