2003-08-13 05:53:07 +04:00
/*
Unix SMB / CIFS implementation .
Password and authentication handling
2005-07-19 07:58:44 +04:00
Copyright ( C ) Andrew Tridgell 1992 - 2005
2005-04-10 11:39:51 +04:00
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2005
2003-08-13 05:53:07 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2004-11-02 10:18:24 +03:00
# include "smb_server/smb_server.h"
2005-07-19 07:58:44 +04:00
# include "dlinklist.h"
2003-08-13 05:53:07 +04:00
2005-11-18 15:57:48 +03:00
/*
* init the sessions structures
*/
NTSTATUS smbsrv_init_sessions ( struct smbsrv_connection * smb_conn , uint64_t limit )
2003-08-13 05:53:07 +04:00
{
2005-11-18 15:57:48 +03:00
/*
* the idr_ * functions take ' int ' as limit ,
* and only work with a max limit 0x00FFFFFF
*/
limit & = 0x00FFFFFF ;
smb_conn - > sessions . idtree_vuid = idr_init ( smb_conn ) ;
2005-11-18 11:44:36 +03:00
NT_STATUS_HAVE_NO_MEMORY ( smb_conn - > sessions . idtree_vuid ) ;
2005-11-18 15:57:48 +03:00
smb_conn - > sessions . idtree_limit = limit ;
smb_conn - > sessions . list = NULL ;
2005-11-18 11:44:36 +03:00
return NT_STATUS_OK ;
2005-04-10 11:39:51 +04:00
}
2003-08-13 05:53:07 +04:00
2005-11-18 15:57:48 +03:00
/*
* Find the session structure assoicated with a VUID
* ( not one from an in - progress session setup )
*/
2006-03-26 15:32:27 +04:00
struct smbsrv_session * smbsrv_session_find ( struct smbsrv_connection * smb_conn ,
uint64_t vuid , struct timeval request_time )
2005-04-10 11:39:51 +04:00
{
2005-11-18 15:57:48 +03:00
void * p ;
struct smbsrv_session * sess ;
if ( vuid = = 0 ) return NULL ;
if ( vuid > smb_conn - > sessions . idtree_limit ) return NULL ;
p = idr_find ( smb_conn - > sessions . idtree_vuid , vuid ) ;
if ( ! p ) return NULL ;
/* only return a finished session */
sess = talloc_get_type ( p , struct smbsrv_session ) ;
if ( sess & & sess - > session_info ) {
2006-03-26 15:32:27 +04:00
sess - > statistics . last_request_time = request_time ;
2005-04-10 11:39:51 +04:00
return sess ;
2003-08-13 05:53:07 +04:00
}
2005-11-18 15:57:48 +03:00
2003-08-13 05:53:07 +04:00
return NULL ;
}
2005-11-18 15:57:48 +03:00
/*
* Find the session structure assoicated with a VUID
* ( assoicated with an in - progress session setup )
*/
struct smbsrv_session * smbsrv_session_find_sesssetup ( struct smbsrv_connection * smb_conn , uint64_t vuid )
2003-08-13 05:53:07 +04:00
{
2005-11-18 15:57:48 +03:00
void * p ;
struct smbsrv_session * sess ;
if ( vuid = = 0 ) return NULL ;
if ( vuid > smb_conn - > sessions . idtree_limit ) return NULL ;
p = idr_find ( smb_conn - > sessions . idtree_vuid , vuid ) ;
if ( ! p ) return NULL ;
/* only return an unfinished session */
sess = talloc_get_type ( p , struct smbsrv_session ) ;
if ( sess & & ! sess - > session_info ) {
2005-04-10 11:39:51 +04:00
return sess ;
}
return NULL ;
}
2003-08-13 05:53:07 +04:00
2005-11-18 15:57:48 +03:00
/*
* the session will be marked as valid for usage
* by attaching a auth_session_info to the session .
*
* session_info will be talloc_stealed
*/
NTSTATUS smbsrv_session_sesssetup_finished ( struct smbsrv_session * sess ,
struct auth_session_info * session_info )
2005-04-10 11:39:51 +04:00
{
2005-11-18 15:57:48 +03:00
/* this check is to catch programmer errors */
if ( ! session_info ) {
talloc_free ( sess ) ;
return NT_STATUS_ACCESS_DENIED ;
}
2003-08-13 05:53:07 +04:00
2005-11-18 15:57:48 +03:00
/* mark the session as successful authenticated */
sess - > session_info = talloc_steal ( sess , session_info ) ;
2005-04-10 11:39:51 +04:00
2005-11-18 15:57:48 +03:00
/* now fill in some statistics */
sess - > statistics . auth_time = timeval_current ( ) ;
2005-07-19 07:58:44 +04:00
2005-11-18 15:57:48 +03:00
return NT_STATUS_OK ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
2005-11-18 15:57:48 +03:00
destroy a session structure
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-11-18 15:57:48 +03:00
static int smbsrv_session_destructor ( void * p )
2003-08-13 05:53:07 +04:00
{
2005-11-18 15:57:48 +03:00
struct smbsrv_session * sess = talloc_get_type ( p , struct smbsrv_session ) ;
struct smbsrv_connection * smb_conn = sess - > smb_conn ;
idr_remove ( smb_conn - > sessions . idtree_vuid , sess - > vuid ) ;
DLIST_REMOVE ( smb_conn - > sessions . list , sess ) ;
return 0 ;
2003-08-13 05:53:07 +04:00
}
2005-11-18 15:57:48 +03:00
/*
* allocate a new session structure with a VUID .
* gensec_ctx is optional , but talloc_steal ' ed when present
2003-08-13 05:53:07 +04:00
*/
2005-11-18 15:57:48 +03:00
struct smbsrv_session * smbsrv_session_new ( struct smbsrv_connection * smb_conn ,
struct gensec_security * gensec_ctx )
2003-08-13 05:53:07 +04:00
{
2004-07-14 16:44:31 +04:00
struct smbsrv_session * sess = NULL ;
2005-04-10 11:39:51 +04:00
int i ;
/* Ensure no vuid gets registered in share level security. */
2005-11-17 15:52:40 +03:00
if ( smb_conn - > config . security = = SEC_SHARE ) return NULL ;
2003-08-13 05:53:07 +04:00
2005-11-18 15:57:48 +03:00
sess = talloc_zero ( smb_conn , struct smbsrv_session ) ;
if ( ! sess ) return NULL ;
sess - > smb_conn = smb_conn ;
2003-08-13 05:53:07 +04:00
2005-11-18 15:57:48 +03:00
i = idr_get_new_random ( smb_conn - > sessions . idtree_vuid , sess , smb_conn - > sessions . idtree_limit ) ;
2005-04-10 11:39:51 +04:00
if ( i = = - 1 ) {
2005-11-17 15:52:40 +03:00
DEBUG ( 1 , ( " ERROR! Out of connection structures \n " ) ) ;
2005-04-10 11:39:51 +04:00
talloc_free ( sess ) ;
return NULL ;
2003-08-13 05:53:07 +04:00
}
2005-04-10 11:39:51 +04:00
sess - > vuid = i ;
2003-08-13 05:53:07 +04:00
/* use this to keep tabs on all our info from the authentication */
2005-11-18 15:57:48 +03:00
sess - > gensec_ctx = talloc_steal ( sess , gensec_ctx ) ;
2005-07-19 07:58:44 +04:00
DLIST_ADD ( smb_conn - > sessions . list , sess ) ;
2005-04-10 11:39:51 +04:00
talloc_set_destructor ( sess , smbsrv_session_destructor ) ;
2005-11-18 15:57:48 +03:00
/* now fill in some statistics */
sess - > statistics . connect_time = timeval_current ( ) ;
2005-04-10 11:39:51 +04:00
return sess ;
2003-08-13 05:53:07 +04:00
}