*/
#include "includes.h"
+#include "smbd/smbd.h"
+#include "system/filesys.h"
+#include "../librpc/gen_ndr/ndr_netlogon.h"
+#include "auth.h"
#define ALLOC_CHECK(ptr, label) do { if ((ptr) == NULL) { DEBUG(0, ("recycle.bin: out of memory!\n")); errno = ENOMEM; goto label; } } while(0)
#undef DBGC_CLASS
#define DBGC_CLASS vfs_recycle_debug_level
-static int recycle_connect(vfs_handle_struct *handle, const char *service, const char *user);
-static void recycle_disconnect(vfs_handle_struct *handle);
static int recycle_unlink(vfs_handle_struct *handle,
const struct smb_filename *smb_fname);
-static vfs_op_tuple recycle_ops[] = {
-
- /* Disk operations */
- {SMB_VFS_OP(recycle_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(recycle_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_TRANSPARENT},
-
- /* File operations */
- {SMB_VFS_OP(recycle_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
-
- {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
-};
-
-static int recycle_connect(vfs_handle_struct *handle, const char *service, const char *user)
-{
- DEBUG(10,("recycle_connect() connect to service[%s] as user[%s].\n",
- service,user));
-
- return SMB_VFS_NEXT_CONNECT(handle, service, user);
-}
-
-static void recycle_disconnect(vfs_handle_struct *handle)
-{
- DEBUG(10,("recycle_disconnect() connect to service[%s].\n",
- lp_servicename(SNUM(handle->conn))));
-
- SMB_VFS_NEXT_DISCONNECT(handle);
-}
-
static const char *recycle_repository(vfs_handle_struct *handle)
{
const char *tmp_str = NULL;
-
tmp_str = lp_parm_const_string(SNUM(handle->conn), "recycle", "repository",".recycle");
DEBUG(10, ("recycle: repository = %s\n", tmp_str));
-
+
return tmp_str;
}
static bool recycle_keep_dir_tree(vfs_handle_struct *handle)
{
bool ret;
-
+
ret = lp_parm_bool(SNUM(handle->conn), "recycle", "keeptree", False);
DEBUG(10, ("recycle_bin: keeptree = %s\n", ret?"True":"False"));
-
+
return ret;
}
ret = lp_parm_bool(SNUM(handle->conn), "recycle", "versions", False);
DEBUG(10, ("recycle: versions = %s\n", ret?"True":"False"));
-
+
return ret;
}
ret = lp_parm_bool(SNUM(handle->conn), "recycle", "touch", False);
DEBUG(10, ("recycle: touch = %s\n", ret?"True":"False"));
-
+
return ret;
}
ret = lp_parm_bool(SNUM(handle->conn), "recycle", "touch_mtime", False);
DEBUG(10, ("recycle: touch_mtime = %s\n", ret?"True":"False"));
-
+
return ret;
}
static const char **recycle_exclude(vfs_handle_struct *handle)
{
const char **tmp_lp;
-
+
tmp_lp = lp_parm_string_list(SNUM(handle->conn), "recycle", "exclude", NULL);
DEBUG(10, ("recycle: exclude = %s ...\n", tmp_lp?*tmp_lp:""));
-
+
return tmp_lp;
}
static const char **recycle_exclude_dir(vfs_handle_struct *handle)
{
const char **tmp_lp;
-
+
tmp_lp = lp_parm_string_list(SNUM(handle->conn), "recycle", "exclude_dir", NULL);
DEBUG(10, ("recycle: exclude_dir = %s ...\n", tmp_lp?*tmp_lp:""));
-
+
return tmp_lp;
}
static const char **recycle_noversions(vfs_handle_struct *handle)
{
const char **tmp_lp;
-
+
tmp_lp = lp_parm_string_list(SNUM(handle->conn), "recycle", "noversions", NULL);
DEBUG(10, ("recycle: noversions = %s\n", tmp_lp?*tmp_lp:""));
-
+
return tmp_lp;
}
static SMB_OFF_T recycle_maxsize(vfs_handle_struct *handle)
{
SMB_OFF_T maxsize;
-
+
maxsize = conv_str_size(lp_parm_const_string(SNUM(handle->conn),
"recycle", "maxsize", NULL));
DEBUG(10, ("recycle: maxsize = %lu\n", (long unsigned int)maxsize));
-
+
return maxsize;
}
static SMB_OFF_T recycle_minsize(vfs_handle_struct *handle)
{
SMB_OFF_T minsize;
-
+
minsize = conv_str_size(lp_parm_const_string(SNUM(handle->conn),
"recycle", "minsize", NULL));
DEBUG(10, ("recycle: minsize = %lu\n", (long unsigned int)minsize));
-
+
return minsize;
}
*new_dir = '\0';
if (dname[0] == '/') {
/* Absolute path. */
- safe_strcat(new_dir,"/",len);
+ if (strlcat(new_dir,"/",len+1) >= len+1) {
+ goto done;
+ }
}
/* Create directory tree if neccessary */
for(token = strtok_r(tok_str, "/", &saveptr); token;
token = strtok_r(NULL, "/", &saveptr)) {
- safe_strcat(new_dir, token, len);
+ if (strlcat(new_dir, token, len+1) >= len+1) {
+ goto done;
+ }
if (recycle_directory_exist(handle, new_dir))
DEBUG(10, ("recycle: dir %s already exists\n", new_dir));
else {
goto done;
}
}
- safe_strcat(new_dir, "/", len);
+ if (strlcat(new_dir, "/", len+1) >= len+1) {
+ goto done;
+ }
mode = recycle_subdir_mode(handle);
}
{
struct smb_filename *smb_fname_tmp = NULL;
struct smb_file_time ft;
- char *fname = NULL;
NTSTATUS status;
int ret, err;
/* mtime */
ft.mtime = touch_mtime ? ft.atime : smb_fname_tmp->st.st_ex_mtime;
- status = get_full_smb_filename(talloc_tos(), smb_fname_tmp, &fname);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
- }
-
become_root();
- ret = SMB_VFS_NEXT_NTIMES(handle, fname, &ft);
+ ret = SMB_VFS_NEXT_NTIMES(handle, smb_fname_tmp, &ft);
err = errno;
unbecome_root();
if (ret == -1 ) {
DEBUG(0, ("recycle: touching %s failed, reason = %s\n",
smb_fname_str_dbg(smb_fname_tmp), strerror(err)));
}
-
out:
- TALLOC_FREE(fname);
+ TALLOC_FREE(smb_fname_tmp);
}
/**
int rc = -1;
repository = talloc_sub_advanced(NULL, lp_servicename(SNUM(conn)),
- conn->server_info->unix_name,
+ conn->session_info->unix_info->unix_name,
conn->connectpath,
- conn->server_info->utok.gid,
- conn->server_info->sanitized_username,
- pdb_get_domain(conn->server_info->sam_account),
+ conn->session_info->unix_token->gid,
+ conn->session_info->unix_info->sanitized_username,
+ conn->session_info->info->domain_name,
recycle_repository(handle));
ALLOC_CHECK(repository, done);
/* shouldn't we allow absolute path names here? --metze */
/* Yes :-). JRA. */
trim_char(repository, '\0', '/');
-
+
if(!repository || *(repository) == '\0') {
DEBUG(3, ("recycle: repository path not set, purging %s...\n",
smb_fname_str_dbg(smb_fname)));
return rc;
}
+static struct vfs_fn_pointers vfs_recycle_fns = {
+ .unlink_fn = recycle_unlink
+};
+
NTSTATUS vfs_recycle_init(void);
NTSTATUS vfs_recycle_init(void)
{
- NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "recycle", recycle_ops);
+ NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "recycle",
+ &vfs_recycle_fns);
if (!NT_STATUS_IS_OK(ret))
return ret;
-
+
vfs_recycle_debug_level = debug_add_class("recycle");
if (vfs_recycle_debug_level == -1) {
vfs_recycle_debug_level = DBGC_VFS;
} else {
DEBUG(10, ("vfs_recycle: Debug class number of 'recycle': %d\n", vfs_recycle_debug_level));
}
-
+
return ret;
}