1 /*
2 Bacula(R) - The Network Backup Solution
3
4 Copyright (C) 2000-2020 Kern Sibbald
5
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
8
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
13
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
16
17 Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20 * Enable backup privileges for Win32 systems.
21 *
22 * Kern Sibbald, May MMIII
23 *
24 */
25
26 #include "bacula.h"
27 #include "find.h"
28 #include "jcr.h"
29
30
31 /*=============================================================*/
32 /* */
33 /* * * * U n i x * * * * */
34 /* */
35 /*=============================================================*/
36
37 #if !defined(HAVE_WIN32)
38
enable_backup_privileges(JCR * jcr,int ignore_errors)39 int enable_backup_privileges(JCR *jcr, int ignore_errors)
40 { return 0; }
41
42
43 #endif
44
45
46
47 /*=============================================================*/
48 /* */
49 /* * * * W i n 3 2 * * * * */
50 /* */
51 /*=============================================================*/
52
53 #if defined(HAVE_WIN32)
54
55 void win_error(JCR *jcr, const char *prefix, DWORD lerror);
56
57 static int
enable_priv(JCR * jcr,HANDLE hToken,const char * name,int ignore_errors)58 enable_priv(JCR *jcr, HANDLE hToken, const char *name, int ignore_errors)
59 {
60 TOKEN_PRIVILEGES tkp;
61 DWORD lerror;
62
63 if (!(p_LookupPrivilegeValue && p_AdjustTokenPrivileges)) {
64 return 0; /* not avail on this OS */
65 }
66
67 // Get the LUID for the security privilege.
68 if (!p_LookupPrivilegeValue(NULL, name, &tkp.Privileges[0].Luid)) {
69 win_error(jcr, "LookupPrivilegeValue", GetLastError());
70 return 0;
71 }
72
73 /* Set the security privilege for this process. */
74 tkp.PrivilegeCount = 1;
75 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
76 p_AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
77 lerror = GetLastError();
78 if (lerror != ERROR_SUCCESS) {
79 if (!ignore_errors) {
80 char buf[200];
81 strcpy(buf, _("AdjustTokenPrivileges set "));
82 bstrncat(buf, name, sizeof(buf));
83 win_error(jcr, buf, lerror);
84 }
85 return 0;
86 }
87 return 1;
88 }
89
90 /*
91 * Setup privileges we think we will need. We probably do not need
92 * the SE_SECURITY_NAME, but since nothing seems to be working,
93 * we get it hoping to fix the problems.
94 */
enable_backup_privileges(JCR * jcr,int ignore_errors)95 int enable_backup_privileges(JCR *jcr, int ignore_errors)
96 {
97 HANDLE hToken, hProcess;
98 int stat = 0;
99
100 if (!p_OpenProcessToken) {
101 return 0; /* No avail on this OS */
102 }
103
104 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
105
106 // Get a token for this process.
107 if (!p_OpenProcessToken(hProcess,
108 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
109 if (!ignore_errors) {
110 win_error(jcr, "OpenProcessToken", GetLastError());
111 }
112 /* Forge on anyway */
113 }
114
115 /* Return a bit map of permissions set. */
116 if (enable_priv(jcr, hToken, SE_BACKUP_NAME, ignore_errors)) {
117 stat |= 1<<1;
118 }
119 if (enable_priv(jcr, hToken, SE_RESTORE_NAME, ignore_errors)) {
120 stat |= 1<<2;
121 }
122 if (enable_priv(jcr, hToken, SE_SECURITY_NAME, ignore_errors)) {
123 stat |= 1<<0;
124 }
125 if (enable_priv(jcr, hToken, SE_TAKE_OWNERSHIP_NAME, ignore_errors)) {
126 stat |= 1<<3;
127 }
128 if (enable_priv(jcr, hToken, SE_ASSIGNPRIMARYTOKEN_NAME, ignore_errors)) {
129 stat |= 1<<4;
130 }
131 if (enable_priv(jcr, hToken, SE_SYSTEM_ENVIRONMENT_NAME, ignore_errors)) {
132 stat |= 1<<5;
133 }
134 if (enable_priv(jcr, hToken, SE_CREATE_TOKEN_NAME, ignore_errors)) {
135 stat |= 1<<6;
136 }
137 if (enable_priv(jcr, hToken, SE_MACHINE_ACCOUNT_NAME, ignore_errors)) {
138 stat |= 1<<7;
139 }
140 if (enable_priv(jcr, hToken, SE_TCB_NAME, ignore_errors)) {
141 stat |= 1<<8;
142 }
143 if (enable_priv(jcr, hToken, SE_CREATE_PERMANENT_NAME, ignore_errors)) {
144 stat |= 1<<10;
145 }
146
147 if (stat) {
148 stat |= 1<<9;
149 }
150
151 CloseHandle(hToken);
152 CloseHandle(hProcess);
153 return stat;
154 }
155
156 #endif /* HAVE_WIN32 */
157