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