rpcclient registry key delete command: "regdeletekey".
[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-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 REG Open Policy
37 ****************************************************************************/
38 BOOL do_reg_open_policy(struct cli_state *cli, uint16 unknown_0, uint32 level,
39                                 POLICY_HND *hnd)
40 {
41         prs_struct rbuf;
42         prs_struct buf; 
43         REG_Q_OPEN_POLICY q_o;
44         BOOL valid_pol = False;
45
46         if (hnd == NULL) return False;
47
48         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
49         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
50
51         /* create and send a MSRPC command with api REG_OPEN_POLICY */
52
53         DEBUG(4,("REG Open Policy\n"));
54
55         make_reg_q_open_pol(&q_o, unknown_0, level);
56
57         /* turn parameters into data stream */
58         reg_io_q_open_policy("", &q_o, &buf, 0);
59
60         /* send the data on \PIPE\ */
61         if (rpc_api_pipe_req(cli, REG_OPEN_POLICY, &buf, &rbuf))
62         {
63                 REG_R_OPEN_POLICY r_o;
64                 BOOL p;
65
66                 ZERO_STRUCT(r_o);
67
68                 reg_io_r_open_policy("", &r_o, &rbuf, 0);
69                 p = rbuf.offset != 0;
70
71                 if (p && r_o.status != 0)
72                 {
73                         /* report error code */
74                         DEBUG(0,("REG_OPEN_POLICY: %s\n", get_nt_error_msg(r_o.status)));
75                         p = False;
76                 }
77
78                 if (p)
79                 {
80                         /* ok, at last: we're happy. return the policy handle */
81                         memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
82                         valid_pol = True;
83                 }
84         }
85
86         prs_mem_free(&rbuf);
87         prs_mem_free(&buf );
88
89         return valid_pol;
90 }
91
92 /****************************************************************************
93 do a REG Open Unknown 4
94 ****************************************************************************/
95 BOOL do_reg_open_unk_4(struct cli_state *cli, uint16 unknown_0, uint32 level,
96                                 POLICY_HND *hnd)
97 {
98         prs_struct rbuf;
99         prs_struct buf; 
100         REG_Q_OPEN_UNK_4 q_o;
101         BOOL valid_pol = False;
102
103         if (hnd == NULL) return False;
104
105         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
106         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
107
108         /* create and send a MSRPC command with api REG_OPEN_UNK_4 */
109
110         DEBUG(4,("REG Open Unknown4\n"));
111
112         make_reg_q_open_unk_4(&q_o, unknown_0, level);
113
114         /* turn parameters into data stream */
115         reg_io_q_open_unk_4("", &q_o, &buf, 0);
116
117         /* send the data on \PIPE\ */
118         if (rpc_api_pipe_req(cli, REG_OPEN_UNK_4, &buf, &rbuf))
119         {
120                 REG_R_OPEN_UNK_4 r_o;
121                 BOOL p;
122
123                 ZERO_STRUCT(r_o);
124
125                 reg_io_r_open_unk_4("", &r_o, &rbuf, 0);
126                 p = rbuf.offset != 0;
127
128                 if (p && r_o.status != 0)
129                 {
130                         /* report error code */
131                         DEBUG(0,("REG_OPEN_UNK_4: %s\n", get_nt_error_msg(r_o.status)));
132                         p = False;
133                 }
134
135                 if (p)
136                 {
137                         /* ok, at last: we're happy. return the policy handle */
138                         memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
139                         valid_pol = True;
140                 }
141         }
142
143         prs_mem_free(&rbuf);
144         prs_mem_free(&buf );
145
146         return valid_pol;
147 }
148
149 /****************************************************************************
150 do a REG Unknown 0xB command.  sent after a create key or create value.
151 this might be some sort of "sync" or "refresh" command, sent after
152 modification of the registry...
153 ****************************************************************************/
154 BOOL do_reg_unk_b(struct cli_state *cli, POLICY_HND *hnd)
155 {
156         prs_struct rbuf;
157         prs_struct buf; 
158         REG_Q_UNK_B q_o;
159         BOOL valid_query = False;
160
161         if (hnd == NULL) return False;
162
163         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
164         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
165
166         /* create and send a MSRPC command with api REG_UNK_B */
167
168         DEBUG(4,("REG Unknown 0xB\n"));
169
170         make_reg_q_unk_b(&q_o, hnd);
171
172         /* turn parameters into data stream */
173         reg_io_q_unk_b("", &q_o, &buf, 0);
174
175         /* send the data on \PIPE\ */
176         if (rpc_api_pipe_req(cli, REG_UNK_B, &buf, &rbuf))
177         {
178                 REG_R_UNK_B r_o;
179                 BOOL p;
180
181                 ZERO_STRUCT(r_o);
182
183                 reg_io_r_unk_b("", &r_o, &rbuf, 0);
184                 p = rbuf.offset != 0;
185
186                 if (p && r_o.status != 0)
187                 {
188                         /* report error code */
189                         DEBUG(0,("REG_UNK_B: %s\n", get_nt_error_msg(r_o.status)));
190                         p = False;
191                 }
192
193                 if (p)
194                 {
195                         valid_query = True;
196                 }
197         }
198
199         prs_mem_free(&rbuf);
200         prs_mem_free(&buf );
201
202         return valid_query;
203 }
204
205 /****************************************************************************
206 do a REG Query Key
207 ****************************************************************************/
208 BOOL do_reg_query_key(struct cli_state *cli, POLICY_HND *hnd,
209                                 char *class, uint32 *class_len,
210                                 uint32 *num_subkeys, uint32 *max_subkeylen,
211                                 uint32 *max_subkeysize, uint32 *num_values,
212                                 uint32 *max_valnamelen, uint32 *max_valbufsize,
213                                 uint32 *sec_desc, NTTIME *mod_time)
214 {
215         prs_struct rbuf;
216         prs_struct buf; 
217         REG_Q_QUERY_KEY q_o;
218         BOOL valid_query = 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_QUERY_KEY */
226
227         DEBUG(4,("REG Query Key\n"));
228
229         make_reg_q_query_key(&q_o, hnd, *class_len);
230
231         /* turn parameters into data stream */
232         reg_io_q_query_key("", &q_o, &buf, 0);
233
234         /* send the data on \PIPE\ */
235         if (rpc_api_pipe_req(cli, REG_QUERY_KEY, &buf, &rbuf))
236         {
237                 REG_R_QUERY_KEY r_o;
238                 BOOL p;
239
240                 ZERO_STRUCT(r_o);
241
242                 reg_io_r_query_key("", &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_QUERY_KEY: %s\n", get_nt_error_msg(r_o.status)));
249                         p = False;
250                 }
251
252                 if (p)
253                 {
254                         valid_query = True;
255                         
256                         *class_len      = r_o.hdr_class.uni_max_len;
257                         fstrcpy(class, unistr2_to_str(&r_o.uni_class));
258                         *num_subkeys    = r_o.num_subkeys   ;
259                         *max_subkeylen  = r_o.max_subkeylen ;
260                         *max_subkeysize = r_o.max_subkeysize;
261                         *num_values     = r_o.num_values    ;
262                         *max_valnamelen = r_o.max_valnamelen;
263                         *max_valbufsize = r_o.max_valbufsize;
264                         *sec_desc       = r_o.sec_desc      ;
265                         *mod_time       = r_o.mod_time      ;
266                 }
267         }
268
269         prs_mem_free(&rbuf);
270         prs_mem_free(&buf );
271
272         return valid_query;
273 }
274
275 /****************************************************************************
276 do a REG Unknown 1A
277 ****************************************************************************/
278 BOOL do_reg_unknown_1a(struct cli_state *cli, POLICY_HND *hnd, uint32 *unk)
279 {
280         prs_struct rbuf;
281         prs_struct buf; 
282         REG_Q_UNK_1A q_o;
283         BOOL valid_query = False;
284
285         if (hnd == NULL) return False;
286
287         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
288         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
289
290         /* create and send a MSRPC command with api REG_UNKNOWN_1A */
291
292         DEBUG(4,("REG Unknown 1a\n"));
293
294         make_reg_q_unk_1a(&q_o, hnd);
295
296         /* turn parameters into data stream */
297         reg_io_q_unk_1a("", &q_o, &buf, 0);
298
299         /* send the data on \PIPE\ */
300         if (rpc_api_pipe_req(cli, REG_UNK_1A, &buf, &rbuf))
301         {
302                 REG_R_UNK_1A r_o;
303                 BOOL p;
304
305                 ZERO_STRUCT(r_o);
306
307                 reg_io_r_unk_1a("", &r_o, &rbuf, 0);
308                 p = rbuf.offset != 0;
309
310                 if (p && r_o.status != 0)
311                 {
312                         /* report error code */
313                         DEBUG(0,("REG_UNK_1A: %s\n", get_nt_error_msg(r_o.status)));
314                         p = False;
315                 }
316
317                 if (p)
318                 {
319                         valid_query = True;
320                         (*unk) = r_o.unknown;
321                 }
322         }
323
324         prs_mem_free(&rbuf);
325         prs_mem_free(&buf );
326
327         return valid_query;
328 }
329
330 /****************************************************************************
331 do a REG Query Info
332 ****************************************************************************/
333 BOOL do_reg_query_info(struct cli_state *cli, POLICY_HND *hnd,
334                                 char *type, uint32 *unk_0, uint32 *unk_1)
335 {
336         prs_struct rbuf;
337         prs_struct buf; 
338         REG_Q_INFO q_o;
339         BOOL valid_query = False;
340
341         if (hnd == NULL) return False;
342
343         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
344         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
345
346         /* create and send a MSRPC command with api REG_INFO */
347
348         DEBUG(4,("REG Query Info\n"));
349
350         make_reg_q_info(&q_o, hnd, "ProductType", time(NULL), 4, 1);
351
352         /* turn parameters into data stream */
353         reg_io_q_info("", &q_o, &buf, 0);
354
355         /* send the data on \PIPE\ */
356         if (rpc_api_pipe_req(cli, REG_INFO, &buf, &rbuf))
357         {
358                 REG_R_INFO r_o;
359                 BOOL p;
360
361                 ZERO_STRUCT(r_o);
362
363                 reg_io_r_info("", &r_o, &rbuf, 0);
364                 p = rbuf.offset != 0;
365
366                 if (p && r_o.status != 0)
367                 {
368                         /* report error code */
369                         DEBUG(0,("REG_INFO: %s\n", get_nt_error_msg(r_o.status)));
370                         p = False;
371                 }
372
373                 if (p)
374                 {
375                         valid_query = True;
376                         fstrcpy(type, buffer2_to_str(&r_o.uni_type));
377                         (*unk_0) = r_o.unknown_0;
378                         (*unk_1) = r_o.unknown_1;
379                 }
380         }
381
382         prs_mem_free(&rbuf);
383         prs_mem_free(&buf );
384
385         return valid_query;
386 }
387
388 /****************************************************************************
389 do a REG Query Key Security 
390 ****************************************************************************/
391 BOOL do_reg_get_key_sec(struct cli_state *cli, POLICY_HND *hnd,
392                                 uint32 *sec_buf_size, SEC_DESC_BUF *sec_buf)
393 {
394         prs_struct rbuf;
395         prs_struct buf; 
396         REG_Q_GET_KEY_SEC q_o;
397         BOOL valid_query = False;
398
399         if (hnd == NULL) return False;
400
401         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
402         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
403
404         /* create and send a MSRPC command with api REG_GET_KEY_SEC */
405
406         DEBUG(4,("REG query key security.  buf_size: %d\n", *sec_buf_size));
407
408         make_reg_q_get_key_sec(&q_o, hnd, *sec_buf_size, sec_buf);
409
410         /* turn parameters into data stream */
411         reg_io_q_get_key_sec("", &q_o, &buf, 0);
412
413         /* send the data on \PIPE\ */
414         if (rpc_api_pipe_req(cli, REG_GET_KEY_SEC, &buf, &rbuf))
415         {
416                 REG_R_GET_KEY_SEC r_o;
417                 BOOL p;
418
419                 ZERO_STRUCT(r_o);
420
421                 r_o.data = sec_buf;
422                 reg_io_r_get_key_sec("", &r_o, &rbuf, 0);
423                 p = rbuf.offset != 0;
424
425                 if (p && r_o.status == 0x0000007a)
426                 {
427                         /*
428                          * get the maximum buffer size: it was too small
429                          */
430                         (*sec_buf_size) = r_o.hdr_sec.buf_max_len;
431                         DEBUG(5,("sec_buf_size too small.  use %d\n", *sec_buf_size));
432                         valid_query = True;
433                 }
434                 else if (p && r_o.status != 0)
435                 {
436                         /* report error code */
437                         DEBUG(0,("REG_GET_KEY_SEC: %s\n", get_nt_error_msg(r_o.status)));
438                         p = False;
439                 }
440                 else
441                 {
442                         valid_query = True;
443                         (*sec_buf_size) = r_o.data->len;
444                 }
445         }
446
447         prs_mem_free(&rbuf);
448         prs_mem_free(&buf );
449
450         return valid_query;
451 }
452
453 /****************************************************************************
454 do a REG Delete Key
455 ****************************************************************************/
456 BOOL do_reg_delete_key(struct cli_state *cli, POLICY_HND *hnd, char *key_name)
457 {
458         prs_struct rbuf;
459         prs_struct buf; 
460         REG_Q_DELETE_KEY q_o;
461         BOOL valid_delete = False;
462
463         if (hnd == NULL) return False;
464
465         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
466         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
467
468         /* create and send a MSRPC command with api REG_DELETE_KEY */
469
470         DEBUG(4,("REG Delete Key: %s\n", key_name));
471
472         make_reg_q_delete_key(&q_o, hnd, key_name);
473
474         /* turn parameters into data stream */
475         reg_io_q_delete_key("", &q_o, &buf, 0);
476
477         /* send the data on \PIPE\ */
478         if (rpc_api_pipe_req(cli, REG_DELETE_KEY, &buf, &rbuf))
479         {
480                 REG_R_DELETE_KEY r_o;
481                 BOOL p;
482
483                 ZERO_STRUCT(r_o);
484
485                 reg_io_r_delete_key("", &r_o, &rbuf, 0);
486                 p = rbuf.offset != 0;
487
488                 if (p && r_o.status != 0)
489                 {
490                         /* report error code */
491                         DEBUG(0,("REG_DELETE_KEY: %s\n", get_nt_error_msg(r_o.status)));
492                         p = False;
493                 }
494
495                 if (p)
496                 {
497                         valid_delete = True;
498                 }
499         }
500
501         prs_mem_free(&rbuf);
502         prs_mem_free(&buf );
503
504         return valid_delete;
505 }
506
507 /****************************************************************************
508 do a REG Create Key
509 ****************************************************************************/
510 BOOL do_reg_create_key(struct cli_state *cli, POLICY_HND *hnd,
511                                 char *key_name, char *key_class,
512                                 SEC_INFO *sam_access,
513                                 POLICY_HND *key)
514 {
515         prs_struct rbuf;
516         prs_struct buf; 
517         REG_Q_CREATE_KEY q_o;
518         BOOL valid_create = False;
519
520         if (hnd == NULL) return False;
521
522         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
523         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
524
525         /* create and send a MSRPC command with api REG_CREATE_KEY */
526
527         DEBUG(4,("REG Create Key: %s %s 0x%08x\n", key_name, key_class,
528                 sam_access != NULL ? sam_access->perms : 0));
529
530         make_reg_q_create_key(&q_o, hnd, key_name, key_class, sam_access);
531
532         /* turn parameters into data stream */
533         reg_io_q_create_key("", &q_o, &buf, 0);
534
535         /* send the data on \PIPE\ */
536         if (rpc_api_pipe_req(cli, REG_CREATE_KEY, &buf, &rbuf))
537         {
538                 REG_R_CREATE_KEY r_o;
539                 BOOL p;
540
541                 ZERO_STRUCT(r_o);
542
543                 reg_io_r_create_key("", &r_o, &rbuf, 0);
544                 p = rbuf.offset != 0;
545
546                 if (p && r_o.status != 0)
547                 {
548                         /* report error code */
549                         DEBUG(0,("REG_CREATE_KEY: %s\n", get_nt_error_msg(r_o.status)));
550                         p = False;
551                 }
552
553                 if (p)
554                 {
555                         valid_create = True;
556                         memcpy(key, r_o.key_pol.data, sizeof(key->data));
557                 }
558         }
559
560         prs_mem_free(&rbuf);
561         prs_mem_free(&buf );
562
563         return valid_create;
564 }
565
566 /****************************************************************************
567 do a REG Enum Key
568 ****************************************************************************/
569 BOOL do_reg_enum_key(struct cli_state *cli, POLICY_HND *hnd,
570                                 int key_index, char *key_name,
571                                 uint32 *unk_1, uint32 *unk_2,
572                                 time_t *mod_time)
573 {
574         prs_struct rbuf;
575         prs_struct buf; 
576         REG_Q_ENUM_KEY q_o;
577         BOOL valid_query = False;
578
579         if (hnd == NULL) return False;
580
581         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
582         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
583
584         /* create and send a MSRPC command with api REG_ENUM_KEY */
585
586         DEBUG(4,("REG Enum Key\n"));
587
588         make_reg_q_enum_key(&q_o, hnd, key_index);
589
590         /* turn parameters into data stream */
591         reg_io_q_enum_key("", &q_o, &buf, 0);
592
593         /* send the data on \PIPE\ */
594         if (rpc_api_pipe_req(cli, REG_ENUM_KEY, &buf, &rbuf))
595         {
596                 REG_R_ENUM_KEY r_o;
597                 BOOL p;
598
599                 ZERO_STRUCT(r_o);
600
601                 reg_io_r_enum_key("", &r_o, &rbuf, 0);
602                 p = rbuf.offset != 0;
603
604                 if (p && r_o.status != 0)
605                 {
606                         /* report error code */
607                         DEBUG(0,("REG_ENUM_KEY: %s\n", get_nt_error_msg(r_o.status)));
608                         p = False;
609                 }
610
611                 if (p)
612                 {
613                         valid_query = True;
614                         (*unk_1) = r_o.unknown_1;
615                         (*unk_2) = r_o.unknown_2;
616                         fstrcpy(key_name, unistr2(r_o.key_name.str.buffer));
617                         (*mod_time) = nt_time_to_unix(&r_o.time);
618                 }
619         }
620
621         prs_mem_free(&rbuf);
622         prs_mem_free(&buf );
623
624         return valid_query;
625 }
626
627 /****************************************************************************
628 do a REG Create Value
629 ****************************************************************************/
630 BOOL do_reg_create_val(struct cli_state *cli, POLICY_HND *hnd,
631                                 char *val_name, uint32 type, BUFFER3 *data)
632 {
633         prs_struct rbuf;
634         prs_struct buf; 
635         REG_Q_CREATE_VALUE q_o;
636         BOOL valid_create = False;
637
638         if (hnd == NULL) return False;
639
640         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
641         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
642
643         /* create and send a MSRPC command with api REG_CREATE_VALUE */
644
645         DEBUG(4,("REG Create Value: %s\n", val_name));
646
647         make_reg_q_create_val(&q_o, hnd, val_name, type, data);
648
649         /* turn parameters into data stream */
650         reg_io_q_create_val("", &q_o, &buf, 0);
651
652         /* send the data on \PIPE\ */
653         if (rpc_api_pipe_req(cli, REG_CREATE_VALUE, &buf, &rbuf))
654         {
655                 REG_R_CREATE_VALUE r_o;
656                 BOOL p;
657
658                 ZERO_STRUCT(r_o);
659
660                 reg_io_r_create_val("", &r_o, &rbuf, 0);
661                 p = rbuf.offset != 0;
662
663                 if (p && r_o.status != 0)
664                 {
665                         /* report error code */
666                         DEBUG(0,("REG_CREATE_VALUE: %s\n", get_nt_error_msg(r_o.status)));
667                         p = False;
668                 }
669
670                 if (p)
671                 {
672                         valid_create = True;
673                 }
674         }
675
676         prs_mem_free(&rbuf);
677         prs_mem_free(&buf );
678
679         return valid_create;
680 }
681
682 /****************************************************************************
683 do a REG Enum Value
684 ****************************************************************************/
685 BOOL do_reg_enum_val(struct cli_state *cli, POLICY_HND *hnd,
686                                 int val_index, int max_valnamelen, int max_valbufsize,
687                                 fstring val_name,
688                                 uint32 *val_type, BUFFER2 *value)
689 {
690         prs_struct rbuf;
691         prs_struct buf; 
692         REG_Q_ENUM_VALUE q_o;
693         BOOL valid_query = False;
694
695         if (hnd == NULL) return False;
696
697         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
698         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
699
700         /* create and send a MSRPC command with api REG_ENUM_VALUE */
701
702         DEBUG(4,("REG Enum Value\n"));
703
704         make_reg_q_enum_val(&q_o, hnd, val_index, max_valnamelen, max_valbufsize);
705
706         /* turn parameters into data stream */
707         reg_io_q_enum_val("", &q_o, &buf, 0);
708
709         /* send the data on \PIPE\ */
710         if (rpc_api_pipe_req(cli, REG_ENUM_VALUE, &buf, &rbuf))
711         {
712                 REG_R_ENUM_VALUE r_o;
713                 BOOL p;
714
715                 ZERO_STRUCT(r_o);
716                 r_o.buf_value = value;
717
718                 reg_io_r_enum_val("", &r_o, &rbuf, 0);
719                 p = rbuf.offset != 0;
720
721                 if (p && r_o.status != 0)
722                 {
723                         /* report error code */
724                         DEBUG(0,("REG_ENUM_VALUE: %s\n", get_nt_error_msg(r_o.status)));
725                         p = False;
726                 }
727
728                 if (p)
729                 {
730                         valid_query = True;
731                         (*val_type) = r_o.type;
732                         fstrcpy(val_name, unistr2_to_str(&r_o.uni_name));
733                 }
734         }
735
736         prs_mem_free(&rbuf);
737         prs_mem_free(&buf );
738
739         return valid_query;
740 }
741
742 /****************************************************************************
743 do a REG Open Key
744 ****************************************************************************/
745 BOOL do_reg_open_entry(struct cli_state *cli, POLICY_HND *hnd,
746                                 char *key_name, uint32 unk_0,
747                                 POLICY_HND *key_hnd)
748 {
749         prs_struct rbuf;
750         prs_struct buf; 
751         REG_Q_OPEN_ENTRY q_o;
752         BOOL valid_pol = False;
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_OPEN_ENTRY */
760
761         DEBUG(4,("REG Open Entry\n"));
762
763         make_reg_q_open_entry(&q_o, hnd, key_name, unk_0);
764
765         /* turn parameters into data stream */
766         reg_io_q_open_entry("", &q_o, &buf, 0);
767
768         /* send the data on \PIPE\ */
769         if (rpc_api_pipe_req(cli, REG_OPEN_ENTRY, &buf, &rbuf))
770         {
771                 REG_R_OPEN_ENTRY r_o;
772                 BOOL p;
773
774                 ZERO_STRUCT(r_o);
775
776                 reg_io_r_open_entry("", &r_o, &rbuf, 0);
777                 p = rbuf.offset != 0;
778
779                 if (p && r_o.status != 0)
780                 {
781                         /* report error code */
782                         DEBUG(0,("REG_OPEN_ENTRY: %s\n", get_nt_error_msg(r_o.status)));
783                         p = False;
784                 }
785
786                 if (p)
787                 {
788                         valid_pol = True;
789                         memcpy(key_hnd, r_o.pol.data, sizeof(key_hnd->data));
790                 }
791         }
792
793         prs_mem_free(&rbuf);
794         prs_mem_free(&buf );
795
796         return valid_pol;
797 }
798
799 /****************************************************************************
800 do a REG Close
801 ****************************************************************************/
802 BOOL do_reg_close(struct cli_state *cli, POLICY_HND *hnd)
803 {
804         prs_struct rbuf;
805         prs_struct buf; 
806         REG_Q_CLOSE q_c;
807         BOOL valid_close = False;
808
809         if (hnd == NULL) return False;
810
811         /* create and send a MSRPC command with api REG_CLOSE */
812
813         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
814         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
815
816         DEBUG(4,("REG Close\n"));
817
818         /* store the parameters */
819         make_reg_q_close(&q_c, hnd);
820
821         /* turn parameters into data stream */
822         reg_io_q_close("", &q_c, &buf, 0);
823
824         /* send the data on \PIPE\ */
825         if (rpc_api_pipe_req(cli, REG_CLOSE, &buf, &rbuf))
826         {
827                 REG_R_CLOSE r_c;
828                 BOOL p;
829
830                 ZERO_STRUCT(r_c);
831
832                 reg_io_r_close("", &r_c, &rbuf, 0);
833                 p = rbuf.offset != 0;
834
835                 if (p && r_c.status != 0)
836                 {
837                         /* report error code */
838                         DEBUG(0,("REG_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
839                         p = False;
840                 }
841
842                 if (p)
843                 {
844                         /* check that the returned policy handle is all zeros */
845                         int i;
846                         valid_close = True;
847
848                         for (i = 0; i < sizeof(r_c.pol.data); i++)
849                         {
850                                 if (r_c.pol.data[i] != 0)
851                                 {
852                                         valid_close = False;
853                                         break;
854                                 }
855                         }       
856                         if (!valid_close)
857                         {
858                                 DEBUG(0,("REG_CLOSE: non-zero handle returned\n"));
859                         }
860                 }
861         }
862
863         prs_mem_free(&rbuf);
864         prs_mem_free(&buf );
865
866         return valid_close;
867 }
868
869