Ok - everything now compiles in HEAD (at least the default stuff). We
[ira/wip.git] / source3 / libsmb / cli_samr.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 2.2
4    RPC pipe client
5    Copyright (C) Tim Potter                             2000,
6    Copyright (C) Andrew Tridgell              1992-1997,2000,
7    Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000,
8    Copyright (C) Paul Ashton                       1997,2000,
9    Copyright (C) Elrond                                 2000.
10    
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 2 of the License, or
14    (at your option) any later version.
15    
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20    
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26 #include "includes.h"
27
28 /* Opens a SMB connection to the SAMR pipe */
29
30 struct cli_state *cli_samr_initialise(struct cli_state *cli, char *system_name,
31                                       struct ntuser_creds *creds)
32 {
33         struct in_addr dest_ip;
34         struct nmb_name calling, called;
35         fstring dest_host;
36         extern pstring global_myname;
37         struct ntuser_creds anon;
38
39         /* Initialise cli_state information */
40
41         if (!cli_initialise(cli)) {
42                 return NULL;
43         }
44
45         if (!creds) {
46                 ZERO_STRUCT(anon);
47                 anon.pwd.null_pwd = 1;
48                 creds = &anon;
49         }
50
51         cli_init_creds(cli, creds);
52
53         /* Establish a SMB connection */
54
55         if (!resolve_srv_name(system_name, dest_host, &dest_ip)) {
56                 return NULL;
57         }
58
59         make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20);
60         make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0);
61
62         if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling, 
63                                       &called, "IPC$", "IPC", False, True)) {
64                 return NULL;
65         }
66
67         /* Open a NT session thingy */
68
69         if (!cli_nt_session_open(cli, PIPE_SAMR)) {
70                 cli_shutdown(cli);
71                 return NULL;
72         }
73
74         return cli;
75 }
76
77 /* Shut down a SMB connection to the SAMR pipe */
78
79 void cli_samr_shutdown(struct cli_state *cli)
80 {
81         if (cli->fd != -1) cli_ulogoff(cli);
82         cli_shutdown(cli);
83 }
84
85 /* Connect to SAMR database */
86
87 uint32 cli_samr_connect(struct cli_state *cli, char *srv_name,
88                         uint32 access_mask, POLICY_HND *connect_pol)
89 {
90         prs_struct qbuf, rbuf;
91         SAMR_Q_CONNECT q;
92         SAMR_R_CONNECT r;
93         uint32 result;
94
95         ZERO_STRUCT(q);
96         ZERO_STRUCT(r);
97
98         /* Initialise parse structures */
99
100         prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
101         prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
102
103         /* Marshall data and send request */
104
105         init_samr_q_connect(&q, srv_name, access_mask);
106
107         if (!samr_io_q_connect("", &q, &qbuf, 0) ||
108             !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) {
109                 result = NT_STATUS_UNSUCCESSFUL;
110                 goto done;
111         }
112
113         /* Unmarshall response */
114
115         if (!samr_io_r_connect("", &r, &rbuf, 0)) {
116                 result = NT_STATUS_UNSUCCESSFUL;
117                 goto done;
118         }
119
120         /* Return output parameters */
121
122         if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
123                 *connect_pol = r.connect_pol;
124         }
125
126  done:
127         prs_mem_free(&qbuf);
128         prs_mem_free(&rbuf);
129
130         return result;
131 }
132
133 /* Close SAMR handle */
134
135 uint32 cli_samr_close(struct cli_state *cli, POLICY_HND *connect_pol)
136 {
137         prs_struct qbuf, rbuf;
138         SAMR_Q_CLOSE_HND q;
139         SAMR_R_CLOSE_HND r;
140         uint32 result;
141
142         ZERO_STRUCT(q);
143         ZERO_STRUCT(r);
144
145         /* Initialise parse structures */
146
147         prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
148         prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
149
150         /* Marshall data and send request */
151
152         init_samr_q_close_hnd(&q, connect_pol);
153
154         if (!samr_io_q_close_hnd("", &q, &qbuf, 0) ||
155             !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf)) {
156                 result = NT_STATUS_UNSUCCESSFUL;
157                 goto done;
158         }
159
160         /* Unmarshall response */
161
162         if (!samr_io_r_close_hnd("", &r, &rbuf, 0)) {
163                 result = NT_STATUS_UNSUCCESSFUL;
164                 goto done;
165         }
166
167         /* Return output parameters */
168
169         if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
170                 *connect_pol = r.pol;
171         }
172
173  done:
174         prs_mem_free(&qbuf);
175         prs_mem_free(&rbuf);
176
177         return result;
178 }
179
180 /* Open handle on a domain */
181
182 uint32 cli_samr_open_domain(struct cli_state *cli, POLICY_HND *connect_pol,
183                             uint32 access_mask, DOM_SID *domain_sid,
184                             POLICY_HND *domain_pol)
185 {
186         prs_struct qbuf, rbuf;
187         SAMR_Q_OPEN_DOMAIN q;
188         SAMR_R_OPEN_DOMAIN r;
189         uint32 result;
190
191         ZERO_STRUCT(q);
192         ZERO_STRUCT(r);
193
194         /* Initialise parse structures */
195
196         prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
197         prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
198
199         /* Marshall data and send request */
200
201         init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid);
202
203         if (!samr_io_q_open_domain("", &q, &qbuf, 0) ||
204             !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf)) {
205                 result = NT_STATUS_UNSUCCESSFUL;
206                 goto done;
207         }
208
209         /* Unmarshall response */
210
211         if (!samr_io_r_open_domain("", &r, &rbuf, 0)) {
212                 result = NT_STATUS_UNSUCCESSFUL;
213                 goto done;
214         }
215
216         /* Return output parameters */
217
218         if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
219                 *domain_pol = r.domain_pol;
220         }
221
222  done:
223         prs_mem_free(&qbuf);
224         prs_mem_free(&rbuf);
225
226         return result;
227 }
228
229 /* Open handle on a user */
230
231 uint32 cli_samr_open_user(struct cli_state *cli, POLICY_HND *domain_pol,
232                           uint32 access_mask, uint32 user_rid,
233                           POLICY_HND *user_pol)
234 {
235         prs_struct qbuf, rbuf;
236         SAMR_Q_OPEN_USER q;
237         SAMR_R_OPEN_USER r;
238         uint32 result;
239
240         ZERO_STRUCT(q);
241         ZERO_STRUCT(r);
242
243         /* Initialise parse structures */
244
245         prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
246         prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
247
248         /* Marshall data and send request */
249
250         init_samr_q_open_user(&q, domain_pol, access_mask, user_rid);
251
252         if (!samr_io_q_open_user("", &q, &qbuf, 0) ||
253             !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf)) {
254                 result = NT_STATUS_UNSUCCESSFUL;
255                 goto done;
256         }
257
258         /* Unmarshall response */
259
260         if (!samr_io_r_open_user("", &r, &rbuf, 0)) {
261                 result = NT_STATUS_UNSUCCESSFUL;
262                 goto done;
263         }
264
265         /* Return output parameters */
266
267         if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
268                 *user_pol = r.user_pol;
269         }
270
271  done:
272         prs_mem_free(&qbuf);
273         prs_mem_free(&rbuf);
274
275         return result;
276 }
277
278 /* Open handle on a group */
279
280 uint32 cli_samr_open_group(struct cli_state *cli, POLICY_HND *domain_pol,
281                           uint32 access_mask, uint32 group_rid,
282                           POLICY_HND *group_pol)
283 {
284         prs_struct qbuf, rbuf;
285         SAMR_Q_OPEN_GROUP q;
286         SAMR_R_OPEN_GROUP r;
287         uint32 result;
288
289         ZERO_STRUCT(q);
290         ZERO_STRUCT(r);
291
292         /* Initialise parse structures */
293
294         prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
295         prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
296
297         /* Marshall data and send request */
298
299         init_samr_q_open_group(&q, domain_pol, access_mask, group_rid);
300
301         if (!samr_io_q_open_group("", &q, &qbuf, 0) ||
302             !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf)) {
303                 result = NT_STATUS_UNSUCCESSFUL;
304                 goto done;
305         }
306
307         /* Unmarshall response */
308
309         if (!samr_io_r_open_group("", &r, &rbuf, 0)) {
310                 result = NT_STATUS_UNSUCCESSFUL;
311                 goto done;
312         }
313
314         /* Return output parameters */
315
316         if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
317                 *group_pol = r.pol;
318         }
319
320  done:
321         prs_mem_free(&qbuf);
322         prs_mem_free(&rbuf);
323
324         return result;
325 }
326
327 /* Query user info */
328
329 uint32 cli_samr_query_userinfo(struct cli_state *cli, POLICY_HND *user_pol, 
330                                uint16 switch_value, SAM_USERINFO_CTR *ctr)
331 {
332         prs_struct qbuf, rbuf;
333         SAMR_Q_QUERY_USERINFO q;
334         SAMR_R_QUERY_USERINFO r;
335         uint32 result;
336
337         ZERO_STRUCT(q);
338         ZERO_STRUCT(r);
339
340         /* Initialise parse structures */
341
342         prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
343         prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
344
345         /* Marshall data and send request */
346
347         init_samr_q_query_userinfo(&q, user_pol, switch_value);
348
349         if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) ||
350             !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf)) {
351                 result = NT_STATUS_UNSUCCESSFUL;
352                 goto done;
353         }
354
355         /* Unmarshall response */
356
357         r.ctr = ctr;
358
359         if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) {
360                 result = NT_STATUS_UNSUCCESSFUL;
361                 goto done;
362         }
363
364         /* Return output parameters */
365
366         result = r.status;
367
368  done:
369         prs_mem_free(&qbuf);
370         prs_mem_free(&rbuf);
371
372         return result;
373 }
374
375 /* Query group info */
376
377 uint32 cli_samr_query_groupinfo(struct cli_state *cli, POLICY_HND *group_pol,
378                                 uint32 info_level, GROUP_INFO_CTR *ctr)
379 {
380         prs_struct qbuf, rbuf;
381         SAMR_Q_QUERY_GROUPINFO q;
382         SAMR_R_QUERY_GROUPINFO r;
383         uint32 result;
384
385         ZERO_STRUCT(q);
386         ZERO_STRUCT(r);
387
388         /* Initialise parse structures */
389
390         prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
391         prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
392
393         /* Marshall data and send request */
394
395         init_samr_q_query_groupinfo(&q, group_pol, info_level);
396
397         if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) ||
398             !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf)) {
399                 result = NT_STATUS_UNSUCCESSFUL;
400                 goto done;
401         }
402
403         /* Unmarshall response */
404
405         r.ctr = ctr;
406
407         if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0)) {
408                 result = NT_STATUS_UNSUCCESSFUL;
409                 goto done;
410         }
411
412         /* Return output parameters */
413
414         result = r.status;
415
416  done:
417         prs_mem_free(&qbuf);
418         prs_mem_free(&rbuf);
419
420         return result;
421 }
422
423 /* Query user groups */
424
425 uint32 cli_samr_query_usergroups(struct cli_state *cli, POLICY_HND *user_pol,
426                                  uint32 *num_groups, DOM_GID **gid)
427 {
428         prs_struct qbuf, rbuf;
429         SAMR_Q_QUERY_USERGROUPS q;
430         SAMR_R_QUERY_USERGROUPS r;
431         uint32 result;
432
433         ZERO_STRUCT(q);
434         ZERO_STRUCT(r);
435
436         /* Initialise parse structures */
437
438         prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
439         prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
440
441         /* Marshall data and send request */
442
443         init_samr_q_query_usergroups(&q, user_pol);
444
445         if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) ||
446             !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf)) {
447                 result = NT_STATUS_UNSUCCESSFUL;
448                 goto done;
449         }
450
451         /* Unmarshall response */
452
453         if (!samr_io_r_query_usergroups("", &r, &rbuf, 0)) {
454                 result = NT_STATUS_UNSUCCESSFUL;
455                 goto done;
456         }
457
458         /* Return output parameters */
459
460         if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
461                 *num_groups = r.num_entries;
462                 *gid = r.gid;
463         }
464
465  done:
466         prs_mem_free(&qbuf);
467         prs_mem_free(&rbuf);
468
469         return result;
470 }
471
472 /* Query user groups */
473
474 uint32 cli_samr_query_groupmem(struct cli_state *cli, POLICY_HND *group_pol,
475                                uint32 *num_mem, uint32 **rid, uint32 **attr)
476 {
477         prs_struct qbuf, rbuf;
478         SAMR_Q_QUERY_GROUPMEM q;
479         SAMR_R_QUERY_GROUPMEM r;
480         uint32 result;
481
482         ZERO_STRUCT(q);
483         ZERO_STRUCT(r);
484
485         /* Initialise parse structures */
486
487         prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
488         prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
489
490         /* Marshall data and send request */
491
492         init_samr_q_query_groupmem(&q, group_pol);
493
494         if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) ||
495             !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf)) {
496                 result = NT_STATUS_UNSUCCESSFUL;
497                 goto done;
498         }
499
500         /* Unmarshall response */
501
502         if (!samr_io_r_query_groupmem("", &r, &rbuf, 0)) {
503                 result = NT_STATUS_UNSUCCESSFUL;
504                 goto done;
505         }
506
507         /* Return output parameters */
508
509         if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
510                 *num_mem = r.num_entries;
511                 *rid = r.rid;
512                 *attr = r.attr;
513         }
514
515  done:
516         prs_mem_free(&qbuf);
517         prs_mem_free(&rbuf);
518
519         return result;
520 }