2004-05-03 18:58:08 +04:00
/*
Unix SMB / CIFS implementation .
interface functions for the sam database
Copyright ( C ) Andrew Tridgell 2004
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2004-11-02 05:57:18 +03:00
# include "librpc/gen_ndr/ndr_netlogon.h"
2005-07-28 02:14:55 +04:00
# include "librpc/gen_ndr/ndr_misc.h"
2004-11-16 12:00:52 +03:00
# include "lib/ldb/include/ldb.h"
2005-12-10 02:39:00 +03:00
# include "lib/ldb/include/ldb_errors.h"
2005-01-12 05:40:25 +03:00
# include "system/time.h"
2005-02-10 08:09:35 +03:00
# include "system/filesys.h"
2005-02-10 10:22:25 +03:00
# include "db_wrap.h"
2004-05-03 18:58:08 +04:00
/*
connect to the SAM database
2004-05-06 16:42:42 +04:00
return an opaque context pointer on success , or NULL on failure
2004-05-03 18:58:08 +04:00
*/
2005-10-07 15:31:45 +04:00
struct ldb_context * samdb_connect ( TALLOC_CTX * mem_ctx , struct auth_session_info * session_info )
2004-05-03 18:58:08 +04:00
{
2005-10-07 15:31:45 +04:00
struct ldb_context * ldb ;
ldb = ldb_wrap_connect ( mem_ctx , lp_sam_url ( ) , 0 , NULL ) ;
if ( ldb_set_opaque ( ldb , " sessionInfo " , session_info ) ) {
return NULL ;
}
return ldb ;
2004-05-06 16:42:42 +04:00
}
2004-05-06 13:55:05 +04:00
2004-12-30 20:01:49 +03:00
/*
search the sam for the specified attributes in a specific domain , filter on
objectSid being in domain_sid .
*/
2005-02-27 14:35:47 +03:00
int samdb_search_domain ( struct ldb_context * sam_ldb ,
2004-12-30 20:01:49 +03:00
TALLOC_CTX * mem_ctx ,
2005-08-18 19:02:01 +04:00
const struct ldb_dn * basedn ,
2004-12-30 20:01:49 +03:00
struct ldb_message * * * res ,
const char * const * attrs ,
const struct dom_sid * domain_sid ,
const char * format , . . . ) _PRINTF_ATTRIBUTE ( 7 , 8 )
{
va_list ap ;
int i , count ;
va_start ( ap , format ) ;
2005-06-15 21:15:01 +04:00
count = gendb_search_v ( sam_ldb , mem_ctx , basedn ,
res , attrs , format , ap ) ;
2004-12-30 20:01:49 +03:00
va_end ( ap ) ;
i = 0 ;
while ( i < count ) {
struct dom_sid * entry_sid ;
2005-06-24 04:18:20 +04:00
entry_sid = samdb_result_dom_sid ( mem_ctx , ( * res ) [ i ] , " objectSid " ) ;
2004-12-30 20:01:49 +03:00
if ( ( entry_sid = = NULL ) | |
( ! dom_sid_in_domain ( domain_sid , entry_sid ) ) ) {
/* Delete that entry from the result set */
( * res ) [ i ] = ( * res ) [ count - 1 ] ;
count - = 1 ;
2005-06-24 04:18:20 +04:00
talloc_free ( entry_sid ) ;
2004-12-30 20:01:49 +03:00
continue ;
}
2005-06-24 04:18:20 +04:00
talloc_free ( entry_sid ) ;
2004-12-30 20:01:49 +03:00
i + = 1 ;
}
return count ;
}
2004-05-03 18:58:08 +04:00
/*
search the sam for a single string attribute in exactly 1 record
*/
2005-02-27 14:35:47 +03:00
const char * samdb_search_string_v ( struct ldb_context * sam_ldb ,
2004-05-08 04:02:31 +04:00
TALLOC_CTX * mem_ctx ,
2005-08-18 19:02:01 +04:00
const struct ldb_dn * basedn ,
2004-05-08 04:02:31 +04:00
const char * attr_name ,
2004-08-25 11:15:21 +04:00
const char * format , va_list ap ) _PRINTF_ATTRIBUTE ( 5 , 0 )
2004-05-03 18:58:08 +04:00
{
int count ;
2005-07-22 15:32:01 +04:00
const char * attrs [ 2 ] = { NULL , NULL } ;
2004-05-03 18:58:08 +04:00
struct ldb_message * * res = NULL ;
2005-07-22 15:32:01 +04:00
attrs [ 0 ] = attr_name ;
2005-02-27 14:35:47 +03:00
count = gendb_search_v ( sam_ldb , mem_ctx , basedn , & res , attrs , format , ap ) ;
2004-05-08 04:02:31 +04:00
if ( count > 1 ) {
DEBUG ( 1 , ( " samdb: search for %s %s not single valued (count=%d) \n " ,
attr_name , format , count ) ) ;
2004-05-03 18:58:08 +04:00
}
2004-05-08 04:02:31 +04:00
if ( count ! = 1 ) {
2005-04-25 16:46:18 +04:00
talloc_free ( res ) ;
2004-05-03 18:58:08 +04:00
return NULL ;
}
2004-05-08 04:02:31 +04:00
return samdb_result_string ( res [ 0 ] , attr_name , NULL ) ;
}
/*
search the sam for a single string attribute in exactly 1 record
*/
2005-02-27 14:35:47 +03:00
const char * samdb_search_string ( struct ldb_context * sam_ldb ,
2004-05-08 04:02:31 +04:00
TALLOC_CTX * mem_ctx ,
2005-08-18 19:02:01 +04:00
const struct ldb_dn * basedn ,
2004-05-08 04:02:31 +04:00
const char * attr_name ,
2004-05-26 12:02:20 +04:00
const char * format , . . . ) _PRINTF_ATTRIBUTE ( 5 , 6 )
2004-05-08 04:02:31 +04:00
{
va_list ap ;
const char * str ;
2004-05-03 18:58:08 +04:00
2004-05-08 04:02:31 +04:00
va_start ( ap , format ) ;
2005-02-27 14:35:47 +03:00
str = samdb_search_string_v ( sam_ldb , mem_ctx , basedn , attr_name , format , ap ) ;
2004-05-08 04:02:31 +04:00
va_end ( ap ) ;
2004-05-03 18:58:08 +04:00
return str ;
}
2005-08-26 20:12:25 +04:00
struct ldb_dn * samdb_search_dn ( struct ldb_context * sam_ldb ,
TALLOC_CTX * mem_ctx ,
const struct ldb_dn * basedn ,
const char * format , . . . ) _PRINTF_ATTRIBUTE ( 4 , 5 )
{
va_list ap ;
struct ldb_dn * ret ;
struct ldb_message * * res = NULL ;
int count ;
va_start ( ap , format ) ;
count = gendb_search_v ( sam_ldb , mem_ctx , basedn , & res , NULL , format , ap ) ;
va_end ( ap ) ;
if ( count ! = 1 ) return NULL ;
ret = talloc_steal ( mem_ctx , res [ 0 ] - > dn ) ;
talloc_free ( res ) ;
return ret ;
}
2005-06-24 04:18:20 +04:00
/*
search the sam for a dom_sid attribute in exactly 1 record
*/
struct dom_sid * samdb_search_dom_sid ( struct ldb_context * sam_ldb ,
TALLOC_CTX * mem_ctx ,
2005-08-18 19:02:01 +04:00
const struct ldb_dn * basedn ,
2005-06-24 04:18:20 +04:00
const char * attr_name ,
const char * format , . . . ) _PRINTF_ATTRIBUTE ( 5 , 6 )
{
va_list ap ;
int count ;
struct ldb_message * * res ;
2005-07-22 15:32:01 +04:00
const char * attrs [ 2 ] = { NULL , NULL } ;
2005-06-24 04:18:20 +04:00
struct dom_sid * sid ;
2005-07-22 15:32:01 +04:00
attrs [ 0 ] = attr_name ;
2005-06-24 04:18:20 +04:00
va_start ( ap , format ) ;
count = gendb_search_v ( sam_ldb , mem_ctx , basedn , & res , attrs , format , ap ) ;
va_end ( ap ) ;
if ( count > 1 ) {
DEBUG ( 1 , ( " samdb: search for %s %s not single valued (count=%d) \n " ,
attr_name , format , count ) ) ;
}
if ( count ! = 1 ) {
talloc_free ( res ) ;
return NULL ;
}
sid = samdb_result_dom_sid ( mem_ctx , res [ 0 ] , attr_name ) ;
talloc_free ( res ) ;
return sid ;
}
2004-05-27 08:13:58 +04:00
/*
return the count of the number of records in the sam matching the query
*/
2005-02-27 14:35:47 +03:00
int samdb_search_count ( struct ldb_context * sam_ldb ,
2004-05-27 08:13:58 +04:00
TALLOC_CTX * mem_ctx ,
2005-08-18 19:02:01 +04:00
const struct ldb_dn * basedn ,
2004-05-27 08:13:58 +04:00
const char * format , . . . ) _PRINTF_ATTRIBUTE ( 4 , 5 )
{
va_list ap ;
struct ldb_message * * res ;
const char * const attrs [ ] = { NULL } ;
int ret ;
va_start ( ap , format ) ;
2005-02-27 14:35:47 +03:00
ret = gendb_search_v ( sam_ldb , mem_ctx , basedn , & res , attrs , format , ap ) ;
2004-05-27 08:13:58 +04:00
va_end ( ap ) ;
return ret ;
}
2004-05-09 16:32:25 +04:00
/*
search the sam for a single integer attribute in exactly 1 record
*/
2005-02-27 14:35:47 +03:00
uint_t samdb_search_uint ( struct ldb_context * sam_ldb ,
2004-05-09 16:32:25 +04:00
TALLOC_CTX * mem_ctx ,
uint_t default_value ,
2005-08-18 19:02:01 +04:00
const struct ldb_dn * basedn ,
2004-05-09 16:32:25 +04:00
const char * attr_name ,
2004-05-26 12:02:20 +04:00
const char * format , . . . ) _PRINTF_ATTRIBUTE ( 6 , 7 )
2004-05-09 16:32:25 +04:00
{
va_list ap ;
int count ;
struct ldb_message * * res ;
2005-07-22 15:32:01 +04:00
const char * attrs [ 2 ] = { NULL , NULL } ;
attrs [ 0 ] = attr_name ;
2004-05-09 16:32:25 +04:00
va_start ( ap , format ) ;
2005-02-27 14:35:47 +03:00
count = gendb_search_v ( sam_ldb , mem_ctx , basedn , & res , attrs , format , ap ) ;
2004-05-09 16:32:25 +04:00
va_end ( ap ) ;
if ( count ! = 1 ) {
return default_value ;
}
return samdb_result_uint ( res [ 0 ] , attr_name , default_value ) ;
}
2004-05-25 17:57:39 +04:00
/*
search the sam for a single signed 64 bit integer attribute in exactly 1 record
*/
2005-02-27 14:35:47 +03:00
int64_t samdb_search_int64 ( struct ldb_context * sam_ldb ,
2004-05-25 17:57:39 +04:00
TALLOC_CTX * mem_ctx ,
int64_t default_value ,
2005-08-18 19:02:01 +04:00
const struct ldb_dn * basedn ,
2004-05-25 17:57:39 +04:00
const char * attr_name ,
2004-05-26 12:02:20 +04:00
const char * format , . . . ) _PRINTF_ATTRIBUTE ( 6 , 7 )
2004-05-25 17:57:39 +04:00
{
va_list ap ;
int count ;
struct ldb_message * * res ;
2005-07-22 15:32:01 +04:00
const char * attrs [ 2 ] = { NULL , NULL } ;
attrs [ 0 ] = attr_name ;
2004-05-25 17:57:39 +04:00
va_start ( ap , format ) ;
2005-02-27 14:35:47 +03:00
count = gendb_search_v ( sam_ldb , mem_ctx , basedn , & res , attrs , format , ap ) ;
2004-05-25 17:57:39 +04:00
va_end ( ap ) ;
if ( count ! = 1 ) {
return default_value ;
}
return samdb_result_int64 ( res [ 0 ] , attr_name , default_value ) ;
}
2004-05-03 18:58:08 +04:00
/*
search the sam for multipe records each giving a single string attribute
return the number of matches , or - 1 on error
*/
2005-02-27 14:35:47 +03:00
int samdb_search_string_multiple ( struct ldb_context * sam_ldb ,
2004-05-06 16:42:42 +04:00
TALLOC_CTX * mem_ctx ,
2005-08-18 19:02:01 +04:00
const struct ldb_dn * basedn ,
2004-05-08 04:02:31 +04:00
const char * * * strs ,
2004-05-03 18:58:08 +04:00
const char * attr_name ,
2004-05-26 12:02:20 +04:00
const char * format , . . . ) _PRINTF_ATTRIBUTE ( 6 , 7 )
2004-05-03 18:58:08 +04:00
{
va_list ap ;
int count , i ;
2005-07-22 15:32:01 +04:00
const char * attrs [ 2 ] = { NULL , NULL } ;
2004-05-03 18:58:08 +04:00
struct ldb_message * * res = NULL ;
2005-07-22 15:32:01 +04:00
attrs [ 0 ] = attr_name ;
2004-05-03 18:58:08 +04:00
va_start ( ap , format ) ;
2005-02-27 14:35:47 +03:00
count = gendb_search_v ( sam_ldb , mem_ctx , basedn , & res , attrs , format , ap ) ;
2004-05-03 18:58:08 +04:00
va_end ( ap ) ;
if ( count < = 0 ) {
return count ;
}
/* make sure its single valued */
for ( i = 0 ; i < count ; i + + ) {
2004-05-08 04:02:31 +04:00
if ( res [ i ] - > num_elements ! = 1 ) {
2004-05-03 18:58:08 +04:00
DEBUG ( 1 , ( " samdb: search for %s %s not single valued \n " ,
attr_name , format ) ) ;
2005-04-25 16:46:18 +04:00
talloc_free ( res ) ;
2004-05-03 18:58:08 +04:00
return - 1 ;
}
}
2005-01-27 10:08:20 +03:00
* strs = talloc_array ( mem_ctx , const char * , count + 1 ) ;
2004-05-03 18:58:08 +04:00
if ( ! * strs ) {
2005-04-25 16:46:18 +04:00
talloc_free ( res ) ;
2004-05-03 18:58:08 +04:00
return - 1 ;
}
for ( i = 0 ; i < count ; i + + ) {
2004-05-08 04:02:31 +04:00
( * strs ) [ i ] = samdb_result_string ( res [ i ] , attr_name , NULL ) ;
2004-05-03 18:58:08 +04:00
}
( * strs ) [ count ] = NULL ;
return count ;
}
2004-05-04 11:53:06 +04:00
/*
pull a uint from a result set .
*/
uint_t samdb_result_uint ( struct ldb_message * msg , const char * attr , uint_t default_value )
{
return ldb_msg_find_uint ( msg , attr , default_value ) ;
}
2004-05-08 04:02:31 +04:00
2004-05-25 17:57:39 +04:00
/*
pull a ( signed ) int64 from a result set .
*/
int64_t samdb_result_int64 ( struct ldb_message * msg , const char * attr , int64_t default_value )
{
return ldb_msg_find_int64 ( msg , attr , default_value ) ;
}
2004-05-08 04:02:31 +04:00
/*
pull a string from a result set .
*/
2004-05-08 18:42:45 +04:00
const char * samdb_result_string ( struct ldb_message * msg , const char * attr ,
const char * default_value )
2004-05-08 04:02:31 +04:00
{
return ldb_msg_find_string ( msg , attr , default_value ) ;
}
2005-08-18 19:02:01 +04:00
struct ldb_dn * samdb_result_dn ( TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
const char * attr , struct ldb_dn * default_value )
{
const char * string = samdb_result_string ( msg , attr , NULL ) ;
if ( string = = NULL ) return default_value ;
return ldb_dn_explode ( mem_ctx , string ) ;
}
2004-05-08 18:42:45 +04:00
/*
pull a rid from a objectSid in a result set .
*/
2004-05-25 20:24:13 +04:00
uint32_t samdb_result_rid_from_sid ( TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
2005-06-24 04:18:20 +04:00
const char * attr , uint32_t default_value )
2004-05-08 18:42:45 +04:00
{
struct dom_sid * sid ;
2005-06-24 04:18:20 +04:00
uint32_t rid ;
2004-05-08 18:42:45 +04:00
2005-06-24 04:18:20 +04:00
sid = samdb_result_dom_sid ( mem_ctx , msg , attr ) ;
if ( sid = = NULL ) {
return default_value ;
}
rid = sid - > sub_auths [ sid - > num_auths - 1 ] ;
talloc_free ( sid ) ;
return rid ;
2004-05-08 18:42:45 +04:00
}
2004-05-20 17:29:38 +04:00
/*
pull a dom_sid structure from a objectSid in a result set .
*/
struct dom_sid * samdb_result_dom_sid ( TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
const char * attr )
{
2005-06-24 04:18:20 +04:00
const struct ldb_val * v ;
struct dom_sid * sid ;
NTSTATUS status ;
v = ldb_msg_find_ldb_val ( msg , attr ) ;
if ( v = = NULL ) {
return NULL ;
}
sid = talloc ( mem_ctx , struct dom_sid ) ;
if ( sid = = NULL ) {
return NULL ;
}
status = ndr_pull_struct_blob ( v , sid , sid ,
( ndr_pull_flags_fn_t ) ndr_pull_dom_sid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
talloc_free ( sid ) ;
return NULL ;
}
return sid ;
2004-05-20 17:29:38 +04:00
}
2004-05-27 10:27:21 +04:00
/*
pull a guid structure from a objectGUID in a result set .
*/
struct GUID samdb_result_guid ( struct ldb_message * msg , const char * attr )
{
2005-07-08 09:14:46 +04:00
const struct ldb_val * v ;
2004-05-27 10:27:21 +04:00
NTSTATUS status ;
struct GUID guid ;
2005-07-08 09:14:46 +04:00
TALLOC_CTX * mem_ctx ;
2004-05-27 10:27:21 +04:00
ZERO_STRUCT ( guid ) ;
2005-07-08 09:14:46 +04:00
v = ldb_msg_find_ldb_val ( msg , attr ) ;
if ( ! v ) return guid ;
2004-05-27 10:27:21 +04:00
2005-07-08 09:14:46 +04:00
mem_ctx = talloc_named_const ( NULL , 0 , " samdb_result_guid " ) ;
if ( ! mem_ctx ) return guid ;
status = ndr_pull_struct_blob ( v , mem_ctx , & guid ,
( ndr_pull_flags_fn_t ) ndr_pull_GUID ) ;
talloc_free ( mem_ctx ) ;
2004-05-27 10:27:21 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return guid ;
}
return guid ;
}
2004-05-20 17:29:38 +04:00
/*
pull a sid prefix from a objectSid in a result set .
this is used to find the domain sid for a user
*/
2005-06-24 04:18:20 +04:00
struct dom_sid * samdb_result_sid_prefix ( TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
const char * attr )
2004-05-20 17:29:38 +04:00
{
struct dom_sid * sid = samdb_result_dom_sid ( mem_ctx , msg , attr ) ;
if ( ! sid | | sid - > num_auths < 1 ) return NULL ;
sid - > num_auths - - ;
2005-06-24 04:18:20 +04:00
return sid ;
2004-05-20 17:29:38 +04:00
}
2004-05-08 18:42:45 +04:00
/*
2004-05-09 13:39:47 +04:00
pull a NTTIME in a result set .
2004-05-08 18:42:45 +04:00
*/
2005-08-08 06:42:35 +04:00
NTTIME samdb_result_nttime ( struct ldb_message * msg , const char * attr , NTTIME default_value )
2004-05-08 18:42:45 +04:00
{
2005-08-08 06:42:35 +04:00
const char * str = ldb_msg_find_string ( msg , attr , NULL ) ;
if ( ! str ) return default_value ;
2004-05-08 18:42:45 +04:00
return nttime_from_string ( str ) ;
}
2004-05-09 13:39:47 +04:00
/*
2004-05-25 17:57:39 +04:00
pull a uint64_t from a result set .
2004-05-09 13:39:47 +04:00
*/
2004-05-25 17:57:39 +04:00
uint64_t samdb_result_uint64 ( struct ldb_message * msg , const char * attr , uint64_t default_value )
2004-05-09 13:39:47 +04:00
{
2004-05-25 17:57:39 +04:00
return ldb_msg_find_uint64 ( msg , attr , default_value ) ;
2004-05-09 13:39:47 +04:00
}
/*
2004-06-05 07:22:10 +04:00
construct the allow_password_change field from the PwdLastSet attribute and the
2004-05-09 13:39:47 +04:00
domain password settings
*/
2005-02-27 14:35:47 +03:00
NTTIME samdb_result_allow_password_change ( struct ldb_context * sam_ldb ,
2005-01-11 16:55:45 +03:00
TALLOC_CTX * mem_ctx ,
2005-08-18 19:02:01 +04:00
const struct ldb_dn * domain_dn ,
2004-06-05 07:22:10 +04:00
struct ldb_message * msg ,
const char * attr )
2004-05-09 13:39:47 +04:00
{
2004-05-25 17:57:39 +04:00
uint64_t attr_time = samdb_result_uint64 ( msg , attr , 0 ) ;
int64_t minPwdAge ;
if ( attr_time = = 0 ) {
return 0 ;
2004-05-09 13:39:47 +04:00
}
2004-05-25 17:57:39 +04:00
2005-10-11 15:00:16 +04:00
minPwdAge = samdb_search_int64 ( sam_ldb , mem_ctx , 0 , domain_dn , " minPwdAge " , NULL ) ;
2004-05-25 17:57:39 +04:00
/* yes, this is a -= not a += as minPwdAge is stored as the negative
of the number of 100 - nano - seconds */
attr_time - = minPwdAge ;
return attr_time ;
2004-05-09 13:39:47 +04:00
}
/*
2004-06-05 07:22:10 +04:00
construct the force_password_change field from the PwdLastSet attribute and the
2004-05-09 13:39:47 +04:00
domain password settings
*/
2005-02-27 14:35:47 +03:00
NTTIME samdb_result_force_password_change ( struct ldb_context * sam_ldb ,
2005-01-11 16:55:45 +03:00
TALLOC_CTX * mem_ctx ,
2005-08-18 19:02:01 +04:00
const struct ldb_dn * domain_dn ,
2004-06-05 07:22:10 +04:00
struct ldb_message * msg ,
const char * attr )
2004-05-09 13:39:47 +04:00
{
2004-05-25 17:57:39 +04:00
uint64_t attr_time = samdb_result_uint64 ( msg , attr , 0 ) ;
int64_t maxPwdAge ;
if ( attr_time = = 0 ) {
return 0 ;
2004-05-09 13:39:47 +04:00
}
2004-05-25 17:57:39 +04:00
2005-10-11 15:00:16 +04:00
maxPwdAge = samdb_search_int64 ( sam_ldb , mem_ctx , 0 , domain_dn , " maxPwdAge " , NULL ) ;
2004-05-25 17:57:39 +04:00
if ( maxPwdAge = = 0 ) {
2004-05-26 12:02:20 +04:00
return 0 ;
2004-05-25 17:57:39 +04:00
} else {
attr_time - = maxPwdAge ;
}
return attr_time ;
2004-05-09 13:39:47 +04:00
}
2004-05-10 15:23:50 +04:00
/*
2004-06-04 15:58:46 +04:00
pull a samr_Password structutre from a result set .
2004-05-10 15:23:50 +04:00
*/
2004-06-04 15:58:46 +04:00
struct samr_Password samdb_result_hash ( struct ldb_message * msg , const char * attr )
2004-05-10 15:23:50 +04:00
{
2004-06-04 15:58:46 +04:00
struct samr_Password hash ;
2004-05-10 15:23:50 +04:00
const struct ldb_val * val = ldb_msg_find_ldb_val ( msg , attr ) ;
ZERO_STRUCT ( hash ) ;
if ( val ) {
2004-09-11 19:04:40 +04:00
memcpy ( hash . hash , val - > data , MIN ( val - > length , sizeof ( hash . hash ) ) ) ;
2004-05-10 15:23:50 +04:00
}
return hash ;
}
/*
2004-06-04 15:58:46 +04:00
pull an array of samr_Password structutres from a result set .
2004-05-10 15:23:50 +04:00
*/
uint_t samdb_result_hashes ( TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
2004-06-04 15:58:46 +04:00
const char * attr , struct samr_Password * * hashes )
2004-05-10 15:23:50 +04:00
{
uint_t count = 0 ;
const struct ldb_val * val = ldb_msg_find_ldb_val ( msg , attr ) ;
int i ;
* hashes = NULL ;
if ( ! val ) {
return 0 ;
}
count = val - > length / 16 ;
if ( count = = 0 ) {
return 0 ;
}
2005-01-27 10:08:20 +03:00
* hashes = talloc_array ( mem_ctx , struct samr_Password , count ) ;
2004-05-10 15:23:50 +04:00
if ( ! * hashes ) {
return 0 ;
}
for ( i = 0 ; i < count ; i + + ) {
memcpy ( ( * hashes ) [ i ] . hash , ( i * 16 ) + ( char * ) val - > data , 16 ) ;
}
return count ;
}
2004-05-15 11:51:38 +04:00
NTSTATUS samdb_result_passwords ( TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
2004-06-04 15:58:46 +04:00
struct samr_Password * * lm_pwd , struct samr_Password * * nt_pwd )
2004-05-15 11:51:38 +04:00
{
const char * unicodePwd = samdb_result_string ( msg , " unicodePwd " , NULL ) ;
2004-06-04 15:58:46 +04:00
struct samr_Password * lmPwdHash , * ntPwdHash ;
2004-05-15 11:51:38 +04:00
if ( unicodePwd ) {
if ( nt_pwd ) {
2005-01-27 10:08:20 +03:00
ntPwdHash = talloc ( mem_ctx , struct samr_Password ) ;
2004-05-15 11:51:38 +04:00
if ( ! ntPwdHash ) {
return NT_STATUS_NO_MEMORY ;
}
E_md4hash ( unicodePwd , ntPwdHash - > hash ) ;
2004-06-04 15:58:46 +04:00
* nt_pwd = ntPwdHash ;
2004-05-15 11:51:38 +04:00
}
if ( lm_pwd ) {
BOOL lm_hash_ok ;
2005-01-27 10:08:20 +03:00
lmPwdHash = talloc ( mem_ctx , struct samr_Password ) ;
2004-05-15 11:51:38 +04:00
if ( ! lmPwdHash ) {
return NT_STATUS_NO_MEMORY ;
}
/* compute the new nt and lm hashes */
lm_hash_ok = E_deshash ( unicodePwd , lmPwdHash - > hash ) ;
if ( lm_hash_ok ) {
2004-06-04 15:58:46 +04:00
* lm_pwd = lmPwdHash ;
2004-05-15 11:51:38 +04:00
} else {
* lm_pwd = NULL ;
}
}
} else {
if ( nt_pwd ) {
int num_nt ;
num_nt = samdb_result_hashes ( mem_ctx , msg , " ntPwdHash " , & ntPwdHash ) ;
if ( num_nt = = 0 ) {
2004-05-25 18:21:09 +04:00
* nt_pwd = NULL ;
2004-05-15 11:51:38 +04:00
} else if ( num_nt > 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
} else {
2004-06-04 15:58:46 +04:00
* nt_pwd = & ntPwdHash [ 0 ] ;
2004-05-15 11:51:38 +04:00
}
}
if ( lm_pwd ) {
int num_lm ;
num_lm = samdb_result_hashes ( mem_ctx , msg , " lmPwdHash " , & lmPwdHash ) ;
if ( num_lm = = 0 ) {
* lm_pwd = NULL ;
} else if ( num_lm > 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
} else {
2004-06-04 15:58:46 +04:00
* lm_pwd = & lmPwdHash [ 0 ] ;
2004-05-15 11:51:38 +04:00
}
}
}
return NT_STATUS_OK ;
}
2004-05-10 15:23:50 +04:00
2004-05-09 13:39:47 +04:00
/*
pull a samr_LogonHours structutre from a result set .
*/
struct samr_LogonHours samdb_result_logon_hours ( TALLOC_CTX * mem_ctx , struct ldb_message * msg , const char * attr )
{
struct samr_LogonHours hours ;
const int units_per_week = 168 ;
const struct ldb_val * val = ldb_msg_find_ldb_val ( msg , attr ) ;
ZERO_STRUCT ( hours ) ;
2005-02-10 08:09:35 +03:00
hours . bits = talloc_array ( mem_ctx , uint8_t , units_per_week ) ;
2005-01-05 18:24:20 +03:00
if ( ! hours . bits ) {
2004-05-09 13:39:47 +04:00
return hours ;
}
hours . units_per_week = units_per_week ;
2005-01-05 18:24:20 +03:00
memset ( hours . bits , 0xFF , units_per_week ) ;
2004-05-09 13:39:47 +04:00
if ( val ) {
2005-01-05 18:24:20 +03:00
memcpy ( hours . bits , val - > data , MIN ( val - > length , units_per_week ) ) ;
2004-05-09 13:39:47 +04:00
}
return hours ;
}
/*
pull a set of account_flags from a result set .
*/
2004-05-25 21:24:24 +04:00
uint16_t samdb_result_acct_flags ( struct ldb_message * msg , const char * attr )
2004-05-09 13:39:47 +04:00
{
uint_t userAccountControl = ldb_msg_find_uint ( msg , attr , 0 ) ;
2004-05-15 11:51:38 +04:00
return samdb_uf2acb ( userAccountControl ) ;
2004-05-09 13:39:47 +04:00
}
2004-05-08 04:02:31 +04:00
/*
copy from a template record to a message
*/
2005-02-27 14:35:47 +03:00
int samdb_copy_template ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx ,
2004-05-08 04:02:31 +04:00
struct ldb_message * msg , const char * expression )
{
struct ldb_message * * res , * t ;
int ret , i , j ;
/* pull the template record */
2005-03-23 04:30:43 +03:00
ret = gendb_search ( sam_ldb , mem_ctx , NULL , & res , NULL , " %s " , expression ) ;
2004-05-08 04:02:31 +04:00
if ( ret ! = 1 ) {
DEBUG ( 1 , ( " samdb: ERROR: template '%s' matched %d records \n " ,
expression , ret ) ) ;
return - 1 ;
}
t = res [ 0 ] ;
for ( i = 0 ; i < t - > num_elements ; i + + ) {
struct ldb_message_element * el = & t - > elements [ i ] ;
/* some elements should not be copied from the template */
if ( strcasecmp ( el - > name , " cn " ) = = 0 | |
strcasecmp ( el - > name , " name " ) = = 0 | |
strcasecmp ( el - > name , " sAMAccountName " ) = = 0 ) {
continue ;
}
for ( j = 0 ; j < el - > num_values ; j + + ) {
if ( strcasecmp ( el - > name , " objectClass " ) = = 0 & &
2004-05-10 16:05:54 +04:00
( strcasecmp ( ( char * ) el - > values [ j ] . data , " Template " ) = = 0 | |
strcasecmp ( ( char * ) el - > values [ j ] . data , " userTemplate " ) = = 0 | |
2004-12-23 01:19:54 +03:00
strcasecmp ( ( char * ) el - > values [ j ] . data , " groupTemplate " ) = = 0 | |
2004-12-28 01:20:17 +03:00
strcasecmp ( ( char * ) el - > values [ j ] . data , " foreignSecurityTemplate " ) = = 0 | |
2005-01-12 05:40:25 +03:00
strcasecmp ( ( char * ) el - > values [ j ] . data , " aliasTemplate " ) = = 0 | |
strcasecmp ( ( char * ) el - > values [ j ] . data , " trustedDomainTemplate " ) = = 0 | |
strcasecmp ( ( char * ) el - > values [ j ] . data , " secretTemplate " ) = = 0 ) ) {
2004-05-09 15:21:46 +04:00
continue ;
}
2005-02-27 14:35:47 +03:00
samdb_msg_add_string ( sam_ldb , mem_ctx , msg , el - > name ,
2004-05-08 04:02:31 +04:00
( char * ) el - > values [ j ] . data ) ;
}
}
return 0 ;
}
/*
add a string element to a message
*/
2005-02-27 14:35:47 +03:00
int samdb_msg_add_string ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
2004-05-08 04:02:31 +04:00
const char * attr_name , const char * str )
{
char * s = talloc_strdup ( mem_ctx , str ) ;
char * a = talloc_strdup ( mem_ctx , attr_name ) ;
if ( s = = NULL | | a = = NULL ) {
return - 1 ;
}
2005-10-12 10:10:23 +04:00
return ldb_msg_add_string ( msg , a , s ) ;
2004-05-08 04:02:31 +04:00
}
2005-06-24 04:18:20 +04:00
/*
add a dom_sid element to a message
*/
int samdb_msg_add_dom_sid ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
const char * attr_name , struct dom_sid * sid )
{
struct ldb_val v ;
NTSTATUS status ;
status = ndr_push_struct_blob ( & v , mem_ctx , sid ,
( ndr_push_flags_fn_t ) ndr_push_dom_sid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return - 1 ;
}
2005-10-12 10:10:23 +04:00
return ldb_msg_add_value ( msg , attr_name , & v ) ;
2005-06-24 04:18:20 +04:00
}
2005-07-08 09:14:46 +04:00
2004-05-10 16:05:54 +04:00
/*
add a delete element operation to a message
*/
2005-02-27 14:35:47 +03:00
int samdb_msg_add_delete ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
2004-05-10 16:05:54 +04:00
const char * attr_name )
{
char * a = talloc_strdup ( mem_ctx , attr_name ) ;
if ( a = = NULL ) {
return - 1 ;
}
2004-05-22 04:53:57 +04:00
/* we use an empty replace rather than a delete, as it allows for
samdb_replace ( ) to be used everywhere */
2005-10-12 10:10:23 +04:00
return ldb_msg_add_empty ( msg , a , LDB_FLAG_MOD_REPLACE ) ;
2004-05-10 16:05:54 +04:00
}
2004-12-26 21:02:18 +03:00
/*
add a add attribute value to a message
*/
2005-02-27 14:35:47 +03:00
int samdb_msg_add_addval ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
2004-12-26 21:02:18 +03:00
const char * attr_name , const char * value )
{
struct ldb_message_element * el ;
char * a , * v ;
int ret ;
a = talloc_strdup ( mem_ctx , attr_name ) ;
if ( a = = NULL )
return - 1 ;
v = talloc_strdup ( mem_ctx , value ) ;
if ( v = = NULL )
return - 1 ;
2005-10-12 10:10:23 +04:00
ret = ldb_msg_add_string ( msg , a , v ) ;
2004-12-26 21:02:18 +03:00
if ( ret ! = 0 )
return ret ;
el = ldb_msg_find_element ( msg , a ) ;
if ( el = = NULL )
return - 1 ;
el - > flags = LDB_FLAG_MOD_ADD ;
return 0 ;
}
/*
add a delete attribute value to a message
*/
2005-02-27 14:35:47 +03:00
int samdb_msg_add_delval ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
2004-12-26 21:02:18 +03:00
const char * attr_name , const char * value )
{
struct ldb_message_element * el ;
char * a , * v ;
int ret ;
a = talloc_strdup ( mem_ctx , attr_name ) ;
if ( a = = NULL )
return - 1 ;
v = talloc_strdup ( mem_ctx , value ) ;
if ( v = = NULL )
return - 1 ;
2005-10-12 10:10:23 +04:00
ret = ldb_msg_add_string ( msg , a , v ) ;
2004-12-26 21:02:18 +03:00
if ( ret ! = 0 )
return ret ;
el = ldb_msg_find_element ( msg , a ) ;
if ( el = = NULL )
return - 1 ;
el - > flags = LDB_FLAG_MOD_DELETE ;
return 0 ;
}
2004-05-08 18:42:45 +04:00
/*
add a uint_t element to a message
*/
2005-02-27 14:35:47 +03:00
int samdb_msg_add_uint ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
2004-05-08 18:42:45 +04:00
const char * attr_name , uint_t v )
{
const char * s = talloc_asprintf ( mem_ctx , " %u " , v ) ;
2005-02-27 14:35:47 +03:00
return samdb_msg_add_string ( sam_ldb , mem_ctx , msg , attr_name , s ) ;
2004-05-08 18:42:45 +04:00
}
2004-05-10 15:23:50 +04:00
/*
2004-05-25 17:57:39 +04:00
add a ( signed ) int64_t element to a message
*/
2005-02-27 14:35:47 +03:00
int samdb_msg_add_int64 ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
2004-05-25 17:57:39 +04:00
const char * attr_name , int64_t v )
{
2005-11-30 05:08:15 +03:00
const char * s = talloc_asprintf ( mem_ctx , " %lld " , ( long long ) v ) ;
2005-02-27 14:35:47 +03:00
return samdb_msg_add_string ( sam_ldb , mem_ctx , msg , attr_name , s ) ;
2004-05-25 17:57:39 +04:00
}
/*
add a uint64_t element to a message
2004-05-10 15:23:50 +04:00
*/
2005-02-27 14:35:47 +03:00
int samdb_msg_add_uint64 ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
2004-05-25 17:57:39 +04:00
const char * attr_name , uint64_t v )
2004-05-10 15:23:50 +04:00
{
2005-11-30 05:08:15 +03:00
const char * s = talloc_asprintf ( mem_ctx , " %llu " , ( unsigned long long ) v ) ;
2005-02-27 14:35:47 +03:00
return samdb_msg_add_string ( sam_ldb , mem_ctx , msg , attr_name , s ) ;
2004-05-10 15:23:50 +04:00
}
/*
2004-06-04 15:58:46 +04:00
add a samr_Password element to a message
2004-05-10 15:23:50 +04:00
*/
2005-02-27 14:35:47 +03:00
int samdb_msg_add_hash ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
2005-01-10 20:28:36 +03:00
const char * attr_name , struct samr_Password * hash )
2004-05-10 15:23:50 +04:00
{
struct ldb_val val ;
2005-01-10 20:28:36 +03:00
val . data = talloc_memdup ( mem_ctx , hash - > hash , 16 ) ;
2004-05-10 15:23:50 +04:00
if ( ! val . data ) {
return - 1 ;
}
2005-01-06 06:06:58 +03:00
val . length = 16 ;
2005-10-12 10:10:23 +04:00
return ldb_msg_add_value ( msg , attr_name , & val ) ;
2004-05-10 15:23:50 +04:00
}
/*
2004-06-04 15:58:46 +04:00
add a samr_Password array to a message
2004-05-10 15:23:50 +04:00
*/
2005-02-27 14:35:47 +03:00
int samdb_msg_add_hashes ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
2004-06-04 15:58:46 +04:00
const char * attr_name , struct samr_Password * hashes , uint_t count )
2004-05-10 15:23:50 +04:00
{
struct ldb_val val ;
int i ;
2005-01-07 07:39:16 +03:00
val . data = talloc_array_size ( mem_ctx , 16 , count ) ;
2004-05-10 15:23:50 +04:00
val . length = count * 16 ;
if ( ! val . data ) {
return - 1 ;
}
for ( i = 0 ; i < count ; i + + ) {
memcpy ( i * 16 + ( char * ) val . data , hashes [ i ] . hash , 16 ) ;
}
2005-10-12 10:10:23 +04:00
return ldb_msg_add_value ( msg , attr_name , & val ) ;
2004-05-10 15:23:50 +04:00
}
2004-05-09 13:39:47 +04:00
/*
add a acct_flags element to a message
*/
2005-02-27 14:35:47 +03:00
int samdb_msg_add_acct_flags ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
2004-05-25 20:24:13 +04:00
const char * attr_name , uint32_t v )
2004-05-09 13:39:47 +04:00
{
2005-02-27 14:35:47 +03:00
return samdb_msg_add_uint ( sam_ldb , mem_ctx , msg , attr_name , samdb_acb2uf ( v ) ) ;
2004-05-09 13:39:47 +04:00
}
/*
add a logon_hours element to a message
*/
2005-02-27 14:35:47 +03:00
int samdb_msg_add_logon_hours ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
2004-11-02 05:57:18 +03:00
const char * attr_name , struct samr_LogonHours * hours )
2004-05-09 13:39:47 +04:00
{
struct ldb_val val ;
2004-11-02 05:57:18 +03:00
val . length = hours - > units_per_week / 8 ;
2005-01-05 18:24:20 +03:00
val . data = hours - > bits ;
2005-10-12 10:10:23 +04:00
return ldb_msg_add_value ( msg , attr_name , & val ) ;
2004-05-09 13:39:47 +04:00
}
2005-01-11 16:55:45 +03:00
/*
add a general value element to a message
*/
2005-02-27 14:35:47 +03:00
int samdb_msg_add_value ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
2005-01-11 16:55:45 +03:00
const char * attr_name , const struct ldb_val * val )
{
2005-10-12 10:10:23 +04:00
return ldb_msg_add_value ( msg , attr_name , val ) ;
2005-01-11 16:55:45 +03:00
}
2005-01-16 04:21:58 +03:00
/*
sets a general value element to a message
*/
2005-02-27 14:35:47 +03:00
int samdb_msg_set_value ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
2005-01-16 04:21:58 +03:00
const char * attr_name , const struct ldb_val * val )
{
struct ldb_message_element * el ;
el = ldb_msg_find_element ( msg , attr_name ) ;
if ( el ) {
el - > num_values = 0 ;
}
2005-10-12 10:10:23 +04:00
return ldb_msg_add_value ( msg , attr_name , val ) ;
2005-01-16 04:21:58 +03:00
}
2004-05-08 04:02:31 +04:00
/*
set a string element in a message
*/
2005-02-27 14:35:47 +03:00
int samdb_msg_set_string ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , struct ldb_message * msg ,
2004-05-08 04:02:31 +04:00
const char * attr_name , const char * str )
{
struct ldb_message_element * el ;
el = ldb_msg_find_element ( msg , attr_name ) ;
if ( el ) {
el - > num_values = 0 ;
}
2005-02-27 14:35:47 +03:00
return samdb_msg_add_string ( sam_ldb , mem_ctx , msg , attr_name , str ) ;
2004-05-08 04:02:31 +04:00
}
/*
add a record
*/
2005-02-27 14:35:47 +03:00
int samdb_add ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , struct ldb_message * msg )
2004-05-08 04:02:31 +04:00
{
2005-02-27 14:35:47 +03:00
return ldb_add ( sam_ldb , msg ) ;
2004-05-08 04:02:31 +04:00
}
/*
delete a record
*/
2005-08-18 19:02:01 +04:00
int samdb_delete ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , const struct ldb_dn * dn )
2004-05-08 04:02:31 +04:00
{
2005-02-27 14:35:47 +03:00
return ldb_delete ( sam_ldb , dn ) ;
2004-05-08 04:02:31 +04:00
}
2004-05-08 18:42:45 +04:00
/*
modify a record
*/
2005-02-27 14:35:47 +03:00
int samdb_modify ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , struct ldb_message * msg )
2004-05-08 18:42:45 +04:00
{
2005-02-27 14:35:47 +03:00
return ldb_modify ( sam_ldb , msg ) ;
2004-05-08 18:42:45 +04:00
}
2004-05-10 15:23:50 +04:00
2004-05-22 04:53:57 +04:00
/*
replace elements in a record
*/
2005-02-27 14:35:47 +03:00
int samdb_replace ( struct ldb_context * sam_ldb , TALLOC_CTX * mem_ctx , struct ldb_message * msg )
2004-05-22 04:53:57 +04:00
{
int i ;
/* mark all the message elements as LDB_FLAG_MOD_REPLACE */
for ( i = 0 ; i < msg - > num_elements ; i + + ) {
msg - > elements [ i ] . flags = LDB_FLAG_MOD_REPLACE ;
}
/* modify the samdb record */
2005-02-27 14:35:47 +03:00
return samdb_modify ( sam_ldb , mem_ctx , msg ) ;
2004-05-22 04:53:57 +04:00
}
2004-05-28 17:23:30 +04:00
/*
return a default security descriptor
*/
struct security_descriptor * samdb_default_security_descriptor ( TALLOC_CTX * mem_ctx )
{
struct security_descriptor * sd ;
2004-11-17 17:35:29 +03:00
sd = security_descriptor_initialise ( mem_ctx ) ;
2004-05-28 17:23:30 +04:00
return sd ;
}
2005-09-02 03:26:50 +04:00
struct ldb_dn * samdb_base_dn ( TALLOC_CTX * mem_ctx )
{
TALLOC_CTX * tmp_ctx = talloc_new ( mem_ctx ) ;
int server_role = lp_server_role ( ) ;
const char * * split_realm ;
struct ldb_dn * dn ;
if ( ! tmp_ctx ) {
return NULL ;
}
if ( ( server_role = = ROLE_DOMAIN_PDC )
| | ( server_role = = ROLE_DOMAIN_BDC ) ) {
int i ;
split_realm = str_list_make ( tmp_ctx , lp_realm ( ) , " . " ) ;
if ( ! split_realm ) {
talloc_free ( tmp_ctx ) ;
return NULL ;
}
dn = NULL ;
i = str_list_length ( split_realm ) ;
i - - ;
for ( ; i > = 0 ; i - - ) {
dn = ldb_dn_build_child ( tmp_ctx , " dc " , split_realm [ i ] , dn ) ;
if ( ! dn ) {
talloc_free ( tmp_ctx ) ;
return NULL ;
}
}
return dn ;
}
return ldb_dn_string_compose ( mem_ctx , NULL , " cn=%s " , lp_netbios_name ( ) ) ;
}
2005-12-10 02:39:00 +03:00
/*
work out the domain sid for the current open ldb
*/
const struct dom_sid * samdb_domain_sid ( struct ldb_context * ldb )
{
const char * attrs [ ] = { " rootDomainNamingContext " , NULL } ;
int ret ;
struct ldb_result * res = NULL ;
TALLOC_CTX * tmp_ctx = talloc_new ( ldb ) ;
struct dom_sid * domain_sid ;
const char * basedn_s ;
struct ldb_dn * basedn ;
/* see if we have a cached copy */
domain_sid = ldb_get_opaque ( ldb , " cache.domain_sid " ) ;
if ( domain_sid ) {
return domain_sid ;
}
basedn = ldb_dn_explode ( tmp_ctx , " " ) ;
if ( basedn = = NULL ) {
goto failed ;
}
/* find the basedn of the domain from the rootdse */
ret = ldb_search ( ldb , basedn , LDB_SCOPE_BASE , NULL , attrs , & res ) ;
talloc_steal ( tmp_ctx , res ) ;
if ( ret ! = LDB_SUCCESS | | res - > count ! = 1 ) {
goto failed ;
}
basedn_s = ldb_msg_find_string ( res - > msgs [ 0 ] , " rootDomainNamingContext " , NULL ) ;
if ( basedn_s = = NULL ) {
goto failed ;
}
basedn = ldb_dn_explode ( tmp_ctx , basedn_s ) ;
if ( basedn = = NULL ) {
goto failed ;
}
/* find the domain_sid */
domain_sid = samdb_search_dom_sid ( ldb , tmp_ctx , basedn ,
" objectSid " , " objectClass=domainDNS " ) ;
if ( domain_sid = = NULL ) {
goto failed ;
}
/* cache the domain_sid in the ldb */
if ( ldb_set_opaque ( ldb , " cache.domain_sid " , domain_sid ) ! = LDB_SUCCESS ) {
goto failed ;
}
talloc_steal ( ldb , domain_sid ) ;
talloc_free ( tmp_ctx ) ;
return domain_sid ;
failed :
DEBUG ( 1 , ( " Failed to find domain_sid for open ldb \n " ) ) ;
talloc_free ( tmp_ctx ) ;
return NULL ;
}