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_commands(void)
57 PyObject
*netcmd_module
, *py_cmds
;
58 netcmd_module
= PyImport_ImportModule("samba.netcmd");
59 if (netcmd_module
== NULL
) {
64 py_cmds
= PyObject_GetAttrString(netcmd_module
, "commands");
65 if (py_cmds
== NULL
) {
70 if (!PyDict_Check(py_cmds
)) {
71 fprintf(stderr
, "Python net commands is not a dictionary\n");
79 run a function from a function table. If not found then
80 call the specified usage function
82 int net_run_function(struct net_context
*ctx
,
83 int argc
, const char **argv
,
84 const struct net_functable
*functable
,
85 int (*usage_fn
)(struct net_context
*ctx
, int argc
, const char **argv
))
88 PyObject
*py_cmds
, *py_cmd
;
91 return usage_fn(ctx
, argc
, argv
);
93 } else if (argc
== 1 && strequal(argv
[0], "help")) {
94 return net_help(ctx
, functable
);
97 for (i
=0; functable
[i
].name
; i
++) {
98 if (strcasecmp_m(argv
[0], functable
[i
].name
) == 0)
99 return functable
[i
].fn(ctx
, argc
-1, argv
+1);
102 py_cmds
= py_commands();
103 if (py_cmds
== NULL
) {
107 py_cmd
= PyDict_GetItemString(py_cmds
, argv
[0]);
108 if (py_cmd
!= NULL
) {
109 PyObject
*ret
= PyObject_CallMethod(py_cmd
, "run", "");
114 return PyInt_AsLong(ret
);
117 d_printf("No command: %s\n", argv
[0]);
118 return usage_fn(ctx
, argc
, argv
);
122 run a usage function from a function table. If not found then fail
124 int net_run_usage(struct net_context
*ctx
,
125 int argc
, const char **argv
,
126 const struct net_functable
*functable
)
129 PyObject
*py_cmds
, *py_cmd
;
131 for (i
=0; functable
[i
].name
; i
++) {
132 if (strcasecmp_m(argv
[0], functable
[i
].name
) == 0)
133 if (functable
[i
].usage
) {
134 return functable
[i
].usage(ctx
, argc
-1, argv
+1);
138 py_cmds
= py_commands();
139 if (py_cmds
== NULL
) {
143 py_cmd
= PyDict_GetItemString(py_cmds
, argv
[0]);
144 if (py_cmd
!= NULL
) {
145 PyObject
*ret
= PyObject_CallMethod(py_cmd
, "usage", "");
150 return PyInt_AsLong(ret
);
153 d_printf("No usage information for command: %s\n", argv
[0]);
159 /* main function table */
160 static const struct net_functable net_functable
[] = {
161 {"password", "change password\n", net_password
, net_password_usage
},
162 {"time", "get remote server's time\n", net_time
, net_time_usage
},
163 {"join", "join a domain\n", net_join
, net_join_usage
},
164 {"samdump", "dump the sam of a domain\n", net_samdump
, net_samdump_usage
},
165 {"export", "dump the sam of this domain\n", net_export
, net_export_usage
},
166 {"vampire", "join and syncronise an AD domain onto the local server\n", net_vampire
, net_vampire_usage
},
167 {"samsync", "synchronise into the local ldb the sam of an NT4 domain\n", net_samsync_ldb
, net_samsync_ldb_usage
},
168 {"user", "manage user accounts\n", net_user
, net_user_usage
},
169 {"machinepw", "Get a machine password out of our SAM\n", net_machinepw
, net_machinepw_usage
},
170 {NULL
, NULL
, NULL
, NULL
}
173 static int net_help_builtin(const struct net_functable
*ftable
)
176 const char *name
= ftable
[i
].name
;
177 const char *desc
= ftable
[i
].desc
;
179 while (name
&& desc
) {
180 if (strlen(name
) > 7) {
181 d_printf("\t%s\t%s", name
, desc
);
183 d_printf("\t%s\t\t%s", name
, desc
);
185 name
= ftable
[++i
].name
;
186 desc
= ftable
[i
].desc
;
191 static int net_help_python(void)
194 PyObject
*key
, *value
;
197 py_cmds
= py_commands();
198 if (py_cmds
== NULL
) {
202 while (PyDict_Next(py_cmds
, &pos
, &key
, &value
)) {
205 if (!PyString_Check(key
)) {
206 fprintf(stderr
, "Command name not a string\n");
209 name
= PyString_AsString(key
);
210 py_desc
= PyObject_GetAttrString(value
, "description");
211 if (py_desc
== NULL
) {
215 if (!PyString_Check(py_desc
)) {
216 fprintf(stderr
, "Command description for %s not a string\n", name
);
219 desc
= PyString_AsString(py_desc
);
220 if (strlen(name
) > 7) {
221 d_printf("\t%s\t%s", name
, desc
);
223 d_printf("\t%s\t\t%s", name
, desc
);
229 int net_help(struct net_context
*ctx
, const struct net_functable
*ftable
)
231 d_printf("Available commands:\n");
232 net_help_builtin(ftable
);
237 static int net_usage(struct net_context
*ctx
, int argc
, const char **argv
)
239 d_printf("Usage:\n");
240 d_printf("net <command> [options]\n");
241 d_printf("Type 'net help' for all available commands\n");
245 /****************************************************************************
247 ****************************************************************************/
248 static int binary_net(int argc
, const char **argv
)
253 const char **argv_new
;
254 struct tevent_context
*ev
;
255 struct net_context
*ctx
= NULL
;
257 struct poptOption long_options
[] = {
260 POPT_COMMON_CONNECTION
261 POPT_COMMON_CREDENTIALS
268 pc
= poptGetContext("net", argc
, (const char **) argv
, long_options
,
269 POPT_CONTEXT_KEEP_FIRST
);
271 while((opt
= poptGetNextOpt(pc
)) != -1) {
274 d_printf("Invalid option %s: %s\n",
275 poptBadOption(pc
, 0), poptStrerror(opt
));
276 net_usage(ctx
, argc
, argv
);
281 argv_new
= (const char **)poptGetArgs(pc
);
284 for (i
=0; i
<argc
; i
++) {
285 if (argv_new
[i
] == NULL
) {
292 return net_usage(ctx
, argc
, argv
);
295 dcerpc_init(cmdline_lp_ctx
);
297 ev
= s4_event_context_init(NULL
);
299 d_printf("Failed to create an event context\n");
302 ctx
= talloc(ev
, struct net_context
);
304 d_printf("Failed to talloc a net_context\n");
309 ctx
->lp_ctx
= cmdline_lp_ctx
;
310 ctx
->credentials
= cmdline_credentials
;
313 py_load_samba_modules();
315 py_update_path("bin"); /* FIXME: Can't assume this is always the case */
317 rc
= net_run_function(ctx
, argc_new
-1, argv_new
+1, net_functable
,
321 DEBUG(0,("return code = %d\n", rc
));
328 int main(int argc
, const char **argv
)
330 return binary_net(argc
, argv
);