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 /*****************************************************/
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"
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);
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) {
109 py_cmds = PyObject_GetAttrString(netcmd_module, "commands");
110 if (py_cmds == NULL) {
115 if (!PyDict_Check(py_cmds)) {
116 d_printf("Python net commands is not a dictionary\n");
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))
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)
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) {
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,
178 d_printf("No usage information for command: %s\n", argv[0]);
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)
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);
208 d_printf("\t%s\t\t%s", name, desc);
210 name = ftable[++i].name;
211 desc = ftable[i].desc;
216 static int net_help_python(void)
219 PyObject *key, *value;
222 py_cmds = py_commands();
223 if (py_cmds == NULL) {
227 while (PyDict_Next(py_cmds, &pos, &key, &value)) {
230 if (!PyString_Check(key)) {
231 d_printf("Command name not a string\n");
234 name = PyString_AsString(key);
235 py_desc = PyObject_GetAttrString(value, "description");
236 if (py_desc == NULL) {
240 if (!PyString_Check(py_desc)) {
241 d_printf("Command description for %s not a string\n",
245 desc = PyString_AsString(py_desc);
246 if (strlen(name) > 7) {
247 d_printf("\t%s\t%s\n", name, desc);
249 d_printf("\t%s\t\t%s\n", name, desc);
255 int net_help(struct net_context *ctx, const struct net_functable *ftable)
257 d_printf("Available commands:\n");
258 net_help_builtin(ftable);
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");
271 /****************************************************************************
273 ****************************************************************************/
274 static int binary_net(int argc, const char **argv)
279 PyObject *py_cmds, *py_cmd;
280 const char **argv_new;
281 struct tevent_context *ev;
282 struct net_context *ctx = NULL;
284 struct poptOption long_options[] = {
287 POPT_COMMON_CONNECTION
288 POPT_COMMON_CREDENTIALS
295 pc = poptGetContext("net", argc, (const char **) argv, long_options,
296 POPT_CONTEXT_KEEP_FIRST);
298 while((opt = poptGetNextOpt(pc)) != -1) {
301 d_printf("Invalid option %s: %s\n",
302 poptBadOption(pc, 0), poptStrerror(opt));
303 net_usage(ctx, argc, argv);
308 argv_new = (const char **)poptGetArgs(pc);
311 for (i=0; i<argc; i++) {
312 if (argv_new[i] == NULL) {
319 return net_usage(ctx, argc, argv);
322 dcerpc_init(cmdline_lp_ctx);
324 ev = s4_event_context_init(NULL);
326 d_printf("Failed to create an event context\n");
329 ctx = talloc(ev, struct net_context);
331 d_printf("Failed to talloc a net_context\n");
336 ctx->lp_ctx = cmdline_lp_ctx;
337 ctx->credentials = cmdline_credentials;
340 py_load_samba_modules();
342 py_update_path("bin"); /* FIXME: Can't assume this is always the case */
344 py_cmds = py_commands();
345 if (py_cmds == NULL) {
349 py_cmd = PyDict_GetItemString(py_cmds, argv[1]);
350 if (py_cmd != NULL) {
351 rc = py_call_with_string_args(py_cmd, "_run",
357 rc = net_run_function(ctx, argc_new-1, argv_new+1, net_functable,
361 DEBUG(0,("return code = %d\n", rc));
368 int main(int argc, const char **argv)
370 return binary_net(argc, argv);