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