*/
status = openat_pathref_fsp(dirptr->dir_hnd->fsp, atname);
if (!NT_STATUS_IS_OK(status) &&
- !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
- !NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK))
+ !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND))
{
TALLOC_FREE(atname);
TALLOC_FREE(dname);
TALLOC_FREE(fname);
TALLOC_FREE(smb_fname);
continue;
- } else if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
+ } else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
if (!(atname->flags & SMB_FILENAME_POSIX_PATH)) {
- TALLOC_FREE(atname);
- TALLOC_FREE(dname);
- TALLOC_FREE(fname);
- TALLOC_FREE(smb_fname);
- continue;
+ check_dfs_symlink = true;
}
/*
- * It's a symlink, disable getting dosmode in the
- * mode_fn() and prime the mode as
- * FILE_ATTRIBUTE_NORMAL.
+ * Check if it's a symlink. We only want to return this
+ * if it's a DFS symlink or in POSIX mode. Disable
+ * getting dosmode in the mode_fn() and prime the mode
+ * as FILE_ATTRIBUTE_NORMAL.
*/
mode = FILE_ATTRIBUTE_NORMAL;
get_dosmode = false;
- } else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
- if (atname->flags & SMB_FILENAME_POSIX_PATH) {
- TALLOC_FREE(atname);
- TALLOC_FREE(dname);
- TALLOC_FREE(fname);
- TALLOC_FREE(smb_fname);
- continue;
- }
- /*
- * Likely a dangling symlink. We only want to return
- * this if it's a DFS symlink, so we need to check for
- * that. Set get_dosmode to skip getting dosmode.
- */
- get_dosmode = false;
- check_dfs_symlink = true;
}
status = move_smb_fname_fsp_link(smb_fname, atname);
}
status = openat_pathref_fsp(conn->cwd_fsp, smb_fname);
- if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
/*
- * Don't leak NT_STATUS_STOPPED_ON_SYMLINK into the callers:
- * it's a special SMB2 error that needs an extended SMB2 error
- * response. We don't support that for SMB2 and it doesn't exist
- * at all in SMB1.
- *
- * So we deal with symlinks here as we do in
+ * We deal with symlinks here as we do in
* SMB_VFS_CREATE_FILE(): return success for POSIX clients with
* the notable difference that there will be no fsp in
* smb_fname->fsp.
* For Windows (non POSIX) clients fail with
* NT_STATUS_OBJECT_NAME_NOT_FOUND.
*/
- if (ucf_flags & UCF_POSIX_PATHNAMES) {
+ if (smb_fname->flags & SMB_FILENAME_POSIX_PATH &&
+ S_ISLNK(smb_fname->st.st_ex_mode))
+ {
status = NT_STATUS_OK;
- } else {
- status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
}
if (!NT_STATUS_IS_OK(status)) {
}
if (S_ISLNK(smb_fname->st.st_ex_mode)) {
- return NT_STATUS_STOPPED_ON_SYMLINK;
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
status = fsp_new(conn, conn, &fsp);
status = fd_openat(dirfsp, smb_fname, fsp, open_flags, 0);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) ||
- NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
+ NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND) ||
+ NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK))
{
/*
* streams_xattr return NT_STATUS_NOT_FOUND for
*
* NT_STATUS_OBJECT_NAME_NOT_FOUND is the simple
* ENOENT case.
+ *
+ * NT_STATUS_STOPPED_ON_SYMLINK is returned when trying
+ * to open a symlink, our callers are not interested in
+ * this.
*/
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
}
status = openat_pathref_fsp(conn->cwd_fsp, f);
- if (!NT_STATUS_IS_OK(status) &&
- !NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK))
+ if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
+ (f->flags & SMB_FILENAME_POSIX_PATH) &&
+ S_ISLNK(f->st.st_ex_mode))
{
+ status = NT_STATUS_OK;
+ }
+ if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(dir_hnd);
TALLOC_FREE(frame);
TALLOC_FREE(talloced);
int ret;
status = openat_pathref_fsp(conn->cwd_fsp, smb_fname);
- if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
+ (smb_fname->flags & SMB_FILENAME_POSIX_PATH) &&
+ S_ISLNK(smb_fname->st.st_ex_mode))
+ {
status = NT_STATUS_OK;
}
if (!NT_STATUS_IS_OK(status)) {