• 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 "cloud_print/service/win/local_security_policy.h"
6 
7 #include <atlsecurity.h>
8 #include <ntsecapi.h>
9 #include <windows.h>
10 
11 #include "base/logging.h"
12 #include "base/strings/string_util.h"
13 
14 const wchar_t kSeServiceLogonRight[] = L"SeServiceLogonRight";
15 
16 #ifndef STATUS_SUCCESS
17 #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
18 #endif
19 
20 namespace {
21 
22 template<class T>
23 class ScopedLsaMemory {
24  public:
ScopedLsaMemory()25   ScopedLsaMemory() : lsa_memory_(NULL) {
26   }
27 
~ScopedLsaMemory()28   ~ScopedLsaMemory() {
29     Close();
30   }
31 
Close()32   void Close() {
33     if (lsa_memory_) {
34       LsaFreeMemory(lsa_memory_);
35       lsa_memory_ = NULL;
36     }
37   }
38 
Get() const39   T* Get() const {
40     return lsa_memory_;
41   }
42 
Receive()43   T** Receive() {
44     Close();
45     return &lsa_memory_;
46   }
47 
48  private:
49   T* lsa_memory_;
50   DISALLOW_COPY_AND_ASSIGN(ScopedLsaMemory);
51 };
52 
53 }  // namespace
54 
LocalSecurityPolicy()55 LocalSecurityPolicy::LocalSecurityPolicy() : policy_(NULL) {
56 }
57 
~LocalSecurityPolicy()58 LocalSecurityPolicy::~LocalSecurityPolicy() {
59   Close();
60 }
61 
Close()62 void LocalSecurityPolicy::Close() {
63   if (policy_) {
64     LsaClose(policy_);
65     policy_ = NULL;
66   }
67 }
68 
Open()69 bool LocalSecurityPolicy::Open() {
70   DCHECK(!policy_);
71   Close();
72   LSA_OBJECT_ATTRIBUTES attributes = {0};
73   return STATUS_SUCCESS ==
74       ::LsaOpenPolicy(NULL, &attributes,
75                       POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES,
76                       &policy_);
77 }
78 
IsPrivilegeSet(const base::string16 & username,const base::string16 & privilage) const79 bool LocalSecurityPolicy::IsPrivilegeSet(
80     const base::string16& username,
81     const base::string16& privilage) const {
82   DCHECK(policy_);
83   ATL::CSid user_sid;
84   if (!user_sid.LoadAccount(username.c_str())) {
85     LOG(ERROR) << "Unable to load Sid for" << username;
86     return false;
87   }
88   ScopedLsaMemory<LSA_UNICODE_STRING> rights;
89   ULONG count = 0;
90   NTSTATUS status = ::LsaEnumerateAccountRights(
91       policy_, const_cast<SID*>(user_sid.GetPSID()), rights.Receive(), &count);
92   if (STATUS_SUCCESS != status || !rights.Get())
93     return false;
94   for (size_t i = 0; i < count; ++i) {
95     if (privilage == rights.Get()[i].Buffer)
96       return true;
97   }
98   return false;
99 }
100 
SetPrivilege(const base::string16 & username,const base::string16 & privilage)101 bool LocalSecurityPolicy::SetPrivilege(const base::string16& username,
102                                        const base::string16& privilage) {
103   DCHECK(policy_);
104   ATL::CSid user_sid;
105   if (!user_sid.LoadAccount(username.c_str())) {
106     LOG(ERROR) << "Unable to load Sid for" << username;
107     return false;
108   }
109   LSA_UNICODE_STRING privilege_string;
110   base::string16 privilage_copy(privilage);
111   privilege_string.Buffer = &privilage_copy[0];
112   privilege_string.Length = wcslen(privilege_string.Buffer) *
113                             sizeof(privilege_string.Buffer[0]);
114   privilege_string.MaximumLength = privilege_string.Length +
115                                    sizeof(privilege_string.Buffer[0]);
116   return STATUS_SUCCESS ==
117       ::LsaAddAccountRights(policy_, const_cast<SID*>(user_sid.GetPSID()),
118                             &privilege_string, 1);
119 }
120 
121