static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
connection_struct *conn,
const char *orig_path,
- const char *basepath,
- const char *streamname,
- SMB_STRUCT_STAT *pst,
- char **path);
+ struct smb_filename *smb_fname);
/****************************************************************************
Mangle the 2nd name and check if it is then equal to the first name.
}
}
+NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname,
+ char **full_name)
+{
+ if (smb_fname->stream_name) {
+ *full_name = talloc_asprintf(ctx, "%s%s", smb_fname->base_name,
+ smb_fname->stream_name);
+ } else {
+ *full_name = talloc_strdup(ctx, smb_fname->base_name);
+ }
+
+ if (!*full_name) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return NT_STATUS_OK;
+}
+
/****************************************************************************
This routine is called to convert names from the dos namespace to unix
-namespace. It needs to handle any case conversions, mangling, format
-changes etc.
+namespace. It needs to handle any case conversions, mangling, format changes,
+streams etc.
We assume that we have already done a chdir() to the right "root" directory
for this service.
The function will return an NTSTATUS error if some part of the name except for
the last part cannot be resolved, else NT_STATUS_OK.
-Note NT_STATUS_OK doesn't mean the name exists or is valid, just that we didn't
-get any fatal errors that should immediately terminate the calling
-SMB processing whilst resolving.
+Note NT_STATUS_OK doesn't mean the name exists or is valid, just that we
+didn't get any fatal errors that should immediately terminate the calling SMB
+processing whilst resolving.
-If the saved_last_component != 0, then the unmodified last component
-of the pathname is returned there. If saved_last_component == 0 then nothing
-is returned there.
+If the UCF_SAVE_LCOMP flag is passed in, then the unmodified last component
+of the pathname is set in smb_filename->original_lcomp.
-If last_component_wcard is true then a MS wildcard was detected and
+If UCF_ALLOW_WCARD_LCOMP is passed in, then a MS wildcard was detected and
should be allowed in the last component of the path only.
-On exit from unix_convert, if *pst was not null, then the file stat
-struct will be returned if the file exists and was found, if not this
-stat struct will be filled with zeros (and this can be detected by checking
-for nlinks = 0, which can never be true for any file).
+If the orig_path was a stream, smb_filename->base_name will point to the base
+filename, and smb_filename->stream_name will point to the stream name. If
+orig_path was not a stream, then smb_filename->stream_name will be NULL.
+
+On exit from unix_convert, the smb_filename->st stat struct will be populated
+if the file exists and was found, if not this stat struct will be filled with
+zeros (and this can be detected by checking for nlinks = 0, which can never be
+true for any file).
****************************************************************************/
NTSTATUS unix_convert(TALLOC_CTX *ctx,
- connection_struct *conn,
- const char *orig_path,
- bool allow_wcard_last_component,
- char **pp_conv_path,
- char **pp_saved_last_component,
- SMB_STRUCT_STAT *pst)
+ connection_struct *conn,
+ const char *orig_path,
+ struct smb_filename **smb_fname_out,
+ uint32_t ucf_flags)
{
SMB_STRUCT_STAT st;
+ struct smb_filename *smb_fname = NULL;
char *start, *end;
char *dirpath = NULL;
char *name = NULL;
bool component_was_mangled = False;
bool name_has_wildcard = False;
bool posix_pathnames = false;
+ bool allow_wcard_last_component = ucf_flags & UCF_ALLOW_WCARD_LCOMP;
+ bool save_last_component = ucf_flags & UCF_SAVE_LCOMP;
NTSTATUS result;
int ret = -1;
- SET_STAT_INVALID(*pst);
- *pp_conv_path = NULL;
- if(pp_saved_last_component) {
- *pp_saved_last_component = NULL;
+ *smb_fname_out = NULL;
+
+ smb_fname = TALLOC_ZERO_P(talloc_tos(), struct smb_filename);
+ if (smb_fname == NULL) {
+ return NT_STATUS_NO_MEMORY;
}
if (conn->printer) {
/* we don't ever use the filenames on a printer share as a
filename - so don't convert them */
- if (!(*pp_conv_path = talloc_strdup(ctx,orig_path))) {
+ if (!(smb_fname->base_name = talloc_strdup(smb_fname,
+ orig_path))) {
return NT_STATUS_NO_MEMORY;
}
+ *smb_fname_out = smb_fname;
return NT_STATUS_OK;
}
return NT_STATUS_NO_MEMORY;
}
if (SMB_VFS_STAT(conn,name,&st) == 0) {
- *pst = st;
+ smb_fname->st = st;
} else {
return map_nt_error_from_unix(errno);
}
* Ensure saved_last_component is valid even if file exists.
*/
- if(pp_saved_last_component) {
+ if(save_last_component) {
end = strrchr_m(name, '/');
if (end) {
- *pp_saved_last_component = talloc_strdup(ctx, end + 1);
+ smb_fname->original_lcomp = talloc_strdup(ctx,
+ end + 1);
} else {
- *pp_saved_last_component = talloc_strdup(ctx,
- name);
+ smb_fname->original_lcomp = talloc_strdup(ctx, name);
}
}
posix_pathnames = lp_posix_pathnames();
+ /* Strip off the stream. Should we use any of the other stream parsing
+ * at this point? Also, should we set the is_stream bit? */
if (!posix_pathnames) {
stream = strchr_m(name, ':');
if((!conn->case_sensitive || !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) &&
stat_cache_lookup(conn, &name, &dirpath, &start, &st)) {
- *pst = st;
+ smb_fname->st = st;
goto done;
}
}
stat_cache_add(orig_path, name, conn->case_sensitive);
DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
- *pst = st;
+ smb_fname->st = st;
goto done;
}
*end = 0;
}
- if (pp_saved_last_component) {
- TALLOC_FREE(*pp_saved_last_component);
- *pp_saved_last_component = talloc_strdup(ctx,
+ if (save_last_component) {
+ TALLOC_FREE(smb_fname->original_lcomp);
+ smb_fname->original_lcomp = talloc_strdup(ctx,
end ? end + 1 : start);
- if (!*pp_saved_last_component) {
+ if (!smb_fname->original_lcomp) {
DEBUG(0, ("talloc failed\n"));
return NT_STATUS_NO_MEMORY;
}
* struct. JRA.
*/
- *pst = st;
+ smb_fname->st = st;
}
} else {
}
if (ret == 0) {
- *pst = st;
+ smb_fname->st = st;
} else {
SET_STAT_INVALID(st);
}
DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
done:
+ smb_fname->base_name = name;
+
if (stream != NULL) {
- char *tmp = NULL;
+ smb_fname->stream_name = stream;
- result = build_stream_path(ctx, conn, orig_path, name, stream,
- pst, &tmp);
+ /* Check path now that the base_name has been converted. */
+ result = build_stream_path(ctx, conn, orig_path, smb_fname);
if (!NT_STATUS_IS_OK(result)) {
goto fail;
}
-
- DEBUG(10, ("build_stream_path returned %s\n", tmp));
-
- TALLOC_FREE(name);
- name = tmp;
}
- *pp_conv_path = name;
TALLOC_FREE(dirpath);
+ *smb_fname_out = smb_fname;
return NT_STATUS_OK;
fail:
DEBUG(10, ("dirpath = [%s] start = [%s]\n", dirpath, start));
if (*dirpath != '\0') {
- *pp_conv_path = talloc_asprintf(ctx,
- "%s/%s", dirpath, start);
+ smb_fname->base_name = talloc_asprintf(ctx, "%s/%s", dirpath,
+ start);
} else {
- *pp_conv_path = talloc_strdup(ctx, start);
+ smb_fname->base_name = talloc_strdup(ctx, start);
}
- if (!*pp_conv_path) {
+ if (!smb_fname->base_name) {
DEBUG(0, ("talloc_asprintf failed\n"));
return NT_STATUS_NO_MEMORY;
}
+
+ *smb_fname_out = smb_fname;
TALLOC_FREE(name);
TALLOC_FREE(dirpath);
return result;
static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
connection_struct *conn,
const char *orig_path,
- const char *basepath,
- const char *streamname,
- SMB_STRUCT_STAT *pst,
- char **path)
+ struct smb_filename *smb_fname)
{
- SMB_STRUCT_STAT st;
char *result = NULL;
NTSTATUS status;
unsigned int i, num_streams;
struct stream_struct *streams = NULL;
- result = talloc_asprintf(mem_ctx, "%s%s", basepath, streamname);
- if (result == NULL) {
+ status = get_full_smb_filename(mem_ctx, smb_fname, &result);
+ if (!NT_STATUS_IS_OK(status)) {
return NT_STATUS_NO_MEMORY;
}
- if (SMB_VFS_STAT(conn, result, &st) == 0) {
- *pst = st;
- *path = result;
+ if (SMB_VFS_STAT(conn, result, &smb_fname->st) == 0) {
return NT_STATUS_OK;
}
goto fail;
}
- status = SMB_VFS_STREAMINFO(conn, NULL, basepath, mem_ctx,
+ /* Fall back to a case-insensitive scan of all streams on the file. */
+ status = SMB_VFS_STREAMINFO(conn, NULL, smb_fname->base_name, mem_ctx,
&num_streams, &streams);
if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
- SET_STAT_INVALID(*pst);
- *path = result;
+ SET_STAT_INVALID(smb_fname->st);
return NT_STATUS_OK;
}
for (i=0; i<num_streams; i++) {
DEBUG(10, ("comparing [%s] and [%s]: ",
- streamname, streams[i].name));
- if (fname_equal(streamname, streams[i].name,
+ smb_fname->stream_name, streams[i].name));
+ if (fname_equal(smb_fname->stream_name, streams[i].name,
conn->case_sensitive)) {
DEBUGADD(10, ("equal\n"));
break;
DEBUGADD(10, ("not equal\n"));
}
+ /* Couldn't find the stream. */
if (i == num_streams) {
- SET_STAT_INVALID(*pst);
- *path = result;
+ SET_STAT_INVALID(smb_fname->st);
TALLOC_FREE(streams);
return NT_STATUS_OK;
}
- TALLOC_FREE(result);
+ DEBUG(10, ("case insensitive stream. requested: %s, actual: %s\n",
+ smb_fname->stream_name, streams[i].name));
+
- result = talloc_asprintf(mem_ctx, "%s%s", basepath, streams[i].name);
- if (result == NULL) {
+ TALLOC_FREE(smb_fname->stream_name);
+ smb_fname->stream_name = talloc_strdup(mem_ctx, streams[i].name);
+
+ TALLOC_FREE(result);
+ status = get_full_smb_filename(mem_ctx, smb_fname, &result);
+ if (!NT_STATUS_IS_OK(status)) {
status = NT_STATUS_NO_MEMORY;
goto fail;
}
- SET_STAT_INVALID(*pst);
+ SET_STAT_INVALID(smb_fname->st);
- if (SMB_VFS_STAT(conn, result, pst) == 0) {
+ if (SMB_VFS_STAT(conn, result, &smb_fname->st) == 0) {
stat_cache_add(orig_path, result, conn->case_sensitive);
}
- *path = result;
TALLOC_FREE(streams);
return NT_STATUS_OK;
void reply_checkpath(struct smb_request *req)
{
connection_struct *conn = req->conn;
+ struct smb_filename *smb_fname = NULL;
char *name = NULL;
- SMB_STRUCT_STAT sbuf;
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->vwv+0, 0)));
- status = unix_convert(ctx, conn, name, False, &name, NULL, &sbuf);
+ status = unix_convert(ctx, conn, name, &smb_fname, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto path_err;
+ }
+
+ status = get_full_smb_filename(ctx, smb_fname, &name);
if (!NT_STATUS_IS_OK(status)) {
goto path_err;
}
goto path_err;
}
- if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,name,&sbuf) != 0)) {
+ if (!VALID_STAT(smb_fname->st) &&
+ (SMB_VFS_STAT(conn, name, &smb_fname->st) != 0)) {
DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",name,strerror(errno)));
status = map_nt_error_from_unix(errno);
goto path_err;
}
- if (!S_ISDIR(sbuf.st_mode)) {
+ if (!S_ISDIR(smb_fname->st.st_mode)) {
reply_botherror(req, NT_STATUS_NOT_A_DIRECTORY,
ERRDOS, ERRbadpath);
- END_PROFILE(SMBcheckpath);
- return;
+ goto out;
}
reply_outbuf(req, 0, 0);
-
+ out:
+ if (smb_fname) {
+ TALLOC_FREE(smb_fname);
+ }
END_PROFILE(SMBcheckpath);
return;
- path_err:
+ path_err:
+
+ if (smb_fname) {
+ TALLOC_FREE(smb_fname);
+ }
END_PROFILE(SMBcheckpath);
void reply_getatr(struct smb_request *req)
{
connection_struct *conn = req->conn;
+ struct smb_filename *smb_fname = NULL;
char *fname = NULL;
- SMB_STRUCT_STAT sbuf;
int mode=0;
SMB_OFF_T size=0;
time_t mtime=0;
p += srvstr_get_path_req(ctx, req, &fname, p, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBgetatr);
- return;
+ goto out;
}
status = resolve_dfspath(ctx, conn,
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
ERRSRV, ERRbadpath);
- END_PROFILE(SMBgetatr);
- return;
+ goto out;
}
reply_nterror(req, status);
- END_PROFILE(SMBgetatr);
- return;
+ goto out;
}
/* dos smetimes asks for a stat of "" - it returns a "hidden directory"
size = 0;
mtime = 0;
} else {
- status = unix_convert(ctx, conn, fname, False, &fname, NULL,&sbuf);
+ status = unix_convert(ctx, conn, fname, &smb_fname, 0);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBgetatr);
- return;
+ goto out;
+ }
+ status = get_full_smb_filename(ctx, smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
}
status = check_name(conn, fname);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3,("reply_getatr: check_name of %s failed (%s)\n",fname,nt_errstr(status)));
reply_nterror(req, status);
- END_PROFILE(SMBgetatr);
- return;
+ goto out;
}
- if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,fname,&sbuf) != 0)) {
+ if (!VALID_STAT(smb_fname->st) &&
+ (SMB_VFS_STAT(conn, fname, &smb_fname->st) != 0)) {
DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",fname,strerror(errno)));
reply_unixerror(req, ERRDOS,ERRbadfile);
- END_PROFILE(SMBgetatr);
- return;
+ goto out;
}
- mode = dos_mode(conn,fname,&sbuf);
- size = sbuf.st_size;
- mtime = sbuf.st_mtime;
+ mode = dos_mode(conn, fname, &smb_fname->st);
+ size = smb_fname->st.st_size;
+ mtime = smb_fname->st.st_mtime;
if (mode & aDIR) {
size = 0;
}
DEBUG(3,("reply_getatr: name=%s mode=%d size=%u\n", fname, mode, (unsigned int)size ) );
+ out:
+ if (smb_fname) {
+ TALLOC_FREE(smb_fname);
+ }
END_PROFILE(SMBgetatr);
return;
}
{
struct smb_file_time ft;
connection_struct *conn = req->conn;
+ struct smb_filename *smb_fname = NULL;
char *fname = NULL;
int mode;
time_t mtime;
- SMB_STRUCT_STAT sbuf;
const char *p;
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
if (req->wct < 2) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ goto out;
}
p = (const char *)req->buf + 1;
p += srvstr_get_path_req(ctx, req, &fname, p, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBsetatr);
- return;
+ goto out;
}
status = resolve_dfspath(ctx, conn,
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
ERRSRV, ERRbadpath);
- END_PROFILE(SMBsetatr);
- return;
+ goto out;
}
reply_nterror(req, status);
- END_PROFILE(SMBsetatr);
- return;
+ goto out;
}
- status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
+ status = unix_convert(ctx, conn, fname, &smb_fname, 0);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBsetatr);
- return;
+ goto out;
+ }
+
+ status = get_full_smb_filename(ctx, smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
}
status = check_name(conn, fname);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBsetatr);
- return;
+ goto out;
}
if (fname[0] == '.' && fname[1] == '\0') {
* condition. Might be moved to somewhere else later -- vl
*/
reply_nterror(req, NT_STATUS_ACCESS_DENIED);
- END_PROFILE(SMBsetatr);
- return;
+ goto out;
}
mode = SVAL(req->vwv+0, 0);
ft.mtime = convert_time_t_to_timespec(mtime);
status = smb_set_file_time(conn, NULL, fname,
- &sbuf, &ft, true);
+ &smb_fname->st, &ft, true);
if (!NT_STATUS_IS_OK(status)) {
reply_unixerror(req, ERRDOS, ERRnoaccess);
- END_PROFILE(SMBsetatr);
- return;
+ goto out;
}
if (mode != FILE_ATTRIBUTE_NORMAL) {
- if (VALID_STAT_OF_DIR(sbuf))
+ if (VALID_STAT_OF_DIR(smb_fname->st))
mode |= aDIR;
else
mode &= ~aDIR;
- if (file_set_dosmode(conn,fname,mode,&sbuf,NULL,false) != 0) {
+ if (file_set_dosmode(conn, fname, mode, &smb_fname->st, NULL,
+ false) != 0) {
reply_unixerror(req, ERRDOS, ERRnoaccess);
- END_PROFILE(SMBsetatr);
- return;
+ goto out;
}
}
reply_outbuf(req, 0, 0);
DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
-
+ out:
+ if (smb_fname) {
+ TALLOC_FREE(smb_fname);
+ }
END_PROFILE(SMBsetatr);
return;
}
/* dirtype &= ~aDIR; */
if (status_len == 0) {
- SMB_STRUCT_STAT sbuf;
+ struct smb_filename *smb_fname = NULL;
- nt_status = unix_convert(ctx, conn, path, True,
- &directory, NULL, &sbuf);
+ nt_status = unix_convert(ctx, conn, path, &smb_fname,
+ UCF_ALLOW_WCARD_LCOMP);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ reply_nterror(req, nt_status);
+ END_PROFILE(SMBsearch);
+ return;
+ }
+
+ nt_status = get_full_smb_filename(ctx, smb_fname, &directory);
+ TALLOC_FREE(smb_fname);
if (!NT_STATUS_IS_OK(nt_status)) {
reply_nterror(req, nt_status);
END_PROFILE(SMBsearch);
void reply_ctemp(struct smb_request *req)
{
connection_struct *conn = req->conn;
+ struct smb_filename *smb_fname = NULL;
char *fname = NULL;
uint32 fattr;
files_struct *fsp;
int oplock_request;
int tmpfd;
- SMB_STRUCT_STAT sbuf;
char *s;
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
if (req->wct < 3) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- END_PROFILE(SMBctemp);
- return;
+ goto out;
}
fattr = SVAL(req->vwv+0, 0);
STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBctemp);
- return;
+ goto out;
}
if (*fname) {
fname = talloc_asprintf(ctx,
if (!fname) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBctemp);
- return;
+ goto out;
}
status = resolve_dfspath(ctx, conn,
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
ERRSRV, ERRbadpath);
- END_PROFILE(SMBctemp);
- return;
+ goto out;
}
reply_nterror(req, status);
- END_PROFILE(SMBctemp);
- return;
+ goto out;
}
- status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
+ status = unix_convert(ctx, conn, fname, &smb_fname, 0);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBctemp);
- return;
+ goto out;
+ }
+
+ status = get_full_smb_filename(ctx, smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
}
status = check_name(conn, fname);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBctemp);
- return;
+ goto out;
}
tmpfd = mkstemp(fname);
if (tmpfd == -1) {
reply_unixerror(req, ERRDOS, ERRnoaccess);
- END_PROFILE(SMBctemp);
- return;
+ goto out;
}
- SET_STAT_INVALID(sbuf);
- SMB_VFS_STAT(conn,fname,&sbuf);
+ SET_STAT_INVALID(smb_fname->st);
+ SMB_VFS_STAT(conn, fname, &smb_fname->st);
/* We should fail if file does not exist. */
status = SMB_VFS_CREATE_FILE(
NULL, /* ea_list */
&fsp, /* result */
NULL, /* pinfo */
- &sbuf); /* psbuf */
+ &smb_fname->st); /* psbuf */
/* close fd from mkstemp() */
close(tmpfd);
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
/* We have re-scheduled this call. */
- END_PROFILE(SMBctemp);
- return;
+ goto out;
}
reply_openerror(req, status);
- END_PROFILE(SMBctemp);
- return;
+ goto out;
}
reply_outbuf(req, 1, 0);
if (message_push_string(&req->outbuf, s, STR_ASCII|STR_TERMINATE)
== -1) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBctemp);
- return;
+ goto out;
}
if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) );
DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name,
- fsp->fh->fd, (unsigned int)sbuf.st_mode ) );
-
+ fsp->fh->fd, (unsigned int)smb_fname->st.st_mode));
+ out:
+ if (smb_fname) {
+ TALLOC_FREE(smb_fname);
+ }
END_PROFILE(SMBctemp);
return;
}
NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
uint32 dirtype, const char *name_in, bool has_wild)
{
+ struct smb_filename *smb_fname = NULL;
const char *directory = NULL;
char *mask = NULL;
char *name = NULL;
char *p = NULL;
int count=0;
NTSTATUS status = NT_STATUS_OK;
- SMB_STRUCT_STAT sbuf, st;
+ SMB_STRUCT_STAT st;
TALLOC_CTX *ctx = talloc_tos();
- status = unix_convert(ctx, conn, name_in, has_wild, &name, NULL, &sbuf);
+ status = unix_convert(ctx, conn, name_in, &smb_fname,
+ has_wild ? UCF_ALLOW_WCARD_LCOMP : 0);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
+ status = get_full_smb_filename(ctx, smb_fname, &name);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(smb_fname);
+ return status;
+ }
+
p = strrchr_m(name,'/');
if (!p) {
directory = talloc_strdup(ctx, ".");
if (!directory) {
+ TALLOC_FREE(smb_fname);
return NT_STATUS_NO_MEMORY;
}
mask = name;
* Tine Smukavec <valentin.smukavec@hermes.si>.
*/
- if (!VALID_STAT(sbuf) && mangle_is_mangled(mask,conn->params)) {
+ if (!VALID_STAT(smb_fname->st) && mangle_is_mangled(mask,conn->params)) {
char *new_mask = NULL;
mangle_lookup_name_from_8_3(ctx,
mask,
mask = new_mask;
}
}
+ TALLOC_FREE(smb_fname);
if (!has_wild) {
directory = talloc_asprintf(ctx,
void reply_mkdir(struct smb_request *req)
{
connection_struct *conn = req->conn;
+ struct smb_filename *smb_dname = NULL;
char *directory = NULL;
NTSTATUS status;
- SMB_STRUCT_STAT sbuf;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBmkdir);
STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBmkdir);
- return;
+ goto out;
}
status = resolve_dfspath(ctx, conn,
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
ERRSRV, ERRbadpath);
- END_PROFILE(SMBmkdir);
- return;
+ goto out;
}
reply_nterror(req, status);
- END_PROFILE(SMBmkdir);
- return;
+ goto out;
}
- status = unix_convert(ctx, conn, directory, False, &directory, NULL, &sbuf);
+ status = unix_convert(ctx, conn, directory, &smb_dname, 0);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBmkdir);
- return;
+ goto out;
+ }
+
+ status = get_full_smb_filename(ctx, smb_dname, &directory);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
}
status = check_name(conn, directory);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBmkdir);
- return;
+ goto out;
}
status = create_directory(conn, req, directory);
}
reply_nterror(req, status);
- END_PROFILE(SMBmkdir);
- return;
+ goto out;
}
reply_outbuf(req, 0, 0);
DEBUG( 3, ( "mkdir %s\n", directory ) );
-
+ out:
+ if (smb_dname) {
+ TALLOC_FREE(smb_dname);
+ }
END_PROFILE(SMBmkdir);
return;
}
void reply_rmdir(struct smb_request *req)
{
connection_struct *conn = req->conn;
+ struct smb_filename *smb_dname = NULL;
char *directory = NULL;
- SMB_STRUCT_STAT sbuf;
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBrmdir);
- return;
+ goto out;
}
status = resolve_dfspath(ctx, conn,
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
ERRSRV, ERRbadpath);
- END_PROFILE(SMBrmdir);
- return;
+ goto out;
}
reply_nterror(req, status);
- END_PROFILE(SMBrmdir);
- return;
+ goto out;
}
- status = unix_convert(ctx, conn, directory, False, &directory,
- NULL, &sbuf);
+ status = unix_convert(ctx, conn, directory, &smb_dname, 0);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBrmdir);
- return;
+ goto out;
+ }
+
+ status = get_full_smb_filename(ctx, smb_dname, &directory);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
}
status = check_name(conn, directory);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBrmdir);
- return;
+ goto out;
}
dptr_closepath(directory, req->smbpid);
status = rmdir_internals(ctx, conn, directory);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBrmdir);
- return;
+ goto out;
}
reply_outbuf(req, 0, 0);
DEBUG( 3, ( "rmdir %s\n", directory ) );
-
+ out:
+ if (smb_dname) {
+ TALLOC_FREE(smb_dname);
+ }
END_PROFILE(SMBrmdir);
return;
}
bool dest_has_wild,
uint32_t access_mask)
{
+ struct smb_filename *smb_fname = NULL;
+ struct smb_filename *smb_fname_new = NULL;
char *directory = NULL;
char *mask = NULL;
- char *last_component_src = NULL;
- char *last_component_dest = NULL;
char *name = NULL;
char *newname = NULL;
char *p;
int count=0;
NTSTATUS status = NT_STATUS_OK;
- SMB_STRUCT_STAT sbuf1, sbuf2;
struct smb_Dir *dir_hnd = NULL;
const char *dname;
long offset = 0;
int create_options = 0;
bool posix_pathnames = lp_posix_pathnames();
- ZERO_STRUCT(sbuf1);
- ZERO_STRUCT(sbuf2);
+ status = unix_convert(ctx, conn, name_in, &smb_fname,
+ src_has_wild ? UCF_ALLOW_WCARD_LCOMP : 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+
+ status = get_full_smb_filename(ctx, smb_fname, &name);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
- status = unix_convert(ctx, conn, name_in, src_has_wild, &name,
- &last_component_src, &sbuf1);
+ status = unix_convert(ctx, conn, newname_in, &smb_fname_new,
+ (UCF_SAVE_LCOMP |
+ (dest_has_wild ? UCF_ALLOW_WCARD_LCOMP : 0)));
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ goto out;
}
- status = unix_convert(ctx, conn, newname_in, dest_has_wild, &newname,
- &last_component_dest, &sbuf2);
+ status = get_full_smb_filename(ctx, smb_fname_new, &newname);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ goto out;
}
/*
if (!p) {
directory = talloc_strdup(ctx, ".");
if (!directory) {
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
}
mask = name;
} else {
*p = 0;
directory = talloc_strdup(ctx, name);
if (!directory) {
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
}
mask = p+1;
*p = '/'; /* Replace needed for exceptional test below. */
* Tine Smukavec <valentin.smukavec@hermes.si>.
*/
- if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
+ if (!VALID_STAT(smb_fname->st) && mangle_is_mangled(mask, conn->params)) {
char *new_mask = NULL;
mangle_lookup_name_from_8_3(ctx,
mask,
"/%s",
mask);
if (!directory) {
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
}
/* Ensure newname contains a '/' also */
"./%s",
newname);
if (!newname) {
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
}
}
"last_component_dest = %s\n",
conn->case_sensitive, conn->case_preserve,
conn->short_case_preserve, directory,
- newname, last_component_dest));
+ newname, smb_fname_new->original_lcomp));
/* The dest name still may have wildcards. */
if (dest_has_wild) {
"%s %s failed\n",
directory,
newname));
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
}
newname = mod_newname;
}
- ZERO_STRUCT(sbuf1);
+ ZERO_STRUCT(smb_fname->st);
if (posix_pathnames) {
- SMB_VFS_LSTAT(conn, directory, &sbuf1);
+ SMB_VFS_LSTAT(conn, directory, &smb_fname->st);
} else {
- SMB_VFS_STAT(conn, directory, &sbuf1);
+ SMB_VFS_STAT(conn, directory, &smb_fname->st);
}
- if (S_ISDIR(sbuf1.st_mode)) {
+ if (S_ISDIR(smb_fname->st.st_mode)) {
create_options |= FILE_DIRECTORY_FILE;
}
NULL, /* ea_list */
&fsp, /* result */
NULL, /* pinfo */
- &sbuf1); /* psbuf */
+ &smb_fname->st); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("Could not open rename source %s: %s\n",
directory, nt_errstr(status)));
- return status;
+ goto out;
}
status = rename_internals_fsp(conn, fsp, newname,
- last_component_dest,
+ smb_fname_new->original_lcomp,
attrs, replace_if_exists);
close_file(req, fsp, NORMAL_CLOSE);
DEBUG(3, ("rename_internals: Error %s rename %s -> %s\n",
nt_errstr(status), directory,newname));
- return status;
+ goto out;
}
/*
status = check_name(conn, directory);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ goto out;
}
dir_hnd = OpenDir(talloc_tos(), conn, directory, mask, attrs);
if (dir_hnd == NULL) {
- return map_nt_error_from_unix(errno);
+ status = map_nt_error_from_unix(errno);
+ goto out;
}
status = NT_STATUS_NO_SUCH_FILE;
* - gentest fix. JRA
*/
- while ((dname = ReadDirName(dir_hnd, &offset, &sbuf1))) {
+ while ((dname = ReadDirName(dir_hnd, &offset, &smb_fname->st))) {
files_struct *fsp = NULL;
char *fname = NULL;
char *destname = NULL;
}
}
- if (!is_visible_file(conn, directory, dname, &sbuf1, False)) {
+ if (!is_visible_file(conn, directory, dname, &smb_fname->st,
+ False)) {
continue;
}
directory,
dname);
if (!fname) {
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
}
if (!resolve_wildcards(ctx,
continue;
}
if (!destname) {
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
}
- ZERO_STRUCT(sbuf1);
+ ZERO_STRUCT(smb_fname->st);
if (posix_pathnames) {
- SMB_VFS_LSTAT(conn, fname, &sbuf1);
+ SMB_VFS_LSTAT(conn, fname, &smb_fname->st);
} else {
- SMB_VFS_STAT(conn, fname, &sbuf1);
+ SMB_VFS_STAT(conn, fname, &smb_fname->st);
}
create_options = 0;
- if (S_ISDIR(sbuf1.st_mode)) {
+ if (S_ISDIR(smb_fname->st.st_mode)) {
create_options |= FILE_DIRECTORY_FILE;
}
NULL, /* ea_list */
&fsp, /* result */
NULL, /* pinfo */
- &sbuf1); /* psbuf */
+ &smb_fname->st); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3,("rename_internals: SMB_VFS_CREATE_FILE "
status = map_nt_error_from_unix(errno);
}
+ out:
+ if (smb_fname) {
+ TALLOC_FREE(smb_fname);
+ }
+ if (smb_fname_new) {
+ TALLOC_FREE(smb_fname_new);
+ }
return status;
}
void reply_copy(struct smb_request *req)
{
connection_struct *conn = req->conn;
+ struct smb_filename *smb_fname = NULL;
+ struct smb_filename *smb_fname_new = NULL;
char *name = NULL;
char *newname = NULL;
char *directory = NULL;
bool target_is_directory=False;
bool source_has_wild = False;
bool dest_has_wild = False;
- SMB_STRUCT_STAT sbuf1, sbuf2;
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
if (req->wct < 3) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
tid2 = SVAL(req->vwv+0, 0);
&status, &source_has_wild);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
p += srvstr_get_path_req_wcard(ctx, req, &newname, p, STR_TERMINATE,
&status, &dest_has_wild);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
/* can't currently handle inter share copies XXXX */
DEBUG(3,("Rejecting inter-share copy\n"));
reply_doserror(req, ERRSRV, ERRinvdevice);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
status = resolve_dfspath_wcard(ctx, conn,
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
ERRSRV, ERRbadpath);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
reply_nterror(req, status);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
status = resolve_dfspath_wcard(ctx, conn,
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
ERRSRV, ERRbadpath);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
reply_nterror(req, status);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
- status = unix_convert(ctx, conn, name, source_has_wild,
- &name, NULL, &sbuf1);
+ status = unix_convert(ctx, conn, name, &smb_fname,
+ source_has_wild ? UCF_ALLOW_WCARD_LCOMP : 0);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
- status = unix_convert(ctx, conn, newname, dest_has_wild,
- &newname, NULL, &sbuf2);
+ status = get_full_smb_filename(ctx, smb_fname, &name);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
+ }
+
+ status = unix_convert(ctx, conn, newname, &smb_fname_new,
+ dest_has_wild ? UCF_ALLOW_WCARD_LCOMP : 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
+ }
+
+ status = get_full_smb_filename(ctx, smb_fname_new, &newname);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
}
- target_is_directory = VALID_STAT_OF_DIR(sbuf2);
+ target_is_directory = VALID_STAT_OF_DIR(smb_fname_new->st);
if ((flags&1) && target_is_directory) {
reply_doserror(req, ERRDOS, ERRbadfile);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
if ((flags&2) && !target_is_directory) {
reply_doserror(req, ERRDOS, ERRbadpath);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
- if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
+ if ((flags&(1<<5)) && VALID_STAT_OF_DIR(smb_fname->st)) {
/* wants a tree copy! XXXX */
DEBUG(3,("Rejecting tree copy\n"));
reply_doserror(req, ERRSRV, ERRerror);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
p = strrchr_m(name,'/');
if (!directory) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
/*
* Tine Smukavec <valentin.smukavec@hermes.si>.
*/
- if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
+ if (!VALID_STAT(smb_fname->st) &&
+ mangle_is_mangled(mask, conn->params)) {
char *new_mask = NULL;
mangle_lookup_name_from_8_3(ctx,
mask,
if (!resolve_wildcards(ctx,
directory,newname,&mod_newname)) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
newname = mod_newname;
}
status = check_name(conn, directory);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
status = check_name(conn, newname);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
status = copy_file(ctx,conn,directory,newname,ofun,
if(!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
} else {
count++;
}
status = check_name(conn, directory);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
dir_hnd = OpenDir(talloc_tos(), conn, directory, mask, 0);
if (dir_hnd == NULL) {
status = map_nt_error_from_unix(errno);
reply_nterror(req, status);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
error = ERRbadfile;
- while ((dname = ReadDirName(dir_hnd, &offset, &sbuf1))) {
+ while ((dname = ReadDirName(dir_hnd, &offset,
+ &smb_fname->st))) {
char *destname = NULL;
char *fname = NULL;
continue;
}
- if (!is_visible_file(conn, directory, dname, &sbuf1, False)) {
+ if (!is_visible_file(conn, directory, dname,
+ &smb_fname->st, False)) {
continue;
}
if (!fname) {
TALLOC_FREE(dir_hnd);
reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
if (!resolve_wildcards(ctx,
if (!destname) {
TALLOC_FREE(dir_hnd);
reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
status = check_name(conn, fname);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(dir_hnd);
reply_nterror(req, status);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
status = check_name(conn, destname);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(dir_hnd);
reply_nterror(req, status);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname, destname));
/* Error on close... */
errno = err;
reply_unixerror(req, ERRHRD, ERRgeneral);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
reply_doserror(req, ERRDOS, error);
- END_PROFILE(SMBcopy);
- return;
+ goto out;
}
reply_outbuf(req, 1, 0);
SSVAL(req->outbuf,smb_vwv0,count);
-
+ out:
+ if (smb_fname) {
+ TALLOC_FREE(smb_fname);
+ }
+ if (smb_fname_new) {
+ TALLOC_FREE(smb_fname_new);
+ }
END_PROFILE(SMBcopy);
return;
}
maxentries then so be it. We assume that the redirector has
enough room for the fixed number of parameter bytes it has
requested. */
+ struct smb_filename *smb_dname = NULL;
char *params = *pparams;
char *pdata = *ppdata;
char *data_end;
bool out_of_space = False;
int space_remaining;
bool mask_contains_wcard = False;
- SMB_STRUCT_STAT sbuf;
struct ea_list *ea_list = NULL;
NTSTATUS ntstatus = NT_STATUS_OK;
bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
return;
}
- ntstatus = unix_convert(ctx, conn, directory, True, &directory, &mask, &sbuf);
+ ntstatus = unix_convert(ctx, conn, directory, &smb_dname,
+ (UCF_SAVE_LCOMP | UCF_ALLOW_WCARD_LCOMP));
+ if (!NT_STATUS_IS_OK(ntstatus)) {
+ reply_nterror(req, ntstatus);
+ return;
+ }
+
+ mask = smb_dname->original_lcomp;
+
+ ntstatus = get_full_smb_filename(ctx, smb_dname, &directory);
+ TALLOC_FREE(smb_dname);
if (!NT_STATUS_IS_OK(ntstatus)) {
reply_nterror(req, ntstatus);
return;
SMB_STRUCT_STAT sbuf;
char *dos_fname = NULL;
char *fname = NULL;
+ struct smb_filename *smb_fname = NULL;
char *fullpathname;
char *base_name;
char *p;
return;
}
- status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
+ status = unix_convert(ctx, conn, fname, &smb_fname, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+ sbuf = smb_fname->st;
+
+ status = get_full_smb_filename(ctx, smb_fname, &fname);
+ TALLOC_FREE(smb_fname);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
return;
}
+
status = check_name(conn, fname);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,nt_errstr(status)));
const char *oldname_in,
const char *newname_in)
{
- SMB_STRUCT_STAT sbuf1, sbuf2;
- char *last_component_oldname = NULL;
- char *last_component_newname = NULL;
+ struct smb_filename *smb_fname = NULL;
+ struct smb_filename *smb_fname_new = NULL;
char *oldname = NULL;
char *newname = NULL;
NTSTATUS status = NT_STATUS_OK;
- ZERO_STRUCT(sbuf1);
- ZERO_STRUCT(sbuf2);
+ status = unix_convert(ctx, conn, oldname_in, &smb_fname, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
- status = unix_convert(ctx, conn, oldname_in, False, &oldname,
- &last_component_oldname, &sbuf1);
+ status = get_full_smb_filename(ctx, smb_fname, &oldname);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ goto out;
}
status = check_name(conn, oldname);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ goto out;
}
/* source must already exist. */
- if (!VALID_STAT(sbuf1)) {
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ if (!VALID_STAT(smb_fname->st)) {
+ status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ goto out;
}
- status = unix_convert(ctx, conn, newname_in, False, &newname,
- &last_component_newname, &sbuf2);
+ status = unix_convert(ctx, conn, newname_in, &smb_fname_new, 0);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ goto out;
+ }
+
+ status = get_full_smb_filename(ctx, smb_fname_new, &newname);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
}
status = check_name(conn, newname);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ goto out;
}
/* Disallow if newname already exists. */
- if (VALID_STAT(sbuf2)) {
- return NT_STATUS_OBJECT_NAME_COLLISION;
+ if (VALID_STAT(smb_fname_new->st)) {
+ status = NT_STATUS_OBJECT_NAME_COLLISION;
+ goto out;
}
/* No links from a directory. */
- if (S_ISDIR(sbuf1.st_mode)) {
- return NT_STATUS_FILE_IS_A_DIRECTORY;
+ if (S_ISDIR(smb_fname->st.st_mode)) {
+ status = NT_STATUS_FILE_IS_A_DIRECTORY;
+ goto out;
}
/* Ensure this is within the share. */
status = check_reduced_name(conn, oldname);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ goto out;
}
DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
status = map_nt_error_from_unix(errno);
DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
- nt_errstr(status), newname, oldname));
+ nt_errstr(status), newname, oldname));
+ }
+ out:
+ if (smb_fname) {
+ TALLOC_FREE(smb_fname);
+ }
+ if (smb_fname_new) {
+ TALLOC_FREE(smb_fname_new);
}
-
return status;
}
uint32 len;
char *newname = NULL;
char *base_name = NULL;
+ struct smb_filename *smb_fname = NULL;
bool dest_has_wcard = False;
- SMB_STRUCT_STAT sbuf;
- char *newname_last_component = NULL;
NTSTATUS status = NT_STATUS_OK;
char *p;
TALLOC_CTX *ctx = talloc_tos();
return NT_STATUS_INVALID_PARAMETER;
}
- ZERO_STRUCT(sbuf);
-
overwrite = (CVAL(pdata,0) ? True : False);
root_fid = IVAL(pdata,4);
len = IVAL(pdata,8);
return NT_STATUS_NO_MEMORY;
}
- status = unix_convert(ctx, conn, newname, False,
- &newname,
- &newname_last_component,
- &sbuf);
+ status = unix_convert(ctx, conn, newname, &smb_fname,
+ UCF_SAVE_LCOMP);
/* If an error we expect this to be
* NT_STATUS_OBJECT_PATH_NOT_FOUND */
if (!NT_STATUS_IS_OK(status)
&& !NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND,
status)) {
- return status;
+ goto out;
}
}
DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
fsp->fnum, fsp->fsp_name, base_name ));
status = rename_internals_fsp(conn, fsp, base_name,
- newname_last_component, 0,
- overwrite);
+ smb_fname ?
+ smb_fname->original_lcomp : NULL,
+ 0, overwrite);
} else {
DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
fname, base_name ));
overwrite, False, dest_has_wcard,
FILE_WRITE_ATTRIBUTES);
}
-
+ out:
+ if (smb_fname) {
+ TALLOC_FREE(smb_fname);
+ }
return status;
}
uint16 info_level;
SMB_STRUCT_STAT sbuf;
char *fname = NULL;
+ struct smb_filename *smb_fname = NULL;
files_struct *fsp = NULL;
NTSTATUS status = NT_STATUS_OK;
int data_return_size = 0;
return;
}
- status = unix_convert(ctx, conn, fname, False,
- &fname, NULL, &sbuf);
+ status = unix_convert(ctx, conn, fname, &smb_fname, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+ sbuf = smb_fname->st;
+
+ status = get_full_smb_filename(ctx, smb_fname, &fname);
+ TALLOC_FREE(smb_fname);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
return;
char **ppdata, int total_data,
unsigned int max_data_bytes)
{
+ struct smb_filename *smb_dname = NULL;
char *params = *pparams;
char *pdata = *ppdata;
char *directory = NULL;
- SMB_STRUCT_STAT sbuf;
NTSTATUS status = NT_STATUS_OK;
struct ea_list *ea_list = NULL;
TALLOC_CTX *ctx = talloc_tos();
DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
- status = unix_convert(ctx, conn, directory, False, &directory, NULL, &sbuf);
+ status = unix_convert(ctx, conn, directory, &smb_dname, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+
+ status = get_full_smb_filename(ctx, smb_dname, &directory);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
return;