s3: Fix build file due to file move. Use the new path of iniparser
[Samba/ekacnet.git] / source4 / utils / net / net.c
blob62d7afcbd95cf4635255278bc51238278c39e00b
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 "utils/net/net.h"
47 #include "lib/cmdline/popt_common.h"
48 #include "lib/ldb/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"
54 #include "utils/net/drs/net_drs.h"
56 /* There's no Py_ssize_t in 2.4, apparently */
57 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
58 typedef int Py_ssize_t;
59 #endif
61 static PyObject *py_tuple_from_argv(int argc, const char *argv[])
63 PyObject *l;
64 Py_ssize_t i;
66 l = PyTuple_New(argc);
67 if (l == NULL) {
68 return NULL;
71 for (i = 0; i < argc; i++) {
72 PyTuple_SetItem(l, i, PyString_FromString(argv[i]));
75 return l;
78 static int py_call_with_string_args(PyObject *self, const char *method, int argc, const char *argv[])
80 PyObject *ret, *args, *py_method;
82 args = py_tuple_from_argv(argc, argv);
83 if (args == NULL) {
84 PyErr_Print();
85 return 1;
88 py_method = PyObject_GetAttrString(self, method);
89 if (py_method == NULL) {
90 PyErr_Print();
91 return 1;
94 ret = PyObject_CallObject(py_method, args);
96 Py_DECREF(args);
98 if (ret == NULL) {
99 PyErr_Print();
100 return 1;
103 if (ret == Py_None) {
104 return 0;
105 } else if (PyInt_Check(ret)) {
106 return PyInt_AsLong(ret);
107 } else {
108 fprintf(stderr, "Function return value type unexpected.\n");
109 return -1;
113 static PyObject *py_commands(void)
115 PyObject *netcmd_module, *py_cmds;
116 netcmd_module = PyImport_ImportModule("samba.netcmd");
117 if (netcmd_module == NULL) {
118 PyErr_Print();
119 return NULL;
122 py_cmds = PyObject_GetAttrString(netcmd_module, "commands");
123 if (py_cmds == NULL) {
124 PyErr_Print();
125 return NULL;
128 if (!PyDict_Check(py_cmds)) {
129 d_printf("Python net commands is not a dictionary\n");
130 return NULL;
133 return py_cmds;
137 run a function from a function table. If not found then
138 call the specified usage function
140 int net_run_function(struct net_context *ctx,
141 int argc, const char **argv,
142 const struct net_functable *functable,
143 int (*usage_fn)(struct net_context *ctx, int argc, const char **argv))
145 int i;
147 if (argc == 0) {
148 return usage_fn(ctx, argc, argv);
150 } else if (argc == 1 && strequal(argv[0], "help")) {
151 return net_help(ctx, functable);
154 for (i=0; functable[i].name; i++) {
155 if (strcasecmp_m(argv[0], functable[i].name) == 0)
156 return functable[i].fn(ctx, argc-1, argv+1);
159 d_printf("No command: %s\n", argv[0]);
160 return usage_fn(ctx, argc, argv);
164 run a usage function from a function table. If not found then fail
166 int net_run_usage(struct net_context *ctx,
167 int argc, const char **argv,
168 const struct net_functable *functable)
170 int i;
171 PyObject *py_cmds, *py_cmd;
173 for (i=0; functable[i].name; i++) {
174 if (strcasecmp_m(argv[0], functable[i].name) == 0)
175 if (functable[i].usage) {
176 return functable[i].usage(ctx, argc-1, argv+1);
180 py_cmds = py_commands();
181 if (py_cmds == NULL) {
182 return 1;
185 py_cmd = PyDict_GetItemString(py_cmds, argv[0]);
186 if (py_cmd != NULL) {
187 return py_call_with_string_args(py_cmd, "usage", argc-1,
188 argv+1);
191 d_printf("No usage information for command: %s\n", argv[0]);
193 return 1;
197 /* main function table */
198 static const struct net_functable net_functable[] = {
199 {"password", "change password\n", net_password, net_password_usage},
200 {"time", "get remote server's time\n", net_time, net_time_usage},
201 {"join", "join a domain\n", net_join, net_join_usage},
202 {"samdump", "dump the sam of a domain\n", net_samdump, net_samdump_usage},
203 {"export", "dump the sam of this domain\n", net_export, net_export_usage},
204 {"vampire", "join and syncronise an AD domain onto the local server\n", net_vampire, net_vampire_usage},
205 {"samsync", "synchronise into the local ldb the sam of an NT4 domain\n", net_samsync_ldb, net_samsync_ldb_usage},
206 {"user", "manage user accounts\n", net_user, net_user_usage},
207 {"machinepw", "Get a machine password out of our SAM\n", net_machinepw, net_machinepw_usage},
208 {"drs", "Implements functionality offered by repadmin.exe utility in Windows\n", net_drs, net_drs_usage},
209 {NULL, NULL, NULL, NULL}
212 static int net_help_builtin(const struct net_functable *ftable)
214 int i = 0;
215 const char *name = ftable[i].name;
216 const char *desc = ftable[i].desc;
218 while (name && desc) {
219 if (strlen(name) > 7) {
220 d_printf("\t%s\t%s", name, desc);
221 } else {
222 d_printf("\t%s\t\t%s", name, desc);
224 name = ftable[++i].name;
225 desc = ftable[i].desc;
227 return 0;
230 static int net_help_python(void)
232 PyObject *py_cmds;
233 PyObject *key, *value;
234 Py_ssize_t pos = 0;
236 py_cmds = py_commands();
237 if (py_cmds == NULL) {
238 return 1;
241 while (PyDict_Next(py_cmds, &pos, &key, &value)) {
242 char *name, *desc;
243 PyObject *py_desc;
244 if (!PyString_Check(key)) {
245 d_printf("Command name not a string\n");
246 return 1;
248 name = PyString_AsString(key);
249 py_desc = PyObject_GetAttrString(value, "description");
250 if (py_desc == NULL) {
251 PyErr_Print();
252 return 1;
254 if (!PyString_Check(py_desc)) {
255 d_printf("Command description for %s not a string\n",
256 name);
257 return 1;
259 desc = PyString_AsString(py_desc);
260 if (strlen(name) > 7) {
261 d_printf("\t%s\t%s\n", name, desc);
262 } else {
263 d_printf("\t%s\t\t%s\n", name, desc);
266 return 0;
269 int net_help(struct net_context *ctx, const struct net_functable *ftable)
271 d_printf("Available commands:\n");
272 net_help_builtin(ftable);
273 net_help_python();
274 return 0;
277 static int net_usage(struct net_context *ctx, int argc, const char **argv)
279 d_printf("Usage:\n");
280 d_printf("net <command> [options]\n");
281 d_printf("Type 'net help' for all available commands\n");
282 return 0;
285 /****************************************************************************
286 main program
287 ****************************************************************************/
288 static int binary_net(int argc, const char **argv)
290 int opt,i;
291 int rc;
292 int argc_new;
293 PyObject *py_cmds, *py_cmd;
294 const char **argv_new;
295 struct tevent_context *ev;
296 struct net_context *ctx = NULL;
297 poptContext pc;
298 struct poptOption long_options[] = {
299 POPT_AUTOHELP
300 POPT_COMMON_SAMBA
301 POPT_COMMON_CONNECTION
302 POPT_COMMON_CREDENTIALS
303 POPT_COMMON_VERSION
304 { NULL }
307 setlinebuf(stdout);
309 dcerpc_init(cmdline_lp_ctx);
311 ev = s4_event_context_init(NULL);
312 if (!ev) {
313 d_printf("Failed to create an event context\n");
314 exit(1);
316 py_load_samba_modules();
317 Py_Initialize();
318 PySys_SetArgv(argc, argv);
319 py_update_path("bin"); /* FIXME: Can't assume this is always the case */
321 py_cmds = py_commands();
322 if (py_cmds == NULL) {
323 return 1;
326 if (argc > 1) {
327 py_cmd = PyDict_GetItemString(py_cmds, argv[1]);
328 if (py_cmd != NULL) {
329 rc = py_call_with_string_args(py_cmd, "_run",
330 argc-1, argv+1);
331 talloc_free(ev);
332 return rc;
336 pc = poptGetContext("net", argc, (const char **) argv, long_options,
337 POPT_CONTEXT_KEEP_FIRST);
339 while((opt = poptGetNextOpt(pc)) != -1) {
340 switch (opt) {
341 default:
342 d_printf("Invalid option %s: %s\n",
343 poptBadOption(pc, 0), poptStrerror(opt));
344 net_usage(ctx, argc, argv);
345 exit(1);
349 argv_new = (const char **)poptGetArgs(pc);
351 argc_new = argc;
352 for (i=0; i<argc; i++) {
353 if (argv_new[i] == NULL) {
354 argc_new = i;
355 break;
359 if (argc_new < 2) {
360 return net_usage(ctx, argc, argv);
364 ctx = talloc(ev, struct net_context);
365 if (!ctx) {
366 d_printf("Failed to talloc a net_context\n");
367 exit(1);
370 ZERO_STRUCTP(ctx);
371 ctx->lp_ctx = cmdline_lp_ctx;
372 ctx->credentials = cmdline_credentials;
373 ctx->event_ctx = ev;
377 rc = net_run_function(ctx, argc_new-1, argv_new+1, net_functable,
378 net_usage);
380 if (rc != 0) {
381 DEBUG(0,("return code = %d\n", rc));
384 talloc_free(ev);
385 return rc;
388 int main(int argc, const char **argv)
390 return binary_net(argc, argv);