1/* 2 * Unix SMB/CIFS implementation. 3 * cacusermgr utility functions. 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/*prints usage and quits*/ 24void usage() { 25 printf("Usage:\n"); 26 printf(" cacusermgr [options] server\n\n"); 27 printf("options:\n"); 28 printf(" -u USERNAME Username to login with\n"); 29 printf(" -d/-w DOMAIN Domain name\n"); 30 printf(" -D LEVEL Debug level\n"); 31 printf(" -h Print this message\n"); 32 33 exit(1); 34} 35 36/*initializes values in the server handle from the command line returns 0 if there is a problem, non-zero if everything is ok*/ 37int process_cmd_line(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, int argc, char **argv) { 38 char op; 39 40 if(!hnd || !mem_ctx || !argc) 41 return 0; 42 43 while( (op = getopt(argc, argv, "u:U:d:w:W:D:h")) != -1) { 44 switch(op) { 45 case 'u': /*username*/ 46 case 'U': 47 if(optarg) 48 strncpy(hnd->username, optarg, sizeof(fstring)); 49 else 50 usage(); 51 break; 52 53 case 'd': /*domain name*/ 54 case 'w': 55 case 'W': 56 if(optarg) 57 strncpy(hnd->domain, optarg, sizeof(fstring)); 58 else 59 usage(); 60 break; 61 62 case 'D': /*debug level*/ 63 if(optarg) 64 hnd->debug = atoi(optarg); 65 else 66 usage(); 67 break; 68 69 case 'h': /*help*/ 70 usage(); 71 break; 72 73 case '?': 74 default: 75 printf("Unknown option -%c\n", op); 76 usage(); 77 } 78 } 79 80 if(optind >= argc) 81 usage(); 82 83 /*whatever is less should be the server*/ 84 strncpy(hnd->server, argv[optind], sizeof(fstring)); 85 86 return 1; 87} 88 89void mgr_getline(fstring line) { 90 91 fgets(line, sizeof(fstring), stdin); 92 93 if(line[strlen(line) - 1] == '\n') 94 line[strlen(line) - 1] = '\0'; 95 96} 97 98/*this is pretty similar to the other get_auth_data_fn's*/ 99void mgr_GetAuthDataFn(const char * pServer, 100 const char * pShare, 101 char * pWorkgroup, 102 int maxLenWorkgroup, 103 char * pUsername, 104 int maxLenUsername, 105 char * pPassword, 106 int maxLenPassword) 107 108{ 109 char temp[sizeof(fstring)]; 110 111 static char authUsername[sizeof(fstring)]; 112 static char authWorkgroup[sizeof(fstring)]; 113 static char authPassword[sizeof(fstring)]; 114 static char authSet = 0; 115 116 char *pass = NULL; 117 118 if (authSet) 119 { 120 strncpy(pWorkgroup, authWorkgroup, maxLenWorkgroup - 1); 121 strncpy(pUsername, authUsername, maxLenUsername - 1); 122 strncpy(pPassword, authPassword, maxLenPassword - 1); 123 } 124 else 125 { 126 if(pWorkgroup[0] != '\0') { 127 strncpy(authWorkgroup, pWorkgroup, maxLenWorkgroup - 1); 128 } 129 else { 130 d_printf("Domain: [%s] ", pWorkgroup); 131 mgr_getline(pWorkgroup); 132 133 if (temp[0] != '\0') 134 { 135 strncpy(pWorkgroup, temp, maxLenWorkgroup - 1); 136 strncpy(authWorkgroup, temp, maxLenWorkgroup - 1); 137 } 138 } 139 140 141 if(pUsername[0] != '\0') { 142 strncpy(authUsername, pUsername, maxLenUsername - 1); 143 } 144 else { 145 d_printf("Username: [%s] ", pUsername); 146 mgr_getline(pUsername); 147 148 if (temp[strlen(temp) - 1] == '\n') /* A new line? */ 149 { 150 temp[strlen(temp) - 1] = '\0'; 151 } 152 153 if (temp[0] != '\0') 154 { 155 strncpy(pUsername, temp, maxLenUsername - 1); 156 strncpy(authUsername, pUsername, maxLenUsername - 1); 157 } 158 } 159 if(pPassword[0] != '\0') { 160 strncpy(authPassword, pPassword, maxLenPassword - 1); 161 } 162 else { 163 pass = getpass("Password: "); 164 if (pass) 165 fstrcpy(temp, pass); 166 if (temp[strlen(temp) - 1] == '\n') /* A new line? */ 167 { 168 temp[strlen(temp) - 1] = '\0'; 169 } 170 if (temp[0] != '\0') 171 { 172 strncpy(pPassword, temp, maxLenPassword - 1); 173 strncpy(authPassword, pPassword, maxLenPassword - 1); 174 } 175 } 176 authSet = 1; 177 } 178} 179 180void mgr_page(uint32 line_count) { 181 182 if( (line_count % DEFAULT_SCREEN_LINES) != 0) 183 return; 184 185 printf("--Press enter to continue--\n"); 186 getchar(); 187} 188 189/*reads a line from stdin, figures out if it is a RID or name, gets a CacLookupRidsRecord and then returns the type*/ 190uint32 rid_or_name(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *dom_hnd, uint32 *rid, char **name) { 191 fstring line; 192 193 BOOL is_rid = False; 194 uint32 rid_type = 0; 195 196 struct SamGetNamesFromRids getnames; 197 struct SamGetRidsFromNames getrids; 198 199 mgr_getline(line); 200 201 if(strncmp(line, "0x", 2) == 0) { 202 /*then this is a RID*/ 203 sscanf( (line + 2), "%x", rid); 204 is_rid = True; 205 } 206 else { 207 /*then this is a name*/ 208 *name = talloc_strdup(mem_ctx, line); 209 } 210 211 if(is_rid) { 212 ZERO_STRUCT(getnames); 213 214 getnames.in.dom_hnd = dom_hnd; 215 getnames.in.rids = rid; 216 getnames.in.num_rids = 1; 217 218 cac_SamGetNamesFromRids(hnd, mem_ctx, &getnames); 219 220 if(getnames.out.num_names > 0) 221 rid_type = getnames.out.map[0].type; 222 223 } 224 else { 225 ZERO_STRUCT(getrids); 226 227 getrids.in.dom_hnd = dom_hnd; 228 getrids.in.names = name; 229 getrids.in.num_names = 1; 230 231 cac_SamGetRidsFromNames(hnd, mem_ctx, &getrids); 232 233 if(getrids.out.num_rids > 0) { 234 rid_type = getrids.out.map[0].type; 235 236 /*send back the RID so cac_SamOpenXX() doesn't have to look it up*/ 237 *rid = getrids.out.map[0].rid; 238 } 239 } 240 241 return rid_type; 242} 243 244/*print's out some common error messages*/ 245void printerr(const char *msg, NTSTATUS status) { 246 if(NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) 247 printf("%s You do not have sufficient rights.\n", msg); 248 249 else if(NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) 250 printf("%s No such user.\n", msg); 251 252 else if(NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_GROUP)) 253 printf("%s No such group.\n", msg); 254 255 else if(NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) 256 printf("%s User already exists.\n", msg); 257 258 else if(NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) 259 printf("%s Group already exists.\n", msg); 260 261 else 262 printf("%s %s.\n", msg, nt_errstr(status)); 263} 264 265char *get_new_password(TALLOC_CTX *mem_ctx) { 266 char *pass1 = NULL; 267 268 pass1 = getpass("Enter new password: "); 269 270 return talloc_strdup(mem_ctx, pass1); 271} 272 273void print_rid_list(uint32 *rids, char **names, uint32 num_rids) { 274 uint32 i = 0; 275 276 if(!names || !rids) 277 return; 278 279 printf(" RID Name\n"); 280 281 while(i < num_rids) { 282 printf("[0x%x] [%s]\n", rids[i], names[i]); 283 284 i++; 285 286 mgr_page(i); 287 } 288} 289 290void print_lookup_records(CacLookupRidsRecord *map, uint32 num_rids) { 291 uint32 i = 0; 292 293 if(!map) 294 return; 295 296 printf("RID Name\n"); 297 298 while(i < num_rids) { 299 if(map[i].found) { 300 printf("[0x%x] [%s]\n", map[i].rid, map[i].name); 301 } 302 303 i++; 304 305 mgr_page(i); 306 } 307} 308 309int list_groups(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *dom_hnd) { 310 struct SamEnumGroups eg; 311 312 if(!hnd || !mem_ctx || !dom_hnd) 313 return 0; 314 315 ZERO_STRUCT(eg); 316 eg.in.dom_hnd = dom_hnd; 317 318 while(cac_SamEnumGroups(hnd, mem_ctx, &eg)) 319 print_rid_list(eg.out.rids, eg.out.names, eg.out.num_groups); 320 321 if(CAC_OP_FAILED(hnd->status)) { 322 printerr("Could not enumerate groups.", hnd->status); 323 return 0; 324 } 325 326 return 1; 327} 328 329void list_users(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *dom_hnd) { 330 struct SamEnumUsers eu; 331 332 if(!hnd || !mem_ctx || !dom_hnd) 333 return; 334 335 ZERO_STRUCT(eu); 336 eu.in.dom_hnd = dom_hnd; 337 338 while(cac_SamEnumUsers(hnd, mem_ctx, &eu)) 339 print_rid_list(eu.out.rids, eu.out.names, eu.out.num_users); 340 341 if(CAC_OP_FAILED(hnd->status)) 342 printerr("Could not enumerate users.", hnd->status); 343} 344