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 ret
= mkdir(path
, 0700);
45 struct dir_key
*key
= talloc(mem_ctx
, struct dir_key
);
46 key
->key
.ops
= ®_backend_dir
;
47 key
->path
= talloc_steal(key
, path
);
48 *result
= (struct hive_key
*)key
;
53 return WERR_ALREADY_EXISTS
;
54 printf("FAILED %s BECAUSE: %s\n", path
, strerror(errno
));
55 return WERR_GENERAL_FAILURE
;
58 static WERROR
reg_dir_delete_recursive(const char *name
)
66 DEBUG(3,("Unable to open '%s': %s\n", name
,
71 while((e
= readdir(d
))) {
75 if (ISDOT(e
->d_name
) || ISDOTDOT(e
->d_name
))
78 path
= talloc_asprintf(name
, "%s/%s", name
, e
->d_name
);
84 if (!S_ISDIR(stbuf
.st_mode
)) {
85 if (unlink(path
) < 0) {
88 return WERR_GENERAL_FAILURE
;
91 werr
= reg_dir_delete_recursive(path
);
92 if (!W_ERROR_IS_OK(werr
)) {
103 if (rmdir(name
) == 0)
105 else if (errno
== ENOENT
)
108 return WERR_GENERAL_FAILURE
;
111 static WERROR
reg_dir_del_key(const struct hive_key
*k
, const char *name
)
113 struct dir_key
*dk
= talloc_get_type(k
, struct dir_key
);
114 char *child
= talloc_asprintf(NULL
, "%s/%s", dk
->path
, name
);
117 ret
= reg_dir_delete_recursive(child
);
124 static WERROR
reg_dir_open_key(TALLOC_CTX
*mem_ctx
,
125 const struct hive_key
*parent
,
126 const char *name
, struct hive_key
**subkey
)
130 const struct dir_key
*p
= talloc_get_type(parent
, struct dir_key
);
134 DEBUG(0, ("NULL pointer passed as directory name!"));
135 return WERR_INVALID_PARAM
;
138 fullpath
= talloc_asprintf(mem_ctx
, "%s/%s", p
->path
, name
);
140 d
= opendir(fullpath
);
142 DEBUG(3,("Unable to open '%s': %s\n", fullpath
,
147 ret
= talloc(mem_ctx
, struct dir_key
);
148 ret
->key
.ops
= ®_backend_dir
;
149 ret
->path
= talloc_steal(ret
, fullpath
);
150 *subkey
= (struct hive_key
*)ret
;
154 static WERROR
reg_dir_key_by_index(TALLOC_CTX
*mem_ctx
,
155 const struct hive_key
*k
, uint32_t idx
,
157 const char **classname
,
158 NTTIME
*last_mod_time
)
161 const struct dir_key
*dk
= talloc_get_type(k
, struct dir_key
);
165 d
= opendir(dk
->path
);
168 return WERR_INVALID_PARAM
;
170 while((e
= readdir(d
))) {
171 if(!ISDOT(e
->d_name
) && !ISDOTDOT(e
->d_name
)) {
175 /* Check if file is a directory */
176 asprintf(&thispath
, "%s/%s", dk
->path
, e
->d_name
);
177 stat(thispath
, &stbuf
);
179 if (!S_ISDIR(stbuf
.st_mode
)) {
186 *name
= talloc_strdup(mem_ctx
, e
->d_name
);
189 unix_to_nt_time(last_mod_time
, st
.st_mtime
);
202 return WERR_NO_MORE_ITEMS
;
205 WERROR
reg_open_directory(TALLOC_CTX
*parent_ctx
,
206 const char *location
, struct hive_key
**key
)
210 if (location
== NULL
)
211 return WERR_INVALID_PARAM
;
213 dk
= talloc(parent_ctx
, struct dir_key
);
214 dk
->key
.ops
= ®_backend_dir
;
215 dk
->path
= talloc_strdup(dk
, location
);
216 *key
= (struct hive_key
*)dk
;
220 WERROR
reg_create_directory(TALLOC_CTX
*parent_ctx
,
221 const char *location
, struct hive_key
**key
)
223 if (mkdir(location
, 0700) != 0) {
225 return WERR_GENERAL_FAILURE
;
228 return reg_open_directory(parent_ctx
, location
, key
);
231 static WERROR
reg_dir_get_info(TALLOC_CTX
*ctx
, const struct hive_key
*key
,
232 const char **classname
,
233 uint32_t *num_subkeys
,
234 uint32_t *num_values
,
236 uint32_t *max_subkeynamelen
,
237 uint32_t *max_valnamelen
,
238 uint32_t *max_valbufsize
)
241 const struct dir_key
*dk
= talloc_get_type(key
, struct dir_key
);
245 SMB_ASSERT(key
!= NULL
);
247 if (classname
!= NULL
)
250 d
= opendir(dk
->path
);
252 return WERR_INVALID_PARAM
;
254 if (num_subkeys
!= NULL
)
257 if (num_values
!= NULL
)
260 if (max_subkeynamelen
!= NULL
)
261 *max_subkeynamelen
= 0;
263 if (max_valnamelen
!= NULL
)
266 if (max_valbufsize
!= NULL
)
269 while((e
= readdir(d
))) {
270 if(!ISDOT(e
->d_name
) && !ISDOTDOT(e
->d_name
)) {
271 char *path
= talloc_asprintf(ctx
, "%s/%s",
272 dk
->path
, e
->d_name
);
274 if (stat(path
, &st
) < 0) {
275 DEBUG(0, ("Error statting %s: %s\n", path
,
280 if (S_ISDIR(st
.st_mode
)) {
281 if (num_subkeys
!= NULL
)
283 if (max_subkeynamelen
!= NULL
)
284 *max_subkeynamelen
= MAX(*max_subkeynamelen
, strlen(e
->d_name
));
287 if (!S_ISDIR(st
.st_mode
)) {
288 if (num_values
!= NULL
)
290 if (max_valnamelen
!= NULL
)
291 *max_valnamelen
= MAX(*max_valnamelen
, strlen(e
->d_name
));
292 if (max_valbufsize
!= NULL
)
293 *max_valbufsize
= MAX(*max_valbufsize
, st
.st_size
);
307 static WERROR
reg_dir_set_value(struct hive_key
*key
, const char *name
,
308 uint32_t type
, const DATA_BLOB data
)
310 const struct dir_key
*dk
= talloc_get_type(key
, struct dir_key
);
311 char *path
= talloc_asprintf(dk
, "%s/%s", dk
->path
, name
);
313 if (!file_save(path
, data
.data
, data
.length
))
314 return WERR_GENERAL_FAILURE
;
321 static WERROR
reg_dir_get_value(TALLOC_CTX
*mem_ctx
,
322 struct hive_key
*key
, const char *name
,
323 uint32_t *type
, DATA_BLOB
*data
)
325 const struct dir_key
*dk
= talloc_get_type(key
, struct dir_key
);
326 char *path
= talloc_asprintf(mem_ctx
, "%s/%s", dk
->path
, name
);
330 contents
= file_load(path
, &size
, 0, mem_ctx
);
332 if (contents
== NULL
)
336 *type
= 4; /* FIXME */
338 data
->data
= (uint8_t *)contents
;
344 static WERROR
reg_dir_enum_value(TALLOC_CTX
*mem_ctx
,
345 struct hive_key
*key
, uint32_t idx
,
347 uint32_t *type
, DATA_BLOB
*data
)
349 const struct dir_key
*dk
= talloc_get_type(key
, struct dir_key
);
354 d
= opendir(dk
->path
);
356 DEBUG(3,("Unable to open '%s': %s\n", dk
->path
,
362 while((e
= readdir(d
))) {
363 if (ISDOT(e
->d_name
) || ISDOTDOT(e
->d_name
))
368 *name
= talloc_strdup(mem_ctx
, e
->d_name
);
369 W_ERROR_NOT_OK_RETURN(reg_dir_get_value(mem_ctx
, key
,
379 return WERR_NO_MORE_ITEMS
;
383 static WERROR
reg_dir_del_value (struct hive_key
*key
, const char *name
)
385 const struct dir_key
*dk
= talloc_get_type(key
, struct dir_key
);
386 char *path
= talloc_asprintf(key
, "%s/%s", dk
->path
, name
);
387 if (unlink(path
) < 0) {
391 return WERR_GENERAL_FAILURE
;
398 static struct hive_operations reg_backend_dir
= {
400 .get_key_by_name
= reg_dir_open_key
,
401 .get_key_info
= reg_dir_get_info
,
402 .add_key
= reg_dir_add_key
,
403 .del_key
= reg_dir_del_key
,
404 .enum_key
= reg_dir_key_by_index
,
405 .set_value
= reg_dir_set_value
,
406 .get_value_by_name
= reg_dir_get_value
,
407 .enum_value
= reg_dir_enum_value
,
408 .delete_value
= reg_dir_del_value
,