Line data Source code
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 "conn_tdb.h"
28 : #include "util_tdb.h"
29 : #include "lib/util/string_wrappers.h"
30 :
31 : struct connections_forall_state {
32 : struct db_context *session_by_pid;
33 : int (*fn)(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 : uint16_t signing;
47 : uint8_t signing_flags;
48 : };
49 :
50 0 : static int collect_sessions_fn(struct smbXsrv_session_global0 *global,
51 : void *connections_forall_state)
52 : {
53 : NTSTATUS status;
54 0 : struct connections_forall_state *state =
55 : (struct connections_forall_state*)connections_forall_state;
56 :
57 0 : uint32_t id = global->session_global_id;
58 : struct connections_forall_session sess;
59 :
60 0 : if (global->auth_session_info == NULL) {
61 0 : sess.uid = -1;
62 0 : sess.gid = -1;
63 : } else {
64 0 : sess.uid = global->auth_session_info->unix_token->uid;
65 0 : sess.gid = global->auth_session_info->unix_token->gid;
66 : }
67 0 : fstrcpy(sess.machine, global->channels[0].remote_name);
68 0 : fstrcpy(sess.addr, global->channels[0].remote_address);
69 0 : sess.cipher = global->channels[0].encryption_cipher;
70 0 : sess.signing = global->channels[0].signing_algo;
71 0 : sess.dialect = global->connection_dialect;
72 0 : sess.signing_flags = global->signing_flags;
73 :
74 0 : status = dbwrap_store(state->session_by_pid,
75 : make_tdb_data((void*)&id, sizeof(id)),
76 : make_tdb_data((void*)&sess, sizeof(sess)),
77 : TDB_INSERT);
78 0 : if (!NT_STATUS_IS_OK(status)) {
79 0 : DEBUG(0, ("Failed to store record: %s\n", nt_errstr(status)));
80 : }
81 0 : return 0;
82 : }
83 :
84 0 : static int traverse_tcon_fn(struct smbXsrv_tcon_global0 *global,
85 : void *connections_forall_state)
86 : {
87 : NTSTATUS status;
88 0 : struct connections_forall_state *state =
89 : (struct connections_forall_state*)connections_forall_state;
90 :
91 : struct connections_data data;
92 :
93 0 : uint32_t sess_id = global->session_global_id;
94 0 : struct connections_forall_session sess = {
95 : .uid = -1,
96 : .gid = -1,
97 : };
98 :
99 0 : TDB_DATA val = tdb_null;
100 :
101 : /*
102 : * Note: that share_name is defined as array without a pointer.
103 : * that's why it's always a valid pointer here.
104 : */
105 0 : if (strlen(global->share_name) == 0) {
106 : /*
107 : * when a smbXsrv_tcon is created it's created
108 : * with empty share_name first in order to allocate
109 : * an id, before filling in the details.
110 : */
111 0 : return 0;
112 : }
113 :
114 0 : status = dbwrap_fetch(state->session_by_pid, state,
115 : make_tdb_data((void*)&sess_id, sizeof(sess_id)),
116 : &val);
117 0 : if (NT_STATUS_IS_OK(status)) {
118 0 : memcpy((uint8_t *)&sess, val.dptr, val.dsize);
119 : }
120 :
121 0 : ZERO_STRUCT(data);
122 :
123 0 : data.pid = global->server_id;
124 0 : data.cnum = global->tcon_global_id;
125 0 : data.sess_id = sess_id;
126 0 : fstrcpy(data.servicename, global->share_name);
127 0 : data.uid = sess.uid;
128 0 : data.gid = sess.gid;
129 0 : fstrcpy(data.addr, sess.addr);
130 0 : fstrcpy(data.machine, sess.machine);
131 0 : data.start = global->creation_time;
132 0 : data.encryption_flags = global->encryption_flags;
133 0 : data.cipher = sess.cipher;
134 0 : data.dialect = sess.dialect;
135 0 : data.signing = sess.signing;
136 0 : data.signing_flags = global->signing_flags;
137 :
138 0 : state->count++;
139 :
140 0 : return state->fn(&data, state->private_data);
141 : }
142 :
143 0 : int connections_forall_read(int (*fn)(const struct connections_data *data,
144 : void *private_data),
145 : void *private_data)
146 : {
147 0 : TALLOC_CTX *frame = talloc_stackframe();
148 0 : struct connections_forall_state *state =
149 0 : talloc_zero(talloc_tos(), struct connections_forall_state);
150 : NTSTATUS status;
151 0 : int ret = -1;
152 :
153 0 : state->session_by_pid = db_open_rbt(state);
154 0 : state->fn = fn;
155 0 : state->private_data = private_data;
156 0 : status = smbXsrv_session_global_traverse(collect_sessions_fn, state);
157 0 : if (!NT_STATUS_IS_OK(status)) {
158 0 : DEBUG(0, ("Failed to traverse sessions: %s\n",
159 : nt_errstr(status)));
160 0 : goto done;
161 : }
162 :
163 0 : status = smbXsrv_tcon_global_traverse(traverse_tcon_fn, state);
164 0 : if (!NT_STATUS_IS_OK(status)) {
165 0 : DEBUG(0, ("Failed to traverse tree connects: %s\n",
166 : nt_errstr(status)));
167 0 : goto done;
168 : }
169 0 : ret = state->count;
170 0 : done:
171 0 : talloc_free(frame);
172 0 : return ret;
173 : }
|