LCOV - code coverage report
Current view: top level - source4/ntvfs/posix - pvfs_acl.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 386 524 73.7 %
Date: 2024-02-28 12:06:22 Functions: 21 22 95.5 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    POSIX NTVFS backend - ACL support
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2004
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             :    
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             :    
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "system/passwd.h"
      24             : #include "auth/auth.h"
      25             : #include "vfs_posix.h"
      26             : #include "librpc/gen_ndr/xattr.h"
      27             : #include "libcli/security/security.h"
      28             : #include "param/param.h"
      29             : #include "../lib/util/unix_privs.h"
      30             : #include "lib/util/samba_modules.h"
      31             : 
      32             : /* the list of currently registered ACL backends */
      33             : static struct pvfs_acl_backend {
      34             :         const struct pvfs_acl_ops *ops;
      35             : } *backends = NULL;
      36             : static int num_backends;
      37             : 
      38             : /*
      39             :   register a pvfs acl backend. 
      40             : 
      41             :   The 'name' can be later used by other backends to find the operations
      42             :   structure for this backend.  
      43             : */
      44           8 : NTSTATUS pvfs_acl_register(TALLOC_CTX *ctx, const struct pvfs_acl_ops *ops)
      45             : {
      46           0 :         struct pvfs_acl_ops *new_ops;
      47             : 
      48           8 :         if (pvfs_acl_backend_byname(ops->name) != NULL) {
      49           0 :                 DEBUG(0,("pvfs acl backend '%s' already registered\n", ops->name));
      50           0 :                 return NT_STATUS_OBJECT_NAME_COLLISION;
      51             :         }
      52             : 
      53           8 :         backends = talloc_realloc(ctx, backends,
      54             :                         struct pvfs_acl_backend, num_backends+1);
      55           8 :         NT_STATUS_HAVE_NO_MEMORY(backends);
      56             : 
      57           8 :         new_ops = (struct pvfs_acl_ops *)talloc_memdup(backends, ops, sizeof(*ops));
      58           8 :         new_ops->name = talloc_strdup(new_ops, ops->name);
      59             : 
      60           8 :         backends[num_backends].ops = new_ops;
      61             : 
      62           8 :         num_backends++;
      63             : 
      64           8 :         DEBUG(3,("NTVFS backend '%s' registered\n", ops->name));
      65             : 
      66           8 :         return NT_STATUS_OK;
      67             : }
      68             : 
      69             : 
      70             : /*
      71             :   return the operations structure for a named backend
      72             : */
      73        1336 : const struct pvfs_acl_ops *pvfs_acl_backend_byname(const char *name)
      74             : {
      75           0 :         int i;
      76             : 
      77        1340 :         for (i=0;i<num_backends;i++) {
      78        1332 :                 if (strcmp(backends[i].ops->name, name) == 0) {
      79        1328 :                         return backends[i].ops;
      80             :                 }
      81             :         }
      82             : 
      83           8 :         return NULL;
      84             : }
      85             : 
      86        1328 : NTSTATUS pvfs_acl_init(void)
      87             : {
      88           0 :         static bool initialized = false;
      89             : #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
      90           0 :         STATIC_pvfs_acl_MODULES_PROTO;
      91        1328 :         init_module_fn static_init[] = { STATIC_pvfs_acl_MODULES };
      92           0 :         init_module_fn *shared_init;
      93             : 
      94        1328 :         if (initialized) return NT_STATUS_OK;
      95           4 :         initialized = true;
      96             : 
      97           4 :         shared_init = load_samba_modules(NULL, "pvfs_acl");
      98             : 
      99           4 :         run_init_functions(NULL, static_init);
     100           4 :         run_init_functions(NULL, shared_init);
     101             : 
     102           4 :         talloc_free(shared_init);
     103             : 
     104           4 :         return NT_STATUS_OK;
     105             : }
     106             : 
     107             : 
     108             : /*
     109             :   map a single access_mask from generic to specific bits for files/dirs
     110             : */
     111      478588 : static uint32_t pvfs_translate_mask(uint32_t access_mask)
     112             : {
     113      478588 :         if (access_mask & SEC_MASK_GENERIC) {
     114         155 :                 if (access_mask & SEC_GENERIC_READ)    access_mask |= SEC_RIGHTS_FILE_READ;
     115         155 :                 if (access_mask & SEC_GENERIC_WRITE)   access_mask |= SEC_RIGHTS_FILE_WRITE;
     116         155 :                 if (access_mask & SEC_GENERIC_EXECUTE) access_mask |= SEC_RIGHTS_FILE_EXECUTE;
     117         155 :                 if (access_mask & SEC_GENERIC_ALL)     access_mask |= SEC_RIGHTS_FILE_ALL;
     118         155 :                 access_mask &= ~SEC_MASK_GENERIC;
     119             :         }
     120      478588 :         return access_mask;
     121             : }
     122             : 
     123             : 
     124             : /*
     125             :   map any generic access bits in the given acl
     126             :   this relies on the fact that the mappings for files and directories
     127             :   are the same
     128             : */
     129        1056 : static void pvfs_translate_generic_bits(struct security_acl *acl)
     130             : {
     131           0 :         unsigned i;
     132             : 
     133        1056 :         if (!acl) return;
     134             : 
     135        5757 :         for (i=0;i<acl->num_aces;i++) {
     136        4740 :                 struct security_ace *ace = &acl->aces[i];
     137        4740 :                 ace->access_mask = pvfs_translate_mask(ace->access_mask);
     138             :         }
     139             : }
     140             : 
     141             : 
     142             : /*
     143             :   setup a default ACL for a file
     144             : */
     145         786 : static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs,
     146             :                                  struct ntvfs_request *req,
     147             :                                  struct pvfs_filename *name, int fd, 
     148             :                                  struct security_descriptor **psd)
     149             : {
     150           0 :         struct security_descriptor *sd;
     151           0 :         NTSTATUS status;
     152         786 :         struct security_ace ace = {};
     153           0 :         mode_t mode;
     154           0 :         struct id_map *ids;
     155             : 
     156         786 :         *psd = security_descriptor_initialise(req);
     157         786 :         if (*psd == NULL) {
     158           0 :                 return NT_STATUS_NO_MEMORY;
     159             :         }
     160         786 :         sd = *psd;
     161             : 
     162         786 :         ids = talloc_zero_array(sd, struct id_map, 2);
     163         786 :         NT_STATUS_HAVE_NO_MEMORY(ids);
     164             : 
     165         786 :         ids[0].xid.id = name->st.st_uid;
     166         786 :         ids[0].xid.type = ID_TYPE_UID;
     167         786 :         ids[0].sid = NULL;
     168             : 
     169         786 :         ids[1].xid.id = name->st.st_gid;
     170         786 :         ids[1].xid.type = ID_TYPE_GID;
     171         786 :         ids[1].sid = NULL;
     172             : 
     173         786 :         status = wbc_xids_to_sids(ids, 2);
     174         786 :         NT_STATUS_NOT_OK_RETURN(status);
     175             : 
     176         786 :         sd->owner_sid = talloc_steal(sd, ids[0].sid);
     177         786 :         sd->group_sid = talloc_steal(sd, ids[1].sid);
     178             : 
     179         786 :         talloc_free(ids);
     180         786 :         sd->type |= SEC_DESC_DACL_PRESENT;
     181             : 
     182         786 :         mode = name->st.st_mode;
     183             : 
     184             :         /*
     185             :           we provide up to 4 ACEs
     186             :             - Owner
     187             :             - Group
     188             :             - Everyone
     189             :             - Administrator
     190             :          */
     191             : 
     192             : 
     193             :         /* setup owner ACE */
     194         786 :         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
     195         786 :         ace.flags = 0;
     196         786 :         ace.trustee = *sd->owner_sid;
     197         786 :         ace.access_mask = 0;
     198             : 
     199         786 :         if (mode & S_IRUSR) {
     200         786 :                 if (mode & S_IWUSR) {
     201         786 :                         ace.access_mask |= SEC_RIGHTS_FILE_ALL;
     202             :                 } else {
     203           0 :                         ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
     204             :                 }
     205             :         }
     206         786 :         if (mode & S_IWUSR) {
     207         786 :                 ace.access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE;
     208             :         }
     209         786 :         if (ace.access_mask) {
     210         786 :                 security_descriptor_dacl_add(sd, &ace);
     211             :         }
     212             : 
     213             : 
     214             :         /* setup group ACE */
     215         786 :         ace.trustee = *sd->group_sid;
     216         786 :         ace.access_mask = 0;
     217         786 :         if (mode & S_IRGRP) {
     218         786 :                 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
     219             :         }
     220         786 :         if (mode & S_IWGRP) {
     221             :                 /* note that delete is not granted - this matches posix behaviour */
     222           1 :                 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
     223             :         }
     224         786 :         if (ace.access_mask) {
     225         786 :                 security_descriptor_dacl_add(sd, &ace);
     226             :         }
     227             : 
     228             :         /* setup other ACE */
     229         786 :         ace.trustee = global_sid_World;
     230         786 :         ace.access_mask = 0;
     231         786 :         if (mode & S_IROTH) {
     232         786 :                 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
     233             :         }
     234         786 :         if (mode & S_IWOTH) {
     235           1 :                 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
     236             :         }
     237         786 :         if (ace.access_mask) {
     238         786 :                 security_descriptor_dacl_add(sd, &ace);
     239             :         }
     240             : 
     241             :         /* setup system ACE */
     242         786 :         ace.trustee = global_sid_System;
     243         786 :         ace.access_mask = SEC_RIGHTS_FILE_ALL;
     244         786 :         security_descriptor_dacl_add(sd, &ace);
     245             :         
     246         786 :         return NT_STATUS_OK;
     247             : }
     248             :                                  
     249             : 
     250             : /*
     251             :   omit any security_descriptor elements not specified in the given
     252             :   secinfo flags
     253             : */
     254         639 : static void normalise_sd_flags(struct security_descriptor *sd, uint32_t secinfo_flags)
     255             : {
     256         639 :         if (!(secinfo_flags & SECINFO_OWNER)) {
     257         218 :                 sd->owner_sid = NULL;
     258             :         }
     259         639 :         if (!(secinfo_flags & SECINFO_GROUP)) {
     260         572 :                 sd->group_sid = NULL;
     261             :         }
     262         639 :         if (!(secinfo_flags & SECINFO_DACL)) {
     263           1 :                 sd->dacl = NULL;
     264             :         }
     265         639 :         if (!(secinfo_flags & SECINFO_SACL)) {
     266         639 :                 sd->sacl = NULL;
     267             :         }
     268         639 : }
     269             : 
     270      369671 : static bool pvfs_privileged_access(uid_t uid)
     271             : {
     272           0 :         uid_t euid;
     273             : 
     274      369671 :         if (uid_wrapper_enabled()) {
     275      369671 :                 setenv("UID_WRAPPER_MYUID", "1", 1);
     276             :         }
     277             : 
     278      369671 :         euid = geteuid();
     279             : 
     280      369671 :         if (uid_wrapper_enabled()) {
     281      369671 :                 unsetenv("UID_WRAPPER_MYUID");
     282             :         }
     283             : 
     284      369671 :         return (uid == euid);
     285             : }
     286             : 
     287             : /*
     288             :   answer a setfileinfo for an ACL
     289             : */
     290        1021 : NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, 
     291             :                       struct ntvfs_request *req,
     292             :                       struct pvfs_filename *name, int fd, 
     293             :                       uint32_t access_mask,
     294             :                       union smb_setfileinfo *info)
     295             : {
     296        1021 :         uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags;
     297           0 :         struct security_descriptor *new_sd, *sd, orig_sd;
     298        1021 :         NTSTATUS status = NT_STATUS_NOT_FOUND;
     299        1021 :         uid_t old_uid = -1;
     300        1021 :         gid_t old_gid = -1;
     301        1021 :         uid_t new_uid = -1;
     302        1021 :         gid_t new_gid = -1;
     303           0 :         struct id_map *ids;
     304             : 
     305        1021 :         if (pvfs->acl_ops != NULL) {
     306        1021 :                 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
     307             :         }
     308        1021 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
     309         562 :                 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
     310             :         }
     311        1021 :         if (!NT_STATUS_IS_OK(status)) {
     312           0 :                 return status;
     313             :         }
     314             : 
     315        1021 :         ids = talloc(req, struct id_map);
     316        1021 :         NT_STATUS_HAVE_NO_MEMORY(ids);
     317        1021 :         ZERO_STRUCT(ids->xid);
     318        1021 :         ids->sid = NULL;
     319        1021 :         ids->status = ID_UNKNOWN;
     320             : 
     321        1021 :         new_sd = info->set_secdesc.in.sd;
     322        1021 :         orig_sd = *sd;
     323             : 
     324        1021 :         old_uid = name->st.st_uid;
     325        1021 :         old_gid = name->st.st_gid;
     326             : 
     327             :         /* only set the elements that have been specified */
     328        1021 :         if (secinfo_flags & SECINFO_OWNER) {
     329         122 :                 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
     330           0 :                         return NT_STATUS_ACCESS_DENIED;
     331             :                 }
     332         122 :                 if (!dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) {
     333          83 :                         ids->sid = new_sd->owner_sid;
     334          83 :                         status = wbc_sids_to_xids(ids, 1);
     335          83 :                         NT_STATUS_NOT_OK_RETURN(status);
     336             : 
     337          83 :                         if (ids->xid.type == ID_TYPE_BOTH ||
     338          24 :                             ids->xid.type == ID_TYPE_UID) {
     339          83 :                                 new_uid = ids->xid.id;
     340             :                         }
     341             :                 }
     342         122 :                 sd->owner_sid = new_sd->owner_sid;
     343             :         }
     344             : 
     345        1021 :         if (secinfo_flags & SECINFO_GROUP) {
     346          82 :                 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
     347           0 :                         return NT_STATUS_ACCESS_DENIED;
     348             :                 }
     349          82 :                 if (!dom_sid_equal(sd->group_sid, new_sd->group_sid)) {
     350          59 :                         ids->sid = new_sd->group_sid;
     351          59 :                         status = wbc_sids_to_xids(ids, 1);
     352          59 :                         NT_STATUS_NOT_OK_RETURN(status);
     353             : 
     354          59 :                         if (ids->xid.type == ID_TYPE_BOTH ||
     355           0 :                             ids->xid.type == ID_TYPE_GID) {
     356          59 :                                 new_gid = ids->xid.id;
     357             :                         }
     358             : 
     359             :                 }
     360          82 :                 sd->group_sid = new_sd->group_sid;
     361             :         }
     362             : 
     363        1021 :         if (secinfo_flags & SECINFO_DACL) {
     364        1021 :                 if (!(access_mask & SEC_STD_WRITE_DAC)) {
     365           0 :                         return NT_STATUS_ACCESS_DENIED;
     366             :                 }
     367        1021 :                 sd->dacl = new_sd->dacl;
     368        1021 :                 pvfs_translate_generic_bits(sd->dacl);
     369        1021 :                 sd->type |= SEC_DESC_DACL_PRESENT;
     370             :         }
     371             : 
     372        1021 :         if (secinfo_flags & SECINFO_SACL) {
     373          35 :                 if (!(access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
     374           0 :                         return NT_STATUS_ACCESS_DENIED;
     375             :                 }
     376          35 :                 sd->sacl = new_sd->sacl;
     377          35 :                 pvfs_translate_generic_bits(sd->sacl);
     378          35 :                 sd->type |= SEC_DESC_SACL_PRESENT;
     379             :         }
     380             : 
     381        1021 :         if (secinfo_flags & SECINFO_PROTECTED_DACL) {
     382          43 :                 if (new_sd->type & SEC_DESC_DACL_PROTECTED) {
     383          43 :                         sd->type |= SEC_DESC_DACL_PROTECTED;
     384             :                 } else {
     385           0 :                         sd->type &= ~SEC_DESC_DACL_PROTECTED;
     386             :                 }
     387             :         }
     388             : 
     389        1021 :         if (secinfo_flags & SECINFO_PROTECTED_SACL) {
     390           0 :                 if (new_sd->type & SEC_DESC_SACL_PROTECTED) {
     391           0 :                         sd->type |= SEC_DESC_SACL_PROTECTED;
     392             :                 } else {
     393           0 :                         sd->type &= ~SEC_DESC_SACL_PROTECTED;
     394             :                 }
     395             :         }
     396             : 
     397        1021 :         if (new_uid == old_uid) {
     398          12 :                 new_uid = -1;
     399             :         }
     400             : 
     401        1021 :         if (new_gid == old_gid) {
     402           0 :                 new_gid = -1;
     403             :         }
     404             : 
     405             :         /* if there's something to change try it */
     406        1021 :         if (new_uid != -1 || new_gid != -1) {
     407           0 :                 int ret;
     408          71 :                 if (fd == -1) {
     409          48 :                         ret = chown(name->full_name, new_uid, new_gid);
     410             :                 } else {
     411          23 :                         ret = fchown(fd, new_uid, new_gid);
     412             :                 }
     413          71 :                 if (errno == EPERM) {
     414          71 :                         if (pvfs_privileged_access(name->st.st_uid)) {
     415          71 :                                 ret = 0;
     416             :                         } else {
     417             :                                 /* try again as root if we have SEC_PRIV_RESTORE or
     418             :                                    SEC_PRIV_TAKE_OWNERSHIP */
     419           0 :                                 if (security_token_has_privilege(req->session_info->security_token,
     420           0 :                                                                  SEC_PRIV_RESTORE) ||
     421           0 :                                     security_token_has_privilege(req->session_info->security_token,
     422             :                                                                  SEC_PRIV_TAKE_OWNERSHIP)) {
     423           0 :                                         void *privs;
     424           0 :                                         privs = root_privileges();
     425           0 :                                         if (fd == -1) {
     426           0 :                                                 ret = chown(name->full_name, new_uid, new_gid);
     427             :                                         } else {
     428           0 :                                                 ret = fchown(fd, new_uid, new_gid);
     429             :                                         }
     430           0 :                                         talloc_free(privs);
     431             :                                 }
     432             :                         }
     433             :                 }
     434          71 :                 if (ret == -1) {
     435           0 :                         return pvfs_map_errno(pvfs, errno);
     436             :                 }
     437             :         }
     438             : 
     439             :         /* we avoid saving if the sd is the same. This means when clients
     440             :            copy files and end up copying the default sd that we don't
     441             :            needlessly use xattrs */
     442        1021 :         if (!security_descriptor_equal(sd, &orig_sd) && pvfs->acl_ops) {
     443         614 :                 status = pvfs->acl_ops->acl_save(pvfs, name, fd, sd);
     444             :         }
     445             : 
     446        1021 :         return status;
     447             : }
     448             : 
     449             : 
     450             : /*
     451             :   answer a fileinfo query for the ACL
     452             : */
     453         639 : NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs, 
     454             :                         struct ntvfs_request *req,
     455             :                         struct pvfs_filename *name, int fd, 
     456             :                         union smb_fileinfo *info)
     457             : {
     458         639 :         NTSTATUS status = NT_STATUS_NOT_FOUND;
     459           0 :         struct security_descriptor *sd;
     460             : 
     461         639 :         if (pvfs->acl_ops) {
     462         639 :                 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
     463             :         }
     464         639 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
     465         224 :                 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
     466             :         }
     467         639 :         if (!NT_STATUS_IS_OK(status)) {
     468           0 :                 return status;
     469             :         }
     470             : 
     471         639 :         normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags);
     472             : 
     473         639 :         info->query_secdesc.out.sd = sd;
     474             : 
     475         639 :         return NT_STATUS_OK;
     476             : }
     477             : 
     478             : 
     479             : /*
     480             :   check the read only bit against any of the write access bits
     481             : */
     482      843448 : static bool pvfs_read_only(struct pvfs_state *pvfs, uint32_t access_mask)
     483             : {
     484      843448 :         if ((pvfs->flags & PVFS_FLAG_READONLY) &&
     485           0 :             (access_mask & (SEC_FILE_WRITE_DATA |
     486             :                             SEC_FILE_APPEND_DATA | 
     487             :                             SEC_FILE_WRITE_EA | 
     488             :                             SEC_FILE_WRITE_ATTRIBUTE | 
     489             :                             SEC_STD_DELETE | 
     490             :                             SEC_STD_WRITE_DAC | 
     491             :                             SEC_STD_WRITE_OWNER | 
     492             :                             SEC_DIR_DELETE_CHILD))) {
     493           0 :                 return true;
     494             :         }
     495      843448 :         return false;
     496             : }
     497             : 
     498             : /*
     499             :   see if we are a member of the appropriate unix group
     500             :  */
     501           0 : static bool pvfs_group_member(struct pvfs_state *pvfs, gid_t gid)
     502             : {
     503           0 :         int i, ngroups;
     504           0 :         gid_t *groups;
     505           0 :         if (getegid() == gid) {
     506           0 :                 return true;
     507             :         }
     508           0 :         ngroups = getgroups(0, NULL);
     509           0 :         if (ngroups <= 0) {
     510           0 :                 return false;
     511             :         }
     512           0 :         groups = talloc_array(pvfs, gid_t, ngroups);
     513           0 :         if (groups == NULL) {
     514           0 :                 return false;
     515             :         }
     516           0 :         if (getgroups(ngroups, groups) != ngroups) {
     517           0 :                 talloc_free(groups);
     518           0 :                 return false;
     519             :         }
     520           0 :         for (i=0; i<ngroups; i++) {
     521           0 :                 if (groups[i] == gid) break;
     522             :         }
     523           0 :         talloc_free(groups);
     524           0 :         return i < ngroups;
     525             : }
     526             : 
     527             : /*
     528             :   default access check function based on unix permissions
     529             :   doing this saves on building a full security descriptor
     530             :   for the common case of access check on files with no 
     531             :   specific NT ACL
     532             : 
     533             :   If name is NULL then treat as a new file creation
     534             : */
     535      369600 : static NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs,
     536             :                                        struct ntvfs_request *req,
     537             :                                        struct pvfs_filename *name,
     538             :                                        uint32_t *access_mask)
     539             : {
     540      369600 :         uint32_t max_bits = 0;
     541      369600 :         struct security_token *token = req->session_info->security_token;
     542             : 
     543      369600 :         if (pvfs_read_only(pvfs, *access_mask)) {
     544           0 :                 return NT_STATUS_ACCESS_DENIED;
     545             :         }
     546             : 
     547      369600 :         if (name == NULL) {
     548           0 :                 max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
     549      369600 :         } else if (pvfs_privileged_access(name->st.st_uid)) {
     550             :                 /* use the IxUSR bits */
     551      369600 :                 if ((name->st.st_mode & S_IWUSR)) {
     552      369600 :                         max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
     553           0 :                 } else if ((name->st.st_mode & (S_IRUSR | S_IXUSR))) {
     554           0 :                         max_bits |= SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_EXECUTE | SEC_STD_ALL;
     555             :                 }
     556           0 :         } else if (pvfs_group_member(pvfs, name->st.st_gid)) {
     557             :                 /* use the IxGRP bits */
     558           0 :                 if ((name->st.st_mode & S_IWGRP)) {
     559           0 :                         max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
     560           0 :                 } else if ((name->st.st_mode & (S_IRGRP | S_IXGRP))) {
     561           0 :                         max_bits |= SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_EXECUTE | SEC_STD_ALL;
     562             :                 }
     563             :         } else {
     564             :                 /* use the IxOTH bits */
     565           0 :                 if ((name->st.st_mode & S_IWOTH)) {
     566           0 :                         max_bits |= SEC_RIGHTS_FILE_ALL | SEC_STD_ALL;
     567           0 :                 } else if ((name->st.st_mode & (S_IROTH | S_IXOTH))) {
     568           0 :                         max_bits |= SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_EXECUTE | SEC_STD_ALL;
     569             :                 }
     570             :         }
     571             : 
     572      369600 :         if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
     573         341 :                 *access_mask |= max_bits;
     574         341 :                 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
     575             :         }
     576             : 
     577      369689 :         if ((*access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
     578          89 :             security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
     579          89 :                 max_bits |= SEC_FLAG_SYSTEM_SECURITY;
     580             :         }
     581             :         
     582      369600 :         if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_RESTORE) &&
     583           0 :             security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
     584           0 :                 max_bits |= ~(SEC_RIGHTS_PRIV_RESTORE);
     585             :         }
     586      369600 :         if (((*access_mask & ~max_bits) & SEC_RIGHTS_PRIV_BACKUP) &&
     587           0 :             security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
     588           0 :                 max_bits |= ~(SEC_RIGHTS_PRIV_BACKUP);
     589             :         }
     590             : 
     591      369600 :         if (*access_mask & ~max_bits) {
     592           0 :                 DEBUG(5,(__location__ " denied access to '%s' - wanted 0x%08x but got 0x%08x (missing 0x%08x)\n",
     593             :                          name?name->full_name:"(new file)", *access_mask, max_bits, *access_mask & ~max_bits));
     594           0 :                 return NT_STATUS_ACCESS_DENIED;
     595             :         }
     596             : 
     597      369600 :         if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
     598             :                 /* on SMB, this bit is always granted, even if not
     599             :                    asked for */
     600      163446 :                 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
     601             :         }
     602             : 
     603      369600 :         return NT_STATUS_OK;
     604             : }
     605             : 
     606             : 
     607             : /*
     608             :   check the security descriptor on a file, if any
     609             :   
     610             :   *access_mask is modified with the access actually granted
     611             : */
     612      372160 : NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, 
     613             :                            struct ntvfs_request *req,
     614             :                            struct pvfs_filename *name,
     615             :                            uint32_t *access_mask)
     616             : {
     617      372160 :         struct security_token *token = req->session_info->security_token;
     618           0 :         struct xattr_NTACL *acl;
     619           0 :         NTSTATUS status;
     620           0 :         struct security_descriptor *sd;
     621      372160 :         bool allow_delete = false;
     622             : 
     623             :         /* on SMB2 a blank access mask is always denied */
     624      372160 :         if (pvfs->ntvfs->ctx->protocol >= PROTOCOL_SMB2_02 &&
     625      208436 :             *access_mask == 0) {
     626           1 :                 return NT_STATUS_ACCESS_DENIED;
     627             :         }
     628             : 
     629      372159 :         if (pvfs_read_only(pvfs, *access_mask)) {
     630           0 :                 return NT_STATUS_ACCESS_DENIED;
     631             :         }
     632             : 
     633      372159 :         if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED ||
     634      371785 :             *access_mask & SEC_STD_DELETE) {
     635      113241 :                 status = pvfs_access_check_parent(pvfs, req,
     636             :                                                   name, SEC_DIR_DELETE_CHILD);
     637      113241 :                 if (NT_STATUS_IS_OK(status)) {
     638      113238 :                         allow_delete = true;
     639      113238 :                         *access_mask &= ~SEC_STD_DELETE;
     640             :                 }
     641             :         }
     642             : 
     643      372159 :         acl = talloc(req, struct xattr_NTACL);
     644      372159 :         if (acl == NULL) {
     645           0 :                 return NT_STATUS_NO_MEMORY;
     646             :         }
     647             : 
     648             :         /* expand the generic access bits to file specific bits */
     649      372159 :         *access_mask = pvfs_translate_mask(*access_mask);
     650      372159 :         if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
     651      163724 :                 *access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
     652             :         }
     653             : 
     654      372159 :         status = pvfs_acl_load(pvfs, name, -1, acl);
     655      372159 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
     656      369600 :                 talloc_free(acl);
     657      369600 :                 status = pvfs_access_check_unix(pvfs, req, name, access_mask);
     658      369600 :                 goto done;
     659             :         }
     660        2559 :         if (!NT_STATUS_IS_OK(status)) {
     661           0 :                 return status;
     662             :         }
     663             : 
     664        2559 :         switch (acl->version) {
     665        2559 :         case 1:
     666        2559 :                 sd = acl->info.sd;
     667        2559 :                 break;
     668           0 :         default:
     669           0 :                 return NT_STATUS_INVALID_ACL;
     670             :         }
     671             : 
     672             :         /* check the acl against the required access mask */
     673        2559 :         status = se_file_access_check(sd, token, false, *access_mask, access_mask);
     674        2559 :         talloc_free(acl);
     675             : 
     676             :         /* if we used a NT acl, then allow access override if the
     677             :            share allows for posix permission override
     678             :         */
     679        2559 :         if (NT_STATUS_IS_OK(status)) {
     680        2515 :                 name->allow_override = (pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) != 0;
     681             :         }
     682             : 
     683          44 : done:
     684      372159 :         if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
     685             :                 /* on SMB, this bit is always granted, even if not
     686             :                    asked for */
     687      163724 :                 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
     688             :         }
     689             : 
     690      372159 :         if (allow_delete) {
     691      113238 :                 *access_mask |= SEC_STD_DELETE;
     692             :         }
     693             : 
     694      372159 :         return status;
     695             : }
     696             : 
     697             : 
     698             : /*
     699             :   a simplified interface to access check, designed for calls that
     700             :   do not take or return an access check mask
     701             : */
     702      166208 : NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs, 
     703             :                                   struct ntvfs_request *req,
     704             :                                   struct pvfs_filename *name,
     705             :                                   uint32_t access_needed)
     706             : {
     707      166208 :         if (access_needed == 0) {
     708          32 :                 return NT_STATUS_OK;
     709             :         }
     710      166176 :         return pvfs_access_check(pvfs, req, name, &access_needed);
     711             : }
     712             : 
     713             : /*
     714             :   access check for creating a new file/directory
     715             : */
     716      101689 : NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs, 
     717             :                                   struct ntvfs_request *req,
     718             :                                   struct pvfs_filename *name,
     719             :                                   uint32_t *access_mask,
     720             :                                   bool container,
     721             :                                   struct security_descriptor **sd)
     722             : {
     723           0 :         struct pvfs_filename *parent;
     724           0 :         NTSTATUS status;
     725           0 :         uint32_t parent_mask;
     726      101689 :         bool allow_delete = false;
     727             : 
     728      101689 :         if (pvfs_read_only(pvfs, *access_mask)) {
     729           0 :                 return NT_STATUS_ACCESS_DENIED;
     730             :         }
     731             : 
     732      101689 :         status = pvfs_resolve_parent(pvfs, req, name, &parent);
     733      101689 :         NT_STATUS_NOT_OK_RETURN(status);
     734             : 
     735      101689 :         if (container) {
     736        4669 :                 parent_mask = SEC_DIR_ADD_SUBDIR;
     737             :         } else {
     738       97020 :                 parent_mask = SEC_DIR_ADD_FILE;
     739             :         }
     740      101689 :         if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED ||
     741      101457 :             *access_mask & SEC_STD_DELETE) {
     742       85581 :                 parent_mask |= SEC_DIR_DELETE_CHILD;
     743             :         }
     744             : 
     745      101689 :         status = pvfs_access_check(pvfs, req, parent, &parent_mask);
     746      101689 :         if (NT_STATUS_IS_OK(status)) {
     747      101683 :                 if (parent_mask & SEC_DIR_DELETE_CHILD) {
     748       85575 :                         allow_delete = true;
     749             :                 }
     750           6 :         } else if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
     751             :                 /*
     752             :                  * on ACCESS_DENIED we get the rejected bits
     753             :                  * remove the non critical SEC_DIR_DELETE_CHILD
     754             :                  * and check if something else was rejected.
     755             :                  */
     756           6 :                 parent_mask &= ~SEC_DIR_DELETE_CHILD;
     757           6 :                 if (parent_mask != 0) {
     758           0 :                         return NT_STATUS_ACCESS_DENIED;
     759             :                 }
     760           6 :                 status = NT_STATUS_OK;
     761             :         } else {
     762           0 :                 return status;
     763             :         }
     764             : 
     765      101689 :         if (*sd == NULL) {
     766      101675 :                 status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, sd);
     767             :         }
     768             : 
     769      101689 :         talloc_free(parent);
     770      101689 :         if (!NT_STATUS_IS_OK(status)) {
     771           0 :                 return status;
     772             :         }
     773             : 
     774             :         /* expand the generic access bits to file specific bits */
     775      101689 :         *access_mask = pvfs_translate_mask(*access_mask);
     776             : 
     777      101689 :         if (*access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
     778         232 :                 *access_mask |= SEC_RIGHTS_FILE_ALL;
     779         232 :                 *access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
     780             :         }
     781             : 
     782      101689 :         if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
     783             :                 /* on SMB, this bit is always granted, even if not
     784             :                    asked for */
     785       35382 :                 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
     786             :         }
     787             : 
     788      101689 :         if (allow_delete) {
     789       85575 :                 *access_mask |= SEC_STD_DELETE;
     790             :         }
     791             : 
     792      101689 :         return NT_STATUS_OK;
     793             : }
     794             : 
     795             : /*
     796             :   access check for creating a new file/directory - no access mask supplied
     797             : */
     798      123038 : NTSTATUS pvfs_access_check_parent(struct pvfs_state *pvfs, 
     799             :                                   struct ntvfs_request *req,
     800             :                                   struct pvfs_filename *name,
     801             :                                   uint32_t access_mask)
     802             : {
     803           0 :         struct pvfs_filename *parent;
     804           0 :         NTSTATUS status;
     805             : 
     806      123038 :         status = pvfs_resolve_parent(pvfs, req, name, &parent);
     807      123038 :         if (!NT_STATUS_IS_OK(status)) {
     808           3 :                 return status;
     809             :         }
     810             : 
     811      123035 :         status = pvfs_access_check_simple(pvfs, req, parent, access_mask);
     812      123035 :         if (NT_STATUS_IS_OK(status) && parent->allow_override) {
     813         399 :                 name->allow_override = true;
     814             :         }
     815      123035 :         return status;
     816             : }
     817             : 
     818             : 
     819             : /*
     820             :   determine if an ACE is inheritable
     821             : */
     822        2815 : static bool pvfs_inheritable_ace(struct pvfs_state *pvfs,
     823             :                                  const struct security_ace *ace,
     824             :                                  bool container)
     825             : {
     826        2815 :         if (!container) {
     827        1091 :                 return (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0;
     828             :         }
     829             : 
     830        1724 :         if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
     831        1614 :                 return true;
     832             :         }
     833             : 
     834         110 :         if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) &&
     835           4 :             !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
     836           2 :                 return true;
     837             :         }
     838             : 
     839         108 :         return false;
     840             : }
     841             : 
     842             : /*
     843             :   this is the core of ACL inheritance. It copies any inheritable
     844             :   aces from the parent SD to the child SD. Note that the algorithm 
     845             :   depends on whether the child is a container or not
     846             : */
     847         395 : static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs, 
     848             :                                       struct security_descriptor *parent_sd,
     849             :                                       struct security_descriptor *sd,
     850             :                                       bool container)
     851             : {
     852           0 :         int i;
     853             :         
     854        3210 :         for (i=0;i<parent_sd->dacl->num_aces;i++) {
     855        2815 :                 struct security_ace ace = parent_sd->dacl->aces[i];
     856           0 :                 NTSTATUS status;
     857        2815 :                 const struct dom_sid *creator = NULL, *new_id = NULL;
     858           0 :                 uint32_t orig_flags;
     859             : 
     860        2815 :                 if (!pvfs_inheritable_ace(pvfs, &ace, container)) {
     861         220 :                         continue;
     862             :                 }
     863             : 
     864        2595 :                 orig_flags = ace.flags;
     865             : 
     866             :                 /* see the RAW-ACLS inheritance test for details on these rules */
     867        2595 :                 if (!container) {
     868         979 :                         ace.flags = 0;
     869             :                 } else {
     870        1616 :                         ace.flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
     871             : 
     872        1616 :                         if (!(ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
     873           2 :                                 ace.flags |= SEC_ACE_FLAG_INHERIT_ONLY;
     874             :                         }
     875        1616 :                         if (ace.flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
     876           4 :                                 ace.flags = 0;
     877             :                         }
     878             :                 }
     879             : 
     880             :                 /* the CREATOR sids are special when inherited */
     881        2595 :                 if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_owner)) {
     882         304 :                         creator = pvfs->sid_cache.creator_owner;
     883         304 :                         new_id = sd->owner_sid;
     884        2291 :                 } else if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_group)) {
     885           0 :                         creator = pvfs->sid_cache.creator_group;
     886           0 :                         new_id = sd->group_sid;
     887             :                 } else {
     888        2291 :                         new_id = &ace.trustee;
     889             :                 }
     890             : 
     891        2595 :                 if (creator && container && 
     892         358 :                     (ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
     893         176 :                         uint32_t flags = ace.flags;
     894             : 
     895         176 :                         ace.trustee = *new_id;
     896         176 :                         ace.flags = 0;
     897         176 :                         status = security_descriptor_dacl_add(sd, &ace);
     898         176 :                         if (!NT_STATUS_IS_OK(status)) {
     899           0 :                                 return status;
     900             :                         }
     901             : 
     902         176 :                         ace.trustee = *creator;
     903         176 :                         ace.flags = flags | SEC_ACE_FLAG_INHERIT_ONLY;
     904         176 :                         status = security_descriptor_dacl_add(sd, &ace);
     905        2419 :                 } else if (container && 
     906        1440 :                            !(orig_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
     907        1436 :                         status = security_descriptor_dacl_add(sd, &ace);
     908             :                 } else {
     909         983 :                         ace.trustee = *new_id;
     910         983 :                         status = security_descriptor_dacl_add(sd, &ace);
     911             :                 }
     912             : 
     913        2595 :                 if (!NT_STATUS_IS_OK(status)) {
     914           0 :                         return status;
     915             :                 }
     916             :         }
     917             : 
     918         395 :         return NT_STATUS_OK;
     919             : }
     920             : 
     921             : 
     922             : 
     923             : /*
     924             :   calculate the ACL on a new file/directory based on the inherited ACL
     925             :   from the parent. If there is no inherited ACL then return a NULL
     926             :   ACL, which means the default ACL should be used
     927             : */
     928      104258 : NTSTATUS pvfs_acl_inherited_sd(struct pvfs_state *pvfs, 
     929             :                                TALLOC_CTX *mem_ctx,
     930             :                                struct ntvfs_request *req,
     931             :                                struct pvfs_filename *parent,
     932             :                                bool container,
     933             :                                struct security_descriptor **ret_sd)
     934             : {
     935           0 :         struct xattr_NTACL *acl;
     936           0 :         NTSTATUS status;
     937           0 :         struct security_descriptor *parent_sd, *sd;
     938           0 :         struct id_map *ids;
     939      104258 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     940             : 
     941      104258 :         *ret_sd = NULL;
     942             : 
     943      104258 :         acl = talloc(req, struct xattr_NTACL);
     944      104258 :         if (acl == NULL) {
     945           0 :                 TALLOC_FREE(tmp_ctx);
     946           0 :                 return NT_STATUS_NO_MEMORY;
     947             :         }
     948             : 
     949      104258 :         status = pvfs_acl_load(pvfs, parent, -1, acl);
     950      104258 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
     951      103863 :                 talloc_free(tmp_ctx);
     952      103863 :                 return NT_STATUS_OK;
     953             :         }
     954         395 :         if (!NT_STATUS_IS_OK(status)) {
     955           0 :                 TALLOC_FREE(tmp_ctx);
     956           0 :                 return status;
     957             :         }
     958             : 
     959         395 :         switch (acl->version) {
     960         395 :         case 1:
     961         395 :                 parent_sd = acl->info.sd;
     962         395 :                 break;
     963           0 :         default:
     964           0 :                 talloc_free(tmp_ctx);
     965           0 :                 return NT_STATUS_INVALID_ACL;
     966             :         }
     967             : 
     968         395 :         if (parent_sd == NULL ||
     969         395 :             parent_sd->dacl == NULL ||
     970         395 :             parent_sd->dacl->num_aces == 0) {
     971             :                 /* go with the default ACL */
     972           0 :                 talloc_free(tmp_ctx);
     973           0 :                 return NT_STATUS_OK;
     974             :         }
     975             : 
     976             :         /* create the new sd */
     977         395 :         sd = security_descriptor_initialise(req);
     978         395 :         if (sd == NULL) {
     979           0 :                 TALLOC_FREE(tmp_ctx);
     980           0 :                 return NT_STATUS_NO_MEMORY;
     981             :         }
     982             : 
     983         395 :         ids = talloc_array(sd, struct id_map, 2);
     984         395 :         if (ids == NULL) {
     985           0 :                 TALLOC_FREE(tmp_ctx);
     986           0 :                 return NT_STATUS_NO_MEMORY;
     987             :         }
     988             : 
     989         395 :         ids[0].xid.id = geteuid();
     990         395 :         ids[0].xid.type = ID_TYPE_UID;
     991         395 :         ids[0].sid = NULL;
     992         395 :         ids[0].status = ID_UNKNOWN;
     993             : 
     994         395 :         ids[1].xid.id = getegid();
     995         395 :         ids[1].xid.type = ID_TYPE_GID;
     996         395 :         ids[1].sid = NULL;
     997         395 :         ids[1].status = ID_UNKNOWN;
     998             : 
     999         395 :         status = wbc_xids_to_sids(ids, 2);
    1000         395 :         if (!NT_STATUS_IS_OK(status)) {
    1001           0 :                 TALLOC_FREE(tmp_ctx);
    1002           0 :                 return status;
    1003             :         }
    1004             : 
    1005         395 :         sd->owner_sid = talloc_steal(sd, ids[0].sid);
    1006         395 :         sd->group_sid = talloc_steal(sd, ids[1].sid);
    1007             : 
    1008         395 :         sd->type |= SEC_DESC_DACL_PRESENT;
    1009             : 
    1010             :         /* fill in the aces from the parent */
    1011         395 :         status = pvfs_acl_inherit_aces(pvfs, parent_sd, sd, container);
    1012         395 :         if (!NT_STATUS_IS_OK(status)) {
    1013           0 :                 TALLOC_FREE(tmp_ctx);
    1014           0 :                 return status;
    1015             :         }
    1016             : 
    1017             :         /* if there is nothing to inherit then we fallback to the
    1018             :            default acl */
    1019         395 :         if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
    1020          14 :                 talloc_free(tmp_ctx);
    1021          14 :                 return NT_STATUS_OK;
    1022             :         }
    1023             : 
    1024         381 :         *ret_sd = talloc_steal(mem_ctx, sd);
    1025             : 
    1026         381 :         talloc_free(tmp_ctx);
    1027         381 :         return NT_STATUS_OK;
    1028             : }
    1029             : 
    1030             : 
    1031             : /*
    1032             :   setup an ACL on a new file/directory based on the inherited ACL from
    1033             :   the parent. If there is no inherited ACL then we don't set anything,
    1034             :   as the default ACL applies anyway
    1035             : */
    1036        2583 : NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs, 
    1037             :                           struct ntvfs_request *req,
    1038             :                           struct pvfs_filename *name,
    1039             :                           int fd)
    1040             : {
    1041           0 :         struct xattr_NTACL acl;
    1042           0 :         NTSTATUS status;
    1043           0 :         struct security_descriptor *sd;
    1044           0 :         struct pvfs_filename *parent;
    1045           0 :         bool container;
    1046             : 
    1047             :         /* form the parents path */
    1048        2583 :         status = pvfs_resolve_parent(pvfs, req, name, &parent);
    1049        2583 :         NT_STATUS_NOT_OK_RETURN(status);
    1050             : 
    1051        2583 :         container = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) ? true:false;
    1052             : 
    1053        2583 :         status = pvfs_acl_inherited_sd(pvfs, req, req, parent, container, &sd);
    1054        2583 :         if (!NT_STATUS_IS_OK(status)) {
    1055           0 :                 talloc_free(parent);
    1056           0 :                 return status;
    1057             :         }
    1058             : 
    1059        2583 :         if (sd == NULL) {
    1060        2583 :                 return NT_STATUS_OK;
    1061             :         }
    1062             : 
    1063           0 :         acl.version = 1;
    1064           0 :         acl.info.sd = sd;
    1065             : 
    1066           0 :         status = pvfs_acl_save(pvfs, name, fd, &acl);
    1067           0 :         talloc_free(sd);
    1068           0 :         talloc_free(parent);
    1069             : 
    1070           0 :         return status;
    1071             : }
    1072             : 
    1073             : /*
    1074             :   return the maximum allowed access mask
    1075             : */
    1076          12 : NTSTATUS pvfs_access_maximal_allowed(struct pvfs_state *pvfs, 
    1077             :                                      struct ntvfs_request *req,
    1078             :                                      struct pvfs_filename *name,
    1079             :                                      uint32_t *maximal_access)
    1080             : {
    1081          12 :         *maximal_access = SEC_FLAG_MAXIMUM_ALLOWED;
    1082          12 :         return pvfs_access_check(pvfs, req, name, maximal_access);
    1083             : }

Generated by: LCOV version 1.14