1 /*
2  * Samba Unix/Linux SMB client library
3  * Registry Editor
4  * Copyright (C) Christopher Davis 2012
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 /* s3 registry backend, adapted from rpc backend */
21 
22 #include "includes.h"
23 #include "lib/registry/registry.h"
24 #include "regedit.h"
25 
26 struct samba3_key {
27 	struct registry_key key;
28 	struct samba3_registry_key s3key;
29 };
30 
31 struct samba3_registry_context {
32 	struct registry_context context;
33 };
34 
35 static struct registry_operations reg_backend_s3;
36 
37 static struct {
38 	uint32_t hkey;
39 	const char *name;
40 } known_hives[] = {
41 	{ HKEY_LOCAL_MACHINE, "HKLM" },
42 	{ HKEY_CURRENT_USER, "HKCU" },
43 	{ HKEY_CLASSES_ROOT, "HKCR" },
44 	{ HKEY_PERFORMANCE_DATA, "HKPD" },
45 	{ HKEY_USERS, "HKU" },
46 	{ HKEY_DYN_DATA, "HKDD" },
47 	{ HKEY_CURRENT_CONFIG, "HKCC" },
48 	{ 0, NULL }
49 };
50 
samba3_get_predefined_key(struct registry_context * ctx,uint32_t hkey_type,struct registry_key ** k)51 static WERROR samba3_get_predefined_key(struct registry_context *ctx,
52 				        uint32_t hkey_type,
53 				        struct registry_key **k)
54 {
55 	int n;
56 	const char *name;
57 	struct samba3_key *mykeydata;
58 
59 	*k = NULL;
60 	name = NULL;
61 
62 	for(n = 0; known_hives[n].hkey; n++) {
63 		if(known_hives[n].hkey == hkey_type) {
64 			name = known_hives[n].name;
65 			break;
66 		}
67 	}
68 
69 	if (name == NULL) {
70 		DEBUG(1, ("No such hive %d\n", hkey_type));
71 		return WERR_NO_MORE_ITEMS;
72 	}
73 
74 	mykeydata = talloc_zero(ctx, struct samba3_key);
75 	W_ERROR_HAVE_NO_MEMORY(mykeydata);
76 	mykeydata->key.context = ctx;
77 	*k = (struct registry_key *)mykeydata;
78 
79 	return reg_openhive_wrap(ctx, name, &mykeydata->s3key);
80 }
81 
samba3_open_key(TALLOC_CTX * mem_ctx,struct registry_key * h,const char * name,struct registry_key ** key)82 static WERROR samba3_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h,
83 			      const char *name, struct registry_key **key)
84 {
85 	struct samba3_key *parentkeydata, *mykeydata;
86 
87 	parentkeydata = talloc_get_type(h, struct samba3_key);
88 
89 	mykeydata = talloc_zero(mem_ctx, struct samba3_key);
90 	W_ERROR_HAVE_NO_MEMORY(mykeydata);
91 	mykeydata->key.context = h->context;
92 	*key = (struct registry_key *)mykeydata;
93 
94 	return reg_openkey_wrap(mem_ctx, &parentkeydata->s3key,
95 				name, &mykeydata->s3key);
96 }
97 
samba3_get_value_by_index(TALLOC_CTX * mem_ctx,const struct registry_key * parent,uint32_t n,const char ** value_name,uint32_t * type,DATA_BLOB * data)98 static WERROR samba3_get_value_by_index(TALLOC_CTX *mem_ctx,
99 				        const struct registry_key *parent,
100 				        uint32_t n,
101 				        const char **value_name,
102 				        uint32_t *type,
103 				        DATA_BLOB *data)
104 {
105 	struct samba3_key *mykeydata;
106 
107 	mykeydata = talloc_get_type(parent, struct samba3_key);
108 
109 	return reg_enumvalue_wrap(mem_ctx, &mykeydata->s3key, n,
110 				  discard_const(value_name), type, data);
111 }
112 
samba3_get_value_by_name(TALLOC_CTX * mem_ctx,const struct registry_key * parent,const char * value_name,uint32_t * type,DATA_BLOB * data)113 static WERROR samba3_get_value_by_name(TALLOC_CTX *mem_ctx,
114 				       const struct registry_key *parent,
115 				       const char *value_name,
116 				       uint32_t *type,
117 				       DATA_BLOB *data)
118 {
119 	struct samba3_key *mykeydata;
120 
121 	mykeydata = talloc_get_type(parent, struct samba3_key);
122 
123 	return reg_queryvalue_wrap(mem_ctx, &mykeydata->s3key,
124 				   value_name, type, data);
125 }
126 
samba3_get_subkey_by_index(TALLOC_CTX * mem_ctx,const struct registry_key * parent,uint32_t n,const char ** name,const char ** keyclass,NTTIME * last_changed_time)127 static WERROR samba3_get_subkey_by_index(TALLOC_CTX *mem_ctx,
128 				         const struct registry_key *parent,
129 				         uint32_t n,
130 				         const char **name,
131 				         const char **keyclass,
132 				         NTTIME *last_changed_time)
133 {
134 	struct samba3_key *mykeydata;
135 
136 	mykeydata = talloc_get_type(parent, struct samba3_key);
137 
138 	*keyclass = NULL;
139 
140 	return reg_enumkey_wrap(mem_ctx, &mykeydata->s3key, n,
141 				discard_const(name), last_changed_time);
142 }
143 
samba3_add_key(TALLOC_CTX * mem_ctx,struct registry_key * parent,const char * path,const char * key_class,struct security_descriptor * sec,struct registry_key ** key)144 static WERROR samba3_add_key(TALLOC_CTX *mem_ctx,
145 			     struct registry_key *parent, const char *path,
146 			     const char *key_class,
147 			     struct security_descriptor *sec,
148 			     struct registry_key **key)
149 {
150 	struct samba3_key *parentkd;
151 	struct samba3_key *newkd;
152 
153 	parentkd = talloc_get_type(parent, struct samba3_key);
154 	newkd = talloc_zero(mem_ctx, struct samba3_key);
155 
156 	W_ERROR_HAVE_NO_MEMORY(newkd);
157 	newkd->key.context = parent->context;
158 	*key = (struct registry_key *)newkd;
159 
160 	return reg_createkey_wrap(mem_ctx, &parentkd->s3key, path,
161 				  &newkd->s3key);
162 }
163 
samba3_del_key(TALLOC_CTX * mem_ctx,struct registry_key * parent,const char * name)164 static WERROR samba3_del_key(TALLOC_CTX *mem_ctx, struct registry_key *parent,
165 			     const char *name)
166 {
167 	struct samba3_key *mykeydata;
168 
169 	mykeydata = talloc_get_type(parent, struct samba3_key);
170 
171 	return reg_deletekey_wrap(&mykeydata->s3key, name);
172 }
173 
samba3_del_value(TALLOC_CTX * mem_ctx,struct registry_key * key,const char * name)174 static WERROR samba3_del_value(TALLOC_CTX *mem_ctx, struct registry_key *key,
175                                const char *name)
176 {
177 	struct samba3_key *mykeydata = talloc_get_type(key, struct samba3_key);
178 
179         return reg_deletevalue_wrap(&mykeydata->s3key, name);
180 }
181 
samba3_set_value(struct registry_key * key,const char * name,uint32_t type,const DATA_BLOB data)182 static WERROR samba3_set_value(struct registry_key *key, const char *name,
183                                uint32_t type, const DATA_BLOB data)
184 {
185 	struct samba3_key *mykeydata = talloc_get_type(key, struct samba3_key);
186 
187         return reg_setvalue_wrap(&mykeydata->s3key, name, type, data);
188 }
189 
samba3_get_info(TALLOC_CTX * mem_ctx,const struct registry_key * key,const char ** classname,uint32_t * num_subkeys,uint32_t * num_values,NTTIME * last_changed_time,uint32_t * max_subkeylen,uint32_t * max_valnamelen,uint32_t * max_valbufsize)190 static WERROR samba3_get_info(TALLOC_CTX *mem_ctx,
191 			      const struct registry_key *key,
192 			      const char **classname,
193 			      uint32_t *num_subkeys,
194 			      uint32_t *num_values,
195 			      NTTIME *last_changed_time,
196 			      uint32_t *max_subkeylen,
197 			      uint32_t *max_valnamelen,
198 			      uint32_t *max_valbufsize)
199 {
200 	struct samba3_key *mykeydata = talloc_get_type(key, struct samba3_key);
201 	uint32_t max_subkeysize, secdescsize;
202 
203 	return reg_queryinfokey_wrap(&mykeydata->s3key, num_subkeys,
204 				     max_subkeylen, &max_subkeysize,
205 				     num_values, max_valnamelen,
206 				     max_valbufsize, &secdescsize,
207 				     last_changed_time);
208 }
209 
210 static struct registry_operations reg_backend_s3 = {
211 	.name = "samba3",
212 	.open_key = samba3_open_key,
213 	.get_predefined_key = samba3_get_predefined_key,
214 	.enum_key = samba3_get_subkey_by_index,
215 	.enum_value = samba3_get_value_by_index,
216 	.get_value = samba3_get_value_by_name,
217 	.set_value = samba3_set_value,
218 	.delete_value = samba3_del_value,
219 	.create_key = samba3_add_key,
220 	.delete_key = samba3_del_key,
221 	.get_key_info = samba3_get_info,
222 };
223 
reg_open_samba3(TALLOC_CTX * mem_ctx,struct registry_context ** ctx)224 WERROR reg_open_samba3(TALLOC_CTX *mem_ctx, struct registry_context **ctx)
225 {
226 	WERROR rv;
227 	struct samba3_registry_context *rctx;
228 
229 	/* initialize s3 registry */
230 	rv = reg_init_wrap();
231 	if (!W_ERROR_IS_OK(rv)) {
232 		return rv;
233 	}
234 
235 	rctx = talloc_zero(mem_ctx, struct samba3_registry_context);
236 	if (rctx == NULL) {
237 		return WERR_NOT_ENOUGH_MEMORY;
238 	}
239 
240 	*ctx = (struct registry_context *)rctx;
241 	(*ctx)->ops = &reg_backend_s3;
242 
243 	return WERR_OK;
244 }
245