70410a674095b607a237cb5366bc5d09fabe98d7
[metze/old/v3-2-winbind-ndr.git] / source / registry / reg_objects.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  Virtual Windows Registry Layer
4  *  Copyright (C) Gerald Carter                     2002-2005
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *  
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *  
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20
21 /* Implementation of registry frontend view functions. */
22
23 #include "includes.h"
24
25 #undef DBGC_CLASS
26 #define DBGC_CLASS DBGC_RPC_SRV
27
28 /**********************************************************************
29
30  Note that the REGSUB_CTR and REGVAL_CTR objects *must* be talloc()'d
31  since the methods use the object pointer as the talloc context for 
32  internal private data.
33
34  There is no longer a regXXX_ctr_intit() and regXXX_ctr_destroy()
35  pair of functions.  Simply TALLOC_ZERO_P() and TALLOC_FREE() the 
36  object.
37
38  **********************************************************************/
39
40 /***********************************************************************
41  Add a new key to the array
42  **********************************************************************/
43
44 int regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname )
45 {
46         char **pp;
47
48         if ( !keyname )
49                 return ctr->num_subkeys;
50
51         /* make sure the keyname is not already there */
52
53         if ( regsubkey_ctr_key_exists( ctr, keyname ) )
54                 return ctr->num_subkeys;
55                 
56         /* allocate a space for the char* in the array */
57                 
58         if (  ctr->subkeys == 0 )
59                 ctr->subkeys = TALLOC_P( ctr, char *);
60         else {
61                 pp = TALLOC_REALLOC_ARRAY( ctr, ctr->subkeys, char *, ctr->num_subkeys+1);
62                 if ( pp )
63                         ctr->subkeys = pp;
64         }
65
66         /* allocate the string and save it in the array */
67         
68         ctr->subkeys[ctr->num_subkeys] = talloc_strdup( ctr, keyname );
69         ctr->num_subkeys++;
70         
71         return ctr->num_subkeys;
72 }
73  
74  /***********************************************************************
75  Add a new key to the array
76  **********************************************************************/
77
78 int regsubkey_ctr_delkey( REGSUBKEY_CTR *ctr, const char *keyname )
79 {
80         int i;
81
82         if ( !keyname )
83                 return ctr->num_subkeys;
84
85         /* make sure the keyname is actually already there */
86
87         for ( i=0; i<ctr->num_subkeys; i++ ) {
88                 if ( strequal( ctr->subkeys[i], keyname ) )
89                         break;
90         }
91         
92         if ( i == ctr->num_subkeys )
93                 return ctr->num_subkeys;
94
95         /* update if we have any keys left */
96         ctr->num_subkeys--;
97         if ( i < ctr->num_subkeys )
98                 memmove( &ctr->subkeys[i], &ctr->subkeys[i+1], sizeof(char*) * (ctr->num_subkeys-i) );
99         
100         return ctr->num_subkeys;
101 }
102
103 /***********************************************************************
104  Check for the existance of a key
105  **********************************************************************/
106
107 BOOL regsubkey_ctr_key_exists( REGSUBKEY_CTR *ctr, const char *keyname )
108 {
109         int     i;
110         
111         for ( i=0; i<ctr->num_subkeys; i++ ) {
112                 if ( strequal( ctr->subkeys[i],keyname ) )
113                         return True;
114         }
115         
116         return False;
117 }
118
119 /***********************************************************************
120  How many keys does the container hold ?
121  **********************************************************************/
122
123 int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr )
124 {
125         return ctr->num_subkeys;
126 }
127
128 /***********************************************************************
129  Retreive a specific key string
130  **********************************************************************/
131
132 char* regsubkey_ctr_specific_key( REGSUBKEY_CTR *ctr, uint32 key_index )
133 {
134         if ( ! (key_index < ctr->num_subkeys) )
135                 return NULL;
136                 
137         return ctr->subkeys[key_index];
138 }
139
140 /*
141  * Utility functions for REGVAL_CTR
142  */
143
144 /***********************************************************************
145  How many keys does the container hold ?
146  **********************************************************************/
147
148 int regval_ctr_numvals( REGVAL_CTR *ctr )
149 {
150         return ctr->num_values;
151 }
152
153 /***********************************************************************
154  allocate memory for and duplicate a REGISTRY_VALUE.
155  This is malloc'd memory so the caller should free it when done
156  **********************************************************************/
157
158 REGISTRY_VALUE* dup_registry_value( REGISTRY_VALUE *val )
159 {
160         REGISTRY_VALUE  *copy = NULL;
161         
162         if ( !val )
163                 return NULL;
164         
165         if ( !(copy = SMB_MALLOC_P( REGISTRY_VALUE)) ) {
166                 DEBUG(0,("dup_registry_value: malloc() failed!\n"));
167                 return NULL;
168         }
169         
170         /* copy all the non-pointer initial data */
171         
172         memcpy( copy, val, sizeof(REGISTRY_VALUE) );
173         
174         copy->size = 0;
175         copy->data_p = NULL;
176         
177         if ( val->data_p && val->size ) 
178         {
179                 if ( !(copy->data_p = memdup( val->data_p, val->size )) ) {
180                         DEBUG(0,("dup_registry_value: memdup() failed for [%d] bytes!\n",
181                                 val->size));
182                         SAFE_FREE( copy );
183                 }
184                 copy->size = val->size;
185         }
186         
187         return copy;    
188 }
189
190 /**********************************************************************
191  free the memory allocated to a REGISTRY_VALUE 
192  *********************************************************************/
193  
194 void free_registry_value( REGISTRY_VALUE *val )
195 {
196         if ( !val )
197                 return;
198                 
199         SAFE_FREE( val->data_p );
200         SAFE_FREE( val );
201         
202         return;
203 }
204
205 /**********************************************************************
206  *********************************************************************/
207
208 uint8* regval_data_p( REGISTRY_VALUE *val )
209 {
210         return val->data_p;
211 }
212
213 /**********************************************************************
214  *********************************************************************/
215
216 uint32 regval_size( REGISTRY_VALUE *val )
217 {
218         return val->size;
219 }
220
221 /**********************************************************************
222  *********************************************************************/
223
224 char* regval_name( REGISTRY_VALUE *val )
225 {
226         return val->valuename;
227 }
228
229 /**********************************************************************
230  *********************************************************************/
231
232 uint32 regval_type( REGISTRY_VALUE *val )
233 {
234         return val->type;
235 }
236
237 /***********************************************************************
238  Retreive a pointer to a specific value.  Caller shoud dup the structure
239  since this memory may go away with a regval_ctr_destroy()
240  **********************************************************************/
241
242 REGISTRY_VALUE* regval_ctr_specific_value( REGVAL_CTR *ctr, uint32 idx )
243 {
244         if ( !(idx < ctr->num_values) )
245                 return NULL;
246                 
247         return ctr->values[idx];
248 }
249
250 /***********************************************************************
251  Check for the existance of a value
252  **********************************************************************/
253
254 BOOL regval_ctr_key_exists( REGVAL_CTR *ctr, const char *value )
255 {
256         int     i;
257         
258         for ( i=0; i<ctr->num_values; i++ ) {
259                 if ( strequal( ctr->values[i]->valuename, value) )
260                         return True;
261         }
262         
263         return False;
264 }
265 /***********************************************************************
266  Add a new registry value to the array
267  **********************************************************************/
268
269 int regval_ctr_addvalue( REGVAL_CTR *ctr, const char *name, uint16 type, 
270                          const char *data_p, size_t size )
271 {
272         REGISTRY_VALUE **ppreg;
273         
274         if ( !name )
275                 return ctr->num_values;
276
277         /* Delete the current value (if it exists) and add the new one */
278
279         regval_ctr_delvalue( ctr, name );
280
281         /* allocate a slot in the array of pointers */
282                 
283         if (  ctr->num_values == 0 )
284                 ctr->values = TALLOC_P( ctr, REGISTRY_VALUE *);
285         else {
286                 ppreg = TALLOC_REALLOC_ARRAY( ctr, ctr->values, REGISTRY_VALUE *, ctr->num_values+1 );
287                 if ( ppreg )
288                         ctr->values = ppreg;
289         }
290
291         /* allocate a new value and store the pointer in the arrya */
292                 
293         ctr->values[ctr->num_values] = TALLOC_P( ctr, REGISTRY_VALUE);
294
295         /* init the value */
296         
297         fstrcpy( ctr->values[ctr->num_values]->valuename, name );
298         ctr->values[ctr->num_values]->type = type;
299         ctr->values[ctr->num_values]->data_p = TALLOC_MEMDUP( ctr, data_p, size );
300         ctr->values[ctr->num_values]->size = size;
301         ctr->num_values++;
302
303         return ctr->num_values;
304 }
305
306 /***********************************************************************
307  Add a new registry value to the array
308  **********************************************************************/
309
310 int regval_ctr_copyvalue( REGVAL_CTR *ctr, REGISTRY_VALUE *val )
311 {
312         REGISTRY_VALUE **ppreg;
313         
314         if ( val )
315         {
316                 /* allocate a slot in the array of pointers */
317                 
318                 if (  ctr->num_values == 0 )
319                         ctr->values = TALLOC_P( ctr, REGISTRY_VALUE *);
320                 else {
321                         ppreg = TALLOC_REALLOC_ARRAY( ctr, ctr->values, REGISTRY_VALUE *, ctr->num_values+1 );
322                         if ( ppreg )
323                                 ctr->values = ppreg;
324                 }
325
326                 /* allocate a new value and store the pointer in the arrya */
327                 
328                 ctr->values[ctr->num_values] = TALLOC_P( ctr, REGISTRY_VALUE);
329
330                 /* init the value */
331         
332                 fstrcpy( ctr->values[ctr->num_values]->valuename, val->valuename );
333                 ctr->values[ctr->num_values]->type = val->type;
334                 ctr->values[ctr->num_values]->data_p = TALLOC_MEMDUP( ctr, val->data_p, val->size );
335                 ctr->values[ctr->num_values]->size = val->size;
336                 ctr->num_values++;
337         }
338
339         return ctr->num_values;
340 }
341
342 /***********************************************************************
343  Delete a single value from the registry container.
344  No need to free memory since it is talloc'd.
345  **********************************************************************/
346
347 int regval_ctr_delvalue( REGVAL_CTR *ctr, const char *name )
348 {
349         int     i;
350         
351         for ( i=0; i<ctr->num_values; i++ ) {
352                 if ( strequal( ctr->values[i]->valuename, name ) )
353                         break;
354         }
355         
356         /* just return if we don't find it */
357         
358         if ( i == ctr->num_values )
359                 return ctr->num_values;
360         
361         /* If 'i' was not the last element, just shift everything down one */
362         ctr->num_values--;
363         if ( i < ctr->num_values )
364                 memmove( &ctr->values[i], &ctr->values[i+1], sizeof(REGISTRY_VALUE*)*(ctr->num_values-i) );
365         
366         return ctr->num_values;
367 }
368
369 /***********************************************************************
370  Retrieve single value from the registry container.
371  No need to free memory since it is talloc'd.
372  **********************************************************************/
373
374 REGISTRY_VALUE* regval_ctr_getvalue( REGVAL_CTR *ctr, const char *name )
375 {
376         int     i;
377         
378         /* search for the value */
379         
380         for ( i=0; i<ctr->num_values; i++ ) {
381                 if ( strequal( ctr->values[i]->valuename, name ) )
382                         return ctr->values[i];
383         }
384         
385         return NULL;
386 }
387