root/source3/modules/vfs_acl_xattr.c

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

DEFINITIONS

This source file includes following definitions.
  1. parse_acl_blob
  2. get_acl_blob
  3. create_acl_blob
  4. store_acl_blob_fsp
  5. store_acl_blob_pathname
  6. get_nt_acl_xattr_internal
  7. default_file_sd
  8. inherit_new_acl
  9. open_acl_xattr
  10. mkdir_acl_xattr
  11. fget_nt_acl_xattr
  12. get_nt_acl_xattr
  13. fset_nt_acl_xattr
  14. sys_acl_set_file_xattr
  15. sys_acl_set_fd_xattr
  16. vfs_acl_xattr_init

   1 /*
   2  * Store Windows ACLs in xattrs.
   3  *
   4  * Copyright (C) Volker Lendecke, 2008
   5  * Copyright (C) Jeremy Allison, 2008
   6  *
   7  * This program is free software; you can redistribute it and/or modify
   8  * it under the terms of the GNU General Public License as published by
   9  * the Free Software Foundation; either version 3 of the License, or
  10  * (at your option) any later version.
  11  *
  12  * This program is distributed in the hope that it will be useful,
  13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15  * GNU General Public License for more details.
  16  *
  17  * You should have received a copy of the GNU General Public License
  18  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  19  */
  20 
  21 /* NOTE: This is an experimental module, not yet finished. JRA. */
  22 
  23 #include "includes.h"
  24 #include "librpc/gen_ndr/xattr.h"
  25 #include "librpc/gen_ndr/ndr_xattr.h"
  26 
  27 #undef DBGC_CLASS
  28 #define DBGC_CLASS DBGC_VFS
  29 
  30 /*******************************************************************
  31  Parse out a struct security_descriptor from a DATA_BLOB.
  32 *******************************************************************/
  33 
  34 static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
     /* [<][>][^][v][top][bottom][index][help] */
  35                                 uint32 security_info,
  36                                 struct security_descriptor **ppdesc)
  37 {
  38         TALLOC_CTX *ctx = talloc_tos();
  39         struct xattr_NTACL xacl;
  40         enum ndr_err_code ndr_err;
  41         size_t sd_size;
  42 
  43         ndr_err = ndr_pull_struct_blob(pblob, ctx, NULL, &xacl,
  44                         (ndr_pull_flags_fn_t)ndr_pull_xattr_NTACL);
  45 
  46         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
  47                 DEBUG(5, ("parse_acl_blob: ndr_pull_xattr_NTACL failed: %s\n",
  48                         ndr_errstr(ndr_err)));
  49                 return ndr_map_error2ntstatus(ndr_err);;
  50         }
  51 
  52         if (xacl.version != 2) {
  53                 return NT_STATUS_REVISION_MISMATCH;
  54         }
  55 
  56         *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION, xacl.info.sd_hs->sd->type | SEC_DESC_SELF_RELATIVE,
  57                         (security_info & OWNER_SECURITY_INFORMATION)
  58                         ? xacl.info.sd_hs->sd->owner_sid : NULL,
  59                         (security_info & GROUP_SECURITY_INFORMATION)
  60                         ? xacl.info.sd_hs->sd->group_sid : NULL,
  61                         (security_info & SACL_SECURITY_INFORMATION)
  62                         ? xacl.info.sd_hs->sd->sacl : NULL,
  63                         (security_info & DACL_SECURITY_INFORMATION)
  64                         ? xacl.info.sd_hs->sd->dacl : NULL,
  65                         &sd_size);
  66 
  67         TALLOC_FREE(xacl.info.sd);
  68 
  69         return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
  70 }
  71 
  72 /*******************************************************************
  73  Pull a security descriptor into a DATA_BLOB from a xattr.
  74 *******************************************************************/
  75 
  76 static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  77                         vfs_handle_struct *handle,
  78                         files_struct *fsp,
  79                         const char *name,
  80                         DATA_BLOB *pblob)
  81 {
  82         size_t size = 1024;
  83         uint8_t *val = NULL;
  84         uint8_t *tmp;
  85         ssize_t sizeret;
  86         int saved_errno = 0;
  87 
  88         ZERO_STRUCTP(pblob);
  89 
  90   again:
  91 
  92         tmp = TALLOC_REALLOC_ARRAY(ctx, val, uint8_t, size);
  93         if (tmp == NULL) {
  94                 TALLOC_FREE(val);
  95                 return NT_STATUS_NO_MEMORY;
  96         }
  97         val = tmp;
  98 
  99         become_root();
 100         if (fsp && fsp->fh->fd != -1) {
 101                 sizeret = SMB_VFS_FGETXATTR(fsp, XATTR_NTACL_NAME, val, size);
 102         } else {
 103                 sizeret = SMB_VFS_GETXATTR(handle->conn, name,
 104                                         XATTR_NTACL_NAME, val, size);
 105         }
 106         if (sizeret == -1) {
 107                 saved_errno = errno;
 108         }
 109         unbecome_root();
 110 
 111         /* Max ACL size is 65536 bytes. */
 112         if (sizeret == -1) {
 113                 errno = saved_errno;
 114                 if ((errno == ERANGE) && (size != 65536)) {
 115                         /* Too small, try again. */
 116                         size = 65536;
 117                         goto again;
 118                 }
 119 
 120                 /* Real error - exit here. */
 121                 TALLOC_FREE(val);
 122                 return map_nt_error_from_unix(errno);
 123         }
 124 
 125         pblob->data = val;
 126         pblob->length = sizeret;
 127         return NT_STATUS_OK;
 128 }
 129 
 130 /*******************************************************************
 131  Create a DATA_BLOB from a security descriptor.
 132 *******************************************************************/
 133 
 134 static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob)
     /* [<][>][^][v][top][bottom][index][help] */
 135 {
 136         struct xattr_NTACL xacl;
 137         struct security_descriptor_hash sd_hs;
 138         enum ndr_err_code ndr_err;
 139         TALLOC_CTX *ctx = talloc_tos();
 140 
 141         ZERO_STRUCT(xacl);
 142         ZERO_STRUCT(sd_hs);
 143 
 144         xacl.version = 2;
 145         xacl.info.sd_hs = &sd_hs;
 146         xacl.info.sd_hs->sd = CONST_DISCARD(struct security_descriptor *, psd);
 147         memset(&xacl.info.sd_hs->hash[0], '\0', 16);
 148 
 149         ndr_err = ndr_push_struct_blob(
 150                         pblob, ctx, NULL, &xacl,
 151                         (ndr_push_flags_fn_t)ndr_push_xattr_NTACL);
 152 
 153         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 154                 DEBUG(5, ("create_acl_blob: ndr_push_xattr_NTACL failed: %s\n",
 155                         ndr_errstr(ndr_err)));
 156                 return ndr_map_error2ntstatus(ndr_err);;
 157         }
 158 
 159         return NT_STATUS_OK;
 160 }
 161 
 162 /*******************************************************************
 163  Store a DATA_BLOB into an xattr given an fsp pointer.
 164 *******************************************************************/
 165 
 166 static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
     /* [<][>][^][v][top][bottom][index][help] */
 167                                 files_struct *fsp,
 168                                 DATA_BLOB *pblob)
 169 {
 170         int ret;
 171         int saved_errno = 0;
 172 
 173         DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n",
 174                         (unsigned int)pblob->length, fsp->fsp_name));
 175 
 176         become_root();
 177         if (fsp->fh->fd != -1) {
 178                 ret = SMB_VFS_FSETXATTR(fsp, XATTR_NTACL_NAME,
 179                         pblob->data, pblob->length, 0);
 180         } else {
 181                 ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name,
 182                                 XATTR_NTACL_NAME,
 183                                 pblob->data, pblob->length, 0);
 184         }
 185         if (ret) {
 186                 saved_errno = errno;
 187         }
 188         unbecome_root();
 189         if (ret) {
 190                 errno = saved_errno;
 191                 DEBUG(5, ("store_acl_blob_fsp: setting attr failed for file %s"
 192                         "with error %s\n",
 193                         fsp->fsp_name,
 194                         strerror(errno) ));
 195                 return map_nt_error_from_unix(errno);
 196         }
 197         return NT_STATUS_OK;
 198 }
 199 
 200 /*******************************************************************
 201  Store a DATA_BLOB into an xattr given a pathname.
 202 *******************************************************************/
 203 
 204 static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle,
     /* [<][>][^][v][top][bottom][index][help] */
 205                                         const char *fname,
 206                                         DATA_BLOB *pblob)
 207 {
 208         connection_struct *conn = handle->conn;
 209         int ret;
 210         int saved_errno = 0;
 211 
 212         DEBUG(10,("store_acl_blob_pathname: storing blob "
 213                         "length %u on file %s\n",
 214                         (unsigned int)pblob->length, fname));
 215 
 216         become_root();
 217         ret = SMB_VFS_SETXATTR(conn, fname,
 218                                 XATTR_NTACL_NAME,
 219                                 pblob->data, pblob->length, 0);
 220         if (ret) {
 221                 saved_errno = errno;
 222         }
 223         unbecome_root();
 224         if (ret) {
 225                 errno = saved_errno;
 226                 DEBUG(5, ("store_acl_blob_pathname: setting attr failed "
 227                         "for file %s with error %s\n",
 228                         fname,
 229                         strerror(errno) ));
 230                 return map_nt_error_from_unix(errno);
 231         }
 232         return NT_STATUS_OK;
 233 }
 234 
 235 /*******************************************************************
 236  Store a DATA_BLOB into an xattr given a pathname.
 237 *******************************************************************/
 238 
 239 static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle,
     /* [<][>][^][v][top][bottom][index][help] */
 240                                         files_struct *fsp,
 241                                         const char *name,
 242                                         uint32 security_info,
 243                                         struct security_descriptor **ppdesc)
 244 {
 245         TALLOC_CTX *ctx = talloc_tos();
 246         DATA_BLOB blob;
 247         NTSTATUS status;
 248 
 249         if (fsp && name == NULL) {
 250                 name = fsp->fsp_name;
 251         }
 252 
 253         DEBUG(10, ("get_nt_acl_xattr_internal: name=%s\n", name));
 254 
 255         status = get_acl_blob(ctx, handle, fsp, name, &blob);
 256         if (!NT_STATUS_IS_OK(status)) {
 257                 DEBUG(10, ("get_acl_blob returned %s\n", nt_errstr(status)));
 258                 return status;
 259         }
 260 
 261         status = parse_acl_blob(&blob, security_info, ppdesc);
 262         if (!NT_STATUS_IS_OK(status)) {
 263                 DEBUG(10, ("parse_acl_blob returned %s\n",
 264                                 nt_errstr(status)));
 265                 return status;
 266         }
 267 
 268         TALLOC_FREE(blob.data);
 269         return status;
 270 }
 271 
 272 /*********************************************************************
 273  Create a default security descriptor for a file in case no inheritance
 274  exists. All permissions to the owner and SYSTEM.
 275 *********************************************************************/
 276 
 277 static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 278                                                 SMB_STRUCT_STAT *psbuf)
 279 {
 280         struct dom_sid owner_sid, group_sid;
 281         size_t sd_size;
 282         struct security_ace *pace = NULL;
 283         struct security_acl *pacl = NULL;
 284 
 285         uid_to_sid(&owner_sid, psbuf->st_uid);
 286         gid_to_sid(&group_sid, psbuf->st_gid);
 287 
 288         pace = TALLOC_ARRAY(mem_ctx, struct security_ace, 2);
 289         if (!pace) {
 290                 return NULL;
 291         }
 292 
 293         init_sec_ace(&pace[0], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
 294                         SEC_RIGHTS_FILE_ALL, 0);
 295         init_sec_ace(&pace[1], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED,
 296                         SEC_RIGHTS_FILE_ALL, 0);
 297 
 298         pacl = make_sec_acl(mem_ctx,
 299                                 NT4_ACL_REVISION,
 300                                 2,
 301                                 pace);
 302         if (!pacl) {
 303                 return NULL;
 304         }
 305         return make_sec_desc(mem_ctx,
 306                         SECURITY_DESCRIPTOR_REVISION_1,
 307                         SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
 308                         &owner_sid,
 309                         &group_sid,
 310                         NULL,
 311                         pacl,
 312                         &sd_size);
 313 }
 314 
 315 /*********************************************************************
 316 *********************************************************************/
 317 
 318 static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
     /* [<][>][^][v][top][bottom][index][help] */
 319                                         const char *fname,
 320                                         files_struct *fsp,
 321                                         bool container)
 322 {
 323         TALLOC_CTX *ctx = talloc_tos();
 324         NTSTATUS status;
 325         struct security_descriptor *parent_desc = NULL;
 326         struct security_descriptor *psd = NULL;
 327         DATA_BLOB blob;
 328         size_t size;
 329         char *parent_name;
 330 
 331         if (!parent_dirname(ctx, fname, &parent_name, NULL)) {
 332                 return NT_STATUS_NO_MEMORY;
 333         }
 334 
 335         DEBUG(10,("inherit_new_acl: check directory %s\n",
 336                         parent_name));
 337 
 338         status = get_nt_acl_xattr_internal(handle,
 339                                         NULL,
 340                                         parent_name,
 341                                         (OWNER_SECURITY_INFORMATION |
 342                                          GROUP_SECURITY_INFORMATION |
 343                                          DACL_SECURITY_INFORMATION),
 344                                         &parent_desc);
 345         if (NT_STATUS_IS_OK(status)) {
 346                 /* Create an inherited descriptor from the parent. */
 347 
 348                 if (DEBUGLEVEL >= 10) {
 349                         DEBUG(10,("inherit_new_acl: parent acl is:\n"));
 350                         NDR_PRINT_DEBUG(security_descriptor, parent_desc);
 351                 }
 352 
 353                 status = se_create_child_secdesc(ctx,
 354                                 &psd,
 355                                 &size,
 356                                 parent_desc,
 357                                 &handle->conn->server_info->ptok->user_sids[PRIMARY_USER_SID_INDEX],
 358                                 &handle->conn->server_info->ptok->user_sids[PRIMARY_GROUP_SID_INDEX],
 359                                 container);
 360                 if (!NT_STATUS_IS_OK(status)) {
 361                         return status;
 362                 }
 363 
 364                 if (DEBUGLEVEL >= 10) {
 365                         DEBUG(10,("inherit_new_acl: child acl is:\n"));
 366                         NDR_PRINT_DEBUG(security_descriptor, psd);
 367                 }
 368 
 369         } else {
 370                 DEBUG(10,("inherit_new_acl: directory %s failed "
 371                         "to get acl %s\n",
 372                         parent_name,
 373                         nt_errstr(status) ));
 374         }
 375 
 376         if (!psd || psd->dacl == NULL) {
 377                 SMB_STRUCT_STAT sbuf;
 378                 int ret;
 379 
 380                 TALLOC_FREE(psd);
 381                 if (fsp && !fsp->is_directory && fsp->fh->fd != -1) {
 382                         ret = SMB_VFS_FSTAT(fsp, &sbuf);
 383                 } else {
 384                         if (fsp && fsp->posix_open) {
 385                                 ret = SMB_VFS_LSTAT(handle->conn,fname, &sbuf);
 386                         } else {
 387                                 ret = SMB_VFS_STAT(handle->conn,fname, &sbuf);
 388                         }
 389                 }
 390                 if (ret == -1) {
 391                         return map_nt_error_from_unix(errno);
 392                 }
 393                 psd = default_file_sd(ctx, &sbuf);
 394                 if (!psd) {
 395                         return NT_STATUS_NO_MEMORY;
 396                 }
 397 
 398                 if (DEBUGLEVEL >= 10) {
 399                         DEBUG(10,("inherit_new_acl: default acl is:\n"));
 400                         NDR_PRINT_DEBUG(security_descriptor, psd);
 401                 }
 402         }
 403 
 404         status = create_acl_blob(psd, &blob);
 405         if (!NT_STATUS_IS_OK(status)) {
 406                 return status;
 407         }
 408         if (fsp) {
 409                 return store_acl_blob_fsp(handle, fsp, &blob);
 410         } else {
 411                 return store_acl_blob_pathname(handle, fname, &blob);
 412         }
 413 }
 414 
 415 /*********************************************************************
 416  Check ACL on open. For new files inherit from parent directory.
 417 *********************************************************************/
 418 
 419 static int open_acl_xattr(vfs_handle_struct *handle,
     /* [<][>][^][v][top][bottom][index][help] */
 420                                         const char *fname,
 421                                         files_struct *fsp,
 422                                         int flags,
 423                                         mode_t mode)
 424 {
 425         uint32_t access_granted = 0;
 426         struct security_descriptor *pdesc = NULL;
 427         bool file_existed = true;
 428         NTSTATUS status = get_nt_acl_xattr_internal(handle,
 429                                         NULL,
 430                                         fname,
 431                                         (OWNER_SECURITY_INFORMATION |
 432                                          GROUP_SECURITY_INFORMATION |
 433                                          DACL_SECURITY_INFORMATION),
 434                                         &pdesc);
 435         if (NT_STATUS_IS_OK(status)) {
 436                 /* See if we can access it. */
 437                 status = smb1_file_se_access_check(pdesc,
 438                                         handle->conn->server_info->ptok,
 439                                         fsp->access_mask,
 440                                         &access_granted);
 441                 if (!NT_STATUS_IS_OK(status)) {
 442                         DEBUG(10,("open_acl_xattr: file %s open "
 443                                 "refused with error %s\n",
 444                                 fname,
 445                                 nt_errstr(status) ));
 446                         errno = map_errno_from_nt_status(status);
 447                         return -1;
 448                 }
 449         } else if (NT_STATUS_EQUAL(status,NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
 450                 file_existed = false;
 451         }
 452 
 453         DEBUG(10,("open_acl_xattr: get_nt_acl_attr_internal for "
 454                 "file %s returned %s\n",
 455                 fname,
 456                 nt_errstr(status) ));
 457 
 458         fsp->fh->fd = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
 459 
 460         if (!file_existed && fsp->fh->fd != -1) {
 461                 /* File was created. Inherit from parent directory. */
 462                 string_set(&fsp->fsp_name, fname);
 463                 inherit_new_acl(handle, fname, fsp, false);
 464         }
 465 
 466         return fsp->fh->fd;
 467 }
 468 
 469 static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t mode)
     /* [<][>][^][v][top][bottom][index][help] */
 470 {
 471         int ret = SMB_VFS_NEXT_MKDIR(handle, path, mode);
 472 
 473         if (ret == -1) {
 474                 return ret;
 475         }
 476         /* New directory - inherit from parent. */
 477         inherit_new_acl(handle, path, NULL, true);
 478         return ret;
 479 }
 480 
 481 /*********************************************************************
 482  Fetch a security descriptor given an fsp.
 483 *********************************************************************/
 484 
 485 static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
     /* [<][>][^][v][top][bottom][index][help] */
 486         uint32 security_info, struct security_descriptor **ppdesc)
 487 {
 488         NTSTATUS status = get_nt_acl_xattr_internal(handle, fsp,
 489                                 NULL, security_info, ppdesc);
 490         if (NT_STATUS_IS_OK(status)) {
 491                 if (DEBUGLEVEL >= 10) {
 492                         DEBUG(10,("fget_nt_acl_xattr: returning xattr sd for file %s\n",
 493                                 fsp->fsp_name));
 494                         NDR_PRINT_DEBUG(security_descriptor, *ppdesc);
 495                 }
 496                 return NT_STATUS_OK;
 497         }
 498 
 499         DEBUG(10,("fget_nt_acl_xattr: failed to get xattr sd for file %s, Error %s\n",
 500                         fsp->fsp_name,
 501                         nt_errstr(status) ));
 502 
 503         return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp,
 504                         security_info, ppdesc);
 505 }
 506 
 507 /*********************************************************************
 508  Fetch a security descriptor given a pathname.
 509 *********************************************************************/
 510 
 511 static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle,
     /* [<][>][^][v][top][bottom][index][help] */
 512         const char *name, uint32 security_info, struct security_descriptor **ppdesc)
 513 {
 514         NTSTATUS status = get_nt_acl_xattr_internal(handle, NULL,
 515                                 name, security_info, ppdesc);
 516         if (NT_STATUS_IS_OK(status)) {
 517                 if (DEBUGLEVEL >= 10) {
 518                         DEBUG(10,("get_nt_acl_xattr: returning xattr sd for file %s\n",
 519                                 name));
 520                         NDR_PRINT_DEBUG(security_descriptor, *ppdesc);
 521                 }
 522                 return NT_STATUS_OK;
 523         }
 524 
 525         DEBUG(10,("get_nt_acl_xattr: failed to get xattr sd for file %s, Error %s\n",
 526                         name,
 527                         nt_errstr(status) ));
 528 
 529         return SMB_VFS_NEXT_GET_NT_ACL(handle, name,
 530                         security_info, ppdesc);
 531 }
 532 
 533 /*********************************************************************
 534  Store a security descriptor given an fsp.
 535 *********************************************************************/
 536 
 537 static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
     /* [<][>][^][v][top][bottom][index][help] */
 538         uint32 security_info_sent, const struct security_descriptor *psd)
 539 {
 540         NTSTATUS status;
 541         DATA_BLOB blob;
 542 
 543         if (DEBUGLEVEL >= 10) {
 544                 DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n",
 545                         fsp->fsp_name));
 546                 NDR_PRINT_DEBUG(security_descriptor,
 547                         CONST_DISCARD(struct security_descriptor *,psd));
 548         }
 549 
 550         status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
 551         if (!NT_STATUS_IS_OK(status)) {
 552                 return status;
 553         }
 554 
 555         /* Ensure owner and group are set. */
 556         if (!psd->owner_sid || !psd->group_sid) {
 557                 int ret;
 558                 SMB_STRUCT_STAT sbuf;
 559                 DOM_SID owner_sid, group_sid;
 560                 struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd);
 561 
 562                 if (!nc_psd) {
 563                         return NT_STATUS_OK;
 564                 }
 565                 if (fsp->is_directory || fsp->fh->fd == -1) {
 566                         if (fsp->posix_open) {
 567                                 ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name, &sbuf);
 568                         } else {
 569                                 ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf);
 570                         }
 571                 } else {
 572                         ret = SMB_VFS_FSTAT(fsp, &sbuf);
 573                 }
 574                 if (ret == -1) {
 575                         /* Lower level acl set succeeded,
 576                          * so still return OK. */
 577                         return NT_STATUS_OK;
 578                 }
 579                 create_file_sids(&sbuf, &owner_sid, &group_sid);
 580                 /* This is safe as nc_psd is discarded at fn exit. */
 581                 nc_psd->owner_sid = &owner_sid;
 582                 nc_psd->group_sid = &group_sid;
 583                 security_info_sent |= (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION);
 584                 psd = nc_psd;
 585         }
 586 
 587 #if 0
 588         if ((security_info_sent & DACL_SECURITY_INFORMATION) &&
 589                         psd->dacl != NULL &&
 590                         (psd->type & (SE_DESC_DACL_AUTO_INHERITED|
 591                                 SE_DESC_DACL_AUTO_INHERIT_REQ))==
 592                                 (SE_DESC_DACL_AUTO_INHERITED|
 593                                 SE_DESC_DACL_AUTO_INHERIT_REQ) ) {
 594                 struct security_descriptor *new_psd = NULL;
 595                 status = append_parent_acl(fsp, psd, &new_psd);
 596                 if (!NT_STATUS_IS_OK(status)) {
 597                         /* Lower level acl set succeeded,
 598                          * so still return OK. */
 599                         return NT_STATUS_OK;
 600                 }
 601                 psd = new_psd;
 602         }
 603 #endif
 604 
 605         if (DEBUGLEVEL >= 10) {
 606                 DEBUG(10,("fset_nt_acl_xattr: storing xattr sd for file %s\n",
 607                         fsp->fsp_name));
 608                 NDR_PRINT_DEBUG(security_descriptor,
 609                         CONST_DISCARD(struct security_descriptor *,psd));
 610         }
 611         create_acl_blob(psd, &blob);
 612         store_acl_blob_fsp(handle, fsp, &blob);
 613 
 614         return NT_STATUS_OK;
 615 }
 616 
 617 /*********************************************************************
 618  Remove a Windows ACL - we're setting the underlying POSIX ACL.
 619 *********************************************************************/
 620 
 621 static int sys_acl_set_file_xattr(vfs_handle_struct *handle,
     /* [<][>][^][v][top][bottom][index][help] */
 622                               const char *name,
 623                               SMB_ACL_TYPE_T type,
 624                               SMB_ACL_T theacl)
 625 {
 626         int ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle,
 627                                                 name,
 628                                                 type,
 629                                                 theacl);
 630         if (ret == -1) {
 631                 return -1;
 632         }
 633 
 634         become_root();
 635         SMB_VFS_REMOVEXATTR(handle->conn, name, XATTR_NTACL_NAME);
 636         unbecome_root();
 637 
 638         return ret;
 639 }
 640 
 641 /*********************************************************************
 642  Remove a Windows ACL - we're setting the underlying POSIX ACL.
 643 *********************************************************************/
 644 
 645 static int sys_acl_set_fd_xattr(vfs_handle_struct *handle,
     /* [<][>][^][v][top][bottom][index][help] */
 646                             files_struct *fsp,
 647                             SMB_ACL_T theacl)
 648 {
 649         int ret = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle,
 650                                                 fsp,
 651                                                 theacl);
 652         if (ret == -1) {
 653                 return -1;
 654         }
 655 
 656         become_root();
 657         SMB_VFS_FREMOVEXATTR(fsp, XATTR_NTACL_NAME);
 658         unbecome_root();
 659 
 660         return ret;
 661 }
 662 
 663 /* VFS operations structure */
 664 
 665 static vfs_op_tuple skel_op_tuples[] =
 666 {
 667         {SMB_VFS_OP(mkdir_acl_xattr), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_TRANSPARENT},
 668         {SMB_VFS_OP(open_acl_xattr),  SMB_VFS_OP_OPEN,  SMB_VFS_LAYER_TRANSPARENT},
 669 
 670         /* NT File ACL operations */
 671 
 672         {SMB_VFS_OP(fget_nt_acl_xattr),SMB_VFS_OP_FGET_NT_ACL,SMB_VFS_LAYER_TRANSPARENT},
 673         {SMB_VFS_OP(get_nt_acl_xattr), SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
 674         {SMB_VFS_OP(fset_nt_acl_xattr),SMB_VFS_OP_FSET_NT_ACL,SMB_VFS_LAYER_TRANSPARENT},
 675 
 676         /* POSIX ACL operations. */
 677         {SMB_VFS_OP(sys_acl_set_file_xattr), SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_TRANSPARENT},
 678         {SMB_VFS_OP(sys_acl_set_fd_xattr), SMB_VFS_OP_SYS_ACL_SET_FD, SMB_VFS_LAYER_TRANSPARENT},
 679 
 680         {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
 681 };
 682 
 683 NTSTATUS vfs_acl_xattr_init(void)
     /* [<][>][^][v][top][bottom][index][help] */
 684 {
 685         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "acl_xattr", skel_op_tuples);
 686 }

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