r23801: The FSF has moved around a lot. This fixes their Mass Ave address.
[ira/wip.git] / source3 / registry / reg_frontend.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 3 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, see <http://www.gnu.org/licenses/>.
18  */
19
20 /* Implementation of registry frontend view functions. */
21
22 #include "includes.h"
23
24 #undef DBGC_CLASS
25 #define DBGC_CLASS DBGC_RPC_SRV
26
27 extern REGISTRY_OPS printing_ops;
28 extern REGISTRY_OPS eventlog_ops;
29 extern REGISTRY_OPS shares_reg_ops;
30 extern REGISTRY_OPS smbconf_reg_ops;
31 extern REGISTRY_OPS regdb_ops;          /* these are the default */
32
33 /* array of REGISTRY_HOOK's which are read into a tree for easy access */
34 /* #define REG_TDB_ONLY         1 */
35
36 REGISTRY_HOOK reg_hooks[] = {
37 #ifndef REG_TDB_ONLY 
38   { KEY_PRINTING,               &printing_ops },
39   { KEY_PRINTING_2K,            &printing_ops },
40   { KEY_PRINTING_PORTS,         &printing_ops },
41   { KEY_SHARES,                 &shares_reg_ops },
42   { KEY_SMBCONF,                &smbconf_reg_ops },
43 #endif
44   { NULL, NULL }
45 };
46
47 /***********************************************************************
48  Open the registry database and initialize the REGISTRY_HOOK cache
49  ***********************************************************************/
50  
51 BOOL init_registry( void )
52 {
53         int i;
54         
55         
56         if ( !regdb_init() ) {
57                 DEBUG(0,("init_registry: failed to initialize the registry tdb!\n"));
58                 return False;
59         }
60
61         /* build the cache tree of registry hooks */
62         
63         reghook_cache_init();
64         
65         for ( i=0; reg_hooks[i].keyname; i++ ) {
66                 if ( !reghook_cache_add(&reg_hooks[i]) )
67                         return False;
68         }
69
70         if ( DEBUGLEVEL >= 20 )
71                 reghook_dump_cache(20);
72
73         /* add any keys for other services */
74
75         svcctl_init_keys();
76         eventlog_init_keys();
77         perfcount_init_keys();
78
79         /* close and let each smbd open up as necessary */
80
81         regdb_close();
82
83         return True;
84 }
85
86 WERROR regkey_open_internal( TALLOC_CTX *ctx, REGISTRY_KEY **regkey,
87                              const char *path,
88                              const struct nt_user_token *token,
89                              uint32 access_desired )
90 {
91         struct registry_key *key;
92         WERROR err;
93
94         err = reg_open_path(NULL, path, access_desired, token, &key);
95         if (!W_ERROR_IS_OK(err)) {
96                 return err;
97         }
98
99         *regkey = talloc_move(ctx, &key->key);
100         TALLOC_FREE(key);
101         return WERR_OK;
102 }
103
104 WERROR regkey_set_secdesc(REGISTRY_KEY *key,
105                           struct security_descriptor *psecdesc)
106 {
107         if (key->hook && key->hook->ops && key->hook->ops->set_secdesc) {
108                 return key->hook->ops->set_secdesc(key->name, psecdesc);
109         }
110
111         return WERR_ACCESS_DENIED;
112 }
113
114 /*
115  * Utility function to create a registry key without opening the hive
116  * before. Assumes the hive already exists.
117  */
118
119 WERROR reg_create_path(TALLOC_CTX *mem_ctx, const char *orig_path,
120                        uint32 desired_access,
121                        const struct nt_user_token *token,
122                        enum winreg_CreateAction *paction,
123                        struct registry_key **pkey)
124 {
125         struct registry_key *hive;
126         char *path, *p;
127         WERROR err;
128
129         if (!(path = SMB_STRDUP(orig_path))) {
130                 return WERR_NOMEM;
131         }
132
133         p = strchr(path, '\\');
134
135         if ((p == NULL) || (p[1] == '\0')) {
136                 /*
137                  * No key behind the hive, just return the hive
138                  */
139
140                 err = reg_openhive(mem_ctx, path, desired_access, token,
141                                    &hive);
142                 if (!W_ERROR_IS_OK(err)) {
143                         SAFE_FREE(path);
144                         return err;
145                 }
146                 SAFE_FREE(path);
147                 *pkey = hive;
148                 *paction = REG_OPENED_EXISTING_KEY;
149                 return WERR_OK;
150         }
151
152         *p = '\0';
153
154         err = reg_openhive(mem_ctx, path,
155                            (strchr(p+1, '\\') != NULL) ?
156                            SEC_RIGHTS_ENUM_SUBKEYS : SEC_RIGHTS_CREATE_SUBKEY,
157                            token, &hive);
158         if (!W_ERROR_IS_OK(err)) {
159                 SAFE_FREE(path);
160                 return err;
161         }
162
163         err = reg_createkey(mem_ctx, hive, p+1, desired_access, pkey, paction);
164         SAFE_FREE(path);
165         TALLOC_FREE(hive);
166         return err;
167 }
168
169 /*
170  * Utility function to create a registry key without opening the hive
171  * before. Will not delete a hive.
172  */
173
174 WERROR reg_delete_path(const struct nt_user_token *token,
175                        const char *orig_path)
176 {
177         struct registry_key *hive;
178         char *path, *p;
179         WERROR err;
180
181         if (!(path = SMB_STRDUP(orig_path))) {
182                 return WERR_NOMEM;
183         }
184
185         p = strchr(path, '\\');
186
187         if ((p == NULL) || (p[1] == '\0')) {
188                 SAFE_FREE(path);
189                 return WERR_INVALID_PARAM;
190         }
191
192         *p = '\0';
193
194         err = reg_openhive(NULL, path,
195                            (strchr(p+1, '\\') != NULL) ?
196                            SEC_RIGHTS_ENUM_SUBKEYS : SEC_RIGHTS_CREATE_SUBKEY,
197                            token, &hive);
198         if (!W_ERROR_IS_OK(err)) {
199                 SAFE_FREE(path);
200                 return err;
201         }
202
203         err = reg_deletekey(hive, p+1);
204         SAFE_FREE(path);
205         TALLOC_FREE(hive);
206         return err;
207 }