2 Unix SMB/CIFS implementation.
6 Copyright (C) Andrew Tridgell 2004
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "vfs_posix.h"
25 /****************************************************************************
26 Change a unix mode to a dos mode.
27 ****************************************************************************/
28 static uint32_t dos_mode_from_stat(struct pvfs_state
*pvfs
, struct stat
*st
)
32 if ((st
->st_mode
& S_IWUSR
) == 0)
33 result
|= FILE_ATTRIBUTE_READONLY
;
35 if ((pvfs
->flags
& PVFS_FLAG_MAP_ARCHIVE
) && ((st
->st_mode
& S_IXUSR
) != 0))
36 result
|= FILE_ATTRIBUTE_ARCHIVE
;
38 if ((pvfs
->flags
& PVFS_FLAG_MAP_SYSTEM
) && ((st
->st_mode
& S_IXGRP
) != 0))
39 result
|= FILE_ATTRIBUTE_SYSTEM
;
41 if ((pvfs
->flags
& PVFS_FLAG_MAP_HIDDEN
) && ((st
->st_mode
& S_IXOTH
) != 0))
42 result
|= FILE_ATTRIBUTE_HIDDEN
;
44 if (S_ISDIR(st
->st_mode
))
45 result
= FILE_ATTRIBUTE_DIRECTORY
| (result
& FILE_ATTRIBUTE_READONLY
);
53 fill in the dos file attributes for a file
55 NTSTATUS
pvfs_fill_dos_info(struct pvfs_state
*pvfs
, struct pvfs_filename
*name
,
56 unsigned int flags
, int fd
)
62 /* make directories appear as size 0 with 1 link */
63 if (S_ISDIR(name
->st
.st_mode
)) {
65 name
->st
.st_nlink
= 1;
66 } else if (name
->stream_id
== 0) {
67 name
->stream_name
= NULL
;
70 /* for now just use the simple samba mapping */
71 unix_to_nt_time(&name
->dos
.create_time
, name
->st
.st_ctime
);
72 unix_to_nt_time(&name
->dos
.access_time
, name
->st
.st_atime
);
73 unix_to_nt_time(&name
->dos
.write_time
, name
->st
.st_mtime
);
74 unix_to_nt_time(&name
->dos
.change_time
, name
->st
.st_ctime
);
75 #ifdef HAVE_STAT_TV_NSEC
76 name
->dos
.create_time
+= name
->st
.st_ctim
.tv_nsec
/ 100;
77 name
->dos
.access_time
+= name
->st
.st_atim
.tv_nsec
/ 100;
78 name
->dos
.write_time
+= name
->st
.st_mtim
.tv_nsec
/ 100;
79 name
->dos
.change_time
+= name
->st
.st_ctim
.tv_nsec
/ 100;
81 name
->dos
.attrib
= dos_mode_from_stat(pvfs
, &name
->st
);
82 name
->dos
.alloc_size
= pvfs_round_alloc_size(pvfs
, name
->st
.st_size
);
83 name
->dos
.nlink
= name
->st
.st_nlink
;
84 name
->dos
.ea_size
= 4; /* TODO: Fill this in without hitting the stream bad in pvfs_doseas_load() */
85 if (pvfs
->ntvfs
->ctx
->protocol
>= PROTOCOL_SMB2_02
) {
86 /* SMB2 represents a null EA with zero bytes */
87 name
->dos
.ea_size
= 0;
90 name
->dos
.file_id
= (((uint64_t)name
->st
.st_dev
)<<32) | name
->st
.st_ino
;
93 status
= pvfs_dosattrib_load(pvfs
, name
, fd
);
94 NT_STATUS_NOT_OK_RETURN(status
);
96 if (flags
& PVFS_RESOLVE_NO_OPENDB
) {
100 status
= pvfs_locking_key(name
, name
, &lkey
);
101 NT_STATUS_NOT_OK_RETURN(status
);
103 status
= odb_get_file_infos(pvfs
->odb_context
, &lkey
,
105 data_blob_free(&lkey
);
106 if (!NT_STATUS_IS_OK(status
)) {
107 DEBUG(1,("WARNING: odb_get_file_infos: %s\n", nt_errstr(status
)));
111 if (!null_time(write_time
)) {
112 name
->dos
.write_time
= write_time
;
120 return a set of unix file permissions for a new file or directory
122 mode_t
pvfs_fileperms(struct pvfs_state
*pvfs
, uint32_t attrib
)
124 mode_t mode
= (S_IRUSR
| S_IRGRP
| S_IROTH
| S_IWUSR
| S_IWGRP
| S_IWOTH
);
126 if (!(pvfs
->flags
& PVFS_FLAG_XATTR_ENABLE
) &&
127 (attrib
& FILE_ATTRIBUTE_READONLY
)) {
128 mode
&= ~(S_IWUSR
| S_IWGRP
| S_IWOTH
);
131 if (!(pvfs
->flags
& PVFS_FLAG_XATTR_ENABLE
)) {
132 if ((attrib
& FILE_ATTRIBUTE_ARCHIVE
) &&
133 (pvfs
->flags
& PVFS_FLAG_MAP_ARCHIVE
)) {
136 if ((attrib
& FILE_ATTRIBUTE_SYSTEM
) &&
137 (pvfs
->flags
& PVFS_FLAG_MAP_SYSTEM
)) {
140 if ((attrib
& FILE_ATTRIBUTE_HIDDEN
) &&
141 (pvfs
->flags
& PVFS_FLAG_MAP_HIDDEN
)) {
146 if (attrib
& FILE_ATTRIBUTE_DIRECTORY
) {
147 mode
|= (S_IFDIR
| S_IWUSR
);
148 mode
|= (S_IXUSR
| S_IXGRP
| S_IXOTH
);
149 mode
&= pvfs
->options
.dir_mask
;
150 mode
|= pvfs
->options
.force_dir_mode
;
152 mode
&= pvfs
->options
.create_mask
;
153 mode
|= pvfs
->options
.force_create_mode
;