1 | /*Some group management stuff*/
|
---|
2 |
|
---|
3 | #include "libmsrpc.h"
|
---|
4 | #include "test_util.h"
|
---|
5 |
|
---|
6 | int main(int argc, char **argv) {
|
---|
7 | CacServerHandle *hnd = NULL;
|
---|
8 | TALLOC_CTX *mem_ctx = NULL;
|
---|
9 |
|
---|
10 |
|
---|
11 | struct SamEnumGroups eg;
|
---|
12 | struct SamEnumUsers eu;
|
---|
13 | struct SamCreateGroup cg;
|
---|
14 | struct SamOpenGroup og;
|
---|
15 | struct SamGetGroupMembers ggm;
|
---|
16 | struct SamGetNamesFromRids gn;
|
---|
17 | struct SamAddGroupMember add;
|
---|
18 | struct SamRemoveGroupMember del;
|
---|
19 | struct SamSetGroupMembers set;
|
---|
20 | struct SamGetGroupsForUser gg;
|
---|
21 | struct SamOpenUser ou;
|
---|
22 | struct SamGetGroupInfo gi;
|
---|
23 | struct SamSetGroupInfo si;
|
---|
24 | struct SamRenameGroup rg;
|
---|
25 | struct SamGetSecurityObject gso;
|
---|
26 |
|
---|
27 | POLICY_HND *group_hnd = NULL;
|
---|
28 |
|
---|
29 | fstring tmp;
|
---|
30 | fstring input;
|
---|
31 |
|
---|
32 | int i;
|
---|
33 |
|
---|
34 | mem_ctx = talloc_init("cac_samgroup");
|
---|
35 |
|
---|
36 | hnd = cac_NewServerHandle(True);
|
---|
37 |
|
---|
38 | cac_parse_cmd_line(argc, argv, hnd);
|
---|
39 |
|
---|
40 | if(!cac_Connect(hnd, NULL)) {
|
---|
41 | fprintf(stderr, "Could not connect to server %s. Error: %s\n", hnd->server, nt_errstr(hnd->status));
|
---|
42 | exit(-1);
|
---|
43 | }
|
---|
44 |
|
---|
45 | struct SamOpenDomain sod;
|
---|
46 | ZERO_STRUCT(sod);
|
---|
47 |
|
---|
48 | sod.in.access = MAXIMUM_ALLOWED_ACCESS;
|
---|
49 |
|
---|
50 | if(!cac_SamOpenDomain(hnd, mem_ctx, &sod)) {
|
---|
51 | fprintf(stderr, "Could not open domain. Error: %s\n", nt_errstr(hnd->status));
|
---|
52 | goto done;
|
---|
53 | }
|
---|
54 |
|
---|
55 | tmp[0] = 0x00;
|
---|
56 | while(tmp[0] != 'q') {
|
---|
57 | printf("\n");
|
---|
58 | printf("[l]ist groups\n");
|
---|
59 | printf("[c]reate group\n");
|
---|
60 | printf("[o]pen group\n");
|
---|
61 | printf("[d]elete group\n");
|
---|
62 | printf("list [m]embers\n");
|
---|
63 | printf("list [u]sers\n");
|
---|
64 | printf("list [g]roup for users\n");
|
---|
65 | printf("[a]dd member\n");
|
---|
66 | printf("[r]emove member\n");
|
---|
67 | printf("[x] clear members\n");
|
---|
68 | printf("get group [i]nfo\n");
|
---|
69 | printf("[e]dit group info\n");
|
---|
70 | printf("[s]et members\n");
|
---|
71 | printf("re[n]ame group\n");
|
---|
72 | printf("[z] close group\n");
|
---|
73 | printf("[t] get security info\n");
|
---|
74 |
|
---|
75 | printf("[q]uit\n\n");
|
---|
76 | printf("Enter option: ");
|
---|
77 | cactest_readline(stdin, tmp);
|
---|
78 |
|
---|
79 | printf("\n");
|
---|
80 |
|
---|
81 | switch(tmp[0]) {
|
---|
82 | case 'c': /*create group*/
|
---|
83 | if(group_hnd != NULL) {
|
---|
84 | /*then we have an open handle.. close it*/
|
---|
85 | cac_SamClose(hnd, mem_ctx, group_hnd);
|
---|
86 | group_hnd = NULL;
|
---|
87 | }
|
---|
88 |
|
---|
89 | printf("Enter group name: ");
|
---|
90 | cactest_readline(stdin, input);
|
---|
91 |
|
---|
92 | ZERO_STRUCT(cg);
|
---|
93 |
|
---|
94 | cg.in.name = talloc_strdup(mem_ctx, input);
|
---|
95 | cg.in.access = MAXIMUM_ALLOWED_ACCESS;
|
---|
96 | cg.in.dom_hnd = sod.out.dom_hnd;
|
---|
97 |
|
---|
98 | if(!cac_SamCreateGroup(hnd, mem_ctx, &cg)) {
|
---|
99 | fprintf(stderr, "Could not create group. Error: %s\n", nt_errstr(hnd->status));
|
---|
100 | }
|
---|
101 | else {
|
---|
102 | printf("Created group %s\n", cg.in.name);
|
---|
103 |
|
---|
104 | group_hnd = cg.out.group_hnd;
|
---|
105 | }
|
---|
106 | break;
|
---|
107 |
|
---|
108 | case 'o': /*open group*/
|
---|
109 | if(group_hnd != NULL) {
|
---|
110 | /*then we have an open handle.. close it*/
|
---|
111 | cac_SamClose(hnd, mem_ctx, group_hnd);
|
---|
112 | group_hnd = NULL;
|
---|
113 | }
|
---|
114 |
|
---|
115 | ZERO_STRUCT(og);
|
---|
116 |
|
---|
117 | og.in.dom_hnd = sod.out.dom_hnd;
|
---|
118 | og.in.access = MAXIMUM_ALLOWED_ACCESS;
|
---|
119 |
|
---|
120 | printf("Enter RID: 0x");
|
---|
121 | scanf("%x", &og.in.rid);
|
---|
122 |
|
---|
123 | if(!cac_SamOpenGroup(hnd, mem_ctx, &og)) {
|
---|
124 | fprintf(stderr, "Could not open group. Error: %s\n", nt_errstr(hnd->status));
|
---|
125 | }
|
---|
126 | else {
|
---|
127 | printf("Opened group\n");
|
---|
128 | group_hnd = og.out.group_hnd;
|
---|
129 | }
|
---|
130 |
|
---|
131 | break;
|
---|
132 |
|
---|
133 | case 'l': /*list groups*/
|
---|
134 | ZERO_STRUCT(eg);
|
---|
135 | eg.in.dom_hnd = sod.out.dom_hnd;
|
---|
136 |
|
---|
137 | while(cac_SamEnumGroups(hnd, mem_ctx, &eg)) {
|
---|
138 | for(i = 0; i < eg.out.num_groups; i++) {
|
---|
139 | printf("RID: 0x%x Name: %s\n", eg.out.rids[i], eg.out.names[i]);
|
---|
140 | }
|
---|
141 | }
|
---|
142 |
|
---|
143 | if(CAC_OP_FAILED(hnd->status)) {
|
---|
144 | printf("Could not enumerate Groups. Error: %s\n", nt_errstr(hnd->status));
|
---|
145 | }
|
---|
146 |
|
---|
147 | break;
|
---|
148 |
|
---|
149 | case 'm': /*list group members*/
|
---|
150 | if(!group_hnd) {
|
---|
151 | printf("Must open group first!\n");
|
---|
152 | break;
|
---|
153 | }
|
---|
154 |
|
---|
155 | ZERO_STRUCT(ggm);
|
---|
156 | ggm.in.group_hnd = group_hnd;
|
---|
157 |
|
---|
158 | if(!cac_SamGetGroupMembers(hnd, mem_ctx, &ggm)) {
|
---|
159 | fprintf(stderr, "Could not get group members. Error: %s\n", nt_errstr(hnd->status));
|
---|
160 | break;
|
---|
161 | }
|
---|
162 |
|
---|
163 | printf("Group has %d members:\n", ggm.out.num_members);
|
---|
164 |
|
---|
165 | if(ggm.out.num_members == 0) /*just skip the rest of this case*/
|
---|
166 | break;
|
---|
167 |
|
---|
168 | /**get the user names*/
|
---|
169 | gn.in.dom_hnd = sod.out.dom_hnd;
|
---|
170 | gn.in.num_rids = ggm.out.num_members;
|
---|
171 | gn.in.rids = ggm.out.rids;
|
---|
172 |
|
---|
173 | if(!cac_SamGetNamesFromRids(hnd, mem_ctx, &gn)) {
|
---|
174 | fprintf(stderr, "Could not lookup names. Error: %s\n", nt_errstr(hnd->status));
|
---|
175 | break;
|
---|
176 | }
|
---|
177 |
|
---|
178 | for(i = 0; i < gn.out.num_names; i++) {
|
---|
179 | printf("RID: 0x%x Name: %s\n", gn.out.map[i].rid, gn.out.map[i].name);
|
---|
180 | }
|
---|
181 |
|
---|
182 | break;
|
---|
183 |
|
---|
184 | case 'd': /*delete group*/
|
---|
185 | if(!group_hnd) {
|
---|
186 | printf("Must open group first!\n");
|
---|
187 | break;
|
---|
188 | }
|
---|
189 |
|
---|
190 | if(!cac_SamDeleteGroup(hnd, mem_ctx, group_hnd)) {
|
---|
191 | fprintf(stderr, "Could not delete group. Error: %s\n", nt_errstr(hnd->status));
|
---|
192 | }
|
---|
193 | else {
|
---|
194 | printf("Deleted group.\n");
|
---|
195 | group_hnd = NULL;
|
---|
196 | }
|
---|
197 | break;
|
---|
198 |
|
---|
199 | case 'u': /*list users*/
|
---|
200 | ZERO_STRUCT(eu);
|
---|
201 |
|
---|
202 | eu.in.dom_hnd = sod.out.dom_hnd;
|
---|
203 |
|
---|
204 | while(cac_SamEnumUsers(hnd, mem_ctx, &eu)) {
|
---|
205 | for(i = 0; i < eu.out.num_users; i++) {
|
---|
206 | printf(" RID: 0x%x Name: %s\n", eu.out.rids[i], eu.out.names[i]);
|
---|
207 | }
|
---|
208 | }
|
---|
209 |
|
---|
210 | if(CAC_OP_FAILED(hnd->status)) {
|
---|
211 | printf("Could not enumerate users. Error: %s\n", nt_errstr(hnd->status));
|
---|
212 | }
|
---|
213 |
|
---|
214 | break;
|
---|
215 |
|
---|
216 | case 'a': /*add member to group*/
|
---|
217 | if(!group_hnd) {
|
---|
218 | printf("Must open group first!\n");
|
---|
219 | break;
|
---|
220 | }
|
---|
221 |
|
---|
222 | ZERO_STRUCT(add);
|
---|
223 |
|
---|
224 | add.in.group_hnd = group_hnd;
|
---|
225 |
|
---|
226 | printf("Enter user RID: 0x");
|
---|
227 | scanf("%x", &add.in.rid);
|
---|
228 |
|
---|
229 | if(!cac_SamAddGroupMember(hnd, mem_ctx, &add)) {
|
---|
230 | fprintf(stderr, "Could not add user to group. Error: %s\n", nt_errstr(hnd->status));
|
---|
231 | }
|
---|
232 | else {
|
---|
233 | printf("Successfully added user to group\n");
|
---|
234 | }
|
---|
235 | break;
|
---|
236 |
|
---|
237 | case 'r': /*remove user from group*/
|
---|
238 | if(!group_hnd) {
|
---|
239 | printf("Must open group first!\n");
|
---|
240 | break;
|
---|
241 | }
|
---|
242 |
|
---|
243 | ZERO_STRUCT(del);
|
---|
244 | del.in.group_hnd = group_hnd;
|
---|
245 |
|
---|
246 | printf("Enter RID: 0x");
|
---|
247 | scanf("%x", &del.in.rid);
|
---|
248 |
|
---|
249 | if(!cac_SamRemoveGroupMember(hnd, mem_ctx, &del)) {
|
---|
250 | fprintf(stderr, "Could not remove user from group. Error: %s\n", nt_errstr(hnd->status));
|
---|
251 | }
|
---|
252 | else {
|
---|
253 | printf("Removed user from group.\n");
|
---|
254 | }
|
---|
255 |
|
---|
256 | break;
|
---|
257 |
|
---|
258 | case 'x': /*clear group members*/
|
---|
259 | if(!group_hnd) {
|
---|
260 | printf("Must open group first!\n");
|
---|
261 | break;
|
---|
262 | }
|
---|
263 |
|
---|
264 | if(!cac_SamClearGroupMembers(hnd, mem_ctx, group_hnd)) {
|
---|
265 | fprintf(stderr, "Could not clear group members. Error: %s\n", nt_errstr(hnd->status));
|
---|
266 | }
|
---|
267 | else {
|
---|
268 | printf("Cleared group members\n");
|
---|
269 | }
|
---|
270 |
|
---|
271 | break;
|
---|
272 |
|
---|
273 | case 's': /*set members*/
|
---|
274 | if(!group_hnd) {
|
---|
275 | printf("Must open group first!\n");
|
---|
276 | break;
|
---|
277 | }
|
---|
278 |
|
---|
279 | ZERO_STRUCT(set);
|
---|
280 |
|
---|
281 | set.in.group_hnd = group_hnd;
|
---|
282 |
|
---|
283 | printf("Enter the number of members: ");
|
---|
284 | scanf("%d", &set.in.num_members);
|
---|
285 |
|
---|
286 | set.in.rids = TALLOC_ARRAY(mem_ctx, uint32, set.in.num_members);
|
---|
287 |
|
---|
288 | for(i = 0; i < set.in.num_members; i++) {
|
---|
289 | printf("Enter RID #%d: 0x", (i+1));
|
---|
290 | scanf("%x", (set.in.rids + i));
|
---|
291 | }
|
---|
292 |
|
---|
293 | if(!cac_SamSetGroupMembers(hnd, mem_ctx, &set)) {
|
---|
294 | printf("could not set members. Error: %s\n", nt_errstr(hnd->status));
|
---|
295 | }
|
---|
296 | else {
|
---|
297 | printf("Set users\n");
|
---|
298 | }
|
---|
299 |
|
---|
300 | break;
|
---|
301 |
|
---|
302 | case 'g': /*list groups for user*/
|
---|
303 | ZERO_STRUCT(ou);
|
---|
304 | ZERO_STRUCT(gg);
|
---|
305 |
|
---|
306 | printf("Enter username: ");
|
---|
307 | cactest_readline(stdin, input);
|
---|
308 |
|
---|
309 | if(input[0] != '\0') {
|
---|
310 | ou.in.name = talloc_strdup(mem_ctx, input);
|
---|
311 | }
|
---|
312 | else {
|
---|
313 | printf("Enter RID: 0x");
|
---|
314 | scanf("%x", &ou.in.rid);
|
---|
315 | }
|
---|
316 |
|
---|
317 | ou.in.access = MAXIMUM_ALLOWED_ACCESS;
|
---|
318 | ou.in.dom_hnd = sod.out.dom_hnd;
|
---|
319 |
|
---|
320 | if(!cac_SamOpenUser(hnd, mem_ctx, &ou)) {
|
---|
321 | fprintf(stderr, "Could not open user %s. Error: %s\n", ou.in.name, nt_errstr(hnd->status));
|
---|
322 | break;
|
---|
323 | }
|
---|
324 |
|
---|
325 | /*now find the groups*/
|
---|
326 | gg.in.user_hnd = ou.out.user_hnd;
|
---|
327 |
|
---|
328 | if(!cac_SamGetGroupsForUser(hnd, mem_ctx, &gg)) {
|
---|
329 | fprintf(stderr, "Could not get groups for user. Error: %s\n", nt_errstr(hnd->status));
|
---|
330 | break;
|
---|
331 | }
|
---|
332 |
|
---|
333 | cac_SamClose(hnd, mem_ctx, ou.out.user_hnd);
|
---|
334 |
|
---|
335 | ZERO_STRUCT(gn);
|
---|
336 |
|
---|
337 | gn.in.dom_hnd = sod.out.dom_hnd;
|
---|
338 | gn.in.num_rids = gg.out.num_groups;
|
---|
339 | gn.in.rids = gg.out.rids;
|
---|
340 |
|
---|
341 | if(!cac_SamGetNamesFromRids(hnd, mem_ctx, &gn)) {
|
---|
342 | fprintf(stderr, "Could not get names from RIDs. Error: %s\n", nt_errstr(hnd->status));
|
---|
343 | break;
|
---|
344 | }
|
---|
345 |
|
---|
346 | printf("%d groups: \n", gn.out.num_names);
|
---|
347 |
|
---|
348 | for(i = 0; i < gn.out.num_names; i++) {
|
---|
349 | printf("RID: 0x%x ", gn.out.map[i].rid);
|
---|
350 |
|
---|
351 | if(gn.out.map[i].found)
|
---|
352 | printf("Name: %s\n", gn.out.map[i].name);
|
---|
353 | else
|
---|
354 | printf("Unknown RID\n");
|
---|
355 | }
|
---|
356 |
|
---|
357 | break;
|
---|
358 |
|
---|
359 | case 'z': /*close group*/
|
---|
360 | if(!group_hnd) {
|
---|
361 | printf("Must open group first!\n");
|
---|
362 | break;
|
---|
363 | }
|
---|
364 |
|
---|
365 | if(!cac_SamClose(hnd, mem_ctx, group_hnd)) {
|
---|
366 | printf("Could not close group\n");
|
---|
367 | break;
|
---|
368 | }
|
---|
369 |
|
---|
370 | group_hnd = NULL;
|
---|
371 | break;
|
---|
372 |
|
---|
373 | case 'i': /*get group info*/
|
---|
374 | if(!group_hnd) {
|
---|
375 | printf("Must open group first!\n");
|
---|
376 | break;
|
---|
377 | }
|
---|
378 |
|
---|
379 | ZERO_STRUCT(gi);
|
---|
380 | gi.in.group_hnd = group_hnd;
|
---|
381 |
|
---|
382 | if(!cac_SamGetGroupInfo(hnd, mem_ctx, &gi)) {
|
---|
383 | printf("Could not get group info. Error: %s\n", nt_errstr(hnd->status));
|
---|
384 | }
|
---|
385 | else {
|
---|
386 | printf("Retrieved Group info\n");
|
---|
387 | print_cac_group_info(gi.out.info);
|
---|
388 | }
|
---|
389 |
|
---|
390 | break;
|
---|
391 |
|
---|
392 | case 'e': /*edit group info*/
|
---|
393 | if(!group_hnd) {
|
---|
394 | printf("Must open group first!\n");
|
---|
395 | break;
|
---|
396 | }
|
---|
397 |
|
---|
398 | ZERO_STRUCT(gi);
|
---|
399 | ZERO_STRUCT(si);
|
---|
400 |
|
---|
401 | gi.in.group_hnd = group_hnd;
|
---|
402 |
|
---|
403 | if(!cac_SamGetGroupInfo(hnd, mem_ctx, &gi)) {
|
---|
404 | printf("Could not get group info. Error: %s\n", nt_errstr(hnd->status));
|
---|
405 | break;
|
---|
406 | }
|
---|
407 |
|
---|
408 | edit_cac_group_info(mem_ctx, gi.out.info);
|
---|
409 |
|
---|
410 | si.in.group_hnd = group_hnd;
|
---|
411 | si.in.info = gi.out.info;
|
---|
412 |
|
---|
413 | if(!cac_SamSetGroupInfo(hnd, mem_ctx, &si)) {
|
---|
414 | printf("Could not set group info. Error: %s\n", nt_errstr(hnd->status));
|
---|
415 | }
|
---|
416 | else {
|
---|
417 | printf(" Done.\n");
|
---|
418 | }
|
---|
419 |
|
---|
420 | break;
|
---|
421 |
|
---|
422 | case 'n': /*rename group*/
|
---|
423 | if(!group_hnd) {
|
---|
424 | printf("Must open group first!\n");
|
---|
425 | break;
|
---|
426 | }
|
---|
427 |
|
---|
428 | ZERO_STRUCT(rg);
|
---|
429 |
|
---|
430 | printf("Enter new group name: ");
|
---|
431 | cactest_readline(stdin, tmp);
|
---|
432 |
|
---|
433 | rg.in.group_hnd = group_hnd;
|
---|
434 | rg.in.new_name = talloc_strdup(mem_ctx, tmp);
|
---|
435 |
|
---|
436 | if(!cac_SamRenameGroup(hnd, mem_ctx, &rg))
|
---|
437 | printf("Could not rename group. Error: %s\n", nt_errstr(hnd->status));
|
---|
438 | else
|
---|
439 | printf("Done.\n");
|
---|
440 |
|
---|
441 | break;
|
---|
442 | case 't': /*get security info*/
|
---|
443 | if(!group_hnd) {
|
---|
444 | printf("Must open group first!\n");
|
---|
445 | break;
|
---|
446 | }
|
---|
447 |
|
---|
448 | ZERO_STRUCT(gso);
|
---|
449 |
|
---|
450 | gso.in.pol = group_hnd;
|
---|
451 |
|
---|
452 | if(!cac_SamGetSecurityObject(hnd, mem_ctx, &gso)) {
|
---|
453 | printf("Could not get security descriptor info. Error: %s\n", nt_errstr(hnd->status));
|
---|
454 | }
|
---|
455 | else {
|
---|
456 | printf("Got it.\n");
|
---|
457 | }
|
---|
458 | break;
|
---|
459 |
|
---|
460 | case 'q':
|
---|
461 | break;
|
---|
462 |
|
---|
463 | default:
|
---|
464 | printf("Invalid command\n");
|
---|
465 | }
|
---|
466 | }
|
---|
467 |
|
---|
468 | cac_SamClose(hnd, mem_ctx, sod.out.dom_hnd);
|
---|
469 |
|
---|
470 | if(group_hnd)
|
---|
471 | cac_SamClose(hnd, mem_ctx, group_hnd);
|
---|
472 |
|
---|
473 | done:
|
---|
474 | cac_FreeHandle(hnd);
|
---|
475 |
|
---|
476 | talloc_destroy(mem_ctx);
|
---|
477 |
|
---|
478 | return 0;
|
---|
479 | }
|
---|
480 |
|
---|