valid_pol in lsa_query_secret() needed to be initialised to False.
[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 Open Secret
103 ****************************************************************************/
104 BOOL lsa_open_secret(struct cli_state *cli, uint16 fnum,
105                      POLICY_HND *hnd_pol, char *secret_name, uint32 des_access,
106                      POLICY_HND *hnd_secret)
107 {
108         prs_struct rbuf;
109         prs_struct buf; 
110         LSA_Q_OPEN_SECRET q_o;
111         BOOL valid_pol = False;
112
113         if (hnd_pol == NULL) return False;
114
115         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
116         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
117
118         /* create and send a MSRPC command with api LSA_OPENSECRET */
119
120         DEBUG(4,("LSA Open Secret\n"));
121
122         make_q_open_secret(&q_o, hnd_pol, secret_name, des_access);
123
124         /* turn parameters into data stream */
125         lsa_io_q_open_secret("", &q_o, &buf, 0);
126
127         /* send the data on \PIPE\ */
128         if (rpc_api_pipe_req(cli, fnum, LSA_OPENSECRET, &buf, &rbuf))
129         {
130                 LSA_R_OPEN_SECRET r_o;
131                 BOOL p;
132
133                 lsa_io_r_open_secret("", &r_o, &rbuf, 0);
134                 p = rbuf.offset != 0;
135
136                 if (p && r_o.status != 0)
137                 {
138                         /* report error code */
139                         DEBUG(0,("LSA_OPENSECRET: %s\n", get_nt_error_msg(r_o.status)));
140                         p = False;
141                 }
142
143                 if (p)
144                 {
145                         /* ok, at last: we're happy. return the policy handle */
146                         memcpy(hnd_secret, r_o.pol.data, sizeof(hnd_secret->data));
147                         valid_pol = True;
148                 }
149         }
150
151         prs_mem_free(&rbuf);
152         prs_mem_free(&buf );
153
154         return valid_pol;
155 }
156
157 /****************************************************************************
158 do a LSA Query Secret
159 ****************************************************************************/
160 BOOL lsa_query_secret(struct cli_state *cli, uint16 fnum,
161                       POLICY_HND *pol, STRING2 *enc_secret,
162                       NTTIME *last_update)
163 {
164         prs_struct rbuf;
165         prs_struct buf; 
166         LSA_Q_QUERY_SECRET q_q;
167         BOOL valid_info = False;
168
169         if (pol == NULL) return False;
170
171         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
172         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
173
174         /* create and send a MSRPC command with api LSA_QUERYSECRET */
175
176         DEBUG(4,("LSA Query Secret\n"));
177
178         make_q_query_secret(&q_q, pol);
179
180         /* turn parameters into data stream */
181         lsa_io_q_query_secret("", &q_q, &buf, 0);
182
183         /* send the data on \PIPE\ */
184         if (rpc_api_pipe_req(cli, fnum, LSA_QUERYSECRET, &buf, &rbuf))
185         {
186                 LSA_R_QUERY_SECRET r_q;
187                 BOOL p;
188
189                 lsa_io_r_query_secret("", &r_q, &rbuf, 0);
190                 p = rbuf.offset != 0;
191
192                 if (p && r_q.status != 0)
193                 {
194                         /* report error code */
195                         DEBUG(0,("LSA_QUERYSECRET: %s\n", get_nt_error_msg(r_q.status)));
196                         p = False;
197                 }
198
199                 if (p && (r_q.info.ptr_value != 0) &&
200                     (r_q.info.value.ptr_secret != 0) &&
201                     (r_q.info.ptr_update != 0))
202                 {
203                         memcpy(enc_secret,  &(r_q.info.value.enc_secret), sizeof(STRING2));
204                         memcpy(last_update, &(r_q.info.last_update),      sizeof(NTTIME));
205                         valid_info = True;
206                 }
207         }
208
209         prs_mem_free(&rbuf);
210         prs_mem_free(&buf );
211
212         return valid_info;
213 }
214
215
216 /****************************************************************************
217 do a LSA Lookup Names
218 ****************************************************************************/
219 BOOL lsa_lookup_names(struct cli_state *cli, uint16 fnum,
220                         POLICY_HND *hnd,
221                         int num_names,
222                         const char **names,
223                         DOM_SID **sids,
224                         uint8 **types,
225                         int *num_sids)
226 {
227         prs_struct rbuf;
228         prs_struct buf; 
229         LSA_Q_LOOKUP_NAMES q_l;
230         BOOL valid_response = False;
231
232         if (hnd == NULL || num_sids == 0 || sids == NULL) return False;
233
234         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
235         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
236
237         /* create and send a MSRPC command with api LSA_LOOKUP_NAMES */
238
239         DEBUG(4,("LSA Lookup NAMEs\n"));
240
241         /* store the parameters */
242         make_q_lookup_names(&q_l, hnd, num_names, names);
243
244         /* turn parameters into data stream */
245         lsa_io_q_lookup_names("", &q_l, &buf, 0);
246
247         /* send the data on \PIPE\ */
248         if (rpc_api_pipe_req(cli, fnum, LSA_LOOKUPNAMES, &buf, &rbuf))
249         {
250                 LSA_R_LOOKUP_NAMES r_l;
251                 DOM_R_REF ref;
252                 DOM_RID2 t_rids[MAX_LOOKUP_SIDS];
253                 BOOL p;
254
255                 ZERO_STRUCT(ref);
256                 ZERO_STRUCT(t_rids);
257
258                 r_l.dom_ref = &ref;
259                 r_l.dom_rid = t_rids;
260
261                 lsa_io_r_lookup_names("", &r_l, &rbuf, 0);
262                 p = rbuf.offset != 0;
263                 
264                 if (p && r_l.status != 0)
265                 {
266                         /* report error code */
267                         DEBUG(0,("LSA_LOOKUP_NAMES: %s\n", get_nt_error_msg(r_l.status)));
268                         p = False;
269                 }
270
271                 if (p)
272                 {
273                         if (r_l.undoc_buffer != 0 && ref.undoc_buffer != 0)
274                         {
275                                 valid_response = True;
276                         }
277                 }
278
279                 if (num_sids != NULL && valid_response)
280                 {
281                         (*num_sids) = r_l.num_entries;
282                 }
283                 if (valid_response)
284                 {
285                         int i;
286                         for (i = 0; i < r_l.num_entries; i++)
287                         {
288                                 if (t_rids[i].rid_idx >= ref.num_ref_doms_1 &&
289                                     t_rids[i].rid_idx != 0xffffffff)
290                                 {
291                                         DEBUG(0,("LSA_LOOKUP_NAMES: domain index %d out of bounds\n",
292                                                   t_rids[i].rid_idx));
293                                         valid_response = False;
294                                         break;
295                                 }
296                         }
297                 }
298
299                 if (types != NULL && valid_response && r_l.num_entries != 0)
300                 {
301                         (*types) = (uint8*)malloc((*num_sids) * sizeof(uint8));
302                 }
303
304                 if (sids != NULL && valid_response && r_l.num_entries != 0)
305                 {
306                         (*sids) = (DOM_SID*)malloc((*num_sids) * sizeof(DOM_SID));
307                 }
308
309                 if (sids != NULL && (*sids) != NULL)
310                 {
311                         int i;
312                         /* take each name, construct a SID */
313                         for (i = 0; i < (*num_sids); i++)
314                         {
315                                 uint32 dom_idx = t_rids[i].rid_idx;
316                                 uint32 dom_rid = t_rids[i].rid;
317                                 DOM_SID *sid = &(*sids)[i];
318                                 if (dom_idx != 0xffffffff)
319                                 {
320                                         sid_copy(sid, &ref.ref_dom[dom_idx].ref_dom.sid);
321                                         if (dom_rid != 0xffffffff)
322                                         {
323                                                 sid_append_rid(sid, dom_rid);
324                                         }
325                                         if (types != NULL && (*types) != NULL)
326                                         {
327                                                 (*types)[i] = t_rids[i].type;
328                                         }
329                                 }
330                                 else
331                                 {
332                                         ZERO_STRUCTP(sid);
333                                         if (types != NULL && (*types) != NULL)
334                                         {
335                                                 (*types)[i] = SID_NAME_UNKNOWN;
336                                         }
337                                 }
338                         }
339                 }
340         }
341
342         prs_mem_free(&rbuf);
343         prs_mem_free(&buf );
344
345         return valid_response;
346 }
347
348 /****************************************************************************
349 do a LSA Lookup SIDs
350 ****************************************************************************/
351 BOOL lsa_lookup_sids(struct cli_state *cli, uint16 fnum,
352                         POLICY_HND *hnd,
353                         int num_sids,
354                         DOM_SID **sids,
355                         char ***names,
356                         uint8 **types,
357                         int *num_names)
358 {
359         prs_struct rbuf;
360         prs_struct buf; 
361         LSA_Q_LOOKUP_SIDS q_l;
362         BOOL valid_response = False;
363
364         if (hnd == NULL || num_sids == 0 || sids == NULL) return False;
365
366         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
367         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
368
369         /* create and send a MSRPC command with api LSA_LOOKUP_SIDS */
370
371         DEBUG(4,("LSA Lookup SIDs\n"));
372
373         /* store the parameters */
374         make_q_lookup_sids(&q_l, hnd, num_sids, sids, 1);
375
376         /* turn parameters into data stream */
377         lsa_io_q_lookup_sids("", &q_l, &buf, 0);
378
379         /* send the data on \PIPE\ */
380         if (rpc_api_pipe_req(cli, fnum, LSA_LOOKUPSIDS, &buf, &rbuf))
381         {
382                 LSA_R_LOOKUP_SIDS r_l;
383                 DOM_R_REF ref;
384                 LSA_TRANS_NAME_ENUM t_names;
385                 BOOL p;
386
387                 r_l.dom_ref = &ref;
388                 r_l.names   = &t_names;
389
390                 lsa_io_r_lookup_sids("", &r_l, &rbuf, 0);
391                 p = rbuf.offset != 0;
392                 
393                 if (p && r_l.status != 0)
394                 {
395                         /* report error code */
396                         DEBUG(0,("LSA_LOOKUP_SIDS: %s\n", get_nt_error_msg(r_l.status)));
397                         p = False;
398                 }
399
400                 if (p)
401                 {
402                         if (t_names.ptr_trans_names != 0 && ref.undoc_buffer != 0)
403                         {
404                                 valid_response = True;
405                         }
406                 }
407
408                 if (num_names != NULL && valid_response)
409                 {
410                         (*num_names) = t_names.num_entries;
411                 }
412                 if (valid_response)
413                 {
414                         int i;
415                         for (i = 0; i < t_names.num_entries; i++)
416                         {
417                                 if (t_names.name[i].domain_idx >= ref.num_ref_doms_1)
418                                 {
419                                         DEBUG(0,("LSA_LOOKUP_SIDS: domain index out of bounds\n"));
420                                         valid_response = False;
421                                         break;
422                                 }
423                         }
424                 }
425
426                 if (types != NULL && valid_response && t_names.num_entries != 0)
427                 {
428                         (*types) = (uint8*)malloc((*num_names) * sizeof(uint8));
429                 }
430
431                 if (names != NULL && valid_response && t_names.num_entries != 0)
432                 {
433                         (*names) = (char**)malloc((*num_names) * sizeof(char*));
434                 }
435
436                 if (names != NULL && (*names) != NULL)
437                 {
438                         int i;
439                         /* take each name, construct a \DOMAIN\name string */
440                         for (i = 0; i < (*num_names); i++)
441                         {
442                                 fstring name;
443                                 fstring dom_name;
444                                 fstring full_name;
445                                 uint32 dom_idx = t_names.name[i].domain_idx;
446
447                                 if (dom_idx != 0xffffffff)
448                                 {
449                                         unistr2_to_ascii(dom_name, &ref.ref_dom[dom_idx].uni_dom_name, sizeof(dom_name)-1);
450                                         unistr2_to_ascii(name, &t_names.uni_name[i], sizeof(name)-1);
451                                         
452                                         memset(full_name, 0, sizeof(full_name));
453
454                                         slprintf(full_name, sizeof(full_name)-1, "%s\\%s",
455                                                  dom_name, name);
456
457                                         (*names)[i] = strdup(full_name);
458                                         if (types != NULL && (*types) != NULL)
459                                         {
460                                                 (*types)[i] = t_names.name[i].sid_name_use;
461                                         }
462                                 }
463                                 else
464                                 {
465                                         (*names)[i] = NULL;
466                                         if (types != NULL && (*types) != NULL)
467                                         {
468                                                 (*types)[i] = SID_NAME_UNKNOWN;
469                                         }
470                                 }
471                         }
472                 }
473         }
474
475         prs_mem_free(&rbuf);
476         prs_mem_free(&buf );
477
478         return valid_response;
479 }
480
481 /****************************************************************************
482 do a LSA Query Info Policy
483 ****************************************************************************/
484 BOOL lsa_query_info_pol(struct cli_state *cli, uint16 fnum,
485                         POLICY_HND *hnd, uint16 info_class,
486                         fstring domain_name, DOM_SID *domain_sid)
487 {
488         prs_struct rbuf;
489         prs_struct buf; 
490         LSA_Q_QUERY_INFO q_q;
491         BOOL valid_response = False;
492
493         ZERO_STRUCTP(domain_sid);
494         domain_name[0] = 0;
495
496         if (hnd == NULL || domain_name == NULL || domain_sid == NULL) return False;
497
498         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
499         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
500
501         /* create and send a MSRPC command with api LSA_QUERYINFOPOLICY */
502
503         DEBUG(4,("LSA Query Info Policy\n"));
504
505         /* store the parameters */
506         make_q_query(&q_q, hnd, info_class);
507
508         /* turn parameters into data stream */
509         lsa_io_q_query("", &q_q, &buf, 0);
510
511         /* send the data on \PIPE\ */
512         if (rpc_api_pipe_req(cli, fnum, LSA_QUERYINFOPOLICY, &buf, &rbuf))
513         {
514                 LSA_R_QUERY_INFO r_q;
515                 BOOL p;
516
517                 lsa_io_r_query("", &r_q, &rbuf, 0);
518                 p = rbuf.offset != 0;
519                 
520                 if (p && r_q.status != 0)
521                 {
522                         /* report error code */
523                         DEBUG(0,("LSA_QUERYINFOPOLICY: %s\n", get_nt_error_msg(r_q.status)));
524                         p = False;
525                 }
526
527                 if (p && r_q.info_class != q_q.info_class)
528                 {
529                         /* report different info classes */
530                         DEBUG(0,("LSA_QUERYINFOPOLICY: error info_class (q,r) differ - (%x,%x)\n",
531                                         q_q.info_class, r_q.info_class));
532                         p = False;
533                 }
534
535                 if (p)
536                 {
537                         fstring sid_str;
538                         /* ok, at last: we're happy. */
539                         switch (r_q.info_class)
540                         {
541                                 case 3:
542                                 {
543                                         if (r_q.dom.id3.buffer_dom_name != 0)
544                                         {
545                                                 unistr2_to_ascii(domain_name, &r_q.dom.id3.uni_domain_name, sizeof(fstring)-1);
546                                         }
547                                         if (r_q.dom.id3.buffer_dom_sid != 0)
548                                         {
549                                                 *domain_sid = r_q.dom.id3.dom_sid.sid;
550                                         }
551
552                                         valid_response = True;
553                                         break;
554                                 }
555                                 case 5:
556                                 {
557                                         if (r_q.dom.id5.buffer_dom_name != 0)
558                                         {
559                                                 unistr2_to_ascii(domain_name, &r_q.dom.id5.uni_domain_name, sizeof(fstring)-1);
560                                         }
561                                         if (r_q.dom.id5.buffer_dom_sid != 0)
562                                         {
563                                                 *domain_sid = r_q.dom.id5.dom_sid.sid;
564                                         }
565
566                                         valid_response = True;
567                                         break;
568                                 }
569                                 default:
570                                 {
571                                         DEBUG(3,("LSA_QUERYINFOPOLICY: unknown info class\n"));
572                                         domain_name[0] = 0;
573
574                                         break;
575                                 }
576                         }
577                 
578                         sid_to_string(sid_str, domain_sid);
579                         DEBUG(3,("LSA_QUERYINFOPOLICY (level %x): domain:%s  domain sid:%s\n",
580                                   r_q.info_class, domain_name, sid_str));
581                 }
582         }
583
584         prs_mem_free(&rbuf);
585         prs_mem_free(&buf );
586
587         return valid_response;
588 }
589
590 /****************************************************************************
591 do a LSA Close
592 ****************************************************************************/
593 BOOL lsa_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd)
594 {
595         prs_struct rbuf;
596         prs_struct buf; 
597         LSA_Q_CLOSE q_c;
598     BOOL valid_close = False;
599
600         if (hnd == NULL) return False;
601
602         /* create and send a MSRPC command with api LSA_OPENPOLICY */
603
604         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
605         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
606
607         DEBUG(4,("LSA Close\n"));
608
609         /* store the parameters */
610         make_lsa_q_close(&q_c, hnd);
611
612         /* turn parameters into data stream */
613         lsa_io_q_close("", &q_c, &buf, 0);
614
615         /* send the data on \PIPE\ */
616         if (rpc_api_pipe_req(cli, fnum, LSA_CLOSE, &buf, &rbuf))
617         {
618                 LSA_R_CLOSE r_c;
619                 BOOL p;
620
621                 lsa_io_r_close("", &r_c, &rbuf, 0);
622                 p = rbuf.offset != 0;
623
624                 if (p && r_c.status != 0)
625                 {
626                         /* report error code */
627                         DEBUG(0,("LSA_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
628                         p = False;
629                 }
630
631                 if (p)
632                 {
633                         /* check that the returned policy handle is all zeros */
634                         int i;
635                         valid_close = True;
636
637                         for (i = 0; i < sizeof(r_c.pol.data); i++)
638                         {
639                                 if (r_c.pol.data[i] != 0)
640                                 {
641                                         valid_close = False;
642                                         break;
643                                 }
644                         }       
645                         if (!valid_close)
646                         {
647                                 DEBUG(0,("LSA_CLOSE: non-zero handle returned\n"));
648                         }
649                 }
650         }
651
652         prs_mem_free(&rbuf);
653         prs_mem_free(&buf );
654
655         return valid_close;
656 }
657
658