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