| 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 2 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 | }
|
|---|