s3-auth: Split out get_user_sid_info3_and_extra() from create_local_nt_token_from_info3()
[amitay/samba.git] / source3 / modules / vfs_recycle.c
index 626147ca83a6aceb19f3dfd5ba39714a3494e480..dfc3b9cc0f352f841c48c3f11d86f73fee191653 100644 (file)
  */
 
 #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)
 
@@ -32,33 +35,9 @@ static int vfs_recycle_debug_level = DBGC_VFS;
 #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 int recycle_connect(vfs_handle_struct *handle, const char *service, const char *user)
-{
-       int ret = SMB_VFS_NEXT_CONNECT(handle, service, user);
-
-       if (ret < 0) {
-               return ret;
-       }
-
-       DEBUG(10,("recycle_connect() connect to service[%s] as user[%s].\n",
-               service,user));
-
-       return 0;
-}
-
-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;
@@ -147,9 +126,9 @@ static const char **recycle_noversions(vfs_handle_struct *handle)
        return tmp_lp;
 }
 
-static SMB_OFF_T recycle_maxsize(vfs_handle_struct *handle)
+static off_t recycle_maxsize(vfs_handle_struct *handle)
 {
-       SMB_OFF_T maxsize;
+       off_t maxsize;
 
        maxsize = conv_str_size(lp_parm_const_string(SNUM(handle->conn),
                                            "recycle", "maxsize", NULL));
@@ -159,9 +138,9 @@ static SMB_OFF_T recycle_maxsize(vfs_handle_struct *handle)
        return maxsize;
 }
 
-static SMB_OFF_T recycle_minsize(vfs_handle_struct *handle)
+static off_t recycle_minsize(vfs_handle_struct *handle)
 {
-       SMB_OFF_T minsize;
+       off_t minsize;
 
        minsize = conv_str_size(lp_parm_const_string(SNUM(handle->conn),
                                            "recycle", "minsize", NULL));
@@ -207,10 +186,12 @@ static mode_t recycle_subdir_mode(vfs_handle_struct *handle)
 
 static bool recycle_directory_exist(vfs_handle_struct *handle, const char *dname)
 {
-       SMB_STRUCT_STAT st;
+       struct smb_filename smb_fname = {
+                       .base_name = discard_const_p(char, dname)
+       };
 
-       if (vfs_stat_smb_fname(handle->conn, dname, &st) == 0) {
-               if (S_ISDIR(st.st_ex_mode)) {
+       if (SMB_VFS_STAT(handle->conn, &smb_fname) == 0) {
+               if (S_ISDIR(smb_fname.st.st_ex_mode)) {
                        return True;
                }
        }
@@ -222,11 +203,10 @@ static bool recycle_file_exist(vfs_handle_struct *handle,
                               const struct smb_filename *smb_fname)
 {
        struct smb_filename *smb_fname_tmp = NULL;
-       NTSTATUS status;
        bool ret = false;
 
-       status = copy_smb_filename(talloc_tos(), smb_fname, &smb_fname_tmp);
-       if (!NT_STATUS_IS_OK(status)) {
+       smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
+       if (smb_fname_tmp == NULL) {
                return false;
        }
 
@@ -246,23 +226,22 @@ static bool recycle_file_exist(vfs_handle_struct *handle,
  * @param fname file name
  * @return size in bytes
  **/
-static SMB_OFF_T recycle_get_file_size(vfs_handle_struct *handle,
+static off_t recycle_get_file_size(vfs_handle_struct *handle,
                                       const struct smb_filename *smb_fname)
 {
        struct smb_filename *smb_fname_tmp = NULL;
-       NTSTATUS status;
-       SMB_OFF_T size;
+       off_t size;
 
-       status = copy_smb_filename(talloc_tos(), smb_fname, &smb_fname_tmp);
-       if (!NT_STATUS_IS_OK(status)) {
-               size = (SMB_OFF_T)0;
+       smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
+       if (smb_fname_tmp == NULL) {
+               size = (off_t)0;
                goto out;
        }
 
        if (SMB_VFS_STAT(handle->conn, smb_fname_tmp) != 0) {
                DEBUG(0,("recycle: stat for %s returned %s\n",
                         smb_fname_str_dbg(smb_fname_tmp), strerror(errno)));
-               size = (SMB_OFF_T)0;
+               size = (off_t)0;
                goto out;
        }
 
@@ -301,24 +280,44 @@ static bool recycle_create_dir(vfs_handle_struct *handle, const char *dname)
        *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 {
+                       struct smb_filename *smb_fname = NULL;
+
                        DEBUG(5, ("recycle: creating new dir %s\n", new_dir));
-                       if (SMB_VFS_NEXT_MKDIR(handle, new_dir, mode) != 0) {
+
+                       smb_fname = synthetic_smb_fname(talloc_tos(),
+                                               new_dir,
+                                               NULL,
+                                               NULL,
+                                               0);
+                       if (smb_fname == NULL) {
+                               goto done;
+                       }
+
+                       if (SMB_VFS_NEXT_MKDIR(handle, smb_fname, mode) != 0) {
                                DEBUG(1,("recycle: mkdir failed for %s with error: %s\n", new_dir, strerror(errno)));
+                               TALLOC_FREE(smb_fname);
                                ret = False;
                                goto done;
                        }
+                       TALLOC_FREE(smb_fname);
+               }
+               if (strlcat(new_dir, "/", len+1) >= len+1) {
+                       goto done;
                }
-               safe_strcat(new_dir, "/", len);
                mode = recycle_subdir_mode(handle);
        }
 
@@ -411,13 +410,12 @@ static void recycle_do_touch(vfs_handle_struct *handle,
 {
        struct smb_filename *smb_fname_tmp = NULL;
        struct smb_file_time ft;
-       NTSTATUS status;
        int ret, err;
 
        ZERO_STRUCT(ft);
 
-       status = copy_smb_filename(talloc_tos(), smb_fname, &smb_fname_tmp);
-       if (!NT_STATUS_IS_OK(status)) {
+       smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
+       if (smb_fname_tmp == NULL) {
                return;
        }
 
@@ -457,18 +455,17 @@ static int recycle_unlink(vfs_handle_struct *handle,
        const char *base;
        char *repository = NULL;
        int i = 1;
-       SMB_OFF_T maxsize, minsize;
-       SMB_OFF_T file_size; /* space_avail;    */
+       off_t maxsize, minsize;
+       off_t file_size; /* space_avail;        */
        bool exist;
-       NTSTATUS status;
        int rc = -1;
 
-       repository = talloc_sub_advanced(NULL, lp_servicename(SNUM(conn)),
-                                       conn->session_info->unix_name,
+       repository = talloc_sub_advanced(NULL, lp_servicename(talloc_tos(), SNUM(conn)),
+                                       conn->session_info->unix_info->unix_name,
                                        conn->connectpath,
-                                       conn->session_info->utok.gid,
-                                       conn->session_info->sanitized_username,
-                                       conn->session_info->info3->base.domain.string,
+                                       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 */
@@ -593,10 +590,12 @@ static int recycle_unlink(vfs_handle_struct *handle,
        }
 
        /* Create smb_fname with final base name and orig stream name. */
-       status = create_synthetic_smb_fname(talloc_tos(), final_name,
-                                           smb_fname->stream_name, NULL,
-                                           &smb_fname_final);
-       if (!NT_STATUS_IS_OK(status)) {
+       smb_fname_final = synthetic_smb_fname(talloc_tos(),
+                                       final_name,
+                                       smb_fname->stream_name,
+                                       NULL,
+                                       smb_fname->flags);
+       if (smb_fname_final == NULL) {
                rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
                goto done;
        }
@@ -660,9 +659,7 @@ done:
 }
 
 static struct vfs_fn_pointers vfs_recycle_fns = {
-       .connect_fn = recycle_connect,
-       .disconnect = recycle_disconnect,
-       .unlink = recycle_unlink
+       .unlink_fn = recycle_unlink
 };
 
 NTSTATUS vfs_recycle_init(void);