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