2007-08-21 06:04:24 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
1996-05-04 11:50:46 +04:00
Password and authentication handling
1998-01-22 16:27:43 +03:00
Copyright ( C ) Andrew Tridgell 1992 - 1998
2007-08-21 06:04:24 +04:00
Copyright ( C ) Jeremy Allison 2007.
1996-05-04 11:50:46 +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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
1996-05-04 11:50:46 +04:00
( at your option ) any later version .
2007-08-21 06:04:24 +04:00
1996-05-04 11:50:46 +04:00
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 .
2007-08-21 06:04:24 +04:00
1996-05-04 11:50:46 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
1996-05-04 11:50:46 +04:00
*/
# include "includes.h"
2011-02-25 19:14:22 +03:00
# include "system/passwd.h"
2011-03-22 18:57:01 +03:00
# include "smbd/smbd.h"
2009-01-08 14:03:45 +03:00
# include "smbd/globals.h"
2010-08-05 17:14:04 +04:00
# include "../librpc/gen_ndr/netlogon.h"
2011-03-24 15:46:20 +03:00
# include "auth.h"
2011-07-19 05:57:05 +04:00
# include "../libcli/security/security.h"
1999-12-13 16:27:58 +03:00
2010-06-15 08:52:42 +04:00
/* Fix up prototypes for OSX 10.4, where they're missing */
# ifndef HAVE_SETNETGRENT_PROTOTYPE
extern int setnetgrent ( const char * netgroup ) ;
# endif
# ifndef HAVE_GETNETGRENT_PROTOTYPE
extern int getnetgrent ( char * * host , char * * user , char * * domain ) ;
# endif
# ifndef HAVE_ENDNETGRENT_PROTOTYPE
extern void endnetgrent ( void ) ;
# endif
2007-08-21 05:43:22 +04:00
enum server_allocated_state { SERVER_ALLOCATED_REQUIRED_YES ,
SERVER_ALLOCATED_REQUIRED_NO ,
SERVER_ALLOCATED_REQUIRED_ANY } ;
2003-07-17 22:55:40 +04:00
2012-06-05 14:04:15 +04:00
static struct user_struct * get_valid_user_struct_internal (
2009-05-26 18:38:45 +04:00
struct smbd_server_connection * sconn ,
2012-06-05 20:17:15 +04:00
uint64_t vuid ,
2007-08-21 05:43:22 +04:00
enum server_allocated_state server_allocated )
1999-12-13 16:27:58 +03:00
{
2012-06-05 14:04:15 +04:00
struct user_struct * usp ;
2000-11-29 01:17:44 +03:00
int count = 0 ;
if ( vuid = = UID_FIELD_INVALID )
return NULL ;
2012-03-03 08:41:43 +04:00
usp = sconn - > users ;
2009-05-26 18:38:45 +04:00
for ( ; usp ; usp = usp - > next , count + + ) {
2007-08-21 05:43:22 +04:00
if ( vuid = = usp - > vuid ) {
switch ( server_allocated ) {
case SERVER_ALLOCATED_REQUIRED_YES :
2011-02-21 12:25:52 +03:00
if ( usp - > session_info = = NULL ) {
2007-08-21 05:43:22 +04:00
continue ;
}
break ;
case SERVER_ALLOCATED_REQUIRED_NO :
2011-02-21 12:25:52 +03:00
if ( usp - > session_info ! = NULL ) {
2007-08-21 05:43:22 +04:00
continue ;
}
case SERVER_ALLOCATED_REQUIRED_ANY :
break ;
}
2005-07-14 18:39:27 +04:00
if ( count > 10 ) {
2012-03-03 08:41:43 +04:00
DLIST_PROMOTE ( sconn - > users , usp ) ;
2005-07-14 18:39:27 +04:00
}
return usp ;
}
}
return NULL ;
}
/****************************************************************************
2007-08-21 05:43:22 +04:00
Check if a uid has been validated , and return an pointer to the user_struct
if it has . NULL if not . vuid is biased by an offset . This allows us to
tell random client vuid ' s ( normally zero ) from valid vuids .
2005-07-14 18:39:27 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-06-05 14:04:15 +04:00
struct user_struct * get_valid_user_struct ( struct smbd_server_connection * sconn ,
2012-06-05 20:17:15 +04:00
uint64_t vuid )
2005-07-14 18:39:27 +04:00
{
2009-05-26 18:38:45 +04:00
return get_valid_user_struct_internal ( sconn , vuid ,
2007-08-21 06:04:24 +04:00
SERVER_ALLOCATED_REQUIRED_YES ) ;
2007-08-21 05:43:22 +04:00
}
2005-07-14 18:39:27 +04:00
1999-12-13 16:27:58 +03:00
/****************************************************************************
2003-07-17 22:55:40 +04:00
Invalidate a uid .
1999-12-13 16:27:58 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-07-17 22:55:40 +04:00
2012-06-05 20:17:15 +04:00
void invalidate_vuid ( struct smbd_server_connection * sconn , uint64_t vuid )
1999-12-13 16:27:58 +03:00
{
2012-06-05 14:04:15 +04:00
struct user_struct * vuser = NULL ;
2007-08-21 05:43:22 +04:00
2009-05-26 18:38:45 +04:00
vuser = get_valid_user_struct_internal ( sconn , vuid ,
2007-08-21 05:43:22 +04:00
SERVER_ALLOCATED_REQUIRED_ANY ) ;
if ( vuser = = NULL ) {
2000-06-09 22:45:31 +04:00
return ;
2007-08-21 05:43:22 +04:00
}
2012-08-23 16:47:33 +04:00
session_yield ( vuser - > session ) ;
2003-02-24 05:35:54 +03:00
2012-03-03 08:41:43 +04:00
DLIST_REMOVE ( sconn - > users , vuser ) ;
SMB_ASSERT ( sconn - > num_users > 0 ) ;
sconn - > num_users - - ;
2000-06-09 07:30:54 +04:00
2002-09-25 19:19:00 +04:00
/* clear the vuid from the 'cache' on each connection, and
from the vuid ' owner ' of connections */
2009-05-27 13:15:44 +04:00
conn_clear_vuid_caches ( sconn , vuid ) ;
2002-09-25 19:19:00 +04:00
2007-04-02 07:46:13 +04:00
TALLOC_FREE ( vuser ) ;
1999-12-13 16:27:58 +03:00
}
2010-05-18 05:22:19 +04:00
int register_homes_share ( const char * username )
2008-04-29 15:23:47 +04:00
{
int result ;
struct passwd * pwd ;
result = lp_servicenumber ( username ) ;
if ( result ! = - 1 ) {
DEBUG ( 3 , ( " Using static (or previously created) service for "
" user '%s'; path = '%s' \n " , username ,
2014-02-02 17:04:46 +04:00
lp_path ( talloc_tos ( ) , result ) ) ) ;
2008-04-29 15:23:47 +04:00
return result ;
}
2010-10-20 19:16:23 +04:00
pwd = Get_Pwnam_alloc ( talloc_tos ( ) , username ) ;
2008-04-29 15:23:47 +04:00
if ( ( pwd = = NULL ) | | ( pwd - > pw_dir [ 0 ] = = ' \0 ' ) ) {
DEBUG ( 3 , ( " No home directory defined for user '%s' \n " ,
username ) ) ;
TALLOC_FREE ( pwd ) ;
return - 1 ;
}
DEBUG ( 3 , ( " Adding homes service for user '%s' using home directory: "
" '%s' \n " , username , pwd - > pw_dir ) ) ;
result = add_home_service ( username , username , pwd - > pw_dir ) ;
TALLOC_FREE ( pwd ) ;
return result ;
}