gencache: Bail out of stabilize if we can not get the allrecord lock
[kai/samba-autobuild/.git] / source3 / lib / conn_tdb.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Low-level connections.tdb access functions
4    Copyright (C) Volker Lendecke 2007
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 "smbd/globals.h"
23 #include "dbwrap/dbwrap.h"
24 #include "dbwrap/dbwrap_open.h"
25 #include "dbwrap/dbwrap_rbt.h"
26 #include "messages.h"
27 #include "lib/conn_tdb.h"
28 #include "util_tdb.h"
29
30 struct connections_forall_state {
31         struct db_context *session_by_pid;
32         int (*fn)(const struct connections_key *key,
33                   const struct connections_data *data,
34                   void *private_data);
35         void *private_data;
36         int count;
37 };
38
39 struct connections_forall_session {
40         uid_t uid;
41         gid_t gid;
42         fstring machine;
43         fstring addr;
44         uint16_t cipher;
45         uint16_t dialect;
46         uint8_t signing_flags;
47 };
48
49 static int collect_sessions_fn(struct smbXsrv_session_global0 *global,
50                                void *connections_forall_state)
51 {
52         NTSTATUS status;
53         struct connections_forall_state *state =
54                 (struct connections_forall_state*)connections_forall_state;
55
56         uint32_t id = global->session_global_id;
57         struct connections_forall_session sess;
58
59         if (global->auth_session_info == NULL) {
60                 sess.uid = -1;
61                 sess.gid = -1;
62         } else {
63                 sess.uid = global->auth_session_info->unix_token->uid;
64                 sess.gid = global->auth_session_info->unix_token->gid;
65         }
66         fstrcpy(sess.machine, global->channels[0].remote_name);
67         fstrcpy(sess.addr, global->channels[0].remote_address);
68         sess.cipher = global->channels[0].encryption_cipher;
69         sess.dialect = global->connection_dialect;
70         sess.signing_flags = global->signing_flags;
71
72         status = dbwrap_store(state->session_by_pid,
73                               make_tdb_data((void*)&id, sizeof(id)),
74                               make_tdb_data((void*)&sess, sizeof(sess)),
75                               TDB_INSERT);
76         if (!NT_STATUS_IS_OK(status)) {
77                 DEBUG(0, ("Failed to store record: %s\n", nt_errstr(status)));
78         }
79         return 0;
80 }
81
82 static int traverse_tcon_fn(struct smbXsrv_tcon_global0 *global,
83                             void *connections_forall_state)
84 {
85         NTSTATUS status;
86         struct connections_forall_state *state =
87                 (struct connections_forall_state*)connections_forall_state;
88
89         struct connections_key key;
90         struct connections_data data;
91
92         uint32_t sess_id = global->session_global_id;
93         struct connections_forall_session sess = {
94                 .uid = -1,
95                 .gid = -1,
96         };
97
98         TDB_DATA val = tdb_null;
99
100         /*
101          * Note: that share_name is defined as array without a pointer.
102          * that's why it's always a valid pointer here.
103          */
104         if (strlen(global->share_name) == 0) {
105                 /*
106                  * when a smbXsrv_tcon is created it's created
107                  * with emtpy share_name first in order to allocate
108                  * an id, before filling in the details.
109                  */
110                 return 0;
111         }
112
113         status = dbwrap_fetch(state->session_by_pid, state,
114                               make_tdb_data((void*)&sess_id, sizeof(sess_id)),
115                               &val);
116         if (NT_STATUS_IS_OK(status)) {
117                 memcpy((uint8_t *)&sess, val.dptr, val.dsize);
118         }
119
120         ZERO_STRUCT(key);
121         ZERO_STRUCT(data);
122
123         key.pid = data.pid = global->server_id;
124         key.cnum = data.cnum = global->tcon_global_id;
125         fstrcpy(key.name, global->share_name);
126         fstrcpy(data.servicename, global->share_name);
127         data.uid = sess.uid;
128         data.gid = sess.gid;
129         fstrcpy(data.addr, sess.addr);
130         fstrcpy(data.machine, sess.machine);
131         data.start = nt_time_to_unix(global->creation_time);
132         data.encryption_flags = global->encryption_flags;
133         data.cipher = sess.cipher;
134         data.dialect = sess.dialect;
135         data.signing_flags = global->signing_flags;
136
137         state->count++;
138
139         return state->fn(&key, &data, state->private_data);
140 }
141
142 int connections_forall_read(int (*fn)(const struct connections_key *key,
143                                       const struct connections_data *data,
144                                       void *private_data),
145                             void *private_data)
146 {
147         TALLOC_CTX *frame = talloc_stackframe();
148         struct connections_forall_state *state =
149                 talloc_zero(talloc_tos(), struct connections_forall_state);
150         NTSTATUS status;
151         int ret = -1;
152
153         state->session_by_pid = db_open_rbt(state);
154         state->fn = fn;
155         state->private_data = private_data;
156         status = smbXsrv_session_global_traverse(collect_sessions_fn, state);
157         if (!NT_STATUS_IS_OK(status)) {
158                 DEBUG(0, ("Failed to traverse sessions: %s\n",
159                           nt_errstr(status)));
160                 goto done;
161         }
162
163         status = smbXsrv_tcon_global_traverse(traverse_tcon_fn, state);
164         if (!NT_STATUS_IS_OK(status)) {
165                 DEBUG(0, ("Failed to traverse tree connects: %s\n",
166                           nt_errstr(status)));
167                 goto done;
168         }
169         ret = state->count;
170 done:
171         talloc_free(frame);
172         return ret;
173 }
174