• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "remoting/host/win/security_descriptor.h"
6 
7 #include <sddl.h>
8 
9 #include "base/strings/string16.h"
10 #include "base/strings/utf_string_conversions.h"
11 
12 namespace remoting {
13 
ConvertSddlToSd(const std::string & sddl)14 ScopedSd ConvertSddlToSd(const std::string& sddl) {
15   PSECURITY_DESCRIPTOR raw_sd = NULL;
16   ULONG length = 0;
17   if (!ConvertStringSecurityDescriptorToSecurityDescriptor(
18           base::UTF8ToUTF16(sddl).c_str(), SDDL_REVISION_1, &raw_sd, &length)) {
19     return ScopedSd();
20   }
21 
22   ScopedSd sd(length);
23   memcpy(sd.get(), raw_sd, length);
24 
25   LocalFree(raw_sd);
26   return sd.Pass();
27 }
28 
29 // Converts a SID into a text string.
ConvertSidToString(SID * sid)30 std::string ConvertSidToString(SID* sid) {
31   base::char16* c_sid_string = NULL;
32   if (!ConvertSidToStringSid(sid, &c_sid_string))
33     return std::string();
34 
35   base::string16 sid_string(c_sid_string);
36   LocalFree(c_sid_string);
37   return base::UTF16ToUTF8(sid_string);
38 }
39 
40 // Returns the logon SID of a token. Returns NULL if the token does not specify
41 // a logon SID or in case of an error.
GetLogonSid(HANDLE token)42 ScopedSid GetLogonSid(HANDLE token) {
43   DWORD length = 0;
44   if (GetTokenInformation(token, TokenGroups, NULL, 0, &length) ||
45       GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
46     return ScopedSid();
47   }
48 
49   TypedBuffer<TOKEN_GROUPS> groups(length);
50   if (!GetTokenInformation(token, TokenGroups, groups.get(), length, &length))
51     return ScopedSid();
52 
53   for (uint32 i = 0; i < groups->GroupCount; ++i) {
54     if ((groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) ==
55         SE_GROUP_LOGON_ID) {
56       length = GetLengthSid(groups->Groups[i].Sid);
57       ScopedSid logon_sid(length);
58       if (!CopySid(length, logon_sid.get(), groups->Groups[i].Sid))
59         return ScopedSid();
60 
61       return logon_sid.Pass();
62     }
63   }
64 
65   return ScopedSid();
66 }
67 
MakeScopedAbsoluteSd(const ScopedSd & relative_sd,ScopedSd * absolute_sd,ScopedAcl * dacl,ScopedSid * group,ScopedSid * owner,ScopedAcl * sacl)68 bool MakeScopedAbsoluteSd(const ScopedSd& relative_sd,
69                           ScopedSd* absolute_sd,
70                           ScopedAcl* dacl,
71                           ScopedSid* group,
72                           ScopedSid* owner,
73                           ScopedAcl* sacl) {
74   // Get buffer sizes.
75   DWORD absolute_sd_size = 0;
76   DWORD dacl_size = 0;
77   DWORD group_size = 0;
78   DWORD owner_size = 0;
79   DWORD sacl_size = 0;
80   if (MakeAbsoluteSD(relative_sd.get(),
81                      NULL,
82                      &absolute_sd_size,
83                      NULL,
84                      &dacl_size,
85                      NULL,
86                      &sacl_size,
87                      NULL,
88                      &owner_size,
89                      NULL,
90                      &group_size) ||
91       GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
92     return false;
93   }
94 
95   // Allocate buffers.
96   ScopedSd local_absolute_sd(absolute_sd_size);
97   ScopedAcl local_dacl(dacl_size);
98   ScopedSid local_group(group_size);
99   ScopedSid local_owner(owner_size);
100   ScopedAcl local_sacl(sacl_size);
101 
102   // Do the conversion.
103   if (!MakeAbsoluteSD(relative_sd.get(),
104                       local_absolute_sd.get(),
105                       &absolute_sd_size,
106                       local_dacl.get(),
107                       &dacl_size,
108                       local_sacl.get(),
109                       &sacl_size,
110                       local_owner.get(),
111                       &owner_size,
112                       local_group.get(),
113                       &group_size)) {
114     return false;
115   }
116 
117   absolute_sd->Swap(local_absolute_sd);
118   dacl->Swap(local_dacl);
119   group->Swap(local_group);
120   owner->Swap(local_owner);
121   sacl->Swap(local_sacl);
122   return true;
123 }
124 
125 }  // namespace remoting
126