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