s4/net: Use d_printf consistently when reporting errors.
[Samba/fernandojvsilva.git] / source4 / utils / net / net.c
blob9725402c7ffdcc4b9770edcf6dbd027187c13dd0
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;
133 PyObject *py_cmds, *py_cmd;
135 if (argc == 0) {
136 return usage_fn(ctx, argc, argv);
138 } else if (argc == 1 && strequal(argv[0], "help")) {
139 return net_help(ctx, functable);
142 for (i=0; functable[i].name; i++) {
143 if (strcasecmp_m(argv[0], functable[i].name) == 0)
144 return functable[i].fn(ctx, argc-1, argv+1);
147 py_cmds = py_commands();
148 if (py_cmds == NULL) {
149 return 1;
152 py_cmd = PyDict_GetItemString(py_cmds, argv[0]);
153 if (py_cmd != NULL) {
154 return py_call_with_string_args(py_cmd, "_run",
155 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", "change password\n", net_password, net_password_usage},
199 {"time", "get remote server's time\n", net_time, net_time_usage},
200 {"join", "join a domain\n", net_join, net_join_usage},
201 {"samdump", "dump the sam of a domain\n", net_samdump, net_samdump_usage},
202 {"export", "dump the sam of this domain\n", net_export, net_export_usage},
203 {"vampire", "join and syncronise an AD domain onto the local server\n", net_vampire, net_vampire_usage},
204 {"samsync", "synchronise into the local ldb the sam of an NT4 domain\n", net_samsync_ldb, net_samsync_ldb_usage},
205 {"user", "manage user accounts\n", net_user, net_user_usage},
206 {"machinepw", "Get a machine password out of our SAM\n", net_machinepw, net_machinepw_usage},
207 {NULL, NULL, NULL, NULL}
210 static int net_help_builtin(const struct net_functable *ftable)
212 int i = 0;
213 const char *name = ftable[i].name;
214 const char *desc = ftable[i].desc;
216 while (name && desc) {
217 if (strlen(name) > 7) {
218 d_printf("\t%s\t%s", name, desc);
219 } else {
220 d_printf("\t%s\t\t%s", name, desc);
222 name = ftable[++i].name;
223 desc = ftable[i].desc;
225 return 0;
228 static int net_help_python(void)
230 PyObject *py_cmds;
231 PyObject *key, *value;
232 Py_ssize_t pos = 0;
234 py_cmds = py_commands();
235 if (py_cmds == NULL) {
236 return 1;
239 while (PyDict_Next(py_cmds, &pos, &key, &value)) {
240 char *name, *desc;
241 PyObject *py_desc;
242 if (!PyString_Check(key)) {
243 d_printf("Command name not a string\n");
244 return 1;
246 name = PyString_AsString(key);
247 py_desc = PyObject_GetAttrString(value, "description");
248 if (py_desc == NULL) {
249 PyErr_Print();
250 return 1;
252 if (!PyString_Check(py_desc)) {
253 d_printf("Command description for %s not a string\n",
254 name);
255 return 1;
257 desc = PyString_AsString(py_desc);
258 if (strlen(name) > 7) {
259 d_printf("\t%s\t%s\n", name, desc);
260 } else {
261 d_printf("\t%s\t\t%s\n", name, desc);
264 return 0;
267 int net_help(struct net_context *ctx, const struct net_functable *ftable)
269 d_printf("Available commands:\n");
270 net_help_builtin(ftable);
271 net_help_python();
272 return 0;
275 static int net_usage(struct net_context *ctx, int argc, const char **argv)
277 d_printf("Usage:\n");
278 d_printf("net <command> [options]\n");
279 d_printf("Type 'net help' for all available commands\n");
280 return 0;
283 /****************************************************************************
284 main program
285 ****************************************************************************/
286 static int binary_net(int argc, const char **argv)
288 int opt,i;
289 int rc;
290 int argc_new;
291 const char **argv_new;
292 struct tevent_context *ev;
293 struct net_context *ctx = NULL;
294 poptContext pc;
295 struct poptOption long_options[] = {
296 POPT_AUTOHELP
297 POPT_COMMON_SAMBA
298 POPT_COMMON_CONNECTION
299 POPT_COMMON_CREDENTIALS
300 POPT_COMMON_VERSION
301 { NULL }
304 setlinebuf(stdout);
306 pc = poptGetContext("net", argc, (const char **) argv, long_options,
307 POPT_CONTEXT_KEEP_FIRST);
309 while((opt = poptGetNextOpt(pc)) != -1) {
310 switch (opt) {
311 default:
312 d_printf("Invalid option %s: %s\n",
313 poptBadOption(pc, 0), poptStrerror(opt));
314 net_usage(ctx, argc, argv);
315 exit(1);
319 argv_new = (const char **)poptGetArgs(pc);
321 argc_new = argc;
322 for (i=0; i<argc; i++) {
323 if (argv_new[i] == NULL) {
324 argc_new = i;
325 break;
329 if (argc_new < 2) {
330 return net_usage(ctx, argc, argv);
333 dcerpc_init(cmdline_lp_ctx);
335 ev = s4_event_context_init(NULL);
336 if (!ev) {
337 d_printf("Failed to create an event context\n");
338 exit(1);
340 ctx = talloc(ev, struct net_context);
341 if (!ctx) {
342 d_printf("Failed to talloc a net_context\n");
343 exit(1);
346 ZERO_STRUCTP(ctx);
347 ctx->lp_ctx = cmdline_lp_ctx;
348 ctx->credentials = cmdline_credentials;
349 ctx->event_ctx = ev;
351 py_load_samba_modules();
352 Py_Initialize();
353 py_update_path("bin"); /* FIXME: Can't assume this is always the case */
355 rc = net_run_function(ctx, argc_new-1, argv_new+1, net_functable,
356 net_usage);
358 if (rc != 0) {
359 DEBUG(0,("return code = %d\n", rc));
362 talloc_free(ev);
363 return rc;
366 int main(int argc, const char **argv)
368 return binary_net(argc, argv);