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