2 Unix SMB/CIFS implementation.
3 session handling for utmp and PAM
5 Copyright (C) tridge@samba.org 2001
6 Copyright (C) abartlet@samba.org 2001
7 Copyright (C) Gerald (Jerry) Carter 2006
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.
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.
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/>.
23 /* a "session" is claimed when we do a SessionSetupX operation
24 and is yielded when the corresponding vuid is destroyed.
26 sessions are used to populate utmp and PAM session structures
30 #include "smbd/smbd.h"
31 #include "smbd/globals.h"
32 #include "dbwrap/dbwrap.h"
35 #include "../lib/tsocket/tsocket.h"
36 #include "../libcli/security/security.h"
39 /********************************************************************
40 called when a session is created
41 ********************************************************************/
43 bool session_claim(struct smbXsrv_session *session)
45 struct auth_session_info *session_info =
46 session->global->auth_session_info;
52 /* don't register sessions for the guest user - its just too
53 expensive to go through pam session code for browsing etc */
54 if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
58 id_num = session->global->session_global_id;
60 snprintf(id_str, sizeof(id_str), "smb/%u", id_num);
62 /* Make clear that we require the optional unix_token in the source3 code */
63 SMB_ASSERT(session_info->unix_token);
65 username = session_info->unix_info->unix_name;
66 hostname = session->global->channels[0].remote_name;
68 if (!smb_pam_claim_session(username, id_str, hostname)) {
69 DEBUG(1,("pam_session rejected the session for %s [%s]\n",
75 sys_utmp_claim(username, hostname, id_str, id_num);
81 /********************************************************************
82 called when a session is destroyed
83 ********************************************************************/
85 void session_yield(struct smbXsrv_session *session)
87 struct auth_session_info *session_info =
88 session->global->auth_session_info;
94 id_num = session->global->session_global_id;
96 snprintf(id_str, sizeof(id_str), "smb/%u", id_num);
98 /* Make clear that we require the optional unix_token in the source3 code */
99 SMB_ASSERT(session_info->unix_token);
101 username = session_info->unix_info->unix_name;
102 hostname = session->global->channels[0].remote_name;
105 sys_utmp_yield(username, hostname, id_str, id_num);
108 smb_pam_close_session(username, id_str, hostname);
111 /********************************************************************
112 ********************************************************************/
114 struct session_list {
117 struct sessionid *sessions;
120 static int gather_sessioninfo(const char *key, struct sessionid *session,
123 struct session_list *sesslist = (struct session_list *)private_data;
125 sesslist->sessions = talloc_realloc(
126 sesslist->mem_ctx, sesslist->sessions, struct sessionid,
129 if (!sesslist->sessions) {
134 memcpy(&sesslist->sessions[sesslist->count], session,
135 sizeof(struct sessionid));
139 DEBUG(7, ("gather_sessioninfo session from %s@%s\n",
140 session->username, session->remote_machine));
145 /********************************************************************
146 ********************************************************************/
148 int list_sessions(TALLOC_CTX *mem_ctx, struct sessionid **session_list)
150 struct session_list sesslist;
153 sesslist.mem_ctx = mem_ctx;
155 sesslist.sessions = NULL;
157 status = sessionid_traverse_read(gather_sessioninfo, (void *) &sesslist);
158 if (!NT_STATUS_IS_OK(status)) {
159 DEBUG(3, ("Session traverse failed\n"));
160 SAFE_FREE(sesslist.sessions);
161 *session_list = NULL;
165 *session_list = sesslist.sessions;
166 return sesslist.count;