Makefile.in: Added target for makeyodldocs - not used by default.
[samba.git] / source / 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_connect(struct cli_state *cli, char *full_keyname,
39                                 POLICY_HND *reg_hnd,
40                                 POLICY_HND *key_hnd)
41 {
42         fstring key_name;
43         char *srch;
44         BOOL res1;
45         BOOL res = False;
46         BOOL hklm = False;
47         BOOL hku  = False;
48
49         if (full_keyname == NULL)
50         {
51                 return False;
52         }
53
54         srch = "HKLM";
55         if (strnequal(full_keyname, srch, strlen(srch)))
56         {
57                 full_keyname += strlen(srch);
58                 if (*full_keyname == '\\')
59                 {
60                         full_keyname++;
61                         fstrcpy(key_name, full_keyname);
62                 }
63                 else if (*full_keyname != 0)
64                 {
65                         return False;
66                 }
67         }
68
69         /* open registry receive a policy handle */
70
71         if (hklm)
72         {
73                 res = do_reg_open_hklm(cli,
74                                 0x84E0, 0x02000000,
75                                 reg_hnd);
76         }
77         
78         if (hku)
79         {
80                 res = do_reg_open_hku(cli,
81                                 0x84E0, 0x02000000,
82                                 reg_hnd);
83         }
84
85         /* open an entry */
86         res1 = res  ? do_reg_open_entry(cli, reg_hnd,
87                                  key_name, 0x02000000, key_hnd) : False;
88
89         return res1 && res;
90 }
91
92 /****************************************************************************
93 do a REG Open Policy
94 ****************************************************************************/
95 BOOL do_reg_open_hklm(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_HKLM 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_HKLM */
109
110         DEBUG(4,("REG Open HKLM\n"));
111
112         make_reg_q_open_hklm(&q_o, unknown_0, level);
113
114         /* turn parameters into data stream */
115         reg_io_q_open_hklm("", &q_o, &buf, 0);
116
117         /* send the data on \PIPE\ */
118         if (rpc_api_pipe_req(cli, REG_OPEN_HKLM, &buf, &rbuf))
119         {
120                 REG_R_OPEN_HKLM r_o;
121                 BOOL p;
122
123                 ZERO_STRUCT(r_o);
124
125                 reg_io_r_open_hklm("", &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_HKLM: %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 Open HKU
151 ****************************************************************************/
152 BOOL do_reg_open_hku(struct cli_state *cli, uint16 unknown_0, uint32 level,
153                                 POLICY_HND *hnd)
154 {
155         prs_struct rbuf;
156         prs_struct buf; 
157         REG_Q_OPEN_HKU q_o;
158         BOOL valid_pol = False;
159
160         if (hnd == NULL) return False;
161
162         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
163         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
164
165         /* create and send a MSRPC command with api REG_OPEN_HKU */
166
167         DEBUG(4,("REG Open HKU\n"));
168
169         make_reg_q_open_hku(&q_o, unknown_0, level);
170
171         /* turn parameters into data stream */
172         reg_io_q_open_hku("", &q_o, &buf, 0);
173
174         /* send the data on \PIPE\ */
175         if (rpc_api_pipe_req(cli, REG_OPEN_HKU, &buf, &rbuf))
176         {
177                 REG_R_OPEN_HKU r_o;
178                 BOOL p;
179
180                 ZERO_STRUCT(r_o);
181
182                 reg_io_r_open_hku("", &r_o, &rbuf, 0);
183                 p = rbuf.offset != 0;
184
185                 if (p && r_o.status != 0)
186                 {
187                         /* report error code */
188                         DEBUG(0,("REG_OPEN_HKU: %s\n", get_nt_error_msg(r_o.status)));
189                         p = False;
190                 }
191
192                 if (p)
193                 {
194                         /* ok, at last: we're happy. return the policy handle */
195                         memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
196                         valid_pol = True;
197                 }
198         }
199
200         prs_mem_free(&rbuf);
201         prs_mem_free(&buf );
202
203         return valid_pol;
204 }
205
206 /****************************************************************************
207 do a REG Unknown 0xB command.  sent after a create key or create value.
208 this might be some sort of "sync" or "refresh" command, sent after
209 modification of the registry...
210 ****************************************************************************/
211 BOOL do_reg_flush_key(struct cli_state *cli, POLICY_HND *hnd)
212 {
213         prs_struct rbuf;
214         prs_struct buf; 
215         REG_Q_FLUSH_KEY q_o;
216         BOOL valid_query = False;
217
218         if (hnd == NULL) return False;
219
220         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
221         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
222
223         /* create and send a MSRPC command with api REG_FLUSH_KEY */
224
225         DEBUG(4,("REG Unknown 0xB\n"));
226
227         make_reg_q_flush_key(&q_o, hnd);
228
229         /* turn parameters into data stream */
230         reg_io_q_flush_key("", &q_o, &buf, 0);
231
232         /* send the data on \PIPE\ */
233         if (rpc_api_pipe_req(cli, REG_FLUSH_KEY, &buf, &rbuf))
234         {
235                 REG_R_FLUSH_KEY r_o;
236                 BOOL p;
237
238                 ZERO_STRUCT(r_o);
239
240                 reg_io_r_flush_key("", &r_o, &rbuf, 0);
241                 p = rbuf.offset != 0;
242
243                 if (p && r_o.status != 0)
244                 {
245                         /* report error code */
246                         DEBUG(0,("REG_FLUSH_KEY: %s\n", get_nt_error_msg(r_o.status)));
247                         p = False;
248                 }
249
250                 if (p)
251                 {
252                         valid_query = True;
253                 }
254         }
255
256         prs_mem_free(&rbuf);
257         prs_mem_free(&buf );
258
259         return valid_query;
260 }
261
262 /****************************************************************************
263 do a REG Query Key
264 ****************************************************************************/
265 BOOL do_reg_query_key(struct cli_state *cli, POLICY_HND *hnd,
266                                 char *class, uint32 *class_len,
267                                 uint32 *num_subkeys, uint32 *max_subkeylen,
268                                 uint32 *max_subkeysize, uint32 *num_values,
269                                 uint32 *max_valnamelen, uint32 *max_valbufsize,
270                                 uint32 *sec_desc, NTTIME *mod_time)
271 {
272         prs_struct rbuf;
273         prs_struct buf; 
274         REG_Q_QUERY_KEY q_o;
275         BOOL valid_query = False;
276
277         if (hnd == NULL) return False;
278
279         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
280         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
281
282         /* create and send a MSRPC command with api REG_QUERY_KEY */
283
284         DEBUG(4,("REG Query Key\n"));
285
286         make_reg_q_query_key(&q_o, hnd, *class_len);
287
288         /* turn parameters into data stream */
289         reg_io_q_query_key("", &q_o, &buf, 0);
290
291         /* send the data on \PIPE\ */
292         if (rpc_api_pipe_req(cli, REG_QUERY_KEY, &buf, &rbuf))
293         {
294                 REG_R_QUERY_KEY r_o;
295                 BOOL p;
296
297                 ZERO_STRUCT(r_o);
298
299                 reg_io_r_query_key("", &r_o, &rbuf, 0);
300                 p = rbuf.offset != 0;
301
302                 if (p && r_o.status != 0)
303                 {
304                         /* report error code */
305                         DEBUG(0,("REG_QUERY_KEY: %s\n", get_nt_error_msg(r_o.status)));
306                         p = False;
307                 }
308
309                 if (p)
310                 {
311                         valid_query = True;
312                         
313                         *class_len      = r_o.hdr_class.uni_max_len;
314                         fstrcpy(class, unistr2_to_str(&r_o.uni_class));
315                         *num_subkeys    = r_o.num_subkeys   ;
316                         *max_subkeylen  = r_o.max_subkeylen ;
317                         *max_subkeysize = r_o.max_subkeysize;
318                         *num_values     = r_o.num_values    ;
319                         *max_valnamelen = r_o.max_valnamelen;
320                         *max_valbufsize = r_o.max_valbufsize;
321                         *sec_desc       = r_o.sec_desc      ;
322                         *mod_time       = r_o.mod_time      ;
323                 }
324         }
325
326         prs_mem_free(&rbuf);
327         prs_mem_free(&buf );
328
329         return valid_query;
330 }
331
332 /****************************************************************************
333 do a REG Unknown 1A
334 ****************************************************************************/
335 BOOL do_reg_unknown_1a(struct cli_state *cli, POLICY_HND *hnd, uint32 *unk)
336 {
337         prs_struct rbuf;
338         prs_struct buf; 
339         REG_Q_UNK_1A q_o;
340         BOOL valid_query = False;
341
342         if (hnd == NULL) return False;
343
344         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
345         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
346
347         /* create and send a MSRPC command with api REG_UNKNOWN_1A */
348
349         DEBUG(4,("REG Unknown 1a\n"));
350
351         make_reg_q_unk_1a(&q_o, hnd);
352
353         /* turn parameters into data stream */
354         reg_io_q_unk_1a("", &q_o, &buf, 0);
355
356         /* send the data on \PIPE\ */
357         if (rpc_api_pipe_req(cli, REG_UNK_1A, &buf, &rbuf))
358         {
359                 REG_R_UNK_1A r_o;
360                 BOOL p;
361
362                 ZERO_STRUCT(r_o);
363
364                 reg_io_r_unk_1a("", &r_o, &rbuf, 0);
365                 p = rbuf.offset != 0;
366
367                 if (p && r_o.status != 0)
368                 {
369                         /* report error code */
370                         DEBUG(0,("REG_UNK_1A: %s\n", get_nt_error_msg(r_o.status)));
371                         p = False;
372                 }
373
374                 if (p)
375                 {
376                         valid_query = True;
377                         (*unk) = r_o.unknown;
378                 }
379         }
380
381         prs_mem_free(&rbuf);
382         prs_mem_free(&buf );
383
384         return valid_query;
385 }
386
387 /****************************************************************************
388 do a REG Query Info
389 ****************************************************************************/
390 BOOL do_reg_query_info(struct cli_state *cli, POLICY_HND *hnd,
391                                 char *type, uint32 *unk_0, uint32 *unk_1)
392 {
393         prs_struct rbuf;
394         prs_struct buf; 
395         REG_Q_INFO q_o;
396         BOOL valid_query = False;
397
398         if (hnd == NULL) return False;
399
400         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
401         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
402
403         /* create and send a MSRPC command with api REG_INFO */
404
405         DEBUG(4,("REG Query Info\n"));
406
407         make_reg_q_info(&q_o, hnd, "ProductType", time(NULL), 4, 1);
408
409         /* turn parameters into data stream */
410         reg_io_q_info("", &q_o, &buf, 0);
411
412         /* send the data on \PIPE\ */
413         if (rpc_api_pipe_req(cli, REG_INFO, &buf, &rbuf))
414         {
415                 REG_R_INFO r_o;
416                 BOOL p;
417
418                 ZERO_STRUCT(r_o);
419
420                 reg_io_r_info("", &r_o, &rbuf, 0);
421                 p = rbuf.offset != 0;
422
423                 if (p && r_o.status != 0)
424                 {
425                         /* report error code */
426                         DEBUG(0,("REG_INFO: %s\n", get_nt_error_msg(r_o.status)));
427                         p = False;
428                 }
429
430                 if (p)
431                 {
432                         valid_query = True;
433                         fstrcpy(type, buffer2_to_str(&r_o.uni_type));
434                         (*unk_0) = r_o.unknown_0;
435                         (*unk_1) = r_o.unknown_1;
436                 }
437         }
438
439         prs_mem_free(&rbuf);
440         prs_mem_free(&buf );
441
442         return valid_query;
443 }
444
445 /****************************************************************************
446 do a REG Query Key Security 
447 ****************************************************************************/
448 BOOL do_reg_get_key_sec(struct cli_state *cli, POLICY_HND *hnd,
449                                 uint32 *sec_buf_size, SEC_DESC_BUF *sec_buf)
450 {
451         prs_struct rbuf;
452         prs_struct buf; 
453         REG_Q_GET_KEY_SEC q_o;
454         BOOL valid_query = False;
455
456         if (hnd == NULL) return False;
457
458         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
459         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
460
461         /* create and send a MSRPC command with api REG_GET_KEY_SEC */
462
463         DEBUG(4,("REG query key security.  buf_size: %d\n", *sec_buf_size));
464
465         make_reg_q_get_key_sec(&q_o, hnd, *sec_buf_size, sec_buf);
466
467         /* turn parameters into data stream */
468         reg_io_q_get_key_sec("", &q_o, &buf, 0);
469
470         /* send the data on \PIPE\ */
471         if (rpc_api_pipe_req(cli, REG_GET_KEY_SEC, &buf, &rbuf))
472         {
473                 REG_R_GET_KEY_SEC r_o;
474                 BOOL p;
475
476                 ZERO_STRUCT(r_o);
477
478                 r_o.data = sec_buf;
479                 reg_io_r_get_key_sec("", &r_o, &rbuf, 0);
480                 p = rbuf.offset != 0;
481
482                 if (p && r_o.status == 0x0000007a)
483                 {
484                         /*
485                          * get the maximum buffer size: it was too small
486                          */
487                         (*sec_buf_size) = r_o.hdr_sec.buf_max_len;
488                         DEBUG(5,("sec_buf_size too small.  use %d\n", *sec_buf_size));
489                         valid_query = True;
490                 }
491                 else if (p && r_o.status != 0)
492                 {
493                         /* report error code */
494                         DEBUG(0,("REG_GET_KEY_SEC: %s\n", get_nt_error_msg(r_o.status)));
495                         p = False;
496                 }
497                 else
498                 {
499                         valid_query = True;
500                         (*sec_buf_size) = r_o.data->len;
501                 }
502         }
503
504         prs_mem_free(&rbuf);
505         prs_mem_free(&buf );
506
507         return valid_query;
508 }
509
510 /****************************************************************************
511 do a REG Delete Value
512 ****************************************************************************/
513 BOOL do_reg_delete_val(struct cli_state *cli, POLICY_HND *hnd, char *val_name)
514 {
515         prs_struct rbuf;
516         prs_struct buf; 
517         REG_Q_DELETE_VALUE q_o;
518         BOOL valid_delete = 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_DELETE_VALUE */
526
527         DEBUG(4,("REG Delete Value: %s\n", val_name));
528
529         make_reg_q_delete_val(&q_o, hnd, val_name);
530
531         /* turn parameters into data stream */
532         reg_io_q_delete_val("", &q_o, &buf, 0);
533
534         /* send the data on \PIPE\ */
535         if (rpc_api_pipe_req(cli, REG_DELETE_VALUE, &buf, &rbuf))
536         {
537                 REG_R_DELETE_VALUE r_o;
538                 BOOL p;
539
540                 ZERO_STRUCT(r_o);
541
542                 reg_io_r_delete_val("", &r_o, &rbuf, 0);
543                 p = rbuf.offset != 0;
544
545                 if (p && r_o.status != 0)
546                 {
547                         /* report error code */
548                         DEBUG(0,("REG_DELETE_VALUE: %s\n", get_nt_error_msg(r_o.status)));
549                         p = False;
550                 }
551
552                 if (p)
553                 {
554                         valid_delete = True;
555                 }
556         }
557
558         prs_mem_free(&rbuf);
559         prs_mem_free(&buf );
560
561         return valid_delete;
562 }
563
564 /****************************************************************************
565 do a REG Delete Key
566 ****************************************************************************/
567 BOOL do_reg_delete_key(struct cli_state *cli, POLICY_HND *hnd, char *key_name)
568 {
569         prs_struct rbuf;
570         prs_struct buf; 
571         REG_Q_DELETE_KEY q_o;
572         BOOL valid_delete = False;
573
574         if (hnd == NULL) return False;
575
576         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
577         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
578
579         /* create and send a MSRPC command with api REG_DELETE_KEY */
580
581         DEBUG(4,("REG Delete Key: %s\n", key_name));
582
583         make_reg_q_delete_key(&q_o, hnd, key_name);
584
585         /* turn parameters into data stream */
586         reg_io_q_delete_key("", &q_o, &buf, 0);
587
588         /* send the data on \PIPE\ */
589         if (rpc_api_pipe_req(cli, REG_DELETE_KEY, &buf, &rbuf))
590         {
591                 REG_R_DELETE_KEY r_o;
592                 BOOL p;
593
594                 ZERO_STRUCT(r_o);
595
596                 reg_io_r_delete_key("", &r_o, &rbuf, 0);
597                 p = rbuf.offset != 0;
598
599                 if (p && r_o.status != 0)
600                 {
601                         /* report error code */
602                         DEBUG(0,("REG_DELETE_KEY: %s\n", get_nt_error_msg(r_o.status)));
603                         p = False;
604                 }
605
606                 if (p)
607                 {
608                         valid_delete = True;
609                 }
610         }
611
612         prs_mem_free(&rbuf);
613         prs_mem_free(&buf );
614
615         return valid_delete;
616 }
617
618 /****************************************************************************
619 do a REG Create Key
620 ****************************************************************************/
621 BOOL do_reg_create_key(struct cli_state *cli, POLICY_HND *hnd,
622                                 char *key_name, char *key_class,
623                                 SEC_INFO *sam_access,
624                                 POLICY_HND *key)
625 {
626         prs_struct rbuf;
627         prs_struct buf; 
628         REG_Q_CREATE_KEY q_o;
629         BOOL valid_create = False;
630
631         if (hnd == NULL) return False;
632
633         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
634         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
635
636         /* create and send a MSRPC command with api REG_CREATE_KEY */
637
638         DEBUG(4,("REG Create Key: %s %s 0x%08x\n", key_name, key_class,
639                 sam_access != NULL ? sam_access->perms : 0));
640
641         make_reg_q_create_key(&q_o, hnd, key_name, key_class, sam_access);
642
643         /* turn parameters into data stream */
644         reg_io_q_create_key("", &q_o, &buf, 0);
645
646         /* send the data on \PIPE\ */
647         if (rpc_api_pipe_req(cli, REG_CREATE_KEY, &buf, &rbuf))
648         {
649                 REG_R_CREATE_KEY r_o;
650                 BOOL p;
651
652                 ZERO_STRUCT(r_o);
653
654                 reg_io_r_create_key("", &r_o, &rbuf, 0);
655                 p = rbuf.offset != 0;
656
657                 if (p && r_o.status != 0)
658                 {
659                         /* report error code */
660                         DEBUG(0,("REG_CREATE_KEY: %s\n", get_nt_error_msg(r_o.status)));
661                         p = False;
662                 }
663
664                 if (p)
665                 {
666                         valid_create = True;
667                         memcpy(key, r_o.key_pol.data, sizeof(key->data));
668                 }
669         }
670
671         prs_mem_free(&rbuf);
672         prs_mem_free(&buf );
673
674         return valid_create;
675 }
676
677 /****************************************************************************
678 do a REG Enum Key
679 ****************************************************************************/
680 BOOL do_reg_enum_key(struct cli_state *cli, POLICY_HND *hnd,
681                                 int key_index, char *key_name,
682                                 uint32 *unk_1, uint32 *unk_2,
683                                 time_t *mod_time)
684 {
685         prs_struct rbuf;
686         prs_struct buf; 
687         REG_Q_ENUM_KEY q_o;
688         BOOL valid_query = 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_ENUM_KEY */
696
697         DEBUG(4,("REG Enum Key\n"));
698
699         make_reg_q_enum_key(&q_o, hnd, key_index);
700
701         /* turn parameters into data stream */
702         reg_io_q_enum_key("", &q_o, &buf, 0);
703
704         /* send the data on \PIPE\ */
705         if (rpc_api_pipe_req(cli, REG_ENUM_KEY, &buf, &rbuf))
706         {
707                 REG_R_ENUM_KEY r_o;
708                 BOOL p;
709
710                 ZERO_STRUCT(r_o);
711
712                 reg_io_r_enum_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_ENUM_KEY: %s\n", get_nt_error_msg(r_o.status)));
719                         p = False;
720                 }
721
722                 if (p)
723                 {
724                         valid_query = True;
725                         (*unk_1) = r_o.unknown_1;
726                         (*unk_2) = r_o.unknown_2;
727                         fstrcpy(key_name, unistr2(r_o.key_name.str.buffer));
728                         (*mod_time) = nt_time_to_unix(&r_o.time);
729                 }
730         }
731
732         prs_mem_free(&rbuf);
733         prs_mem_free(&buf );
734
735         return valid_query;
736 }
737
738 /****************************************************************************
739 do a REG Create Value
740 ****************************************************************************/
741 BOOL do_reg_create_val(struct cli_state *cli, POLICY_HND *hnd,
742                                 char *val_name, uint32 type, BUFFER3 *data)
743 {
744         prs_struct rbuf;
745         prs_struct buf; 
746         REG_Q_CREATE_VALUE q_o;
747         BOOL valid_create = False;
748
749         if (hnd == NULL) return False;
750
751         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
752         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
753
754         /* create and send a MSRPC command with api REG_CREATE_VALUE */
755
756         DEBUG(4,("REG Create Value: %s\n", val_name));
757
758         make_reg_q_create_val(&q_o, hnd, val_name, type, data);
759
760         /* turn parameters into data stream */
761         reg_io_q_create_val("", &q_o, &buf, 0);
762
763         /* send the data on \PIPE\ */
764         if (rpc_api_pipe_req(cli, REG_CREATE_VALUE, &buf, &rbuf))
765         {
766                 REG_R_CREATE_VALUE r_o;
767                 BOOL p;
768
769                 ZERO_STRUCT(r_o);
770
771                 reg_io_r_create_val("", &r_o, &rbuf, 0);
772                 p = rbuf.offset != 0;
773
774                 if (p && r_o.status != 0)
775                 {
776                         /* report error code */
777                         DEBUG(0,("REG_CREATE_VALUE: %s\n", get_nt_error_msg(r_o.status)));
778                         p = False;
779                 }
780
781                 if (p)
782                 {
783                         valid_create = True;
784                 }
785         }
786
787         prs_mem_free(&rbuf);
788         prs_mem_free(&buf );
789
790         return valid_create;
791 }
792
793 /****************************************************************************
794 do a REG Enum Value
795 ****************************************************************************/
796 BOOL do_reg_enum_val(struct cli_state *cli, POLICY_HND *hnd,
797                                 int val_index, int max_valnamelen, int max_valbufsize,
798                                 fstring val_name,
799                                 uint32 *val_type, BUFFER2 *value)
800 {
801         prs_struct rbuf;
802         prs_struct buf; 
803         REG_Q_ENUM_VALUE q_o;
804         BOOL valid_query = False;
805
806         if (hnd == NULL) return False;
807
808         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
809         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
810
811         /* create and send a MSRPC command with api REG_ENUM_VALUE */
812
813         DEBUG(4,("REG Enum Value\n"));
814
815         make_reg_q_enum_val(&q_o, hnd, val_index, max_valnamelen, max_valbufsize);
816
817         /* turn parameters into data stream */
818         reg_io_q_enum_val("", &q_o, &buf, 0);
819
820         /* send the data on \PIPE\ */
821         if (rpc_api_pipe_req(cli, REG_ENUM_VALUE, &buf, &rbuf))
822         {
823                 REG_R_ENUM_VALUE r_o;
824                 BOOL p;
825
826                 ZERO_STRUCT(r_o);
827                 r_o.buf_value = value;
828
829                 reg_io_r_enum_val("", &r_o, &rbuf, 0);
830                 p = rbuf.offset != 0;
831
832                 if (p && r_o.status != 0)
833                 {
834                         /* report error code */
835                         DEBUG(0,("REG_ENUM_VALUE: %s\n", get_nt_error_msg(r_o.status)));
836                         p = False;
837                 }
838
839                 if (p)
840                 {
841                         valid_query = True;
842                         (*val_type) = r_o.type;
843                         fstrcpy(val_name, unistr2_to_str(&r_o.uni_name));
844                 }
845         }
846
847         prs_mem_free(&rbuf);
848         prs_mem_free(&buf );
849
850         return valid_query;
851 }
852
853 /****************************************************************************
854 do a REG Open Key
855 ****************************************************************************/
856 BOOL do_reg_open_entry(struct cli_state *cli, POLICY_HND *hnd,
857                                 char *key_name, uint32 unk_0,
858                                 POLICY_HND *key_hnd)
859 {
860         prs_struct rbuf;
861         prs_struct buf; 
862         REG_Q_OPEN_ENTRY q_o;
863         BOOL valid_pol = False;
864
865         if (hnd == NULL) return False;
866
867         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
868         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
869
870         /* create and send a MSRPC command with api REG_OPEN_ENTRY */
871
872         DEBUG(4,("REG Open Entry\n"));
873
874         make_reg_q_open_entry(&q_o, hnd, key_name, unk_0);
875
876         /* turn parameters into data stream */
877         reg_io_q_open_entry("", &q_o, &buf, 0);
878
879         /* send the data on \PIPE\ */
880         if (rpc_api_pipe_req(cli, REG_OPEN_ENTRY, &buf, &rbuf))
881         {
882                 REG_R_OPEN_ENTRY r_o;
883                 BOOL p;
884
885                 ZERO_STRUCT(r_o);
886
887                 reg_io_r_open_entry("", &r_o, &rbuf, 0);
888                 p = rbuf.offset != 0;
889
890                 if (p && r_o.status != 0)
891                 {
892                         /* report error code */
893                         DEBUG(0,("REG_OPEN_ENTRY: %s\n", get_nt_error_msg(r_o.status)));
894                         p = False;
895                 }
896
897                 if (p)
898                 {
899                         valid_pol = True;
900                         memcpy(key_hnd, r_o.pol.data, sizeof(key_hnd->data));
901                 }
902         }
903
904         prs_mem_free(&rbuf);
905         prs_mem_free(&buf );
906
907         return valid_pol;
908 }
909
910 /****************************************************************************
911 do a REG Close
912 ****************************************************************************/
913 BOOL do_reg_close(struct cli_state *cli, POLICY_HND *hnd)
914 {
915         prs_struct rbuf;
916         prs_struct buf; 
917         REG_Q_CLOSE q_c;
918         BOOL valid_close = False;
919
920         if (hnd == NULL) return False;
921
922         /* create and send a MSRPC command with api REG_CLOSE */
923
924         prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
925         prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
926
927         DEBUG(4,("REG Close\n"));
928
929         /* store the parameters */
930         make_reg_q_close(&q_c, hnd);
931
932         /* turn parameters into data stream */
933         reg_io_q_close("", &q_c, &buf, 0);
934
935         /* send the data on \PIPE\ */
936         if (rpc_api_pipe_req(cli, REG_CLOSE, &buf, &rbuf))
937         {
938                 REG_R_CLOSE r_c;
939                 BOOL p;
940
941                 ZERO_STRUCT(r_c);
942
943                 reg_io_r_close("", &r_c, &rbuf, 0);
944                 p = rbuf.offset != 0;
945
946                 if (p && r_c.status != 0)
947                 {
948                         /* report error code */
949                         DEBUG(0,("REG_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
950                         p = False;
951                 }
952
953                 if (p)
954                 {
955                         /* check that the returned policy handle is all zeros */
956                         int i;
957                         valid_close = True;
958
959                         for (i = 0; i < sizeof(r_c.pol.data); i++)
960                         {
961                                 if (r_c.pol.data[i] != 0)
962                                 {
963                                         valid_close = False;
964                                         break;
965                                 }
966                         }       
967                         if (!valid_close)
968                         {
969                                 DEBUG(0,("REG_CLOSE: non-zero handle returned\n"));
970                         }
971                 }
972         }
973
974         prs_mem_free(&rbuf);
975         prs_mem_free(&buf );
976
977         return valid_close;
978 }
979
980