1/*Some group management stuff*/ 2 3#include "libmsrpc.h" 4#include "test_util.h" 5 6int 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 473done: 474 cac_FreeHandle(hnd); 475 476 talloc_destroy(mem_ctx); 477 478 return 0; 479} 480 481