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
10   Largely rewritten by metze in August 2004
11
12   Originally written by Steve and Jim. Largely rewritten by tridge in
13   November 2001.
14
15   Reworked again by abartlet in December 2001
16
17   This program is free software; you can redistribute it and/or modify
18   it under the terms of the GNU General Public License as published by
19   the Free Software Foundation; either version 3 of the License, or
20   (at your option) any later version.
21
22   This program is distributed in the hope that it will be useful,
23   but WITHOUT ANY WARRANTY; without even the implied warranty of
24   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25   GNU General Public License for more details.
26
27   You should have received a copy of the GNU General Public License
28   along with this program.  If not, see <http://www.gnu.org/licenses/>.
29*/
30
31/*****************************************************/
32/*                                                   */
33/*   Distributed SMB/CIFS Server Management Utility  */
34/*                                                   */
35/*   The intent was to make the syntax similar       */
36/*   to the NET utility (first developed in DOS      */
37/*   with additional interesting & useful functions  */
38/*   added in later SMB server network operating     */
39/*   systems).                                       */
40/*                                                   */
41/*****************************************************/
42
43#include "includes.h"
44#include "utils/net/net.h"
45#include "lib/cmdline/popt_common.h"
46#include "lib/ldb/include/ldb.h"
47#include "librpc/rpc/dcerpc.h"
48#include "param/param.h"
49#include "lib/events/events.h"
50#include "auth/credentials/credentials.h"
51
52/*
53  run a function from a function table. If not found then
54  call the specified usage function
55*/
56int net_run_function(struct net_context *ctx,
57			int argc, const char **argv,
58			const struct net_functable *functable,
59			int (*usage_fn)(struct net_context *ctx, int argc, const char **argv))
60{
61	int i;
62
63	if (argc == 0) {
64		return usage_fn(ctx, argc, argv);
65
66	} else if (argc == 1 && strequal(argv[0], "help")) {
67		return net_help(ctx, functable);
68	}
69
70	for (i=0; functable[i].name; i++) {
71		if (strcasecmp_m(argv[0], functable[i].name) == 0)
72			return functable[i].fn(ctx, argc-1, argv+1);
73	}
74
75	d_printf("No command: %s\n", argv[0]);
76	return usage_fn(ctx, argc, argv);
77}
78
79/*
80  run a usage function from a function table. If not found then fail
81*/
82int net_run_usage(struct net_context *ctx,
83			int argc, const char **argv,
84			const struct net_functable *functable)
85{
86	int i;
87
88	for (i=0; functable[i].name; i++) {
89		if (strcasecmp_m(argv[0], functable[i].name) == 0)
90			if (functable[i].usage) {
91				return functable[i].usage(ctx, argc-1, argv+1);
92			}
93	}
94
95	d_printf("No usage information for command: %s\n", argv[0]);
96
97	return 1;
98}
99
100
101/* main function table */
102static const struct net_functable net_functable[] = {
103	{"password", "change password\n", net_password, net_password_usage},
104	{"time", "get remote server's time\n", net_time, net_time_usage},
105	{"join", "join a domain\n", net_join, net_join_usage},
106	{"samdump", "dump the sam of a domain\n", net_samdump, net_samdump_usage},
107	{"export", "dump the sam of this domain\n", net_export, net_export_usage},
108	{"vampire", "join and syncronise an AD domain onto the local server\n", net_vampire, net_vampire_usage},
109	{"samsync", "synchronise into the local ldb the sam of an NT4 domain\n", net_samsync_ldb, net_samsync_ldb_usage},
110	{"user", "manage user accounts\n", net_user, net_user_usage},
111	{"machinepw", "Get a machine password out of our SAM\n", net_machinepw, net_machinepw_usage},
112	{NULL, NULL, NULL, NULL}
113};
114
115int net_help(struct net_context *ctx, const struct net_functable *ftable)
116{
117	int i = 0;
118	const char *name = ftable[i].name;
119	const char *desc = ftable[i].desc;
120
121	d_printf("Available commands:\n");
122	while (name && desc) {
123		d_printf("\t%s\t\t%s", name, desc);
124		name = ftable[++i].name;
125		desc = ftable[i].desc;
126	}
127
128	return 0;
129}
130
131static int net_usage(struct net_context *ctx, int argc, const char **argv)
132{
133	d_printf("Usage:\n");
134	d_printf("net <command> [options]\n");
135	return 0;
136}
137
138/****************************************************************************
139  main program
140****************************************************************************/
141static int binary_net(int argc, const char **argv)
142{
143	int opt,i;
144	int rc;
145	int argc_new;
146	const char **argv_new;
147	struct tevent_context *ev;
148	struct net_context *ctx = NULL;
149	poptContext pc;
150	struct poptOption long_options[] = {
151		POPT_AUTOHELP
152		POPT_COMMON_SAMBA
153		POPT_COMMON_CONNECTION
154		POPT_COMMON_CREDENTIALS
155		POPT_COMMON_VERSION
156		{ NULL }
157	};
158
159	setlinebuf(stdout);
160
161	pc = poptGetContext("net", argc, (const char **) argv, long_options,
162			    POPT_CONTEXT_KEEP_FIRST);
163
164	while((opt = poptGetNextOpt(pc)) != -1) {
165		switch (opt) {
166		default:
167			d_printf("Invalid option %s: %s\n",
168				 poptBadOption(pc, 0), poptStrerror(opt));
169			net_usage(ctx, argc, argv);
170			exit(1);
171		}
172	}
173
174	argv_new = (const char **)poptGetArgs(pc);
175
176	argc_new = argc;
177	for (i=0; i<argc; i++) {
178		if (argv_new[i] == NULL) {
179			argc_new = i;
180			break;
181		}
182	}
183
184	if (argc_new < 2) {
185		return net_usage(ctx, argc, argv);
186	}
187
188	dcerpc_init(cmdline_lp_ctx);
189
190	ev = s4_event_context_init(NULL);
191	if (!ev) {
192		d_printf("Failed to create an event context\n");
193		exit(1);
194	}
195	ctx = talloc(ev, struct net_context);
196	if (!ctx) {
197		d_printf("Failed to talloc a net_context\n");
198		exit(1);
199	}
200
201	ZERO_STRUCTP(ctx);
202	ctx->lp_ctx = cmdline_lp_ctx;
203	ctx->credentials = cmdline_credentials;
204	ctx->event_ctx = ev;
205
206	rc = net_run_function(ctx, argc_new-1, argv_new+1, net_functable, net_usage);
207
208	if (rc != 0) {
209		DEBUG(0,("return code = %d\n", rc));
210	}
211
212	talloc_free(ev);
213	return rc;
214}
215
216 int main(int argc, const char **argv)
217{
218	return binary_net(argc, argv);
219}
220