1 /*
2 Bacula(R) - The Network Backup Solution
3
4 Copyright (C) 2000-2018 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 * Written by James Harper, July 2010
21 *
22 * Used only in "old Exchange plugin" now deprecated.
23 */
24
25 #include "exchange-fd.h"
26
dbi_node_t(char * name,node_t * parent_node)27 dbi_node_t::dbi_node_t(char *name, node_t *parent_node) : node_t(name, NODE_TYPE_DATABASE_INFO, parent_node)
28 {
29 restore_display_name = NULL;
30 restore_input_streams = NULL;
31 buffer = NULL;
32 }
33
~dbi_node_t()34 dbi_node_t::~dbi_node_t()
35 {
36 safe_delete(buffer);
37 safe_delete(restore_input_streams);
38 safe_delete(restore_display_name);
39 }
40
41 bRC
startBackupFile(exchange_fd_context_t * context,struct save_pkt * sp)42 dbi_node_t::startBackupFile(exchange_fd_context_t *context, struct save_pkt *sp)
43 {
44 time_t now = time(NULL);
45
46 _DebugMessage(100, "startBackupNode_DBI state = %d\n", state);
47
48 if (context->job_level == 'F') {
49 sp->fname = full_path;
50 sp->link = full_path;
51 sp->statp.st_mode = 0700 | S_IFREG;
52 sp->statp.st_ctime = now;
53 sp->statp.st_mtime = now;
54 sp->statp.st_atime = now;
55 sp->statp.st_size = (uint64_t)-1;
56 sp->type = FT_REG;
57 return bRC_OK;
58 }
59 else
60 {
61 bfuncs->setBaculaValue(context->bpContext, bVarFileSeen, (void *)full_path);
62 return bRC_Seen;
63 }
64 }
65
66 bRC
endBackupFile(exchange_fd_context_t * context)67 dbi_node_t::endBackupFile(exchange_fd_context_t *context)
68 {
69 _DebugMessage(100, "endBackupNode_DBI state = %d\n", state);
70
71 context->current_node = parent;
72
73 return bRC_OK;
74 }
75
76 bRC
createFile(exchange_fd_context_t * context,struct restore_pkt * rp)77 dbi_node_t::createFile(exchange_fd_context_t *context, struct restore_pkt *rp)
78 {
79 _DebugMessage(0, "createFile_DBI state = %d\n", state);
80
81 rp->create_status = CF_EXTRACT;
82
83 return bRC_OK;
84 }
85
86 bRC
endRestoreFile(exchange_fd_context_t * context)87 dbi_node_t::endRestoreFile(exchange_fd_context_t *context)
88 {
89 _DebugMessage(0, "endRestoreFile_DBI state = %d\n", state);
90
91 context->current_node = parent;
92
93 return bRC_OK;
94 }
95
96 bRC
pluginIoOpen(exchange_fd_context_t * context,struct io_pkt * io)97 dbi_node_t::pluginIoOpen(exchange_fd_context_t *context, struct io_pkt *io)
98 {
99 uint32_t len;
100 WCHAR *ptr;
101 WCHAR *stream;
102 //char tmp[512];
103
104 buffer_pos = 0;
105 buffer_size = 65536;
106 buffer = new char[buffer_size];
107
108 if (context->job_type == JOB_TYPE_BACKUP)
109 {
110 ptr = (WCHAR *)buffer;
111 len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"DatabaseBackupInfo\n");
112 if (len < 0)
113 goto fail;
114 buffer_pos += len * 2;
115 ptr += len;
116
117 len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%d\n", EXCHANGE_PLUGIN_VERSION);
118 if (len < 0)
119 goto fail;
120 buffer_pos += len * 2;
121 ptr += len;
122
123 len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%s\n", dbi->wszDatabaseDisplayName);
124 if (len < 0)
125 goto fail;
126 buffer_pos += len * 2;
127 ptr += len;
128
129 len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
130 dbi->rguidDatabase.Data1, dbi->rguidDatabase.Data2, dbi->rguidDatabase.Data3,
131 dbi->rguidDatabase.Data4[0], dbi->rguidDatabase.Data4[1],
132 dbi->rguidDatabase.Data4[2], dbi->rguidDatabase.Data4[3],
133 dbi->rguidDatabase.Data4[4], dbi->rguidDatabase.Data4[5],
134 dbi->rguidDatabase.Data4[6], dbi->rguidDatabase.Data4[7]);
135 if (len < 0)
136 goto fail;
137 buffer_pos += len * 2;
138 ptr += len;
139
140 stream = dbi->wszDatabaseStreams;
141 while (*stream)
142 {
143 len = snwprintf(ptr, (buffer_size - buffer_pos) / 2, L"%s\n", stream);
144 if (len < 0)
145 goto fail;
146 buffer_pos += len * 2;
147 ptr += len;
148 stream += wcslen(stream) + 1;
149 }
150
151 buffer_size = buffer_pos;
152 buffer_pos = 0;
153 }
154
155 io->status = 0;
156 io->io_errno = 0;
157 return bRC_OK;
158
159 fail:
160 io->status = 0;
161 io->io_errno = 1;
162 return bRC_Error;
163 }
164
165 bRC
pluginIoRead(exchange_fd_context_t * context,struct io_pkt * io)166 dbi_node_t::pluginIoRead(exchange_fd_context_t *context, struct io_pkt *io)
167 {
168 io->status = 0;
169 io->io_errno = 0;
170
171 io->status = MIN(io->count, (int)(buffer_size - buffer_pos));
172 if (io->status == 0)
173 return bRC_OK;
174 memcpy(io->buf, buffer + buffer_pos, io->status);
175 buffer_pos += io->status;
176
177 return bRC_OK;
178 }
179
180 bRC
pluginIoWrite(exchange_fd_context_t * context,struct io_pkt * io)181 dbi_node_t::pluginIoWrite(exchange_fd_context_t *context, struct io_pkt *io)
182 {
183 memcpy(&buffer[buffer_pos], io->buf, io->count);
184 buffer_pos += io->count;
185 io->status = io->count;
186 io->io_errno = 0;
187 return bRC_OK;
188 }
189
190 bRC
pluginIoClose(exchange_fd_context_t * context,struct io_pkt * io)191 dbi_node_t::pluginIoClose(exchange_fd_context_t *context, struct io_pkt *io)
192 {
193 WCHAR tmp[128];
194 WCHAR *ptr;
195 WCHAR eol;
196 int wchars_read;
197 int version;
198 int stream_buf_count;
199 WCHAR *streams_start;
200
201 if (context->job_type == JOB_TYPE_RESTORE)
202 {
203 // need to think about making this buffer overflow proof...
204 _DebugMessage(100, "analyzing DatabaseBackupInfo\n");
205 ptr = (WCHAR *)buffer;
206
207 if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
208 goto restore_fail;
209 ptr += wchars_read;
210 _DebugMessage(150, "Header = %S\n", tmp);
211 // verify that header == "DatabaseBackupInfo"
212
213 if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
214 goto restore_fail;
215 if (swscanf(tmp, L"%d%c", &version, &eol) != 1)
216 {
217 version = 0;
218 _DebugMessage(150, "Version = 0 (inferred)\n");
219 }
220 else
221 {
222 ptr += wchars_read;
223 _DebugMessage(150, "Version = %d\n", version);
224 if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
225 goto restore_fail;
226 }
227 restore_display_name = new WCHAR[wchars_read];
228 swscanf(ptr, L"%127[^\n]", restore_display_name);
229 _DebugMessage(150, "Database Display Name = %S\n", restore_display_name);
230 ptr += wchars_read;
231
232 if (swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) != 2)
233 goto restore_fail;
234
235 if (swscanf(ptr, L"%8x-%4x-%4x-%2x%2x-%2x%2x%2x%2x%2x%2x",
236 &restore_guid.Data1, &restore_guid.Data2, &restore_guid.Data3,
237 &restore_guid.Data4[0], &restore_guid.Data4[1],
238 &restore_guid.Data4[2], &restore_guid.Data4[3],
239 &restore_guid.Data4[4], &restore_guid.Data4[5],
240 &restore_guid.Data4[6], &restore_guid.Data4[7]) != 11)
241 {
242 goto restore_fail;
243 }
244 _DebugMessage(150, "GUID = %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
245 restore_guid.Data1, restore_guid.Data2, restore_guid.Data3,
246 restore_guid.Data4[0], restore_guid.Data4[1],
247 restore_guid.Data4[2], restore_guid.Data4[3],
248 restore_guid.Data4[4], restore_guid.Data4[5],
249 restore_guid.Data4[6], restore_guid.Data4[7]);
250
251 ptr += wchars_read;
252
253 stream_buf_count = 1;
254 streams_start = ptr;
255 while (ptr < (WCHAR *)(buffer + buffer_pos) && swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) == 2)
256 {
257 _DebugMessage(150, "File = %S\n", tmp);
258 ptr += wchars_read;
259 stream_buf_count += wchars_read;
260 }
261 restore_input_streams = new WCHAR[stream_buf_count];
262 ptr = streams_start;
263 stream_buf_count = 0;
264 while (ptr < (WCHAR *)(buffer + buffer_pos) && swscanf(ptr, L"%127[^\n]%c%n", tmp, &eol, &wchars_read) == 2)
265 {
266 snwprintf(&restore_input_streams[stream_buf_count], 65535, L"%s", tmp);
267 ptr += wchars_read;
268 stream_buf_count += wchars_read;
269 }
270 restore_input_streams[stream_buf_count] = 0;
271
272 _DebugMessage(100, "done analyzing DatabasePluginInfo\n");
273 }
274 safe_delete(buffer);
275 return bRC_OK;
276 restore_fail:
277 _JobMessage(M_FATAL, "Format of %s is incorrect", full_path);
278 safe_delete(buffer);
279 return bRC_Error;
280 }
281