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