* enumerate streams using the vfs_streaminfo interface and then want to
* operate on each stream.
*/
-NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name,
- const char *stream_name,
- const SMB_STRUCT_STAT *psbuf,
- struct smb_filename **smb_fname_out)
+struct smb_filename *synthetic_smb_fname(TALLOC_CTX *mem_ctx,
+ const char *base_name,
+ const char *stream_name,
+ const SMB_STRUCT_STAT *psbuf)
{
- struct smb_filename smb_fname_loc;
-
- ZERO_STRUCT(smb_fname_loc);
+ struct smb_filename smb_fname_loc = { 0, };
/* Setup the base_name/stream_name. */
smb_fname_loc.base_name = discard_const_p(char, base_name);
if (psbuf)
smb_fname_loc.st = *psbuf;
- /* Let copy_smb_filename() do the heavy lifting. */
- return copy_smb_filename(ctx, &smb_fname_loc, smb_fname_out);
+ /* Let cp_smb_filename() do the heavy lifting. */
+ return cp_smb_filename(mem_ctx, &smb_fname_loc);
}
/**
* XXX: This is temporary and there should be no callers of this once
* smb_filename is plumbed through all path based operations.
*/
-NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx,
- const char *fname,
- const SMB_STRUCT_STAT *psbuf,
- struct smb_filename **smb_fname_out)
+struct smb_filename *synthetic_smb_fname_split(TALLOC_CTX *ctx,
+ const char *fname,
+ const SMB_STRUCT_STAT *psbuf)
{
- NTSTATUS status;
const char *stream_name = NULL;
char *base_name = NULL;
+ struct smb_filename *ret;
if (!lp_posix_pathnames()) {
stream_name = strchr_m(fname, ':');
}
if (!base_name) {
- return NT_STATUS_NO_MEMORY;
+ return NULL;
}
- status = create_synthetic_smb_fname(ctx, base_name, stream_name, psbuf,
- smb_fname_out);
+ ret = synthetic_smb_fname(ctx, base_name, stream_name, psbuf);
TALLOC_FREE(base_name);
- return status;
+ return ret;
}
/**
const struct smb_filename *in)
{
struct smb_filename *out;
+ size_t base_len = 0;
+ size_t stream_len = 0;
+ size_t lcomp_len = 0;
+ int num = 0;
/* stream_name must always be NULL if there is no stream. */
if (in->stream_name) {
SMB_ASSERT(in->stream_name[0] != '\0');
}
- out = talloc_zero(mem_ctx, struct smb_filename);
+ if (in->base_name != NULL) {
+ base_len = strlen(in->base_name) + 1;
+ num += 1;
+ }
+ if (in->stream_name != NULL) {
+ stream_len = strlen(in->stream_name) + 1;
+ num += 1;
+ }
+ if (in->original_lcomp != NULL) {
+ lcomp_len = strlen(in->original_lcomp) + 1;
+ num += 1;
+ }
+
+ out = talloc_pooled_object(mem_ctx, struct smb_filename,
+ num, stream_len + base_len + lcomp_len);
if (out == NULL) {
return NULL;
}
+ ZERO_STRUCTP(out);
+
+ /*
+ * The following allocations cannot fails as we
+ * pre-allocated space for them in the out pooled
+ * object.
+ */
if (in->base_name != NULL) {
- out->base_name = talloc_strdup(out, in->base_name);
- if (out->base_name == NULL) {
- goto fail;
- }
+ out->base_name = talloc_memdup(
+ out, in->base_name, base_len);
}
if (in->stream_name != NULL) {
- out->stream_name = talloc_strdup(out, in->stream_name);
- if (out->stream_name == NULL) {
- goto fail;
- }
+ out->stream_name = talloc_memdup(
+ out, in->stream_name, stream_len);
}
if (in->original_lcomp != NULL) {
- out->original_lcomp = talloc_strdup(out, in->original_lcomp);
- if (out->original_lcomp == NULL) {
- goto fail;
- }
+ out->original_lcomp = talloc_memdup(
+ out, in->original_lcomp, lcomp_len);
}
out->st = in->st;
return out;
-fail:
- TALLOC_FREE(out);
- return NULL;
-}
-
-NTSTATUS copy_smb_filename(TALLOC_CTX *ctx,
- const struct smb_filename *smb_fname_in,
- struct smb_filename **smb_fname_out)
-{
- *smb_fname_out = cp_smb_filename(ctx, smb_fname_in);
- if (*smb_fname_out == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
- return NT_STATUS_OK;
}
/****************************************************************************
return strcasecmp_m(smb_fname->stream_name, "::$DATA") == 0;
}
+
+/****************************************************************************
+ Filter out Windows invalid EA names (list probed from Windows 2012).
+****************************************************************************/
+
+static char bad_ea_name_chars[] = "\"*+,/:;<=>?[\\]|";
+
+bool is_invalid_windows_ea_name(const char *name)
+{
+ int i;
+ /* EA name is pulled as ascii so we can examine
+ individual bytes here. */
+ for (i = 0; name[i] != 0; i++) {
+ int val = (name[i] & 0xff);
+ if (val < ' ' || strchr(bad_ea_name_chars, val)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ea_list_has_invalid_name(struct ea_list *ea_list)
+{
+ if (lp_posix_pathnames()) {
+ return false;
+ }
+
+ for (;ea_list; ea_list = ea_list->next) {
+ if (is_invalid_windows_ea_name(ea_list->ea.name)) {
+ return true;
+ }
+ }
+ return false;
+}