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
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 /*****************************************************/
34 /* Distributed SMB/CIFS Server Management Utility */
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 */
42 /*****************************************************/
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"
55 static PyObject *py_tuple_from_argv(int argc, const char *argv[])
60 l = PyTuple_New(argc);
65 for (i = 0; i < argc; i++) {
66 PyTuple_SetItem(l, i, PyString_FromString(argv[i]));
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);
82 py_method = PyObject_GetAttrString(self, method);
83 if (py_method == NULL) {
88 ret = PyObject_CallObject(py_method, args);
99 } else if (PyInt_Check(ret)) {
100 return PyInt_AsLong(ret);
102 fprintf(stderr, "Function return value type unexpected.\n");
107 static PyObject *py_commands(void)
109 PyObject *netcmd_module, *py_cmds;
110 netcmd_module = PyImport_ImportModule("samba.netcmd");
111 if (netcmd_module == NULL) {
116 py_cmds = PyObject_GetAttrString(netcmd_module, "commands");
117 if (py_cmds == NULL) {
122 if (!PyDict_Check(py_cmds)) {
123 d_printf("Python net commands is not a dictionary\n");
131 run a function from a function table. If not found then
132 call the specified usage function
134 int net_run_function(struct net_context *ctx,
135 int argc, const char **argv,
136 const struct net_functable *functable,
137 int (*usage_fn)(struct net_context *ctx, int argc, const char **argv))
142 return usage_fn(ctx, argc, argv);
144 } else if (argc == 1 && strequal(argv[0], "help")) {
145 return net_help(ctx, functable);
148 for (i=0; functable[i].name; i++) {
149 if (strcasecmp_m(argv[0], functable[i].name) == 0)
150 return functable[i].fn(ctx, argc-1, argv+1);
153 d_printf("No command: %s\n", argv[0]);
154 return usage_fn(ctx, argc, argv);
158 run a usage function from a function table. If not found then fail
160 int net_run_usage(struct net_context *ctx,
161 int argc, const char **argv,
162 const struct net_functable *functable)
165 PyObject *py_cmds, *py_cmd;
167 for (i=0; functable[i].name; i++) {
168 if (strcasecmp_m(argv[0], functable[i].name) == 0)
169 if (functable[i].usage) {
170 return functable[i].usage(ctx, argc-1, argv+1);
174 py_cmds = py_commands();
175 if (py_cmds == NULL) {
179 py_cmd = PyDict_GetItemString(py_cmds, argv[0]);
180 if (py_cmd != NULL) {
181 return py_call_with_string_args(py_cmd, "usage", argc-1,
185 d_printf("No usage information for command: %s\n", argv[0]);
191 /* main function table */
192 static const struct net_functable net_functable[] = {
193 {"password", "change password\n", net_password, net_password_usage},
194 {"time", "get remote server's time\n", net_time, net_time_usage},
195 {"join", "join a domain\n", net_join, net_join_usage},
196 {"samdump", "dump the sam of a domain\n", net_samdump, net_samdump_usage},
197 {"export", "dump the sam of this domain\n", net_export, net_export_usage},
198 {"vampire", "join and syncronise an AD domain onto the local server\n", net_vampire, net_vampire_usage},
199 {"samsync", "synchronise into the local ldb the sam of an NT4 domain\n", net_samsync_ldb, net_samsync_ldb_usage},
200 {"user", "manage user accounts\n", net_user, net_user_usage},
201 {"machinepw", "Get a machine password out of our SAM\n", net_machinepw, net_machinepw_usage},
202 {NULL, NULL, NULL, NULL}
205 static int net_help_builtin(const struct net_functable *ftable)
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);
215 d_printf("\t%s\t\t%s", name, desc);
217 name = ftable[++i].name;
218 desc = ftable[i].desc;
223 static int net_help_python(void)
226 PyObject *key, *value;
229 py_cmds = py_commands();
230 if (py_cmds == NULL) {
234 while (PyDict_Next(py_cmds, &pos, &key, &value)) {
237 if (!PyString_Check(key)) {
238 d_printf("Command name not a string\n");
241 name = PyString_AsString(key);
242 py_desc = PyObject_GetAttrString(value, "description");
243 if (py_desc == NULL) {
247 if (!PyString_Check(py_desc)) {
248 d_printf("Command description for %s not a string\n",
252 desc = PyString_AsString(py_desc);
253 if (strlen(name) > 7) {
254 d_printf("\t%s\t%s\n", name, desc);
256 d_printf("\t%s\t\t%s\n", name, desc);
262 int net_help(struct net_context *ctx, const struct net_functable *ftable)
264 d_printf("Available commands:\n");
265 net_help_builtin(ftable);
270 static int net_usage(struct net_context *ctx, int argc, const char **argv)
272 d_printf("Usage:\n");
273 d_printf("net <command> [options]\n");
274 d_printf("Type 'net help' for all available commands\n");
278 /****************************************************************************
280 ****************************************************************************/
281 static int binary_net(int argc, const char **argv)
286 PyObject *py_cmds, *py_cmd;
287 const char **argv_new;
288 struct tevent_context *ev;
289 struct net_context *ctx = NULL;
291 struct poptOption long_options[] = {
294 POPT_COMMON_CONNECTION
295 POPT_COMMON_CREDENTIALS
302 dcerpc_init(cmdline_lp_ctx);
304 ev = s4_event_context_init(NULL);
306 d_printf("Failed to create an event context\n");
309 py_load_samba_modules();
311 PySys_SetArgv(argc, argv);
312 py_update_path("bin"); /* FIXME: Can't assume this is always the case */
314 py_cmds = py_commands();
315 if (py_cmds == NULL) {
320 py_cmd = PyDict_GetItemString(py_cmds, argv[1]);
321 if (py_cmd != NULL) {
322 rc = py_call_with_string_args(py_cmd, "_run",
329 pc = poptGetContext("net", argc, (const char **) argv, long_options,
330 POPT_CONTEXT_KEEP_FIRST);
332 while((opt = poptGetNextOpt(pc)) != -1) {
335 d_printf("Invalid option %s: %s\n",
336 poptBadOption(pc, 0), poptStrerror(opt));
337 net_usage(ctx, argc, argv);
342 argv_new = (const char **)poptGetArgs(pc);
345 for (i=0; i<argc; i++) {
346 if (argv_new[i] == NULL) {
353 return net_usage(ctx, argc, argv);
357 ctx = talloc(ev, struct net_context);
359 d_printf("Failed to talloc a net_context\n");
364 ctx->lp_ctx = cmdline_lp_ctx;
365 ctx->credentials = cmdline_credentials;
370 rc = net_run_function(ctx, argc_new-1, argv_new+1, net_functable,
374 DEBUG(0,("return code = %d\n", rc));
381 int main(int argc, const char **argv)
383 return binary_net(argc, argv);