added HKEY_CLASSES_ROOT MSRPC open call. reg_open_hkcr etc. supported
[kai/samba-autobuild/.git] / source3 / rpc_client / cli_reg.c
1
2 /* 
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-1998,
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
8  *  Copyright (C) Paul Ashton                  1997-1998.
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 do a REG Open Policy
36 ****************************************************************************/
37 BOOL do_reg_connect(struct cli_state *cli, uint16 fnum, char *full_keyname, char *key_name,
38                                 POLICY_HND *reg_hnd)
39 {
40         BOOL res = True;
41         uint32 reg_type = 0;
42
43         if (full_keyname == NULL)
44         {
45                 return False;
46         }
47
48         ZERO_STRUCTP(reg_hnd);
49
50         /*
51          * open registry receive a policy handle
52          */
53
54         if (!reg_split_key(full_keyname, &reg_type, key_name))
55         {
56                 DEBUG(0,("do_reg_connect: unrecognised key name %s\n", full_keyname));  
57                 return False;
58         }
59
60         switch (reg_type)
61         {
62                 case HKEY_CLASSES_ROOT:
63                 {
64                         res = res ? do_reg_open_hkcr(cli, fnum,
65                                         0x5428, 0x02000000,
66                                         reg_hnd) : False;
67                         break;
68                 }
69         
70                 case HKEY_LOCAL_MACHINE:
71                 {
72                         res = res ? do_reg_open_hklm(cli, fnum,
73                                         0x84E0, 0x02000000,
74                                         reg_hnd) : False;
75                         break;
76                 }
77         
78                 case HKEY_USERS:
79                 {
80                         res = res ? do_reg_open_hku(cli, fnum,
81                                         0x84E0, 0x02000000,
82                                         reg_hnd) : False;
83                         break;
84                 }
85                 default:
86                 {
87                         DEBUG(0,("do_reg_connect: unrecognised hive key\n"));   
88                         return False;
89                 }
90         }
91
92         return res;
93 }
94
95 /****************************************************************************
96 do a REG Open Policy
97 ****************************************************************************/
98 BOOL do_reg_open_hkcr(struct cli_state *cli, uint16 fnum, uint16 unknown_0, uint32 level,
99                                 POLICY_HND *hnd)
100 {
101         prs_struct rbuf;
102         prs_struct buf; 
103         REG_Q_OPEN_HKCR q_o;
104         BOOL valid_pol = False;
105
106         if (hnd == NULL) return False;
107
108         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
109         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
110
111         /* create and send a MSRPC command with api REG_OPEN_HKCR */
112
113         DEBUG(4,("REG Open HKCR\n"));
114
115         make_reg_q_open_hkcr(&q_o, unknown_0, level);
116
117         /* turn parameters into data stream */
118         reg_io_q_open_hkcr("", &q_o, &buf, 0);
119
120         /* send the data on \PIPE\ */
121         if (rpc_api_pipe_req(cli, fnum, REG_OPEN_HKCR, &buf, &rbuf))
122         {
123                 REG_R_OPEN_HKCR r_o;
124                 BOOL p;
125
126                 ZERO_STRUCT(r_o);
127
128                 reg_io_r_open_hkcr("", &r_o, &rbuf, 0);
129                 p = rbuf.offset != 0;
130
131                 if (p && r_o.status != 0)
132                 {
133                         /* report error code */
134                         DEBUG(0,("REG_OPEN_HKCR: %s\n", get_nt_error_msg(r_o.status)));
135                         p = False;
136                 }
137
138                 if (p)
139                 {
140                         /* ok, at last: we're happy. return the policy handle */
141                         memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
142                         valid_pol = True;
143                 }
144         }
145
146         prs_mem_free(&rbuf);
147         prs_mem_free(&buf );
148
149         return valid_pol;
150 }
151
152 /****************************************************************************
153 do a REG Open Policy
154 ****************************************************************************/
155 BOOL do_reg_open_hklm(struct cli_state *cli, uint16 fnum, uint16 unknown_0, uint32 level,
156                                 POLICY_HND *hnd)
157 {
158         prs_struct rbuf;
159         prs_struct buf; 
160         REG_Q_OPEN_HKLM q_o;
161         BOOL valid_pol = False;
162
163         if (hnd == NULL) return False;
164
165         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
166         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
167
168         /* create and send a MSRPC command with api REG_OPEN_HKLM */
169
170         DEBUG(4,("REG Open HKLM\n"));
171
172         make_reg_q_open_hklm(&q_o, unknown_0, level);
173
174         /* turn parameters into data stream */
175         reg_io_q_open_hklm("", &q_o, &buf, 0);
176
177         /* send the data on \PIPE\ */
178         if (rpc_api_pipe_req(cli, fnum, REG_OPEN_HKLM, &buf, &rbuf))
179         {
180                 REG_R_OPEN_HKLM r_o;
181                 BOOL p;
182
183                 ZERO_STRUCT(r_o);
184
185                 reg_io_r_open_hklm("", &r_o, &rbuf, 0);
186                 p = rbuf.offset != 0;
187
188                 if (p && r_o.status != 0)
189                 {
190                         /* report error code */
191                         DEBUG(0,("REG_OPEN_HKLM: %s\n", get_nt_error_msg(r_o.status)));
192                         p = False;
193                 }
194
195                 if (p)
196                 {
197                         /* ok, at last: we're happy. return the policy handle */
198                         memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
199                         valid_pol = True;
200                 }
201         }
202
203         prs_mem_free(&rbuf);
204         prs_mem_free(&buf );
205
206         return valid_pol;
207 }
208
209 /****************************************************************************
210 do a REG Open HKU
211 ****************************************************************************/
212 BOOL do_reg_open_hku(struct cli_state *cli, uint16 fnum, uint16 unknown_0, uint32 level,
213                                 POLICY_HND *hnd)
214 {
215         prs_struct rbuf;
216         prs_struct buf; 
217         REG_Q_OPEN_HKU q_o;
218         BOOL valid_pol = False;
219
220         if (hnd == NULL) return False;
221
222         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
223         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
224
225         /* create and send a MSRPC command with api REG_OPEN_HKU */
226
227         DEBUG(4,("REG Open HKU\n"));
228
229         make_reg_q_open_hku(&q_o, unknown_0, level);
230
231         /* turn parameters into data stream */
232         reg_io_q_open_hku("", &q_o, &buf, 0);
233
234         /* send the data on \PIPE\ */
235         if (rpc_api_pipe_req(cli, fnum, REG_OPEN_HKU, &buf, &rbuf))
236         {
237                 REG_R_OPEN_HKU r_o;
238                 BOOL p;
239
240                 ZERO_STRUCT(r_o);
241
242                 reg_io_r_open_hku("", &r_o, &rbuf, 0);
243                 p = rbuf.offset != 0;
244
245                 if (p && r_o.status != 0)
246                 {
247                         /* report error code */
248                         DEBUG(0,("REG_OPEN_HKU: %s\n", get_nt_error_msg(r_o.status)));
249                         p = False;
250                 }
251
252                 if (p)
253                 {
254                         /* ok, at last: we're happy. return the policy handle */
255                         memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
256                         valid_pol = True;
257                 }
258         }
259
260         prs_mem_free(&rbuf);
261         prs_mem_free(&buf );
262
263         return valid_pol;
264 }
265
266 /****************************************************************************
267 do a REG Unknown 0xB command.  sent after a create key or create value.
268 this might be some sort of "sync" or "refresh" command, sent after
269 modification of the registry...
270 ****************************************************************************/
271 BOOL do_reg_flush_key(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd)
272 {
273         prs_struct rbuf;
274         prs_struct buf; 
275         REG_Q_FLUSH_KEY q_o;
276         BOOL valid_query = False;
277
278         if (hnd == NULL) return False;
279
280         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
281         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
282
283         /* create and send a MSRPC command with api REG_FLUSH_KEY */
284
285         DEBUG(4,("REG Unknown 0xB\n"));
286
287         make_reg_q_flush_key(&q_o, hnd);
288
289         /* turn parameters into data stream */
290         reg_io_q_flush_key("", &q_o, &buf, 0);
291
292         /* send the data on \PIPE\ */
293         if (rpc_api_pipe_req(cli, fnum, REG_FLUSH_KEY, &buf, &rbuf))
294         {
295                 REG_R_FLUSH_KEY r_o;
296                 BOOL p;
297
298                 ZERO_STRUCT(r_o);
299
300                 reg_io_r_flush_key("", &r_o, &rbuf, 0);
301                 p = rbuf.offset != 0;
302
303                 if (p && r_o.status != 0)
304                 {
305                         /* report error code */
306                         DEBUG(0,("REG_FLUSH_KEY: %s\n", get_nt_error_msg(r_o.status)));
307                         p = False;
308                 }
309
310                 if (p)
311                 {
312                         valid_query = True;
313                 }
314         }
315
316         prs_mem_free(&rbuf);
317         prs_mem_free(&buf );
318
319         return valid_query;
320 }
321
322 /****************************************************************************
323 do a REG Query Key
324 ****************************************************************************/
325 BOOL do_reg_query_key(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd,
326                                 char *key_class, uint32 *class_len,
327                                 uint32 *num_subkeys, uint32 *max_subkeylen,
328                                 uint32 *max_subkeysize, uint32 *num_values,
329                                 uint32 *max_valnamelen, uint32 *max_valbufsize,
330                                 uint32 *sec_desc, NTTIME *mod_time)
331 {
332         prs_struct rbuf;
333         prs_struct buf; 
334         REG_Q_QUERY_KEY q_o;
335         BOOL valid_query = False;
336
337         if (hnd == NULL) return False;
338
339         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
340         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
341
342         /* create and send a MSRPC command with api REG_QUERY_KEY */
343
344         DEBUG(4,("REG Query Key\n"));
345
346         make_reg_q_query_key(&q_o, hnd, *class_len);
347
348         /* turn parameters into data stream */
349         reg_io_q_query_key("", &q_o, &buf, 0);
350
351         /* send the data on \PIPE\ */
352         if (rpc_api_pipe_req(cli, fnum, REG_QUERY_KEY, &buf, &rbuf))
353         {
354                 REG_R_QUERY_KEY r_o;
355                 BOOL p;
356
357                 ZERO_STRUCT(r_o);
358
359                 reg_io_r_query_key("", &r_o, &rbuf, 0);
360                 p = rbuf.offset != 0;
361
362                 if (p && r_o.status != 0)
363                 {
364                         /* report error code */
365                         DEBUG(0,("REG_QUERY_KEY: %s\n", get_nt_error_msg(r_o.status)));
366                         p = False;
367                 }
368
369                 if (p)
370                 {
371                         valid_query = True;
372                         
373                         *class_len      = r_o.hdr_class.uni_max_len;
374                         unistr2_to_ascii(key_class, &r_o.uni_class, sizeof(fstring)-1);
375                         *num_subkeys    = r_o.num_subkeys   ;
376                         *max_subkeylen  = r_o.max_subkeylen ;
377                         *max_subkeysize = r_o.max_subkeysize;
378                         *num_values     = r_o.num_values    ;
379                         *max_valnamelen = r_o.max_valnamelen;
380                         *max_valbufsize = r_o.max_valbufsize;
381                         *sec_desc       = r_o.sec_desc      ;
382                         *mod_time       = r_o.mod_time      ;
383                 }
384         }
385
386         prs_mem_free(&rbuf);
387         prs_mem_free(&buf );
388
389         return valid_query;
390 }
391
392 /****************************************************************************
393 do a REG Unknown 1A
394 ****************************************************************************/
395 BOOL do_reg_unknown_1a(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd, uint32 *unk)
396 {
397         prs_struct rbuf;
398         prs_struct buf; 
399         REG_Q_UNK_1A q_o;
400         BOOL valid_query = False;
401
402         if (hnd == NULL) return False;
403
404         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
405         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
406
407         /* create and send a MSRPC command with api REG_UNKNOWN_1A */
408
409         DEBUG(4,("REG Unknown 1a\n"));
410
411         make_reg_q_unk_1a(&q_o, hnd);
412
413         /* turn parameters into data stream */
414         reg_io_q_unk_1a("", &q_o, &buf, 0);
415
416         /* send the data on \PIPE\ */
417         if (rpc_api_pipe_req(cli, fnum, REG_UNK_1A, &buf, &rbuf))
418         {
419                 REG_R_UNK_1A r_o;
420                 BOOL p;
421
422                 ZERO_STRUCT(r_o);
423
424                 reg_io_r_unk_1a("", &r_o, &rbuf, 0);
425                 p = rbuf.offset != 0;
426
427                 if (p && r_o.status != 0)
428                 {
429                         /* report error code */
430                         DEBUG(0,("REG_UNK_1A: %s\n", get_nt_error_msg(r_o.status)));
431                         p = False;
432                 }
433
434                 if (p)
435                 {
436                         valid_query = True;
437                         (*unk) = r_o.unknown;
438                 }
439         }
440
441         prs_mem_free(&rbuf);
442         prs_mem_free(&buf );
443
444         return valid_query;
445 }
446
447 /****************************************************************************
448 do a REG Query Info
449 ****************************************************************************/
450 BOOL do_reg_query_info(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd,
451                                 char *type, uint32 *unk_0, uint32 *unk_1)
452 {
453         prs_struct rbuf;
454         prs_struct buf; 
455         REG_Q_INFO q_o;
456         BOOL valid_query = False;
457
458         if (hnd == NULL) return False;
459
460         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
461         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
462
463         /* create and send a MSRPC command with api REG_INFO */
464
465         DEBUG(4,("REG Query Info\n"));
466
467         make_reg_q_info(&q_o, hnd, "ProductType", time(NULL), 4, 1);
468
469         /* turn parameters into data stream */
470         reg_io_q_info("", &q_o, &buf, 0);
471
472         /* send the data on \PIPE\ */
473         if (rpc_api_pipe_req(cli, fnum, REG_INFO, &buf, &rbuf))
474         {
475                 REG_R_INFO r_o;
476                 BOOL p;
477
478                 ZERO_STRUCT(r_o);
479
480                 reg_io_r_info("", &r_o, &rbuf, 0);
481                 p = rbuf.offset != 0;
482
483                 if (p && r_o.status != 0)
484                 {
485                         /* report error code */
486                         DEBUG(0,("REG_INFO: %s\n", get_nt_error_msg(r_o.status)));
487                         p = False;
488                 }
489
490                 if (p)
491                 {
492                         valid_query = True;
493                         unibuf_to_ascii(type, (const char*)r_o.uni_type.buffer,
494                                 MIN(r_o.uni_type.buf_len, sizeof(fstring)-1));
495                         (*unk_0) = r_o.unknown_0;
496                         (*unk_1) = r_o.unknown_1;
497                 }
498         }
499
500         prs_mem_free(&rbuf);
501         prs_mem_free(&buf );
502
503         return valid_query;
504 }
505
506 /****************************************************************************
507 do a REG Set Key Security 
508 ****************************************************************************/
509 BOOL do_reg_set_key_sec(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd,
510                                 uint32 sec_buf_size, SEC_DESC *sec_buf)
511 {
512         prs_struct rbuf;
513         prs_struct buf; 
514         REG_Q_SET_KEY_SEC q_o;
515         BOOL valid_query = False;
516
517         if (hnd == NULL) return False;
518
519         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
520         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
521
522         /* create and send a MSRPC command with api REG_SET_KEY_SEC */
523
524         DEBUG(4,("REG Set Key security.\n"));
525
526         make_reg_q_set_key_sec(&q_o, hnd, sec_buf_size, sec_buf);
527
528         /* turn parameters into data stream */
529         reg_io_q_set_key_sec("", &q_o, &buf, 0);
530
531         /* send the data on \PIPE\ */
532         if (rpc_api_pipe_req(cli, fnum, REG_SET_KEY_SEC, &buf, &rbuf))
533         {
534                 REG_R_SET_KEY_SEC r_o;
535                 BOOL p;
536
537                 ZERO_STRUCT(r_o);
538
539                 reg_io_r_set_key_sec("", &r_o, &rbuf, 0);
540                 p = rbuf.offset != 0;
541
542                 if (p && r_o.status != 0)
543                 {
544                         valid_query = True;
545                 }
546         }
547
548         prs_mem_free(&rbuf);
549         prs_mem_free(&buf );
550
551         return valid_query;
552 }
553
554
555 /****************************************************************************
556 do a REG Query Key Security 
557 ****************************************************************************/
558 BOOL do_reg_get_key_sec(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd,
559                                 uint32 *sec_buf_size, SEC_DESC_BUF *sec_buf)
560 {
561         prs_struct rbuf;
562         prs_struct buf; 
563         REG_Q_GET_KEY_SEC q_o;
564         BOOL valid_query = False;
565
566         if (hnd == NULL) return False;
567
568         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
569         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
570
571         /* create and send a MSRPC command with api REG_GET_KEY_SEC */
572
573         DEBUG(4,("REG query key security.  buf_size: %d\n", *sec_buf_size));
574
575         make_reg_q_get_key_sec(&q_o, hnd, *sec_buf_size, sec_buf);
576
577         /* turn parameters into data stream */
578         reg_io_q_get_key_sec("", &q_o, &buf, 0);
579
580         /* send the data on \PIPE\ */
581         if (rpc_api_pipe_req(cli, fnum, REG_GET_KEY_SEC, &buf, &rbuf))
582         {
583                 REG_R_GET_KEY_SEC r_o;
584                 BOOL p;
585
586                 ZERO_STRUCT(r_o);
587
588                 r_o.data = sec_buf;
589                 if (*sec_buf_size != 0)
590                 {
591                         sec_buf->sec = (SEC_DESC*)malloc(*sec_buf_size);
592                 }
593                 reg_io_r_get_key_sec("", &r_o, &rbuf, 0);
594                 p = rbuf.offset != 0;
595
596                 if (p && r_o.status == 0x0000007a)
597                 {
598                         /*
599                          * get the maximum buffer size: it was too small
600                          */
601                         (*sec_buf_size) = r_o.hdr_sec.buf_max_len;
602                         DEBUG(5,("sec_buf_size too small.  use %d\n", *sec_buf_size));
603                         valid_query = True;
604                 }
605                 else if (p && r_o.status != 0)
606                 {
607                         /* report error code */
608                         DEBUG(0,("REG_GET_KEY_SEC: %s\n", get_nt_error_msg(r_o.status)));
609                         p = False;
610                 }
611                 else
612                 {
613                         valid_query = True;
614                         (*sec_buf_size) = r_o.data->len;
615                 }
616         }
617
618         prs_mem_free(&rbuf);
619         prs_mem_free(&buf );
620
621         return valid_query;
622 }
623
624 /****************************************************************************
625 do a REG Delete Value
626 ****************************************************************************/
627 BOOL do_reg_delete_val(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd, char *val_name)
628 {
629         prs_struct rbuf;
630         prs_struct buf; 
631         REG_Q_DELETE_VALUE q_o;
632         BOOL valid_delete = False;
633
634         if (hnd == NULL) return False;
635
636         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
637         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
638
639         /* create and send a MSRPC command with api REG_DELETE_VALUE */
640
641         DEBUG(4,("REG Delete Value: %s\n", val_name));
642
643         make_reg_q_delete_val(&q_o, hnd, val_name);
644
645         /* turn parameters into data stream */
646         reg_io_q_delete_val("", &q_o, &buf, 0);
647
648         /* send the data on \PIPE\ */
649         if (rpc_api_pipe_req(cli, fnum, REG_DELETE_VALUE, &buf, &rbuf))
650         {
651                 REG_R_DELETE_VALUE r_o;
652                 BOOL p;
653
654                 ZERO_STRUCT(r_o);
655
656                 reg_io_r_delete_val("", &r_o, &rbuf, 0);
657                 p = rbuf.offset != 0;
658
659                 if (p && r_o.status != 0)
660                 {
661                         /* report error code */
662                         DEBUG(0,("REG_DELETE_VALUE: %s\n", get_nt_error_msg(r_o.status)));
663                         p = False;
664                 }
665
666                 if (p)
667                 {
668                         valid_delete = True;
669                 }
670         }
671
672         prs_mem_free(&rbuf);
673         prs_mem_free(&buf );
674
675         return valid_delete;
676 }
677
678 /****************************************************************************
679 do a REG Delete Key
680 ****************************************************************************/
681 BOOL do_reg_delete_key(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd, char *key_name)
682 {
683         prs_struct rbuf;
684         prs_struct buf; 
685         REG_Q_DELETE_KEY q_o;
686         BOOL valid_delete = False;
687
688         if (hnd == NULL) return False;
689
690         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
691         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
692
693         /* create and send a MSRPC command with api REG_DELETE_KEY */
694
695         DEBUG(4,("REG Delete Key: %s\n", key_name));
696
697         make_reg_q_delete_key(&q_o, hnd, key_name);
698
699         /* turn parameters into data stream */
700         reg_io_q_delete_key("", &q_o, &buf, 0);
701
702         /* send the data on \PIPE\ */
703         if (rpc_api_pipe_req(cli, fnum, REG_DELETE_KEY, &buf, &rbuf))
704         {
705                 REG_R_DELETE_KEY r_o;
706                 BOOL p;
707
708                 ZERO_STRUCT(r_o);
709
710                 reg_io_r_delete_key("", &r_o, &rbuf, 0);
711                 p = rbuf.offset != 0;
712
713                 if (p && r_o.status != 0)
714                 {
715                         /* report error code */
716                         DEBUG(0,("REG_DELETE_KEY: %s\n", get_nt_error_msg(r_o.status)));
717                         p = False;
718                 }
719
720                 if (p)
721                 {
722                         valid_delete = True;
723                 }
724         }
725
726         prs_mem_free(&rbuf);
727         prs_mem_free(&buf );
728
729         return valid_delete;
730 }
731
732 /****************************************************************************
733 do a REG Create Key
734 ****************************************************************************/
735 BOOL do_reg_create_key(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd,
736                                 char *key_name, char *key_class,
737                                 SEC_ACCESS *sam_access,
738                                 POLICY_HND *key)
739 {
740         prs_struct rbuf;
741         prs_struct buf; 
742         REG_Q_CREATE_KEY q_o;
743         BOOL valid_create = False;
744         SEC_DESC sec;
745         SEC_DESC_BUF sec_buf;
746         int sec_len;
747
748         ZERO_STRUCT(sec);
749         ZERO_STRUCT(sec_buf);
750         ZERO_STRUCT(q_o);
751
752         if (hnd == NULL) return False;
753
754         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
755         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
756
757         /* create and send a MSRPC command with api REG_CREATE_KEY */
758
759         DEBUG(4,("REG Create Key: %s %s 0x%08x\n", key_name, key_class,
760                 sam_access != NULL ? sam_access->mask : 0));
761
762         sec_len = make_sec_desc(&sec, 1, SEC_DESC_SELF_RELATIVE,
763                                 NULL, NULL, NULL, NULL);
764
765         DEBUG(10,("make_sec_desc: len = %d\n", sec_len));
766
767         make_reg_q_create_key(&q_o, hnd, key_name, key_class, sam_access,
768                               &sec_buf, sec_len, &sec);
769
770         /* turn parameters into data stream */
771         reg_io_q_create_key("", &q_o, &buf, 0);
772
773         /* send the data on \PIPE\ */
774         if (rpc_api_pipe_req(cli, fnum, REG_CREATE_KEY, &buf, &rbuf))
775         {
776                 REG_R_CREATE_KEY r_o;
777                 BOOL p;
778
779                 ZERO_STRUCT(r_o);
780
781                 reg_io_r_create_key("", &r_o, &rbuf, 0);
782                 p = rbuf.offset != 0;
783
784                 if (p && r_o.status != 0)
785                 {
786                         /* report error code */
787                         DEBUG(0,("REG_CREATE_KEY: %s\n", get_nt_error_msg(r_o.status)));
788                         p = False;
789                 }
790
791                 if (p)
792                 {
793                         valid_create = True;
794                         memcpy(key, r_o.key_pol.data, sizeof(key->data));
795                 }
796         }
797
798         free_sec_desc(&sec);
799
800         prs_mem_free(&rbuf);
801         prs_mem_free(&buf );
802
803         return valid_create;
804 }
805
806 /****************************************************************************
807 do a REG Enum Key
808 ****************************************************************************/
809 BOOL do_reg_enum_key(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd,
810                                 int key_index, char *key_name,
811                                 uint32 *unk_1, uint32 *unk_2,
812                                 time_t *mod_time)
813 {
814         prs_struct rbuf;
815         prs_struct buf; 
816         REG_Q_ENUM_KEY q_o;
817         BOOL valid_query = False;
818
819         if (hnd == NULL) return False;
820
821         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
822         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
823
824         /* create and send a MSRPC command with api REG_ENUM_KEY */
825
826         DEBUG(4,("REG Enum Key\n"));
827
828         make_reg_q_enum_key(&q_o, hnd, key_index);
829
830         /* turn parameters into data stream */
831         reg_io_q_enum_key("", &q_o, &buf, 0);
832
833         /* send the data on \PIPE\ */
834         if (rpc_api_pipe_req(cli, fnum, REG_ENUM_KEY, &buf, &rbuf))
835         {
836                 REG_R_ENUM_KEY r_o;
837                 BOOL p;
838
839                 ZERO_STRUCT(r_o);
840
841                 reg_io_r_enum_key("", &r_o, &rbuf, 0);
842                 p = rbuf.offset != 0;
843
844                 if (p && r_o.status != 0)
845                 {
846                         /* report error code */
847                         DEBUG(0,("REG_ENUM_KEY: %s\n", get_nt_error_msg(r_o.status)));
848                         p = False;
849                 }
850
851                 if (p)
852                 {
853                         valid_query = True;
854                         (*unk_1) = r_o.unknown_1;
855                         (*unk_2) = r_o.unknown_2;
856                         unistr_to_ascii(key_name, r_o.key_name.str.buffer,
857                                         sizeof(fstring)-1);
858                         (*mod_time) = nt_time_to_unix(&r_o.time);
859                 }
860         }
861
862         prs_mem_free(&rbuf);
863         prs_mem_free(&buf );
864
865         return valid_query;
866 }
867
868 /****************************************************************************
869 do a REG Create Value
870 ****************************************************************************/
871 BOOL do_reg_create_val(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd,
872                                 char *val_name, uint32 type, BUFFER3 *data)
873 {
874         prs_struct rbuf;
875         prs_struct buf; 
876         REG_Q_CREATE_VALUE q_o;
877         BOOL valid_create = False;
878
879         if (hnd == NULL) return False;
880
881         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
882         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
883
884         /* create and send a MSRPC command with api REG_CREATE_VALUE */
885
886         DEBUG(4,("REG Create Value: %s\n", val_name));
887
888         make_reg_q_create_val(&q_o, hnd, val_name, type, data);
889
890         /* turn parameters into data stream */
891         reg_io_q_create_val("", &q_o, &buf, 0);
892
893         /* send the data on \PIPE\ */
894         if (rpc_api_pipe_req(cli, fnum, REG_CREATE_VALUE, &buf, &rbuf))
895         {
896                 REG_R_CREATE_VALUE r_o;
897                 BOOL p;
898
899                 ZERO_STRUCT(r_o);
900
901                 reg_io_r_create_val("", &r_o, &rbuf, 0);
902                 p = rbuf.offset != 0;
903
904                 if (p && r_o.status != 0)
905                 {
906                         /* report error code */
907                         DEBUG(0,("REG_CREATE_VALUE: %s\n", get_nt_error_msg(r_o.status)));
908                         p = False;
909                 }
910
911                 if (p)
912                 {
913                         valid_create = True;
914                 }
915         }
916
917         prs_mem_free(&rbuf);
918         prs_mem_free(&buf );
919
920         return valid_create;
921 }
922
923 /****************************************************************************
924 do a REG Enum Value
925 ****************************************************************************/
926 BOOL do_reg_enum_val(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd,
927                                 int val_index, int max_valnamelen, int max_valbufsize,
928                                 fstring val_name,
929                                 uint32 *val_type, BUFFER2 *value)
930 {
931         prs_struct rbuf;
932         prs_struct buf; 
933         REG_Q_ENUM_VALUE q_o;
934         BOOL valid_query = False;
935
936         if (hnd == NULL) return False;
937
938         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
939         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
940
941         /* create and send a MSRPC command with api REG_ENUM_VALUE */
942
943         DEBUG(4,("REG Enum Value\n"));
944
945         make_reg_q_enum_val(&q_o, hnd, val_index, max_valnamelen, max_valbufsize);
946
947         /* turn parameters into data stream */
948         reg_io_q_enum_val("", &q_o, &buf, 0);
949
950         /* send the data on \PIPE\ */
951         if (rpc_api_pipe_req(cli, fnum, REG_ENUM_VALUE, &buf, &rbuf))
952         {
953                 REG_R_ENUM_VALUE r_o;
954                 BOOL p;
955
956                 ZERO_STRUCT(r_o);
957                 r_o.buf_value = value;
958
959                 reg_io_r_enum_val("", &r_o, &rbuf, 0);
960                 p = rbuf.offset != 0;
961
962                 if (p && r_o.status != 0)
963                 {
964                         /* report error code */
965                         DEBUG(0,("REG_ENUM_VALUE: %s\n", get_nt_error_msg(r_o.status)));
966                         p = False;
967                 }
968
969                 if (p)
970                 {
971                         valid_query = True;
972                         (*val_type) = r_o.type;
973                         unistr2_to_ascii(val_name, &r_o.uni_name, sizeof(fstring)-1);
974                 }
975         }
976
977         prs_mem_free(&rbuf);
978         prs_mem_free(&buf );
979
980         return valid_query;
981 }
982
983 /****************************************************************************
984 do a REG Open Key
985 ****************************************************************************/
986 BOOL do_reg_open_entry(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd,
987                                 char *key_name, uint32 unk_0,
988                                 POLICY_HND *key_hnd)
989 {
990         prs_struct rbuf;
991         prs_struct buf; 
992         REG_Q_OPEN_ENTRY q_o;
993         BOOL valid_pol = False;
994
995         if (hnd == NULL) return False;
996
997         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
998         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
999
1000         /* create and send a MSRPC command with api REG_OPEN_ENTRY */
1001
1002         DEBUG(4,("REG Open Entry\n"));
1003
1004         make_reg_q_open_entry(&q_o, hnd, key_name, unk_0);
1005
1006         /* turn parameters into data stream */
1007         reg_io_q_open_entry("", &q_o, &buf, 0);
1008
1009         /* send the data on \PIPE\ */
1010         if (rpc_api_pipe_req(cli, fnum, REG_OPEN_ENTRY, &buf, &rbuf))
1011         {
1012                 REG_R_OPEN_ENTRY r_o;
1013                 BOOL p;
1014
1015                 ZERO_STRUCT(r_o);
1016
1017                 reg_io_r_open_entry("", &r_o, &rbuf, 0);
1018                 p = rbuf.offset != 0;
1019
1020                 if (p && r_o.status != 0)
1021                 {
1022                         /* report error code */
1023                         DEBUG(0,("REG_OPEN_ENTRY: %s\n", get_nt_error_msg(r_o.status)));
1024                         p = False;
1025                 }
1026
1027                 if (p)
1028                 {
1029                         valid_pol = True;
1030                         memcpy(key_hnd, r_o.pol.data, sizeof(key_hnd->data));
1031                 }
1032         }
1033
1034         prs_mem_free(&rbuf);
1035         prs_mem_free(&buf );
1036
1037         return valid_pol;
1038 }
1039
1040 /****************************************************************************
1041 do a REG Close
1042 ****************************************************************************/
1043 BOOL do_reg_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd)
1044 {
1045         prs_struct rbuf;
1046         prs_struct buf; 
1047         REG_Q_CLOSE q_c;
1048         BOOL valid_close = False;
1049
1050         if (hnd == NULL) return False;
1051
1052         /* create and send a MSRPC command with api REG_CLOSE */
1053
1054         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
1055         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
1056
1057         DEBUG(4,("REG Close\n"));
1058
1059         /* store the parameters */
1060         make_reg_q_close(&q_c, hnd);
1061
1062         /* turn parameters into data stream */
1063         reg_io_q_close("", &q_c, &buf, 0);
1064
1065         /* send the data on \PIPE\ */
1066         if (rpc_api_pipe_req(cli, fnum, REG_CLOSE, &buf, &rbuf))
1067         {
1068                 REG_R_CLOSE r_c;
1069                 BOOL p;
1070
1071                 ZERO_STRUCT(r_c);
1072
1073                 reg_io_r_close("", &r_c, &rbuf, 0);
1074                 p = rbuf.offset != 0;
1075
1076                 if (p && r_c.status != 0)
1077                 {
1078                         /* report error code */
1079                         DEBUG(0,("REG_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
1080                         p = False;
1081                 }
1082
1083                 if (p)
1084                 {
1085                         /* check that the returned policy handle is all zeros */
1086                         uint32 i;
1087                         valid_close = True;
1088
1089                         for (i = 0; i < sizeof(r_c.pol.data); i++)
1090                         {
1091                                 if (r_c.pol.data[i] != 0)
1092                                 {
1093                                         valid_close = False;
1094                                         break;
1095                                 }
1096                         }       
1097                         if (!valid_close)
1098                         {
1099                                 DEBUG(0,("REG_CLOSE: non-zero handle returned\n"));
1100                         }
1101                 }
1102         }
1103
1104         prs_mem_free(&rbuf);
1105         prs_mem_free(&buf );
1106
1107         return valid_close;
1108 }
1109
1110 /****************************************************************************
1111 do a REG Shutdown Server
1112 ****************************************************************************/
1113 BOOL do_reg_shutdown(struct cli_state *cli, uint16 fnum, 
1114                                 char *msg, uint32 timeout, uint16 flags)
1115 {
1116         prs_struct rbuf;
1117         prs_struct buf; 
1118         REG_Q_SHUTDOWN q_o;
1119         BOOL valid_shutdown = False;
1120
1121         if (msg == NULL) return False;
1122
1123         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
1124         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
1125
1126         /* create and send a MSRPC command with api REG_SHUTDOWN */
1127
1128         DEBUG(4,("REG Shutdown: (timeout: %d secs) %s\n", timeout, msg));
1129
1130         make_reg_q_shutdown(&q_o, msg, timeout, flags);
1131
1132         /* turn parameters into data stream */
1133         reg_io_q_shutdown("", &q_o, &buf, 0);
1134
1135         /* send the data on \PIPE\ */
1136         if (rpc_api_pipe_req(cli, fnum, REG_SHUTDOWN, &buf, &rbuf))
1137         {
1138                 REG_R_SHUTDOWN r_o;
1139                 BOOL p;
1140
1141                 ZERO_STRUCT(r_o);
1142
1143                 reg_io_r_shutdown("", &r_o, &rbuf, 0);
1144                 p = rbuf.offset != 0;
1145
1146                 if (p && r_o.status != 0)
1147                 {
1148                         /* report error code */
1149                         DEBUG(0,("REG_SHUTDOWN: %s\n", get_nt_error_msg(r_o.status)));
1150                         p = False;
1151                 }
1152
1153                 if (p)
1154                 {
1155                         valid_shutdown = True;
1156                 }
1157         }
1158
1159         prs_mem_free(&rbuf);
1160         prs_mem_free(&buf );
1161
1162         return valid_shutdown;
1163 }
1164
1165