├── LICENSE
├── LICENSES
└── Apache-2.0.txt
├── README.md
├── REUSE.toml
├── application_management
├── Privileges2_manifest.json
├── README.md
└── example_profiles
│ ├── Example_EnforcePrivileges.mobileconfig
│ ├── Example_ExpirationInterval.mobileconfig
│ ├── Example_ExpirationIntervalMax.mobileconfig
│ ├── Example_LimitToGroup.mobileconfig
│ ├── Example_LimitToUser.mobileconfig
│ ├── Example_ReasonRequired.mobileconfig
│ ├── Example_RemoteLogging.mobileconfig
│ └── Example_RequireAuthentication.mobileconfig
├── readme_images
├── CommandLine.png
├── DemoGIF.gif
├── DemoGIFviaDock.gif
├── DockIconCountDown 1.png
├── IllustrationAppComponents.png
├── ManagedDockIcons.png
├── PrivilegesGranted.jpg
├── PrivilegesRevoked.png
├── PrivilegesToogleViaDock.png
├── RequestPrivilegesWindow.png
├── RevertPrivilegesWindow.png
├── RunAppWhenPrivilegeChange.gif
├── UninstallationWindow.png
├── console_show_privileges_process.png
├── console_show_privileges_process_filtered_for_admin.png
├── github banner new.png
├── locked.png
├── locked_managed.png
├── log_show_privileges_process.png
├── log_show_privileges_process_filtered_for_admin.png
├── renewal_custom.png
├── settings_general.png
├── settings_managed.png
├── settings_privileges.png
├── unlocked.png
└── unlocked_managed.png
└── source
├── Privileges.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── .DS_Store
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── WorkspaceSettings.xcsettings
└── xcshareddata
│ ├── .DS_Store
│ └── xcschemes
│ ├── Privileges Beta.xcscheme
│ └── Privileges.xcscheme
├── Privileges
├── AppDelegate.h
├── AppDelegate.m
├── AppleScript sample.scpt
├── Base.lproj
│ └── Main.storyboard
├── Beta-Info.plist
├── Beta-InfoPlist.xcstrings
├── Credits.rtf
├── Localizable.xcstrings
├── MTReasonAccessory.xib
├── Privileges-ParentConstraint.coderequirement
├── Privileges-SelfConstraint.coderequirement
├── Privileges.entitlements
├── Privileges.mobileconfig
├── Release-Info.plist
├── Release-InfoPlist.xcstrings
├── View Controllers
│ ├── MTReasonAccessoryController.h
│ ├── MTReasonAccessoryController.m
│ ├── MTSettingsGeneralController.h
│ ├── MTSettingsGeneralController.m
│ ├── MTSettingsPrivilegesController.h
│ ├── MTSettingsPrivilegesController.m
│ ├── MTTabViewController.h
│ └── MTTabViewController.m
├── corp.sap.privileges.agent.plist
├── corp.sap.privileges.daemon.plist
├── corp.sap.privileges.watcher.plist
├── main.m
└── mul.lproj
│ └── Main.xcstrings
├── PrivilegesAgent
├── AppDelegate.h
├── AppDelegate.m
├── Classes
│ ├── MTClientCertificate.h
│ ├── MTClientCertificate.m
│ ├── MTDaemonConnection.h
│ ├── MTDaemonConnection.m
│ ├── MTLocalNotification.h
│ ├── MTLocalNotification.m
│ ├── MTPrivilegeExpirationCommand.h
│ ├── MTPrivilegeExpirationCommand.m
│ ├── MTPrivilegeStatusCommand.h
│ ├── MTPrivilegeStatusCommand.m
│ ├── MTStatusItemMenu.h
│ ├── MTStatusItemMenu.m
│ ├── MTSyslogMessage.h
│ ├── MTSyslogMessage.m
│ ├── MTSyslogMessageStructuredData.h
│ ├── MTSyslogMessageStructuredData.m
│ ├── MTWebhook.h
│ └── MTWebhook.m
├── Info.plist
├── InfoPlist.xcstrings
├── Localizable.xcstrings
├── Main.storyboard
├── PrivilegesAgent-ParentConstraint.coderequirement
├── PrivilegesAgent-SelfConstraint.coderequirement
├── PrivilegesAgent.entitlements
├── PrivilegesAgent.sdef
├── PrivilegesAgentProtocol.h
├── StatusItem.xcassets
│ ├── Contents.json
│ ├── locked.imageset
│ │ ├── Contents.json
│ │ ├── locked-16.png
│ │ └── locked-32.png
│ ├── locked_managed.imageset
│ │ ├── Contents.json
│ │ ├── locked_managed-16.png
│ │ └── locked_managed-32.png
│ ├── unlocked.imageset
│ │ ├── Contents.json
│ │ ├── unlocked-16.png
│ │ └── unlocked-32.png
│ └── unlocked_managed.imageset
│ │ ├── Contents.json
│ │ ├── unlocked_managed-16.png
│ │ └── unlocked_managed-32.png
└── main.m
├── PrivilegesCLI
├── Classes
│ ├── MTProcessInfo.h
│ └── MTProcessInfo.m
├── PrivilegesCLI-Info.plist
├── PrivilegesCLI.entitlements
└── main.m
├── PrivilegesDaemon
├── Classes
│ ├── MTPrivilegesDaemon.h
│ └── MTPrivilegesDaemon.m
├── PrivilegesDaemon-Info.plist
├── PrivilegesDaemon-ParentConstraint.coderequirement
├── PrivilegesDaemon-SelfConstraint.coderequirement
├── PrivilegesDaemonProtocol.h
└── main.m
├── PrivilegesTile
├── AppIcons-Beta.xcassets
│ ├── Contents.json
│ ├── locked.imageset
│ │ ├── Contents.json
│ │ └── locked.png
│ ├── locked_managed.imageset
│ │ ├── Contents.json
│ │ └── locked_managed.png
│ ├── unlocked.imageset
│ │ ├── Contents.json
│ │ └── unlocked.png
│ └── unlocked_managed.imageset
│ │ ├── Contents.json
│ │ └── unlocked_managed.png
├── AppIcons.xcassets
│ ├── Contents.json
│ ├── locked.imageset
│ │ ├── Contents.json
│ │ └── locked.png
│ ├── locked_managed.imageset
│ │ ├── Contents.json
│ │ └── locked_managed.png
│ ├── unlocked.imageset
│ │ ├── Contents.json
│ │ └── unlocked.png
│ └── unlocked_managed.imageset
│ │ ├── Contents.json
│ │ └── unlocked_managed.png
└── Classes
│ ├── PrivilegesTile.h
│ └── PrivilegesTile.m
├── PrivilegesWatcher
├── PrivilegesWatcher-Info.plist
├── PrivilegesWatcher-ParentConstraint.coderequirement
├── PrivilegesWatcher-SelfConstraint.coderequirement
└── main.m
├── PrivilegesXPC
├── Classes
│ ├── PrivilegesXPC.h
│ └── PrivilegesXPC.m
├── Info.plist
├── InfoPlist.xcstrings
├── PrivilegesXPC-ParentConstraint.coderequirement
├── PrivilegesXPC-ResponsibleConstraint.coderequirement
├── PrivilegesXPC.entitlements
├── PrivilegesXPCProtocol.h
└── main.m
└── Shared
├── Assets.xcassets
├── AccentColor.colorset
│ └── Contents.json
├── AppIcon-Beta.appiconset
│ ├── AppIcon-Beta-1024.png
│ ├── AppIcon-Beta-128.png
│ ├── AppIcon-Beta-16.png
│ ├── AppIcon-Beta-256.png
│ ├── AppIcon-Beta-32.png
│ ├── AppIcon-Beta-512.png
│ ├── AppIcon-Beta-64.png
│ └── Contents.json
├── AppIcon.appiconset
│ ├── AppIcon-1024.png
│ ├── AppIcon-128.png
│ ├── AppIcon-16.png
│ ├── AppIcon-256.png
│ ├── AppIcon-32.png
│ ├── AppIcon-512.png
│ ├── AppIcon-64.png
│ └── Contents.json
└── Contents.json
├── Classes
├── MTAgentConnection.h
├── MTAgentConnection.m
├── MTCodeSigning.h
├── MTCodeSigning.m
├── MTIdentity.h
├── MTIdentity.m
├── MTPrivileges.h
├── MTPrivileges.m
├── MTPrivilegesUser.h
├── MTPrivilegesUser.m
├── MTSystemInfo.h
└── MTSystemInfo.m
├── Constants.h
└── LocalizableMenu.xcstrings
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 |
4 |
5 | # Privileges
6 |
7 | [](https://api.reuse.software/info/github.com/SAP/macOS-enterprise-privileges)
8 |
9 | _Privileges_ is an application for macOS which allows users to work as a standard user for day-to-day tasks, by providing a quick and easy way to request administrator rights. Users can set a timeframe in the application’s settings to perform specific tasks, such as installing or removing an application. To request admin rights, simply click on the _Privileges_ icon in your Dock.
10 |
11 | Working as standard user instead of an administrator adds another layer of security to your Mac and is considered a security best practice. We believe all users, including all developers, can benefit from using _Privileges_.
12 |
13 | **Privileges supports the following macOS versions:**
14 |
15 | * macOS 15.x
16 | * macOS 14.x
17 | * macOS 13.x (*)
18 | * macOS 12.x
19 | * macOS 11.x
20 |
21 |
22 |
23 |
24 | >[!NOTE]
25 | >It seems that macOS 13 erroneously reports a launch constraint violation and terminates the appliction immediately. Therefore starting with version 2.2, we'll provide two different versions of the application. One with launch constraints and one whithout. Nevertheless, we recommend using the version with launch constraints whenever possible.
26 |
27 |
28 | # Features
29 |
30 | 🛠️ Easy install
31 |
32 | :rocket: Perfect for day-to-day use
33 |
34 | :alarm_clock: Turn on admin rights anytime
35 |
36 | :closed_lock_with_key: Enjoy standard user security
37 |
38 | :fire: Command line use supported
39 |
40 |
41 |
42 | ## New Privileges 2 features 🔥
43 |
44 | 📦 Installer package
45 |
46 | ⛔️ Revoke admin rights at login
47 |
48 | ⏳ Unified expiration interval for administrator privileges
49 |
50 | 🔁 Renew expiring administrator privileges
51 |
52 | 🪪 Smart card support
53 |
54 | ▶️ Run actions on privilege change
55 |
56 | 🔒 Status item
57 |
58 | 👆 Command line tool now supports Touch ID
59 |
60 | ⚙️ AppleScript support
61 |
62 | 🪝 Webhooks
63 |
64 | 🔠 Localized in 41 languages
65 |
66 |
67 |
68 | # Demo
69 |
70 | ⚡️ Have a look at how quick and easy you can request admin rights
71 |
72 | 
73 |
74 |
75 |
76 | # Application Management
77 | As of _Privileges_ 1.5.0, it is possible to manage settings for _Privileges_ or the _PrivilegesCLI_ command line tool using a macOS configuration profile. [For details, please click here](https://github.com/SAP/macOS-enterprise-privileges/wiki/Managing-Privileges).
78 |
79 |
80 |
81 | # Articles
82 |
83 | See who's talking about _Privileges_…
84 |
85 | 2025
86 | * [Leveling Up - Managing admin rights in the enterprise - Rich Trouton's session at MacAD.UK 2025](https://youtu.be/JSnCdmV_N5U)
87 | * [9To5Mac: Privileges 2.1 continues to be one of the must-have macOS apps in the enterprise](https://9to5mac.com/2025/03/15/privileges-2-1-continues-to-be-one-of-the-must-have-macos-apps-in-the-enterprise/)
88 | * [Caschys Blog: Privileges 2.3.0: Mehr Sicherheit und Kontrolle für Mac-Admins (German language)](https://stadt-bremerhaven.de/privileges-2-3-0-mehr-sicherheit-und-kontrolle-fuer-mac-admins/)
89 |
90 | 2022
91 | * [Mac & i: SAP-Werkzeug erleichtert Arbeit als Standardnutzer (German language)](https://www.heise.de/-7192631)
92 | * [ifun.de: Privileges.app von SAP: Nur noch auf Zuruf zum Admin (German language)](https://www.ifun.de/privileges-app-von-sap-nur-noch-auf-zuruf-zum-admin-191491/)
93 | * [Leveling Up - Rich Trouton's session at MacSysAdmin 2022](https://docs.macsysadmin.se/2022/video/day1session2.mp4)
94 | * [The Great Debate: Admin or Standard Users? - A talk hosted by Kandji](https://youtu.be/LCj59EIKFDg)
95 |
96 | 2019
97 | * [9To5Mac: Privileges for macOS is the open source tool that all Apple IT departments need](https://9to5mac.com/2019/11/16/privileges-app-for-macos/)
98 |
99 |
100 |
101 | # Documentation
102 |
103 | 📚 If you want to learn more about _Privileges_ features, make sure to take a look at our [wiki](https://github.com/SAP/macOS-enterprise-privileges/wiki) or the links below:
104 |
105 | * [Installation](https://github.com/SAP/macOS-enterprise-privileges/wiki/Installation)
106 | * [Uninstallation](https://github.com/SAP/macOS-enterprise-privileges/wiki/Uninstallation)
107 | * [Using Privileges](https://github.com/SAP/macOS-enterprise-privileges/wiki/Using-Privileges)
108 | * [Managing Privileges](https://github.com/SAP/macOS-enterprise-privileges/wiki/Managing-Privileges)
109 | * [Frequently Asked Questions](https://github.com/SAP/macOS-enterprise-privileges/wiki/Frequently-Asked-Questions)
110 |
111 |
112 |
113 | # License
114 |
115 | Copyright (c) 2018-2025 SAP SE or an SAP affiliate company and macOS-enterprise-privileges contributors. Please see our [LICENSE](LICENSE) for copyright and license information. Detailed information including third-party components and their licensing/copyright information is available [via the REUSE tool](https://api.reuse.software/info/github.com/SAP/macOS-enterprise-privileges).
116 |
117 |
118 |
119 | # Security
120 |
121 | Found a security-related issue or vulnerability and want to notify us? [Please see here for how to report it](https://github.com/SAP/macOS-enterprise-privileges/security/policy).
122 |
123 |
124 |
125 | # Support
126 |
127 | This project is 'as-is' with no support, no changes being made. You are welcome to make changes to improve it but we are not available for questions or support of any kind.
128 |
--------------------------------------------------------------------------------
/REUSE.toml:
--------------------------------------------------------------------------------
1 | version = 1
2 | SPDX-PackageName = "macOS-enterprise-privileges"
3 | SPDX-PackageDownloadLocation = "https://github.com/SAP/macOS-enterprise-privileges"
4 | SPDX-PackageComment = "The code in this project may include calls to APIs (“API Calls”) of\n SAP or third-party products or services developed outside of this project\n (“External Products”).\n “APIs” means application programming interfaces, as well as their respective\n specifications and implementing code that allows software to communicate with\n other software.\n API Calls to External Products are not licensed under the open source license\n that governs this project. The use of such API Calls and related External\n Products are subject to applicable additional agreements with the relevant\n provider of the External Products. In no event shall the open source license\n that governs this project grant any rights in or to any External Products,or\n alter, expand or supersede any terms of the applicable additional agreements.\n If you have a valid license agreement with SAP for the use of a particular SAP\n External Product, then you may make use of any API Calls included in this\n project’s code for that SAP External Product, subject to the terms of such\n license agreement. If you do not have a valid license agreement for the use of\n a particular SAP External Product, then you may only make use of any API Calls\n in this project for that SAP External Product for your internal, non-productive\n and non-commercial test and evaluation of such API Calls. Nothing herein grants\n you any rights to use or access any SAP External Product, or provide any third\n parties the right to use of access any SAP External Product, through API Calls."
5 |
6 | [[annotations]]
7 | path = "**"
8 | precedence = "aggregate"
9 | SPDX-FileCopyrightText = "2018-2025 SAP SE or an SAP affiliate company and macOS-enterprise-privileges contributors"
10 | SPDX-License-Identifier = "Apache-2.0"
11 |
--------------------------------------------------------------------------------
/application_management/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Managing Privileges
4 |
5 | For documentation on managing Privileges using configuration profiles, please see the [Managing Privileges](https://github.com/SAP/macOS-enterprise-privileges/wiki/Managing-Privileges) page in our wiki.
6 |
--------------------------------------------------------------------------------
/application_management/example_profiles/Example_EnforcePrivileges.mobileconfig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PayloadContent
6 |
7 |
8 | PayloadContent
9 |
10 | corp.sap.privileges
11 |
12 | Forced
13 |
14 |
15 | mcx_preference_settings
16 |
17 |
27 | EnforcePrivileges
28 | admin
29 |
30 |
31 |
32 |
33 |
34 | PayloadDescription
35 |
36 | PayloadDisplayName
37 | Privileges configuration
38 | PayloadEnabled
39 |
40 | PayloadIdentifier
41 | com.apple.ManagedClient.preferences.3F98C2D8-E845-4F59-B447-16AEA78FB584
42 | PayloadOrganization
43 | SAP SE
44 | PayloadType
45 | com.apple.ManagedClient.preferences
46 | PayloadUUID
47 | 3F98C2D8-E845-4F59-B447-16AEA78FB584
48 | PayloadVersion
49 | 1
50 |
51 |
52 | PayloadDescription
53 | Configures the Privileges app.
54 | PayloadDisplayName
55 | Privileges configuration
56 | PayloadEnabled
57 |
58 | PayloadIdentifier
59 | 5790E5B5-A81D-4E4F-9AB6-6F573CC399DD
60 | PayloadOrganization
61 | SAP SE
62 | PayloadRemovalDisallowed
63 |
64 | PayloadScope
65 | System
66 | PayloadType
67 | Configuration
68 | PayloadUUID
69 | 19BF1861-0134-4BC2-9C83-5E4F2FA96BAE
70 | PayloadVersion
71 | 1
72 |
73 |
74 |
--------------------------------------------------------------------------------
/application_management/example_profiles/Example_ExpirationInterval.mobileconfig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PayloadContent
6 |
7 |
8 | PayloadContent
9 |
10 | corp.sap.privileges
11 |
12 | Forced
13 |
14 |
15 | mcx_preference_settings
16 |
17 |
25 | ExpirationInterval
26 | 15
27 |
28 |
29 |
30 |
31 |
32 | PayloadDescription
33 |
34 | PayloadDisplayName
35 | Privileges configuration
36 | PayloadEnabled
37 |
38 | PayloadIdentifier
39 | com.apple.ManagedClient.preferences.AEC544EE-591D-4834-900E-4C94858E7871
40 | PayloadOrganization
41 | SAP SE
42 | PayloadType
43 | com.apple.ManagedClient.preferences
44 | PayloadUUID
45 | AEC544EE-591D-4834-900E-4C94858E7871
46 | PayloadVersion
47 | 1
48 |
49 |
50 | PayloadDescription
51 | Configures the Privileges app.
52 | PayloadDisplayName
53 | Privileges configuration
54 | PayloadEnabled
55 |
56 | PayloadIdentifier
57 | 82A2ED21-27DA-428E-8516-446A52169C71
58 | PayloadOrganization
59 | SAP SE
60 | PayloadRemovalDisallowed
61 |
62 | PayloadScope
63 | System
64 | PayloadType
65 | Configuration
66 | PayloadUUID
67 | C2F39834-001F-4930-AC7D-E5BA0DE82529
68 | PayloadVersion
69 | 1
70 |
71 |
72 |
--------------------------------------------------------------------------------
/application_management/example_profiles/Example_ExpirationIntervalMax.mobileconfig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PayloadContent
6 |
7 |
8 | PayloadContent
9 |
10 | corp.sap.privileges
11 |
12 | Forced
13 |
14 |
15 | mcx_preference_settings
16 |
17 |
31 | ExpirationIntervalMax
32 | 20
33 |
34 |
35 |
36 |
37 |
38 | PayloadDescription
39 |
40 | PayloadDisplayName
41 | Privileges configuration
42 | PayloadEnabled
43 |
44 | PayloadIdentifier
45 | com.apple.ManagedClient.preferences.8436814F-858D-4875-8552-4263D70478E2
46 | PayloadOrganization
47 | SAP SE
48 | PayloadType
49 | com.apple.ManagedClient.preferences
50 | PayloadUUID
51 | 8436814F-858D-4875-8552-4263D70478E2
52 | PayloadVersion
53 | 1
54 |
55 |
56 | PayloadDescription
57 | Configures the Privileges app.
58 | PayloadDisplayName
59 | Privileges configuration
60 | PayloadEnabled
61 |
62 | PayloadIdentifier
63 | E9DDB703-8D19-40AA-B01D-B6D778E8253D
64 | PayloadOrganization
65 | SAP SE
66 | PayloadRemovalDisallowed
67 |
68 | PayloadScope
69 | System
70 | PayloadType
71 | Configuration
72 | PayloadUUID
73 | C2F39834-001F-4930-AC7D-E5BA0DE82529
74 | PayloadVersion
75 | 1
76 |
77 |
78 |
--------------------------------------------------------------------------------
/application_management/example_profiles/Example_LimitToGroup.mobileconfig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PayloadContent
6 |
7 |
8 | PayloadContent
9 |
10 | corp.sap.privileges
11 |
12 | Forced
13 |
14 |
15 | mcx_preference_settings
16 |
17 |
23 | LimitToGroup
24 |
25 | group_name_goes_here
26 | another_group_name_goes_here
27 |
28 |
29 |
30 |
31 |
32 |
33 | PayloadDescription
34 |
35 | PayloadDisplayName
36 | Privileges configuration
37 | PayloadEnabled
38 |
39 | PayloadIdentifier
40 | com.apple.ManagedClient.preferences.36132147-235E-4663-ADA8-2664C67C4DD2
41 | PayloadOrganization
42 | SAP SE
43 | PayloadType
44 | com.apple.ManagedClient.preferences
45 | PayloadUUID
46 | 36132147-235E-4663-ADA8-2664C67C4DD2
47 | PayloadVersion
48 | 1
49 |
50 |
51 | PayloadDescription
52 | Configures the Privileges app.
53 | PayloadDisplayName
54 | Privileges configuration
55 | PayloadEnabled
56 |
57 | PayloadIdentifier
58 | CF401A42-35CA-4DA6-9123-5A49C87ECB5A
59 | PayloadOrganization
60 | SAP SE
61 | PayloadRemovalDisallowed
62 |
63 | PayloadScope
64 | System
65 | PayloadType
66 | Configuration
67 | PayloadUUID
68 | 50870D16-7AAD-478B-BFFE-BED09499F7E0
69 | PayloadVersion
70 | 1
71 |
72 |
73 |
--------------------------------------------------------------------------------
/application_management/example_profiles/Example_LimitToUser.mobileconfig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PayloadContent
6 |
7 |
8 | PayloadContent
9 |
10 | corp.sap.privileges
11 |
12 | Forced
13 |
14 |
15 | mcx_preference_settings
16 |
17 |
25 | LimitToUser
26 |
27 | username_goes_here
28 | another_username_goes_here
29 |
30 |
31 |
32 |
33 |
34 |
35 | PayloadDescription
36 |
37 | PayloadDisplayName
38 | Privileges configuration
39 | PayloadEnabled
40 |
41 | PayloadIdentifier
42 | com.apple.ManagedClient.preferences.36132147-235E-4663-ADA8-2664C67C4DD2
43 | PayloadOrganization
44 | SAP SE
45 | PayloadType
46 | com.apple.ManagedClient.preferences
47 | PayloadUUID
48 | 36132147-235E-4663-ADA8-2664C67C4DD2
49 | PayloadVersion
50 | 1
51 |
52 |
53 | PayloadDescription
54 | Configures the Privileges app.
55 | PayloadDisplayName
56 | Privileges configuration
57 | PayloadEnabled
58 |
59 | PayloadIdentifier
60 | CF401A42-35CA-4DA6-9123-5A49C87ECB5A
61 | PayloadOrganization
62 | SAP SE
63 | PayloadRemovalDisallowed
64 |
65 | PayloadScope
66 | System
67 | PayloadType
68 | Configuration
69 | PayloadUUID
70 | 50870D16-7AAD-478B-BFFE-BED09499F7E0
71 | PayloadVersion
72 | 1
73 |
74 |
75 |
--------------------------------------------------------------------------------
/application_management/example_profiles/Example_ReasonRequired.mobileconfig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PayloadContent
6 |
7 |
8 | PayloadContent
9 |
10 | corp.sap.privileges
11 |
12 | Forced
13 |
14 |
15 | mcx_preference_settings
16 |
17 |
26 | ReasonRequired
27 |
28 |
29 |
38 | ReasonMinLength
39 | 20
40 |
41 |
51 | ReasonMaxLength
52 | 50
53 |
54 |
63 | ReasonPresetList
64 |
65 |
66 | default
67 | Just for fun
68 |
69 |
70 | default
71 | For installing software
72 |
73 |
74 | default
75 | Don't know
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | PayloadDescription
84 |
85 | PayloadDisplayName
86 | Privileges configuration
87 | PayloadEnabled
88 |
89 | PayloadIdentifier
90 | com.apple.ManagedClient.preferences.36132147-235E-4663-ADA8-2664C67C4DD2
91 | PayloadOrganization
92 | SAP SE
93 | PayloadType
94 | com.apple.ManagedClient.preferences
95 | PayloadUUID
96 | 36132147-235E-4663-ADA8-2664C67C4DD2
97 | PayloadVersion
98 | 1
99 |
100 |
101 | PayloadDescription
102 | Configures the Privileges app.
103 | PayloadDisplayName
104 | Privileges configuration
105 | PayloadEnabled
106 |
107 | PayloadIdentifier
108 | CF401A42-35CA-4DA6-9123-5A49C87ECB5A
109 | PayloadOrganization
110 | SAP SE
111 | PayloadRemovalDisallowed
112 |
113 | PayloadScope
114 | System
115 | PayloadType
116 | Configuration
117 | PayloadUUID
118 | 50870D16-7AAD-478B-BFFE-BED09499F7E0
119 | PayloadVersion
120 | 1
121 |
122 |
123 |
--------------------------------------------------------------------------------
/application_management/example_profiles/Example_RequireAuthentication.mobileconfig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PayloadContent
6 |
7 |
8 | PayloadContent
9 |
10 | corp.sap.privileges
11 |
12 | Forced
13 |
14 |
15 | mcx_preference_settings
16 |
17 |
27 | RequireAuthentication
28 |
29 |
30 |
38 | AllowCLIBiometricAuthentication
39 |
40 |
41 |
42 |
43 |
44 |
45 | PayloadDescription
46 |
47 | PayloadDisplayName
48 | Privileges configuration
49 | PayloadEnabled
50 |
51 | PayloadIdentifier
52 | com.apple.ManagedClient.preferences.36132147-235E-4663-ADA8-2664C67C4DD2
53 | PayloadOrganization
54 | SAP SE
55 | PayloadType
56 | com.apple.ManagedClient.preferences
57 | PayloadUUID
58 | 36132147-235E-4663-ADA8-2664C67C4DD2
59 | PayloadVersion
60 | 1
61 |
62 |
63 | PayloadDescription
64 | Configures the Privileges app.
65 | PayloadDisplayName
66 | Privileges configuration
67 | PayloadEnabled
68 |
69 | PayloadIdentifier
70 | CF401A42-35CA-4DA6-9123-5A49C87ECB5A
71 | PayloadOrganization
72 | SAP SE
73 | PayloadRemovalDisallowed
74 |
75 | PayloadScope
76 | System
77 | PayloadType
78 | Configuration
79 | PayloadUUID
80 | 50870D16-7AAD-478B-BFFE-BED09499F7E0
81 | PayloadVersion
82 | 1
83 |
84 |
85 |
--------------------------------------------------------------------------------
/readme_images/CommandLine.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/CommandLine.png
--------------------------------------------------------------------------------
/readme_images/DemoGIF.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/DemoGIF.gif
--------------------------------------------------------------------------------
/readme_images/DemoGIFviaDock.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/DemoGIFviaDock.gif
--------------------------------------------------------------------------------
/readme_images/DockIconCountDown 1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/DockIconCountDown 1.png
--------------------------------------------------------------------------------
/readme_images/IllustrationAppComponents.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/IllustrationAppComponents.png
--------------------------------------------------------------------------------
/readme_images/ManagedDockIcons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/ManagedDockIcons.png
--------------------------------------------------------------------------------
/readme_images/PrivilegesGranted.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/PrivilegesGranted.jpg
--------------------------------------------------------------------------------
/readme_images/PrivilegesRevoked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/PrivilegesRevoked.png
--------------------------------------------------------------------------------
/readme_images/PrivilegesToogleViaDock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/PrivilegesToogleViaDock.png
--------------------------------------------------------------------------------
/readme_images/RequestPrivilegesWindow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/RequestPrivilegesWindow.png
--------------------------------------------------------------------------------
/readme_images/RevertPrivilegesWindow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/RevertPrivilegesWindow.png
--------------------------------------------------------------------------------
/readme_images/RunAppWhenPrivilegeChange.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/RunAppWhenPrivilegeChange.gif
--------------------------------------------------------------------------------
/readme_images/UninstallationWindow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/UninstallationWindow.png
--------------------------------------------------------------------------------
/readme_images/console_show_privileges_process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/console_show_privileges_process.png
--------------------------------------------------------------------------------
/readme_images/console_show_privileges_process_filtered_for_admin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/console_show_privileges_process_filtered_for_admin.png
--------------------------------------------------------------------------------
/readme_images/github banner new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/github banner new.png
--------------------------------------------------------------------------------
/readme_images/locked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/locked.png
--------------------------------------------------------------------------------
/readme_images/locked_managed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/locked_managed.png
--------------------------------------------------------------------------------
/readme_images/log_show_privileges_process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/log_show_privileges_process.png
--------------------------------------------------------------------------------
/readme_images/log_show_privileges_process_filtered_for_admin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/log_show_privileges_process_filtered_for_admin.png
--------------------------------------------------------------------------------
/readme_images/renewal_custom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/renewal_custom.png
--------------------------------------------------------------------------------
/readme_images/settings_general.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/settings_general.png
--------------------------------------------------------------------------------
/readme_images/settings_managed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/settings_managed.png
--------------------------------------------------------------------------------
/readme_images/settings_privileges.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/settings_privileges.png
--------------------------------------------------------------------------------
/readme_images/unlocked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/unlocked.png
--------------------------------------------------------------------------------
/readme_images/unlocked_managed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/readme_images/unlocked_managed.png
--------------------------------------------------------------------------------
/source/Privileges.xcodeproj/project.xcworkspace/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/Privileges.xcodeproj/project.xcworkspace/.DS_Store
--------------------------------------------------------------------------------
/source/Privileges.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/source/Privileges.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/source/Privileges.xcodeproj/xcshareddata/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/Privileges.xcodeproj/xcshareddata/.DS_Store
--------------------------------------------------------------------------------
/source/Privileges.xcodeproj/xcshareddata/xcschemes/Privileges Beta.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
9 |
10 |
16 |
22 |
23 |
24 |
25 |
26 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
60 |
62 |
68 |
69 |
70 |
71 |
73 |
74 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/source/Privileges.xcodeproj/xcshareddata/xcschemes/Privileges.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
9 |
10 |
16 |
22 |
23 |
24 |
25 |
26 |
31 |
32 |
35 |
36 |
37 |
38 |
48 |
50 |
56 |
57 |
58 |
59 |
65 |
67 |
73 |
74 |
75 |
76 |
78 |
79 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/source/Privileges/AppDelegate.h:
--------------------------------------------------------------------------------
1 | /*
2 | AppDelegate.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 |
20 | @interface AppDelegate : NSObject
21 |
22 | @end
23 |
24 |
--------------------------------------------------------------------------------
/source/Privileges/AppleScript sample.scpt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/Privileges/AppleScript sample.scpt
--------------------------------------------------------------------------------
/source/Privileges/Beta-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSDockTilePlugIn
6 | PrivilegesTile.docktileplugin
7 |
8 |
9 |
--------------------------------------------------------------------------------
/source/Privileges/Credits.rtf:
--------------------------------------------------------------------------------
1 | {\rtf1\ansi\ansicpg1252\cocoartf2761
2 | \cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 SFPro-Regular;}
3 | {\colortbl;\red255\green255\blue255;\red0\green0\blue0;\red0\green0\blue0;}
4 | {\*\expandedcolortbl;;\cssrgb\c0\c0\c0\c49804\cname secondaryLabelColor;\csgray\c0\c0;}
5 | \paperw11900\paperh16840\vieww20740\viewh8340\viewkind0
6 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc\partightenfactor0
7 |
8 | \f0\fs20 \cf2 \cb3 \
9 | Design & Engineering\
10 | Marc Thielemann\
11 | \
12 | \pard\pardeftab720\qc\partightenfactor0
13 | \cf2 \expnd0\expndtw0\kerning0
14 | This application can be redistributed\
15 | and modified under \kerning1\expnd0\expndtw0 the\
16 | \pard\pardeftab720\qc\partightenfactor0
17 | {\field{\*\fldinst{HYPERLINK "http://www.apache.org/licenses/LICENSE-2.0"}}{\fldrslt \cf2 Apache License, Version 2.0}}\expnd0\expndtw0\kerning0
18 | \
19 | }
--------------------------------------------------------------------------------
/source/Privileges/MTReasonAccessory.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/source/Privileges/Privileges-ParentConstraint.coderequirement:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | is-init-proc
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/source/Privileges/Privileges-SelfConstraint.coderequirement:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | launch-type
6 | 3
7 |
8 |
9 |
--------------------------------------------------------------------------------
/source/Privileges/Privileges.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.application-groups
8 |
9 | $(TeamIdentifierPrefix)corp.sap.privileges
10 |
11 | com.apple.security.files.user-selected.read-only
12 |
13 | com.apple.security.temporary-exception.shared-preference.read-write
14 | corp.sap.privileges.docktileplugin
15 |
16 |
17 |
--------------------------------------------------------------------------------
/source/Privileges/Release-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSDockTilePlugIn
6 | PrivilegesTile.docktileplugin
7 |
8 |
9 |
--------------------------------------------------------------------------------
/source/Privileges/View Controllers/MTReasonAccessoryController.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTReasonAccessoryController.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 |
20 | @interface MTReasonAccessoryController : NSViewController
21 | @property (weak) IBOutlet NSPopUpButton *predefinedReasonsButton;
22 | @property (weak) IBOutlet NSTextField *reasonTextField;
23 | @end
24 |
--------------------------------------------------------------------------------
/source/Privileges/View Controllers/MTReasonAccessoryController.m:
--------------------------------------------------------------------------------
1 | /*
2 | MTReasonAccessoryController.m
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import "MTReasonAccessoryController.h"
19 | #import "MTPrivileges.h"
20 | #import "Constants.h"
21 |
22 | @interface MTReasonAccessoryController ()
23 | @property (nonatomic, strong, readwrite) NSString *reasonPlaceHolder;
24 | @end
25 |
26 | @implementation MTReasonAccessoryController
27 |
28 | - (void)viewDidLoad
29 | {
30 | [super viewDidLoad];
31 |
32 | MTPrivileges *privilegesApp = [[MTPrivileges alloc] init];
33 |
34 | [_predefinedReasonsButton setHidden:YES];
35 | [[_predefinedReasonsButton menu] removeAllItems];
36 |
37 | NSInteger minLength = [privilegesApp reasonMinLength];
38 | _reasonPlaceHolder = [NSString localizedStringWithFormat:NSLocalizedString(@"minLengthPlaceholder", nil), minLength];
39 |
40 | [_reasonTextField setPlaceholderString:_reasonPlaceHolder];
41 |
42 | // create the menu with pre-defined reasons (if configured)
43 | if ([privilegesApp reasonRequired]) {
44 |
45 | NSArray *predefinedReasons = [privilegesApp predefinedReasons];
46 |
47 | if (predefinedReasons && [predefinedReasons count] > 0) {
48 |
49 | NSMutableArray *allReasons = [[NSMutableArray alloc] init];
50 | NSString *languageCode = [[NSLocale currentLocale] languageCode];
51 |
52 | for (NSDictionary *aReason in predefinedReasons) {
53 |
54 | if ([aReason isKindOfClass:[NSDictionary class]]) {
55 | NSString *localizedReasonString = [aReason objectForKey:languageCode];
56 | if (!localizedReasonString) { localizedReasonString = [aReason objectForKey:@"default"]; }
57 | if (!localizedReasonString) { localizedReasonString = [aReason objectForKey:@"en"]; }
58 | if (localizedReasonString) { [allReasons addObject:localizedReasonString]; }
59 | }
60 | }
61 |
62 | if ([allReasons count] > 0) {
63 |
64 | [allReasons insertObject:NSLocalizedString(@"otherMenuEntry", nil) atIndex:0];
65 |
66 | for (NSString *aReason in allReasons) {
67 |
68 | [[_predefinedReasonsButton menu] addItemWithTitle:aReason
69 | action:nil
70 | keyEquivalent:@""
71 | ];
72 | }
73 |
74 | [_predefinedReasonsButton setHidden:NO];
75 | }
76 | }
77 | }
78 | }
79 |
80 | - (IBAction)selectPredefinedReason:(id)sender
81 | {
82 | if ([_predefinedReasonsButton indexOfSelectedItem] == 0) {
83 |
84 | [_reasonTextField setEnabled:YES];
85 | [_reasonTextField setTextColor:[NSColor textColor]];
86 | [_reasonTextField setPlaceholderString:_reasonPlaceHolder];
87 | [_reasonTextField selectText:nil];
88 |
89 | } else {
90 |
91 | [_reasonTextField setEnabled:NO];
92 | [_reasonTextField setTextColor:[NSColor clearColor]];
93 | [_reasonTextField setPlaceholderString:nil];
94 | }
95 | }
96 |
97 | @end
98 |
--------------------------------------------------------------------------------
/source/Privileges/View Controllers/MTSettingsGeneralController.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTSettingsGeneralController.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 |
20 | @interface MTSettingsGeneralController : NSViewController
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/source/Privileges/View Controllers/MTSettingsGeneralController.m:
--------------------------------------------------------------------------------
1 | /*
2 | MTSettingsGeneralController.m
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import "MTSettingsGeneralController.h"
19 | #import "MTPrivileges.h"
20 | #import "Constants.h"
21 |
22 | @interface MTSettingsGeneralController ()
23 | @property (retain) id configurationObserver;
24 | @property (nonatomic, strong, readwrite) MTPrivileges *privilegesApp;
25 | @property (nonatomic, strong, readwrite) NSString *configuredByProfileLabel;
26 |
27 | @property (weak) IBOutlet NSButton *hideWindowsButton;
28 | @property (weak) IBOutlet NSButton *menuBarButton;
29 | @end
30 |
31 | @implementation MTSettingsGeneralController
32 |
33 | - (void)viewDidLoad
34 | {
35 | [super viewDidLoad];
36 |
37 | [[[self view] window] setAccessibilityLabel:[[[self view] window] title]];
38 | [[[self view] window] setAccessibilityEnabled:YES];
39 |
40 | _privilegesApp = [[MTPrivileges alloc] init];
41 |
42 | // set the initial state of the "Hide other windows" checkbox
43 | [self setHideWindowsCheckbox];
44 |
45 | // set the initial state of the "Show in Menu Bar" checkbox
46 | [self setMenuBarCheckbox];
47 |
48 | self.configuredByProfileLabel = NSLocalizedString(@"configuredByProfileLabel", nil);
49 |
50 | _configurationObserver = [[NSDistributedNotificationCenter defaultCenter] addObserverForName:kMTNotificationNameConfigDidChange
51 | object:nil
52 | queue:nil
53 | usingBlock:^(NSNotification *notification) {
54 | NSDictionary *userInfo = [notification userInfo];
55 |
56 | if (userInfo) {
57 |
58 | NSString *changedKey = [userInfo objectForKey:kMTNotificationKeyPreferencesChanged];
59 |
60 | NSArray *keysToObserve = [[NSArray alloc] initWithObjects:
61 | kMTDefaultsHideOtherWindowsKey,
62 | kMTDefaultsShowInMenuBarKey,
63 | nil
64 | ];
65 |
66 | if (changedKey && [keysToObserve containsObject:changedKey]) {
67 |
68 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
69 |
70 | if ([changedKey isEqualToString:kMTDefaultsHideOtherWindowsKey]) {
71 |
72 | [self setHideWindowsCheckbox];
73 |
74 | } else if ([changedKey isEqualToString:kMTDefaultsShowInMenuBarKey]) {
75 |
76 | [self setMenuBarCheckbox];
77 | }
78 | });
79 | }
80 | }
81 | }];
82 | }
83 |
84 | - (void)setHideWindowsCheckbox
85 | {
86 | [self willChangeValueForKey:@"hideWindowsIsForced"];
87 | [_hideWindowsButton setState:([_privilegesApp hideOtherWindows]) ? NSControlStateValueOn : NSControlStateValueOff];
88 | [_hideWindowsButton setEnabled:![_privilegesApp hideOtherWindowsIsForced]];
89 | [self didChangeValueForKey:@"hideWindowsIsForced"];
90 | }
91 |
92 | - (void)setMenuBarCheckbox
93 | {
94 | [self willChangeValueForKey:@"menuBarIsForced"];
95 | [_menuBarButton setState:([_privilegesApp showInMenuBar]) ? NSControlStateValueOn : NSControlStateValueOff];
96 | [_menuBarButton setEnabled:![_privilegesApp showInMenuBarIsForced]];
97 | [self didChangeValueForKey:@"menuBarIsForced"];
98 | }
99 |
100 | - (void)dealloc
101 | {
102 | [[NSDistributedNotificationCenter defaultCenter] removeObserver:_configurationObserver];
103 | _configurationObserver = nil;
104 | }
105 |
106 | #pragma mark Bindings
107 |
108 | - (BOOL)hideWindowsIsForced
109 | {
110 | return [_privilegesApp hideOtherWindowsIsForced];
111 | }
112 |
113 | - (BOOL)menuBarIsForced
114 | {
115 | return [_privilegesApp showInMenuBarIsForced];
116 | }
117 |
118 |
119 | #pragma mark IBActions
120 |
121 | - (IBAction)setHideOtherWindows:(id)sender
122 | {
123 | [_privilegesApp setHideOtherWindows:([(NSButton*)sender state] == NSControlStateValueOn)];
124 | }
125 |
126 | - (IBAction)setShowInMenuBar:(id)sender
127 | {
128 | [_privilegesApp setShowInMenuBar:([(NSButton*)sender state] == NSControlStateValueOn)];
129 | }
130 |
131 | @end
132 |
--------------------------------------------------------------------------------
/source/Privileges/View Controllers/MTSettingsPrivilegesController.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTSettingsPrivilegesController.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 |
20 | @interface MTSettingsPrivilegesController : NSViewController
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/source/Privileges/View Controllers/MTTabViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTTabViewController.h
3 | Copyright 2023-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 |
20 | @interface MTTabViewController : NSTabViewController
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/source/Privileges/View Controllers/MTTabViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | MTTabViewController.m
3 | Copyright 2023-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import "MTTabViewController.h"
19 | #import "Constants.h"
20 |
21 | @interface MTTabViewController ()
22 | @property (assign) BOOL allowSelection;
23 | @end
24 |
25 | @implementation MTTabViewController
26 |
27 | - (void)viewDidLoad
28 | {
29 | [super viewDidLoad];
30 |
31 | // select the last tab the user selected
32 | NSInteger selectedTabIndex = [[NSUserDefaults standardUserDefaults] integerForKey:kMTDefaultsSettingsSelectedTabKey];
33 | _allowSelection = YES;
34 |
35 | if (selectedTabIndex >= 0 && selectedTabIndex < [[self tabViewItems] count]) {
36 | [self setSelectedTabViewItemIndex:selectedTabIndex];
37 | } else {
38 | [self setSelectedTabViewItemIndex:0];
39 | }
40 | }
41 |
42 | - (void)viewWillAppear
43 | {
44 | [super viewWillAppear];
45 | [self updateWindowTitle];
46 | }
47 |
48 | - (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem
49 | {
50 | [super tabView:tabView didSelectTabViewItem:tabViewItem];
51 | [self updateWindowTitle];
52 |
53 | // we ignore the initial tab selection (the one we had to define in Xcode)
54 | if (_allowSelection) {
55 |
56 | [[NSUserDefaults standardUserDefaults] setInteger:[tabView indexOfTabViewItem:[tabView selectedTabViewItem]]
57 | forKey:kMTDefaultsSettingsSelectedTabKey
58 | ];
59 | }
60 | }
61 |
62 | - (void)updateWindowTitle
63 | {
64 | // set the window title to the label of the selected tab
65 | NSTabViewItem *selectedItem = [[self tabView] selectedTabViewItem];
66 | [[[self tabView] window] setTitle:[selectedItem label]];
67 | }
68 |
69 | @end
70 |
--------------------------------------------------------------------------------
/source/Privileges/corp.sap.privileges.agent.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | MachServices
6 |
7 | corp.sap.privileges.agent.xpc
8 |
9 |
10 | Label
11 | corp.sap.privileges.agent
12 | Program
13 | /Applications/Privileges.app/Contents/MacOS/PrivilegesAgent.app/Contents/MacOS/PrivilegesAgent
14 | AssociatedBundleIdentifiers
15 | corp.sap.privileges
16 | SpawnConstraint
17 |
18 | team-identifier
19 | 7R5ZEU67FQ
20 | signing-identifier
21 | corp.sap.privileges.agent
22 |
23 | RunAtLoad
24 |
25 | KeepAlive
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/source/Privileges/corp.sap.privileges.daemon.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | MachServices
6 |
7 | corp.sap.privileges.daemon.xpc
8 |
9 |
10 | Label
11 | corp.sap.privileges.daemon
12 | Program
13 | /Applications/Privileges.app/Contents/MacOS/PrivilegesDaemon
14 | AssociatedBundleIdentifiers
15 | corp.sap.privileges
16 | SpawnConstraint
17 |
18 | team-identifier
19 | 7R5ZEU67FQ
20 | signing-identifier
21 | corp.sap.privileges.daemon
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/source/Privileges/corp.sap.privileges.watcher.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Label
6 | corp.sap.privileges.watcher
7 | Program
8 | /Applications/Privileges.app/Contents/MacOS/PrivilegesWatcher
9 | WatchPaths
10 |
11 | /var/db/dslocal/nodes/Default/groups/admin.plist
12 |
13 | AssociatedBundleIdentifiers
14 | corp.sap.privileges
15 | SpawnConstraint
16 |
17 | team-identifier
18 | 7R5ZEU67FQ
19 | signing-identifier
20 | corp.sap.privileges.watcher
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/source/Privileges/main.m:
--------------------------------------------------------------------------------
1 | /*
2 | main.m
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 |
20 | int main(int argc, const char * argv[])
21 | {
22 | return NSApplicationMain(argc, argv);
23 | }
24 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/AppDelegate.h:
--------------------------------------------------------------------------------
1 | /*
2 | AppDelegate.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 | #import "MTLocalNotification.h"
20 |
21 | /*!
22 | @protocol AppleScriptDataProvider
23 | @abstract Defines an interface for accessing some of the PrivilegesAgent's values via AppleScript.
24 | */
25 | @protocol AppleScriptDataProvider
26 |
27 | /*!
28 | @method privilegesTimeLeft
29 | @abstract Get the number of minutes remaining until the current user's administrator privileges expire.
30 | @discussion Returns the number of minutes remaining until the current user's administrator privileges expire,
31 | or 0 if the user does not have administrator privileges.
32 | */
33 | - (NSUInteger)privilegesTimeLeft;
34 |
35 | /*!
36 | @method userHasAdminPrivileges:
37 | @abstract Get whether the current user has administrator privileges.
38 | @discussion Returns YES if the current user has administrator privileges, otherwise returns NO.
39 | */
40 | - (BOOL)userHasAdminPrivileges;
41 |
42 | @end
43 |
44 | @interface AppDelegate : NSObject
45 |
46 | @end
47 |
48 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/Classes/MTClientCertificate.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTClientCertificate.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 |
20 | /*!
21 | @class MTClientCertificate
22 | @abstract A class that provides methods to find a matching identity for a given distinguished name.
23 | */
24 |
25 | @interface MTClientCertificate : NSObject
26 |
27 | /*!
28 | @method init
29 | @discussion The init method is not available. Please use initWithinitWithDistinguishedName: instead.
30 | */
31 | - (instancetype)init NS_UNAVAILABLE;
32 |
33 | /*!
34 | @method initWithinitWithDistinguishedName:
35 | @abstract Initialize a MTClientCertificate object with a given NSData object containing a DER
36 | encoded distinguished name.
37 | @param encodedData The DER-encoded distinguished name.
38 | @discussion Returns an initialized MTClientCertificate object or nil if an error occurred.
39 | */
40 | - (instancetype)initWithDistinguishedName:(NSData*)encodedData NS_DESIGNATED_INITIALIZER;
41 |
42 | /*!
43 | @method dictionaryRepresentation
44 | @abstract Get a dictionary representation of the DN containing all its OIDs and their respective values.
45 | @discussion Returns a NSDictionary with OIDs and its values or nil if an error occurred.
46 | */
47 | - (NSDictionary*)dictionaryRepresentation;
48 |
49 | /*!
50 | @method matchingIdentityWithSecItems:
51 | @abstract Initialize a MTClientCertificate object with a given NSData object containing a DER
52 | encoded distinguished name.
53 | @param secItems An array of SecIdentityRef.
54 | @discussion Returns the first SecIdentityRef that matches the DN the MTClientCertificate object
55 | has been initialized with or nil if an error occurred.
56 | */
57 | - (SecIdentityRef)matchingIdentityWithSecItems:(NSArray*)secItems;
58 |
59 | @end
60 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/Classes/MTDaemonConnection.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTDaemonConnection.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 | #import "PrivilegesDaemonProtocol.h"
20 | #import
21 | #import
22 |
23 | /*!
24 | @class MTDaemonConnection
25 | @abstract A class that provides an easy way to connect to the Privileges daemon.
26 | */
27 |
28 | @interface MTDaemonConnection : NSObject
29 |
30 | /*!
31 | @property connection
32 | @abstract A property to store the connection object.
33 | @discussion The value of this property is NSXPCConnection.
34 | */
35 | @property (atomic, strong, readonly) NSXPCConnection *connection;
36 |
37 | /*!
38 | @method connectToDaemonWithExportedObject:andExecuteCommandBlock:
39 | @abstract Connects to the daemon and executes the given command block.
40 | @param commandBlock The command block that should be executed after the connection has been established.
41 | */
42 | - (void)connectToDaemonAndExecuteCommandBlock:(void(^)(void))commandBlock;
43 |
44 | /*!
45 | @method invalidate
46 | @abstract Invalidates the connection to the daemon (and xpc service).
47 | */
48 | - (void)invalidate;
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/Classes/MTDaemonConnection.m:
--------------------------------------------------------------------------------
1 | /*
2 | MTDaemonConnection.m
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import "MTDaemonConnection.h"
19 | #import "Constants.h"
20 |
21 | @interface MTDaemonConnection ()
22 | @property (atomic, strong, readwrite) NSXPCConnection *connection;
23 | @property (atomic, strong, readwrite) NSXPCListenerEndpoint *listenerEndpoint;
24 | @property (nonatomic, strong, readwrite) NSTimer *xpcTimeoutTimer;
25 | @end
26 |
27 |
28 | @implementation MTDaemonConnection
29 |
30 | - (void)connectToDaemonAndExecuteCommandBlock:(void(^)(void))commandBlock
31 | {
32 | if (!_connection) {
33 |
34 | _connection = [[NSXPCConnection alloc] initWithMachServiceName:kMTDaemonMachServiceName
35 | options:NSXPCConnectionPrivileged
36 | ];
37 | [_connection setRemoteObjectInterface:[NSXPCInterface interfaceWithProtocol:@protocol(PrivilegesDaemonProtocol)]];
38 |
39 | #pragma clang diagnostic push
40 | #pragma clang diagnostic ignored "-Warc-retain-cycles"
41 | [_connection setInvalidationHandler:^{
42 |
43 | [self->_connection setInvalidationHandler:nil];
44 | dispatch_async(dispatch_get_main_queue(), ^{
45 | os_log(OS_LOG_DEFAULT, "SAPCorp: Daemon connection invalidated");
46 | self->_connection = nil;
47 | });
48 | }];
49 |
50 | [_connection setInterruptionHandler:^{
51 |
52 | [self->_connection setInterruptionHandler:nil];
53 | dispatch_async(dispatch_get_main_queue(), ^{
54 | os_log(OS_LOG_DEFAULT, "SAPCorp: Daemon connection interrupted");
55 | self->_connection = nil;
56 | });
57 | }];
58 | #pragma clang diagnostic pop
59 |
60 | [_connection resume];
61 | }
62 |
63 | // and execute the command block
64 | commandBlock();
65 |
66 | dispatch_async(dispatch_get_main_queue(), ^{
67 |
68 | self->_xpcTimeoutTimer = [NSTimer scheduledTimerWithTimeInterval:60
69 | repeats:NO
70 | block:^(NSTimer *timer) {
71 | [self invalidate];
72 | }];
73 | });
74 | }
75 |
76 | - (void)invalidate
77 | {
78 | if (_connection) { [_connection invalidate]; }
79 | }
80 |
81 | @end
82 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/Classes/MTLocalNotification.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTLocalNotification.h
3 | Copyright 2022-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 | #import
20 |
21 | @interface MTLocalNotification : NSObject
22 |
23 | /*!
24 | @enum MTLocalNotificationType
25 | @abstract Specifies the type of a notification.
26 | @constant MTLocalNotificationTypeNoChange Specifies a notification that informs the user that privileges have not been changed.
27 | @constant MTLocalNotificationTypeGrantSuccess Specifies a notification that informs the user that administrator privileges have been granted.
28 | @constant MTLocalNotificationTypeRevokeSuccess Specifies a notification that informs the user that administrator privileges have been revoked.
29 | @constant MTLocalNotificationTypeError Specifies a notification that informs the user that privileges could not be changed due to an error.
30 | @constant MTLocalNotificationTypeRenew Specifies a notification that informs the user that administrator privileges are about to expire and asks to renew privileges.
31 | @constant MTLocalNotificationTypeRenewSuccess Specifies a notification that informs the user that administrator privileges have been renewed.
32 | */
33 | typedef enum {
34 | MTLocalNotificationTypeNoChange = 0,
35 | MTLocalNotificationTypeGrantSuccess = 1,
36 | MTLocalNotificationTypeRevokeSuccess = 2,
37 | MTLocalNotificationTypeError = 3,
38 | MTLocalNotificationTypeRenew = 4,
39 | MTLocalNotificationTypeRenewSuccess = 5,
40 | } MTLocalNotificationType;
41 |
42 | @property (nonatomic, strong, readwrite) NSArray *actions;
43 | @property (nonatomic, strong, readwrite) NSString *categoryIdentifier;
44 | @property (weak) id delegate;
45 |
46 | /*!
47 | @method requestAuthorizationWithCompletionHandler:
48 | @abstract Requests a user's authorization to allow local and remote notifications for the app.
49 | @param completionHandler The handler to call when the request is complete.
50 | @discussion Returns YES if the user granted authorization, otherwise returns NO. In case of an error the error object might contain
51 | information about the error that caused the operation to fail.
52 | */
53 | - (void)requestAuthorizationWithCompletionHandler:(void (^)(BOOL granted, NSError *error))completionHandler;
54 |
55 | /*!
56 | @method sendNotificationWithTitle:message:userInfo:replaceExisting:
57 | @abstract Sends a notification to the user notificatiion center.
58 | @param title The title of the notification.
59 | @param message The notification body (the message).
60 | @param userInfo An optional dictionary containing custom data to associate with the notification.
61 | @param replaceExisting A boolean specifying if existing notification should be removed or not.
62 | @param action A boolean specifying if the notification should have an action attached.
63 | @param completionHandler The handler to call when the request is complete.
64 | @discussion The returned error object might contain error information if an error occurred or will be nil if no error occurred.
65 | */
66 | - (void)sendNotificationWithTitle:(NSString*)title
67 | message:(NSString*)message
68 | userInfo:(NSDictionary*)userInfo
69 | replaceExisting:(BOOL)replaceExisting
70 | action:(BOOL)action
71 | completionHandler:(void (^)(NSError *error))completionHandler;
72 |
73 | @end
74 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/Classes/MTLocalNotification.m:
--------------------------------------------------------------------------------
1 | /*
2 | MTLocalNotification.m
3 | Copyright 2022-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import "MTLocalNotification.h"
19 | #import "Constants.h"
20 |
21 | @implementation MTLocalNotification
22 |
23 | - (void)requestAuthorizationWithCompletionHandler:(void (^)(BOOL granted, NSError *error))completionHandler
24 | {
25 | UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
26 | [center requestAuthorizationWithOptions:(
27 | UNAuthorizationOptionAlert |
28 | UNAuthorizationOptionSound |
29 | UNAuthorizationOptionBadge
30 | )
31 | completionHandler:^(BOOL granted, NSError *error) {
32 | if (completionHandler) { completionHandler(granted, error); }
33 | }];
34 | }
35 |
36 | - (void)sendNotificationWithTitle:(NSString*)title
37 | message:(NSString*)message
38 | userInfo:(NSDictionary*)userInfo
39 | replaceExisting:(BOOL)replaceExisting
40 | action:(BOOL)action
41 | completionHandler:(void (^)(NSError *error))completionHandler;
42 | {
43 |
44 |
45 | UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
46 | [center setDelegate:_delegate];
47 |
48 | UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
49 | [content setTitle:title];
50 | [content setBody:message];
51 | [content setSound:[UNNotificationSound defaultSound]];
52 | [content setUserInfo:userInfo];
53 |
54 | if (action && [_actions count] > 0 && _categoryIdentifier) {
55 |
56 | UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:_categoryIdentifier
57 | actions:_actions
58 | intentIdentifiers:[NSArray new]
59 | options:UNNotificationCategoryOptionCustomDismissAction
60 | ];
61 |
62 | [content setCategoryIdentifier:_categoryIdentifier];
63 | [center setNotificationCategories:[NSSet setWithObject:category]];
64 | }
65 |
66 | UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:[[NSUUID UUID] UUIDString]
67 | content:content
68 | trigger:nil
69 | ];
70 |
71 | // remove existing notifications
72 | if (replaceExisting) {
73 | [center removeAllDeliveredNotifications];
74 | [NSThread sleepForTimeInterval:.5];
75 | }
76 |
77 | [center addNotificationRequest:request
78 | withCompletionHandler:^(NSError *error) {
79 |
80 | if (completionHandler) { completionHandler(error); }
81 | }];
82 | }
83 |
84 | @end
85 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/Classes/MTPrivilegeExpirationCommand.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTPrivilegeExpirationCommand.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 |
20 | /*!
21 | @class MTPrivilegeExpirationCommand
22 | @abstract This class contains the code for the AppleScript command "expiration of administrator privileges".
23 | */
24 |
25 | @interface MTPrivilegeExpirationCommand : NSScriptCommand
26 |
27 | @end
28 |
29 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/Classes/MTPrivilegeExpirationCommand.m:
--------------------------------------------------------------------------------
1 | /*
2 | MTPrivilegeExpirationCommand.m
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import "MTPrivilegeExpirationCommand.h"
19 | #import "AppDelegate.h"
20 |
21 | @implementation MTPrivilegeExpirationCommand
22 |
23 | - (id)performDefaultImplementation
24 | {
25 | NSUInteger timeLeft = 0;
26 | AppDelegate *appDelegate = (AppDelegate*)[NSApp delegate];
27 |
28 | if ([appDelegate conformsToProtocol:@protocol(AppleScriptDataProvider)]) {
29 |
30 | if ([appDelegate respondsToSelector:@selector(privilegesTimeLeft)]) {
31 | timeLeft = [appDelegate privilegesTimeLeft];
32 | }
33 | }
34 |
35 | return [NSNumber numberWithUnsignedInteger:timeLeft];
36 | }
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/Classes/MTPrivilegeStatusCommand.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTPrivilegeStatusCommand.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 |
20 | /*!
21 | @class MTPrivilegeStatusCommand
22 | @abstract This class contains the code for the AppleScript command "status of administrator privileges".
23 | */
24 |
25 | @interface MTPrivilegeStatusCommand : NSScriptCommand
26 |
27 | @end
28 |
29 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/Classes/MTPrivilegeStatusCommand.m:
--------------------------------------------------------------------------------
1 | /*
2 | MTPrivilegeStatusCommand.m
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import "MTPrivilegeStatusCommand.h"
19 | #import "AppDelegate.h"
20 |
21 | @implementation MTPrivilegeStatusCommand
22 |
23 | - (id)performDefaultImplementation
24 | {
25 | BOOL hasAdminPrivileges = NO;
26 | AppDelegate *appDelegate = (AppDelegate*)[NSApp delegate];
27 |
28 | if ([appDelegate conformsToProtocol:@protocol(AppleScriptDataProvider)]) {
29 |
30 | if ([appDelegate respondsToSelector:@selector(userHasAdminPrivileges)]) {
31 | hasAdminPrivileges = [appDelegate userHasAdminPrivileges];
32 | }
33 | }
34 |
35 | return [NSNumber numberWithBool:hasAdminPrivileges];
36 | }
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/Classes/MTStatusItemMenu.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTStatusItemMenu.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 |
20 | /*!
21 | @class MTStatusItemMenu
22 | @abstract This class defines the menu for the status item.
23 | */
24 |
25 | @interface MTStatusItemMenu : NSMenu
26 |
27 | /*!
28 | @method updateMenu
29 | @abstract Updates the menu and makes sure the menu items are named and enabled/disabled
30 | according to the user's current privileges and configuration.
31 | */
32 | - (void)updateMenu;
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/Classes/MTStatusItemMenu.m:
--------------------------------------------------------------------------------
1 | /*
2 | MTStatusItemMenu.m
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import "MTStatusItemMenu.h"
19 | #import "MTPrivileges.h"
20 | #import "Constants.h"
21 |
22 | @implementation MTStatusItemMenu
23 |
24 | - (instancetype)init
25 | {
26 | self = [super init];
27 |
28 | if (self) { [self setUpView]; }
29 |
30 | return self;
31 | }
32 |
33 | - (instancetype)initWithCoder:(NSCoder *)coder
34 | {
35 | self = [super initWithCoder:coder];
36 |
37 | if (self) { [self setUpView]; }
38 |
39 | return self;
40 | }
41 |
42 | - (void)setUpView
43 | {
44 | [self setDelegate:self];
45 | [self setAutoenablesItems:NO];
46 | }
47 |
48 | - (void)updateMenu
49 | {
50 | MTPrivileges *privilegesApp = [[MTPrivileges alloc] init];
51 | BOOL hasAdminPrivileges = [[privilegesApp currentUser] hasAdminPrivileges];
52 |
53 | if (hasAdminPrivileges) {
54 |
55 | [[self itemWithTag:1000] setTitle:NSLocalizedStringFromTable(@"revertMenuItem", @"LocalizableMenu", nil)];
56 |
57 | } else {
58 |
59 | [[self itemWithTag:1000] setTitle:NSLocalizedStringFromTable(@"requestMenuItem", @"LocalizableMenu", nil)];
60 | }
61 |
62 | [[self itemWithTag:1000] setEnabled:!([[privilegesApp currentUser] useIsRestricted] || (!hasAdminPrivileges && [privilegesApp reasonRequired]))];
63 | [[self itemWithTag:2000] setAlternate:(hasAdminPrivileges && [privilegesApp privilegeRenewalAllowed] && [privilegesApp expirationInterval] > 0 && ![[privilegesApp currentUser] hasUnexpectedPrivilegeState])];
64 | [[self itemWithTag:2000] setHidden:![[self itemWithTag:2000] isAlternate]];
65 | }
66 |
67 | - (void)menuWillOpen:(NSMenu *)menu
68 | {
69 | [self updateMenu];
70 | }
71 |
72 | @end
73 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/Classes/MTSyslogMessageStructuredData.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTSyslogMessageStructuredData.h
3 | Copyright 2020-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 |
20 | /*!
21 | @class MTSyslogMessageStructuredData
22 | @abstract This class provides methods for creating the structured data part of a syslog message (as defined in RFC 5424).
23 | */
24 |
25 | @interface MTSyslogMessageStructuredData : NSObject
26 |
27 | /*!
28 | @method addStructuredData:withID:
29 | @abstract Add an element to the structured data object.
30 | @param data A dictionary containing the keys and values of the element.
31 | @param sdID The id/name of the element.
32 | */
33 | - (void)addStructuredData:(NSDictionary*)data withID:(NSString*)sdID;
34 |
35 | /*!
36 | @method structuredDataWithDictionary:
37 | @abstract Create the structured data object from a given dictionary.
38 | @param data A dictionary containing one or more structured data element(s).
39 | @discussion The following example shows a dictionary with two structured data elements:
40 | @code
41 | {
42 | exampleSDID@32473 = {
43 | iut = 3;
44 | eventSource = Application;
45 | eventID = 1011;
46 | };
47 | examplePriority@32473 = {
48 | class = high;
49 | }
50 | }
51 | */
52 | - (void)structuredDataWithDictionary:(NSDictionary*)data;
53 |
54 | /*!
55 | @method composedString
56 | @abstract Get the stuctured data as RFC 5424-compliant structured data string.
57 | @discussion Returns a string containing the structured data or nil if no data has been added or an error occurred.
58 | */
59 | - (NSString*)composedString;
60 |
61 | /*!
62 | @method cleanString:maximumLength:
63 | @abstract Converts the given string into US-ASCII and removes non-printable characters, ensuring the given maximum length.
64 | @param originalString The string that should be converted.
65 | @param maxLength The maximum length that the converted string should not exceed. If set to 0, the length is unlimited.
66 | @discussion Returns the cleaned string or nil if an error occurred.
67 | */
68 | + (NSString*)cleanString:(NSString*)originalString maximumLength:(NSInteger)maxLength;
69 |
70 | @end
71 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/Classes/MTSyslogMessageStructuredData.m:
--------------------------------------------------------------------------------
1 | /*
2 | MTSyslogMessageStructuredData.m
3 | Copyright 2020-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import "MTSyslogMessageStructuredData.h"
19 |
20 | @interface MTSyslogMessageStructuredData ()
21 | @property (nonatomic, strong, readwrite) NSMutableDictionary *structuredData;
22 | @end
23 |
24 | @implementation MTSyslogMessageStructuredData
25 |
26 | - (instancetype)init
27 | {
28 | self = [super init];
29 |
30 | if (self) {
31 |
32 | _structuredData = [[NSMutableDictionary alloc] init];
33 | }
34 |
35 | return self;
36 | }
37 |
38 | - (void)addStructuredData:(NSDictionary*)data withID:(NSString*)sdID
39 | {
40 | [_structuredData setObject:data forKey:sdID];
41 | }
42 |
43 | - (void)structuredDataWithDictionary:(NSDictionary*)data
44 | {
45 | if ([data isKindOfClass:[NSDictionary class]]) {
46 |
47 | _structuredData = [NSMutableDictionary dictionaryWithDictionary:data];
48 | }
49 | }
50 |
51 | - (NSString*)composedString
52 | {
53 | NSString *returnValue = nil;
54 |
55 | if ([_structuredData count] > 0) {
56 |
57 | NSMutableArray *sdElements = [[NSMutableArray alloc] init];
58 |
59 | [_structuredData enumerateKeysAndObjectsUsingBlock:^(id sdID, id params, BOOL *stop) {
60 |
61 | if ([sdID isKindOfClass:[NSString class]] && [params isKindOfClass:[NSDictionary class]]) {
62 |
63 | NSMutableString *sdElement = [NSMutableString stringWithFormat:@"[%@ ", sdID];
64 | NSMutableArray *paramStrings = [[NSMutableArray alloc] init];
65 |
66 | [params enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
67 |
68 | if ([key isKindOfClass:[NSString class]] && [value isKindOfClass:[NSString class]]) {
69 |
70 | NSString *cleanedKey = [self cleanedKeyWithString:key];
71 | NSString *escapedValue = [self escapedValueWithString:value];
72 | [paramStrings addObject:[NSString stringWithFormat:@"%@=\"%@\"", cleanedKey, escapedValue]];
73 | }
74 | }];
75 |
76 | [sdElement appendString:[paramStrings componentsJoinedByString:@" "]];
77 | [sdElement appendString:@"]"];
78 |
79 | [sdElements addObject:sdElement];
80 | }
81 | }];
82 |
83 | returnValue = [sdElements componentsJoinedByString:@""];
84 | }
85 |
86 | return returnValue;
87 | }
88 |
89 | - (NSString*)escapedValueWithString:(NSString*)originalString
90 | {
91 | NSString *escapedString = [originalString stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"];
92 | escapedString = [escapedString stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
93 | escapedString = [escapedString stringByReplacingOccurrencesOfString:@"]" withString:@"\\]"];
94 |
95 | return escapedString;
96 | }
97 |
98 | - (NSString*)cleanedKeyWithString:(NSString*)originalString
99 | {
100 | NSMutableCharacterSet *invalidCharacters = [[NSMutableCharacterSet alloc] init];
101 | [invalidCharacters addCharactersInString:@"= ]\""];
102 |
103 | NSString *cleanedString = [[originalString componentsSeparatedByCharactersInSet:invalidCharacters] componentsJoinedByString:@""];
104 | cleanedString = [MTSyslogMessageStructuredData cleanString:cleanedString maximumLength:32];
105 |
106 | return cleanedString;
107 | }
108 |
109 | + (NSString*)cleanString:(NSString*)originalString maximumLength:(NSInteger)maxLength
110 | {
111 | NSString *cleanedString = nil;
112 |
113 | if (originalString) {
114 |
115 | // convert string to US-ASCII
116 | NSData *stringData = [originalString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
117 | cleanedString = [[NSString alloc] initWithData:stringData encoding:NSASCIIStringEncoding];
118 |
119 | // remove all non-prinable characters
120 | cleanedString = [cleanedString stringByReplacingOccurrencesOfString:@"[^\x21-\x7E]"
121 | withString:@""
122 | options:NSRegularExpressionSearch
123 | range:NSMakeRange(0, [originalString length])];
124 |
125 | // make sure the string does not exceed the allowed length
126 | if (maxLength > 0 && [cleanedString length] > maxLength) {
127 | cleanedString = [cleanedString substringToIndex:(maxLength - 1)];
128 | }
129 | }
130 |
131 | return cleanedString;
132 | }
133 |
134 | @end
135 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/Classes/MTWebhook.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTWebhook.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 | #import "MTPrivilegesUser.h"
20 |
21 | /*!
22 | @class MTWebhook
23 | @abstract A class that provides a method to post information about a privilege change to a webhook.
24 | */
25 |
26 | @interface MTWebhook : NSObject
27 |
28 | /*!
29 | @method init
30 | @discussion The init method is not available. Please use initWithURL: instead.
31 | */
32 | - (instancetype)init NS_UNAVAILABLE;
33 |
34 | /*!
35 | @method initWithURL:
36 | @abstract Initialize a MTWebhook object with a given url.
37 | @param url The url of the webhook.
38 | @discussion Returns an initialized MTWebhook object or nil if an error occurred.
39 | */
40 | - (instancetype)initWithURL:(NSURL*)url NS_DESIGNATED_INITIALIZER;
41 |
42 | /*!
43 | @method postToWebhookForUser:reason:expirationDate:completionHandler:
44 | @abstract Post data about a privilege change to the webhook.
45 | @param user The MTPrivilegesUser the privilege change belongs to.
46 | @param reason The reason for the privilege change. Might be nil.
47 | @param expiration The date the administrator privileges expire. Might be nil.
48 | @param customData An optional dictionary that is added to the webhook data.
49 | @param completionHandler The handler to call when the request is complete.
50 | @discussion The returned error object might contain error information if an error occurred or will be nil if no error occurred.
51 | */
52 | - (void)postToWebhookForUser:(MTPrivilegesUser*)user
53 | reason:(NSString*)reason
54 | expirationDate:(NSDate*)expiration
55 | customData:(NSDictionary*)customData
56 | completionHandler:(void (^) (NSError *error))completionHandler;
57 |
58 | @end
59 |
60 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/Classes/MTWebhook.m:
--------------------------------------------------------------------------------
1 | /*
2 | MTWebhook.m
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import "MTWebhook.h"
19 | #import "MTSystemInfo.h"
20 | #import "Constants.h"
21 | #import "MTClientCertificate.h"
22 |
23 | @interface MTWebhook ()
24 | @property (nonatomic, strong, readwrite) NSURL *url;
25 | @end
26 |
27 | @implementation MTWebhook
28 |
29 | - (instancetype)initWithURL:(NSURL*)url
30 | {
31 | self = [super init];
32 |
33 | if (self) {
34 | _url = url;
35 | }
36 |
37 | return self;
38 | }
39 |
40 |
41 | - (void)postToWebhookForUser:(MTPrivilegesUser*)user
42 | reason:(NSString*)reason
43 | expirationDate:(NSDate*)expiration
44 | customData:(NSDictionary*)customData
45 | completionHandler:(void (^) (NSError *error))completionHandler
46 | {
47 | NSString *expirationDateString = @"";
48 | NSISO8601DateFormatter *dateFormatter = [[NSISO8601DateFormatter alloc] init];
49 |
50 | if ([user hasAdminPrivileges] && expiration) { expirationDateString = [dateFormatter stringFromDate:expiration]; }
51 |
52 | NSMutableDictionary *jsonDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
53 | [user userName], @"user",
54 | [NSNumber numberWithBool:[user hasAdminPrivileges]], @"admin",
55 | expirationDateString, @"expires",
56 | (reason) ? reason : @"", @"reason",
57 | ([user hasAdminPrivileges]) ? kMTWebhookEventTypeGranted : kMTWebhookEventTypeRevoked, @"event",
58 | [MTSystemInfo machineUUID], @"machine",
59 | [dateFormatter stringFromDate:[NSDate now]], @"timestamp",
60 | nil
61 | ];
62 |
63 | if ([[customData allKeys] count] > 0) { [jsonDict setObject:customData forKey:@"custom_data"]; }
64 |
65 | NSError *error = nil;
66 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDict
67 | options:NSJSONWritingSortedKeys
68 | error:&error
69 | ];
70 |
71 | if (!error) {
72 |
73 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:_url];
74 | [request setHTTPMethod:@"POST"];
75 | [request setValue:@"application/json;charset=utf-8" forHTTPHeaderField:@"Content-Type"];
76 | [request setHTTPBody:jsonData];
77 |
78 | NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
79 | delegate:self
80 | delegateQueue:nil
81 | ];
82 | NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request
83 | completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
84 |
85 | if (completionHandler) { completionHandler(error); }
86 | [session finishTasksAndInvalidate];
87 | }];
88 |
89 | [dataTask resume];
90 |
91 | } else {
92 |
93 | if (completionHandler) { completionHandler(error); }
94 | }
95 | }
96 |
97 | - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler
98 | {
99 | BOOL credentialsFound = NO;
100 |
101 | if ([[[challenge protectionSpace] authenticationMethod] isEqualToString:NSURLAuthenticationMethodClientCertificate]) {
102 |
103 | CFTypeRef items = NULL;
104 |
105 | NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:
106 | (id)kSecClassIdentity, (id)kSecClass,
107 | [NSNumber numberWithBool:YES], (id)kSecReturnRef,
108 | (id)kSecMatchLimitAll, (id)kSecMatchLimit,
109 | nil
110 | ];
111 |
112 | OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)attrs, &items);
113 |
114 | if (status == errSecSuccess && items) {
115 |
116 | NSArray *allSecItems = CFBridgingRelease(items);
117 |
118 | for (NSData *distinguishedName in [[challenge protectionSpace] distinguishedNames]) {
119 |
120 | MTClientCertificate *clientCert = [[MTClientCertificate alloc] initWithDistinguishedName:distinguishedName];
121 | SecIdentityRef matchingIdentityRef = [clientCert matchingIdentityWithSecItems:allSecItems];
122 |
123 | if (matchingIdentityRef) {
124 |
125 | NSURLCredential *credential = [NSURLCredential credentialWithIdentity:matchingIdentityRef
126 | certificates:nil
127 | persistence:NSURLCredentialPersistenceForSession
128 | ];
129 |
130 | credentialsFound = YES;
131 | completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
132 |
133 | break;
134 | }
135 | }
136 | }
137 | }
138 |
139 | if (!credentialsFound) { completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); }
140 | }
141 |
142 | @end
143 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSAppleScriptEnabled
6 |
7 | OSAScriptingDefinition
8 | PrivilegesAgent.sdef
9 |
10 |
11 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/PrivilegesAgent-ParentConstraint.coderequirement:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | is-init-proc
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/PrivilegesAgent-SelfConstraint.coderequirement:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | $or-array
6 |
7 |
8 | $or
9 |
10 | launch-type
11 |
12 | $lt
13 | 3
14 |
15 |
16 |
17 |
18 | $or
19 |
20 | launch-type
21 |
22 | $gt
23 | 3
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/PrivilegesAgent.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.application-groups
6 |
7 | $(TeamIdentifierPrefix)corp.sap.privileges
8 |
9 | com.apple.security.automation.apple-events
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/PrivilegesAgent.sdef:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/PrivilegesAgentProtocol.h:
--------------------------------------------------------------------------------
1 | /*
2 | PrivilegesAgentProtocol.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 |
20 | /*!
21 | @protocol PrivilegesAgentProtocol
22 | @abstract Defines the protocol implemented by the agent..
23 | */
24 |
25 | @protocol PrivilegesAgentProtocol
26 |
27 | /*!
28 | @method connectWithEndpointReply:
29 | @abstract Returns an endpoint that's connected to the daemon.
30 | @param reply The reply block to call when the request is complete.
31 | @discussion This method is only called by the xpc service.
32 | */
33 | - (void)connectWithEndpointReply:(void (^)(NSXPCListenerEndpoint* endpoint))reply;
34 |
35 | /*!
36 | @method requestAdminRightsWithReason:completionHandler:
37 | @abstract Request administrator privileges for the current user.
38 | @param reason A string containing the reason the user requests administrator privileges. May be nil.
39 | @param completionHandler The handler to call when the request is complete.
40 | @discussion Returns YES if the operation was successful, otherwise returns NO.
41 | */
42 | - (void)requestAdminRightsWithReason:(NSString*)reason completionHandler:(void(^)(BOOL success))completionHandler;
43 |
44 | /*!
45 | @method revokeAdminPrivilegesWithCompletionHandler:
46 | @abstract Revoke administrator privileges for the current user.
47 | @param completionHandler The handler to call when the request is complete.
48 | @discussion Returns YES if the operation was successful, otherwise returns NO.
49 | */
50 | - (void)revokeAdminRightsWithCompletionHandler:(void(^)(BOOL success))completionHandler;
51 |
52 | /*!
53 | @method renewAdminRightsWithCompletionHandler:
54 | @abstract Renew expiring administrator privileges for the current user.
55 | @param completionHandler The handler to call when the request is complete.
56 | @discussion Returns YES if the operation was successful, otherwise returns NO.
57 | */
58 | - (void)renewAdminRightsWithCompletionHandler:(void(^)(BOOL success))completionHandler;
59 |
60 | /*!
61 | @method authenticateUserWithCompletionHandler:
62 | @param completionHandler The reply block to call when the request is complete.
63 | */
64 | - (void)authenticateUserWithCompletionHandler:(void(^)(BOOL success))completionHandler;
65 |
66 | /*!
67 | @method expirationWithReply:
68 | @abstract Get the date when the current user's administrator privileges expire.
69 | @param reply The reply block to call when the request is complete.
70 | @discussion Returns the expiration date and the number of minutes remaining. Expiration date will be nil
71 | if the administrator privileges are already expired.
72 | */
73 | - (void)expirationWithReply:(void(^)(NSDate *expires, NSUInteger remaining))reply;
74 |
75 | /*!
76 | @method isExecutableFileAtURL:reply:
77 | @abstract Get whether the current user can execute the file at the given url.
78 | @param reply The reply block to call when the request is complete.
79 | @discussion Returns YES if the file can be executed by the current user, otherwise returns NO.
80 | */
81 | - (void)isExecutableFileAtURL:(NSURL*)url reply:(void(^)(BOOL isExecutable))reply;
82 |
83 | @end
84 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/StatusItem.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/StatusItem.xcassets/locked.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "locked-16.png",
5 | "idiom" : "mac",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "locked-32.png",
10 | "idiom" : "mac",
11 | "scale" : "2x"
12 | }
13 | ],
14 | "info" : {
15 | "author" : "xcode",
16 | "version" : 1
17 | },
18 | "properties" : {
19 | "template-rendering-intent" : "template"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/StatusItem.xcassets/locked.imageset/locked-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/PrivilegesAgent/StatusItem.xcassets/locked.imageset/locked-16.png
--------------------------------------------------------------------------------
/source/PrivilegesAgent/StatusItem.xcassets/locked.imageset/locked-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/PrivilegesAgent/StatusItem.xcassets/locked.imageset/locked-32.png
--------------------------------------------------------------------------------
/source/PrivilegesAgent/StatusItem.xcassets/locked_managed.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "locked_managed-16.png",
5 | "idiom" : "mac",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "locked_managed-32.png",
10 | "idiom" : "mac",
11 | "scale" : "2x"
12 | }
13 | ],
14 | "info" : {
15 | "author" : "xcode",
16 | "version" : 1
17 | },
18 | "properties" : {
19 | "template-rendering-intent" : "template"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/StatusItem.xcassets/locked_managed.imageset/locked_managed-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/PrivilegesAgent/StatusItem.xcassets/locked_managed.imageset/locked_managed-16.png
--------------------------------------------------------------------------------
/source/PrivilegesAgent/StatusItem.xcassets/locked_managed.imageset/locked_managed-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/PrivilegesAgent/StatusItem.xcassets/locked_managed.imageset/locked_managed-32.png
--------------------------------------------------------------------------------
/source/PrivilegesAgent/StatusItem.xcassets/unlocked.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "unlocked-16.png",
5 | "idiom" : "mac",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "unlocked-32.png",
10 | "idiom" : "mac",
11 | "scale" : "2x"
12 | }
13 | ],
14 | "info" : {
15 | "author" : "xcode",
16 | "version" : 1
17 | },
18 | "properties" : {
19 | "template-rendering-intent" : "template"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/StatusItem.xcassets/unlocked.imageset/unlocked-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/PrivilegesAgent/StatusItem.xcassets/unlocked.imageset/unlocked-16.png
--------------------------------------------------------------------------------
/source/PrivilegesAgent/StatusItem.xcassets/unlocked.imageset/unlocked-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/PrivilegesAgent/StatusItem.xcassets/unlocked.imageset/unlocked-32.png
--------------------------------------------------------------------------------
/source/PrivilegesAgent/StatusItem.xcassets/unlocked_managed.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "unlocked_managed-16.png",
5 | "idiom" : "mac",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "unlocked_managed-32.png",
10 | "idiom" : "mac",
11 | "scale" : "2x"
12 | }
13 | ],
14 | "info" : {
15 | "author" : "xcode",
16 | "version" : 1
17 | },
18 | "properties" : {
19 | "template-rendering-intent" : "template"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/source/PrivilegesAgent/StatusItem.xcassets/unlocked_managed.imageset/unlocked_managed-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/PrivilegesAgent/StatusItem.xcassets/unlocked_managed.imageset/unlocked_managed-16.png
--------------------------------------------------------------------------------
/source/PrivilegesAgent/StatusItem.xcassets/unlocked_managed.imageset/unlocked_managed-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/PrivilegesAgent/StatusItem.xcassets/unlocked_managed.imageset/unlocked_managed-32.png
--------------------------------------------------------------------------------
/source/PrivilegesAgent/main.m:
--------------------------------------------------------------------------------
1 | /*
2 | main.m
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 |
20 | int main(int argc, const char * argv[])
21 | {
22 | return NSApplicationMain(argc, argv);
23 | }
24 |
--------------------------------------------------------------------------------
/source/PrivilegesCLI/Classes/MTProcessInfo.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTProcessInfo.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 |
20 | /*!
21 | @class MTProcessInfo
22 | @abstract A class that provides methods to access the relevant command line arguments.
23 | */
24 |
25 | @interface MTProcessInfo : NSProcessInfo
26 |
27 | /*!
28 | @method showStatus
29 | @abstract Get whether the status should be displayed.
30 | @discussion Returns YES if the status should be displayed, otherwise returns NO.
31 | */
32 | - (BOOL)showStatus;
33 |
34 | /*!
35 | @method showVersion
36 | @abstract Get whether the version should be displayed.
37 | @discussion Returns YES if the version should be displayed, otherwise returns NO.
38 | */
39 | - (BOOL)showVersion;
40 |
41 | /*!
42 | @method requestPrivileges
43 | @abstract Get whether administrator privileges were requested.
44 | @discussion Returns YES if administrator privileges were requested, otherwise returns NO.
45 | */
46 | - (BOOL)requestPrivileges;
47 |
48 | /*!
49 | @method revertPrivileges
50 | @abstract Get whether administrator privileges should be reverted.
51 | @discussion Returns YES if administrator privileges should be reverted, otherwise returns NO.
52 | */
53 | - (BOOL)revertPrivileges;
54 |
55 | /*!
56 | @method launchURL
57 | @abstract Get the launch url of the current process.
58 | @discussion Returns an NSURL object or nil, if an error occurred.
59 | */
60 | - (NSURL*)launchURL;
61 |
62 | /*!
63 | @method requestReason
64 | @abstract Get the reason the user provided to get administator privileges.
65 | @discussion Returns a NSString object containing the provided reason. Returns nil if no reason has been provided.
66 | */
67 | - (NSString*)requestReason;
68 |
69 | @end
70 |
--------------------------------------------------------------------------------
/source/PrivilegesCLI/Classes/MTProcessInfo.m:
--------------------------------------------------------------------------------
1 | /*
2 | MTProcessInfo.m
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import "MTProcessInfo.h"
19 |
20 | @implementation MTProcessInfo
21 |
22 | - (BOOL)showStatus
23 | {
24 | BOOL show = [[self arguments] containsObject:@"-s"] || [[self arguments] containsObject:@"--status"];
25 | return show;
26 | }
27 |
28 | - (BOOL)requestPrivileges
29 | {
30 | BOOL request = [[self arguments] containsObject:@"-a"] || [[self arguments] containsObject:@"--add"];
31 | return request;
32 | }
33 |
34 | - (BOOL)revertPrivileges
35 | {
36 | BOOL revert = [[self arguments] containsObject:@"-r"] || [[self arguments] containsObject:@"--remove"];
37 | return revert;
38 | }
39 |
40 | - (BOOL)showVersion
41 | {
42 | BOOL show = [[self arguments] containsObject:@"-v"] || [[self arguments] containsObject:@"--version"];
43 | return show;
44 | }
45 |
46 | - (NSURL*)launchURL
47 | {
48 | NSURL *url = nil;
49 |
50 | NSString *launchPath = [[self arguments] firstObject];
51 | if (launchPath) { url = [NSURL fileURLWithPath:launchPath]; }
52 |
53 | return url;
54 | }
55 |
56 | - (NSString *)requestReason
57 | {
58 | NSString *reason = nil;
59 |
60 | NSInteger index = [[self arguments] indexOfObject:@"-n"];
61 | if (index == NSNotFound) { index = [[self arguments] indexOfObject:@"--reason"]; }
62 |
63 | if (index != NSNotFound && index + 1 < [[self arguments] count]) {
64 |
65 | reason = [[self arguments] objectAtIndex:index + 1];
66 | }
67 |
68 | return reason;
69 | }
70 |
71 | @end
72 |
--------------------------------------------------------------------------------
/source/PrivilegesCLI/PrivilegesCLI-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleIdentifier
6 | corp.sap.privileges.cli
7 | CFBundleInfoDictionaryVersion
8 | 6.0
9 | CFBundleName
10 | PrivilegesCLI
11 | CFBundleShortVersionString
12 | $(MARKETING_VERSION)
13 | CFBundleVersion
14 | $(CURRENT_PROJECT_VERSION)
15 | NSHumanReadableCopyright
16 | © 2016-2025 SAP SE. All rights reserved.
17 |
18 |
19 |
--------------------------------------------------------------------------------
/source/PrivilegesCLI/PrivilegesCLI.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.application-groups
6 |
7 | $(TeamIdentifierPrefix)corp.sap.privileges
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/source/PrivilegesDaemon/Classes/MTPrivilegesDaemon.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTPrivilegesDaemon.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 | #import "PrivilegesDaemonProtocol.h"
20 |
21 | @interface MTPrivilegesDaemon : NSObject
22 |
23 | /*!
24 | @method invalidateXPC
25 | @abstract Invalidates all connections to the daemon.
26 | */
27 | - (void)invalidateXPC;
28 |
29 | /*!
30 | @method numberOfActiveXPCConnections
31 | @abstract Get the number of connections currently open to the daemon.
32 | */
33 | - (NSInteger)numberOfActiveXPCConnections;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/source/PrivilegesDaemon/PrivilegesDaemon-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleIdentifier
6 | corp.sap.privileges.daemon
7 | CFBundleInfoDictionaryVersion
8 | 6.0
9 | CFBundleName
10 | PrivilegesDaemon
11 | CFBundleShortVersionString
12 | $(MARKETING_VERSION)
13 | CFBundleVersion
14 | $(CURRENT_PROJECT_VERSION)
15 | NSHumanReadableCopyright
16 | © 2025 SAP SE. All rights reserved.
17 |
18 |
19 |
--------------------------------------------------------------------------------
/source/PrivilegesDaemon/PrivilegesDaemon-ParentConstraint.coderequirement:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | is-init-proc
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/source/PrivilegesDaemon/PrivilegesDaemon-SelfConstraint.coderequirement:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | $or-array
6 |
7 |
8 | $or
9 |
10 | launch-type
11 |
12 | $lt
13 | 3
14 |
15 |
16 |
17 |
18 | $or
19 |
20 | launch-type
21 |
22 | $gt
23 | 3
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/source/PrivilegesDaemon/PrivilegesDaemonProtocol.h:
--------------------------------------------------------------------------------
1 | /*
2 | PrivilegesDaemonProtocol.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 | #import
20 |
21 | /*!
22 | @protocol PrivilegesDaemonProtocol
23 | @abstract Defines the protocol implemented by the daemon and called by the xpc service and Privileges.
24 | */
25 |
26 | @protocol PrivilegesDaemonProtocol
27 |
28 | /*!
29 | @method grantAdminRightsToUser:reason:completionHandler:
30 | @abstract Grant administrator privileges to the given user.
31 | @param userName A string containing the user name.
32 | @param reason A string containing the reason the user requests administrator privileges. May be nil.
33 | @param completionHandler The handler to call when the request is complete.
34 | @discussion Returns YES if adminstrator privileges were successfully granted, otherwise returns NO.
35 | */
36 | - (void)grantAdminRightsToUser:(NSString*)userName
37 | reason:(NSString*)reason
38 | completionHandler:(void(^)(BOOL success))completionHandler;
39 |
40 | /*!
41 | @method removeAdminRightsFromUser:reason:completionHandler:
42 | @abstract Remove administrator privileges from the current user.
43 | @param userName A string containing the user name.
44 | @param reason A string containing the reason the user requests administrator privileges. May be nil.
45 | @param completionHandler The handler to call when the request is complete.
46 | @discussion Returns YES if adminstrator privileges were successfully removed, otherwise returns NO.
47 | */
48 | - (void)removeAdminRightsFromUser:(NSString*)userName
49 | reason:(NSString*)reason
50 | completionHandler:(void(^)(BOOL success))completionHandler;
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/source/PrivilegesDaemon/main.m:
--------------------------------------------------------------------------------
1 | /*
2 | main.m
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 | #import "MTPrivilegesDaemon.h"
20 | #import "Constants.h"
21 |
22 | @interface Main : NSObject
23 | @property (nonatomic, strong, readwrite) MTPrivilegesDaemon *privilegesDaemon;
24 | @property (assign) BOOL shouldTerminate;
25 | @end
26 |
27 | @implementation Main
28 |
29 | - (void)run
30 | {
31 | os_log(OS_LOG_DEFAULT, "SAPCorp: Starting");
32 |
33 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(30 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
34 |
35 | self->_shouldTerminate = YES;
36 | });
37 |
38 | while (!_shouldTerminate || [_privilegesDaemon numberOfActiveXPCConnections] > 0) {
39 |
40 | [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:60]];
41 | }
42 |
43 | [_privilegesDaemon invalidateXPC];
44 | os_log(OS_LOG_DEFAULT, "SAPCorp: Exiting");
45 | }
46 |
47 | @end
48 |
49 |
50 | int main(int argc, const char * argv[])
51 | {
52 | #pragma unused(argc)
53 | #pragma unused(argv)
54 |
55 | @autoreleasepool {
56 |
57 | Main *m = [[Main alloc] init];
58 | m.privilegesDaemon = [[MTPrivilegesDaemon alloc] init];
59 | [m run];
60 | }
61 |
62 | return EXIT_SUCCESS;
63 | }
64 |
--------------------------------------------------------------------------------
/source/PrivilegesTile/AppIcons-Beta.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/source/PrivilegesTile/AppIcons-Beta.xcassets/locked.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "locked.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/source/PrivilegesTile/AppIcons-Beta.xcassets/locked.imageset/locked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/PrivilegesTile/AppIcons-Beta.xcassets/locked.imageset/locked.png
--------------------------------------------------------------------------------
/source/PrivilegesTile/AppIcons-Beta.xcassets/locked_managed.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "locked_managed.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/source/PrivilegesTile/AppIcons-Beta.xcassets/locked_managed.imageset/locked_managed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/PrivilegesTile/AppIcons-Beta.xcassets/locked_managed.imageset/locked_managed.png
--------------------------------------------------------------------------------
/source/PrivilegesTile/AppIcons-Beta.xcassets/unlocked.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "unlocked.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/source/PrivilegesTile/AppIcons-Beta.xcassets/unlocked.imageset/unlocked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/PrivilegesTile/AppIcons-Beta.xcassets/unlocked.imageset/unlocked.png
--------------------------------------------------------------------------------
/source/PrivilegesTile/AppIcons-Beta.xcassets/unlocked_managed.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "unlocked_managed.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/source/PrivilegesTile/AppIcons-Beta.xcassets/unlocked_managed.imageset/unlocked_managed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/PrivilegesTile/AppIcons-Beta.xcassets/unlocked_managed.imageset/unlocked_managed.png
--------------------------------------------------------------------------------
/source/PrivilegesTile/AppIcons.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/source/PrivilegesTile/AppIcons.xcassets/locked.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "locked.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/source/PrivilegesTile/AppIcons.xcassets/locked.imageset/locked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/PrivilegesTile/AppIcons.xcassets/locked.imageset/locked.png
--------------------------------------------------------------------------------
/source/PrivilegesTile/AppIcons.xcassets/locked_managed.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "locked_managed.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/source/PrivilegesTile/AppIcons.xcassets/locked_managed.imageset/locked_managed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/PrivilegesTile/AppIcons.xcassets/locked_managed.imageset/locked_managed.png
--------------------------------------------------------------------------------
/source/PrivilegesTile/AppIcons.xcassets/unlocked.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "unlocked.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/source/PrivilegesTile/AppIcons.xcassets/unlocked.imageset/unlocked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/PrivilegesTile/AppIcons.xcassets/unlocked.imageset/unlocked.png
--------------------------------------------------------------------------------
/source/PrivilegesTile/AppIcons.xcassets/unlocked_managed.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "unlocked_managed.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/source/PrivilegesTile/AppIcons.xcassets/unlocked_managed.imageset/unlocked_managed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/PrivilegesTile/AppIcons.xcassets/unlocked_managed.imageset/unlocked_managed.png
--------------------------------------------------------------------------------
/source/PrivilegesTile/Classes/PrivilegesTile.h:
--------------------------------------------------------------------------------
1 | /*
2 | PrivilegesTile.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 |
20 | @interface PrivilegesTile : NSObject
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/source/PrivilegesWatcher/PrivilegesWatcher-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleIdentifier
6 | corp.sap.privileges.watcher
7 | CFBundleInfoDictionaryVersion
8 | 6.0
9 | CFBundleName
10 | PrivilegesWatcher
11 | CFBundleShortVersionString
12 | $(MARKETING_VERSION)
13 | CFBundleVersion
14 | $(CURRENT_PROJECT_VERSION)
15 | NSHumanReadableCopyright
16 | © 2016-2025 SAP SE. All rights reserved.
17 |
18 |
19 |
--------------------------------------------------------------------------------
/source/PrivilegesWatcher/PrivilegesWatcher-ParentConstraint.coderequirement:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | is-init-proc
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/source/PrivilegesWatcher/PrivilegesWatcher-SelfConstraint.coderequirement:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | $or-array
6 |
7 |
8 | $or
9 |
10 | launch-type
11 |
12 | $lt
13 | 3
14 |
15 |
16 |
17 |
18 | $or
19 |
20 | launch-type
21 |
22 | $gt
23 | 3
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/source/PrivilegesWatcher/main.m:
--------------------------------------------------------------------------------
1 | /*
2 | main.m
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 | #import "Constants.h"
20 | #import
21 |
22 | @protocol PrivilegesWatcherDelegate
23 | - (void)postNotification;
24 | @end
25 |
26 | void fsevents_callback(ConstFSEventStreamRef streamRef, void *clientCallBackInfo, size_t numEvents, void *eventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[])
27 | {
28 | char **paths = eventPaths;
29 | id myDelegate = (__bridge id)clientCallBackInfo;
30 |
31 | if (myDelegate) {
32 |
33 | for (int i = 0; i < numEvents; i++) {
34 |
35 | NSString *eventPath = [NSString stringWithUTF8String:paths[i]];
36 |
37 | if ([[eventPath lastPathComponent] isEqualToString:@"admin.plist"]) {
38 |
39 | dispatch_async(dispatch_get_main_queue(), ^{ [myDelegate postNotification]; });
40 | break;
41 | }
42 | }
43 | }
44 | }
45 |
46 | @interface Main : NSObject
47 | @property (nonatomic, strong, readwrite) NSTimer *delayTimer;
48 | @property (nonatomic, strong, readwrite) NSTimer *terminationTimer;
49 | @property (assign) BOOL shouldTerminate;
50 | @end
51 |
52 | @implementation Main
53 |
54 | - (void)run
55 | {
56 | os_log(OS_LOG_DEFAULT, "SAPCorp: Starting");
57 |
58 | [self scheduleTerminationTimer];
59 |
60 | // post a notification so the PrivilegesAgent knows about the change
61 | [self postNotification];
62 |
63 | // monitor the admin group for further changes
64 | NSString *basePath = @"/var/db/dslocal/nodes/Default/groups";
65 | NSArray *pathsToWatch = [NSArray arrayWithObject:basePath];
66 | FSEventStreamContext cntxt = {0, (__bridge void *)(self), NULL, NULL, NULL};
67 | dispatch_queue_t queue = dispatch_queue_create("corp.sap.privileges.watcher.queue", DISPATCH_QUEUE_SERIAL);
68 |
69 | FSEventStreamRef stream = FSEventStreamCreate(
70 | NULL,
71 | &fsevents_callback,
72 | &cntxt,
73 | (__bridge CFArrayRef)pathsToWatch,
74 | kFSEventStreamEventIdSinceNow,
75 | 0.1,
76 | kFSEventStreamCreateFlagFileEvents
77 | );
78 |
79 | if (stream) {
80 |
81 | FSEventStreamSetDispatchQueue(stream, queue);
82 | FSEventStreamStart(stream);
83 | }
84 |
85 | while (!_shouldTerminate) {
86 |
87 | [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:60]];
88 | }
89 |
90 | if (stream) {
91 |
92 | FSEventStreamStop(stream);
93 | FSEventStreamRelease(stream);
94 | }
95 |
96 | os_log(OS_LOG_DEFAULT, "SAPCorp: Exiting");
97 | }
98 |
99 | - (void)scheduleTerminationTimer
100 | {
101 | if (_terminationTimer) {
102 | [_terminationTimer invalidate];
103 | _terminationTimer = nil;
104 | };
105 |
106 | _terminationTimer = [NSTimer scheduledTimerWithTimeInterval:30
107 | repeats:YES
108 | block:^(NSTimer *timer) {
109 | self->_shouldTerminate = YES;
110 | }];
111 | }
112 |
113 | - (void)postNotification
114 | {
115 | [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kMTNotificationNameAdminGroupDidChange
116 | object:nil
117 | userInfo:nil
118 | options:NSNotificationDeliverImmediately | NSNotificationPostToAllSessions
119 | ];
120 |
121 | [self scheduleTerminationTimer];
122 | }
123 |
124 | @end
125 |
126 | int main(int argc, const char * argv[])
127 | {
128 | #pragma unused(argc)
129 | #pragma unused(argv)
130 |
131 | @autoreleasepool {
132 |
133 | Main *m = [[Main alloc] init];
134 | [m run];
135 | }
136 |
137 | return 0;
138 | }
139 |
--------------------------------------------------------------------------------
/source/PrivilegesXPC/Classes/PrivilegesXPC.h:
--------------------------------------------------------------------------------
1 | /*
2 | PrivilegesXPC.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 | #import "PrivilegesXPCProtocol.h"
20 |
21 | @interface PrivilegesXPC : NSObject
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/source/PrivilegesXPC/Classes/PrivilegesXPC.m:
--------------------------------------------------------------------------------
1 | /*
2 | PrivilegesXPC.m
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import "PrivilegesXPC.h"
19 | #import "MTAgentConnection.h"
20 | #import
21 |
22 | @interface PrivilegesXPC ()
23 | @property (nonatomic, strong, readwrite) MTAgentConnection *agentConnection;
24 | @end
25 |
26 | @implementation PrivilegesXPC
27 |
28 | - (void)connectWithAgentEndpointReply:(void(^)(NSXPCListenerEndpoint *endpoint))reply
29 | {
30 | if (!_agentConnection) { _agentConnection = [[MTAgentConnection alloc] init]; }
31 |
32 | [_agentConnection connectToAgentWithExportedObject:nil
33 | andExecuteCommandBlock:^{
34 |
35 | [[[self->_agentConnection connection] remoteObjectProxyWithErrorHandler:^(NSError *error) {
36 |
37 | os_log_with_type(OS_LOG_DEFAULT, OS_LOG_TYPE_FAULT, "SAPCorp: Failed to connect to agent: %{public}@", error);
38 |
39 | }] connectWithEndpointReply:^(NSXPCListenerEndpoint *endpoint) {
40 |
41 | reply(endpoint);
42 | }];
43 | }];
44 | }
45 |
46 | - (void)dealloc
47 | {
48 | if (_agentConnection) { [_agentConnection invalidate]; }
49 | }
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/source/PrivilegesXPC/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | XPCService
6 |
7 | ServiceType
8 | Application
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/source/PrivilegesXPC/PrivilegesXPC-ParentConstraint.coderequirement:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | is-init-proc
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/source/PrivilegesXPC/PrivilegesXPC-ResponsibleConstraint.coderequirement:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | team-identifier
6 | 7R5ZEU67FQ
7 | signing-identifier
8 | corp.sap.privileges
9 |
10 |
11 |
--------------------------------------------------------------------------------
/source/PrivilegesXPC/PrivilegesXPC.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/source/PrivilegesXPC/PrivilegesXPCProtocol.h:
--------------------------------------------------------------------------------
1 | /*
2 | PrivilegesXPCProtocol.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 |
20 | /*!
21 | @protocol PrivilegesXPCProtocol
22 | @abstract Defines the protocol implemented by the xpc service and
23 | called by Privileges.
24 | */
25 |
26 | @protocol PrivilegesXPCProtocol
27 |
28 | /*!
29 | @method connectWithAgentEndpointReply:
30 | @abstract Returns an endpoint that's connected to the agent.
31 | @param reply The reply block to call when the request is complete.
32 | */
33 | - (void)connectWithAgentEndpointReply:(void(^)(NSXPCListenerEndpoint *endpoint))reply;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/source/PrivilegesXPC/main.m:
--------------------------------------------------------------------------------
1 | /*
2 | main.m
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 | #import "PrivilegesXPC.h"
20 | #import "MTCodeSigning.h"
21 | #import
22 |
23 | @interface ServiceDelegate : NSObject
24 | @end
25 |
26 | @interface ExtendedNSXPCConnection : NSXPCConnection
27 | @property audit_token_t auditToken;
28 | @end
29 |
30 | OSStatus SecTaskValidateForRequirement(SecTaskRef task, CFStringRef requirement);
31 |
32 | @implementation ServiceDelegate
33 |
34 | - (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection
35 | {
36 | BOOL acceptConnection = NO;
37 |
38 | // see how we have been signed and make sure only processes with the same signing authority can connect.
39 | // additionally the calling application must have the same version number as this xpc service and must be
40 | // one of the components using a bundle identifier starting with "corp.sap.privileges"
41 | NSError *error = nil;
42 | NSString *signingAuth = [MTCodeSigning getSigningAuthorityWithError:&error];
43 | NSString *requiredVersion = [[NSBundle bundleForClass:[self class]] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
44 |
45 | if (signingAuth) {
46 |
47 | NSString *reqString = [MTCodeSigning codeSigningRequirementsWithCommonName:signingAuth
48 | bundleIdentifier:@"corp.sap.privileges*"
49 | versionString:requiredVersion
50 | ];
51 | SecTaskRef taskRef = SecTaskCreateWithAuditToken(NULL, ((ExtendedNSXPCConnection*)newConnection).auditToken);
52 |
53 | if (taskRef) {
54 |
55 | if (SecTaskValidateForRequirement(taskRef, (__bridge CFStringRef)(reqString)) == errSecSuccess) {
56 |
57 | acceptConnection = YES;
58 |
59 | newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(PrivilegesXPCProtocol)];
60 | PrivilegesXPC *exportedObject = [PrivilegesXPC new];
61 | newConnection.exportedObject = exportedObject;
62 | #pragma clang diagnostic push
63 | #pragma clang diagnostic ignored "-Warc-retain-cycles"
64 | [newConnection setInvalidationHandler:^{
65 |
66 | [newConnection setInvalidationHandler:nil];
67 | dispatch_async(dispatch_get_main_queue(), ^{
68 | os_log(OS_LOG_DEFAULT, "SAPCorp: %{public}@ invalidated", newConnection);
69 | });
70 | }];
71 | #pragma clang diagnostic pop
72 |
73 | [newConnection resume];
74 |
75 | dispatch_async(dispatch_get_main_queue(), ^{
76 | os_log(OS_LOG_DEFAULT, "SAPCorp: %{public}@ established", newConnection);
77 | });
78 |
79 | } else {
80 | os_log_with_type(OS_LOG_DEFAULT, OS_LOG_TYPE_ERROR, "SAPCorp: Code signature verification failed");
81 | }
82 |
83 | CFRelease(taskRef);
84 | }
85 |
86 | } else {
87 | os_log_with_type(OS_LOG_DEFAULT, OS_LOG_TYPE_ERROR, "SAPCorp: Failed to get code signature: %{public}@", error);
88 | }
89 |
90 | return acceptConnection;
91 | }
92 |
93 | @end
94 |
95 | int main(int argc, const char *argv[])
96 | {
97 | // Create the delegate for the service.
98 | ServiceDelegate *delegate = [ServiceDelegate new];
99 |
100 | // Set up the one NSXPCListener for this service. It will handle all incoming connections.
101 | NSXPCListener *listener = [NSXPCListener serviceListener];
102 | listener.delegate = delegate;
103 |
104 | // Resuming the serviceListener starts this service. This method does not return.
105 | [listener resume];
106 |
107 | return 0;
108 | }
109 |
--------------------------------------------------------------------------------
/source/Shared/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "color-space" : "srgb",
6 | "components" : {
7 | "alpha" : "1.000",
8 | "blue" : "211",
9 | "green" : "143",
10 | "red" : "0"
11 | }
12 | },
13 | "idiom" : "universal"
14 | },
15 | {
16 | "appearances" : [
17 | {
18 | "appearance" : "luminosity",
19 | "value" : "dark"
20 | }
21 | ],
22 | "color" : {
23 | "color-space" : "srgb",
24 | "components" : {
25 | "alpha" : "1.000",
26 | "blue" : "1.000",
27 | "green" : "0.667",
28 | "red" : "0.059"
29 | }
30 | },
31 | "idiom" : "universal"
32 | }
33 | ],
34 | "info" : {
35 | "author" : "xcode",
36 | "version" : 1
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/source/Shared/Assets.xcassets/AppIcon-Beta.appiconset/AppIcon-Beta-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/Shared/Assets.xcassets/AppIcon-Beta.appiconset/AppIcon-Beta-1024.png
--------------------------------------------------------------------------------
/source/Shared/Assets.xcassets/AppIcon-Beta.appiconset/AppIcon-Beta-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/Shared/Assets.xcassets/AppIcon-Beta.appiconset/AppIcon-Beta-128.png
--------------------------------------------------------------------------------
/source/Shared/Assets.xcassets/AppIcon-Beta.appiconset/AppIcon-Beta-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/Shared/Assets.xcassets/AppIcon-Beta.appiconset/AppIcon-Beta-16.png
--------------------------------------------------------------------------------
/source/Shared/Assets.xcassets/AppIcon-Beta.appiconset/AppIcon-Beta-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/Shared/Assets.xcassets/AppIcon-Beta.appiconset/AppIcon-Beta-256.png
--------------------------------------------------------------------------------
/source/Shared/Assets.xcassets/AppIcon-Beta.appiconset/AppIcon-Beta-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/Shared/Assets.xcassets/AppIcon-Beta.appiconset/AppIcon-Beta-32.png
--------------------------------------------------------------------------------
/source/Shared/Assets.xcassets/AppIcon-Beta.appiconset/AppIcon-Beta-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/Shared/Assets.xcassets/AppIcon-Beta.appiconset/AppIcon-Beta-512.png
--------------------------------------------------------------------------------
/source/Shared/Assets.xcassets/AppIcon-Beta.appiconset/AppIcon-Beta-64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/Shared/Assets.xcassets/AppIcon-Beta.appiconset/AppIcon-Beta-64.png
--------------------------------------------------------------------------------
/source/Shared/Assets.xcassets/AppIcon-Beta.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "AppIcon-Beta-16.png",
5 | "idiom" : "mac",
6 | "scale" : "1x",
7 | "size" : "16x16"
8 | },
9 | {
10 | "filename" : "AppIcon-Beta-32.png",
11 | "idiom" : "mac",
12 | "scale" : "2x",
13 | "size" : "16x16"
14 | },
15 | {
16 | "filename" : "AppIcon-Beta-32.png",
17 | "idiom" : "mac",
18 | "scale" : "1x",
19 | "size" : "32x32"
20 | },
21 | {
22 | "filename" : "AppIcon-Beta-64.png",
23 | "idiom" : "mac",
24 | "scale" : "2x",
25 | "size" : "32x32"
26 | },
27 | {
28 | "filename" : "AppIcon-Beta-128.png",
29 | "idiom" : "mac",
30 | "scale" : "1x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "filename" : "AppIcon-Beta-256.png",
35 | "idiom" : "mac",
36 | "scale" : "2x",
37 | "size" : "128x128"
38 | },
39 | {
40 | "filename" : "AppIcon-Beta-256.png",
41 | "idiom" : "mac",
42 | "scale" : "1x",
43 | "size" : "256x256"
44 | },
45 | {
46 | "filename" : "AppIcon-Beta-512.png",
47 | "idiom" : "mac",
48 | "scale" : "2x",
49 | "size" : "256x256"
50 | },
51 | {
52 | "filename" : "AppIcon-Beta-512.png",
53 | "idiom" : "mac",
54 | "scale" : "1x",
55 | "size" : "512x512"
56 | },
57 | {
58 | "filename" : "AppIcon-Beta-1024.png",
59 | "idiom" : "mac",
60 | "scale" : "2x",
61 | "size" : "512x512"
62 | }
63 | ],
64 | "info" : {
65 | "author" : "xcode",
66 | "version" : 1
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/source/Shared/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/Shared/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png
--------------------------------------------------------------------------------
/source/Shared/Assets.xcassets/AppIcon.appiconset/AppIcon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/Shared/Assets.xcassets/AppIcon.appiconset/AppIcon-128.png
--------------------------------------------------------------------------------
/source/Shared/Assets.xcassets/AppIcon.appiconset/AppIcon-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/Shared/Assets.xcassets/AppIcon.appiconset/AppIcon-16.png
--------------------------------------------------------------------------------
/source/Shared/Assets.xcassets/AppIcon.appiconset/AppIcon-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/Shared/Assets.xcassets/AppIcon.appiconset/AppIcon-256.png
--------------------------------------------------------------------------------
/source/Shared/Assets.xcassets/AppIcon.appiconset/AppIcon-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/Shared/Assets.xcassets/AppIcon.appiconset/AppIcon-32.png
--------------------------------------------------------------------------------
/source/Shared/Assets.xcassets/AppIcon.appiconset/AppIcon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/Shared/Assets.xcassets/AppIcon.appiconset/AppIcon-512.png
--------------------------------------------------------------------------------
/source/Shared/Assets.xcassets/AppIcon.appiconset/AppIcon-64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP/macOS-enterprise-privileges/608e9e7af7fc1c05f509524f1329e49e82e3f999/source/Shared/Assets.xcassets/AppIcon.appiconset/AppIcon-64.png
--------------------------------------------------------------------------------
/source/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "16x16",
5 | "idiom" : "mac",
6 | "filename" : "AppIcon-16.png",
7 | "scale" : "1x"
8 | },
9 | {
10 | "size" : "16x16",
11 | "idiom" : "mac",
12 | "filename" : "AppIcon-32.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "32x32",
17 | "idiom" : "mac",
18 | "filename" : "AppIcon-32.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "32x32",
23 | "idiom" : "mac",
24 | "filename" : "AppIcon-64.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "128x128",
29 | "idiom" : "mac",
30 | "filename" : "AppIcon-128.png",
31 | "scale" : "1x"
32 | },
33 | {
34 | "size" : "128x128",
35 | "idiom" : "mac",
36 | "filename" : "AppIcon-256.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "256x256",
41 | "idiom" : "mac",
42 | "filename" : "AppIcon-256.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "256x256",
47 | "idiom" : "mac",
48 | "filename" : "AppIcon-512.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "512x512",
53 | "idiom" : "mac",
54 | "filename" : "AppIcon-512.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "512x512",
59 | "idiom" : "mac",
60 | "filename" : "AppIcon-1024.png",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/source/Shared/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/source/Shared/Classes/MTAgentConnection.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTAgentConnection.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 | #import "PrivilegesXPCProtocol.h"
20 | #import "PrivilegesAgentProtocol.h"
21 | #import
22 | #import
23 |
24 | /*!
25 | @protocol MTAgentConnectionDelegate
26 | @abstract Defines an interface for delegates of MTAgentConnection to be notified if
27 | the connection to the agent failed.
28 | */
29 | @protocol MTAgentConnectionDelegate
30 |
31 | /*!
32 | @method connection:didFailWithError:
33 | @abstract Called if the connection to the agent failed.
34 | @param connection A reference to the NSXPCConnection instance that failed.
35 | @param error A reference to a NSError object that indicates why the xpc connection failed.
36 | @discussion Delegates receive this message if the connection to the agent failed.
37 | */
38 | - (void)connection:(NSXPCConnection*)connection didFailWithError:(NSError*)error;
39 |
40 | @end
41 |
42 | /*!
43 | @class MTAgentConnection
44 | @abstract A class that provides an easy way to connect to the Privileges agent.
45 | */
46 |
47 | @interface MTAgentConnection : NSObject
48 |
49 | /*!
50 | @property delegate
51 | @abstract The receiver's connection delegate.
52 | @discussion The value of this property is an object conforming to the MTAgentConnectionDelegate protocol.
53 | */
54 | @property (weak) id delegate;
55 |
56 | /*!
57 | @property connection
58 | @abstract A property to store the connection object.
59 | @discussion The value of this property is NSXPCConnection.
60 | */
61 | @property (atomic, strong, readonly) NSXPCConnection *connection;
62 |
63 | /*!
64 | @property remoteObjectProxy
65 | @abstract A property to store the connection's remote object proxy.
66 | @discussion The value of this property is id.
67 | */
68 | @property (atomic, strong, readonly) id remoteObjectProxy;
69 |
70 | /*!
71 | @method connectToXPCServiceWithRemoteObjectProxyReply:
72 | @abstract Returns a proxy for the xpc service.
73 | @param reply The reply block to call when the request is complete.
74 | @discussion Returns a proxy for the xpc service or nil if an error occurred. In case of an error
75 | the error object might contain information about the error that caused the operation
76 | to fail.
77 | */
78 | - (void)connectToXPCServiceWithRemoteObjectProxyReply:(void (^)(id remoteObjectProxy, NSError *error))reply;
79 |
80 | /*!
81 | @method connectToAgentWithExportedObject:andExecuteCommandBlock:
82 | @abstract Connects to the agent and executes the given command block.
83 | @param exportedObject The object you want to export to the agent. May be nil.
84 | @param commandBlock The command block that should be executed after the connection has been established.
85 | */
86 | - (void)connectToAgentWithExportedObject:(id)exportedObject
87 | andExecuteCommandBlock:(void(^)(void))commandBlock;
88 |
89 | /*!
90 | @method invalidate
91 | @abstract Invalidates the connection to the agent (and xpc service).
92 | */
93 | - (void)invalidate;
94 |
95 | @end
96 |
--------------------------------------------------------------------------------
/source/Shared/Classes/MTCodeSigning.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTCodeSigning.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 |
20 | /*!
21 | @class MTCodeSigning
22 | @abstract A class that provides some methods related to code signing and sandboxing.
23 | */
24 |
25 | @interface MTCodeSigning : NSObject
26 |
27 | /*!
28 | @method getSigningAuthorityWithError:
29 | @abstract Returns the current app's signing authority.
30 | @param error A reference to a NSError object that indicates why the xpc connection failed.
31 | @discussion Returns the current app's signing authority or nil if an error occurred. In case of an error
32 | the error object might contain information about the error that caused the operation
33 | to fail.
34 | */
35 | + (NSString*)getSigningAuthorityWithError:(NSError**)error;
36 |
37 | /*!
38 | @method codeSigningRequirementsWithCommonName:bundleIdentifier:versionString:
39 | @abstract Returns the code signing requirements constructed from the given parameters.
40 | @param commonName The common name (signing authority) that should be used for the code signing requirements.
41 | @param bundleIdentifier The app's bundle identifier that should be used for the code signing requirements.
42 | @param versionString The app's version string (e.g. 2.0.0) that should be used for the code signing requirements.
43 | @discussion Returns a string containing the code signing requirements or nil if an error occurred.
44 | */
45 | + (NSString*)codeSigningRequirementsWithCommonName:(NSString*)commonName
46 | bundleIdentifier:(NSString*)bundleIdentifier
47 | versionString:(NSString*)versionString;
48 |
49 | /*!
50 | @method sandboxStatusWithCompletionHandler:
51 | @abstract Returns whether the current application is sandboxed or not.
52 | @param completionHandler The completion handler to call when the request is complete.
53 | @discussion Returns YES if the current application is sandboxed, otherwise returns NO. In case of an error
54 | the error object might contain information about the error that caused the operation
55 | to fail.
56 | */
57 | + (void)sandboxStatusWithCompletionHandler:(void (^)(BOOL isSandboxed, NSError *error))completionHandler;
58 |
59 | @end
60 |
61 |
--------------------------------------------------------------------------------
/source/Shared/Classes/MTCodeSigning.m:
--------------------------------------------------------------------------------
1 | /*
2 | MTCodeSigning.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import "MTCodeSigning.h"
19 |
20 | @implementation MTCodeSigning
21 |
22 | + (NSString*)getSigningAuthorityWithError:(NSError**)error
23 | {
24 | OSStatus result = errSecSuccess;
25 | SecCodeRef helperCodeRef = NULL;
26 | NSString *returnValue = nil;
27 | NSString *errorMsg = nil;
28 |
29 | // get our code object
30 | result = SecCodeCopySelf(kSecCSDefaultFlags, &helperCodeRef);
31 |
32 | if (result != errSecSuccess) {
33 |
34 | errorMsg = [NSString stringWithFormat:@"Failed to copy code object: %d", result];
35 |
36 | } else {
37 |
38 | // get our static code
39 | SecStaticCodeRef staticCodeRef = NULL;
40 | result = SecCodeCopyStaticCode(helperCodeRef, kSecCSDefaultFlags, &staticCodeRef);
41 |
42 | if (result != errSecSuccess) {
43 |
44 | errorMsg = [NSString stringWithFormat:@"Failed to get static code object: %d", result];
45 |
46 | } else {
47 |
48 | // get our own signing information
49 | CFDictionaryRef signingInfo = NULL;
50 | result = SecCodeCopySigningInformation(staticCodeRef, kSecCSSigningInformation, &signingInfo);
51 |
52 | if (result != errSecSuccess) {
53 |
54 | errorMsg = [NSString stringWithFormat:@"Failed to get signing information: %d", result];
55 |
56 | } else {
57 |
58 | CFArrayRef certChain = (CFArrayRef) CFDictionaryGetValue(signingInfo, kSecCodeInfoCertificates);
59 |
60 | if (certChain && CFGetTypeID(certChain) == CFArrayGetTypeID() && CFArrayGetCount(certChain) > 0) {
61 |
62 | SecCertificateRef issuerCert = (SecCertificateRef) CFArrayGetValueAtIndex(certChain, 0);
63 |
64 | if (issuerCert) {
65 |
66 | CFStringRef subjectCN = NULL;
67 | SecCertificateCopyCommonName(issuerCert, &subjectCN);
68 | if (subjectCN) { returnValue = CFBridgingRelease(subjectCN); }
69 | }
70 | }
71 | }
72 |
73 | if (signingInfo) { CFRelease(signingInfo); }
74 | }
75 |
76 | if (staticCodeRef) { CFRelease(staticCodeRef); }
77 | }
78 |
79 | if (helperCodeRef) { CFRelease(helperCodeRef); }
80 |
81 | if (errorMsg && error) {
82 |
83 | NSDictionary *errorDetail = [NSDictionary dictionaryWithObjectsAndKeys:errorMsg, NSLocalizedDescriptionKey, nil];
84 | *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:100 userInfo:errorDetail];
85 | }
86 |
87 | return returnValue;
88 | }
89 |
90 | + (NSString*)codeSigningRequirementsWithCommonName:(NSString*)commonName
91 | bundleIdentifier:(NSString*)bundleIdentifier
92 | versionString:(NSString*)versionString
93 | {
94 | NSString *reqString = [NSString stringWithFormat:@"anchor trusted and certificate leaf [subject.CN] = \"%@\" and info [CFBundleShortVersionString] >= \"%@\" and info [CFBundleIdentifier] = %@", commonName, versionString, bundleIdentifier];
95 |
96 | return reqString;
97 | }
98 |
99 | + (void)sandboxStatusWithCompletionHandler:(void (^)(BOOL isSandboxed, NSError *error))completionHandler
100 | {
101 | if (completionHandler) {
102 |
103 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
104 |
105 | BOOL isSandboxed = NO;
106 | NSError *error = nil;
107 |
108 | SecCodeRef codeRef = NULL;
109 | CFDictionaryRef infoDict = NULL;
110 | CFTypeRef entitlements = NULL;
111 |
112 | OSStatus err = SecCodeCopySelf(kSecCSDefaultFlags, &codeRef);
113 |
114 | if (err == errSecSuccess) {
115 |
116 | err = SecCodeCopySigningInformation(codeRef, (SecCSFlags) kSecCSDynamicInformation, &infoDict);
117 |
118 | if (err == errSecSuccess) {
119 |
120 | if (CFDictionaryGetValueIfPresent(infoDict, kSecCodeInfoEntitlementsDict, &entitlements)) {
121 |
122 | if (entitlements != NULL && CFDictionaryGetValue(entitlements, CFSTR("com.apple.security.app-sandbox")) != NULL) {
123 |
124 | isSandboxed = YES;
125 | }
126 |
127 | } else {
128 |
129 | err = errSecMissingEntitlement;
130 | }
131 | }
132 | }
133 |
134 | if (err != errSecSuccess) { error = [NSError errorWithDomain:NSOSStatusErrorDomain code:err userInfo:nil]; }
135 |
136 | completionHandler(isSandboxed, error);
137 | });
138 | }
139 | }
140 |
141 | @end
142 |
--------------------------------------------------------------------------------
/source/Shared/Classes/MTIdentity.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTIdentity.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 | #import
20 | #import
21 | #import
22 |
23 | /*!
24 | @class MTIdentity
25 | @abstract This class provides methods for handling user identities.
26 | */
27 |
28 | @interface MTIdentity : NSObject
29 |
30 | /*!
31 | @method gidFromGroupName:
32 | @abstract Get the group id from a group name.
33 | @param groupName The short name of the group.
34 | @discussion Returns the id of the given group or -1 if an error occurred.
35 | */
36 | + (int)gidFromGroupName:(NSString*)groupName;
37 |
38 | /*!
39 | @method groupMembershipForUser:groupID:error
40 | @abstract Check if a given user is member of a given group.
41 | @param userName The short name of the user.
42 | @param groupID The id of the group.
43 | @param error A reference to an NSError object that contains a detailed error message if an error occurred. May be nil.
44 | @discussion Returns YES if the user is member of the group, otherwise returns NO.
45 | */
46 | + (BOOL)groupMembershipForUser:(NSString*)userName groupID:(gid_t)groupID error:(NSError**)error;
47 |
48 | /*!
49 | @method groupMembershipForUser:groupName:error
50 | @abstract Check if a given user is member of a given group.
51 | @param userName The short name of the user.
52 | @param groupName The name of the group.
53 | @param error A reference to an NSError object that contains a detailed error message if an error occurred. May be nil.
54 | @discussion Returns YES if the user is member of the group, otherwise returns NO.
55 | */
56 | + (BOOL)groupMembershipForUser:(NSString*)userName groupName:(NSString*)groupName error:(NSError**)error;
57 |
58 | /*!
59 | @method authenticateUserWithReason:completionHandler
60 | @abstract Authenticate the user either by using Touch ID (if available) or password.
61 | @param authReason The reason for requesting authentication, which displays in the authentication dialog presented to the user.
62 | @param completionHandler The handler to call when the request is complete.
63 | @discussion Returns YES if authentication succeeded, otherwise returns NO. If an error occurred, the completion handler's NSError object
64 | contains error details.
65 | */
66 | + (void)authenticateUserWithReason:(NSString*)authReason completionHandler:(void (^) (BOOL success, NSError *error))completionHandler;
67 |
68 | /*!
69 | @method authenticatePIVUserWithReason:completionHandler
70 | @abstract Authenticate the user either by using a smart card/PIV token or password.
71 | @param authReason The reason for requesting authentication, which displays in the authentication dialog presented to the user.
72 | @param completionHandler The handler to call when the request is complete.
73 | @discussion Returns YES if authentication succeeded, otherwise returns NO. If an error occurred, the completion handler's NSError object
74 | contains error details.
75 | */
76 | + (void)authenticatePIVUserWithReason:(NSString*)authReason completionHandler:(void (^) (BOOL success, NSError *error))completionHandler;
77 |
78 | /*!
79 | @method verifyPassword:forUser
80 | @abstract Verifies if a given password can be used to authenticate a given user.
81 | @param userPassword The user's password.
82 | @param userName The short name of the user.
83 | @discussion Returns YES if verification succeeded, otherwise returns NO.
84 | */
85 | + (BOOL)verifyPassword:(NSString*)userPassword forUser:(NSString*)userName;
86 |
87 | @end
88 |
--------------------------------------------------------------------------------
/source/Shared/Classes/MTPrivilegesUser.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTPrivilegesUser.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 | #import "MTIdentity.h"
20 |
21 | /*!
22 | @class MTPrivilegesUser
23 | @abstract This class provides methods for the current Privileges user to request and revoke administrator privileges.
24 | */
25 |
26 | @interface MTPrivilegesUser : NSObject
27 |
28 | /*!
29 | @property userName
30 | @abstract Returns the user name of the MTPrivilegesUser.
31 | @discussion The value of this property is string.
32 | */
33 | @property (nonatomic, strong, readonly) NSString *userName;
34 |
35 | /*!
36 | @method hasAdminPrivileges
37 | @abstract Get whether the MTPrivilegesUser has administrator privileges.
38 | @discussion Returns YES if the user has administrator privileges, otherwise returns NO.
39 | */
40 | - (BOOL)hasAdminPrivileges;
41 |
42 | /*!
43 | @method hasUnexpectedPrivilegeState
44 | @abstract Get whether the privileges of the MTPrivilegesUser have an unexpected state.
45 | @discussion Returns YES if the privileges for the user have been changed by another process and therefore
46 | different from the privileges we have set for this user, otherwise returns NO.
47 | */
48 | - (BOOL)hasUnexpectedPrivilegeState;
49 |
50 | /*!
51 | @method setUnexpectedPrivilegeState:
52 | @abstract Set whether the privileges for the MTPrivilegesUser are unexpected.
53 | @param unexpectedState A boolean indicating if the privileges are unexpected (YES) or not (NO).
54 | */
55 | - (void)setUnexpectedPrivilegeState:(BOOL)unexpectedState;
56 |
57 | /*!
58 | @method requestAdminPrivilegesWithReason:completionHandler:
59 | @abstract Request administrator privileges for the current MTPrivilegesUser.
60 | @param reason A string containing the reason the user requests administrator privileges. May be nil.
61 | @param completionHandler The handler to call when the request is complete.
62 | @discussion Returns YES if the operation was successful, otherwise returns NO.
63 | */
64 | - (void)requestAdminPrivilegesWithReason:(NSString*)reason completionHandler:(void(^)(BOOL success))completionHandler;
65 |
66 | /*!
67 | @method revokeAdminPrivilegesWithCompletionHandler:
68 | @abstract Revoke administrator privileges for the current MTPrivilegesUser.
69 | @param completionHandler The handler to call when the request is complete.
70 | @discussion Returns YES if the operation was successful, otherwise returns NO.
71 | */
72 | - (void)revokeAdminPrivilegesWithCompletionHandler:(void(^)(BOOL success))completionHandler;
73 |
74 | /*!
75 | @method renewAdminPrivilegesWithCompletionHandler:
76 | @abstract Renew expiring administrator privileges for the current MTPrivilegesUser.
77 | @param completionHandler The handler to call when the request is complete.
78 | @discussion Returns YES if the operation was successful, otherwise returns NO.
79 | */
80 | - (void)renewAdminPrivilegesWithCompletionHandler:(void(^)(BOOL success))completionHandler;
81 |
82 | /*!
83 | @method authenticateWithCompletionHandler:
84 | @abstract Authenticate the current MTPrivilegesUser.
85 | @param completionHandler The handler to call when the request is complete.
86 | @discussion Returns YES if the operation was successful, otherwise returns NO.
87 | */
88 | - (void)authenticateWithCompletionHandler:(void(^)(BOOL success))completionHandler;
89 |
90 | /*!
91 | @method privilegesExpirationWithReply:
92 | @abstract Get the date when the current user's administrator privileges expire.
93 | @param reply The reply block to call when the request is complete.
94 | @discussion Returns the expiration date and the number of minutes remaining. Expiration date will be nil
95 | if the administrator privileges are already expired.
96 | */
97 | - (void)privilegesExpirationWithReply:(void(^)(NSDate *expire, NSUInteger remaining))reply;
98 |
99 | /*!
100 | @method canExecuteFileAtURL:reply:
101 | @abstract Get whether the current user can execute the file at the given url.
102 | @param reply The reply block to call when the request is complete.
103 | @discussion Returns YES if the file can be executed by the current user, otherwise returns NO.
104 | */
105 | - (void)canExecuteFileAtURL:(NSURL*)url reply:(void (^)(BOOL canExecute))reply;
106 |
107 | /*!
108 | @method useIsRestricted
109 | @abstract Get whether the app usage is restricted for the user.
110 | @discussion Returns YES if the app usage is restricted for the user, otherwise returns NO.
111 | */
112 | - (BOOL)useIsRestricted;
113 |
114 | /*!
115 | @method isExcludedFromRevokeAtLogin
116 | @abstract Get whether the current user is excluded from the automatic privilege removal at login.
117 | @discussion Returns YES if the user is excluded, otherwise returns NO.
118 | */
119 | - (BOOL)isExcludedFromRevokeAtLogin;
120 |
121 | @end
122 |
123 |
--------------------------------------------------------------------------------
/source/Shared/Classes/MTSystemInfo.h:
--------------------------------------------------------------------------------
1 | /*
2 | MTSystemInfo.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import
19 |
20 | /*!
21 | @class MTSystemInfo
22 | @abstract This class provides methods to get some system information.
23 | */
24 |
25 | @interface MTSystemInfo : NSObject
26 |
27 | /*!
28 | @method machineUUID
29 | @abstract Returns the uuid of the current machine.
30 | @discussion Returns a NSString containing the uuid or nil if an error occurred.
31 | */
32 | + (NSString*)machineUUID;
33 |
34 | /*!
35 | @method sessionStartDate
36 | @abstract Returns the start date of the current login session.
37 | @discussion Returns the start date of the current login session or a date in the distant future if an error occurred.
38 | */
39 | + (NSDate*)sessionStartDate;
40 |
41 | /*!
42 | @method isExecutableFileAtURL:
43 | @abstract Returns whether the file at the given url is executable.
44 | @param url The file url to check.
45 | @discussion Returns YES, if the file url is valid, the file exists and if it's executable. Otherwise returns NO.
46 | */
47 | + (BOOL)isExecutableFileAtURL:(NSURL*)url;
48 |
49 | @end
50 |
51 |
--------------------------------------------------------------------------------
/source/Shared/Classes/MTSystemInfo.m:
--------------------------------------------------------------------------------
1 | /*
2 | MTSystemInfo.m
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #import "MTSystemInfo.h"
19 | #import
20 | #import
21 |
22 | @implementation MTSystemInfo
23 |
24 | + (NSString*)machineUUID
25 | {
26 | NSString *returnValue = @"";
27 |
28 | // get the Platform Expert object
29 | io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
30 |
31 | if (platformExpert) {
32 |
33 | CFStringRef uuid = IORegistryEntryCreateCFProperty(platformExpert, CFSTR(kIOPlatformUUIDKey), kCFAllocatorDefault, kNilOptions);
34 |
35 | if (uuid) {
36 |
37 | returnValue = (__bridge NSString *)(uuid);
38 | CFRelease(uuid);
39 | }
40 |
41 | IOObjectRelease(platformExpert);
42 | }
43 |
44 | return returnValue;
45 | }
46 |
47 | + (NSDate*)sessionStartDate
48 | {
49 | NSDate *startDate = [NSDate distantFuture];
50 |
51 | size_t len = 4;
52 | int mib[len];
53 | struct kinfo_proc kp;
54 |
55 | if (sysctlnametomib("kern.proc.pid", mib, &len) == 0) {
56 |
57 | // get the loginwindow process
58 | NSRunningApplication *app = [[NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.loginwindow"] firstObject];
59 | mib[3] = [app processIdentifier];
60 | len = sizeof(kp);
61 |
62 | if (sysctl(mib, 4, &kp, &len, NULL, 0) == 0) {
63 |
64 | struct timeval processStartTime = kp.kp_proc.p_un.__p_starttime;
65 | startDate = [NSDate dateWithTimeIntervalSince1970:processStartTime.tv_sec + processStartTime.tv_usec / 1e6];
66 | }
67 | }
68 |
69 | return startDate;
70 | }
71 |
72 | + (BOOL)isExecutableFileAtURL:(NSURL*)url
73 | {
74 | BOOL isExecutable = NO;
75 |
76 | if (url && [url isFileURL]) {
77 |
78 | NSDictionary *resourceValues = [url resourceValuesForKeys:[NSArray arrayWithObjects:NSURLIsPackageKey, NSURLIsExecutableKey, nil]
79 | error:nil
80 | ];
81 |
82 | if (resourceValues && [[resourceValues objectForKey:NSURLIsPackageKey] boolValue]) {
83 |
84 | isExecutable = [[resourceValues objectForKey:NSURLIsExecutableKey] boolValue];
85 |
86 | } else {
87 |
88 | int status = access([[url path] UTF8String], X_OK);
89 | isExecutable = (status == -1) ? NO : YES;
90 | }
91 | }
92 |
93 | return isExecutable;
94 | }
95 |
96 | @end
97 |
--------------------------------------------------------------------------------
/source/Shared/Constants.h:
--------------------------------------------------------------------------------
1 | /*
2 | Constants.h
3 | Copyright 2016-2025 SAP SE
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 | */
17 |
18 | #define kMTAppName @"Privileges"
19 | #define kMTDaemonMachServiceName @"corp.sap.privileges.daemon.xpc"
20 | #define kMTAgentMachServiceName @"corp.sap.privileges.agent.xpc"
21 | #define kMTXPCServiceName @"corp.sap.privileges.xpcservice"
22 | #define kMTAppBundleIdentifier @"corp.sap.privileges"
23 | #define kMTAuthRightName "corp.sap.privileges.auth"
24 | #define kMTAppGroupIdentifier @"7R5ZEU67FQ.corp.sap.privileges"
25 | #define kMTDockTilePluginBundleIdentifier @"corp.sap.privileges.docktileplugin"
26 | #define kMTErrorDomain @"corp.sap.privileges.ErrorDomain"
27 | #define kMTWebhookEventTypeGranted @"corp.sap.privileges.granted"
28 | #define kMTWebhookEventTypeRevoked @"corp.sap.privileges.revoked"
29 | #define kMTGitHubURL @"https://github.com/SAP/macOS-enterprise-privileges"
30 |
31 | #define kMTAdminGroupID 80
32 | #define kMTExpirationDefault 20
33 | #define kMTReasonMinLengthDefault 10
34 | #define kMTReasonMaxLengthDefault 250
35 | #define kMTFixedExpirationIntervals @[@0, @5, @10, @20, @30, @60]
36 | #define kMTRevokeAtLoginThreshold 60
37 |
38 | #define kMTEnforcedPrivilegeTypeNone @"none"
39 | #define kMTEnforcedPrivilegeTypeAdmin @"admin"
40 | #define kMTEnforcedPrivilegeTypeUser @"user"
41 |
42 | #define kMTRemoteLoggingServerTypeSyslog @"syslog"
43 | #define kMTRemoteLoggingServerTypeWebhook @"webhook"
44 |
45 | // NSUserDefaults
46 | #define kMTDefaultsExpirationIntervalKey @"ExpirationInterval"
47 | #define kMTDefaultsAutoExpirationIntervalMaxKey @"ExpirationIntervalMax"
48 | #define kMTDefaultsEnforcePrivilegesKey @"EnforcePrivileges"
49 | #define kMTDefaultsAuthRequiredKey @"RequireAuthentication"
50 | #define kMTDefaultsAuthCLIBiometricsAllowedKey @"AllowCLIBiometricAuthentication"
51 | #define kMTDefaultsLimitToUserKey @"LimitToUser"
52 | #define kMTDefaultsLimitToGroupKey @"LimitToGroup"
53 | #define kMTDefaultsRequireReasonKey @"ReasonRequired"
54 | #define kMTDefaultsReasonMinLengthKey @"ReasonMinLength"
55 | #define kMTDefaultsReasonMaxLengthKey @"ReasonMaxLength"
56 | #define kMTDefaultsReasonPresetsKey @"ReasonPresetList"
57 | #define kMTDefaultsReasonCheckingEnabledKey @"ReasonCheckingEnabled"
58 | #define kMTDefaultsRemoteLoggingKey @"RemoteLogging"
59 | #define kMTDefaultsRemoteLoggingServerTypeKey @"ServerType"
60 | #define kMTDefaultsRemoteLoggingServerAddressKey @"ServerAddress"
61 | #define kMTDefaultsRemoteLoggingSyslogOptionsKey @"SyslogOptions"
62 | #define kMTDefaultsRemoteLoggingSyslogServerPortKey @"ServerPort"
63 | #define kMTDefaultsRemoteLoggingSyslogUseTLSKey @"UseTLS"
64 | #define kMTDefaultsRemoteLoggingSyslogFacilityKey @"LogFacility"
65 | #define kMTDefaultsRemoteLoggingSyslogSeverityKey @"LogSeverity"
66 | #define kMTDefaultsRemoteLoggingSyslogMaxSizeKey @"MaximumMessageSize"
67 | #define kMTDefaultsRemoteLoggingSyslogFormatKey @"MessageFormat"
68 | #define kMTDefaultsRemoteLoggingSyslogSDKey @"StructuredData"
69 | #define kMTDefaultsRemoteLoggingWebhookDataKey @"WebhookCustomData"
70 | #define kMTDefaultsHideOtherWindowsKey @"HideOtherWindows"
71 | #define kMTDefaultsRevokeAtLoginKey @"RevokePrivilegesAtLogin"
72 | #define kMTDefaultsRevokeAtLoginExcludedUsersKey @"RevokeAtLoginExcludedUsers"
73 | #define kMTDefaultsPostChangeExecutablePathKey @"PostChangeExecutablePath"
74 | #define kMTDefaultsPostChangeActionOnGrantOnlyKey @"PostChangeActionOnGrantOnly"
75 | #define kMTDefaultsAgentTimerExpirationKey @"TimerExpires"
76 | #define kMTDefaultsUnhideOtherWindowsKey @"UnhideOtherWindows"
77 | #define kMTDefaultsHideSettingsButtonKey @"HideSettingsButton"
78 | #define kMTDefaultsHideSettingsFromDockMenuKey @"HideSettingsFromDockMenu"
79 | #define kMTDefaultsHideSettingsFromStatusItemKey @"HideSettingsFromStatusItem"
80 | #define kMTDefaultsAllowPrivilegeRenewalKey @"AllowPrivilegeRenewal"
81 | #define kMTDefaultsRenewalFollowsAuthSettingKey @"RenewalFollowsAuthSetting"
82 | #define kMTDefaultsHideHelpButtonKey @"HideHelpButton"
83 | #define kMTDefaultsHelpButtonCustomURLKey @"HelpButtonCustomURL"
84 | #define kMTDefaultsPassReasonToExecutableKey @"PassReasonToExecutable"
85 | #define kMTDefaultsShowInMenuBarKey @"ShowInMenuBar"
86 | #define kMTDefaultsSettingsSelectedTabKey @"SettingsSelectedTab"
87 | #define kMTDefaultsEnableSmartCardSupportKey @"EnableSmartCardSupport"
88 | #define kMTDefaultsRenewalCustomActionKey @"RenewalCustomAction"
89 | #define kMTDefaultsRenewalCustomActionPathKey @"ActionExecutablePath"
90 | #define kMTDefaultsRenewalCustomActionIntervalKey @"ActionNotificationInterval"
91 | #define kMTDefaultsUnexpectedPrivilegeStateKey @"UnexpectedPrivilegeState"
92 |
93 | // NSNotification
94 | #define kMTNotificationNamePrivilegesDidChange @"corp.sap.privileges.PrivilegesDidChange"
95 | #define kMTNotificationNameExpirationTimeLeft @"corp.sap.privileges.ExpirationTimeLeft"
96 | #define kMTNotificationNameConfigDidChange @"corp.sap.privileges.ConfigDidChange"
97 | #define kMTNotificationCategoryIdentifier @"corp.sap.privileges.action"
98 | #define kMTNotificationActionIdentifierRenew @"corp.sap.privileges.action.renew"
99 | #define kMTNotificationNameAdminGroupDidChange @"corp.sap.privileges.AdminGroupDidChange"
100 |
101 | // NSNotification user info keys
102 | #define kMTNotificationKeyTimeLeft @"TimeLeft"
103 | #define kMTNotificationKeyPreferencesChanged @"PreferenceKey"
104 |
--------------------------------------------------------------------------------