smbd: Split create_conn_struct into a fn that does not change the working dir
[Samba/bb.git] / source3 / lib / conn_tdb.c
bloba7e7cf02eb714024e340b6c1957711a57a1bc682
1 /*
2 Unix SMB/CIFS implementation.
3 Low-level connections.tdb access functions
4 Copyright (C) Volker Lendecke 2007
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.
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.
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/>.
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"
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;
39 struct connections_forall_session {
40 uid_t uid;
41 gid_t gid;
42 char machine[FSTRING_LEN];
43 char addr[FSTRING_LEN];
46 static int collect_sessions_fn(struct smbXsrv_session_global0 *global,
47 void *connections_forall_state)
49 NTSTATUS status;
50 struct connections_forall_state *state =
51 (struct connections_forall_state*)connections_forall_state;
53 uint32_t id = global->session_global_id;
54 struct connections_forall_session sess;
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));
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)));
68 return 0;
71 static int traverse_tcon_fn(struct smbXsrv_tcon_global0 *global,
72 void *connections_forall_state)
74 NTSTATUS status;
75 struct connections_forall_state *state =
76 (struct connections_forall_state*)connections_forall_state;
78 struct connections_key key;
79 struct connections_data data;
81 uint32_t sess_id = global->session_global_id;
82 struct connections_forall_session sess = {
83 .uid = -1,
84 .gid = -1,
87 TDB_DATA val = tdb_null;
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);
96 ZERO_STRUCT(key);
97 ZERO_STRUCT(data);
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);
109 state->count++;
111 return state->fn(&key, &data, state->private_data);
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)
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;
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;
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;
141 ret = state->count;
142 done:
143 talloc_free(frame);
144 return ret;