1998-05-07 22:19:05 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
1998-05-07 22:19:05 +04:00
Password and authentication handling
2001-09-26 00:21:21 +04:00
Copyright ( C ) Jeremy Allison 1996 - 2001
2000-11-14 02:03:34 +03:00
Copyright ( C ) Luke Kenneth Casson Leighton 1996 - 1998
2001-04-26 02:12:13 +04:00
Copyright ( C ) Gerald ( Jerry ) Carter 2000 - 2001
2002-01-12 04:55:09 +03:00
Copyright ( C ) Andrew Bartlett 2001 - 2002
2003-05-12 22:12:31 +04:00
Copyright ( C ) Simo Sorce 2003
1998-05-19 01:30:57 +04:00
1998-05-07 22:19:05 +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"
2002-07-15 14:35:28 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_PASSDB
2003-07-01 08:11:42 +04:00
/******************************************************************
get the default domain / netbios name to be used when
testing authentication . For example , if you connect
to a Windows member server using a bogus domain name , the
Windows box will map the BOGUS \ user to DOMAIN \ user . A
standalone box will map to WKS \ user .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
const char * get_default_sam_name ( void )
2003-05-07 12:21:06 +04:00
{
2003-07-01 00:45:14 +04:00
/* standalone servers can only use the local netbios name */
if ( lp_server_role ( ) = = ROLE_STANDALONE )
return global_myname ( ) ;
2003-07-01 08:11:42 +04:00
/* Windows domain members default to the DOMAIN
2003-07-01 00:45:14 +04:00
name when not specified */
return lp_workgroup ( ) ;
2003-05-07 12:21:06 +04:00
}
1999-12-13 16:27:58 +03:00
2001-09-27 13:13:26 +04:00
/************************************************************
Fill the SAM_ACCOUNT with default values .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-05-12 22:12:31 +04:00
void pdb_fill_default_sam ( SAM_ACCOUNT * user )
2001-09-27 13:13:26 +04:00
{
2002-01-15 04:02:13 +03:00
ZERO_STRUCT ( user - > private ) ; /* Don't touch the talloc context */
2001-10-04 03:08:10 +04:00
2002-11-07 10:19:10 +03:00
/* no initial methods */
user - > methods = NULL ;
2001-10-04 03:08:10 +04:00
/* Don't change these timestamp settings without a good reason.
They are important for NT member server compatibility . */
2002-01-02 10:41:54 +03:00
user - > private . logon_time = ( time_t ) 0 ;
user - > private . pass_last_set_time = ( time_t ) 0 ;
user - > private . pass_can_change_time = ( time_t ) 0 ;
user - > private . logoff_time =
user - > private . kickoff_time =
user - > private . pass_must_change_time = get_time_t_max ( ) ;
2004-02-12 19:16:53 +03:00
user - > private . fields_present = 0x00ffffff ;
2002-01-02 10:41:54 +03:00
user - > private . logon_divs = 168 ; /* hours per week */
user - > private . hours_len = 21 ; /* 21 times 8 bits = 168 */
memset ( user - > private . hours , 0xff , user - > private . hours_len ) ; /* available at all hours */
2003-09-19 03:53:48 +04:00
user - > private . bad_password_count = 0 ;
user - > private . logon_count = 0 ;
2002-01-02 10:41:54 +03:00
user - > private . unknown_6 = 0x000004ec ; /* don't know */
2002-01-15 04:14:58 +03:00
/* Some parts of samba strlen their pdb_get...() returns,
so this keeps the interface unchanged for now . */
user - > private . username = " " ;
user - > private . domain = " " ;
user - > private . nt_username = " " ;
user - > private . full_name = " " ;
user - > private . home_dir = " " ;
user - > private . logon_script = " " ;
user - > private . profile_path = " " ;
user - > private . acct_desc = " " ;
user - > private . workstations = " " ;
user - > private . unknown_str = " " ;
user - > private . munged_dial = " " ;
2002-09-25 19:19:00 +04:00
user - > private . plaintext_pw = NULL ;
2003-10-10 16:57:44 +04:00
/*
Unless we know otherwise have a Account Control Bit
value of ' normal user ' . This helps User Manager , which
asks for a filtered list of users .
*/
user - > private . acct_ctrl = ACB_NORMAL ;
2001-09-27 13:13:26 +04:00
}
2002-01-15 04:02:13 +03:00
static void destroy_pdb_talloc ( SAM_ACCOUNT * * user )
{
if ( * user ) {
2002-09-25 19:19:00 +04:00
data_blob_clear_free ( & ( ( * user ) - > private . lm_pw ) ) ;
data_blob_clear_free ( & ( ( * user ) - > private . nt_pw ) ) ;
if ( ( * user ) - > private . plaintext_pw ! = NULL )
memset ( ( * user ) - > private . plaintext_pw , ' \0 ' , strlen ( ( * user ) - > private . plaintext_pw ) ) ;
2002-01-15 04:02:13 +03:00
talloc_destroy ( ( * user ) - > mem_ctx ) ;
* user = NULL ;
}
}
2001-09-27 13:13:26 +04:00
2002-01-15 04:02:13 +03:00
/**********************************************************************
2004-01-08 01:44:28 +03:00
Allocates memory and initialises a struct sam_passwd on supplied mem_ctx .
2002-01-15 04:02:13 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-09-26 00:21:21 +04:00
2002-01-15 04:02:13 +03:00
NTSTATUS pdb_init_sam_talloc ( TALLOC_CTX * mem_ctx , SAM_ACCOUNT * * user )
1998-05-07 22:19:05 +04:00
{
2001-05-04 19:44:27 +04:00
if ( * user ! = NULL ) {
2002-07-15 14:35:28 +04:00
DEBUG ( 0 , ( " pdb_init_sam_talloc: SAM_ACCOUNT was non NULL \n " ) ) ;
2001-05-04 19:44:27 +04:00
#if 0
2002-03-21 06:53:44 +03:00
smb_panic ( " non-NULL pointer passed to pdb_init_sam \n " ) ;
2001-05-04 19:44:27 +04:00
# endif
2002-01-15 04:02:13 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2001-05-04 19:44:27 +04:00
}
2002-01-15 04:02:13 +03:00
if ( ! mem_ctx ) {
DEBUG ( 0 , ( " pdb_init_sam_talloc: mem_ctx was NULL! \n " ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
* user = ( SAM_ACCOUNT * ) talloc ( mem_ctx , sizeof ( SAM_ACCOUNT ) ) ;
2002-01-02 10:41:54 +03:00
2001-05-04 19:44:27 +04:00
if ( * user = = NULL ) {
2002-07-15 14:35:28 +04:00
DEBUG ( 0 , ( " pdb_init_sam_talloc: error while allocating memory \n " ) ) ;
2002-01-15 04:02:13 +03:00
return NT_STATUS_NO_MEMORY ;
2001-05-04 19:44:27 +04:00
}
2001-09-27 13:13:26 +04:00
2002-01-15 04:02:13 +03:00
( * user ) - > mem_ctx = mem_ctx ;
( * user ) - > free_fn = NULL ;
2001-09-27 13:13:26 +04:00
pdb_fill_default_sam ( * user ) ;
2002-01-15 04:02:13 +03:00
return NT_STATUS_OK ;
}
2001-09-27 13:13:26 +04:00
2002-01-15 04:02:13 +03:00
/*************************************************************
2004-02-12 18:20:40 +03:00
Allocates memory and initialises a struct sam_passwd .
2002-01-15 04:02:13 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS pdb_init_sam ( SAM_ACCOUNT * * user )
{
TALLOC_CTX * mem_ctx ;
NTSTATUS nt_status ;
2002-12-20 23:21:31 +03:00
mem_ctx = talloc_init ( " passdb internal SAM_ACCOUNT allocation " ) ;
2002-01-15 04:02:13 +03:00
if ( ! mem_ctx ) {
DEBUG ( 0 , ( " pdb_init_sam: error while doing talloc_init() \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
if ( ! NT_STATUS_IS_OK ( nt_status = pdb_init_sam_talloc ( mem_ctx , user ) ) ) {
talloc_destroy ( mem_ctx ) ;
return nt_status ;
}
( * user ) - > free_fn = destroy_pdb_talloc ;
return NT_STATUS_OK ;
2001-09-27 13:13:26 +04:00
}
2004-02-12 18:20:40 +03:00
/**************************************************************************
* This function will take care of all the steps needed to correctly
* allocate and set the user SID , please do use this function to create new
* users , messing with SIDs is not good .
*
* account_data must be provided initialized , pwd may be null .
* SSS
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS pdb_set_sam_sids ( SAM_ACCOUNT * account_data , const struct passwd * pwd )
{
const char * guest_account = lp_guestaccount ( ) ;
GROUP_MAP map ;
BOOL ret ;
if ( ! account_data | | ! pwd ) {
return NT_STATUS_INVALID_PARAMETER ;
}
/* this is a hack this thing should not be set
this way - - SSS */
if ( ! ( guest_account & & * guest_account ) ) {
DEBUG ( 1 , ( " NULL guest account!?!? \n " ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
} else {
/* Ensure this *must* be set right */
if ( strcmp ( pwd - > pw_name , guest_account ) = = 0 ) {
if ( ! pdb_set_user_sid_from_rid ( account_data , DOMAIN_USER_RID_GUEST , PDB_DEFAULT ) ) {
return NT_STATUS_UNSUCCESSFUL ;
}
if ( ! pdb_set_group_sid_from_rid ( account_data , DOMAIN_GROUP_RID_GUESTS , PDB_DEFAULT ) ) {
return NT_STATUS_UNSUCCESSFUL ;
}
return NT_STATUS_OK ;
}
}
if ( ! pdb_set_user_sid_from_rid ( account_data , fallback_pdb_uid_to_user_rid ( pwd - > pw_uid ) , PDB_SET ) ) {
DEBUG ( 0 , ( " Can't set User SID from RID! \n " ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
/* call the mapping code here */
become_root ( ) ;
ret = pdb_getgrgid ( & map , pwd - > pw_gid ) ;
unbecome_root ( ) ;
if ( ret ) {
if ( ! pdb_set_group_sid ( account_data , & map . sid , PDB_SET ) ) {
DEBUG ( 0 , ( " Can't set Group SID! \n " ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
}
else {
if ( ! pdb_set_group_sid_from_rid ( account_data , pdb_gid_to_group_rid ( pwd - > pw_gid ) , PDB_SET ) ) {
DEBUG ( 0 , ( " Can't set Group SID \n " ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
}
return NT_STATUS_OK ;
}
2001-09-27 13:13:26 +04:00
/*************************************************************
Initialises a struct sam_passwd with sane values .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-15 14:35:28 +04:00
NTSTATUS pdb_fill_sam_pw ( SAM_ACCOUNT * sam_account , const struct passwd * pwd )
2001-09-27 13:13:26 +04:00
{
2003-05-12 22:12:31 +04:00
NTSTATUS ret ;
2002-08-17 21:00:51 +04:00
2001-09-27 13:13:26 +04:00
if ( ! pwd ) {
2002-01-15 04:02:13 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2001-09-27 13:13:26 +04:00
}
2002-07-15 14:35:28 +04:00
pdb_fill_default_sam ( sam_account ) ;
2002-11-02 06:47:48 +03:00
pdb_set_username ( sam_account , pwd - > pw_name , PDB_SET ) ;
pdb_set_fullname ( sam_account , pwd - > pw_gecos , PDB_SET ) ;
2001-09-27 13:13:26 +04:00
2002-11-02 06:47:48 +03:00
pdb_set_unix_homedir ( sam_account , pwd - > pw_dir , PDB_SET ) ;
2001-10-31 13:46:25 +03:00
2003-05-13 19:29:23 +04:00
pdb_set_domain ( sam_account , get_global_sam_name ( ) , PDB_DEFAULT ) ;
2001-12-27 09:38:04 +03:00
2002-07-15 14:35:28 +04:00
/* When we get a proper uid -> SID and SID -> uid allocation
mechinism , we should call it here .
We can ' t just set this to 0 or allow it only to be filled
2003-05-14 04:46:43 +04:00
in when added to the backend , because the user ' s SID
2002-07-15 14:35:28 +04:00
may already be in security descriptors etc .
- - abartlet 11 - May - 02
*/
2003-05-12 22:12:31 +04:00
ret = pdb_set_sam_sids ( sam_account , pwd ) ;
2003-06-22 14:09:52 +04:00
if ( ! NT_STATUS_IS_OK ( ret ) ) return ret ;
2002-07-15 14:35:28 +04:00
/* check if this is a user account or a machine account */
if ( pwd - > pw_name [ strlen ( pwd - > pw_name ) - 1 ] ! = ' $ ' )
{
pdb_set_profile_path ( sam_account ,
talloc_sub_specified ( ( sam_account ) - > mem_ctx ,
lp_logon_path ( ) ,
2002-11-13 02:20:50 +03:00
pwd - > pw_name , global_myname ( ) ,
2002-07-15 14:35:28 +04:00
pwd - > pw_uid , pwd - > pw_gid ) ,
2002-11-02 06:47:48 +03:00
PDB_DEFAULT ) ;
2002-07-15 14:35:28 +04:00
pdb_set_homedir ( sam_account ,
talloc_sub_specified ( ( sam_account ) - > mem_ctx ,
lp_logon_home ( ) ,
2002-11-13 02:20:50 +03:00
pwd - > pw_name , global_myname ( ) ,
2002-07-15 14:35:28 +04:00
pwd - > pw_uid , pwd - > pw_gid ) ,
2002-11-02 06:47:48 +03:00
PDB_DEFAULT ) ;
2001-12-27 09:38:04 +03:00
2002-07-15 14:35:28 +04:00
pdb_set_dir_drive ( sam_account ,
talloc_sub_specified ( ( sam_account ) - > mem_ctx ,
lp_logon_drive ( ) ,
2002-11-13 02:20:50 +03:00
pwd - > pw_name , global_myname ( ) ,
2002-07-15 14:35:28 +04:00
pwd - > pw_uid , pwd - > pw_gid ) ,
2002-11-02 06:47:48 +03:00
PDB_DEFAULT ) ;
2002-07-15 14:35:28 +04:00
pdb_set_logon_script ( sam_account ,
talloc_sub_specified ( ( sam_account ) - > mem_ctx ,
lp_logon_script ( ) ,
2002-11-13 02:20:50 +03:00
pwd - > pw_name , global_myname ( ) ,
2002-07-15 14:35:28 +04:00
pwd - > pw_uid , pwd - > pw_gid ) ,
2002-11-02 06:47:48 +03:00
PDB_DEFAULT ) ;
if ( ! pdb_set_acct_ctrl ( sam_account , ACB_NORMAL , PDB_DEFAULT ) ) {
2002-09-25 19:19:00 +04:00
DEBUG ( 1 , ( " Failed to set 'normal account' flags for user %s. \n " , pwd - > pw_name ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
} else {
2002-11-02 06:47:48 +03:00
if ( ! pdb_set_acct_ctrl ( sam_account , ACB_WSTRUST , PDB_DEFAULT ) ) {
2002-09-25 19:19:00 +04:00
DEBUG ( 1 , ( " Failed to set 'trusted workstation account' flags for user %s. \n " , pwd - > pw_name ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
2002-07-15 14:35:28 +04:00
}
return NT_STATUS_OK ;
}
This commit is number 2 of 4.
In particular this commit focuses on:
The guts of the moving about inside passdb.
While these changes have been mildly tested, and are pretty small, any
assistance in this is appreciated.
----
These changes allow for the introduction of a large dose of 'const' to
the Samba tree.
There are a number of good reasons to do this:
- I want to allow the SAM_ACCOUNT structure to move from wasteful
pstrings and fstrings to allocated strings. We can't do that if
people are modifying these outputs, as they may well make
assumptions about getting pstrings and fstrings
- I want --with-pam_smbpass to compile with a slightly sane
volume of warnings, currently its pretty bad, even in 2.2
where is compiles at all.
- Tridge assures me that he no longer opposes 'const religion'
based on the ability to #define const the problem away.
- Changed Get_Pwnam(x,y) into two variants (so that the const
parameter can work correctly): - Get_Pwnam(const x) and
Get_Pwnam_Modify(x).
- Reworked smbd/chgpasswd.c to work with these mods, passing
around a 'struct passwd' rather than the modified username
passdb/
- Kill off disp_info stuff, it isn't used any more - Kill off
support for writing to the old smbpasswd format, it isn't relevent
to Samba 3.0
- Move around and modify the pdb_...() helper functions, adding
one that sets the last changed time to 'now' and that sets the
must change time appropriately.
- Remove the ugly forced update of the LCT- value in
pdb_smbpasswd. - Remove the implicit modification of the ACB
flags when both NT and LM passwords are set.
- Removed substation in pdb_getsampwnam output, as a single
password change will render them inoperable in any case (they
will be substituted and stored)
- Added a default RID to the init_sam_from_pw() function, based on
our rid algorithm.
- Added checks that an smbpasswd stored user has a uid-based RID.
- Fail to store tdb based users without a RID
lib/
- Change the substituion code to use global_myname if there is
no connection (and therefore no called name) at the present time.
(This used to be commit 8f607810eb24ed1157bbd2e896c2c167bc34d986)
2001-10-29 10:24:49 +03:00
2002-07-15 14:35:28 +04:00
/*************************************************************
Initialises a struct sam_passwd with sane values .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS pdb_init_sam_pw ( SAM_ACCOUNT * * new_sam_acct , const struct passwd * pwd )
{
NTSTATUS nt_status ;
if ( ! pwd ) {
new_sam_acct = NULL ;
2003-02-24 06:09:08 +03:00
return NT_STATUS_INVALID_PARAMETER ;
2002-07-15 14:35:28 +04:00
}
if ( ! NT_STATUS_IS_OK ( nt_status = pdb_init_sam ( new_sam_acct ) ) ) {
new_sam_acct = NULL ;
return nt_status ;
}
if ( ! NT_STATUS_IS_OK ( nt_status = pdb_fill_sam_pw ( * new_sam_acct , pwd ) ) ) {
pdb_free_sam ( new_sam_acct ) ;
new_sam_acct = NULL ;
return nt_status ;
}
2002-01-15 04:02:13 +03:00
return NT_STATUS_OK ;
1998-05-07 22:19:05 +04:00
}
2001-09-27 13:13:26 +04:00
2003-04-29 13:43:17 +04:00
/*************************************************************
Initialises a SAM_ACCOUNT ready to add a new account , based
2003-07-11 09:33:40 +04:00
on the UNIX user . Pass in a RID if you have one
2003-04-29 13:43:17 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-07-11 09:33:40 +04:00
NTSTATUS pdb_init_sam_new ( SAM_ACCOUNT * * new_sam_acct , const char * username ,
uint32 rid )
2003-04-29 13:43:17 +04:00
{
2003-07-11 09:33:40 +04:00
NTSTATUS nt_status = NT_STATUS_NO_MEMORY ;
struct passwd * pwd ;
BOOL ret ;
2003-04-29 13:43:17 +04:00
pwd = Get_Pwnam ( username ) ;
2003-07-11 09:33:40 +04:00
if ( ! pwd )
return NT_STATUS_NO_SUCH_USER ;
if ( ! NT_STATUS_IS_OK ( nt_status = pdb_init_sam_pw ( new_sam_acct , pwd ) ) ) {
* new_sam_acct = NULL ;
return nt_status ;
2003-04-29 13:43:17 +04:00
}
2003-07-11 09:33:40 +04:00
/* see if we need to generate a new rid using the 2.2 algorithm */
if ( rid = = 0 & & lp_enable_rid_algorithm ( ) ) {
DEBUG ( 10 , ( " pdb_init_sam_new: no RID specified. Generating one via old algorithm \n " ) ) ;
rid = fallback_pdb_uid_to_user_rid ( pwd - > pw_uid ) ;
}
/* set the new SID */
ret = pdb_set_user_sid_from_rid ( * new_sam_acct , rid , PDB_SET ) ;
return ( ret ? NT_STATUS_OK : NT_STATUS_NO_SUCH_USER ) ;
2003-04-29 13:43:17 +04:00
}
2002-01-02 10:41:54 +03:00
/**
* Free the contets of the SAM_ACCOUNT , but not the structure .
*
2003-01-03 11:28:12 +03:00
* Also wipes the LM and NT hashes and plaintext password from
2002-07-15 14:35:28 +04:00
* memory .
2002-01-02 10:41:54 +03:00
*
* @ param user SAM_ACCOUNT to free members of .
* */
2001-09-26 00:21:21 +04:00
2002-01-15 04:02:13 +03:00
static void pdb_free_sam_contents ( SAM_ACCOUNT * user )
1998-05-07 22:19:05 +04:00
{
2002-07-15 14:35:28 +04:00
/* Kill off sensitive data. Free()ed by the
talloc mechinism */
2001-09-27 13:13:26 +04:00
2002-01-02 10:41:54 +03:00
data_blob_clear_free ( & ( user - > private . lm_pw ) ) ;
data_blob_clear_free ( & ( user - > private . nt_pw ) ) ;
2002-09-25 19:19:00 +04:00
if ( user - > private . plaintext_pw ! = NULL )
memset ( user - > private . plaintext_pw , ' \0 ' , strlen ( user - > private . plaintext_pw ) ) ;
2003-07-05 13:46:12 +04:00
if ( user - > private . backend_private_data & & user - > private . backend_private_data_free_fn ) {
user - > private . backend_private_data_free_fn ( & user - > private . backend_private_data ) ;
}
1998-05-07 22:19:05 +04:00
}
2001-09-27 13:13:26 +04:00
2001-05-07 18:04:46 +04:00
/************************************************************
2001-09-27 13:13:26 +04:00
Reset the SAM_ACCOUNT and free the NT / LM hashes .
2001-05-07 18:04:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-01-15 04:02:13 +03:00
NTSTATUS pdb_reset_sam ( SAM_ACCOUNT * user )
2001-05-07 18:04:46 +04:00
{
if ( user = = NULL ) {
DEBUG ( 0 , ( " pdb_reset_sam: SAM_ACCOUNT was NULL \n " ) ) ;
2001-09-29 17:14:19 +04:00
#if 0
smb_panic ( " NULL pointer passed to pdb_free_sam \n " ) ;
# endif
2002-01-15 04:02:13 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2001-05-07 18:04:46 +04:00
}
2002-01-15 04:02:13 +03:00
pdb_free_sam_contents ( user ) ;
2001-09-27 13:13:26 +04:00
2002-01-15 04:02:13 +03:00
pdb_fill_default_sam ( user ) ;
2001-05-07 18:04:46 +04:00
2002-01-15 04:02:13 +03:00
return NT_STATUS_OK ;
2001-05-07 18:04:46 +04:00
}
2000-02-26 01:25:25 +03:00
2001-09-27 13:13:26 +04:00
/************************************************************
2002-01-02 10:41:54 +03:00
Free the SAM_ACCOUNT and the member pointers .
2001-09-27 13:13:26 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-01-15 04:02:13 +03:00
NTSTATUS pdb_free_sam ( SAM_ACCOUNT * * user )
2001-09-27 13:13:26 +04:00
{
2001-09-29 17:14:19 +04:00
if ( * user = = NULL ) {
2001-09-27 13:13:26 +04:00
DEBUG ( 0 , ( " pdb_free_sam: SAM_ACCOUNT was NULL \n " ) ) ;
#if 0
smb_panic ( " NULL pointer passed to pdb_free_sam \n " ) ;
# endif
2002-01-15 04:02:13 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2001-09-27 13:13:26 +04:00
}
2002-01-15 04:02:13 +03:00
pdb_free_sam_contents ( * user ) ;
if ( ( * user ) - > free_fn ) {
( * user ) - > free_fn ( user ) ;
2001-09-27 13:13:26 +04:00
}
2002-01-15 04:02:13 +03:00
return NT_STATUS_OK ;
2001-09-27 13:13:26 +04:00
}
2001-09-26 00:21:21 +04:00
/**********************************************************
Encode the account control bits into a string .
length = length of string to encode into ( including terminating
null ) . length * MUST BE MORE THAN 2 * !
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
char * pdb_encode_acct_ctrl ( uint16 acct_ctrl , size_t length )
{
static fstring acct_str ;
2004-02-08 14:02:11 +03:00
2001-09-26 00:21:21 +04:00
size_t i = 0 ;
2004-02-09 18:21:42 +03:00
SMB_ASSERT ( length < = sizeof ( acct_str ) ) ;
2001-09-26 00:21:21 +04:00
acct_str [ i + + ] = ' [ ' ;
if ( acct_ctrl & ACB_PWNOTREQ ) acct_str [ i + + ] = ' N ' ;
if ( acct_ctrl & ACB_DISABLED ) acct_str [ i + + ] = ' D ' ;
if ( acct_ctrl & ACB_HOMDIRREQ ) acct_str [ i + + ] = ' H ' ;
if ( acct_ctrl & ACB_TEMPDUP ) acct_str [ i + + ] = ' T ' ;
if ( acct_ctrl & ACB_NORMAL ) acct_str [ i + + ] = ' U ' ;
if ( acct_ctrl & ACB_MNS ) acct_str [ i + + ] = ' M ' ;
if ( acct_ctrl & ACB_WSTRUST ) acct_str [ i + + ] = ' W ' ;
if ( acct_ctrl & ACB_SVRTRUST ) acct_str [ i + + ] = ' S ' ;
if ( acct_ctrl & ACB_AUTOLOCK ) acct_str [ i + + ] = ' L ' ;
if ( acct_ctrl & ACB_PWNOEXP ) acct_str [ i + + ] = ' X ' ;
if ( acct_ctrl & ACB_DOMTRUST ) acct_str [ i + + ] = ' I ' ;
for ( ; i < length - 2 ; i + + )
acct_str [ i ] = ' ' ;
i = length - 2 ;
acct_str [ i + + ] = ' ] ' ;
acct_str [ i + + ] = ' \0 ' ;
return acct_str ;
}
/**********************************************************
Decode the account control bits from a string .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint16 pdb_decode_acct_ctrl ( const char * p )
{
uint16 acct_ctrl = 0 ;
BOOL finished = False ;
/*
* Check if the account type bits have been encoded after the
* NT password ( in the form [ NDHTUWSLXI ] ) .
*/
if ( * p ! = ' [ ' )
return 0 ;
for ( p + + ; * p & & ! finished ; p + + ) {
switch ( * p ) {
case ' N ' : { acct_ctrl | = ACB_PWNOTREQ ; break ; /* 'N'o password. */ }
case ' D ' : { acct_ctrl | = ACB_DISABLED ; break ; /* 'D'isabled. */ }
case ' H ' : { acct_ctrl | = ACB_HOMDIRREQ ; break ; /* 'H'omedir required. */ }
case ' T ' : { acct_ctrl | = ACB_TEMPDUP ; break ; /* 'T'emp account. */ }
case ' U ' : { acct_ctrl | = ACB_NORMAL ; break ; /* 'U'ser account (normal). */ }
case ' M ' : { acct_ctrl | = ACB_MNS ; break ; /* 'M'NS logon user account. What is this ? */ }
case ' W ' : { acct_ctrl | = ACB_WSTRUST ; break ; /* 'W'orkstation account. */ }
case ' S ' : { acct_ctrl | = ACB_SVRTRUST ; break ; /* 'S'erver account. */ }
case ' L ' : { acct_ctrl | = ACB_AUTOLOCK ; break ; /* 'L'ocked account. */ }
case ' X ' : { acct_ctrl | = ACB_PWNOEXP ; break ; /* No 'X'piry on password */ }
case ' I ' : { acct_ctrl | = ACB_DOMTRUST ; break ; /* 'I'nterdomain trust account. */ }
case ' ' : { break ; }
case ' : ' :
case ' \n ' :
case ' \0 ' :
case ' ] ' :
default : { finished = True ; }
}
}
return acct_ctrl ;
}
/*************************************************************
Routine to set 32 hex password characters from a 16 byte array .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
This commit is number 4 of 4.
In particular this commit focuses on:
Actually adding the 'const' to the passdb interface, and the flow-on changes.
Also kill off the 'disp_info' stuff, as its no longer used.
While these changes have been mildly tested, and are pretty small, any
assistance in this is appreciated.
----
These changes introduces a large dose of 'const' to the Samba tree.
There are a number of good reasons to do this:
- I want to allow the SAM_ACCOUNT structure to move from wasteful
pstrings and fstrings to allocated strings. We can't do that if
people are modifying these outputs, as they may well make
assumptions about getting pstrings and fstrings
- I want --with-pam_smbpass to compile with a slightly sane
volume of warnings, currently its pretty bad, even in 2.2
where is compiles at all.
- Tridge assures me that he no longer opposes 'const religion'
based on the ability to #define const the problem away.
- Changed Get_Pwnam(x,y) into two variants (so that the const
parameter can work correctly): - Get_Pwnam(const x) and
Get_Pwnam_Modify(x).
- Reworked smbd/chgpasswd.c to work with these mods, passing
around a 'struct passwd' rather than the modified username
---
This finishes this line of commits off, your tree should now compile again :-)
Andrew Bartlett
(This used to be commit c95f5aeb9327347674589ae313b75bee3bf8e317)
2001-10-29 10:35:11 +03:00
void pdb_sethexpwd ( char * p , const unsigned char * pwd , uint16 acct_ctrl )
2001-09-26 00:21:21 +04:00
{
if ( pwd ! = NULL ) {
int i ;
for ( i = 0 ; i < 16 ; i + + )
slprintf ( & p [ i * 2 ] , 3 , " %02X " , pwd [ i ] ) ;
} else {
if ( acct_ctrl & ACB_PWNOTREQ )
safe_strcpy ( p , " NO PASSWORDXXXXXXXXXXXXXXXXXXXXX " , 33 ) ;
else
safe_strcpy ( p , " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX " , 33 ) ;
}
}
/*************************************************************
Routine to get the 32 hex characters and turn them
into a 16 byte array .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
This commit is number 4 of 4.
In particular this commit focuses on:
Actually adding the 'const' to the passdb interface, and the flow-on changes.
Also kill off the 'disp_info' stuff, as its no longer used.
While these changes have been mildly tested, and are pretty small, any
assistance in this is appreciated.
----
These changes introduces a large dose of 'const' to the Samba tree.
There are a number of good reasons to do this:
- I want to allow the SAM_ACCOUNT structure to move from wasteful
pstrings and fstrings to allocated strings. We can't do that if
people are modifying these outputs, as they may well make
assumptions about getting pstrings and fstrings
- I want --with-pam_smbpass to compile with a slightly sane
volume of warnings, currently its pretty bad, even in 2.2
where is compiles at all.
- Tridge assures me that he no longer opposes 'const religion'
based on the ability to #define const the problem away.
- Changed Get_Pwnam(x,y) into two variants (so that the const
parameter can work correctly): - Get_Pwnam(const x) and
Get_Pwnam_Modify(x).
- Reworked smbd/chgpasswd.c to work with these mods, passing
around a 'struct passwd' rather than the modified username
---
This finishes this line of commits off, your tree should now compile again :-)
Andrew Bartlett
(This used to be commit c95f5aeb9327347674589ae313b75bee3bf8e317)
2001-10-29 10:35:11 +03:00
BOOL pdb_gethexpwd ( const char * p , unsigned char * pwd )
2001-09-26 00:21:21 +04:00
{
int i ;
unsigned char lonybble , hinybble ;
2003-01-03 11:28:12 +03:00
const char * hexchars = " 0123456789ABCDEF " ;
2001-09-26 00:21:21 +04:00
char * p1 , * p2 ;
if ( ! p )
return ( False ) ;
for ( i = 0 ; i < 32 ; i + = 2 ) {
hinybble = toupper ( p [ i ] ) ;
lonybble = toupper ( p [ i + 1 ] ) ;
p1 = strchr ( hexchars , hinybble ) ;
p2 = strchr ( hexchars , lonybble ) ;
if ( ! p1 | | ! p2 )
return ( False ) ;
hinybble = PTR_DIFF ( p1 , hexchars ) ;
lonybble = PTR_DIFF ( p2 , hexchars ) ;
pwd [ i / 2 ] = ( hinybble < < 4 ) | lonybble ;
}
return ( True ) ;
}
This patch cleans up some of our ldap code, for better behaviour:
We now always read the Domain SID out of LDAP. If the local secrets.tdb
is ever different to LDAP, it is overwritten out of LDAP. We also
store the 'algorithmic rid base' into LDAP, and assert if it changes.
(This ensures cross-host synchronisation, and allows for possible
integration with idmap). If we fail to read/add the domain entry, we just
fallback to the old behaviour.
We always use an existing DN when adding IDMAP entries to LDAP, unless
no suitable entry is available. This means that a user's posixAccount
will have a SID added to it, or a user's sambaSamAccount will have a UID
added. Where we cannot us an existing DN, we use
'sambaSid=S-x-y-z,....' as the DN.
The code now allows modifications to the ID mapping in many cases.
Likewise, we now check more carefully when adding new user entires to LDAP,
to not duplicate SIDs (for users, at this stage), and to add the sambaSamAccount
onto the idmap entry for that user, if it is already established (ensuring
we do not duplicate sambaSid entries in the directory).
The allocated UID code has been expanded to take into account the space
between '1000 - algorithmic rid base'. This much better fits into what
an NT4 does - allocating in the bottom part of the RID range.
On the code cleanup side of things, we now share as much code as
possible between idmap_ldap and pdb_ldap.
We also no longer use the race-prone 'enumerate all users' method for
finding the next RID to allocate. Instead, we just start at the bottom
of the range, and increment again if the user already exists. The first
time this is run, it may well take a long time, but next time will just
be able to use the next Rid.
Thanks to metze and AB for double-checking parts of this.
Andrew Bartlett
(This used to be commit 9c595c8c2327b92a86901d84c3f2c284dabd597e)
2003-07-04 17:29:42 +04:00
int algorithmic_rid_base ( void )
2002-11-05 10:20:27 +03:00
{
static int rid_offset = 0 ;
if ( rid_offset ! = 0 )
return rid_offset ;
rid_offset = lp_algorithmic_rid_base ( ) ;
if ( rid_offset < BASE_RID ) {
/* Try to prevent admin foot-shooting, we can't put algorithmic
rids below 1000 , that ' s the ' well known RIDs ' on NT */
DEBUG ( 0 , ( " 'algorithmic rid base' must be equal to or above %ld \n " , BASE_RID ) ) ;
rid_offset = BASE_RID ;
}
if ( rid_offset & 1 ) {
DEBUG ( 0 , ( " algorithmic rid base must be even \n " ) ) ;
rid_offset + = 1 ;
}
return rid_offset ;
}
2003-05-12 22:12:31 +04:00
/*******************************************************************
Converts NT user RID to a UNIX uid .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-05 10:20:27 +03:00
2002-07-15 14:35:28 +04:00
uid_t fallback_pdb_user_rid_to_uid ( uint32 user_rid )
1999-12-13 16:27:58 +03:00
{
2002-11-05 10:20:27 +03:00
int rid_offset = algorithmic_rid_base ( ) ;
2003-05-12 22:12:31 +04:00
return ( uid_t ) ( ( ( user_rid & ( ~ USER_RID_TYPE ) ) - rid_offset ) / RID_MULTIPLIER ) ;
1999-12-13 16:27:58 +03:00
}
This commit is number 4 of 4.
In particular this commit focuses on:
Actually adding the 'const' to the passdb interface, and the flow-on changes.
Also kill off the 'disp_info' stuff, as its no longer used.
While these changes have been mildly tested, and are pretty small, any
assistance in this is appreciated.
----
These changes introduces a large dose of 'const' to the Samba tree.
There are a number of good reasons to do this:
- I want to allow the SAM_ACCOUNT structure to move from wasteful
pstrings and fstrings to allocated strings. We can't do that if
people are modifying these outputs, as they may well make
assumptions about getting pstrings and fstrings
- I want --with-pam_smbpass to compile with a slightly sane
volume of warnings, currently its pretty bad, even in 2.2
where is compiles at all.
- Tridge assures me that he no longer opposes 'const religion'
based on the ability to #define const the problem away.
- Changed Get_Pwnam(x,y) into two variants (so that the const
parameter can work correctly): - Get_Pwnam(const x) and
Get_Pwnam_Modify(x).
- Reworked smbd/chgpasswd.c to work with these mods, passing
around a 'struct passwd' rather than the modified username
---
This finishes this line of commits off, your tree should now compile again :-)
Andrew Bartlett
(This used to be commit c95f5aeb9327347674589ae313b75bee3bf8e317)
2001-10-29 10:35:11 +03:00
/*******************************************************************
2002-03-18 14:35:53 +03:00
converts UNIX uid to an NT User RID .
This commit is number 4 of 4.
In particular this commit focuses on:
Actually adding the 'const' to the passdb interface, and the flow-on changes.
Also kill off the 'disp_info' stuff, as its no longer used.
While these changes have been mildly tested, and are pretty small, any
assistance in this is appreciated.
----
These changes introduces a large dose of 'const' to the Samba tree.
There are a number of good reasons to do this:
- I want to allow the SAM_ACCOUNT structure to move from wasteful
pstrings and fstrings to allocated strings. We can't do that if
people are modifying these outputs, as they may well make
assumptions about getting pstrings and fstrings
- I want --with-pam_smbpass to compile with a slightly sane
volume of warnings, currently its pretty bad, even in 2.2
where is compiles at all.
- Tridge assures me that he no longer opposes 'const religion'
based on the ability to #define const the problem away.
- Changed Get_Pwnam(x,y) into two variants (so that the const
parameter can work correctly): - Get_Pwnam(const x) and
Get_Pwnam_Modify(x).
- Reworked smbd/chgpasswd.c to work with these mods, passing
around a 'struct passwd' rather than the modified username
---
This finishes this line of commits off, your tree should now compile again :-)
Andrew Bartlett
(This used to be commit c95f5aeb9327347674589ae313b75bee3bf8e317)
2001-10-29 10:35:11 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-15 14:35:28 +04:00
uint32 fallback_pdb_uid_to_user_rid ( uid_t uid )
This commit is number 4 of 4.
In particular this commit focuses on:
Actually adding the 'const' to the passdb interface, and the flow-on changes.
Also kill off the 'disp_info' stuff, as its no longer used.
While these changes have been mildly tested, and are pretty small, any
assistance in this is appreciated.
----
These changes introduces a large dose of 'const' to the Samba tree.
There are a number of good reasons to do this:
- I want to allow the SAM_ACCOUNT structure to move from wasteful
pstrings and fstrings to allocated strings. We can't do that if
people are modifying these outputs, as they may well make
assumptions about getting pstrings and fstrings
- I want --with-pam_smbpass to compile with a slightly sane
volume of warnings, currently its pretty bad, even in 2.2
where is compiles at all.
- Tridge assures me that he no longer opposes 'const religion'
based on the ability to #define const the problem away.
- Changed Get_Pwnam(x,y) into two variants (so that the const
parameter can work correctly): - Get_Pwnam(const x) and
Get_Pwnam_Modify(x).
- Reworked smbd/chgpasswd.c to work with these mods, passing
around a 'struct passwd' rather than the modified username
---
This finishes this line of commits off, your tree should now compile again :-)
Andrew Bartlett
(This used to be commit c95f5aeb9327347674589ae313b75bee3bf8e317)
2001-10-29 10:35:11 +03:00
{
2002-11-05 10:20:27 +03:00
int rid_offset = algorithmic_rid_base ( ) ;
2002-07-15 14:35:28 +04:00
return ( ( ( ( ( uint32 ) uid ) * RID_MULTIPLIER ) + rid_offset ) | USER_RID_TYPE ) ;
This commit is number 4 of 4.
In particular this commit focuses on:
Actually adding the 'const' to the passdb interface, and the flow-on changes.
Also kill off the 'disp_info' stuff, as its no longer used.
While these changes have been mildly tested, and are pretty small, any
assistance in this is appreciated.
----
These changes introduces a large dose of 'const' to the Samba tree.
There are a number of good reasons to do this:
- I want to allow the SAM_ACCOUNT structure to move from wasteful
pstrings and fstrings to allocated strings. We can't do that if
people are modifying these outputs, as they may well make
assumptions about getting pstrings and fstrings
- I want --with-pam_smbpass to compile with a slightly sane
volume of warnings, currently its pretty bad, even in 2.2
where is compiles at all.
- Tridge assures me that he no longer opposes 'const religion'
based on the ability to #define const the problem away.
- Changed Get_Pwnam(x,y) into two variants (so that the const
parameter can work correctly): - Get_Pwnam(const x) and
Get_Pwnam_Modify(x).
- Reworked smbd/chgpasswd.c to work with these mods, passing
around a 'struct passwd' rather than the modified username
---
This finishes this line of commits off, your tree should now compile again :-)
Andrew Bartlett
(This used to be commit c95f5aeb9327347674589ae313b75bee3bf8e317)
2001-10-29 10:35:11 +03:00
}
2000-11-14 02:03:34 +03:00
/*******************************************************************
2002-03-18 14:35:53 +03:00
Converts NT group RID to a UNIX gid .
2000-11-14 02:03:34 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
2002-03-18 14:35:53 +03:00
gid_t pdb_group_rid_to_gid ( uint32 group_rid )
1999-12-13 16:27:58 +03:00
{
2002-11-05 10:20:27 +03:00
int rid_offset = algorithmic_rid_base ( ) ;
2002-07-15 14:35:28 +04:00
return ( gid_t ) ( ( ( group_rid & ( ~ GROUP_RID_TYPE ) ) - rid_offset ) / RID_MULTIPLIER ) ;
1999-12-13 16:27:58 +03:00
}
2000-11-14 02:03:34 +03:00
/*******************************************************************
converts NT Group RID to a UNIX uid .
2001-12-02 03:03:35 +03:00
warning : you must not call that function only
you must do a call to the group mapping first .
there is not anymore a direct link between the gid and the rid .
2000-11-14 02:03:34 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-10-07 19:56:36 +04:00
2000-11-14 02:03:34 +03:00
uint32 pdb_gid_to_group_rid ( gid_t gid )
2000-10-07 19:56:36 +04:00
{
2002-11-05 10:20:27 +03:00
int rid_offset = algorithmic_rid_base ( ) ;
2002-07-15 14:35:28 +04:00
return ( ( ( ( ( uint32 ) gid ) * RID_MULTIPLIER ) + rid_offset ) | GROUP_RID_TYPE ) ;
2000-10-07 19:56:36 +04:00
}
2000-11-14 02:03:34 +03:00
/*******************************************************************
Decides if a RID is a well known RID .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL pdb_rid_is_well_known ( uint32 rid )
2000-10-07 19:56:36 +04:00
{
2003-05-14 04:46:43 +04:00
/* Not using rid_offset here, because this is the actual
2002-07-15 14:35:28 +04:00
NT fixed value ( 1000 ) */
return ( rid < BASE_RID ) ;
2000-10-07 19:56:36 +04:00
}
1999-12-13 16:27:58 +03:00
2000-11-14 02:03:34 +03:00
/*******************************************************************
Decides if a RID is a user or group RID .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-09-26 00:21:21 +04:00
2003-05-12 22:12:31 +04:00
BOOL fallback_pdb_rid_is_user ( uint32 rid )
2000-11-14 02:03:34 +03:00
{
/* lkcl i understand that NT attaches an enumeration to a RID
* such that it can be identified as either a user , group etc
* type . there are 5 such categories , and they are documented .
*/
2002-08-17 21:00:51 +04:00
/* However, they are not in the RID, just somthing you can query
seperatly . Sorry luke : - ) */
2000-11-14 02:03:34 +03:00
if ( pdb_rid_is_well_known ( rid ) ) {
/*
* The only well known user RIDs are DOMAIN_USER_RID_ADMIN
* and DOMAIN_USER_RID_GUEST .
*/
if ( rid = = DOMAIN_USER_RID_ADMIN | | rid = = DOMAIN_USER_RID_GUEST )
return True ;
} else if ( ( rid & RID_TYPE_MASK ) = = USER_RID_TYPE ) {
return True ;
}
return False ;
}
/*******************************************************************
Convert a rid into a name . Used in the lookup SID rpc .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-09-26 00:21:21 +04:00
2004-03-31 19:21:48 +04:00
BOOL local_lookup_sid ( const DOM_SID * sid , char * name , enum SID_NAME_USE * psid_name_use )
2000-11-14 02:03:34 +03:00
{
2001-12-05 00:53:47 +03:00
uint32 rid ;
2002-01-26 15:24:18 +03:00
SAM_ACCOUNT * sam_account = NULL ;
2002-04-12 14:18:46 +04:00
GROUP_MAP map ;
2003-12-10 19:40:17 +03:00
BOOL ret ;
1999-12-13 16:27:58 +03:00
2002-07-15 14:35:28 +04:00
if ( ! sid_peek_check_rid ( get_global_sam_sid ( ) , sid , & rid ) ) {
2003-05-12 22:12:31 +04:00
DEBUG ( 0 , ( " local_lookup_sid: sid_peek_check_rid return False! SID: %s \n " ,
2002-07-15 14:35:28 +04:00
sid_string_static ( & map . sid ) ) ) ;
return False ;
}
2001-10-10 00:54:56 +04:00
* psid_name_use = SID_NAME_UNKNOWN ;
2002-04-12 14:18:46 +04:00
DEBUG ( 5 , ( " local_lookup_sid: looking up RID %u. \n " , ( unsigned int ) rid ) ) ;
if ( rid = = DOMAIN_USER_RID_ADMIN ) {
2002-11-13 02:20:50 +03:00
const char * * admin_list = lp_admin_users ( - 1 ) ;
2002-04-12 14:18:46 +04:00
* psid_name_use = SID_NAME_USER ;
if ( admin_list ) {
2002-11-13 02:20:50 +03:00
const char * p = * admin_list ;
2000-11-14 02:03:34 +03:00
if ( ! next_token ( & p , name , NULL , sizeof ( fstring ) ) )
2002-04-12 14:18:46 +04:00
fstrcpy ( name , " Administrator " ) ;
2000-11-14 02:03:34 +03:00
} else {
2002-04-12 14:18:46 +04:00
fstrcpy ( name , " Administrator " ) ;
}
return True ;
}
if ( ! NT_STATUS_IS_OK ( pdb_init_sam ( & sam_account ) ) ) {
return False ;
}
2003-04-23 03:14:49 +04:00
/* see if the passdb can help us with the name of the user */
2003-07-09 04:20:43 +04:00
2003-12-10 19:40:17 +03:00
/* BEING ROOT BLLOCK */
2003-07-09 04:20:43 +04:00
become_root ( ) ;
2002-07-15 14:35:28 +04:00
if ( pdb_getsampwsid ( sam_account , sid ) ) {
2003-12-10 19:40:17 +03:00
unbecome_root ( ) ; /* -----> EXIT BECOME_ROOT() */
2002-04-12 14:18:46 +04:00
fstrcpy ( name , pdb_get_username ( sam_account ) ) ;
* psid_name_use = SID_NAME_USER ;
pdb_free_sam ( & sam_account ) ;
2002-01-26 15:24:18 +03:00
2002-04-12 14:18:46 +04:00
return True ;
}
pdb_free_sam ( & sam_account ) ;
2003-12-10 19:40:17 +03:00
ret = pdb_getgrsid ( & map , * sid ) ;
unbecome_root ( ) ;
/* END BECOME_ROOT BLOCK */
if ( ret ) {
2003-02-24 06:09:08 +03:00
if ( map . gid ! = ( gid_t ) - 1 ) {
2002-04-12 14:18:46 +04:00
DEBUG ( 5 , ( " local_lookup_sid: mapped group %s to gid %u \n " , map . nt_name , ( unsigned int ) map . gid ) ) ;
2002-07-15 14:35:28 +04:00
} else {
DEBUG ( 5 , ( " local_lookup_sid: mapped group %s to no unix gid. Returning name. \n " , map . nt_name ) ) ;
2002-04-12 14:18:46 +04:00
}
2002-07-15 14:35:28 +04:00
fstrcpy ( name , map . nt_name ) ;
* psid_name_use = map . sid_name_use ;
return True ;
}
2002-04-12 14:18:46 +04:00
2003-05-12 22:12:31 +04:00
if ( fallback_pdb_rid_is_user ( rid ) ) {
2002-07-15 14:35:28 +04:00
uid_t uid ;
2003-08-06 03:24:14 +04:00
struct passwd * pw = NULL ;
2002-07-15 14:35:28 +04:00
DEBUG ( 5 , ( " assuming RID %u is a user \n " , ( unsigned ) rid ) ) ;
uid = fallback_pdb_user_rid_to_uid ( rid ) ;
2003-08-06 03:24:14 +04:00
pw = sys_getpwuid ( uid ) ;
DEBUG ( 5 , ( " local_lookup_sid: looking up uid %u %s \n " , ( unsigned int ) uid ,
pw ? " succeeded " : " failed " ) ) ;
if ( ! pw )
2003-08-06 04:06:37 +04:00
fstr_sprintf ( name , " unix_user.%u " , ( unsigned int ) uid ) ;
2003-08-06 03:24:14 +04:00
else
fstrcpy ( name , pw - > pw_name ) ;
DEBUG ( 5 , ( " local_lookup_sid: found user %s for rid %u \n " , name ,
( unsigned int ) rid ) ) ;
2003-08-22 01:05:01 +04:00
* psid_name_use = SID_NAME_USER ;
2003-08-06 03:24:14 +04:00
return ( pw ! = NULL ) ;
2000-11-14 02:03:34 +03:00
} else {
2001-09-26 00:21:21 +04:00
gid_t gid ;
2001-01-10 19:05:41 +03:00
struct group * gr ;
2002-04-12 14:18:46 +04:00
2002-07-15 14:35:28 +04:00
DEBUG ( 5 , ( " assuming RID %u is a group \n " , ( unsigned ) rid ) ) ;
2001-12-02 03:03:35 +03:00
gid = pdb_group_rid_to_gid ( rid ) ;
2001-05-04 19:44:27 +04:00
gr = getgrgid ( gid ) ;
2002-04-12 14:18:46 +04:00
2001-09-26 00:21:21 +04:00
* psid_name_use = SID_NAME_ALIAS ;
2002-04-12 14:18:46 +04:00
2001-12-05 00:53:47 +03:00
DEBUG ( 5 , ( " local_lookup_sid: looking up gid %u %s \n " , ( unsigned int ) gid ,
2002-04-12 14:18:46 +04:00
gr ? " succeeded " : " failed " ) ) ;
2003-08-06 03:24:14 +04:00
if ( ! gr )
2003-08-06 04:06:37 +04:00
fstr_sprintf ( name , " unix_group.%u " , ( unsigned int ) gid ) ;
2003-08-06 03:24:14 +04:00
else
fstrcpy ( name , gr - > gr_name ) ;
2002-04-12 14:18:46 +04:00
2001-12-05 00:53:47 +03:00
DEBUG ( 5 , ( " local_lookup_sid: found group %s for rid %u \n " , name ,
2002-04-12 14:18:46 +04:00
( unsigned int ) rid ) ) ;
2003-08-22 01:05:01 +04:00
/* assume fallback groups aer domain global groups */
* psid_name_use = SID_NAME_DOM_GRP ;
2003-08-06 03:24:14 +04:00
return ( gr ! = NULL ) ;
2000-11-14 02:03:34 +03:00
}
1998-05-18 19:50:56 +04:00
}
2000-11-14 02:03:34 +03:00
/*******************************************************************
Convert a name into a SID . Used in the lookup name rpc .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
2002-01-26 12:56:47 +03:00
BOOL local_lookup_name ( const char * c_user , DOM_SID * psid , enum SID_NAME_USE * psid_name_use )
1998-05-18 18:43:06 +04:00
{
2000-11-14 02:03:34 +03:00
DOM_SID local_sid ;
2004-05-20 22:28:21 +04:00
DOM_SID sid ;
2001-03-21 02:07:36 +03:00
fstring user ;
This is another *BIG* change...
Samba now features a pluggable passdb interface, along the same lines as the
one in use in the auth subsystem. In this case, only one backend may be active
at a time by the 'normal' interface, and only one backend per passdb_context is
permitted outside that.
This pluggable interface is designed to allow any number of passdb backends to
be compiled in, with the selection at runtime. The 'passdb backend' paramater
has been created (and documented!) to support this.
As such, configure has been modfied to allow (for example) --with-ldap and the
old smbpasswd to be selected at the same time.
This patch also introduces two new backends: smbpasswd_nua and tdbsam_nua.
These two backends accept 'non unix accounts', where the user does *not* exist
in /etc/passwd. These accounts' don't have UIDs in the unix sense, but to
avoid conflicts in the algroitmic mapping of RIDs, they use the values
specified in the 'non unix account range' paramter - in the same way as the
winbind ranges are specifed.
While I was at it, I cleaned up some of the code in pdb_tdb (code copied
directly from smbpasswd and not really considered properly). Most of this was
to do with % macro expansion on stored data. It isn't easy to get the macros
into the tdb, and the first password change will 'expand' them. tdbsam needs
to use a similar system to pdb_ldap in this regard.
This patch only makes minor adjustments to pdb_nisplus and pdb_ldap, becouse I
don't have the test facilities for these. I plan to incoroprate at least
pdb_ldap into this scheme after consultation with Jerry.
Each (converted) passdb module now no longer has any 'static' variables, and
only exports 1 init function outside its .c file.
The non-unix-account support in this patch has been proven! It is now possible
to join a win2k machine to a Samba PDC without an account in /etc/passwd!
Other changes:
Minor interface adjustments:
pdb_delete_sam_account() now takes a SAM_ACCOUNT, not a char*.
pdb_update_sam_account() no longer takes the 'override' argument that was being
ignored so often (every other passdb backend). Extra checks have been added in
some places.
Minor code changes:
smbpasswd no longer attempts to initialise the passdb at startup, this is
now done on first use.
pdbedit has lost some of its 'machine account' logic, as this behaviour is now
controlled by the passdb subsystem directly.
The samr subsystem no longer calls 'local password change', but does the pdb
interactions directly. This allow the ACB_ flags specifed to be transferred
direct to the backend, without interference.
Doco:
I've updated the doco to reflect some of the changes, and removed some paramters
no longer applicable to HEAD.
(This used to be commit ff354c99c585068af6dc1ff35a1f109a806b326b)
2002-01-20 17:30:58 +03:00
SAM_ACCOUNT * sam_account = NULL ;
2002-07-15 14:35:28 +04:00
struct group * grp ;
GROUP_MAP map ;
2004-05-20 22:28:21 +04:00
2001-10-10 00:54:56 +04:00
* psid_name_use = SID_NAME_UNKNOWN ;
2001-03-21 02:07:36 +03:00
/*
2002-01-26 12:56:47 +03:00
* user may be quoted a const string , and map_username and
* friends can modify it . Make a modifiable copy . JRA .
2001-03-21 02:07:36 +03:00
*/
fstrcpy ( user , c_user ) ;
2000-11-14 02:03:34 +03:00
2002-07-15 14:35:28 +04:00
sid_copy ( & local_sid , get_global_sam_sid ( ) ) ;
2000-11-14 02:03:34 +03:00
2004-05-20 22:28:21 +04:00
if ( map_name_to_wellknown_sid ( & sid , psid_name_use , user ) ) {
fstring sid_str ;
sid_copy ( psid , & sid ) ;
sid_to_string ( sid_str , & sid ) ;
DEBUG ( 10 , ( " lookup_name: name %s = SID %s, type = %u \n " , user , sid_str ,
( unsigned int ) * psid_name_use ) ) ;
2000-11-14 02:03:34 +03:00
return True ;
}
( void ) map_username ( user ) ;
This is another *BIG* change...
Samba now features a pluggable passdb interface, along the same lines as the
one in use in the auth subsystem. In this case, only one backend may be active
at a time by the 'normal' interface, and only one backend per passdb_context is
permitted outside that.
This pluggable interface is designed to allow any number of passdb backends to
be compiled in, with the selection at runtime. The 'passdb backend' paramater
has been created (and documented!) to support this.
As such, configure has been modfied to allow (for example) --with-ldap and the
old smbpasswd to be selected at the same time.
This patch also introduces two new backends: smbpasswd_nua and tdbsam_nua.
These two backends accept 'non unix accounts', where the user does *not* exist
in /etc/passwd. These accounts' don't have UIDs in the unix sense, but to
avoid conflicts in the algroitmic mapping of RIDs, they use the values
specified in the 'non unix account range' paramter - in the same way as the
winbind ranges are specifed.
While I was at it, I cleaned up some of the code in pdb_tdb (code copied
directly from smbpasswd and not really considered properly). Most of this was
to do with % macro expansion on stored data. It isn't easy to get the macros
into the tdb, and the first password change will 'expand' them. tdbsam needs
to use a similar system to pdb_ldap in this regard.
This patch only makes minor adjustments to pdb_nisplus and pdb_ldap, becouse I
don't have the test facilities for these. I plan to incoroprate at least
pdb_ldap into this scheme after consultation with Jerry.
Each (converted) passdb module now no longer has any 'static' variables, and
only exports 1 init function outside its .c file.
The non-unix-account support in this patch has been proven! It is now possible
to join a win2k machine to a Samba PDC without an account in /etc/passwd!
Other changes:
Minor interface adjustments:
pdb_delete_sam_account() now takes a SAM_ACCOUNT, not a char*.
pdb_update_sam_account() no longer takes the 'override' argument that was being
ignored so often (every other passdb backend). Extra checks have been added in
some places.
Minor code changes:
smbpasswd no longer attempts to initialise the passdb at startup, this is
now done on first use.
pdbedit has lost some of its 'machine account' logic, as this behaviour is now
controlled by the passdb subsystem directly.
The samr subsystem no longer calls 'local password change', but does the pdb
interactions directly. This allow the ACB_ flags specifed to be transferred
direct to the backend, without interference.
Doco:
I've updated the doco to reflect some of the changes, and removed some paramters
no longer applicable to HEAD.
(This used to be commit ff354c99c585068af6dc1ff35a1f109a806b326b)
2002-01-20 17:30:58 +03:00
if ( ! NT_STATUS_IS_OK ( pdb_init_sam ( & sam_account ) ) ) {
return False ;
}
2003-11-24 20:31:38 +03:00
/* BEGIN ROOT BLOCK */
2003-07-09 04:20:43 +04:00
become_root ( ) ;
This is another *BIG* change...
Samba now features a pluggable passdb interface, along the same lines as the
one in use in the auth subsystem. In this case, only one backend may be active
at a time by the 'normal' interface, and only one backend per passdb_context is
permitted outside that.
This pluggable interface is designed to allow any number of passdb backends to
be compiled in, with the selection at runtime. The 'passdb backend' paramater
has been created (and documented!) to support this.
As such, configure has been modfied to allow (for example) --with-ldap and the
old smbpasswd to be selected at the same time.
This patch also introduces two new backends: smbpasswd_nua and tdbsam_nua.
These two backends accept 'non unix accounts', where the user does *not* exist
in /etc/passwd. These accounts' don't have UIDs in the unix sense, but to
avoid conflicts in the algroitmic mapping of RIDs, they use the values
specified in the 'non unix account range' paramter - in the same way as the
winbind ranges are specifed.
While I was at it, I cleaned up some of the code in pdb_tdb (code copied
directly from smbpasswd and not really considered properly). Most of this was
to do with % macro expansion on stored data. It isn't easy to get the macros
into the tdb, and the first password change will 'expand' them. tdbsam needs
to use a similar system to pdb_ldap in this regard.
This patch only makes minor adjustments to pdb_nisplus and pdb_ldap, becouse I
don't have the test facilities for these. I plan to incoroprate at least
pdb_ldap into this scheme after consultation with Jerry.
Each (converted) passdb module now no longer has any 'static' variables, and
only exports 1 init function outside its .c file.
The non-unix-account support in this patch has been proven! It is now possible
to join a win2k machine to a Samba PDC without an account in /etc/passwd!
Other changes:
Minor interface adjustments:
pdb_delete_sam_account() now takes a SAM_ACCOUNT, not a char*.
pdb_update_sam_account() no longer takes the 'override' argument that was being
ignored so often (every other passdb backend). Extra checks have been added in
some places.
Minor code changes:
smbpasswd no longer attempts to initialise the passdb at startup, this is
now done on first use.
pdbedit has lost some of its 'machine account' logic, as this behaviour is now
controlled by the passdb subsystem directly.
The samr subsystem no longer calls 'local password change', but does the pdb
interactions directly. This allow the ACB_ flags specifed to be transferred
direct to the backend, without interference.
Doco:
I've updated the doco to reflect some of the changes, and removed some paramters
no longer applicable to HEAD.
(This used to be commit ff354c99c585068af6dc1ff35a1f109a806b326b)
2002-01-20 17:30:58 +03:00
if ( pdb_getsampwnam ( sam_account , user ) ) {
2003-07-09 04:20:43 +04:00
unbecome_root ( ) ;
2002-07-15 14:35:28 +04:00
sid_copy ( psid , pdb_get_user_sid ( sam_account ) ) ;
This is another *BIG* change...
Samba now features a pluggable passdb interface, along the same lines as the
one in use in the auth subsystem. In this case, only one backend may be active
at a time by the 'normal' interface, and only one backend per passdb_context is
permitted outside that.
This pluggable interface is designed to allow any number of passdb backends to
be compiled in, with the selection at runtime. The 'passdb backend' paramater
has been created (and documented!) to support this.
As such, configure has been modfied to allow (for example) --with-ldap and the
old smbpasswd to be selected at the same time.
This patch also introduces two new backends: smbpasswd_nua and tdbsam_nua.
These two backends accept 'non unix accounts', where the user does *not* exist
in /etc/passwd. These accounts' don't have UIDs in the unix sense, but to
avoid conflicts in the algroitmic mapping of RIDs, they use the values
specified in the 'non unix account range' paramter - in the same way as the
winbind ranges are specifed.
While I was at it, I cleaned up some of the code in pdb_tdb (code copied
directly from smbpasswd and not really considered properly). Most of this was
to do with % macro expansion on stored data. It isn't easy to get the macros
into the tdb, and the first password change will 'expand' them. tdbsam needs
to use a similar system to pdb_ldap in this regard.
This patch only makes minor adjustments to pdb_nisplus and pdb_ldap, becouse I
don't have the test facilities for these. I plan to incoroprate at least
pdb_ldap into this scheme after consultation with Jerry.
Each (converted) passdb module now no longer has any 'static' variables, and
only exports 1 init function outside its .c file.
The non-unix-account support in this patch has been proven! It is now possible
to join a win2k machine to a Samba PDC without an account in /etc/passwd!
Other changes:
Minor interface adjustments:
pdb_delete_sam_account() now takes a SAM_ACCOUNT, not a char*.
pdb_update_sam_account() no longer takes the 'override' argument that was being
ignored so often (every other passdb backend). Extra checks have been added in
some places.
Minor code changes:
smbpasswd no longer attempts to initialise the passdb at startup, this is
now done on first use.
pdbedit has lost some of its 'machine account' logic, as this behaviour is now
controlled by the passdb subsystem directly.
The samr subsystem no longer calls 'local password change', but does the pdb
interactions directly. This allow the ACB_ flags specifed to be transferred
direct to the backend, without interference.
Doco:
I've updated the doco to reflect some of the changes, and removed some paramters
no longer applicable to HEAD.
(This used to be commit ff354c99c585068af6dc1ff35a1f109a806b326b)
2002-01-20 17:30:58 +03:00
* psid_name_use = SID_NAME_USER ;
2002-01-26 15:24:18 +03:00
2002-04-12 14:18:46 +04:00
pdb_free_sam ( & sam_account ) ;
return True ;
2002-01-26 15:24:18 +03:00
}
pdb_free_sam ( & sam_account ) ;
This is another *BIG* change...
Samba now features a pluggable passdb interface, along the same lines as the
one in use in the auth subsystem. In this case, only one backend may be active
at a time by the 'normal' interface, and only one backend per passdb_context is
permitted outside that.
This pluggable interface is designed to allow any number of passdb backends to
be compiled in, with the selection at runtime. The 'passdb backend' paramater
has been created (and documented!) to support this.
As such, configure has been modfied to allow (for example) --with-ldap and the
old smbpasswd to be selected at the same time.
This patch also introduces two new backends: smbpasswd_nua and tdbsam_nua.
These two backends accept 'non unix accounts', where the user does *not* exist
in /etc/passwd. These accounts' don't have UIDs in the unix sense, but to
avoid conflicts in the algroitmic mapping of RIDs, they use the values
specified in the 'non unix account range' paramter - in the same way as the
winbind ranges are specifed.
While I was at it, I cleaned up some of the code in pdb_tdb (code copied
directly from smbpasswd and not really considered properly). Most of this was
to do with % macro expansion on stored data. It isn't easy to get the macros
into the tdb, and the first password change will 'expand' them. tdbsam needs
to use a similar system to pdb_ldap in this regard.
This patch only makes minor adjustments to pdb_nisplus and pdb_ldap, becouse I
don't have the test facilities for these. I plan to incoroprate at least
pdb_ldap into this scheme after consultation with Jerry.
Each (converted) passdb module now no longer has any 'static' variables, and
only exports 1 init function outside its .c file.
The non-unix-account support in this patch has been proven! It is now possible
to join a win2k machine to a Samba PDC without an account in /etc/passwd!
Other changes:
Minor interface adjustments:
pdb_delete_sam_account() now takes a SAM_ACCOUNT, not a char*.
pdb_update_sam_account() no longer takes the 'override' argument that was being
ignored so often (every other passdb backend). Extra checks have been added in
some places.
Minor code changes:
smbpasswd no longer attempts to initialise the passdb at startup, this is
now done on first use.
pdbedit has lost some of its 'machine account' logic, as this behaviour is now
controlled by the passdb subsystem directly.
The samr subsystem no longer calls 'local password change', but does the pdb
interactions directly. This allow the ACB_ flags specifed to be transferred
direct to the backend, without interference.
Doco:
I've updated the doco to reflect some of the changes, and removed some paramters
no longer applicable to HEAD.
(This used to be commit ff354c99c585068af6dc1ff35a1f109a806b326b)
2002-01-20 17:30:58 +03:00
2002-07-15 14:35:28 +04:00
/*
* Maybe it was a group ?
*/
This is another *BIG* change...
Samba now features a pluggable passdb interface, along the same lines as the
one in use in the auth subsystem. In this case, only one backend may be active
at a time by the 'normal' interface, and only one backend per passdb_context is
permitted outside that.
This pluggable interface is designed to allow any number of passdb backends to
be compiled in, with the selection at runtime. The 'passdb backend' paramater
has been created (and documented!) to support this.
As such, configure has been modfied to allow (for example) --with-ldap and the
old smbpasswd to be selected at the same time.
This patch also introduces two new backends: smbpasswd_nua and tdbsam_nua.
These two backends accept 'non unix accounts', where the user does *not* exist
in /etc/passwd. These accounts' don't have UIDs in the unix sense, but to
avoid conflicts in the algroitmic mapping of RIDs, they use the values
specified in the 'non unix account range' paramter - in the same way as the
winbind ranges are specifed.
While I was at it, I cleaned up some of the code in pdb_tdb (code copied
directly from smbpasswd and not really considered properly). Most of this was
to do with % macro expansion on stored data. It isn't easy to get the macros
into the tdb, and the first password change will 'expand' them. tdbsam needs
to use a similar system to pdb_ldap in this regard.
This patch only makes minor adjustments to pdb_nisplus and pdb_ldap, becouse I
don't have the test facilities for these. I plan to incoroprate at least
pdb_ldap into this scheme after consultation with Jerry.
Each (converted) passdb module now no longer has any 'static' variables, and
only exports 1 init function outside its .c file.
The non-unix-account support in this patch has been proven! It is now possible
to join a win2k machine to a Samba PDC without an account in /etc/passwd!
Other changes:
Minor interface adjustments:
pdb_delete_sam_account() now takes a SAM_ACCOUNT, not a char*.
pdb_update_sam_account() no longer takes the 'override' argument that was being
ignored so often (every other passdb backend). Extra checks have been added in
some places.
Minor code changes:
smbpasswd no longer attempts to initialise the passdb at startup, this is
now done on first use.
pdbedit has lost some of its 'machine account' logic, as this behaviour is now
controlled by the passdb subsystem directly.
The samr subsystem no longer calls 'local password change', but does the pdb
interactions directly. This allow the ACB_ flags specifed to be transferred
direct to the backend, without interference.
Doco:
I've updated the doco to reflect some of the changes, and removed some paramters
no longer applicable to HEAD.
(This used to be commit ff354c99c585068af6dc1ff35a1f109a806b326b)
2002-01-20 17:30:58 +03:00
2002-07-15 14:35:28 +04:00
/* check if it's a mapped group */
2003-06-18 19:24:10 +04:00
if ( pdb_getgrnam ( & map , user ) ) {
2002-08-17 21:00:51 +04:00
/* yes it's a mapped group */
sid_copy ( & local_sid , & map . sid ) ;
* psid_name_use = map . sid_name_use ;
2002-04-12 14:18:46 +04:00
} else {
2002-07-15 14:35:28 +04:00
/* it's not a mapped group */
grp = getgrnam ( user ) ;
2003-11-24 20:31:38 +03:00
if ( ! grp ) {
unbecome_root ( ) ; /* ---> exit form block */
2002-07-15 14:35:28 +04:00
return False ;
2003-11-24 20:31:38 +03:00
}
2002-07-15 14:35:28 +04:00
/*
* check if it ' s mapped , if it is reply it doesn ' t exist
*
* that ' s to prevent this case :
*
* unix group ug is mapped to nt group ng
* someone does a lookup on ug
* we must not reply as it doesn ' t " exist " anymore
* for NT . For NT only ng exists .
* JFM , 30 / 11 / 2001
2000-11-14 02:03:34 +03:00
*/
2001-11-23 18:11:22 +03:00
2003-06-18 19:24:10 +04:00
if ( pdb_getgrgid ( & map , grp - > gr_gid ) ) {
2003-11-24 20:31:38 +03:00
unbecome_root ( ) ; /* ---> exit form block */
2002-07-15 14:35:28 +04:00
return False ;
2001-11-23 18:11:22 +03:00
}
2002-07-15 14:35:28 +04:00
sid_append_rid ( & local_sid , pdb_gid_to_group_rid ( grp - > gr_gid ) ) ;
* psid_name_use = SID_NAME_ALIAS ;
2000-11-14 02:03:34 +03:00
}
2003-11-24 20:31:38 +03:00
unbecome_root ( ) ;
/* END ROOT BLOCK */
2000-11-14 02:03:34 +03:00
sid_copy ( psid , & local_sid ) ;
return True ;
1998-05-18 18:43:06 +04:00
}
2000-11-14 02:03:34 +03:00
/*************************************************************
2001-09-26 00:21:21 +04:00
Change a password entry in the local smbpasswd file .
2000-11-14 02:03:34 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
This commit is number 4 of 4.
In particular this commit focuses on:
Actually adding the 'const' to the passdb interface, and the flow-on changes.
Also kill off the 'disp_info' stuff, as its no longer used.
While these changes have been mildly tested, and are pretty small, any
assistance in this is appreciated.
----
These changes introduces a large dose of 'const' to the Samba tree.
There are a number of good reasons to do this:
- I want to allow the SAM_ACCOUNT structure to move from wasteful
pstrings and fstrings to allocated strings. We can't do that if
people are modifying these outputs, as they may well make
assumptions about getting pstrings and fstrings
- I want --with-pam_smbpass to compile with a slightly sane
volume of warnings, currently its pretty bad, even in 2.2
where is compiles at all.
- Tridge assures me that he no longer opposes 'const religion'
based on the ability to #define const the problem away.
- Changed Get_Pwnam(x,y) into two variants (so that the const
parameter can work correctly): - Get_Pwnam(const x) and
Get_Pwnam_Modify(x).
- Reworked smbd/chgpasswd.c to work with these mods, passing
around a 'struct passwd' rather than the modified username
---
This finishes this line of commits off, your tree should now compile again :-)
Andrew Bartlett
(This used to be commit c95f5aeb9327347674589ae313b75bee3bf8e317)
2001-10-29 10:35:11 +03:00
BOOL local_password_change ( const char * user_name , int local_flags ,
const char * new_passwd ,
2000-11-14 02:03:34 +03:00
char * err_str , size_t err_str_len ,
char * msg_str , size_t msg_str_len )
{
2001-05-04 19:44:27 +04:00
SAM_ACCOUNT * sam_pass = NULL ;
2002-09-25 19:19:00 +04:00
uint16 other_acb ;
1999-12-13 16:27:58 +03:00
2000-11-14 02:03:34 +03:00
* err_str = ' \0 ' ;
* msg_str = ' \0 ' ;
1999-12-13 16:27:58 +03:00
2000-11-14 02:03:34 +03:00
/* Get the smb passwd entry for this user */
2001-05-04 19:44:27 +04:00
pdb_init_sam ( & sam_pass ) ;
2003-07-09 04:20:43 +04:00
become_root ( ) ;
2001-09-26 00:21:21 +04:00
if ( ! pdb_getsampwnam ( sam_pass , user_name ) ) {
2003-07-09 04:20:43 +04:00
unbecome_root ( ) ;
2001-09-29 17:14:19 +04:00
pdb_free_sam ( & sam_pass ) ;
2001-05-07 18:04:46 +04:00
2003-04-29 13:43:17 +04:00
if ( ( local_flags & LOCAL_ADD_USER ) | | ( local_flags & LOCAL_DELETE_USER ) ) {
2003-07-11 09:33:40 +04:00
/* Might not exist in /etc/passwd. Use rid algorithm here */
if ( ! NT_STATUS_IS_OK ( pdb_init_sam_new ( & sam_pass , user_name , 0 ) ) ) {
2003-10-04 02:09:33 +04:00
slprintf ( err_str , err_str_len - 1 , " Failed to initialise SAM_ACCOUNT for user %s. \n " , user_name ) ;
This is another *BIG* change...
Samba now features a pluggable passdb interface, along the same lines as the
one in use in the auth subsystem. In this case, only one backend may be active
at a time by the 'normal' interface, and only one backend per passdb_context is
permitted outside that.
This pluggable interface is designed to allow any number of passdb backends to
be compiled in, with the selection at runtime. The 'passdb backend' paramater
has been created (and documented!) to support this.
As such, configure has been modfied to allow (for example) --with-ldap and the
old smbpasswd to be selected at the same time.
This patch also introduces two new backends: smbpasswd_nua and tdbsam_nua.
These two backends accept 'non unix accounts', where the user does *not* exist
in /etc/passwd. These accounts' don't have UIDs in the unix sense, but to
avoid conflicts in the algroitmic mapping of RIDs, they use the values
specified in the 'non unix account range' paramter - in the same way as the
winbind ranges are specifed.
While I was at it, I cleaned up some of the code in pdb_tdb (code copied
directly from smbpasswd and not really considered properly). Most of this was
to do with % macro expansion on stored data. It isn't easy to get the macros
into the tdb, and the first password change will 'expand' them. tdbsam needs
to use a similar system to pdb_ldap in this regard.
This patch only makes minor adjustments to pdb_nisplus and pdb_ldap, becouse I
don't have the test facilities for these. I plan to incoroprate at least
pdb_ldap into this scheme after consultation with Jerry.
Each (converted) passdb module now no longer has any 'static' variables, and
only exports 1 init function outside its .c file.
The non-unix-account support in this patch has been proven! It is now possible
to join a win2k machine to a Samba PDC without an account in /etc/passwd!
Other changes:
Minor interface adjustments:
pdb_delete_sam_account() now takes a SAM_ACCOUNT, not a char*.
pdb_update_sam_account() no longer takes the 'override' argument that was being
ignored so often (every other passdb backend). Extra checks have been added in
some places.
Minor code changes:
smbpasswd no longer attempts to initialise the passdb at startup, this is
now done on first use.
pdbedit has lost some of its 'machine account' logic, as this behaviour is now
controlled by the passdb subsystem directly.
The samr subsystem no longer calls 'local password change', but does the pdb
interactions directly. This allow the ACB_ flags specifed to be transferred
direct to the backend, without interference.
Doco:
I've updated the doco to reflect some of the changes, and removed some paramters
no longer applicable to HEAD.
(This used to be commit ff354c99c585068af6dc1ff35a1f109a806b326b)
2002-01-20 17:30:58 +03:00
return False ;
}
} else {
2003-04-29 13:43:17 +04:00
slprintf ( err_str , err_str_len - 1 , " Failed to find entry for user %s. \n " , user_name ) ;
return False ;
2001-09-27 13:13:26 +04:00
}
2001-05-04 19:44:27 +04:00
} else {
2003-07-09 04:20:43 +04:00
unbecome_root ( ) ;
2000-11-14 02:03:34 +03:00
/* the entry already existed */
local_flags & = ~ LOCAL_ADD_USER ;
}
1999-12-13 16:27:58 +03:00
2002-09-25 19:19:00 +04:00
/* the 'other' acb bits not being changed here */
other_acb = ( pdb_get_acct_ctrl ( sam_pass ) & ( ! ( ACB_WSTRUST | ACB_DOMTRUST | ACB_SVRTRUST | ACB_NORMAL ) ) ) ;
if ( local_flags & LOCAL_TRUST_ACCOUNT ) {
2002-11-02 06:47:48 +03:00
if ( ! pdb_set_acct_ctrl ( sam_pass , ACB_WSTRUST | other_acb , PDB_CHANGED ) ) {
2002-09-25 19:19:00 +04:00
slprintf ( err_str , err_str_len - 1 , " Failed to set 'trusted workstation account' flags for user %s. \n " , user_name ) ;
pdb_free_sam ( & sam_pass ) ;
return False ;
}
} else if ( local_flags & LOCAL_INTERDOM_ACCOUNT ) {
2002-11-02 06:47:48 +03:00
if ( ! pdb_set_acct_ctrl ( sam_pass , ACB_DOMTRUST | other_acb , PDB_CHANGED ) ) {
2002-09-25 19:19:00 +04:00
slprintf ( err_str , err_str_len - 1 , " Failed to set 'domain trust account' flags for user %s. \n " , user_name ) ;
pdb_free_sam ( & sam_pass ) ;
return False ;
}
} else {
2002-11-02 06:47:48 +03:00
if ( ! pdb_set_acct_ctrl ( sam_pass , ACB_NORMAL | other_acb , PDB_CHANGED ) ) {
2002-09-25 19:19:00 +04:00
slprintf ( err_str , err_str_len - 1 , " Failed to set 'normal account' flags for user %s. \n " , user_name ) ;
pdb_free_sam ( & sam_pass ) ;
return False ;
}
}
1999-12-13 16:27:58 +03:00
/*
2000-11-14 02:03:34 +03:00
* We are root - just write the new password
* and the valid last change time .
1999-12-13 16:27:58 +03:00
*/
2001-09-29 17:14:19 +04:00
if ( local_flags & LOCAL_DISABLE_USER ) {
2002-11-02 06:47:48 +03:00
if ( ! pdb_set_acct_ctrl ( sam_pass , pdb_get_acct_ctrl ( sam_pass ) | ACB_DISABLED , PDB_CHANGED ) ) {
2001-09-29 17:14:19 +04:00
slprintf ( err_str , err_str_len - 1 , " Failed to set 'disabled' flag for user %s. \n " , user_name ) ;
pdb_free_sam ( & sam_pass ) ;
return False ;
}
2001-09-26 00:21:21 +04:00
} else if ( local_flags & LOCAL_ENABLE_USER ) {
2002-11-02 06:47:48 +03:00
if ( ! pdb_set_acct_ctrl ( sam_pass , pdb_get_acct_ctrl ( sam_pass ) & ( ~ ACB_DISABLED ) , PDB_CHANGED ) ) {
2001-09-29 17:14:19 +04:00
slprintf ( err_str , err_str_len - 1 , " Failed to unset 'disabled' flag for user %s. \n " , user_name ) ;
pdb_free_sam ( & sam_pass ) ;
return False ;
}
}
if ( local_flags & LOCAL_SET_NO_PASSWORD ) {
2002-11-02 06:47:48 +03:00
if ( ! pdb_set_acct_ctrl ( sam_pass , pdb_get_acct_ctrl ( sam_pass ) | ACB_PWNOTREQ , PDB_CHANGED ) ) {
2001-09-29 17:14:19 +04:00
slprintf ( err_str , err_str_len - 1 , " Failed to set 'no password required' flag for user %s. \n " , user_name ) ;
pdb_free_sam ( & sam_pass ) ;
return False ;
1999-12-13 16:27:58 +03:00
}
2001-10-30 08:21:16 +03:00
} else if ( local_flags & LOCAL_SET_PASSWORD ) {
1999-12-13 16:27:58 +03:00
/*
2000-11-14 02:03:34 +03:00
* If we ' re dealing with setting a completely empty user account
* ie . One with a password of ' XXXX ' , but not set disabled ( like
* an account created from scratch ) then if the old password was
* ' XX ' s then getsmbpwent will have set the ACB_DISABLED flag .
* We remove that as we ' re giving this user their first password
* and the decision hasn ' t really been made to disable them ( ie .
* don ' t create them disabled ) . JRA .
1999-12-13 16:27:58 +03:00
*/
2001-09-29 17:14:19 +04:00
if ( ( pdb_get_lanman_passwd ( sam_pass ) = = NULL ) & & ( pdb_get_acct_ctrl ( sam_pass ) & ACB_DISABLED ) ) {
2002-11-02 06:47:48 +03:00
if ( ! pdb_set_acct_ctrl ( sam_pass , pdb_get_acct_ctrl ( sam_pass ) & ( ~ ACB_DISABLED ) , PDB_CHANGED ) ) {
2001-09-29 17:14:19 +04:00
slprintf ( err_str , err_str_len - 1 , " Failed to unset 'disabled' flag for user %s. \n " , user_name ) ;
pdb_free_sam ( & sam_pass ) ;
return False ;
}
}
2002-11-02 06:47:48 +03:00
if ( ! pdb_set_acct_ctrl ( sam_pass , pdb_get_acct_ctrl ( sam_pass ) & ( ~ ACB_PWNOTREQ ) , PDB_CHANGED ) ) {
2001-09-29 17:14:19 +04:00
slprintf ( err_str , err_str_len - 1 , " Failed to unset 'no password required' flag for user %s. \n " , user_name ) ;
pdb_free_sam ( & sam_pass ) ;
return False ;
}
if ( ! pdb_set_plaintext_passwd ( sam_pass , new_passwd ) ) {
slprintf ( err_str , err_str_len - 1 , " Failed to set password for user %s. \n " , user_name ) ;
pdb_free_sam ( & sam_pass ) ;
return False ;
}
}
if ( local_flags & LOCAL_ADD_USER ) {
if ( pdb_add_sam_account ( sam_pass ) ) {
slprintf ( msg_str , msg_str_len - 1 , " Added user %s. \n " , user_name ) ;
pdb_free_sam ( & sam_pass ) ;
return True ;
} else {
slprintf ( err_str , err_str_len - 1 , " Failed to add entry for user %s. \n " , user_name ) ;
pdb_free_sam ( & sam_pass ) ;
return False ;
}
2002-01-30 15:06:22 +03:00
} else if ( local_flags & LOCAL_DELETE_USER ) {
if ( ! pdb_delete_sam_account ( sam_pass ) ) {
slprintf ( err_str , err_str_len - 1 , " Failed to delete entry for user %s. \n " , user_name ) ;
pdb_free_sam ( & sam_pass ) ;
return False ;
}
slprintf ( msg_str , msg_str_len - 1 , " Deleted user %s. \n " , user_name ) ;
2001-09-26 00:21:21 +04:00
} else {
This is another *BIG* change...
Samba now features a pluggable passdb interface, along the same lines as the
one in use in the auth subsystem. In this case, only one backend may be active
at a time by the 'normal' interface, and only one backend per passdb_context is
permitted outside that.
This pluggable interface is designed to allow any number of passdb backends to
be compiled in, with the selection at runtime. The 'passdb backend' paramater
has been created (and documented!) to support this.
As such, configure has been modfied to allow (for example) --with-ldap and the
old smbpasswd to be selected at the same time.
This patch also introduces two new backends: smbpasswd_nua and tdbsam_nua.
These two backends accept 'non unix accounts', where the user does *not* exist
in /etc/passwd. These accounts' don't have UIDs in the unix sense, but to
avoid conflicts in the algroitmic mapping of RIDs, they use the values
specified in the 'non unix account range' paramter - in the same way as the
winbind ranges are specifed.
While I was at it, I cleaned up some of the code in pdb_tdb (code copied
directly from smbpasswd and not really considered properly). Most of this was
to do with % macro expansion on stored data. It isn't easy to get the macros
into the tdb, and the first password change will 'expand' them. tdbsam needs
to use a similar system to pdb_ldap in this regard.
This patch only makes minor adjustments to pdb_nisplus and pdb_ldap, becouse I
don't have the test facilities for these. I plan to incoroprate at least
pdb_ldap into this scheme after consultation with Jerry.
Each (converted) passdb module now no longer has any 'static' variables, and
only exports 1 init function outside its .c file.
The non-unix-account support in this patch has been proven! It is now possible
to join a win2k machine to a Samba PDC without an account in /etc/passwd!
Other changes:
Minor interface adjustments:
pdb_delete_sam_account() now takes a SAM_ACCOUNT, not a char*.
pdb_update_sam_account() no longer takes the 'override' argument that was being
ignored so often (every other passdb backend). Extra checks have been added in
some places.
Minor code changes:
smbpasswd no longer attempts to initialise the passdb at startup, this is
now done on first use.
pdbedit has lost some of its 'machine account' logic, as this behaviour is now
controlled by the passdb subsystem directly.
The samr subsystem no longer calls 'local password change', but does the pdb
interactions directly. This allow the ACB_ flags specifed to be transferred
direct to the backend, without interference.
Doco:
I've updated the doco to reflect some of the changes, and removed some paramters
no longer applicable to HEAD.
(This used to be commit ff354c99c585068af6dc1ff35a1f109a806b326b)
2002-01-20 17:30:58 +03:00
if ( ! pdb_update_sam_account ( sam_pass ) ) {
2000-11-14 02:03:34 +03:00
slprintf ( err_str , err_str_len - 1 , " Failed to modify entry for user %s. \n " , user_name ) ;
2001-09-29 17:14:19 +04:00
pdb_free_sam ( & sam_pass ) ;
2000-11-14 02:03:34 +03:00
return False ;
}
if ( local_flags & LOCAL_DISABLE_USER )
slprintf ( msg_str , msg_str_len - 1 , " Disabled user %s. \n " , user_name ) ;
else if ( local_flags & LOCAL_ENABLE_USER )
slprintf ( msg_str , msg_str_len - 1 , " Enabled user %s. \n " , user_name ) ;
else if ( local_flags & LOCAL_SET_NO_PASSWORD )
slprintf ( msg_str , msg_str_len - 1 , " User %s password set to none. \n " , user_name ) ;
1999-03-03 23:48:48 +03:00
}
2000-11-14 02:03:34 +03:00
2001-09-29 17:14:19 +04:00
pdb_free_sam ( & sam_pass ) ;
2000-11-14 02:03:34 +03:00
return True ;
1999-12-13 16:27:58 +03:00
}
2003-07-07 09:11:10 +04:00
2003-09-19 01:19:41 +04:00
/****************************************************************************
Convert a uid to SID - algorithmic .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-01-02 08:32:07 +03:00
DOM_SID * algorithmic_uid_to_sid ( DOM_SID * psid , uid_t uid )
2003-09-19 01:19:41 +04:00
{
if ( ! lp_enable_rid_algorithm ( ) )
return NULL ;
DEBUG ( 8 , ( " algorithmic_uid_to_sid: falling back to RID algorithm \n " ) ) ;
sid_copy ( psid , get_global_sam_sid ( ) ) ;
sid_append_rid ( psid , fallback_pdb_uid_to_user_rid ( uid ) ) ;
DEBUG ( 10 , ( " algorithmic_uid_to_sid: uid (%d) -> SID %s. \n " ,
( unsigned int ) uid , sid_string_static ( psid ) ) ) ;
return psid ;
}
2003-07-07 09:11:10 +04:00
/****************************************************************************
Convert a uid to SID - locally .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
DOM_SID * local_uid_to_sid ( DOM_SID * psid , uid_t uid )
{
SAM_ACCOUNT * sampw = NULL ;
struct passwd * unix_pw ;
2003-07-15 06:27:00 +04:00
BOOL ret ;
2003-07-07 09:11:10 +04:00
unix_pw = sys_getpwuid ( uid ) ;
if ( ! unix_pw ) {
2003-09-18 05:17:22 +04:00
DEBUG ( 4 , ( " local_uid_to_sid: host has no idea of uid %lu \n " , ( unsigned long ) uid ) ) ;
2003-09-19 01:19:41 +04:00
return algorithmic_uid_to_sid ( psid , uid ) ;
2003-07-07 09:11:10 +04:00
}
if ( ! NT_STATUS_IS_OK ( pdb_init_sam ( & sampw ) ) ) {
2003-07-15 06:27:00 +04:00
DEBUG ( 0 , ( " local_uid_to_sid: failed to allocate SAM_ACCOUNT object \n " ) ) ;
2003-07-07 09:11:10 +04:00
return NULL ;
}
2003-07-09 04:20:43 +04:00
become_root ( ) ;
2003-07-15 06:27:00 +04:00
ret = pdb_getsampwnam ( sampw , unix_pw - > pw_name ) ;
unbecome_root ( ) ;
if ( ret )
sid_copy ( psid , pdb_get_user_sid ( sampw ) ) ;
else {
2003-07-22 08:31:20 +04:00
DEBUG ( 4 , ( " local_uid_to_sid: User %s [uid == %lu] has no samba account \n " ,
unix_pw - > pw_name , ( unsigned long ) uid ) ) ;
2003-07-15 06:27:00 +04:00
2003-09-19 01:19:41 +04:00
return algorithmic_uid_to_sid ( psid , uid ) ;
2003-07-07 09:11:10 +04:00
}
2003-07-15 06:27:00 +04:00
2003-07-07 09:11:10 +04:00
DEBUG ( 10 , ( " local_uid_to_sid: uid (%d) -> SID %s (%s). \n " ,
( unsigned int ) uid , sid_string_static ( psid ) , unix_pw - > pw_name ) ) ;
return psid ;
}
/****************************************************************************
Convert a SID to uid - locally .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-07-07 21:04:48 +04:00
BOOL local_sid_to_uid ( uid_t * puid , const DOM_SID * psid , enum SID_NAME_USE * name_type )
2003-07-07 09:11:10 +04:00
{
SAM_ACCOUNT * sampw = NULL ;
struct passwd * unix_pw ;
const char * user_name ;
* name_type = SID_NAME_UNKNOWN ;
/*
* We can only convert to a uid if this is our local
* Domain SID ( ie . we are the controling authority ) .
*/
2003-07-14 01:41:23 +04:00
if ( ! sid_check_is_in_our_domain ( psid ) ) {
DEBUG ( 5 , ( " local_sid_to_uid: this SID (%s) is not from our domain \n " , sid_string_static ( psid ) ) ) ;
2003-07-07 09:11:10 +04:00
return False ;
2003-07-14 01:41:23 +04:00
}
2003-07-07 09:11:10 +04:00
/* lookup the user account */
if ( ! NT_STATUS_IS_OK ( pdb_init_sam ( & sampw ) ) ) {
DEBUG ( 0 , ( " local_sid_to_uid: Failed to allocate memory for SAM_ACCOUNT object \n " ) ) ;
return False ;
}
2003-07-09 04:20:43 +04:00
become_root ( ) ;
2003-07-07 09:11:10 +04:00
if ( ! pdb_getsampwsid ( sampw , psid ) ) {
2003-07-09 04:20:43 +04:00
unbecome_root ( ) ;
2003-07-07 09:11:10 +04:00
DEBUG ( 8 , ( " local_sid_to_uid: Could not find SID %s in passdb \n " ,
sid_string_static ( psid ) ) ) ;
return False ;
}
2003-07-09 04:20:43 +04:00
unbecome_root ( ) ;
2003-07-07 09:11:10 +04:00
user_name = pdb_get_username ( sampw ) ;
unix_pw = sys_getpwnam ( user_name ) ;
if ( ! unix_pw ) {
DEBUG ( 0 , ( " local_sid_to_uid: %s found in passdb but getpwnam() return NULL! \n " ,
user_name ) ) ;
pdb_free_sam ( & sampw ) ;
return False ;
}
* puid = unix_pw - > pw_uid ;
DEBUG ( 10 , ( " local_sid_to_uid: SID %s -> uid (%u) (%s). \n " , sid_string_static ( psid ) ,
( unsigned int ) * puid , user_name ) ) ;
* name_type = SID_NAME_USER ;
return True ;
}
2004-05-06 09:31:52 +04:00
/****************************************************************************
Convert a gid to SID - algorithmic .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
DOM_SID * algorithmic_gid_to_sid ( DOM_SID * psid , uid_t gid )
{
if ( ! lp_enable_rid_algorithm ( ) )
return NULL ;
DEBUG ( 8 , ( " algorithmic_gid_to_sid: falling back to RID algorithm \n " ) ) ;
sid_copy ( psid , get_global_sam_sid ( ) ) ;
sid_append_rid ( psid , pdb_gid_to_group_rid ( gid ) ) ;
DEBUG ( 10 , ( " algorithmic_gid_to_sid: gid (%d) -> SID %s. \n " ,
( unsigned int ) gid , sid_string_static ( psid ) ) ) ;
return psid ;
}
2003-07-07 09:11:10 +04:00
/****************************************************************************
Convert a gid to SID - locally .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
DOM_SID * local_gid_to_sid ( DOM_SID * psid , gid_t gid )
{
GROUP_MAP group ;
2003-08-11 11:05:23 +04:00
BOOL ret ;
2003-07-07 09:11:10 +04:00
/* we don't need to disable winbindd since the gid is stored in
the GROUP_MAP object */
2003-08-11 11:05:23 +04:00
/* done as root since ldap backend requires root to open a connection */
2003-07-07 09:11:10 +04:00
2003-08-11 11:05:23 +04:00
become_root ( ) ;
ret = pdb_getgrgid ( & group , gid ) ;
unbecome_root ( ) ;
if ( ! ret ) {
2003-07-07 09:11:10 +04:00
/* fallback to rid mapping if enabled */
if ( lp_enable_rid_algorithm ( ) ) {
DEBUG ( 10 , ( " local_gid_to_sid: Fall back to algorithmic mapping: %u -> %s \n " ,
( unsigned int ) gid , sid_string_static ( psid ) ) ) ;
2004-05-06 09:31:52 +04:00
return algorithmic_gid_to_sid ( psid , gid ) ;
2003-07-07 09:11:10 +04:00
}
else
return NULL ;
}
sid_copy ( psid , & group . sid ) ;
DEBUG ( 10 , ( " local_gid_to_sid: gid (%d) -> SID %s. \n " ,
( unsigned int ) gid , sid_string_static ( psid ) ) ) ;
return psid ;
}
/****************************************************************************
Convert a SID to gid - locally .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-07-07 21:04:48 +04:00
BOOL local_sid_to_gid ( gid_t * pgid , const DOM_SID * psid , enum SID_NAME_USE * name_type )
2003-07-07 09:11:10 +04:00
{
uint32 rid ;
GROUP_MAP group ;
2003-12-10 19:40:17 +03:00
BOOL ret ;
2003-07-07 09:11:10 +04:00
* name_type = SID_NAME_UNKNOWN ;
2003-07-11 20:37:23 +04:00
/* This call can enumerate group mappings for foreign sids as well.
2003-07-07 09:11:10 +04:00
So don ' t check for a match against our domain SID */
/* we don't need to disable winbindd since the gid is stored in
the GROUP_MAP object */
2003-12-10 19:40:17 +03:00
become_root ( ) ;
2003-12-11 13:24:43 +03:00
ret = pdb_getgrsid ( & group , * psid ) ;
2003-12-10 19:40:17 +03:00
unbecome_root ( ) ;
if ( ! ret ) {
2003-07-07 09:11:10 +04:00
/* fallback to rid mapping if enabled */
if ( lp_enable_rid_algorithm ( ) ) {
2003-07-14 01:41:23 +04:00
if ( ! sid_check_is_in_our_domain ( psid ) ) {
DEBUG ( 5 , ( " local_sid_to_gid: RID algorithm only supported for our domain (%s is not) \n " , sid_string_static ( psid ) ) ) ;
2003-07-07 09:11:10 +04:00
return False ;
}
if ( ! sid_peek_rid ( psid , & rid ) ) {
2004-05-06 08:32:56 +04:00
DEBUG ( 10 , ( " local_sid_to_gid: invalid SID! \n " ) ) ;
2003-07-07 09:11:10 +04:00
return False ;
}
DEBUG ( 10 , ( " local_sid_to_gid: Fall back to algorithmic mapping \n " ) ) ;
if ( fallback_pdb_rid_is_user ( rid ) ) {
DEBUG ( 3 , ( " local_sid_to_gid: SID %s is *NOT* a group \n " , sid_string_static ( psid ) ) ) ;
return False ;
} else {
* pgid = pdb_group_rid_to_gid ( rid ) ;
DEBUG ( 10 , ( " local_sid_to_gid: mapping: %s -> %u \n " , sid_string_static ( psid ) , ( unsigned int ) ( * pgid ) ) ) ;
return True ;
}
}
return False ;
}
* pgid = group . gid ;
DEBUG ( 10 , ( " local_sid_to_gid: SID %s -> gid (%u) \n " , sid_string_static ( psid ) ,
( unsigned int ) * pgid ) ) ;
return True ;
}
2003-07-09 01:58:29 +04:00
/**********************************************************************
Marshall / unmarshall SAM_ACCOUNT structs .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-13 17:48:20 +03:00
# define TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
# define TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
2003-07-09 01:58:29 +04:00
/**********************************************************************
Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL init_sam_from_buffer ( SAM_ACCOUNT * sampass , uint8 * buf , uint32 buflen )
2004-02-13 17:48:20 +03:00
{
return ( init_sam_from_buffer_v1 ( sampass , buf , buflen ) ) ;
}
/**********************************************************************
Intialize a BYTE buffer from a SAM_ACCOUNT struct
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 init_buffer_from_sam ( uint8 * * buf , const SAM_ACCOUNT * sampass , BOOL size_only )
{
return ( init_buffer_from_sam_v1 ( buf , sampass , size_only ) ) ;
}
BOOL init_sam_from_buffer_v0 ( SAM_ACCOUNT * sampass , uint8 * buf , uint32 buflen )
2003-07-09 01:58:29 +04:00
{
/* times are stored as 32bit integer
take care on system with 64 bit wide time_t
- - SSS */
uint32 logon_time ,
logoff_time ,
kickoff_time ,
pass_last_set_time ,
pass_can_change_time ,
pass_must_change_time ;
char * username ;
char * domain ;
char * nt_username ;
char * dir_drive ;
char * unknown_str ;
char * munged_dial ;
char * fullname ;
char * homedir ;
char * logon_script ;
char * profile_path ;
char * acct_desc ;
char * workstations ;
uint32 username_len , domain_len , nt_username_len ,
dir_drive_len , unknown_str_len , munged_dial_len ,
fullname_len , homedir_len , logon_script_len ,
profile_path_len , acct_desc_len , workstations_len ;
2004-02-13 17:48:20 +03:00
uint32 user_rid , group_rid , remove_me , hours_len , unknown_6 ;
2003-07-09 01:58:29 +04:00
uint16 acct_ctrl , logon_divs ;
2003-09-19 03:53:48 +04:00
uint16 bad_password_count , logon_count ;
2003-07-09 01:58:29 +04:00
uint8 * hours ;
static uint8 * lm_pw_ptr , * nt_pw_ptr ;
uint32 len = 0 ;
uint32 lm_pw_len , nt_pw_len , hourslen ;
BOOL ret = True ;
if ( sampass = = NULL | | buf = = NULL ) {
DEBUG ( 0 , ( " init_sam_from_buffer: NULL parameters found! \n " ) ) ;
return False ;
}
/* unpack the buffer into variables */
2004-02-13 17:48:20 +03:00
len = tdb_unpack ( ( char * ) buf , buflen , TDB_FORMAT_STRING_V0 ,
2003-07-09 01:58:29 +04:00
& logon_time ,
& logoff_time ,
& kickoff_time ,
& pass_last_set_time ,
& pass_can_change_time ,
& pass_must_change_time ,
& username_len , & username ,
& domain_len , & domain ,
& nt_username_len , & nt_username ,
& fullname_len , & fullname ,
& homedir_len , & homedir ,
& dir_drive_len , & dir_drive ,
& logon_script_len , & logon_script ,
& profile_path_len , & profile_path ,
& acct_desc_len , & acct_desc ,
& workstations_len , & workstations ,
& unknown_str_len , & unknown_str ,
& munged_dial_len , & munged_dial ,
& user_rid ,
& group_rid ,
& lm_pw_len , & lm_pw_ptr ,
& nt_pw_len , & nt_pw_ptr ,
& acct_ctrl ,
2004-02-13 17:48:20 +03:00
& remove_me , /* remove on the next TDB_FORMAT upgarde */
2003-07-09 01:58:29 +04:00
& logon_divs ,
& hours_len ,
& hourslen , & hours ,
2003-09-19 03:53:48 +04:00
& bad_password_count ,
& logon_count ,
2003-07-09 01:58:29 +04:00
& unknown_6 ) ;
2004-02-19 21:35:43 +03:00
if ( len = = ( uint32 ) - 1 ) {
2003-07-09 01:58:29 +04:00
ret = False ;
goto done ;
}
pdb_set_logon_time ( sampass , logon_time , PDB_SET ) ;
pdb_set_logoff_time ( sampass , logoff_time , PDB_SET ) ;
pdb_set_kickoff_time ( sampass , kickoff_time , PDB_SET ) ;
pdb_set_pass_can_change_time ( sampass , pass_can_change_time , PDB_SET ) ;
pdb_set_pass_must_change_time ( sampass , pass_must_change_time , PDB_SET ) ;
pdb_set_pass_last_set_time ( sampass , pass_last_set_time , PDB_SET ) ;
pdb_set_username ( sampass , username , PDB_SET ) ;
pdb_set_domain ( sampass , domain , PDB_SET ) ;
pdb_set_nt_username ( sampass , nt_username , PDB_SET ) ;
pdb_set_fullname ( sampass , fullname , PDB_SET ) ;
if ( homedir ) {
pdb_set_homedir ( sampass , homedir , PDB_SET ) ;
}
else {
pdb_set_homedir ( sampass ,
2003-09-11 20:52:10 +04:00
talloc_sub_basic ( sampass - > mem_ctx , username , lp_logon_home ( ) ) ,
PDB_DEFAULT ) ;
2003-07-09 01:58:29 +04:00
}
if ( dir_drive )
pdb_set_dir_drive ( sampass , dir_drive , PDB_SET ) ;
else {
pdb_set_dir_drive ( sampass ,
2003-09-11 20:52:10 +04:00
talloc_sub_basic ( sampass - > mem_ctx , username , lp_logon_drive ( ) ) ,
PDB_DEFAULT ) ;
2003-07-09 01:58:29 +04:00
}
if ( logon_script )
pdb_set_logon_script ( sampass , logon_script , PDB_SET ) ;
else {
pdb_set_logon_script ( sampass ,
2003-09-11 20:52:10 +04:00
talloc_sub_basic ( sampass - > mem_ctx , username , lp_logon_script ( ) ) ,
PDB_DEFAULT ) ;
2003-07-09 01:58:29 +04:00
}
if ( profile_path ) {
pdb_set_profile_path ( sampass , profile_path , PDB_SET ) ;
} else {
pdb_set_profile_path ( sampass ,
2003-09-11 20:52:10 +04:00
talloc_sub_basic ( sampass - > mem_ctx , username , lp_logon_path ( ) ) ,
PDB_DEFAULT ) ;
2003-07-09 01:58:29 +04:00
}
pdb_set_acct_desc ( sampass , acct_desc , PDB_SET ) ;
pdb_set_workstations ( sampass , workstations , PDB_SET ) ;
pdb_set_munged_dial ( sampass , munged_dial , PDB_SET ) ;
if ( lm_pw_ptr & & lm_pw_len = = LM_HASH_LEN ) {
if ( ! pdb_set_lanman_passwd ( sampass , lm_pw_ptr , PDB_SET ) ) {
ret = False ;
goto done ;
}
}
if ( nt_pw_ptr & & nt_pw_len = = NT_HASH_LEN ) {
if ( ! pdb_set_nt_passwd ( sampass , nt_pw_ptr , PDB_SET ) ) {
ret = False ;
goto done ;
}
}
pdb_set_user_sid_from_rid ( sampass , user_rid , PDB_SET ) ;
pdb_set_group_sid_from_rid ( sampass , group_rid , PDB_SET ) ;
pdb_set_hours_len ( sampass , hours_len , PDB_SET ) ;
2003-09-19 03:53:48 +04:00
pdb_set_bad_password_count ( sampass , bad_password_count , PDB_SET ) ;
pdb_set_logon_count ( sampass , logon_count , PDB_SET ) ;
2003-07-09 01:58:29 +04:00
pdb_set_unknown_6 ( sampass , unknown_6 , PDB_SET ) ;
pdb_set_acct_ctrl ( sampass , acct_ctrl , PDB_SET ) ;
pdb_set_logon_divs ( sampass , logon_divs , PDB_SET ) ;
pdb_set_hours ( sampass , hours , PDB_SET ) ;
done :
SAFE_FREE ( username ) ;
SAFE_FREE ( domain ) ;
SAFE_FREE ( nt_username ) ;
SAFE_FREE ( fullname ) ;
SAFE_FREE ( homedir ) ;
SAFE_FREE ( dir_drive ) ;
SAFE_FREE ( logon_script ) ;
SAFE_FREE ( profile_path ) ;
SAFE_FREE ( acct_desc ) ;
SAFE_FREE ( workstations ) ;
SAFE_FREE ( munged_dial ) ;
SAFE_FREE ( unknown_str ) ;
SAFE_FREE ( hours ) ;
return ret ;
}
2004-02-13 17:48:20 +03:00
uint32 init_buffer_from_sam_v0 ( uint8 * * buf , const SAM_ACCOUNT * sampass , BOOL size_only )
2003-07-09 01:58:29 +04:00
{
size_t len , buflen ;
/* times are stored as 32bit integer
take care on system with 64 bit wide time_t
- - SSS */
uint32 logon_time ,
logoff_time ,
kickoff_time ,
pass_last_set_time ,
pass_can_change_time ,
pass_must_change_time ;
uint32 user_rid , group_rid ;
const char * username ;
const char * domain ;
const char * nt_username ;
const char * dir_drive ;
const char * unknown_str ;
const char * munged_dial ;
const char * fullname ;
const char * homedir ;
const char * logon_script ;
const char * profile_path ;
const char * acct_desc ;
const char * workstations ;
uint32 username_len , domain_len , nt_username_len ,
dir_drive_len , unknown_str_len , munged_dial_len ,
fullname_len , homedir_len , logon_script_len ,
profile_path_len , acct_desc_len , workstations_len ;
const uint8 * lm_pw ;
const uint8 * nt_pw ;
uint32 lm_pw_len = 16 ;
uint32 nt_pw_len = 16 ;
/* do we have a valid SAM_ACCOUNT pointer? */
if ( sampass = = NULL ) {
DEBUG ( 0 , ( " init_buffer_from_sam: SAM_ACCOUNT is NULL! \n " ) ) ;
return - 1 ;
}
* buf = NULL ;
buflen = 0 ;
logon_time = ( uint32 ) pdb_get_logon_time ( sampass ) ;
logoff_time = ( uint32 ) pdb_get_logoff_time ( sampass ) ;
kickoff_time = ( uint32 ) pdb_get_kickoff_time ( sampass ) ;
pass_can_change_time = ( uint32 ) pdb_get_pass_can_change_time ( sampass ) ;
pass_must_change_time = ( uint32 ) pdb_get_pass_must_change_time ( sampass ) ;
pass_last_set_time = ( uint32 ) pdb_get_pass_last_set_time ( sampass ) ;
user_rid = pdb_get_user_rid ( sampass ) ;
group_rid = pdb_get_group_rid ( sampass ) ;
username = pdb_get_username ( sampass ) ;
if ( username )
username_len = strlen ( username ) + 1 ;
else
username_len = 0 ;
domain = pdb_get_domain ( sampass ) ;
if ( domain )
domain_len = strlen ( domain ) + 1 ;
else
domain_len = 0 ;
nt_username = pdb_get_nt_username ( sampass ) ;
if ( nt_username )
nt_username_len = strlen ( nt_username ) + 1 ;
else
nt_username_len = 0 ;
fullname = pdb_get_fullname ( sampass ) ;
if ( fullname )
fullname_len = strlen ( fullname ) + 1 ;
else
fullname_len = 0 ;
/*
* Only updates fields which have been set ( not defaults from smb . conf )
*/
if ( ! IS_SAM_DEFAULT ( sampass , PDB_DRIVE ) )
dir_drive = pdb_get_dir_drive ( sampass ) ;
else
dir_drive = NULL ;
if ( dir_drive )
dir_drive_len = strlen ( dir_drive ) + 1 ;
else
dir_drive_len = 0 ;
if ( ! IS_SAM_DEFAULT ( sampass , PDB_SMBHOME ) )
homedir = pdb_get_homedir ( sampass ) ;
else
homedir = NULL ;
if ( homedir )
homedir_len = strlen ( homedir ) + 1 ;
else
homedir_len = 0 ;
if ( ! IS_SAM_DEFAULT ( sampass , PDB_LOGONSCRIPT ) )
logon_script = pdb_get_logon_script ( sampass ) ;
else
logon_script = NULL ;
if ( logon_script )
logon_script_len = strlen ( logon_script ) + 1 ;
else
logon_script_len = 0 ;
if ( ! IS_SAM_DEFAULT ( sampass , PDB_PROFILE ) )
profile_path = pdb_get_profile_path ( sampass ) ;
else
profile_path = NULL ;
if ( profile_path )
profile_path_len = strlen ( profile_path ) + 1 ;
else
profile_path_len = 0 ;
lm_pw = pdb_get_lanman_passwd ( sampass ) ;
if ( ! lm_pw )
lm_pw_len = 0 ;
nt_pw = pdb_get_nt_passwd ( sampass ) ;
if ( ! nt_pw )
nt_pw_len = 0 ;
acct_desc = pdb_get_acct_desc ( sampass ) ;
if ( acct_desc )
acct_desc_len = strlen ( acct_desc ) + 1 ;
else
acct_desc_len = 0 ;
workstations = pdb_get_workstations ( sampass ) ;
if ( workstations )
workstations_len = strlen ( workstations ) + 1 ;
else
workstations_len = 0 ;
unknown_str = NULL ;
unknown_str_len = 0 ;
munged_dial = pdb_get_munged_dial ( sampass ) ;
if ( munged_dial )
munged_dial_len = strlen ( munged_dial ) + 1 ;
else
munged_dial_len = 0 ;
/* one time to get the size needed */
2004-02-13 17:48:20 +03:00
len = tdb_pack ( NULL , 0 , TDB_FORMAT_STRING_V0 ,
2003-07-09 01:58:29 +04:00
logon_time ,
logoff_time ,
kickoff_time ,
pass_last_set_time ,
pass_can_change_time ,
pass_must_change_time ,
username_len , username ,
domain_len , domain ,
nt_username_len , nt_username ,
fullname_len , fullname ,
homedir_len , homedir ,
dir_drive_len , dir_drive ,
logon_script_len , logon_script ,
profile_path_len , profile_path ,
acct_desc_len , acct_desc ,
workstations_len , workstations ,
unknown_str_len , unknown_str ,
munged_dial_len , munged_dial ,
user_rid ,
group_rid ,
lm_pw_len , lm_pw ,
nt_pw_len , nt_pw ,
pdb_get_acct_ctrl ( sampass ) ,
2004-02-13 17:48:20 +03:00
0 , /* was: fileds_present, to be removed on format change */
2003-07-09 01:58:29 +04:00
pdb_get_logon_divs ( sampass ) ,
pdb_get_hours_len ( sampass ) ,
MAX_HOURS_LEN , pdb_get_hours ( sampass ) ,
2003-09-19 03:53:48 +04:00
pdb_get_bad_password_count ( sampass ) ,
pdb_get_logon_count ( sampass ) ,
2003-07-09 01:58:29 +04:00
pdb_get_unknown_6 ( sampass ) ) ;
if ( size_only )
return buflen ;
/* malloc the space needed */
if ( ( * buf = ( uint8 * ) malloc ( len ) ) = = NULL ) {
DEBUG ( 0 , ( " init_buffer_from_sam: Unable to malloc() memory for buffer! \n " ) ) ;
return ( - 1 ) ;
}
/* now for the real call to tdb_pack() */
2004-02-13 17:48:20 +03:00
buflen = tdb_pack ( ( char * ) * buf , len , TDB_FORMAT_STRING_V0 ,
2003-07-09 01:58:29 +04:00
logon_time ,
logoff_time ,
kickoff_time ,
pass_last_set_time ,
pass_can_change_time ,
pass_must_change_time ,
username_len , username ,
domain_len , domain ,
nt_username_len , nt_username ,
fullname_len , fullname ,
homedir_len , homedir ,
dir_drive_len , dir_drive ,
logon_script_len , logon_script ,
profile_path_len , profile_path ,
acct_desc_len , acct_desc ,
workstations_len , workstations ,
unknown_str_len , unknown_str ,
munged_dial_len , munged_dial ,
user_rid ,
group_rid ,
lm_pw_len , lm_pw ,
nt_pw_len , nt_pw ,
pdb_get_acct_ctrl ( sampass ) ,
2004-02-13 17:48:20 +03:00
0 , /* was: fileds_present, to be removed on format change */
pdb_get_logon_divs ( sampass ) ,
pdb_get_hours_len ( sampass ) ,
MAX_HOURS_LEN , pdb_get_hours ( sampass ) ,
pdb_get_bad_password_count ( sampass ) ,
pdb_get_logon_count ( sampass ) ,
pdb_get_unknown_6 ( sampass ) ) ;
/* check to make sure we got it correct */
if ( buflen ! = len ) {
DEBUG ( 0 , ( " init_buffer_from_sam: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations! \n " ,
( unsigned long ) buflen , ( unsigned long ) len ) ) ;
/* error */
SAFE_FREE ( * buf ) ;
return ( - 1 ) ;
}
return ( buflen ) ;
}
BOOL init_sam_from_buffer_v1 ( SAM_ACCOUNT * sampass , uint8 * buf , uint32 buflen )
{
/* times are stored as 32bit integer
take care on system with 64 bit wide time_t
- - SSS */
uint32 logon_time ,
logoff_time ,
kickoff_time ,
bad_password_time ,
pass_last_set_time ,
pass_can_change_time ,
pass_must_change_time ;
char * username ;
char * domain ;
char * nt_username ;
char * dir_drive ;
char * unknown_str ;
char * munged_dial ;
char * fullname ;
char * homedir ;
char * logon_script ;
char * profile_path ;
char * acct_desc ;
char * workstations ;
uint32 username_len , domain_len , nt_username_len ,
dir_drive_len , unknown_str_len , munged_dial_len ,
fullname_len , homedir_len , logon_script_len ,
profile_path_len , acct_desc_len , workstations_len ;
uint32 user_rid , group_rid , remove_me , hours_len , unknown_6 ;
uint16 acct_ctrl , logon_divs ;
uint16 bad_password_count , logon_count ;
uint8 * hours ;
static uint8 * lm_pw_ptr , * nt_pw_ptr ;
uint32 len = 0 ;
uint32 lm_pw_len , nt_pw_len , hourslen ;
BOOL ret = True ;
if ( sampass = = NULL | | buf = = NULL ) {
DEBUG ( 0 , ( " init_sam_from_buffer: NULL parameters found! \n " ) ) ;
return False ;
}
/* unpack the buffer into variables */
len = tdb_unpack ( ( char * ) buf , buflen , TDB_FORMAT_STRING_V1 ,
& logon_time ,
& logoff_time ,
& kickoff_time ,
& bad_password_time ,
& pass_last_set_time ,
& pass_can_change_time ,
& pass_must_change_time ,
& username_len , & username ,
& domain_len , & domain ,
& nt_username_len , & nt_username ,
& fullname_len , & fullname ,
& homedir_len , & homedir ,
& dir_drive_len , & dir_drive ,
& logon_script_len , & logon_script ,
& profile_path_len , & profile_path ,
& acct_desc_len , & acct_desc ,
& workstations_len , & workstations ,
& unknown_str_len , & unknown_str ,
& munged_dial_len , & munged_dial ,
& user_rid ,
& group_rid ,
& lm_pw_len , & lm_pw_ptr ,
& nt_pw_len , & nt_pw_ptr ,
& acct_ctrl ,
& remove_me ,
& logon_divs ,
& hours_len ,
& hourslen , & hours ,
& bad_password_count ,
& logon_count ,
& unknown_6 ) ;
2004-02-19 21:35:43 +03:00
if ( len = = ( uint32 ) - 1 ) {
2004-02-13 17:48:20 +03:00
ret = False ;
goto done ;
}
pdb_set_logon_time ( sampass , logon_time , PDB_SET ) ;
pdb_set_logoff_time ( sampass , logoff_time , PDB_SET ) ;
pdb_set_kickoff_time ( sampass , kickoff_time , PDB_SET ) ;
2004-02-19 18:59:35 +03:00
pdb_set_bad_password_time ( sampass , bad_password_time , PDB_SET ) ;
2004-02-13 17:48:20 +03:00
pdb_set_pass_can_change_time ( sampass , pass_can_change_time , PDB_SET ) ;
pdb_set_pass_must_change_time ( sampass , pass_must_change_time , PDB_SET ) ;
pdb_set_pass_last_set_time ( sampass , pass_last_set_time , PDB_SET ) ;
pdb_set_username ( sampass , username , PDB_SET ) ;
pdb_set_domain ( sampass , domain , PDB_SET ) ;
pdb_set_nt_username ( sampass , nt_username , PDB_SET ) ;
pdb_set_fullname ( sampass , fullname , PDB_SET ) ;
if ( homedir ) {
pdb_set_homedir ( sampass , homedir , PDB_SET ) ;
}
else {
pdb_set_homedir ( sampass ,
talloc_sub_basic ( sampass - > mem_ctx , username , lp_logon_home ( ) ) ,
PDB_DEFAULT ) ;
}
if ( dir_drive )
pdb_set_dir_drive ( sampass , dir_drive , PDB_SET ) ;
else {
pdb_set_dir_drive ( sampass ,
talloc_sub_basic ( sampass - > mem_ctx , username , lp_logon_drive ( ) ) ,
PDB_DEFAULT ) ;
}
if ( logon_script )
pdb_set_logon_script ( sampass , logon_script , PDB_SET ) ;
else {
pdb_set_logon_script ( sampass ,
talloc_sub_basic ( sampass - > mem_ctx , username , lp_logon_script ( ) ) ,
PDB_DEFAULT ) ;
}
if ( profile_path ) {
pdb_set_profile_path ( sampass , profile_path , PDB_SET ) ;
} else {
pdb_set_profile_path ( sampass ,
talloc_sub_basic ( sampass - > mem_ctx , username , lp_logon_path ( ) ) ,
PDB_DEFAULT ) ;
}
pdb_set_acct_desc ( sampass , acct_desc , PDB_SET ) ;
pdb_set_workstations ( sampass , workstations , PDB_SET ) ;
pdb_set_munged_dial ( sampass , munged_dial , PDB_SET ) ;
if ( lm_pw_ptr & & lm_pw_len = = LM_HASH_LEN ) {
if ( ! pdb_set_lanman_passwd ( sampass , lm_pw_ptr , PDB_SET ) ) {
ret = False ;
goto done ;
}
}
if ( nt_pw_ptr & & nt_pw_len = = NT_HASH_LEN ) {
if ( ! pdb_set_nt_passwd ( sampass , nt_pw_ptr , PDB_SET ) ) {
ret = False ;
goto done ;
}
}
pdb_set_user_sid_from_rid ( sampass , user_rid , PDB_SET ) ;
pdb_set_group_sid_from_rid ( sampass , group_rid , PDB_SET ) ;
pdb_set_hours_len ( sampass , hours_len , PDB_SET ) ;
pdb_set_bad_password_count ( sampass , bad_password_count , PDB_SET ) ;
pdb_set_logon_count ( sampass , logon_count , PDB_SET ) ;
pdb_set_unknown_6 ( sampass , unknown_6 , PDB_SET ) ;
pdb_set_acct_ctrl ( sampass , acct_ctrl , PDB_SET ) ;
pdb_set_logon_divs ( sampass , logon_divs , PDB_SET ) ;
pdb_set_hours ( sampass , hours , PDB_SET ) ;
done :
SAFE_FREE ( username ) ;
SAFE_FREE ( domain ) ;
SAFE_FREE ( nt_username ) ;
SAFE_FREE ( fullname ) ;
SAFE_FREE ( homedir ) ;
SAFE_FREE ( dir_drive ) ;
SAFE_FREE ( logon_script ) ;
SAFE_FREE ( profile_path ) ;
SAFE_FREE ( acct_desc ) ;
SAFE_FREE ( workstations ) ;
SAFE_FREE ( munged_dial ) ;
SAFE_FREE ( unknown_str ) ;
SAFE_FREE ( hours ) ;
return ret ;
}
uint32 init_buffer_from_sam_v1 ( uint8 * * buf , const SAM_ACCOUNT * sampass , BOOL size_only )
{
size_t len , buflen ;
/* times are stored as 32bit integer
take care on system with 64 bit wide time_t
- - SSS */
uint32 logon_time ,
logoff_time ,
kickoff_time ,
bad_password_time ,
pass_last_set_time ,
pass_can_change_time ,
pass_must_change_time ;
uint32 user_rid , group_rid ;
const char * username ;
const char * domain ;
const char * nt_username ;
const char * dir_drive ;
const char * unknown_str ;
const char * munged_dial ;
const char * fullname ;
const char * homedir ;
const char * logon_script ;
const char * profile_path ;
const char * acct_desc ;
const char * workstations ;
uint32 username_len , domain_len , nt_username_len ,
dir_drive_len , unknown_str_len , munged_dial_len ,
fullname_len , homedir_len , logon_script_len ,
profile_path_len , acct_desc_len , workstations_len ;
const uint8 * lm_pw ;
const uint8 * nt_pw ;
uint32 lm_pw_len = 16 ;
uint32 nt_pw_len = 16 ;
/* do we have a valid SAM_ACCOUNT pointer? */
if ( sampass = = NULL ) {
DEBUG ( 0 , ( " init_buffer_from_sam: SAM_ACCOUNT is NULL! \n " ) ) ;
return - 1 ;
}
* buf = NULL ;
buflen = 0 ;
logon_time = ( uint32 ) pdb_get_logon_time ( sampass ) ;
logoff_time = ( uint32 ) pdb_get_logoff_time ( sampass ) ;
kickoff_time = ( uint32 ) pdb_get_kickoff_time ( sampass ) ;
2004-02-19 18:59:35 +03:00
bad_password_time = ( uint32 ) pdb_get_bad_password_time ( sampass ) ;
2004-02-13 17:48:20 +03:00
pass_can_change_time = ( uint32 ) pdb_get_pass_can_change_time ( sampass ) ;
pass_must_change_time = ( uint32 ) pdb_get_pass_must_change_time ( sampass ) ;
pass_last_set_time = ( uint32 ) pdb_get_pass_last_set_time ( sampass ) ;
user_rid = pdb_get_user_rid ( sampass ) ;
group_rid = pdb_get_group_rid ( sampass ) ;
username = pdb_get_username ( sampass ) ;
if ( username )
username_len = strlen ( username ) + 1 ;
else
username_len = 0 ;
domain = pdb_get_domain ( sampass ) ;
if ( domain )
domain_len = strlen ( domain ) + 1 ;
else
domain_len = 0 ;
nt_username = pdb_get_nt_username ( sampass ) ;
if ( nt_username )
nt_username_len = strlen ( nt_username ) + 1 ;
else
nt_username_len = 0 ;
fullname = pdb_get_fullname ( sampass ) ;
if ( fullname )
fullname_len = strlen ( fullname ) + 1 ;
else
fullname_len = 0 ;
/*
* Only updates fields which have been set ( not defaults from smb . conf )
*/
if ( ! IS_SAM_DEFAULT ( sampass , PDB_DRIVE ) )
dir_drive = pdb_get_dir_drive ( sampass ) ;
else
dir_drive = NULL ;
if ( dir_drive )
dir_drive_len = strlen ( dir_drive ) + 1 ;
else
dir_drive_len = 0 ;
if ( ! IS_SAM_DEFAULT ( sampass , PDB_SMBHOME ) )
homedir = pdb_get_homedir ( sampass ) ;
else
homedir = NULL ;
if ( homedir )
homedir_len = strlen ( homedir ) + 1 ;
else
homedir_len = 0 ;
if ( ! IS_SAM_DEFAULT ( sampass , PDB_LOGONSCRIPT ) )
logon_script = pdb_get_logon_script ( sampass ) ;
else
logon_script = NULL ;
if ( logon_script )
logon_script_len = strlen ( logon_script ) + 1 ;
else
logon_script_len = 0 ;
if ( ! IS_SAM_DEFAULT ( sampass , PDB_PROFILE ) )
profile_path = pdb_get_profile_path ( sampass ) ;
else
profile_path = NULL ;
if ( profile_path )
profile_path_len = strlen ( profile_path ) + 1 ;
else
profile_path_len = 0 ;
lm_pw = pdb_get_lanman_passwd ( sampass ) ;
if ( ! lm_pw )
lm_pw_len = 0 ;
nt_pw = pdb_get_nt_passwd ( sampass ) ;
if ( ! nt_pw )
nt_pw_len = 0 ;
acct_desc = pdb_get_acct_desc ( sampass ) ;
if ( acct_desc )
acct_desc_len = strlen ( acct_desc ) + 1 ;
else
acct_desc_len = 0 ;
workstations = pdb_get_workstations ( sampass ) ;
if ( workstations )
workstations_len = strlen ( workstations ) + 1 ;
else
workstations_len = 0 ;
unknown_str = NULL ;
unknown_str_len = 0 ;
munged_dial = pdb_get_munged_dial ( sampass ) ;
if ( munged_dial )
munged_dial_len = strlen ( munged_dial ) + 1 ;
else
munged_dial_len = 0 ;
/* one time to get the size needed */
len = tdb_pack ( NULL , 0 , TDB_FORMAT_STRING_V1 ,
logon_time ,
logoff_time ,
kickoff_time ,
bad_password_time ,
pass_last_set_time ,
pass_can_change_time ,
pass_must_change_time ,
username_len , username ,
domain_len , domain ,
nt_username_len , nt_username ,
fullname_len , fullname ,
homedir_len , homedir ,
dir_drive_len , dir_drive ,
logon_script_len , logon_script ,
profile_path_len , profile_path ,
acct_desc_len , acct_desc ,
workstations_len , workstations ,
unknown_str_len , unknown_str ,
munged_dial_len , munged_dial ,
user_rid ,
group_rid ,
lm_pw_len , lm_pw ,
nt_pw_len , nt_pw ,
pdb_get_acct_ctrl ( sampass ) ,
0 ,
pdb_get_logon_divs ( sampass ) ,
pdb_get_hours_len ( sampass ) ,
MAX_HOURS_LEN , pdb_get_hours ( sampass ) ,
pdb_get_bad_password_count ( sampass ) ,
pdb_get_logon_count ( sampass ) ,
pdb_get_unknown_6 ( sampass ) ) ;
if ( size_only )
return buflen ;
/* malloc the space needed */
if ( ( * buf = ( uint8 * ) malloc ( len ) ) = = NULL ) {
DEBUG ( 0 , ( " init_buffer_from_sam: Unable to malloc() memory for buffer! \n " ) ) ;
return ( - 1 ) ;
}
/* now for the real call to tdb_pack() */
buflen = tdb_pack ( ( char * ) * buf , len , TDB_FORMAT_STRING_V1 ,
logon_time ,
logoff_time ,
kickoff_time ,
bad_password_time ,
pass_last_set_time ,
pass_can_change_time ,
pass_must_change_time ,
username_len , username ,
domain_len , domain ,
nt_username_len , nt_username ,
fullname_len , fullname ,
homedir_len , homedir ,
dir_drive_len , dir_drive ,
logon_script_len , logon_script ,
profile_path_len , profile_path ,
acct_desc_len , acct_desc ,
workstations_len , workstations ,
unknown_str_len , unknown_str ,
munged_dial_len , munged_dial ,
user_rid ,
group_rid ,
lm_pw_len , lm_pw ,
nt_pw_len , nt_pw ,
pdb_get_acct_ctrl ( sampass ) ,
0 ,
2003-07-09 01:58:29 +04:00
pdb_get_logon_divs ( sampass ) ,
pdb_get_hours_len ( sampass ) ,
MAX_HOURS_LEN , pdb_get_hours ( sampass ) ,
2003-09-19 03:53:48 +04:00
pdb_get_bad_password_count ( sampass ) ,
pdb_get_logon_count ( sampass ) ,
2003-07-09 01:58:29 +04:00
pdb_get_unknown_6 ( sampass ) ) ;
/* check to make sure we got it correct */
if ( buflen ! = len ) {
2003-07-25 08:24:40 +04:00
DEBUG ( 0 , ( " init_buffer_from_sam: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations! \n " ,
( unsigned long ) buflen , ( unsigned long ) len ) ) ;
2003-07-09 01:58:29 +04:00
/* error */
SAFE_FREE ( * buf ) ;
return ( - 1 ) ;
}
return ( buflen ) ;
}
2003-08-13 04:08:28 +04:00
/**********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL get_free_ugid_range ( uint32 * low , uint32 * high )
{
uid_t u_low , u_high ;
gid_t g_low , g_high ;
if ( ! lp_idmap_uid ( & u_low , & u_high ) | | ! lp_idmap_gid ( & g_low , & g_high ) ) {
return False ;
}
* low = ( u_low < g_low ) ? u_low : g_low ;
* high = ( u_high < g_high ) ? u_high : g_high ;
return True ;
}
/******************************************************************
Get the the non - algorithmic RID range if idmap range are defined
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL get_free_rid_range ( uint32 * low , uint32 * high )
{
uint32 id_low , id_high ;
if ( ! lp_enable_rid_algorithm ( ) ) {
* low = BASE_RID ;
* high = ( uint32 ) - 1 ;
}
if ( ! get_free_ugid_range ( & id_low , & id_high ) ) {
return False ;
}
* low = fallback_pdb_uid_to_user_rid ( id_low ) ;
if ( fallback_pdb_user_rid_to_uid ( ( uint32 ) - 1 ) < id_high ) {
* high = ( uint32 ) - 1 ;
} else {
* high = fallback_pdb_uid_to_user_rid ( id_high ) ;
}
return True ;
}
2004-02-19 21:35:43 +03:00
/*********************************************************************
Update the bad password count checking the AP_RESET_COUNT_TIME
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL pdb_update_bad_password_count ( SAM_ACCOUNT * sampass , BOOL * updated )
{
time_t LastBadPassword ;
uint16 BadPasswordCount ;
uint32 resettime ;
2004-02-20 00:37:24 +03:00
if ( ! sampass ) return False ;
2004-02-19 21:35:43 +03:00
BadPasswordCount = pdb_get_bad_password_count ( sampass ) ;
2004-02-20 00:37:24 +03:00
if ( ! BadPasswordCount ) {
DEBUG ( 9 , ( " No bad password attempts. \n " ) ) ;
return True ;
}
if ( ! account_policy_get ( AP_RESET_COUNT_TIME , & resettime ) ) {
DEBUG ( 0 , ( " pdb_update_bad_password_count: account_policy_get failed. \n " ) ) ;
return False ;
}
/* First, check if there is a reset time to compare */
2004-02-20 19:00:25 +03:00
if ( ( resettime = = ( uint32 ) - 1 ) | | ( resettime = = 0 ) ) {
DEBUG ( 9 , ( " No reset time, can't reset bad pw count \n " ) ) ;
2004-02-20 00:37:24 +03:00
return True ;
}
LastBadPassword = pdb_get_bad_password_time ( sampass ) ;
DEBUG ( 7 , ( " LastBadPassword=%d, resettime=%d, current time=%d. \n " ,
( uint32 ) LastBadPassword , resettime , ( uint32 ) time ( NULL ) ) ) ;
if ( time ( NULL ) > ( LastBadPassword + ( time_t ) resettime * 60 ) ) {
pdb_set_bad_password_count ( sampass , 0 , PDB_CHANGED ) ;
pdb_set_bad_password_time ( sampass , 0 , PDB_CHANGED ) ;
if ( updated ) * updated = True ;
2004-02-19 21:35:43 +03:00
}
2004-02-20 00:37:24 +03:00
2004-02-19 21:35:43 +03:00
return True ;
}
/*********************************************************************
Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL pdb_update_autolock_flag ( SAM_ACCOUNT * sampass , BOOL * updated )
{
uint32 duration ;
time_t LastBadPassword ;
2004-02-20 00:37:24 +03:00
if ( ! sampass ) return False ;
2004-02-19 21:35:43 +03:00
2004-02-20 00:37:24 +03:00
if ( ! ( pdb_get_acct_ctrl ( sampass ) & ACB_AUTOLOCK ) ) {
DEBUG ( 9 , ( " Account not autolocked, no check needed \n " ) ) ;
return True ;
2004-02-19 21:35:43 +03:00
}
2004-02-20 00:37:24 +03:00
if ( ! account_policy_get ( AP_LOCK_ACCOUNT_DURATION , & duration ) ) {
DEBUG ( 0 , ( " pdb_update_autolock_flag: account_policy_get failed. \n " ) ) ;
return False ;
}
/* First, check if there is a duration to compare */
2004-02-20 19:00:25 +03:00
if ( ( duration = = ( uint32 ) - 1 ) | | ( duration = = 0 ) ) {
DEBUG ( 9 , ( " No reset duration, can't reset autolock \n " ) ) ;
2004-02-20 00:37:24 +03:00
return True ;
}
LastBadPassword = pdb_get_bad_password_time ( sampass ) ;
DEBUG ( 7 , ( " LastBadPassword=%d, duration=%d, current time =%d. \n " ,
( uint32 ) LastBadPassword , duration * 60 , ( uint32 ) time ( NULL ) ) ) ;
if ( ( time ( NULL ) > ( LastBadPassword + ( time_t ) duration * 60 ) ) ) {
pdb_set_acct_ctrl ( sampass ,
pdb_get_acct_ctrl ( sampass ) & ~ ACB_AUTOLOCK ,
PDB_CHANGED ) ;
pdb_set_bad_password_count ( sampass , 0 , PDB_CHANGED ) ;
pdb_set_bad_password_time ( sampass , 0 , PDB_CHANGED ) ;
if ( updated ) * updated = True ;
}
2004-02-19 21:35:43 +03:00
return True ;
}
/*********************************************************************
Increment the bad_password_count
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL pdb_increment_bad_password_count ( SAM_ACCOUNT * sampass )
{
uint32 account_policy_lockout ;
2004-02-20 00:37:24 +03:00
BOOL autolock_updated = False , badpw_updated = False ;
2004-02-19 21:35:43 +03:00
if ( ! sampass )
return False ;
2004-02-20 00:37:24 +03:00
/* Retrieve the account lockout policy */
if ( ! account_policy_get ( AP_BAD_ATTEMPT_LOCKOUT ,
& account_policy_lockout ) ) {
DEBUG ( 0 , ( " pdb_increment_bad_password_count: account_policy_get failed. \n " ) ) ;
2004-02-19 21:35:43 +03:00
return False ;
2004-02-20 00:37:24 +03:00
}
2004-02-19 21:35:43 +03:00
2004-02-20 00:37:24 +03:00
/* If there is no policy, we don't need to continue checking */
if ( ! account_policy_lockout ) {
DEBUG ( 9 , ( " No lockout policy, don't track bad passwords \n " ) ) ;
2004-02-19 21:35:43 +03:00
return True ;
}
2004-02-20 00:37:24 +03:00
/* Check if the autolock needs to be cleared */
if ( ! pdb_update_autolock_flag ( sampass , & autolock_updated ) )
return False ;
/* Check if the badpw count needs to be reset */
if ( ! pdb_update_bad_password_count ( sampass , & badpw_updated ) )
return False ;
/*
Ok , now we can assume that any resetting that needs to be
done has been done , and just get on with incrementing
and autolocking if necessary
*/
pdb_set_bad_password_count ( sampass ,
pdb_get_bad_password_count ( sampass ) + 1 ,
PDB_CHANGED ) ;
pdb_set_bad_password_time ( sampass , time ( NULL ) , PDB_CHANGED ) ;
if ( pdb_get_bad_password_count ( sampass ) < account_policy_lockout )
return True ;
if ( ! pdb_set_acct_ctrl ( sampass ,
pdb_get_acct_ctrl ( sampass ) | ACB_AUTOLOCK ,
PDB_CHANGED ) ) {
DEBUG ( 1 , ( " pdb_increment_bad_password_count:failed to set 'autolock' flag. \n " ) ) ;
return False ;
}
return True ;
2004-02-19 21:35:43 +03:00
}