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 10 : static int collect_sessions_fn(struct smbXsrv_session_global0 *global, 51 : void *connections_forall_state) 52 : { 53 0 : NTSTATUS status; 54 10 : struct connections_forall_state *state = 55 : (struct connections_forall_state*)connections_forall_state; 56 : 57 10 : uint32_t id = global->session_global_id; 58 0 : struct connections_forall_session sess; 59 : 60 10 : if (global->auth_session_info == NULL) { 61 0 : sess.uid = -1; 62 0 : sess.gid = -1; 63 : } else { 64 10 : sess.uid = global->auth_session_info->unix_token->uid; 65 10 : sess.gid = global->auth_session_info->unix_token->gid; 66 : } 67 10 : fstrcpy(sess.machine, global->channels[0].remote_name); 68 10 : fstrcpy(sess.addr, global->channels[0].remote_address); 69 10 : sess.cipher = global->channels[0].encryption_cipher; 70 10 : sess.signing = global->channels[0].signing_algo; 71 10 : sess.dialect = global->connection_dialect; 72 10 : sess.signing_flags = global->signing_flags; 73 : 74 10 : 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 10 : if (!NT_STATUS_IS_OK(status)) { 79 0 : DEBUG(0, ("Failed to store record: %s\n", nt_errstr(status))); 80 : } 81 10 : return 0; 82 : } 83 : 84 10 : static int traverse_tcon_fn(struct smbXsrv_tcon_global0 *global, 85 : void *connections_forall_state) 86 : { 87 0 : NTSTATUS status; 88 10 : struct connections_forall_state *state = 89 : (struct connections_forall_state*)connections_forall_state; 90 : 91 0 : struct connections_data data; 92 : 93 10 : uint32_t sess_id = global->session_global_id; 94 10 : struct connections_forall_session sess = { 95 : .uid = -1, 96 : .gid = -1, 97 : }; 98 : 99 10 : 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 10 : 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 10 : status = dbwrap_fetch(state->session_by_pid, state, 115 : make_tdb_data((void*)&sess_id, sizeof(sess_id)), 116 : &val); 117 10 : if (NT_STATUS_IS_OK(status)) { 118 10 : memcpy((uint8_t *)&sess, val.dptr, val.dsize); 119 : } 120 : 121 10 : ZERO_STRUCT(data); 122 : 123 10 : data.pid = global->server_id; 124 10 : data.cnum = global->tcon_global_id; 125 10 : data.sess_id = sess_id; 126 10 : fstrcpy(data.servicename, global->share_name); 127 10 : data.uid = sess.uid; 128 10 : data.gid = sess.gid; 129 10 : fstrcpy(data.addr, sess.addr); 130 10 : fstrcpy(data.machine, sess.machine); 131 10 : data.start = global->creation_time; 132 10 : data.encryption_flags = global->encryption_flags; 133 10 : data.cipher = sess.cipher; 134 10 : data.dialect = sess.dialect; 135 10 : data.signing = sess.signing; 136 10 : data.signing_flags = global->signing_flags; 137 : 138 10 : state->count++; 139 : 140 10 : return state->fn(&data, state->private_data); 141 : } 142 : 143 10 : int connections_forall_read(int (*fn)(const struct connections_data *data, 144 : void *private_data), 145 : void *private_data) 146 : { 147 10 : TALLOC_CTX *frame = talloc_stackframe(); 148 0 : struct connections_forall_state *state = 149 10 : talloc_zero(talloc_tos(), struct connections_forall_state); 150 0 : NTSTATUS status; 151 10 : int ret = -1; 152 : 153 10 : state->session_by_pid = db_open_rbt(state); 154 10 : state->fn = fn; 155 10 : state->private_data = private_data; 156 10 : status = smbXsrv_session_global_traverse(collect_sessions_fn, state); 157 10 : 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 10 : status = smbXsrv_tcon_global_traverse(traverse_tcon_fn, state); 164 10 : 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 10 : ret = state->count; 170 10 : done: 171 10 : talloc_free(frame); 172 10 : return ret; 173 : }