ReactOS  0.4.14-dev-49-gfb4591c
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  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");
446  goto end;
447  }
448 
449  RtlSetGroupSecurityDescriptor(&sd, groupsid, false);
450 
451  if (!NT_SUCCESS(Status)) {
452  ERR("RtlSetGroupSecurityDescriptor returned %08x\n", Status);
453  goto end;
454  }
455 
456  acl = load_default_acl();
457 
458  if (!acl) {
459  ERR("out of memory\n");
460  goto end;
461  }
462 
463  Status = RtlSetDaclSecurityDescriptor(&sd, true, acl, false);
464 
465  if (!NT_SUCCESS(Status)) {
466  ERR("RtlSetDaclSecurityDescriptor returned %08x\n", Status);
467  goto end;
468  }
469 
470  // FIXME - SACL_SECURITY_INFORMATION
471 
472  buflen = 0;
473 
474  // get sd size
477  ERR("RtlAbsoluteToSelfRelativeSD 1 returned %08x\n", Status);
478  goto end;
479  }
480 
481  if (buflen == 0 || Status == STATUS_SUCCESS) {
482  TRACE("RtlAbsoluteToSelfRelativeSD said SD is zero-length\n");
483  goto end;
484  }
485 
487  if (!fcb->sd) {
488  ERR("out of memory\n");
490  goto end;
491  }
492 
493  Status = RtlAbsoluteToSelfRelativeSD(&sd, fcb->sd, &buflen);
494 
495  if (!NT_SUCCESS(Status)) {
496  ERR("RtlAbsoluteToSelfRelativeSD 2 returned %08x\n", Status);
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  }
532 
533  Status = uid_to_sid(fcb->inode_item.st_uid, &usersid);
534  if (!NT_SUCCESS(Status)) {
535  ERR("uid_to_sid returned %08x\n", Status);
536  return;
537  }
538 
539  RtlSetOwnerSecurityDescriptor(&fcb->sd, usersid, false);
540 
541  gid_to_sid(fcb->inode_item.st_gid, &groupsid);
542  if (!groupsid) {
543  ERR("out of memory\n");
544  return;
545  }
546 
547  RtlSetGroupSecurityDescriptor(&fcb->sd, groupsid, false);
548 
549  ExFreePool(usersid);
550  ExFreePool(groupsid);
551 }
552 
555  fcb* fcb = FileObject->FsContext;
556  ccb* ccb = FileObject->FsContext2;
557  file_ref* fileref = ccb ? ccb->fileref : NULL;
558 
559  if (fcb->ads) {
560  if (fileref && fileref->parent)
561  fcb = fileref->parent->fcb;
562  else {
563  ERR("could not get parent fcb for stream\n");
564  return STATUS_INTERNAL_ERROR;
565  }
566  }
567 
568  // Why (void**)? Is this a bug in mingw?
569  Status = SeQuerySecurityDescriptorInfo(&flags, relsd, buflen, (void**)&fcb->sd);
570 
572  TRACE("SeQuerySecurityDescriptorInfo returned %08x\n", Status);
573  else if (!NT_SUCCESS(Status))
574  ERR("SeQuerySecurityDescriptorInfo returned %08x\n", Status);
575 
576  return Status;
577 }
578 
581 NTSTATUS __stdcall drv_query_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
586  ULONG buflen;
587  bool top_level;
589  ccb* ccb = FileObject ? FileObject->FsContext2 : NULL;
590 
592 
593  TRACE("query security\n");
594 
595  top_level = is_top_level(Irp);
596 
597  if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
599  goto end;
600  } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
602  goto end;
603  }
604 
605  if (!ccb) {
606  ERR("no ccb\n");
608  goto end;
609  }
610 
611  if (Irp->RequestorMode == UserMode && !(ccb->access & READ_CONTROL)) {
612  WARN("insufficient permissions\n");
614  goto end;
615  }
616 
618 
619  Irp->IoStatus.Information = 0;
620 
621  if (IrpSp->Parameters.QuerySecurity.SecurityInformation & OWNER_SECURITY_INFORMATION)
622  TRACE("OWNER_SECURITY_INFORMATION\n");
623 
624  if (IrpSp->Parameters.QuerySecurity.SecurityInformation & GROUP_SECURITY_INFORMATION)
625  TRACE("GROUP_SECURITY_INFORMATION\n");
626 
627  if (IrpSp->Parameters.QuerySecurity.SecurityInformation & DACL_SECURITY_INFORMATION)
628  TRACE("DACL_SECURITY_INFORMATION\n");
629 
630  if (IrpSp->Parameters.QuerySecurity.SecurityInformation & SACL_SECURITY_INFORMATION)
631  TRACE("SACL_SECURITY_INFORMATION\n");
632 
633  TRACE("length = %u\n", IrpSp->Parameters.QuerySecurity.Length);
634 
636  TRACE("sd = %p\n", sd);
637 
638  if (Irp->MdlAddress && !sd) {
639  ERR("MmGetSystemAddressForMdlSafe returned NULL\n");
641  goto end;
642  }
643 
644  buflen = IrpSp->Parameters.QuerySecurity.Length;
645 
646  Status = get_file_security(IrpSp->FileObject, sd, &buflen, IrpSp->Parameters.QuerySecurity.SecurityInformation);
647 
648  if (NT_SUCCESS(Status))
649  Irp->IoStatus.Information = IrpSp->Parameters.QuerySecurity.Length;
650  else if (Status == STATUS_BUFFER_TOO_SMALL) {
651  Irp->IoStatus.Information = buflen;
653  } else
654  Irp->IoStatus.Information = 0;
655 
656 end:
657  TRACE("Irp->IoStatus.Information = %u\n", Irp->IoStatus.Information);
658 
659  Irp->IoStatus.Status = Status;
660 
662 
663  if (top_level)
665 
666  TRACE("returning %08x\n", Status);
667 
669 
670  return Status;
671 }
672 
675  fcb* fcb = FileObject->FsContext;
676  ccb* ccb = FileObject->FsContext2;
677  file_ref* fileref = ccb ? ccb->fileref : NULL;
678  SECURITY_DESCRIPTOR* oldsd;
680  BTRFS_TIME now;
681 
682  TRACE("(%p, %p, %p, %x)\n", Vcb, FileObject, sd, *flags);
683 
684  if (Vcb->readonly)
686 
687  if (fcb->ads) {
688  if (fileref && fileref->parent)
689  fcb = fileref->parent->fcb;
690  else {
691  ERR("could not find parent fcb for stream\n");
692  return STATUS_INTERNAL_ERROR;
693  }
694  }
695 
696  if (!fcb || !ccb)
698 
699  ExAcquireResourceExclusiveLite(fcb->Header.Resource, true);
700 
701  if (is_subvol_readonly(fcb->subvol, Irp)) {
703  goto end;
704  }
705 
706  oldsd = fcb->sd;
707 
709 
710  if (!NT_SUCCESS(Status)) {
711  ERR("SeSetSecurityDescriptorInfo returned %08x\n", Status);
712  goto end;
713  }
714 
715  ExFreePool(oldsd);
716 
719 
720  fcb->inode_item.transid = Vcb->superblock.generation;
721 
724 
726 
727  fcb->sd_dirty = true;
728  fcb->sd_deleted = false;
729  fcb->inode_item_changed = true;
730 
731  fcb->subvol->root_item.ctransid = Vcb->superblock.generation;
732  fcb->subvol->root_item.ctime = now;
733 
735 
737 
738 end:
739  ExReleaseResourceLite(fcb->Header.Resource);
740 
741  return Status;
742 }
743 
750  ccb* ccb = FileObject ? FileObject->FsContext2 : NULL;
752  ULONG access_req = 0;
753  bool top_level;
754 
756 
757  TRACE("set security\n");
758 
759  top_level = is_top_level(Irp);
760 
761  if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
763  goto end;
764  } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
766  goto end;
767  }
768 
769  if (!ccb) {
770  ERR("no ccb\n");
772  goto end;
773  }
774 
776 
777  Irp->IoStatus.Information = 0;
778 
779  if (IrpSp->Parameters.SetSecurity.SecurityInformation & OWNER_SECURITY_INFORMATION) {
780  TRACE("OWNER_SECURITY_INFORMATION\n");
781  access_req |= WRITE_OWNER;
782  }
783 
784  if (IrpSp->Parameters.SetSecurity.SecurityInformation & GROUP_SECURITY_INFORMATION) {
785  TRACE("GROUP_SECURITY_INFORMATION\n");
786  access_req |= WRITE_OWNER;
787  }
788 
789  if (IrpSp->Parameters.SetSecurity.SecurityInformation & DACL_SECURITY_INFORMATION) {
790  TRACE("DACL_SECURITY_INFORMATION\n");
791  access_req |= WRITE_DAC;
792  }
793 
794  if (IrpSp->Parameters.SetSecurity.SecurityInformation & SACL_SECURITY_INFORMATION) {
795  TRACE("SACL_SECURITY_INFORMATION\n");
796  access_req |= ACCESS_SYSTEM_SECURITY;
797  }
798 
799  if (Irp->RequestorMode == UserMode && (ccb->access & access_req) != access_req) {
801  WARN("insufficient privileges\n");
802  goto end;
803  }
804 
805  Status = set_file_security(DeviceObject->DeviceExtension, FileObject, IrpSp->Parameters.SetSecurity.SecurityDescriptor,
806  &IrpSp->Parameters.SetSecurity.SecurityInformation, Irp);
807 
808 end:
809  Irp->IoStatus.Status = Status;
810 
812 
813  TRACE("returning %08x\n", Status);
814 
815  if (top_level)
817 
819 
820  return Status;
821 }
822 
823 static bool search_for_gid(fcb* fcb, PSID sid) {
824  LIST_ENTRY* le;
825 
826  le = gid_map_list.Flink;
827  while (le != &gid_map_list) {
828  gid_map* gm = CONTAINING_RECORD(le, gid_map, listentry);
829 
830  if (RtlEqualSid(sid, gm->sid)) {
831  fcb->inode_item.st_gid = gm->gid;
832  return true;
833  }
834 
835  le = le->Flink;
836  }
837 
838  return false;
839 }
840 
841 void find_gid(struct _fcb* fcb, struct _fcb* parfcb, PSECURITY_SUBJECT_CONTEXT subjcont) {
843  TOKEN_OWNER* to;
844  TOKEN_PRIMARY_GROUP* tpg;
845  TOKEN_GROUPS* tg;
846 
847  if (parfcb && parfcb->inode_item.st_mode & S_ISGID) {
849  return;
850  }
851 
853 
854  if (!subjcont || !subjcont->PrimaryToken || IsListEmpty(&gid_map_list)) {
856  return;
857  }
858 
859  Status = SeQueryInformationToken(subjcont->PrimaryToken, TokenOwner, (void**)&to);
860  if (!NT_SUCCESS(Status))
861  ERR("SeQueryInformationToken returned %08x\n", Status);
862  else {
863  if (search_for_gid(fcb, to->Owner)) {
865  ExFreePool(to);
866  return;
867  }
868 
869  ExFreePool(to);
870  }
871 
872  Status = SeQueryInformationToken(subjcont->PrimaryToken, TokenPrimaryGroup, (void**)&tpg);
873  if (!NT_SUCCESS(Status))
874  ERR("SeQueryInformationToken returned %08x\n", Status);
875  else {
876  if (search_for_gid(fcb, tpg->PrimaryGroup)) {
878  ExFreePool(tpg);
879  return;
880  }
881 
882  ExFreePool(tpg);
883  }
884 
885  Status = SeQueryInformationToken(subjcont->PrimaryToken, TokenGroups, (void**)&tg);
886  if (!NT_SUCCESS(Status))
887  ERR("SeQueryInformationToken returned %08x\n", Status);
888  else {
889  ULONG i;
890 
891  for (i = 0; i < tg->GroupCount; i++) {
892  if (search_for_gid(fcb, tg->Groups[i].Sid)) {
894  ExFreePool(tg);
895  return;
896  }
897  }
898 
899  ExFreePool(tg);
900  }
901 
903 }
904 
907  PSID owner;
908  BOOLEAN defaulted;
909 
910  Status = SeAssignSecurityEx(parfileref ? parfileref->fcb->sd : NULL, as->SecurityDescriptor, (void**)&fcb->sd, NULL, fcb->type == BTRFS_TYPE_DIRECTORY,
912 
913  if (!NT_SUCCESS(Status)) {
914  ERR("SeAssignSecurityEx returned %08x\n", Status);
915  return Status;
916  }
917 
918  Status = RtlGetOwnerSecurityDescriptor(fcb->sd, &owner, &defaulted);
919  if (!NT_SUCCESS(Status)) {
920  ERR("RtlGetOwnerSecurityDescriptor returned %08x\n", Status);
922  } else {
923  fcb->inode_item.st_uid = sid_to_uid(owner);
924  }
925 
926  find_gid(fcb, parfileref ? parfileref->fcb : NULL, &as->SubjectSecurityContext);
927 
928  return STATUS_SUCCESS;
929 }
#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:346
#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:875
NTSTATUS vol_query_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:869
_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:310
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:657
#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:377
#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:272
PSID sid
Definition: btrfs_drv.h:875
BTRFS_TIME st_ctime
Definition: btrfs.h:283
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:579
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
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
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:276
SECURITY_DESCRIPTOR * sd
Definition: btrfs_drv.h:282
PSID sid
Definition: btrfs_drv.h:869
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:997
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:673
uint64_t sequence
Definition: btrfs.h:280
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:823
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:81
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:1664
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:280
_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:103
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:272
#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:310
r parent
Definition: btrfs.c:2897
__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:659
uint64_t inode
Definition: btrfs_drv.h:278
Definition: security.c:35
bool user_set_change_time
Definition: btrfs_drv.h:385
#define Vcb
Definition: cdprocs.h:1425
static __inline void * map_user_buffer(PIRP Irp, ULONG priority)
Definition: btrfs_drv.h:941
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:874
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:335
Definition: typedefs.h:117
INODE_ITEM inode_item
Definition: btrfs_drv.h:281
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:876
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:61
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:270
LIST_ENTRY listentry
Definition: btrfs_drv.h:868
#define OWNER_SECURITY_INFORMATION
Definition: setypes.h:123
struct _root * subvol
Definition: btrfs_drv.h:277
uint32_t uid
Definition: btrfs_drv.h:870
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:319
static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME *out)
Definition: btrfs_drv.h:953
ULONG ERESOURCE
Definition: env_spec_w32.h:594
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
void send_notification_fcb(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1583
NTSTATUS fcb_get_new_sd(fcb *fcb, file_ref *parfileref, ACCESS_STATE *as)
Definition: security.c:905
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:553
file_ref * fileref
Definition: btrfs_drv.h:378
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
#define uint32_t
Definition: nsiface.idl:61
uint32_t st_uid
Definition: btrfs.h:275
return STATUS_SUCCESS
Definition: btrfs.c:2966
bool inode_item_changed
Definition: btrfs_drv.h:296
void find_gid(struct _fcb *fcb, struct _fcb *parfcb, PSECURITY_SUBJECT_CONTEXT subjcont)
Definition: security.c:841
#define OBJECT_INHERIT_ACE
Definition: setypes.h:714
ULONG ACCESS_MASK
Definition: nt_native.h:40
struct _device_extension * Vcb
Definition: btrfs_drv.h:276
#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:277