r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation
[samba.git] / source3 / smbd / open.c
index b08ca0f58b9125b45f0018b9f07ba9d12ae589d2..bf3fbf7fecd556afbed62caaf134432421731a8b 100644 (file)
@@ -592,7 +592,7 @@ static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T
        int i;
        int num_share_modes;
        int oplock_contention_count = 0;
-       share_mode_entry *old_shares = 0;
+       share_mode_entry *old_shares = NULL;
        BOOL fcbopen = False;
        BOOL broke_oplock;
 
@@ -601,12 +601,15 @@ static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T
        
        num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
        
-       if(num_share_modes == 0)
+       if(num_share_modes == 0) {
+               SAFE_FREE(old_shares);
                return 0;
+       }
        
        if (desired_access && ((desired_access & ~(SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES))==0) &&
                ((desired_access & (SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES)) != 0)) {
                /* Stat open that doesn't trigger oplock breaks or share mode checks... ! JRA. */
+               SAFE_FREE(old_shares);
                return num_share_modes;
        }
 
@@ -678,7 +681,7 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
                                        return -1;
                                }
                                
-                               broken_entry = malloc(sizeof(struct share_mode_entry_list));
+                               broken_entry = SMB_MALLOC_P(struct share_mode_entry_list);
                                if (!broken_entry) {
                                        smb_panic("open_mode_check: malloc fail.\n");
                                }
@@ -758,9 +761,6 @@ after break ! For file %s, dev = %x, inode = %.0f. Deleting it to continue...\n"
                free_broken_entry_list(broken_entry_list);
        } while(broke_oplock);
        
-       if(old_shares != 0)
-               SAFE_FREE(old_shares);
-       
        /*
         * Refuse to grant an oplock in case the contention limit is
         * reached when going through the lock list multiple times.
@@ -772,6 +772,7 @@ after break ! For file %s, dev = %x, inode = %.0f. Deleting it to continue...\n"
                         oplock_contention_count ));
        }
        
+       SAFE_FREE(old_shares);
        return num_share_modes;
 }
 
@@ -978,7 +979,7 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
        struct pending_message_list *pml = NULL;
        uint16 mid = get_current_mid();
        /* We add aARCH to this as this mode is only used if the file is created new. */
-       mode_t mode = unix_mode(conn,new_dos_mode | aARCH,fname);
+       mode_t mode = unix_mode(conn,new_dos_mode | aARCH,fname, True);
 
        if (oplock_request == INTERNAL_OPEN_ONLY) {
                internal_only_open = True;
@@ -1375,6 +1376,8 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
                (*Access) = open_mode;
        }
 
+       action = 0;
+
        if (file_existed && !(flags2 & O_TRUNC))
                action = FILE_WAS_OPENED;
        if (file_existed && (flags2 & O_TRUNC))
@@ -1408,9 +1411,17 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
        }
 
        if (delete_on_close) {
-               NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
+               uint32 dosmode = existing_dos_mode;
+               NTSTATUS result;
+
+               if (action == FILE_WAS_OVERWRITTEN || action == FILE_WAS_CREATED) {
+                       dosmode = new_dos_mode;
+               }
+               result = set_delete_on_close_internal(fsp, delete_on_close, dosmode);
 
                if (NT_STATUS_V(result) !=  NT_STATUS_V(NT_STATUS_OK)) {
+                       uint8 u_e_c;
+                       uint32 u_e_code;
                        /* Remember to delete the mode we just added. */
                        if (add_share_mode) {
                                del_share_mode(fsp, NULL);
@@ -1418,6 +1429,10 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
                        unlock_share_entry_fsp(fsp);
                        fd_close(conn,fsp);
                        file_free(fsp);
+                       ntstatus_to_dos(result, &u_e_c, &u_e_code);
+                        unix_ERR_ntstatus = result;
+                        unix_ERR_class = u_e_c;
+                        unix_ERR_code = u_e_code;
                        return NULL;
                }
        }
@@ -1425,7 +1440,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
        if (action == FILE_WAS_OVERWRITTEN || action == FILE_WAS_CREATED) {
                /* Files should be initially set as archive */
                if (lp_map_archive(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
-                       file_set_dosmode(conn, fname, new_dos_mode | aARCH, NULL);
+                       file_set_dosmode(conn, fname, new_dos_mode | aARCH, NULL, True);
                }
        }
 
@@ -1586,7 +1601,7 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
                                return NULL;
                        }
 
-                       if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname)) < 0) {
+                       if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname, True)) < 0) {
                                DEBUG(2,("open_directory: unable to create %s. Error was %s\n",
                                         fname, strerror(errno) ));
                                file_free(fsp);
@@ -1650,7 +1665,7 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
        string_set(&fsp->fsp_name,fname);
 
        if (delete_on_close) {
-               NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
+               NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close, 0);
 
                if (NT_STATUS_V(result) !=  NT_STATUS_V(NT_STATUS_OK)) {
                        file_free(fsp);