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