s3:vfs_nfs4acl_xattr: make use of lp_parm_substituted_string()
[samba.git] / source3 / modules / vfs_nfs4acl_xattr.c
1 /*
2  * Convert NFSv4 acls stored per http://www.suse.de/~agruen/nfs4acl/ to NT acls and vice versa.
3  *
4  * Copyright (C) Jiri Sasek, 2007
5  * based on the foobar.c module which is copyrighted by Volker Lendecke
6  * based on pvfs_acl_nfs4.c  Copyright (C) Andrew Tridgell 2006
7  *
8  * based on vfs_fake_acls:
9  * Copyright (C) Tim Potter, 1999-2000
10  * Copyright (C) Alexander Bokovoy, 2002
11  * Copyright (C) Andrew Bartlett, 2002,2012
12  * Copyright (C) Ralph Boehme 2017
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, see <http://www.gnu.org/licenses/>.
26  *
27  */
28
29 #include "includes.h"
30 #include "system/filesys.h"
31 #include "smbd/smbd.h"
32 #include "libcli/security/security_token.h"
33 #include "libcli/security/dom_sid.h"
34 #include "nfs4_acls.h"
35 #include "librpc/gen_ndr/ndr_nfs4acl.h"
36 #include "nfs4acl_xattr.h"
37 #include "nfs4acl_xattr_ndr.h"
38 #include "nfs4acl_xattr_xdr.h"
39 #include "nfs4acl_xattr_nfs.h"
40
41 #undef DBGC_CLASS
42 #define DBGC_CLASS DBGC_VFS
43
44 static const struct enum_list nfs4acl_encoding[] = {
45         {NFS4ACL_ENCODING_NDR, "ndr"},
46         {NFS4ACL_ENCODING_XDR, "xdr"},
47         {NFS4ACL_ENCODING_NFS, "nfs"},
48 };
49
50 /*
51  * Check if someone changed the POSIX mode, for files we expect 0666, for
52  * directories 0777. Discard the ACL blob if the mode is different.
53  */
54 static bool nfs4acl_validate_blob(vfs_handle_struct *handle,
55                                   const struct smb_filename *smb_fname)
56 {
57         struct nfs4acl_config *config = NULL;
58         mode_t expected_mode;
59         int ret;
60
61         SMB_VFS_HANDLE_GET_DATA(handle, config,
62                                 struct nfs4acl_config,
63                                 return false);
64
65         if (!config->validate_mode) {
66                 return true;
67         }
68
69         if (!VALID_STAT(smb_fname->st)) {
70                 /* might be a create */
71                 return true;
72         }
73
74         if (S_ISDIR(smb_fname->st.st_ex_mode)) {
75                 expected_mode = 0777;
76         } else {
77                 expected_mode = 0666;
78         }
79         if ((smb_fname->st.st_ex_mode & expected_mode) == expected_mode) {
80                 return true;
81         }
82
83         ret = SMB_VFS_NEXT_REMOVEXATTR(handle,
84                                        smb_fname,
85                                        config->xattr_name);
86         if (ret != 0 && errno != ENOATTR) {
87                 DBG_ERR("Removing NFS4 xattr failed: %s\n", strerror(errno));
88                 return false;
89         }
90
91         return true;
92 }
93
94 static NTSTATUS nfs4acl_get_blob(struct vfs_handle_struct *handle,
95                                  files_struct *fsp,
96                                  const struct smb_filename *smb_fname_in,
97                                  TALLOC_CTX *mem_ctx,
98                                  DATA_BLOB *blob)
99 {
100         struct nfs4acl_config *config = NULL;
101         const struct smb_filename *smb_fname = NULL;
102         size_t allocsize = 256;
103         ssize_t length;
104         bool ok;
105
106         SMB_VFS_HANDLE_GET_DATA(handle, config,
107                                 struct nfs4acl_config,
108                                 return NT_STATUS_INTERNAL_ERROR);
109
110         *blob = data_blob_null;
111
112         if (fsp == NULL && smb_fname_in == NULL) {
113                 return NT_STATUS_INTERNAL_ERROR;
114         }
115         smb_fname = smb_fname_in;
116         if (smb_fname == NULL) {
117                 smb_fname = fsp->fsp_name;
118         }
119         if (smb_fname == NULL) {
120                 return NT_STATUS_INTERNAL_ERROR;
121         }
122
123         ok = nfs4acl_validate_blob(handle, smb_fname);
124         if (!ok) {
125                 return NT_STATUS_INTERNAL_ERROR;
126         }
127
128         do {
129
130                 allocsize *= 4;
131                 ok = data_blob_realloc(mem_ctx, blob, allocsize);
132                 if (!ok) {
133                         return NT_STATUS_NO_MEMORY;
134                 }
135
136                 if (fsp != NULL && fsp->fh->fd != -1) {
137                         length = SMB_VFS_NEXT_FGETXATTR(handle,
138                                                         fsp,
139                                                         config->xattr_name,
140                                                         blob->data,
141                                                         blob->length);
142                 } else {
143                         length = SMB_VFS_NEXT_GETXATTR(handle,
144                                                        smb_fname,
145                                                        config->xattr_name,
146                                                        blob->data,
147                                                        blob->length);
148                 }
149         } while (length == -1 && errno == ERANGE && allocsize <= 65536);
150
151         if (length == -1) {
152                 return map_nt_error_from_unix(errno);
153         }
154
155         return NT_STATUS_OK;
156 }
157
158 static NTSTATUS nfs4acl_xattr_default_sd(
159         struct vfs_handle_struct *handle,
160         const struct smb_filename *smb_fname,
161         TALLOC_CTX *mem_ctx,
162         struct security_descriptor **sd)
163 {
164         struct nfs4acl_config *config = NULL;
165         enum default_acl_style default_acl_style;
166         mode_t required_mode;
167         SMB_STRUCT_STAT sbuf = smb_fname->st;
168         int ret;
169
170         SMB_VFS_HANDLE_GET_DATA(handle, config,
171                                 struct nfs4acl_config,
172                                 return NT_STATUS_INTERNAL_ERROR);
173
174         default_acl_style = config->default_acl_style;
175
176         if (!VALID_STAT(sbuf)) {
177                 ret = vfs_stat_smb_basename(handle->conn,
178                                             smb_fname,
179                                             &sbuf);
180                 if (ret != 0) {
181                         return map_nt_error_from_unix(errno);
182                 }
183         }
184
185         if (S_ISDIR(sbuf.st_ex_mode)) {
186                 required_mode = 0777;
187         } else {
188                 required_mode = 0666;
189         }
190         if ((sbuf.st_ex_mode & required_mode) != required_mode) {
191                 default_acl_style = DEFAULT_ACL_POSIX;
192         }
193
194         return make_default_filesystem_acl(mem_ctx,
195                                            default_acl_style,
196                                            smb_fname->base_name,
197                                            &sbuf,
198                                            sd);
199 }
200
201 static NTSTATUS nfs4acl_blob_to_smb4(struct vfs_handle_struct *handle,
202                                      DATA_BLOB *blob,
203                                      TALLOC_CTX *mem_ctx,
204                                      struct SMB4ACL_T **smb4acl)
205 {
206         struct nfs4acl_config *config = NULL;
207         NTSTATUS status;
208
209         SMB_VFS_HANDLE_GET_DATA(handle, config,
210                                 struct nfs4acl_config,
211                                 return NT_STATUS_INTERNAL_ERROR);
212
213         switch (config->encoding) {
214         case NFS4ACL_ENCODING_NDR:
215                 status = nfs4acl_ndr_blob_to_smb4(handle, mem_ctx, blob, smb4acl);
216                 break;
217         case NFS4ACL_ENCODING_XDR:
218                 status = nfs4acl_xdr_blob_to_smb4(handle, mem_ctx, blob, smb4acl);
219                 break;
220         case NFS4ACL_ENCODING_NFS:
221                 status = nfs4acl_nfs_blob_to_smb4(handle, mem_ctx, blob, smb4acl);
222                 break;
223         default:
224                 status = NT_STATUS_INTERNAL_ERROR;
225                 break;
226         }
227
228         return status;
229 }
230
231 static NTSTATUS nfs4acl_xattr_fget_nt_acl(struct vfs_handle_struct *handle,
232                                    struct files_struct *fsp,
233                                    uint32_t security_info,
234                                    TALLOC_CTX *mem_ctx,
235                                    struct security_descriptor **sd)
236 {
237         struct SMB4ACL_T *smb4acl = NULL;
238         TALLOC_CTX *frame = talloc_stackframe();
239         DATA_BLOB blob;
240         NTSTATUS status;
241
242         status = nfs4acl_get_blob(handle, fsp, NULL, frame, &blob);
243         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
244                 TALLOC_FREE(frame);
245                 return nfs4acl_xattr_default_sd(
246                         handle, fsp->fsp_name, mem_ctx, sd);
247         }
248         if (!NT_STATUS_IS_OK(status)) {
249                 TALLOC_FREE(frame);
250                 return status;
251         }
252
253         status = nfs4acl_blob_to_smb4(handle, &blob, frame, &smb4acl);
254         if (!NT_STATUS_IS_OK(status)) {
255                 TALLOC_FREE(frame);
256                 return status;
257         }
258
259         status = smb_fget_nt_acl_nfs4(fsp, NULL, security_info, mem_ctx,
260                                       sd, smb4acl);
261         TALLOC_FREE(frame);
262         return status;
263 }
264
265 static NTSTATUS nfs4acl_xattr_get_nt_acl(struct vfs_handle_struct *handle,
266                                   const struct smb_filename *smb_fname,
267                                   uint32_t security_info,
268                                   TALLOC_CTX *mem_ctx,
269                                   struct security_descriptor **sd)
270 {
271         struct SMB4ACL_T *smb4acl = NULL;
272         TALLOC_CTX *frame = talloc_stackframe();
273         DATA_BLOB blob;
274         NTSTATUS status;
275
276         status = nfs4acl_get_blob(handle, NULL, smb_fname, frame, &blob);
277         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
278                 TALLOC_FREE(frame);
279                 return nfs4acl_xattr_default_sd(
280                         handle, smb_fname, mem_ctx, sd);
281         }
282         if (!NT_STATUS_IS_OK(status)) {
283                 TALLOC_FREE(frame);
284                 return status;
285         }
286
287         status = nfs4acl_blob_to_smb4(handle, &blob, frame, &smb4acl);
288         if (!NT_STATUS_IS_OK(status)) {
289                 TALLOC_FREE(frame);
290                 return status;
291         }
292
293         status = smb_get_nt_acl_nfs4(handle->conn, smb_fname, NULL,
294                                      security_info, mem_ctx, sd,
295                                      smb4acl);
296         TALLOC_FREE(frame);
297         return status;
298 }
299
300 static bool nfs4acl_smb4acl_set_fn(vfs_handle_struct *handle,
301                                    files_struct *fsp,
302                                    struct SMB4ACL_T *smb4acl)
303 {
304         struct nfs4acl_config *config = NULL;
305         DATA_BLOB blob;
306         NTSTATUS status;
307         int saved_errno = 0;
308         int ret;
309
310         SMB_VFS_HANDLE_GET_DATA(handle, config,
311                                 struct nfs4acl_config,
312                                 return false);
313
314         switch (config->encoding) {
315         case NFS4ACL_ENCODING_NDR:
316                 status = nfs4acl_smb4acl_to_ndr_blob(handle, talloc_tos(),
317                                                      smb4acl, &blob);
318                 break;
319         case NFS4ACL_ENCODING_XDR:
320                 status = nfs4acl_smb4acl_to_xdr_blob(handle, talloc_tos(),
321                                                      smb4acl, &blob);
322                 break;
323         case NFS4ACL_ENCODING_NFS:
324                 status = nfs4acl_smb4acl_to_nfs_blob(handle, talloc_tos(),
325                                                      smb4acl, &blob);
326                 break;
327         default:
328                 status = NT_STATUS_INTERNAL_ERROR;
329                 break;
330         }
331         if (!NT_STATUS_IS_OK(status)) {
332                 return false;
333         }
334
335         if (fsp->fh->fd != -1) {
336                 ret = SMB_VFS_NEXT_FSETXATTR(handle, fsp, config->xattr_name,
337                                              blob.data, blob.length, 0);
338         } else {
339                 ret = SMB_VFS_NEXT_SETXATTR(handle, fsp->fsp_name,
340                                             config->xattr_name,
341                                             blob.data, blob.length, 0);
342         }
343         if (ret != 0) {
344                 saved_errno = errno;
345         }
346         data_blob_free(&blob);
347         if (saved_errno != 0) {
348                 errno = saved_errno;
349         }
350         if (ret != 0) {
351                 DBG_ERR("can't store acl in xattr: %s\n", strerror(errno));
352                 return false;
353         }
354
355         return true;
356 }
357
358 static NTSTATUS nfs4acl_xattr_fset_nt_acl(vfs_handle_struct *handle,
359                          files_struct *fsp,
360                          uint32_t security_info_sent,
361                          const struct security_descriptor *psd)
362 {
363         struct nfs4acl_config *config = NULL;
364         const struct security_token *token = NULL;
365         mode_t existing_mode;
366         mode_t expected_mode;
367         mode_t restored_mode;
368         bool chown_needed = false;
369         struct dom_sid_buf buf;
370         NTSTATUS status;
371         int ret;
372
373         SMB_VFS_HANDLE_GET_DATA(handle, config,
374                                 struct nfs4acl_config,
375                                 return NT_STATUS_INTERNAL_ERROR);
376
377         if (!VALID_STAT(fsp->fsp_name->st)) {
378                 DBG_ERR("Invalid stat info on [%s]\n", fsp_str_dbg(fsp));
379                 return NT_STATUS_INTERNAL_ERROR;
380         }
381
382         existing_mode = fsp->fsp_name->st.st_ex_mode;
383         if (S_ISDIR(existing_mode)) {
384                 expected_mode = 0777;
385         } else {
386                 expected_mode = 0666;
387         }
388         if (!config->validate_mode) {
389                 existing_mode = 0;
390                 expected_mode = 0;
391         }
392         if ((existing_mode & expected_mode) != expected_mode) {
393
394                 restored_mode = existing_mode | expected_mode;
395
396                 if (fsp->fh->fd != -1) {
397                         ret = SMB_VFS_NEXT_FCHMOD(handle,
398                                                   fsp,
399                                                   restored_mode);
400                 } else {
401                         ret = SMB_VFS_NEXT_CHMOD(handle,
402                                                  fsp->fsp_name,
403                                                  restored_mode);
404                 }
405                 if (ret != 0) {
406                         DBG_ERR("Resetting POSIX mode on [%s] from [0%o]: %s\n",
407                                 fsp_str_dbg(fsp), existing_mode,
408                                 strerror(errno));
409                         return map_nt_error_from_unix(errno);
410                 }
411         }
412
413         status = smb_set_nt_acl_nfs4(handle,
414                                      fsp,
415                                      &config->nfs4_params,
416                                      security_info_sent,
417                                      psd,
418                                      nfs4acl_smb4acl_set_fn);
419         if (NT_STATUS_IS_OK(status)) {
420                 return NT_STATUS_OK;
421         }
422         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
423                 return status;
424         }
425
426         /*
427          * We got access denied. If we're already root, or we didn't
428          * need to do a chown, or the fsp isn't open with WRITE_OWNER
429          * access, just return.
430          */
431
432         if ((security_info_sent & SECINFO_OWNER) &&
433             (psd->owner_sid != NULL))
434         {
435                 chown_needed = true;
436         }
437         if ((security_info_sent & SECINFO_GROUP) &&
438             (psd->group_sid != NULL))
439         {
440                 chown_needed = true;
441         }
442
443         if (get_current_uid(handle->conn) == 0 ||
444             chown_needed == false ||
445             !(fsp->access_mask & SEC_STD_WRITE_OWNER))
446         {
447                 return NT_STATUS_ACCESS_DENIED;
448         }
449
450         /*
451          * Only allow take-ownership, not give-ownership. That's the way Windows
452          * implements SEC_STD_WRITE_OWNER. MS-FSA 2.1.5.16 just states: If
453          * InputBuffer.OwnerSid is not a valid owner SID for a file in the
454          * objectstore, as determined in an implementation specific manner, the
455          * object store MUST return STATUS_INVALID_OWNER.
456          */
457         token = get_current_nttok(fsp->conn);
458         if (!security_token_is_sid(token, psd->owner_sid)) {
459                 return NT_STATUS_INVALID_OWNER;
460         }
461
462         DBG_DEBUG("overriding chown on file %s for sid %s\n",
463                   fsp_str_dbg(fsp),
464                   dom_sid_str_buf(psd->owner_sid, &buf));
465
466         status = smb_set_nt_acl_nfs4(handle,
467                                      fsp,
468                                      &config->nfs4_params,
469                                      security_info_sent,
470                                      psd,
471                                      nfs4acl_smb4acl_set_fn);
472         return status;
473 }
474
475 static int nfs4acl_connect(struct vfs_handle_struct *handle,
476                            const char *service,
477                            const char *user)
478 {
479         const struct loadparm_substitution *lp_sub =
480                 loadparm_s3_global_substitution();
481         struct nfs4acl_config *config = NULL;
482         const struct enum_list *default_acl_style_list = NULL;
483         const char *default_xattr_name = NULL;
484         bool default_validate_mode = true;
485         int enumval;
486         unsigned nfs_version;
487         int ret;
488
489         default_acl_style_list = get_default_acl_style_list();
490
491         config = talloc_zero(handle->conn, struct nfs4acl_config);
492         if (config == NULL) {
493                 DBG_ERR("talloc_zero() failed\n");
494                 return -1;
495         }
496
497         ret = SMB_VFS_NEXT_CONNECT(handle, service, user);
498         if (ret < 0) {
499                 TALLOC_FREE(config);
500                 return ret;
501         }
502
503         ret = smbacl4_get_vfs_params(handle->conn, &config->nfs4_params);
504         if (ret < 0) {
505                 TALLOC_FREE(config);
506                 return ret;
507         }
508
509         enumval = lp_parm_enum(SNUM(handle->conn),
510                                "nfs4acl_xattr",
511                                "encoding",
512                                nfs4acl_encoding,
513                                NFS4ACL_ENCODING_NDR);
514         if (enumval == -1) {
515                 DBG_ERR("Invalid \"nfs4acl_xattr:encoding\" parameter\n");
516                 return -1;
517         }
518         config->encoding = (enum nfs4acl_encoding)enumval;
519
520         switch (config->encoding) {
521         case NFS4ACL_ENCODING_XDR:
522                 default_xattr_name = NFS4ACL_XDR_XATTR_NAME;
523                 break;
524         case NFS4ACL_ENCODING_NFS:
525                 default_xattr_name = NFS4ACL_NFS_XATTR_NAME;
526                 default_validate_mode = false;
527                 break;
528         case NFS4ACL_ENCODING_NDR:
529         default:
530                 default_xattr_name = NFS4ACL_NDR_XATTR_NAME;
531                 break;
532         }
533
534         nfs_version = (unsigned)lp_parm_int(SNUM(handle->conn),
535                                             "nfs4acl_xattr",
536                                             "version",
537                                             41);
538         switch (nfs_version) {
539         case 40:
540                 config->nfs_version = ACL4_XATTR_VERSION_40;
541                 break;
542         case 41:
543                 config->nfs_version = ACL4_XATTR_VERSION_41;
544                 break;
545         default:
546                 config->nfs_version = ACL4_XATTR_VERSION_DEFAULT;
547                 break;
548         }
549
550         config->default_acl_style = lp_parm_enum(SNUM(handle->conn),
551                                                  "nfs4acl_xattr",
552                                                  "default acl style",
553                                                  default_acl_style_list,
554                                                  DEFAULT_ACL_EVERYONE);
555
556         config->xattr_name = lp_parm_substituted_string(config, lp_sub,
557                                                    SNUM(handle->conn),
558                                                    "nfs4acl_xattr",
559                                                    "xattr_name",
560                                                    default_xattr_name);
561
562         config->nfs4_id_numeric = lp_parm_bool(SNUM(handle->conn),
563                                                "nfs4acl_xattr",
564                                                "nfs4_id_numeric",
565                                                false);
566
567
568         config->validate_mode = lp_parm_bool(SNUM(handle->conn),
569                                              "nfs4acl_xattr",
570                                              "validate_mode",
571                                              default_validate_mode);
572
573         SMB_VFS_HANDLE_SET_DATA(handle, config, NULL, struct nfs4acl_config,
574                                 return -1);
575
576         /*
577          * Ensure we have the parameters correct if we're using this module.
578          */
579         DBG_NOTICE("Setting 'inherit acls = true', "
580                    "'dos filemode = true', "
581                    "'force unknown acl user = true', "
582                    "'create mask = 0666', "
583                    "'directory mask = 0777' and "
584                    "'store dos attributes = yes' "
585                    "for service [%s]\n", service);
586
587         lp_do_parameter(SNUM(handle->conn), "inherit acls", "true");
588         lp_do_parameter(SNUM(handle->conn), "dos filemode", "true");
589         lp_do_parameter(SNUM(handle->conn), "force unknown acl user", "true");
590         lp_do_parameter(SNUM(handle->conn), "create mask", "0666");
591         lp_do_parameter(SNUM(handle->conn), "directory mask", "0777");
592         lp_do_parameter(SNUM(handle->conn), "store dos attributes", "yes");
593
594         return 0;
595 }
596
597 /*
598    As long as Samba does not support an exiplicit method for a module
599    to define conflicting vfs methods, we should override all conflicting
600    methods here.  That way, we know we are using the NFSv4 storage
601
602    Function declarations taken from vfs_solarisacl
603 */
604
605 static SMB_ACL_T nfs4acl_xattr_fail__sys_acl_get_file(vfs_handle_struct *handle,
606                                         const struct smb_filename *smb_fname,
607                                         SMB_ACL_TYPE_T type,
608                                         TALLOC_CTX *mem_ctx)
609 {
610         return (SMB_ACL_T)NULL;
611 }
612
613 static SMB_ACL_T nfs4acl_xattr_fail__sys_acl_get_fd(vfs_handle_struct *handle,
614                                                     files_struct *fsp,
615                                                     TALLOC_CTX *mem_ctx)
616 {
617         return (SMB_ACL_T)NULL;
618 }
619
620 static int nfs4acl_xattr_fail__sys_acl_set_file(vfs_handle_struct *handle,
621                                          const struct smb_filename *smb_fname,
622                                          SMB_ACL_TYPE_T type,
623                                          SMB_ACL_T theacl)
624 {
625         return -1;
626 }
627
628 static int nfs4acl_xattr_fail__sys_acl_set_fd(vfs_handle_struct *handle,
629                                        files_struct *fsp,
630                                        SMB_ACL_T theacl)
631 {
632         return -1;
633 }
634
635 static int nfs4acl_xattr_fail__sys_acl_delete_def_file(vfs_handle_struct *handle,
636                         const struct smb_filename *smb_fname)
637 {
638         return -1;
639 }
640
641 static int nfs4acl_xattr_fail__sys_acl_blob_get_file(vfs_handle_struct *handle,
642                         const struct smb_filename *smb_fname,
643                         TALLOC_CTX *mem_ctx,
644                         char **blob_description,
645                         DATA_BLOB *blob)
646 {
647         return -1;
648 }
649
650 static int nfs4acl_xattr_fail__sys_acl_blob_get_fd(vfs_handle_struct *handle, files_struct *fsp, TALLOC_CTX *mem_ctx, char **blob_description, DATA_BLOB *blob)
651 {
652         return -1;
653 }
654
655 /* VFS operations structure */
656
657 static struct vfs_fn_pointers nfs4acl_xattr_fns = {
658         .connect_fn = nfs4acl_connect,
659         .fget_nt_acl_fn = nfs4acl_xattr_fget_nt_acl,
660         .get_nt_acl_fn = nfs4acl_xattr_get_nt_acl,
661         .fset_nt_acl_fn = nfs4acl_xattr_fset_nt_acl,
662
663         .sys_acl_get_file_fn = nfs4acl_xattr_fail__sys_acl_get_file,
664         .sys_acl_get_fd_fn = nfs4acl_xattr_fail__sys_acl_get_fd,
665         .sys_acl_blob_get_file_fn = nfs4acl_xattr_fail__sys_acl_blob_get_file,
666         .sys_acl_blob_get_fd_fn = nfs4acl_xattr_fail__sys_acl_blob_get_fd,
667         .sys_acl_set_file_fn = nfs4acl_xattr_fail__sys_acl_set_file,
668         .sys_acl_set_fd_fn = nfs4acl_xattr_fail__sys_acl_set_fd,
669         .sys_acl_delete_def_file_fn = nfs4acl_xattr_fail__sys_acl_delete_def_file,
670 };
671
672 static_decl_vfs;
673 NTSTATUS vfs_nfs4acl_xattr_init(TALLOC_CTX *ctx)
674 {
675         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "nfs4acl_xattr",
676                                 &nfs4acl_xattr_fns);
677 }