s3: Slightly simplify db_ctdb_marshall_loop_next
[kai/samba.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         char machine[FSTRING_LEN];
43         char addr[FSTRING_LEN];
44 };
45
46 static int collect_sessions_fn(struct smbXsrv_session_global0 *global,
47                                void *connections_forall_state)
48 {
49         NTSTATUS status;
50         struct connections_forall_state *state =
51                 (struct connections_forall_state*)connections_forall_state;
52
53         uint32_t id = global->session_global_id;
54         struct connections_forall_session sess;
55
56         sess.uid = global->auth_session_info->unix_token->uid;
57         sess.gid = global->auth_session_info->unix_token->gid;
58         strncpy(sess.machine, global->channels[0].remote_name, sizeof(sess.machine));
59         strncpy(sess.addr, global->channels[0].remote_address, sizeof(sess.addr));
60
61         status = dbwrap_store(state->session_by_pid,
62                               make_tdb_data((void*)&id, sizeof(id)),
63                               make_tdb_data((void*)&sess, sizeof(sess)),
64                               TDB_INSERT);
65         if (!NT_STATUS_IS_OK(status)) {
66                 DEBUG(0, ("Failed to store record: %s\n", nt_errstr(status)));
67         }
68         return 0;
69 }
70
71 static int traverse_tcon_fn(struct smbXsrv_tcon_global0 *global,
72                             void *connections_forall_state)
73 {
74         NTSTATUS status;
75         struct connections_forall_state *state =
76                 (struct connections_forall_state*)connections_forall_state;
77
78         struct connections_key key;
79         struct connections_data data;
80
81         uint32_t sess_id = global->session_global_id;
82         struct connections_forall_session sess = {
83                 .uid = -1,
84                 .gid = -1,
85         };
86
87         TDB_DATA val = tdb_null;
88
89         status = dbwrap_fetch(state->session_by_pid, state,
90                               make_tdb_data((void*)&sess_id, sizeof(sess_id)),
91                               &val);
92         if (NT_STATUS_IS_OK(status)) {
93                 memcpy((uint8_t *)&sess, val.dptr, val.dsize);
94         }
95
96         ZERO_STRUCT(key);
97         ZERO_STRUCT(data);
98
99         key.pid = data.pid = global->server_id;
100         key.cnum = data.cnum = global->tcon_global_id;
101         strncpy(key.name, global->share_name, sizeof(key.name));
102         strncpy(data.servicename, global->share_name, sizeof(data.servicename));
103         data.uid = sess.uid;
104         data.gid = sess.gid;
105         strncpy(data.addr, sess.addr, sizeof(data.addr));
106         strncpy(data.machine, sess.machine, sizeof(data.machine));
107         data.start = nt_time_to_unix(global->creation_time);
108
109         state->count++;
110
111         return state->fn(&key, &data, state->private_data);
112 }
113
114 int connections_forall_read(int (*fn)(const struct connections_key *key,
115                                       const struct connections_data *data,
116                                       void *private_data),
117                             void *private_data)
118 {
119         TALLOC_CTX *frame = talloc_stackframe();
120         struct connections_forall_state *state =
121                 talloc_zero(talloc_tos(), struct connections_forall_state);
122         NTSTATUS status;
123         int ret = -1;
124
125         state->session_by_pid = db_open_rbt(state);
126         state->fn = fn;
127         state->private_data = private_data;
128         status = smbXsrv_session_global_traverse(collect_sessions_fn, state);
129         if (!NT_STATUS_IS_OK(status)) {
130                 DEBUG(0, ("Failed to traverse sessions: %s\n",
131                           nt_errstr(status)));
132                 goto done;
133         }
134
135         status = smbXsrv_tcon_global_traverse(traverse_tcon_fn, state);
136         if (!NT_STATUS_IS_OK(status)) {
137                 DEBUG(0, ("Failed to traverse tree connects: %s\n",
138                           nt_errstr(status)));
139                 goto done;
140         }
141         ret = state->count;
142 done:
143         talloc_free(frame);
144         return ret;
145 }
146