r23801: The FSF has moved around a lot. This fixes their Mass Ave address.
[samba.git] / source3 / registry / reg_eventlog.c
1
2 /* 
3  *  Unix SMB/CIFS implementation.
4  *  Virtual Windows Registry Layer
5  *  Copyright (C) Marcin Krzysztof Porwit    2005,
6  *  Copyright (C) Brian Moran                2005.
7  *  Copyright (C) Gerald (Jerry) Carter      2005.
8  *  
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 3 of the License, or
12  *  (at your option) any later version.
13  *  
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *  
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
21  */
22
23 #include "includes.h"
24
25
26 /**********************************************************************
27  for an eventlog, add in the default values
28 *********************************************************************/
29
30 BOOL eventlog_init_keys( void )
31 {
32         /* Find all of the eventlogs, add keys for each of them */
33         const char **elogs = lp_eventlog_list(  );
34         pstring evtlogpath;
35         pstring evtfilepath;
36         REGSUBKEY_CTR *subkeys;
37         REGVAL_CTR *values;
38         uint32 uiMaxSize;
39         uint32 uiRetention;
40         uint32 uiCategoryCount;
41         UNISTR2 data;
42
43         while ( elogs && *elogs ) {
44                 if ( !( subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR ) ) ) {
45                         DEBUG( 0, ( "talloc() failure!\n" ) );
46                         return False;
47                 }
48                 regdb_fetch_keys( KEY_EVENTLOG, subkeys );
49                 regsubkey_ctr_addkey( subkeys, *elogs );
50                 if ( !regdb_store_keys( KEY_EVENTLOG, subkeys ) ) {
51                         TALLOC_FREE(subkeys);
52                         return False;
53                 }
54                 TALLOC_FREE( subkeys );
55
56                 /* add in the key of form KEY_EVENTLOG/Application */
57                 DEBUG( 5,
58                        ( "Adding key of [%s] to path of [%s]\n", *elogs,
59                          KEY_EVENTLOG ) );
60
61                 slprintf( evtlogpath, sizeof( evtlogpath ) - 1, "%s\\%s",
62                           KEY_EVENTLOG, *elogs );
63                 /* add in the key of form KEY_EVENTLOG/Application/Application */
64                 DEBUG( 5,
65                        ( "Adding key of [%s] to path of [%s]\n", *elogs,
66                          evtlogpath ) );
67                 if ( !( subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR ) ) ) {
68                         DEBUG( 0, ( "talloc() failure!\n" ) );
69                         return False;
70                 }
71                 regdb_fetch_keys( evtlogpath, subkeys );
72                 regsubkey_ctr_addkey( subkeys, *elogs );
73
74                 if ( !regdb_store_keys( evtlogpath, subkeys ) ) {
75                         TALLOC_FREE(subkeys);
76                         return False;
77                 }
78                 TALLOC_FREE( subkeys );
79
80                 /* now add the values to the KEY_EVENTLOG/Application form key */
81                 if ( !( values = TALLOC_ZERO_P( NULL, REGVAL_CTR ) ) ) {
82                         DEBUG( 0, ( "talloc() failure!\n" ) );
83                         return False;
84                 }
85                 DEBUG( 5,
86                        ( "Storing values to eventlog path of [%s]\n",
87                          evtlogpath ) );
88                 regdb_fetch_values( evtlogpath, values );
89
90
91                 if ( !regval_ctr_key_exists( values, "MaxSize" ) ) {
92
93                         /* assume we have none, add them all */
94
95                         /* hard code some initial values */
96
97                         /* uiDisplayNameId = 0x00000100; */
98                         uiMaxSize = 0x00080000;
99                         uiRetention = 0x93A80;
100
101                         regval_ctr_addvalue( values, "MaxSize", REG_DWORD,
102                                              ( char * ) &uiMaxSize,
103                                              sizeof( uint32 ) );
104
105                         regval_ctr_addvalue( values, "Retention", REG_DWORD,
106                                              ( char * ) &uiRetention,
107                                              sizeof( uint32 ) );
108                         init_unistr2( &data, *elogs, UNI_STR_TERMINATE );
109
110                         regval_ctr_addvalue( values, "PrimaryModule", REG_SZ,
111                                              ( char * ) data.buffer,
112                                              data.uni_str_len *
113                                              sizeof( uint16 ) );
114                         init_unistr2( &data, *elogs, UNI_STR_TERMINATE );
115
116                         regval_ctr_addvalue( values, "Sources", REG_MULTI_SZ,
117                                              ( char * ) data.buffer,
118                                              data.uni_str_len *
119                                              sizeof( uint16 ) );
120
121                         pstr_sprintf( evtfilepath, "%%SystemRoot%%\\system32\\config\\%s.tdb", *elogs );
122                         init_unistr2( &data, evtfilepath, UNI_STR_TERMINATE );
123                         regval_ctr_addvalue( values, "File", REG_EXPAND_SZ, ( char * ) data.buffer,
124                                              data.uni_str_len * sizeof( uint16 ) );
125                         regdb_store_values( evtlogpath, values );
126
127                 }
128
129                 TALLOC_FREE( values );
130
131                 /* now do the values under KEY_EVENTLOG/Application/Application */
132                 slprintf( evtlogpath, sizeof( evtlogpath ) - 1, "%s\\%s\\%s",
133                           KEY_EVENTLOG, *elogs, *elogs );
134                 if ( !( values = TALLOC_ZERO_P( NULL, REGVAL_CTR ) ) ) {
135                         DEBUG( 0, ( "talloc() failure!\n" ) );
136                         return False;
137                 }
138                 DEBUG( 5,
139                        ( "Storing values to eventlog path of [%s]\n",
140                          evtlogpath ) );
141                 regdb_fetch_values( evtlogpath, values );
142                 if ( !regval_ctr_key_exists( values, "CategoryCount" ) ) {
143
144                         /* hard code some initial values */
145
146                         uiCategoryCount = 0x00000007;
147                         regval_ctr_addvalue( values, "CategoryCount",
148                                              REG_DWORD,
149                                              ( char * ) &uiCategoryCount,
150                                              sizeof( uint32 ) );
151                         init_unistr2( &data,
152                                       "%SystemRoot%\\system32\\eventlog.dll",
153                                       UNI_STR_TERMINATE );
154
155                         regval_ctr_addvalue( values, "CategoryMessageFile",
156                                              REG_EXPAND_SZ,
157                                              ( char * ) data.buffer,
158                                              data.uni_str_len *
159                                              sizeof( uint16 ) );
160                         regdb_store_values( evtlogpath, values );
161                 }
162                 TALLOC_FREE( values );
163                 elogs++;
164         }
165
166         return True;
167
168 }
169
170 /*********************************************************************
171  for an eventlog, add in a source name. If the eventlog doesn't 
172  exist (not in the list) do nothing.   If a source for the log 
173  already exists, change the information (remove, replace)
174 *********************************************************************/
175
176 BOOL eventlog_add_source( const char *eventlog, const char *sourcename,
177                           const char *messagefile )
178 {
179         /* Find all of the eventlogs, add keys for each of them */
180         /* need to add to the value KEY_EVENTLOG/<eventlog>/Sources string (Creating if necessary)
181            need to add KEY of source to KEY_EVENTLOG/<eventlog>/<source> */
182
183         const char **elogs = lp_eventlog_list(  );
184         char **wrklist, **wp;
185         pstring evtlogpath;
186         REGSUBKEY_CTR *subkeys;
187         REGVAL_CTR *values;
188         REGISTRY_VALUE *rval;
189         UNISTR2 data;
190         uint16 *msz_wp;
191         int mbytes, ii;
192         BOOL already_in;
193         int i;
194         int numsources;
195
196         if (!elogs) {
197                 return False;
198         }
199
200         for ( i = 0; elogs[i]; i++ ) {
201                 if ( strequal( elogs[i], eventlog ) )
202                         break;
203         }
204
205         if ( !elogs[i] ) {
206                 DEBUG( 0,
207                        ( "Eventlog [%s] not found in list of valid event logs\n",
208                          eventlog ) );
209                 return False;   /* invalid named passed in */
210         }
211
212         /* have to assume that the evenlog key itself exists at this point */
213         /* add in a key of [sourcename] under the eventlog key */
214
215         /* todo add to Sources */
216
217         if ( !( values = TALLOC_ZERO_P( NULL, REGVAL_CTR ) ) ) {
218                 DEBUG( 0, ( "talloc() failure!\n" ) );
219                 return False;
220         }
221
222         pstr_sprintf( evtlogpath, "%s\\%s", KEY_EVENTLOG, eventlog );
223
224         regdb_fetch_values( evtlogpath, values );
225
226
227         if ( !( rval = regval_ctr_getvalue( values, "Sources" ) ) ) {
228                 DEBUG( 0, ( "No Sources value for [%s]!\n", eventlog ) );
229                 return False;
230         }
231         /* perhaps this adding a new string to a multi_sz should be a fn? */
232         /* check to see if it's there already */
233
234         if ( rval->type != REG_MULTI_SZ ) {
235                 DEBUG( 0,
236                        ( "Wrong type for Sources, should be REG_MULTI_SZ\n" ) );
237                 return False;
238         }
239         /* convert to a 'regulah' chars to do some comparisons */
240
241         already_in = False;
242         wrklist = NULL;
243         dump_data( 1, rval->data_p, rval->size );
244         if ( ( numsources =
245                regval_convert_multi_sz( ( uint16 * ) rval->data_p, rval->size,
246                                         &wrklist ) ) > 0 ) {
247
248                 ii = numsources;
249                 /* see if it's in there already */
250                 wp = wrklist;
251
252                 while ( ii && wp && *wp ) {
253                         if ( strequal( *wp, sourcename ) ) {
254                                 DEBUG( 5,
255                                        ( "Source name [%s] already in list for [%s] \n",
256                                          sourcename, eventlog ) );
257                                 already_in = True;
258                                 break;
259                         }
260                         wp++;
261                         ii--;
262                 }
263         } else {
264                 if ( numsources < 0 ) {
265                         DEBUG( 3, ( "problem in getting the sources\n" ) );
266                         return False;
267                 }
268                 DEBUG( 3,
269                        ( "Nothing in the sources list, this might be a problem\n" ) );
270         }
271
272         wp = wrklist;
273
274         if ( !already_in ) {
275                 /* make a new list with an additional entry; copy values, add another */
276                 wp = TALLOC_ARRAY( NULL, char *, numsources + 2 );
277
278                 if ( !wp ) {
279                         DEBUG( 0, ( "talloc() failed \n" ) );
280                         return False;
281                 }
282                 memcpy( wp, wrklist, sizeof( char * ) * numsources );
283                 *( wp + numsources ) = ( char * ) sourcename;
284                 *( wp + numsources + 1 ) = NULL;
285                 mbytes = regval_build_multi_sz( wp, &msz_wp );
286                 dump_data( 1, ( uint8 * ) msz_wp, mbytes );
287                 regval_ctr_addvalue( values, "Sources", REG_MULTI_SZ,
288                                      ( char * ) msz_wp, mbytes );
289                 regdb_store_values( evtlogpath, values );
290                 TALLOC_FREE( msz_wp );
291         } else {
292                 DEBUG( 3,
293                        ( "Source name [%s] found in existing list of sources\n",
294                          sourcename ) );
295         }
296         TALLOC_FREE( values );
297         TALLOC_FREE( wrklist ); /*  */
298
299         if ( !( subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR ) ) ) {
300                 DEBUG( 0, ( "talloc() failure!\n" ) );
301                 return False;
302         }
303         pstr_sprintf( evtlogpath, "%s\\%s", KEY_EVENTLOG, eventlog );
304
305         regdb_fetch_keys( evtlogpath, subkeys );
306
307         if ( !regsubkey_ctr_key_exists( subkeys, sourcename ) ) {
308                 DEBUG( 5,
309                        ( " Source name [%s] for eventlog [%s] didn't exist, adding \n",
310                          sourcename, eventlog ) );
311                 regsubkey_ctr_addkey( subkeys, sourcename );
312                 if ( !regdb_store_keys( evtlogpath, subkeys ) )
313                         return False;
314         }
315         TALLOC_FREE( subkeys );
316
317         /* at this point KEY_EVENTLOG/<eventlog>/<sourcename> key is in there. Now need to add EventMessageFile */
318
319         /* now allocate room for the source's subkeys */
320
321         if ( !( subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR ) ) ) {
322                 DEBUG( 0, ( "talloc() failure!\n" ) );
323                 return False;
324         }
325         slprintf( evtlogpath, sizeof( evtlogpath ) - 1, "%s\\%s\\%s",
326                   KEY_EVENTLOG, eventlog, sourcename );
327
328         regdb_fetch_keys( evtlogpath, subkeys );
329
330         /* now add the values to the KEY_EVENTLOG/Application form key */
331         if ( !( values = TALLOC_ZERO_P( NULL, REGVAL_CTR ) ) ) {
332                 DEBUG( 0, ( "talloc() failure!\n" ) );
333                 return False;
334         }
335         DEBUG( 5,
336                ( "Storing EventMessageFile [%s] to eventlog path of [%s]\n",
337                  messagefile, evtlogpath ) );
338
339         regdb_fetch_values( evtlogpath, values );
340
341         init_unistr2( &data, messagefile, UNI_STR_TERMINATE );
342
343         regval_ctr_addvalue( values, "EventMessageFile", REG_SZ,
344                              ( char * ) data.buffer,
345                              data.uni_str_len * sizeof( uint16 ) );
346         regdb_store_values( evtlogpath, values );
347
348         TALLOC_FREE( values );
349
350         return True;
351 }