Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : * Virtual Windows Registry Layer
4 : * Copyright (C) Gerald Carter 2002-2005
5 : * Copyright (C) Michael Adam 2006-2008
6 : *
7 : * This program is free software; you can redistribute it and/or modify
8 : * it under the terms of the GNU General Public License as published by
9 : * the Free Software Foundation; either version 3 of the License, or
10 : * (at your option) any later version.
11 : *
12 : * This program is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU General Public License
18 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : /*
22 : * Implementation of registry frontend view functions.
23 : * Functions moved from reg_frontend.c to minimize linker deps.
24 : */
25 :
26 : #include "includes.h"
27 : #include "system/passwd.h" /* uid_wrapper */
28 : #include "registry.h"
29 : #include "reg_dispatcher.h"
30 : #include "../libcli/security/security.h"
31 :
32 : #undef DBGC_CLASS
33 : #define DBGC_CLASS DBGC_REGISTRY
34 :
35 : static const struct generic_mapping reg_generic_map =
36 : { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL };
37 :
38 : /********************************************************************
39 : ********************************************************************/
40 :
41 20963 : static WERROR construct_registry_sd(TALLOC_CTX *ctx, struct security_descriptor **psd)
42 : {
43 69 : struct security_ace ace[3];
44 20963 : size_t i = 0;
45 69 : struct security_descriptor *sd;
46 69 : struct security_acl *theacl;
47 69 : size_t sd_size;
48 :
49 : /* basic access for Everyone */
50 :
51 20963 : init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
52 : REG_KEY_READ, 0);
53 :
54 : /* Full Access 'BUILTIN\Administrators' */
55 :
56 20963 : init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
57 : SEC_ACE_TYPE_ACCESS_ALLOWED, REG_KEY_ALL, 0);
58 :
59 : /* Full Access 'NT Authority\System' */
60 :
61 20963 : init_sec_ace(&ace[i++], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED,
62 : REG_KEY_ALL, 0);
63 :
64 : /* create the security descriptor */
65 :
66 20963 : theacl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace);
67 20963 : if (theacl == NULL) {
68 0 : return WERR_NOT_ENOUGH_MEMORY;
69 : }
70 :
71 20963 : sd = make_sec_desc(ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
72 : &global_sid_Builtin_Administrators,
73 : &global_sid_System, NULL, theacl,
74 : &sd_size);
75 20963 : if (sd == NULL) {
76 0 : return WERR_NOT_ENOUGH_MEMORY;
77 : }
78 :
79 20963 : *psd = sd;
80 20963 : return WERR_OK;
81 : }
82 :
83 : /***********************************************************************
84 : High level wrapper function for storing registry subkeys
85 : ***********************************************************************/
86 :
87 0 : bool store_reg_keys(struct registry_key_handle *key,
88 : struct regsubkey_ctr *subkeys)
89 : {
90 0 : if (key->ops && key->ops->store_subkeys)
91 0 : return key->ops->store_subkeys(key->name, subkeys);
92 :
93 0 : return false;
94 : }
95 :
96 : /***********************************************************************
97 : High level wrapper function for storing registry values
98 : ***********************************************************************/
99 :
100 19642 : bool store_reg_values(struct registry_key_handle *key, struct regval_ctr *val)
101 : {
102 19642 : if (key->ops && key->ops->store_values)
103 19640 : return key->ops->store_values(key->name, val);
104 :
105 2 : return false;
106 : }
107 :
108 2527 : WERROR create_reg_subkey(struct registry_key_handle *key, const char *subkey)
109 : {
110 2527 : if (key->ops && key->ops->create_subkey) {
111 2527 : return key->ops->create_subkey(key->name, subkey);
112 : }
113 :
114 0 : return WERR_NOT_SUPPORTED;
115 : }
116 :
117 1594 : WERROR delete_reg_subkey(struct registry_key_handle *key, const char *subkey, bool lazy)
118 : {
119 1594 : if (key->ops && key->ops->delete_subkey) {
120 1594 : return key->ops->delete_subkey(key->name, subkey, lazy);
121 : }
122 :
123 0 : return WERR_NOT_SUPPORTED;
124 : }
125 :
126 : /***********************************************************************
127 : High level wrapper function for enumerating registry subkeys
128 : Initialize the TALLOC_CTX if necessary
129 : ***********************************************************************/
130 :
131 3318960 : int fetch_reg_keys(struct registry_key_handle *key,
132 : struct regsubkey_ctr *subkey_ctr)
133 : {
134 3318960 : int result = -1;
135 :
136 3318960 : if (key->ops && key->ops->fetch_subkeys)
137 3318960 : result = key->ops->fetch_subkeys(key->name, subkey_ctr);
138 :
139 3318960 : return result;
140 : }
141 :
142 : /***********************************************************************
143 : High level wrapper function for enumerating registry values
144 : ***********************************************************************/
145 :
146 53191 : int fetch_reg_values(struct registry_key_handle *key, struct regval_ctr *val)
147 : {
148 53191 : int result = -1;
149 :
150 53191 : DEBUG(10, ("fetch_reg_values called for key '%s' (ops %p)\n", key->name,
151 : (key->ops) ? (void *)key->ops : NULL));
152 :
153 53191 : if (key->ops && key->ops->fetch_values)
154 53191 : result = key->ops->fetch_values(key->name, val);
155 :
156 53191 : return result;
157 : }
158 :
159 : /***********************************************************************
160 : High level access check for passing the required access mask to the
161 : underlying registry backend
162 : ***********************************************************************/
163 :
164 400371 : bool regkey_access_check(struct registry_key_handle *key, uint32_t requested,
165 : uint32_t *granted,
166 : const struct security_token *token )
167 : {
168 193 : struct security_descriptor *sec_desc;
169 193 : NTSTATUS status;
170 193 : WERROR err;
171 :
172 : /* root free-pass, like we have on all other pipes like samr, lsa, etc. */
173 400371 : if (root_mode()) {
174 399444 : *granted = REG_KEY_ALL;
175 399444 : return true;
176 : }
177 :
178 : /* use the default security check if the backend has not defined its
179 : * own */
180 :
181 927 : if (key->ops && key->ops->reg_access_check) {
182 328 : return key->ops->reg_access_check(key->name, requested,
183 : granted, token);
184 : }
185 :
186 599 : err = regkey_get_secdesc(talloc_tos(), key, &sec_desc);
187 :
188 599 : if (!W_ERROR_IS_OK(err)) {
189 0 : return false;
190 : }
191 :
192 599 : se_map_generic( &requested, ®_generic_map );
193 :
194 599 : status =se_access_check(sec_desc, token, requested, granted);
195 599 : TALLOC_FREE(sec_desc);
196 599 : if (!NT_STATUS_IS_OK(status)) {
197 0 : return false;
198 : }
199 :
200 530 : return NT_STATUS_IS_OK(status);
201 : }
202 :
203 20963 : WERROR regkey_get_secdesc(TALLOC_CTX *mem_ctx, struct registry_key_handle *key,
204 : struct security_descriptor **psecdesc)
205 : {
206 69 : struct security_descriptor *secdesc;
207 69 : WERROR werr;
208 :
209 20963 : if (key->ops && key->ops->get_secdesc) {
210 20955 : werr = key->ops->get_secdesc(mem_ctx, key->name, psecdesc);
211 20955 : if (W_ERROR_IS_OK(werr)) {
212 0 : return WERR_OK;
213 : }
214 : }
215 :
216 20963 : werr = construct_registry_sd(mem_ctx, &secdesc);
217 20963 : if (!W_ERROR_IS_OK(werr)) {
218 0 : return werr;
219 : }
220 :
221 20963 : *psecdesc = secdesc;
222 20963 : return WERR_OK;
223 : }
224 :
225 0 : WERROR regkey_set_secdesc(struct registry_key_handle *key,
226 : struct security_descriptor *psecdesc)
227 : {
228 0 : if (key->ops && key->ops->set_secdesc) {
229 0 : return key->ops->set_secdesc(key->name, psecdesc);
230 : }
231 :
232 0 : return WERR_ACCESS_DENIED;
233 : }
234 :
235 : /**
236 : * Check whether the in-memory version of the subkyes of a
237 : * registry key needs update from disk.
238 : */
239 311764 : bool reg_subkeys_need_update(struct registry_key_handle *key,
240 : struct regsubkey_ctr *subkeys)
241 : {
242 311764 : if (key->ops && key->ops->subkeys_need_update)
243 : {
244 311764 : return key->ops->subkeys_need_update(subkeys);
245 : }
246 :
247 0 : return true;
248 : }
249 :
250 : /**
251 : * Check whether the in-memory version of the values of a
252 : * registry key needs update from disk.
253 : */
254 259032 : bool reg_values_need_update(struct registry_key_handle *key,
255 : struct regval_ctr *values)
256 : {
257 259032 : if (key->ops && key->ops->values_need_update)
258 : {
259 258484 : return key->ops->values_need_update(values);
260 : }
261 :
262 548 : return true;
263 : }
264 :
|