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