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"
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;
61 static PyObject *py_tuple_from_argv(int argc, const char *argv[])
66 l = PyTuple_New(argc);
71 for (i = 0; i < argc; i++) {
72 PyTuple_SetItem(l, i, PyString_FromString(argv[i]));
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);
88 py_method = PyObject_GetAttrString(self, method);
89 if (py_method == NULL) {
94 ret = PyObject_CallObject(py_method, args);
103 if (ret == Py_None) {
105 } else if (PyInt_Check(ret)) {
106 return PyInt_AsLong(ret);
108 fprintf(stderr, "Function return value type unexpected.\n");
113 static PyObject *py_commands(void)
115 PyObject *netcmd_module, *py_cmds;
116 netcmd_module = PyImport_ImportModule("samba.netcmd");
117 if (netcmd_module == NULL) {
122 py_cmds = PyObject_GetAttrString(netcmd_module, "commands");
123 if (py_cmds == NULL) {
128 if (!PyDict_Check(py_cmds)) {
129 d_printf("Python net commands is not a dictionary\n");
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))
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)
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) {
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,
191 d_printf("No usage information for command: %s\n", argv[0]);
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 {"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 {"drs", "Implements functionality offered by repadmin.exe utility in Windows\n", net_drs, net_drs_usage},
208 {NULL, NULL, NULL, NULL}
211 static int net_help_builtin(const struct net_functable *ftable)
214 const char *name = ftable[i].name;
215 const char *desc = ftable[i].desc;
217 while (name && desc) {
218 if (strlen(name) > 7) {
219 d_printf("\t%s\t%s", name, desc);
221 d_printf("\t%s\t\t%s", name, desc);
223 name = ftable[++i].name;
224 desc = ftable[i].desc;
229 static int net_help_python(void)
232 PyObject *key, *value;
235 py_cmds = py_commands();
236 if (py_cmds == NULL) {
240 while (PyDict_Next(py_cmds, &pos, &key, &value)) {
243 if (!PyString_Check(key)) {
244 d_printf("Command name not a string\n");
247 name = PyString_AsString(key);
248 py_desc = PyObject_GetAttrString(value, "description");
249 if (py_desc == NULL) {
253 if (!PyString_Check(py_desc)) {
254 d_printf("Command description for %s not a string\n",
258 desc = PyString_AsString(py_desc);
259 if (strlen(name) > 7) {
260 d_printf("\t%s\t%s\n", name, desc);
262 d_printf("\t%s\t\t%s\n", name, desc);
268 int net_help(struct net_context *ctx, const struct net_functable *ftable)
270 d_printf("Available commands:\n");
271 net_help_builtin(ftable);
276 static int net_usage(struct net_context *ctx, int argc, const char **argv)
278 d_printf("Usage:\n");
279 d_printf("net <command> [options]\n");
280 d_printf("Type 'net help' for all available commands\n");
284 /****************************************************************************
286 ****************************************************************************/
287 static int binary_net(int argc, const char **argv)
292 PyObject *py_cmds, *py_cmd;
293 const char **argv_new;
294 struct tevent_context *ev;
295 struct net_context *ctx = NULL;
297 struct poptOption long_options[] = {
300 POPT_COMMON_CONNECTION
301 POPT_COMMON_CREDENTIALS
308 dcerpc_init(cmdline_lp_ctx);
310 ev = s4_event_context_init(NULL);
312 d_printf("Failed to create an event context\n");
315 py_load_samba_modules();
317 PySys_SetArgv(argc, discard_const_p(char *, argv));
318 py_update_path("bin"); /* FIXME: Can't assume this is always the case */
320 py_cmds = py_commands();
321 if (py_cmds == NULL) {
326 py_cmd = PyDict_GetItemString(py_cmds, argv[1]);
327 if (py_cmd != NULL) {
328 rc = py_call_with_string_args(py_cmd, "_run",
335 pc = poptGetContext("net", argc, (const char **) argv, long_options,
336 POPT_CONTEXT_KEEP_FIRST);
338 while((opt = poptGetNextOpt(pc)) != -1) {
341 d_printf("Invalid option %s: %s\n",
342 poptBadOption(pc, 0), poptStrerror(opt));
343 net_usage(ctx, argc, argv);
348 argv_new = (const char **)poptGetArgs(pc);
351 for (i=0; i<argc; i++) {
352 if (argv_new[i] == NULL) {
359 return net_usage(ctx, argc, argv);
363 ctx = talloc(ev, struct net_context);
365 d_printf("Failed to talloc a net_context\n");
370 ctx->lp_ctx = cmdline_lp_ctx;
371 ctx->credentials = cmdline_credentials;
376 rc = net_run_function(ctx, argc_new-1, argv_new+1, net_functable,
380 DEBUG(0,("return code = %d\n", rc));
387 int main(int argc, const char **argv)
389 return binary_net(argc, argv);