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 14const wchar_t kSeServiceLogonRight[] = L"SeServiceLogonRight"; 15 16#ifndef STATUS_SUCCESS 17#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) 18#endif 19 20namespace { 21 22template<class T> 23class ScopedLsaMemory { 24 public: 25 ScopedLsaMemory() : lsa_memory_(NULL) { 26 } 27 28 ~ScopedLsaMemory() { 29 Close(); 30 } 31 32 void Close() { 33 if (lsa_memory_) { 34 LsaFreeMemory(lsa_memory_); 35 lsa_memory_ = NULL; 36 } 37 } 38 39 T* Get() const { 40 return lsa_memory_; 41 } 42 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 55LocalSecurityPolicy::LocalSecurityPolicy() : policy_(NULL) { 56} 57 58LocalSecurityPolicy::~LocalSecurityPolicy() { 59 Close(); 60} 61 62void LocalSecurityPolicy::Close() { 63 if (policy_) { 64 LsaClose(policy_); 65 policy_ = NULL; 66 } 67} 68 69bool 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 79bool 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 101bool 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