LCOV - code coverage report
Current view: top level - source3/modules - nfs4acl_xattr_nfs.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 319 420 76.0 %
Date: 2024-04-21 15:09:00 Functions: 26 26 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) Ralph Boehme 2018
       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 "system/passwd.h"
      22             : #include "libcli/security/security_descriptor.h"
      23             : #include "libcli/security/security_token.h"
      24             : 
      25             : #ifdef HAVE_RPC_XDR_H
      26             : /* <rpc/xdr.h> uses TRUE and FALSE */
      27             : #ifdef TRUE
      28             : #undef TRUE
      29             : #endif
      30             : 
      31             : #ifdef FALSE
      32             : #undef FALSE
      33             : #endif
      34             : 
      35             : #ifdef HAVE_RPC_TYPES_H
      36             : #include <rpc/types.h>
      37             : #endif
      38             : #include <rpc/xdr.h>
      39             : 
      40             : #include "nfs4_acls.h"
      41             : #include "nfs41acl.h"
      42             : #include "nfs4acl_xattr.h"
      43             : #include "nfs4acl_xattr_nfs.h"
      44             : #include "nfs4acl_xattr_util.h"
      45             : 
      46             : #undef DBGC_CLASS
      47             : #define DBGC_CLASS DBGC_VFS
      48             : 
      49             : #define OVERFLOW_CHECK(val1, val2) ((val1) + (val2) < (val1))
      50             : #define XDR_UTF8STR_ALIGNMENT 4
      51             : #define XDR_UTF8STR_ALIGN(l) \
      52             :         (((l) + ((XDR_UTF8STR_ALIGNMENT) - 1)) & ~((XDR_UTF8STR_ALIGNMENT) - 1))
      53             : 
      54             : static struct nfs4_to_smb4_id_map {
      55             :         const char *nfs4_id;
      56             :         uint32_t smb4_id;
      57             : } nfs4_to_smb4_id_map[] = {
      58             :         {"OWNER@",            SMB_ACE4_WHO_OWNER},
      59             :         {"GROUP@",            SMB_ACE4_WHO_GROUP},
      60             :         {"EVERYONE@",         SMB_ACE4_WHO_EVERYONE},
      61             :         {"INTERACTIVE@",      SMB_ACE4_WHO_INTERACTIVE},
      62             :         {"NETWORK@",          SMB_ACE4_WHO_NETWORK},
      63             :         {"DIALUP@",           SMB_ACE4_WHO_DIALUP},
      64             :         {"BATCH@",            SMB_ACE4_WHO_BATCH},
      65             :         {"ANONYMOUS@",                SMB_ACE4_WHO_ANONYMOUS},
      66             :         {"AUTHENTICATED@",    SMB_ACE4_WHO_AUTHENTICATED},
      67             :         {"SERVICE@",          SMB_ACE4_WHO_SERVICE},
      68             : };
      69             : 
      70        3272 : static bool is_special_nfs4_id(const char *nfs4_id)
      71             : {
      72        3272 :         char *at = NULL;
      73             : 
      74        3272 :         at = strchr(nfs4_id, '@');
      75        3272 :         if (at == NULL) {
      76         404 :                 return false;
      77             :         }
      78        2868 :         if (at[1] != '\0') {
      79           0 :                 return false;
      80             :         }
      81        2868 :         return true;
      82             : }
      83             : 
      84        2868 : static bool map_special_nfs4_to_smb4_id(const char *nfs4_id, uint32_t *smb4_id)
      85             : {
      86             :         size_t i;
      87             :         int cmp;
      88             : 
      89        4692 :         for (i = 0; i < ARRAY_SIZE(nfs4_to_smb4_id_map); i++) {
      90        4692 :                 cmp = strcmp(nfs4_to_smb4_id_map[i].nfs4_id, nfs4_id);
      91        4692 :                 if (cmp != 0) {
      92        1824 :                         continue;
      93             :                 }
      94        2868 :                 *smb4_id = nfs4_to_smb4_id_map[i].smb4_id;
      95        2868 :                 return true;
      96             :         }
      97           0 :         return false;
      98             : }
      99             : 
     100        1480 : static bool map_special_smb4_to_nfs4_id(uint32_t smb4_id, const char **nfs4_id)
     101             : {
     102             :         size_t i;
     103             : 
     104        1856 :         for (i = 0; i < ARRAY_SIZE(nfs4_to_smb4_id_map); i++) {
     105        1856 :                 if (nfs4_to_smb4_id_map[i].smb4_id != smb4_id) {
     106         376 :                         continue;
     107             :                 }
     108        1480 :                 *nfs4_id = nfs4_to_smb4_id_map[i].nfs4_id;
     109        1480 :                 return true;
     110             :         }
     111           0 :         return false;
     112             : }
     113             : 
     114        2754 : static unsigned nfs40acl_get_naces(nfsacl40 *nacl)
     115             : {
     116        2754 :         return nacl->na40_aces.na40_aces_len;
     117             : }
     118             : 
     119        2754 : static unsigned nfs41acl_get_naces(nfsacl41 *nacl)
     120             : {
     121        2754 :         return nacl->na41_aces.na41_aces_len;
     122             : }
     123             : 
     124        2216 : static void nfs40acl_set_naces(nfsacl40 *nacl, unsigned naces)
     125             : {
     126        2216 :         nacl->na40_aces.na40_aces_len = naces;
     127        2216 : }
     128             : 
     129        2216 : static void nfs41acl_set_naces(nfsacl41 *nacl, unsigned naces)
     130             : {
     131        2216 :         nacl->na41_aces.na41_aces_len = naces;
     132        2216 : }
     133             : 
     134        1252 : static unsigned nfs41acl_get_flags(nfsacl41 *nacl)
     135             : {
     136        1252 :         return nacl->na41_flag;
     137             : }
     138             : 
     139         714 : static void nfs41acl_set_flags(nfsacl41 *nacl, unsigned flags)
     140             : {
     141         714 :         nacl->na41_flag = flags;
     142         714 : }
     143             : 
     144        3212 : static nfsace4 *nfs40acl_get_ace(nfsacl40 *nacl, size_t n)
     145             : {
     146        3212 :         return &nacl->na40_aces.na40_aces_val[n];
     147             : }
     148             : 
     149        3212 : static nfsace4 *nfs41acl_get_ace(nfsacl41 *nacl, size_t n)
     150             : {
     151        3212 :         return &nacl->na41_aces.na41_aces_val[n];
     152             : }
     153             : 
     154         714 : static size_t nfs40acl_get_xdrblob_size(nfsacl40 *nacl)
     155             : {
     156             :         size_t acl_size;
     157             :         size_t aces_size;
     158             :         size_t identifier_size;
     159             :         unsigned i;
     160         714 :         unsigned naces = nfs40acl_get_naces(nacl);
     161             : 
     162             :         /* ACE structure minus actual identifier strings */
     163             :         struct nfsace4_size {
     164             :                 acetype4 type;
     165             :                 aceflag4 flag;
     166             :                 acemask4 access_mask;
     167             :                 u_int who_length;
     168             :         };
     169             : 
     170             :         /*
     171             :          * acl_size =
     172             :          *   sizeof(ace_count) +
     173             :          *   (ace_count * (sizeof(nfsace4_size)) +
     174             :          *   length of all identifiers strings
     175             :          */
     176             : 
     177         714 :         acl_size = sizeof(unsigned);
     178             : 
     179         714 :         if (naces > NFS4ACL_XDR_MAX_ACES) {
     180           0 :                 DBG_ERR("Too many ACEs: %u\n", naces);
     181           0 :                 return 0;
     182             :         }
     183             : 
     184         714 :         aces_size = naces * sizeof(struct nfsace4_size);
     185             : 
     186         714 :         if (OVERFLOW_CHECK(acl_size, aces_size)) {
     187           0 :                 DBG_ERR("Integer Overflow error\n");
     188           0 :                 return 0;
     189             :         }
     190         714 :         acl_size += aces_size;
     191             : 
     192         714 :         identifier_size = 0;
     193        1502 :         for (i = 0;  i < naces; i++) {
     194         788 :                 nfsace4 *nace = nfs40acl_get_ace(nacl, i);
     195         788 :                 size_t string_size = nace->who.utf8string_len;
     196             :                 size_t id_size;
     197             : 
     198         788 :                 id_size = XDR_UTF8STR_ALIGN(string_size);
     199             : 
     200         788 :                 if (OVERFLOW_CHECK(identifier_size, id_size)) {
     201           0 :                         DBG_ERR("Integer Overflow error\n");
     202           0 :                         return 0;
     203             :                 }
     204         788 :                 identifier_size += id_size;
     205             :         }
     206             : 
     207         714 :         if (OVERFLOW_CHECK(acl_size, identifier_size)) {
     208           0 :                 DBG_ERR("Integer Overflow error\n");
     209           0 :                 return 0;
     210             :         }
     211         714 :         acl_size += identifier_size;
     212             : 
     213         714 :         DBG_DEBUG("acl_size: %zd\n", acl_size);
     214         714 :         return acl_size;
     215             : }
     216             : 
     217         714 : static size_t nfs41acl_get_xdrblob_size(nfsacl41 *nacl)
     218             : {
     219             :         size_t acl_size;
     220             :         size_t aces_size;
     221             :         size_t identifier_size;
     222             :         unsigned i;
     223         714 :         unsigned naces = nfs41acl_get_naces(nacl);
     224             : 
     225             :         /* ACE structure minus actual identifier strings */
     226             :         struct nfsace4_size {
     227             :                 acetype4 type;
     228             :                 aceflag4 flag;
     229             :                 acemask4 access_mask;
     230             :                 u_int who_length;
     231             :         };
     232             : 
     233             :         /*
     234             :          * acl_size =
     235             :          *   sizeof(acl_flag) +
     236             :          *   sizeof(ace_count) +
     237             :          *   (ace_count * (sizeof(nfsace4_size)) +
     238             :          *   length of all identifiers strings
     239             :          */
     240             : 
     241         714 :         acl_size = 2 * sizeof(unsigned);
     242             : 
     243         714 :         if (naces > NFS4ACL_XDR_MAX_ACES) {
     244           0 :                 DBG_ERR("Too many ACEs: %u\n", naces);
     245           0 :                 return 0;
     246             :         }
     247             : 
     248         714 :         aces_size = naces * sizeof(struct nfsace4_size);
     249             : 
     250         714 :         if (OVERFLOW_CHECK(acl_size, aces_size)) {
     251           0 :                 DBG_ERR("Integer Overflow error\n");
     252           0 :                 return 0;
     253             :         }
     254         714 :         acl_size += aces_size;
     255             : 
     256         714 :         identifier_size = 0;
     257        1502 :         for (i = 0;  i < naces; i++) {
     258         788 :                 nfsace4 *nace = nfs41acl_get_ace(nacl, i);
     259         788 :                 size_t string_size = nace->who.utf8string_len;
     260             :                 size_t id_size;
     261             : 
     262         788 :                 id_size = XDR_UTF8STR_ALIGN(string_size);
     263             : 
     264         788 :                 if (OVERFLOW_CHECK(identifier_size, id_size)) {
     265           0 :                         DBG_ERR("Integer Overflow error\n");
     266           0 :                         return 0;
     267             :                 }
     268         788 :                 identifier_size += id_size;
     269             :         }
     270             : 
     271         714 :         if (OVERFLOW_CHECK(acl_size, identifier_size)) {
     272           0 :                 DBG_ERR("Integer Overflow error\n");
     273           0 :                 return 0;
     274             :         }
     275         714 :         acl_size += identifier_size;
     276             : 
     277         714 :         DBG_DEBUG("acl_size: %zd\n", acl_size);
     278         714 :         return acl_size;
     279             : }
     280             : 
     281         714 : static nfsacl40 *nfs40acl_alloc(TALLOC_CTX *mem_ctx, unsigned naces)
     282             : {
     283             :         size_t acl_size;
     284             :         size_t aces_size;
     285         714 :         nfsacl40 *nacl = NULL;
     286             : 
     287         714 :         if (naces > NFS4ACL_XDR_MAX_ACES) {
     288           0 :                 DBG_ERR("Too many ACEs: %d\n", naces);
     289           0 :                 return NULL;
     290             :         }
     291             : 
     292         714 :         acl_size = sizeof(nfsacl40);
     293         714 :         aces_size = (naces * sizeof(struct nfsace4));
     294             : 
     295         714 :         if (OVERFLOW_CHECK(acl_size, aces_size)) {
     296           0 :                 DBG_ERR("Integer Overflow error\n");
     297           0 :                 return NULL;
     298             :         }
     299         714 :         acl_size += aces_size;
     300             : 
     301         714 :         nacl = talloc_zero_size(mem_ctx, acl_size);
     302         714 :         if (nacl == NULL) {
     303           0 :                 DBG_ERR("talloc_zero_size failed\n");
     304           0 :                 return NULL;
     305             :         }
     306             : 
     307         714 :         nfs40acl_set_naces(nacl, naces);
     308         714 :         nacl->na40_aces.na40_aces_val =
     309         714 :                 (nfsace4 *)((uint8_t *)nacl + sizeof(nfsacl40));
     310             : 
     311         714 :         return nacl;
     312             : }
     313             : 
     314         714 : static nfsacl41 *nfs41acl_alloc(TALLOC_CTX *mem_ctx, unsigned naces)
     315             : {
     316             :         size_t acl_size;
     317             :         size_t aces_size;
     318         714 :         nfsacl41 *nacl = NULL;
     319             : 
     320         714 :         if (naces > NFS4ACL_XDR_MAX_ACES) {
     321           0 :                 DBG_ERR("Too many ACEs: %d\n", naces);
     322           0 :                 return NULL;
     323             :         }
     324             : 
     325         714 :         acl_size = sizeof(nfsacl41);
     326         714 :         aces_size = (naces * sizeof(struct nfsace4));
     327             : 
     328         714 :         if (OVERFLOW_CHECK(acl_size, aces_size)) {
     329           0 :                 DBG_ERR("Integer Overflow error\n");
     330           0 :                 return NULL;
     331             :         }
     332         714 :         acl_size += aces_size;
     333             : 
     334         714 :         nacl = talloc_zero_size(mem_ctx, acl_size);
     335         714 :         if (nacl == NULL) {
     336           0 :                 DBG_ERR("talloc_zero_size failed\n");
     337           0 :                 return NULL;
     338             :         }
     339             : 
     340         714 :         nfs41acl_set_naces(nacl, naces);
     341         714 :         nacl->na41_aces.na41_aces_val =
     342         714 :                 (nfsace4 *)((uint8_t *)nacl + sizeof(nfsacl41));
     343             : 
     344         714 :         return nacl;
     345             : }
     346             : 
     347        1480 : static bool create_special_id(TALLOC_CTX *mem_ctx,
     348             :                               nfsace4 *nace,
     349             :                               const char *id)
     350             : {
     351        1480 :         char *s = talloc_strdup(mem_ctx, id);
     352             : 
     353        1480 :         if (s == NULL) {
     354           0 :                 DBG_ERR("talloc_strdup failed\n");
     355           0 :                 return false;
     356             :         }
     357        1480 :         nace->who.utf8string_val = s;
     358        1480 :         nace->who.utf8string_len = talloc_get_size(s) - 1;
     359        1480 :         return true;
     360             : }
     361             : 
     362        1576 : static bool map_smb4_to_nfs4_id(TALLOC_CTX *mem_ctx,
     363             :                                 struct nfs4acl_config *config,
     364             :                                 nfsace4 *nace,
     365             :                                 SMB_ACE4PROP_T *sace)
     366             : {
     367        1576 :         const char *nfs4_id = NULL;
     368        1576 :         const char *name = NULL;
     369        1576 :         char *ace_name = NULL;
     370             :         uid_t id;
     371             :         bool ok;
     372             : 
     373        1576 :         if (sace->flags & SMB_ACE4_ID_SPECIAL) {
     374        1480 :                 ok = map_special_smb4_to_nfs4_id(sace->who.special_id,
     375             :                                                  &nfs4_id);
     376        1480 :                 if (!ok) {
     377           0 :                         DBG_ERR("Unsupported special id [%"PRIu32"]\n",
     378             :                                 sace->who.special_id);
     379           0 :                         return false;
     380             :                 }
     381             : 
     382        1480 :                 ok = create_special_id(mem_ctx, nace, nfs4_id);
     383        1480 :                 if (!ok) {
     384           0 :                         return false;
     385             :                 }
     386        1480 :                 DBG_DEBUG("Special id [%s]\n", nace->who.utf8string_val);
     387        1480 :                 return true;
     388             :         }
     389             : 
     390          96 :         if (sace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP) {
     391          20 :                 nace->flag |= ACE4_IDENTIFIER_GROUP;
     392             :         }
     393             : 
     394          96 :         if (config->nfs4_id_numeric) {
     395           0 :                 char *strid = NULL;
     396             : 
     397           0 :                 if (sace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP) {
     398           0 :                         id = sace->who.gid;
     399             :                 } else {
     400           0 :                         id = sace->who.uid;
     401             :                 }
     402             : 
     403           0 :                 strid = talloc_asprintf(mem_ctx, "%jd", (intmax_t)id);
     404           0 :                 if (strid == NULL) {
     405           0 :                         DBG_ERR("talloc_asprintf failed\n");
     406           0 :                         return false;
     407             :                 }
     408           0 :                 nace->who.utf8string_val = strid;
     409           0 :                 nace->who.utf8string_len = talloc_get_size(strid) - 1;
     410           0 :                 DBG_DEBUG("Numeric id [%s]\n", nace->who.utf8string_val);
     411           0 :                 return true;
     412             :         }
     413             : 
     414          96 :         if (sace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP) {
     415          20 :                 struct group *grp = NULL;
     416             : 
     417          20 :                 grp = getgrgid(sace->who.gid);
     418          20 :                 if (grp == NULL) {
     419           0 :                         DBG_ERR("Unknown gid [%jd]\n", (intmax_t)sace->who.gid);
     420           0 :                         return false;
     421             :                 }
     422          20 :                 name = grp->gr_name;
     423             :         } else {
     424          76 :                 struct passwd *pwd = NULL;
     425             : 
     426          76 :                 pwd = getpwuid(sace->who.uid);
     427          76 :                 if (pwd == NULL) {
     428           0 :                         DBG_ERR("Unknown uid [%jd]\n", (intmax_t)sace->who.uid);
     429           0 :                         return false;
     430             :                 }
     431          76 :                 name = pwd->pw_name;
     432             :         }
     433             : 
     434          96 :         ace_name = talloc_strdup(mem_ctx, name);
     435          96 :         if (ace_name == NULL) {
     436           0 :                 DBG_ERR("talloc_asprintf failed\n");
     437           0 :                 return false;
     438             :         }
     439          96 :         nace->who.utf8string_val = ace_name;
     440          96 :         nace->who.utf8string_len = talloc_get_size(ace_name) - 1;
     441             : 
     442          96 :         DBG_DEBUG("id [%s]\n", nace->who.utf8string_val);
     443          96 :         return true;
     444             : }
     445             : 
     446         714 : static bool smb4acl_to_nfs40acl(vfs_handle_struct *handle,
     447             :                                TALLOC_CTX *mem_ctx,
     448             :                                struct SMB4ACL_T *smb4acl,
     449             :                                nfsacl40 **_nacl)
     450             : {
     451         714 :         struct nfs4acl_config *config = NULL;
     452         714 :         struct SMB4ACE_T *smb4ace = NULL;
     453         714 :         nfsacl40 *nacl = NULL;
     454         714 :         size_t naces = smb_get_naces(smb4acl);
     455             :         bool ok;
     456             : 
     457         714 :         SMB_VFS_HANDLE_GET_DATA(handle, config,
     458             :                                 struct nfs4acl_config,
     459             :                                 return false);
     460             : 
     461         714 :         nacl = nfs40acl_alloc(mem_ctx, naces);
     462         714 :         nfs40acl_set_naces(nacl, 0);
     463             : 
     464         714 :         smb4ace = smb_first_ace4(smb4acl);
     465        1502 :         while (smb4ace != NULL) {
     466         788 :                 SMB_ACE4PROP_T *ace4prop = smb_get_ace4(smb4ace);
     467         788 :                 size_t nace_count = nfs40acl_get_naces(nacl);
     468         788 :                 nfsace4 *nace = nfs40acl_get_ace(nacl, nace_count);
     469             : 
     470         788 :                 nace->type = ace4prop->aceType;
     471         788 :                 nace->flag = ace4prop->aceFlags;
     472         788 :                 nace->access_mask = ace4prop->aceMask;
     473             : 
     474         788 :                 ok = map_smb4_to_nfs4_id(nacl, config, nace, ace4prop);
     475         788 :                 if (!ok) {
     476           0 :                         smb4ace = smb_next_ace4(smb4ace);
     477           0 :                         continue;
     478             :                 }
     479             : 
     480         788 :                 nace_count++;
     481         788 :                 nfs40acl_set_naces(nacl, nace_count);
     482         788 :                 smb4ace = smb_next_ace4(smb4ace);
     483             :         }
     484             : 
     485         714 :         *_nacl = nacl;
     486         714 :         return true;
     487             : }
     488             : 
     489         714 : static bool smb4acl_to_nfs41acl(vfs_handle_struct *handle,
     490             :                                TALLOC_CTX *mem_ctx,
     491             :                                struct SMB4ACL_T *smb4acl,
     492             :                                nfsacl41 **_nacl)
     493             : {
     494         714 :         struct nfs4acl_config *config = NULL;
     495         714 :         struct SMB4ACE_T *smb4ace = NULL;
     496         714 :         nfsacl41 *nacl = NULL;
     497         714 :         size_t naces = smb_get_naces(smb4acl);
     498             :         uint16_t smb4acl_flags;
     499             :         unsigned nacl_flags;
     500             :         bool ok;
     501             : 
     502         714 :         SMB_VFS_HANDLE_GET_DATA(handle, config,
     503             :                                 struct nfs4acl_config,
     504             :                                 return false);
     505             : 
     506         714 :         nacl = nfs41acl_alloc(mem_ctx, naces);
     507         714 :         nfs41acl_set_naces(nacl, 0);
     508             : 
     509         714 :         smb4acl_flags = smbacl4_get_controlflags(smb4acl);
     510         714 :         nacl_flags = smb4acl_to_nfs4acl_flags(smb4acl_flags);
     511         714 :         nfs41acl_set_flags(nacl, nacl_flags);
     512             : 
     513         714 :         smb4ace = smb_first_ace4(smb4acl);
     514        1502 :         while (smb4ace != NULL) {
     515         788 :                 SMB_ACE4PROP_T *ace4prop = smb_get_ace4(smb4ace);
     516         788 :                 size_t nace_count = nfs41acl_get_naces(nacl);
     517         788 :                 nfsace4 *nace = nfs41acl_get_ace(nacl, nace_count);
     518             : 
     519         788 :                 nace->type = ace4prop->aceType;
     520         788 :                 nace->flag = ace4prop->aceFlags;
     521         788 :                 nace->access_mask = ace4prop->aceMask;
     522             : 
     523         788 :                 ok = map_smb4_to_nfs4_id(nacl, config, nace, ace4prop);
     524         788 :                 if (!ok) {
     525           0 :                         smb4ace = smb_next_ace4(smb4ace);
     526           0 :                         continue;
     527             :                 }
     528             : 
     529         788 :                 nace_count++;
     530         788 :                 nfs41acl_set_naces(nacl, nace_count);
     531         788 :                 smb4ace = smb_next_ace4(smb4ace);
     532             :         }
     533             : 
     534         714 :         *_nacl = nacl;
     535         714 :         return true;
     536             : }
     537             : 
     538        1428 : NTSTATUS nfs4acl_smb4acl_to_nfs_blob(vfs_handle_struct *handle,
     539             :                                      TALLOC_CTX *mem_ctx,
     540             :                                      struct SMB4ACL_T *smb4acl,
     541             :                                      DATA_BLOB *_blob)
     542             : {
     543        1428 :         struct nfs4acl_config *config = NULL;
     544        1428 :         nfsacl40 *nacl40 = NULL;
     545        1428 :         nfsacl41 *nacl41 = NULL;
     546        1428 :         XDR xdr = {0};
     547             :         size_t aclblobsize;
     548             :         DATA_BLOB blob;
     549             :         bool ok;
     550             : 
     551        1428 :         SMB_VFS_HANDLE_GET_DATA(handle, config,
     552             :                                 struct nfs4acl_config,
     553             :                                 return NT_STATUS_INTERNAL_ERROR);
     554             : 
     555        1428 :         if (config->nfs_version == ACL4_XATTR_VERSION_40) {
     556         714 :                 ok = smb4acl_to_nfs40acl(handle, mem_ctx, smb4acl, &nacl40);
     557         714 :                 if (!ok) {
     558           0 :                         DBG_ERR("smb4acl_to_nfs4acl failed\n");
     559           0 :                         return NT_STATUS_INTERNAL_ERROR;
     560             :                 }
     561             : 
     562         714 :                 aclblobsize = nfs40acl_get_xdrblob_size(nacl40);
     563         714 :                 if (aclblobsize == 0) {
     564           0 :                         DBG_ERR("Error calculating XDR blob size\n");
     565           0 :                         return NT_STATUS_INTERNAL_ERROR;
     566             :                 }
     567             :         } else {
     568         714 :                 ok = smb4acl_to_nfs41acl(handle, mem_ctx, smb4acl, &nacl41);
     569         714 :                 if (!ok) {
     570           0 :                         DBG_ERR("smb4acl_to_nfs4acl failed\n");
     571           0 :                         return NT_STATUS_INTERNAL_ERROR;
     572             :                 }
     573             : 
     574         714 :                 aclblobsize = nfs41acl_get_xdrblob_size(nacl41);
     575         714 :                 if (aclblobsize == 0) {
     576           0 :                         DBG_ERR("Error calculating XDR blob size\n");
     577           0 :                         return NT_STATUS_INTERNAL_ERROR;
     578             :                 }
     579             :         }
     580             : 
     581        1428 :         blob = data_blob_talloc(mem_ctx, NULL, aclblobsize);
     582        1428 :         if (blob.data == NULL) {
     583           0 :                 TALLOC_FREE(nacl40);
     584           0 :                 TALLOC_FREE(nacl41);
     585           0 :                 return NT_STATUS_NO_MEMORY;
     586             :         }
     587             : 
     588        1428 :         xdrmem_create(&xdr, (char *)blob.data, blob.length, XDR_ENCODE);
     589             : 
     590        1428 :         if (config->nfs_version == ACL4_XATTR_VERSION_40) {
     591         714 :                 ok = xdr_nfsacl40(&xdr, nacl40);
     592         714 :                 TALLOC_FREE(nacl40);
     593         714 :                 if (!ok) {
     594           0 :                         DBG_ERR("xdr_nfs4acl40 failed\n");
     595           0 :                         return NT_STATUS_NO_MEMORY;
     596             :                 }
     597             :         } else {
     598         714 :                 ok = xdr_nfsacl41(&xdr, nacl41);
     599         714 :                 TALLOC_FREE(nacl41);
     600         714 :                 if (!ok) {
     601           0 :                         DBG_ERR("xdr_nfs4acl40 failed\n");
     602           0 :                         return NT_STATUS_NO_MEMORY;
     603             :                 }
     604             :         }
     605             : 
     606        1428 :         *_blob = blob;
     607        1428 :         return NT_STATUS_OK;
     608             : }
     609             : 
     610        1252 : static NTSTATUS nfs4acl_nfs_blob_to_nfs40acl(struct vfs_handle_struct *handle,
     611             :                                              TALLOC_CTX *mem_ctx,
     612             :                                              DATA_BLOB *blob,
     613             :                                              nfsacl40 **_nacl)
     614             : {
     615        1252 :         nfsacl40 *nacl = NULL;
     616        1252 :         XDR xdr = {0};
     617             :         bool ok;
     618             : 
     619        1252 :         nacl = talloc_zero_size(mem_ctx, sizeof(nfsacl40));
     620        1252 :         if (nacl == NULL) {
     621           0 :                 DBG_ERR("talloc_zero_size failed\n");
     622           0 :                 return NT_STATUS_NO_MEMORY;
     623             :         }
     624             : 
     625        1252 :         xdrmem_create(&xdr, (char *)blob->data, blob->length, XDR_DECODE);
     626             : 
     627        1252 :         ok = xdr_nfsacl40(&xdr, nacl);
     628        1252 :         if (!ok) {
     629           0 :                 DBG_ERR("xdr_nfsacl40 failed\n");
     630           0 :                 return NT_STATUS_INTERNAL_ERROR;
     631             :         }
     632             : 
     633        1252 :         DBG_DEBUG("naces = %d \n", nacl->na40_aces.na40_aces_len);
     634             : 
     635        1252 :         *_nacl = nacl;
     636        1252 :         return NT_STATUS_OK;
     637             : }
     638             : 
     639        1252 : static NTSTATUS nfs4acl_nfs_blob_to_nfs41acl(struct vfs_handle_struct *handle,
     640             :                                              TALLOC_CTX *mem_ctx,
     641             :                                              DATA_BLOB *blob,
     642             :                                              nfsacl41 **_nacl)
     643             : {
     644        1252 :         nfsacl41 *nacl = NULL;
     645        1252 :         XDR xdr = {0};
     646             :         bool ok;
     647             : 
     648        1252 :         nacl = talloc_zero_size(mem_ctx, sizeof(nfsacl41));
     649        1252 :         if (nacl == NULL) {
     650           0 :                 DBG_ERR("talloc_zero_size failed\n");
     651           0 :                 return NT_STATUS_NO_MEMORY;
     652             :         }
     653             : 
     654        1252 :         xdrmem_create(&xdr, (char *)blob->data, blob->length, XDR_DECODE);
     655             : 
     656        1252 :         ok = xdr_nfsacl41(&xdr, nacl);
     657        1252 :         if (!ok) {
     658           0 :                 DBG_ERR("xdr_nfsacl40 failed\n");
     659           0 :                 return NT_STATUS_INTERNAL_ERROR;
     660             :         }
     661             : 
     662        1252 :         DBG_DEBUG("naces = %d \n", nacl->na41_aces.na41_aces_len);
     663             : 
     664        1252 :         *_nacl = nacl;
     665        1252 :         return NT_STATUS_OK;
     666             : }
     667             : 
     668        3272 : static bool map_ace_nfs4_to_smb4(struct nfs4acl_config *config,
     669             :                                  const nfsace4 *nace,
     670             :                                  SMB_ACE4PROP_T *sace)
     671             : {
     672        3272 :         char *name = NULL;
     673        3272 :         char *p = NULL;
     674             :         uint32_t smb4_id;
     675             :         bool ok;
     676             : 
     677        3272 :         name = talloc_strndup(talloc_tos(),
     678        3272 :                               nace->who.utf8string_val,
     679        3272 :                               nace->who.utf8string_len);
     680        3272 :         if (name == NULL) {
     681           0 :                 return false;
     682             :         }
     683             : 
     684        3272 :         sace->aceType = nace->type;
     685        3272 :         sace->aceFlags = nace->flag;
     686        3272 :         sace->aceMask = nace->access_mask;
     687             : 
     688        3272 :         if (is_special_nfs4_id(name)) {
     689        2868 :                 ok = map_special_nfs4_to_smb4_id(name, &smb4_id);
     690        2868 :                 if (!ok) {
     691           0 :                         DBG_WARNING("Unknown special id [%s]\n", name);
     692           0 :                         return false;
     693             :                 }
     694        2868 :                 sace->flags |= SMB_ACE4_ID_SPECIAL;
     695        2868 :                 sace->who.special_id = smb4_id;
     696        2868 :                 return true;
     697             :         }
     698             : 
     699         404 :         p = strtok(name, "@");
     700         404 :         if (p == NULL && !config->nfs4_id_numeric) {
     701           0 :                 DBG_ERR("Unqualified name [%s]\n", name);
     702           0 :                 TALLOC_FREE(name);
     703           0 :                 return false;
     704             :         }
     705             : 
     706             :         /*
     707             :          * nametouid() and nametogid() work with both names and numbers...
     708             :          */
     709             : 
     710         404 :         if (nace->flag & ACE4_IDENTIFIER_GROUP) {
     711          36 :                 sace->who.gid = nametogid(name);
     712          36 :                 if (sace->who.gid == (gid_t)-1) {
     713           0 :                         DBG_ERR("converting id [%s] failed\n", name);
     714           0 :                         TALLOC_FREE(name);
     715           0 :                         return false;
     716             :                 }
     717          36 :                 TALLOC_FREE(name);
     718          36 :                 return true;
     719             :         }
     720             : 
     721         368 :         sace->who.uid = nametouid(name);
     722         368 :         if (sace->who.uid == (gid_t)-1) {
     723           0 :                 DBG_ERR("converting id [%s] failed\n", name);
     724           0 :                 TALLOC_FREE(name);
     725           0 :                 return false;
     726             :         }
     727         368 :         TALLOC_FREE(name);
     728         368 :         return true;
     729             : }
     730             : 
     731        1252 : static NTSTATUS nfs40acl_to_smb4acl(struct vfs_handle_struct *handle,
     732             :                                    TALLOC_CTX *mem_ctx,
     733             :                                    nfsacl40 *nacl,
     734             :                                    struct SMB4ACL_T **_smb4acl)
     735             : {
     736        1252 :         struct nfs4acl_config *config = NULL;
     737        1252 :         struct SMB4ACL_T *smb4acl = NULL;
     738        1252 :         unsigned naces = nfs40acl_get_naces(nacl);
     739             :         unsigned int i;
     740             :         bool ok;
     741             : 
     742        1252 :         SMB_VFS_HANDLE_GET_DATA(handle, config,
     743             :                                 struct nfs4acl_config,
     744             :                                 return NT_STATUS_INTERNAL_ERROR);
     745             : 
     746        1252 :         smb4acl = smb_create_smb4acl(mem_ctx);
     747        1252 :         if (smb4acl == NULL) {
     748           0 :                 return NT_STATUS_INTERNAL_ERROR;
     749             :         }
     750             : 
     751        1252 :         DBG_DEBUG("nace [%u]\n", naces);
     752             : 
     753        2888 :         for (i = 0; i < naces; i++) {
     754        1636 :                 nfsace4 *nace = nfs40acl_get_ace(nacl, i);
     755        1636 :                 SMB_ACE4PROP_T sace = { 0 };
     756             : 
     757        1636 :                 DBG_DEBUG("type [%d] flag [%x] mask [%x] who [%*s]\n",
     758             :                           nace->type, nace->flag,
     759             :                           nace->access_mask,
     760             :                           nace->who.utf8string_len,
     761             :                           nace->who.utf8string_val);
     762             : 
     763        1636 :                 ok = map_ace_nfs4_to_smb4(config, nace, &sace);
     764        1636 :                 if (!ok) {
     765           0 :                         continue;
     766             :                 }
     767             : 
     768        1636 :                 smb_add_ace4(smb4acl, &sace);
     769             :         }
     770             : 
     771        1252 :         *_smb4acl = smb4acl;
     772        1252 :         return NT_STATUS_OK;
     773             : }
     774             : 
     775        1252 : static NTSTATUS nfs41acl_to_smb4acl(struct vfs_handle_struct *handle,
     776             :                                    TALLOC_CTX *mem_ctx,
     777             :                                    nfsacl41 *nacl,
     778             :                                    struct SMB4ACL_T **_smb4acl)
     779             : {
     780        1252 :         struct nfs4acl_config *config = NULL;
     781        1252 :         struct SMB4ACL_T *smb4acl = NULL;
     782        1252 :         unsigned nfsacl41_flag = 0;
     783        1252 :         uint16_t smb4acl_flags = 0;
     784        1252 :         unsigned naces = nfs41acl_get_naces(nacl);
     785             :         unsigned int i;
     786             :         bool ok;
     787             : 
     788        1252 :         SMB_VFS_HANDLE_GET_DATA(handle, config,
     789             :                                 struct nfs4acl_config,
     790             :                                 return NT_STATUS_INTERNAL_ERROR);
     791             : 
     792        1252 :         smb4acl = smb_create_smb4acl(mem_ctx);
     793        1252 :         if (smb4acl == NULL) {
     794           0 :                 return NT_STATUS_INTERNAL_ERROR;
     795             :         }
     796             : 
     797        1252 :         nfsacl41_flag = nfs41acl_get_flags(nacl);
     798        1252 :         smb4acl_flags = nfs4acl_to_smb4acl_flags(nfsacl41_flag);
     799        1252 :         smbacl4_set_controlflags(smb4acl, smb4acl_flags);
     800             : 
     801        1252 :         DBG_DEBUG("flags [%x] nace [%u]\n", smb4acl_flags, naces);
     802             : 
     803        2888 :         for (i = 0; i < naces; i++) {
     804        1636 :                 nfsace4 *nace = nfs41acl_get_ace(nacl, i);
     805        1636 :                 SMB_ACE4PROP_T sace = { 0 };
     806             : 
     807        1636 :                 DBG_DEBUG("type [%d] flag [%x] mask [%x] who [%*s]\n",
     808             :                           nace->type, nace->flag,
     809             :                           nace->access_mask,
     810             :                           nace->who.utf8string_len,
     811             :                           nace->who.utf8string_val);
     812             : 
     813        1636 :                 ok = map_ace_nfs4_to_smb4(config, nace, &sace);
     814        1636 :                 if (!ok) {
     815           0 :                         continue;
     816             :                 }
     817             : 
     818        1636 :                 smb_add_ace4(smb4acl, &sace);
     819             :         }
     820             : 
     821        1252 :         *_smb4acl = smb4acl;
     822        1252 :         return NT_STATUS_OK;
     823             : }
     824             : 
     825        2504 : NTSTATUS nfs4acl_nfs_blob_to_smb4(struct vfs_handle_struct *handle,
     826             :                                   TALLOC_CTX *mem_ctx,
     827             :                                   DATA_BLOB *blob,
     828             :                                   struct SMB4ACL_T **_smb4acl)
     829             : {
     830        2504 :         struct nfs4acl_config *config = NULL;
     831        2504 :         struct SMB4ACL_T *smb4acl = NULL;
     832             :         NTSTATUS status;
     833             : 
     834        2504 :         SMB_VFS_HANDLE_GET_DATA(handle, config,
     835             :                                 struct nfs4acl_config,
     836             :                                 return NT_STATUS_INTERNAL_ERROR);
     837             : 
     838        2504 :         if (config->nfs_version == ACL4_XATTR_VERSION_40) {
     839        1252 :                 nfsacl40 *nacl = NULL;
     840             : 
     841        1252 :                 status = nfs4acl_nfs_blob_to_nfs40acl(handle,
     842             :                                                       talloc_tos(),
     843             :                                                       blob,
     844             :                                                       &nacl);
     845        1252 :                 if (!NT_STATUS_IS_OK(status)) {
     846           0 :                         return status;
     847             :                 }
     848             : 
     849        1252 :                 status = nfs40acl_to_smb4acl(handle, mem_ctx, nacl, &smb4acl);
     850        1252 :                 TALLOC_FREE(nacl);
     851        1252 :                 if (!NT_STATUS_IS_OK(status)) {
     852           0 :                         return status;
     853             :                 }
     854             :         } else {
     855        1252 :                 nfsacl41 *nacl = NULL;
     856             : 
     857        1252 :                 status = nfs4acl_nfs_blob_to_nfs41acl(handle,
     858             :                                                       talloc_tos(),
     859             :                                                       blob,
     860             :                                                       &nacl);
     861        1252 :                 if (!NT_STATUS_IS_OK(status)) {
     862           0 :                         return status;
     863             :                 }
     864             : 
     865        1252 :                 status = nfs41acl_to_smb4acl(handle, mem_ctx, nacl, &smb4acl);
     866        1252 :                 TALLOC_FREE(nacl);
     867        1252 :                 if (!NT_STATUS_IS_OK(status)) {
     868           0 :                         return status;
     869             :                 }
     870             :         }
     871             : 
     872        2504 :         *_smb4acl = smb4acl;
     873        2504 :         return NT_STATUS_OK;
     874             : }
     875             : 
     876             : #else /* !HAVE_RPC_XDR_H */
     877             : #include "nfs4_acls.h"
     878             : #include "nfs4acl_xattr_nfs.h"
     879             : NTSTATUS nfs4acl_nfs_blob_to_smb4(struct vfs_handle_struct *handle,
     880             :                                   TALLOC_CTX *mem_ctx,
     881             :                                   DATA_BLOB *blob,
     882             :                                   struct SMB4ACL_T **_smb4acl)
     883             : {
     884             :         return NT_STATUS_NOT_SUPPORTED;
     885             : }
     886             : 
     887             : NTSTATUS nfs4acl_smb4acl_to_nfs_blob(vfs_handle_struct *handle,
     888             :                                      TALLOC_CTX *mem_ctx,
     889             :                                      struct SMB4ACL_T *smbacl,
     890             :                                      DATA_BLOB *blob)
     891             : {
     892             :         return NT_STATUS_NOT_SUPPORTED;
     893             : }
     894             : #endif /* HAVE_RPC_XDR_H */

Generated by: LCOV version 1.14