s4:kdc: Implement KDC plugin hardware authentication policy
[samba.git] / source3 / modules / vfs_streams_xattr.c
index 3e39770bb378091f4752b2b3e4e562224a650693..03ff6147cb030bd56829670bbdc72f8c22fd5ba4 100644 (file)
@@ -74,17 +74,15 @@ static NTSTATUS streams_xattr_get_name(vfs_handle_struct *handle,
                                       const char *stream_name,
                                       char **xattr_name)
 {
-       char *sname;
+       size_t stream_name_len = strlen(stream_name);
        char *stype;
        struct streams_xattr_config *config;
 
        SMB_VFS_HANDLE_GET_DATA(handle, config, struct streams_xattr_config,
                                return NT_STATUS_UNSUCCESSFUL);
 
-       sname = talloc_strdup(ctx, stream_name + 1);
-       if (sname == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
+       SMB_ASSERT(stream_name[0] == ':');
+       stream_name += 1;
 
        /*
         * With vfs_fruit option "fruit:encoding = native" we're
@@ -100,34 +98,32 @@ static NTSTATUS streams_xattr_get_name(vfs_handle_struct *handle,
         * In check_path_syntax() we've already ensured the streamname
         * we got from the client is valid.
         */
-       stype = strrchr_m(sname, ':');
+       stype = strrchr_m(stream_name, ':');
 
        if (stype) {
                /*
                 * We only support one stream type: "$DATA"
                 */
                if (strcasecmp_m(stype, ":$DATA") != 0) {
-                       talloc_free(sname);
                        return NT_STATUS_INVALID_PARAMETER;
                }
 
                /* Split name and type */
-               stype[0] = '\0';
+               stream_name_len = (stype - stream_name);
        }
 
-       *xattr_name = talloc_asprintf(ctx, "%s%s%s",
+       *xattr_name = talloc_asprintf(ctx, "%s%.*s%s",
                                      config->prefix,
-                                     sname,
+                                     (int)stream_name_len,
+                                     stream_name,
                                      config->store_stream_type ? ":$DATA" : "");
        if (*xattr_name == NULL) {
-               talloc_free(sname);
                return NT_STATUS_NO_MEMORY;
        }
 
        DEBUG(10, ("xattr_name: %s, stream_name: %s\n", *xattr_name,
                   stream_name));
 
-       talloc_free(sname);
        return NT_STATUS_OK;
 }
 
@@ -315,8 +311,7 @@ static int streams_xattr_openat(struct vfs_handle_struct *handle,
                                const struct files_struct *dirfsp,
                                const struct smb_filename *smb_fname,
                                files_struct *fsp,
-                               int flags,
-                               mode_t mode)
+                               const struct vfs_open_how *how)
 {
        NTSTATUS status;
        struct streams_xattr_config *config = NULL;
@@ -332,18 +327,23 @@ static int streams_xattr_openat(struct vfs_handle_struct *handle,
 
        DBG_DEBUG("called for %s with flags 0x%x\n",
                  smb_fname_str_dbg(smb_fname),
-                 flags);
+                 how->flags);
 
        if (!is_named_stream(smb_fname)) {
                return SMB_VFS_NEXT_OPENAT(handle,
                                           dirfsp,
                                           smb_fname,
                                           fsp,
-                                          flags,
-                                          mode);
+                                          how);
+       }
+
+       if (how->resolve != 0) {
+               errno = ENOSYS;
+               return -1;
        }
 
        SMB_ASSERT(fsp_is_alternate_stream(fsp));
+       SMB_ASSERT(dirfsp == NULL);
 
        status = streams_xattr_get_name(handle, talloc_tos(),
                                        smb_fname->stream_name, &xattr_name);
@@ -372,7 +372,7 @@ static int streams_xattr_openat(struct vfs_handle_struct *handle,
                        goto fail;
                }
 
-               if (!(flags & O_CREAT)) {
+               if (!(how->flags & O_CREAT)) {
                        errno = ENOATTR;
                        goto fail;
                }
@@ -380,7 +380,7 @@ static int streams_xattr_openat(struct vfs_handle_struct *handle,
                set_empty_xattr = true;
        }
 
-       if (flags & O_TRUNC) {
+       if (how->flags & O_TRUNC) {
                set_empty_xattr = true;
        }
 
@@ -400,7 +400,7 @@ static int streams_xattr_openat(struct vfs_handle_struct *handle,
                ret = SMB_VFS_FSETXATTR(fsp->base_fsp,
                                       xattr_name,
                                       &null, sizeof(null),
-                                      flags & O_EXCL ? XATTR_CREATE : 0);
+                                      how->flags & O_EXCL ? XATTR_CREATE : 0);
                if (ret != 0) {
                        goto fail;
                }
@@ -1535,6 +1535,38 @@ static bool streams_xattr_strict_lock_check(struct vfs_handle_struct *handle,
        return true;
 }
 
+static int streams_xattr_fcntl(vfs_handle_struct *handle,
+                              files_struct *fsp,
+                              int cmd,
+                              va_list cmd_arg)
+{
+       va_list dup_cmd_arg;
+       void *arg;
+       int ret;
+
+       if (fsp_is_alternate_stream(fsp)) {
+               switch (cmd) {
+               case F_GETFL:
+               case F_SETFL:
+                       break;
+               default:
+                       DBG_ERR("Unsupported fcntl() cmd [%d] on [%s]\n",
+                               cmd, fsp_str_dbg(fsp));
+                       errno = EINVAL;
+                       return -1;
+               }
+       }
+
+       va_copy(dup_cmd_arg, cmd_arg);
+       arg = va_arg(dup_cmd_arg, void *);
+
+       ret = SMB_VFS_NEXT_FCNTL(handle, fsp, cmd, arg);
+
+       va_end(dup_cmd_arg);
+
+       return ret;
+}
+
 static struct vfs_fn_pointers vfs_streams_xattr_fns = {
        .fs_capabilities_fn = streams_xattr_fs_capabilities,
        .connect_fn = streams_xattr_connect,
@@ -1563,6 +1595,7 @@ static struct vfs_fn_pointers vfs_streams_xattr_fns = {
        .filesystem_sharemode_fn = streams_xattr_filesystem_sharemode,
        .linux_setlease_fn = streams_xattr_linux_setlease,
        .strict_lock_check_fn = streams_xattr_strict_lock_check,
+       .fcntl_fn = streams_xattr_fcntl,
 
        .fchown_fn = streams_xattr_fchown,
        .fchmod_fn = streams_xattr_fchmod,