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