2 Unix SMB/CIFS implementation.
4 Copyright (C) Jelmer Vernooij 2004-2007.
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.
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.
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/>.
22 #include "system/dir.h"
23 #include "system/filesys.h"
30 static struct hive_operations reg_backend_dir
;
32 static WERROR
reg_dir_add_key(TALLOC_CTX
*mem_ctx
,
33 const struct hive_key
*parent
,
34 const char *name
, const char *classname
,
35 struct security_descriptor
*desc
,
36 struct hive_key
**result
)
38 struct dir_key
*dk
= talloc_get_type(parent
, struct dir_key
);
42 path
= talloc_asprintf(mem_ctx
, "%s/%s", dk
->path
, name
);
43 W_ERROR_HAVE_NO_MEMORY(path
);
44 ret
= mkdir(path
, 0700);
46 struct dir_key
*key
= talloc(mem_ctx
, struct dir_key
);
47 W_ERROR_HAVE_NO_MEMORY(key
);
48 key
->key
.ops
= ®_backend_dir
;
49 key
->path
= talloc_steal(key
, path
);
50 *result
= (struct hive_key
*)key
;
55 return WERR_ALREADY_EXISTS
;
56 printf("FAILED %s BECAUSE: %s\n", path
, strerror(errno
));
57 return WERR_GENERAL_FAILURE
;
60 static WERROR
reg_dir_delete_recursive(const char *name
)
68 DEBUG(3,("Unable to open '%s': %s\n", name
,
73 while((e
= readdir(d
))) {
77 if (ISDOT(e
->d_name
) || ISDOTDOT(e
->d_name
))
80 path
= talloc_asprintf(name
, "%s/%s", name
, e
->d_name
);
81 W_ERROR_HAVE_NO_MEMORY(path
);
85 if (!S_ISDIR(stbuf
.st_mode
)) {
86 if (unlink(path
) < 0) {
89 return WERR_GENERAL_FAILURE
;
92 werr
= reg_dir_delete_recursive(path
);
93 if (!W_ERROR_IS_OK(werr
)) {
104 if (rmdir(name
) == 0)
106 else if (errno
== ENOENT
)
109 return WERR_GENERAL_FAILURE
;
112 static WERROR
reg_dir_del_key(TALLOC_CTX
*mem_ctx
, const struct hive_key
*k
,
115 struct dir_key
*dk
= talloc_get_type(k
, struct dir_key
);
119 child
= talloc_asprintf(mem_ctx
, "%s/%s", dk
->path
, name
);
120 W_ERROR_HAVE_NO_MEMORY(child
);
122 ret
= reg_dir_delete_recursive(child
);
129 static WERROR
reg_dir_open_key(TALLOC_CTX
*mem_ctx
,
130 const struct hive_key
*parent
,
131 const char *name
, struct hive_key
**subkey
)
135 const struct dir_key
*p
= talloc_get_type(parent
, struct dir_key
);
139 DEBUG(0, ("NULL pointer passed as directory name!"));
140 return WERR_INVALID_PARAM
;
143 fullpath
= talloc_asprintf(mem_ctx
, "%s/%s", p
->path
, name
);
144 W_ERROR_HAVE_NO_MEMORY(fullpath
);
146 d
= opendir(fullpath
);
148 DEBUG(3,("Unable to open '%s': %s\n", fullpath
,
150 talloc_free(fullpath
);
154 ret
= talloc(mem_ctx
, struct dir_key
);
155 ret
->key
.ops
= ®_backend_dir
;
156 ret
->path
= talloc_steal(ret
, fullpath
);
157 *subkey
= (struct hive_key
*)ret
;
161 static WERROR
reg_dir_key_by_index(TALLOC_CTX
*mem_ctx
,
162 const struct hive_key
*k
, uint32_t idx
,
164 const char **classname
,
165 NTTIME
*last_mod_time
)
168 const struct dir_key
*dk
= talloc_get_type(k
, struct dir_key
);
172 d
= opendir(dk
->path
);
175 return WERR_INVALID_PARAM
;
177 while((e
= readdir(d
))) {
178 if(!ISDOT(e
->d_name
) && !ISDOTDOT(e
->d_name
)) {
182 /* Check if file is a directory */
183 thispath
= talloc_asprintf(mem_ctx
, "%s/%s", dk
->path
,
185 W_ERROR_HAVE_NO_MEMORY(thispath
);
186 stat(thispath
, &stbuf
);
188 if (!S_ISDIR(stbuf
.st_mode
)) {
189 talloc_free(thispath
);
195 *name
= talloc_strdup(mem_ctx
, e
->d_name
);
196 W_ERROR_HAVE_NO_MEMORY(*name
);
199 unix_to_nt_time(last_mod_time
, st
.st_mtime
);
200 talloc_free(thispath
);
206 talloc_free(thispath
);
212 return WERR_NO_MORE_ITEMS
;
215 WERROR
reg_open_directory(TALLOC_CTX
*parent_ctx
,
216 const char *location
, struct hive_key
**key
)
220 if (location
== NULL
)
221 return WERR_INVALID_PARAM
;
223 dk
= talloc(parent_ctx
, struct dir_key
);
224 W_ERROR_HAVE_NO_MEMORY(dk
);
225 dk
->key
.ops
= ®_backend_dir
;
226 dk
->path
= talloc_strdup(dk
, location
);
227 *key
= (struct hive_key
*)dk
;
231 WERROR
reg_create_directory(TALLOC_CTX
*parent_ctx
,
232 const char *location
, struct hive_key
**key
)
234 if (mkdir(location
, 0700) != 0) {
236 return WERR_GENERAL_FAILURE
;
239 return reg_open_directory(parent_ctx
, location
, key
);
242 static WERROR
reg_dir_get_info(TALLOC_CTX
*ctx
, const struct hive_key
*key
,
243 const char **classname
,
244 uint32_t *num_subkeys
,
245 uint32_t *num_values
,
247 uint32_t *max_subkeynamelen
,
248 uint32_t *max_valnamelen
,
249 uint32_t *max_valbufsize
)
252 const struct dir_key
*dk
= talloc_get_type(key
, struct dir_key
);
256 SMB_ASSERT(key
!= NULL
);
258 if (classname
!= NULL
)
261 d
= opendir(dk
->path
);
263 return WERR_INVALID_PARAM
;
265 if (num_subkeys
!= NULL
)
268 if (num_values
!= NULL
)
271 if (max_subkeynamelen
!= NULL
)
272 *max_subkeynamelen
= 0;
274 if (max_valnamelen
!= NULL
)
277 if (max_valbufsize
!= NULL
)
280 while((e
= readdir(d
))) {
281 if(!ISDOT(e
->d_name
) && !ISDOTDOT(e
->d_name
)) {
282 char *path
= talloc_asprintf(ctx
, "%s/%s",
283 dk
->path
, e
->d_name
);
284 W_ERROR_HAVE_NO_MEMORY(path
);
286 if (stat(path
, &st
) < 0) {
287 DEBUG(0, ("Error statting %s: %s\n", path
,
293 if (S_ISDIR(st
.st_mode
)) {
294 if (num_subkeys
!= NULL
)
296 if (max_subkeynamelen
!= NULL
)
297 *max_subkeynamelen
= MAX(*max_subkeynamelen
, strlen(e
->d_name
));
300 if (!S_ISDIR(st
.st_mode
)) {
301 if (num_values
!= NULL
)
303 if (max_valnamelen
!= NULL
)
304 *max_valnamelen
= MAX(*max_valnamelen
, strlen(e
->d_name
));
305 if (max_valbufsize
!= NULL
)
306 *max_valbufsize
= MAX(*max_valbufsize
, st
.st_size
);
320 static WERROR
reg_dir_set_value(struct hive_key
*key
, const char *name
,
321 uint32_t type
, const DATA_BLOB data
)
323 const struct dir_key
*dk
= talloc_get_type(key
, struct dir_key
);
327 path
= talloc_asprintf(dk
, "%s/%s", dk
->path
, name
);
328 W_ERROR_HAVE_NO_MEMORY(path
);
330 ret
= file_save(path
, data
.data
, data
.length
);
335 return WERR_GENERAL_FAILURE
;
343 static WERROR
reg_dir_get_value(TALLOC_CTX
*mem_ctx
,
344 struct hive_key
*key
, const char *name
,
345 uint32_t *type
, DATA_BLOB
*data
)
347 const struct dir_key
*dk
= talloc_get_type(key
, struct dir_key
);
352 path
= talloc_asprintf(mem_ctx
, "%s/%s", dk
->path
, name
);
353 W_ERROR_HAVE_NO_MEMORY(path
);
355 contents
= file_load(path
, &size
, 0, mem_ctx
);
359 if (contents
== NULL
)
363 *type
= 4; /* FIXME */
365 data
->data
= (uint8_t *)contents
;
371 static WERROR
reg_dir_enum_value(TALLOC_CTX
*mem_ctx
,
372 struct hive_key
*key
, uint32_t idx
,
374 uint32_t *type
, DATA_BLOB
*data
)
376 const struct dir_key
*dk
= talloc_get_type(key
, struct dir_key
);
381 d
= opendir(dk
->path
);
383 DEBUG(3,("Unable to open '%s': %s\n", dk
->path
,
389 while((e
= readdir(d
))) {
390 if (ISDOT(e
->d_name
) || ISDOTDOT(e
->d_name
))
395 *name
= talloc_strdup(mem_ctx
, e
->d_name
);
396 W_ERROR_HAVE_NO_MEMORY(*name
);
398 W_ERROR_NOT_OK_RETURN(reg_dir_get_value(mem_ctx
, key
,
408 return WERR_NO_MORE_ITEMS
;
412 static WERROR
reg_dir_del_value(TALLOC_CTX
*mem_ctx
,
413 struct hive_key
*key
, const char *name
)
415 const struct dir_key
*dk
= talloc_get_type(key
, struct dir_key
);
419 path
= talloc_asprintf(mem_ctx
, "%s/%s", dk
->path
, name
);
420 W_ERROR_HAVE_NO_MEMORY(path
);
429 return WERR_GENERAL_FAILURE
;
435 static struct hive_operations reg_backend_dir
= {
437 .get_key_by_name
= reg_dir_open_key
,
438 .get_key_info
= reg_dir_get_info
,
439 .add_key
= reg_dir_add_key
,
440 .del_key
= reg_dir_del_key
,
441 .enum_key
= reg_dir_key_by_index
,
442 .set_value
= reg_dir_set_value
,
443 .get_value_by_name
= reg_dir_get_value
,
444 .enum_value
= reg_dir_enum_value
,
445 .delete_value
= reg_dir_del_value
,