check_name() not needed in mkdir.
[mat/samba.git] / source3 / smbd / open.c
index 461206893be6a8601a019ad875605e2c41948b2e..fd99994ca79873d4bc2f552baca2bbf9a3047740 100644 (file)
@@ -99,6 +99,16 @@ NTSTATUS smbd_check_access_rights(struct connection_struct *conn,
                return NT_STATUS_OK;
        }
 
+       if (access_mask == DELETE_ACCESS &&
+                       VALID_STAT(smb_fname->st) &&
+                       S_ISLNK(smb_fname->st.st_ex_mode)) {
+               /* We can always delete a symlink. */
+               DEBUG(10,("smbd_check_access_rights: not checking ACL "
+                       "on DELETE_ACCESS on symlink %s.\n",
+                       smb_fname_str_dbg(smb_fname) ));
+               return NT_STATUS_OK;
+       }
+
        status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
                        (SECINFO_OWNER |
                        SECINFO_GROUP |
@@ -1076,7 +1086,7 @@ static NTSTATUS send_break_message(files_struct *fsp,
 
 static void find_oplock_types(files_struct *fsp,
                                int oplock_request,
-                               struct share_mode_lock *lck,
+                               const struct share_mode_lock *lck,
                                struct share_mode_entry **pp_batch,
                                struct share_mode_entry **pp_ex_or_batch,
                                bool *got_level2,
@@ -1150,13 +1160,13 @@ static bool delay_for_batch_oplocks(files_struct *fsp,
        if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
                return false;
        }
-
-       if (batch_entry != NULL) {
-               /* Found a batch oplock */
-               send_break_message(fsp, batch_entry, mid, oplock_request);
-               return true;
+       if (batch_entry == NULL) {
+               return false;
        }
-       return false;
+
+       /* Found a batch oplock */
+       send_break_message(fsp, batch_entry, mid, oplock_request);
+       return true;
 }
 
 static bool delay_for_exclusive_oplocks(files_struct *fsp,
@@ -1164,20 +1174,26 @@ static bool delay_for_exclusive_oplocks(files_struct *fsp,
                                        int oplock_request,
                                        struct share_mode_entry *ex_entry)
 {
+       bool delay_it;
+
        if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
                return false;
        }
+       if (ex_entry == NULL) {
+               return false;
+       }
 
-       if (ex_entry != NULL) {
-               /* Found an exclusive or batch oplock */
-               bool delay_it = is_delete_request(fsp) ?
-                               BATCH_OPLOCK_TYPE(ex_entry->op_type) : true;
-               if (delay_it) {
-                       send_break_message(fsp, ex_entry, mid, oplock_request);
-                       return true;
-               }
+       /* Found an exclusive or batch oplock */
+
+       delay_it = is_delete_request(fsp) ?
+               BATCH_OPLOCK_TYPE(ex_entry->op_type) : true;
+
+       if (!delay_it) {
+               return false;
        }
-       return false;
+
+       send_break_message(fsp, ex_entry, mid, oplock_request);
+       return true;
 }
 
 static void grant_fsp_oplock_type(files_struct *fsp,
@@ -1275,11 +1291,9 @@ static void defer_open(struct share_mode_lock *lck,
        for (i=0; i<lck->num_share_modes; i++) {
                struct share_mode_entry *e = &lck->share_modes[i];
 
-               if (!is_deferred_open_entry(e)) {
-                       continue;
-               }
-
-               if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
+               if (is_deferred_open_entry(e) &&
+                   procid_is_me(&e->pid) &&
+                   (e->op_mid == req->mid)) {
                        DEBUG(0, ("Trying to defer an already deferred "
                                "request: mid=%llu, exiting\n",
                                (unsigned long long)req->mid));
@@ -1300,7 +1314,7 @@ static void defer_open(struct share_mode_lock *lck,
                exit_server("push_deferred_open_message_smb failed");
        }
        add_deferred_open(lck, req->mid, request_time,
-                         sconn_server_id(req->sconn), state->id);
+                         messaging_server_id(req->sconn->msg_ctx), state->id);
 }
 
 
@@ -1627,7 +1641,6 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
        bool posix_open = False;
        bool new_file_created = False;
        bool clear_ads = false;
-       struct file_id id;
        NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
        mode_t new_unx_mode = (mode_t)0;
        mode_t unx_mode = (mode_t)0;
@@ -1639,8 +1652,6 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
        NTSTATUS status;
        char *parent_dir;
 
-       ZERO_STRUCT(id);
-
        if (conn->printer) {
                /*
                 * Printers are handled completely differently.
@@ -1718,18 +1729,13 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
                        /* Remove the deferred open entry under lock. */
                        remove_deferred_open_entry(
                                state->id, req->mid,
-                               sconn_server_id(req->sconn));
+                               messaging_server_id(req->sconn->msg_ctx));
 
                        /* Ensure we don't reprocess this message. */
                        remove_deferred_open_message_smb(req->sconn, req->mid);
                }
        }
 
-       status = check_name(conn, smb_fname->base_name);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
        if (!posix_open) {
                new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
                if (file_existed) {
@@ -1951,6 +1957,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
                struct share_mode_entry *exclusive_entry = NULL;
                bool got_level2_oplock = false;
                bool got_a_none_oplock = false;
+               struct file_id id;
 
                struct timespec old_write_time = smb_fname->st.st_ex_mtime;
                id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
@@ -2184,6 +2191,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
                bool got_level2_oplock = false;
                bool got_a_none_oplock = false;
                struct timespec old_write_time = smb_fname->st.st_ex_mtime;
+               struct file_id id;
                /*
                 * Deal with the race condition where two smbd's detect the
                 * file doesn't exist and do the create at the same time. One
@@ -2369,10 +2377,10 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
                        fsp->oplock_type = NO_OPLOCK;
                }
 
-               if (!(flags2 & O_TRUNC)) {
-                       info = FILE_WAS_OPENED;
-               } else {
+               if (flags2 & O_TRUNC) {
                        info = FILE_WAS_OVERWRITTEN;
+               } else {
+                       info = FILE_WAS_OPENED;
                }
        } else {
                info = FILE_WAS_CREATED;
@@ -2395,10 +2403,6 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
                fsp->oplock_type = NO_OPLOCK;
        }
 
-       if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED || info == FILE_WAS_SUPERSEDED) {
-               new_file_created = True;
-       }
-
        set_share_mode(lck, fsp, get_current_uid(conn),
                        req ? req->mid : 0,
                       fsp->oplock_type);
@@ -2420,6 +2424,12 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
                fsp->initial_delete_on_close = True;
        }
 
+       if (info == FILE_WAS_OVERWRITTEN
+           || info == FILE_WAS_CREATED
+           || info == FILE_WAS_SUPERSEDED) {
+               new_file_created = True;
+       }
+
        if (new_file_created) {
                /* Files should be initially set as archive */
                if (lp_map_archive(SNUM(conn)) ||
@@ -2492,7 +2502,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
         * records. */
        if (req != NULL) {
                del_deferred_open_entry(lck, req->mid,
-                                       sconn_server_id(req->sconn));
+                                       messaging_server_id(req->sconn->msg_ctx));
        }
        TALLOC_FREE(lck);
 
@@ -2549,11 +2559,6 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       status = check_name(conn, smb_dname->base_name);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
        if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
                            NULL)) {
                return NT_STATUS_NO_MEMORY;
@@ -3848,13 +3853,6 @@ NTSTATUS create_file_default(connection_struct *conn,
                }
        }
 
-       /* All file access must go through check_name() */
-
-       status = check_name(conn, smb_fname->base_name);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto fail;
-       }
-
        if (stream_name && is_ntfs_default_stream_smb_fname(smb_fname)) {
                int ret;
                smb_fname->stream_name = NULL;