files_struct *fsp,
const SMB_STRUCT_STAT *psbuf);
+NTSTATUS check_access_fsp(const struct files_struct *fsp,
+ uint32_t access_mask)
+{
+ if (!(fsp->access_mask & access_mask)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ return NT_STATUS_OK;
+}
+
/********************************************************************
The canonical "check access" based on object handle or path function.
********************************************************************/
const struct smb_filename *smb_fname,
uint32_t access_mask)
{
+ NTSTATUS status;
+
if (fsp) {
- if (!(fsp->access_mask & access_mask)) {
- return NT_STATUS_ACCESS_DENIED;
- }
+ status = check_access_fsp(fsp, access_mask);
} else {
- NTSTATUS status = smbd_check_access_rights(conn,
- smb_fname,
- false,
- access_mask);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ status = smbd_check_access_rights(conn, smb_fname,
+ false, access_mask);
}
- return NT_STATUS_OK;
+
+ return status;
}
/********************************************************************
"= %u\n", (unsigned int)*pea_total_len, dos_ea_name,
(unsigned int)listp->ea.value.length));
- DLIST_ADD_END(ea_list_head, listp, struct ea_list *);
+ DLIST_ADD_END(ea_list_head, listp);
}
}
offset += (namelen + 1); /* Go past the name + terminating zero. */
- DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
+ DLIST_ADD_END(ea_list_head, eal);
DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
}
return NULL;
}
- DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
+ DLIST_ADD_END(ea_list_head, eal);
offset += bytes_used;
}
uint32_t create_disposition;
uint32_t create_options = 0;
uint32_t private_flags = 0;
+ uint32_t ucf_flags = (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
TALLOC_CTX *ctx = talloc_tos();
/*
goto out;
}
- srvstr_get_path(ctx, params, req->flags2, &fname, pname,
- total_params - 28, STR_TERMINATE,
+ if (req->posix_pathnames) {
+ srvstr_get_path_posix(ctx,
+ params,
+ req->flags2,
+ &fname,
+ pname,
+ total_params - 28,
+ STR_TERMINATE,
+ &status);
+ } else {
+ srvstr_get_path(ctx,
+ params,
+ req->flags2,
+ &fname,
+ pname,
+ total_params - 28,
+ STR_TERMINATE,
&status);
+ }
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
goto out;
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- 0,
+ ucf_flags,
NULL,
&smb_fname);
if (!NT_STATUS_IS_OK(status)) {
struct ea_list *ea_list = NULL;
NTSTATUS ntstatus = NT_STATUS_OK;
bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
- TALLOC_CTX *ctx = talloc_tos();
struct dptr_struct *dirptr = NULL;
struct smbd_server_connection *sconn = req->sconn;
- uint32_t ucf_flags = (UCF_SAVE_LCOMP | UCF_ALWAYS_ALLOW_WCARD_LCOMP);
+ uint32_t ucf_flags = UCF_SAVE_LCOMP | UCF_ALWAYS_ALLOW_WCARD_LCOMP |
+ (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
bool backup_priv = false;
bool as_root = false;
goto out;
}
- srvstr_get_path_wcard(ctx, params, req->flags2, &directory,
- params+12, total_params - 12,
- STR_TERMINATE, &ntstatus, &mask_contains_wcard);
+ if (req->posix_pathnames) {
+ srvstr_get_path_wcard_posix(talloc_tos(),
+ params,
+ req->flags2,
+ &directory,
+ params+12,
+ total_params - 12,
+ STR_TERMINATE,
+ &ntstatus,
+ &mask_contains_wcard);
+ } else {
+ srvstr_get_path_wcard(talloc_tos(),
+ params,
+ req->flags2,
+ &directory,
+ params+12,
+ total_params - 12,
+ STR_TERMINATE,
+ &ntstatus,
+ &mask_contains_wcard);
+ }
if (!NT_STATUS_IS_OK(ntstatus)) {
reply_nterror(req, ntstatus);
goto out;
if (backup_priv) {
become_root();
as_root = true;
- ntstatus = filename_convert_with_privilege(ctx,
+ ntstatus = filename_convert_with_privilege(talloc_tos(),
conn,
req,
directory,
&mask_contains_wcard,
&smb_dname);
} else {
- ntstatus = filename_convert(ctx, conn,
+ ntstatus = filename_convert(talloc_tos(), conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
directory,
ucf_flags,
if(p == NULL) {
/* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
if((directory[0] == '.') && (directory[1] == '\0')) {
- mask = talloc_strdup(ctx,"*");
+ mask = talloc_strdup(talloc_tos(),"*");
if (!mask) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
goto out;
reply_nterror(req, NT_STATUS_NO_MEMORY);
goto out;
}
+ /* Ensure smb_dname->base_name matches. */
+ smb_dname->base_name = directory;
}
DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
}
/* Pull out the list of names. */
- ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
+ ea_list = read_ea_name_list(talloc_tos(), pdata + 4, ea_size - 4);
if (!ea_list) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
goto out;
ntstatus = dptr_create(conn,
req,
NULL, /* fsp */
- directory,
+ smb_dname,
False,
True,
req->smbpid,
a different TRANS2 call. */
DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
- directory,lp_dont_descend(ctx, SNUM(conn))));
- if (in_list(directory,lp_dont_descend(ctx, SNUM(conn)),conn->case_sensitive))
+ directory,lp_dont_descend(talloc_tos(), SNUM(conn))));
+ if (in_list(directory,
+ lp_dont_descend(talloc_tos(), SNUM(conn)),
+ conn->case_sensitive)) {
dont_descend = True;
+ }
p = pdata;
space_remaining = max_data_bytes;
out_of_space = True;
finished = False;
} else {
- ntstatus = get_lanman2_dir_entry(ctx,
+ ntstatus = get_lanman2_dir_entry(talloc_tos(),
conn,
dirptr,
req->flags2,
if (!continue_bit) {
/* We only need resume_name if continue_bit is zero. */
- srvstr_get_path_wcard(ctx, params, req->flags2, &resume_name,
- params+12,
- total_params - 12, STR_TERMINATE, &ntstatus,
- &mask_contains_wcard);
+ if (req->posix_pathnames) {
+ srvstr_get_path_wcard_posix(ctx,
+ params,
+ req->flags2,
+ &resume_name,
+ params+12,
+ total_params - 12,
+ STR_TERMINATE,
+ &ntstatus,
+ &mask_contains_wcard);
+ } else {
+ srvstr_get_path_wcard(ctx,
+ params,
+ req->flags2,
+ &resume_name,
+ params+12,
+ total_params - 12,
+ STR_TERMINATE,
+ &ntstatus,
+ &mask_contains_wcard);
+ }
if (!NT_STATUS_IS_OK(ntstatus)) {
/* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
complain (it thinks we're asking for the directory above the shared
return NT_STATUS_INVALID_PARAMETER;
}
- status = vfs_streaminfo(conn, fsp, smb_fname->base_name,
- talloc_tos(), &num_streams, &streams);
+ status = vfs_streaminfo(conn,
+ fsp,
+ smb_fname,
+ talloc_tos(),
+ &num_streams,
+ &streams);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("could not get stream info: %s\n",
} else {
uint32_t name_hash;
char *fname = NULL;
- uint32_t ucf_flags = 0;
+ uint32_t ucf_flags = (req->posix_pathnames ?
+ UCF_POSIX_PATHNAMES : 0);
/* qpathinfo */
if (total_params < 7) {
}
}
- srvstr_get_path(req, params, req->flags2, &fname, ¶ms[6],
+ if (req->posix_pathnames) {
+ srvstr_get_path_posix(req,
+ params,
+ req->flags2,
+ &fname,
+ ¶ms[6],
+ total_params - 6,
+ STR_TERMINATE,
+ &status);
+ } else {
+ srvstr_get_path(req,
+ params,
+ req->flags2,
+ &fname,
+ ¶ms[6],
total_params - 6,
- STR_TERMINATE, &status);
+ STR_TERMINATE,
+ &status);
+ }
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
return;
{
char *oldname = NULL;
struct smb_filename *smb_fname_old = NULL;
+ uint32_t ucf_flags = (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
TALLOC_CTX *ctx = talloc_tos();
NTSTATUS status = NT_STATUS_OK;
return NT_STATUS_INVALID_PARAMETER;
}
- srvstr_get_path(ctx, pdata, req->flags2, &oldname, pdata,
- total_data, STR_TERMINATE, &status);
+ if (req->posix_pathnames) {
+ srvstr_get_path_posix(ctx,
+ pdata,
+ req->flags2,
+ &oldname,
+ pdata,
+ total_data,
+ STR_TERMINATE,
+ &status);
+ } else {
+ srvstr_get_path(ctx,
+ pdata,
+ req->flags2,
+ &oldname,
+ pdata,
+ total_data,
+ STR_TERMINATE,
+ &status);
+ }
if (!NT_STATUS_IS_OK(status)) {
return status;
}
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
oldname,
- 0,
+ ucf_flags,
NULL,
&smb_fname_old);
if (!NT_STATUS_IS_OK(status)) {
uint32_t len;
char *newname = NULL;
struct smb_filename *smb_fname_dst = NULL;
+ uint32_t ucf_flags = UCF_SAVE_LCOMP |
+ (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
NTSTATUS status = NT_STATUS_OK;
TALLOC_CTX *ctx = talloc_tos();
return NT_STATUS_INVALID_PARAMETER;
}
- srvstr_get_path(ctx, pdata, req->flags2, &newname,
- &pdata[20], len, STR_TERMINATE,
+ if (req->posix_pathnames) {
+ srvstr_get_path_posix(ctx,
+ pdata,
+ req->flags2,
+ &newname,
+ &pdata[20],
+ len,
+ STR_TERMINATE,
+ &status);
+ } else {
+ srvstr_get_path(ctx,
+ pdata,
+ req->flags2,
+ &newname,
+ &pdata[20],
+ len,
+ STR_TERMINATE,
&status);
+ }
if (!NT_STATUS_IS_OK(status)) {
return status;
}
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
newname,
- UCF_SAVE_LCOMP,
+ ucf_flags,
NULL,
&smb_fname_dst);
if (!NT_STATUS_IS_OK(status)) {
char *newname = NULL;
struct smb_filename *smb_fname_dst = NULL;
NTSTATUS status = NT_STATUS_OK;
+ uint32_t ucf_flags = UCF_SAVE_LCOMP |
+ (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
TALLOC_CTX *ctx = talloc_tos();
if (!fsp) {
return NT_STATUS_INVALID_PARAMETER;
}
- srvstr_get_path(ctx, pdata, req->flags2, &newname,
- &pdata[20], len, STR_TERMINATE,
+ if (req->posix_pathnames) {
+ srvstr_get_path_posix(ctx,
+ pdata,
+ req->flags2,
+ &newname,
+ &pdata[20],
+ len,
+ STR_TERMINATE,
+ &status);
+ } else {
+ srvstr_get_path(ctx,
+ pdata,
+ req->flags2,
+ &newname,
+ &pdata[20],
+ len,
+ STR_TERMINATE,
&status);
+ }
if (!NT_STATUS_IS_OK(status)) {
return status;
}
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
newname,
- UCF_SAVE_LCOMP,
+ ucf_flags,
NULL,
&smb_fname_dst);
if (!NT_STATUS_IS_OK(status)) {
return NT_STATUS_INVALID_PARAMETER;
}
- srvstr_get_path_wcard(ctx, pdata, req->flags2, &newname, &pdata[12],
- len, 0, &status,
- &dest_has_wcard);
+ if (req->posix_pathnames) {
+ srvstr_get_path_wcard_posix(ctx,
+ pdata,
+ req->flags2,
+ &newname,
+ &pdata[12],
+ len,
+ 0,
+ &status,
+ &dest_has_wcard);
+ } else {
+ srvstr_get_path_wcard(ctx,
+ pdata,
+ req->flags2,
+ &newname,
+ &pdata[12],
+ len,
+ 0,
+ &status,
+ &dest_has_wcard);
+ }
if (!NT_STATUS_IS_OK(status)) {
return status;
}
if (fsp && fsp->fh->fd != -1) {
ret = SMB_VFS_FCHMOD(fsp, unixmode);
} else {
- ret = SMB_VFS_CHMOD(conn, smb_fname->base_name, unixmode);
+ ret = SMB_VFS_CHMOD(conn, smb_fname, unixmode);
}
if (ret != 0) {
return map_nt_error_from_unix(errno);
* UNIX extensions calls must always operate
* on symlinks.
*/
- ret = SMB_VFS_LCHOWN(conn, smb_fname->base_name,
+ ret = SMB_VFS_LCHOWN(conn, smb_fname,
set_owner, (gid_t)-1);
}
* UNIX extensions calls must always operate
* on symlinks.
*/
- ret = SMB_VFS_LCHOWN(conn, smb_fname->base_name, (uid_t)-1,
+ ret = SMB_VFS_LCHOWN(conn, smb_fname, (uid_t)-1,
set_grp);
}
if (ret != 0) {
}
} else {
char *fname = NULL;
- uint32_t ucf_flags = 0;
+ uint32_t ucf_flags = (req->posix_pathnames ?
+ UCF_POSIX_PATHNAMES : 0);
/* set path info */
if (total_params < 7) {
}
info_level = SVAL(params,0);
- srvstr_get_path(req, params, req->flags2, &fname, ¶ms[6],
- total_params - 6, STR_TERMINATE,
+ if (req->posix_pathnames) {
+ srvstr_get_path_posix(req,
+ params,
+ req->flags2,
+ &fname,
+ ¶ms[6],
+ total_params - 6,
+ STR_TERMINATE,
&status);
+ } else {
+ srvstr_get_path(req,
+ params,
+ req->flags2,
+ &fname,
+ ¶ms[6],
+ total_params - 6,
+ STR_TERMINATE,
+ &status);
+ }
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
return;
char *directory = NULL;
NTSTATUS status = NT_STATUS_OK;
struct ea_list *ea_list = NULL;
+ uint32_t ucf_flags = (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
TALLOC_CTX *ctx = talloc_tos();
if (!CAN_WRITE(conn)) {
return;
}
- srvstr_get_path(ctx, params, req->flags2, &directory, ¶ms[4],
- total_params - 4, STR_TERMINATE,
+ if (req->posix_pathnames) {
+ srvstr_get_path_posix(ctx,
+ params,
+ req->flags2,
+ &directory,
+ ¶ms[4],
+ total_params - 4,
+ STR_TERMINATE,
+ &status);
+ } else {
+ srvstr_get_path(ctx,
+ params,
+ req->flags2,
+ &directory,
+ ¶ms[4],
+ total_params - 4,
+ STR_TERMINATE,
&status);
+ }
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
return;
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
directory,
- 0,
+ ucf_flags,
NULL,
&smb_dname);