Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-test
[gd/samba-autobuild/.git] / source4 / utils / net / net.c
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 */
56 int 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 */
82 int 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 */
102 static 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         {"vampire", "join and syncronise an AD domain onto the local server\n", net_vampire, net_vampire_usage},
108         {"samsync", "synchronise into the local ldb the sam of an NT4 domain\n", net_samsync_ldb, net_samsync_ldb_usage},
109         {"user", "manage user accounts\n", net_user, net_user_usage},
110         {NULL, NULL, NULL, NULL}
111 };
112
113 int net_help(struct net_context *ctx, const struct net_functable *ftable)
114 {
115         int i = 0;
116         const char *name = ftable[i].name;
117         const char *desc = ftable[i].desc;
118
119         d_printf("Available commands:\n");
120         while (name && desc) {
121                 d_printf("\t%s\t\t%s", name, desc);
122                 name = ftable[++i].name;
123                 desc = ftable[i].desc;
124         }
125
126         return 0;
127 }
128
129 static int net_usage(struct net_context *ctx, int argc, const char **argv)
130 {
131         d_printf("Usage:\n");
132         d_printf("net <command> [options]\n");
133         return 0;
134 }
135
136 /****************************************************************************
137   main program
138 ****************************************************************************/
139 static int binary_net(int argc, const char **argv)
140 {
141         int opt,i;
142         int rc;
143         int argc_new;
144         const char **argv_new;
145         struct event_context *ev;
146         struct net_context *ctx = NULL;
147         poptContext pc;
148         struct poptOption long_options[] = {
149                 POPT_AUTOHELP
150                 POPT_COMMON_SAMBA
151                 POPT_COMMON_CONNECTION
152                 POPT_COMMON_CREDENTIALS
153                 POPT_COMMON_VERSION
154                 { NULL }
155         };
156
157         setlinebuf(stdout);
158
159         pc = poptGetContext("net", argc, (const char **) argv, long_options, 
160                             POPT_CONTEXT_KEEP_FIRST);
161
162         while((opt = poptGetNextOpt(pc)) != -1) {
163                 switch (opt) {
164                 default:
165                         d_printf("Invalid option %s: %s\n", 
166                                  poptBadOption(pc, 0), poptStrerror(opt));
167                         net_usage(ctx, argc, argv);
168                         exit(1);
169                 }
170         }
171
172         argv_new = (const char **)poptGetArgs(pc);
173
174         argc_new = argc;
175         for (i=0; i<argc; i++) {
176                 if (argv_new[i] == NULL) {
177                         argc_new = i;
178                         break;
179                 }
180         }
181
182         if (argc_new < 2) {
183                 return net_usage(ctx, argc, argv);
184         }
185
186         dcerpc_init();
187
188         ev = event_context_init(NULL);
189         if (!ev) {
190                 d_printf("Failed to create an event context\n");
191                 exit(1);
192         }
193         ctx = talloc(ev, struct net_context);
194         if (!ctx) {
195                 d_printf("Failed to talloc a net_context\n");
196                 exit(1);
197         }
198
199         ZERO_STRUCTP(ctx);
200         ctx->lp_ctx = cmdline_lp_ctx;
201         ctx->credentials = cmdline_credentials;
202         ctx->event_ctx = ev;
203
204         rc = net_run_function(ctx, argc_new-1, argv_new+1, net_functable, net_usage);
205
206         if (rc != 0) {
207                 DEBUG(0,("return code = %d\n", rc));
208         }
209
210         talloc_free(ev);
211         return rc;
212 }
213
214  int main(int argc, const char **argv)
215 {
216         return binary_net(argc, argv);
217 }