Initial import
[samba] / examples / libmsrpc / cacusermgr / util.c
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*/
24 void 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*/
37 int 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
89 void 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*/
99 void 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
180 void 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*/
190 uint32 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*/
245 void 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
265 char *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
273 void 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
290 void 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
309 int 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
329 void 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 }