http://linux-ntfs.sourceforge.net/snapshots/ntfsprogs-200309071734.tar.bz2
[ntfsprogs.git] / ntfsprogs / sd.c
1 #include "types.h"
2 #include "layout.h"
3
4 /**
5  * init_system_file_sd
6  *
7  * NTFS 1.2 - System files security decriptors
8  * ===========================================
9  *
10  * Create the security descriptor for system file number @sys_file_no and
11  * return a pointer to the descriptor.
12  *
13  * $MFT, $MFTMirr, $LogFile, $AttrDef, $Bitmap, $Boot, $BadClus, and $UpCase
14  * are the same.
15  *
16  * $Volume, $Quota, and system files 0xb-0xf are the same. They are almost the
17  * same as the above, the only difference being that the two SIDs present in
18  * the DACL grant GENERIC_WRITE and GENERIC_READ equivalent priviledges while
19  * the above only grant GENERIC_READ equivalent priviledges. (For some reason
20  * the flags for GENERIC_READ/GENERIC_WRITE are not set by NT4, even though
21  * the permissions are equivalent, so we comply.
22  *
23  * Root directory system file (".") is different altogether.
24  *
25  * The sd is recturned in *@sd_val and has length *@sd_val_len.
26  *
27  * Do NOT free *@sd_val as it is static memory. This also means that you can
28  * only use *@sd_val until the next call to this function.
29  */
30 void init_system_file_sd(int sys_file_no, char **sd_val, int *sd_val_len)
31 {
32         static char sd_array[0x68];
33         SECURITY_DESCRIPTOR_RELATIVE *sd;
34         ACL *acl;
35         ACCESS_ALLOWED_ACE *aa_ace;
36         SID *sid;
37
38         if (sys_file_no < 0 || sys_file_no > 0xf) {
39                 *sd_val = NULL;
40                 *sd_val_len = 0;
41                 return;
42         }
43         *sd_val = (char*)&sd_array;
44         sd = (SECURITY_DESCRIPTOR_RELATIVE*)&sd_array;
45         sd->revision = 1;
46         sd->alignment = 0;
47         sd->control = SE_SELF_RELATIVE | SE_DACL_PRESENT;
48         if (sys_file_no == FILE_root) {
49                 *sd_val_len = 0x50;
50                 sd->owner = cpu_to_le32(0x30);
51                 sd->group = cpu_to_le32(0x40);
52         } else {
53                 *sd_val_len = 0x68;
54                 sd->owner = cpu_to_le32(0x48);
55                 sd->group = cpu_to_le32(0x58);
56         }
57         sd->sacl = cpu_to_le32(0);
58         sd->dacl = cpu_to_le32(0x14);
59         /*
60          * Now at offset 0x14, as specified in the security descriptor, we have
61          * the DACL.
62          */
63         acl = (ACL*)((char*)sd + le32_to_cpu(sd->dacl));
64         acl->revision = 2;
65         acl->alignment1 = 0;
66         if (sys_file_no == FILE_root) {
67                 acl->size = cpu_to_le16(0x1c);
68                 acl->ace_count = cpu_to_le16(1);
69         } else {
70                 acl->size = cpu_to_le16(0x34);
71                 acl->ace_count = cpu_to_le16(2);
72         }
73         acl->alignment2 = cpu_to_le16(0);
74         /*
75          * Now at offset 0x1c, just after the DACL's ACL, we have the first
76          * ACE of the DACL. The type of the ACE is access allowed.
77          */
78         aa_ace = (ACCESS_ALLOWED_ACE*)((char*)acl + sizeof(ACL));
79         aa_ace->type = ACCESS_ALLOWED_ACE_TYPE;
80         if (sys_file_no == FILE_root)
81                 aa_ace->flags = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
82         else
83                 aa_ace->flags = 0;
84         aa_ace->size = cpu_to_le16(0x14);
85         switch (sys_file_no) {
86         case FILE_MFT:          case FILE_MFTMirr:      case FILE_LogFile:
87         case FILE_AttrDef:      case FILE_Bitmap:       case FILE_Boot:
88         case FILE_BadClus:      case FILE_UpCase:
89                 aa_ace->mask = SYNCHRONIZE | STANDARD_RIGHTS_READ |
90                         FILE_READ_ATTRIBUTES | FILE_READ_EA | FILE_READ_DATA;
91                 break;
92         case FILE_Volume:       case FILE_Secure:       case 0xb ... 0xf:
93                 aa_ace->mask = SYNCHRONIZE | STANDARD_RIGHTS_WRITE |
94                         FILE_WRITE_ATTRIBUTES | FILE_READ_ATTRIBUTES |
95                         FILE_WRITE_EA | FILE_READ_EA | FILE_APPEND_DATA |
96                         FILE_WRITE_DATA | FILE_READ_DATA;
97                 break;
98         case FILE_root:
99                 aa_ace->mask = STANDARD_RIGHTS_ALL | FILE_WRITE_ATTRIBUTES |
100                         FILE_READ_ATTRIBUTES | FILE_DELETE_CHILD |
101                         FILE_TRAVERSE | FILE_WRITE_EA | FILE_READ_EA |
102                         FILE_ADD_SUBDIRECTORY | FILE_ADD_FILE |
103                         FILE_LIST_DIRECTORY;
104                 break;
105         }
106         aa_ace->sid.revision = 1;
107         aa_ace->sid.sub_authority_count = 1;
108         aa_ace->sid.identifier_authority.value[0] = 0;
109         aa_ace->sid.identifier_authority.value[1] = 0;
110         aa_ace->sid.identifier_authority.value[2] = 0;
111         aa_ace->sid.identifier_authority.value[3] = 0;
112         aa_ace->sid.identifier_authority.value[4] = 0;
113         if (sys_file_no == FILE_root) {
114                 /* SECURITY_WORLD_SID_AUTHORITY (S-1-1) */
115                 aa_ace->sid.identifier_authority.value[5] = 1;
116                 aa_ace->sid.sub_authority[0] =
117                                 cpu_to_le32(SECURITY_WORLD_RID);
118                 /* This is S-1-1-0, the WORLD_SID. */
119         } else {
120                 /* SECURITY_NT_SID_AUTHORITY (S-1-5) */
121                 aa_ace->sid.identifier_authority.value[5] = 5;
122                 aa_ace->sid.sub_authority[0] =
123                                 cpu_to_le32(SECURITY_LOCAL_SYSTEM_RID);
124         }
125         /*
126          * Now at offset 0x30 within security descriptor, just after the first
127          * ACE of the DACL. All system files, except the root directory, have
128          * a second ACE.
129          */
130         if (sys_file_no != FILE_root) {
131                 /* The second ACE of the DACL. Type is access allowed. */
132                 aa_ace = (ACCESS_ALLOWED_ACE*)((char*)aa_ace +
133                                 le16_to_cpu(aa_ace->size));
134                 aa_ace->type = ACCESS_ALLOWED_ACE_TYPE;
135                 aa_ace->flags = 0;
136                 aa_ace->size = cpu_to_le16(0x18);
137                 switch (sys_file_no) {
138                 case FILE_MFT:          case FILE_MFTMirr:
139                 case FILE_LogFile:      case FILE_AttrDef:
140                 case FILE_Bitmap:       case FILE_Boot:
141                 case FILE_BadClus:      case FILE_UpCase:
142                         aa_ace->mask = SYNCHRONIZE | STANDARD_RIGHTS_READ |
143                                         FILE_READ_ATTRIBUTES | FILE_READ_EA |
144                                         FILE_READ_DATA;
145                         break;
146                 case FILE_Volume:       case FILE_Secure:
147                 case 0xb ... 0xf:
148                         aa_ace->mask = SYNCHRONIZE | STANDARD_RIGHTS_READ |
149                                         FILE_WRITE_ATTRIBUTES |
150                                         FILE_READ_ATTRIBUTES | FILE_WRITE_EA |
151                                         FILE_READ_EA | FILE_APPEND_DATA |
152                                         FILE_WRITE_DATA | FILE_READ_DATA;
153                         break;
154                 }
155                 aa_ace->sid.revision = 1;
156                 aa_ace->sid.sub_authority_count = 2;
157                 /* SECURITY_NT_SID_AUTHORITY (S-1-5) */
158                 aa_ace->sid.identifier_authority.value[0] = 0;
159                 aa_ace->sid.identifier_authority.value[1] = 0;
160                 aa_ace->sid.identifier_authority.value[2] = 0;
161                 aa_ace->sid.identifier_authority.value[3] = 0;
162                 aa_ace->sid.identifier_authority.value[4] = 0;
163                 aa_ace->sid.identifier_authority.value[5] = 5;
164                 aa_ace->sid.sub_authority[0] =
165                                 cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
166                 aa_ace->sid.sub_authority[1] =
167                                 cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
168                 /* Now at offset 0x48 into the security descriptor. */
169         }
170         /* As specified in the security descriptor, we now have the owner SID.*/
171         sid = (SID*)((char*)sd + le32_to_cpu(sd->owner));
172         sid->revision = 1;
173         sid->sub_authority_count = 2;
174         /* SECURITY_NT_SID_AUTHORITY (S-1-5) */
175         sid->identifier_authority.value[0] = 0;
176         sid->identifier_authority.value[1] = 0;
177         sid->identifier_authority.value[2] = 0;
178         sid->identifier_authority.value[3] = 0;
179         sid->identifier_authority.value[4] = 0;
180         sid->identifier_authority.value[5] = 5;
181         sid->sub_authority[0] = cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
182         sid->sub_authority[1] = cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
183         /*
184          * Now at offset 0x40 or 0x58 (root directory and the other system
185          * files, respectively) into the security descriptor, as specified in
186          * the security descriptor, we have the group SID.
187          */
188         sid = (SID*)((char*)sd + le32_to_cpu(sd->group));
189         sid->revision = 1;
190         sid->sub_authority_count = 2;
191         /* SECURITY_NT_SID_AUTHORITY (S-1-5) */
192         sid->identifier_authority.value[0] = 0;
193         sid->identifier_authority.value[1] = 0;
194         sid->identifier_authority.value[2] = 0;
195         sid->identifier_authority.value[3] = 0;
196         sid->identifier_authority.value[4] = 0;
197         sid->identifier_authority.value[5] = 5;
198         sid->sub_authority[0] = cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
199         sid->sub_authority[1] = cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
200 }
201