auth/credentials: don't ignore "client use kerberos" and --use-kerberos for machine...
[samba.git] / source3 / smbd / dosmode.c
index 5b695a1d6e303aeed91943c01c63bb4515d53362..fac226459cef2acc1b775af99600f7aae1e0a3d0 100644 (file)
@@ -69,9 +69,10 @@ static void dos_mode_debug_print(const char *func, uint32_t mode)
                 modestr);
 }
 
-static uint32_t filter_mode_by_protocol(uint32_t mode)
+static uint32_t filter_mode_by_protocol(enum protocol_types protocol,
+                                       uint32_t mode)
 {
-       if (get_Protocol() <= PROTOCOL_LANMAN2) {
+       if (protocol <= PROTOCOL_LANMAN2) {
                DEBUG(10,("filter_mode_by_protocol: "
                        "filtering result 0x%x to 0x%x\n",
                        (unsigned int)mode,
@@ -354,8 +355,16 @@ NTSTATUS parse_dos_attribute_blob(struct smb_filename *smb_fname,
                dosattr |= FILE_ATTRIBUTE_DIRECTORY;
        }
 
-       /* FILE_ATTRIBUTE_SPARSE is valid on get but not on set. */
-       *pattr |= (uint32_t)(dosattr & (SAMBA_ATTRIBUTES_MASK|FILE_ATTRIBUTE_SPARSE));
+       /*
+        * _SPARSE and _REPARSE_POINT are valid on get but not on
+        * set. Both are created via special fcntls.
+        */
+
+       dosattr &= (SAMBA_ATTRIBUTES_MASK|
+                   FILE_ATTRIBUTE_SPARSE|
+                   FILE_ATTRIBUTE_REPARSE_POINT);
+
+       *pattr |= dosattr;
 
        dos_mode_debug_print(__func__, *pattr);
 
@@ -588,7 +597,7 @@ uint32_t dos_mode_msdfs(connection_struct *conn,
                result = FILE_ATTRIBUTE_NORMAL;
        }
 
-       result = filter_mode_by_protocol(result);
+       result = filter_mode_by_protocol(conn_protocol(conn->sconn), result);
 
        /*
         * Add in that it is a reparse point
@@ -669,7 +678,8 @@ static uint32_t dos_mode_post(uint32_t dosmode,
                dosmode = FILE_ATTRIBUTE_NORMAL;
        }
 
-       dosmode = filter_mode_by_protocol(dosmode);
+       dosmode = filter_mode_by_protocol(conn_protocol(fsp->conn->sconn),
+                                         dosmode);
 
        dos_mode_debug_print(func, dosmode);
        return dosmode;
@@ -686,16 +696,6 @@ uint32_t fdos_mode(struct files_struct *fsp)
        uint32_t result = 0;
        NTSTATUS status = NT_STATUS_OK;
 
-       if (fsp == NULL) {
-               /*
-                * The pathological case where a caller does
-                * fdos_mode(smb_fname->fsp) passing a pathref fsp. But as
-                * smb_fname points at a symlink in POSIX context smb_fname->fsp
-                * is NULL.
-                */
-               return FILE_ATTRIBUTE_NORMAL;
-       }
-
        DBG_DEBUG("%s\n", fsp_str_dbg(fsp));
 
        if (fsp->fake_file_handle != NULL) {
@@ -715,7 +715,9 @@ uint32_t fdos_mode(struct files_struct *fsp)
        }
 
        /* Get the DOS attributes via the VFS if we can */
-       status = vfs_fget_dos_attributes(fsp, &result);
+       status = SMB_VFS_FGET_DOS_ATTRIBUTES(fsp->conn,
+                                            metadata_fsp(fsp),
+                                            &result);
        if (!NT_STATUS_IS_OK(status)) {
                /*
                 * Only fall back to using UNIX modes if we get NOT_IMPLEMENTED.
@@ -925,7 +927,7 @@ int file_set_dosmode(connection_struct *conn,
                return -1;
        }
 
-       if (smb_fname->fsp->posix_flags & FSP_POSIX_FLAGS_OPEN &&
+       if ((smb_fname->fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) &&
            !lp_store_dos_attributes(SNUM(conn)))
        {
                return 0;
@@ -1084,15 +1086,17 @@ NTSTATUS file_set_sparse(connection_struct *conn,
         * Windows Server 2008 & 2012 permit FSCTL_SET_SPARSE if any of the
         * following access flags are granted.
         */
-       if ((fsp->access_mask & (FILE_WRITE_DATA
-                               | FILE_WRITE_ATTRIBUTES
-                               | SEC_FILE_APPEND_DATA)) == 0) {
-               DEBUG(9,("file_set_sparse: fname[%s] set[%u] "
-                       "access_mask[0x%08X] - access denied\n",
-                       smb_fname_str_dbg(fsp->fsp_name),
-                       sparse,
-                       fsp->access_mask));
-               return NT_STATUS_ACCESS_DENIED;
+       status = check_any_access_fsp(fsp,
+                                 FILE_WRITE_DATA
+                                 | FILE_WRITE_ATTRIBUTES
+                                 | SEC_FILE_APPEND_DATA);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_DEBUG("fname[%s] set[%u] "
+                         "access_mask[0x%08X] - access denied\n",
+                         smb_fname_str_dbg(fsp->fsp_name),
+                         sparse,
+                         fsp->access_mask);
+               return status;
        }
 
        if (fsp->fsp_flags.is_directory) {
@@ -1193,7 +1197,8 @@ int file_ntimes(connection_struct *conn,
        }
 
        if (SMB_VFS_FNTIMES(fsp, ft) == 0) {
-               return 0;
+               ret = 0;
+               goto done;
        }
 
        if((errno != EPERM) && (errno != EACCES)) {
@@ -1218,6 +1223,11 @@ int file_ntimes(connection_struct *conn,
                unbecome_root();
        }
 
+done:
+       if (ret == 0) {
+               copy_stat_ex_timestamps(fsp, ft);
+       }
+
        return ret;
 }