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 26void 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 140void 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 292int 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 331cleanup: 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} 345