auth/credentials: don't ignore "client use kerberos" and --use-kerberos for machine...
[samba.git] / source3 / smbd / fileio.c
index b03f86d49d67235a6e89539205f591a9fadce19e..ed62159a4955976616a9514614c3d96bf89ed0e4 100644 (file)
@@ -31,7 +31,9 @@
 
 ssize_t read_file(files_struct *fsp,char *data,off_t pos,size_t n)
 {
+       off_t new_pos;
        ssize_t ret = 0;
+       bool ok;
 
        /* you can't read from print files */
        if (fsp->print_file) {
@@ -39,7 +41,13 @@ ssize_t read_file(files_struct *fsp,char *data,off_t pos,size_t n)
                return -1;
        }
 
-       fsp->fh->pos = pos;
+       ok = vfs_valid_pread_range(pos, n);
+       if (!ok) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       fh_set_pos(fsp->fh, pos);
 
        if (n > 0) {
                ret = SMB_VFS_PREAD(fsp,data,n,pos);
@@ -52,8 +60,9 @@ ssize_t read_file(files_struct *fsp,char *data,off_t pos,size_t n)
        DEBUG(10,("read_file (%s): pos = %.0f, size = %lu, returned %lu\n",
                  fsp_str_dbg(fsp), (double)pos, (unsigned long)n, (long)ret));
 
-       fsp->fh->pos += ret;
-       fsp->fh->position_information = fsp->fh->pos;
+       new_pos = fh_get_pos(fsp->fh) + ret;
+       fh_set_pos(fsp->fh, new_pos);
+       fh_set_position_information(fsp->fh, new_pos);
 
        return(ret);
 }
@@ -69,10 +78,23 @@ static ssize_t real_write_file(struct smb_request *req,
                                size_t n)
 {
        ssize_t ret;
+       bool ok;
+
+       ok = vfs_valid_pwrite_range(pos, n);
+       if (!ok) {
+               errno = EINVAL;
+               return -1;
+       }
 
-       fsp->fh->pos = pos;
-       if (pos && lp_strict_allocate(SNUM(fsp->conn) &&
-                       !fsp->is_sparse)) {
+       if (n == 0) {
+               return 0;
+       }
+
+       fh_set_pos(fsp->fh, pos);
+       if (pos &&
+           lp_strict_allocate(SNUM(fsp->conn)) &&
+           !fsp->fsp_flags.is_sparse)
+       {
                if (vfs_fill_sparse(fsp, pos) == -1) {
                        return -1;
                }
@@ -83,7 +105,8 @@ static ssize_t real_write_file(struct smb_request *req,
                  fsp_str_dbg(fsp), (double)pos, (unsigned long)n, (long)ret));
 
        if (ret != -1) {
-               fsp->fh->pos += ret;
+               off_t new_pos = fh_get_pos(fsp->fh) + ret;
+               fh_set_pos(fsp->fh, new_pos);
 
 /* Yes - this is correct - writes don't update this. JRA. */
 /* Found by Samba4 tests. */
@@ -104,15 +127,7 @@ void fsp_flush_write_time_update(struct files_struct *fsp)
 
        DEBUG(5, ("Update write time on %s\n", fsp_str_dbg(fsp)));
 
-       /* change the write time in the open file db. */
-       (void)set_write_time(fsp->file_id, timespec_current());
-
-       /* And notify. */
-        notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
-                     FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name->base_name);
-
-       /* Remove the timed event handler. */
-       TALLOC_FREE(fsp->update_write_time_event);
+       trigger_write_time_update_immediate(fsp);
 }
 
 static void update_write_time_handler(struct tevent_context *ctx,
@@ -138,7 +153,7 @@ void trigger_write_time_update(struct files_struct *fsp)
                return;
        }
 
-       if (fsp->write_time_forced) {
+       if (fsp->fsp_flags.write_time_forced) {
                /* No point - "sticky" write times
                 * in effect.
                 */
@@ -148,9 +163,9 @@ void trigger_write_time_update(struct files_struct *fsp)
        /* We need to remember someone did a write
         * and update to current time on close. */
 
-       fsp->update_write_time_on_close = true;
+       fsp->fsp_flags.update_write_time_on_close = true;
 
-       if (fsp->update_write_time_triggered) {
+       if (fsp->fsp_flags.update_write_time_triggered) {
                /*
                 * We only update the write time after 2 seconds
                 * on the first normal write. After that
@@ -158,7 +173,7 @@ void trigger_write_time_update(struct files_struct *fsp)
                 */
                return;
        }
-       fsp->update_write_time_triggered = true;
+       fsp->fsp_flags.update_write_time_triggered = true;
 
        delay = lp_parm_int(SNUM(fsp->conn),
                            "smbd", "writetimeupdatedelay",
@@ -178,12 +193,14 @@ void trigger_write_time_update_immediate(struct files_struct *fsp)
 {
        struct smb_file_time ft;
 
+       init_smb_file_time(&ft);
+
        if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
                /* Don't use delayed writes on POSIX files. */
                return;
        }
 
-        if (fsp->write_time_forced) {
+        if (fsp->fsp_flags.write_time_forced) {
                /*
                 * No point - "sticky" write times
                 * in effect.
@@ -196,10 +213,10 @@ void trigger_write_time_update_immediate(struct files_struct *fsp)
                  fsp_str_dbg(fsp)));
 
        /* After an immediate update, reset the trigger. */
-       fsp->update_write_time_triggered = true;
-        fsp->update_write_time_on_close = false;
+       fsp->fsp_flags.update_write_time_triggered = true;
+        fsp->fsp_flags.update_write_time_on_close = false;
 
-       ft = (struct smb_file_time) { .mtime = timespec_current() };
+       ft.mtime = timespec_current();
 
        /* Update the time in the open file db. */
        (void)set_write_time(fsp->file_id, ft.mtime);
@@ -212,27 +229,21 @@ void mark_file_modified(files_struct *fsp)
 {
        int dosmode;
 
-       if (fsp->modified) {
-               return;
-       }
-
-       fsp->modified = true;
-
-       if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
-               return;
-       }
        trigger_write_time_update(fsp);
 
-       if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
+       if (fsp->fsp_flags.modified) {
                return;
        }
+
+       fsp->fsp_flags.modified = true;
+
        if (!(lp_store_dos_attributes(SNUM(fsp->conn)) ||
              MAP_ARCHIVE(fsp->conn))) {
                return;
        }
 
-       dosmode = dos_mode(fsp->conn, fsp->fsp_name);
-       if (IS_DOS_ARCHIVE(dosmode)) {
+       dosmode = fdos_mode(fsp);
+       if (dosmode & FILE_ATTRIBUTE_ARCHIVE) {
                return;
        }
        file_set_dosmode(fsp->conn, fsp->fsp_name,
@@ -263,7 +274,7 @@ ssize_t write_file(struct smb_request *req,
                return t;
        }
 
-       if (!fsp->can_write) {
+       if (!fsp->fsp_flags.can_write) {
                errno = EPERM;
                return -1;
        }
@@ -292,7 +303,7 @@ sync a file
 
 NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, bool write_through)
 {
-               if (fsp->fh->fd == -1)
+       if (fsp_get_io_fd(fsp) == -1)
                return NT_STATUS_INVALID_HANDLE;
 
        if (lp_strict_sync(SNUM(conn)) &&