ca4b63c282242b8c16e967b1ef5609a433fc257d
[samba.git] / source3 / rpc_client / cli_reg.c
1 /* 
2    Unix SMB/CIFS implementation.
3    RPC Pipe client
4  
5    Copyright (C) Andrew Tridgell              1992-2000,
6    Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
7    Copyright (C) Paul Ashton                  1997-2000.
8    Copyright (C) Jeremy Allison                    1999.
9    Copyright (C) Simo Sorce                        2001
10    Copyright (C) Jeremy Cooper                     2004
11    Copyright (C) Gerald (Jerry) Carter             2005
12    
13    This program is free software; you can redistribute it and/or modify
14    it under the terms of the GNU General Public License as published by
15    the Free Software Foundation; either version 2 of the License, or
16    (at your option) any later version.
17    
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21    GNU General Public License for more details.
22    
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28 #include "includes.h"
29 #include "rpc_client.h"
30
31 /* Shutdown a server */
32
33 /*******************************************************************
34  internal connect to a registry hive root (open a registry policy)
35 *******************************************************************/
36
37 static WERROR cli_reg_open_hive_int(struct cli_state *cli,
38                                       TALLOC_CTX *mem_ctx, uint16 op_code,
39                                       const char *op_name,
40                                       uint32 access_mask, POLICY_HND *hnd)
41 {
42         REG_Q_OPEN_HIVE in;
43         REG_R_OPEN_HIVE out;
44         prs_struct qbuf, rbuf;
45
46         ZERO_STRUCT(in);
47         ZERO_STRUCT(out);
48
49         init_reg_q_open_hive(&in, access_mask);
50
51         CLI_DO_RPC( cli, mem_ctx, PI_WINREG, op_code, 
52                     in, out, 
53                     qbuf, rbuf,
54                     reg_io_q_open_hive,
55                     reg_io_r_open_hive, 
56                     WERR_GENERAL_FAILURE );
57
58         if ( !W_ERROR_IS_OK( out.status ) )
59                 return out.status;
60
61         memcpy( hnd, &out.pol, sizeof(POLICY_HND) );
62
63         return out.status;
64 }
65
66 /*******************************************************************
67  connect to a registry hive root (open a registry policy)
68 *******************************************************************/
69
70 WERROR cli_reg_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
71                          uint32 reg_type, uint32 access_mask,
72                          POLICY_HND *reg_hnd)
73 {       uint16 op_code;
74         const char *op_name;
75
76         ZERO_STRUCTP(reg_hnd);
77
78         switch (reg_type)
79         {
80         case HKEY_CLASSES_ROOT:
81                 op_code = REG_OPEN_HKCR;
82                 op_name = "REG_OPEN_HKCR";
83                 break;
84         case HKEY_LOCAL_MACHINE:
85                 op_code = REG_OPEN_HKLM;
86                 op_name = "REG_OPEN_HKLM";
87                 break;
88         case HKEY_USERS:
89                 op_code = REG_OPEN_HKU;
90                 op_name = "REG_OPEN_HKU";
91                 break;
92         case HKEY_PERFORMANCE_DATA:
93                 op_code = REG_OPEN_HKPD;
94                 op_name = "REG_OPEN_HKPD";
95                 break;
96         default:
97                 return WERR_INVALID_PARAM;
98         }
99
100         return cli_reg_open_hive_int(cli, mem_ctx, op_code, op_name,
101                                      access_mask, reg_hnd);
102 }
103
104
105 /*******************************************************************
106 *******************************************************************/
107
108 WERROR cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx,
109                           const char *msg, uint32 timeout, BOOL do_reboot,
110                           BOOL force)
111 {
112         REG_Q_SHUTDOWN in;
113         REG_R_SHUTDOWN out;
114         prs_struct qbuf, rbuf;
115
116         if (msg == NULL) 
117                 return WERR_INVALID_PARAM;
118
119         ZERO_STRUCT (in);
120         ZERO_STRUCT (out);
121
122         /* Marshall data and send request */
123
124         init_reg_q_shutdown(&in, msg, timeout, do_reboot, force);
125
126         CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_SHUTDOWN, 
127                     in, out, 
128                     qbuf, rbuf,
129                     reg_io_q_shutdown,
130                     reg_io_r_shutdown, 
131                     WERR_GENERAL_FAILURE );
132
133         return out.status;
134 }
135
136 /*******************************************************************
137 *******************************************************************/
138
139 WERROR cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx)
140 {
141         REG_Q_ABORT_SHUTDOWN in;
142         REG_R_ABORT_SHUTDOWN out;
143         prs_struct qbuf, rbuf;
144
145         ZERO_STRUCT (in);
146         ZERO_STRUCT (out);
147
148         CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_ABORT_SHUTDOWN, 
149                     in, out, 
150                     qbuf, rbuf,
151                     reg_io_q_abort_shutdown,
152                     reg_io_r_abort_shutdown, 
153                     WERR_GENERAL_FAILURE );
154
155         return out.status;      
156 }
157
158
159 /****************************************************************************
160 do a REG Unknown 0xB command.  sent after a create key or create value.
161 this might be some sort of "sync" or "refresh" command, sent after
162 modification of the registry...
163 ****************************************************************************/
164 WERROR cli_reg_flush_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
165                            POLICY_HND *hnd)
166 {
167         REG_Q_FLUSH_KEY in;
168         REG_R_FLUSH_KEY out;
169         prs_struct qbuf, rbuf;
170
171         ZERO_STRUCT (in);
172         ZERO_STRUCT (out);
173         
174         init_reg_q_flush_key(&in, hnd);
175
176         CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_FLUSH_KEY, 
177                     in, out, 
178                     qbuf, rbuf,
179                     reg_io_q_flush_key,
180                     reg_io_r_flush_key, 
181                     WERR_GENERAL_FAILURE );
182                     
183         return out.status;
184 }
185
186 /****************************************************************************
187 do a REG Query Key
188 ****************************************************************************/
189 WERROR cli_reg_query_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
190                            POLICY_HND *hnd,
191                            char *key_class, uint32 *class_len,
192                            uint32 *num_subkeys, uint32 *max_subkeylen,
193                            uint32 *max_classlen, uint32 *num_values,
194                            uint32 *max_valnamelen, uint32 *max_valbufsize,
195                            uint32 *sec_desc, NTTIME *mod_time)
196 {
197         REG_Q_QUERY_KEY in;
198         REG_R_QUERY_KEY out;
199         prs_struct qbuf, rbuf;
200         uint32 saved_class_len = *class_len;
201
202         ZERO_STRUCT (in);
203         ZERO_STRUCT (out);
204
205         init_reg_q_query_key( &in, hnd, key_class );
206
207         CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_QUERY_KEY, 
208                     in, out, 
209                     qbuf, rbuf,
210                     reg_io_q_query_key,
211                     reg_io_r_query_key, 
212                     WERR_GENERAL_FAILURE );
213
214         if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
215                 ZERO_STRUCT (in);
216
217                 *class_len = out.class.string->uni_max_len;
218                 if ( *class_len > saved_class_len )
219                         return out.status;
220                         
221                 /* set a string of spaces and NULL terminate */
222
223                 memset( key_class, (int)' ', *class_len );
224                 key_class[*class_len] = '\0';
225                 
226                 init_reg_q_query_key( &in, hnd, key_class );
227
228                 ZERO_STRUCT (out);
229
230                 CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_QUERY_KEY, 
231                             in, out, 
232                             qbuf, rbuf,
233                             reg_io_q_query_key,
234                             reg_io_r_query_key, 
235                             WERR_GENERAL_FAILURE );
236         }
237         
238         if ( !W_ERROR_IS_OK( out.status ) )
239                 return out.status;
240
241         *class_len      = out.class.string->uni_max_len;
242         unistr2_to_ascii(key_class, out.class.string, saved_class_len-1);
243         *num_subkeys    = out.num_subkeys   ;
244         *max_subkeylen  = out.max_subkeylen ;
245         *num_values     = out.num_values    ;
246         *max_valnamelen = out.max_valnamelen;
247         *max_valbufsize = out.max_valbufsize;
248         *sec_desc       = out.sec_desc      ;
249         *mod_time       = out.mod_time      ;
250         /* Maybe: *max_classlen = out.reserved; */
251
252         return out.status;
253 }
254
255 /****************************************************************************
256 ****************************************************************************/
257
258 WERROR cli_reg_getversion(struct cli_state *cli, TALLOC_CTX *mem_ctx,
259                             POLICY_HND *hnd, uint32 *version)
260 {
261         REG_Q_GETVERSION in;
262         REG_R_GETVERSION out;
263         prs_struct qbuf, rbuf;
264
265         ZERO_STRUCT (in);
266         ZERO_STRUCT (out);
267         
268         init_reg_q_getversion(&in, hnd);
269
270         CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_GETVERSION, 
271                     in, out, 
272                     qbuf, rbuf,
273                     reg_io_q_getversion,
274                     reg_io_r_getversion, 
275                     WERR_GENERAL_FAILURE );
276                     
277
278         if ( !W_ERROR_IS_OK( out.status ) )
279                 return out.status;
280                 
281         *version = out.win_version;
282
283         return out.status;
284 }
285
286 /****************************************************************************
287 do a REG Query Info
288 ****************************************************************************/
289 WERROR cli_reg_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
290                            POLICY_HND *hnd, const char *val_name,
291                            uint32 *type, REGVAL_BUFFER *buffer)
292 {
293         REG_Q_INFO in;
294         REG_R_INFO out;
295         prs_struct qbuf, rbuf;
296
297         ZERO_STRUCT (in);
298         ZERO_STRUCT (out);
299         
300         init_reg_q_info(&in, hnd, val_name, buffer);
301
302         CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_QUERY_KEY, 
303                     in, out, 
304                     qbuf, rbuf,
305                     reg_io_q_info,
306                     reg_io_r_info, 
307                     WERR_GENERAL_FAILURE );
308                     
309
310         if ( !W_ERROR_IS_OK( out.status ) )
311                 return out.status;
312                 
313         *type   = *out.type;
314         *buffer = *out.value;
315
316         return out.status;
317 }
318
319 /****************************************************************************
320 do a REG Set Key Security 
321 ****************************************************************************/
322 WERROR cli_reg_set_key_sec(struct cli_state *cli, TALLOC_CTX *mem_ctx,
323                              POLICY_HND *hnd, uint32 sec_info,
324                              size_t secdesc_size, SEC_DESC *sec_desc)
325 {
326         REG_Q_SET_KEY_SEC in;
327         REG_R_SET_KEY_SEC out;
328         prs_struct qbuf, rbuf;
329         SEC_DESC_BUF *sec_desc_buf;
330
331         ZERO_STRUCT (in);
332         ZERO_STRUCT (out);
333         
334         /* Flatten the security descriptor */
335         
336         if ( !(sec_desc_buf = make_sec_desc_buf(mem_ctx, secdesc_size, sec_desc)) )
337                 return WERR_GENERAL_FAILURE;
338                 
339         init_reg_q_set_key_sec(&in, hnd, sec_info, sec_desc_buf);
340
341         CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_SET_KEY_SEC, 
342                     in, out, 
343                     qbuf, rbuf,
344                     reg_io_q_set_key_sec,
345                     reg_io_r_set_key_sec, 
346                     WERR_GENERAL_FAILURE );
347                     
348
349         return out.status;
350 }
351
352
353 /****************************************************************************
354 do a REG Query Key Security 
355 ****************************************************************************/
356 WERROR cli_reg_get_key_sec(struct cli_state *cli, TALLOC_CTX *mem_ctx,
357                              POLICY_HND *hnd, uint32 sec_info,
358                              uint32 *sec_buf_size, SEC_DESC_BUF *sec_buf)
359 {
360         REG_Q_GET_KEY_SEC in;
361         REG_R_GET_KEY_SEC out;
362         prs_struct qbuf, rbuf;
363
364         ZERO_STRUCT (in);
365         ZERO_STRUCT (out);
366         
367         init_reg_q_get_key_sec(&in, hnd, sec_info, *sec_buf_size, sec_buf);
368
369         CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_GET_KEY_SEC, 
370                     in, out, 
371                     qbuf, rbuf,
372                     reg_io_q_get_key_sec,
373                     reg_io_r_get_key_sec, 
374                     WERR_GENERAL_FAILURE );
375                     
376
377         /* this might be able to return WERR_MORE_DATA, I'm not sure */
378         
379         if ( !W_ERROR_IS_OK( out.status ) )
380                 return out.status;
381         
382         sec_buf       = out.data;
383         *sec_buf_size = out.data->len;
384                 
385         return out.status;      
386 }
387
388 /****************************************************************************
389 do a REG Delete Value
390 ****************************************************************************/
391 WERROR cli_reg_delete_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
392                             POLICY_HND *hnd, char *val_name)
393 {
394         REG_Q_DELETE_VALUE in;
395         REG_R_DELETE_VALUE out;
396         prs_struct qbuf, rbuf;
397
398         ZERO_STRUCT (in);
399         ZERO_STRUCT (out);
400         
401         init_reg_q_delete_val(&in, hnd, val_name);
402
403         CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_DELETE_VALUE, 
404                     in, out, 
405                     qbuf, rbuf,
406                     reg_io_q_delete_value,
407                     reg_io_r_delete_value, 
408                     WERR_GENERAL_FAILURE );
409         
410         return out.status;
411 }
412
413 /****************************************************************************
414 do a REG Delete Key
415 ****************************************************************************/
416 WERROR cli_reg_delete_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
417                             POLICY_HND *hnd, char *key_name)
418 {
419         REG_Q_DELETE_KEY in;
420         REG_R_DELETE_KEY out;
421         prs_struct qbuf, rbuf;
422
423         ZERO_STRUCT (in);
424         ZERO_STRUCT (out);
425         
426         init_reg_q_delete_key(&in, hnd, key_name);
427
428         CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_DELETE_KEY, 
429                     in, out, 
430                     qbuf, rbuf,
431                     reg_io_q_delete_key,
432                     reg_io_r_delete_key, 
433                     WERR_GENERAL_FAILURE );
434         
435         return out.status;
436 }
437
438 /****************************************************************************
439 do a REG Create Key
440 ****************************************************************************/
441 WERROR cli_reg_create_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
442                             POLICY_HND *hnd, char *key_name, char *key_class,
443                             uint32 access_desired, POLICY_HND *key)
444 {
445         REG_Q_CREATE_KEY in;
446         REG_R_CREATE_KEY out;
447         prs_struct qbuf, rbuf;
448         SEC_DESC *sec;
449         SEC_DESC_BUF *sec_buf;
450         size_t sec_len;
451
452         ZERO_STRUCT (in);
453         ZERO_STRUCT (out);
454         
455         if ( !(sec = make_sec_desc(mem_ctx, 1, SEC_DESC_SELF_RELATIVE,
456                 NULL, NULL, NULL, NULL, &sec_len)) )
457         {
458                 return WERR_GENERAL_FAILURE;
459         }
460                                  
461         if ( !(sec_buf = make_sec_desc_buf(mem_ctx, sec_len, sec)) )
462                 return WERR_GENERAL_FAILURE;
463
464         init_reg_q_create_key(&in, hnd, key_name, key_class, access_desired, sec_buf);
465
466         CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_CREATE_KEY, 
467                     in, out, 
468                     qbuf, rbuf,
469                     reg_io_q_create_key,
470                     reg_io_r_create_key, 
471                     WERR_GENERAL_FAILURE );
472                     
473
474         if ( !W_ERROR_IS_OK( out.status ) )
475                 return out.status;
476         
477         memcpy( key, &out.handle, sizeof(POLICY_HND) );
478         
479         return out.status;
480 }
481
482 /****************************************************************************
483 do a REG Enum Key
484 ****************************************************************************/
485 WERROR cli_reg_enum_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
486                           POLICY_HND *hnd, int key_index, fstring key_name,
487                           fstring class_name, time_t *mod_time)
488 {
489         REG_Q_ENUM_KEY in;
490         REG_R_ENUM_KEY out;
491         prs_struct qbuf, rbuf;
492
493         ZERO_STRUCT (in);
494         ZERO_STRUCT (out);
495         
496         init_reg_q_enum_key(&in, hnd, key_index);
497
498         CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_ENUM_KEY, 
499                     in, out, 
500                     qbuf, rbuf,
501                     reg_io_q_enum_key,
502                     reg_io_r_enum_key, 
503                     WERR_GENERAL_FAILURE );
504
505         if ( !W_ERROR_IS_OK(out.status) )
506                 return out.status;
507
508         if ( out.keyname.string )
509                 rpcstr_pull( key_name, out.keyname.string->buffer, sizeof(fstring), -1, STR_TERMINATE );
510         else
511                 fstrcpy( key_name, "(Default)" );
512
513         if ( out.classname && out.classname->string )
514                 rpcstr_pull( class_name, out.classname->string->buffer, sizeof(fstring), -1, STR_TERMINATE );
515         else
516                 fstrcpy( class_name, "" );
517
518         *mod_time   = nt_time_to_unix(out.time);
519
520         return out.status;
521 }
522
523 /****************************************************************************
524 do a REG Create Value
525 ****************************************************************************/
526 WERROR cli_reg_set_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
527                             POLICY_HND *hnd, char *val_name, uint32 type,
528                             RPC_DATA_BLOB *data)
529 {
530         REG_Q_SET_VALUE in;
531         REG_R_SET_VALUE out;
532         prs_struct qbuf, rbuf;
533
534         ZERO_STRUCT (in);
535         ZERO_STRUCT (out);
536         
537         init_reg_q_set_val(&in, hnd, val_name, type, data);
538
539         CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_SET_VALUE, 
540                     in, out, 
541                     qbuf, rbuf,
542                     reg_io_q_set_value,
543                     reg_io_r_set_value, 
544                     WERR_GENERAL_FAILURE );
545
546         return out.status;
547 }
548
549 /****************************************************************************
550 do a REG Enum Value
551 ****************************************************************************/
552 WERROR cli_reg_enum_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
553                           POLICY_HND *hnd, int idx,
554                           fstring val_name, uint32 *type, REGVAL_BUFFER *value)
555 {
556         REG_Q_ENUM_VALUE in;
557         REG_R_ENUM_VALUE out;
558         prs_struct qbuf, rbuf;
559
560         ZERO_STRUCT (in);
561         ZERO_STRUCT (out);
562         
563         init_reg_q_enum_val(&in, hnd, idx, 0x0100, 0x1000);
564
565         CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_ENUM_VALUE, 
566                     in, out, 
567                     qbuf, rbuf,
568                     reg_io_q_enum_val,
569                     reg_io_r_enum_val, 
570                     WERR_GENERAL_FAILURE );
571
572         if ( W_ERROR_EQUAL(out.status, WERR_MORE_DATA) ) {
573
574                 ZERO_STRUCT (in);
575
576                 init_reg_q_enum_val(&in, hnd, idx, 0x0100, *out.buffer_len1);
577
578                 ZERO_STRUCT (out);
579
580                 CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_ENUM_VALUE, 
581                             in, out, 
582                             qbuf, rbuf,
583                             reg_io_q_enum_val,
584                             reg_io_r_enum_val, 
585                             WERR_GENERAL_FAILURE );
586         }
587
588         if ( !W_ERROR_IS_OK(out.status) )
589                 return out.status;
590
591         unistr2_to_ascii(val_name, out.name.string, sizeof(fstring)-1);
592         *type      = *out.type;
593         *value     = *out.value;
594         
595         return out.status;
596 }
597
598 /****************************************************************************
599 ****************************************************************************/
600
601 WERROR cli_reg_open_entry(struct cli_state *cli, TALLOC_CTX *mem_ctx,
602                             POLICY_HND *hnd, char *key_name,
603                             uint32 access_desired, POLICY_HND *key_hnd)
604 {
605         REG_Q_OPEN_ENTRY in;
606         REG_R_OPEN_ENTRY out;
607         prs_struct qbuf, rbuf;
608
609         ZERO_STRUCT (in);
610         ZERO_STRUCT (out);
611         
612         init_reg_q_open_entry(&in, hnd, key_name, access_desired);
613
614         CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_OPEN_ENTRY, 
615                     in, out, 
616                     qbuf, rbuf,
617                     reg_io_q_open_entry,
618                     reg_io_r_open_entry, 
619                     WERR_GENERAL_FAILURE );
620
621         if ( !W_ERROR_IS_OK( out.status ) )
622                 return out.status;
623
624         memcpy( key_hnd, &out.handle, sizeof(POLICY_HND) );
625         
626         return out.status;
627 }
628
629 /****************************************************************************
630 ****************************************************************************/
631
632 WERROR cli_reg_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
633                        POLICY_HND *hnd)
634 {
635         REG_Q_CLOSE in;
636         REG_R_CLOSE out;
637         prs_struct qbuf, rbuf;
638
639         ZERO_STRUCT (in);
640         ZERO_STRUCT (out);
641         
642         init_reg_q_close(&in, hnd);
643
644         CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_CLOSE, 
645                     in, out, 
646                     qbuf, rbuf,
647                     reg_io_q_close,
648                     reg_io_r_close, 
649                     WERR_GENERAL_FAILURE );
650         
651         return out.status;
652 }
653
654 /****************************************************************************
655 do a REG Query Info
656 ****************************************************************************/
657 WERROR cli_reg_save_key( struct cli_state *cli, TALLOC_CTX *mem_ctx,
658                          POLICY_HND *hnd, const char *filename )
659 {
660         REG_Q_SAVE_KEY in;
661         REG_R_SAVE_KEY out;
662         prs_struct qbuf, rbuf;
663
664         ZERO_STRUCT (in);
665         ZERO_STRUCT (out);
666         
667         init_q_reg_save_key( &in, hnd, filename );
668
669         CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_SAVE_KEY, 
670                     in, out, 
671                     qbuf, rbuf,
672                     reg_io_q_save_key,
673                     reg_io_r_save_key,
674                     WERR_GENERAL_FAILURE );
675
676         return out.status;
677 }
678
679
680 /* 
681  #################################################################
682   Utility functions
683  #################################################################
684  */
685
686 /*****************************************************************
687  Splits out the start of the key (HKLM or HKU) and the rest of the key.
688 *****************************************************************/  
689
690 BOOL reg_split_hive(const char *full_keyname, uint32 *reg_type, pstring key_name)
691 {
692         pstring tmp;
693
694         if (!next_token(&full_keyname, tmp, "\\", sizeof(tmp)))
695                 return False;
696
697         (*reg_type) = 0;
698
699         DEBUG(10, ("reg_split_key: hive %s\n", tmp));
700
701         if (strequal(tmp, "HKLM") || strequal(tmp, "HKEY_LOCAL_MACHINE"))
702                 (*reg_type) = HKEY_LOCAL_MACHINE;
703         else if (strequal(tmp, "HKCR") || strequal(tmp, "HKEY_CLASSES_ROOT"))
704                 (*reg_type) = HKEY_CLASSES_ROOT;
705         else if (strequal(tmp, "HKU") || strequal(tmp, "HKEY_USERS"))
706                 (*reg_type) = HKEY_USERS;
707         else if (strequal(tmp, "HKPD")||strequal(tmp, "HKEY_PERFORMANCE_DATA"))
708                 (*reg_type) = HKEY_PERFORMANCE_DATA;
709         else {
710                 DEBUG(10,("reg_split_key: unrecognised hive key %s\n", tmp));
711                 return False;
712         }
713         
714         if (next_token(&full_keyname, tmp, "\n\r", sizeof(tmp)))
715                 pstrcpy(key_name, tmp);
716         else
717                 key_name[0] = 0;
718
719         DEBUG(10, ("reg_split_key: name %s\n", key_name));
720
721         return True;
722 }
723
724