s3:auth: only call secrets_fetch_domain_sid() once in finalize_local_nt_token()
[Samba.git] / source3 / lib / cleanupdb.c
blob3250d609d0331298146302c395dc5eab6bf6c66e
1 /*
2 Unix SMB/CIFS implementation.
3 Implementation of reliable cleanup events
4 Copyright (C) Ralph Boehme 2016
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.
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.
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/>.
20 #include "cleanupdb.h"
22 struct cleanup_key {
23 pid_t pid;
26 struct cleanup_rec {
27 bool unclean;
30 static struct tdb_wrap *cleanup_db(void)
32 static struct tdb_wrap *db;
33 char *db_path = NULL;
34 int tdbflags = TDB_INCOMPATIBLE_HASH | TDB_CLEAR_IF_FIRST |
35 TDB_MUTEX_LOCKING;
37 if (db != NULL) {
38 return db;
41 db_path = lock_path("smbd_cleanupd.tdb");
42 if (db_path == NULL) {
43 return NULL;
46 db = tdb_wrap_open(NULL, db_path, 0, tdbflags,
47 O_CREAT | O_RDWR, 0644);
48 if (db == NULL) {
49 DBG_ERR("Failed to open smbd_cleanupd.tdb\n");
52 TALLOC_FREE(db_path);
53 return db;
56 bool cleanupdb_store_child(const pid_t pid, const bool unclean)
58 struct tdb_wrap *db;
59 struct cleanup_key key = { .pid = pid };
60 struct cleanup_rec rec = { .unclean = unclean };
61 TDB_DATA tdbkey = { .dptr = (uint8_t *)&key, .dsize = sizeof(key) };
62 TDB_DATA tdbdata = { .dptr = (uint8_t *)&rec, .dsize = sizeof(rec) };
63 int result;
65 db = cleanup_db();
66 if (db == NULL) {
67 return false;
70 result = tdb_store(db->tdb, tdbkey, tdbdata, TDB_REPLACE);
71 if (result != 0) {
72 DBG_ERR("tdb_store failed for pid %d\n", (int)pid);
73 return false;
76 return true;
79 bool cleanupdb_delete_child(const pid_t pid)
81 struct tdb_wrap *db;
82 struct cleanup_key key = { .pid = pid };
83 TDB_DATA tdbkey = { .dptr = (uint8_t *)&key, .dsize = sizeof(key) };
84 int result;
86 db = cleanup_db();
87 if (db == NULL) {
88 return false;
91 result = tdb_delete(db->tdb, tdbkey);
92 if (result != 0) {
93 DBG_ERR("tdb_delete failed for pid %d\n", (int)pid);
94 return false;
97 return true;
100 struct cleanup_read_state {
101 int (*fn)(const pid_t pid, const bool cleanup, void *private_data);
102 void *private_data;
105 static int cleanup_traverse_fn(struct tdb_context *tdb,
106 TDB_DATA key, TDB_DATA value,
107 void *private_data)
109 struct cleanup_read_state *state =
110 (struct cleanup_read_state *)private_data;
111 struct cleanup_key ckey;
112 struct cleanup_rec rec;
113 int result;
115 if (key.dsize != sizeof(struct cleanup_key)) {
116 DBG_ERR("Found invalid key length %zu in cleanup.tdb\n",
117 key.dsize);
118 return -1;
120 memcpy(&ckey, key.dptr, sizeof(struct cleanup_key));
122 if (value.dsize != sizeof(struct cleanup_rec)) {
123 DBG_ERR("Found invalid value length %zu in cleanup.tdb\n",
124 value.dsize);
125 return -1;
127 memcpy(&rec, value.dptr, sizeof(struct cleanup_rec));
129 result = state->fn(ckey.pid, rec.unclean, state->private_data);
130 if (result != 0) {
131 return -1;
134 return 0;
137 int cleanupdb_traverse_read(int (*fn)(const pid_t pid,
138 const bool cleanup,
139 void *private_data),
140 void *private_data)
142 struct tdb_wrap *db;
143 struct cleanup_read_state state;
144 int result;
146 db = cleanup_db();
147 if (db == NULL) {
148 return -1;
151 state = (struct cleanup_read_state) {
152 .fn = fn,
153 .private_data = private_data
156 result = tdb_traverse_read(db->tdb, cleanup_traverse_fn, &state);
157 if (result < 0) {
158 DBG_ERR("tdb_traverse_read failed\n");
159 return -1;
162 return result;