s3: fix comment header description for smbd_shim
[kai/samba.git] / source3 / lib / sessionid_tdb.c
1 /*
2    Unix SMB/CIFS implementation.
3    Low-level sessionid.tdb access functions
4    Copyright (C) Volker Lendecke 2010
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 #include "includes.h"
21 #include "system/filesys.h"
22 #include "dbwrap/dbwrap.h"
23 #include "dbwrap/dbwrap_open.h"
24 #include "session.h"
25 #include "util_tdb.h"
26
27 static struct db_context *session_db_ctx(void)
28 {
29         static struct db_context *session_db_ctx_ptr;
30
31         if (session_db_ctx_ptr != NULL) {
32                 return session_db_ctx_ptr;
33         }
34
35         session_db_ctx_ptr = db_open(NULL, lock_path("sessionid.tdb"), 0,
36                                      TDB_CLEAR_IF_FIRST|TDB_DEFAULT|TDB_INCOMPATIBLE_HASH,
37                                      O_RDWR | O_CREAT, 0644,
38                                      DBWRAP_LOCK_ORDER_1);
39         return session_db_ctx_ptr;
40 }
41
42 bool sessionid_init(void)
43 {
44         if (session_db_ctx() == NULL) {
45                 DEBUG(1,("session_init: failed to open sessionid tdb\n"));
46                 return False;
47         }
48
49         return True;
50 }
51
52 struct db_record *sessionid_fetch_record(TALLOC_CTX *mem_ctx, const char *key)
53 {
54         struct db_context *db;
55
56         db = session_db_ctx();
57         if (db == NULL) {
58                 return NULL;
59         }
60         return dbwrap_fetch_locked(db, mem_ctx, string_term_tdb_data(key));
61 }
62
63 struct sessionid_traverse_state {
64         int (*fn)(struct db_record *rec, const char *key,
65                   struct sessionid *session, void *private_data);
66         void *private_data;
67 };
68
69 static int sessionid_traverse_fn(struct db_record *rec, void *private_data)
70 {
71         TDB_DATA key;
72         TDB_DATA value;
73         struct sessionid_traverse_state *state =
74                 (struct sessionid_traverse_state *)private_data;
75         struct sessionid session;
76
77         key = dbwrap_record_get_key(rec);
78         value = dbwrap_record_get_value(rec);
79         if ((key.dptr[key.dsize-1] != '\0')
80             || (value.dsize != sizeof(struct sessionid))) {
81                 DEBUG(1, ("Found invalid record in sessionid.tdb\n"));
82                 return 0;
83         }
84
85         memcpy(&session, value.dptr, sizeof(session));
86
87         return state->fn(rec, (char *)key.dptr, &session,
88                          state->private_data);
89 }
90
91 NTSTATUS sessionid_traverse(int (*fn)(struct db_record *rec, const char *key,
92                                       struct sessionid *session,
93                                       void *private_data),
94                             void *private_data)
95 {
96         struct db_context *db;
97         struct sessionid_traverse_state state;
98         NTSTATUS status;
99
100         db = session_db_ctx();
101         if (db == NULL) {
102                 return NT_STATUS_UNSUCCESSFUL;
103         }
104         state.fn = fn;
105         state.private_data = private_data;
106         status = dbwrap_traverse(db, sessionid_traverse_fn, &state, NULL);
107         return status;
108 }
109
110 struct sessionid_traverse_read_state {
111         int (*fn)(const char *key, struct sessionid *session,
112                   void *private_data);
113         void *private_data;
114 };
115
116 static int sessionid_traverse_read_fn(struct db_record *rec,
117                                       void *private_data)
118 {
119         TDB_DATA key;
120         TDB_DATA value;
121         struct sessionid_traverse_read_state *state =
122                 (struct sessionid_traverse_read_state *)private_data;
123         struct sessionid session;
124
125         key = dbwrap_record_get_key(rec);
126         value = dbwrap_record_get_value(rec);
127
128         if ((key.dptr[key.dsize-1] != '\0')
129             || (value.dsize != sizeof(struct sessionid))) {
130                 DEBUG(1, ("Found invalid record in sessionid.tdb\n"));
131                 return 0;
132         }
133
134         memcpy(&session, value.dptr, sizeof(session));
135
136         return state->fn((char *)key.dptr, &session,
137                          state->private_data);
138 }
139
140 NTSTATUS sessionid_traverse_read(int (*fn)(const char *key,
141                                           struct sessionid *session,
142                                           void *private_data),
143                                  void *private_data)
144 {
145         struct db_context *db;
146         struct sessionid_traverse_read_state state;
147         NTSTATUS status;
148
149         db = session_db_ctx();
150         if (db == NULL) {
151                 return NT_STATUS_UNSUCCESSFUL;
152         }
153         state.fn = fn;
154         state.private_data = private_data;
155         status = dbwrap_traverse_read(db, sessionid_traverse_read_fn, &state,
156                                       NULL);
157         return status;
158 }