6fd3bbc487afd1e78385020032600694898cb715
[tridge/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         return session_db_ctx_ptr;
39 }
40
41 bool sessionid_init(void)
42 {
43         if (session_db_ctx() == NULL) {
44                 DEBUG(1,("session_init: failed to open sessionid tdb\n"));
45                 return False;
46         }
47
48         return True;
49 }
50
51 struct db_record *sessionid_fetch_record(TALLOC_CTX *mem_ctx, const char *key)
52 {
53         struct db_context *db;
54
55         db = session_db_ctx();
56         if (db == NULL) {
57                 return NULL;
58         }
59         return dbwrap_fetch_locked(db, mem_ctx, string_term_tdb_data(key));
60 }
61
62 struct sessionid_traverse_state {
63         int (*fn)(struct db_record *rec, const char *key,
64                   struct sessionid *session, void *private_data);
65         void *private_data;
66 };
67
68 static int sessionid_traverse_fn(struct db_record *rec, void *private_data)
69 {
70         TDB_DATA key;
71         TDB_DATA value;
72         struct sessionid_traverse_state *state =
73                 (struct sessionid_traverse_state *)private_data;
74         struct sessionid session;
75
76         key = dbwrap_record_get_key(rec);
77         value = dbwrap_record_get_value(rec);
78         if ((key.dptr[key.dsize-1] != '\0')
79             || (value.dsize != sizeof(struct sessionid))) {
80                 DEBUG(1, ("Found invalid record in sessionid.tdb\n"));
81                 return 0;
82         }
83
84         memcpy(&session, value.dptr, sizeof(session));
85
86         return state->fn(rec, (char *)key.dptr, &session,
87                          state->private_data);
88 }
89
90 NTSTATUS sessionid_traverse(int (*fn)(struct db_record *rec, const char *key,
91                                       struct sessionid *session,
92                                       void *private_data),
93                             void *private_data)
94 {
95         struct db_context *db;
96         struct sessionid_traverse_state state;
97         NTSTATUS status;
98
99         db = session_db_ctx();
100         if (db == NULL) {
101                 return NT_STATUS_UNSUCCESSFUL;
102         }
103         state.fn = fn;
104         state.private_data = private_data;
105         status = dbwrap_traverse(db, sessionid_traverse_fn, &state, NULL);
106         return status;
107 }
108
109 struct sessionid_traverse_read_state {
110         int (*fn)(const char *key, struct sessionid *session,
111                   void *private_data);
112         void *private_data;
113 };
114
115 static int sessionid_traverse_read_fn(struct db_record *rec,
116                                       void *private_data)
117 {
118         TDB_DATA key;
119         TDB_DATA value;
120         struct sessionid_traverse_read_state *state =
121                 (struct sessionid_traverse_read_state *)private_data;
122         struct sessionid session;
123
124         key = dbwrap_record_get_key(rec);
125         value = dbwrap_record_get_value(rec);
126
127         if ((key.dptr[key.dsize-1] != '\0')
128             || (value.dsize != sizeof(struct sessionid))) {
129                 DEBUG(1, ("Found invalid record in sessionid.tdb\n"));
130                 return 0;
131         }
132
133         memcpy(&session, value.dptr, sizeof(session));
134
135         return state->fn((char *)key.dptr, &session,
136                          state->private_data);
137 }
138
139 NTSTATUS sessionid_traverse_read(int (*fn)(const char *key,
140                                           struct sessionid *session,
141                                           void *private_data),
142                                  void *private_data)
143 {
144         struct db_context *db;
145         struct sessionid_traverse_read_state state;
146         NTSTATUS status;
147
148         db = session_db_ctx();
149         if (db == NULL) {
150                 return NT_STATUS_UNSUCCESSFUL;
151         }
152         state.fn = fn;
153         state.private_data = private_data;
154         status = dbwrap_traverse_read(db, sessionid_traverse_read_fn, &state,
155                                       NULL);
156         return status;
157 }