struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
const struct file_id id,
const char *servicepath,
- const char *fname,
+ const struct smb_filename *smb_fname,
const struct timespec *old_write_time);
struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
- const struct file_id id,
- const char *servicepath,
- const char *fname);
+ const struct file_id id);
bool rename_share_filename(struct messaging_context *msg_ctx,
struct share_mode_lock *lck,
const char *servicepath,
- const char *newname);
+ const struct smb_filename *smb_fname);
void get_file_infos(struct file_id id,
bool *delete_on_close,
struct timespec *write_time);
NTSTATUS fcb_or_dos_open(struct smb_request *req,
connection_struct *conn,
files_struct *fsp_to_dup_into,
- const char *fname,
+ const struct smb_filename *smb_fname,
struct file_id id,
uint16 file_pid,
uint16 vuid,
struct share_mode_lock {
const char *servicepath; /* canonicalized. */
- const char *filename;
+ const char *base_name;
+ const char *stream_name;
struct file_id id;
int num_share_modes;
struct share_mode_entry *share_modes;
(lck->num_share_modes * sizeof(struct share_mode_entry)) +
data.u.s.delete_token_size;
- lck->filename = (const char *)dbuf.dptr + sizeof(struct locking_data) +
+ lck->base_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
(lck->num_share_modes * sizeof(struct share_mode_entry)) +
data.u.s.delete_token_size +
strlen(lck->servicepath) + 1;
+ lck->stream_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
+ (lck->num_share_modes * sizeof(struct share_mode_entry)) +
+ data.u.s.delete_token_size +
+ strlen(lck->servicepath) + 1 +
+ strlen(lck->base_name) + 1;
+
/*
* Ensure that each entry has a real process attached.
*/
int i;
struct locking_data *data;
ssize_t offset;
- ssize_t sp_len;
+ ssize_t sp_len, bn_len, sn_len;
uint32 delete_token_size;
result.dptr = NULL;
}
sp_len = strlen(lck->servicepath);
+ bn_len = strlen(lck->base_name);
+ sn_len = lck->stream_name != NULL ? strlen(lck->stream_name) : 0;
+
delete_token_size = (lck->delete_token ?
(sizeof(uid_t) + sizeof(gid_t) + (lck->delete_token->ngroups*sizeof(gid_t))) : 0);
lck->num_share_modes * sizeof(struct share_mode_entry) +
delete_token_size +
sp_len + 1 +
- strlen(lck->filename) + 1;
+ bn_len + 1 +
+ sn_len + 1;
result.dptr = TALLOC_ARRAY(lck, uint8, result.dsize);
if (result.dptr == NULL) {
safe_strcpy((char *)result.dptr + offset, lck->servicepath,
result.dsize - offset - 1);
offset += sp_len + 1;
- safe_strcpy((char *)result.dptr + offset, lck->filename,
+ safe_strcpy((char *)result.dptr + offset, lck->base_name,
+ result.dsize - offset - 1);
+ offset += bn_len + 1;
+ safe_strcpy((char *)result.dptr + offset, lck->stream_name,
result.dsize - offset - 1);
if (DEBUGLEVEL >= 10) {
static bool fill_share_mode_lock(struct share_mode_lock *lck,
struct file_id id,
const char *servicepath,
- const char *fname,
+ const struct smb_filename *smb_fname,
TDB_DATA share_mode_data,
const struct timespec *old_write_time)
{
valid even if parse_share_modes fails. */
lck->servicepath = NULL;
- lck->filename = NULL;
+ lck->base_name = NULL;
+ lck->stream_name = NULL;
lck->id = id;
lck->num_share_modes = 0;
lck->share_modes = NULL;
lck->fresh = (share_mode_data.dptr == NULL);
if (lck->fresh) {
- if (fname == NULL || servicepath == NULL
+ bool has_stream;
+ if (smb_fname == NULL || servicepath == NULL
|| old_write_time == NULL) {
return False;
}
- lck->filename = talloc_strdup(lck, fname);
+
+ has_stream = smb_fname->stream_name != NULL;
+
+ lck->base_name = talloc_strdup(lck, smb_fname->base_name);
+ lck->stream_name = talloc_strdup(lck, smb_fname->stream_name);
lck->servicepath = talloc_strdup(lck, servicepath);
- if (lck->filename == NULL || lck->servicepath == NULL) {
+ if (lck->base_name == NULL ||
+ (has_stream && lck->stream_name == NULL) ||
+ lck->servicepath == NULL) {
DEBUG(0, ("talloc failed\n"));
return False;
}
struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
const struct file_id id,
const char *servicepath,
- const char *fname,
+ const struct smb_filename *smb_fname,
const struct timespec *old_write_time)
{
struct share_mode_lock *lck;
return NULL;
}
- if (!fill_share_mode_lock(lck, id, servicepath, fname,
+ if (!fill_share_mode_lock(lck, id, servicepath, smb_fname,
lck->record->value, old_write_time)) {
DEBUG(3, ("fill_share_mode_lock failed\n"));
TALLOC_FREE(lck);
}
struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
- const struct file_id id,
- const char *servicepath,
- const char *fname)
+ const struct file_id id)
{
struct share_mode_lock *lck;
struct file_id tmp;
return NULL;
}
- if (!fill_share_mode_lock(lck, id, servicepath, fname, data, NULL)) {
+ if (!fill_share_mode_lock(lck, id, NULL, NULL, data, NULL)) {
DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
"around (file not open)\n"));
TALLOC_FREE(lck);
bool rename_share_filename(struct messaging_context *msg_ctx,
struct share_mode_lock *lck,
const char *servicepath,
- const char *newname)
+ const struct smb_filename *smb_fname_dst)
{
size_t sp_len;
- size_t fn_len;
+ size_t bn_len;
+ size_t sn_len;
size_t msg_len;
char *frm = NULL;
int i;
+ bool strip_two_chars = false;
+ bool has_stream = smb_fname_dst->stream_name != NULL;
DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
- servicepath, newname));
+ servicepath, smb_fname_dst->base_name));
/*
* rename_internal_fsp() and rename_internals() add './' to
* head of newname if newname does not contain a '/'.
*/
- while (newname[0] && newname[1] && newname[0] == '.' && newname[1] == '/') {
- newname += 2;
+ if (smb_fname_dst->base_name[0] &&
+ smb_fname_dst->base_name[1] &&
+ smb_fname_dst->base_name[0] == '.' &&
+ smb_fname_dst->base_name[1] == '/') {
+ strip_two_chars = true;
}
lck->servicepath = talloc_strdup(lck, servicepath);
- lck->filename = talloc_strdup(lck, newname);
- if (lck->filename == NULL || lck->servicepath == NULL) {
+ lck->base_name = talloc_strdup(lck, smb_fname_dst->base_name +
+ (strip_two_chars ? 2 : 0));
+ lck->stream_name = talloc_strdup(lck, smb_fname_dst->stream_name);
+ if (lck->base_name == NULL ||
+ (has_stream && lck->stream_name == NULL) ||
+ lck->servicepath == NULL) {
DEBUG(0, ("rename_share_filename: talloc failed\n"));
return False;
}
lck->modified = True;
sp_len = strlen(lck->servicepath);
- fn_len = strlen(lck->filename);
+ bn_len = strlen(lck->base_name);
+ sn_len = has_stream ? strlen(lck->stream_name) : 0;
- msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + fn_len + 1;
+ msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
+ sn_len + 1;
/* Set up the name changed message. */
frm = TALLOC_ARRAY(lck, char, msg_len);
DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
safe_strcpy(&frm[24], lck->servicepath, sp_len);
- safe_strcpy(&frm[24 + sp_len + 1], lck->filename, fn_len);
+ safe_strcpy(&frm[24 + sp_len + 1], lck->base_name, bn_len);
+ safe_strcpy(&frm[24 + sp_len + 1 + bn_len + 1], lck->stream_name,
+ sn_len);
/* Send the messages. */
for (i=0; i<lck->num_share_modes; i++) {
continue;
}
- DEBUG(10,("rename_share_filename: sending rename message to pid %s "
- "file_id %s sharepath %s newname %s\n",
+ DEBUG(10,("rename_share_filename: sending rename message to "
+ "pid %s file_id %s sharepath %s base_name %s "
+ "stream_name %s\n",
procid_str_static(&se->pid),
file_id_string_tos(&lck->id),
- lck->servicepath, lck->filename ));
+ lck->servicepath, lck->base_name,
+ has_stream ? lck->stream_name : ""));
messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
(uint8 *)frm, msg_len);
ZERO_STRUCTP(write_time);
}
- if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id, NULL, NULL))) {
+ if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
return;
}
int granted_oplock;
uint64_t oplock_callback_id = 0;
uint32 createfile_attributes = 0;
- char *fname = NULL;
ZERO_STRUCT(id);
- status = get_full_smb_filename(talloc_tos(), smb_fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
if (conn->printer) {
/*
* Printers are handled completely differently.
DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
smb_fname_str_dbg(smb_fname)));
- return print_fsp_open(req, conn, fname, req->vuid, fsp,
- &smb_fname->st);
+ return print_fsp_open(req, conn, smb_fname->base_name,
+ req->vuid, fsp, &smb_fname->st);
}
if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
lck = get_share_mode_lock(talloc_tos(), id,
conn->connectpath,
- fname, &old_write_time);
+ smb_fname, &old_write_time);
if (lck == NULL) {
DEBUG(0, ("Could not get share mode lock\n"));
id = vfs_file_id_from_sbuf(conn,
&smb_fname->st);
if (!(lck = get_share_mode_lock(talloc_tos(),
- id, conn->connectpath, fname,
+ id, conn->connectpath, smb_fname,
&old_write_time))) {
/*
* Emergency exit
status = fcb_or_dos_open(req,
conn,
fsp,
- fname,
+ smb_fname,
id,
req->smbpid,
req->vuid,
lck = get_share_mode_lock(talloc_tos(), id,
conn->connectpath,
- fname, &old_write_time);
+ smb_fname, &old_write_time);
if (lck == NULL) {
DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
* semantics and to make smbstatus more useful.
*/
lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
- conn->connectpath, smb_dname->base_name,
- &mtimespec);
+ conn->connectpath, smb_dname, &mtimespec);
if (lck == NULL) {
DEBUG(0, ("onefs_open_directory: Could not get share mode "
NTSTATUS fcb_or_dos_open(struct smb_request *req,
connection_struct *conn,
files_struct *fsp_to_dup_into,
- const char *fname,
+ const struct smb_filename *smb_fname,
struct file_id id,
uint16 file_pid,
uint16 vuid,
uint32 create_options)
{
files_struct *fsp;
+ char *fname = NULL;
+ NTSTATUS status;
+
+ status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
- "file %s.\n", fname ));
+ "file %s.\n", smb_fname_str_dbg(smb_fname)));
for(fsp = file_find_di_first(id); fsp;
fsp = file_find_di_next(fsp)) {
}
/* quite an insane set of semantics ... */
- if (is_executable(fname) &&
+ if (is_executable(smb_fname->base_name) &&
(fsp->fh->private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) {
DEBUG(10,("fcb_or_dos_open: file fail due to is_executable.\n"));
return NT_STATUS_INVALID_PARAMETER;
uint32 open_access_mask = access_mask;
NTSTATUS status;
int ret_flock;
- char *fname = NULL;
char *parent_dir;
ZERO_STRUCT(id);
- status = get_full_smb_filename(talloc_tos(), smb_fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
if (conn->printer) {
/*
* Printers are handled completely differently.
return NT_STATUS_INTERNAL_ERROR;
}
- return print_fsp_open(req, conn, fname, req->vuid, fsp,
- &smb_fname->st);
+ return print_fsp_open(req, conn, smb_fname->base_name,
+ req->vuid, fsp, &smb_fname->st);
}
if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
lck = get_share_mode_lock(talloc_tos(), id,
conn->connectpath,
- fname, &old_write_time);
+ smb_fname, &old_write_time);
if (lck == NULL) {
DEBUG(0, ("Could not get share mode lock\n"));
status = fcb_or_dos_open(req,
conn,
fsp,
- fname,
+ smb_fname,
id,
req->smbpid,
req->vuid,
lck = get_share_mode_lock(talloc_tos(), id,
conn->connectpath,
- fname, &old_write_time);
+ smb_fname, &old_write_time);
if (lck == NULL) {
DEBUG(0, ("open_file_ntcreate: Could not get share "
mtimespec = smb_dname->st.st_ex_mtime;
lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
- conn->connectpath, smb_dname->base_name,
- &mtimespec);
+ conn->connectpath, smb_dname, &mtimespec);
if (lck == NULL) {
DEBUG(0, ("open_directory: Could not get share mode lock for "
char *frm = (char *)data->data;
struct file_id id;
const char *sharepath;
- const char *newname;
- size_t sp_len;
+ const char *base_name;
+ const char *stream_name;
+ struct smb_filename *smb_fname = NULL;
+ size_t sp_len, bn_len;
+ NTSTATUS status;
if (data->data == NULL
|| data->length < MSG_FILE_RENAMED_MIN_SIZE + 2) {
/* Unpack the message. */
pull_file_id_24(frm, &id);
sharepath = &frm[24];
- newname = sharepath + strlen(sharepath) + 1;
sp_len = strlen(sharepath);
+ base_name = sharepath + sp_len + 1;
+ bn_len = strlen(base_name);
+ stream_name = sharepath + sp_len + 1 + bn_len + 1;
+
+ status = create_synthetic_smb_fname(talloc_tos(), base_name,
+ stream_name, NULL, &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return;
+ }
DEBUG(10,("msg_file_was_renamed: Got rename message for sharepath %s, new name %s, "
"file_id %s\n",
- sharepath, newname, file_id_string_tos(&id)));
+ sharepath, smb_fname_str_dbg(smb_fname),
+ file_id_string_tos(&id)));
for(fsp = file_find_di_first(id); fsp; fsp = file_find_di_next(fsp)) {
if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) {
- DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n",
- fsp->fnum, fsp->fsp_name, newname ));
+ char *newname = NULL;
+
+ DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n",
+ fsp->fnum, fsp->fsp_name,
+ smb_fname_str_dbg(smb_fname)));
+ status = get_full_smb_filename(talloc_tos(),
+ smb_fname, &newname);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
string_set(&fsp->fsp_name, newname);
+ TALLOC_FREE(newname);
} else {
/* TODO. JRA. */
/* Now we have the complete path we can work out if this is
sharepath,
fsp->fnum,
fsp->fsp_name,
- newname ));
+ smb_fname_str_dbg(smb_fname)));
}
}
+ out:
+ TALLOC_FREE(smb_fname);
+ return;
}
struct case_semantics_state {
char *fname_dst = NULL;
NTSTATUS status;
- status = get_full_smb_filename(talloc_tos(), smb_fname_dst,
- &fname_dst);
- if (!NT_STATUS_IS_OK(status)) {
- return;
- }
-
for(fsp = file_find_di_first(lck->id); fsp;
fsp = file_find_di_next(fsp)) {
/* fsp_name is a relative path under the fsp. To change this for other
"(file_id %s) from %s -> %s\n", fsp->fnum,
file_id_string_tos(&fsp->file_id), fsp->fsp_name,
smb_fname_str_dbg(smb_fname_dst)));
+
+ status = get_full_smb_filename(talloc_tos(), smb_fname_dst,
+ &fname_dst);
+ if (!NT_STATUS_IS_OK(status)) {
+ return;
+ }
string_set(&fsp->fsp_name, fname_dst);
did_rename = True;
+ TALLOC_FREE(fname_dst);
}
if (!did_rename) {
/* Send messages to all smbd's (not ourself) that the name has changed. */
rename_share_filename(smbd_messaging_context(), lck, conn->connectpath,
- fname_dst);
- TALLOC_FREE(fname_dst);
+ smb_fname_dst);
+
}
/****************************************************************************
};
const char *desc="X";
const char *sharepath = "";
- const char *fname = "";
+ char *fname = NULL;
struct share_mode_lock *share_mode;
if (count==0) {
}
count++;
- share_mode = fetch_share_mode_unlocked(NULL, id, "__unspecified__", "__unspecified__");
+ share_mode = fetch_share_mode_unlocked(NULL, id);
if (share_mode) {
- sharepath = share_mode->servicepath;
- fname = share_mode->filename;
+ bool has_stream = share_mode->stream_name != NULL;
+
+ fname = talloc_asprintf(NULL, "%s%s%s", share_mode->base_name,
+ has_stream ? ":" : "",
+ has_stream ? share_mode->stream_name :
+ "");
+ } else {
+ fname = talloc_strdup(NULL, "");
+ if (fname == NULL) {
+ return;
+ }
}
for (i=0;i<ARRAY_SIZE(lock_types);i++) {
(double)start, (double)size,
sharepath, fname);
+ TALLOC_FREE(fname);
TALLOC_FREE(share_mode);
}