2006-02-04 01:19:41 +03:00
/*
Unix SMB / CIFS implementation .
Winbind daemon - cached credentials funcions
Copyright ( C ) Guenther Deschner 2005
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2006-02-04 01:19:41 +03:00
( 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
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2006-02-04 01:19:41 +03:00
*/
# include "includes.h"
# include "winbindd.h"
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_WINBIND
# define MAX_CACHED_LOGINS 10
NTSTATUS winbindd_get_creds ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
const DOM_SID * sid ,
2008-02-17 04:08:12 +03:00
struct netr_SamInfo3 * * info3 ,
2006-08-20 07:53:42 +04:00
const uint8 * cached_nt_pass [ NT_HASH_LEN ] ,
const uint8 * cred_salt [ NT_HASH_LEN ] )
2006-02-04 01:19:41 +03:00
{
2008-02-17 04:08:12 +03:00
struct netr_SamInfo3 * info ;
2006-02-04 01:19:41 +03:00
NTSTATUS status ;
2006-08-20 07:53:42 +04:00
status = wcache_get_creds ( domain , mem_ctx , sid , cached_nt_pass , cred_salt ) ;
2006-02-04 01:19:41 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
info = netsamlogon_cache_get ( mem_ctx , sid ) ;
if ( info = = NULL ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
* info3 = info ;
return NT_STATUS_OK ;
}
NTSTATUS winbindd_store_creds ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
const char * user ,
const char * pass ,
2008-02-17 04:08:12 +03:00
struct netr_SamInfo3 * info3 ,
2006-02-04 01:19:41 +03:00
const DOM_SID * user_sid )
{
NTSTATUS status ;
uchar nt_pass [ NT_HASH_LEN ] ;
DOM_SID cred_sid ;
if ( info3 ! = NULL ) {
DOM_SID sid ;
2008-02-17 04:08:12 +03:00
sid_copy ( & sid , info3 - > base . domain_sid ) ;
sid_append_rid ( & sid , info3 - > base . rid ) ;
2006-02-04 01:19:41 +03:00
sid_copy ( & cred_sid , & sid ) ;
2008-02-17 04:08:12 +03:00
info3 - > base . user_flags | = NETLOGON_CACHED_ACCOUNT ;
2006-02-04 01:19:41 +03:00
} else if ( user_sid ! = NULL ) {
sid_copy ( & cred_sid , user_sid ) ;
} else if ( user ! = NULL ) {
/* do lookup ourself */
2006-09-08 18:28:06 +04:00
enum lsa_SidType type ;
2006-02-04 01:19:41 +03:00
if ( ! lookup_cached_name ( mem_ctx ,
domain - > name ,
user ,
& cred_sid ,
& type ) ) {
return NT_STATUS_NO_SUCH_USER ;
}
} else {
return NT_STATUS_INVALID_PARAMETER ;
}
if ( pass ) {
int count = 0 ;
status = wcache_count_cached_creds ( domain , & count ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
DEBUG ( 11 , ( " we have %d cached creds \n " , count ) ) ;
if ( count + 1 > MAX_CACHED_LOGINS ) {
DEBUG ( 10 , ( " need to delete the oldest cached login \n " ) ) ;
status = wcache_remove_oldest_cached_creds ( domain , & cred_sid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " failed to remove oldest cached cred: %s \n " ,
nt_errstr ( status ) ) ) ;
return status ;
}
}
E_md4hash ( pass , nt_pass ) ;
2007-08-15 00:43:02 +04:00
dump_data_pw ( " nt_pass " , nt_pass , NT_HASH_LEN ) ;
2006-02-04 01:19:41 +03:00
status = wcache_save_creds ( domain , mem_ctx , & cred_sid , nt_pass ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
}
if ( info3 ! = NULL & & user ! = NULL ) {
if ( ! netsamlogon_cache_store ( user , info3 ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
}
return NT_STATUS_OK ;
}
NTSTATUS winbindd_update_creds_by_info3 ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
const char * user ,
const char * pass ,
2008-02-17 04:08:12 +03:00
struct netr_SamInfo3 * info3 )
2006-02-04 01:19:41 +03:00
{
return winbindd_store_creds ( domain , mem_ctx , user , pass , info3 , NULL ) ;
}
NTSTATUS winbindd_update_creds_by_sid ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
const DOM_SID * sid ,
const char * pass )
{
return winbindd_store_creds ( domain , mem_ctx , NULL , pass , NULL , sid ) ;
}
NTSTATUS winbindd_update_creds_by_name ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
const char * user ,
const char * pass )
{
return winbindd_store_creds ( domain , mem_ctx , user , pass , NULL , NULL ) ;
}