Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : session handling for utmp and PAM
4 :
5 : Copyright (C) tridge@samba.org 2001
6 : Copyright (C) abartlet@samba.org 2001
7 : Copyright (C) Gerald (Jerry) Carter 2006
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : /* a "session" is claimed when we do a SessionSetupX operation
24 : and is yielded when the corresponding vuid is destroyed.
25 :
26 : sessions are used to populate utmp and PAM session structures
27 : */
28 :
29 : #include "includes.h"
30 : #include "smbd/smbd.h"
31 : #include "smbd/globals.h"
32 : #include "dbwrap/dbwrap.h"
33 : #include "session.h"
34 : #include "auth.h"
35 : #include "../lib/tsocket/tsocket.h"
36 : #include "../libcli/security/security.h"
37 : #include "messages.h"
38 :
39 : /********************************************************************
40 : called when a session is created
41 : ********************************************************************/
42 :
43 29223 : bool session_claim(struct smbXsrv_session *session)
44 : {
45 29223 : struct auth_session_info *session_info =
46 29223 : session->global->auth_session_info;
47 758 : const char *username;
48 758 : const char *hostname;
49 758 : unsigned int id_num;
50 758 : fstring id_str;
51 :
52 : /* don't register sessions for the guest user - its just too
53 : expensive to go through pam session code for browsing etc */
54 29223 : if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
55 965 : return true;
56 : }
57 :
58 28256 : id_num = session->global->session_global_id;
59 :
60 28256 : snprintf(id_str, sizeof(id_str), "smb/%u", id_num);
61 :
62 : /* Make clear that we require the optional unix_token in the source3 code */
63 28256 : SMB_ASSERT(session_info->unix_token);
64 :
65 28256 : username = session_info->unix_info->unix_name;
66 28256 : hostname = session->global->channels[0].remote_name;
67 :
68 28256 : if (!smb_pam_claim_session(username, id_str, hostname)) {
69 0 : DEBUG(1,("pam_session rejected the session for %s [%s]\n",
70 : username, id_str));
71 0 : return false;
72 : }
73 :
74 28256 : if (lp_utmp()) {
75 0 : sys_utmp_claim(username, hostname, id_str, id_num);
76 : }
77 :
78 27500 : return true;
79 : }
80 :
81 : /********************************************************************
82 : called when a session is destroyed
83 : ********************************************************************/
84 :
85 29209 : void session_yield(struct smbXsrv_session *session)
86 : {
87 29209 : struct auth_session_info *session_info =
88 29209 : session->global->auth_session_info;
89 758 : const char *username;
90 758 : const char *hostname;
91 758 : unsigned int id_num;
92 29209 : fstring id_str = "";
93 :
94 29209 : id_num = session->global->session_global_id;
95 :
96 29209 : snprintf(id_str, sizeof(id_str), "smb/%u", id_num);
97 :
98 : /* Make clear that we require the optional unix_token in the source3 code */
99 29209 : SMB_ASSERT(session_info->unix_token);
100 :
101 29209 : username = session_info->unix_info->unix_name;
102 29209 : hostname = session->global->channels[0].remote_name;
103 :
104 29209 : if (lp_utmp()) {
105 0 : sys_utmp_yield(username, hostname, id_str, id_num);
106 : }
107 :
108 29209 : smb_pam_close_session(username, id_str, hostname);
109 29209 : }
110 :
111 : /********************************************************************
112 : ********************************************************************/
113 :
114 : struct session_list {
115 : TALLOC_CTX *mem_ctx;
116 : int count;
117 : const char *filter_user;
118 : const char *filter_machine;
119 : struct sessionid *sessions;
120 : };
121 :
122 24 : static int gather_sessioninfo(const char *key, struct sessionid *session,
123 : void *private_data)
124 : {
125 24 : struct session_list *sesslist = (struct session_list *)private_data;
126 :
127 : /* filter the session if required */
128 :
129 24 : if (sesslist->filter_user &&
130 0 : (sesslist->filter_user[0] != '\0') &&
131 0 : !strequal(session->username, sesslist->filter_user)) {
132 0 : return 0;
133 : }
134 :
135 24 : if (sesslist->filter_machine &&
136 0 : (sesslist->filter_machine[0] != '\0') &&
137 0 : !strequal(session->remote_machine,
138 : sesslist->filter_machine)) {
139 0 : return 0;
140 : }
141 :
142 24 : if (!process_exists(session->pid)) {
143 4 : return 0;
144 : }
145 :
146 20 : sesslist->sessions = talloc_realloc(
147 : sesslist->mem_ctx, sesslist->sessions, struct sessionid,
148 : sesslist->count+1);
149 :
150 20 : if (!sesslist->sessions) {
151 0 : sesslist->count = 0;
152 0 : return -1;
153 : }
154 :
155 20 : memcpy(&sesslist->sessions[sesslist->count], session,
156 : sizeof(struct sessionid));
157 :
158 20 : sesslist->count++;
159 :
160 20 : DEBUG(7, ("gather_sessioninfo session from %s@%s\n",
161 : session->username, session->remote_machine));
162 :
163 20 : return 0;
164 : }
165 :
166 : /********************************************************************
167 : ********************************************************************/
168 :
169 20 : int list_sessions(TALLOC_CTX *mem_ctx, struct sessionid **session_list)
170 : {
171 0 : struct session_list sesslist;
172 0 : NTSTATUS status;
173 :
174 20 : sesslist.mem_ctx = mem_ctx;
175 20 : sesslist.count = 0;
176 20 : sesslist.filter_user = NULL;
177 20 : sesslist.filter_machine = NULL;
178 20 : sesslist.sessions = NULL;
179 :
180 20 : status = sessionid_traverse_read(gather_sessioninfo, (void *) &sesslist);
181 20 : if (!NT_STATUS_IS_OK(status)) {
182 0 : DBG_ERR("Session traverse failed: %s\n", nt_errstr(status));
183 0 : TALLOC_FREE(sesslist.sessions);
184 0 : *session_list = NULL;
185 0 : return 0;
186 : }
187 :
188 20 : *session_list = sesslist.sessions;
189 20 : return sesslist.count;
190 : }
191 :
192 : /********************************************************************
193 : find the sessions that match the given username and machine
194 : ********************************************************************/
195 :
196 0 : int find_sessions(TALLOC_CTX *mem_ctx, const char *username,
197 : const char *machine, struct sessionid **session_list)
198 : {
199 0 : struct session_list sesslist;
200 0 : NTSTATUS status;
201 :
202 0 : sesslist.mem_ctx = mem_ctx;
203 0 : sesslist.count = 0;
204 0 : sesslist.filter_user = username;
205 0 : sesslist.filter_machine = machine;
206 0 : sesslist.sessions = NULL;
207 :
208 0 : status = sessionid_traverse_read(gather_sessioninfo, (void *)&sesslist);
209 0 : if (!NT_STATUS_IS_OK(status)) {
210 0 : DEBUG(3, ("Session traverse failed: %s\n", nt_errstr(status)));
211 0 : TALLOC_FREE(sesslist.sessions);
212 0 : *session_list = NULL;
213 0 : return 0;
214 : }
215 :
216 0 : *session_list = sesslist.sessions;
217 0 : return sesslist.count;
218 : }
|