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