Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : Map lease keys to file ids
4 : Copyright (C) Volker Lendecke 2013
5 :
6 : This program is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation; either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>.
18 :
19 : */
20 :
21 : #include "includes.h"
22 : #include "system/filesys.h"
23 : #include "locking/leases_db.h"
24 : #include "dbwrap/dbwrap.h"
25 : #include "dbwrap/dbwrap_open.h"
26 : #include "util_tdb.h"
27 : #include "ndr.h"
28 : #include "librpc/gen_ndr/ndr_leases_db.h"
29 :
30 : #undef DBGC_CLASS
31 : #define DBGC_CLASS DBGC_LOCKING
32 :
33 : /* the leases database handle */
34 : static struct db_context *leases_db;
35 :
36 44 : bool leases_db_init(bool read_only)
37 : {
38 : char *db_path;
39 :
40 44 : if (leases_db) {
41 0 : return true;
42 : }
43 :
44 44 : db_path = lock_path(talloc_tos(), "leases.tdb");
45 44 : if (db_path == NULL) {
46 0 : return false;
47 : }
48 :
49 44 : leases_db = db_open(NULL, db_path, 0,
50 : TDB_DEFAULT|
51 : TDB_VOLATILE|
52 : TDB_CLEAR_IF_FIRST|
53 : TDB_SEQNUM|
54 : TDB_INCOMPATIBLE_HASH,
55 : read_only ? O_RDONLY : O_RDWR|O_CREAT, 0644,
56 : DBWRAP_LOCK_ORDER_4, DBWRAP_FLAG_NONE);
57 44 : TALLOC_FREE(db_path);
58 44 : if (leases_db == NULL) {
59 0 : DEBUG(1, ("ERROR: Failed to initialise leases database\n"));
60 0 : return false;
61 : }
62 :
63 44 : return true;
64 : }
65 :
66 : struct leases_db_key_buf {
67 : uint8_t buf[32];
68 : };
69 :
70 0 : static TDB_DATA leases_db_key(struct leases_db_key_buf *buf,
71 : const struct GUID *client_guid,
72 : const struct smb2_lease_key *lease_key)
73 : {
74 0 : struct leases_db_key db_key = {
75 : .client_guid = *client_guid,
76 : .lease_key = *lease_key };
77 0 : DATA_BLOB blob = { .data = buf->buf, .length = sizeof(buf->buf) };
78 : enum ndr_err_code ndr_err;
79 :
80 0 : if (DEBUGLEVEL >= 10) {
81 0 : DBG_DEBUG("\n");
82 0 : NDR_PRINT_DEBUG(leases_db_key, &db_key);
83 : }
84 :
85 0 : ndr_err = ndr_push_struct_into_fixed_blob(
86 : &blob, &db_key, (ndr_push_flags_fn_t)ndr_push_leases_db_key);
87 0 : SMB_ASSERT(NDR_ERR_CODE_IS_SUCCESS(ndr_err));
88 :
89 0 : return (TDB_DATA) { .dptr = buf->buf, .dsize = sizeof(buf->buf) };
90 : }
91 :
92 : struct leases_db_do_locked_state {
93 : void (*fn)(struct leases_db_value *value,
94 : bool *modified,
95 : void *private_data);
96 : void *private_data;
97 : NTSTATUS status;
98 : };
99 :
100 0 : static void leases_db_do_locked_fn(
101 : struct db_record *rec,
102 : TDB_DATA db_value,
103 : void *private_data)
104 : {
105 0 : struct leases_db_do_locked_state *state = private_data;
106 0 : DATA_BLOB blob = { .data = db_value.dptr, .length = db_value.dsize };
107 0 : struct leases_db_value *value = NULL;
108 : enum ndr_err_code ndr_err;
109 0 : bool modified = false;
110 :
111 0 : value = talloc_zero(talloc_tos(), struct leases_db_value);
112 0 : if (value == NULL) {
113 0 : state->status = NT_STATUS_NO_MEMORY;
114 0 : goto done;
115 : }
116 :
117 0 : if (blob.length != 0) {
118 0 : ndr_err = ndr_pull_struct_blob_all(
119 : &blob,
120 : value,
121 : value,
122 : (ndr_pull_flags_fn_t)ndr_pull_leases_db_value);
123 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
124 0 : DBG_ERR("ndr_pull_struct_blob_failed: %s\n",
125 : ndr_errstr(ndr_err));
126 0 : state->status = ndr_map_error2ntstatus(ndr_err);
127 0 : goto done;
128 : }
129 : }
130 :
131 0 : state->fn(value, &modified, state->private_data);
132 :
133 0 : if (!modified) {
134 0 : goto done;
135 : }
136 :
137 0 : if (value->num_files == 0) {
138 0 : state->status = dbwrap_record_delete(rec);
139 0 : if (!NT_STATUS_IS_OK(state->status)) {
140 0 : DBG_ERR("dbwrap_record_delete returned %s\n",
141 : nt_errstr(state->status));
142 : }
143 0 : goto done;
144 : }
145 :
146 0 : ndr_err = ndr_push_struct_blob(
147 : &blob,
148 : value,
149 : value,
150 : (ndr_push_flags_fn_t)ndr_push_leases_db_value);
151 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
152 0 : DBG_ERR("ndr_push_struct_blob_failed: %s\n",
153 : ndr_errstr(ndr_err));
154 0 : state->status = ndr_map_error2ntstatus(ndr_err);
155 0 : goto done;
156 : }
157 :
158 0 : if (DEBUGLEVEL >= 10) {
159 0 : DBG_DEBUG("\n");
160 0 : NDR_PRINT_DEBUG(leases_db_value, value);
161 : }
162 :
163 0 : db_value = make_tdb_data(blob.data, blob.length);
164 :
165 0 : state->status = dbwrap_record_store(rec, db_value, 0);
166 0 : if (!NT_STATUS_IS_OK(state->status)) {
167 0 : DBG_ERR("dbwrap_record_store returned %s\n",
168 : nt_errstr(state->status));
169 : }
170 :
171 0 : done:
172 0 : TALLOC_FREE(value);
173 0 : }
174 :
175 0 : static NTSTATUS leases_db_do_locked(
176 : const struct GUID *client_guid,
177 : const struct smb2_lease_key *lease_key,
178 : void (*fn)(struct leases_db_value *value,
179 : bool *modified,
180 : void *private_data),
181 : void *private_data)
182 : {
183 : struct leases_db_key_buf keybuf;
184 0 : TDB_DATA db_key = leases_db_key(&keybuf, client_guid, lease_key);
185 0 : struct leases_db_do_locked_state state = {
186 : .fn = fn, .private_data = private_data,
187 : };
188 : NTSTATUS status;
189 :
190 0 : if (!leases_db_init(false)) {
191 0 : return NT_STATUS_INTERNAL_ERROR;
192 : }
193 :
194 0 : status = dbwrap_do_locked(
195 : leases_db, db_key, leases_db_do_locked_fn, &state);
196 0 : if (!NT_STATUS_IS_OK(status)) {
197 0 : return status;
198 : }
199 0 : return state.status;
200 : }
201 :
202 : struct leases_db_add_state {
203 : const struct file_id *id;
204 : uint32_t current_state;
205 : uint16_t lease_version;
206 : uint16_t epoch;
207 : const char *servicepath;
208 : const char *base_name;
209 : const char *stream_name;
210 : NTSTATUS status;
211 : };
212 :
213 0 : static void leases_db_add_fn(
214 : struct leases_db_value *value, bool *modified, void *private_data)
215 : {
216 0 : struct leases_db_add_state *state = private_data;
217 0 : struct leases_db_file *tmp = NULL;
218 : uint32_t i;
219 :
220 : /* id must be unique. */
221 0 : for (i = 0; i < value->num_files; i++) {
222 0 : if (file_id_equal(state->id, &value->files[i].id)) {
223 0 : state->status = NT_STATUS_OBJECT_NAME_COLLISION;
224 0 : return;
225 : }
226 : }
227 :
228 0 : if (value->num_files == 0) {
229 : /* new record */
230 0 : value->current_state = state->current_state;
231 0 : value->lease_version = state->lease_version;
232 0 : value->epoch = state->epoch;
233 : }
234 :
235 0 : tmp = talloc_realloc(
236 : value,
237 : value->files,
238 : struct leases_db_file,
239 : value->num_files + 1);
240 0 : if (tmp == NULL) {
241 0 : state->status = NT_STATUS_NO_MEMORY;
242 0 : return;
243 : }
244 0 : value->files = tmp;
245 :
246 0 : value->files[value->num_files] = (struct leases_db_file) {
247 0 : .id = *state->id,
248 0 : .servicepath = state->servicepath,
249 0 : .base_name = state->base_name,
250 0 : .stream_name = state->stream_name,
251 : };
252 0 : value->num_files += 1;
253 :
254 0 : *modified = true;
255 : }
256 :
257 0 : NTSTATUS leases_db_add(const struct GUID *client_guid,
258 : const struct smb2_lease_key *lease_key,
259 : const struct file_id *id,
260 : uint32_t current_state,
261 : uint16_t lease_version,
262 : uint16_t epoch,
263 : const char *servicepath,
264 : const char *base_name,
265 : const char *stream_name)
266 : {
267 0 : struct leases_db_add_state state = {
268 : .id = id,
269 : .current_state = current_state,
270 : .lease_version = lease_version,
271 : .epoch = epoch,
272 : .servicepath = servicepath,
273 : .base_name = base_name,
274 : .stream_name = stream_name,
275 : };
276 : NTSTATUS status;
277 :
278 0 : status = leases_db_do_locked(
279 : client_guid, lease_key, leases_db_add_fn, &state);
280 0 : if (!NT_STATUS_IS_OK(status)) {
281 0 : DBG_DEBUG("leases_db_do_locked failed: %s\n",
282 : nt_errstr(status));
283 0 : return status;
284 : }
285 0 : return state.status;
286 : }
287 :
288 : struct leases_db_del_state {
289 : const struct file_id *id;
290 : NTSTATUS status;
291 : };
292 :
293 0 : static void leases_db_del_fn(
294 : struct leases_db_value *value, bool *modified, void *private_data)
295 : {
296 0 : struct leases_db_del_state *state = private_data;
297 : uint32_t i;
298 :
299 0 : for (i = 0; i < value->num_files; i++) {
300 0 : if (file_id_equal(state->id, &value->files[i].id)) {
301 0 : break;
302 : }
303 : }
304 0 : if (i == value->num_files) {
305 0 : state->status = NT_STATUS_NOT_FOUND;
306 0 : return;
307 : }
308 :
309 0 : value->files[i] = value->files[value->num_files-1];
310 0 : value->num_files -= 1;
311 :
312 0 : *modified = true;
313 : }
314 :
315 0 : NTSTATUS leases_db_del(const struct GUID *client_guid,
316 : const struct smb2_lease_key *lease_key,
317 : const struct file_id *id)
318 : {
319 0 : struct leases_db_del_state state = { .id = id };
320 : NTSTATUS status;
321 :
322 0 : status = leases_db_do_locked(
323 : client_guid, lease_key, leases_db_del_fn, &state);
324 0 : if (!NT_STATUS_IS_OK(status)) {
325 0 : DBG_DEBUG("leases_db_do_locked failed: %s\n",
326 : nt_errstr(status));
327 0 : return status;
328 : }
329 0 : return state.status;
330 : }
331 :
332 : struct leases_db_fetch_state {
333 : void (*parser)(uint32_t num_files,
334 : const struct leases_db_file *files,
335 : void *private_data);
336 : void *private_data;
337 : NTSTATUS status;
338 : };
339 :
340 0 : static void leases_db_parser(TDB_DATA key, TDB_DATA data, void *private_data)
341 : {
342 0 : struct leases_db_fetch_state *state =
343 : (struct leases_db_fetch_state *)private_data;
344 0 : DATA_BLOB blob = { .data = data.dptr, .length = data.dsize };
345 : enum ndr_err_code ndr_err;
346 : struct leases_db_value *value;
347 :
348 0 : value = talloc(talloc_tos(), struct leases_db_value);
349 0 : if (value == NULL) {
350 0 : state->status = NT_STATUS_NO_MEMORY;
351 0 : return;
352 : }
353 :
354 0 : ndr_err = ndr_pull_struct_blob_all(
355 : &blob, value, value,
356 : (ndr_pull_flags_fn_t)ndr_pull_leases_db_value);
357 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
358 0 : DEBUG(10, ("%s: ndr_pull_struct_blob_failed: %s\n",
359 : __func__, ndr_errstr(ndr_err)));
360 0 : TALLOC_FREE(value);
361 0 : state->status = ndr_map_error2ntstatus(ndr_err);
362 0 : return;
363 : }
364 :
365 0 : if (DEBUGLEVEL >= 10) {
366 0 : DEBUG(10, ("%s:\n", __func__));
367 0 : NDR_PRINT_DEBUG(leases_db_value, value);
368 : }
369 :
370 0 : state->parser(value->num_files,
371 0 : value->files,
372 : state->private_data);
373 :
374 0 : TALLOC_FREE(value);
375 0 : state->status = NT_STATUS_OK;
376 : }
377 :
378 0 : NTSTATUS leases_db_parse(const struct GUID *client_guid,
379 : const struct smb2_lease_key *lease_key,
380 : void (*parser)(uint32_t num_files,
381 : const struct leases_db_file *files,
382 : void *private_data),
383 : void *private_data)
384 : {
385 : struct leases_db_key_buf keybuf;
386 0 : TDB_DATA db_key = leases_db_key(&keybuf, client_guid, lease_key);
387 : struct leases_db_fetch_state state;
388 : NTSTATUS status;
389 :
390 0 : if (!leases_db_init(true)) {
391 0 : return NT_STATUS_INTERNAL_ERROR;
392 : }
393 :
394 0 : state = (struct leases_db_fetch_state) {
395 : .parser = parser,
396 : .private_data = private_data,
397 : .status = NT_STATUS_OK
398 : };
399 :
400 0 : status = dbwrap_parse_record(leases_db, db_key, leases_db_parser,
401 : &state);
402 0 : if (!NT_STATUS_IS_OK(status)) {
403 0 : return status;
404 : }
405 0 : return state.status;
406 : }
407 :
408 : struct leases_db_rename_state {
409 : const struct file_id *id;
410 : const char *servicename_new;
411 : const char *filename_new;
412 : const char *stream_name_new;
413 : NTSTATUS status;
414 : };
415 :
416 0 : static void leases_db_rename_fn(
417 : struct leases_db_value *value, bool *modified, void *private_data)
418 : {
419 0 : struct leases_db_rename_state *state = private_data;
420 0 : struct leases_db_file *file = NULL;
421 : uint32_t i;
422 :
423 : /* id must exist. */
424 0 : for (i = 0; i < value->num_files; i++) {
425 0 : if (file_id_equal(state->id, &value->files[i].id)) {
426 0 : break;
427 : }
428 : }
429 0 : if (i == value->num_files) {
430 0 : state->status = NT_STATUS_NOT_FOUND;
431 0 : return;
432 : }
433 :
434 0 : file = &value->files[i];
435 0 : file->servicepath = state->servicename_new;
436 0 : file->base_name = state->filename_new;
437 0 : file->stream_name = state->stream_name_new;
438 :
439 0 : *modified = true;
440 : }
441 :
442 0 : NTSTATUS leases_db_rename(const struct GUID *client_guid,
443 : const struct smb2_lease_key *lease_key,
444 : const struct file_id *id,
445 : const char *servicename_new,
446 : const char *filename_new,
447 : const char *stream_name_new)
448 : {
449 0 : struct leases_db_rename_state state = {
450 : .id = id,
451 : .servicename_new = servicename_new,
452 : .filename_new = filename_new,
453 : .stream_name_new = stream_name_new,
454 : };
455 : NTSTATUS status;
456 :
457 0 : status = leases_db_do_locked(
458 : client_guid, lease_key, leases_db_rename_fn, &state);
459 0 : if (!NT_STATUS_IS_OK(status)) {
460 0 : DBG_DEBUG("leases_db_do_locked failed: %s\n",
461 : nt_errstr(status));
462 0 : return status;
463 : }
464 0 : return state.status;
465 : }
466 :
467 : struct leases_db_set_state {
468 : uint32_t current_state;
469 : bool breaking;
470 : uint32_t breaking_to_requested;
471 : uint32_t breaking_to_required;
472 : uint16_t lease_version;
473 : uint16_t epoch;
474 : };
475 :
476 0 : static void leases_db_set_fn(
477 : struct leases_db_value *value, bool *modified, void *private_data)
478 : {
479 0 : struct leases_db_set_state *state = private_data;
480 :
481 0 : if (value->num_files == 0) {
482 0 : DBG_WARNING("leases_db_set on new entry\n");
483 0 : return;
484 : }
485 0 : value->current_state = state->current_state;
486 0 : value->breaking = state->breaking;
487 0 : value->breaking_to_requested = state->breaking_to_requested;
488 0 : value->breaking_to_required = state->breaking_to_required;
489 0 : value->lease_version = state->lease_version;
490 0 : value->epoch = state->epoch;
491 0 : *modified = true;
492 : }
493 :
494 0 : NTSTATUS leases_db_set(const struct GUID *client_guid,
495 : const struct smb2_lease_key *lease_key,
496 : uint32_t current_state,
497 : bool breaking,
498 : uint32_t breaking_to_requested,
499 : uint32_t breaking_to_required,
500 : uint16_t lease_version,
501 : uint16_t epoch)
502 : {
503 0 : struct leases_db_set_state state = {
504 : .current_state = current_state,
505 : .breaking = breaking,
506 : .breaking_to_requested = breaking_to_requested,
507 : .breaking_to_required = breaking_to_required,
508 : .lease_version = lease_version,
509 : .epoch = epoch,
510 : };
511 : NTSTATUS status;
512 :
513 0 : status = leases_db_do_locked(
514 : client_guid, lease_key, leases_db_set_fn, &state);
515 0 : if (!NT_STATUS_IS_OK(status)) {
516 0 : DBG_DEBUG("leases_db_do_locked failed: %s\n",
517 : nt_errstr(status));
518 0 : return status;
519 : }
520 0 : return NT_STATUS_OK;
521 : }
522 :
523 : struct leases_db_get_state {
524 : const struct file_id *file_id;
525 : uint32_t *current_state;
526 : bool *breaking;
527 : uint32_t *breaking_to_requested;
528 : uint32_t *breaking_to_required;
529 : uint16_t *lease_version;
530 : uint16_t *epoch;
531 : NTSTATUS status;
532 : };
533 :
534 0 : static void leases_db_get_fn(TDB_DATA key, TDB_DATA data, void *private_data)
535 : {
536 0 : struct leases_db_get_state *state = private_data;
537 0 : DATA_BLOB blob = { .data = data.dptr, .length = data.dsize };
538 : enum ndr_err_code ndr_err;
539 : struct leases_db_value *value;
540 : uint32_t i;
541 :
542 0 : value = talloc(talloc_tos(), struct leases_db_value);
543 0 : if (value == NULL) {
544 0 : state->status = NT_STATUS_NO_MEMORY;
545 0 : return;
546 : }
547 :
548 0 : ndr_err = ndr_pull_struct_blob_all(
549 : &blob, value, value,
550 : (ndr_pull_flags_fn_t)ndr_pull_leases_db_value);
551 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
552 0 : DBG_ERR("ndr_pull_struct_blob_failed: %s\n",
553 : ndr_errstr(ndr_err));
554 0 : TALLOC_FREE(value);
555 0 : state->status = ndr_map_error2ntstatus(ndr_err);
556 0 : return;
557 : }
558 :
559 0 : if (DEBUGLEVEL >= 10) {
560 0 : DBG_DEBUG("\n");
561 0 : NDR_PRINT_DEBUG(leases_db_value, value);
562 : }
563 :
564 : /* id must exist. */
565 0 : for (i = 0; i < value->num_files; i++) {
566 0 : if (file_id_equal(state->file_id, &value->files[i].id)) {
567 0 : break;
568 : }
569 : }
570 :
571 0 : if (i == value->num_files) {
572 0 : state->status = NT_STATUS_NOT_FOUND;
573 0 : TALLOC_FREE(value);
574 0 : return;
575 : }
576 :
577 0 : if (state->current_state != NULL) {
578 0 : *state->current_state = value->current_state;
579 : };
580 0 : if (state->breaking != NULL) {
581 0 : *state->breaking = value->breaking;
582 : };
583 0 : if (state->breaking_to_requested != NULL) {
584 0 : *state->breaking_to_requested = value->breaking_to_requested;
585 : };
586 0 : if (state->breaking_to_required != NULL) {
587 0 : *state->breaking_to_required = value->breaking_to_required;
588 : };
589 0 : if (state->lease_version != NULL) {
590 0 : *state->lease_version = value->lease_version;
591 : };
592 0 : if (state->epoch != NULL) {
593 0 : *state->epoch = value->epoch;
594 : };
595 :
596 0 : TALLOC_FREE(value);
597 0 : state->status = NT_STATUS_OK;
598 : }
599 :
600 0 : NTSTATUS leases_db_get(const struct GUID *client_guid,
601 : const struct smb2_lease_key *lease_key,
602 : const struct file_id *file_id,
603 : uint32_t *current_state,
604 : bool *breaking,
605 : uint32_t *breaking_to_requested,
606 : uint32_t *breaking_to_required,
607 : uint16_t *lease_version,
608 : uint16_t *epoch)
609 : {
610 0 : struct leases_db_get_state state = {
611 : .file_id = file_id,
612 : .current_state = current_state,
613 : .breaking = breaking,
614 : .breaking_to_requested = breaking_to_requested,
615 : .breaking_to_required = breaking_to_required,
616 : .lease_version = lease_version,
617 : .epoch = epoch,
618 : };
619 : struct leases_db_key_buf keybuf;
620 0 : TDB_DATA db_key = leases_db_key(&keybuf, client_guid, lease_key);
621 : NTSTATUS status;
622 :
623 0 : if (!leases_db_init(true)) {
624 0 : return NT_STATUS_INTERNAL_ERROR;
625 : }
626 :
627 0 : status = dbwrap_parse_record(
628 : leases_db, db_key, leases_db_get_fn, &state);
629 0 : if (!NT_STATUS_IS_OK(status)) {
630 0 : return status;
631 : }
632 0 : return state.status;
633 : }
634 :
635 : struct leases_db_get_current_state_state {
636 : int seqnum;
637 : uint32_t current_state;
638 : NTSTATUS status;
639 : };
640 :
641 : /*
642 : * This function is an optimization that
643 : * relies on the fact that the
644 : * smb2_lease_state current_state
645 : * (which is a uint32_t size)
646 : * from struct leases_db_value is the first
647 : * entry in the ndr-encoded struct leases_db_value.
648 : * Read it without having to ndr decode all
649 : * the values in struct leases_db_value.
650 : */
651 :
652 0 : static void leases_db_get_current_state_fn(
653 : TDB_DATA key, TDB_DATA data, void *private_data)
654 : {
655 0 : struct leases_db_get_current_state_state *state = private_data;
656 : struct ndr_pull ndr;
657 : enum ndr_err_code ndr_err;
658 :
659 0 : if (data.dsize < sizeof(uint32_t)) {
660 0 : state->status = NT_STATUS_INTERNAL_DB_CORRUPTION;
661 0 : return;
662 : }
663 :
664 0 : state->seqnum = dbwrap_get_seqnum(leases_db);
665 :
666 0 : ndr = (struct ndr_pull) {
667 0 : .data = data.dptr, .data_size = data.dsize,
668 : };
669 0 : ndr_err = ndr_pull_uint32(&ndr, NDR_SCALARS, &state->current_state);
670 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
671 0 : state->status = ndr_map_error2ntstatus(ndr_err);
672 : }
673 : }
674 :
675 0 : NTSTATUS leases_db_get_current_state(
676 : const struct GUID *client_guid,
677 : const struct smb2_lease_key *lease_key,
678 : int *database_seqnum,
679 : uint32_t *current_state)
680 : {
681 0 : struct leases_db_get_current_state_state state = { 0 };
682 : struct leases_db_key_buf keybuf;
683 0 : TDB_DATA db_key = { 0 };
684 : NTSTATUS status;
685 :
686 0 : if (!leases_db_init(true)) {
687 0 : return NT_STATUS_INTERNAL_ERROR;
688 : }
689 :
690 0 : state.seqnum = dbwrap_get_seqnum(leases_db);
691 0 : if (*database_seqnum == state.seqnum) {
692 0 : return NT_STATUS_OK;
693 : }
694 :
695 0 : db_key = leases_db_key(&keybuf, client_guid, lease_key);
696 :
697 0 : status = dbwrap_parse_record(
698 : leases_db, db_key, leases_db_get_current_state_fn, &state);
699 0 : if (!NT_STATUS_IS_OK(status)) {
700 0 : return status;
701 : }
702 0 : *database_seqnum = state.seqnum;
703 0 : *current_state = state.current_state;
704 :
705 0 : return NT_STATUS_OK;
706 : }
707 :
708 0 : NTSTATUS leases_db_copy_file_ids(TALLOC_CTX *mem_ctx,
709 : uint32_t num_files,
710 : const struct leases_db_file *files,
711 : struct file_id **pp_ids)
712 : {
713 : uint32_t i;
714 0 : struct file_id *ids = talloc_array(mem_ctx,
715 : struct file_id,
716 : num_files);
717 0 : if (ids == NULL) {
718 0 : return NT_STATUS_NO_MEMORY;
719 : }
720 :
721 0 : for (i = 0; i < num_files; i++) {
722 0 : ids[i] = files[i].id;
723 : }
724 0 : *pp_ids = ids;
725 0 : return NT_STATUS_OK;
726 : }
|