2008-10-04 04:52:59 +04:00
/* need access mask/acl implementation */
2004-05-27 08:13:58 +04:00
/*
Unix SMB / CIFS implementation .
endpoint server for the lsarpc pipe
Copyright ( C ) Andrew Tridgell 2004
2008-09-08 04:55:34 +04:00
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2004 - 2008
2004-05-27 08:13:58 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2004-05-27 08:13:58 +04: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 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2004-05-27 08:13:58 +04:00
*/
2007-09-17 09:31:49 +04:00
# include "rpc_server/lsa/lsa.h"
2008-08-26 06:18:26 +04:00
# include "system/kerberos.h"
# include "auth/kerberos/kerberos.h"
2008-09-08 04:55:34 +04:00
# include "librpc/gen_ndr/ndr_drsblobs.h"
# include "librpc/gen_ndr/ndr_lsa.h"
2010-08-07 20:15:01 +04:00
# include "../lib/crypto/crypto.h"
2010-02-13 05:00:55 +03:00
# include "lib/util/tsort.h"
2010-08-07 20:15:01 +04:00
# include "dsdb/common/util.h"
2004-05-27 08:13:58 +04:00
/*
this type allows us to distinguish handle types
*/
2004-12-19 08:01:52 +03:00
/*
state associated with a lsa_OpenAccount ( ) operation
*/
struct lsa_account_state {
struct lsa_policy_state * policy ;
uint32_t access_mask ;
struct dom_sid * account_sid ;
} ;
2005-01-11 17:04:58 +03:00
/*
state associated with a lsa_OpenSecret ( ) operation
*/
struct lsa_secret_state {
struct lsa_policy_state * policy ;
uint32_t access_mask ;
2006-08-31 12:22:13 +04:00
struct ldb_dn * secret_dn ;
2005-02-27 14:35:47 +03:00
struct ldb_context * sam_ldb ;
2007-10-07 02:25:41 +04:00
bool global ;
2005-01-11 17:04:58 +03:00
} ;
2005-01-12 05:40:25 +03:00
/*
state associated with a lsa_OpenTrustedDomain ( ) operation
*/
struct lsa_trusted_domain_state {
struct lsa_policy_state * policy ;
uint32_t access_mask ;
2006-11-22 03:59:34 +03:00
struct ldb_dn * trusted_domain_dn ;
2008-09-08 04:55:34 +04:00
struct ldb_dn * trusted_domain_user_dn ;
2005-01-12 05:40:25 +03:00
} ;
2009-09-22 11:16:58 +04:00
/*
this is based on the samba3 function make_lsa_object_sd ( )
It uses the same logic , but with samba4 helper functions
*/
static NTSTATUS dcesrv_build_lsa_sd ( TALLOC_CTX * mem_ctx ,
struct security_descriptor * * sd ,
struct dom_sid * sid ,
uint32_t sid_access )
{
NTSTATUS status ;
uint32_t rid ;
struct dom_sid * domain_sid , * domain_admins_sid ;
const char * domain_admins_sid_str , * sidstr ;
TALLOC_CTX * tmp_ctx = talloc_new ( mem_ctx ) ;
status = dom_sid_split_rid ( tmp_ctx , sid , & domain_sid , & rid ) ;
2009-10-16 10:05:27 +04:00
NT_STATUS_NOT_OK_RETURN_AND_FREE ( status , tmp_ctx ) ;
2009-09-22 11:16:58 +04:00
domain_admins_sid = dom_sid_add_rid ( tmp_ctx , domain_sid , DOMAIN_RID_ADMINS ) ;
NT_STATUS_HAVE_NO_MEMORY_AND_FREE ( domain_admins_sid , tmp_ctx ) ;
domain_admins_sid_str = dom_sid_string ( tmp_ctx , domain_admins_sid ) ;
NT_STATUS_HAVE_NO_MEMORY_AND_FREE ( domain_admins_sid_str , tmp_ctx ) ;
sidstr = dom_sid_string ( tmp_ctx , sid ) ;
NT_STATUS_HAVE_NO_MEMORY_AND_FREE ( sidstr , tmp_ctx ) ;
* sd = security_descriptor_dacl_create ( mem_ctx ,
0 , sidstr , NULL ,
SID_WORLD ,
SEC_ACE_TYPE_ACCESS_ALLOWED ,
SEC_GENERIC_EXECUTE | SEC_GENERIC_READ , 0 ,
SID_BUILTIN_ADMINISTRATORS ,
SEC_ACE_TYPE_ACCESS_ALLOWED ,
SEC_GENERIC_ALL , 0 ,
SID_BUILTIN_ACCOUNT_OPERATORS ,
SEC_ACE_TYPE_ACCESS_ALLOWED ,
SEC_GENERIC_ALL , 0 ,
domain_admins_sid_str ,
SEC_ACE_TYPE_ACCESS_ALLOWED ,
SEC_GENERIC_ALL , 0 ,
sidstr ,
SEC_ACE_TYPE_ACCESS_ALLOWED ,
sid_access , 0 ,
NULL ) ;
talloc_free ( tmp_ctx ) ;
NT_STATUS_HAVE_NO_MEMORY ( * sd ) ;
return NT_STATUS_OK ;
}
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_EnumAccountRights ( struct dcesrv_call_state * dce_call ,
2006-07-06 09:23:29 +04:00
TALLOC_CTX * mem_ctx ,
struct lsa_EnumAccountRights * r ) ;
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_AddRemoveAccountRights ( struct dcesrv_call_state * dce_call ,
2006-07-06 09:23:29 +04:00
TALLOC_CTX * mem_ctx ,
struct lsa_policy_state * state ,
int ldb_flag ,
struct dom_sid * sid ,
const struct lsa_RightSet * rights ) ;
2004-05-27 08:13:58 +04:00
/*
lsa_Close
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_Close ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-27 08:13:58 +04:00
struct lsa_Close * r )
{
struct dcesrv_handle * h ;
* r - > out . handle = * r - > in . handle ;
DCESRV_PULL_HANDLE ( h , r - > in . handle , DCESRV_HANDLE_ANY ) ;
2005-01-10 15:15:26 +03:00
talloc_free ( h ) ;
2004-05-27 08:13:58 +04:00
ZERO_STRUCTP ( r - > out . handle ) ;
return NT_STATUS_OK ;
}
/*
lsa_Delete
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_Delete ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-27 08:13:58 +04:00
struct lsa_Delete * r )
2008-08-26 04:32:49 +04:00
{
return NT_STATUS_NOT_SUPPORTED ;
}
/*
lsa_DeleteObject
*/
static NTSTATUS dcesrv_lsa_DeleteObject ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct lsa_DeleteObject * r )
2004-05-27 08:13:58 +04:00
{
2005-01-12 03:37:13 +03:00
struct dcesrv_handle * h ;
int ret ;
DCESRV_PULL_HANDLE ( h , r - > in . handle , DCESRV_HANDLE_ANY ) ;
2008-03-20 04:12:10 +03:00
2005-01-12 03:37:13 +03:00
if ( h - > wire_handle . handle_type = = LSA_HANDLE_SECRET ) {
struct lsa_secret_state * secret_state = h - > data ;
2008-03-20 04:12:10 +03:00
/* Ensure user is permitted to delete this... */
2010-04-22 10:48:01 +04:00
switch ( security_session_user_level ( dce_call - > conn - > auth_state . session_info , NULL ) )
2008-03-20 04:12:10 +03:00
{
case SECURITY_SYSTEM :
case SECURITY_ADMINISTRATOR :
break ;
default :
2010-06-28 13:05:59 +04:00
/* Users and anonymous are not allowed to delete things */
2008-03-20 04:12:10 +03:00
return NT_STATUS_ACCESS_DENIED ;
}
2007-11-27 03:25:11 +03:00
ret = ldb_delete ( secret_state - > sam_ldb ,
secret_state - > secret_dn ) ;
2009-11-21 21:46:25 +03:00
if ( ret ! = LDB_SUCCESS ) {
2005-01-12 03:37:13 +03:00
return NT_STATUS_INVALID_HANDLE ;
}
2008-08-26 04:32:49 +04:00
ZERO_STRUCTP ( r - > out . handle ) ;
2005-01-12 05:40:25 +03:00
return NT_STATUS_OK ;
2010-06-28 13:05:59 +04:00
2005-01-12 05:40:25 +03:00
} else if ( h - > wire_handle . handle_type = = LSA_HANDLE_TRUSTED_DOMAIN ) {
2008-10-04 04:52:59 +04:00
struct lsa_trusted_domain_state * trusted_domain_state =
talloc_get_type ( h - > data , struct lsa_trusted_domain_state ) ;
2008-09-08 04:55:34 +04:00
ret = ldb_transaction_start ( trusted_domain_state - > policy - > sam_ldb ) ;
2009-11-21 21:46:25 +03:00
if ( ret ! = LDB_SUCCESS ) {
2008-09-08 04:55:34 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2007-11-27 03:25:11 +03:00
ret = ldb_delete ( trusted_domain_state - > policy - > sam_ldb ,
trusted_domain_state - > trusted_domain_dn ) ;
2009-11-21 21:46:25 +03:00
if ( ret ! = LDB_SUCCESS ) {
2008-09-08 04:55:34 +04:00
ldb_transaction_cancel ( trusted_domain_state - > policy - > sam_ldb ) ;
2005-01-12 05:40:25 +03:00
return NT_STATUS_INVALID_HANDLE ;
}
2008-09-08 04:55:34 +04:00
if ( trusted_domain_state - > trusted_domain_user_dn ) {
ret = ldb_delete ( trusted_domain_state - > policy - > sam_ldb ,
trusted_domain_state - > trusted_domain_user_dn ) ;
2009-11-21 21:46:25 +03:00
if ( ret ! = LDB_SUCCESS ) {
2008-09-08 04:55:34 +04:00
ldb_transaction_cancel ( trusted_domain_state - > policy - > sam_ldb ) ;
return NT_STATUS_INVALID_HANDLE ;
}
}
ret = ldb_transaction_commit ( trusted_domain_state - > policy - > sam_ldb ) ;
2009-11-21 21:46:25 +03:00
if ( ret ! = LDB_SUCCESS ) {
2008-09-08 04:55:34 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2010-06-28 13:05:59 +04:00
2008-08-26 04:32:49 +04:00
ZERO_STRUCTP ( r - > out . handle ) ;
2005-01-12 03:37:13 +03:00
return NT_STATUS_OK ;
2010-06-28 13:05:59 +04:00
2006-07-06 09:23:29 +04:00
} else if ( h - > wire_handle . handle_type = = LSA_HANDLE_ACCOUNT ) {
struct lsa_RightSet * rights ;
struct lsa_account_state * astate ;
struct lsa_EnumAccountRights r2 ;
NTSTATUS status ;
rights = talloc ( mem_ctx , struct lsa_RightSet ) ;
DCESRV_PULL_HANDLE ( h , r - > in . handle , LSA_HANDLE_ACCOUNT ) ;
astate = h - > data ;
r2 . in . handle = & astate - > policy - > handle - > wire_handle ;
r2 . in . sid = astate - > account_sid ;
r2 . out . rights = rights ;
2008-10-04 04:52:59 +04:00
/* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
but we have a LSA_HANDLE_ACCOUNT here , so this call
will always fail */
2007-01-17 17:49:36 +03:00
status = dcesrv_lsa_EnumAccountRights ( dce_call , mem_ctx , & r2 ) ;
2006-07-06 09:23:29 +04:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_OBJECT_NAME_NOT_FOUND ) ) {
return NT_STATUS_OK ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2007-01-17 17:49:36 +03:00
status = dcesrv_lsa_AddRemoveAccountRights ( dce_call , mem_ctx , astate - > policy ,
2006-07-06 09:23:29 +04:00
LDB_FLAG_MOD_DELETE , astate - > account_sid ,
r2 . out . rights ) ;
if ( NT_STATUS_EQUAL ( status , NT_STATUS_OBJECT_NAME_NOT_FOUND ) ) {
return NT_STATUS_OK ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2008-08-26 04:32:49 +04:00
ZERO_STRUCTP ( r - > out . handle ) ;
2010-06-28 13:05:59 +04:00
return NT_STATUS_OK ;
2005-01-12 03:37:13 +03:00
}
return NT_STATUS_INVALID_HANDLE ;
2004-05-27 08:13:58 +04:00
}
/*
lsa_EnumPrivs
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_EnumPrivs ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-27 08:13:58 +04:00
struct lsa_EnumPrivs * r )
{
2004-12-14 08:20:38 +03:00
struct dcesrv_handle * h ;
struct lsa_policy_state * state ;
2009-11-21 21:26:02 +03:00
uint32_t i ;
2010-08-26 12:38:59 +04:00
enum sec_privilege priv ;
2004-12-14 08:20:38 +03:00
const char * privname ;
DCESRV_PULL_HANDLE ( h , r - > in . handle , LSA_HANDLE_POLICY ) ;
state = h - > data ;
i = * r - > in . resume_handle ;
2010-08-31 03:28:51 +04:00
while ( ( ( priv = sec_privilege_from_index ( i ) ) ! = SEC_PRIV_INVALID ) & &
2004-12-14 08:20:38 +03:00
r - > out . privs - > count < r - > in . max_count ) {
struct lsa_PrivEntry * e ;
2010-08-26 12:38:59 +04:00
privname = sec_privilege_name ( priv ) ;
2005-01-27 10:08:20 +03:00
r - > out . privs - > privs = talloc_realloc ( r - > out . privs ,
2004-12-14 08:20:38 +03:00
r - > out . privs - > privs ,
struct lsa_PrivEntry ,
r - > out . privs - > count + 1 ) ;
if ( r - > out . privs - > privs = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
e = & r - > out . privs - > privs [ r - > out . privs - > count ] ;
2010-09-11 14:38:15 +04:00
e - > luid . low = priv ;
2004-12-14 08:32:51 +03:00
e - > luid . high = 0 ;
2004-12-14 08:20:38 +03:00
e - > name . string = privname ;
r - > out . privs - > count + + ;
i + + ;
}
2004-12-30 22:08:32 +03:00
* r - > out . resume_handle = i ;
2004-12-14 08:20:38 +03:00
return NT_STATUS_OK ;
2004-05-27 08:13:58 +04:00
}
/*
lsa_QuerySecObj
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_QuerySecurity ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2009-09-22 11:16:58 +04:00
struct lsa_QuerySecurity * r )
2004-05-27 08:13:58 +04:00
{
2009-09-22 11:16:58 +04:00
struct dcesrv_handle * h ;
struct security_descriptor * sd ;
NTSTATUS status ;
struct dom_sid * sid ;
DCESRV_PULL_HANDLE ( h , r - > in . handle , DCESRV_HANDLE_ANY ) ;
2010-08-20 06:15:15 +04:00
sid = & dce_call - > conn - > auth_state . session_info - > security_token - > sids [ PRIMARY_USER_SID_INDEX ] ;
2009-09-22 11:16:58 +04:00
if ( h - > wire_handle . handle_type = = LSA_HANDLE_POLICY ) {
status = dcesrv_build_lsa_sd ( mem_ctx , & sd , sid , 0 ) ;
} else if ( h - > wire_handle . handle_type = = LSA_HANDLE_ACCOUNT ) {
status = dcesrv_build_lsa_sd ( mem_ctx , & sd , sid ,
LSA_ACCOUNT_ALL_ACCESS ) ;
} else {
return NT_STATUS_INVALID_HANDLE ;
}
NT_STATUS_NOT_OK_RETURN ( status ) ;
( * r - > out . sdbuf ) = talloc ( mem_ctx , struct sec_desc_buf ) ;
NT_STATUS_HAVE_NO_MEMORY ( * r - > out . sdbuf ) ;
( * r - > out . sdbuf ) - > sd = sd ;
return NT_STATUS_OK ;
2004-05-27 08:13:58 +04:00
}
/*
lsa_SetSecObj
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_SetSecObj ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-27 08:13:58 +04:00
struct lsa_SetSecObj * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_ChangePassword
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_ChangePassword ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-27 08:13:58 +04:00
struct lsa_ChangePassword * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
2006-08-31 17:10:11 +04:00
/*
dssetup_DsRoleGetPrimaryDomainInformation
2006-09-11 09:11:10 +04:00
This is not an LSA call , but is the only call left on the DSSETUP
pipe ( after the pipe was truncated ) , and needs lsa_get_policy_state
2006-08-31 17:10:11 +04:00
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation ( struct dcesrv_call_state * dce_call ,
2006-08-31 17:10:11 +04:00
TALLOC_CTX * mem_ctx ,
struct dssetup_DsRoleGetPrimaryDomainInformation * r )
{
union dssetup_DsRoleInfo * info ;
info = talloc ( mem_ctx , union dssetup_DsRoleInfo ) ;
W_ERROR_HAVE_NO_MEMORY ( info ) ;
switch ( r - > in . level ) {
case DS_ROLE_BASIC_INFORMATION :
{
enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER ;
uint32_t flags = 0 ;
const char * domain = NULL ;
const char * dns_domain = NULL ;
const char * forest = NULL ;
struct GUID domain_guid ;
struct lsa_policy_state * state ;
2007-01-17 17:49:36 +03:00
NTSTATUS status = dcesrv_lsa_get_policy_state ( dce_call , mem_ctx , & state ) ;
2006-08-31 17:10:11 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return ntstatus_to_werror ( status ) ;
}
ZERO_STRUCT ( domain_guid ) ;
2010-07-16 08:32:42 +04:00
switch ( lpcfg_server_role ( dce_call - > conn - > dce_ctx - > lp_ctx ) ) {
2006-08-31 17:10:11 +04:00
case ROLE_STANDALONE :
role = DS_ROLE_STANDALONE_SERVER ;
break ;
case ROLE_DOMAIN_MEMBER :
role = DS_ROLE_MEMBER_SERVER ;
break ;
2006-12-13 14:19:51 +03:00
case ROLE_DOMAIN_CONTROLLER :
if ( samdb_is_pdc ( state - > sam_ldb ) ) {
role = DS_ROLE_PRIMARY_DC ;
} else {
role = DS_ROLE_BACKUP_DC ;
}
2006-08-31 17:10:11 +04:00
break ;
}
2010-07-16 08:32:42 +04:00
switch ( lpcfg_server_role ( dce_call - > conn - > dce_ctx - > lp_ctx ) ) {
2006-08-31 17:10:11 +04:00
case ROLE_STANDALONE :
2010-07-16 08:32:42 +04:00
domain = talloc_strdup ( mem_ctx , lpcfg_workgroup ( dce_call - > conn - > dce_ctx - > lp_ctx ) ) ;
2006-08-31 17:10:11 +04:00
W_ERROR_HAVE_NO_MEMORY ( domain ) ;
break ;
case ROLE_DOMAIN_MEMBER :
2010-07-16 08:32:42 +04:00
domain = talloc_strdup ( mem_ctx , lpcfg_workgroup ( dce_call - > conn - > dce_ctx - > lp_ctx ) ) ;
2006-08-31 17:10:11 +04:00
W_ERROR_HAVE_NO_MEMORY ( domain ) ;
/* TODO: what is with dns_domain and forest and guid? */
break ;
2006-12-13 14:19:51 +03:00
case ROLE_DOMAIN_CONTROLLER :
2006-08-31 17:10:11 +04:00
flags = DS_ROLE_PRIMARY_DS_RUNNING ;
if ( state - > mixed_domain = = 1 ) {
flags | = DS_ROLE_PRIMARY_DS_MIXED_MODE ;
}
domain = state - > domain_name ;
dns_domain = state - > domain_dns ;
2007-02-22 16:15:49 +03:00
forest = state - > forest_dns ;
2006-08-31 17:10:11 +04:00
domain_guid = state - > domain_guid ;
flags | = DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT ;
break ;
}
info - > basic . role = role ;
info - > basic . flags = flags ;
info - > basic . domain = domain ;
info - > basic . dns_domain = dns_domain ;
info - > basic . forest = forest ;
info - > basic . domain_guid = domain_guid ;
r - > out . info = info ;
return WERR_OK ;
}
case DS_ROLE_UPGRADE_STATUS :
{
info - > upgrade . upgrading = DS_ROLE_NOT_UPGRADING ;
info - > upgrade . previous_role = DS_ROLE_PREVIOUS_UNKNOWN ;
r - > out . info = info ;
return WERR_OK ;
}
case DS_ROLE_OP_STATUS :
{
info - > opstatus . status = DS_ROLE_OP_IDLE ;
r - > out . info = info ;
return WERR_OK ;
}
default :
return WERR_INVALID_PARAM ;
}
}
2004-05-27 08:13:58 +04:00
/*
fill in the AccountDomain info
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_info_AccountDomain ( struct lsa_policy_state * state , TALLOC_CTX * mem_ctx ,
2004-05-27 08:13:58 +04:00
struct lsa_DomainInfo * info )
{
2005-08-03 09:25:30 +04:00
info - > name . string = state - > domain_name ;
info - > sid = state - > domain_sid ;
2004-05-27 08:13:58 +04:00
return NT_STATUS_OK ;
}
2004-05-27 10:27:21 +04:00
/*
fill in the DNS domain info
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_info_DNS ( struct lsa_policy_state * state , TALLOC_CTX * mem_ctx ,
2004-05-27 10:27:21 +04:00
struct lsa_DnsDomainInfo * info )
{
2005-08-03 09:25:30 +04:00
info - > name . string = state - > domain_name ;
info - > sid = state - > domain_sid ;
2006-08-31 12:22:13 +04:00
info - > dns_domain . string = state - > domain_dns ;
2007-02-22 16:15:49 +03:00
info - > dns_forest . string = state - > forest_dns ;
2006-08-31 12:22:13 +04:00
info - > domain_guid = state - > domain_guid ;
2004-05-27 10:27:21 +04:00
return NT_STATUS_OK ;
}
2004-05-27 08:13:58 +04:00
/*
2004-05-27 10:27:21 +04:00
lsa_QueryInfoPolicy2
2004-05-27 08:13:58 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_QueryInfoPolicy2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-27 10:27:21 +04:00
struct lsa_QueryInfoPolicy2 * r )
2004-05-27 08:13:58 +04:00
{
struct lsa_policy_state * state ;
struct dcesrv_handle * h ;
2008-10-24 17:05:57 +04:00
union lsa_PolicyInformation * info ;
2004-05-27 08:13:58 +04:00
2008-10-24 17:05:57 +04:00
* r - > out . info = NULL ;
2004-05-27 08:13:58 +04:00
DCESRV_PULL_HANDLE ( h , r - > in . handle , LSA_HANDLE_POLICY ) ;
state = h - > data ;
2008-10-24 17:05:57 +04:00
info = talloc_zero ( mem_ctx , union lsa_PolicyInformation ) ;
if ( ! info ) {
2004-05-27 08:13:58 +04:00
return NT_STATUS_NO_MEMORY ;
}
2008-10-24 17:05:57 +04:00
* r - > out . info = info ;
2004-05-27 08:13:58 +04:00
switch ( r - > in . level ) {
2008-10-04 04:52:59 +04:00
case LSA_POLICY_INFO_AUDIT_LOG :
/* we don't need to fill in any of this */
2008-10-24 17:05:57 +04:00
ZERO_STRUCT ( info - > audit_log ) ;
2008-10-04 04:52:59 +04:00
return NT_STATUS_OK ;
case LSA_POLICY_INFO_AUDIT_EVENTS :
/* we don't need to fill in any of this */
2008-10-24 17:05:57 +04:00
ZERO_STRUCT ( info - > audit_events ) ;
2008-10-04 04:52:59 +04:00
return NT_STATUS_OK ;
case LSA_POLICY_INFO_PD :
/* we don't need to fill in any of this */
2008-10-24 17:05:57 +04:00
ZERO_STRUCT ( info - > pd ) ;
2008-10-04 04:52:59 +04:00
return NT_STATUS_OK ;
2008-10-20 08:50:07 +04:00
2004-05-27 10:27:21 +04:00
case LSA_POLICY_INFO_DOMAIN :
2008-10-24 17:05:57 +04:00
return dcesrv_lsa_info_AccountDomain ( state , mem_ctx , & info - > domain ) ;
2004-05-27 08:13:58 +04:00
case LSA_POLICY_INFO_ACCOUNT_DOMAIN :
2008-10-24 17:05:57 +04:00
return dcesrv_lsa_info_AccountDomain ( state , mem_ctx , & info - > account_domain ) ;
2008-10-20 08:50:07 +04:00
case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN :
2008-10-24 17:05:57 +04:00
return dcesrv_lsa_info_AccountDomain ( state , mem_ctx , & info - > l_account_domain ) ;
2008-10-20 08:50:07 +04:00
2008-10-04 04:52:59 +04:00
case LSA_POLICY_INFO_ROLE :
2008-10-24 17:05:57 +04:00
info - > role . role = LSA_ROLE_PRIMARY ;
2008-10-04 04:52:59 +04:00
return NT_STATUS_OK ;
2004-05-27 10:27:21 +04:00
case LSA_POLICY_INFO_DNS :
2008-10-04 04:52:59 +04:00
case LSA_POLICY_INFO_DNS_INT :
2008-10-24 17:05:57 +04:00
return dcesrv_lsa_info_DNS ( state , mem_ctx , & info - > dns ) ;
2008-10-04 04:52:59 +04:00
case LSA_POLICY_INFO_REPLICA :
2008-10-24 17:05:57 +04:00
ZERO_STRUCT ( info - > replica ) ;
2008-10-04 04:52:59 +04:00
return NT_STATUS_OK ;
case LSA_POLICY_INFO_QUOTA :
2008-10-24 17:05:57 +04:00
ZERO_STRUCT ( info - > quota ) ;
2008-10-04 04:52:59 +04:00
return NT_STATUS_OK ;
2008-10-20 08:50:07 +04:00
case LSA_POLICY_INFO_MOD :
2007-09-17 09:31:49 +04:00
case LSA_POLICY_INFO_AUDIT_FULL_SET :
2008-10-20 09:12:37 +04:00
case LSA_POLICY_INFO_AUDIT_FULL_QUERY :
2008-10-04 04:52:59 +04:00
/* windows gives INVALID_PARAMETER */
2008-10-24 17:05:57 +04:00
* r - > out . info = NULL ;
2007-09-17 09:31:49 +04:00
return NT_STATUS_INVALID_PARAMETER ;
2004-05-27 08:13:58 +04:00
}
2008-10-24 17:05:57 +04:00
* r - > out . info = NULL ;
2004-05-27 08:13:58 +04:00
return NT_STATUS_INVALID_INFO_CLASS ;
}
2004-05-27 10:27:21 +04:00
/*
lsa_QueryInfoPolicy
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_QueryInfoPolicy ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-27 10:27:21 +04:00
struct lsa_QueryInfoPolicy * r )
{
struct lsa_QueryInfoPolicy2 r2 ;
NTSTATUS status ;
2008-10-04 04:52:59 +04:00
ZERO_STRUCT ( r2 ) ;
2004-05-27 10:27:21 +04:00
r2 . in . handle = r - > in . handle ;
r2 . in . level = r - > in . level ;
2008-10-24 17:05:57 +04:00
r2 . out . info = r - > out . info ;
2004-05-27 10:27:21 +04:00
2007-01-17 17:49:36 +03:00
status = dcesrv_lsa_QueryInfoPolicy2 ( dce_call , mem_ctx , & r2 ) ;
2004-05-27 10:27:21 +04:00
return status ;
}
2004-05-27 08:13:58 +04:00
/*
lsa_SetInfoPolicy
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_SetInfoPolicy ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-27 08:13:58 +04:00
struct lsa_SetInfoPolicy * r )
{
2008-10-04 04:52:59 +04:00
/* need to support this */
2004-05-27 08:13:58 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_ClearAuditLog
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_ClearAuditLog ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-27 08:13:58 +04:00
struct lsa_ClearAuditLog * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_CreateAccount
2008-03-20 04:12:10 +03:00
This call does not seem to have any long - term effects , hence no database operations
2008-10-04 04:52:59 +04:00
we need to talk to the MS product group to find out what this account database means !
answer is that the lsa database is totally separate from the SAM and
ldap databases . We are going to need a separate ldb to store these
accounts . The SIDs on this account bear no relation to the SIDs in
AD
2004-05-27 08:13:58 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_CreateAccount ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-27 08:13:58 +04:00
struct lsa_CreateAccount * r )
{
2006-07-06 09:23:29 +04:00
struct lsa_account_state * astate ;
struct lsa_policy_state * state ;
struct dcesrv_handle * h , * ah ;
ZERO_STRUCTP ( r - > out . acct_handle ) ;
DCESRV_PULL_HANDLE ( h , r - > in . handle , LSA_HANDLE_POLICY ) ;
state = h - > data ;
astate = talloc ( dce_call - > conn , struct lsa_account_state ) ;
if ( astate = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
astate - > account_sid = dom_sid_dup ( astate , r - > in . sid ) ;
if ( astate - > account_sid = = NULL ) {
talloc_free ( astate ) ;
return NT_STATUS_NO_MEMORY ;
}
astate - > policy = talloc_reference ( astate , state ) ;
astate - > access_mask = r - > in . access_mask ;
ah = dcesrv_handle_new ( dce_call - > context , LSA_HANDLE_ACCOUNT ) ;
if ( ! ah ) {
talloc_free ( astate ) ;
return NT_STATUS_NO_MEMORY ;
}
ah - > data = talloc_steal ( ah , astate ) ;
* r - > out . acct_handle = ah - > wire_handle ;
return NT_STATUS_OK ;
2004-05-27 08:13:58 +04:00
}
/*
lsa_EnumAccounts
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_EnumAccounts ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-27 08:13:58 +04:00
struct lsa_EnumAccounts * r )
{
2004-12-19 08:53:13 +03:00
struct dcesrv_handle * h ;
struct lsa_policy_state * state ;
2009-11-21 21:26:02 +03:00
int ret ;
2004-12-19 08:53:13 +03:00
struct ldb_message * * res ;
const char * const attrs [ ] = { " objectSid " , NULL } ;
2009-11-21 21:26:02 +03:00
uint32_t count , i ;
2004-12-19 08:53:13 +03:00
DCESRV_PULL_HANDLE ( h , r - > in . handle , LSA_HANDLE_POLICY ) ;
state = h - > data ;
2006-07-06 09:23:29 +04:00
/* NOTE: This call must only return accounts that have at least
one privilege set
*/
2009-10-16 10:05:27 +04:00
ret = gendb_search ( state - > pdb , mem_ctx , NULL , & res , attrs ,
2006-07-06 09:23:29 +04:00
" (&(objectSid=*)(privilege=*)) " ) ;
if ( ret < 0 ) {
2010-03-06 13:19:04 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2004-12-19 08:53:13 +03:00
}
if ( * r - > in . resume_handle > = ret ) {
return NT_STATUS_NO_MORE_ENTRIES ;
}
count = ret - * r - > in . resume_handle ;
if ( count > r - > in . num_entries ) {
count = r - > in . num_entries ;
}
if ( count = = 0 ) {
return NT_STATUS_NO_MORE_ENTRIES ;
}
2005-01-27 10:08:20 +03:00
r - > out . sids - > sids = talloc_array ( r - > out . sids , struct lsa_SidPtr , count ) ;
2004-12-19 08:53:13 +03:00
if ( r - > out . sids - > sids = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < count ; i + + ) {
2005-06-24 04:18:20 +04:00
r - > out . sids - > sids [ i ] . sid =
samdb_result_dom_sid ( r - > out . sids - > sids ,
res [ i + * r - > in . resume_handle ] ,
" objectSid " ) ;
NT_STATUS_HAVE_NO_MEMORY ( r - > out . sids - > sids [ i ] . sid ) ;
2004-12-19 08:53:13 +03:00
}
r - > out . sids - > num_sids = count ;
* r - > out . resume_handle = count + * r - > in . resume_handle ;
return NT_STATUS_OK ;
2004-05-27 08:13:58 +04:00
}
2010-03-22 17:48:31 +03:00
/* This decrypts and returns Trusted Domain Auth Information Internal data */
static NTSTATUS get_trustdom_auth_blob ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx , DATA_BLOB * auth_blob ,
struct trustDomainPasswords * auth_struct )
{
DATA_BLOB session_key = data_blob ( NULL , 0 ) ;
enum ndr_err_code ndr_err ;
NTSTATUS nt_status ;
nt_status = dcesrv_fetch_session_key ( dce_call - > conn , & session_key ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
arcfour_crypt_blob ( auth_blob - > data , auth_blob - > length , & session_key ) ;
ndr_err = ndr_pull_struct_blob ( auth_blob , mem_ctx ,
auth_struct ,
( ndr_pull_flags_fn_t ) ndr_pull_trustDomainPasswords ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
return NT_STATUS_INVALID_PARAMETER ;
}
return NT_STATUS_OK ;
}
static NTSTATUS get_trustauth_inout_blob ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
2010-07-16 06:06:48 +04:00
struct trustAuthInOutBlob * iopw ,
2010-03-22 17:48:31 +03:00
DATA_BLOB * trustauth_blob )
{
enum ndr_err_code ndr_err ;
ndr_err = ndr_push_struct_blob ( trustauth_blob , mem_ctx ,
2010-07-16 06:06:48 +04:00
iopw ,
2010-03-22 17:48:31 +03:00
( ndr_push_flags_fn_t ) ndr_push_trustAuthInOutBlob ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
return NT_STATUS_INVALID_PARAMETER ;
}
return NT_STATUS_OK ;
}
2004-05-27 08:13:58 +04:00
2010-03-22 23:37:24 +03:00
static NTSTATUS add_trust_user ( TALLOC_CTX * mem_ctx ,
struct ldb_context * sam_ldb ,
struct ldb_dn * base_dn ,
const char * netbios_name ,
2010-07-16 06:06:48 +04:00
struct trustAuthInOutBlob * in ,
2010-03-22 23:37:24 +03:00
struct ldb_dn * * user_dn )
{
struct ldb_message * msg ;
struct ldb_dn * dn ;
uint32_t i ;
int ret ;
dn = ldb_dn_copy ( mem_ctx , base_dn ) ;
if ( ! dn ) {
return NT_STATUS_NO_MEMORY ;
}
if ( ! ldb_dn_add_child_fmt ( dn , " cn=%s$,cn=users " , netbios_name ) ) {
return NT_STATUS_NO_MEMORY ;
}
msg = ldb_msg_new ( mem_ctx ) ;
if ( ! msg ) {
return NT_STATUS_NO_MEMORY ;
}
msg - > dn = dn ;
ret = ldb_msg_add_string ( msg , " objectClass " , " user " ) ;
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_NO_MEMORY ;
}
ret = ldb_msg_add_fmt ( msg , " samAccountName " , " %s$ " , netbios_name ) ;
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_NO_MEMORY ;
}
ret = ldb_msg_add_fmt ( msg , " userAccountControl " , " %u " ,
UF_INTERDOMAIN_TRUST_ACCOUNT ) ;
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < in - > count ; i + + ) {
const char * attribute ;
struct ldb_val v ;
2010-07-16 06:06:48 +04:00
switch ( in - > current . array [ i ] . AuthType ) {
2010-03-22 23:37:24 +03:00
case TRUST_AUTH_TYPE_NT4OWF :
attribute = " unicodePwd " ;
2010-07-16 06:06:48 +04:00
v . data = ( uint8_t * ) & in - > current . array [ i ] . AuthInfo . nt4owf . password ;
2010-03-22 23:37:24 +03:00
v . length = 16 ;
break ;
case TRUST_AUTH_TYPE_CLEAR :
attribute = " clearTextPassword " ;
2010-07-16 06:06:48 +04:00
v . data = in - > current . array [ i ] . AuthInfo . clear . password ;
v . length = in - > current . array [ i ] . AuthInfo . clear . size ;
2010-03-22 23:37:24 +03:00
break ;
default :
continue ;
}
ret = ldb_msg_add_value ( msg , attribute , & v , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_NO_MEMORY ;
}
}
/* create the trusted_domain user account */
ret = ldb_add ( sam_ldb , msg ) ;
if ( ret ! = LDB_SUCCESS ) {
DEBUG ( 0 , ( " Failed to create user record %s: %s \n " ,
ldb_dn_get_linearized ( msg - > dn ) ,
ldb_errstring ( sam_ldb ) ) ) ;
switch ( ret ) {
case LDB_ERR_ENTRY_ALREADY_EXISTS :
return NT_STATUS_DOMAIN_EXISTS ;
case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS :
return NT_STATUS_ACCESS_DENIED ;
default :
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
}
if ( user_dn ) {
* user_dn = dn ;
}
return NT_STATUS_OK ;
}
2005-01-12 05:40:25 +03:00
/*
lsa_CreateTrustedDomainEx2
*/
2008-09-08 04:55:34 +04:00
static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct lsa_CreateTrustedDomainEx2 * r ,
int op )
2005-01-12 05:40:25 +03:00
{
struct dcesrv_handle * policy_handle ;
struct lsa_policy_state * policy_state ;
struct lsa_trusted_domain_state * trusted_domain_state ;
struct dcesrv_handle * handle ;
2010-03-22 23:37:24 +03:00
struct ldb_message * * msgs , * msg ;
2005-01-12 05:40:25 +03:00
const char * attrs [ ] = {
NULL
} ;
2008-09-08 04:55:34 +04:00
const char * netbios_name ;
const char * dns_name ;
2005-01-12 05:40:25 +03:00
const char * name ;
2008-09-08 04:55:34 +04:00
DATA_BLOB trustAuthIncoming , trustAuthOutgoing , auth_blob ;
2008-09-30 08:36:21 +04:00
struct trustDomainPasswords auth_struct ;
2005-01-12 05:40:25 +03:00
int ret ;
2008-09-08 04:55:34 +04:00
NTSTATUS nt_status ;
2010-02-25 01:10:59 +03:00
struct ldb_context * sam_ldb ;
2010-02-25 00:54:16 +03:00
2008-09-08 04:55:34 +04:00
DCESRV_PULL_HANDLE ( policy_handle , r - > in . policy_handle , LSA_HANDLE_POLICY ) ;
2005-01-12 05:40:25 +03:00
ZERO_STRUCTP ( r - > out . trustdom_handle ) ;
2010-02-25 00:54:16 +03:00
2005-01-12 05:40:25 +03:00
policy_state = policy_handle - > data ;
2010-02-25 01:10:59 +03:00
sam_ldb = policy_state - > sam_ldb ;
2005-01-12 05:40:25 +03:00
2008-09-08 04:55:34 +04:00
netbios_name = r - > in . info - > netbios_name . string ;
if ( ! netbios_name ) {
2005-01-12 05:40:25 +03:00
return NT_STATUS_INVALID_PARAMETER ;
}
2010-02-25 00:54:16 +03:00
2008-09-08 04:55:34 +04:00
dns_name = r - > in . info - > domain_name . string ;
2010-02-25 00:54:16 +03:00
2008-10-04 04:52:59 +04:00
trusted_domain_state = talloc_zero ( mem_ctx , struct lsa_trusted_domain_state ) ;
2005-01-12 05:40:25 +03:00
if ( ! trusted_domain_state ) {
return NT_STATUS_NO_MEMORY ;
}
trusted_domain_state - > policy = policy_state ;
2008-09-08 04:55:34 +04:00
if ( strcasecmp ( netbios_name , " BUILTIN " ) = = 0
2010-02-25 00:54:16 +03:00
| | ( dns_name & & strcasecmp ( dns_name , " BUILTIN " ) = = 0 )
2008-09-08 04:55:34 +04:00
| | ( dom_sid_in_domain ( policy_state - > builtin_sid , r - > in . info - > sid ) ) ) {
2010-03-16 23:15:39 +03:00
return NT_STATUS_INVALID_PARAMETER ;
2005-01-12 05:40:25 +03:00
}
2008-09-08 04:55:34 +04:00
if ( strcasecmp ( netbios_name , policy_state - > domain_name ) = = 0
| | strcasecmp ( netbios_name , policy_state - > domain_dns ) = = 0
2010-02-25 00:54:16 +03:00
| | ( dns_name & & strcasecmp ( dns_name , policy_state - > domain_dns ) = = 0 )
2008-09-08 04:55:34 +04:00
| | ( dns_name & & strcasecmp ( dns_name , policy_state - > domain_name ) = = 0 )
| | ( dom_sid_equal ( policy_state - > domain_sid , r - > in . info - > sid ) ) ) {
return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED ;
}
/* While this is a REF pointer, some of the functions that wrap this don't provide this */
if ( op = = NDR_LSA_CREATETRUSTEDDOMAIN ) {
/* No secrets are created at this time, for this function */
auth_struct . outgoing . count = 0 ;
auth_struct . incoming . count = 0 ;
} else {
2010-03-22 17:48:31 +03:00
auth_blob = data_blob_const ( r - > in . auth_info - > auth_blob . data ,
r - > in . auth_info - > auth_blob . size ) ;
nt_status = get_trustdom_auth_blob ( dce_call , mem_ctx ,
& auth_blob , & auth_struct ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
2010-02-25 00:54:16 +03:00
}
2008-10-02 00:12:15 +04:00
if ( op = = NDR_LSA_CREATETRUSTEDDOMAINEX ) {
if ( auth_struct . incoming . count > 1 ) {
return NT_STATUS_INVALID_PARAMETER ;
}
}
2008-09-08 04:55:34 +04:00
}
if ( auth_struct . incoming . count ) {
2010-03-22 17:48:31 +03:00
nt_status = get_trustauth_inout_blob ( dce_call , mem_ctx ,
& auth_struct . incoming ,
& trustAuthIncoming ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
2008-09-08 04:55:34 +04:00
}
} else {
trustAuthIncoming = data_blob ( NULL , 0 ) ;
2005-01-12 05:40:25 +03:00
}
2010-02-25 00:54:16 +03:00
2008-09-08 04:55:34 +04:00
if ( auth_struct . outgoing . count ) {
2010-03-22 17:48:31 +03:00
nt_status = get_trustauth_inout_blob ( dce_call , mem_ctx ,
& auth_struct . outgoing ,
& trustAuthOutgoing ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
2008-09-08 04:55:34 +04:00
}
} else {
trustAuthOutgoing = data_blob ( NULL , 0 ) ;
}
2010-02-25 01:07:26 +03:00
ret = ldb_transaction_start ( sam_ldb ) ;
2008-09-08 04:55:34 +04:00
if ( ret ! = LDB_SUCCESS ) {
2005-01-12 05:40:25 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2008-09-08 04:55:34 +04:00
if ( dns_name ) {
char * dns_encoded = ldb_binary_encode_string ( mem_ctx , netbios_name ) ;
char * netbios_encoded = ldb_binary_encode_string ( mem_ctx , netbios_name ) ;
/* search for the trusted_domain record */
2010-02-25 01:07:26 +03:00
ret = gendb_search ( sam_ldb ,
2008-09-08 04:55:34 +04:00
mem_ctx , policy_state - > system_dn , & msgs , attrs ,
2010-02-25 00:54:16 +03:00
" (&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain)) " ,
2008-09-08 04:55:34 +04:00
dns_encoded , dns_encoded , dns_encoded , netbios_encoded , netbios_encoded , netbios_encoded ) ;
if ( ret > 0 ) {
2010-02-25 01:07:26 +03:00
ldb_transaction_cancel ( sam_ldb ) ;
2008-09-08 04:55:34 +04:00
return NT_STATUS_OBJECT_NAME_COLLISION ;
}
} else {
char * netbios_encoded = ldb_binary_encode_string ( mem_ctx , netbios_name ) ;
/* search for the trusted_domain record */
2010-02-25 01:07:26 +03:00
ret = gendb_search ( sam_ldb ,
2008-09-08 04:55:34 +04:00
mem_ctx , policy_state - > system_dn , & msgs , attrs ,
2010-02-25 00:54:16 +03:00
" (&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain)) " ,
2008-09-08 04:55:34 +04:00
netbios_encoded , netbios_encoded , netbios_encoded ) ;
if ( ret > 0 ) {
2010-02-25 01:07:26 +03:00
ldb_transaction_cancel ( sam_ldb ) ;
2008-09-08 04:55:34 +04:00
return NT_STATUS_OBJECT_NAME_COLLISION ;
}
}
2010-02-25 00:54:16 +03:00
2008-09-08 04:55:34 +04:00
if ( ret < 0 ) {
2010-02-25 01:07:26 +03:00
ldb_transaction_cancel ( sam_ldb ) ;
2008-09-08 04:55:34 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2010-02-25 00:54:16 +03:00
2008-09-08 04:55:34 +04:00
name = dns_name ? dns_name : netbios_name ;
msg = ldb_msg_new ( mem_ctx ) ;
if ( msg = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2006-11-22 03:59:34 +03:00
msg - > dn = ldb_dn_copy ( mem_ctx , policy_state - > system_dn ) ;
2006-12-27 06:23:25 +03:00
if ( ! ldb_dn_add_child_fmt ( msg - > dn , " cn=%s " , name ) ) {
2010-02-25 01:07:26 +03:00
ldb_transaction_cancel ( sam_ldb ) ;
2005-01-12 05:40:25 +03:00
return NT_STATUS_NO_MEMORY ;
}
2010-02-25 00:54:16 +03:00
2010-02-25 01:07:26 +03:00
samdb_msg_add_string ( sam_ldb , mem_ctx , msg , " flatname " , netbios_name ) ;
2005-01-12 05:40:25 +03:00
if ( r - > in . info - > sid ) {
2010-02-25 01:10:59 +03:00
ret = samdb_msg_add_dom_sid ( sam_ldb , mem_ctx , msg , " securityIdentifier " , r - > in . info - > sid ) ;
if ( ret ! = LDB_SUCCESS ) {
2010-02-25 01:07:26 +03:00
ldb_transaction_cancel ( sam_ldb ) ;
2010-02-25 01:10:59 +03:00
return NT_STATUS_INVALID_PARAMETER ;
2005-01-12 05:40:25 +03:00
}
}
2010-02-25 01:07:26 +03:00
samdb_msg_add_string ( sam_ldb , mem_ctx , msg , " objectClass " , " trustedDomain " ) ;
2008-09-01 08:43:00 +04:00
2010-02-25 01:07:26 +03:00
samdb_msg_add_int ( sam_ldb , mem_ctx , msg , " trustType " , r - > in . info - > trust_type ) ;
2008-09-01 08:43:00 +04:00
2010-02-25 01:07:26 +03:00
samdb_msg_add_int ( sam_ldb , mem_ctx , msg , " trustAttributes " , r - > in . info - > trust_attributes ) ;
2008-09-01 08:43:00 +04:00
2010-02-25 01:07:26 +03:00
samdb_msg_add_int ( sam_ldb , mem_ctx , msg , " trustDirection " , r - > in . info - > trust_direction ) ;
2010-02-25 00:54:16 +03:00
2008-09-08 04:55:34 +04:00
if ( dns_name ) {
2010-02-25 01:07:26 +03:00
samdb_msg_add_string ( sam_ldb , mem_ctx , msg , " trustPartner " , dns_name ) ;
2008-09-08 04:55:34 +04:00
}
if ( trustAuthIncoming . data ) {
ret = ldb_msg_add_value ( msg , " trustAuthIncoming " , & trustAuthIncoming , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
2010-02-25 01:07:26 +03:00
ldb_transaction_cancel ( sam_ldb ) ;
2008-09-08 04:55:34 +04:00
return NT_STATUS_NO_MEMORY ;
}
}
if ( trustAuthOutgoing . data ) {
ret = ldb_msg_add_value ( msg , " trustAuthOutgoing " , & trustAuthOutgoing , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
2010-02-25 01:07:26 +03:00
ldb_transaction_cancel ( sam_ldb ) ;
2008-09-08 04:55:34 +04:00
return NT_STATUS_NO_MEMORY ;
}
}
2005-01-12 05:40:25 +03:00
trusted_domain_state - > trusted_domain_dn = talloc_reference ( trusted_domain_state , msg - > dn ) ;
/* create the trusted_domain */
2010-08-06 00:00:27 +04:00
ret = dsdb_add ( sam_ldb , msg , DSDB_MODIFY_RELAX ) ;
2008-03-13 08:35:11 +03:00
switch ( ret ) {
case LDB_SUCCESS :
break ;
case LDB_ERR_ENTRY_ALREADY_EXISTS :
2010-02-25 01:07:26 +03:00
ldb_transaction_cancel ( sam_ldb ) ;
2008-03-13 08:35:11 +03:00
DEBUG ( 0 , ( " Failed to create trusted domain record %s: %s \n " ,
ldb_dn_get_linearized ( msg - > dn ) ,
2010-02-25 01:07:26 +03:00
ldb_errstring ( sam_ldb ) ) ) ;
2008-03-13 08:35:11 +03:00
return NT_STATUS_DOMAIN_EXISTS ;
case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS :
2010-02-25 01:07:26 +03:00
ldb_transaction_cancel ( sam_ldb ) ;
2008-03-13 08:35:11 +03:00
DEBUG ( 0 , ( " Failed to create trusted domain record %s: %s \n " ,
ldb_dn_get_linearized ( msg - > dn ) ,
2010-02-25 01:07:26 +03:00
ldb_errstring ( sam_ldb ) ) ) ;
2008-03-13 08:35:11 +03:00
return NT_STATUS_ACCESS_DENIED ;
default :
2010-02-25 01:07:26 +03:00
ldb_transaction_cancel ( sam_ldb ) ;
2008-03-13 08:35:11 +03:00
DEBUG ( 0 , ( " Failed to create user record %s: %s \n " ,
ldb_dn_get_linearized ( msg - > dn ) ,
2010-02-25 01:07:26 +03:00
ldb_errstring ( sam_ldb ) ) ) ;
2005-01-12 05:40:25 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2008-09-08 04:55:34 +04:00
if ( r - > in . info - > trust_direction & LSA_TRUST_DIRECTION_INBOUND ) {
2010-03-22 23:37:24 +03:00
struct ldb_dn * user_dn ;
2008-09-08 04:55:34 +04:00
/* Inbound trusts must also create a cn=users object to match */
2010-03-22 23:37:24 +03:00
nt_status = add_trust_user ( mem_ctx , sam_ldb ,
policy_state - > domain_dn ,
netbios_name ,
& auth_struct . incoming ,
& user_dn ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2010-02-25 01:07:26 +03:00
ldb_transaction_cancel ( sam_ldb ) ;
2010-03-22 23:37:24 +03:00
return nt_status ;
2008-09-08 04:55:34 +04:00
}
2010-03-22 23:37:24 +03:00
/* save the trust user dn */
trusted_domain_state - > trusted_domain_user_dn
= talloc_steal ( trusted_domain_state , user_dn ) ;
2008-09-08 04:55:34 +04:00
}
2010-02-25 01:07:26 +03:00
ret = ldb_transaction_commit ( sam_ldb ) ;
2008-09-08 04:55:34 +04:00
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2005-01-12 05:40:25 +03:00
handle = dcesrv_handle_new ( dce_call - > context , LSA_HANDLE_TRUSTED_DOMAIN ) ;
if ( ! handle ) {
return NT_STATUS_NO_MEMORY ;
}
2010-02-25 00:54:16 +03:00
2005-01-12 05:40:25 +03:00
handle - > data = talloc_steal ( handle , trusted_domain_state ) ;
2010-02-25 00:54:16 +03:00
2005-01-12 05:40:25 +03:00
trusted_domain_state - > access_mask = r - > in . access_mask ;
trusted_domain_state - > policy = talloc_reference ( trusted_domain_state , policy_state ) ;
2010-02-25 00:54:16 +03:00
2005-01-12 05:40:25 +03:00
* r - > out . trustdom_handle = handle - > wire_handle ;
2010-02-25 00:54:16 +03:00
2005-01-12 05:40:25 +03:00
return NT_STATUS_OK ;
}
2008-09-08 04:55:34 +04:00
/*
lsa_CreateTrustedDomainEx2
*/
static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2 ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct lsa_CreateTrustedDomainEx2 * r )
{
return dcesrv_lsa_CreateTrustedDomain_base ( dce_call , mem_ctx , r , NDR_LSA_CREATETRUSTEDDOMAINEX2 ) ;
}
/*
lsa_CreateTrustedDomainEx
*/
static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct lsa_CreateTrustedDomainEx * r )
{
struct lsa_CreateTrustedDomainEx2 r2 ;
r2 . in . policy_handle = r - > in . policy_handle ;
r2 . in . info = r - > in . info ;
r2 . in . auth_info = r - > in . auth_info ;
r2 . out . trustdom_handle = r - > out . trustdom_handle ;
return dcesrv_lsa_CreateTrustedDomain_base ( dce_call , mem_ctx , & r2 , NDR_LSA_CREATETRUSTEDDOMAINEX ) ;
}
/*
lsa_CreateTrustedDomain
*/
static NTSTATUS dcesrv_lsa_CreateTrustedDomain ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct lsa_CreateTrustedDomain * r )
{
struct lsa_CreateTrustedDomainEx2 r2 ;
r2 . in . policy_handle = r - > in . policy_handle ;
r2 . in . info = talloc ( mem_ctx , struct lsa_TrustDomainInfoInfoEx ) ;
if ( ! r2 . in . info ) {
return NT_STATUS_NO_MEMORY ;
}
r2 . in . info - > domain_name . string = NULL ;
r2 . in . info - > netbios_name = r - > in . info - > name ;
r2 . in . info - > sid = r - > in . info - > sid ;
r2 . in . info - > trust_direction = LSA_TRUST_DIRECTION_OUTBOUND ;
r2 . in . info - > trust_type = LSA_TRUST_TYPE_DOWNLEVEL ;
r2 . in . info - > trust_attributes = 0 ;
r2 . in . access_mask = r - > in . access_mask ;
r2 . out . trustdom_handle = r - > out . trustdom_handle ;
return dcesrv_lsa_CreateTrustedDomain_base ( dce_call , mem_ctx , & r2 , NDR_LSA_CREATETRUSTEDDOMAIN ) ;
}
2005-01-12 05:40:25 +03:00
/*
lsa_OpenTrustedDomain
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_OpenTrustedDomain ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-01-12 05:40:25 +03:00
struct lsa_OpenTrustedDomain * r )
{
struct dcesrv_handle * policy_handle ;
struct lsa_policy_state * policy_state ;
struct lsa_trusted_domain_state * trusted_domain_state ;
struct dcesrv_handle * handle ;
struct ldb_message * * msgs ;
const char * attrs [ ] = {
2008-09-08 04:55:34 +04:00
" trustDirection " ,
" flatname " ,
2005-01-12 05:40:25 +03:00
NULL
} ;
const char * sid_string ;
int ret ;
DCESRV_PULL_HANDLE ( policy_handle , r - > in . handle , LSA_HANDLE_POLICY ) ;
ZERO_STRUCTP ( r - > out . trustdom_handle ) ;
policy_state = policy_handle - > data ;
2008-10-04 04:52:59 +04:00
trusted_domain_state = talloc_zero ( mem_ctx , struct lsa_trusted_domain_state ) ;
2005-01-12 05:40:25 +03:00
if ( ! trusted_domain_state ) {
return NT_STATUS_NO_MEMORY ;
}
trusted_domain_state - > policy = policy_state ;
sid_string = dom_sid_string ( mem_ctx , r - > in . sid ) ;
if ( ! sid_string ) {
return NT_STATUS_NO_MEMORY ;
}
/* search for the trusted_domain record */
2005-03-23 04:30:43 +03:00
ret = gendb_search ( trusted_domain_state - > policy - > sam_ldb ,
2005-01-12 05:40:25 +03:00
mem_ctx , policy_state - > system_dn , & msgs , attrs ,
" (&(securityIdentifier=%s)(objectclass=trustedDomain)) " ,
sid_string ) ;
if ( ret = = 0 ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
if ( ret ! = 1 ) {
2005-08-18 19:02:01 +04:00
DEBUG ( 0 , ( " Found %d records matching DN %s \n " , ret ,
2006-11-22 05:05:19 +03:00
ldb_dn_get_linearized ( policy_state - > system_dn ) ) ) ;
2005-01-12 05:40:25 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
trusted_domain_state - > trusted_domain_dn = talloc_reference ( trusted_domain_state , msgs [ 0 ] - > dn ) ;
2008-09-08 04:55:34 +04:00
trusted_domain_state - > trusted_domain_user_dn = NULL ;
if ( ldb_msg_find_attr_as_int ( msgs [ 0 ] , " trustDirection " , 0 ) & LSA_TRUST_DIRECTION_INBOUND ) {
const char * flatname = ldb_binary_encode_string ( mem_ctx , ldb_msg_find_attr_as_string ( msgs [ 0 ] , " flatname " , NULL ) ) ;
/* search for the trusted_domain record */
ret = gendb_search ( trusted_domain_state - > policy - > sam_ldb ,
mem_ctx , policy_state - > domain_dn , & msgs , attrs ,
2010-10-05 11:27:36 +04:00
" (&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%u)) " ,
2008-09-08 04:55:34 +04:00
flatname , UF_INTERDOMAIN_TRUST_ACCOUNT ) ;
if ( ret = = 1 ) {
trusted_domain_state - > trusted_domain_user_dn = talloc_steal ( trusted_domain_state , msgs [ 0 ] - > dn ) ;
}
}
2005-01-12 05:40:25 +03:00
handle = dcesrv_handle_new ( dce_call - > context , LSA_HANDLE_TRUSTED_DOMAIN ) ;
if ( ! handle ) {
return NT_STATUS_NO_MEMORY ;
}
handle - > data = talloc_steal ( handle , trusted_domain_state ) ;
trusted_domain_state - > access_mask = r - > in . access_mask ;
trusted_domain_state - > policy = talloc_reference ( trusted_domain_state , policy_state ) ;
* r - > out . trustdom_handle = handle - > wire_handle ;
return NT_STATUS_OK ;
}
/*
lsa_OpenTrustedDomainByName
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName ( struct dcesrv_call_state * dce_call ,
2005-01-12 05:40:25 +03:00
TALLOC_CTX * mem_ctx ,
struct lsa_OpenTrustedDomainByName * r )
{
struct dcesrv_handle * policy_handle ;
2010-02-20 01:46:42 +03:00
2005-01-12 05:40:25 +03:00
struct lsa_policy_state * policy_state ;
struct lsa_trusted_domain_state * trusted_domain_state ;
struct dcesrv_handle * handle ;
struct ldb_message * * msgs ;
const char * attrs [ ] = {
NULL
} ;
2010-02-20 02:09:48 +03:00
char * td_name ;
2005-01-12 05:40:25 +03:00
int ret ;
DCESRV_PULL_HANDLE ( policy_handle , r - > in . handle , LSA_HANDLE_POLICY ) ;
ZERO_STRUCTP ( r - > out . trustdom_handle ) ;
policy_state = policy_handle - > data ;
if ( ! r - > in . name . string ) {
return NT_STATUS_INVALID_PARAMETER ;
}
2010-02-20 01:46:42 +03:00
2008-10-04 04:52:59 +04:00
trusted_domain_state = talloc_zero ( mem_ctx , struct lsa_trusted_domain_state ) ;
2005-01-12 05:40:25 +03:00
if ( ! trusted_domain_state ) {
return NT_STATUS_NO_MEMORY ;
}
2005-01-12 10:57:33 +03:00
trusted_domain_state - > policy = policy_state ;
2005-01-12 05:40:25 +03:00
/* search for the trusted_domain record */
2010-02-20 02:09:48 +03:00
td_name = ldb_binary_encode_string ( mem_ctx , r - > in . name . string ) ;
2005-03-23 04:30:43 +03:00
ret = gendb_search ( trusted_domain_state - > policy - > sam_ldb ,
2005-01-12 05:40:25 +03:00
mem_ctx , policy_state - > system_dn , & msgs , attrs ,
2010-02-20 02:09:48 +03:00
" (&(|(flatname=%s)(cn=%s)(trustPartner=%s)) "
" (objectclass=trustedDomain)) " ,
td_name , td_name , td_name ) ;
2005-01-12 05:40:25 +03:00
if ( ret = = 0 ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
2010-02-20 01:46:42 +03:00
2005-01-12 05:40:25 +03:00
if ( ret ! = 1 ) {
2005-08-18 19:02:01 +04:00
DEBUG ( 0 , ( " Found %d records matching DN %s \n " , ret ,
2006-11-22 05:05:19 +03:00
ldb_dn_get_linearized ( policy_state - > system_dn ) ) ) ;
2005-01-12 05:40:25 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2010-02-20 02:09:48 +03:00
/* TODO: perform access checks */
2005-01-12 05:40:25 +03:00
trusted_domain_state - > trusted_domain_dn = talloc_reference ( trusted_domain_state , msgs [ 0 ] - > dn ) ;
2010-02-20 01:46:42 +03:00
2005-01-12 05:40:25 +03:00
handle = dcesrv_handle_new ( dce_call - > context , LSA_HANDLE_TRUSTED_DOMAIN ) ;
if ( ! handle ) {
return NT_STATUS_NO_MEMORY ;
}
2010-02-20 01:46:42 +03:00
2005-01-12 05:40:25 +03:00
handle - > data = talloc_steal ( handle , trusted_domain_state ) ;
2010-02-20 01:46:42 +03:00
2005-01-12 05:40:25 +03:00
trusted_domain_state - > access_mask = r - > in . access_mask ;
trusted_domain_state - > policy = talloc_reference ( trusted_domain_state , policy_state ) ;
2010-02-20 01:46:42 +03:00
2005-01-12 05:40:25 +03:00
* r - > out . trustdom_handle = handle - > wire_handle ;
2010-02-20 01:46:42 +03:00
2005-01-12 05:40:25 +03:00
return NT_STATUS_OK ;
}
2006-08-31 12:22:13 +04:00
2005-01-12 05:40:25 +03:00
/*
2006-08-31 12:22:13 +04:00
lsa_SetTrustedDomainInfo
2005-01-12 05:40:25 +03:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-08-31 12:22:13 +04:00
struct lsa_SetTrustedDomainInfo * r )
2005-01-12 05:40:25 +03:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
2006-08-31 12:22:13 +04:00
2010-03-16 23:15:39 +03:00
/* parameters 4 to 6 are optional if the dn is a dn of a TDO object,
* otherwise at least one must be provided */
static NTSTATUS get_tdo ( struct ldb_context * sam , TALLOC_CTX * mem_ctx ,
struct ldb_dn * basedn , const char * dns_domain ,
const char * netbios , struct dom_sid2 * sid ,
struct ldb_message * * * msgs )
{
const char * attrs [ ] = { " flatname " , " trustPartner " ,
" securityIdentifier " , " trustDirection " ,
" trustType " , " trustAttributes " ,
" trustPosixOffset " ,
" msDs-supportedEncryptionTypes " , NULL } ;
char * dns = NULL ;
char * nbn = NULL ;
char * sidstr = NULL ;
char * filter ;
int ret ;
if ( dns_domain | | netbios | | sid ) {
filter = talloc_strdup ( mem_ctx ,
" (&(objectclass=trustedDomain)(| " ) ;
} else {
filter = talloc_strdup ( mem_ctx ,
" (objectclass=trustedDomain) " ) ;
}
if ( ! filter ) {
return NT_STATUS_NO_MEMORY ;
}
if ( dns_domain ) {
dns = ldb_binary_encode_string ( mem_ctx , dns_domain ) ;
if ( ! dns ) {
return NT_STATUS_NO_MEMORY ;
}
filter = talloc_asprintf_append ( filter ,
" (trustPartner=%s) " , dns ) ;
if ( ! filter ) {
return NT_STATUS_NO_MEMORY ;
}
}
if ( netbios ) {
nbn = ldb_binary_encode_string ( mem_ctx , netbios ) ;
if ( ! nbn ) {
return NT_STATUS_NO_MEMORY ;
}
filter = talloc_asprintf_append ( filter ,
" (flatname=%s) " , nbn ) ;
if ( ! filter ) {
return NT_STATUS_NO_MEMORY ;
}
}
if ( sid ) {
sidstr = dom_sid_string ( mem_ctx , sid ) ;
if ( ! sidstr ) {
return NT_STATUS_INVALID_PARAMETER ;
}
filter = talloc_asprintf_append ( filter ,
" (securityIdentifier=%s) " ,
sidstr ) ;
if ( ! filter ) {
return NT_STATUS_NO_MEMORY ;
}
}
if ( dns_domain | | netbios | | sid ) {
filter = talloc_asprintf_append ( filter , " )) " ) ;
if ( ! filter ) {
return NT_STATUS_NO_MEMORY ;
}
}
ret = gendb_search ( sam , mem_ctx , basedn , msgs , attrs , " %s " , filter ) ;
if ( ret = = 0 ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
if ( ret ! = 1 ) {
return NT_STATUS_OBJECT_NAME_COLLISION ;
}
return NT_STATUS_OK ;
}
static NTSTATUS update_uint32_t_value ( TALLOC_CTX * mem_ctx ,
struct ldb_message * orig ,
struct ldb_message * dest ,
const char * attribute ,
uint32_t value ,
uint32_t * orig_value )
{
const struct ldb_val * orig_val ;
uint32_t orig_uint = 0 ;
char * str_val ;
int flags = 0 ;
int ret ;
orig_val = ldb_msg_find_ldb_val ( orig , attribute ) ;
if ( ! orig_val | | ! orig_val - > data ) {
/* add new attribute */
flags = LDB_FLAG_MOD_ADD ;
} else {
errno = 0 ;
orig_uint = strtoul ( ( const char * ) orig_val - > data , NULL , 0 ) ;
if ( errno ! = 0 | | orig_uint ! = value ) {
/* replace also if can't get value */
flags = LDB_FLAG_MOD_REPLACE ;
}
}
if ( flags = = 0 ) {
/* stored value is identical, nothing to change */
goto done ;
}
ret = ldb_msg_add_empty ( dest , attribute , flags , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_NO_MEMORY ;
}
str_val = talloc_asprintf ( mem_ctx , " %u " , value ) ;
if ( ! str_val ) {
return NT_STATUS_NO_MEMORY ;
}
ret = ldb_msg_add_steal_string ( dest , attribute , str_val ) ;
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_NO_MEMORY ;
}
done :
if ( orig_value ) {
* orig_value = orig_uint ;
}
return NT_STATUS_OK ;
}
static NTSTATUS update_trust_user ( TALLOC_CTX * mem_ctx ,
struct ldb_context * sam_ldb ,
struct ldb_dn * base_dn ,
bool delete_user ,
const char * netbios_name ,
2010-07-16 06:06:48 +04:00
struct trustAuthInOutBlob * in )
2010-03-16 23:15:39 +03:00
{
const char * attrs [ ] = { " userAccountControl " , NULL } ;
struct ldb_message * * msgs ;
struct ldb_message * msg ;
uint32_t uac ;
uint32_t i ;
int ret ;
ret = gendb_search ( sam_ldb , mem_ctx ,
base_dn , & msgs , attrs ,
" samAccountName=%s$ " , netbios_name ) ;
if ( ret > 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
if ( ret = = 0 ) {
if ( delete_user ) {
return NT_STATUS_OK ;
}
/* ok no existing user, add it from scratch */
return add_trust_user ( mem_ctx , sam_ldb , base_dn ,
netbios_name , in , NULL ) ;
}
/* check user is what we are looking for */
uac = ldb_msg_find_attr_as_uint ( msgs [ 0 ] ,
" userAccountControl " , 0 ) ;
if ( ! ( uac & UF_INTERDOMAIN_TRUST_ACCOUNT ) ) {
return NT_STATUS_OBJECT_NAME_COLLISION ;
}
if ( delete_user ) {
ret = ldb_delete ( sam_ldb , msgs [ 0 ] - > dn ) ;
switch ( ret ) {
case LDB_SUCCESS :
return NT_STATUS_OK ;
case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS :
return NT_STATUS_ACCESS_DENIED ;
default :
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
}
/* entry exists, just modify secret if any */
if ( in - > count = = 0 ) {
return NT_STATUS_OK ;
}
msg = ldb_msg_new ( mem_ctx ) ;
if ( ! msg ) {
return NT_STATUS_NO_MEMORY ;
}
msg - > dn = msgs [ 0 ] - > dn ;
for ( i = 0 ; i < in - > count ; i + + ) {
const char * attribute ;
struct ldb_val v ;
2010-07-16 06:06:48 +04:00
switch ( in - > current . array [ i ] . AuthType ) {
2010-03-16 23:15:39 +03:00
case TRUST_AUTH_TYPE_NT4OWF :
attribute = " unicodePwd " ;
2010-07-16 06:06:48 +04:00
v . data = ( uint8_t * ) & in - > current . array [ i ] . AuthInfo . nt4owf . password ;
2010-03-16 23:15:39 +03:00
v . length = 16 ;
break ;
case TRUST_AUTH_TYPE_CLEAR :
attribute = " clearTextPassword " ;
2010-07-16 06:06:48 +04:00
v . data = in - > current . array [ i ] . AuthInfo . clear . password ;
v . length = in - > current . array [ i ] . AuthInfo . clear . size ;
2010-03-16 23:15:39 +03:00
break ;
default :
continue ;
}
ret = ldb_msg_add_empty ( msg , attribute ,
LDB_FLAG_MOD_REPLACE , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_NO_MEMORY ;
}
ret = ldb_msg_add_value ( msg , attribute , & v , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_NO_MEMORY ;
}
}
/* create the trusted_domain user account */
ret = ldb_modify ( sam_ldb , msg ) ;
if ( ret ! = LDB_SUCCESS ) {
DEBUG ( 0 , ( " Failed to create user record %s: %s \n " ,
ldb_dn_get_linearized ( msg - > dn ) ,
ldb_errstring ( sam_ldb ) ) ) ;
switch ( ret ) {
case LDB_ERR_ENTRY_ALREADY_EXISTS :
return NT_STATUS_DOMAIN_EXISTS ;
case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS :
return NT_STATUS_ACCESS_DENIED ;
default :
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
}
return NT_STATUS_OK ;
}
static NTSTATUS setInfoTrustedDomain_base ( struct dcesrv_call_state * dce_call ,
struct dcesrv_handle * p_handle ,
TALLOC_CTX * mem_ctx ,
struct ldb_message * dom_msg ,
enum lsa_TrustDomInfoEnum level ,
union lsa_TrustedDomainInfo * info )
{
struct lsa_policy_state * p_state = p_handle - > data ;
uint32_t * posix_offset = NULL ;
struct lsa_TrustDomainInfoInfoEx * info_ex = NULL ;
struct lsa_TrustDomainInfoAuthInfo * auth_info = NULL ;
struct lsa_TrustDomainInfoAuthInfoInternal * auth_info_int = NULL ;
uint32_t * enc_types = NULL ;
DATA_BLOB trustAuthIncoming , trustAuthOutgoing , auth_blob ;
struct trustDomainPasswords auth_struct ;
NTSTATUS nt_status ;
struct ldb_message * * msgs ;
struct ldb_message * msg ;
bool add_outgoing = false ;
bool add_incoming = false ;
bool del_outgoing = false ;
bool del_incoming = false ;
bool in_transaction = false ;
int ret ;
2010-04-16 00:37:40 +04:00
bool am_rodc ;
2010-03-16 23:15:39 +03:00
switch ( level ) {
case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET :
posix_offset = & info - > posix_offset . posix_offset ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_INFO_EX :
info_ex = & info - > info_ex ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO :
auth_info = & info - > auth_info ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO :
posix_offset = & info - > full_info . posix_offset . posix_offset ;
info_ex = & info - > full_info . info_ex ;
auth_info = & info - > full_info . auth_info ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL :
auth_info_int = & info - > auth_info_internal ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL :
posix_offset = & info - > full_info_internal . posix_offset . posix_offset ;
info_ex = & info - > full_info_internal . info_ex ;
auth_info_int = & info - > full_info_internal . auth_info ;
break ;
case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES :
enc_types = & info - > enc_types . enc_types ;
break ;
default :
return NT_STATUS_INVALID_PARAMETER ;
}
if ( auth_info ) {
/* FIXME: not handled yet */
return NT_STATUS_INVALID_PARAMETER ;
}
/* decode auth_info_int if set */
if ( auth_info_int ) {
/* now decrypt blob */
auth_blob = data_blob_const ( auth_info_int - > auth_blob . data ,
auth_info_int - > auth_blob . size ) ;
nt_status = get_trustdom_auth_blob ( dce_call , mem_ctx ,
& auth_blob , & auth_struct ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
}
if ( info_ex ) {
/* verify data matches */
if ( info_ex - > trust_attributes &
LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE ) {
/* TODO: check what behavior level we have */
if ( strcasecmp_m ( p_state - > domain_dns ,
p_state - > forest_dns ) ! = 0 ) {
return NT_STATUS_INVALID_DOMAIN_STATE ;
}
}
2010-04-16 00:37:40 +04:00
ret = samdb_rodc ( p_state - > sam_ldb , & am_rodc ) ;
if ( ret = = LDB_SUCCESS & & am_rodc ) {
2010-03-16 23:15:39 +03:00
return NT_STATUS_NO_SUCH_DOMAIN ;
}
/* verify only one object matches the dns/netbios/sid
* triplet and that this is the one we already have */
nt_status = get_tdo ( p_state - > sam_ldb , mem_ctx ,
p_state - > system_dn ,
info_ex - > domain_name . string ,
info_ex - > netbios_name . string ,
info_ex - > sid , & msgs ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
if ( ldb_dn_compare ( dom_msg - > dn , msgs [ 0 ] - > dn ) ! = 0 ) {
return NT_STATUS_OBJECT_NAME_COLLISION ;
}
talloc_free ( msgs ) ;
}
/* TODO: should we fetch previous values from the existing entry
* and append them ? */
if ( auth_struct . incoming . count ) {
nt_status = get_trustauth_inout_blob ( dce_call , mem_ctx ,
& auth_struct . incoming ,
& trustAuthIncoming ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
} else {
trustAuthIncoming = data_blob ( NULL , 0 ) ;
}
if ( auth_struct . outgoing . count ) {
nt_status = get_trustauth_inout_blob ( dce_call , mem_ctx ,
& auth_struct . outgoing ,
& trustAuthOutgoing ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
} else {
trustAuthOutgoing = data_blob ( NULL , 0 ) ;
}
msg = ldb_msg_new ( mem_ctx ) ;
if ( msg = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
msg - > dn = dom_msg - > dn ;
if ( posix_offset ) {
nt_status = update_uint32_t_value ( mem_ctx , dom_msg , msg ,
" trustPosixOffset " ,
* posix_offset , NULL ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
}
if ( info_ex ) {
uint32_t origattrs ;
uint32_t origdir ;
uint32_t tmp ;
int origtype ;
nt_status = update_uint32_t_value ( mem_ctx , dom_msg , msg ,
" trustDirection " ,
info_ex - > trust_direction ,
& origdir ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
tmp = info_ex - > trust_direction ^ origdir ;
if ( tmp & LSA_TRUST_DIRECTION_INBOUND ) {
if ( origdir & LSA_TRUST_DIRECTION_INBOUND ) {
del_incoming = true ;
} else {
add_incoming = true ;
}
}
if ( tmp & LSA_TRUST_DIRECTION_OUTBOUND ) {
if ( origdir & LSA_TRUST_DIRECTION_OUTBOUND ) {
del_outgoing = true ;
} else {
add_outgoing = true ;
}
}
origtype = ldb_msg_find_attr_as_int ( dom_msg , " trustType " , - 1 ) ;
if ( origtype = = - 1 | | origtype ! = info_ex - > trust_type ) {
DEBUG ( 1 , ( " Attempted to change trust type! "
" Operation not handled \n " ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
nt_status = update_uint32_t_value ( mem_ctx , dom_msg , msg ,
" trustAttributes " ,
info_ex - > trust_attributes ,
& origattrs ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
/* TODO: check forestFunctionality from ldb opaque */
/* TODO: check what is set makes sense */
/* for now refuse changes */
if ( origattrs = = - 1 | |
origattrs ! = info_ex - > trust_attributes ) {
DEBUG ( 1 , ( " Attempted to change trust attributes! "
" Operation not handled \n " ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
}
if ( enc_types ) {
nt_status = update_uint32_t_value ( mem_ctx , dom_msg , msg ,
" msDS-SupportedEncryptionTypes " ,
* enc_types , NULL ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
}
if ( add_incoming & & trustAuthIncoming . data ) {
ret = ldb_msg_add_empty ( msg , " trustAuthIncoming " ,
LDB_FLAG_MOD_REPLACE , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_NO_MEMORY ;
}
ret = ldb_msg_add_value ( msg , " trustAuthIncoming " ,
& trustAuthIncoming , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_NO_MEMORY ;
}
}
if ( add_outgoing & & trustAuthOutgoing . data ) {
ret = ldb_msg_add_empty ( msg , " trustAuthIncoming " ,
LDB_FLAG_MOD_REPLACE , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_NO_MEMORY ;
}
ret = ldb_msg_add_value ( msg , " trustAuthOutgoing " ,
& trustAuthOutgoing , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_NO_MEMORY ;
}
}
/* start transaction */
ret = ldb_transaction_start ( p_state - > sam_ldb ) ;
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
in_transaction = true ;
ret = ldb_modify ( p_state - > sam_ldb , msg ) ;
if ( ret ! = LDB_SUCCESS ) {
DEBUG ( 1 , ( " Failed to modify trusted domain record %s: %s \n " ,
ldb_dn_get_linearized ( msg - > dn ) ,
ldb_errstring ( p_state - > sam_ldb ) ) ) ;
if ( ret = = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS ) {
nt_status = NT_STATUS_ACCESS_DENIED ;
} else {
nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
goto done ;
}
if ( add_incoming | | del_incoming ) {
const char * netbios_name ;
netbios_name = ldb_msg_find_attr_as_string ( dom_msg ,
" flatname " , NULL ) ;
if ( ! netbios_name ) {
nt_status = NT_STATUS_INVALID_DOMAIN_STATE ;
goto done ;
}
nt_status = update_trust_user ( mem_ctx ,
p_state - > sam_ldb ,
p_state - > domain_dn ,
del_incoming ,
netbios_name ,
& auth_struct . incoming ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
goto done ;
}
}
/* ok, all fine, commit transaction and return */
ret = ldb_transaction_commit ( p_state - > sam_ldb ) ;
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
in_transaction = false ;
nt_status = NT_STATUS_OK ;
done :
if ( in_transaction ) {
ldb_transaction_cancel ( p_state - > sam_ldb ) ;
}
return nt_status ;
}
/*
2006-08-31 12:22:13 +04:00
lsa_SetInfomrationTrustedDomain
2005-01-12 05:40:25 +03:00
*/
2010-03-16 23:15:39 +03:00
static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain (
struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct lsa_SetInformationTrustedDomain * r )
2005-01-12 05:40:25 +03:00
{
2010-03-16 23:15:39 +03:00
struct dcesrv_handle * h ;
struct lsa_trusted_domain_state * td_state ;
struct ldb_message * * msgs ;
NTSTATUS nt_status ;
DCESRV_PULL_HANDLE ( h , r - > in . trustdom_handle ,
LSA_HANDLE_TRUSTED_DOMAIN ) ;
td_state = talloc_get_type ( h - > data , struct lsa_trusted_domain_state ) ;
/* get the trusted domain object */
nt_status = get_tdo ( td_state - > policy - > sam_ldb , mem_ctx ,
td_state - > trusted_domain_dn ,
NULL , NULL , NULL , & msgs ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
if ( NT_STATUS_EQUAL ( nt_status ,
NT_STATUS_OBJECT_NAME_NOT_FOUND ) ) {
return nt_status ;
}
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
return setInfoTrustedDomain_base ( dce_call , h , mem_ctx ,
msgs [ 0 ] , r - > in . level , r - > in . info ) ;
2005-01-12 05:40:25 +03:00
}
/*
2006-08-31 12:22:13 +04:00
lsa_DeleteTrustedDomain
2005-01-12 05:40:25 +03:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_DeleteTrustedDomain ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-08-31 12:22:13 +04:00
struct lsa_DeleteTrustedDomain * r )
2005-01-12 05:40:25 +03:00
{
2006-08-31 12:22:13 +04:00
NTSTATUS status ;
2009-02-02 14:25:14 +03:00
struct lsa_OpenTrustedDomain opn ;
struct lsa_DeleteObject del ;
2006-08-31 12:22:13 +04:00
struct dcesrv_handle * h ;
2009-02-02 14:25:14 +03:00
opn . in . handle = r - > in . handle ;
opn . in . sid = r - > in . dom_sid ;
opn . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
opn . out . trustdom_handle = talloc ( mem_ctx , struct policy_handle ) ;
if ( ! opn . out . trustdom_handle ) {
2006-08-31 12:22:13 +04:00
return NT_STATUS_NO_MEMORY ;
}
2009-02-02 14:25:14 +03:00
status = dcesrv_lsa_OpenTrustedDomain ( dce_call , mem_ctx , & opn ) ;
2006-08-31 12:22:13 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2009-02-02 14:25:14 +03:00
DCESRV_PULL_HANDLE ( h , opn . out . trustdom_handle , DCESRV_HANDLE_ANY ) ;
2006-08-31 12:22:13 +04:00
talloc_steal ( mem_ctx , h ) ;
2009-02-02 14:25:14 +03:00
del . in . handle = opn . out . trustdom_handle ;
del . out . handle = opn . out . trustdom_handle ;
status = dcesrv_lsa_DeleteObject ( dce_call , mem_ctx , & del ) ;
2006-08-31 12:22:13 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
return NT_STATUS_OK ;
2005-01-12 05:40:25 +03:00
}
2006-08-31 12:22:13 +04:00
static NTSTATUS fill_trust_domain_ex ( TALLOC_CTX * mem_ctx ,
struct ldb_message * msg ,
struct lsa_TrustDomainInfoInfoEx * info_ex )
{
info_ex - > domain_name . string
= ldb_msg_find_attr_as_string ( msg , " trustPartner " , NULL ) ;
info_ex - > netbios_name . string
= ldb_msg_find_attr_as_string ( msg , " flatname " , NULL ) ;
info_ex - > sid
= samdb_result_dom_sid ( mem_ctx , msg , " securityIdentifier " ) ;
info_ex - > trust_direction
= ldb_msg_find_attr_as_int ( msg , " trustDirection " , 0 ) ;
info_ex - > trust_type
= ldb_msg_find_attr_as_int ( msg , " trustType " , 0 ) ;
info_ex - > trust_attributes
= ldb_msg_find_attr_as_int ( msg , " trustAttributes " , 0 ) ;
return NT_STATUS_OK ;
}
2005-01-12 05:40:25 +03:00
/*
lsa_QueryTrustedDomainInfo
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-01-12 14:54:11 +03:00
struct lsa_QueryTrustedDomainInfo * r )
2005-01-12 05:40:25 +03:00
{
2008-10-21 12:33:27 +04:00
union lsa_TrustedDomainInfo * info = NULL ;
2005-01-12 14:54:11 +03:00
struct dcesrv_handle * h ;
struct lsa_trusted_domain_state * trusted_domain_state ;
struct ldb_message * msg ;
int ret ;
struct ldb_message * * res ;
const char * attrs [ ] = {
2006-08-31 12:22:13 +04:00
" flatname " ,
" trustPartner " ,
2005-01-12 14:54:11 +03:00
" securityIdentifier " ,
2006-08-31 12:22:13 +04:00
" trustDirection " ,
" trustType " ,
" trustAttributes " ,
2008-08-26 04:32:49 +04:00
" msDs-supportedEncryptionTypes " ,
2005-01-12 14:54:11 +03:00
NULL
} ;
DCESRV_PULL_HANDLE ( h , r - > in . trustdom_handle , LSA_HANDLE_TRUSTED_DOMAIN ) ;
2008-10-04 04:52:59 +04:00
trusted_domain_state = talloc_get_type ( h - > data , struct lsa_trusted_domain_state ) ;
2005-01-12 14:54:11 +03:00
/* pull all the user attributes */
2005-06-14 23:15:17 +04:00
ret = gendb_search_dn ( trusted_domain_state - > policy - > sam_ldb , mem_ctx ,
trusted_domain_state - > trusted_domain_dn , & res , attrs ) ;
2005-01-12 14:54:11 +03:00
if ( ret ! = 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
msg = res [ 0 ] ;
2008-10-21 12:33:27 +04:00
info = talloc_zero ( mem_ctx , union lsa_TrustedDomainInfo ) ;
if ( ! info ) {
2005-01-12 14:54:11 +03:00
return NT_STATUS_NO_MEMORY ;
}
2008-10-21 12:33:27 +04:00
* r - > out . info = info ;
2005-01-12 14:54:11 +03:00
switch ( r - > in . level ) {
case LSA_TRUSTED_DOMAIN_INFO_NAME :
2008-10-21 12:33:27 +04:00
info - > name . netbios_name . string
2005-01-12 14:54:11 +03:00
= samdb_result_string ( msg , " flatname " , NULL ) ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET :
2008-10-21 12:33:27 +04:00
info - > posix_offset . posix_offset
2005-01-12 14:54:11 +03:00
= samdb_result_uint ( msg , " posixOffset " , 0 ) ;
break ;
2006-08-31 12:22:13 +04:00
#if 0 /* Win2k3 doesn't implement this */
case LSA_TRUSTED_DOMAIN_INFO_BASIC :
r - > out . info - > info_basic . netbios_name . string
= ldb_msg_find_attr_as_string ( msg , " flatname " , NULL ) ;
r - > out . info - > info_basic . sid
= samdb_result_dom_sid ( mem_ctx , msg , " securityIdentifier " ) ;
break ;
# endif
case LSA_TRUSTED_DOMAIN_INFO_INFO_EX :
2008-10-21 12:33:27 +04:00
return fill_trust_domain_ex ( mem_ctx , msg , & info - > info_ex ) ;
2006-08-31 12:22:13 +04:00
case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO :
2008-10-21 12:33:27 +04:00
ZERO_STRUCT ( info - > full_info ) ;
return fill_trust_domain_ex ( mem_ctx , msg , & info - > full_info . info_ex ) ;
2006-08-31 12:22:13 +04:00
2008-08-26 04:32:49 +04:00
case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL :
2008-10-21 12:33:27 +04:00
ZERO_STRUCT ( info - > full_info2_internal ) ;
info - > full_info2_internal . posix_offset . posix_offset
2008-08-26 04:32:49 +04:00
= samdb_result_uint ( msg , " posixOffset " , 0 ) ;
2008-10-21 12:33:27 +04:00
return fill_trust_domain_ex ( mem_ctx , msg , & info - > full_info2_internal . info . info_ex ) ;
2008-08-26 04:32:49 +04:00
2009-07-16 04:48:34 +04:00
case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES :
2008-10-21 12:33:27 +04:00
info - > enc_types . enc_types
2008-08-26 04:32:49 +04:00
= samdb_result_uint ( msg , " msDs-supportedEncryptionTypes " , KERB_ENCTYPE_RC4_HMAC_MD5 ) ;
break ;
2006-08-31 12:22:13 +04:00
2008-08-26 04:32:49 +04:00
case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS :
case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL :
2006-08-31 12:22:13 +04:00
/* oops, we don't want to return the info after all */
2008-10-21 12:33:27 +04:00
talloc_free ( info ) ;
2008-10-28 14:21:44 +03:00
* r - > out . info = NULL ;
2006-08-31 12:22:13 +04:00
return NT_STATUS_INVALID_PARAMETER ;
2005-01-12 14:54:11 +03:00
default :
/* oops, we don't want to return the info after all */
2008-10-21 12:33:27 +04:00
talloc_free ( info ) ;
2008-10-28 14:21:44 +03:00
* r - > out . info = NULL ;
2005-01-12 14:54:11 +03:00
return NT_STATUS_INVALID_INFO_CLASS ;
}
return NT_STATUS_OK ;
2005-01-12 05:40:25 +03:00
}
/*
2006-08-31 12:22:13 +04:00
lsa_QueryTrustedDomainInfoBySid
2005-01-12 05:40:25 +03:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-08-31 12:22:13 +04:00
struct lsa_QueryTrustedDomainInfoBySid * r )
2005-01-12 05:40:25 +03:00
{
2006-08-31 12:22:13 +04:00
NTSTATUS status ;
2009-02-02 14:25:14 +03:00
struct lsa_OpenTrustedDomain opn ;
2006-08-31 12:22:13 +04:00
struct lsa_QueryTrustedDomainInfo query ;
struct dcesrv_handle * h ;
2009-02-02 14:25:14 +03:00
opn . in . handle = r - > in . handle ;
opn . in . sid = r - > in . dom_sid ;
opn . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
opn . out . trustdom_handle = talloc ( mem_ctx , struct policy_handle ) ;
if ( ! opn . out . trustdom_handle ) {
2006-08-31 12:22:13 +04:00
return NT_STATUS_NO_MEMORY ;
}
2009-02-02 14:25:14 +03:00
status = dcesrv_lsa_OpenTrustedDomain ( dce_call , mem_ctx , & opn ) ;
2006-08-31 12:22:13 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2005-01-12 05:40:25 +03:00
2006-08-31 12:22:13 +04:00
/* Ensure this handle goes away at the end of this call */
2009-02-02 14:25:14 +03:00
DCESRV_PULL_HANDLE ( h , opn . out . trustdom_handle , DCESRV_HANDLE_ANY ) ;
2006-08-31 12:22:13 +04:00
talloc_steal ( mem_ctx , h ) ;
2008-10-21 12:33:27 +04:00
2009-02-02 14:25:14 +03:00
query . in . trustdom_handle = opn . out . trustdom_handle ;
2006-08-31 12:22:13 +04:00
query . in . level = r - > in . level ;
2008-10-21 04:34:45 +04:00
query . out . info = r - > out . info ;
2007-01-17 17:49:36 +03:00
status = dcesrv_lsa_QueryTrustedDomainInfo ( dce_call , mem_ctx , & query ) ;
2006-08-31 12:22:13 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2008-10-21 04:34:45 +04:00
2006-08-31 12:22:13 +04:00
return NT_STATUS_OK ;
2005-01-12 05:40:25 +03:00
}
/*
lsa_SetTrustedDomainInfoByName
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName ( struct dcesrv_call_state * dce_call ,
2005-01-12 05:40:25 +03:00
TALLOC_CTX * mem_ctx ,
struct lsa_SetTrustedDomainInfoByName * r )
{
2010-03-16 23:15:39 +03:00
struct dcesrv_handle * policy_handle ;
struct lsa_policy_state * policy_state ;
struct ldb_message * * msgs ;
NTSTATUS nt_status ;
DCESRV_PULL_HANDLE ( policy_handle , r - > in . handle , LSA_HANDLE_POLICY ) ;
policy_state = policy_handle - > data ;
/* get the trusted domain object */
nt_status = get_tdo ( policy_state - > sam_ldb , mem_ctx ,
policy_state - > domain_dn ,
r - > in . trusted_domain - > string ,
r - > in . trusted_domain - > string ,
NULL , & msgs ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
if ( NT_STATUS_EQUAL ( nt_status ,
NT_STATUS_OBJECT_NAME_NOT_FOUND ) ) {
return nt_status ;
}
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
return setInfoTrustedDomain_base ( dce_call , policy_handle , mem_ctx ,
msgs [ 0 ] , r - > in . level , r - > in . info ) ;
2005-01-12 05:40:25 +03:00
}
2006-08-31 12:22:13 +04:00
/*
lsa_QueryTrustedDomainInfoByName
2005-01-12 05:40:25 +03:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName ( struct dcesrv_call_state * dce_call ,
2006-08-31 12:22:13 +04:00
TALLOC_CTX * mem_ctx ,
struct lsa_QueryTrustedDomainInfoByName * r )
2005-01-12 05:40:25 +03:00
{
2006-08-31 12:22:13 +04:00
NTSTATUS status ;
2009-02-02 14:25:14 +03:00
struct lsa_OpenTrustedDomainByName opn ;
2006-08-31 12:22:13 +04:00
struct lsa_QueryTrustedDomainInfo query ;
struct dcesrv_handle * h ;
2009-02-02 14:25:14 +03:00
opn . in . handle = r - > in . handle ;
opn . in . name = * r - > in . trusted_domain ;
opn . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
opn . out . trustdom_handle = talloc ( mem_ctx , struct policy_handle ) ;
if ( ! opn . out . trustdom_handle ) {
2006-08-31 12:22:13 +04:00
return NT_STATUS_NO_MEMORY ;
}
2009-02-02 14:25:14 +03:00
status = dcesrv_lsa_OpenTrustedDomainByName ( dce_call , mem_ctx , & opn ) ;
2006-08-31 12:22:13 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
/* Ensure this handle goes away at the end of this call */
2009-02-02 14:25:14 +03:00
DCESRV_PULL_HANDLE ( h , opn . out . trustdom_handle , DCESRV_HANDLE_ANY ) ;
2006-08-31 12:22:13 +04:00
talloc_steal ( mem_ctx , h ) ;
2009-02-02 14:25:14 +03:00
query . in . trustdom_handle = opn . out . trustdom_handle ;
2006-08-31 12:22:13 +04:00
query . in . level = r - > in . level ;
2008-10-21 12:23:14 +04:00
query . out . info = r - > out . info ;
2007-01-17 17:49:36 +03:00
status = dcesrv_lsa_QueryTrustedDomainInfo ( dce_call , mem_ctx , & query ) ;
2006-08-31 12:22:13 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
return NT_STATUS_OK ;
2005-01-12 05:40:25 +03:00
}
/*
2006-08-31 12:22:13 +04:00
lsa_CloseTrustedDomainEx
2005-01-12 05:40:25 +03:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx ( struct dcesrv_call_state * dce_call ,
2005-01-12 05:40:25 +03:00
TALLOC_CTX * mem_ctx ,
struct lsa_CloseTrustedDomainEx * r )
2004-05-27 08:13:58 +04:00
{
2006-08-31 12:22:13 +04:00
/* The result of a bad hair day from an IDL programmer? Not
* implmented in Win2k3 . You should always just lsa_Close
* anyway . */
return NT_STATUS_NOT_IMPLEMENTED ;
2004-05-27 08:13:58 +04:00
}
2005-01-12 10:57:33 +03:00
/*
comparison function for sorting lsa_DomainInformation array
*/
2006-08-31 12:22:13 +04:00
static int compare_DomainInfo ( struct lsa_DomainInfo * e1 , struct lsa_DomainInfo * e2 )
2005-01-12 10:57:33 +03:00
{
2006-09-01 08:37:31 +04:00
return strcasecmp_m ( e1 - > name . string , e2 - > name . string ) ;
2005-01-12 10:57:33 +03:00
}
2004-05-27 08:13:58 +04:00
/*
lsa_EnumTrustDom
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_EnumTrustDom ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-01-12 10:57:33 +03:00
struct lsa_EnumTrustDom * r )
2004-05-27 08:13:58 +04:00
{
2005-01-12 10:57:33 +03:00
struct dcesrv_handle * policy_handle ;
2006-08-31 12:22:13 +04:00
struct lsa_DomainInfo * entries ;
2005-01-12 10:57:33 +03:00
struct lsa_policy_state * policy_state ;
struct ldb_message * * domains ;
const char * attrs [ ] = {
" flatname " ,
" securityIdentifier " ,
NULL
} ;
int count , i ;
* r - > out . resume_handle = 0 ;
r - > out . domains - > domains = NULL ;
r - > out . domains - > count = 0 ;
DCESRV_PULL_HANDLE ( policy_handle , r - > in . handle , LSA_HANDLE_POLICY ) ;
policy_state = policy_handle - > data ;
/* search for all users in this domain. This could possibly be cached and
resumed based on resume_key */
2005-03-23 04:30:43 +03:00
count = gendb_search ( policy_state - > sam_ldb , mem_ctx , policy_state - > system_dn , & domains , attrs ,
2005-01-12 10:57:33 +03:00
" objectclass=trustedDomain " ) ;
2010-03-06 13:19:04 +03:00
if ( count < 0 ) {
2005-01-12 10:57:33 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2006-08-31 12:22:13 +04:00
/* convert to lsa_TrustInformation format */
entries = talloc_array ( mem_ctx , struct lsa_DomainInfo , count ) ;
2005-01-12 10:57:33 +03:00
if ( ! entries ) {
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < count ; i + + ) {
entries [ i ] . sid = samdb_result_dom_sid ( mem_ctx , domains [ i ] , " securityIdentifier " ) ;
entries [ i ] . name . string = samdb_result_string ( domains [ i ] , " flatname " , NULL ) ;
}
/* sort the results by name */
2010-02-13 05:00:55 +03:00
TYPESAFE_QSORT ( entries , count , compare_DomainInfo ) ;
2005-01-12 10:57:33 +03:00
if ( * r - > in . resume_handle > = count ) {
* r - > out . resume_handle = - 1 ;
return NT_STATUS_NO_MORE_ENTRIES ;
}
/* return the rest, limit by max_size. Note that we
use the w2k3 element size value of 60 */
r - > out . domains - > count = count - * r - > in . resume_handle ;
r - > out . domains - > count = MIN ( r - > out . domains - > count ,
1 + ( r - > in . max_size / LSA_ENUM_TRUST_DOMAIN_MULTIPLIER ) ) ;
r - > out . domains - > domains = entries + * r - > in . resume_handle ;
r - > out . domains - > count = r - > out . domains - > count ;
if ( r - > out . domains - > count < count - * r - > in . resume_handle ) {
* r - > out . resume_handle = * r - > in . resume_handle + r - > out . domains - > count ;
return STATUS_MORE_ENTRIES ;
}
2009-10-21 04:18:54 +04:00
/* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
* always be larger than the previous input resume handle , in
* particular when hitting the last query it is vital to set the
* resume handle correctly to avoid infinite client loops , as
* seen e . g . with Windows XP SP3 when resume handle is 0 and
* status is NT_STATUS_OK - gd */
* r - > out . resume_handle = ( uint32_t ) - 1 ;
2005-01-12 10:57:33 +03:00
return NT_STATUS_OK ;
2004-05-27 08:13:58 +04:00
}
2006-08-31 12:22:13 +04:00
/*
comparison function for sorting lsa_DomainInformation array
*/
static int compare_TrustDomainInfoInfoEx ( struct lsa_TrustDomainInfoInfoEx * e1 , struct lsa_TrustDomainInfoInfoEx * e2 )
{
2006-09-01 08:37:31 +04:00
return strcasecmp_m ( e1 - > netbios_name . string , e2 - > netbios_name . string ) ;
2006-08-31 12:22:13 +04:00
}
/*
lsa_EnumTrustedDomainsEx
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-08-31 12:22:13 +04:00
struct lsa_EnumTrustedDomainsEx * r )
{
struct dcesrv_handle * policy_handle ;
struct lsa_TrustDomainInfoInfoEx * entries ;
struct lsa_policy_state * policy_state ;
struct ldb_message * * domains ;
const char * attrs [ ] = {
" flatname " ,
" trustPartner " ,
" securityIdentifier " ,
" trustDirection " ,
" trustType " ,
" trustAttributes " ,
NULL
} ;
NTSTATUS nt_status ;
int count , i ;
* r - > out . resume_handle = 0 ;
r - > out . domains - > domains = NULL ;
r - > out . domains - > count = 0 ;
DCESRV_PULL_HANDLE ( policy_handle , r - > in . handle , LSA_HANDLE_POLICY ) ;
policy_state = policy_handle - > data ;
/* search for all users in this domain. This could possibly be cached and
resumed based on resume_key */
count = gendb_search ( policy_state - > sam_ldb , mem_ctx , policy_state - > system_dn , & domains , attrs ,
" objectclass=trustedDomain " ) ;
2010-03-06 13:19:04 +03:00
if ( count < 0 ) {
2006-08-31 12:22:13 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
/* convert to lsa_DomainInformation format */
entries = talloc_array ( mem_ctx , struct lsa_TrustDomainInfoInfoEx , count ) ;
if ( ! entries ) {
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < count ; i + + ) {
nt_status = fill_trust_domain_ex ( mem_ctx , domains [ i ] , & entries [ i ] ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
}
/* sort the results by name */
2010-02-13 05:00:55 +03:00
TYPESAFE_QSORT ( entries , count , compare_TrustDomainInfoInfoEx ) ;
2006-08-31 12:22:13 +04:00
if ( * r - > in . resume_handle > = count ) {
* r - > out . resume_handle = - 1 ;
return NT_STATUS_NO_MORE_ENTRIES ;
}
/* return the rest, limit by max_size. Note that we
use the w2k3 element size value of 60 */
r - > out . domains - > count = count - * r - > in . resume_handle ;
r - > out . domains - > count = MIN ( r - > out . domains - > count ,
1 + ( r - > in . max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER ) ) ;
r - > out . domains - > domains = entries + * r - > in . resume_handle ;
r - > out . domains - > count = r - > out . domains - > count ;
if ( r - > out . domains - > count < count - * r - > in . resume_handle ) {
* r - > out . resume_handle = * r - > in . resume_handle + r - > out . domains - > count ;
return STATUS_MORE_ENTRIES ;
}
return NT_STATUS_OK ;
}
2004-05-27 08:13:58 +04:00
/*
lsa_OpenAccount
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_OpenAccount ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-19 08:01:52 +03:00
struct lsa_OpenAccount * r )
2004-05-27 08:13:58 +04:00
{
2004-12-19 08:01:52 +03:00
struct dcesrv_handle * h , * ah ;
struct lsa_policy_state * state ;
struct lsa_account_state * astate ;
ZERO_STRUCTP ( r - > out . acct_handle ) ;
DCESRV_PULL_HANDLE ( h , r - > in . handle , LSA_HANDLE_POLICY ) ;
state = h - > data ;
2005-01-27 10:08:20 +03:00
astate = talloc ( dce_call - > conn , struct lsa_account_state ) ;
2004-12-19 08:01:52 +03:00
if ( astate = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
astate - > account_sid = dom_sid_dup ( astate , r - > in . sid ) ;
if ( astate - > account_sid = = NULL ) {
talloc_free ( astate ) ;
return NT_STATUS_NO_MEMORY ;
}
astate - > policy = talloc_reference ( astate , state ) ;
astate - > access_mask = r - > in . access_mask ;
2005-01-10 15:15:26 +03:00
ah = dcesrv_handle_new ( dce_call - > context , LSA_HANDLE_ACCOUNT ) ;
2004-12-19 08:01:52 +03:00
if ( ! ah ) {
talloc_free ( astate ) ;
return NT_STATUS_NO_MEMORY ;
}
2005-01-10 15:15:26 +03:00
ah - > data = talloc_steal ( ah , astate ) ;
2004-12-19 08:01:52 +03:00
* r - > out . acct_handle = ah - > wire_handle ;
return NT_STATUS_OK ;
2004-05-27 08:13:58 +04:00
}
/*
lsa_EnumPrivsAccount
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_EnumPrivsAccount ( struct dcesrv_call_state * dce_call ,
2004-12-15 01:18:33 +03:00
TALLOC_CTX * mem_ctx ,
struct lsa_EnumPrivsAccount * r )
2004-05-27 08:13:58 +04:00
{
2004-12-19 09:41:27 +03:00
struct dcesrv_handle * h ;
struct lsa_account_state * astate ;
2009-11-21 21:26:02 +03:00
int ret ;
2010-09-11 10:58:45 +04:00
unsigned int i , j ;
2004-12-19 09:41:27 +03:00
struct ldb_message * * res ;
const char * const attrs [ ] = { " privilege " , NULL } ;
struct ldb_message_element * el ;
2006-07-06 09:23:29 +04:00
const char * sidstr ;
2008-10-21 04:11:54 +04:00
struct lsa_PrivilegeSet * privs ;
2004-12-19 09:41:27 +03:00
DCESRV_PULL_HANDLE ( h , r - > in . handle , LSA_HANDLE_ACCOUNT ) ;
astate = h - > data ;
2008-10-21 04:11:54 +04:00
privs = talloc ( mem_ctx , struct lsa_PrivilegeSet ) ;
if ( privs = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
privs - > count = 0 ;
privs - > unknown = 0 ;
privs - > set = NULL ;
* r - > out . privs = privs ;
2004-12-19 09:41:27 +03:00
2006-07-06 09:23:29 +04:00
sidstr = ldap_encode_ndr_dom_sid ( mem_ctx , astate - > account_sid ) ;
if ( sidstr = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2009-10-16 10:05:27 +04:00
ret = gendb_search ( astate - > policy - > pdb , mem_ctx , NULL , & res , attrs ,
2006-07-06 09:23:29 +04:00
" objectSid=%s " , sidstr ) ;
2010-03-06 13:19:04 +03:00
if ( ret < 0 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2004-12-19 09:41:27 +03:00
if ( ret ! = 1 ) {
return NT_STATUS_OK ;
}
el = ldb_msg_find_element ( res [ 0 ] , " privilege " ) ;
if ( el = = NULL | | el - > num_values = = 0 ) {
return NT_STATUS_OK ;
}
2008-10-21 04:11:54 +04:00
privs - > set = talloc_array ( privs ,
struct lsa_LUIDAttribute , el - > num_values ) ;
if ( privs - > set = = NULL ) {
2004-12-19 09:41:27 +03:00
return NT_STATUS_NO_MEMORY ;
}
2010-09-11 10:58:45 +04:00
j = 0 ;
2004-12-19 09:41:27 +03:00
for ( i = 0 ; i < el - > num_values ; i + + ) {
2005-07-13 19:18:20 +04:00
int id = sec_privilege_id ( ( const char * ) el - > values [ i ] . data ) ;
2010-08-30 08:00:50 +04:00
if ( id = = SEC_PRIV_INVALID ) {
2010-09-11 10:58:45 +04:00
/* Perhaps an account right, not a privilege */
continue ;
2004-12-19 09:41:27 +03:00
}
2010-09-11 10:58:45 +04:00
privs - > set [ j ] . attribute = 0 ;
privs - > set [ j ] . luid . low = id ;
privs - > set [ j ] . luid . high = 0 ;
j + + ;
2004-12-19 09:41:27 +03:00
}
2010-09-11 10:58:45 +04:00
privs - > count = j ;
2004-12-19 09:41:27 +03:00
return NT_STATUS_OK ;
2004-05-27 08:13:58 +04:00
}
2004-12-19 14:34:19 +03:00
/*
lsa_EnumAccountRights
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_EnumAccountRights ( struct dcesrv_call_state * dce_call ,
2004-12-19 14:34:19 +03:00
TALLOC_CTX * mem_ctx ,
struct lsa_EnumAccountRights * r )
{
struct dcesrv_handle * h ;
struct lsa_policy_state * state ;
2009-11-21 21:26:02 +03:00
int ret ;
unsigned int i ;
2004-12-19 14:34:19 +03:00
struct ldb_message * * res ;
const char * const attrs [ ] = { " privilege " , NULL } ;
const char * sidstr ;
struct ldb_message_element * el ;
DCESRV_PULL_HANDLE ( h , r - > in . handle , LSA_HANDLE_POLICY ) ;
state = h - > data ;
2005-06-24 04:18:20 +04:00
sidstr = ldap_encode_ndr_dom_sid ( mem_ctx , r - > in . sid ) ;
2004-12-19 14:34:19 +03:00
if ( sidstr = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2009-10-16 10:05:27 +04:00
ret = gendb_search ( state - > pdb , mem_ctx , NULL , & res , attrs ,
2006-07-06 09:23:29 +04:00
" (&(objectSid=%s)(privilege=*)) " , sidstr ) ;
if ( ret = = 0 ) {
2004-12-19 14:34:19 +03:00
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
2010-03-06 13:19:04 +03:00
if ( ret ! = 1 ) {
2006-07-06 09:23:29 +04:00
DEBUG ( 3 , ( " searching for account rights for SID: %s failed: %s " ,
dom_sid_string ( mem_ctx , r - > in . sid ) ,
2009-10-16 10:05:27 +04:00
ldb_errstring ( state - > pdb ) ) ) ;
2006-07-06 09:23:29 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2004-12-19 14:34:19 +03:00
el = ldb_msg_find_element ( res [ 0 ] , " privilege " ) ;
if ( el = = NULL | | el - > num_values = = 0 ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
r - > out . rights - > count = el - > num_values ;
2005-01-27 10:08:20 +03:00
r - > out . rights - > names = talloc_array ( r - > out . rights ,
2006-01-09 18:50:08 +03:00
struct lsa_StringLarge , r - > out . rights - > count ) ;
2004-12-19 14:34:19 +03:00
if ( r - > out . rights - > names = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < el - > num_values ; i + + ) {
2005-07-13 19:18:20 +04:00
r - > out . rights - > names [ i ] . string = ( const char * ) el - > values [ i ] . data ;
2004-12-19 14:34:19 +03:00
}
return NT_STATUS_OK ;
}
2004-05-27 08:13:58 +04:00
2004-12-19 10:50:19 +03:00
/*
helper for lsa_AddAccountRights and lsa_RemoveAccountRights
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_AddRemoveAccountRights ( struct dcesrv_call_state * dce_call ,
2004-12-19 10:50:19 +03:00
TALLOC_CTX * mem_ctx ,
struct lsa_policy_state * state ,
int ldb_flag ,
2004-12-19 14:34:19 +03:00
struct dom_sid * sid ,
2004-12-19 10:50:19 +03:00
const struct lsa_RightSet * rights )
{
2009-10-16 10:05:27 +04:00
const char * sidstr , * sidndrstr ;
2005-01-12 05:40:25 +03:00
struct ldb_message * msg ;
2006-07-06 09:23:29 +04:00
struct ldb_message_element * el ;
2009-11-21 21:26:02 +03:00
int ret ;
uint32_t i ;
2004-12-19 14:34:19 +03:00
struct lsa_EnumAccountRights r2 ;
2009-10-16 10:05:27 +04:00
char * dnstr ;
2004-12-19 10:50:19 +03:00
2010-04-22 10:48:01 +04:00
if ( security_session_user_level ( dce_call - > conn - > auth_state . session_info , NULL ) <
2009-10-16 11:22:48 +04:00
SECURITY_ADMINISTRATOR ) {
DEBUG ( 0 , ( " lsa_AddRemoveAccount refused for supplied security token \n " ) ) ;
return NT_STATUS_ACCESS_DENIED ;
}
2005-01-12 05:40:25 +03:00
msg = ldb_msg_new ( mem_ctx ) ;
if ( msg = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2009-10-16 10:05:27 +04:00
sidndrstr = ldap_encode_ndr_dom_sid ( msg , sid ) ;
NT_STATUS_HAVE_NO_MEMORY_AND_FREE ( sidndrstr , msg ) ;
2005-01-12 05:40:25 +03:00
2009-10-16 10:05:27 +04:00
sidstr = dom_sid_string ( msg , sid ) ;
NT_STATUS_HAVE_NO_MEMORY_AND_FREE ( sidstr , msg ) ;
dnstr = talloc_asprintf ( msg , " sid=%s " , sidstr ) ;
NT_STATUS_HAVE_NO_MEMORY_AND_FREE ( dnstr , msg ) ;
msg - > dn = ldb_dn_new ( msg , state - > pdb , dnstr ) ;
NT_STATUS_HAVE_NO_MEMORY_AND_FREE ( msg - > dn , msg ) ;
2004-12-19 14:34:19 +03:00
2010-08-17 05:21:11 +04:00
if ( LDB_FLAG_MOD_TYPE ( ldb_flag ) = = LDB_FLAG_MOD_ADD ) {
2004-12-19 14:34:19 +03:00
NTSTATUS status ;
r2 . in . handle = & state - > handle - > wire_handle ;
r2 . in . sid = sid ;
2005-01-27 10:08:20 +03:00
r2 . out . rights = talloc ( mem_ctx , struct lsa_RightSet ) ;
2004-12-19 14:34:19 +03:00
2007-01-17 17:49:36 +03:00
status = dcesrv_lsa_EnumAccountRights ( dce_call , mem_ctx , & r2 ) ;
2004-12-19 14:34:19 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
ZERO_STRUCTP ( r2 . out . rights ) ;
}
}
for ( i = 0 ; i < rights - > count ; i + + ) {
2010-08-30 08:00:50 +04:00
if ( sec_privilege_id ( rights - > names [ i ] . string ) = = SEC_PRIV_INVALID ) {
2010-09-11 10:58:45 +04:00
if ( sec_right_bit ( rights - > names [ i ] . string ) = = 0 ) {
talloc_free ( msg ) ;
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
2009-10-16 10:05:27 +04:00
talloc_free ( msg ) ;
2004-12-19 10:50:19 +03:00
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
2004-12-19 14:34:19 +03:00
2010-08-17 05:21:11 +04:00
if ( LDB_FLAG_MOD_TYPE ( ldb_flag ) = = LDB_FLAG_MOD_ADD ) {
2009-11-21 21:26:02 +03:00
uint32_t j ;
2004-12-19 14:34:19 +03:00
for ( j = 0 ; j < r2 . out . rights - > count ; j + + ) {
2005-08-30 15:55:05 +04:00
if ( strcasecmp_m ( r2 . out . rights - > names [ j ] . string ,
2004-12-19 14:34:19 +03:00
rights - > names [ i ] . string ) = = 0 ) {
break ;
}
}
if ( j ! = r2 . out . rights - > count ) continue ;
}
2006-07-06 09:23:29 +04:00
ret = ldb_msg_add_string ( msg , " privilege " , rights - > names [ i ] . string ) ;
if ( ret ! = LDB_SUCCESS ) {
2009-10-16 10:05:27 +04:00
talloc_free ( msg ) ;
2004-12-19 10:50:19 +03:00
return NT_STATUS_NO_MEMORY ;
}
2004-12-19 14:34:19 +03:00
}
2006-07-06 09:23:29 +04:00
el = ldb_msg_find_element ( msg , " privilege " ) ;
if ( ! el ) {
2009-10-16 10:05:27 +04:00
talloc_free ( msg ) ;
2004-12-19 14:34:19 +03:00
return NT_STATUS_OK ;
2004-12-19 10:50:19 +03:00
}
2009-10-16 10:05:27 +04:00
el - > flags = ldb_flag ;
ret = ldb_modify ( state - > pdb , msg ) ;
if ( ret = = LDB_ERR_NO_SUCH_OBJECT ) {
if ( samdb_msg_add_dom_sid ( state - > pdb , msg , msg , " objectSid " , sid ) ! = LDB_SUCCESS ) {
talloc_free ( msg ) ;
return NT_STATUS_NO_MEMORY ;
}
samdb_msg_add_string ( state - > pdb , msg , msg , " comment " , " added via LSA " ) ;
ret = ldb_add ( state - > pdb , msg ) ;
}
2009-11-21 21:46:25 +03:00
if ( ret ! = LDB_SUCCESS ) {
2010-08-17 05:21:11 +04:00
if ( LDB_FLAG_MOD_TYPE ( ldb_flag ) = = LDB_FLAG_MOD_DELETE & & ret = = LDB_ERR_NO_SUCH_ATTRIBUTE ) {
2009-10-16 10:05:27 +04:00
talloc_free ( msg ) ;
return NT_STATUS_OK ;
2004-12-19 10:50:19 +03:00
}
2006-07-06 09:23:29 +04:00
DEBUG ( 3 , ( " Could not %s attributes from %s: %s " ,
2010-08-17 05:21:11 +04:00
LDB_FLAG_MOD_TYPE ( ldb_flag ) = = LDB_FLAG_MOD_DELETE ? " delete " : " add " ,
2009-10-16 10:05:27 +04:00
ldb_dn_get_linearized ( msg - > dn ) , ldb_errstring ( state - > pdb ) ) ) ;
talloc_free ( msg ) ;
2004-12-19 10:50:19 +03:00
return NT_STATUS_UNEXPECTED_IO_ERROR ;
}
2009-10-16 10:05:27 +04:00
talloc_free ( msg ) ;
2004-12-19 10:50:19 +03:00
return NT_STATUS_OK ;
}
2004-05-27 08:13:58 +04:00
/*
2004-08-14 05:11:34 +04:00
lsa_AddPrivilegesToAccount
2004-05-27 08:13:58 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-19 10:50:19 +03:00
struct lsa_AddPrivilegesToAccount * r )
2004-05-27 08:13:58 +04:00
{
2004-12-19 10:50:19 +03:00
struct lsa_RightSet rights ;
struct dcesrv_handle * h ;
struct lsa_account_state * astate ;
2009-11-21 21:26:02 +03:00
uint32_t i ;
2004-12-19 10:50:19 +03:00
DCESRV_PULL_HANDLE ( h , r - > in . handle , LSA_HANDLE_ACCOUNT ) ;
astate = h - > data ;
rights . count = r - > in . privs - > count ;
2006-01-09 18:50:08 +03:00
rights . names = talloc_array ( mem_ctx , struct lsa_StringLarge , rights . count ) ;
2004-12-19 10:50:19 +03:00
if ( rights . names = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < rights . count ; i + + ) {
int id = r - > in . privs - > set [ i ] . luid . low ;
if ( r - > in . privs - > set [ i ] . luid . high ) {
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
rights . names [ i ] . string = sec_privilege_name ( id ) ;
if ( rights . names [ i ] . string = = NULL ) {
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
}
2007-01-17 17:49:36 +03:00
return dcesrv_lsa_AddRemoveAccountRights ( dce_call , mem_ctx , astate - > policy ,
2004-12-19 10:50:19 +03:00
LDB_FLAG_MOD_ADD , astate - > account_sid ,
& rights ) ;
2004-05-27 08:13:58 +04:00
}
/*
2004-08-14 05:11:34 +04:00
lsa_RemovePrivilegesFromAccount
2004-05-27 08:13:58 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-19 10:50:19 +03:00
struct lsa_RemovePrivilegesFromAccount * r )
2004-05-27 08:13:58 +04:00
{
2004-12-19 10:50:19 +03:00
struct lsa_RightSet * rights ;
struct dcesrv_handle * h ;
struct lsa_account_state * astate ;
2009-11-21 21:26:02 +03:00
uint32_t i ;
2004-12-19 10:50:19 +03:00
DCESRV_PULL_HANDLE ( h , r - > in . handle , LSA_HANDLE_ACCOUNT ) ;
astate = h - > data ;
2005-01-27 10:08:20 +03:00
rights = talloc ( mem_ctx , struct lsa_RightSet ) ;
2004-12-19 10:50:19 +03:00
if ( r - > in . remove_all = = 1 & &
r - > in . privs = = NULL ) {
struct lsa_EnumAccountRights r2 ;
NTSTATUS status ;
r2 . in . handle = & astate - > policy - > handle - > wire_handle ;
r2 . in . sid = astate - > account_sid ;
r2 . out . rights = rights ;
2007-01-17 17:49:36 +03:00
status = dcesrv_lsa_EnumAccountRights ( dce_call , mem_ctx , & r2 ) ;
2004-12-19 10:50:19 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2007-01-17 17:49:36 +03:00
return dcesrv_lsa_AddRemoveAccountRights ( dce_call , mem_ctx , astate - > policy ,
2004-12-19 10:50:19 +03:00
LDB_FLAG_MOD_DELETE , astate - > account_sid ,
r2 . out . rights ) ;
}
if ( r - > in . remove_all ! = 0 ) {
return NT_STATUS_INVALID_PARAMETER ;
}
rights - > count = r - > in . privs - > count ;
2006-01-09 18:50:08 +03:00
rights - > names = talloc_array ( mem_ctx , struct lsa_StringLarge , rights - > count ) ;
2004-12-19 10:50:19 +03:00
if ( rights - > names = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < rights - > count ; i + + ) {
int id = r - > in . privs - > set [ i ] . luid . low ;
if ( r - > in . privs - > set [ i ] . luid . high ) {
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
rights - > names [ i ] . string = sec_privilege_name ( id ) ;
if ( rights - > names [ i ] . string = = NULL ) {
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
}
2007-01-17 17:49:36 +03:00
return dcesrv_lsa_AddRemoveAccountRights ( dce_call , mem_ctx , astate - > policy ,
2004-12-19 10:50:19 +03:00
LDB_FLAG_MOD_DELETE , astate - > account_sid ,
rights ) ;
2004-05-27 08:13:58 +04:00
}
/*
2004-08-14 05:11:34 +04:00
lsa_GetQuotasForAccount
2004-05-27 08:13:58 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_GetQuotasForAccount ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-08-14 05:11:34 +04:00
struct lsa_GetQuotasForAccount * r )
2004-05-27 08:13:58 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2004-08-14 05:11:34 +04:00
lsa_SetQuotasForAccount
2004-05-27 08:13:58 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_SetQuotasForAccount ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-08-14 05:11:34 +04:00
struct lsa_SetQuotasForAccount * r )
2004-05-27 08:13:58 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2004-08-14 05:11:34 +04:00
lsa_GetSystemAccessAccount
2004-05-27 08:13:58 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_GetSystemAccessAccount ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-08-14 05:11:34 +04:00
struct lsa_GetSystemAccessAccount * r )
2004-05-27 08:13:58 +04:00
{
2010-09-11 10:58:45 +04:00
struct dcesrv_handle * h ;
struct lsa_account_state * astate ;
int ret ;
unsigned int i ;
struct ldb_message * * res ;
const char * const attrs [ ] = { " privilege " , NULL } ;
struct ldb_message_element * el ;
const char * sidstr ;
2008-10-21 04:11:54 +04:00
2010-09-11 10:58:45 +04:00
* ( r - > out . access_mask ) = 0x00000000 ;
2008-10-20 08:50:07 +04:00
2010-09-11 10:58:45 +04:00
DCESRV_PULL_HANDLE ( h , r - > in . handle , LSA_HANDLE_ACCOUNT ) ;
2008-10-20 08:50:07 +04:00
2010-09-11 10:58:45 +04:00
astate = h - > data ;
2008-10-20 08:50:07 +04:00
2010-09-11 10:58:45 +04:00
sidstr = ldap_encode_ndr_dom_sid ( mem_ctx , astate - > account_sid ) ;
if ( sidstr = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2008-10-20 08:50:07 +04:00
2010-09-11 10:58:45 +04:00
ret = gendb_search ( astate - > policy - > pdb , mem_ctx , NULL , & res , attrs ,
" objectSid=%s " , sidstr ) ;
if ( ret < 0 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
if ( ret ! = 1 ) {
return NT_STATUS_OK ;
}
2008-10-20 08:50:07 +04:00
2010-09-11 10:58:45 +04:00
el = ldb_msg_find_element ( res [ 0 ] , " privilege " ) ;
if ( el = = NULL | | el - > num_values = = 0 ) {
return NT_STATUS_OK ;
}
for ( i = 0 ; i < el - > num_values ; i + + ) {
uint32_t right_bit = sec_right_bit ( ( const char * ) el - > values [ i ] . data ) ;
if ( right_bit = = 0 ) {
/* Perhaps an privilege, not a right */
continue ;
2008-10-20 08:50:07 +04:00
}
2010-09-11 10:58:45 +04:00
* ( r - > out . access_mask ) | = right_bit ;
2008-10-20 08:50:07 +04:00
}
return NT_STATUS_OK ;
2004-05-27 08:13:58 +04:00
}
/*
2004-08-14 05:11:34 +04:00
lsa_SetSystemAccessAccount
2004-05-27 08:13:58 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_SetSystemAccessAccount ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-08-14 05:11:34 +04:00
struct lsa_SetSystemAccessAccount * r )
2004-05-27 08:13:58 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
2005-01-11 17:04:58 +03:00
/*
lsa_CreateSecret
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_CreateSecret ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-01-11 17:04:58 +03:00
struct lsa_CreateSecret * r )
{
struct dcesrv_handle * policy_handle ;
struct lsa_policy_state * policy_state ;
struct lsa_secret_state * secret_state ;
struct dcesrv_handle * handle ;
struct ldb_message * * msgs , * msg ;
const char * attrs [ ] = {
NULL
} ;
const char * name ;
int ret ;
DCESRV_PULL_HANDLE ( policy_handle , r - > in . handle , LSA_HANDLE_POLICY ) ;
ZERO_STRUCTP ( r - > out . sec_handle ) ;
2010-04-22 10:48:01 +04:00
switch ( security_session_user_level ( dce_call - > conn - > auth_state . session_info , NULL ) )
2008-03-20 04:12:10 +03:00
{
case SECURITY_SYSTEM :
case SECURITY_ADMINISTRATOR :
break ;
default :
/* Users and annonymous are not allowed create secrets */
return NT_STATUS_ACCESS_DENIED ;
}
2005-01-11 17:04:58 +03:00
policy_state = policy_handle - > data ;
if ( ! r - > in . name . string ) {
return NT_STATUS_INVALID_PARAMETER ;
}
secret_state = talloc ( mem_ctx , struct lsa_secret_state ) ;
if ( ! secret_state ) {
return NT_STATUS_NO_MEMORY ;
}
2005-01-12 05:40:25 +03:00
secret_state - > policy = policy_state ;
2005-01-11 17:04:58 +03:00
msg = ldb_msg_new ( mem_ctx ) ;
if ( msg = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
if ( strncmp ( " G$ " , r - > in . name . string , 2 ) = = 0 ) {
const char * name2 ;
name = & r - > in . name . string [ 2 ] ;
2008-09-08 06:46:04 +04:00
/* We need to connect to the database as system, as this is one of the rare RPC calls that must read the secrets (and this is denied otherwise) */
secret_state - > sam_ldb = talloc_reference ( secret_state ,
2010-10-10 19:00:45 +04:00
samdb_connect ( mem_ctx , dce_call - > event_ctx , dce_call - > conn - > dce_ctx - > lp_ctx , system_session ( dce_call - > conn - > dce_ctx - > lp_ctx ) , 0 ) ) ;
2007-10-07 02:25:41 +04:00
secret_state - > global = true ;
2005-01-11 17:04:58 +03:00
if ( strlen ( name ) < 1 ) {
return NT_STATUS_INVALID_PARAMETER ;
}
2005-12-19 10:07:11 +03:00
name2 = talloc_asprintf ( mem_ctx , " %s Secret " , ldb_binary_encode_string ( mem_ctx , name ) ) ;
2005-01-11 17:04:58 +03:00
/* search for the secret record */
2005-03-23 04:30:43 +03:00
ret = gendb_search ( secret_state - > sam_ldb ,
2005-01-11 17:04:58 +03:00
mem_ctx , policy_state - > system_dn , & msgs , attrs ,
" (&(cn=%s)(objectclass=secret)) " ,
name2 ) ;
if ( ret > 0 ) {
return NT_STATUS_OBJECT_NAME_COLLISION ;
}
2010-03-06 13:19:04 +03:00
if ( ret < 0 ) {
2006-07-06 09:23:29 +04:00
DEBUG ( 0 , ( " Failure searching for CN=%s: %s \n " ,
name2 , ldb_errstring ( secret_state - > sam_ldb ) ) ) ;
2005-01-11 17:04:58 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2006-11-22 03:59:34 +03:00
msg - > dn = ldb_dn_copy ( mem_ctx , policy_state - > system_dn ) ;
if ( ! name2 | | ! ldb_dn_add_child_fmt ( msg - > dn , " cn=%s " , name2 ) ) {
2005-01-11 17:04:58 +03:00
return NT_STATUS_NO_MEMORY ;
}
2005-02-27 14:35:47 +03:00
samdb_msg_add_string ( secret_state - > sam_ldb , mem_ctx , msg , " cn " , name2 ) ;
2005-01-11 17:04:58 +03:00
} else {
2007-10-07 02:25:41 +04:00
secret_state - > global = false ;
2005-01-12 01:16:14 +03:00
2005-01-11 17:04:58 +03:00
name = r - > in . name . string ;
if ( strlen ( name ) < 1 ) {
return NT_STATUS_INVALID_PARAMETER ;
}
2007-12-04 22:05:00 +03:00
secret_state - > sam_ldb = talloc_reference ( secret_state ,
2008-06-14 19:24:17 +04:00
secrets_db_connect ( mem_ctx , dce_call - > event_ctx , dce_call - > conn - > dce_ctx - > lp_ctx ) ) ;
2005-01-11 17:04:58 +03:00
/* search for the secret record */
2005-08-18 19:02:01 +04:00
ret = gendb_search ( secret_state - > sam_ldb , mem_ctx ,
2006-11-22 03:59:34 +03:00
ldb_dn_new ( mem_ctx , secret_state - > sam_ldb , " cn=LSA Secrets " ) ,
2005-08-18 19:02:01 +04:00
& msgs , attrs ,
2005-12-19 10:07:11 +03:00
" (&(cn=%s)(objectclass=secret)) " ,
ldb_binary_encode_string ( mem_ctx , name ) ) ;
2005-01-11 17:04:58 +03:00
if ( ret > 0 ) {
return NT_STATUS_OBJECT_NAME_COLLISION ;
}
2010-03-06 13:19:04 +03:00
if ( ret < 0 ) {
2006-07-06 09:23:29 +04:00
DEBUG ( 0 , ( " Failure searching for CN=%s: %s \n " ,
name , ldb_errstring ( secret_state - > sam_ldb ) ) ) ;
2005-01-11 17:04:58 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2006-11-22 03:59:34 +03:00
msg - > dn = ldb_dn_new_fmt ( mem_ctx , secret_state - > sam_ldb , " cn=%s,cn=LSA Secrets " , name ) ;
2005-02-27 14:35:47 +03:00
samdb_msg_add_string ( secret_state - > sam_ldb , mem_ctx , msg , " cn " , name ) ;
2005-01-11 17:04:58 +03:00
}
2005-01-12 05:40:25 +03:00
2005-02-27 14:35:47 +03:00
samdb_msg_add_string ( secret_state - > sam_ldb , mem_ctx , msg , " objectClass " , " secret " ) ;
2005-01-11 17:04:58 +03:00
secret_state - > secret_dn = talloc_reference ( secret_state , msg - > dn ) ;
/* create the secret */
2010-08-06 00:00:27 +04:00
ret = dsdb_add ( secret_state - > sam_ldb , msg , DSDB_MODIFY_RELAX ) ;
2009-11-21 21:46:25 +03:00
if ( ret ! = LDB_SUCCESS ) {
2006-07-06 09:23:29 +04:00
DEBUG ( 0 , ( " Failed to create secret record %s: %s \n " ,
2006-11-22 05:05:19 +03:00
ldb_dn_get_linearized ( msg - > dn ) ,
2006-07-06 09:23:29 +04:00
ldb_errstring ( secret_state - > sam_ldb ) ) ) ;
2007-09-07 11:31:26 +04:00
return NT_STATUS_ACCESS_DENIED ;
2005-01-11 17:04:58 +03:00
}
handle = dcesrv_handle_new ( dce_call - > context , LSA_HANDLE_SECRET ) ;
if ( ! handle ) {
return NT_STATUS_NO_MEMORY ;
}
handle - > data = talloc_steal ( handle , secret_state ) ;
secret_state - > access_mask = r - > in . access_mask ;
secret_state - > policy = talloc_reference ( secret_state , policy_state ) ;
* r - > out . sec_handle = handle - > wire_handle ;
return NT_STATUS_OK ;
}
2004-05-27 08:13:58 +04:00
/*
lsa_OpenSecret
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_OpenSecret ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-01-11 17:04:58 +03:00
struct lsa_OpenSecret * r )
2004-05-27 08:13:58 +04:00
{
2005-01-11 17:04:58 +03:00
struct dcesrv_handle * policy_handle ;
struct lsa_policy_state * policy_state ;
struct lsa_secret_state * secret_state ;
struct dcesrv_handle * handle ;
struct ldb_message * * msgs ;
const char * attrs [ ] = {
NULL
} ;
const char * name ;
int ret ;
DCESRV_PULL_HANDLE ( policy_handle , r - > in . handle , LSA_HANDLE_POLICY ) ;
ZERO_STRUCTP ( r - > out . sec_handle ) ;
policy_state = policy_handle - > data ;
if ( ! r - > in . name . string ) {
return NT_STATUS_INVALID_PARAMETER ;
}
2010-04-22 10:48:01 +04:00
switch ( security_session_user_level ( dce_call - > conn - > auth_state . session_info , NULL ) )
2008-03-20 04:12:10 +03:00
{
case SECURITY_SYSTEM :
case SECURITY_ADMINISTRATOR :
break ;
default :
/* Users and annonymous are not allowed to access secrets */
return NT_STATUS_ACCESS_DENIED ;
}
2005-01-11 17:04:58 +03:00
secret_state = talloc ( mem_ctx , struct lsa_secret_state ) ;
if ( ! secret_state ) {
return NT_STATUS_NO_MEMORY ;
}
2005-01-12 05:40:25 +03:00
secret_state - > policy = policy_state ;
2005-01-11 17:04:58 +03:00
if ( strncmp ( " G$ " , r - > in . name . string , 2 ) = = 0 ) {
name = & r - > in . name . string [ 2 ] ;
2008-09-08 06:46:04 +04:00
/* We need to connect to the database as system, as this is one of the rare RPC calls that must read the secrets (and this is denied otherwise) */
secret_state - > sam_ldb = talloc_reference ( secret_state ,
2010-10-10 19:00:45 +04:00
samdb_connect ( mem_ctx , dce_call - > event_ctx , dce_call - > conn - > dce_ctx - > lp_ctx , system_session ( dce_call - > conn - > dce_ctx - > lp_ctx ) , 0 ) ) ;
2007-10-07 02:25:41 +04:00
secret_state - > global = true ;
2005-01-11 17:04:58 +03:00
if ( strlen ( name ) < 1 ) {
return NT_STATUS_INVALID_PARAMETER ;
}
/* search for the secret record */
2005-03-23 04:30:43 +03:00
ret = gendb_search ( secret_state - > sam_ldb ,
2005-01-11 17:04:58 +03:00
mem_ctx , policy_state - > system_dn , & msgs , attrs ,
" (&(cn=%s Secret)(objectclass=secret)) " ,
2005-12-19 10:07:11 +03:00
ldb_binary_encode_string ( mem_ctx , name ) ) ;
2005-01-11 17:04:58 +03:00
if ( ret = = 0 ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
if ( ret ! = 1 ) {
2005-08-18 19:02:01 +04:00
DEBUG ( 0 , ( " Found %d records matching DN %s \n " , ret ,
2006-11-22 05:05:19 +03:00
ldb_dn_get_linearized ( policy_state - > system_dn ) ) ) ;
2005-01-11 17:04:58 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
} else {
2008-03-20 04:12:10 +03:00
secret_state - > global = false ;
2007-11-29 18:01:16 +03:00
secret_state - > sam_ldb = talloc_reference ( secret_state ,
2008-06-14 19:24:17 +04:00
secrets_db_connect ( mem_ctx , dce_call - > event_ctx , dce_call - > conn - > dce_ctx - > lp_ctx ) ) ;
2005-01-12 01:16:14 +03:00
2005-01-11 17:04:58 +03:00
name = r - > in . name . string ;
if ( strlen ( name ) < 1 ) {
return NT_STATUS_INVALID_PARAMETER ;
}
/* search for the secret record */
2005-08-18 19:02:01 +04:00
ret = gendb_search ( secret_state - > sam_ldb , mem_ctx ,
2006-11-22 03:59:34 +03:00
ldb_dn_new ( mem_ctx , secret_state - > sam_ldb , " cn=LSA Secrets " ) ,
2005-08-18 19:02:01 +04:00
& msgs , attrs ,
2005-12-19 10:07:11 +03:00
" (&(cn=%s)(objectclass=secret)) " ,
ldb_binary_encode_string ( mem_ctx , name ) ) ;
2005-01-11 17:04:58 +03:00
if ( ret = = 0 ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
if ( ret ! = 1 ) {
2007-09-07 11:31:26 +04:00
DEBUG ( 0 , ( " Found %d records matching CN=%s \n " ,
ret , ldb_binary_encode_string ( mem_ctx , name ) ) ) ;
2005-01-11 17:04:58 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
}
secret_state - > secret_dn = talloc_reference ( secret_state , msgs [ 0 ] - > dn ) ;
handle = dcesrv_handle_new ( dce_call - > context , LSA_HANDLE_SECRET ) ;
if ( ! handle ) {
return NT_STATUS_NO_MEMORY ;
}
handle - > data = talloc_steal ( handle , secret_state ) ;
secret_state - > access_mask = r - > in . access_mask ;
secret_state - > policy = talloc_reference ( secret_state , policy_state ) ;
* r - > out . sec_handle = handle - > wire_handle ;
return NT_STATUS_OK ;
2004-05-27 08:13:58 +04:00
}
/*
lsa_SetSecret
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_SetSecret ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-01-11 17:04:58 +03:00
struct lsa_SetSecret * r )
2004-05-27 08:13:58 +04:00
{
2005-01-11 17:04:58 +03:00
struct dcesrv_handle * h ;
struct lsa_secret_state * secret_state ;
struct ldb_message * msg ;
DATA_BLOB session_key ;
DATA_BLOB crypt_secret , secret ;
struct ldb_val val ;
int ret ;
NTSTATUS status = NT_STATUS_OK ;
struct timeval now = timeval_current ( ) ;
NTTIME nt_now = timeval_to_nttime ( & now ) ;
DCESRV_PULL_HANDLE ( h , r - > in . sec_handle , LSA_HANDLE_SECRET ) ;
secret_state = h - > data ;
msg = ldb_msg_new ( mem_ctx ) ;
if ( msg = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
msg - > dn = talloc_reference ( mem_ctx , secret_state - > secret_dn ) ;
if ( ! msg - > dn ) {
return NT_STATUS_NO_MEMORY ;
}
status = dcesrv_fetch_session_key ( dce_call - > conn , & session_key ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
if ( r - > in . old_val ) {
/* Decrypt */
crypt_secret . data = r - > in . old_val - > data ;
crypt_secret . length = r - > in . old_val - > size ;
status = sess_decrypt_blob ( mem_ctx , & crypt_secret , & session_key , & secret ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
val . data = secret . data ;
val . length = secret . length ;
/* set value */
2005-02-27 14:35:47 +03:00
if ( samdb_msg_add_value ( secret_state - > sam_ldb ,
2009-11-21 21:46:25 +03:00
mem_ctx , msg , " priorValue " , & val ) ! = LDB_SUCCESS ) {
2005-01-11 17:04:58 +03:00
return NT_STATUS_NO_MEMORY ;
}
/* set old value mtime */
2005-02-27 14:35:47 +03:00
if ( samdb_msg_add_uint64 ( secret_state - > sam_ldb ,
2009-11-21 21:46:25 +03:00
mem_ctx , msg , " priorSetTime " , nt_now ) ! = LDB_SUCCESS ) {
2005-01-11 17:04:58 +03:00
return NT_STATUS_NO_MEMORY ;
}
2005-01-12 01:16:14 +03:00
2008-09-08 06:46:04 +04:00
} else {
/* If the old value is not set, then migrate the
* current value to the old value */
const struct ldb_val * old_val ;
NTTIME last_set_time ;
struct ldb_message * * res ;
const char * attrs [ ] = {
" currentValue " ,
" lastSetTime " ,
NULL
} ;
/* search for the secret record */
ret = gendb_search_dn ( secret_state - > sam_ldb , mem_ctx ,
secret_state - > secret_dn , & res , attrs ) ;
if ( ret = = 0 ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
if ( ret ! = 1 ) {
DEBUG ( 0 , ( " Found %d records matching dn=%s \n " , ret ,
ldb_dn_get_linearized ( secret_state - > secret_dn ) ) ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
old_val = ldb_msg_find_ldb_val ( res [ 0 ] , " currentValue " ) ;
last_set_time = ldb_msg_find_attr_as_uint64 ( res [ 0 ] , " lastSetTime " , 0 ) ;
if ( old_val ) {
/* set old value */
if ( samdb_msg_add_value ( secret_state - > sam_ldb ,
mem_ctx , msg , " priorValue " ,
old_val ) ! = 0 ) {
2008-08-26 04:33:41 +04:00
return NT_STATUS_NO_MEMORY ;
}
2008-09-08 06:46:04 +04:00
} else {
2008-08-26 04:33:41 +04:00
if ( samdb_msg_add_delete ( secret_state - > sam_ldb ,
2008-09-08 06:46:04 +04:00
mem_ctx , msg , " priorValue " ) ) {
2008-08-26 04:33:41 +04:00
return NT_STATUS_NO_MEMORY ;
2005-01-12 01:16:14 +03:00
}
2008-09-08 06:46:04 +04:00
}
/* set old value mtime */
if ( ldb_msg_find_ldb_val ( res [ 0 ] , " lastSetTime " ) ) {
if ( samdb_msg_add_uint64 ( secret_state - > sam_ldb ,
2009-11-21 21:46:25 +03:00
mem_ctx , msg , " priorSetTime " , last_set_time ) ! = LDB_SUCCESS ) {
2008-09-08 06:46:04 +04:00
return NT_STATUS_NO_MEMORY ;
}
} else {
if ( samdb_msg_add_uint64 ( secret_state - > sam_ldb ,
2009-11-21 21:46:25 +03:00
mem_ctx , msg , " priorSetTime " , nt_now ) ! = LDB_SUCCESS ) {
2008-09-08 06:46:04 +04:00
return NT_STATUS_NO_MEMORY ;
}
2005-01-12 01:16:14 +03:00
}
2005-01-11 17:04:58 +03:00
}
if ( r - > in . new_val ) {
/* Decrypt */
crypt_secret . data = r - > in . new_val - > data ;
crypt_secret . length = r - > in . new_val - > size ;
status = sess_decrypt_blob ( mem_ctx , & crypt_secret , & session_key , & secret ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
val . data = secret . data ;
val . length = secret . length ;
/* set value */
2005-02-27 14:35:47 +03:00
if ( samdb_msg_add_value ( secret_state - > sam_ldb ,
2009-11-21 21:46:25 +03:00
mem_ctx , msg , " currentValue " , & val ) ! = LDB_SUCCESS ) {
2005-01-11 17:04:58 +03:00
return NT_STATUS_NO_MEMORY ;
}
/* set new value mtime */
2005-02-27 14:35:47 +03:00
if ( samdb_msg_add_uint64 ( secret_state - > sam_ldb ,
2009-11-21 21:46:25 +03:00
mem_ctx , msg , " lastSetTime " , nt_now ) ! = LDB_SUCCESS ) {
2005-01-11 17:04:58 +03:00
return NT_STATUS_NO_MEMORY ;
}
2008-09-08 06:46:04 +04:00
} else {
/* NULL out the NEW value */
if ( samdb_msg_add_uint64 ( secret_state - > sam_ldb ,
2009-11-21 21:46:25 +03:00
mem_ctx , msg , " lastSetTime " , nt_now ) ! = LDB_SUCCESS ) {
2008-09-08 06:46:04 +04:00
return NT_STATUS_NO_MEMORY ;
}
if ( samdb_msg_add_delete ( secret_state - > sam_ldb ,
2009-11-21 21:46:25 +03:00
mem_ctx , msg , " currentValue " ) ! = LDB_SUCCESS ) {
2008-09-08 06:46:04 +04:00
return NT_STATUS_NO_MEMORY ;
2005-01-11 17:04:58 +03:00
}
}
/* modify the samdb record */
2010-02-16 06:45:16 +03:00
ret = dsdb_replace ( secret_state - > sam_ldb , msg , 0 ) ;
2009-11-21 21:46:25 +03:00
if ( ret ! = LDB_SUCCESS ) {
2005-01-11 17:04:58 +03:00
/* we really need samdb.c to return NTSTATUS */
return NT_STATUS_UNSUCCESSFUL ;
}
return NT_STATUS_OK ;
2004-05-27 08:13:58 +04:00
}
/*
lsa_QuerySecret
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_QuerySecret ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-01-11 17:04:58 +03:00
struct lsa_QuerySecret * r )
2004-05-27 08:13:58 +04:00
{
2005-01-11 17:04:58 +03:00
struct dcesrv_handle * h ;
struct lsa_secret_state * secret_state ;
struct ldb_message * msg ;
DATA_BLOB session_key ;
DATA_BLOB crypt_secret , secret ;
int ret ;
struct ldb_message * * res ;
const char * attrs [ ] = {
2006-09-11 10:29:58 +04:00
" currentValue " ,
" priorValue " ,
2005-01-11 17:04:58 +03:00
" lastSetTime " ,
" priorSetTime " ,
NULL
} ;
NTSTATUS nt_status ;
DCESRV_PULL_HANDLE ( h , r - > in . sec_handle , LSA_HANDLE_SECRET ) ;
2008-03-20 04:12:10 +03:00
/* Ensure user is permitted to read this... */
2010-04-22 10:48:01 +04:00
switch ( security_session_user_level ( dce_call - > conn - > auth_state . session_info , NULL ) )
2008-03-20 04:12:10 +03:00
{
case SECURITY_SYSTEM :
case SECURITY_ADMINISTRATOR :
break ;
default :
/* Users and annonymous are not allowed to read secrets */
return NT_STATUS_ACCESS_DENIED ;
}
2005-01-11 17:04:58 +03:00
secret_state = h - > data ;
/* pull all the user attributes */
2005-06-14 23:15:17 +04:00
ret = gendb_search_dn ( secret_state - > sam_ldb , mem_ctx ,
secret_state - > secret_dn , & res , attrs ) ;
2005-01-11 17:04:58 +03:00
if ( ret ! = 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
msg = res [ 0 ] ;
nt_status = dcesrv_fetch_session_key ( dce_call - > conn , & session_key ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
if ( r - > in . old_val ) {
const struct ldb_val * prior_val ;
2005-01-12 01:16:14 +03:00
r - > out . old_val = talloc_zero ( mem_ctx , struct lsa_DATA_BUF_PTR ) ;
if ( ! r - > out . old_val ) {
return NT_STATUS_NO_MEMORY ;
}
2006-09-11 10:29:58 +04:00
prior_val = ldb_msg_find_ldb_val ( res [ 0 ] , " priorValue " ) ;
2005-01-11 17:04:58 +03:00
if ( prior_val & & prior_val - > length ) {
secret . data = prior_val - > data ;
secret . length = prior_val - > length ;
2006-11-13 06:20:24 +03:00
/* Encrypt */
2005-01-11 17:04:58 +03:00
crypt_secret = sess_encrypt_blob ( mem_ctx , & secret , & session_key ) ;
if ( ! crypt_secret . length ) {
return NT_STATUS_NO_MEMORY ;
}
r - > out . old_val - > buf = talloc ( mem_ctx , struct lsa_DATA_BUF ) ;
2005-01-12 01:16:14 +03:00
if ( ! r - > out . old_val - > buf ) {
return NT_STATUS_NO_MEMORY ;
}
2005-01-11 17:04:58 +03:00
r - > out . old_val - > buf - > size = crypt_secret . length ;
r - > out . old_val - > buf - > length = crypt_secret . length ;
r - > out . old_val - > buf - > data = crypt_secret . data ;
}
}
if ( r - > in . old_mtime ) {
2005-01-27 09:16:59 +03:00
r - > out . old_mtime = talloc ( mem_ctx , NTTIME ) ;
2005-01-11 17:04:58 +03:00
if ( ! r - > out . old_mtime ) {
return NT_STATUS_NO_MEMORY ;
}
2006-08-13 12:00:36 +04:00
* r - > out . old_mtime = ldb_msg_find_attr_as_uint64 ( res [ 0 ] , " priorSetTime " , 0 ) ;
2005-01-11 17:04:58 +03:00
}
if ( r - > in . new_val ) {
const struct ldb_val * new_val ;
2005-01-12 01:16:14 +03:00
r - > out . new_val = talloc_zero ( mem_ctx , struct lsa_DATA_BUF_PTR ) ;
if ( ! r - > out . new_val ) {
return NT_STATUS_NO_MEMORY ;
}
2006-09-11 10:29:58 +04:00
new_val = ldb_msg_find_ldb_val ( res [ 0 ] , " currentValue " ) ;
2005-01-11 17:04:58 +03:00
if ( new_val & & new_val - > length ) {
secret . data = new_val - > data ;
secret . length = new_val - > length ;
2006-11-13 06:20:24 +03:00
/* Encrypt */
2005-01-11 17:04:58 +03:00
crypt_secret = sess_encrypt_blob ( mem_ctx , & secret , & session_key ) ;
if ( ! crypt_secret . length ) {
return NT_STATUS_NO_MEMORY ;
}
r - > out . new_val - > buf = talloc ( mem_ctx , struct lsa_DATA_BUF ) ;
2005-01-12 01:16:14 +03:00
if ( ! r - > out . new_val - > buf ) {
return NT_STATUS_NO_MEMORY ;
}
2005-01-11 17:04:58 +03:00
r - > out . new_val - > buf - > length = crypt_secret . length ;
r - > out . new_val - > buf - > size = crypt_secret . length ;
r - > out . new_val - > buf - > data = crypt_secret . data ;
}
}
if ( r - > in . new_mtime ) {
2005-01-27 09:16:59 +03:00
r - > out . new_mtime = talloc ( mem_ctx , NTTIME ) ;
2005-01-11 17:04:58 +03:00
if ( ! r - > out . new_mtime ) {
return NT_STATUS_NO_MEMORY ;
}
2006-08-13 12:00:36 +04:00
* r - > out . new_mtime = ldb_msg_find_attr_as_uint64 ( res [ 0 ] , " lastSetTime " , 0 ) ;
2005-01-11 17:04:58 +03:00
}
return NT_STATUS_OK ;
2004-05-27 08:13:58 +04:00
}
/*
2004-08-14 05:11:34 +04:00
lsa_LookupPrivValue
2004-05-27 08:13:58 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_LookupPrivValue ( struct dcesrv_call_state * dce_call ,
2004-12-14 08:32:51 +03:00
TALLOC_CTX * mem_ctx ,
struct lsa_LookupPrivValue * r )
2004-05-27 08:13:58 +04:00
{
2004-12-14 08:32:51 +03:00
struct dcesrv_handle * h ;
struct lsa_policy_state * state ;
int id ;
DCESRV_PULL_HANDLE ( h , r - > in . handle , LSA_HANDLE_POLICY ) ;
state = h - > data ;
id = sec_privilege_id ( r - > in . name - > string ) ;
2010-08-30 08:00:50 +04:00
if ( id = = SEC_PRIV_INVALID ) {
2004-12-14 08:32:51 +03:00
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
r - > out . luid - > low = id ;
r - > out . luid - > high = 0 ;
return NT_STATUS_OK ;
2004-05-27 08:13:58 +04:00
}
/*
lsa_LookupPrivName
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_LookupPrivName ( struct dcesrv_call_state * dce_call ,
2004-12-14 08:32:51 +03:00
TALLOC_CTX * mem_ctx ,
struct lsa_LookupPrivName * r )
2004-05-27 08:13:58 +04:00
{
2004-12-14 08:51:01 +03:00
struct dcesrv_handle * h ;
struct lsa_policy_state * state ;
2008-10-21 04:24:07 +04:00
struct lsa_StringLarge * name ;
2004-12-14 08:51:01 +03:00
const char * privname ;
DCESRV_PULL_HANDLE ( h , r - > in . handle , LSA_HANDLE_POLICY ) ;
state = h - > data ;
if ( r - > in . luid - > high ! = 0 ) {
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
privname = sec_privilege_name ( r - > in . luid - > low ) ;
if ( privname = = NULL ) {
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
2008-10-21 04:24:07 +04:00
name = talloc ( mem_ctx , struct lsa_StringLarge ) ;
if ( name = = NULL ) {
2004-12-14 08:51:01 +03:00
return NT_STATUS_NO_MEMORY ;
}
2008-10-21 04:24:07 +04:00
name - > string = privname ;
* r - > out . name = name ;
2004-12-14 08:51:01 +03:00
return NT_STATUS_OK ;
2004-05-27 08:13:58 +04:00
}
/*
2004-08-14 05:11:34 +04:00
lsa_LookupPrivDisplayName
2004-05-27 08:13:58 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_LookupPrivDisplayName ( struct dcesrv_call_state * dce_call ,
2004-12-14 08:51:01 +03:00
TALLOC_CTX * mem_ctx ,
struct lsa_LookupPrivDisplayName * r )
2004-05-27 08:13:58 +04:00
{
2004-12-14 08:51:01 +03:00
struct dcesrv_handle * h ;
struct lsa_policy_state * state ;
2008-10-21 03:53:32 +04:00
struct lsa_StringLarge * disp_name = NULL ;
2010-09-02 08:15:13 +04:00
enum sec_privilege id ;
2004-12-14 08:51:01 +03:00
DCESRV_PULL_HANDLE ( h , r - > in . handle , LSA_HANDLE_POLICY ) ;
state = h - > data ;
id = sec_privilege_id ( r - > in . name - > string ) ;
2010-08-30 08:00:50 +04:00
if ( id = = SEC_PRIV_INVALID ) {
2004-12-14 08:51:01 +03:00
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
2008-10-21 03:53:32 +04:00
disp_name = talloc ( mem_ctx , struct lsa_StringLarge ) ;
if ( disp_name = = NULL ) {
2004-12-14 08:51:01 +03:00
return NT_STATUS_NO_MEMORY ;
}
2008-10-21 03:53:32 +04:00
disp_name - > string = sec_privilege_display_name ( id , & r - > in . language_id ) ;
if ( disp_name - > string = = NULL ) {
2004-12-14 08:51:01 +03:00
return NT_STATUS_INTERNAL_ERROR ;
}
2008-10-21 03:53:32 +04:00
* r - > out . disp_name = disp_name ;
* r - > out . returned_language_id = 0 ;
2004-12-14 08:51:01 +03:00
return NT_STATUS_OK ;
2004-05-27 08:13:58 +04:00
}
/*
2004-08-14 05:11:34 +04:00
lsa_EnumAccountsWithUserRight
2004-05-27 08:13:58 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight ( struct dcesrv_call_state * dce_call ,
2004-12-14 08:07:29 +03:00
TALLOC_CTX * mem_ctx ,
struct lsa_EnumAccountsWithUserRight * r )
2004-05-27 08:13:58 +04:00
{
2004-12-14 08:07:29 +03:00
struct dcesrv_handle * h ;
struct lsa_policy_state * state ;
int ret , i ;
struct ldb_message * * res ;
const char * const attrs [ ] = { " objectSid " , NULL } ;
const char * privname ;
DCESRV_PULL_HANDLE ( h , r - > in . handle , LSA_HANDLE_POLICY ) ;
state = h - > data ;
if ( r - > in . name = = NULL ) {
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
privname = r - > in . name - > string ;
2010-09-11 10:58:45 +04:00
if ( sec_privilege_id ( privname ) = = SEC_PRIV_INVALID & & sec_right_bit ( privname ) = = 0 ) {
2004-12-14 08:07:29 +03:00
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
2009-10-16 10:05:27 +04:00
ret = gendb_search ( state - > pdb , mem_ctx , NULL , & res , attrs ,
2004-12-14 08:07:29 +03:00
" privilege=%s " , privname ) ;
2010-03-06 13:19:04 +03:00
if ( ret < 0 ) {
2006-07-06 09:23:29 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
if ( ret = = 0 ) {
return NT_STATUS_NO_MORE_ENTRIES ;
2004-12-14 08:07:29 +03:00
}
2005-01-27 10:08:20 +03:00
r - > out . sids - > sids = talloc_array ( r - > out . sids , struct lsa_SidPtr , ret ) ;
2004-12-14 08:07:29 +03:00
if ( r - > out . sids - > sids = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < ret ; i + + ) {
2005-06-24 04:18:20 +04:00
r - > out . sids - > sids [ i ] . sid = samdb_result_dom_sid ( r - > out . sids - > sids ,
res [ i ] , " objectSid " ) ;
NT_STATUS_HAVE_NO_MEMORY ( r - > out . sids - > sids [ i ] . sid ) ;
2004-12-14 08:07:29 +03:00
}
r - > out . sids - > num_sids = ret ;
return NT_STATUS_OK ;
2004-05-27 08:13:58 +04:00
}
2004-12-14 09:17:33 +03:00
/*
lsa_AddAccountRights
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_AddAccountRights ( struct dcesrv_call_state * dce_call ,
2004-12-14 09:17:33 +03:00
TALLOC_CTX * mem_ctx ,
struct lsa_AddAccountRights * r )
{
struct dcesrv_handle * h ;
struct lsa_policy_state * state ;
DCESRV_PULL_HANDLE ( h , r - > in . handle , LSA_HANDLE_POLICY ) ;
state = h - > data ;
2007-01-17 17:49:36 +03:00
return dcesrv_lsa_AddRemoveAccountRights ( dce_call , mem_ctx , state ,
2004-12-14 09:17:33 +03:00
LDB_FLAG_MOD_ADD ,
r - > in . sid , r - > in . rights ) ;
}
2004-05-27 08:13:58 +04:00
/*
2004-08-14 05:11:34 +04:00
lsa_RemoveAccountRights
2004-05-27 08:13:58 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_RemoveAccountRights ( struct dcesrv_call_state * dce_call ,
2004-12-14 09:10:45 +03:00
TALLOC_CTX * mem_ctx ,
struct lsa_RemoveAccountRights * r )
2004-05-27 08:13:58 +04:00
{
2004-12-14 09:17:33 +03:00
struct dcesrv_handle * h ;
struct lsa_policy_state * state ;
DCESRV_PULL_HANDLE ( h , r - > in . handle , LSA_HANDLE_POLICY ) ;
state = h - > data ;
2007-01-17 17:49:36 +03:00
return dcesrv_lsa_AddRemoveAccountRights ( dce_call , mem_ctx , state ,
2004-12-14 09:17:33 +03:00
LDB_FLAG_MOD_DELETE ,
r - > in . sid , r - > in . rights ) ;
2004-05-27 08:13:58 +04:00
}
/*
2004-08-14 05:11:34 +04:00
lsa_StorePrivateData
2004-05-27 08:13:58 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_StorePrivateData ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-08-14 05:11:34 +04:00
struct lsa_StorePrivateData * r )
2004-05-27 08:13:58 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2004-08-14 05:11:34 +04:00
lsa_RetrievePrivateData
2004-05-27 08:13:58 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_RetrievePrivateData ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-08-14 05:11:34 +04:00
struct lsa_RetrievePrivateData * r )
2004-05-27 08:13:58 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2004-08-14 05:11:34 +04:00
lsa_GetUserName
2004-05-27 08:13:58 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_GetUserName ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-10-06 15:15:20 +04:00
struct lsa_GetUserName * r )
2004-05-27 08:13:58 +04:00
{
2004-12-21 15:22:57 +03:00
NTSTATUS status = NT_STATUS_OK ;
const char * account_name ;
const char * authority_name ;
struct lsa_String * _account_name ;
2008-10-21 03:20:53 +04:00
struct lsa_String * _authority_name = NULL ;
2004-12-21 15:22:57 +03:00
/* this is what w2k3 does */
r - > out . account_name = r - > in . account_name ;
r - > out . authority_name = r - > in . authority_name ;
2008-10-21 03:20:53 +04:00
if ( r - > in . account_name
& & * r - > in . account_name
/* && *(*r->in.account_name)->string */
) {
2004-12-21 15:22:57 +03:00
return NT_STATUS_INVALID_PARAMETER ;
}
2008-10-21 03:20:53 +04:00
if ( r - > in . authority_name
& & * r - > in . authority_name
/* && *(*r->in.authority_name)->string */
) {
2004-12-21 15:22:57 +03:00
return NT_STATUS_INVALID_PARAMETER ;
}
2004-12-23 06:02:57 +03:00
account_name = talloc_reference ( mem_ctx , dce_call - > conn - > auth_state . session_info - > server_info - > account_name ) ;
2005-01-09 15:55:25 +03:00
authority_name = talloc_reference ( mem_ctx , dce_call - > conn - > auth_state . session_info - > server_info - > domain_name ) ;
2004-12-21 15:22:57 +03:00
2005-01-27 10:08:20 +03:00
_account_name = talloc ( mem_ctx , struct lsa_String ) ;
2006-04-29 15:48:56 +04:00
NT_STATUS_HAVE_NO_MEMORY ( _account_name ) ;
2004-12-21 15:22:57 +03:00
_account_name - > string = account_name ;
if ( r - > in . authority_name ) {
2008-10-21 03:20:53 +04:00
_authority_name = talloc ( mem_ctx , struct lsa_String ) ;
2006-04-29 15:48:56 +04:00
NT_STATUS_HAVE_NO_MEMORY ( _authority_name ) ;
2008-10-21 03:20:53 +04:00
_authority_name - > string = authority_name ;
2004-12-21 15:22:57 +03:00
}
2008-10-21 03:20:53 +04:00
* r - > out . account_name = _account_name ;
if ( r - > out . authority_name ) {
* r - > out . authority_name = _authority_name ;
}
2004-12-21 15:22:57 +03:00
return status ;
2004-05-27 08:13:58 +04:00
}
2004-08-14 05:11:34 +04:00
/*
lsa_SetInfoPolicy2
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_SetInfoPolicy2 ( struct dcesrv_call_state * dce_call ,
2004-08-14 05:11:34 +04:00
TALLOC_CTX * mem_ctx ,
struct lsa_SetInfoPolicy2 * r )
{
2008-10-04 04:52:59 +04:00
/* need to support these */
2004-08-14 05:11:34 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_QueryDomainInformationPolicy
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy ( struct dcesrv_call_state * dce_call ,
2004-08-14 05:11:34 +04:00
TALLOC_CTX * mem_ctx ,
struct lsa_QueryDomainInformationPolicy * r )
{
2008-10-21 15:03:49 +04:00
union lsa_DomainInformationPolicy * info ;
info = talloc ( r - > out . info , union lsa_DomainInformationPolicy ) ;
if ( ! info ) {
2008-08-26 06:18:26 +04:00
return NT_STATUS_NO_MEMORY ;
}
switch ( r - > in . level ) {
case LSA_DOMAIN_INFO_POLICY_EFS :
2008-10-21 15:03:49 +04:00
talloc_free ( info ) ;
* r - > out . info = NULL ;
2008-08-26 06:18:26 +04:00
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
case LSA_DOMAIN_INFO_POLICY_KERBEROS :
{
2008-10-21 15:03:49 +04:00
struct lsa_DomainInfoKerberos * k = & info - > kerberos_info ;
2008-08-26 06:18:26 +04:00
struct smb_krb5_context * smb_krb5_context ;
int ret = smb_krb5_init_context ( mem_ctx ,
dce_call - > event_ctx ,
dce_call - > conn - > dce_ctx - > lp_ctx ,
& smb_krb5_context ) ;
if ( ret ! = 0 ) {
2008-10-28 14:21:44 +03:00
talloc_free ( info ) ;
* r - > out . info = NULL ;
2008-08-26 06:18:26 +04:00
return NT_STATUS_INTERNAL_ERROR ;
}
k - > enforce_restrictions = 0 ; /* FIXME, details missing from MS-LSAD 2.2.53 */
k - > service_tkt_lifetime = 0 ; /* Need to find somewhere to store this, and query in KDC too */
k - > user_tkt_lifetime = 0 ; /* Need to find somewhere to store this, and query in KDC too */
k - > user_tkt_renewaltime = 0 ; /* Need to find somewhere to store this, and query in KDC too */
k - > clock_skew = krb5_get_max_time_skew ( smb_krb5_context - > krb5_context ) ;
talloc_free ( smb_krb5_context ) ;
2008-10-21 15:03:49 +04:00
* r - > out . info = info ;
2008-08-26 06:18:26 +04:00
return NT_STATUS_OK ;
}
default :
2008-10-21 15:03:49 +04:00
talloc_free ( info ) ;
* r - > out . info = NULL ;
2008-08-26 06:18:26 +04:00
return NT_STATUS_INVALID_INFO_CLASS ;
}
2004-08-14 05:11:34 +04:00
}
/*
lsa_SetDomInfoPolicy
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy ( struct dcesrv_call_state * dce_call ,
2005-09-01 14:36:48 +04:00
TALLOC_CTX * mem_ctx ,
struct lsa_SetDomainInformationPolicy * r )
2004-08-14 05:11:34 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_TestCall
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_TestCall ( struct dcesrv_call_state * dce_call ,
2004-08-14 05:11:34 +04:00
TALLOC_CTX * mem_ctx ,
struct lsa_TestCall * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
2004-12-31 09:08:43 +03:00
/*
lsa_CREDRWRITE
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_CREDRWRITE ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-31 09:08:43 +03:00
struct lsa_CREDRWRITE * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_CREDRREAD
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_CREDRREAD ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-31 09:08:43 +03:00
struct lsa_CREDRREAD * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_CREDRENUMERATE
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_CREDRENUMERATE ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-31 09:08:43 +03:00
struct lsa_CREDRENUMERATE * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_CREDRWRITEDOMAINCREDENTIALS
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-31 09:08:43 +03:00
struct lsa_CREDRWRITEDOMAINCREDENTIALS * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_CREDRREADDOMAINCREDENTIALS
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-31 09:08:43 +03:00
struct lsa_CREDRREADDOMAINCREDENTIALS * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_CREDRDELETE
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_CREDRDELETE ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-31 09:08:43 +03:00
struct lsa_CREDRDELETE * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_CREDRGETTARGETINFO
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-31 09:08:43 +03:00
struct lsa_CREDRGETTARGETINFO * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_CREDRPROFILELOADED
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-31 09:08:43 +03:00
struct lsa_CREDRPROFILELOADED * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_CREDRGETSESSIONTYPES
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-31 09:08:43 +03:00
struct lsa_CREDRGETSESSIONTYPES * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_LSARREGISTERAUDITEVENT
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-31 09:08:43 +03:00
struct lsa_LSARREGISTERAUDITEVENT * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_LSARGENAUDITEVENT
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-31 09:08:43 +03:00
struct lsa_LSARGENAUDITEVENT * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_LSARUNREGISTERAUDITEVENT
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-31 09:08:43 +03:00
struct lsa_LSARUNREGISTERAUDITEVENT * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2007-06-08 14:42:33 +04:00
lsa_lsaRQueryForestTrustInformation
2004-12-31 09:08:43 +03:00
*/
2007-06-08 14:42:33 +04:00
static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct lsa_lsaRQueryForestTrustInformation * r )
2004-12-31 09:08:43 +03:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
2010-02-26 05:41:09 +03:00
# define DNS_CMP_MATCH 0
# define DNS_CMP_FIRST_IS_CHILD 1
# define DNS_CMP_SECOND_IS_CHILD 2
# define DNS_CMP_NO_MATCH 3
/* this function assumes names are well formed DNS names.
* it doesn ' t validate them */
static int dns_cmp ( const char * s1 , size_t l1 ,
const char * s2 , size_t l2 )
{
const char * p1 , * p2 ;
size_t t1 , t2 ;
int cret ;
2004-12-31 09:08:43 +03:00
2010-02-26 05:41:09 +03:00
if ( l1 = = l2 ) {
if ( strcasecmp_m ( s1 , s2 ) = = 0 ) {
return DNS_CMP_MATCH ;
}
return DNS_CMP_NO_MATCH ;
}
if ( l1 > l2 ) {
p1 = s1 ;
p2 = s2 ;
t1 = l1 ;
t2 = l2 ;
cret = DNS_CMP_FIRST_IS_CHILD ;
} else {
p1 = s2 ;
p2 = s1 ;
t1 = l2 ;
t2 = l1 ;
cret = DNS_CMP_SECOND_IS_CHILD ;
}
if ( p1 [ t1 - t2 - 1 ] ! = ' . ' ) {
return DNS_CMP_NO_MATCH ;
}
if ( strcasecmp_m ( & p1 [ t1 - t2 ] , p2 ) = = 0 ) {
return cret ;
}
return DNS_CMP_NO_MATCH ;
}
/* decode all TDOs forest trust info blobs */
static NTSTATUS get_ft_info ( TALLOC_CTX * mem_ctx ,
struct ldb_message * msg ,
struct ForestTrustInfo * info )
{
const struct ldb_val * ft_blob ;
enum ndr_err_code ndr_err ;
ft_blob = ldb_msg_find_ldb_val ( msg , " msDS-TrustForestTrustInfo " ) ;
if ( ! ft_blob | | ! ft_blob - > data ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
/* ldb_val is equivalent to DATA_BLOB */
2010-05-09 19:20:01 +04:00
ndr_err = ndr_pull_struct_blob_all ( ft_blob , mem_ctx , info ,
2010-02-26 05:41:09 +03:00
( ndr_pull_flags_fn_t ) ndr_pull_ForestTrustInfo ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
return NT_STATUS_INVALID_DOMAIN_STATE ;
}
return NT_STATUS_OK ;
}
static NTSTATUS own_ft_info ( struct lsa_policy_state * ps ,
struct ForestTrustInfo * fti )
{
struct ForestTrustDataDomainInfo * info ;
struct ForestTrustInfoRecord * rec ;
fti - > version = 1 ;
fti - > count = 2 ;
fti - > records = talloc_array ( fti ,
struct ForestTrustInfoRecordArmor , 2 ) ;
if ( ! fti - > records ) {
return NT_STATUS_NO_MEMORY ;
}
/* TLN info */
rec = & fti - > records [ 0 ] . record ;
rec - > flags = 0 ;
rec - > timestamp = 0 ;
rec - > type = LSA_FOREST_TRUST_TOP_LEVEL_NAME ;
rec - > data . name . string = talloc_strdup ( fti , ps - > forest_dns ) ;
if ( ! rec - > data . name . string ) {
return NT_STATUS_NO_MEMORY ;
}
rec - > data . name . size = strlen ( rec - > data . name . string ) ;
/* DOMAIN info */
rec = & fti - > records [ 1 ] . record ;
rec - > flags = 0 ;
rec - > timestamp = 0 ;
rec - > type = LSA_FOREST_TRUST_DOMAIN_INFO ;
info = & rec - > data . info ;
info - > sid = * ps - > domain_sid ;
info - > dns_name . string = talloc_strdup ( fti , ps - > domain_dns ) ;
if ( ! info - > dns_name . string ) {
return NT_STATUS_NO_MEMORY ;
}
info - > dns_name . size = strlen ( info - > dns_name . string ) ;
info - > netbios_name . string = talloc_strdup ( fti , ps - > domain_name ) ;
if ( ! info - > netbios_name . string ) {
return NT_STATUS_NO_MEMORY ;
}
info - > netbios_name . size = strlen ( info - > netbios_name . string ) ;
return NT_STATUS_OK ;
}
static NTSTATUS make_ft_info ( TALLOC_CTX * mem_ctx ,
struct lsa_ForestTrustInformation * lfti ,
struct ForestTrustInfo * fti )
{
struct lsa_ForestTrustRecord * lrec ;
struct ForestTrustInfoRecord * rec ;
struct lsa_StringLarge * tln ;
struct lsa_ForestTrustDomainInfo * info ;
uint32_t i ;
fti - > version = 1 ;
fti - > count = lfti - > count ;
fti - > records = talloc_array ( mem_ctx ,
struct ForestTrustInfoRecordArmor ,
fti - > count ) ;
if ( ! fti - > records ) {
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < fti - > count ; i + + ) {
lrec = lfti - > entries [ i ] ;
rec = & fti - > records [ i ] . record ;
rec - > flags = lrec - > flags ;
rec - > timestamp = lrec - > time ;
rec - > type = lrec - > type ;
switch ( lrec - > type ) {
case LSA_FOREST_TRUST_TOP_LEVEL_NAME :
case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX :
tln = & lrec - > forest_trust_data . top_level_name ;
rec - > data . name . string =
talloc_strdup ( mem_ctx , tln - > string ) ;
if ( ! rec - > data . name . string ) {
return NT_STATUS_NO_MEMORY ;
}
rec - > data . name . size = strlen ( rec - > data . name . string ) ;
break ;
case LSA_FOREST_TRUST_DOMAIN_INFO :
info = & lrec - > forest_trust_data . domain_info ;
rec - > data . info . sid = * info - > domain_sid ;
rec - > data . info . dns_name . string =
talloc_strdup ( mem_ctx ,
info - > dns_domain_name . string ) ;
if ( ! rec - > data . info . dns_name . string ) {
return NT_STATUS_NO_MEMORY ;
}
rec - > data . info . dns_name . size =
strlen ( rec - > data . info . dns_name . string ) ;
rec - > data . info . netbios_name . string =
talloc_strdup ( mem_ctx ,
info - > netbios_domain_name . string ) ;
if ( ! rec - > data . info . netbios_name . string ) {
return NT_STATUS_NO_MEMORY ;
}
rec - > data . info . netbios_name . size =
strlen ( rec - > data . info . netbios_name . string ) ;
break ;
default :
return NT_STATUS_INVALID_DOMAIN_STATE ;
}
}
return NT_STATUS_OK ;
}
static NTSTATUS add_collision ( struct lsa_ForestTrustCollisionInfo * c_info ,
uint32_t index , uint32_t collision_type ,
uint32_t conflict_type , const char * tdo_name ) ;
static NTSTATUS check_ft_info ( TALLOC_CTX * mem_ctx ,
const char * tdo_name ,
struct ForestTrustInfo * tdo_fti ,
struct ForestTrustInfo * new_fti ,
struct lsa_ForestTrustCollisionInfo * c_info )
{
struct ForestTrustInfoRecord * nrec ;
struct ForestTrustInfoRecord * trec ;
const char * dns_name ;
const char * nb_name ;
struct dom_sid * sid ;
const char * tname ;
size_t dns_len ;
size_t nb_len ;
size_t tlen ;
NTSTATUS nt_status ;
uint32_t new_fti_idx ;
uint32_t i ;
/* use always TDO type, until we understand when Xref can be used */
uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO ;
bool tln_conflict ;
bool sid_conflict ;
bool nb_conflict ;
bool exclusion ;
bool ex_rule ;
int ret ;
for ( new_fti_idx = 0 ; new_fti_idx < new_fti - > count ; new_fti_idx + + ) {
nrec = & new_fti - > records [ new_fti_idx ] . record ;
dns_name = NULL ;
tln_conflict = false ;
sid_conflict = false ;
nb_conflict = false ;
exclusion = false ;
switch ( nrec - > type ) {
case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX :
/* exclusions do not conflict by definition */
break ;
case FOREST_TRUST_TOP_LEVEL_NAME :
dns_name = nrec - > data . name . string ;
dns_len = nrec - > data . name . size ;
break ;
case LSA_FOREST_TRUST_DOMAIN_INFO :
dns_name = nrec - > data . info . dns_name . string ;
dns_len = nrec - > data . info . dns_name . size ;
nb_name = nrec - > data . info . netbios_name . string ;
nb_len = nrec - > data . info . netbios_name . size ;
sid = & nrec - > data . info . sid ;
break ;
}
if ( ! dns_name ) continue ;
/* check if this is already taken and not excluded */
for ( i = 0 ; i < tdo_fti - > count ; i + + ) {
trec = & tdo_fti - > records [ i ] . record ;
switch ( trec - > type ) {
case FOREST_TRUST_TOP_LEVEL_NAME :
ex_rule = false ;
tname = trec - > data . name . string ;
tlen = trec - > data . name . size ;
break ;
case FOREST_TRUST_TOP_LEVEL_NAME_EX :
ex_rule = true ;
tname = trec - > data . name . string ;
tlen = trec - > data . name . size ;
break ;
case FOREST_TRUST_DOMAIN_INFO :
ex_rule = false ;
tname = trec - > data . info . dns_name . string ;
tlen = trec - > data . info . dns_name . size ;
}
ret = dns_cmp ( dns_name , dns_len , tname , tlen ) ;
switch ( ret ) {
case DNS_CMP_MATCH :
/* if it matches exclusion,
* it doesn ' t conflict */
if ( ex_rule ) {
exclusion = true ;
break ;
}
/* fall through */
case DNS_CMP_FIRST_IS_CHILD :
case DNS_CMP_SECOND_IS_CHILD :
tln_conflict = true ;
/* fall through */
default :
break ;
}
/* explicit exclusion, no dns name conflict here */
if ( exclusion ) {
tln_conflict = false ;
}
2010-07-06 22:55:32 +04:00
if ( trec - > type ! = FOREST_TRUST_DOMAIN_INFO ) {
2010-02-26 05:41:09 +03:00
continue ;
}
/* also test for domain info */
if ( ! ( trec - > flags & LSA_SID_DISABLED_ADMIN ) & &
dom_sid_compare ( & trec - > data . info . sid , sid ) = = 0 ) {
sid_conflict = true ;
}
if ( ! ( trec - > flags & LSA_NB_DISABLED_ADMIN ) & &
strcasecmp_m ( trec - > data . info . netbios_name . string ,
nb_name ) = = 0 ) {
nb_conflict = true ;
}
}
if ( tln_conflict ) {
nt_status = add_collision ( c_info , new_fti_idx ,
collision_type ,
LSA_TLN_DISABLED_CONFLICT ,
tdo_name ) ;
}
if ( sid_conflict ) {
nt_status = add_collision ( c_info , new_fti_idx ,
collision_type ,
LSA_SID_DISABLED_CONFLICT ,
tdo_name ) ;
}
if ( nb_conflict ) {
nt_status = add_collision ( c_info , new_fti_idx ,
collision_type ,
LSA_NB_DISABLED_CONFLICT ,
tdo_name ) ;
}
}
return NT_STATUS_OK ;
}
static NTSTATUS add_collision ( struct lsa_ForestTrustCollisionInfo * c_info ,
uint32_t idx , uint32_t collision_type ,
uint32_t conflict_type , const char * tdo_name )
{
struct lsa_ForestTrustCollisionRecord * * es ;
uint32_t i = c_info - > count ;
es = talloc_realloc ( c_info , c_info - > entries ,
struct lsa_ForestTrustCollisionRecord * , i + 1 ) ;
if ( ! es ) {
return NT_STATUS_NO_MEMORY ;
}
c_info - > entries = es ;
c_info - > count = i + 1 ;
es [ i ] = talloc ( es , struct lsa_ForestTrustCollisionRecord ) ;
if ( ! es [ i ] ) {
return NT_STATUS_NO_MEMORY ;
}
es [ i ] - > index = idx ;
es [ i ] - > type = collision_type ;
es [ i ] - > flags . flags = conflict_type ;
es [ i ] - > name . string = talloc_strdup ( es [ i ] , tdo_name ) ;
if ( ! es [ i ] - > name . string ) {
return NT_STATUS_NO_MEMORY ;
}
es [ i ] - > name . size = strlen ( es [ i ] - > name . string ) ;
return NT_STATUS_OK ;
}
/*
2010-03-16 16:03:49 +03:00
lsa_lsaRSetForestTrustInformation
2004-12-31 09:08:43 +03:00
*/
2010-02-26 05:41:09 +03:00
static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct lsa_lsaRSetForestTrustInformation * r )
2004-12-31 09:08:43 +03:00
{
2010-02-26 05:41:09 +03:00
struct dcesrv_handle * h ;
struct lsa_policy_state * p_state ;
const char * trust_attrs [ ] = { " trustPartner " , " trustAttributes " ,
" msDS-TrustForestTrustInfo " , NULL } ;
struct ldb_message * * dom_res = NULL ;
struct ldb_dn * tdo_dn ;
struct ldb_message * msg ;
int num_res , i ;
const char * td_name ;
uint32_t trust_attributes ;
struct lsa_ForestTrustCollisionInfo * c_info ;
struct ForestTrustInfo * nfti ;
struct ForestTrustInfo * fti ;
DATA_BLOB ft_blob ;
enum ndr_err_code ndr_err ;
NTSTATUS nt_status ;
2010-04-16 01:54:13 +04:00
bool am_rodc ;
2010-02-26 05:41:09 +03:00
int ret ;
DCESRV_PULL_HANDLE ( h , r - > in . handle , LSA_HANDLE_POLICY ) ;
p_state = h - > data ;
if ( strcmp ( p_state - > domain_dns , p_state - > forest_dns ) ) {
return NT_STATUS_INVALID_DOMAIN_STATE ;
}
/* abort if we are not a PDC */
if ( ! samdb_is_pdc ( p_state - > sam_ldb ) ) {
return NT_STATUS_INVALID_DOMAIN_ROLE ;
}
2010-04-16 01:54:13 +04:00
ret = samdb_rodc ( p_state - > sam_ldb , & am_rodc ) ;
if ( ret = = LDB_SUCCESS & & am_rodc ) {
2010-02-26 05:41:09 +03:00
return NT_STATUS_NO_SUCH_DOMAIN ;
}
/* check caller has TRUSTED_SET_AUTH */
/* fetch all trusted domain objects */
num_res = gendb_search ( p_state - > sam_ldb , mem_ctx ,
p_state - > system_dn ,
& dom_res , trust_attrs ,
" (objectclass=trustedDomain) " ) ;
if ( num_res = = 0 ) {
return NT_STATUS_NO_SUCH_DOMAIN ;
}
for ( i = 0 ; i < num_res ; i + + ) {
td_name = ldb_msg_find_attr_as_string ( dom_res [ i ] ,
" trustPartner " , NULL ) ;
if ( ! td_name ) {
return NT_STATUS_INVALID_DOMAIN_STATE ;
}
if ( strcasecmp_m ( td_name ,
r - > in . trusted_domain_name - > string ) = = 0 ) {
break ;
}
}
if ( i > = num_res ) {
return NT_STATUS_NO_SUCH_DOMAIN ;
}
tdo_dn = dom_res [ i ] - > dn ;
trust_attributes = samdb_result_uint ( dom_res [ i ] ,
" trustAttributes " , 0 ) ;
if ( ! ( trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE ) ) {
return NT_STATUS_INVALID_PARAMETER ;
}
if ( r - > in . highest_record_type > = LSA_FOREST_TRUST_RECORD_TYPE_LAST ) {
return NT_STATUS_INVALID_PARAMETER ;
}
nfti = talloc ( mem_ctx , struct ForestTrustInfo ) ;
if ( ! nfti ) {
return NT_STATUS_NO_MEMORY ;
}
nt_status = make_ft_info ( nfti , r - > in . forest_trust_info , nfti ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
c_info = talloc_zero ( r - > out . collision_info ,
struct lsa_ForestTrustCollisionInfo ) ;
if ( ! c_info ) {
return NT_STATUS_NO_MEMORY ;
}
/* first check own info, then other domains */
fti = talloc ( mem_ctx , struct ForestTrustInfo ) ;
if ( ! fti ) {
return NT_STATUS_NO_MEMORY ;
}
nt_status = own_ft_info ( p_state , fti ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
nt_status = check_ft_info ( c_info , p_state - > domain_dns ,
fti , nfti , c_info ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
for ( i = 0 ; i < num_res ; i + + ) {
fti = talloc ( mem_ctx , struct ForestTrustInfo ) ;
if ( ! fti ) {
return NT_STATUS_NO_MEMORY ;
}
2010-05-09 19:20:01 +04:00
nt_status = get_ft_info ( mem_ctx , dom_res [ i ] , fti ) ;
2010-02-26 05:41:09 +03:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
if ( NT_STATUS_EQUAL ( nt_status ,
NT_STATUS_OBJECT_NAME_NOT_FOUND ) ) {
continue ;
}
return nt_status ;
}
td_name = ldb_msg_find_attr_as_string ( dom_res [ i ] ,
" trustPartner " , NULL ) ;
if ( ! td_name ) {
return NT_STATUS_INVALID_DOMAIN_STATE ;
}
nt_status = check_ft_info ( c_info , td_name , fti , nfti , c_info ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
}
* r - > out . collision_info = c_info ;
if ( r - > in . check_only ! = 0 ) {
return NT_STATUS_OK ;
}
/* not just a check, write info back */
2010-05-09 19:20:01 +04:00
ndr_err = ndr_push_struct_blob ( & ft_blob , mem_ctx , nfti ,
2010-02-26 05:41:09 +03:00
( ndr_push_flags_fn_t ) ndr_push_ForestTrustInfo ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
return NT_STATUS_INVALID_PARAMETER ;
}
msg = ldb_msg_new ( mem_ctx ) ;
if ( msg = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
msg - > dn = ldb_dn_copy ( mem_ctx , tdo_dn ) ;
if ( ! msg - > dn ) {
return NT_STATUS_NO_MEMORY ;
}
ret = ldb_msg_add_empty ( msg , " msDS-TrustForestTrustInfo " ,
LDB_FLAG_MOD_REPLACE , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_NO_MEMORY ;
}
ret = ldb_msg_add_value ( msg , " msDS-TrustForestTrustInfo " ,
& ft_blob , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_NO_MEMORY ;
}
ret = ldb_modify ( p_state - > sam_ldb , msg ) ;
if ( ret ! = LDB_SUCCESS ) {
DEBUG ( 0 , ( " Failed to store Forest Trust Info: %s \n " ,
ldb_errstring ( p_state - > sam_ldb ) ) ) ;
switch ( ret ) {
case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS :
return NT_STATUS_ACCESS_DENIED ;
default :
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
}
2004-12-31 09:08:43 +03:00
2010-02-26 05:41:09 +03:00
return NT_STATUS_OK ;
}
2004-12-31 09:08:43 +03:00
/*
lsa_CREDRRENAME
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_CREDRRENAME ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-31 09:08:43 +03:00
struct lsa_CREDRRENAME * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_LSAROPENPOLICYSCE
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-31 09:08:43 +03:00
struct lsa_LSAROPENPOLICYSCE * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_LSARADTREGISTERSECURITYEVENTSOURCE
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-31 09:08:43 +03:00
struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-31 09:08:43 +03:00
struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
lsa_LSARADTREPORTSECURITYEVENT
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-31 09:08:43 +03:00
struct lsa_LSARADTREPORTSECURITYEVENT * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
2004-05-27 08:13:58 +04:00
/* include the generated boilerplate */
# include "librpc/gen_ndr/ndr_lsa_s.c"
2006-08-31 17:10:11 +04:00
/*****************************************
NOTE ! The remaining calls below were
removed in w2k3 , so the DCESRV_FAULT ( )
replies are the correct implementation . Do
not try and fill these in with anything else
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
dssetup_DsRoleDnsNameToFlatName
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-08-31 17:10:11 +04:00
struct dssetup_DsRoleDnsNameToFlatName * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
dssetup_DsRoleDcAsDc
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_dssetup_DsRoleDcAsDc ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-08-31 17:10:11 +04:00
struct dssetup_DsRoleDcAsDc * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
dssetup_DsRoleDcAsReplica
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_dssetup_DsRoleDcAsReplica ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-08-31 17:10:11 +04:00
struct dssetup_DsRoleDcAsReplica * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
dssetup_DsRoleDemoteDc
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_dssetup_DsRoleDemoteDc ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-08-31 17:10:11 +04:00
struct dssetup_DsRoleDemoteDc * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
dssetup_DsRoleGetDcOperationProgress
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-08-31 17:10:11 +04:00
struct dssetup_DsRoleGetDcOperationProgress * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
dssetup_DsRoleGetDcOperationResults
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-08-31 17:10:11 +04:00
struct dssetup_DsRoleGetDcOperationResults * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
dssetup_DsRoleCancel
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_dssetup_DsRoleCancel ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-08-31 17:10:11 +04:00
struct dssetup_DsRoleCancel * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
dssetup_DsRoleServerSaveStateForUpgrade
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-08-31 17:10:11 +04:00
struct dssetup_DsRoleServerSaveStateForUpgrade * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
dssetup_DsRoleUpgradeDownlevelServer
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-08-31 17:10:11 +04:00
struct dssetup_DsRoleUpgradeDownlevelServer * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
dssetup_DsRoleAbortDownlevelServerUpgrade
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-08-31 17:10:11 +04:00
struct dssetup_DsRoleAbortDownlevelServerUpgrade * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/* include the generated boilerplate */
# include "librpc/gen_ndr/ndr_dssetup_s.c"
NTSTATUS dcerpc_server_lsa_init ( void )
{
NTSTATUS ret ;
ret = dcerpc_server_dssetup_init ( ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
return ret ;
}
ret = dcerpc_server_lsarpc_init ( ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
return ret ;
}
return ret ;
}