ReactOS  0.4.14-dev-614-gbfd8a84
security.c
Go to the documentation of this file.
1 /* Copyright (c) Mark Harmstone 2016-17
2  *
3  * This file is part of WinBtrfs.
4  *
5  * WinBtrfs is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public Licence as published by
7  * the Free Software Foundation, either version 3 of the Licence, or
8  * (at your option) any later version.
9  *
10  * WinBtrfs is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public Licence for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public Licence
16  * along with WinBtrfs. If not, see <http://www.gnu.org/licenses/>. */
17 
18 #include "btrfs_drv.h"
19 
20 #define SEF_DACL_AUTO_INHERIT 0x01
21 #define SEF_SACL_AUTO_INHERIT 0x02
22 
23 typedef struct {
26  UCHAR auth[6];
27  uint32_t nums[8];
28 } sid_header;
29 
30 static sid_header sid_BA = { 1, 2, SECURITY_NT_AUTHORITY, {32, 544}}; // BUILTIN\Administrators
31 static sid_header sid_SY = { 1, 1, SECURITY_NT_AUTHORITY, {18}}; // NT AUTHORITY\SYSTEM
32 static sid_header sid_BU = { 1, 2, SECURITY_NT_AUTHORITY, {32, 545}}; // BUILTIN\Users
33 static sid_header sid_AU = { 1, 1, SECURITY_NT_AUTHORITY, {11}}; // NT AUTHORITY\Authenticated Users
34 
35 typedef struct {
39 } dacl;
40 
41 static dacl def_dacls[] = {
42  { 0, FILE_ALL_ACCESS, &sid_BA },
44  { 0, FILE_ALL_ACCESS, &sid_SY },
49  // FIXME - Mandatory Label\High Mandatory Level:(OI)(NP)(IO)(NW)
50  { 0, 0, NULL }
51 };
52 
54 extern ERESOURCE mapping_lock;
55 
56 void add_user_mapping(WCHAR* sidstring, ULONG sidstringlength, uint32_t uid) {
57  unsigned int i, np;
58  uint8_t numdashes;
59  uint64_t val;
60  ULONG sidsize;
61  sid_header* sid;
62  uid_map* um;
63 
64  if (sidstringlength < 4 ||
65  sidstring[0] != 'S' ||
66  sidstring[1] != '-' ||
67  sidstring[2] != '1' ||
68  sidstring[3] != '-') {
69  ERR("invalid SID\n");
70  return;
71  }
72 
73  sidstring = &sidstring[4];
74  sidstringlength -= 4;
75 
76  numdashes = 0;
77  for (i = 0; i < sidstringlength; i++) {
78  if (sidstring[i] == '-') {
79  numdashes++;
80  sidstring[i] = 0;
81  }
82  }
83 
84  sidsize = 8 + (numdashes * 4);
86  if (!sid) {
87  ERR("out of memory\n");
88  return;
89  }
90 
91  sid->revision = 0x01;
92  sid->elements = numdashes;
93 
94  np = 0;
95  while (sidstringlength > 0) {
96  val = 0;
97  i = 0;
98  while (sidstring[i] != '-' && i < sidstringlength) {
99  if (sidstring[i] >= '0' && sidstring[i] <= '9') {
100  val *= 10;
101  val += sidstring[i] - '0';
102  } else
103  break;
104 
105  i++;
106  }
107 
108  i++;
109  TRACE("val = %u, i = %u, ssl = %u\n", (uint32_t)val, i, sidstringlength);
110 
111  if (np == 0) {
112  sid->auth[0] = (uint8_t)((val & 0xff0000000000) >> 40);
113  sid->auth[1] = (uint8_t)((val & 0xff00000000) >> 32);
114  sid->auth[2] = (uint8_t)((val & 0xff000000) >> 24);
115  sid->auth[3] = (uint8_t)((val & 0xff0000) >> 16);
116  sid->auth[4] = (uint8_t)((val & 0xff00) >> 8);
117  sid->auth[5] = val & 0xff;
118  } else {
119  sid->nums[np-1] = (uint32_t)val;
120  }
121 
122  np++;
123 
124  if (sidstringlength > i) {
125  sidstringlength -= i;
126 
127  sidstring = &sidstring[i];
128  } else
129  break;
130  }
131 
133  if (!um) {
134  ERR("out of memory\n");
135  ExFreePool(sid);
136  return;
137  }
138 
139  um->sid = sid;
140  um->uid = uid;
141 
143 }
144 
145 void add_group_mapping(WCHAR* sidstring, ULONG sidstringlength, uint32_t gid) {
146  unsigned int i, np;
147  uint8_t numdashes;
148  uint64_t val;
149  ULONG sidsize;
150  sid_header* sid;
151  gid_map* gm;
152 
153  if (sidstringlength < 4 || sidstring[0] != 'S' || sidstring[1] != '-' || sidstring[2] != '1' || sidstring[3] != '-') {
154  ERR("invalid SID\n");
155  return;
156  }
157 
158  sidstring = &sidstring[4];
159  sidstringlength -= 4;
160 
161  numdashes = 0;
162  for (i = 0; i < sidstringlength; i++) {
163  if (sidstring[i] == '-') {
164  numdashes++;
165  sidstring[i] = 0;
166  }
167  }
168 
169  sidsize = 8 + (numdashes * 4);
171  if (!sid) {
172  ERR("out of memory\n");
173  return;
174  }
175 
176  sid->revision = 0x01;
177  sid->elements = numdashes;
178 
179  np = 0;
180  while (sidstringlength > 0) {
181  val = 0;
182  i = 0;
183  while (sidstring[i] != '-' && i < sidstringlength) {
184  if (sidstring[i] >= '0' && sidstring[i] <= '9') {
185  val *= 10;
186  val += sidstring[i] - '0';
187  } else
188  break;
189 
190  i++;
191  }
192 
193  i++;
194  TRACE("val = %u, i = %u, ssl = %u\n", (uint32_t)val, i, sidstringlength);
195 
196  if (np == 0) {
197  sid->auth[0] = (uint8_t)((val & 0xff0000000000) >> 40);
198  sid->auth[1] = (uint8_t)((val & 0xff00000000) >> 32);
199  sid->auth[2] = (uint8_t)((val & 0xff000000) >> 24);
200  sid->auth[3] = (uint8_t)((val & 0xff0000) >> 16);
201  sid->auth[4] = (uint8_t)((val & 0xff00) >> 8);
202  sid->auth[5] = val & 0xff;
203  } else
204  sid->nums[np-1] = (uint32_t)val;
205 
206  np++;
207 
208  if (sidstringlength > i) {
209  sidstringlength -= i;
210 
211  sidstring = &sidstring[i];
212  } else
213  break;
214  }
215 
217  if (!gm) {
218  ERR("out of memory\n");
219  ExFreePool(sid);
220  return;
221  }
222 
223  gm->sid = sid;
224  gm->gid = gid;
225 
227 }
228 
230  LIST_ENTRY* le;
231  sid_header* sh;
232  UCHAR els;
233 
235 
236  le = uid_map_list.Flink;
237  while (le != &uid_map_list) {
238  uid_map* um = CONTAINING_RECORD(le, uid_map, listentry);
239 
240  if (um->uid == uid) {
242  if (!*sid) {
243  ERR("out of memory\n");
246  }
247 
248  RtlCopyMemory(*sid, um->sid, RtlLengthSid(um->sid));
250  return STATUS_SUCCESS;
251  }
252 
253  le = le->Flink;
254  }
255 
257 
258  if (uid == 0) { // root
259  // FIXME - find actual Administrator account, rather than SYSTEM (S-1-5-18)
260  // (of form S-1-5-21-...-500)
261 
262  els = 1;
263 
264  sh = ExAllocatePoolWithTag(PagedPool, sizeof(sid_header) + ((els - 1) * sizeof(uint32_t)), ALLOC_TAG);
265  if (!sh) {
266  ERR("out of memory\n");
267  *sid = NULL;
269  }
270 
271  sh->revision = 1;
272  sh->elements = els;
273 
274  sh->auth[0] = 0;
275  sh->auth[1] = 0;
276  sh->auth[2] = 0;
277  sh->auth[3] = 0;
278  sh->auth[4] = 0;
279  sh->auth[5] = 5;
280 
281  sh->nums[0] = 18;
282  } else {
283  // fallback to S-1-22-1-X, Samba's SID scheme
285  if (!sh) {
286  ERR("out of memory\n");
287  *sid = NULL;
289  }
290 
291  sh->revision = 1;
292  sh->elements = 2;
293 
294  sh->auth[0] = 0;
295  sh->auth[1] = 0;
296  sh->auth[2] = 0;
297  sh->auth[3] = 0;
298  sh->auth[4] = 0;
299  sh->auth[5] = 22;
300 
301  sh->nums[0] = 1;
302  sh->nums[1] = uid;
303  }
304 
305  *sid = sh;
306 
307  return STATUS_SUCCESS;
308 }
309 
311  LIST_ENTRY* le;
312  sid_header* sh = sid;
313 
315 
316  le = uid_map_list.Flink;
317  while (le != &uid_map_list) {
318  uid_map* um = CONTAINING_RECORD(le, uid_map, listentry);
319 
320  if (RtlEqualSid(sid, um->sid)) {
322  return um->uid;
323  }
324 
325  le = le->Flink;
326  }
327 
329 
330  if (RtlEqualSid(sid, &sid_SY))
331  return 0; // root
332 
333  // Samba's SID scheme: S-1-22-1-X
334  if (sh->revision == 1 && sh->elements == 2 && sh->auth[0] == 0 && sh->auth[1] == 0 && sh->auth[2] == 0 && sh->auth[3] == 0 &&
335  sh->auth[4] == 0 && sh->auth[5] == 22 && sh->nums[0] == 1)
336  return sh->nums[1];
337 
338  return UID_NOBODY;
339 }
340 
341 static void gid_to_sid(uint32_t gid, PSID* sid) {
342  sid_header* sh;
343  UCHAR els;
344 
345  // FIXME - do this properly?
346 
347  // fallback to S-1-22-2-X, Samba's SID scheme
348  els = 2;
349  sh = ExAllocatePoolWithTag(PagedPool, sizeof(sid_header) + ((els - 1) * sizeof(uint32_t)), ALLOC_TAG);
350  if (!sh) {
351  ERR("out of memory\n");
352  *sid = NULL;
353  return;
354  }
355 
356  sh->revision = 1;
357  sh->elements = els;
358 
359  sh->auth[0] = 0;
360  sh->auth[1] = 0;
361  sh->auth[2] = 0;
362  sh->auth[3] = 0;
363  sh->auth[4] = 0;
364  sh->auth[5] = 22;
365 
366  sh->nums[0] = 2;
367  sh->nums[1] = gid;
368 
369  *sid = sh;
370 }
371 
373  uint16_t size, i;
374  ACL* acl;
375  ACCESS_ALLOWED_ACE* aaa;
376 
377  size = sizeof(ACL);
378  i = 0;
379  while (def_dacls[i].sid) {
380  size += sizeof(ACCESS_ALLOWED_ACE);
381  size += 8 + (def_dacls[i].sid->elements * sizeof(uint32_t)) - sizeof(ULONG);
382  i++;
383  }
384 
386  if (!acl) {
387  ERR("out of memory\n");
388  return NULL;
389  }
390 
391  acl->AclRevision = ACL_REVISION;
392  acl->Sbz1 = 0;
393  acl->AclSize = size;
394  acl->AceCount = i;
395  acl->Sbz2 = 0;
396 
397  aaa = (ACCESS_ALLOWED_ACE*)&acl[1];
398  i = 0;
399  while (def_dacls[i].sid) {
401  aaa->Header.AceFlags = def_dacls[i].flags;
402  aaa->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + 8 + (def_dacls[i].sid->elements * sizeof(uint32_t));
403  aaa->Mask = def_dacls[i].mask;
404 
405  RtlCopyMemory(&aaa->SidStart, def_dacls[i].sid, 8 + (def_dacls[i].sid->elements * sizeof(uint32_t)));
406 
407  aaa = (ACCESS_ALLOWED_ACE*)((uint8_t*)aaa + aaa->Header.AceSize);
408 
409  i++;
410  }
411 
412  return acl;
413 }
414 
415 static void get_top_level_sd(fcb* fcb) {
418  ULONG buflen;
419  ACL* acl = NULL;
420  PSID usersid = NULL, groupsid = NULL;
421 
423 
424  if (!NT_SUCCESS(Status)) {
425  ERR("RtlCreateSecurityDescriptor returned %08x\n", Status);
426  goto end;
427  }
428 
429  Status = uid_to_sid(fcb->inode_item.st_uid, &usersid);
430  if (!NT_SUCCESS(Status)) {
431  ERR("uid_to_sid returned %08x\n", Status);
432  goto end;
433  }
434 
435  Status = RtlSetOwnerSecurityDescriptor(&sd, usersid, false);
436 
437  if (!NT_SUCCESS(Status)) {
438  ERR("RtlSetOwnerSecurityDescriptor returned %08x\n", Status);
439  goto end;
440  }
441 
442  gid_to_sid(fcb->inode_item.st_gid, &groupsid);
443  if (!groupsid) {
444  ERR("out of memory\n");
445  goto end;
446  }
447 
448  Status = RtlSetGroupSecurityDescriptor(&sd, groupsid, false);
449 
450  if (!NT_SUCCESS(Status)) {
451  ERR("RtlSetGroupSecurityDescriptor returned %08x\n", Status);
452  goto end;
453  }
454 
455  acl = load_default_acl();
456 
457  if (!acl) {
458  ERR("out of memory\n");
459  goto end;
460  }
461 
462  Status = RtlSetDaclSecurityDescriptor(&sd, true, acl, false);
463 
464  if (!NT_SUCCESS(Status)) {
465  ERR("RtlSetDaclSecurityDescriptor returned %08x\n", Status);
466  goto end;
467  }
468 
469  // FIXME - SACL_SECURITY_INFORMATION
470 
471  buflen = 0;
472 
473  // get sd size
476  ERR("RtlAbsoluteToSelfRelativeSD 1 returned %08x\n", Status);
477  goto end;
478  }
479 
480  if (buflen == 0 || Status == STATUS_SUCCESS) {
481  TRACE("RtlAbsoluteToSelfRelativeSD said SD is zero-length\n");
482  goto end;
483  }
484 
486  if (!fcb->sd) {
487  ERR("out of memory\n");
488  goto end;
489  }
490 
491  Status = RtlAbsoluteToSelfRelativeSD(&sd, fcb->sd, &buflen);
492 
493  if (!NT_SUCCESS(Status)) {
494  ERR("RtlAbsoluteToSelfRelativeSD 2 returned %08x\n", Status);
495  ExFreePool(fcb->sd);
496  fcb->sd = NULL;
497  goto end;
498  }
499 
500 end:
501  if (acl)
502  ExFreePool(acl);
503 
504  if (usersid)
505  ExFreePool(usersid);
506 
507  if (groupsid)
508  ExFreePool(groupsid);
509 }
510 
511 void fcb_get_sd(fcb* fcb, struct _fcb* parent, bool look_for_xattr, PIRP Irp) {
513  PSID usersid = NULL, groupsid = NULL;
514  SECURITY_SUBJECT_CONTEXT subjcont;
515  ULONG buflen;
516 
517  if (look_for_xattr && get_xattr(fcb->Vcb, fcb->subvol, fcb->inode, EA_NTACL, EA_NTACL_HASH, (uint8_t**)&fcb->sd, (uint16_t*)&buflen, Irp))
518  return;
519 
520  if (!parent) {
522  return;
523  }
524 
525  SeCaptureSubjectContext(&subjcont);
526 
529  if (!NT_SUCCESS(Status)) {
530  ERR("SeAssignSecurityEx returned %08x\n", Status);
531  return;
532  }
533 
534  Status = uid_to_sid(fcb->inode_item.st_uid, &usersid);
535  if (!NT_SUCCESS(Status)) {
536  ERR("uid_to_sid returned %08x\n", Status);
537  return;
538  }
539 
540  RtlSetOwnerSecurityDescriptor(&fcb->sd, usersid, false);
541 
542  gid_to_sid(fcb->inode_item.st_gid, &groupsid);
543  if (!groupsid) {
544  ERR("out of memory\n");
545  ExFreePool(usersid);
546  return;
547  }
548 
549  RtlSetGroupSecurityDescriptor(&fcb->sd, groupsid, false);
550 
551  ExFreePool(usersid);
552  ExFreePool(groupsid);
553 }
554 
557  fcb* fcb = FileObject->FsContext;
558  ccb* ccb = FileObject->FsContext2;
559  file_ref* fileref = ccb ? ccb->fileref : NULL;
560 
561  if (fcb->ads) {
562  if (fileref && fileref->parent)
563  fcb = fileref->parent->fcb;
564  else {
565  ERR("could not get parent fcb for stream\n");
566  return STATUS_INTERNAL_ERROR;
567  }
568  }
569 
570  // Why (void**)? Is this a bug in mingw?
571  Status = SeQuerySecurityDescriptorInfo(&flags, relsd, buflen, (void**)&fcb->sd);
572 
574  TRACE("SeQuerySecurityDescriptorInfo returned %08x\n", Status);
575  else if (!NT_SUCCESS(Status))
576  ERR("SeQuerySecurityDescriptorInfo returned %08x\n", Status);
577 
578  return Status;
579 }
580 
583 NTSTATUS __stdcall drv_query_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
588  ULONG buflen;
589  bool top_level;
591  ccb* ccb = FileObject ? FileObject->FsContext2 : NULL;
592 
594 
595  TRACE("query security\n");
596 
597  top_level = is_top_level(Irp);
598 
599  if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
601  goto end;
602  } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
604  goto end;
605  }
606 
607  if (!ccb) {
608  ERR("no ccb\n");
610  goto end;
611  }
612 
613  if (Irp->RequestorMode == UserMode && !(ccb->access & READ_CONTROL)) {
614  WARN("insufficient permissions\n");
616  goto end;
617  }
618 
620 
621  Irp->IoStatus.Information = 0;
622 
623  if (IrpSp->Parameters.QuerySecurity.SecurityInformation & OWNER_SECURITY_INFORMATION)
624  TRACE("OWNER_SECURITY_INFORMATION\n");
625 
626  if (IrpSp->Parameters.QuerySecurity.SecurityInformation & GROUP_SECURITY_INFORMATION)
627  TRACE("GROUP_SECURITY_INFORMATION\n");
628 
629  if (IrpSp->Parameters.QuerySecurity.SecurityInformation & DACL_SECURITY_INFORMATION)
630  TRACE("DACL_SECURITY_INFORMATION\n");
631 
632  if (IrpSp->Parameters.QuerySecurity.SecurityInformation & SACL_SECURITY_INFORMATION)
633  TRACE("SACL_SECURITY_INFORMATION\n");
634 
635  TRACE("length = %u\n", IrpSp->Parameters.QuerySecurity.Length);
636 
638  TRACE("sd = %p\n", sd);
639 
640  if (Irp->MdlAddress && !sd) {
641  ERR("MmGetSystemAddressForMdlSafe returned NULL\n");
643  goto end;
644  }
645 
646  buflen = IrpSp->Parameters.QuerySecurity.Length;
647 
648  Status = get_file_security(IrpSp->FileObject, sd, &buflen, IrpSp->Parameters.QuerySecurity.SecurityInformation);
649 
650  if (NT_SUCCESS(Status))
651  Irp->IoStatus.Information = IrpSp->Parameters.QuerySecurity.Length;
652  else if (Status == STATUS_BUFFER_TOO_SMALL) {
653  Irp->IoStatus.Information = buflen;
655  } else
656  Irp->IoStatus.Information = 0;
657 
658 end:
659  TRACE("Irp->IoStatus.Information = %u\n", Irp->IoStatus.Information);
660 
661  Irp->IoStatus.Status = Status;
662 
664 
665  if (top_level)
667 
668  TRACE("returning %08x\n", Status);
669 
671 
672  return Status;
673 }
674 
677  fcb* fcb = FileObject->FsContext;
678  ccb* ccb = FileObject->FsContext2;
679  file_ref* fileref = ccb ? ccb->fileref : NULL;
680  SECURITY_DESCRIPTOR* oldsd;
682  BTRFS_TIME now;
683 
684  TRACE("(%p, %p, %p, %x)\n", Vcb, FileObject, sd, *flags);
685 
686  if (Vcb->readonly)
688 
689  if (fcb->ads) {
690  if (fileref && fileref->parent)
691  fcb = fileref->parent->fcb;
692  else {
693  ERR("could not find parent fcb for stream\n");
694  return STATUS_INTERNAL_ERROR;
695  }
696  }
697 
698  if (!fcb || !ccb)
700 
701  ExAcquireResourceExclusiveLite(fcb->Header.Resource, true);
702 
703  if (is_subvol_readonly(fcb->subvol, Irp)) {
705  goto end;
706  }
707 
708  oldsd = fcb->sd;
709 
711 
712  if (!NT_SUCCESS(Status)) {
713  ERR("SeSetSecurityDescriptorInfo returned %08x\n", Status);
714  goto end;
715  }
716 
717  ExFreePool(oldsd);
718 
721 
722  fcb->inode_item.transid = Vcb->superblock.generation;
723 
726 
728 
729  fcb->sd_dirty = true;
730  fcb->sd_deleted = false;
731  fcb->inode_item_changed = true;
732 
733  fcb->subvol->root_item.ctransid = Vcb->superblock.generation;
734  fcb->subvol->root_item.ctime = now;
735 
737 
739 
740 end:
741  ExReleaseResourceLite(fcb->Header.Resource);
742 
743  return Status;
744 }
745 
752  ccb* ccb = FileObject ? FileObject->FsContext2 : NULL;
754  ULONG access_req = 0;
755  bool top_level;
756 
758 
759  TRACE("set security\n");
760 
761  top_level = is_top_level(Irp);
762 
763  if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
765  goto end;
766  } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
768  goto end;
769  }
770 
771  if (!ccb) {
772  ERR("no ccb\n");
774  goto end;
775  }
776 
778 
779  Irp->IoStatus.Information = 0;
780 
781  if (IrpSp->Parameters.SetSecurity.SecurityInformation & OWNER_SECURITY_INFORMATION) {
782  TRACE("OWNER_SECURITY_INFORMATION\n");
783  access_req |= WRITE_OWNER;
784  }
785 
786  if (IrpSp->Parameters.SetSecurity.SecurityInformation & GROUP_SECURITY_INFORMATION) {
787  TRACE("GROUP_SECURITY_INFORMATION\n");
788  access_req |= WRITE_OWNER;
789  }
790 
791  if (IrpSp->Parameters.SetSecurity.SecurityInformation & DACL_SECURITY_INFORMATION) {
792  TRACE("DACL_SECURITY_INFORMATION\n");
793  access_req |= WRITE_DAC;
794  }
795 
796  if (IrpSp->Parameters.SetSecurity.SecurityInformation & SACL_SECURITY_INFORMATION) {
797  TRACE("SACL_SECURITY_INFORMATION\n");
798  access_req |= ACCESS_SYSTEM_SECURITY;
799  }
800 
801  if (Irp->RequestorMode == UserMode && (ccb->access & access_req) != access_req) {
803  WARN("insufficient privileges\n");
804  goto end;
805  }
806 
807  Status = set_file_security(DeviceObject->DeviceExtension, FileObject, IrpSp->Parameters.SetSecurity.SecurityDescriptor,
808  &IrpSp->Parameters.SetSecurity.SecurityInformation, Irp);
809 
810 end:
811  Irp->IoStatus.Status = Status;
812 
814 
815  TRACE("returning %08x\n", Status);
816 
817  if (top_level)
819 
821 
822  return Status;
823 }
824 
825 static bool search_for_gid(fcb* fcb, PSID sid) {
826  LIST_ENTRY* le;
827 
828  le = gid_map_list.Flink;
829  while (le != &gid_map_list) {
830  gid_map* gm = CONTAINING_RECORD(le, gid_map, listentry);
831 
832  if (RtlEqualSid(sid, gm->sid)) {
833  fcb->inode_item.st_gid = gm->gid;
834  return true;
835  }
836 
837  le = le->Flink;
838  }
839 
840  return false;
841 }
842 
843 void find_gid(struct _fcb* fcb, struct _fcb* parfcb, PSECURITY_SUBJECT_CONTEXT subjcont) {
845  TOKEN_OWNER* to;
846  TOKEN_PRIMARY_GROUP* tpg;
847  TOKEN_GROUPS* tg;
848 
849  if (parfcb && parfcb->inode_item.st_mode & S_ISGID) {
851  return;
852  }
853 
855 
856  if (!subjcont || !subjcont->PrimaryToken || IsListEmpty(&gid_map_list)) {
858  return;
859  }
860 
861  Status = SeQueryInformationToken(subjcont->PrimaryToken, TokenOwner, (void**)&to);
862  if (!NT_SUCCESS(Status))
863  ERR("SeQueryInformationToken returned %08x\n", Status);
864  else {
865  if (search_for_gid(fcb, to->Owner)) {
867  ExFreePool(to);
868  return;
869  }
870 
871  ExFreePool(to);
872  }
873 
874  Status = SeQueryInformationToken(subjcont->PrimaryToken, TokenPrimaryGroup, (void**)&tpg);
875  if (!NT_SUCCESS(Status))
876  ERR("SeQueryInformationToken returned %08x\n", Status);
877  else {
878  if (search_for_gid(fcb, tpg->PrimaryGroup)) {
880  ExFreePool(tpg);
881  return;
882  }
883 
884  ExFreePool(tpg);
885  }
886 
887  Status = SeQueryInformationToken(subjcont->PrimaryToken, TokenGroups, (void**)&tg);
888  if (!NT_SUCCESS(Status))
889  ERR("SeQueryInformationToken returned %08x\n", Status);
890  else {
891  ULONG i;
892 
893  for (i = 0; i < tg->GroupCount; i++) {
894  if (search_for_gid(fcb, tg->Groups[i].Sid)) {
896  ExFreePool(tg);
897  return;
898  }
899  }
900 
901  ExFreePool(tg);
902  }
903 
905 }
906 
909  PSID owner;
910  BOOLEAN defaulted;
911 
912  Status = SeAssignSecurityEx(parfileref ? parfileref->fcb->sd : NULL, as->SecurityDescriptor, (void**)&fcb->sd, NULL, fcb->type == BTRFS_TYPE_DIRECTORY,
914 
915  if (!NT_SUCCESS(Status)) {
916  ERR("SeAssignSecurityEx returned %08x\n", Status);
917  return Status;
918  }
919 
920  Status = RtlGetOwnerSecurityDescriptor(fcb->sd, &owner, &defaulted);
921  if (!NT_SUCCESS(Status)) {
922  ERR("RtlGetOwnerSecurityDescriptor returned %08x\n", Status);
924  } else {
925  fcb->inode_item.st_uid = sid_to_uid(owner);
926  }
927 
928  find_gid(fcb, parfileref ? parfileref->fcb : NULL, &as->SubjectSecurityContext);
929 
930  return STATUS_SUCCESS;
931 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
PGENERIC_MAPPING NTAPI IoGetFileObjectGenericMapping(VOID)
Definition: file.c:3266
struct _file_ref * parent
Definition: btrfs_drv.h:353
#define FILE_GENERIC_READ
Definition: nt_native.h:653
VOID NTAPI SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext)
Definition: access.c:301
NTKERNELAPI NTSTATUS NTAPI SeAssignSecurityEx(_In_opt_ PSECURITY_DESCRIPTOR ParentDescriptor, _In_opt_ PSECURITY_DESCRIPTOR ExplicitDescriptor, _Out_ PSECURITY_DESCRIPTOR *NewDescriptor, _In_opt_ GUID *ObjectType, _In_ BOOLEAN IsDirectoryObject, _In_ ULONG AutoInheritFlags, _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ PGENERIC_MAPPING GenericMapping, _In_ POOL_TYPE PoolType)
#define IN
Definition: typedefs.h:38
PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: setypes.h:207
ACCESS_MASK mask
Definition: security.c:37
sid_header * sid
Definition: security.c:38
UCHAR AceFlags
Definition: ms-dtyp.idl:211
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTKERNELAPI NTSTATUS NTAPI SeSetSecurityDescriptorInfo(_In_opt_ PVOID Object, _In_ PSECURITY_INFORMATION SecurityInformation, _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Inout_ PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor, _In_ POOL_TYPE PoolType, _In_ PGENERIC_MAPPING GenericMapping)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static ULONG
Definition: security.c:118
#define FsRtlEnterFileSystem
NTSYSAPI NTSTATUS NTAPI RtlSetGroupSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSID Group, IN BOOLEAN GroupDefaulted)
Definition: sd.c:410
#define IRP_MJ_QUERY_SECURITY
#define FILE_ALL_ACCESS
Definition: nt_native.h:651
#define ACCESS_SYSTEM_SECURITY
Definition: nt_native.h:77
#define FsRtlExitFileSystem
#define S_ISGID
Definition: propsheet.h:69
NTSTATUS vol_set_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:898
NTSTATUS vol_query_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:892
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
USHORT AclSize
Definition: ms-dtyp.idl:296
#define IRP_MJ_SET_SECURITY
#define WARN(fmt,...)
Definition: debug.h:111
LONG NTSTATUS
Definition: precomp.h:26
bool sd_deleted
Definition: btrfs_drv.h:317
static dacl def_dacls[]
Definition: security.c:41
FT_UInt sid
Definition: cffcmap.c:139
struct _ACCESS_ALLOWED_ACE ACCESS_ALLOWED_ACE
#define VCB_TYPE_FS
Definition: btrfs_drv.h:664
#define GROUP_SECURITY_INFORMATION
Definition: setypes.h:124
#define EA_NTACL_HASH
Definition: btrfs_drv.h:98
GLuint GLuint end
Definition: gl.h:1545
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
__u16 time
Definition: mkdosfs.c:366
ACCESS_MASK access
Definition: btrfs_drv.h:383
#define WRITE_OWNER
Definition: nt_native.h:60
unsigned short int uint16_t
Definition: acefiex.h:54
#define InsertTailList(ListHead, Entry)
ACE_HEADER Header
Definition: ms-dtyp.idl:216
bool is_top_level(_In_ PIRP Irp)
Definition: btrfs.c:276
PSID sid
Definition: btrfs_drv.h:885
BTRFS_TIME st_ctime
Definition: btrfs.h:284
USHORT AceCount
Definition: ms-dtyp.idl:297
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
_Dispatch_type_(IRP_MJ_QUERY_SECURITY)
Definition: security.c:581
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
static void gid_to_sid(uint32_t gid, PSID *sid)
Definition: security.c:341
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
#define ALLOC_TAG
Definition: btrfs_drv.h:91
USHORT AceSize
Definition: ms-dtyp.idl:212
void queue_notification_fcb(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1586
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
uint32_t st_gid
Definition: btrfs.h:277
SECURITY_DESCRIPTOR * sd
Definition: btrfs_drv.h:289
PSID sid
Definition: btrfs_drv.h:879
static sid_header sid_AU
Definition: security.c:33
LIST_ENTRY uid_map_list
Definition: btrfs.c:72
static sid_header sid_SY
Definition: security.c:31
static void get_top_level_sd(fcb *fcb)
Definition: security.c:415
static __inline bool is_subvol_readonly(root *r, PIRP Irp)
Definition: btrfs_drv.h:1008
DWORD SECURITY_INFORMATION
Definition: ms-dtyp.idl:311
static sid_header sid_BA
Definition: security.c:30
static NTSTATUS set_file_security(device_extension *Vcb, PFILE_OBJECT FileObject, SECURITY_DESCRIPTOR *sd, PSECURITY_INFORMATION flags, PIRP Irp)
Definition: security.c:675
uint64_t sequence
Definition: btrfs.h:281
time_t now
Definition: finger.c:65
NTSYSAPI NTSTATUS NTAPI RtlAbsoluteToSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor, IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor, IN PULONG BufferLength)
Definition: sd.c:626
#define FILE_ACTION_MODIFIED
static bool search_for_gid(fcb *fcb, PSID sid)
Definition: security.c:825
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
struct _ACL ACL
smooth NULL
Definition: ftsmooth.c:416
void mark_fcb_dirty(_In_ fcb *fcb)
Definition: btrfs.c:1614
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
#define IoCompleteRequest
Definition: irp.c:1240
UCHAR elements
Definition: security.c:25
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
uint8_t type
Definition: btrfs_drv.h:287
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:526
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
ERESOURCE mapping_lock
Definition: btrfs.c:106
GLuint GLfloat * val
Definition: glext.h:7180
#define FILE_GENERIC_EXECUTE
Definition: nt_native.h:668
const string EA_NTACL
Definition: recv.cpp:37
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:279
#define CONTAINER_INHERIT_ACE
Definition: setypes.h:715
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
PACCESS_TOKEN PrimaryToken
Definition: setypes.h:192
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
bool sd_dirty
Definition: btrfs_drv.h:317
r parent
Definition: btrfs.c:2869
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
DWORD * PSECURITY_INFORMATION
Definition: ms-dtyp.idl:311
#define VCB_TYPE_VOLUME
Definition: btrfs_drv.h:666
uint64_t inode
Definition: btrfs_drv.h:285
Definition: security.c:35
bool user_set_change_time
Definition: btrfs_drv.h:391
#define Vcb
Definition: cdprocs.h:1425
static __inline void * map_user_buffer(PIRP Irp, ULONG priority)
Definition: btrfs_drv.h:952
static ACL * load_default_acl()
Definition: security.c:372
#define SACL_SECURITY_INFORMATION
Definition: setypes.h:126
UCHAR revision
Definition: security.c:24
#define ACCESS_ALLOWED_ACE_TYPE
Definition: setypes.h:685
#define WRITE_DAC
Definition: nt_native.h:59
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define __stdcall
Definition: typedefs.h:25
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1955
GLbitfield flags
Definition: glext.h:7161
#define SEF_DACL_AUTO_INHERIT
Definition: security.c:20
void add_group_mapping(WCHAR *sidstring, ULONG sidstringlength, uint32_t gid)
Definition: security.c:145
#define READ_CONTROL
Definition: nt_native.h:58
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR sd[]
Definition: suminfo.c:287
unsigned char UCHAR
Definition: xmlstorage.h:181
LIST_ENTRY listentry
Definition: btrfs_drv.h:884
UCHAR AceType
Definition: ms-dtyp.idl:210
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
NTSYSAPI NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR, PSID, BOOLEAN)
SECURITY_SUBJECT_CONTEXT SubjectSecurityContext
Definition: setypes.h:206
USHORT Sbz2
Definition: ms-dtyp.idl:298
fcb * fcb
Definition: btrfs_drv.h:342
Definition: typedefs.h:117
INODE_ITEM inode_item
Definition: btrfs_drv.h:288
DRIVER_DISPATCH(nfs41_FsdDispatch)
BYTE uint8_t
Definition: msvideo1.c:66
void fcb_get_sd(fcb *fcb, struct _fcb *parent, bool look_for_xattr, PIRP Irp)
Definition: security.c:511
Status
Definition: gdiplustypes.h:24
#define FILE_GENERIC_WRITE
Definition: nt_native.h:660
UCHAR Sbz1
Definition: ms-dtyp.idl:295
short sh
Definition: format.c:272
#define ERR(fmt,...)
Definition: debug.h:109
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
UCHAR AclRevision
Definition: ms-dtyp.idl:294
uint32_t gid
Definition: btrfs_drv.h:886
UINT64 uint64_t
Definition: types.h:77
static sid_header sid_BU
Definition: security.c:32
#define uint8_t
Definition: nsiface.idl:59
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
ACCESS_MASK Mask
Definition: ms-dtyp.idl:217
NTSTATUS NTAPI SeQueryInformationToken(IN PACCESS_TOKEN AccessToken, IN TOKEN_INFORMATION_CLASS TokenInformationClass, OUT PVOID *TokenInformation)
Definition: token.c:1309
NTSTATUS uid_to_sid(uint32_t uid, PSID *sid)
Definition: security.c:229
LIST_ENTRY gid_map_list
Definition: btrfs.c:72
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
#define FILE_NOTIFY_CHANGE_SECURITY
uint64_t transid
Definition: btrfs.h:271
LIST_ENTRY listentry
Definition: btrfs_drv.h:878
#define OWNER_SECURITY_INFORMATION
Definition: setypes.h:123
struct _root * subvol
Definition: btrfs_drv.h:284
uint32_t uid
Definition: btrfs_drv.h:880
UINT32 uint32_t
Definition: types.h:75
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
NTSYSAPI NTSTATUS NTAPI RtlGetOwnerSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, OUT PSID *Owner, OUT PBOOLEAN OwnerDefaulted)
Definition: sd.c:257
#define ACL_REVISION
Definition: setypes.h:39
void add_user_mapping(WCHAR *sidstring, ULONG sidstringlength, uint32_t uid)
Definition: security.c:56
bool ads
Definition: btrfs_drv.h:326
static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME *out)
Definition: btrfs_drv.h:964
ULONG ERESOURCE
Definition: env_spec_w32.h:594
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
NTSTATUS fcb_get_new_sd(fcb *fcb, file_ref *parfileref, ACCESS_STATE *as)
Definition: security.c:907
NTKERNELAPI NTSTATUS NTAPI SeQuerySecurityDescriptorInfo(_In_ PSECURITY_INFORMATION SecurityInformation, _Out_writes_bytes_(*Length) PSECURITY_DESCRIPTOR SecurityDescriptor, _Inout_ PULONG Length, _Inout_ PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor)
#define INHERIT_ONLY_ACE
Definition: setypes.h:717
#define SEF_SACL_AUTO_INHERIT
Definition: security.c:21
static NTSTATUS get_file_security(PFILE_OBJECT FileObject, SECURITY_DESCRIPTOR *relsd, ULONG *buflen, SECURITY_INFORMATION flags)
Definition: security.c:555
file_ref * fileref
Definition: btrfs_drv.h:384
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
#define uint32_t
Definition: nsiface.idl:61
uint32_t st_uid
Definition: btrfs.h:276
return STATUS_SUCCESS
Definition: btrfs.c:2938
bool inode_item_changed
Definition: btrfs_drv.h:302
void find_gid(struct _fcb *fcb, struct _fcb *parfcb, PSECURITY_SUBJECT_CONTEXT subjcont)
Definition: security.c:843
#define OBJECT_INHERIT_ACE
Definition: setypes.h:714
ULONG ACCESS_MASK
Definition: nt_native.h:40
struct _device_extension * Vcb
Definition: btrfs_drv.h:283
#define DACL_SECURITY_INFORMATION
Definition: setypes.h:125
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
uint32_t sid_to_uid(PSID sid)
Definition: security.c:310
#define UID_NOBODY
Definition: btrfs_drv.h:94
UCHAR flags
Definition: security.c:36
NTSYSAPI BOOLEAN NTAPI RtlEqualSid(_In_ PSID Sid1, _In_ PSID Sid2)
#define _Function_class_(x)
Definition: no_sal2.h:202
#define DELETE
Definition: nt_native.h:57
uint32_t st_mode
Definition: btrfs.h:278