1 // Copyright 2012 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_MAC_SCOPED_AUTHORIZATIONREF_H_ 6 #define BASE_MAC_SCOPED_AUTHORIZATIONREF_H_ 7 8 #include <Security/Authorization.h> 9 10 #include <utility> 11 12 #include "base/base_export.h" 13 #include "base/check.h" 14 15 // `ScopedAuthorizationRef` maintains ownership of an `AuthorizationRef`. It is 16 // patterned after the `unique_ptr` interface. 17 18 namespace base::mac { 19 20 class BASE_EXPORT ScopedAuthorizationRef { 21 public: 22 explicit ScopedAuthorizationRef(AuthorizationRef authorization = nullptr) authorization_(authorization)23 : authorization_(authorization) {} 24 25 ScopedAuthorizationRef(const ScopedAuthorizationRef&) = delete; 26 ScopedAuthorizationRef& operator=(const ScopedAuthorizationRef&) = delete; 27 ScopedAuthorizationRef(ScopedAuthorizationRef && that)28 ScopedAuthorizationRef(ScopedAuthorizationRef&& that) 29 : authorization_(std::exchange(that.authorization_, nullptr)) {} 30 ScopedAuthorizationRef& operator=(ScopedAuthorizationRef&& that) { 31 authorization_ = std::exchange(that.authorization_, nullptr); 32 return *this; 33 } 34 ~ScopedAuthorizationRef()35 ~ScopedAuthorizationRef() { 36 if (authorization_) { 37 FreeInternal(); 38 } 39 } 40 41 void reset(AuthorizationRef authorization = nullptr) { 42 if (authorization_ != authorization) { 43 if (authorization_) { 44 FreeInternal(); 45 } 46 authorization_ = authorization; 47 } 48 } 49 50 bool operator==(AuthorizationRef that) const { 51 return authorization_ == that; 52 } 53 54 bool operator!=(AuthorizationRef that) const { 55 return authorization_ != that; 56 } 57 AuthorizationRef()58 operator AuthorizationRef() const { 59 return authorization_; 60 } 61 62 explicit operator bool() const { return authorization_ != nullptr; } 63 64 // This is to be used only to take ownership of objects that are created 65 // by pass-by-pointer create functions. To enforce this, require that the 66 // object be reset to NULL before this may be used. InitializeInto()67 [[nodiscard]] AuthorizationRef* InitializeInto() { 68 DCHECK(!authorization_); 69 return &authorization_; 70 } 71 get()72 AuthorizationRef get() const { 73 return authorization_; 74 } 75 76 // ScopedAuthorizationRef::release() is like std::unique_ptr<>::release. It is 77 // NOT a wrapper for AuthorizationFree(). To force a ScopedAuthorizationRef 78 // object to call AuthorizationFree(), use ScopedAuthorizationRef::reset(). release()79 [[nodiscard]] AuthorizationRef release() { 80 AuthorizationRef temp = authorization_; 81 authorization_ = nullptr; 82 return temp; 83 } 84 85 private: 86 // Calling AuthorizationFree, defined in Security.framework, from an inline 87 // function, results in link errors when linking dynamically with 88 // libbase.dylib. So wrap the call in an un-inlined method. This method 89 // doesn't check if |authorization_| is null; that check should be in the 90 // inlined callers. 91 void FreeInternal(); 92 93 AuthorizationRef authorization_; 94 }; 95 96 } // namespace base::mac 97 98 #endif // BASE_MAC_SCOPED_AUTHORIZATIONREF_H_ 99