2007-08-21 02:04:24 +00:00
/*
2002-01-30 06:08:46 +00:00
Unix SMB / CIFS implementation .
1996-05-04 07:50:46 +00:00
Password and authentication handling
1998-01-22 13:27:43 +00:00
Copyright ( C ) Andrew Tridgell 1992 - 1998
2007-08-21 02:04:24 +00:00
Copyright ( C ) Jeremy Allison 2007.
1996-05-04 07:50:46 +00: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 19:25:36 +00:00
the Free Software Foundation ; either version 3 of the License , or
1996-05-04 07:50:46 +00:00
( at your option ) any later version .
2007-08-21 02:04:24 +00:00
1996-05-04 07:50:46 +00: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 02:04:24 +00:00
1996-05-04 07:50:46 +00:00
You should have received a copy of the GNU General Public License
2007-07-10 00:52:41 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
1996-05-04 07:50:46 +00:00
*/
# include "includes.h"
2011-02-25 17:14:22 +01:00
# include "system/passwd.h"
2011-03-22 16:57:01 +01:00
# include "smbd/smbd.h"
2009-01-08 12:03:45 +01:00
# include "smbd/globals.h"
2010-08-05 15:14:04 +02:00
# include "../librpc/gen_ndr/netlogon.h"
2011-03-24 13:46:20 +01:00
# include "auth.h"
2011-07-19 11:57:05 +10:00
# include "../libcli/security/security.h"
1999-12-13 13:27:58 +00:00
2010-06-15 06:52:42 +02: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 01:43:22 +00:00
enum server_allocated_state { SERVER_ALLOCATED_REQUIRED_YES ,
SERVER_ALLOCATED_REQUIRED_NO ,
SERVER_ALLOCATED_REQUIRED_ANY } ;
2003-07-17 18:55:40 +00:00
2012-06-05 12:04:15 +02:00
static struct user_struct * get_valid_user_struct_internal (
2009-05-26 16:38:45 +02:00
struct smbd_server_connection * sconn ,
2012-06-05 18:17:15 +02:00
uint64_t vuid ,
2007-08-21 01:43:22 +00:00
enum server_allocated_state server_allocated )
1999-12-13 13:27:58 +00:00
{
2012-06-05 12:04:15 +02:00
struct user_struct * usp ;
2000-11-28 22:17:44 +00:00
int count = 0 ;
if ( vuid = = UID_FIELD_INVALID )
return NULL ;
2012-03-03 05:41:43 +01:00
usp = sconn - > users ;
2009-05-26 16:38:45 +02:00
for ( ; usp ; usp = usp - > next , count + + ) {
2007-08-21 01:43:22 +00:00
if ( vuid = = usp - > vuid ) {
switch ( server_allocated ) {
case SERVER_ALLOCATED_REQUIRED_YES :
2011-02-21 10:25:52 +01:00
if ( usp - > session_info = = NULL ) {
2007-08-21 01:43:22 +00:00
continue ;
}
break ;
case SERVER_ALLOCATED_REQUIRED_NO :
2011-02-21 10:25:52 +01:00
if ( usp - > session_info ! = NULL ) {
2007-08-21 01:43:22 +00:00
continue ;
}
case SERVER_ALLOCATED_REQUIRED_ANY :
break ;
}
2005-07-14 14:39:27 +00:00
if ( count > 10 ) {
2012-03-03 05:41:43 +01:00
DLIST_PROMOTE ( sconn - > users , usp ) ;
2005-07-14 14:39:27 +00:00
}
return usp ;
}
}
return NULL ;
}
/****************************************************************************
2007-08-21 01:43:22 +00: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 14:39:27 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-06-05 12:04:15 +02:00
struct user_struct * get_valid_user_struct ( struct smbd_server_connection * sconn ,
2012-06-05 18:17:15 +02:00
uint64_t vuid )
2005-07-14 14:39:27 +00:00
{
2009-05-26 16:38:45 +02:00
return get_valid_user_struct_internal ( sconn , vuid ,
2007-08-21 02:04:24 +00:00
SERVER_ALLOCATED_REQUIRED_YES ) ;
2007-08-21 01:43:22 +00:00
}
2005-07-14 14:39:27 +00:00
1999-12-13 13:27:58 +00:00
/****************************************************************************
2003-07-17 18:55:40 +00:00
Invalidate a uid .
1999-12-13 13:27:58 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-07-17 18:55:40 +00:00
2012-06-05 18:17:15 +02:00
void invalidate_vuid ( struct smbd_server_connection * sconn , uint64_t vuid )
1999-12-13 13:27:58 +00:00
{
2012-06-05 12:04:15 +02:00
struct user_struct * vuser = NULL ;
2007-08-21 01:43:22 +00:00
2009-05-26 16:38:45 +02:00
vuser = get_valid_user_struct_internal ( sconn , vuid ,
2007-08-21 01:43:22 +00:00
SERVER_ALLOCATED_REQUIRED_ANY ) ;
if ( vuser = = NULL ) {
2000-06-09 18:45:31 +00:00
return ;
2007-08-21 01:43:22 +00:00
}
2012-08-23 14:47:33 +02:00
session_yield ( vuser - > session ) ;
2003-02-24 02:35:54 +00:00
2012-03-03 05:41:43 +01:00
DLIST_REMOVE ( sconn - > users , vuser ) ;
SMB_ASSERT ( sconn - > num_users > 0 ) ;
sconn - > num_users - - ;
2000-06-09 03:30:54 +00:00
2002-09-25 15:19:00 +00:00
/* clear the vuid from the 'cache' on each connection, and
from the vuid ' owner ' of connections */
2009-05-27 11:15:44 +02:00
conn_clear_vuid_caches ( sconn , vuid ) ;
2002-09-25 15:19:00 +00:00
2007-04-02 03:46:13 +00:00
TALLOC_FREE ( vuser ) ;
1999-12-13 13:27:58 +00:00
}
2010-05-17 18:22:19 -07:00
int register_homes_share ( const char * username )
2008-04-29 13:23:47 +02: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 14:04:46 +01:00
lp_path ( talloc_tos ( ) , result ) ) ) ;
2008-04-29 13:23:47 +02:00
return result ;
}
2010-10-20 08:16:23 -07:00
pwd = Get_Pwnam_alloc ( talloc_tos ( ) , username ) ;
2008-04-29 13:23:47 +02: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 ;
}