root/source4/ntvfs/posix/pvfs_acl.c

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

DEFINITIONS

This source file includes following definitions.
  1. pvfs_acl_register
  2. pvfs_acl_backend_byname
  3. pvfs_acl_init
  4. pvfs_translate_mask
  5. pvfs_translate_generic_bits
  6. pvfs_default_acl
  7. normalise_sd_flags
  8. pvfs_acl_set
  9. pvfs_acl_query
  10. pvfs_read_only
  11. pvfs_access_check_unix
  12. pvfs_access_check
  13. pvfs_access_check_simple
  14. pvfs_access_check_create
  15. pvfs_access_check_parent
  16. pvfs_inheritable_ace
  17. pvfs_acl_inherit_aces
  18. pvfs_acl_inherit
  19. pvfs_access_maximal_allowed

   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 "auth/auth.h"
  24 #include "vfs_posix.h"
  25 #include "librpc/gen_ndr/xattr.h"
  26 #include "libcli/security/security.h"
  27 #include "param/param.h"
  28 
  29 
  30 /* the list of currently registered ACL backends */
  31 static struct pvfs_acl_backend {
  32         const struct pvfs_acl_ops *ops;
  33 } *backends = NULL;
  34 static int num_backends;
  35 
  36 /*
  37   register a pvfs acl backend. 
  38 
  39   The 'name' can be later used by other backends to find the operations
  40   structure for this backend.  
  41 */
  42 NTSTATUS pvfs_acl_register(const struct pvfs_acl_ops *ops)
     /* [<][>][^][v][top][bottom][index][help] */
  43 {
  44         struct pvfs_acl_ops *new_ops;
  45 
  46         if (pvfs_acl_backend_byname(ops->name) != NULL) {
  47                 DEBUG(0,("pvfs acl backend '%s' already registered\n", ops->name));
  48                 return NT_STATUS_OBJECT_NAME_COLLISION;
  49         }
  50 
  51         backends = talloc_realloc(talloc_autofree_context(), backends, struct pvfs_acl_backend, num_backends+1);
  52         NT_STATUS_HAVE_NO_MEMORY(backends);
  53 
  54         new_ops = (struct pvfs_acl_ops *)talloc_memdup(backends, ops, sizeof(*ops));
  55         new_ops->name = talloc_strdup(new_ops, ops->name);
  56 
  57         backends[num_backends].ops = new_ops;
  58 
  59         num_backends++;
  60 
  61         DEBUG(3,("NTVFS backend '%s' registered\n", ops->name));
  62 
  63         return NT_STATUS_OK;
  64 }
  65 
  66 
  67 /*
  68   return the operations structure for a named backend
  69 */
  70 const struct pvfs_acl_ops *pvfs_acl_backend_byname(const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
  71 {
  72         int i;
  73 
  74         for (i=0;i<num_backends;i++) {
  75                 if (strcmp(backends[i].ops->name, name) == 0) {
  76                         return backends[i].ops;
  77                 }
  78         }
  79 
  80         return NULL;
  81 }
  82 
  83 NTSTATUS pvfs_acl_init(struct loadparm_context *lp_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
  84 {
  85         static bool initialized = false;
  86         extern NTSTATUS pvfs_acl_nfs4_init(void);
  87         extern NTSTATUS pvfs_acl_xattr_init(void);
  88         init_module_fn static_init[] = { STATIC_pvfs_acl_MODULES };
  89         init_module_fn *shared_init;
  90 
  91         if (initialized) return NT_STATUS_OK;
  92         initialized = true;
  93 
  94         shared_init = load_samba_modules(NULL, lp_ctx, "pvfs_acl");
  95 
  96         run_init_functions(static_init);
  97         run_init_functions(shared_init);
  98 
  99         talloc_free(shared_init);
 100 
 101         return NT_STATUS_OK;
 102 }
 103 
 104 
 105 /*
 106   map a single access_mask from generic to specific bits for files/dirs
 107 */
 108 static uint32_t pvfs_translate_mask(uint32_t access_mask)
     /* [<][>][^][v][top][bottom][index][help] */
 109 {
 110         if (access_mask & SEC_MASK_GENERIC) {
 111                 if (access_mask & SEC_GENERIC_READ)    access_mask |= SEC_RIGHTS_FILE_READ;
 112                 if (access_mask & SEC_GENERIC_WRITE)   access_mask |= SEC_RIGHTS_FILE_WRITE;
 113                 if (access_mask & SEC_GENERIC_EXECUTE) access_mask |= SEC_RIGHTS_FILE_EXECUTE;
 114                 if (access_mask & SEC_GENERIC_ALL)     access_mask |= SEC_RIGHTS_FILE_ALL;
 115                 access_mask &= ~SEC_MASK_GENERIC;
 116         }
 117         return access_mask;
 118 }
 119 
 120 
 121 /*
 122   map any generic access bits in the given acl
 123   this relies on the fact that the mappings for files and directories
 124   are the same
 125 */
 126 static void pvfs_translate_generic_bits(struct security_acl *acl)
     /* [<][>][^][v][top][bottom][index][help] */
 127 {
 128         unsigned i;
 129 
 130         if (!acl) return;
 131 
 132         for (i=0;i<acl->num_aces;i++) {
 133                 struct security_ace *ace = &acl->aces[i];
 134                 ace->access_mask = pvfs_translate_mask(ace->access_mask);
 135         }
 136 }
 137 
 138 
 139 /*
 140   setup a default ACL for a file
 141 */
 142 static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 143                                  struct ntvfs_request *req,
 144                                  struct pvfs_filename *name, int fd, 
 145                                  struct security_descriptor **psd)
 146 {
 147         struct security_descriptor *sd;
 148         NTSTATUS status;
 149         struct security_ace ace;
 150         mode_t mode;
 151         struct id_mapping *ids;
 152         struct composite_context *ctx;
 153 
 154         *psd = security_descriptor_initialise(req);
 155         if (*psd == NULL) {
 156                 return NT_STATUS_NO_MEMORY;
 157         }
 158         sd = *psd;
 159 
 160         ids = talloc_zero_array(sd, struct id_mapping, 2);
 161         NT_STATUS_HAVE_NO_MEMORY(ids);
 162 
 163         ids[0].unixid = talloc(ids, struct unixid);
 164         NT_STATUS_HAVE_NO_MEMORY(ids[0].unixid);
 165 
 166         ids[0].unixid->id = name->st.st_uid;
 167         ids[0].unixid->type = ID_TYPE_UID;
 168         ids[0].sid = NULL;
 169 
 170         ids[1].unixid = talloc(ids, struct unixid);
 171         NT_STATUS_HAVE_NO_MEMORY(ids[1].unixid);
 172 
 173         ids[1].unixid->id = name->st.st_gid;
 174         ids[1].unixid->type = ID_TYPE_GID;
 175         ids[1].sid = NULL;
 176 
 177         ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids);
 178         NT_STATUS_HAVE_NO_MEMORY(ctx);
 179 
 180         status = wbc_xids_to_sids_recv(ctx, &ids);
 181         NT_STATUS_NOT_OK_RETURN(status);
 182 
 183         sd->owner_sid = talloc_steal(sd, ids[0].sid);
 184         sd->group_sid = talloc_steal(sd, ids[1].sid);
 185 
 186         talloc_free(ids);
 187         sd->type |= SEC_DESC_DACL_PRESENT;
 188 
 189         mode = name->st.st_mode;
 190 
 191         /*
 192           we provide up to 4 ACEs
 193             - Owner
 194             - Group
 195             - Everyone
 196             - Administrator
 197          */
 198 
 199 
 200         /* setup owner ACE */
 201         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
 202         ace.flags = 0;
 203         ace.trustee = *sd->owner_sid;
 204         ace.access_mask = 0;
 205 
 206         if (mode & S_IRUSR) {
 207                 if (mode & S_IWUSR) {
 208                         ace.access_mask |= SEC_RIGHTS_FILE_ALL;
 209                 } else {
 210                         ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
 211                 }
 212         }
 213         if (mode & S_IWUSR) {
 214                 ace.access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE;
 215         }
 216         if (ace.access_mask) {
 217                 security_descriptor_dacl_add(sd, &ace);
 218         }
 219 
 220 
 221         /* setup group ACE */
 222         ace.trustee = *sd->group_sid;
 223         ace.access_mask = 0;
 224         if (mode & S_IRGRP) {
 225                 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
 226         }
 227         if (mode & S_IWGRP) {
 228                 /* note that delete is not granted - this matches posix behaviour */
 229                 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
 230         }
 231         if (ace.access_mask) {
 232                 security_descriptor_dacl_add(sd, &ace);
 233         }
 234 
 235         /* setup other ACE */
 236         ace.trustee = *dom_sid_parse_talloc(req, SID_WORLD);
 237         ace.access_mask = 0;
 238         if (mode & S_IROTH) {
 239                 ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE;
 240         }
 241         if (mode & S_IWOTH) {
 242                 ace.access_mask |= SEC_RIGHTS_FILE_WRITE;
 243         }
 244         if (ace.access_mask) {
 245                 security_descriptor_dacl_add(sd, &ace);
 246         }
 247 
 248         /* setup system ACE */
 249         ace.trustee = *dom_sid_parse_talloc(req, SID_NT_SYSTEM);
 250         ace.access_mask = SEC_RIGHTS_FILE_ALL;
 251         security_descriptor_dacl_add(sd, &ace);
 252         
 253         return NT_STATUS_OK;
 254 }
 255                                  
 256 
 257 /*
 258   omit any security_descriptor elements not specified in the given
 259   secinfo flags
 260 */
 261 static void normalise_sd_flags(struct security_descriptor *sd, uint32_t secinfo_flags)
     /* [<][>][^][v][top][bottom][index][help] */
 262 {
 263         if (!(secinfo_flags & SECINFO_OWNER)) {
 264                 sd->owner_sid = NULL;
 265         }
 266         if (!(secinfo_flags & SECINFO_GROUP)) {
 267                 sd->group_sid = NULL;
 268         }
 269         if (!(secinfo_flags & SECINFO_DACL)) {
 270                 sd->dacl = NULL;
 271         }
 272         if (!(secinfo_flags & SECINFO_SACL)) {
 273                 sd->sacl = NULL;
 274         }
 275 }
 276 
 277 /*
 278   answer a setfileinfo for an ACL
 279 */
 280 NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, 
     /* [<][>][^][v][top][bottom][index][help] */
 281                       struct ntvfs_request *req,
 282                       struct pvfs_filename *name, int fd, 
 283                       uint32_t access_mask,
 284                       union smb_setfileinfo *info)
 285 {
 286         uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags;
 287         struct security_descriptor *new_sd, *sd, orig_sd;
 288         NTSTATUS status = NT_STATUS_NOT_FOUND;
 289         uid_t old_uid = -1;
 290         gid_t old_gid = -1;
 291         uid_t new_uid = -1;
 292         gid_t new_gid = -1;
 293         struct id_mapping *ids;
 294         struct composite_context *ctx;
 295 
 296         if (pvfs->acl_ops != NULL) {
 297                 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
 298         }
 299         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
 300                 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
 301         }
 302         if (!NT_STATUS_IS_OK(status)) {
 303                 return status;
 304         }
 305 
 306         ids = talloc(req, struct id_mapping);
 307         NT_STATUS_HAVE_NO_MEMORY(ids);
 308         ids->unixid = NULL;
 309         ids->sid = NULL;
 310         ids->status = NT_STATUS_NONE_MAPPED;
 311 
 312         new_sd = info->set_secdesc.in.sd;
 313         orig_sd = *sd;
 314 
 315         old_uid = name->st.st_uid;
 316         old_gid = name->st.st_gid;
 317 
 318         /* only set the elements that have been specified */
 319         if (secinfo_flags & SECINFO_OWNER) {
 320                 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
 321                         return NT_STATUS_ACCESS_DENIED;
 322                 }
 323                 if (!dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) {
 324                         ids->sid = new_sd->owner_sid;
 325                         ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx, ids, 1, ids);
 326                         NT_STATUS_HAVE_NO_MEMORY(ctx);
 327                         status = wbc_sids_to_xids_recv(ctx, &ids);
 328                         NT_STATUS_NOT_OK_RETURN(status);
 329 
 330                         if (ids->unixid->type == ID_TYPE_BOTH ||
 331                             ids->unixid->type == ID_TYPE_UID) {
 332                                 new_uid = ids->unixid->id;
 333                         }
 334                 }
 335                 sd->owner_sid = new_sd->owner_sid;
 336         }
 337         if (secinfo_flags & SECINFO_GROUP) {
 338                 if (!(access_mask & SEC_STD_WRITE_OWNER)) {
 339                         return NT_STATUS_ACCESS_DENIED;
 340                 }
 341                 if (!dom_sid_equal(sd->group_sid, new_sd->group_sid)) {
 342                         ids->sid = new_sd->group_sid;
 343                         ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx, ids, 1, ids);
 344                         NT_STATUS_HAVE_NO_MEMORY(ctx);
 345                         status = wbc_sids_to_xids_recv(ctx, &ids);
 346                         NT_STATUS_NOT_OK_RETURN(status);
 347 
 348                         if (ids->unixid->type == ID_TYPE_BOTH ||
 349                             ids->unixid->type == ID_TYPE_GID) {
 350                                 new_gid = ids->unixid->id;
 351                         }
 352 
 353                 }
 354                 sd->group_sid = new_sd->group_sid;
 355         }
 356         if (secinfo_flags & SECINFO_DACL) {
 357                 if (!(access_mask & SEC_STD_WRITE_DAC)) {
 358                         return NT_STATUS_ACCESS_DENIED;
 359                 }
 360                 sd->dacl = new_sd->dacl;
 361                 pvfs_translate_generic_bits(sd->dacl);
 362         }
 363         if (secinfo_flags & SECINFO_SACL) {
 364                 if (!(access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
 365                         return NT_STATUS_ACCESS_DENIED;
 366                 }
 367                 sd->sacl = new_sd->sacl;
 368                 pvfs_translate_generic_bits(sd->sacl);
 369         }
 370 
 371         if (new_uid == old_uid) {
 372                 new_uid = -1;
 373         }
 374 
 375         if (new_gid == old_gid) {
 376                 new_gid = -1;
 377         }
 378 
 379         /* if there's something to change try it */
 380         if (new_uid != -1 || new_gid != -1) {
 381                 int ret;
 382                 if (fd == -1) {
 383                         ret = chown(name->full_name, new_uid, new_gid);
 384                 } else {
 385                         ret = fchown(fd, new_uid, new_gid);
 386                 }
 387                 if (ret == -1) {
 388                         return pvfs_map_errno(pvfs, errno);
 389                 }
 390         }
 391 
 392         /* we avoid saving if the sd is the same. This means when clients
 393            copy files and end up copying the default sd that we don't
 394            needlessly use xattrs */
 395         if (!security_descriptor_equal(sd, &orig_sd) && pvfs->acl_ops) {
 396                 status = pvfs->acl_ops->acl_save(pvfs, name, fd, sd);
 397         }
 398 
 399         return status;
 400 }
 401 
 402 
 403 /*
 404   answer a fileinfo query for the ACL
 405 */
 406 NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs, 
     /* [<][>][^][v][top][bottom][index][help] */
 407                         struct ntvfs_request *req,
 408                         struct pvfs_filename *name, int fd, 
 409                         union smb_fileinfo *info)
 410 {
 411         NTSTATUS status = NT_STATUS_NOT_FOUND;
 412         struct security_descriptor *sd;
 413 
 414         if (pvfs->acl_ops) {
 415                 status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
 416         }
 417         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
 418                 status = pvfs_default_acl(pvfs, req, name, fd, &sd);
 419         }
 420         if (!NT_STATUS_IS_OK(status)) {
 421                 return status;
 422         }
 423 
 424         normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags);
 425 
 426         info->query_secdesc.out.sd = sd;
 427 
 428         return NT_STATUS_OK;
 429 }
 430 
 431 
 432 /*
 433   check the read only bit against any of the write access bits
 434 */
 435 static bool pvfs_read_only(struct pvfs_state *pvfs, uint32_t access_mask)
     /* [<][>][^][v][top][bottom][index][help] */
 436 {
 437         if ((pvfs->flags & PVFS_FLAG_READONLY) &&
 438             (access_mask & (SEC_FILE_WRITE_DATA |
 439                             SEC_FILE_APPEND_DATA | 
 440                             SEC_FILE_WRITE_EA | 
 441                             SEC_FILE_WRITE_ATTRIBUTE | 
 442                             SEC_STD_DELETE | 
 443                             SEC_STD_WRITE_DAC | 
 444                             SEC_STD_WRITE_OWNER | 
 445                             SEC_DIR_DELETE_CHILD))) {
 446                 return true;
 447         }
 448         return false;
 449 }
 450 
 451 /*
 452   default access check function based on unix permissions
 453   doing this saves on building a full security descriptor
 454   for the common case of access check on files with no 
 455   specific NT ACL
 456 */
 457 NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs, 
     /* [<][>][^][v][top][bottom][index][help] */
 458                                 struct ntvfs_request *req,
 459                                 struct pvfs_filename *name,
 460                                 uint32_t *access_mask)
 461 {
 462         uid_t uid = geteuid();
 463         uint32_t max_bits = SEC_RIGHTS_FILE_READ | SEC_FILE_ALL;
 464 
 465         if (pvfs_read_only(pvfs, *access_mask)) {
 466                 return NT_STATUS_ACCESS_DENIED;
 467         }
 468 
 469         /* owner and root get extra permissions */
 470         if (uid == 0) {
 471                 max_bits |= SEC_STD_ALL | SEC_FLAG_SYSTEM_SECURITY;
 472         } else if (uid == name->st.st_uid) {
 473                 max_bits |= SEC_STD_ALL;
 474         }
 475 
 476         if (*access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
 477                 *access_mask = max_bits;
 478                 return NT_STATUS_OK;
 479         }
 480 
 481         if (uid != 0 && (*access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
 482                 return NT_STATUS_ACCESS_DENIED;
 483         }
 484 
 485         if (*access_mask & ~max_bits) {
 486                 return NT_STATUS_ACCESS_DENIED;
 487         }
 488 
 489         if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
 490                 /* on SMB, this bit is always granted, even if not
 491                    asked for */
 492                 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
 493         }
 494 
 495         return NT_STATUS_OK;
 496 }
 497 
 498 
 499 /*
 500   check the security descriptor on a file, if any
 501   
 502   *access_mask is modified with the access actually granted
 503 */
 504 NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, 
     /* [<][>][^][v][top][bottom][index][help] */
 505                            struct ntvfs_request *req,
 506                            struct pvfs_filename *name,
 507                            uint32_t *access_mask)
 508 {
 509         struct security_token *token = req->session_info->security_token;
 510         struct xattr_NTACL *acl;
 511         NTSTATUS status;
 512         struct security_descriptor *sd;
 513 
 514         /* on SMB2 a blank access mask is always denied */
 515         if (pvfs->ntvfs->ctx->protocol == PROTOCOL_SMB2 &&
 516             *access_mask == 0) {
 517                 return NT_STATUS_ACCESS_DENIED;
 518         }
 519 
 520         if (pvfs_read_only(pvfs, *access_mask)) {
 521                 return NT_STATUS_ACCESS_DENIED;
 522         }
 523 
 524         acl = talloc(req, struct xattr_NTACL);
 525         if (acl == NULL) {
 526                 return NT_STATUS_NO_MEMORY;
 527         }
 528 
 529         /* expand the generic access bits to file specific bits */
 530         *access_mask = pvfs_translate_mask(*access_mask);
 531         if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
 532                 *access_mask &= ~SEC_FILE_READ_ATTRIBUTE;
 533         }
 534 
 535         status = pvfs_acl_load(pvfs, name, -1, acl);
 536         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
 537                 talloc_free(acl);
 538                 return pvfs_access_check_unix(pvfs, req, name, access_mask);
 539         }
 540         if (!NT_STATUS_IS_OK(status)) {
 541                 return status;
 542         }
 543 
 544         switch (acl->version) {
 545         case 1:
 546                 sd = acl->info.sd;
 547                 break;
 548         default:
 549                 return NT_STATUS_INVALID_ACL;
 550         }
 551 
 552         /* check the acl against the required access mask */
 553         status = sec_access_check(sd, token, *access_mask, access_mask);
 554 
 555         if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) {
 556                 /* on SMB, this bit is always granted, even if not
 557                    asked for */
 558                 *access_mask |= SEC_FILE_READ_ATTRIBUTE;
 559         }
 560 
 561         talloc_free(acl);
 562         
 563         return status;
 564 }
 565 
 566 
 567 /*
 568   a simplified interface to access check, designed for calls that
 569   do not take or return an access check mask
 570 */
 571 NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs, 
     /* [<][>][^][v][top][bottom][index][help] */
 572                                   struct ntvfs_request *req,
 573                                   struct pvfs_filename *name,
 574                                   uint32_t access_needed)
 575 {
 576         if (access_needed == 0) {
 577                 return NT_STATUS_OK;
 578         }
 579         return pvfs_access_check(pvfs, req, name, &access_needed);
 580 }
 581 
 582 /*
 583   access check for creating a new file/directory
 584 */
 585 NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs, 
     /* [<][>][^][v][top][bottom][index][help] */
 586                                   struct ntvfs_request *req,
 587                                   struct pvfs_filename *name,
 588                                   uint32_t *access_mask)
 589 {
 590         struct pvfs_filename *parent;
 591         NTSTATUS status;
 592 
 593         status = pvfs_resolve_parent(pvfs, req, name, &parent);
 594         if (!NT_STATUS_IS_OK(status)) {
 595                 return status;
 596         }
 597 
 598         status = pvfs_access_check(pvfs, req, parent, access_mask);
 599         if (!NT_STATUS_IS_OK(status)) {
 600                 return status;
 601         }
 602 
 603         if (! ((*access_mask) & SEC_DIR_ADD_FILE)) {
 604                 return pvfs_access_check_simple(pvfs, req, parent, SEC_DIR_ADD_FILE);
 605         }
 606 
 607         return status;
 608 }
 609 
 610 /*
 611   access check for creating a new file/directory - no access mask supplied
 612 */
 613 NTSTATUS pvfs_access_check_parent(struct pvfs_state *pvfs, 
     /* [<][>][^][v][top][bottom][index][help] */
 614                                   struct ntvfs_request *req,
 615                                   struct pvfs_filename *name,
 616                                   uint32_t access_mask)
 617 {
 618         struct pvfs_filename *parent;
 619         NTSTATUS status;
 620 
 621         status = pvfs_resolve_parent(pvfs, req, name, &parent);
 622         if (!NT_STATUS_IS_OK(status)) {
 623                 return status;
 624         }
 625 
 626         return pvfs_access_check_simple(pvfs, req, parent, access_mask);
 627 }
 628 
 629 
 630 /*
 631   determine if an ACE is inheritable
 632 */
 633 static bool pvfs_inheritable_ace(struct pvfs_state *pvfs,
     /* [<][>][^][v][top][bottom][index][help] */
 634                                  const struct security_ace *ace,
 635                                  bool container)
 636 {
 637         if (!container) {
 638                 return (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0;
 639         }
 640 
 641         if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
 642                 return true;
 643         }
 644 
 645         if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) &&
 646             !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
 647                 return true;
 648         }
 649 
 650         return false;
 651 }
 652 
 653 /*
 654   this is the core of ACL inheritance. It copies any inheritable
 655   aces from the parent SD to the child SD. Note that the algorithm 
 656   depends on whether the child is a container or not
 657 */
 658 static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs, 
     /* [<][>][^][v][top][bottom][index][help] */
 659                                       struct security_descriptor *parent_sd,
 660                                       struct security_descriptor *sd,
 661                                       bool container)
 662 {
 663         int i;
 664         
 665         for (i=0;i<parent_sd->dacl->num_aces;i++) {
 666                 struct security_ace ace = parent_sd->dacl->aces[i];
 667                 NTSTATUS status;
 668                 const struct dom_sid *creator = NULL, *new_id = NULL;
 669                 uint32_t orig_flags;
 670 
 671                 if (!pvfs_inheritable_ace(pvfs, &ace, container)) {
 672                         continue;
 673                 }
 674 
 675                 orig_flags = ace.flags;
 676 
 677                 /* see the RAW-ACLS inheritance test for details on these rules */
 678                 if (!container) {
 679                         ace.flags = 0;
 680                 } else {
 681                         ace.flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
 682 
 683                         if (!(ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
 684                                 ace.flags |= SEC_ACE_FLAG_INHERIT_ONLY;
 685                         }
 686                         if (ace.flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
 687                                 ace.flags = 0;
 688                         }
 689                 }
 690 
 691                 /* the CREATOR sids are special when inherited */
 692                 if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_owner)) {
 693                         creator = pvfs->sid_cache.creator_owner;
 694                         new_id = sd->owner_sid;
 695                 } else if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_group)) {
 696                         creator = pvfs->sid_cache.creator_group;
 697                         new_id = sd->group_sid;
 698                 } else {
 699                         new_id = &ace.trustee;
 700                 }
 701 
 702                 if (creator && container && 
 703                     (ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
 704                         uint32_t flags = ace.flags;
 705 
 706                         ace.trustee = *new_id;
 707                         ace.flags = 0;
 708                         status = security_descriptor_dacl_add(sd, &ace);
 709                         if (!NT_STATUS_IS_OK(status)) {
 710                                 return status;
 711                         }
 712 
 713                         ace.trustee = *creator;
 714                         ace.flags = flags | SEC_ACE_FLAG_INHERIT_ONLY;
 715                         status = security_descriptor_dacl_add(sd, &ace);
 716                 } else if (container && 
 717                            !(orig_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
 718                         status = security_descriptor_dacl_add(sd, &ace);
 719                 } else {
 720                         ace.trustee = *new_id;
 721                         status = security_descriptor_dacl_add(sd, &ace);
 722                 }
 723 
 724                 if (!NT_STATUS_IS_OK(status)) {
 725                         return status;
 726                 }
 727         }
 728 
 729         return NT_STATUS_OK;
 730 }
 731 
 732 
 733 
 734 /*
 735   setup an ACL on a new file/directory based on the inherited ACL from
 736   the parent. If there is no inherited ACL then we don't set anything,
 737   as the default ACL applies anyway
 738 */
 739 NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs, 
     /* [<][>][^][v][top][bottom][index][help] */
 740                           struct ntvfs_request *req,
 741                           struct pvfs_filename *name,
 742                           int fd)
 743 {
 744         struct xattr_NTACL *acl;
 745         NTSTATUS status;
 746         struct pvfs_filename *parent;
 747         struct security_descriptor *parent_sd, *sd;
 748         bool container;
 749         struct id_mapping *ids;
 750         struct composite_context *ctx;
 751 
 752         /* form the parents path */
 753         status = pvfs_resolve_parent(pvfs, req, name, &parent);
 754         if (!NT_STATUS_IS_OK(status)) {
 755                 return status;
 756         }
 757 
 758         acl = talloc(req, struct xattr_NTACL);
 759         if (acl == NULL) {
 760                 return NT_STATUS_NO_MEMORY;
 761         }
 762 
 763         status = pvfs_acl_load(pvfs, parent, -1, acl);
 764         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
 765                 return NT_STATUS_OK;
 766         }
 767         if (!NT_STATUS_IS_OK(status)) {
 768                 return status;
 769         }
 770 
 771         switch (acl->version) {
 772         case 1:
 773                 parent_sd = acl->info.sd;
 774                 break;
 775         default:
 776                 return NT_STATUS_INVALID_ACL;
 777         }
 778 
 779         if (parent_sd == NULL ||
 780             parent_sd->dacl == NULL ||
 781             parent_sd->dacl->num_aces == 0) {
 782                 /* go with the default ACL */
 783                 return NT_STATUS_OK;
 784         }
 785 
 786         /* create the new sd */
 787         sd = security_descriptor_initialise(req);
 788         if (sd == NULL) {
 789                 return NT_STATUS_NO_MEMORY;
 790         }
 791 
 792         ids = talloc_array(sd, struct id_mapping, 2);
 793         NT_STATUS_HAVE_NO_MEMORY(ids);
 794 
 795         ids[0].unixid = talloc(ids, struct unixid);
 796         NT_STATUS_HAVE_NO_MEMORY(ids[0].unixid);
 797         ids[0].unixid->id = name->st.st_uid;
 798         ids[0].unixid->type = ID_TYPE_UID;
 799         ids[0].sid = NULL;
 800         ids[0].status = NT_STATUS_NONE_MAPPED;
 801 
 802         ids[1].unixid = talloc(ids, struct unixid);
 803         NT_STATUS_HAVE_NO_MEMORY(ids[1].unixid);
 804         ids[1].unixid->id = name->st.st_gid;
 805         ids[1].unixid->type = ID_TYPE_GID;
 806         ids[1].sid = NULL;
 807         ids[1].status = NT_STATUS_NONE_MAPPED;
 808 
 809         ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids);
 810         NT_STATUS_HAVE_NO_MEMORY(ctx);
 811 
 812         status = wbc_xids_to_sids_recv(ctx, &ids);
 813         NT_STATUS_NOT_OK_RETURN(status);
 814 
 815         sd->owner_sid = talloc_steal(sd, ids[0].sid);
 816         sd->group_sid = talloc_steal(sd, ids[1].sid);
 817 
 818         sd->type |= SEC_DESC_DACL_PRESENT;
 819 
 820         container = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) ? true:false;
 821 
 822         /* fill in the aces from the parent */
 823         status = pvfs_acl_inherit_aces(pvfs, parent_sd, sd, container);
 824         if (!NT_STATUS_IS_OK(status)) {
 825                 return status;
 826         }
 827 
 828         /* if there is nothing to inherit then we fallback to the
 829            default acl */
 830         if (sd->dacl == NULL || sd->dacl->num_aces == 0) {
 831                 return NT_STATUS_OK;
 832         }
 833 
 834         acl->info.sd = sd;
 835 
 836         status = pvfs_acl_save(pvfs, name, fd, acl);
 837         
 838         return status;
 839 }
 840 
 841 /*
 842   return the maximum allowed access mask
 843 */
 844 NTSTATUS pvfs_access_maximal_allowed(struct pvfs_state *pvfs, 
     /* [<][>][^][v][top][bottom][index][help] */
 845                                      struct ntvfs_request *req,
 846                                      struct pvfs_filename *name,
 847                                      uint32_t *maximal_access)
 848 {
 849         *maximal_access = SEC_FLAG_MAXIMUM_ALLOWED;
 850         return pvfs_access_check(pvfs, req, name, maximal_access);
 851 }

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