de3ccab26ae84003ccd15cee58841fff490b31c9
[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.h"
23 #include "session.h"
24 #include "util_tdb.h"
25
26 static struct db_context *session_db_ctx(void)
27 {
28         static struct db_context *session_db_ctx_ptr;
29
30         if (session_db_ctx_ptr != NULL) {
31                 return session_db_ctx_ptr;
32         }
33
34         session_db_ctx_ptr = db_open(NULL, lock_path("sessionid.tdb"), 0,
35                                      TDB_CLEAR_IF_FIRST|TDB_DEFAULT|TDB_INCOMPATIBLE_HASH,
36                                      O_RDWR | O_CREAT, 0644);
37         return session_db_ctx_ptr;
38 }
39
40 bool sessionid_init(void)
41 {
42         if (session_db_ctx() == NULL) {
43                 DEBUG(1,("session_init: failed to open sessionid tdb\n"));
44                 return False;
45         }
46
47         return True;
48 }
49
50 struct db_record *sessionid_fetch_record(TALLOC_CTX *mem_ctx, const char *key)
51 {
52         struct db_context *db;
53
54         db = session_db_ctx();
55         if (db == NULL) {
56                 return NULL;
57         }
58         return db->fetch_locked(db, mem_ctx, string_term_tdb_data(key));
59 }
60
61 struct sessionid_traverse_state {
62         int (*fn)(struct db_record *rec, const char *key,
63                   struct sessionid *session, void *private_data);
64         void *private_data;
65 };
66
67 static int sessionid_traverse_fn(struct db_record *rec, void *private_data)
68 {
69         struct sessionid_traverse_state *state =
70                 (struct sessionid_traverse_state *)private_data;
71         struct sessionid session;
72
73         if ((rec->key.dptr[rec->key.dsize-1] != '\0')
74             || (rec->value.dsize != sizeof(struct sessionid))) {
75                 DEBUG(1, ("Found invalid record in sessionid.tdb\n"));
76                 return 0;
77         }
78
79         memcpy(&session, rec->value.dptr, sizeof(session));
80
81         return state->fn(rec, (char *)rec->key.dptr, &session,
82                          state->private_data);
83 }
84
85 int sessionid_traverse(int (*fn)(struct db_record *rec, const char *key,
86                                  struct sessionid *session,
87                                  void *private_data),
88                        void *private_data)
89 {
90         struct db_context *db;
91         struct sessionid_traverse_state state;
92
93         db = session_db_ctx();
94         if (db == NULL) {
95                 return -1;
96         }
97         state.fn = fn;
98         state.private_data = private_data;
99         return db->traverse(db, sessionid_traverse_fn, &state);
100 }
101
102 struct sessionid_traverse_read_state {
103         int (*fn)(const char *key, struct sessionid *session,
104                   void *private_data);
105         void *private_data;
106 };
107
108 static int sessionid_traverse_read_fn(struct db_record *rec,
109                                       void *private_data)
110 {
111         struct sessionid_traverse_read_state *state =
112                 (struct sessionid_traverse_read_state *)private_data;
113         struct sessionid session;
114
115         if ((rec->key.dptr[rec->key.dsize-1] != '\0')
116             || (rec->value.dsize != sizeof(struct sessionid))) {
117                 DEBUG(1, ("Found invalid record in sessionid.tdb\n"));
118                 return 0;
119         }
120
121         memcpy(&session, rec->value.dptr, sizeof(session));
122
123         return state->fn((char *)rec->key.dptr, &session,
124                          state->private_data);
125 }
126
127 int sessionid_traverse_read(int (*fn)(const char *key,
128                                       struct sessionid *session,
129                                       void *private_data),
130                             void *private_data)
131 {
132         struct db_context *db;
133         struct sessionid_traverse_read_state state;
134
135         db = session_db_ctx();
136         if (db == NULL) {
137                 return -1;
138         }
139         state.fn = fn;
140         state.private_data = private_data;
141         return db->traverse(db, sessionid_traverse_read_fn, &state);
142 }