smbd: Make find_share_mode_lease() static
[kai/samba-autobuild/.git] / source3 / smbd / session.c
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 bool session_claim(struct smbXsrv_session *session)
44 {
45         struct auth_session_info *session_info =
46                 session->global->auth_session_info;
47         const char *username;
48         const char *hostname;
49         unsigned int id_num;
50         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         if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
55                 return true;
56         }
57
58         id_num = session->global->session_global_id;
59
60         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         SMB_ASSERT(session_info->unix_token);
64
65         username = session_info->unix_info->unix_name;
66         hostname = session->global->channels[0].remote_name;
67
68         if (!smb_pam_claim_session(username, id_str, hostname)) {
69                 DEBUG(1,("pam_session rejected the session for %s [%s]\n",
70                                 username, id_str));
71                 return false;
72         }
73
74         if (lp_utmp()) {
75                 sys_utmp_claim(username, hostname, id_str, id_num);
76         }
77
78         return true;
79 }
80
81 /********************************************************************
82  called when a session is destroyed
83 ********************************************************************/
84
85 void session_yield(struct smbXsrv_session *session)
86 {
87         struct auth_session_info *session_info =
88                 session->global->auth_session_info;
89         const char *username;
90         const char *hostname;
91         unsigned int id_num;
92         fstring id_str = "";
93
94         id_num = session->global->session_global_id;
95
96         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         SMB_ASSERT(session_info->unix_token);
100
101         username = session_info->unix_info->unix_name;
102         hostname = session->global->channels[0].remote_name;
103
104         if (lp_utmp()) {
105                 sys_utmp_yield(username, hostname, id_str, id_num);
106         }
107
108         smb_pam_close_session(username, id_str, hostname);
109 }
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 static int gather_sessioninfo(const char *key, struct sessionid *session,
123                               void *private_data)
124 {
125         struct session_list *sesslist = (struct session_list *)private_data;
126
127         /* filter the session if required */
128
129         if (sesslist->filter_user &&
130             (sesslist->filter_user[0] != '\0') &&
131             !strequal(session->username, sesslist->filter_user)) {
132                 return 0;
133         }
134
135         if (sesslist->filter_machine &&
136             (sesslist->filter_machine[0] != '\0') &&
137             !strequal(session->remote_machine,
138                       sesslist->filter_machine)) {
139                 return 0;
140         }
141
142         if (!process_exists(session->pid)) {
143                 return 0;
144         }
145
146         sesslist->sessions = talloc_realloc(
147                 sesslist->mem_ctx, sesslist->sessions, struct sessionid,
148                 sesslist->count+1);
149
150         if (!sesslist->sessions) {
151                 sesslist->count = 0;
152                 return -1;
153         }
154
155         memcpy(&sesslist->sessions[sesslist->count], session,
156                sizeof(struct sessionid));
157
158         sesslist->count++;
159
160         DEBUG(7, ("gather_sessioninfo session from %s@%s\n",
161                   session->username, session->remote_machine));
162
163         return 0;
164 }
165
166 /********************************************************************
167 ********************************************************************/
168
169 int list_sessions(TALLOC_CTX *mem_ctx, struct sessionid **session_list)
170 {
171         struct session_list sesslist;
172         NTSTATUS status;
173
174         sesslist.mem_ctx = mem_ctx;
175         sesslist.count = 0;
176         sesslist.filter_user = NULL;
177         sesslist.filter_machine = NULL;
178         sesslist.sessions = NULL;
179
180         status = sessionid_traverse_read(gather_sessioninfo, (void *) &sesslist);
181         if (!NT_STATUS_IS_OK(status)) {
182                 DBG_ERR("Session traverse failed: %s\n", nt_errstr(status));
183                 TALLOC_FREE(sesslist.sessions);
184                 *session_list = NULL;
185                 return 0;
186         }
187
188         *session_list = sesslist.sessions;
189         return sesslist.count;
190 }
191
192 /********************************************************************
193 find the sessions that match the given username and machine
194 ********************************************************************/
195
196 int find_sessions(TALLOC_CTX *mem_ctx, const char *username,
197                   const char *machine, struct sessionid **session_list)
198 {
199         struct session_list sesslist;
200         NTSTATUS status;
201
202         sesslist.mem_ctx = mem_ctx;
203         sesslist.count = 0;
204         sesslist.filter_user = username;
205         sesslist.filter_machine = machine;
206         sesslist.sessions = NULL;
207
208         status = sessionid_traverse_read(gather_sessioninfo, (void *)&sesslist);
209         if (!NT_STATUS_IS_OK(status)) {
210                 DEBUG(3, ("Session traverse failed: %s\n", nt_errstr(status)));
211                 TALLOC_FREE(sesslist.sessions);
212                 *session_list = NULL;
213                 return 0;
214         }
215
216         *session_list = sesslist.sessions;
217         return sesslist.count;
218 }