The branch, master has been updated via 9341c02 smbd: Prevent a crash via a971cfe s3: smbd: Simplify logic inside rename_internals_fsp() part 2 via bffa598 s3: smbd: Simplify logic inside rename_internals_fsp() part 1. via b4246f8 s3:lib: Move internal lp_posix_pathnames() call out of utility function synthetic_smb_fname_split(). via 153af65 s3:lib: Remove the const SMB_STRUCT_STAT * parameter from synthetic_smb_fname_split(). via e2056f8 s3:lib: Rewrite synthetic_smb_fname_split() to use split_stream_filename(). via 59f6a73 s3:lib. Add split_stream_filename() Not yet used. from b96511f selftest: add some test cases to net ads join
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 9341c02a8998a860d4f390bba2556555a138c71b Author: Volker Lendecke <v...@samba.org> Date: Thu Mar 10 08:54:54 2016 +0100 smbd: Prevent a crash smb2srv_session_close_previous_check crashes if ndr_pull_smbXsrv_session_globalB fails for some reason. It depends on "is_free" to be correctly set. All we can do for an invalid database is to discard the record and set it free. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Fri Mar 11 00:12:18 CET 2016 on sn-devel-144 commit a971cfe0ef47c02d119261596c0705275e17e613 Author: Jeremy Allison <j...@samba.org> Date: Wed Mar 9 16:12:00 2016 -0800 s3: smbd: Simplify logic inside rename_internals_fsp() part 2 Removes the use of an extraneous 'struct smb_filename *' which wasn't being created correctly, only as a place holder for two char * pointers. Use split_stream_filename() to create the char * pointers directly and make it clearer what we're up to here. The logic here is still complex, but I'm satified it does the correct thing. Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> commit bffa598c0479b69b9b74a9093f90c8349327f8b7 Author: Jeremy Allison <j...@samba.org> Date: Wed Mar 9 16:01:52 2016 -0800 s3: smbd: Simplify logic inside rename_internals_fsp() part 1. Use standard parent_dirname() function instead of hand-hacking using strrchr_m(xxx, '/'). Next commit should enable removal of synthetic_smb_fname_split(). Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> commit b4246f863ce15865a772b0be7a949a46688bcc34 Author: Jeremy Allison <j...@samba.org> Date: Wed Mar 9 16:00:47 2016 -0800 s3:lib: Move internal lp_posix_pathnames() call out of utility function synthetic_smb_fname_split(). Make it a passed in parameter instead. Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> commit 153af65e445e8491fb436e7112b579ed4603ca01 Author: Jeremy Allison <j...@samba.org> Date: Wed Mar 9 15:50:02 2016 -0800 s3:lib: Remove the const SMB_STRUCT_STAT * parameter from synthetic_smb_fname_split(). Only one caller uses this, and this can be handled externally. Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> commit e2056f843d71fd7b9c3e326d45c71218cf8faaae Author: Jeremy Allison <j...@samba.org> Date: Wed Mar 9 15:45:55 2016 -0800 s3:lib: Rewrite synthetic_smb_fname_split() to use split_stream_filename(). Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> commit 59f6a73c93c100406851d40e1d676f5b44fd355e Author: Jeremy Allison <j...@samba.org> Date: Wed Mar 9 14:56:49 2016 -0800 s3:lib. Add split_stream_filename() Not yet used. Will replace internals of synthetic_smb_fname_split(). Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Uri Simchoni <u...@samba.org> ----------------------------------------------------------------------- Summary of changes: source3/include/proto.h | 8 +++- source3/lib/filename_util.c | 74 +++++++++++++++++++++++++++-------- source3/smbd/filename.c | 5 ++- source3/smbd/pysmbd.c | 8 +++- source3/smbd/reply.c | 89 +++++++++++++++++++++++++----------------- source3/smbd/smbXsrv_session.c | 8 ++++ source3/torture/cmd_vfs.c | 28 +++++++++---- 7 files changed, 154 insertions(+), 66 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/include/proto.h b/source3/include/proto.h index 8a273c3..dc8fee9 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1141,8 +1141,8 @@ struct smb_filename *synthetic_smb_fname(TALLOC_CTX *mem_ctx, const char *stream_name, const SMB_STRUCT_STAT *psbuf); struct smb_filename *synthetic_smb_fname_split(TALLOC_CTX *ctx, - const char *fname, - const SMB_STRUCT_STAT *psbuf); + const char *fname, + bool posix_path); const char *smb_fname_str_dbg(const struct smb_filename *smb_fname); const char *fsp_str_dbg(const struct files_struct *fsp); const char *fsp_fnum_dbg(const struct files_struct *fsp); @@ -1152,6 +1152,10 @@ bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname); bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname); bool is_invalid_windows_ea_name(const char *name); bool ea_list_has_invalid_name(struct ea_list *ea_list); +bool split_stream_filename(TALLOC_CTX *ctx, + const char *filename_in, + char **filename_out, + char **streamname_out); /* The following definitions come from lib/dummyroot.c */ diff --git a/source3/lib/filename_util.c b/source3/lib/filename_util.c index 9cd348a..6ee91ec 100644 --- a/source3/lib/filename_util.c +++ b/source3/lib/filename_util.c @@ -70,35 +70,33 @@ struct smb_filename *synthetic_smb_fname(TALLOC_CTX *mem_ctx, } /** - * XXX: This is temporary and there should be no callers of this once - * smb_filename is plumbed through all path based operations. + * There are a few legitimate users of this. */ struct smb_filename *synthetic_smb_fname_split(TALLOC_CTX *ctx, - const char *fname, - const SMB_STRUCT_STAT *psbuf) + const char *fname, + bool posix_path) { - const char *stream_name = NULL; + char *stream_name = NULL; char *base_name = NULL; struct smb_filename *ret; + bool ok; - if (!lp_posix_pathnames()) { - stream_name = strchr_m(fname, ':'); + if (posix_path) { + /* No stream name looked for. */ + return synthetic_smb_fname(ctx, fname, NULL, NULL); } - /* Setup the base_name/stream_name. */ - if (stream_name) { - base_name = talloc_strndup(ctx, fname, - PTR_DIFF(stream_name, fname)); - } else { - base_name = talloc_strdup(ctx, fname); - } - - if (!base_name) { + ok = split_stream_filename(ctx, + fname, + &base_name, + &stream_name); + if (!ok) { return NULL; } - ret = synthetic_smb_fname(ctx, base_name, stream_name, psbuf); + ret = synthetic_smb_fname(ctx, base_name, stream_name, NULL); TALLOC_FREE(base_name); + TALLOC_FREE(stream_name); return ret; } @@ -280,3 +278,45 @@ bool ea_list_has_invalid_name(struct ea_list *ea_list) } return false; } + +/**************************************************************************** + Split an incoming name into tallocd filename and stream components. + Returns true on success, false on out of memory. +****************************************************************************/ + +bool split_stream_filename(TALLOC_CTX *ctx, + const char *filename_in, + char **filename_out, + char **streamname_out) +{ + const char *stream_name = NULL; + char *stream_out = NULL; + char *file_out = NULL; + + stream_name = strchr_m(filename_in, ':'); + + if (stream_name) { + stream_out = talloc_strdup(ctx, stream_name); + if (stream_out == NULL) { + return false; + } + file_out = talloc_strndup(ctx, + filename_in, + PTR_DIFF(stream_name, filename_in)); + } else { + file_out = talloc_strdup(ctx, filename_in); + } + + if (file_out == NULL) { + TALLOC_FREE(stream_out); + return false; + } + + if (filename_out) { + *filename_out = file_out; + } + if (streamname_out) { + *streamname_out = stream_out; + } + return true; +} diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 14eb53f..dffa71d 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -1423,11 +1423,12 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx, ZERO_STRUCT(st); st.st_ex_nlink = 1; *pp_smb_fname = synthetic_smb_fname_split(ctx, - name_in, - &st); + name_in, + (ucf_flags & UCF_POSIX_PATHNAMES)); if (*pp_smb_fname == NULL) { return NT_STATUS_NO_MEMORY; } + (*pp_smb_fname)->st = st; return NT_STATUS_OK; } diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c index 68bc3e7..4d95bcf 100644 --- a/source3/smbd/pysmbd.c +++ b/source3/smbd/pysmbd.c @@ -124,7 +124,9 @@ static NTSTATUS set_nt_acl_conn(const char *fname, so set our umask to 0 */ saved_umask = umask(0); - smb_fname = synthetic_smb_fname_split(fsp, fname, NULL); + smb_fname = synthetic_smb_fname_split(fsp, + fname, + lp_posix_pathnames()); if (smb_fname == NULL) { TALLOC_FREE(frame); umask(saved_umask); @@ -446,7 +448,9 @@ static PyObject *py_smbd_unlink(PyObject *self, PyObject *args, PyObject *kwargs return NULL; } - smb_fname = synthetic_smb_fname_split(frame, fname, NULL); + smb_fname = synthetic_smb_fname_split(frame, + fname, + lp_posix_pathnames()); if (smb_fname == NULL) { TALLOC_FREE(frame); return PyErr_NoMemory(); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index bb91d77..b88c2cf 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -6622,59 +6622,75 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, if (!conn->case_sensitive && conn->case_preserve && strequal(fsp->fsp_name->base_name, smb_fname_dst->base_name) && strequal(fsp->fsp_name->stream_name, smb_fname_dst->stream_name)) { - char *last_slash; - char *fname_dst_lcomp_base_mod = NULL; - struct smb_filename *smb_fname_orig_lcomp = NULL; + char *fname_dst_parent = NULL; + const char *fname_dst_lcomp = NULL; + char *orig_lcomp_path = NULL; + char *orig_lcomp_stream = NULL; + bool ok = true; /* - * Get the last component of the destination name. + * Split off the last component of the processed + * destination name. We will compare this to + * the split components of smb_fname_dst->original_lcomp. */ - last_slash = strrchr_m(smb_fname_dst->base_name, '/'); - if (last_slash) { - fname_dst_lcomp_base_mod = talloc_strdup(ctx, last_slash + 1); - } else { - fname_dst_lcomp_base_mod = talloc_strdup(ctx, smb_fname_dst->base_name); - } - if (!fname_dst_lcomp_base_mod) { + if (!parent_dirname(ctx, + smb_fname_dst->base_name, + &fname_dst_parent, + &fname_dst_lcomp)) { status = NT_STATUS_NO_MEMORY; goto out; } /* - * Create an smb_filename struct using the original last - * component of the destination. + * The original_lcomp component contains + * the last_component of the path + stream + * name (if a stream exists). + * + * Split off the stream name so we + * can check them separately. */ - smb_fname_orig_lcomp = synthetic_smb_fname_split( - ctx, smb_fname_dst->original_lcomp, NULL); - if (smb_fname_orig_lcomp == NULL) { + + if (fsp->posix_flags & FSP_POSIX_FLAGS_PATHNAMES) { + /* POSIX - no stream component. */ + orig_lcomp_path = talloc_strdup(ctx, + smb_fname_dst->original_lcomp); + if (orig_lcomp_path == NULL) { + ok = false; + } + } else { + ok = split_stream_filename(ctx, + smb_fname_dst->original_lcomp, + &orig_lcomp_path, + &orig_lcomp_stream); + } + + if (!ok) { + TALLOC_FREE(fname_dst_parent); status = NT_STATUS_NO_MEMORY; - TALLOC_FREE(fname_dst_lcomp_base_mod); goto out; } /* If the base names only differ by case, use original. */ - if(!strcsequal(fname_dst_lcomp_base_mod, - smb_fname_orig_lcomp->base_name)) { + if(!strcsequal(fname_dst_lcomp, orig_lcomp_path)) { char *tmp; /* * Replace the modified last component with the * original. */ - if (last_slash) { - *last_slash = '\0'; /* Truncate at the '/' */ + if (!ISDOT(fname_dst_parent)) { tmp = talloc_asprintf(smb_fname_dst, "%s/%s", - smb_fname_dst->base_name, - smb_fname_orig_lcomp->base_name); + fname_dst_parent, + orig_lcomp_path); } else { - tmp = talloc_asprintf(smb_fname_dst, - "%s", - smb_fname_orig_lcomp->base_name); + tmp = talloc_strdup(smb_fname_dst, + orig_lcomp_path); } if (tmp == NULL) { status = NT_STATUS_NO_MEMORY; - TALLOC_FREE(fname_dst_lcomp_base_mod); - TALLOC_FREE(smb_fname_orig_lcomp); + TALLOC_FREE(fname_dst_parent); + TALLOC_FREE(orig_lcomp_path); + TALLOC_FREE(orig_lcomp_stream); goto out; } TALLOC_FREE(smb_fname_dst->base_name); @@ -6683,22 +6699,23 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, /* If the stream_names only differ by case, use original. */ if(!strcsequal(smb_fname_dst->stream_name, - smb_fname_orig_lcomp->stream_name)) { - char *tmp = NULL; + orig_lcomp_stream)) { /* Use the original stream. */ - tmp = talloc_strdup(smb_fname_dst, - smb_fname_orig_lcomp->stream_name); + char *tmp = talloc_strdup(smb_fname_dst, + orig_lcomp_stream); if (tmp == NULL) { status = NT_STATUS_NO_MEMORY; - TALLOC_FREE(fname_dst_lcomp_base_mod); - TALLOC_FREE(smb_fname_orig_lcomp); + TALLOC_FREE(fname_dst_parent); + TALLOC_FREE(orig_lcomp_path); + TALLOC_FREE(orig_lcomp_stream); goto out; } TALLOC_FREE(smb_fname_dst->stream_name); smb_fname_dst->stream_name = tmp; } - TALLOC_FREE(fname_dst_lcomp_base_mod); - TALLOC_FREE(smb_fname_orig_lcomp); + TALLOC_FREE(fname_dst_parent); + TALLOC_FREE(orig_lcomp_path); + TALLOC_FREE(orig_lcomp_stream); } /* diff --git a/source3/smbd/smbXsrv_session.c b/source3/smbd/smbXsrv_session.c index a5aee8c..cdad47f 100644 --- a/source3/smbd/smbXsrv_session.c +++ b/source3/smbd/smbXsrv_session.c @@ -833,6 +833,10 @@ static void smbXsrv_session_global_verify_record(struct db_record *db_rec, hex_encode_talloc(frame, key.dptr, key.dsize), nt_errstr(status))); TALLOC_FREE(frame); + *is_free = true; + if (was_free) { + *was_free = true; + } return; } @@ -848,6 +852,10 @@ static void smbXsrv_session_global_verify_record(struct db_record *db_rec, global_blob.version)); NDR_PRINT_DEBUG(smbXsrv_session_globalB, &global_blob); TALLOC_FREE(frame); + *is_free = true; + if (was_free) { + *was_free = true; + } return; } diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c index 4bd5417..7c49ce7 100644 --- a/source3/torture/cmd_vfs.c +++ b/source3/torture/cmd_vfs.c @@ -354,7 +354,9 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c } fsp->conn = vfs->conn; - smb_fname = synthetic_smb_fname_split(NULL, argv[1], NULL); + smb_fname = synthetic_smb_fname_split(NULL, + argv[1], + lp_posix_pathnames()); if (smb_fname == NULL) { TALLOC_FREE(fsp); return NT_STATUS_NO_MEMORY; @@ -584,12 +586,16 @@ static NTSTATUS cmd_rename(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, return NT_STATUS_OK; } - smb_fname_src = synthetic_smb_fname_split(mem_ctx, argv[1], NULL); + smb_fname_src = synthetic_smb_fname_split(mem_ctx, + argv[1], + lp_posix_pathnames()); if (smb_fname_src == NULL) { return NT_STATUS_NO_MEMORY; } - smb_fname_dst = synthetic_smb_fname_split(mem_ctx, argv[2], NULL); + smb_fname_dst = synthetic_smb_fname_split(mem_ctx, + argv[2], + lp_posix_pathnames()); if (smb_fname_dst == NULL) { TALLOC_FREE(smb_fname_src); return NT_STATUS_NO_MEMORY; @@ -644,7 +650,9 @@ static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c return NT_STATUS_OK; } - smb_fname = synthetic_smb_fname_split(mem_ctx, argv[1], NULL); + smb_fname = synthetic_smb_fname_split(mem_ctx, + argv[1], + lp_posix_pathnames()); if (smb_fname == NULL) { return NT_STATUS_NO_MEMORY; } @@ -783,7 +791,9 @@ static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, return NT_STATUS_OK; } - smb_fname = synthetic_smb_fname_split(mem_ctx, argv[1], NULL); + smb_fname = synthetic_smb_fname_split(mem_ctx, + argv[1], + lp_posix_pathnames()); if (smb_fname == NULL) { return NT_STATUS_NO_MEMORY; } @@ -1043,7 +1053,9 @@ static NTSTATUS cmd_utime(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, ft.atime = convert_time_t_to_timespec(atoi(argv[2])); ft.mtime = convert_time_t_to_timespec(atoi(argv[3])); - smb_fname = synthetic_smb_fname_split(mem_ctx, argv[1], NULL); + smb_fname = synthetic_smb_fname_split(mem_ctx, + argv[1], + lp_posix_pathnames()); if (smb_fname == NULL) { return NT_STATUS_NO_MEMORY; } @@ -1530,7 +1542,9 @@ static NTSTATUS cmd_set_nt_acl(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int a } fsp->conn = vfs->conn; - smb_fname = synthetic_smb_fname_split(NULL, argv[1], NULL); + smb_fname = synthetic_smb_fname_split(NULL, + argv[1], + lp_posix_pathnames()); if (smb_fname == NULL) { TALLOC_FREE(fsp); return NT_STATUS_NO_MEMORY; -- Samba Shared Repository