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