r23779: Change from v2 or later to v3 or later.
[samba.git] / examples / libmsrpc / cacusermgr / cacusermgr.c
1 /*
2  * Unix SMB/CIFS implementation. 
3  * cacusermgr main implementation.
4  *
5  * Copyright (C) Chris Nicholls     2005
6  * 
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation; either version 3 of the License, or (at your
10  * option) any later version.
11  * 
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  * 
17  * You should have received a copy of the GNU General Public License along with
18  * this program; if not, write to the Free Software Foundation, Inc., 675
19  * Mass Ave, Cambridge, MA 02139, USA.  */
20
21 #include "cacusermgr.h"
22
23 #define DEFAULT_MENU_LINES 15
24
25
26 void create_menu(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *dom_hnd) {
27    struct SamCreateUser  cu;
28    struct SamCreateGroup cg;
29
30    fstring in;
31    fstring tmp;
32
33    if(!hnd || !mem_ctx || !dom_hnd) {
34       printf("No Handle to SAM.\n");
35       return;
36    }
37
38    /*the menu*/
39    in[0] = '\0';
40    while(in[0] != 'c' && in[0] != 'C' && in[0] != 'q' && in[0] != 'Q') {
41       printf("\n");
42       printf("[u] Create User\n");
43       printf("[g] Create Group\n");
44       printf("[m] Create Machine Account\n");
45       printf("[c] Cancel\n\n");
46
47       printf("Command: ");
48       mgr_getline(in);
49
50       printf("\n");
51
52       switch(in[0]) {
53          case 'u': /*create user*/
54          case 'U':
55             ZERO_STRUCT(cu);
56             cu.in.dom_hnd = dom_hnd;
57             cu.in.acb_mask = ACB_NORMAL;
58
59             printf("Enter name: ");
60             mgr_getline(tmp);
61             cu.in.name = talloc_strdup(mem_ctx, tmp);
62
63             if(!cac_SamCreateUser(hnd, mem_ctx, &cu)) {
64                printerr("Could not create user.", hnd->status);
65             }
66             else {
67                user_menu(hnd, mem_ctx, dom_hnd, cu.out.user_hnd);
68             }
69
70             /*this will break the loop and send us back to the main menu*/
71             in[0] = 'c';
72             break;
73
74          case 'g': /*create group*/
75          case 'G':
76             ZERO_STRUCT(cg);
77             cg.in.dom_hnd = dom_hnd;
78             cg.in.access  = MAXIMUM_ALLOWED_ACCESS;
79
80             printf("Enter name: ");
81             mgr_getline(tmp);
82             cg.in.name = talloc_strdup(mem_ctx, tmp);
83
84             if(!cac_SamCreateGroup(hnd, mem_ctx, &cg)) {
85                printerr("Could not create group.", hnd->status);
86             }
87             else {
88                group_menu(hnd, mem_ctx, dom_hnd, cg.out.group_hnd);
89             }
90
91             /*this will break the loop and send us back to the main menu*/
92             in[0] = 'c';
93             break;
94
95          case 'm': /*create machine account*/
96          case 'M':
97             ZERO_STRUCT(cu);
98             cu.in.dom_hnd  = dom_hnd;
99             cu.in.acb_mask = ACB_WSTRUST;
100
101             printf("Enter machine name: ");
102             mgr_getline(tmp);
103
104             /*make sure we have a $ on the end*/
105             if(tmp[strlen(tmp) - 1] != '$')
106                cu.in.name = talloc_asprintf(mem_ctx, "%s$", tmp);
107             else
108                cu.in.name = talloc_strdup(mem_ctx, tmp);
109
110             strlower_m(cu.in.name);
111
112             printf("Creating account: %s\n", cu.in.name);
113
114             if(!cac_SamCreateUser(hnd, mem_ctx, &cu)) {
115                printerr("Could not create account.", hnd->status);
116             }
117             else {
118                user_menu(hnd, mem_ctx, dom_hnd, cu.out.user_hnd);
119             }
120
121             /*this will break the loop and send us back to the main menu*/
122             in[0] = 'c';
123             break;
124
125          case 'c': /*cancel*/
126          case 'C':
127          case 'q':
128          case 'Q':
129             /*do nothing*/
130             break;
131
132          default:
133             printf("Invalid option\n");
134       }
135    }
136
137    return;
138 }
139
140 void main_menu(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *dom_hnd) {
141    fstring in;
142    
143    uint32 rid_type = 0;
144
145    struct SamOpenUser   openu;
146    struct SamOpenGroup  openg;
147    struct SamEnumUsers  enumu;
148    struct SamEnumGroups enumg;
149    struct SamFlush      flush;
150
151    char *name = NULL;
152    uint32 rid = 0;
153
154    if(!hnd || !mem_ctx || !dom_hnd) {
155       printf("No handle to SAM.\n");
156       return;
157    }
158
159    /*initialize this here and don't worry about it later*/
160    ZERO_STRUCT(flush);
161    flush.in.dom_hnd = dom_hnd;
162
163    in[0] = '\0';
164
165    /*handle the menu and commands*/
166    while(in[0] != 'q' && in[0] != 'Q') {
167       printf("\n");
168
169       printf("[o] Open User or Group\n");
170       printf("[c] Create Account or Group\n");
171       printf("[u] List Users\n");
172       printf("[g] List Groups\n");
173       printf("[m] List Machine Accounts\n");
174       printf("[q] Quit\n\n");
175
176       printf("Command: ");
177
178       mgr_getline(in);
179
180       printf("\n");
181
182       switch(in[0]) {
183          case 'o': /*open user or group*/
184          case 'O':
185             printf("Enter RID or Name: ");
186             rid_type = rid_or_name(hnd, mem_ctx, dom_hnd, &rid, &name);
187
188             if(rid_type == CAC_USER_RID) {
189                ZERO_STRUCT(openu);
190                openu.in.dom_hnd = dom_hnd;
191                openu.in.rid     = rid;
192                openu.in.access  = MAXIMUM_ALLOWED_ACCESS;
193
194                if(!cac_SamOpenUser(hnd, mem_ctx, &openu))
195                   printerr("Could not open user.", hnd->status);
196                else {
197                   user_menu(hnd, mem_ctx, dom_hnd, openu.out.user_hnd);
198
199                   if(!cac_SamFlush(hnd, mem_ctx, &flush)) {
200                      printerr("Lost handle while flushing SAM.", hnd->status);
201                      /*we want to quit*/
202                      in[0] = 'q';
203                   }
204                }
205             }
206             else if(rid_type == CAC_GROUP_RID) {
207                ZERO_STRUCT(openg);
208                openg.in.dom_hnd = dom_hnd;
209                openg.in.rid     = rid;
210                openg.in.access  = MAXIMUM_ALLOWED_ACCESS;
211
212                if(!cac_SamOpenGroup(hnd, mem_ctx, &openg))
213                   printerr("Could not open group.", hnd->status);
214                else {
215                   group_menu(hnd, mem_ctx, dom_hnd, openg.out.group_hnd);
216
217                   if(!cac_SamFlush(hnd, mem_ctx, &flush)) {
218                      printerr("Lost handle while flushing SAM.", hnd->status);
219                      /*we want to quit*/
220                      in[0] = 'q';
221                   }
222                }
223             }
224             else {
225                printf("Unknown RID/Name.\n");
226             }
227                
228             break;
229
230          case 'c': /*create account/group*/
231          case 'C':
232             create_menu(hnd, mem_ctx, dom_hnd);
233             if(!cac_SamFlush(hnd, mem_ctx, &flush)) {
234                printerr("Lost handle while flushing SAM.", hnd->status);
235                /*we want to quit*/
236                in[0] = 'q';
237             }
238             break;
239
240          case 'u': /*list users*/
241          case 'U':
242             ZERO_STRUCT(enumu);
243             enumu.in.dom_hnd = dom_hnd;
244             enumu.in.acb_mask = ACB_NORMAL;
245
246             printf("Users:\n");
247             while(cac_SamEnumUsers(hnd, mem_ctx, &enumu)) {
248                print_rid_list(enumu.out.rids, enumu.out.names, enumu.out.num_users);
249             }
250             if(CAC_OP_FAILED(hnd->status))
251                printerr("Error occured while enumerating users.", hnd->status);
252             break;
253
254          case 'g': /*list groups*/
255          case 'G':
256             ZERO_STRUCT(enumg);
257             enumg.in.dom_hnd = dom_hnd;
258
259             while(cac_SamEnumGroups(hnd, mem_ctx, &enumg)) {
260                print_rid_list( enumg.out.rids, enumg.out.names, enumg.out.num_groups);
261             }
262
263             if(CAC_OP_FAILED(hnd->status))
264                printerr("Error occured while enumerating groups.", hnd->status);
265             break;
266
267          case 'm': /*list machine accounts*/
268          case 'M':
269             ZERO_STRUCT(enumu);
270             enumu.in.dom_hnd = dom_hnd;
271             enumu.in.acb_mask = ACB_WSTRUST;
272
273             printf("Users:\n");
274             while(cac_SamEnumUsers(hnd, mem_ctx, &enumu)) {
275                print_rid_list( enumu.out.rids, enumu.out.names, enumu.out.num_users);
276             }
277             if(CAC_OP_FAILED(hnd->status))
278                printerr("Error occured while enumerating accounts.", hnd->status);
279             break;
280
281          case 'q': /*quit*/
282          case 'Q':
283             /*just do nothing*/
284             break;
285
286          default:
287             printf("Invalid Command.\n");
288       }
289    }
290 }
291
292 int main(int argc, char **argv) {
293    CacServerHandle *hnd = NULL;
294    TALLOC_CTX *mem_ctx  = NULL;
295
296    struct SamOpenDomain sod;
297
298    mem_ctx = talloc_init("cacusermgr");
299    if(!mem_ctx) {
300       printf("Could not initialize Talloc Context\n");
301       exit(-1);
302    }
303
304    /**first initialize the server handle with what we have*/
305    hnd = cac_NewServerHandle(True);
306    if(!hnd) {
307       printf("Could not create server handle\n");
308       exit(-1);
309    }
310
311    /*fill in the blanks*/
312    if(!process_cmd_line(hnd, mem_ctx, argc, argv))
313       usage();
314
315    if(!cac_Connect(hnd, NULL)) {
316       printf("Could not connect to server %s. %s\n", hnd->server, nt_errstr(hnd->status));
317       exit(-1);
318    }
319
320    /*open the domain sam*/
321    ZERO_STRUCT(sod);
322    sod.in.access = MAXIMUM_ALLOWED_ACCESS;
323
324    if(!cac_SamOpenDomain(hnd, mem_ctx, &sod)) {
325       printf("Could not open handle to domain SAM. %s\n", nt_errstr(hnd->status));
326       goto cleanup;
327    }
328
329    main_menu(hnd, mem_ctx, sod.out.dom_hnd);
330
331 cleanup:
332
333    if(sod.out.dom_hnd)
334       cac_SamClose(hnd, mem_ctx, sod.out.dom_hnd);
335
336    if(sod.out.sam)
337       cac_SamClose(hnd, mem_ctx, sod.out.sam);
338
339    cac_FreeHandle(hnd);
340
341    talloc_destroy(mem_ctx);
342
343    return 0;
344 }