libndr: Avoid assigning duplicate versions to symbols
[amitay/samba.git] / source3 / registry / reg_api_util.c
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 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         if (!(path = SMB_STRDUP(orig_path))) {
43                 return WERR_NOT_ENOUGH_MEMORY;
44         }
45
46         p = strchr(path, '\\');
47
48         if ((p == NULL) || (p[1] == '\0')) {
49                 /*
50                  * No key behind the hive, just return the hive
51                  */
52
53                 err = reg_openhive(mem_ctx, path, desired_access, token,
54                                    &hive);
55                 if (!W_ERROR_IS_OK(err)) {
56                         SAFE_FREE(path);
57                         return err;
58                 }
59                 SAFE_FREE(path);
60                 *pkey = hive;
61                 return WERR_OK;
62         }
63
64         *p = '\0';
65
66         err = reg_openhive(mem_ctx, path, KEY_ENUMERATE_SUB_KEYS, token,
67                            &hive);
68         if (!W_ERROR_IS_OK(err)) {
69                 SAFE_FREE(path);
70                 return err;
71         }
72
73         err = reg_openkey(mem_ctx, hive, p+1, desired_access, &key);
74
75         TALLOC_FREE(hive);
76         SAFE_FREE(path);
77
78         if (!W_ERROR_IS_OK(err)) {
79                 return err;
80         }
81
82         *pkey = key;
83         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 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         if (!(path = SMB_STRDUP(orig_path))) {
102                 return WERR_NOT_ENOUGH_MEMORY;
103         }
104
105         p = strchr(path, '\\');
106
107         if ((p == NULL) || (p[1] == '\0')) {
108                 /*
109                  * No key behind the hive, just return the hive
110                  */
111
112                 err = reg_openhive(mem_ctx, path, desired_access, token,
113                                    &hive);
114                 if (!W_ERROR_IS_OK(err)) {
115                         SAFE_FREE(path);
116                         return err;
117                 }
118                 SAFE_FREE(path);
119                 *pkey = hive;
120                 *paction = REG_OPENED_EXISTING_KEY;
121                 return WERR_OK;
122         }
123
124         *p = '\0';
125
126         err = reg_openhive(mem_ctx, path,
127                            (strchr(p+1, '\\') != NULL) ?
128                            KEY_ENUMERATE_SUB_KEYS : KEY_CREATE_SUB_KEY,
129                            token, &hive);
130         if (!W_ERROR_IS_OK(err)) {
131                 SAFE_FREE(path);
132                 return err;
133         }
134
135         err = reg_createkey(mem_ctx, hive, p+1, desired_access, pkey, paction);
136         SAFE_FREE(path);
137         TALLOC_FREE(hive);
138         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 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         if (!(path = SMB_STRDUP(orig_path))) {
154                 return WERR_NOT_ENOUGH_MEMORY;
155         }
156
157         p = strchr(path, '\\');
158
159         if ((p == NULL) || (p[1] == '\0')) {
160                 SAFE_FREE(path);
161                 return WERR_INVALID_PARAMETER;
162         }
163
164         *p = '\0';
165
166         err = reg_openhive(NULL, path,
167                            (strchr(p+1, '\\') != NULL) ?
168                            KEY_ENUMERATE_SUB_KEYS : KEY_CREATE_SUB_KEY,
169                            token, &hive);
170         if (!W_ERROR_IS_OK(err)) {
171                 SAFE_FREE(path);
172                 return err;
173         }
174
175         err = reg_deletekey_recursive(hive, p+1);
176         SAFE_FREE(path);
177         TALLOC_FREE(hive);
178         return err;
179 }
180
181 struct registry_value *registry_value_dw(TALLOC_CTX *mem_ctx, uint32_t dw)
182 {
183         struct registry_value *ret;
184
185         ret = talloc_zero(mem_ctx, struct registry_value);
186         if (ret == NULL) {
187                 return NULL;
188         }
189
190         ret->data = data_blob_talloc(ret, NULL, sizeof(uint32_t));
191         if (ret->data.data == NULL) {
192                 talloc_free(ret);
193                 return NULL;
194         }
195
196         ret->type = REG_DWORD;
197
198         SIVAL(ret->data.data, 0, dw);
199
200         return ret;
201 }
202
203 struct registry_value *registry_value_sz(TALLOC_CTX *mem_ctx, const char *str)
204 {
205         struct registry_value *ret;
206
207         ret = talloc_zero(mem_ctx, struct registry_value);
208         if (ret == NULL) {
209                 return NULL;
210         }
211
212         if (!push_reg_sz(ret, &ret->data, str)) {
213                 talloc_free(ret);
214                 return NULL;
215         }
216
217         ret->type = REG_SZ;
218
219         return ret;
220 }
221
222 struct registry_value *registry_value_multi_sz(TALLOC_CTX *mem_ctx, const char **str)
223 {
224         struct registry_value *ret;
225
226         ret = talloc_zero(mem_ctx, struct registry_value);
227         if (ret == NULL) {
228                 return NULL;
229         }
230
231         if (!push_reg_multi_sz(ret, &ret->data, str)) {
232                 talloc_free(ret);
233                 return NULL;
234         }
235
236         ret->type = REG_MULTI_SZ;
237
238         return ret;
239 }
240
241 int registry_value_cmp(const struct registry_value* v1, const struct registry_value* v2)
242 {
243         if (v1->type == v2->type) {
244                 return data_blob_cmp(&v1->data, &v2->data);
245         }
246         return v1->type - v2->type;
247 }