LCOV - code coverage report
Current view: top level - source4/ntvfs/posix - pvfs_acl_nfs4.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 3 101 3.0 %
Date: 2024-04-21 15:09:00 Functions: 1 3 33.3 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    POSIX NTVFS backend - NT ACLs mapped to NFS4 ACLs, as per
       5             :    http://www.suse.de/~agruen/nfs4acl/
       6             : 
       7             :    Copyright (C) Andrew Tridgell 2006
       8             : 
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             :    
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             :    
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "vfs_posix.h"
      25             : #include "../lib/util/unix_privs.h"
      26             : #include "librpc/gen_ndr/ndr_nfs4acl.h"
      27             : #include "libcli/security/security.h"
      28             : 
      29             : NTSTATUS pvfs_acl_nfs4_init(TALLOC_CTX *);
      30             : 
      31             : #define ACE4_IDENTIFIER_GROUP 0x40
      32             : 
      33             : /*
      34             :   load the current ACL from system.nfs4acl
      35             : */
      36           0 : static NTSTATUS pvfs_acl_load_nfs4(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd,
      37             :                                    TALLOC_CTX *mem_ctx,
      38             :                                    struct security_descriptor **psd)
      39             : {
      40           0 :         NTSTATUS status;
      41           0 :         struct nfs4acl *acl;
      42           0 :         struct security_descriptor *sd;
      43           0 :         int i, num_ids;
      44           0 :         struct id_map *ids;
      45             : 
      46           0 :         acl = talloc_zero(mem_ctx, struct nfs4acl);
      47           0 :         NT_STATUS_HAVE_NO_MEMORY(acl);
      48             : 
      49           0 :         status = pvfs_xattr_ndr_load(pvfs, mem_ctx, name->full_name, fd, 
      50             :                                      NFS4ACL_NDR_XATTR_NAME,
      51             :                                      acl, (void *) ndr_pull_nfs4acl);
      52           0 :         if (!NT_STATUS_IS_OK(status)) {
      53           0 :                 talloc_free(acl);
      54           0 :                 return status;
      55             :         }
      56             : 
      57           0 :         *psd = security_descriptor_initialise(mem_ctx);
      58           0 :         NT_STATUS_HAVE_NO_MEMORY(*psd);
      59             : 
      60           0 :         sd = *psd;
      61             : 
      62           0 :         sd->type |= acl->a_flags;
      63             : 
      64             :         /* the number of ids to map is the acl count plus uid and gid */
      65           0 :         num_ids = acl->a_count +2;
      66           0 :         ids = talloc_array(sd, struct id_map, num_ids);
      67           0 :         NT_STATUS_HAVE_NO_MEMORY(ids);
      68             : 
      69           0 :         ids[0].xid.id = name->st.st_uid;
      70           0 :         ids[0].xid.type = ID_TYPE_UID;
      71           0 :         ids[0].sid = NULL;
      72           0 :         ids[0].status = ID_UNKNOWN;
      73             : 
      74           0 :         ids[1].xid.id = name->st.st_gid;
      75           0 :         ids[1].xid.type = ID_TYPE_GID;
      76           0 :         ids[1].sid = NULL;
      77           0 :         ids[1].status = ID_UNKNOWN;
      78             : 
      79           0 :         for (i=0;i<acl->a_count;i++) {
      80           0 :                 struct nfs4ace *a = &acl->ace[i];
      81           0 :                 ids[i+2].xid.id = a->e_id;
      82           0 :                 if (a->e_flags & ACE4_IDENTIFIER_GROUP) {
      83           0 :                         ids[i+2].xid.type = ID_TYPE_GID;
      84             :                 } else {
      85           0 :                         ids[i+2].xid.type = ID_TYPE_UID;
      86             :                 }
      87           0 :                 ids[i+2].sid = NULL;
      88           0 :                 ids[i+2].status = ID_UNKNOWN;
      89             :         }
      90             : 
      91             :         /* Allocate memory for the sids from the security descriptor to be on
      92             :          * the safe side. */
      93           0 :         status = wbc_xids_to_sids(ids, num_ids);
      94           0 :         NT_STATUS_NOT_OK_RETURN(status);
      95             : 
      96           0 :         sd->owner_sid = talloc_steal(sd, ids[0].sid);
      97           0 :         sd->group_sid = talloc_steal(sd, ids[1].sid);
      98             : 
      99           0 :         for (i=0;i<acl->a_count;i++) {
     100           0 :                 struct nfs4ace *a = &acl->ace[i];
     101           0 :                 struct security_ace ace = {};
     102           0 :                 ace.type = a->e_type;
     103           0 :                 ace.flags = a->e_flags;
     104           0 :                 ace.access_mask = a->e_mask;
     105           0 :                 ace.trustee = *ids[i+2].sid;
     106           0 :                 security_descriptor_dacl_add(sd, &ace);
     107             :         }
     108             : 
     109           0 :         return NT_STATUS_OK;
     110             : }
     111             : 
     112             : /*
     113             :   save the acl for a file into system.nfs4acl
     114             : */
     115           0 : static NTSTATUS pvfs_acl_save_nfs4(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd,
     116             :                                    struct security_descriptor *sd)
     117             : {
     118           0 :         NTSTATUS status;
     119           0 :         void *privs;
     120           0 :         struct nfs4acl acl;
     121           0 :         int i;
     122           0 :         TALLOC_CTX *tmp_ctx;
     123           0 :         struct id_map *ids;
     124             : 
     125           0 :         tmp_ctx = talloc_new(pvfs);
     126           0 :         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
     127             : 
     128           0 :         acl.a_version = 0;
     129           0 :         acl.a_flags   = sd->type;
     130           0 :         acl.a_count   = sd->dacl?sd->dacl->num_aces:0;
     131           0 :         acl.a_owner_mask = 0;
     132           0 :         acl.a_group_mask = 0;
     133           0 :         acl.a_other_mask = 0;
     134             : 
     135           0 :         acl.ace = talloc_array(tmp_ctx, struct nfs4ace, acl.a_count);
     136           0 :         if (!acl.ace) {
     137           0 :                 talloc_free(tmp_ctx);
     138           0 :                 return NT_STATUS_NO_MEMORY;
     139             :         }
     140             : 
     141           0 :         ids = talloc_array(tmp_ctx, struct id_map, acl.a_count);
     142           0 :         if (ids == NULL) {
     143           0 :                 talloc_free(tmp_ctx);
     144           0 :                 return NT_STATUS_NO_MEMORY;
     145             :         }
     146             : 
     147           0 :         for (i=0;i<acl.a_count;i++) {
     148           0 :                 struct security_ace *ace = &sd->dacl->aces[i];
     149           0 :                 ZERO_STRUCT(ids[i].xid);
     150           0 :                 ids[i].sid = dom_sid_dup(ids, &ace->trustee);
     151           0 :                 if (ids[i].sid == NULL) {
     152           0 :                         talloc_free(tmp_ctx);
     153           0 :                         return NT_STATUS_NO_MEMORY;
     154             :                 }
     155           0 :                 ids[i].status = ID_UNKNOWN;
     156             :         }
     157             : 
     158           0 :         status = wbc_sids_to_xids(ids, acl.a_count);
     159           0 :         if (!NT_STATUS_IS_OK(status)) {
     160           0 :                 talloc_free(tmp_ctx);
     161           0 :                 return status;
     162             :         }
     163             : 
     164           0 :         for (i=0;i<acl.a_count;i++) {
     165           0 :                 struct nfs4ace *a = &acl.ace[i];
     166           0 :                 struct security_ace *ace = &sd->dacl->aces[i];
     167           0 :                 a->e_type  = ace->type;
     168           0 :                 a->e_flags = ace->flags;
     169           0 :                 a->e_mask  = ace->access_mask;
     170           0 :                 if (ids[i].xid.type != ID_TYPE_UID) {
     171           0 :                         a->e_flags |= ACE4_IDENTIFIER_GROUP;
     172             :                 }
     173           0 :                 a->e_id = ids[i].xid.id;
     174           0 :                 a->e_who   = "";
     175             :         }
     176             : 
     177           0 :         privs = root_privileges();
     178           0 :         status = pvfs_xattr_ndr_save(pvfs, name->full_name, fd, 
     179             :                                      NFS4ACL_NDR_XATTR_NAME,
     180             :                                      &acl, (void *) ndr_push_nfs4acl);
     181           0 :         talloc_free(privs);
     182             : 
     183           0 :         talloc_free(tmp_ctx);
     184           0 :         return status;
     185             : }
     186             : 
     187             : 
     188             : /*
     189             :   initialise pvfs acl NFS4 backend
     190             : */
     191           4 : NTSTATUS pvfs_acl_nfs4_init(TALLOC_CTX *ctx)
     192             : {
     193           4 :         struct pvfs_acl_ops ops = {
     194             :                 .name = "nfs4acl",
     195             :                 .acl_load = pvfs_acl_load_nfs4,
     196             :                 .acl_save = pvfs_acl_save_nfs4
     197             :         };
     198           4 :         return pvfs_acl_register(ctx, &ops);
     199             : }

Generated by: LCOV version 1.14