root/source4/ntvfs/posix/pvfs_acl_nfs4.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pvfs_acl_load_nfs4
  2. pvfs_acl_save_nfs4
  3. pvfs_acl_nfs4_init

   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 #define ACE4_IDENTIFIER_GROUP 0x40
  30 
  31 /*
  32   load the current ACL from system.nfs4acl
  33 */
  34 static NTSTATUS pvfs_acl_load_nfs4(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd,
     /* [<][>][^][v][top][bottom][index][help] */
  35                                    TALLOC_CTX *mem_ctx,
  36                                    struct security_descriptor **psd)
  37 {
  38         NTSTATUS status;
  39         struct nfs4acl *acl;
  40         struct security_descriptor *sd;
  41         int i, num_ids;
  42         struct id_mapping *ids;
  43         struct composite_context *ctx;
  44 
  45         acl = talloc_zero(mem_ctx, struct nfs4acl);
  46         NT_STATUS_HAVE_NO_MEMORY(acl);
  47 
  48         status = pvfs_xattr_ndr_load(pvfs, mem_ctx, name->full_name, fd, 
  49                                      NFS4ACL_XATTR_NAME,
  50                                      acl, ndr_pull_nfs4acl);
  51         if (!NT_STATUS_IS_OK(status)) {
  52                 talloc_free(acl);
  53                 return status;
  54         }
  55 
  56         *psd = security_descriptor_initialise(mem_ctx);
  57         NT_STATUS_HAVE_NO_MEMORY(*psd);
  58 
  59         sd = *psd;
  60 
  61         sd->type |= acl->a_flags;
  62 
  63         /* the number of ids to map is the acl count plus uid and gid */
  64         num_ids = acl->a_count +2;
  65         ids = talloc_array(sd, struct id_mapping, num_ids);
  66         NT_STATUS_HAVE_NO_MEMORY(ids);
  67 
  68         ids[0].unixid = talloc(ids, struct unixid);
  69         NT_STATUS_HAVE_NO_MEMORY(ids[0].unixid);
  70         ids[0].unixid->id = name->st.st_uid;
  71         ids[0].unixid->type = ID_TYPE_UID;
  72         ids[0].sid = NULL;
  73         ids[0].status = NT_STATUS_NONE_MAPPED;
  74 
  75         ids[1].unixid = talloc(ids, struct unixid);
  76         NT_STATUS_HAVE_NO_MEMORY(ids[1].unixid);
  77         ids[1].unixid->id = name->st.st_gid;
  78         ids[1].unixid->type = ID_TYPE_GID;
  79         ids[1].sid = NULL;
  80         ids[1].status = NT_STATUS_NONE_MAPPED;
  81 
  82         for (i=0;i<acl->a_count;i++) {
  83                 struct nfs4ace *a = &acl->ace[i];
  84                 ids[i+2].unixid = talloc(ids, struct unixid);
  85                 NT_STATUS_HAVE_NO_MEMORY(ids[i+2].unixid);
  86                 ids[i+2].unixid->id = a->e_id;
  87                 if (a->e_flags & ACE4_IDENTIFIER_GROUP) {
  88                         ids[i+2].unixid->type = ID_TYPE_GID;
  89                 } else {
  90                         ids[i+2].unixid->type = ID_TYPE_UID;
  91                 }
  92                 ids[i+2].sid = NULL;
  93                 ids[i+2].status = NT_STATUS_NONE_MAPPED;
  94         }
  95 
  96         /* Allocate memory for the sids from the security descriptor to be on
  97          * the safe side. */
  98         ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, sd, num_ids, ids);
  99         NT_STATUS_HAVE_NO_MEMORY(ctx);
 100         status = wbc_xids_to_sids_recv(ctx, &ids);
 101         NT_STATUS_NOT_OK_RETURN(status);
 102 
 103         sd->owner_sid = talloc_steal(sd, ids[0].sid);
 104         sd->group_sid = talloc_steal(sd, ids[1].sid);
 105 
 106         for (i=0;i<acl->a_count;i++) {
 107                 struct nfs4ace *a = &acl->ace[i];
 108                 struct security_ace ace;
 109                 ace.type = a->e_type;
 110                 ace.flags = a->e_flags;
 111                 ace.access_mask = a->e_mask;
 112                 ace.trustee = *ids[i+2].sid;
 113                 security_descriptor_dacl_add(sd, &ace);
 114         }
 115 
 116         return NT_STATUS_OK;
 117 }
 118 
 119 /*
 120   save the acl for a file into system.nfs4acl
 121 */
 122 static NTSTATUS pvfs_acl_save_nfs4(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd,
     /* [<][>][^][v][top][bottom][index][help] */
 123                                    struct security_descriptor *sd)
 124 {
 125         NTSTATUS status;
 126         void *privs;
 127         struct nfs4acl acl;
 128         int i;
 129         TALLOC_CTX *tmp_ctx;
 130         struct id_mapping *ids;
 131         struct composite_context *ctx;
 132 
 133         tmp_ctx = talloc_new(pvfs);
 134         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
 135 
 136         acl.a_version = 0;
 137         acl.a_flags   = sd->type;
 138         acl.a_count   = sd->dacl?sd->dacl->num_aces:0;
 139         acl.a_owner_mask = 0;
 140         acl.a_group_mask = 0;
 141         acl.a_other_mask = 0;
 142 
 143         acl.ace = talloc_array(tmp_ctx, struct nfs4ace, acl.a_count);
 144         if (!acl.ace) {
 145                 talloc_free(tmp_ctx);
 146                 return NT_STATUS_NO_MEMORY;
 147         }
 148 
 149         ids = talloc_array(tmp_ctx, struct id_mapping, acl.a_count);
 150         if (ids == NULL) {
 151                 talloc_free(tmp_ctx);
 152                 return NT_STATUS_NO_MEMORY;
 153         }
 154 
 155         for (i=0;i<acl.a_count;i++) {
 156                 struct security_ace *ace = &sd->dacl->aces[i];
 157                 ids[i].unixid = NULL;
 158                 ids[i].sid = dom_sid_dup(ids, &ace->trustee);
 159                 if (ids[i].sid == NULL) {
 160                         talloc_free(tmp_ctx);
 161                         return NT_STATUS_NO_MEMORY;
 162                 }
 163                 ids[i].status = NT_STATUS_NONE_MAPPED;
 164         }
 165 
 166         ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx,ids, acl.a_count, ids);
 167         if (ctx == NULL) {
 168                 talloc_free(tmp_ctx);
 169                 return NT_STATUS_NO_MEMORY;
 170         }
 171         status = wbc_sids_to_xids_recv(ctx, &ids);
 172         if (!NT_STATUS_IS_OK(status)) {
 173                 talloc_free(tmp_ctx);
 174                 return status;
 175         }
 176 
 177         for (i=0;i<acl.a_count;i++) {
 178                 struct nfs4ace *a = &acl.ace[i];
 179                 struct security_ace *ace = &sd->dacl->aces[i];
 180                 a->e_type  = ace->type;
 181                 a->e_flags = ace->flags;
 182                 a->e_mask  = ace->access_mask;
 183                 if (ids[i].unixid->type != ID_TYPE_UID) {
 184                         a->e_flags |= ACE4_IDENTIFIER_GROUP;
 185                 }
 186                 a->e_id = ids[i].unixid->id;
 187                 a->e_who   = "";
 188         }
 189 
 190         privs = root_privileges();
 191         status = pvfs_xattr_ndr_save(pvfs, name->full_name, fd, 
 192                                      NFS4ACL_XATTR_NAME, 
 193                                      &acl, ndr_push_nfs4acl);
 194         talloc_free(privs);
 195 
 196         talloc_free(tmp_ctx);
 197         return status;
 198 }
 199 
 200 
 201 /*
 202   initialise pvfs acl NFS4 backend
 203 */
 204 NTSTATUS pvfs_acl_nfs4_init(void)
     /* [<][>][^][v][top][bottom][index][help] */
 205 {
 206         struct pvfs_acl_ops ops = {
 207                 .name = "nfs4acl",
 208                 .acl_load = pvfs_acl_load_nfs4,
 209                 .acl_save = pvfs_acl_save_nfs4
 210         };
 211         return pvfs_acl_register(&ops);
 212 }

/* [<][>][^][v][top][bottom][index][help] */