751a84aaaa144a968a3b119edab087deec099de5
[samba.git] / source3 / rpc_client / cli_lsarpc.c
1
2 /* 
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-1997,
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
8  *  Copyright (C) Paul Ashton                       1997.
9  *  
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25
26 #ifdef SYSLOG
27 #undef SYSLOG
28 #endif
29
30 #include "includes.h"
31
32 extern int DEBUGLEVEL;
33
34
35 /****************************************************************************
36 do a LSA Open Policy
37 ****************************************************************************/
38 BOOL lsa_open_policy(struct cli_state *cli, uint16 fnum,
39                         char *server_name, POLICY_HND *hnd,
40                         BOOL sec_qos)
41 {
42         prs_struct rbuf;
43         prs_struct buf; 
44         LSA_Q_OPEN_POL q_o;
45         LSA_SEC_QOS qos;
46         BOOL valid_pol = False;
47
48         if (hnd == NULL) return False;
49
50         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
51         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
52
53         /* create and send a MSRPC command with api LSA_OPENPOLICY */
54
55         DEBUG(4,("LSA Open Policy\n"));
56
57         /* store the parameters */
58         if (sec_qos)
59         {
60                 make_lsa_sec_qos(&qos, 2, 1, 0, 0x20000000);
61                 make_q_open_pol(&q_o, 0x5c, 0, 0, &qos);
62         }
63         else
64         {
65                 make_q_open_pol(&q_o, 0x5c, 0, 0x1, NULL);
66         }
67
68         /* turn parameters into data stream */
69         lsa_io_q_open_pol("", &q_o, &buf, 0);
70
71         /* send the data on \PIPE\ */
72         if (rpc_api_pipe_req(cli, fnum, LSA_OPENPOLICY, &buf, &rbuf))
73         {
74                 LSA_R_OPEN_POL r_o;
75                 BOOL p;
76
77                 lsa_io_r_open_pol("", &r_o, &rbuf, 0);
78                 p = rbuf.offset != 0;
79
80                 if (p && r_o.status != 0)
81                 {
82                         /* report error code */
83                         DEBUG(0,("LSA_OPENPOLICY: %s\n", get_nt_error_msg(r_o.status)));
84                         p = False;
85                 }
86
87                 if (p)
88                 {
89                         /* ok, at last: we're happy. return the policy handle */
90                         memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
91                         valid_pol = True;
92                 }
93         }
94
95         prs_mem_free(&rbuf);
96         prs_mem_free(&buf );
97
98         return valid_pol;
99 }
100
101 /****************************************************************************
102 do a LSA Lookup Names
103 ****************************************************************************/
104 BOOL lsa_lookup_names(struct cli_state *cli, uint16 fnum,
105                         POLICY_HND *hnd,
106                         int num_names,
107                         const char **names,
108                         DOM_SID **sids,
109                         uint8 **types,
110                         int *num_sids)
111 {
112         prs_struct rbuf;
113         prs_struct buf; 
114         LSA_Q_LOOKUP_NAMES q_l;
115         BOOL valid_response = False;
116
117         if (hnd == NULL || num_sids == 0 || sids == NULL) return False;
118
119         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
120         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
121
122         /* create and send a MSRPC command with api LSA_LOOKUP_NAMES */
123
124         DEBUG(4,("LSA Lookup NAMEs\n"));
125
126         /* store the parameters */
127         make_q_lookup_names(&q_l, hnd, num_names, names);
128
129         /* turn parameters into data stream */
130         lsa_io_q_lookup_names("", &q_l, &buf, 0);
131
132         /* send the data on \PIPE\ */
133         if (rpc_api_pipe_req(cli, fnum, LSA_LOOKUPNAMES, &buf, &rbuf))
134         {
135                 LSA_R_LOOKUP_NAMES r_l;
136                 DOM_R_REF ref;
137                 DOM_RID2 t_rids[MAX_LOOKUP_SIDS];
138                 BOOL p;
139
140                 ZERO_STRUCT(ref);
141                 ZERO_STRUCT(t_rids);
142
143                 r_l.dom_ref = &ref;
144                 r_l.dom_rid = t_rids;
145
146                 lsa_io_r_lookup_names("", &r_l, &rbuf, 0);
147                 p = rbuf.offset != 0;
148                 
149                 if (p && r_l.status != 0)
150                 {
151                         /* report error code */
152                         DEBUG(0,("LSA_LOOKUP_NAMES: %s\n", get_nt_error_msg(r_l.status)));
153                         p = False;
154                 }
155
156                 if (p)
157                 {
158                         if (r_l.undoc_buffer != 0 && ref.undoc_buffer != 0)
159                         {
160                                 valid_response = True;
161                         }
162                 }
163
164                 if (num_sids != NULL && valid_response)
165                 {
166                         (*num_sids) = r_l.num_entries;
167                 }
168                 if (valid_response)
169                 {
170                         int i;
171                         for (i = 0; i < r_l.num_entries; i++)
172                         {
173                                 if (t_rids[i].rid_idx >= ref.num_ref_doms_1 &&
174                                     t_rids[i].rid_idx != 0xffffffff)
175                                 {
176                                         DEBUG(0,("LSA_LOOKUP_NAMES: domain index %d out of bounds\n",
177                                                   t_rids[i].rid_idx));
178                                         valid_response = False;
179                                         break;
180                                 }
181                         }
182                 }
183
184                 if (types != NULL && valid_response && r_l.num_entries != 0)
185                 {
186                         (*types) = (uint8*)malloc((*num_sids) * sizeof(uint8));
187                 }
188
189                 if (sids != NULL && valid_response && r_l.num_entries != 0)
190                 {
191                         (*sids) = (DOM_SID*)malloc((*num_sids) * sizeof(DOM_SID));
192                 }
193
194                 if (sids != NULL && (*sids) != NULL)
195                 {
196                         int i;
197                         /* take each name, construct a SID */
198                         for (i = 0; i < (*num_sids); i++)
199                         {
200                                 uint32 dom_idx = t_rids[i].rid_idx;
201                                 uint32 dom_rid = t_rids[i].rid;
202                                 DOM_SID *sid = &(*sids)[i];
203                                 if (dom_idx != 0xffffffff)
204                                 {
205                                         sid_copy(sid, &ref.ref_dom[dom_idx].ref_dom.sid);
206                                         if (dom_rid != 0xffffffff)
207                                         {
208                                                 sid_append_rid(sid, dom_rid);
209                                         }
210                                         if (types != NULL && (*types) != NULL)
211                                         {
212                                                 (*types)[i] = t_rids[i].type;
213                                         }
214                                 }
215                                 else
216                                 {
217                                         ZERO_STRUCTP(sid);
218                                         if (types != NULL && (*types) != NULL)
219                                         {
220                                                 (*types)[i] = SID_NAME_UNKNOWN;
221                                         }
222                                 }
223                         }
224                 }
225         }
226
227         prs_mem_free(&rbuf);
228         prs_mem_free(&buf );
229
230         return valid_response;
231 }
232
233 /****************************************************************************
234 do a LSA Lookup SIDs
235 ****************************************************************************/
236 BOOL lsa_lookup_sids(struct cli_state *cli, uint16 fnum,
237                         POLICY_HND *hnd,
238                         int num_sids,
239                         DOM_SID **sids,
240                         char ***names,
241                         uint8 **types,
242                         int *num_names)
243 {
244         prs_struct rbuf;
245         prs_struct buf; 
246         LSA_Q_LOOKUP_SIDS q_l;
247         BOOL valid_response = False;
248
249         if (hnd == NULL || num_sids == 0 || sids == NULL) return False;
250
251         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
252         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
253
254         /* create and send a MSRPC command with api LSA_LOOKUP_SIDS */
255
256         DEBUG(4,("LSA Lookup SIDs\n"));
257
258         /* store the parameters */
259         make_q_lookup_sids(&q_l, hnd, num_sids, sids, 1);
260
261         /* turn parameters into data stream */
262         lsa_io_q_lookup_sids("", &q_l, &buf, 0);
263
264         /* send the data on \PIPE\ */
265         if (rpc_api_pipe_req(cli, fnum, LSA_LOOKUPSIDS, &buf, &rbuf))
266         {
267                 LSA_R_LOOKUP_SIDS r_l;
268                 DOM_R_REF ref;
269                 LSA_TRANS_NAME_ENUM t_names;
270                 BOOL p;
271
272                 r_l.dom_ref = &ref;
273                 r_l.names   = &t_names;
274
275                 lsa_io_r_lookup_sids("", &r_l, &rbuf, 0);
276                 p = rbuf.offset != 0;
277                 
278                 if (p && r_l.status != 0)
279                 {
280                         /* report error code */
281                         DEBUG(0,("LSA_LOOKUP_SIDS: %s\n", get_nt_error_msg(r_l.status)));
282                         p = False;
283                 }
284
285                 if (p)
286                 {
287                         if (t_names.ptr_trans_names != 0 && ref.undoc_buffer != 0)
288                         {
289                                 valid_response = True;
290                         }
291                 }
292
293                 if (num_names != NULL && valid_response)
294                 {
295                         (*num_names) = t_names.num_entries;
296                 }
297                 if (valid_response)
298                 {
299                         int i;
300                         for (i = 0; i < t_names.num_entries; i++)
301                         {
302                                 if (t_names.name[i].domain_idx >= ref.num_ref_doms_1)
303                                 {
304                                         DEBUG(0,("LSA_LOOKUP_SIDS: domain index out of bounds\n"));
305                                         valid_response = False;
306                                         break;
307                                 }
308                         }
309                 }
310
311                 if (types != NULL && valid_response && t_names.num_entries != 0)
312                 {
313                         (*types) = (uint8*)malloc((*num_names) * sizeof(uint8));
314                 }
315
316                 if (names != NULL && valid_response && t_names.num_entries != 0)
317                 {
318                         (*names) = (char**)malloc((*num_names) * sizeof(char*));
319                 }
320
321                 if (names != NULL && (*names) != NULL)
322                 {
323                         int i;
324                         /* take each name, construct a \DOMAIN\name string */
325                         for (i = 0; i < (*num_names); i++)
326                         {
327                                 fstring name;
328                                 fstring dom_name;
329                                 fstring full_name;
330                                 uint32 dom_idx = t_names.name[i].domain_idx;
331
332                                 if (dom_idx != 0xffffffff)
333                                 {
334                                         unistr2_to_ascii(dom_name, &ref.ref_dom[dom_idx].uni_dom_name, sizeof(dom_name)-1);
335                                         unistr2_to_ascii(name, &t_names.uni_name[i], sizeof(name)-1);
336                                         
337                                         memset(full_name, 0, sizeof(full_name));
338
339                                         slprintf(full_name, sizeof(full_name)-1, "%s\\%s",
340                                                  dom_name, name);
341
342                                         (*names)[i] = strdup(full_name);
343                                         if (types != NULL && (*types) != NULL)
344                                         {
345                                                 (*types)[i] = t_names.name[i].sid_name_use;
346                                         }
347                                 }
348                                 else
349                                 {
350                                         (*names)[i] = NULL;
351                                         if (types != NULL && (*types) != NULL)
352                                         {
353                                                 (*types)[i] = SID_NAME_UNKNOWN;
354                                         }
355                                 }
356                         }
357                 }
358         }
359
360         prs_mem_free(&rbuf);
361         prs_mem_free(&buf );
362
363         return valid_response;
364 }
365
366 /****************************************************************************
367 do a LSA Query Info Policy
368 ****************************************************************************/
369 BOOL lsa_query_info_pol(struct cli_state *cli, uint16 fnum,
370                         POLICY_HND *hnd, uint16 info_class,
371                         fstring domain_name, DOM_SID *domain_sid)
372 {
373         prs_struct rbuf;
374         prs_struct buf; 
375         LSA_Q_QUERY_INFO q_q;
376         BOOL valid_response = False;
377
378         ZERO_STRUCTP(domain_sid);
379         domain_name[0] = 0;
380
381         if (hnd == NULL || domain_name == NULL || domain_sid == NULL) return False;
382
383         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
384         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
385
386         /* create and send a MSRPC command with api LSA_QUERYINFOPOLICY */
387
388         DEBUG(4,("LSA Query Info Policy\n"));
389
390         /* store the parameters */
391         make_q_query(&q_q, hnd, info_class);
392
393         /* turn parameters into data stream */
394         lsa_io_q_query("", &q_q, &buf, 0);
395
396         /* send the data on \PIPE\ */
397         if (rpc_api_pipe_req(cli, fnum, LSA_QUERYINFOPOLICY, &buf, &rbuf))
398         {
399                 LSA_R_QUERY_INFO r_q;
400                 BOOL p;
401
402                 lsa_io_r_query("", &r_q, &rbuf, 0);
403                 p = rbuf.offset != 0;
404                 
405                 if (p && r_q.status != 0)
406                 {
407                         /* report error code */
408                         DEBUG(0,("LSA_QUERYINFOPOLICY: %s\n", get_nt_error_msg(r_q.status)));
409                         p = False;
410                 }
411
412                 if (p && r_q.info_class != q_q.info_class)
413                 {
414                         /* report different info classes */
415                         DEBUG(0,("LSA_QUERYINFOPOLICY: error info_class (q,r) differ - (%x,%x)\n",
416                                         q_q.info_class, r_q.info_class));
417                         p = False;
418                 }
419
420                 if (p)
421                 {
422                         fstring sid_str;
423                         /* ok, at last: we're happy. */
424                         switch (r_q.info_class)
425                         {
426                                 case 3:
427                                 {
428                                         if (r_q.dom.id3.buffer_dom_name != 0)
429                                         {
430                                                 unistr2_to_ascii(domain_name, &r_q.dom.id3.uni_domain_name, sizeof(fstring)-1);
431                                         }
432                                         if (r_q.dom.id3.buffer_dom_sid != 0)
433                                         {
434                                                 *domain_sid = r_q.dom.id3.dom_sid.sid;
435                                         }
436
437                                         valid_response = True;
438                                         break;
439                                 }
440                                 case 5:
441                                 {
442                                         if (r_q.dom.id5.buffer_dom_name != 0)
443                                         {
444                                                 unistr2_to_ascii(domain_name, &r_q.dom.id5.uni_domain_name, sizeof(fstring)-1);
445                                         }
446                                         if (r_q.dom.id5.buffer_dom_sid != 0)
447                                         {
448                                                 *domain_sid = r_q.dom.id5.dom_sid.sid;
449                                         }
450
451                                         valid_response = True;
452                                         break;
453                                 }
454                                 default:
455                                 {
456                                         DEBUG(3,("LSA_QUERYINFOPOLICY: unknown info class\n"));
457                                         domain_name[0] = 0;
458
459                                         break;
460                                 }
461                         }
462                 
463                         sid_to_string(sid_str, domain_sid);
464                         DEBUG(3,("LSA_QUERYINFOPOLICY (level %x): domain:%s  domain sid:%s\n",
465                                   r_q.info_class, domain_name, sid_str));
466                 }
467         }
468
469         prs_mem_free(&rbuf);
470         prs_mem_free(&buf );
471
472         return valid_response;
473 }
474
475 /****************************************************************************
476 do a LSA Close
477 ****************************************************************************/
478 BOOL lsa_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd)
479 {
480         prs_struct rbuf;
481         prs_struct buf; 
482         LSA_Q_CLOSE q_c;
483     BOOL valid_close = False;
484
485         if (hnd == NULL) return False;
486
487         /* create and send a MSRPC command with api LSA_OPENPOLICY */
488
489         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
490         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
491
492         DEBUG(4,("LSA Close\n"));
493
494         /* store the parameters */
495         make_lsa_q_close(&q_c, hnd);
496
497         /* turn parameters into data stream */
498         lsa_io_q_close("", &q_c, &buf, 0);
499
500         /* send the data on \PIPE\ */
501         if (rpc_api_pipe_req(cli, fnum, LSA_CLOSE, &buf, &rbuf))
502         {
503                 LSA_R_CLOSE r_c;
504                 BOOL p;
505
506                 lsa_io_r_close("", &r_c, &rbuf, 0);
507                 p = rbuf.offset != 0;
508
509                 if (p && r_c.status != 0)
510                 {
511                         /* report error code */
512                         DEBUG(0,("LSA_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
513                         p = False;
514                 }
515
516                 if (p)
517                 {
518                         /* check that the returned policy handle is all zeros */
519                         int i;
520                         valid_close = True;
521
522                         for (i = 0; i < sizeof(r_c.pol.data); i++)
523                         {
524                                 if (r_c.pol.data[i] != 0)
525                                 {
526                                         valid_close = False;
527                                         break;
528                                 }
529                         }       
530                         if (!valid_close)
531                         {
532                                 DEBUG(0,("LSA_CLOSE: non-zero handle returned\n"));
533                         }
534                 }
535         }
536
537         prs_mem_free(&rbuf);
538         prs_mem_free(&buf );
539
540         return valid_close;
541 }
542
543