ReactOS  0.4.12-dev-18-gf469aca
acl.c
Go to the documentation of this file.
1 /* NFSv4.1 client for Windows
2  * Copyright 2012 The Regents of the University of Michigan
3  *
4  * Olga Kornievskaia <aglo@umich.edu>
5  * Casey Bodley <cbodley@umich.edu>
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by
9  * the Free Software Foundation; either version 2.1 of the License, or (at
10  * your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful, but
13  * without any warranty; without even the implied warranty of merchantability
14  * or fitness for a particular purpose. See the GNU Lesser General Public
15  * License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  */
21 
22 #include <windows.h>
23 #include <strsafe.h>
24 #include <sddl.h>
25 
26 #include "nfs41_ops.h"
27 #include "delegation.h"
28 #include "daemon_debug.h"
29 #include "util.h"
30 #include "upcall.h"
31 #include "nfs41_xdr.h"
32 
33 //#define DEBUG_ACLS
34 #define ACLLVL 2 /* dprintf level for acl logging */
35 
37 
38 static int parse_getacl(unsigned char *buffer, uint32_t length,
40 {
41  int status;
42  getacl_upcall_args *args = &upcall->args.getacl;
43 
44  status = safe_read(&buffer, &length, &args->query, sizeof(args->query));
45  if (status) goto out;
46 
47  dprintf(1, "parsing NFS41_ACL_QUERY: info_class=%d\n", args->query);
48 out:
49  return status;
50 }
51 
53  DWORD *sid_len)
54 {
55  int status;
56  *sid_len = 0;
57  *sid = NULL;
58 
59  status = CreateWellKnownSid(type, NULL, *sid, sid_len);
60  dprintf(ACLLVL, "create_unknownsid: CreateWellKnownSid type %d returned %d "
61  "GetLastError %d sid len %d needed\n", type, status,
62  GetLastError(), *sid_len);
63  if (status)
64  return ERROR_INTERNAL_ERROR;
65  status = GetLastError();
66  if (status != ERROR_INSUFFICIENT_BUFFER)
67  return status;
68  *sid = malloc(*sid_len);
69  if (*sid == NULL)
71  status = CreateWellKnownSid(type, NULL, *sid, sid_len);
72  if (status)
73  return ERROR_SUCCESS;
74  free(*sid);
75  status = GetLastError();
76  eprintf("create_unknownsid: CreateWellKnownSid failed with %d\n", status);
77  return status;
78 }
79 
80 static void convert_nfs4name_2_user_domain(LPSTR nfs4name,
81  LPSTR *domain)
82 {
83  LPSTR p = nfs4name;
84  for(; p[0] != '\0'; p++) {
85  if (p[0] == '@') {
86  p[0] = '\0';
87  *domain = &p[1];
88  break;
89  }
90  }
91 }
92 
93 static int map_name_2_sid(DWORD *sid_len, PSID *sid, LPCSTR name)
94 {
96  SID_NAME_USE sid_type;
97  LPSTR tmp_buf = NULL;
98  DWORD tmp = 0;
99 
100  status = LookupAccountName(NULL, name, NULL, sid_len, NULL, &tmp, &sid_type);
101  dprintf(ACLLVL, "map_name_2_sid: LookupAccountName for %s returned %d "
102  "GetLastError %d name len %d domain len %d\n", name, status,
103  GetLastError(), *sid_len, tmp);
104  if (status)
105  return ERROR_INTERNAL_ERROR;
106 
107  status = GetLastError();
108  switch(status) {
110  *sid = malloc(*sid_len);
111  if (*sid == NULL) {
112  status = GetLastError();
113  goto out;
114  }
115  tmp_buf = (LPSTR) malloc(tmp);
116  if (tmp_buf == NULL)
117  goto out_free_sid;
118  status = LookupAccountName(NULL, name, *sid, sid_len, tmp_buf,
119  &tmp, &sid_type);
120  free(tmp_buf);
121  if (!status) {
122  eprintf("map_name_2_sid: LookupAccountName for %s failed "
123  "with %d\n", name, GetLastError());
124  goto out_free_sid;
125  } else {
126 #ifdef DEBUG_ACLS
127  LPSTR ssid = NULL;
128  if (IsValidSid(*sid))
129  if (ConvertSidToStringSidA(*sid, &ssid))
130  dprintf(1, "map_name_2_sid: sid_type = %d SID %s\n",
131  sid_type, ssid);
132  else
133  dprintf(1, "map_name_2_sid: ConvertSidToStringSidA failed "
134  "with %d\n", GetLastError());
135  else
136  dprintf(1, "map_name_2_sid: Invalid Sid ?\n");
137  if (ssid) LocalFree(ssid);
138 #endif
139  }
140  status = ERROR_SUCCESS;
141  break;
142  case ERROR_NONE_MAPPED:
143  status = create_unknownsid(WinNullSid, sid, sid_len);
144  if (status)
145  goto out_free_sid;
146  }
147 out:
148  return status;
149 out_free_sid:
150  status = GetLastError();
151  free(*sid);
152  goto out;
153 }
154 
155 static void free_sids(PSID *sids, int count)
156 {
157  int i;
158  for(i = 0; i < count; i++)
159  free(sids[i]);
160  free(sids);
161 }
162 
163 static int check_4_special_identifiers(char *who, PSID *sid, DWORD *sid_len,
164  BOOLEAN *flag)
165 {
166  int status = ERROR_SUCCESS;
168  *flag = TRUE;
169  if (!strncmp(who, ACE4_OWNER, strlen(ACE4_OWNER)-1))
170  type = WinCreatorOwnerSid;
171  else if (!strncmp(who, ACE4_GROUP, strlen(ACE4_GROUP)-1))
172  type = WinCreatorGroupSid;
173  else if (!strncmp(who, ACE4_EVERYONE, strlen(ACE4_EVERYONE)-1))
174  type = WinWorldSid;
175  else if (!strncmp(who, ACE4_NOBODY, strlen(ACE4_NOBODY)))
176  type = WinNullSid;
177  else
178  *flag = FALSE;
179  if (*flag)
180  status = create_unknownsid(type, sid, sid_len);
181  return status;
182 }
183 
185  PACL *dacl_out, PSID **sids_out)
186 {
187  int status = ERROR_NOT_SUPPORTED, size = 0;
188  uint32_t i;
189  DWORD sid_len;
190  PSID *sids;
191  PACL dacl;
192  LPSTR domain = NULL;
193  BOOLEAN flag;
194 
195  sids = malloc(acl->count * sizeof(PSID));
196  if (sids == NULL) {
197  status = GetLastError();
198  goto out;
199  }
200  for (i = 0; i < acl->count; i++) {
201  convert_nfs4name_2_user_domain(acl->aces[i].who, &domain);
202  dprintf(ACLLVL, "handle_getacl: for user=%s domain=%s\n",
203  acl->aces[i].who, domain?domain:"<null>");
204  status = check_4_special_identifiers(acl->aces[i].who, &sids[i],
205  &sid_len, &flag);
206  if (status) {
207  free_sids(sids, i);
208  goto out;
209  }
210  if (!flag) {
211  status = map_name_2_sid(&sid_len, &sids[i], acl->aces[i].who);
212  if (status) {
213  free_sids(sids, i);
214  goto out;
215  }
216  }
217  size += sid_len - sizeof(DWORD);
218  }
219  size += sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE)*acl->count);
220  size = (size + sizeof(DWORD) - 1) & 0xfffffffc; //align size on word boundry
221  dacl = malloc(size);
222  if (dacl == NULL)
223  goto out_free_sids;
224 
225  if (InitializeAcl(dacl, size, ACL_REVISION)) {
227  for (i = 0; i < acl->count; i++) {
228  // nfs4 acemask should be exactly the same as file access mask
229  mask = acl->aces[i].acemask;
230  dprintf(ACLLVL, "access mask %x ace type %s\n", mask,
231  acl->aces[i].acetype?"DENIED ACE":"ALLOWED ACE");
232  if (acl->aces[i].acetype == ACE4_ACCESS_ALLOWED_ACE_TYPE) {
233  status = AddAccessAllowedAce(dacl, ACL_REVISION, mask, sids[i]);
234  if (!status) {
235  eprintf("convert_nfs4acl_2_dacl: AddAccessAllowedAce failed "
236  "with %d\n", status);
237  goto out_free_dacl;
238  }
239  else status = ERROR_SUCCESS;
240  } else if (acl->aces[i].acetype == ACE4_ACCESS_DENIED_ACE_TYPE) {
241  status = AddAccessDeniedAce(dacl, ACL_REVISION, mask, sids[i]);
242  if (!status) {
243  eprintf("convert_nfs4acl_2_dacl: AddAccessDeniedAce failed "
244  "with %d\n", status);
245  goto out_free_dacl;
246  }
247  else status = ERROR_SUCCESS;
248  } else {
249  eprintf("convert_nfs4acl_2_dacl: unknown acetype %d\n",
250  acl->aces[i].acetype);
251  status = ERROR_INTERNAL_ERROR;
252  free(dacl);
253  free_sids(sids, acl->count);
254  goto out;
255  }
256  }
257  } else {
258  eprintf("convert_nfs4acl_2_dacl: InitializeAcl failed with %d\n", status);
259  goto out_free_dacl;
260  }
261  status = ERROR_SUCCESS;
262  *sids_out = sids;
263  *dacl_out = dacl;
264 out:
265  return status;
266 out_free_dacl:
267  free(dacl);
268 out_free_sids:
269  free_sids(sids, acl->count);
270  status = GetLastError();
271  goto out;
272 }
273 
275 {
277  getacl_upcall_args *args = &upcall->args.getacl;
278  nfs41_open_state *state = upcall->state_ref;
279  nfs41_file_info info = { 0 };
280  bitmap4 attr_request = { 0 };
281  LPSTR domain = NULL;
282  SECURITY_DESCRIPTOR sec_desc;
283  PACL dacl = NULL;
284  PSID *sids = NULL;
285  PSID osid = NULL, gsid = NULL;
286  DWORD sid_len;
288  nfsacl41 acl = { 0 };
289 
290  // need to cache owner/group information XX
291  attr_request.count = 2;
292  attr_request.arr[1] = FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP;
293  if (args->query & DACL_SECURITY_INFORMATION) {
294  info.acl = &acl;
295  attr_request.arr[0] |= FATTR4_WORD0_ACL;
296  }
297  info.owner = owner;
298  info.owner_group = group;
299  status = nfs41_getattr(state->session, &state->file, &attr_request, &info);
300  if (status) {
301  eprintf("handle_getacl: nfs41_cached_getattr() failed with %d\n",
302  status);
303  goto out;
304  }
305 
306  status = InitializeSecurityDescriptor(&sec_desc,
308  if (!status) {
309  status = GetLastError();
310  eprintf("handle_getacl: InitializeSecurityDescriptor failed with %d\n",
311  status);
312  goto out;
313  }
314  /* can't (re)use the same sid variable for both owner and group sids
315  * because security descriptor is created in absolute-form and it just
316  * stores pointers to the sids. thus each owner and group needs its own
317  * memory. free them after creating self-relative security descriptor.
318  */
319  if (args->query & OWNER_SECURITY_INFORMATION) {
320  // parse user@domain. currently ignoring domain part XX
321  convert_nfs4name_2_user_domain(info.owner, &domain);
322  dprintf(ACLLVL, "handle_getacl: OWNER_SECURITY_INFORMATION: for user=%s "
323  "domain=%s\n", info.owner, domain?domain:"<null>");
324  sid_len = 0;
325  status = map_name_2_sid(&sid_len, &osid, info.owner);
326  if (status)
327  goto out;
328  status = SetSecurityDescriptorOwner(&sec_desc, osid, TRUE);
329  if (!status) {
330  status = GetLastError();
331  eprintf("handle_getacl: SetSecurityDescriptorOwner failed with "
332  "%d\n", status);
333  goto out;
334  }
335  }
336  if (args->query & GROUP_SECURITY_INFORMATION) {
338  dprintf(ACLLVL, "handle_getacl: GROUP_SECURITY_INFORMATION: for %s "
339  "domain=%s\n", info.owner_group, domain?domain:"<null>");
340  sid_len = 0;
341  status = map_name_2_sid(&sid_len, &gsid, info.owner_group);
342  if (status)
343  goto out;
344  status = SetSecurityDescriptorGroup(&sec_desc, gsid, TRUE);
345  if (!status) {
346  status = GetLastError();
347  eprintf("handle_getacl: SetSecurityDescriptorGroup failed with "
348  "%d\n", status);
349  goto out;
350  }
351  }
352  if (args->query & DACL_SECURITY_INFORMATION) {
353  dprintf(ACLLVL, "handle_getacl: DACL_SECURITY_INFORMATION\n");
354  status = convert_nfs4acl_2_dacl(info.acl, state->type, &dacl, &sids);
355  if (status)
356  goto out;
357  status = SetSecurityDescriptorDacl(&sec_desc, TRUE, dacl, TRUE);
358  if (!status) {
359  status = GetLastError();
360  eprintf("handle_getacl: SetSecurityDescriptorDacl failed with "
361  "%d\n", status);
362  goto out;
363  }
364  }
365 
366  args->sec_desc_len = 0;
367  status = MakeSelfRelativeSD(&sec_desc, args->sec_desc, &args->sec_desc_len);
368  if (status) {
369  status = ERROR_INTERNAL_ERROR;
370  goto out;
371  }
372  status = GetLastError();
373  if (status != ERROR_INSUFFICIENT_BUFFER) {
374  eprintf("handle_getacl: MakeSelfRelativeSD failes with %d\n", status);
375  goto out;
376  }
377  args->sec_desc = malloc(args->sec_desc_len);
378  if (args->sec_desc == NULL) {
379  status = GetLastError();
380  goto out;
381  }
382  status = MakeSelfRelativeSD(&sec_desc, args->sec_desc, &args->sec_desc_len);
383  if (!status) {
384  status = GetLastError();
385  eprintf("handle_getacl: MakeSelfRelativeSD failes with %d\n", status);
386  free(args->sec_desc);
387  goto out;
388  } else status = ERROR_SUCCESS;
389 
390 out:
391  if (args->query & OWNER_SECURITY_INFORMATION) {
392  if (osid) free(osid);
393  }
394  if (args->query & GROUP_SECURITY_INFORMATION) {
395  if (gsid) free(gsid);
396  }
397  if (args->query & DACL_SECURITY_INFORMATION) {
398  if (sids) free_sids(sids, info.acl->count);
399  free(dacl);
400  nfsacl41_free(info.acl);
401  }
402  return status;
403 }
404 
405 static int marshall_getacl(unsigned char *buffer, uint32_t *length,
407 {
409  getacl_upcall_args *args = &upcall->args.getacl;
410 
411  status = safe_write(&buffer, length, &args->sec_desc_len, sizeof(DWORD));
412  if (status) goto out;
413  status = safe_write(&buffer, length, args->sec_desc, args->sec_desc_len);
414  free(args->sec_desc);
415  if (status) goto out;
416 out:
417  return status;
418 }
419 
421  parse_getacl,
424 };
425 
426 static int parse_setacl(unsigned char *buffer, uint32_t length,
428 {
429  int status;
430  setacl_upcall_args *args = &upcall->args.setacl;
431  ULONG sec_desc_len;
432 
433  status = safe_read(&buffer, &length, &args->query, sizeof(args->query));
434  if (status) goto out;
435  status = safe_read(&buffer, &length, &sec_desc_len, sizeof(ULONG));
436  if (status) goto out;
437  args->sec_desc = (PSECURITY_DESCRIPTOR)buffer;
438 
439  dprintf(1, "parsing NFS41_ACL_SET: info_class=%d sec_desc_len=%d\n",
440  args->query, sec_desc_len);
441 out:
442  return status;
443 }
444 
445 static int is_well_known_sid(PSID sid, char *who)
446 {
447  int status, i;
448  for (i = 0; i < 78; i++) {
449  status = IsWellKnownSid(sid, (WELL_KNOWN_SID_TYPE)i);
450  if (!status) continue;
451  else {
452  dprintf(ACLLVL, "WELL_KNOWN_SID_TYPE %d\n", i);
453  switch((WELL_KNOWN_SID_TYPE)i) {
454  case WinCreatorOwnerSid:
455  memcpy(who, ACE4_OWNER, strlen(ACE4_OWNER)+1);
456  return TRUE;
457  case WinNullSid:
459  return TRUE;
460  case WinAnonymousSid:
462  return TRUE;
463  case WinWorldSid:
465  return TRUE;
466  case WinCreatorGroupSid:
467  case WinBuiltinUsersSid:
468  memcpy(who, ACE4_GROUP, strlen(ACE4_GROUP)+1);
469  return TRUE;
470  case WinAuthenticatedUserSid:
472  return TRUE;
473  case WinDialupSid:
475  return TRUE;
476  case WinNetworkSid:
478  return TRUE;
479  case WinBatchSid:
480  memcpy(who, ACE4_BATCH, strlen(ACE4_BATCH)+1);
481  return TRUE;
482  case WinInteractiveSid:
484  return TRUE;
485  case WinNetworkServiceSid:
486  case WinLocalServiceSid:
487  case WinServiceSid:
489  return TRUE;
490  default: return FALSE;
491  }
492  }
493  }
494  return FALSE;
495 }
496 
497 static void map_aceflags(BYTE win_aceflags, uint32_t *nfs4_aceflags)
498 {
499  if (win_aceflags & OBJECT_INHERIT_ACE)
500  *nfs4_aceflags |= ACE4_FILE_INHERIT_ACE;
501  if (win_aceflags & CONTAINER_INHERIT_ACE)
502  *nfs4_aceflags |= ACE4_DIRECTORY_INHERIT_ACE;
503  if (win_aceflags & NO_PROPAGATE_INHERIT_ACE)
504  *nfs4_aceflags |= ACE4_NO_PROPAGATE_INHERIT_ACE;
505  if (win_aceflags & INHERIT_ONLY_ACE)
506  *nfs4_aceflags |= ACE4_INHERIT_ONLY_ACE;
507  if (win_aceflags & INHERITED_ACE)
508  *nfs4_aceflags |= ACE4_INHERITED_ACE;
509  dprintf(ACLLVL, "ACE FLAGS: %x nfs4 aceflags %x\n",
510  win_aceflags, *nfs4_aceflags);
511 }
512 
513 static void map_acemask(ACCESS_MASK mask, int file_type, uint32_t *nfs4_mask)
514 {
515  dprintf(ACLLVL, "ACE MASK: %x\n", mask);
516  print_windows_access_mask(0, mask);
517  /* check if any GENERIC bits set */
518  if (mask & 0xf000000) {
519  if (mask & GENERIC_ALL) {
520  if (file_type == NF4DIR)
521  *nfs4_mask |= ACE4_ALL_DIR;
522  else
523  *nfs4_mask |= ACE4_ALL_FILE;
524  } else {
525  if (mask & GENERIC_READ)
526  *nfs4_mask |= ACE4_GENERIC_READ;
527  if (mask & GENERIC_WRITE)
528  *nfs4_mask |= ACE4_GENERIC_WRITE;
529  if (mask & GENERIC_EXECUTE)
530  *nfs4_mask |= ACE4_GENERIC_EXECUTE;
531  }
532  }
533  else /* ignoring generic and reserved bits */
534  *nfs4_mask = mask & 0x00ffffff;
535  print_nfs_access_mask(0, *nfs4_mask);
536 }
537 
538 static int map_nfs4ace_who(PSID sid, PSID owner_sid, PSID group_sid, char *who_out, char *domain)
539 {
541  DWORD size = 0, tmp_size = 0;
542  SID_NAME_USE sid_type;
543  LPSTR tmp_buf = NULL, who = NULL;
544 
545  /* for ace mapping, we want to map owner's sid into "owner@"
546  * but for set_owner attribute we want to map owner into a user name
547  * same applies to group
548  */
549  status = 0;
550  if (owner_sid) {
551  if (EqualSid(sid, owner_sid)) {
552  dprintf(ACLLVL, "map_nfs4ace_who: this is owner's sid\n");
553  memcpy(who_out, ACE4_OWNER, strlen(ACE4_OWNER)+1);
554  return ERROR_SUCCESS;
555  }
556  }
557  if (group_sid) {
558  if (EqualSid(sid, group_sid)) {
559  dprintf(ACLLVL, "map_nfs4ace_who: this is group's sid\n");
560  memcpy(who_out, ACE4_GROUP, strlen(ACE4_GROUP)+1);
561  return ERROR_SUCCESS;
562  }
563  }
564  status = is_well_known_sid(sid, who_out);
565  if (status) {
566  if (!strncmp(who_out, ACE4_NOBODY, strlen(ACE4_NOBODY))) {
567  size = (DWORD)strlen(ACE4_NOBODY);
568  goto add_domain;
569  }
570  else
571  return ERROR_SUCCESS;
572  }
573 
574  status = LookupAccountSid(NULL, sid, who, &size, tmp_buf,
575  &tmp_size, &sid_type);
576  dprintf(ACLLVL, "map_nfs4ace_who: LookupAccountSid returned %d GetLastError "
577  "%d name len %d domain len %d\n", status, GetLastError(),
578  size, tmp_size);
579  if (status)
580  return ERROR_INTERNAL_ERROR;
581  status = GetLastError();
582  if (status != ERROR_INSUFFICIENT_BUFFER)
583  return ERROR_INTERNAL_ERROR;
584  who = malloc(size);
585  if (who == NULL) {
586  status = GetLastError();
587  goto out;
588  }
589  tmp_buf = malloc(tmp_size);
590  if (tmp_buf == NULL)
591  goto out_free_who;
592  status = LookupAccountSid(NULL, sid, who, &size, tmp_buf,
593  &tmp_size, &sid_type);
594  free(tmp_buf);
595  if (!status) {
596  eprintf("map_nfs4ace_who: LookupAccountSid failed with %d\n",
597  GetLastError());
598  goto out_free_who;
599  }
600  memcpy(who_out, who, size);
601 add_domain:
602  memcpy(who_out+size, "@", sizeof(char));
603  memcpy(who_out+size+1, domain, strlen(domain)+1);
604  dprintf(ACLLVL, "map_nfs4ace_who: who=%s\n", who_out);
605  if (who) free(who);
606  status = ERROR_SUCCESS;
607 out:
608  return status;
609 out_free_who:
610  free(who);
611  status = GetLastError();
612  goto out;
613 }
614 static int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl,
615  int file_type, char *domain)
616 {
617  int status;
618  if (acl == NULL) {
619  dprintf(ACLLVL, "this is a NULL dacl: all access to an object\n");
620  nfs4_acl->count = 1;
621  nfs4_acl->aces = calloc(1, sizeof(nfsace4));
622  if (nfs4_acl->aces == NULL) {
623  status = GetLastError();
624  goto out;
625  }
626  nfs4_acl->flag = 0;
627  memcpy(nfs4_acl->aces->who, ACE4_EVERYONE, strlen(ACE4_EVERYONE)+1);
629  if (file_type == NF4DIR)
630  nfs4_acl->aces->acemask = ACE4_ALL_DIR;
631  else
632  nfs4_acl->aces->acemask = ACE4_ALL_FILE;
633  nfs4_acl->aces->aceflag = 0;
634  } else {
635  int i;
636  PACE_HEADER ace;
637  PBYTE tmp_pointer;
638 
639  dprintf(ACLLVL, "NON-NULL dacl with %d ACEs\n", acl->AceCount);
640  print_hexbuf_no_asci(3, (unsigned char *)"ACL\n",
641  (unsigned char *)acl, acl->AclSize);
642  nfs4_acl->count = acl->AceCount;
643  nfs4_acl->aces = calloc(nfs4_acl->count, sizeof(nfsace4));
644  if (nfs4_acl->aces == NULL) {
645  status = GetLastError();
646  goto out;
647  }
648  nfs4_acl->flag = 0;
649  for (i = 0; i < acl->AceCount; i++) {
650  status = GetAce(acl, i, &ace);
651  if (!status) {
652  status = GetLastError();
653  eprintf("map_dacl_2_nfs4acl: GetAce failed with %d\n", status);
654  goto out_free;
655  }
656  tmp_pointer = (PBYTE)ace;
657  print_hexbuf_no_asci(3, (unsigned char *)"ACE\n",
658  (unsigned char *)ace, ace->AceSize);
659  dprintf(ACLLVL, "ACE TYPE: %x\n", ace->AceType);
660  if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE)
662  else if (ace->AceType == ACCESS_DENIED_ACE_TYPE)
664  else {
665  eprintf("map_dacl_2_nfs4acl: unsupported ACE type %d\n",
666  ace->AceType);
667  status = ERROR_NOT_SUPPORTED;
668  goto out_free;
669  }
670 
671  map_aceflags(ace->AceFlags, &nfs4_acl->aces[i].aceflag);
672  map_acemask(*(PACCESS_MASK)(ace + 1), file_type,
673  &nfs4_acl->aces[i].acemask);
674 
675  tmp_pointer += sizeof(ACCESS_MASK) + sizeof(ACE_HEADER);
676  status = map_nfs4ace_who(tmp_pointer, sid, gsid, nfs4_acl->aces[i].who,
677  domain);
678  if (status)
679  goto out_free;
680  }
681  }
682  status = ERROR_SUCCESS;
683 out:
684  return status;
685 out_free:
686  free(nfs4_acl->aces);
687  goto out;
688 }
689 
691 {
693  setacl_upcall_args *args = &upcall->args.setacl;
694  nfs41_open_state *state = upcall->state_ref;
695  nfs41_file_info info = { 0 };
696  stateid_arg stateid;
697  nfsacl41 nfs4_acl = { 0 };
698  PSID sid = NULL, gsid = NULL;
699  BOOL sid_default, gsid_default;
700 
701  if (args->query & OWNER_SECURITY_INFORMATION) {
702  char owner[NFS4_OPAQUE_LIMIT];
703  dprintf(ACLLVL, "handle_setacl: OWNER_SECURITY_INFORMATION\n");
704  status = GetSecurityDescriptorOwner(args->sec_desc, &sid, &sid_default);
705  if (!status) {
706  status = GetLastError();
707  eprintf("GetSecurityDescriptorOwner failed with %d\n", status);
708  goto out;
709  }
710  info.owner = owner;
711  status = map_nfs4ace_who(sid, NULL, NULL, info.owner, localdomain_name);
712  if (status)
713  goto out;
714  else {
715  info.attrmask.arr[1] |= FATTR4_WORD1_OWNER;
716  info.attrmask.count = 2;
717  }
718  }
719  if (args->query & GROUP_SECURITY_INFORMATION) {
720  char group[NFS4_OPAQUE_LIMIT];
721  dprintf(ACLLVL, "handle_setacl: GROUP_SECURITY_INFORMATION\n");
722  status = GetSecurityDescriptorGroup(args->sec_desc, &sid, &sid_default);
723  if (!status) {
724  status = GetLastError();
725  eprintf("GetSecurityDescriptorOwner failed with %d\n", status);
726  goto out;
727  }
728  info.owner_group = group;
729  status = map_nfs4ace_who(sid, NULL, NULL, info.owner_group,
731  if (status)
732  goto out;
733  else {
735  info.attrmask.count = 2;
736  }
737  }
738  if (args->query & DACL_SECURITY_INFORMATION) {
739  BOOL dacl_present, dacl_default;
740  PACL acl;
741  dprintf(ACLLVL, "handle_setacl: DACL_SECURITY_INFORMATION\n");
742  status = GetSecurityDescriptorDacl(args->sec_desc, &dacl_present,
743  &acl, &dacl_default);
744  if (!status) {
745  status = GetLastError();
746  eprintf("GetSecurityDescriptorDacl failed with %d\n", status);
747  goto out;
748  }
749  status = GetSecurityDescriptorOwner(args->sec_desc, &sid, &sid_default);
750  if (!status) {
751  status = GetLastError();
752  eprintf("GetSecurityDescriptorOwner failed with %d\n", status);
753  goto out;
754  }
755  status = GetSecurityDescriptorGroup(args->sec_desc, &gsid, &gsid_default);
756  if (!status) {
757  status = GetLastError();
758  eprintf("GetSecurityDescriptorOwner failed with %d\n", status);
759  goto out;
760  }
761  status = map_dacl_2_nfs4acl(acl, sid, gsid, &nfs4_acl, state->type,
763  if (status)
764  goto out;
765  else {
766  info.acl = &nfs4_acl;
767  info.attrmask.arr[0] |= FATTR4_WORD0_ACL;
768  if (!info.attrmask.count)
769  info.attrmask.count = 1;
770  }
771  }
772 
773  /* break read delegations before SETATTR */
774  nfs41_delegation_return(state->session, &state->file,
776 
777  nfs41_open_stateid_arg(state, &stateid);
778  status = nfs41_setattr(state->session, &state->file, &stateid, &info);
779  if (status) {
780  dprintf(ACLLVL, "handle_setacl: nfs41_setattr() failed with error %s.\n",
781  nfs_error_string(status));
782  status = nfs_to_windows_error(status, ERROR_NOT_SUPPORTED);
783  }
784  args->ctime = info.change;
785  if (args->query & DACL_SECURITY_INFORMATION)
786  free(nfs4_acl.aces);
787 out:
788  return status;
789 }
790 
791 static int marshall_setacl(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
792 {
793  setacl_upcall_args *args = &upcall->args.setacl;
794  return safe_write(&buffer, length, &args->ctime, sizeof(args->ctime));
795 }
796 
798  parse_setacl,
801 };
struct _SECURITY_DESCRIPTOR * PSECURITY_DESCRIPTOR
Definition: security.c:97
int nfs_to_windows_error(int status, int default_error)
Definition: util.c:235
static int map_name_2_sid(DWORD *sid_len, PSID *sid, LPCSTR name)
Definition: acl.c:93
#define GENERIC_ALL
Definition: nt_native.h:92
#define TRUE
Definition: types.h:120
int nfs41_setattr(IN nfs41_session *session, IN nfs41_path_fh *file, IN stateid_arg *stateid, IN nfs41_file_info *info)
Definition: nfs41_ops.c:1351
ULONGLONG ctime
Definition: upcall.h:172
uint32_t acemask
Definition: nfs41_types.h:133
enum _SID_NAME_USE SID_NAME_USE
#define ERROR_SUCCESS
Definition: deptool.c:10
#define ERROR_INTERNAL_ERROR
Definition: winerror.h:840
BOOL WINAPI GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, LPBOOL lpbDaclPresent, PACL *pDacl, LPBOOL lpbDaclDefaulted)
Definition: sec.c:45
BOOL WINAPI InitializeAcl(PACL pAcl, DWORD nAclLength, DWORD dwAclRevision)
Definition: security.c:881
void nfsacl41_free(nfsacl41 *acl)
Definition: nfs41_xdr.c:335
static int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl, int file_type, char *domain)
Definition: acl.c:614
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ACE4_GROUP
Definition: nfs41_const.h:382
USHORT AclSize
Definition: ms-dtyp.idl:296
#define DWORD
Definition: msvc.h:34
#define ACE4_BATCH
Definition: nfs41_const.h:387
static int map_nfs4ace_who(PSID sid, PSID owner_sid, PSID group_sid, char *who_out, char *domain)
Definition: acl.c:538
BOOL WINAPI InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD dwRevision)
Definition: security.c:804
BOOL WINAPI EqualSid(PSID pSid1, PSID pSid2)
Definition: security.c:704
char who[NFS4_OPAQUE_LIMIT]
Definition: nfs41_types.h:134
GLuint GLuint GLsizei count
Definition: gl.h:1545
static void free_sids(PSID *sids, int count)
Definition: acl.c:155
#define free
Definition: debug_ros.c:5
#define ERROR_NONE_MAPPED
Definition: winerror.h:814
#define ACE4_NOBODY
Definition: nfs41_const.h:391
BOOL WINAPI AddAccessAllowedAce(PACL pAcl, DWORD dwAceRevision, DWORD AccessMask, PSID pSid)
Definition: security.c:914
void print_hexbuf_no_asci(int level, unsigned char *title, unsigned char *buf, int len)
Definition: daemon_debug.c:112
#define ACE4_ALL_DIR
Definition: nfs41_const.h:350
#define ACE4_GENERIC_EXECUTE
Definition: nfs41_const.h:360
static int marshall_setacl(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
Definition: acl.c:791
static int check_4_special_identifiers(char *who, PSID *sid, DWORD *sid_len, BOOLEAN *flag)
Definition: acl.c:163
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
FT_UInt sid
Definition: cffcmap.c:139
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
GLuint buffer
Definition: glext.h:5915
#define GROUP_SECURITY_INFORMATION
Definition: setypes.h:124
#define NO_PROPAGATE_INHERIT_ACE
Definition: setypes.h:716
char * LPSTR
Definition: xmlstorage.h:182
uint32_t arr[3]
Definition: nfs41_types.h:97
void print_nfs_access_mask(int on, int m)
Definition: daemon_debug.c:640
Definition: match.c:390
USHORT AceCount
Definition: ms-dtyp.idl:297
GLuint const GLubyte mask[]
Definition: s_context.h:57
#define ACE4_OWNER
Definition: nfs41_const.h:381
struct __nfs41_session * session
Definition: nfs41.h:132
BOOL WINAPI GetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID *pGroup, LPBOOL lpbGroupDefaulted)
Definition: sec.c:76
PSECURITY_DESCRIPTOR sec_desc
Definition: upcall.h:165
static int handle_setacl(nfs41_upcall *upcall)
Definition: acl.c:690
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
getacl_upcall_args getacl
Definition: upcall.h:189
#define LookupAccountSid
Definition: winbase.h:3681
static int convert_nfs4acl_2_dacl(nfsacl41 *acl, int file_type, PACL *dacl_out, PSID **sids_out)
Definition: acl.c:184
BOOL WINAPI GetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID *pOwner, LPBOOL lpbOwnerDefaulted)
Definition: sec.c:103
USHORT AceSize
Definition: ms-dtyp.idl:212
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define ACE4_INHERIT_ONLY_ACE
Definition: nfs41_const.h:374
GLenum GLint GLuint mask
Definition: glext.h:6028
void print_windows_access_mask(int on, ACCESS_MASK m)
Definition: daemon_debug.c:570
static domain_t * add_domain(session_t *session, WCHAR *name)
Definition: cookie.c:33
nfs41_open_state * state_ref
Definition: upcall.h:207
#define NFS41_HOSTNAME_LEN
Definition: nfs41_const.h:48
#define dprintf
Definition: regdump.c:33
#define GENERIC_WRITE
Definition: nt_native.h:90
uint32_t count
Definition: nfs41_types.h:96
static int handle_getacl(nfs41_upcall *upcall)
Definition: acl.c:274
#define NFS4_OPAQUE_LIMIT
Definition: nfs41_const.h:31
uint32_t type
Definition: nfs41.h:133
unsigned char BOOLEAN
struct _ACL ACL
smooth NULL
Definition: ftsmooth.c:416
#define ACE4_GENERIC_READ
Definition: nfs41_const.h:356
void nfs41_open_stateid_arg(IN nfs41_open_state *state, OUT struct __stateid_arg *arg)
const char * LPCSTR
Definition: xmlstorage.h:183
int nfs41_getattr(IN nfs41_session *session, IN OPTIONAL nfs41_path_fh *file, IN bitmap4 *attr_request, OUT nfs41_file_info *info)
Definition: nfs41_ops.c:1063
static int parse_setacl(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
Definition: acl.c:426
GLboolean GLuint group
Definition: glext.h:11120
#define CONTAINER_INHERIT_ACE
Definition: setypes.h:715
#define ACE4_DIALUP
Definition: nfs41_const.h:386
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizeiptr size
Definition: glext.h:5919
BOOL WINAPI AddAccessDeniedAce(PACL pAcl, DWORD dwAceRevision, DWORD AccessMask, PSID pSid)
Definition: security.c:965
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean flag
Definition: glfuncs.h:72
uint32_t acetype
Definition: nfs41_types.h:131
upcall_args args
Definition: upcall.h:198
#define ACE4_FILE_INHERIT_ACE
Definition: nfs41_const.h:371
#define ACE4_NETWORK
Definition: nfs41_const.h:385
nfsace4 * aces
Definition: nfs41_types.h:139
static int marshall_getacl(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
Definition: acl.c:405
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
Definition: security.c:35
SECURITY_INFORMATION query
Definition: upcall.h:164
int nfs41_delegation_return(IN nfs41_session *session, IN nfs41_path_fh *file, IN enum open_delegation_type4 access, IN bool_t truncate)
Definition: delegation.c:629
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
static FILE * out
Definition: regtests2xml.c:44
static void convert_nfs4name_2_user_domain(LPSTR nfs4name, LPSTR *domain)
Definition: acl.c:80
unsigned long DWORD
Definition: ntddk_ex.h:95
#define ACCESS_ALLOWED_ACE_TYPE
Definition: setypes.h:685
int safe_write(unsigned char **pos, uint32_t *remaining, void *src, uint32_t src_len)
Definition: util.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
FD_TYPE file_type(FDSC **curr, char *fixed)
Definition: file.c:221
#define ACCESS_DENIED_ACE_TYPE
Definition: setypes.h:686
PSECURITY_DESCRIPTOR sec_desc
Definition: upcall.h:171
BOOL WINAPI ConvertSidToStringSidA(PSID Sid, LPSTR *StringSid)
Definition: security.c:3309
SECURITY_INFORMATION query
Definition: upcall.h:170
nfsacl41 * acl
Definition: nfs41_types.h:214
static int parse_getacl(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
Definition: acl.c:38
#define ACE4_GENERIC_WRITE
Definition: nfs41_const.h:358
static int state
Definition: maze.c:121
uint32_t count
Definition: nfs41_types.h:140
const nfs41_upcall_op nfs41_op_getacl
Definition: acl.c:420
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
const nfs41_upcall_op nfs41_op_setacl
Definition: acl.c:797
#define GENERIC_READ
Definition: compat.h:124
#define ACLLVL
Definition: acl.c:34
unsigned char BYTE
Definition: ntddk_ex.h:96
#define ACE4_DIRECTORY_INHERIT_ACE
Definition: nfs41_const.h:372
#define ACE4_ACCESS_DENIED_ACE_TYPE
Definition: nfs41_const.h:319
setacl_upcall_args setacl
Definition: upcall.h:190
nfs41_path_fh file
Definition: nfs41.h:130
#define ACE4_SERVICE
Definition: nfs41_const.h:390
WELL_KNOWN_SID_TYPE
Definition: setypes.h:427
BOOL WINAPI GetAce(PACL pAcl, DWORD dwAceIndex, LPVOID *pAce)
Definition: security.c:1061
#define ACE4_EVERYONE
Definition: nfs41_const.h:383
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
#define ACE4_ACCESS_ALLOWED_ACE_TYPE
Definition: nfs41_const.h:318
static int is_well_known_sid(PSID sid, char *who)
Definition: acl.c:445
#define INHERITED_ACE
Definition: ph.h:47
#define OWNER_SECURITY_INFORMATION
Definition: setypes.h:123
BOOL WINAPI SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, BOOL bDaclPresent, PACL pDacl, BOOL bDaclDefaulted)
Definition: sec.c:262
UINT32 uint32_t
Definition: types.h:75
BOOL WINAPI MakeSelfRelativeSD(PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor, PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor, LPDWORD lpdwBufferLength)
Definition: sec.c:214
#define ACL_REVISION
Definition: setypes.h:39
nfs41_updowncall_list upcall
Definition: nfs41_driver.c:273
#define ERROR_NOT_SUPPORTED
Definition: compat.h:90
Definition: name.c:36
#define calloc
Definition: rosglue.h:14
#define ACE4_ANONYMOUS
Definition: nfs41_const.h:388
unsigned int ULONG
Definition: retypes.h:1
ACCESS_MASK * PACCESS_MASK
Definition: nt_native.h:41
#define ACE4_AUTHENTICATED
Definition: nfs41_const.h:389
int safe_read(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len)
Definition: util.c:33
#define malloc
Definition: debug_ros.c:4
BOOL WINAPI IsValidSid(PSID pSid)
Definition: security.c:694
static void map_aceflags(BYTE win_aceflags, uint32_t *nfs4_aceflags)
Definition: acl.c:497
#define INHERIT_ONLY_ACE
Definition: setypes.h:717
BOOL WINAPI IsWellKnownSid(IN PSID pSid, IN WELL_KNOWN_SID_TYPE WellKnownSidType)
Definition: security.c:671
BOOL WINAPI SetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID pGroup, BOOL bGroupDefaulted)
Definition: sec.c:288
GLfloat GLfloat p
Definition: glext.h:8902
uint32_t aceflag
Definition: nfs41_types.h:132
#define ACE4_NO_PROPAGATE_INHERIT_ACE
Definition: nfs41_const.h:373
#define GENERIC_EXECUTE
Definition: nt_native.h:91
BOOL WINAPI CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType, IN PSID DomainSid OPTIONAL, OUT PSID pSid, IN OUT DWORD *cbSid)
Definition: security.c:597
#define ACE4_INTERACTIVE
Definition: nfs41_const.h:384
static SERVICE_STATUS status
Definition: service.c:31
BYTE * PBYTE
Definition: pedump.c:66
static int create_unknownsid(WELL_KNOWN_SID_TYPE type, PSID *sid, DWORD *sid_len)
Definition: acl.c:52
#define OBJECT_INHERIT_ACE
Definition: setypes.h:714
ULONG ACCESS_MASK
Definition: nt_native.h:40
BOOL WINAPI SetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID pOwner, BOOL bOwnerDefaulted)
Definition: sec.c:312
#define DACL_SECURITY_INFORMATION
Definition: setypes.h:125
#define LookupAccountName
Definition: winbase.h:3680
#define ACE4_INHERITED_ACE
Definition: nfs41_const.h:378
char localdomain_name[NFS41_HOSTNAME_LEN]
Definition: nfs41_daemon.c:49
uint32_t flag
Definition: nfs41_types.h:138
static void map_acemask(ACCESS_MASK mask, int file_type, uint32_t *nfs4_mask)
Definition: acl.c:513
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ACE4_ALL_FILE
Definition: nfs41_const.h:345
Definition: ps.c:97