LCOV - code coverage report
Current view: top level - source3/modules - nfs4acl_xattr_xdr.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 0 186 0.0 %
Date: 2024-06-13 04:01:37 Functions: 0 13 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) Ralph Boehme 2017
       3             :  *
       4             :  * This program is free software; you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation; either version 3 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * This program is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      16             :  *
      17             :  */
      18             : 
      19             : #include "includes.h"
      20             : #include "smbd/proto.h"
      21             : #include "libcli/security/security_descriptor.h"
      22             : #include "libcli/security/security_token.h"
      23             : #include "nfs4_acls.h"
      24             : #include "nfs4acl_xattr.h"
      25             : 
      26             : #undef DBGC_CLASS
      27             : #define DBGC_CLASS DBGC_VFS
      28             : 
      29             : #ifdef HAVE_RPC_XDR_H
      30             : /* <rpc/xdr.h> uses TRUE and FALSE */
      31             : #ifdef TRUE
      32             : #undef TRUE
      33             : #endif
      34             : 
      35             : #ifdef FALSE
      36             : #undef FALSE
      37             : #endif
      38             : 
      39             : #ifdef HAVE_RPC_TYPES_H
      40             : #include <rpc/types.h>
      41             : #endif
      42             : #include <rpc/xdr.h>
      43             : #include "nfs41acl.h"
      44             : #include "nfs4acl_xattr_xdr.h"
      45             : #include "nfs4acl_xattr_util.h"
      46             : 
      47           0 : static unsigned nfs4acli_get_naces(nfsacl41i *nacl)
      48             : {
      49           0 :         return nacl->na41_aces.na41_aces_len;
      50             : }
      51             : 
      52           0 : static void nfs4acli_set_naces(nfsacl41i *nacl, unsigned naces)
      53             : {
      54           0 :         nacl->na41_aces.na41_aces_len = naces;
      55           0 : }
      56             : 
      57           0 : static unsigned nfs4acli_get_flags(nfsacl41i *nacl)
      58             : {
      59           0 :         return nacl->na41_flag;
      60             : }
      61             : 
      62           0 : static void nfs4acli_set_flags(nfsacl41i *nacl, unsigned flags)
      63             : {
      64           0 :         nacl->na41_flag = flags;
      65           0 : }
      66             : 
      67           0 : static size_t nfs4acli_get_xdrblob_size(nfsacl41i *nacl)
      68             : {
      69             :         size_t acl_size;
      70             :         size_t aces_size;
      71           0 :         unsigned naces = nfs4acli_get_naces(nacl);
      72             : 
      73           0 :         acl_size = sizeof(aclflag4) + sizeof(unsigned);
      74             : 
      75           0 :         if (naces > NFS4ACL_XDR_MAX_ACES) {
      76           0 :                 DBG_ERR("Too many ACEs: %u", naces);
      77           0 :                 return 0;
      78             :         }
      79             : 
      80           0 :         aces_size = naces * sizeof(struct nfsace4i);
      81           0 :         if (acl_size + aces_size < acl_size) {
      82           0 :                 return 0;
      83             :         }
      84           0 :         acl_size += aces_size;
      85             : 
      86           0 :         return acl_size;
      87             : }
      88             : 
      89           0 : static size_t nfs4acli_get_xdrblob_naces(size_t _blobsize)
      90             : {
      91           0 :         size_t blobsize = _blobsize;
      92             : 
      93           0 :         blobsize -= sizeof(aclflag4);
      94           0 :         blobsize -= sizeof(unsigned);
      95           0 :         if (blobsize > _blobsize) {
      96           0 :                 return 0;
      97             :         }
      98           0 :         return (blobsize / sizeof(struct nfsace4i));
      99             : }
     100             : 
     101           0 : static nfsacl41i *nfs4acli_alloc(TALLOC_CTX *mem_ctx, unsigned naces)
     102             : {
     103           0 :         size_t acl_size = sizeof(nfsacl41i) + (naces * sizeof(struct nfsace4i));
     104           0 :         nfsacl41i *nacl = NULL;
     105             : 
     106           0 :         if (naces > NFS4ACL_XDR_MAX_ACES) {
     107           0 :                 DBG_ERR("Too many ACEs: %d\n", naces);
     108           0 :                 return NULL;
     109             :         }
     110             : 
     111           0 :         nacl = talloc_zero_size(mem_ctx, acl_size);
     112           0 :         if (nacl == NULL) {
     113           0 :                 DBG_ERR("talloc_zero_size failed\n");
     114           0 :                 return NULL;
     115             :         }
     116             : 
     117           0 :         nfs4acli_set_naces(nacl, naces);
     118           0 :         nacl->na41_aces.na41_aces_val =
     119           0 :                 (nfsace4i *)((char *)nacl + sizeof(nfsacl41i));
     120             : 
     121           0 :         return nacl;
     122             : }
     123             : 
     124           0 : static nfsace4i *nfs4acli_get_ace(nfsacl41i *nacl, size_t n)
     125             : {
     126           0 :         return &nacl->na41_aces.na41_aces_val[n];
     127             : }
     128             : 
     129           0 : static bool smb4acl_to_nfs4acli(vfs_handle_struct *handle,
     130             :                                 TALLOC_CTX *mem_ctx,
     131             :                                 struct SMB4ACL_T *smb4acl,
     132             :                                 nfsacl41i **_nacl)
     133             : {
     134           0 :         struct nfs4acl_config *config = NULL;
     135           0 :         struct SMB4ACE_T *smb4ace = NULL;
     136           0 :         size_t smb4naces = 0;
     137           0 :         nfsacl41i *nacl = NULL;
     138           0 :         uint16_t smb4acl_flags = 0;
     139           0 :         unsigned nacl_flags = 0;
     140             : 
     141           0 :         SMB_VFS_HANDLE_GET_DATA(handle, config,
     142             :                                 struct nfs4acl_config,
     143             :                                 return false);
     144             : 
     145           0 :         smb4naces = smb_get_naces(smb4acl);
     146           0 :         nacl = nfs4acli_alloc(mem_ctx, smb4naces);
     147           0 :         nfs4acli_set_naces(nacl, 0);
     148             : 
     149           0 :         if (config->nfs_version > ACL4_XATTR_VERSION_40) {
     150           0 :                 smb4acl_flags = smbacl4_get_controlflags(smb4acl);
     151           0 :                 nacl_flags = smb4acl_to_nfs4acl_flags(smb4acl_flags);
     152           0 :                 nfs4acli_set_flags(nacl, nacl_flags);
     153             :         }
     154             : 
     155           0 :         smb4ace = smb_first_ace4(smb4acl);
     156           0 :         while (smb4ace != NULL) {
     157           0 :                 SMB_ACE4PROP_T *ace4prop = smb_get_ace4(smb4ace);
     158           0 :                 size_t nace_count = nfs4acli_get_naces(nacl);
     159           0 :                 nfsace4i *nace = nfs4acli_get_ace(nacl, nace_count);
     160             : 
     161           0 :                 nace->type = ace4prop->aceType;
     162           0 :                 nace->flag = ace4prop->aceFlags;
     163           0 :                 nace->access_mask = ace4prop->aceMask;
     164             : 
     165           0 :                 if (ace4prop->flags & SMB_ACE4_ID_SPECIAL) {
     166           0 :                         nace->iflag |= ACEI4_SPECIAL_WHO;
     167             : 
     168           0 :                         switch (ace4prop->who.special_id) {
     169           0 :                         case SMB_ACE4_WHO_OWNER:
     170           0 :                                 nace->who = ACE4_SPECIAL_OWNER;
     171           0 :                                 break;
     172             : 
     173           0 :                         case SMB_ACE4_WHO_GROUP:
     174           0 :                                 nace->who = ACE4_SPECIAL_GROUP;
     175           0 :                                 break;
     176             : 
     177           0 :                         case SMB_ACE4_WHO_EVERYONE:
     178           0 :                                 nace->who = ACE4_SPECIAL_EVERYONE;
     179           0 :                                 break;
     180             : 
     181           0 :                         default:
     182           0 :                                 DBG_ERR("Unsupported special id [%d]\n",
     183             :                                         ace4prop->who.special_id);
     184           0 :                                 continue;
     185             :                         }
     186             :                 } else {
     187           0 :                         if (ace4prop->aceFlags & SMB_ACE4_IDENTIFIER_GROUP) {
     188           0 :                                 nace->flag |= ACE4_IDENTIFIER_GROUP;
     189           0 :                                 nace->who = ace4prop->who.gid;
     190             :                         } else {
     191           0 :                                 nace->who = ace4prop->who.uid;
     192             :                         }
     193             :                 }
     194             : 
     195           0 :                 nace_count++;
     196           0 :                 nfs4acli_set_naces(nacl, nace_count);
     197           0 :                 smb4ace = smb_next_ace4(smb4ace);
     198             :         }
     199             : 
     200           0 :         *_nacl = nacl;
     201           0 :         return true;
     202             : }
     203             : 
     204           0 : NTSTATUS nfs4acl_smb4acl_to_xdr_blob(vfs_handle_struct *handle,
     205             :                                      TALLOC_CTX *mem_ctx,
     206             :                                      struct SMB4ACL_T *smb4acl,
     207             :                                      DATA_BLOB *_blob)
     208             : {
     209           0 :         nfsacl41i *nacl = NULL;
     210           0 :         XDR xdr = {0};
     211             :         size_t aclblobsize;
     212             :         DATA_BLOB blob;
     213             :         bool ok;
     214             : 
     215           0 :         ok = smb4acl_to_nfs4acli(handle, talloc_tos(), smb4acl, &nacl);
     216           0 :         if (!ok) {
     217           0 :                 DBG_ERR("smb4acl_to_nfs4acl failed\n");
     218           0 :                 return NT_STATUS_INTERNAL_ERROR;
     219             :         }
     220             : 
     221           0 :         aclblobsize = nfs4acli_get_xdrblob_size(nacl);
     222           0 :         if (aclblobsize == 0) {
     223           0 :                 return NT_STATUS_INTERNAL_ERROR;
     224             :         }
     225             : 
     226           0 :         blob = data_blob_talloc(mem_ctx, NULL, aclblobsize);
     227           0 :         if (blob.data == NULL) {
     228           0 :                 TALLOC_FREE(nacl);
     229           0 :                 return NT_STATUS_NO_MEMORY;
     230             :         }
     231             : 
     232           0 :         xdrmem_create(&xdr, (char *)blob.data, blob.length, XDR_ENCODE);
     233             : 
     234           0 :         ok = xdr_nfsacl41i(&xdr, nacl);
     235           0 :         TALLOC_FREE(nacl);
     236           0 :         if (!ok) {
     237           0 :                 DBG_ERR("xdr_nfs4acl41 failed\n");
     238           0 :                 return NT_STATUS_NO_MEMORY;
     239             :         }
     240             : 
     241           0 :         *_blob = blob;
     242           0 :         return NT_STATUS_OK;
     243             : }
     244             : 
     245           0 : static NTSTATUS nfs4acl_xdr_blob_to_nfs4acli(struct vfs_handle_struct *handle,
     246             :                                              TALLOC_CTX *mem_ctx,
     247             :                                              DATA_BLOB *blob,
     248             :                                              nfsacl41i **_nacl)
     249             : {
     250           0 :         struct nfs4acl_config *config = NULL;
     251           0 :         nfsacl41i *nacl = NULL;
     252             :         size_t naces;
     253           0 :         XDR xdr = {0};
     254             :         bool ok;
     255             : 
     256           0 :         SMB_VFS_HANDLE_GET_DATA(handle, config,
     257             :                                 struct nfs4acl_config,
     258             :                                 return NT_STATUS_INTERNAL_ERROR);
     259             : 
     260           0 :         naces = nfs4acli_get_xdrblob_naces(blob->length);
     261           0 :         nacl = nfs4acli_alloc(mem_ctx, naces);
     262             : 
     263           0 :         xdrmem_create(&xdr, (char *)blob->data, blob->length, XDR_DECODE);
     264             : 
     265           0 :         ok = xdr_nfsacl41i(&xdr, nacl);
     266           0 :         if (!ok) {
     267           0 :                 DBG_ERR("xdr_nfs4acl41 failed\n");
     268           0 :                 return NT_STATUS_INTERNAL_ERROR;
     269             :         }
     270             : 
     271           0 :         if (config->nfs_version == ACL4_XATTR_VERSION_40) {
     272           0 :                 nacl->na41_flag = 0;
     273             :         }
     274             : 
     275           0 :         *_nacl = nacl;
     276           0 :         return NT_STATUS_OK;
     277             : }
     278             : 
     279           0 : static NTSTATUS nfs4acli_to_smb4acl(struct vfs_handle_struct *handle,
     280             :                                     TALLOC_CTX *mem_ctx,
     281             :                                     nfsacl41i *nacl,
     282             :                                     struct SMB4ACL_T **_smb4acl)
     283             : {
     284           0 :         struct nfs4acl_config *config = NULL;
     285           0 :         struct SMB4ACL_T *smb4acl = NULL;
     286           0 :         unsigned nfsacl41_flag = 0;
     287           0 :         uint16_t smb4acl_flags = 0;
     288           0 :         unsigned naces = nfs4acli_get_naces(nacl);
     289             :         unsigned i;
     290             : 
     291           0 :         SMB_VFS_HANDLE_GET_DATA(handle, config,
     292             :                                 struct nfs4acl_config,
     293             :                                 return NT_STATUS_INTERNAL_ERROR);
     294             : 
     295           0 :         smb4acl = smb_create_smb4acl(mem_ctx);
     296           0 :         if (smb4acl == NULL) {
     297           0 :                 return NT_STATUS_INTERNAL_ERROR;
     298             :         }
     299             : 
     300           0 :         if (config->nfs_version > ACL4_XATTR_VERSION_40) {
     301           0 :                 nfsacl41_flag = nfs4acli_get_flags(nacl);
     302           0 :                 smb4acl_flags = nfs4acl_to_smb4acl_flags(nfsacl41_flag);
     303           0 :                 smbacl4_set_controlflags(smb4acl, smb4acl_flags);
     304             :         }
     305             : 
     306           0 :         DBG_DEBUG("flags [%x] nace [%u]\n", smb4acl_flags, naces);
     307             : 
     308           0 :         for (i = 0; i < naces; i++) {
     309           0 :                 nfsace4i *nace = nfs4acli_get_ace(nacl, i);
     310           0 :                 SMB_ACE4PROP_T smbace = { 0 };
     311             : 
     312           0 :                 DBG_DEBUG("type [%d] iflag [%x] flag [%x] mask [%x] who [%d]\n",
     313             :                           nace->type, nace->iflag, nace->flag,
     314             :                           nace->access_mask, nace->who);
     315             : 
     316           0 :                 smbace.aceType = nace->type;
     317           0 :                 smbace.aceFlags = nace->flag;
     318           0 :                 smbace.aceMask = nace->access_mask;
     319             : 
     320           0 :                 if (nace->iflag & ACEI4_SPECIAL_WHO) {
     321           0 :                         smbace.flags |= SMB_ACE4_ID_SPECIAL;
     322             : 
     323           0 :                         switch (nace->who) {
     324           0 :                         case ACE4_SPECIAL_OWNER:
     325           0 :                                 smbace.who.special_id = SMB_ACE4_WHO_OWNER;
     326           0 :                                 break;
     327             : 
     328           0 :                         case ACE4_SPECIAL_GROUP:
     329           0 :                                 smbace.who.special_id = SMB_ACE4_WHO_GROUP;
     330           0 :                                 break;
     331             : 
     332           0 :                         case ACE4_SPECIAL_EVERYONE:
     333           0 :                                 smbace.who.special_id = SMB_ACE4_WHO_EVERYONE;
     334           0 :                                 break;
     335             : 
     336           0 :                         default:
     337           0 :                                 DBG_ERR("Unknown special id [%d]\n", nace->who);
     338           0 :                                 continue;
     339             :                         }
     340             :                 } else {
     341           0 :                         if (nace->flag & ACE4_IDENTIFIER_GROUP) {
     342           0 :                                 smbace.who.gid = nace->who;
     343             :                         } else {
     344           0 :                                 smbace.who.uid = nace->who;
     345             :                         }
     346             :                 }
     347             : 
     348           0 :                 smb_add_ace4(smb4acl, &smbace);
     349             :         }
     350             : 
     351           0 :         *_smb4acl = smb4acl;
     352           0 :         return NT_STATUS_OK;
     353             : }
     354             : 
     355           0 : NTSTATUS nfs4acl_xdr_blob_to_smb4(struct vfs_handle_struct *handle,
     356             :                                   TALLOC_CTX *mem_ctx,
     357             :                                   DATA_BLOB *blob,
     358             :                                   struct SMB4ACL_T **_smb4acl)
     359             : {
     360           0 :         struct nfs4acl_config *config = NULL;
     361           0 :         nfsacl41i *nacl = NULL;
     362           0 :         struct SMB4ACL_T *smb4acl = NULL;
     363             :         NTSTATUS status;
     364             : 
     365           0 :         SMB_VFS_HANDLE_GET_DATA(handle, config,
     366             :                                 struct nfs4acl_config,
     367             :                                 return NT_STATUS_INTERNAL_ERROR);
     368             : 
     369           0 :         status = nfs4acl_xdr_blob_to_nfs4acli(handle, talloc_tos(), blob, &nacl);
     370           0 :         if (!NT_STATUS_IS_OK(status)) {
     371           0 :                 return status;
     372             :         }
     373             : 
     374           0 :         status = nfs4acli_to_smb4acl(handle, mem_ctx, nacl, &smb4acl);
     375           0 :         TALLOC_FREE(nacl);
     376           0 :         if (!NT_STATUS_IS_OK(status)) {
     377           0 :                 return status;
     378             :         }
     379             : 
     380           0 :         *_smb4acl = smb4acl;
     381           0 :         return NT_STATUS_OK;
     382             : }
     383             : 
     384             : #else /* !HAVE_RPC_XDR_H */
     385             : #include "nfs4acl_xattr_xdr.h"
     386             : NTSTATUS nfs4acl_xdr_blob_to_smb4(struct vfs_handle_struct *handle,
     387             :                                   TALLOC_CTX *mem_ctx,
     388             :                                   DATA_BLOB *blob,
     389             :                                   struct SMB4ACL_T **_smb4acl)
     390             : {
     391             :         return NT_STATUS_NOT_SUPPORTED;
     392             : }
     393             : 
     394             : NTSTATUS nfs4acl_smb4acl_to_xdr_blob(vfs_handle_struct *handle,
     395             :                                      TALLOC_CTX *mem_ctx,
     396             :                                      struct SMB4ACL_T *smbacl,
     397             :                                      DATA_BLOB *blob)
     398             : {
     399             :         return NT_STATUS_NOT_SUPPORTED;
     400             : }
     401             : #endif /* HAVE_RPC_XDR_H */

Generated by: LCOV version 1.13