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