r18343: fixed setlinebuf() prototype, added test for it, and use it in two
[ira/wip.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 2 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, write to the Free Software
29    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 */
31  
32 /*****************************************************/
33 /*                                                   */
34 /*   Distributed SMB/CIFS Server Management Utility  */
35 /*                                                   */
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     */
40 /*   systems).                                       */
41 /*                                                   */
42 /*****************************************************/
43
44 #include "includes.h"
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
50 /*
51   run a function from a function table. If not found then
52   call the specified usage function 
53 */
54 int net_run_function(struct net_context *ctx,
55                         int argc, const char **argv,
56                         const struct net_functable *functable, 
57                         int (*usage_fn)(struct net_context *ctx, int argc, const char **argv))
58 {
59         int i;
60
61         if (argc == 0) {
62                 return usage_fn(ctx, argc, argv);
63
64         } else if (argc == 1 && strequal(argv[0], "help")) {
65                 return net_help(ctx, functable);
66         }
67
68         for (i=0; functable[i].name; i++) {
69                 if (strcasecmp_m(argv[0], functable[i].name) == 0)
70                         return functable[i].fn(ctx, argc-1, argv+1);
71         }
72
73         d_printf("No command: %s\n", argv[0]);
74         return usage_fn(ctx, argc, argv);
75 }
76
77 /*
78   run a usage function from a function table. If not found then fail
79 */
80 int net_run_usage(struct net_context *ctx,
81                         int argc, const char **argv,
82                         const struct net_functable *functable)
83 {
84         int i;
85
86         for (i=0; functable[i].name; i++) {
87                 if (strcasecmp_m(argv[0], functable[i].name) == 0)
88                         if (functable[i].usage) {
89                                 return functable[i].usage(ctx, argc-1, argv+1);
90                         }
91         }
92
93         d_printf("No usage information for command: %s\n", argv[0]);
94
95         return 1;
96 }
97
98
99 /* main function table */
100 static const struct net_functable net_functable[] = {
101         {"password", "change password\n", net_password, net_password_usage},
102         {"time", "get remote server's time\n", net_time, net_time_usage},
103         {"join", "join a domain\n", net_join, net_join_usage},
104         {"samdump", "dump the sam of a domain\n", net_samdump, net_samdump_usage},
105         {"samsync", "synchronise into the local ldb the sam of a domain\n", net_samsync_ldb, net_samsync_ldb_usage},
106         {"user", "manage user accounts\n", net_user, net_user_usage},
107         {NULL, NULL, NULL, NULL}
108 };
109
110 int net_help(struct net_context *ctx, const struct net_functable *ftable)
111 {
112         int i = 0;
113         const char *name = ftable[i].name;
114         const char *desc = ftable[i].desc;
115
116         d_printf("Available commands:\n");
117         while (name && desc) {
118                 d_printf("\t%s\t\t%s", name, desc);
119                 name = ftable[++i].name;
120                 desc = ftable[i].desc;
121         }
122
123         return 0;
124 }
125
126 static int net_usage(struct net_context *ctx, int argc, const char **argv)
127 {
128         d_printf("Usage:\n");
129         d_printf("net <command> [options]\n");
130         return 0;
131 }
132
133 /****************************************************************************
134   main program
135 ****************************************************************************/
136 static int binary_net(int argc, const char **argv)
137 {
138         int opt,i;
139         int rc;
140         int argc_new;
141         const char **argv_new;
142         TALLOC_CTX *mem_ctx;
143         struct net_context *ctx = NULL;
144         poptContext pc;
145         struct poptOption long_options[] = {
146                 POPT_AUTOHELP
147                 POPT_COMMON_SAMBA
148                 POPT_COMMON_CONNECTION
149                 POPT_COMMON_CREDENTIALS
150                 POPT_COMMON_VERSION
151                 { NULL }
152         };
153
154         setlinebuf(stdout);
155
156         pc = poptGetContext("net", argc, (const char **) argv, long_options, 
157                             POPT_CONTEXT_KEEP_FIRST);
158
159         while((opt = poptGetNextOpt(pc)) != -1) {
160                 switch (opt) {
161                 default:
162                         d_printf("Invalid option %s: %s\n", 
163                                  poptBadOption(pc, 0), poptStrerror(opt));
164                         net_usage(ctx, argc, argv);
165                         exit(1);
166                 }
167         }
168
169         argv_new = (const char **)poptGetArgs(pc);
170
171         argc_new = argc;
172         for (i=0; i<argc; i++) {
173                 if (argv_new[i] == NULL) {
174                         argc_new = i;
175                         break;
176                 }
177         }
178
179         if (argc_new < 2) {
180                 return net_usage(ctx, argc, argv);
181         }
182
183         dcerpc_init();
184
185         ldb_global_init();
186
187         mem_ctx = talloc_init("net_context");
188         ctx = talloc(mem_ctx, struct net_context);
189         if (!ctx) {
190                 d_printf("talloc_init(net_context) failed\n");
191                 exit(1);
192         }
193
194         ZERO_STRUCTP(ctx);
195         ctx->mem_ctx = mem_ctx;
196         ctx->credentials = cmdline_credentials;
197
198         rc = net_run_function(ctx, argc_new-1, argv_new+1, net_functable, net_usage);
199
200         if (rc != 0) {
201                 DEBUG(0,("return code = %d\n", rc));
202         }
203
204         talloc_free(mem_ctx);
205         return rc;
206 }
207
208  int main(int argc, const char **argv)
209 {
210         return binary_net(argc, argv);
211 }