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