Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : * Virtual Windows Registry Layer
4 : * Copyright (C) Volker Lendecke 2006
5 : * Copyright (C) Michael Adam 2007-2010
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 : * Higher level utility functions on top of reg_api.c
23 : */
24 :
25 : #include "includes.h"
26 : #include "registry.h"
27 : #include "reg_api.h"
28 : #include "reg_api_util.h"
29 : #include "libcli/registry/util_reg.h"
30 :
31 : /**
32 : * Utility function to open a complete registry path including the hive prefix.
33 : */
34 100 : WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path,
35 : uint32_t desired_access, const struct security_token *token,
36 : struct registry_key **pkey)
37 : {
38 : struct registry_key *hive, *key;
39 : char *path, *p;
40 : WERROR err;
41 :
42 100 : if (!(path = SMB_STRDUP(orig_path))) {
43 0 : return WERR_NOT_ENOUGH_MEMORY;
44 : }
45 :
46 100 : p = strchr(path, '\\');
47 :
48 100 : if ((p == NULL) || (p[1] == '\0')) {
49 : /*
50 : * No key behind the hive, just return the hive
51 : */
52 :
53 0 : err = reg_openhive(mem_ctx, path, desired_access, token,
54 : &hive);
55 0 : if (!W_ERROR_IS_OK(err)) {
56 0 : SAFE_FREE(path);
57 0 : return err;
58 : }
59 0 : SAFE_FREE(path);
60 0 : *pkey = hive;
61 0 : return WERR_OK;
62 : }
63 :
64 100 : *p = '\0';
65 :
66 100 : err = reg_openhive(mem_ctx, path, KEY_ENUMERATE_SUB_KEYS, token,
67 : &hive);
68 100 : if (!W_ERROR_IS_OK(err)) {
69 0 : SAFE_FREE(path);
70 0 : return err;
71 : }
72 :
73 100 : err = reg_openkey(mem_ctx, hive, p+1, desired_access, &key);
74 :
75 100 : TALLOC_FREE(hive);
76 100 : SAFE_FREE(path);
77 :
78 100 : if (!W_ERROR_IS_OK(err)) {
79 0 : return err;
80 : }
81 :
82 100 : *pkey = key;
83 100 : return WERR_OK;
84 : }
85 :
86 : /**
87 : * Utility function to create a registry key without opening the hive
88 : * before. Assumes the hive already exists.
89 : */
90 :
91 0 : WERROR reg_create_path(TALLOC_CTX *mem_ctx, const char *orig_path,
92 : uint32_t desired_access,
93 : const struct security_token *token,
94 : enum winreg_CreateAction *paction,
95 : struct registry_key **pkey)
96 : {
97 : struct registry_key *hive;
98 : char *path, *p;
99 : WERROR err;
100 :
101 0 : if (!(path = SMB_STRDUP(orig_path))) {
102 0 : return WERR_NOT_ENOUGH_MEMORY;
103 : }
104 :
105 0 : p = strchr(path, '\\');
106 :
107 0 : if ((p == NULL) || (p[1] == '\0')) {
108 : /*
109 : * No key behind the hive, just return the hive
110 : */
111 :
112 0 : err = reg_openhive(mem_ctx, path, desired_access, token,
113 : &hive);
114 0 : if (!W_ERROR_IS_OK(err)) {
115 0 : SAFE_FREE(path);
116 0 : return err;
117 : }
118 0 : SAFE_FREE(path);
119 0 : *pkey = hive;
120 0 : *paction = REG_OPENED_EXISTING_KEY;
121 0 : return WERR_OK;
122 : }
123 :
124 0 : *p = '\0';
125 :
126 0 : err = reg_openhive(mem_ctx, path,
127 0 : (strchr(p+1, '\\') != NULL) ?
128 : KEY_ENUMERATE_SUB_KEYS : KEY_CREATE_SUB_KEY,
129 : token, &hive);
130 0 : if (!W_ERROR_IS_OK(err)) {
131 0 : SAFE_FREE(path);
132 0 : return err;
133 : }
134 :
135 0 : err = reg_createkey(mem_ctx, hive, p+1, desired_access, pkey, paction);
136 0 : SAFE_FREE(path);
137 0 : TALLOC_FREE(hive);
138 0 : return err;
139 : }
140 :
141 : /*
142 : * Utility function to recursively delete a registry key without opening the
143 : * hive before. Will not delete a hive.
144 : */
145 :
146 0 : WERROR reg_delete_path(const struct security_token *token,
147 : const char *orig_path)
148 : {
149 : struct registry_key *hive;
150 : char *path, *p;
151 : WERROR err;
152 :
153 0 : if (!(path = SMB_STRDUP(orig_path))) {
154 0 : return WERR_NOT_ENOUGH_MEMORY;
155 : }
156 :
157 0 : p = strchr(path, '\\');
158 :
159 0 : if ((p == NULL) || (p[1] == '\0')) {
160 0 : SAFE_FREE(path);
161 0 : return WERR_INVALID_PARAMETER;
162 : }
163 :
164 0 : *p = '\0';
165 :
166 0 : err = reg_openhive(NULL, path,
167 0 : (strchr(p+1, '\\') != NULL) ?
168 : KEY_ENUMERATE_SUB_KEYS : KEY_CREATE_SUB_KEY,
169 : token, &hive);
170 0 : if (!W_ERROR_IS_OK(err)) {
171 0 : SAFE_FREE(path);
172 0 : return err;
173 : }
174 :
175 0 : err = reg_deletekey_recursive(hive, p+1);
176 0 : SAFE_FREE(path);
177 0 : TALLOC_FREE(hive);
178 0 : return err;
179 : }
180 :
181 0 : struct registry_value *registry_value_dw(TALLOC_CTX *mem_ctx, uint32_t dw)
182 : {
183 : struct registry_value *ret;
184 :
185 0 : ret = talloc_zero(mem_ctx, struct registry_value);
186 0 : if (ret == NULL) {
187 0 : return NULL;
188 : }
189 :
190 0 : ret->data = data_blob_talloc(ret, NULL, sizeof(uint32_t));
191 0 : if (ret->data.data == NULL) {
192 0 : talloc_free(ret);
193 0 : return NULL;
194 : }
195 :
196 0 : ret->type = REG_DWORD;
197 :
198 0 : SIVAL(ret->data.data, 0, dw);
199 :
200 0 : return ret;
201 : }
202 :
203 0 : struct registry_value *registry_value_sz(TALLOC_CTX *mem_ctx, const char *str)
204 : {
205 : struct registry_value *ret;
206 :
207 0 : ret = talloc_zero(mem_ctx, struct registry_value);
208 0 : if (ret == NULL) {
209 0 : return NULL;
210 : }
211 :
212 0 : if (!push_reg_sz(ret, &ret->data, str)) {
213 0 : talloc_free(ret);
214 0 : return NULL;
215 : }
216 :
217 0 : ret->type = REG_SZ;
218 :
219 0 : return ret;
220 : }
221 :
222 0 : struct registry_value *registry_value_multi_sz(TALLOC_CTX *mem_ctx, const char **str)
223 : {
224 : struct registry_value *ret;
225 :
226 0 : ret = talloc_zero(mem_ctx, struct registry_value);
227 0 : if (ret == NULL) {
228 0 : return NULL;
229 : }
230 :
231 0 : if (!push_reg_multi_sz(ret, &ret->data, str)) {
232 0 : talloc_free(ret);
233 0 : return NULL;
234 : }
235 :
236 0 : ret->type = REG_MULTI_SZ;
237 :
238 0 : return ret;
239 : }
240 :
241 0 : int registry_value_cmp(const struct registry_value* v1, const struct registry_value* v2)
242 : {
243 0 : if (v1->type == v2->type) {
244 0 : return data_blob_cmp(&v1->data, &v2->data);
245 : }
246 0 : return v1->type - v2->type;
247 : }
|