2005-01-13 18:20:37 +00:00
/*
2002-01-30 06:08:46 +00:00
* Unix SMB / CIFS implementation .
2001-02-26 19:31:07 +00:00
* RPC Pipe client / server routines
* Copyright ( C ) Andrew Tridgell 1992 - 1997 ,
* Copyright ( C ) Luke Kenneth Casson Leighton 1996 - 1997 ,
2002-07-15 10:35:28 +00:00
* Copyright ( C ) Paul Ashton 1997 ,
2006-02-16 01:06:21 +00:00
* Copyright ( C ) Jeremy Allison 2001 , 2006.
2002-08-17 15:34:15 +00:00
* Copyright ( C ) Rafal Szczesniak 2002 ,
2004-04-13 14:39:48 +00:00
* Copyright ( C ) Jim McDonough < jmcd @ us . ibm . com > 2002 ,
2005-01-13 18:20:37 +00:00
* Copyright ( C ) Simo Sorce 2003.
2005-03-10 18:50:47 +00:00
* Copyright ( C ) Gerald ( Jerry ) Carter 2005.
2006-02-03 22:19:41 +00:00
* Copyright ( C ) Volker Lendecke 2005.
2008-02-27 19:38:48 +01:00
* Copyright ( C ) Guenther Deschner 2008.
2010-08-30 15:38:18 +10:00
* Copyright ( C ) Andrew Bartlett 2010.
2001-02-26 19:31:07 +00:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
2007-07-09 19:25:36 +00:00
* the Free Software Foundation ; either version 3 of the License , or
2001-02-26 19:31:07 +00:00
* ( at your option ) any later version .
2008-02-14 13:12:28 +01:00
*
2001-02-26 19:31:07 +00:00
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
2008-02-14 13:12:28 +01:00
*
2001-02-26 19:31:07 +00:00
* You should have received a copy of the GNU General Public License
2007-07-10 05:23:25 +00:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2001-02-26 19:31:07 +00:00
*/
/* This is the implementation of the lsa server code. */
# include "includes.h"
2011-05-02 13:21:53 +02:00
# include "ntdomain.h"
2009-11-26 18:21:28 +01:00
# include "../librpc/gen_ndr/srv_lsa.h"
2010-08-05 02:25:37 +02:00
# include "secrets.h"
2010-08-05 15:14:04 +02:00
# include "../librpc/gen_ndr/netlogon.h"
2010-08-19 23:15:22 +02:00
# include "rpc_client/init_lsa.h"
2010-10-12 15:27:50 +11:00
# include "../libcli/security/security.h"
2010-08-26 14:44:04 +02:00
# include "../libcli/security/dom_sid.h"
# include "../librpc/gen_ndr/drsblobs.h"
# include "../librpc/gen_ndr/ndr_drsblobs.h"
# include "../lib/crypto/arcfour.h"
2010-09-02 18:13:38 +02:00
# include "../libcli/security/dom_sid.h"
2009-10-30 00:05:32 +01:00
# include "../librpc/gen_ndr/ndr_security.h"
2011-03-18 18:58:37 +01:00
# include "passdb.h"
2011-03-24 12:08:15 +01:00
# include "auth.h"
2011-03-25 11:56:52 +01:00
# include "lib/privileges.h"
2011-03-25 14:12:59 +01:00
# include "rpc_server/srv_access_check.h"
2009-10-30 00:03:21 +01:00
# include "../librpc/gen_ndr/ndr_wkssvc.h"
2011-07-31 22:37:08 +02:00
# include "../libcli/auth/libcli_auth.h"
2011-12-07 16:03:04 +11:00
# include "../libcli/lsarpc/util_lsarpc.h"
2014-09-11 16:11:06 -07:00
# include "lsa.h"
2001-02-26 19:31:07 +00:00
2002-07-15 10:35:28 +00:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_RPC_SRV
2008-10-24 02:01:16 +02:00
# define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
2009-10-19 18:48:07 +02:00
enum lsa_handle_type {
LSA_HANDLE_POLICY_TYPE = 1 ,
LSA_HANDLE_ACCOUNT_TYPE = 2 ,
2009-10-26 13:43:16 +01:00
LSA_HANDLE_TRUST_TYPE = 3 ,
LSA_HANDLE_SECRET_TYPE = 4 } ;
2009-05-20 11:52:11 -07:00
2001-07-09 18:32:54 +00:00
struct lsa_info {
2010-05-21 11:25:01 +10:00
struct dom_sid sid ;
2009-10-29 23:50:20 +01:00
const char * name ;
2015-05-14 18:08:27 -07:00
uint32_t access ;
2009-05-20 11:52:11 -07:00
enum lsa_handle_type type ;
2009-10-29 23:50:20 +01:00
struct security_descriptor * sd ;
2009-05-20 11:52:11 -07:00
} ;
const struct generic_mapping lsa_account_mapping = {
LSA_ACCOUNT_READ ,
LSA_ACCOUNT_WRITE ,
LSA_ACCOUNT_EXECUTE ,
LSA_ACCOUNT_ALL_ACCESS
2001-07-09 18:32:54 +00:00
} ;
2009-05-20 11:52:11 -07:00
const struct generic_mapping lsa_policy_mapping = {
2008-02-27 15:49:31 +01:00
LSA_POLICY_READ ,
LSA_POLICY_WRITE ,
LSA_POLICY_EXECUTE ,
LSA_POLICY_ALL_ACCESS
2001-12-17 23:03:23 +00:00
} ;
2009-10-27 13:50:43 +01:00
const struct generic_mapping lsa_secret_mapping = {
LSA_SECRET_READ ,
LSA_SECRET_WRITE ,
LSA_SECRET_EXECUTE ,
LSA_SECRET_ALL_ACCESS
} ;
2009-10-27 15:29:02 +01:00
const struct generic_mapping lsa_trusted_domain_mapping = {
LSA_TRUSTED_DOMAIN_READ ,
LSA_TRUSTED_DOMAIN_WRITE ,
LSA_TRUSTED_DOMAIN_EXECUTE ,
LSA_TRUSTED_DOMAIN_ALL_ACCESS
} ;
2001-02-26 19:31:07 +00:00
/***************************************************************************
2008-02-08 01:13:50 +01:00
initialize a lsa_DomainInfo structure .
2001-02-26 19:31:07 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-02-08 01:13:50 +01:00
static void init_dom_query_3 ( struct lsa_DomainInfo * r ,
const char * name ,
2010-05-21 11:25:01 +10:00
struct dom_sid * sid )
2001-02-26 19:31:07 +00:00
{
2008-02-08 01:13:50 +01:00
init_lsa_StringLarge ( & r - > name , name ) ;
r - > sid = sid ;
2001-02-26 19:31:07 +00:00
}
2006-04-11 15:47:24 +00:00
/***************************************************************************
2008-02-08 01:13:50 +01:00
initialize a lsa_DomainInfo structure .
2006-04-11 15:47:24 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-02-08 01:13:50 +01:00
static void init_dom_query_5 ( struct lsa_DomainInfo * r ,
const char * name ,
2010-05-21 11:25:01 +10:00
struct dom_sid * sid )
2006-04-11 15:47:24 +00:00
{
2008-02-08 01:13:50 +01:00
init_lsa_StringLarge ( & r - > name , name ) ;
r - > sid = sid ;
2006-04-11 15:47:24 +00:00
}
2001-02-26 19:31:07 +00:00
/***************************************************************************
2006-02-16 01:06:21 +00:00
lookup_lsa_rids . Must be called as root for lookup_name to work .
2001-02-26 19:31:07 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-02-16 01:06:21 +00:00
static NTSTATUS lookup_lsa_rids ( TALLOC_CTX * mem_ctx ,
2008-02-18 14:40:34 +01:00
struct lsa_RefDomainList * ref ,
struct lsa_TranslatedSid * prid ,
uint32_t num_entries ,
struct lsa_String * name ,
int flags ,
uint32_t * pmapped_count )
2001-02-26 19:31:07 +00:00
{
2015-05-14 18:08:27 -07:00
uint32_t mapped_count , i ;
2001-02-26 19:31:07 +00:00
SMB_ASSERT ( num_entries < = MAX_LOOKUP_SIDS ) ;
2005-12-03 18:34:13 +00:00
mapped_count = 0 ;
2006-02-16 01:06:21 +00:00
* pmapped_count = 0 ;
2002-01-26 10:02:23 +00:00
2001-02-26 19:31:07 +00:00
for ( i = 0 ; i < num_entries ; i + + ) {
2010-05-21 11:25:01 +10:00
struct dom_sid sid ;
2015-05-14 18:08:27 -07:00
uint32_t rid ;
2005-12-03 18:34:13 +00:00
int dom_idx ;
2008-02-18 14:40:34 +01:00
const char * full_name ;
2005-12-10 11:22:01 +00:00
const char * domain ;
2011-03-16 18:50:02 +01:00
enum lsa_SidType type ;
2001-02-26 19:31:07 +00:00
/* Split name into domain and user component */
2009-10-21 02:45:21 +02:00
/* follow w2k8 behavior and return the builtin domain when no
* input has been passed in */
if ( name [ i ] . string ) {
full_name = name [ i ] . string ;
} else {
full_name = " BUILTIN " ;
2005-12-03 18:34:13 +00:00
}
2001-02-26 19:31:07 +00:00
2006-02-16 01:06:21 +00:00
DEBUG ( 5 , ( " lookup_lsa_rids: looking up name %s \n " , full_name ) ) ;
2001-02-26 19:31:07 +00:00
2011-03-16 18:50:02 +01:00
if ( ! lookup_name ( mem_ctx , full_name , flags , & domain , NULL ,
& sid , & type ) ) {
type = SID_NAME_UNKNOWN ;
}
2004-04-07 12:43:44 +00:00
2005-12-03 18:34:13 +00:00
switch ( type ) {
case SID_NAME_USER :
case SID_NAME_DOM_GRP :
case SID_NAME_DOMAIN :
case SID_NAME_ALIAS :
case SID_NAME_WKN_GRP :
2006-02-11 02:46:41 +00:00
DEBUG ( 5 , ( " init_lsa_rids: %s found \n " , full_name ) ) ;
2005-12-03 18:34:13 +00:00
/* Leave these unchanged */
break ;
default :
/* Don't hand out anything but the list above */
2006-02-11 02:46:41 +00:00
DEBUG ( 5 , ( " init_lsa_rids: %s not found \n " , full_name ) ) ;
2005-12-03 18:34:13 +00:00
type = SID_NAME_UNKNOWN ;
break ;
}
rid = 0 ;
dom_idx = - 1 ;
if ( type ! = SID_NAME_UNKNOWN ) {
2009-10-20 15:12:58 +02:00
if ( type = = SID_NAME_DOMAIN ) {
rid = ( uint32_t ) - 1 ;
} else {
sid_split_rid ( & sid , & rid ) ;
}
2008-02-18 14:40:34 +01:00
dom_idx = init_lsa_ref_domain_list ( mem_ctx , ref , domain , & sid ) ;
2005-12-03 18:34:13 +00:00
mapped_count + + ;
2001-02-26 19:31:07 +00:00
}
2008-12-08 18:03:01 +01:00
prid [ i ] . sid_type = type ;
prid [ i ] . rid = rid ;
prid [ i ] . sid_index = dom_idx ;
2001-02-26 19:31:07 +00:00
}
2002-01-26 10:02:23 +00:00
2006-02-16 01:06:21 +00:00
* pmapped_count = mapped_count ;
return NT_STATUS_OK ;
}
/***************************************************************************
lookup_lsa_sids . Must be called as root for lookup_name to work .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS lookup_lsa_sids ( TALLOC_CTX * mem_ctx ,
2008-02-18 16:57:02 +01:00
struct lsa_RefDomainList * ref ,
struct lsa_TranslatedSid3 * trans_sids ,
uint32_t num_entries ,
struct lsa_String * name ,
int flags ,
2015-05-14 18:08:27 -07:00
uint32_t * pmapped_count )
2006-02-16 01:06:21 +00:00
{
2015-05-14 18:08:27 -07:00
uint32_t mapped_count , i ;
2006-02-16 01:06:21 +00:00
SMB_ASSERT ( num_entries < = MAX_LOOKUP_SIDS ) ;
mapped_count = 0 ;
* pmapped_count = 0 ;
for ( i = 0 ; i < num_entries ; i + + ) {
2010-05-21 11:25:01 +10:00
struct dom_sid sid ;
2015-05-14 18:08:27 -07:00
uint32_t rid ;
2006-02-16 01:06:21 +00:00
int dom_idx ;
2008-02-18 16:57:02 +01:00
const char * full_name ;
2006-02-16 01:06:21 +00:00
const char * domain ;
2011-03-16 18:50:02 +01:00
enum lsa_SidType type ;
2006-02-16 01:06:21 +00:00
2008-03-04 11:06:02 +01:00
ZERO_STRUCT ( sid ) ;
2006-02-16 01:06:21 +00:00
/* Split name into domain and user component */
2008-02-18 16:57:02 +01:00
full_name = name [ i ] . string ;
2006-02-16 01:06:21 +00:00
if ( full_name = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2012-03-02 16:18:16 +02:00
DEBUG ( 5 , ( " lookup_lsa_sids: looking up name %s \n " , full_name ) ) ;
2006-02-16 01:06:21 +00:00
2011-03-16 18:50:02 +01:00
if ( ! lookup_name ( mem_ctx , full_name , flags , & domain , NULL ,
& sid , & type ) ) {
type = SID_NAME_UNKNOWN ;
}
2006-02-16 01:06:21 +00:00
switch ( type ) {
case SID_NAME_USER :
case SID_NAME_DOM_GRP :
case SID_NAME_DOMAIN :
case SID_NAME_ALIAS :
case SID_NAME_WKN_GRP :
2012-03-02 16:18:16 +02:00
DEBUG ( 5 , ( " lookup_lsa_sids: %s found \n " , full_name ) ) ;
2006-02-16 01:06:21 +00:00
/* Leave these unchanged */
break ;
default :
/* Don't hand out anything but the list above */
2012-03-02 16:18:16 +02:00
DEBUG ( 5 , ( " lookup_lsa_sids: %s not found \n " , full_name ) ) ;
2006-02-16 01:06:21 +00:00
type = SID_NAME_UNKNOWN ;
break ;
}
rid = 0 ;
dom_idx = - 1 ;
if ( type ! = SID_NAME_UNKNOWN ) {
2010-05-21 11:25:01 +10:00
struct dom_sid domain_sid ;
2006-02-16 01:06:21 +00:00
sid_copy ( & domain_sid , & sid ) ;
sid_split_rid ( & domain_sid , & rid ) ;
2008-02-18 16:57:02 +01:00
dom_idx = init_lsa_ref_domain_list ( mem_ctx , ref , domain , & domain_sid ) ;
2006-02-16 01:06:21 +00:00
mapped_count + + ;
}
2008-02-18 16:57:02 +01:00
/* Initialize the lsa_TranslatedSid3 return. */
2006-02-16 01:06:21 +00:00
trans_sids [ i ] . sid_type = type ;
2010-08-26 17:21:39 +02:00
trans_sids [ i ] . sid = dom_sid_dup ( mem_ctx , & sid ) ;
2008-02-18 16:57:02 +01:00
trans_sids [ i ] . sid_index = dom_idx ;
2006-02-16 01:06:21 +00:00
}
2005-12-03 18:34:13 +00:00
2006-02-16 01:06:21 +00:00
* pmapped_count = mapped_count ;
return NT_STATUS_OK ;
2001-02-26 19:31:07 +00:00
}
2010-05-18 10:29:34 +02:00
static NTSTATUS make_lsa_object_sd ( TALLOC_CTX * mem_ctx , struct security_descriptor * * sd , size_t * sd_size ,
2009-05-20 11:52:11 -07:00
const struct generic_mapping * map ,
2010-05-21 11:25:01 +10:00
struct dom_sid * sid , uint32_t sid_access )
2001-12-17 23:03:23 +00:00
{
2010-05-21 11:25:01 +10:00
struct dom_sid adm_sid ;
2010-05-18 03:25:38 +02:00
struct security_ace ace [ 5 ] ;
2009-05-20 11:52:11 -07:00
size_t i = 0 ;
2001-12-17 23:03:23 +00:00
2010-05-18 03:30:40 +02:00
struct security_acl * psa = NULL ;
2001-12-17 23:03:23 +00:00
2009-05-20 11:52:11 -07:00
/* READ|EXECUTE access for Everyone */
init_sec_ace ( & ace [ i + + ] , & global_sid_World , SEC_ACE_TYPE_ACCESS_ALLOWED ,
map - > generic_execute | map - > generic_read , 0 ) ;
2001-12-17 23:03:23 +00:00
2009-05-20 11:52:11 -07:00
/* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
init_sec_ace ( & ace [ i + + ] , & global_sid_Builtin_Administrators ,
SEC_ACE_TYPE_ACCESS_ALLOWED , map - > generic_all , 0 ) ;
init_sec_ace ( & ace [ i + + ] , & global_sid_Builtin_Account_Operators ,
SEC_ACE_TYPE_ACCESS_ALLOWED , map - > generic_all , 0 ) ;
/* Add Full Access for Domain Admins */
2010-05-17 22:04:24 +02:00
sid_compose ( & adm_sid , get_global_sam_sid ( ) , DOMAIN_RID_ADMINS ) ;
2009-05-20 11:52:11 -07:00
init_sec_ace ( & ace [ i + + ] , & adm_sid , SEC_ACE_TYPE_ACCESS_ALLOWED ,
map - > generic_all , 0 ) ;
2001-12-17 23:03:23 +00:00
2009-05-20 11:52:11 -07:00
/* If we have a sid, give it some special access */
if ( sid ) {
init_sec_ace ( & ace [ i + + ] , sid , SEC_ACE_TYPE_ACCESS_ALLOWED ,
sid_access , 0 ) ;
}
2001-12-17 23:03:23 +00:00
2009-05-20 11:52:11 -07:00
if ( ( psa = make_sec_acl ( mem_ctx , NT4_ACL_REVISION , i , ace ) ) = = NULL )
2001-12-17 23:03:23 +00:00
return NT_STATUS_NO_MEMORY ;
2007-12-20 22:27:01 +01:00
if ( ( * sd = make_sec_desc ( mem_ctx , SECURITY_DESCRIPTOR_REVISION_1 ,
SEC_DESC_SELF_RELATIVE , & adm_sid , NULL , NULL ,
psa , sd_size ) ) = = NULL )
2001-12-17 23:03:23 +00:00
return NT_STATUS_NO_MEMORY ;
return NT_STATUS_OK ;
}
2009-10-30 11:09:52 +01:00
/***************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS create_lsa_policy_handle ( TALLOC_CTX * mem_ctx ,
struct pipes_struct * p ,
enum lsa_handle_type type ,
uint32_t acc_granted ,
struct dom_sid * sid ,
const char * name ,
const struct security_descriptor * sd ,
struct policy_handle * handle )
{
struct lsa_info * info ;
ZERO_STRUCTP ( handle ) ;
info = talloc_zero ( mem_ctx , struct lsa_info ) ;
if ( ! info ) {
return NT_STATUS_NO_MEMORY ;
}
info - > type = type ;
info - > access = acc_granted ;
if ( sid ) {
sid_copy ( & info - > sid , sid ) ;
}
info - > name = talloc_strdup ( info , name ) ;
2014-05-26 15:48:34 +02:00
if ( sd ! = NULL ) {
info - > sd = security_descriptor_copy ( info , sd ) ;
if ( info - > sd = = NULL ) {
2009-10-30 11:09:52 +01:00
talloc_free ( info ) ;
return NT_STATUS_NO_MEMORY ;
}
}
if ( ! create_policy_hnd ( p , handle , info ) ) {
talloc_free ( info ) ;
ZERO_STRUCTP ( handle ) ;
return NT_STATUS_NO_MEMORY ;
}
return NT_STATUS_OK ;
}
2002-08-17 15:34:15 +00:00
2001-02-26 19:31:07 +00:00
/***************************************************************************
2008-02-04 21:00:38 +01:00
_lsa_OpenPolicy2
2001-02-26 19:31:07 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_OpenPolicy2 ( struct pipes_struct * p ,
2008-02-04 21:00:38 +01:00
struct lsa_OpenPolicy2 * r )
2001-02-26 19:31:07 +00:00
{
2010-05-18 10:29:34 +02:00
struct security_descriptor * psd = NULL ;
2001-12-17 23:03:23 +00:00
size_t sd_size ;
2015-05-14 18:08:27 -07:00
uint32_t des_access = r - > in . access_mask ;
uint32_t acc_granted ;
2001-12-17 23:03:23 +00:00
NTSTATUS status ;
2012-06-25 18:45:35 +02:00
if ( p - > transport ! = NCACN_NP & & p - > transport ! = NCALRPC ) {
p - > fault_state = DCERPC_FAULT_ACCESS_DENIED ;
return NT_STATUS_ACCESS_DENIED ;
}
2009-05-18 15:44:03 -07:00
/* Work out max allowed. */
2011-02-21 10:25:52 +01:00
map_max_allowed_access ( p - > session_info - > security_token ,
2011-07-15 14:59:14 +10:00
p - > session_info - > unix_token ,
2009-06-29 20:34:03 +02:00
& des_access ) ;
2001-12-17 23:03:23 +00:00
/* map the generic bits to the lsa policy ones */
2009-05-20 11:52:11 -07:00
se_map_generic ( & des_access , & lsa_policy_mapping ) ;
2001-12-17 23:03:23 +00:00
/* get the generic lsa policy SD until we store it */
2009-05-20 11:52:11 -07:00
status = make_lsa_object_sd ( p - > mem_ctx , & psd , & sd_size , & lsa_policy_mapping ,
NULL , 0 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2001-12-17 23:03:23 +00:00
2011-02-21 10:25:52 +01:00
status = access_check_object ( psd , p - > session_info - > security_token ,
2010-08-30 13:30:38 +10:00
SEC_PRIV_INVALID , SEC_PRIV_INVALID , 0 , des_access ,
2009-10-26 23:37:21 +01:00
& acc_granted , " _lsa_OpenPolicy2 " ) ;
2008-10-31 10:51:45 -07:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-05-18 15:44:03 -07:00
return status ;
2003-06-18 15:24:10 +00:00
}
2009-10-30 11:09:52 +01:00
status = create_lsa_policy_handle ( p - > mem_ctx , p ,
LSA_HANDLE_POLICY_TYPE ,
acc_granted ,
get_global_sam_sid ( ) ,
NULL ,
psd ,
r - > out . handle ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2001-03-11 00:32:10 +00:00
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
2009-10-30 11:09:52 +01:00
}
2001-02-26 19:31:07 +00:00
2001-08-27 19:46:22 +00:00
return NT_STATUS_OK ;
2001-02-26 19:31:07 +00:00
}
/***************************************************************************
2008-02-04 21:00:16 +01:00
_lsa_OpenPolicy
2001-02-26 19:31:07 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_OpenPolicy ( struct pipes_struct * p ,
2008-02-04 21:00:16 +01:00
struct lsa_OpenPolicy * r )
2001-02-26 19:31:07 +00:00
{
2009-05-19 00:16:26 +02:00
struct lsa_OpenPolicy2 o ;
2001-12-17 23:03:23 +00:00
2012-06-25 18:45:35 +02:00
/* _lsa_OpenPolicy2 will check if this is a NCACN_NP connection */
2009-05-19 00:16:26 +02:00
o . in . system_name = NULL ; /* should be ignored */
o . in . attr = r - > in . attr ;
o . in . access_mask = r - > in . access_mask ;
2001-12-17 23:03:23 +00:00
2009-05-19 00:16:26 +02:00
o . out . handle = r - > out . handle ;
2001-12-17 23:03:23 +00:00
2009-05-19 00:16:26 +02:00
return _lsa_OpenPolicy2 ( p , & o ) ;
2001-02-26 19:31:07 +00:00
}
/***************************************************************************
2008-02-13 00:02:21 +01:00
_lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA .
2002-07-15 10:35:28 +00:00
ufff , done : ) mimir
2001-02-26 19:31:07 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_EnumTrustDom ( struct pipes_struct * p ,
2008-02-13 00:02:21 +01:00
struct lsa_EnumTrustDom * r )
2001-02-26 19:31:07 +00:00
{
2001-12-17 23:03:23 +00:00
struct lsa_info * info ;
2009-10-20 18:35:49 +02:00
uint32_t count ;
2006-02-03 22:19:41 +00:00
struct trustdom_info * * domains ;
2009-10-20 18:35:49 +02:00
struct lsa_DomainInfo * entries ;
2008-02-13 00:02:21 +01:00
int i ;
2002-07-15 10:35:28 +00:00
NTSTATUS nt_status ;
2001-02-26 19:31:07 +00:00
2008-02-13 00:02:21 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & info ) )
2001-03-11 00:32:10 +00:00
return NT_STATUS_INVALID_HANDLE ;
2009-05-20 11:52:11 -07:00
if ( info - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
2008-07-18 15:31:36 +02:00
/* check if the user has enough rights */
2008-02-27 15:49:31 +01:00
if ( ! ( info - > access & LSA_POLICY_VIEW_LOCAL_INFORMATION ) )
2001-12-17 23:03:23 +00:00
return NT_STATUS_ACCESS_DENIED ;
2008-06-16 13:27:16 +02:00
become_root ( ) ;
2009-10-20 18:35:49 +02:00
nt_status = pdb_enum_trusteddoms ( p - > mem_ctx , & count , & domains ) ;
2008-06-16 13:27:16 +02:00
unbecome_root ( ) ;
2002-07-15 10:35:28 +00:00
2006-02-03 22:19:41 +00:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2002-07-15 10:35:28 +00:00
return nt_status ;
}
2011-06-07 11:58:39 +10:00
entries = talloc_zero_array ( p - > mem_ctx , struct lsa_DomainInfo , count ) ;
2009-10-20 18:35:49 +02:00
if ( ! entries ) {
return NT_STATUS_NO_MEMORY ;
}
2006-02-03 22:19:41 +00:00
2009-10-20 18:35:49 +02:00
for ( i = 0 ; i < count ; i + + ) {
init_lsa_StringLarge ( & entries [ i ] . name , domains [ i ] - > name ) ;
entries [ i ] . sid = & domains [ i ] - > sid ;
}
2006-02-03 22:19:41 +00:00
2009-10-20 18:35:49 +02:00
if ( * r - > in . resume_handle > = count ) {
* r - > out . resume_handle = - 1 ;
TALLOC_FREE ( entries ) ;
return NT_STATUS_NO_MORE_ENTRIES ;
2006-02-03 22:19:41 +00:00
}
2008-02-13 00:02:21 +01:00
2009-10-20 18:35:49 +02:00
/* 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 ) ) ;
2005-04-06 22:27:55 +00:00
2009-10-20 18:35:49 +02:00
r - > out . domains - > domains = entries + * r - > in . resume_handle ;
2001-02-26 19:31:07 +00:00
2009-10-20 18:35:49 +02:00
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 ;
2008-02-13 00:02:21 +01:00
}
2009-10-21 02:17:32 +02: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 ;
2009-10-20 18:35:49 +02:00
return NT_STATUS_OK ;
2001-02-26 19:31:07 +00:00
}
2008-02-27 16:14:27 +01:00
# define LSA_AUDIT_NUM_CATEGORIES_NT4 7
# define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
# define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
2001-02-26 19:31:07 +00:00
/***************************************************************************
2008-02-08 01:13:50 +01:00
_lsa_QueryInfoPolicy
2001-02-26 19:31:07 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_QueryInfoPolicy ( struct pipes_struct * p ,
2008-02-08 01:13:50 +01:00
struct lsa_QueryInfoPolicy * r )
2001-02-26 19:31:07 +00:00
{
2008-02-08 01:13:50 +01:00
NTSTATUS status = NT_STATUS_OK ;
2001-12-17 23:03:23 +00:00
struct lsa_info * handle ;
2010-05-21 11:25:01 +10:00
struct dom_sid domain_sid ;
2002-11-12 23:20:50 +00:00
const char * name ;
2010-05-21 11:25:01 +10:00
struct dom_sid * sid = NULL ;
2008-02-08 01:13:50 +01:00
union lsa_PolicyInformation * info = NULL ;
2009-07-16 16:32:04 +02:00
uint32_t acc_required = 0 ;
2001-02-26 19:31:07 +00:00
2008-02-08 01:13:50 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & handle ) )
2001-03-11 00:32:10 +00:00
return NT_STATUS_INVALID_HANDLE ;
2009-05-20 11:52:11 -07:00
if ( handle - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
2009-07-16 16:32:04 +02:00
switch ( r - > in . level ) {
case LSA_POLICY_INFO_AUDIT_LOG :
case LSA_POLICY_INFO_AUDIT_EVENTS :
acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION ;
break ;
case LSA_POLICY_INFO_DOMAIN :
acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION ;
break ;
case LSA_POLICY_INFO_PD :
acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION ;
break ;
case LSA_POLICY_INFO_ACCOUNT_DOMAIN :
acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION ;
break ;
case LSA_POLICY_INFO_ROLE :
case LSA_POLICY_INFO_REPLICA :
acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION ;
break ;
case LSA_POLICY_INFO_QUOTA :
acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION ;
break ;
case LSA_POLICY_INFO_MOD :
case LSA_POLICY_INFO_AUDIT_FULL_SET :
/* according to MS-LSAD 3.1.4.4.3 */
return NT_STATUS_INVALID_PARAMETER ;
case LSA_POLICY_INFO_AUDIT_FULL_QUERY :
acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION ;
break ;
case LSA_POLICY_INFO_DNS :
case LSA_POLICY_INFO_DNS_INT :
case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN :
acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION ;
break ;
default :
break ;
}
if ( ! ( handle - > access & acc_required ) ) {
/* return NT_STATUS_ACCESS_DENIED; */
}
2011-06-07 11:44:43 +10:00
info = talloc_zero ( p - > mem_ctx , union lsa_PolicyInformation ) ;
2008-02-08 01:13:50 +01:00
if ( ! info ) {
return NT_STATUS_NO_MEMORY ;
}
switch ( r - > in . level ) {
2009-11-03 11:45:15 +01:00
/* according to MS-LSAD 3.1.4.4.3 */
case LSA_POLICY_INFO_MOD :
case LSA_POLICY_INFO_AUDIT_FULL_SET :
case LSA_POLICY_INFO_AUDIT_FULL_QUERY :
return NT_STATUS_INVALID_PARAMETER ;
case LSA_POLICY_INFO_AUDIT_LOG :
info - > audit_log . percent_full = 0 ;
info - > audit_log . maximum_log_size = 0 ;
info - > audit_log . retention_time = 0 ;
info - > audit_log . shutdown_in_progress = 0 ;
info - > audit_log . time_to_shutdown = 0 ;
info - > audit_log . next_audit_record = 0 ;
status = NT_STATUS_OK ;
break ;
case LSA_POLICY_INFO_PD :
info - > pd . name . string = NULL ;
status = NT_STATUS_OK ;
break ;
case LSA_POLICY_INFO_REPLICA :
info - > replica . source . string = NULL ;
info - > replica . account . string = NULL ;
status = NT_STATUS_OK ;
break ;
case LSA_POLICY_INFO_QUOTA :
info - > quota . paged_pool = 0 ;
info - > quota . non_paged_pool = 0 ;
info - > quota . min_wss = 0 ;
info - > quota . max_wss = 0 ;
info - > quota . pagefile = 0 ;
info - > quota . unknown = 0 ;
status = NT_STATUS_OK ;
break ;
2009-06-28 17:48:07 +02:00
case LSA_POLICY_INFO_AUDIT_EVENTS :
2001-02-26 19:31:07 +00:00
{
2006-04-11 15:47:24 +00:00
2015-05-14 18:08:27 -07:00
uint32_t policy_def = LSA_AUDIT_POLICY_ALL ;
2008-02-08 01:13:50 +01:00
2008-07-18 15:31:36 +02:00
/* check if the user has enough rights */
2008-02-27 15:49:31 +01:00
if ( ! ( handle - > access & LSA_POLICY_VIEW_AUDIT_INFORMATION ) ) {
2008-02-08 01:13:50 +01:00
DEBUG ( 10 , ( " _lsa_QueryInfoPolicy: insufficient access rights \n " ) ) ;
2001-12-17 23:03:23 +00:00
return NT_STATUS_ACCESS_DENIED ;
2006-04-11 15:47:24 +00:00
}
2001-12-17 23:03:23 +00:00
/* fake info: We audit everything. ;) */
2006-04-11 15:47:24 +00:00
2008-02-08 01:13:50 +01:00
info - > audit_events . auditing_mode = true ;
info - > audit_events . count = LSA_AUDIT_NUM_CATEGORIES ;
2011-06-07 11:58:39 +10:00
info - > audit_events . settings = talloc_zero_array ( p - > mem_ctx ,
2008-02-08 01:13:50 +01:00
enum lsa_PolicyAuditPolicy ,
info - > audit_events . count ) ;
if ( ! info - > audit_events . settings ) {
2001-12-17 23:03:23 +00:00
return NT_STATUS_NO_MEMORY ;
2008-02-08 01:13:50 +01:00
}
2006-04-11 15:47:24 +00:00
2008-02-08 01:13:50 +01:00
info - > audit_events . settings [ LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT ] = policy_def ;
info - > audit_events . settings [ LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS ] = policy_def ;
info - > audit_events . settings [ LSA_AUDIT_CATEGORY_LOGON ] = policy_def ;
info - > audit_events . settings [ LSA_AUDIT_CATEGORY_PROCCESS_TRACKING ] = policy_def ;
info - > audit_events . settings [ LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES ] = policy_def ;
info - > audit_events . settings [ LSA_AUDIT_CATEGORY_SYSTEM ] = policy_def ;
info - > audit_events . settings [ LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS ] = policy_def ;
2006-04-11 15:47:24 +00:00
2001-12-17 23:03:23 +00:00
break ;
2001-02-26 19:31:07 +00:00
}
2009-06-28 17:48:07 +02:00
case LSA_POLICY_INFO_DOMAIN :
2008-07-18 15:31:36 +02:00
/* check if the user has enough rights */
2008-02-27 15:49:31 +01:00
if ( ! ( handle - > access & LSA_POLICY_VIEW_LOCAL_INFORMATION ) )
2001-12-17 23:03:23 +00:00
return NT_STATUS_ACCESS_DENIED ;
2001-04-21 23:06:59 +00:00
/* Request PolicyPrimaryDomainInformation. */
switch ( lp_server_role ( ) ) {
2001-02-26 19:31:07 +00:00
case ROLE_DOMAIN_PDC :
case ROLE_DOMAIN_BDC :
2003-05-07 08:21:06 +00:00
name = get_global_sam_name ( ) ;
2010-08-26 17:21:39 +02:00
sid = dom_sid_dup ( p - > mem_ctx , get_global_sam_sid ( ) ) ;
2008-03-04 12:46:15 +01:00
if ( ! sid ) {
return NT_STATUS_NO_MEMORY ;
}
2001-02-26 19:31:07 +00:00
break ;
case ROLE_DOMAIN_MEMBER :
2002-11-12 23:20:50 +00:00
name = lp_workgroup ( ) ;
2001-04-21 23:06:59 +00:00
/* We need to return the Domain SID here. */
2008-03-04 12:46:15 +01:00
if ( secrets_fetch_domain_sid ( lp_workgroup ( ) , & domain_sid ) ) {
2010-08-26 17:21:39 +02:00
sid = dom_sid_dup ( p - > mem_ctx , & domain_sid ) ;
2008-03-04 12:46:15 +01:00
if ( ! sid ) {
return NT_STATUS_NO_MEMORY ;
}
} else {
2001-04-21 23:06:59 +00:00
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO ;
2008-03-04 12:46:15 +01:00
}
2001-02-26 19:31:07 +00:00
break ;
2001-03-15 03:08:22 +00:00
case ROLE_STANDALONE :
2002-11-12 23:20:50 +00:00
name = lp_workgroup ( ) ;
2002-01-31 09:37:26 +00:00
sid = NULL ;
2001-03-15 03:08:22 +00:00
break ;
2001-03-15 02:49:06 +00:00
default :
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO ;
2001-02-26 19:31:07 +00:00
}
2008-02-08 01:13:50 +01:00
init_dom_query_3 ( & info - > domain , name , sid ) ;
2001-02-26 19:31:07 +00:00
break ;
2009-06-28 17:48:07 +02:00
case LSA_POLICY_INFO_ACCOUNT_DOMAIN :
2008-07-18 15:31:36 +02:00
/* check if the user has enough rights */
2008-02-27 15:49:31 +01:00
if ( ! ( handle - > access & LSA_POLICY_VIEW_LOCAL_INFORMATION ) )
2001-12-17 23:03:23 +00:00
return NT_STATUS_ACCESS_DENIED ;
2001-04-21 23:06:59 +00:00
/* Request PolicyAccountDomainInformation. */
2003-05-07 08:21:06 +00:00
name = get_global_sam_name ( ) ;
sid = get_global_sam_sid ( ) ;
2008-02-08 01:13:50 +01:00
init_dom_query_5 ( & info - > account_domain , name , sid ) ;
2001-02-26 19:31:07 +00:00
break ;
2009-06-28 17:48:07 +02:00
case LSA_POLICY_INFO_ROLE :
2008-07-18 15:31:36 +02:00
/* check if the user has enough rights */
2008-02-27 15:49:31 +01:00
if ( ! ( handle - > access & LSA_POLICY_VIEW_LOCAL_INFORMATION ) )
2001-12-17 23:03:23 +00:00
return NT_STATUS_ACCESS_DENIED ;
2001-04-21 23:06:59 +00:00
switch ( lp_server_role ( ) ) {
2001-02-26 19:31:07 +00:00
case ROLE_DOMAIN_BDC :
/*
* only a BDC is a backup controller
* of the domain , it controls .
*/
2009-04-02 18:48:15 +02:00
info - > role . role = LSA_ROLE_BACKUP ;
2001-02-26 19:31:07 +00:00
break ;
default :
/*
* any other role is a primary
* of the domain , it controls .
*/
2009-04-02 18:48:15 +02:00
info - > role . role = LSA_ROLE_PRIMARY ;
2008-02-08 01:13:50 +01:00
break ;
2001-02-26 19:31:07 +00:00
}
break ;
2009-07-16 16:28:11 +02:00
case LSA_POLICY_INFO_DNS :
case LSA_POLICY_INFO_DNS_INT : {
2009-06-28 23:07:00 +02:00
struct pdb_domain_info * dominfo ;
if ( ( pdb_capabilities ( ) & PDB_CAP_ADS ) = = 0 ) {
DEBUG ( 10 , ( " Not replying to LSA_POLICY_INFO_DNS "
" without ADS passdb backend \n " ) ) ;
status = NT_STATUS_INVALID_INFO_CLASS ;
break ;
}
dominfo = pdb_get_domain_info ( info ) ;
if ( dominfo = = NULL ) {
status = NT_STATUS_NO_MEMORY ;
break ;
}
init_lsa_StringLarge ( & info - > dns . name ,
dominfo - > name ) ;
init_lsa_StringLarge ( & info - > dns . dns_domain ,
dominfo - > dns_domain ) ;
init_lsa_StringLarge ( & info - > dns . dns_forest ,
dominfo - > dns_forest ) ;
info - > dns . domain_guid = dominfo - > guid ;
info - > dns . sid = & dominfo - > sid ;
break ;
}
2001-02-26 19:31:07 +00:00
default :
2008-02-08 01:13:50 +01:00
DEBUG ( 0 , ( " _lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d \n " ,
r - > in . level ) ) ;
status = NT_STATUS_INVALID_INFO_CLASS ;
2001-02-26 19:31:07 +00:00
break ;
}
2008-02-08 01:13:50 +01:00
* r - > out . info = info ;
2001-02-26 19:31:07 +00:00
2008-02-08 01:13:50 +01:00
return status ;
2001-02-26 19:31:07 +00:00
}
2009-07-16 16:28:11 +02:00
/***************************************************************************
_lsa_QueryInfoPolicy2
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_QueryInfoPolicy2 ( struct pipes_struct * p ,
2009-07-16 16:28:11 +02:00
struct lsa_QueryInfoPolicy2 * r2 )
{
struct lsa_QueryInfoPolicy r ;
if ( ( pdb_capabilities ( ) & PDB_CAP_ADS ) = = 0 ) {
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2009-07-16 16:28:11 +02:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
ZERO_STRUCT ( r ) ;
r . in . handle = r2 - > in . handle ;
r . in . level = r2 - > in . level ;
r . out . info = r2 - > out . info ;
return _lsa_QueryInfoPolicy ( p , & r ) ;
}
2001-02-26 19:31:07 +00:00
/***************************************************************************
2006-02-10 23:52:53 +00:00
_lsa_lookup_sids_internal
2001-02-26 19:31:07 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
static NTSTATUS _lsa_lookup_sids_internal ( struct pipes_struct * p ,
2008-02-19 01:01:15 +01:00
TALLOC_CTX * mem_ctx ,
uint16_t level , /* input */
int num_sids , /* input */
struct lsa_SidPtr * sid , /* input */
struct lsa_RefDomainList * * pp_ref , /* input/output */
struct lsa_TranslatedName2 * * pp_names , /* input/output */
uint32_t * pp_mapped_count ) /* input/output */
2001-02-26 19:31:07 +00:00
{
2006-02-10 23:52:53 +00:00
NTSTATUS status ;
int i ;
2010-05-21 11:25:01 +10:00
const struct dom_sid * * sids = NULL ;
2008-02-19 01:01:15 +01:00
struct lsa_RefDomainList * ref = NULL ;
2015-05-14 18:08:27 -07:00
uint32_t mapped_count = 0 ;
2006-02-10 23:52:53 +00:00
struct lsa_dom_info * dom_infos = NULL ;
struct lsa_name_info * name_infos = NULL ;
2008-02-19 01:01:15 +01:00
struct lsa_TranslatedName2 * names = NULL ;
2002-03-29 21:50:21 +00:00
2006-02-10 23:52:53 +00:00
* pp_mapped_count = 0 ;
2008-02-19 01:01:15 +01:00
* pp_names = NULL ;
2006-02-10 23:52:53 +00:00
* pp_ref = NULL ;
2007-05-04 22:01:26 +00:00
if ( num_sids = = 0 ) {
return NT_STATUS_OK ;
}
2011-06-07 11:30:12 +10:00
sids = talloc_array ( p - > mem_ctx , const struct dom_sid * , num_sids ) ;
2011-06-07 11:44:43 +10:00
ref = talloc_zero ( p - > mem_ctx , struct lsa_RefDomainList ) ;
2006-02-03 22:19:41 +00:00
2007-06-09 00:13:07 +00:00
if ( sids = = NULL | | ref = = NULL ) {
2006-02-10 23:52:53 +00:00
return NT_STATUS_NO_MEMORY ;
2006-02-03 22:19:41 +00:00
}
for ( i = 0 ; i < num_sids ; i + + ) {
2008-02-19 01:01:15 +01:00
sids [ i ] = sid [ i ] . sid ;
2006-02-03 22:19:41 +00:00
}
2006-02-10 23:52:53 +00:00
status = lookup_sids ( p - > mem_ctx , num_sids , sids , level ,
2006-02-03 22:19:41 +00:00
& dom_infos , & name_infos ) ;
2006-02-10 23:52:53 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2006-02-03 22:19:41 +00:00
}
2011-06-07 11:30:12 +10:00
names = talloc_array ( p - > mem_ctx , struct lsa_TranslatedName2 , num_sids ) ;
2008-02-19 01:01:15 +01:00
if ( names = = NULL ) {
2007-05-04 22:01:26 +00:00
return NT_STATUS_NO_MEMORY ;
2004-05-21 18:06:27 +00:00
}
2006-02-03 22:19:41 +00:00
2008-10-24 02:01:16 +02:00
for ( i = 0 ; i < LSA_REF_DOMAIN_LIST_MULTIPLIER ; i + + ) {
2006-02-03 22:19:41 +00:00
if ( ! dom_infos [ i ] . valid ) {
break ;
}
2008-02-19 01:01:15 +01:00
if ( init_lsa_ref_domain_list ( mem_ctx , ref ,
dom_infos [ i ] . name ,
& dom_infos [ i ] . sid ) ! = i ) {
2006-02-03 22:19:41 +00:00
DEBUG ( 0 , ( " Domain %s mentioned twice?? \n " ,
dom_infos [ i ] . name ) ) ;
2006-02-10 23:52:53 +00:00
return NT_STATUS_INTERNAL_ERROR ;
2006-02-03 22:19:41 +00:00
}
}
for ( i = 0 ; i < num_sids ; i + + ) {
struct lsa_name_info * name = & name_infos [ i ] ;
if ( name - > type = = SID_NAME_UNKNOWN ) {
name - > dom_idx = - 1 ;
2006-07-23 08:18:31 +00:00
/* Unknown sids should return the string
* representation of the SID . Windows 2003 behaves
* rather erratic here , in many cases it returns the
* RID as 8 bytes hex , in others it returns the full
* SID . We ( Jerry / VL ) could not figure out which the
* hard cases are , so leave it with the SID . */
2011-03-03 16:20:56 +01:00
name - > name = dom_sid_string ( p - > mem_ctx , sids [ i ] ) ;
2006-02-03 22:19:41 +00:00
if ( name - > name = = NULL ) {
2006-02-10 23:52:53 +00:00
return NT_STATUS_NO_MEMORY ;
2006-02-03 22:19:41 +00:00
}
} else {
mapped_count + = 1 ;
}
2008-12-08 18:03:01 +01:00
names [ i ] . sid_type = name - > type ;
names [ i ] . name . string = name - > name ;
names [ i ] . sid_index = name - > dom_idx ;
names [ i ] . unknown = 0 ;
2008-02-19 01:01:15 +01:00
}
2006-02-03 22:19:41 +00:00
2006-02-10 23:52:53 +00:00
status = NT_STATUS_NONE_MAPPED ;
2006-02-03 22:19:41 +00:00
if ( mapped_count > 0 ) {
2006-02-10 23:52:53 +00:00
status = ( mapped_count < num_sids ) ?
2006-02-03 22:19:41 +00:00
STATUS_SOME_UNMAPPED : NT_STATUS_OK ;
}
DEBUG ( 10 , ( " num_sids %d, mapped_count %d, status %s \n " ,
2006-02-10 23:52:53 +00:00
num_sids , mapped_count , nt_errstr ( status ) ) ) ;
* pp_mapped_count = mapped_count ;
2008-02-19 01:01:15 +01:00
* pp_names = names ;
2006-02-10 23:52:53 +00:00
* pp_ref = ref ;
return status ;
}
/***************************************************************************
2008-02-19 01:01:15 +01:00
_lsa_LookupSids
2006-02-10 23:52:53 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_LookupSids ( struct pipes_struct * p ,
2008-02-19 01:01:15 +01:00
struct lsa_LookupSids * r )
2006-02-10 23:52:53 +00:00
{
2008-02-19 01:01:15 +01:00
NTSTATUS status ;
2006-02-10 23:52:53 +00:00
struct lsa_info * handle ;
2008-02-19 01:01:15 +01:00
int num_sids = r - > in . sids - > num_sids ;
2015-05-14 18:08:27 -07:00
uint32_t mapped_count = 0 ;
2008-02-19 01:01:15 +01:00
struct lsa_RefDomainList * domains = NULL ;
struct lsa_TranslatedName * names_out = NULL ;
struct lsa_TranslatedName2 * names = NULL ;
int i ;
2006-02-10 23:52:53 +00:00
2012-06-25 18:45:35 +02:00
if ( p - > transport ! = NCACN_NP & & p - > transport ! = NCALRPC ) {
p - > fault_state = DCERPC_FAULT_ACCESS_DENIED ;
return NT_STATUS_ACCESS_DENIED ;
}
2008-02-19 01:01:15 +01:00
if ( ( r - > in . level < 1 ) | | ( r - > in . level > 6 ) ) {
2006-02-10 23:52:53 +00:00
return NT_STATUS_INVALID_PARAMETER ;
}
2008-02-19 01:01:15 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & handle ) ) {
2006-02-10 23:52:53 +00:00
return NT_STATUS_INVALID_HANDLE ;
}
2009-05-20 11:52:11 -07:00
if ( handle - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
2006-02-10 23:52:53 +00:00
/* check if the user has enough rights */
2008-02-27 15:49:31 +01:00
if ( ! ( handle - > access & LSA_POLICY_LOOKUP_NAMES ) ) {
2006-02-10 23:52:53 +00:00
return NT_STATUS_ACCESS_DENIED ;
}
if ( num_sids > MAX_LOOKUP_SIDS ) {
2008-02-19 01:01:15 +01:00
DEBUG ( 5 , ( " _lsa_LookupSids: limit of %d exceeded, requested %d \n " ,
2006-02-10 23:52:53 +00:00
MAX_LOOKUP_SIDS , num_sids ) ) ;
return NT_STATUS_NONE_MAPPED ;
}
2008-02-19 01:01:15 +01:00
status = _lsa_lookup_sids_internal ( p ,
p - > mem_ctx ,
r - > in . level ,
num_sids ,
r - > in . sids - > sids ,
& domains ,
& names ,
& mapped_count ) ;
2006-02-10 23:52:53 +00:00
2009-04-16 01:42:35 +02:00
/* Only return here when there is a real error.
NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
the requested sids could be resolved . Older versions of XP ( pre SP3 )
rely that we return with the string representations of those SIDs in
that case . If we don ' t , XP crashes - Guenther
*/
if ( NT_STATUS_IS_ERR ( status ) & &
! NT_STATUS_EQUAL ( status , NT_STATUS_NONE_MAPPED ) ) {
2009-03-24 11:07:16 +01:00
return status ;
}
2008-02-19 01:01:15 +01:00
/* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
2011-06-07 11:30:12 +10:00
names_out = talloc_array ( p - > mem_ctx , struct lsa_TranslatedName ,
2008-02-19 01:01:15 +01:00
num_sids ) ;
if ( ! names_out ) {
return NT_STATUS_NO_MEMORY ;
}
2006-02-10 23:52:53 +00:00
2008-02-19 01:01:15 +01:00
for ( i = 0 ; i < num_sids ; i + + ) {
names_out [ i ] . sid_type = names [ i ] . sid_type ;
names_out [ i ] . name = names [ i ] . name ;
names_out [ i ] . sid_index = names [ i ] . sid_index ;
2006-02-10 23:52:53 +00:00
}
2008-02-19 01:01:15 +01:00
* r - > out . domains = domains ;
r - > out . names - > count = num_sids ;
r - > out . names - > names = names_out ;
* r - > out . count = mapped_count ;
return status ;
2006-02-10 23:52:53 +00:00
}
2012-06-25 18:49:11 +02:00
static NTSTATUS _lsa_LookupSids_common ( struct pipes_struct * p ,
struct lsa_LookupSids2 * r )
2006-02-10 23:52:53 +00:00
{
2008-02-19 01:01:15 +01:00
NTSTATUS status ;
2006-02-10 23:52:53 +00:00
struct lsa_info * handle ;
2008-02-19 01:01:15 +01:00
int num_sids = r - > in . sids - > num_sids ;
2015-05-14 18:08:27 -07:00
uint32_t mapped_count = 0 ;
2008-02-19 01:01:15 +01:00
struct lsa_RefDomainList * domains = NULL ;
struct lsa_TranslatedName2 * names = NULL ;
bool check_policy = true ;
2006-02-10 23:52:53 +00:00
2010-07-09 19:35:22 -04:00
switch ( p - > opnum ) {
2008-02-19 01:01:15 +01:00
case NDR_LSA_LOOKUPSIDS3 :
check_policy = false ;
break ;
case NDR_LSA_LOOKUPSIDS2 :
default :
check_policy = true ;
2006-02-10 23:52:53 +00:00
}
2008-02-19 01:01:15 +01:00
if ( ( r - > in . level < 1 ) | | ( r - > in . level > 6 ) ) {
return NT_STATUS_INVALID_PARAMETER ;
2006-02-10 23:52:53 +00:00
}
2008-02-19 01:01:15 +01:00
if ( check_policy ) {
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & handle ) ) {
return NT_STATUS_INVALID_HANDLE ;
}
2009-05-20 11:52:11 -07:00
if ( handle - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
2008-07-18 15:31:36 +02:00
/* check if the user has enough rights */
2008-02-27 15:49:31 +01:00
if ( ! ( handle - > access & LSA_POLICY_LOOKUP_NAMES ) ) {
2008-02-19 01:01:15 +01:00
return NT_STATUS_ACCESS_DENIED ;
}
2006-02-10 23:52:53 +00:00
}
if ( num_sids > MAX_LOOKUP_SIDS ) {
2008-02-19 01:01:15 +01:00
DEBUG ( 5 , ( " _lsa_LookupSids2: limit of %d exceeded, requested %d \n " ,
2006-02-10 23:52:53 +00:00
MAX_LOOKUP_SIDS , num_sids ) ) ;
return NT_STATUS_NONE_MAPPED ;
}
2008-02-19 01:01:15 +01:00
status = _lsa_lookup_sids_internal ( p ,
p - > mem_ctx ,
r - > in . level ,
num_sids ,
r - > in . sids - > sids ,
& domains ,
& names ,
& mapped_count ) ;
2006-02-10 23:52:53 +00:00
2008-02-19 01:01:15 +01:00
* r - > out . domains = domains ;
r - > out . names - > count = num_sids ;
r - > out . names - > names = names ;
* r - > out . count = mapped_count ;
return status ;
2006-02-10 23:52:53 +00:00
}
2012-06-25 18:49:11 +02:00
/***************************************************************************
_lsa_LookupSids2
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS _lsa_LookupSids2 ( struct pipes_struct * p ,
struct lsa_LookupSids2 * r )
{
if ( p - > transport ! = NCACN_NP & & p - > transport ! = NCALRPC ) {
p - > fault_state = DCERPC_FAULT_ACCESS_DENIED ;
return NT_STATUS_ACCESS_DENIED ;
}
return _lsa_LookupSids_common ( p , r ) ;
}
2006-02-10 23:52:53 +00:00
/***************************************************************************
2008-02-19 01:01:15 +01:00
_lsa_LookupSids3
2006-02-10 23:52:53 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_LookupSids3 ( struct pipes_struct * p ,
2008-02-19 01:01:15 +01:00
struct lsa_LookupSids3 * r )
2006-02-10 23:52:53 +00:00
{
2008-02-19 01:01:15 +01:00
struct lsa_LookupSids2 q ;
2006-02-10 23:52:53 +00:00
2012-06-25 18:49:11 +02:00
if ( p - > transport ! = NCACN_IP_TCP ) {
p - > fault_state = DCERPC_FAULT_ACCESS_DENIED ;
return NT_STATUS_ACCESS_DENIED ;
}
2007-10-10 15:34:30 -05:00
/* No policy handle on this call. Restrict to crypto connections. */
2012-06-26 17:25:57 +02:00
if ( p - > auth . auth_type ! = DCERPC_AUTH_TYPE_SCHANNEL | |
p - > auth . auth_level < DCERPC_AUTH_LEVEL_INTEGRITY ) {
DEBUG ( 1 , ( " _lsa_LookupSids3: The client %s is not using "
" a secure connection over netlogon \n " ,
get_remote_machine_name ( ) ) ) ;
p - > fault_state = DCERPC_FAULT_ACCESS_DENIED ;
return NT_STATUS_ACCESS_DENIED ;
2007-10-10 15:34:30 -05:00
}
2006-07-22 19:44:17 +00:00
2008-02-19 01:01:15 +01:00
q . in . handle = NULL ;
q . in . sids = r - > in . sids ;
q . in . level = r - > in . level ;
2009-09-11 13:55:44 +02:00
q . in . lookup_options = r - > in . lookup_options ;
q . in . client_revision = r - > in . client_revision ;
2008-02-19 01:01:15 +01:00
q . in . names = r - > in . names ;
q . in . count = r - > in . count ;
2006-07-22 19:44:17 +00:00
2008-02-19 01:01:15 +01:00
q . out . domains = r - > out . domains ;
q . out . names = r - > out . names ;
q . out . count = r - > out . count ;
2007-10-10 15:34:30 -05:00
2012-06-25 18:49:11 +02:00
return _lsa_LookupSids_common ( p , & q ) ;
2001-02-26 19:31:07 +00:00
}
2008-02-19 01:01:15 +01:00
/***************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-10-26 23:28:30 +01:00
static int lsa_lookup_level_to_flags ( enum lsa_LookupNamesLevel level )
2007-12-12 18:03:20 +01:00
{
int flags ;
switch ( level ) {
2009-10-26 23:28:30 +01:00
case LSA_LOOKUP_NAMES_ALL : /* 1 */
2007-12-12 18:03:20 +01:00
flags = LOOKUP_NAME_ALL ;
break ;
2009-10-26 23:28:30 +01:00
case LSA_LOOKUP_NAMES_DOMAINS_ONLY : /* 2 */
2007-12-12 18:03:20 +01:00
flags = LOOKUP_NAME_DOMAIN | LOOKUP_NAME_REMOTE | LOOKUP_NAME_ISOLATED ;
break ;
2009-10-26 23:28:30 +01:00
case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY : /* 3 */
2007-12-12 18:03:20 +01:00
flags = LOOKUP_NAME_DOMAIN | LOOKUP_NAME_ISOLATED ;
break ;
2009-10-26 23:28:30 +01:00
case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY : /* 4 */
case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY : /* 5 */
case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 : /* 6 */
case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC : /* 7 */
2007-12-12 18:03:20 +01:00
default :
flags = LOOKUP_NAME_NONE ;
break ;
}
return flags ;
}
2001-02-26 19:31:07 +00:00
/***************************************************************************
2008-02-18 14:40:34 +01:00
_lsa_LookupNames
2001-02-26 19:31:07 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_LookupNames ( struct pipes_struct * p ,
2008-02-18 14:40:34 +01:00
struct lsa_LookupNames * r )
2001-02-26 19:31:07 +00:00
{
2008-02-18 14:40:34 +01:00
NTSTATUS status = NT_STATUS_NONE_MAPPED ;
2001-12-17 23:03:23 +00:00
struct lsa_info * handle ;
2008-02-18 14:40:34 +01:00
struct lsa_String * names = r - > in . names ;
2015-05-14 18:08:27 -07:00
uint32_t num_entries = r - > in . num_names ;
2008-02-18 14:40:34 +01:00
struct lsa_RefDomainList * domains = NULL ;
struct lsa_TranslatedSid * rids = NULL ;
2015-05-14 18:08:27 -07:00
uint32_t mapped_count = 0 ;
2005-12-03 18:34:13 +00:00
int flags = 0 ;
2001-02-26 19:31:07 +00:00
2012-06-25 18:45:35 +02:00
if ( p - > transport ! = NCACN_NP & & p - > transport ! = NCALRPC ) {
p - > fault_state = DCERPC_FAULT_ACCESS_DENIED ;
return NT_STATUS_ACCESS_DENIED ;
}
2002-01-26 10:02:23 +00:00
if ( num_entries > MAX_LOOKUP_SIDS ) {
num_entries = MAX_LOOKUP_SIDS ;
2008-02-18 14:40:34 +01:00
DEBUG ( 5 , ( " _lsa_LookupNames: truncating name lookup list to %d \n " ,
num_entries ) ) ;
2002-01-26 10:02:23 +00:00
}
2008-02-14 13:12:28 +01:00
2008-02-18 14:40:34 +01:00
flags = lsa_lookup_level_to_flags ( r - > in . level ) ;
2005-12-03 18:34:13 +00:00
2011-06-07 11:44:43 +10:00
domains = talloc_zero ( p - > mem_ctx , struct lsa_RefDomainList ) ;
2008-02-18 14:40:34 +01:00
if ( ! domains ) {
2007-04-30 01:17:34 +00:00
return NT_STATUS_NO_MEMORY ;
}
if ( num_entries ) {
2011-06-07 11:58:39 +10:00
rids = talloc_zero_array ( p - > mem_ctx , struct lsa_TranslatedSid ,
2008-02-18 14:40:34 +01:00
num_entries ) ;
2007-04-30 01:17:34 +00:00
if ( ! rids ) {
return NT_STATUS_NO_MEMORY ;
}
} else {
rids = NULL ;
}
2001-03-01 04:01:23 +00:00
2008-02-18 14:40:34 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & handle ) ) {
status = NT_STATUS_INVALID_HANDLE ;
2002-03-29 21:50:21 +00:00
goto done ;
}
2002-03-29 20:37:56 +00:00
2009-05-20 11:52:11 -07:00
if ( handle - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
2008-07-18 15:31:36 +02:00
/* check if the user has enough rights */
2008-02-27 15:49:31 +01:00
if ( ! ( handle - > access & LSA_POLICY_LOOKUP_NAMES ) ) {
2008-02-18 14:40:34 +01:00
status = NT_STATUS_ACCESS_DENIED ;
2002-03-29 21:50:21 +00:00
goto done ;
}
2002-03-29 20:37:56 +00:00
2005-12-03 18:34:13 +00:00
/* set up the LSA Lookup RIDs response */
2006-02-16 01:06:21 +00:00
become_root ( ) ; /* lookup_name can require root privs */
2008-02-18 14:40:34 +01:00
status = lookup_lsa_rids ( p - > mem_ctx , domains , rids , num_entries ,
names , flags , & mapped_count ) ;
2006-02-16 01:06:21 +00:00
unbecome_root ( ) ;
2002-03-29 21:50:21 +00:00
done :
2008-02-18 14:40:34 +01:00
if ( NT_STATUS_IS_OK ( status ) & & ( num_entries ! = 0 ) ) {
if ( mapped_count = = 0 ) {
status = NT_STATUS_NONE_MAPPED ;
} else if ( mapped_count ! = num_entries ) {
status = STATUS_SOME_UNMAPPED ;
}
2004-05-26 18:27:16 +00:00
}
2001-02-26 19:31:07 +00:00
2008-03-04 13:16:02 +01:00
* r - > out . count = mapped_count ;
2008-02-18 14:40:34 +01:00
* r - > out . domains = domains ;
r - > out . sids - > sids = rids ;
2008-03-04 13:16:02 +01:00
r - > out . sids - > count = num_entries ;
2008-02-18 14:40:34 +01:00
return status ;
2001-02-26 19:31:07 +00:00
}
2006-02-11 04:25:06 +00:00
/***************************************************************************
2008-02-18 14:40:34 +01:00
_lsa_LookupNames2
2006-02-11 04:25:06 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_LookupNames2 ( struct pipes_struct * p ,
2008-02-18 14:40:34 +01:00
struct lsa_LookupNames2 * r )
2006-02-11 04:25:06 +00:00
{
2008-02-18 14:40:34 +01:00
NTSTATUS status ;
struct lsa_LookupNames q ;
struct lsa_TransSidArray2 * sid_array2 = r - > in . sids ;
struct lsa_TransSidArray * sid_array = NULL ;
uint32_t i ;
2006-02-11 04:25:06 +00:00
2012-06-25 18:45:35 +02:00
if ( p - > transport ! = NCACN_NP & & p - > transport ! = NCALRPC ) {
p - > fault_state = DCERPC_FAULT_ACCESS_DENIED ;
return NT_STATUS_ACCESS_DENIED ;
}
2011-06-07 11:44:43 +10:00
sid_array = talloc_zero ( p - > mem_ctx , struct lsa_TransSidArray ) ;
2008-02-18 14:40:34 +01:00
if ( ! sid_array ) {
2006-06-21 00:17:14 +00:00
return NT_STATUS_NO_MEMORY ;
2006-06-20 09:16:53 +00:00
}
2008-02-18 14:40:34 +01:00
q . in . handle = r - > in . handle ;
q . in . num_names = r - > in . num_names ;
q . in . names = r - > in . names ;
q . in . level = r - > in . level ;
q . in . sids = sid_array ;
q . in . count = r - > in . count ;
/* we do not know what this is for */
/* = r->in.unknown1; */
/* = r->in.unknown2; */
2007-04-30 01:17:34 +00:00
2008-02-18 14:40:34 +01:00
q . out . domains = r - > out . domains ;
q . out . sids = sid_array ;
q . out . count = r - > out . count ;
2006-02-11 04:25:06 +00:00
2008-02-18 14:40:34 +01:00
status = _lsa_LookupNames ( p , & q ) ;
2006-02-11 04:25:06 +00:00
2009-05-11 18:27:40 +02:00
sid_array2 - > count = sid_array - > count ;
2011-06-07 11:30:12 +10:00
sid_array2 - > sids = talloc_array ( p - > mem_ctx , struct lsa_TranslatedSid2 , sid_array - > count ) ;
2008-02-18 14:40:34 +01:00
if ( ! sid_array2 - > sids ) {
return NT_STATUS_NO_MEMORY ;
2006-02-11 04:25:06 +00:00
}
2008-02-18 14:40:34 +01:00
for ( i = 0 ; i < sid_array - > count ; i + + ) {
sid_array2 - > sids [ i ] . sid_type = sid_array - > sids [ i ] . sid_type ;
sid_array2 - > sids [ i ] . rid = sid_array - > sids [ i ] . rid ;
sid_array2 - > sids [ i ] . sid_index = sid_array - > sids [ i ] . sid_index ;
sid_array2 - > sids [ i ] . unknown = 0 ;
2006-02-11 04:25:06 +00:00
}
2008-02-18 14:40:34 +01:00
r - > out . sids = sid_array2 ;
return status ;
2006-02-11 04:25:06 +00:00
}
2012-06-25 18:53:03 +02:00
static NTSTATUS _lsa_LookupNames_common ( struct pipes_struct * p ,
struct lsa_LookupNames3 * r )
2006-02-11 05:36:27 +00:00
{
2008-02-18 16:57:02 +01:00
NTSTATUS status ;
2006-02-16 01:06:21 +00:00
struct lsa_info * handle ;
2008-02-18 16:57:02 +01:00
struct lsa_String * names = r - > in . names ;
2015-05-14 18:08:27 -07:00
uint32_t num_entries = r - > in . num_names ;
2008-02-18 16:57:02 +01:00
struct lsa_RefDomainList * domains = NULL ;
struct lsa_TranslatedSid3 * trans_sids = NULL ;
2015-05-14 18:08:27 -07:00
uint32_t mapped_count = 0 ;
2006-02-16 01:06:21 +00:00
int flags = 0 ;
2008-02-18 16:57:02 +01:00
bool check_policy = true ;
2010-07-09 19:35:22 -04:00
switch ( p - > opnum ) {
2008-02-18 16:57:02 +01:00
case NDR_LSA_LOOKUPNAMES4 :
check_policy = false ;
break ;
case NDR_LSA_LOOKUPNAMES3 :
default :
check_policy = true ;
}
2006-02-16 01:06:21 +00:00
if ( num_entries > MAX_LOOKUP_SIDS ) {
num_entries = MAX_LOOKUP_SIDS ;
2008-02-18 16:57:02 +01:00
DEBUG ( 5 , ( " _lsa_LookupNames3: truncating name lookup list to %d \n " , num_entries ) ) ;
2006-02-16 01:06:21 +00:00
}
2008-02-14 13:12:28 +01:00
2012-03-02 16:18:16 +02:00
flags = lsa_lookup_level_to_flags ( r - > in . level ) ;
2006-02-16 01:06:21 +00:00
2011-06-07 11:44:43 +10:00
domains = talloc_zero ( p - > mem_ctx , struct lsa_RefDomainList ) ;
2008-02-18 16:57:02 +01:00
if ( ! domains ) {
2007-04-30 01:17:34 +00:00
return NT_STATUS_NO_MEMORY ;
}
2008-02-18 16:57:02 +01:00
2007-04-30 01:17:34 +00:00
if ( num_entries ) {
2011-06-07 11:58:39 +10:00
trans_sids = talloc_zero_array ( p - > mem_ctx , struct lsa_TranslatedSid3 ,
2008-02-18 16:57:02 +01:00
num_entries ) ;
2007-04-30 01:17:34 +00:00
if ( ! trans_sids ) {
return NT_STATUS_NO_MEMORY ;
}
} else {
trans_sids = NULL ;
}
2006-02-16 01:06:21 +00:00
2008-02-18 16:57:02 +01:00
if ( check_policy ) {
2006-02-16 01:06:21 +00:00
2008-02-18 16:57:02 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & handle ) ) {
status = NT_STATUS_INVALID_HANDLE ;
goto done ;
}
2009-05-20 11:52:11 -07:00
if ( handle - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
2008-07-18 15:31:36 +02:00
/* check if the user has enough rights */
2008-02-27 15:49:31 +01:00
if ( ! ( handle - > access & LSA_POLICY_LOOKUP_NAMES ) ) {
2008-02-18 16:57:02 +01:00
status = NT_STATUS_ACCESS_DENIED ;
goto done ;
}
2006-02-16 01:06:21 +00:00
}
/* set up the LSA Lookup SIDs response */
become_root ( ) ; /* lookup_name can require root privs */
2008-02-18 16:57:02 +01:00
status = lookup_lsa_sids ( p - > mem_ctx , domains , trans_sids , num_entries ,
names , flags , & mapped_count ) ;
2006-02-16 01:06:21 +00:00
unbecome_root ( ) ;
done :
2008-02-18 16:57:02 +01:00
if ( NT_STATUS_IS_OK ( status ) ) {
2006-02-16 01:06:21 +00:00
if ( mapped_count = = 0 ) {
2008-02-18 16:57:02 +01:00
status = NT_STATUS_NONE_MAPPED ;
2006-02-16 01:06:21 +00:00
} else if ( mapped_count ! = num_entries ) {
2008-02-18 16:57:02 +01:00
status = STATUS_SOME_UNMAPPED ;
2006-02-16 01:06:21 +00:00
}
}
2008-03-04 13:19:38 +01:00
* r - > out . count = mapped_count ;
2008-02-18 16:57:02 +01:00
* r - > out . domains = domains ;
r - > out . sids - > sids = trans_sids ;
2008-03-04 13:19:38 +01:00
r - > out . sids - > count = num_entries ;
2008-02-18 16:57:02 +01:00
return status ;
2006-02-11 05:36:27 +00:00
}
2012-06-25 18:53:03 +02:00
/***************************************************************************
_lsa_LookupNames3
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS _lsa_LookupNames3 ( struct pipes_struct * p ,
struct lsa_LookupNames3 * r )
{
if ( p - > transport ! = NCACN_NP & & p - > transport ! = NCALRPC ) {
p - > fault_state = DCERPC_FAULT_ACCESS_DENIED ;
return NT_STATUS_ACCESS_DENIED ;
}
return _lsa_LookupNames_common ( p , r ) ;
}
2006-02-11 05:36:27 +00:00
/***************************************************************************
2008-02-18 16:57:02 +01:00
_lsa_LookupNames4
2006-02-11 05:36:27 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_LookupNames4 ( struct pipes_struct * p ,
2008-02-18 16:57:02 +01:00
struct lsa_LookupNames4 * r )
2006-02-11 05:36:27 +00:00
{
2008-02-18 16:57:02 +01:00
struct lsa_LookupNames3 q ;
2006-02-16 01:06:21 +00:00
2012-06-25 18:53:03 +02:00
if ( p - > transport ! = NCACN_IP_TCP ) {
p - > fault_state = DCERPC_FAULT_ACCESS_DENIED ;
return NT_STATUS_ACCESS_DENIED ;
}
2006-02-16 01:06:21 +00:00
/* No policy handle on this call. Restrict to crypto connections. */
2012-06-26 17:25:57 +02:00
if ( p - > auth . auth_type ! = DCERPC_AUTH_TYPE_SCHANNEL | |
p - > auth . auth_level < DCERPC_AUTH_LEVEL_INTEGRITY ) {
DEBUG ( 1 , ( " _lsa_LookupNames4: The client %s is not using "
" a secure connection over netlogon \n " ,
get_remote_machine_name ( ) ) ) ;
p - > fault_state = DCERPC_FAULT_ACCESS_DENIED ;
return NT_STATUS_ACCESS_DENIED ;
2006-02-16 01:06:21 +00:00
}
2008-02-18 16:57:02 +01:00
q . in . handle = NULL ;
q . in . num_names = r - > in . num_names ;
q . in . names = r - > in . names ;
q . in . level = r - > in . level ;
2008-10-15 19:33:16 +02:00
q . in . lookup_options = r - > in . lookup_options ;
q . in . client_revision = r - > in . client_revision ;
2008-02-18 16:57:02 +01:00
q . in . sids = r - > in . sids ;
q . in . count = r - > in . count ;
2006-02-16 01:06:21 +00:00
2008-02-18 16:57:02 +01:00
q . out . domains = r - > out . domains ;
q . out . sids = r - > out . sids ;
q . out . count = r - > out . count ;
2006-02-16 01:06:21 +00:00
2012-06-25 18:53:03 +02:00
return _lsa_LookupNames_common ( p , & q ) ;
2006-02-11 05:36:27 +00:00
}
2006-02-11 04:25:06 +00:00
2001-02-26 19:31:07 +00:00
/***************************************************************************
_lsa_close . Also weird - needs to check if lsa handle is correct . JRA .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_Close ( struct pipes_struct * p , struct lsa_Close * r )
2001-02-26 19:31:07 +00:00
{
2012-06-25 18:45:35 +02:00
if ( p - > transport ! = NCACN_NP & & p - > transport ! = NCALRPC ) {
p - > fault_state = DCERPC_FAULT_ACCESS_DENIED ;
return NT_STATUS_ACCESS_DENIED ;
}
2007-01-18 10:18:59 +00:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , NULL ) ) {
2001-03-11 00:32:10 +00:00
return NT_STATUS_INVALID_HANDLE ;
2006-02-16 01:06:21 +00:00
}
2001-03-11 00:32:10 +00:00
2007-01-18 10:18:59 +00:00
close_policy_hnd ( p , r - > in . handle ) ;
2008-03-03 18:12:26 +01:00
ZERO_STRUCTP ( r - > out . handle ) ;
2001-08-27 19:46:22 +00:00
return NT_STATUS_OK ;
2001-02-26 19:31:07 +00:00
}
2009-07-16 11:55:09 +02:00
/***************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS lsa_lookup_trusted_domain_by_sid ( TALLOC_CTX * mem_ctx ,
const struct dom_sid * sid ,
struct trustdom_info * * info )
{
NTSTATUS status ;
uint32_t num_domains = 0 ;
struct trustdom_info * * domains = NULL ;
int i ;
status = pdb_enum_trusteddoms ( mem_ctx , & num_domains , & domains ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
for ( i = 0 ; i < num_domains ; i + + ) {
if ( dom_sid_equal ( & domains [ i ] - > sid , sid ) ) {
break ;
}
}
if ( i = = num_domains ) {
return NT_STATUS_INVALID_PARAMETER ;
}
* info = domains [ i ] ;
return NT_STATUS_OK ;
}
/***************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS lsa_lookup_trusted_domain_by_name ( TALLOC_CTX * mem_ctx ,
const char * netbios_domain_name ,
struct trustdom_info * * info_p )
{
2010-08-20 11:28:43 +02:00
NTSTATUS status ;
2009-07-16 11:55:09 +02:00
struct trustdom_info * info ;
2010-08-20 11:28:43 +02:00
struct pdb_trusted_domain * td ;
2009-07-16 11:55:09 +02:00
2010-08-20 11:28:43 +02:00
status = pdb_get_trusted_domain ( mem_ctx , netbios_domain_name , & td ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2009-07-16 11:55:09 +02:00
}
info = talloc ( mem_ctx , struct trustdom_info ) ;
if ( ! info ) {
return NT_STATUS_NO_MEMORY ;
}
info - > name = talloc_strdup ( info , netbios_domain_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( info - > name ) ;
2010-08-20 11:28:43 +02:00
sid_copy ( & info - > sid , & td - > security_identifier ) ;
2009-07-16 11:55:09 +02:00
* info_p = info ;
return NT_STATUS_OK ;
}
2001-02-26 19:31:07 +00:00
/***************************************************************************
2009-10-29 23:51:44 +01:00
_lsa_OpenSecret
2001-02-26 19:31:07 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-10-29 23:51:44 +01:00
NTSTATUS _lsa_OpenSecret ( struct pipes_struct * p ,
struct lsa_OpenSecret * r )
2001-02-26 19:31:07 +00:00
{
2009-10-29 23:51:44 +01:00
struct lsa_info * handle ;
struct security_descriptor * psd ;
NTSTATUS status ;
uint32_t acc_granted ;
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & handle ) ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( handle - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( ! r - > in . name . string ) {
return NT_STATUS_INVALID_PARAMETER ;
}
/* Work out max allowed. */
map_max_allowed_access ( p - > session_info - > security_token ,
p - > session_info - > unix_token ,
& r - > in . access_mask ) ;
/* map the generic bits to the lsa policy ones */
se_map_generic ( & r - > in . access_mask , & lsa_secret_mapping ) ;
status = pdb_get_secret ( p - > mem_ctx , r - > in . name . string ,
NULL ,
NULL ,
NULL ,
NULL ,
& psd ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
status = access_check_object ( psd , p - > session_info - > security_token ,
SEC_PRIV_INVALID , SEC_PRIV_INVALID , 0 ,
r - > in . access_mask ,
& acc_granted , " _lsa_OpenSecret " ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
status = create_lsa_policy_handle ( p - > mem_ctx , p ,
LSA_HANDLE_SECRET_TYPE ,
acc_granted ,
NULL ,
r - > in . name . string ,
psd ,
r - > out . sec_handle ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
return NT_STATUS_OK ;
2001-02-26 19:31:07 +00:00
}
2001-06-29 23:12:55 +00:00
2005-05-31 13:46:45 +00:00
/***************************************************************************
2009-07-16 02:26:37 +02:00
_lsa_OpenTrustedDomain_base
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS _lsa_OpenTrustedDomain_base ( struct pipes_struct * p ,
uint32_t access_mask ,
struct trustdom_info * info ,
struct policy_handle * handle )
{
struct security_descriptor * psd = NULL ;
size_t sd_size ;
uint32_t acc_granted ;
NTSTATUS status ;
/* des_access is for the account here, not the policy
* handle - so don ' t check against policy handle . */
/* Work out max allowed. */
2011-02-21 10:25:52 +01:00
map_max_allowed_access ( p - > session_info - > security_token ,
2011-07-15 14:59:14 +10:00
p - > session_info - > unix_token ,
2009-07-16 02:26:37 +02:00
& access_mask ) ;
/* map the generic bits to the lsa account ones */
2011-07-06 16:05:38 +02:00
se_map_generic ( & access_mask , & lsa_trusted_domain_mapping ) ;
2009-07-16 02:26:37 +02:00
/* get the generic lsa account SD until we store it */
status = make_lsa_object_sd ( p - > mem_ctx , & psd , & sd_size ,
& lsa_trusted_domain_mapping ,
NULL , 0 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2011-02-21 10:25:52 +01:00
status = access_check_object ( psd , p - > session_info - > security_token ,
2009-07-16 02:26:37 +02:00
SEC_PRIV_INVALID , SEC_PRIV_INVALID , 0 ,
access_mask , & acc_granted ,
" _lsa_OpenTrustedDomain " ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
status = create_lsa_policy_handle ( p - > mem_ctx , p ,
LSA_HANDLE_TRUST_TYPE ,
acc_granted ,
& info - > sid ,
info - > name ,
psd ,
handle ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
return NT_STATUS_OK ;
}
/***************************************************************************
_lsa_OpenTrustedDomain
2005-05-31 13:46:45 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_OpenTrustedDomain ( struct pipes_struct * p ,
struct lsa_OpenTrustedDomain * r )
2005-05-31 13:46:45 +00:00
{
2009-07-16 02:26:37 +02:00
struct lsa_info * handle = NULL ;
2011-02-21 17:35:45 +01:00
struct trustdom_info * info = NULL ;
2009-07-16 02:26:37 +02:00
NTSTATUS status ;
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & handle ) ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( handle - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
status = lsa_lookup_trusted_domain_by_sid ( p - > mem_ctx ,
r - > in . sid ,
& info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
return _lsa_OpenTrustedDomain_base ( p , r - > in . access_mask , info ,
r - > out . trustdom_handle ) ;
2005-05-31 13:46:45 +00:00
}
2009-10-19 19:02:24 +02:00
/***************************************************************************
_lsa_OpenTrustedDomainByName
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS _lsa_OpenTrustedDomainByName ( struct pipes_struct * p ,
struct lsa_OpenTrustedDomainByName * r )
{
struct lsa_info * handle = NULL ;
2011-02-21 17:35:45 +01:00
struct trustdom_info * info = NULL ;
2009-10-19 19:02:24 +02:00
NTSTATUS status ;
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & handle ) ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( handle - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
status = lsa_lookup_trusted_domain_by_name ( p - > mem_ctx ,
r - > in . name . string ,
& info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
return _lsa_OpenTrustedDomain_base ( p , r - > in . access_mask , info ,
r - > out . trustdom_handle ) ;
}
2012-03-02 16:18:16 +02:00
static NTSTATUS get_trustdom_auth_blob ( struct pipes_struct * p ,
TALLOC_CTX * mem_ctx , DATA_BLOB * auth_blob ,
struct trustDomainPasswords * auth_struct )
{
enum ndr_err_code ndr_err ;
DATA_BLOB lsession_key ;
NTSTATUS status ;
status = session_extract_session_key ( p - > session_info , & lsession_key , KEY_USE_16BYTES ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return NT_STATUS_INVALID_PARAMETER ;
}
arcfour_crypt_blob ( auth_blob - > data , auth_blob - > length , & lsession_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 ( TALLOC_CTX * mem_ctx ,
struct trustAuthInOutBlob * iopw ,
DATA_BLOB * trustauth_blob )
{
enum ndr_err_code ndr_err ;
2015-01-31 11:45:12 +01:00
if ( iopw - > current . count ! = iopw - > count ) {
return NT_STATUS_INVALID_PARAMETER ;
}
if ( iopw - > previous . count > iopw - > current . count ) {
return NT_STATUS_INVALID_PARAMETER ;
}
if ( iopw - > previous . count = = 0 ) {
/*
* If the previous credentials are not present
* we need to make a copy .
*/
iopw - > previous = iopw - > current ;
}
if ( iopw - > previous . count < iopw - > current . count ) {
struct AuthenticationInformationArray * c = & iopw - > current ;
struct AuthenticationInformationArray * p = & iopw - > previous ;
/*
* The previous array needs to have the same size
* as the current one .
*
* We may have to fill with TRUST_AUTH_TYPE_NONE
* elements .
*/
p - > array = talloc_realloc ( mem_ctx , p - > array ,
struct AuthenticationInformation ,
c - > count ) ;
if ( p - > array = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
while ( p - > count < c - > count ) {
struct AuthenticationInformation * a =
& p - > array [ p - > count + + ] ;
* a = ( struct AuthenticationInformation ) {
. LastUpdateTime = p - > array [ 0 ] . LastUpdateTime ,
. AuthType = TRUST_AUTH_TYPE_NONE ,
} ;
}
}
2012-03-02 16:18:16 +02:00
ndr_err = ndr_push_struct_blob ( trustauth_blob , mem_ctx ,
iopw ,
( 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 ;
}
2009-07-16 02:27:17 +02:00
/***************************************************************************
_lsa_CreateTrustedDomainEx2
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS _lsa_CreateTrustedDomainEx2 ( struct pipes_struct * p ,
struct lsa_CreateTrustedDomainEx2 * r )
{
struct lsa_info * policy ;
NTSTATUS status ;
uint32_t acc_granted ;
struct security_descriptor * psd ;
size_t sd_size ;
2010-08-17 17:20:57 +02:00
struct pdb_trusted_domain td ;
2010-08-26 14:44:04 +02:00
struct trustDomainPasswords auth_struct ;
DATA_BLOB auth_blob ;
2009-07-16 02:27:17 +02:00
if ( ! IS_DC ) {
return NT_STATUS_NOT_SUPPORTED ;
}
if ( ! find_policy_by_hnd ( p , r - > in . policy_handle , ( void * * ) ( void * ) & policy ) ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( ! ( policy - > access & LSA_POLICY_TRUST_ADMIN ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
2011-07-15 14:59:14 +10:00
if ( p - > session_info - > unix_token - > uid ! = sec_initial_uid ( ) & &
2011-02-21 10:25:52 +01:00
! nt_token_check_domain_rid ( p - > session_info - > security_token , DOMAIN_RID_ADMINS ) ) {
2009-07-16 02:27:17 +02:00
return NT_STATUS_ACCESS_DENIED ;
}
/* Work out max allowed. */
2011-02-21 10:25:52 +01:00
map_max_allowed_access ( p - > session_info - > security_token ,
2011-07-15 14:59:14 +10:00
p - > session_info - > unix_token ,
2009-07-16 02:27:17 +02:00
& r - > in . access_mask ) ;
/* map the generic bits to the lsa policy ones */
se_map_generic ( & r - > in . access_mask , & lsa_account_mapping ) ;
status = make_lsa_object_sd ( p - > mem_ctx , & psd , & sd_size ,
& lsa_trusted_domain_mapping ,
NULL , 0 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2011-02-21 10:25:52 +01:00
status = access_check_object ( psd , p - > session_info - > security_token ,
2009-07-16 02:27:17 +02:00
SEC_PRIV_INVALID , SEC_PRIV_INVALID , 0 ,
r - > in . access_mask , & acc_granted ,
" _lsa_CreateTrustedDomainEx2 " ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2010-08-17 17:20:57 +02:00
ZERO_STRUCT ( td ) ;
2010-08-26 14:44:04 +02:00
td . domain_name = talloc_strdup ( p - > mem_ctx ,
r - > in . info - > domain_name . string ) ;
if ( td . domain_name = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
td . netbios_name = talloc_strdup ( p - > mem_ctx ,
r - > in . info - > netbios_name . string ) ;
if ( td . netbios_name = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2010-08-17 17:20:57 +02:00
sid_copy ( & td . security_identifier , r - > in . info - > sid ) ;
td . trust_direction = r - > in . info - > trust_direction ;
td . trust_type = r - > in . info - > trust_type ;
td . trust_attributes = r - > in . info - > trust_attributes ;
2011-07-15 17:26:16 +02:00
if ( r - > in . auth_info_internal - > auth_blob . size ! = 0 ) {
auth_blob . length = r - > in . auth_info_internal - > auth_blob . size ;
auth_blob . data = r - > in . auth_info_internal - > auth_blob . data ;
2010-08-26 14:44:04 +02:00
2012-03-02 16:18:16 +02:00
status = get_trustdom_auth_blob ( p , p - > mem_ctx , & auth_blob , & auth_struct ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-08-26 14:44:04 +02:00
return NT_STATUS_UNSUCCESSFUL ;
}
2012-03-02 16:18:16 +02:00
status = get_trustauth_inout_blob ( p - > mem_ctx , & auth_struct . incoming , & td . trust_auth_incoming ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-08-26 14:44:04 +02:00
return NT_STATUS_UNSUCCESSFUL ;
}
2012-03-02 16:18:16 +02:00
status = get_trustauth_inout_blob ( p - > mem_ctx , & auth_struct . outgoing , & td . trust_auth_outgoing ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-08-26 14:44:04 +02:00
return NT_STATUS_UNSUCCESSFUL ;
}
} else {
td . trust_auth_incoming . data = NULL ;
td . trust_auth_incoming . length = 0 ;
td . trust_auth_outgoing . data = NULL ;
td . trust_auth_outgoing . length = 0 ;
}
2010-08-17 17:20:57 +02:00
status = pdb_set_trusted_domain ( r - > in . info - > domain_name . string , & td ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2009-07-16 02:27:17 +02:00
}
status = create_lsa_policy_handle ( p - > mem_ctx , p ,
LSA_HANDLE_TRUST_TYPE ,
acc_granted ,
r - > in . info - > sid ,
r - > in . info - > netbios_name . string ,
psd ,
r - > out . trustdom_handle ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-06-03 15:31:40 +02:00
pdb_del_trusted_domain ( r - > in . info - > netbios_name . string ) ;
2009-07-16 02:27:17 +02:00
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
return NT_STATUS_OK ;
}
2009-10-27 00:15:56 +01:00
/***************************************************************************
_lsa_CreateTrustedDomainEx
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS _lsa_CreateTrustedDomainEx ( struct pipes_struct * p ,
struct lsa_CreateTrustedDomainEx * r )
{
struct lsa_CreateTrustedDomainEx2 q ;
2011-07-15 11:18:00 +02:00
struct lsa_TrustDomainInfoAuthInfoInternal auth_info ;
ZERO_STRUCT ( auth_info ) ;
2009-10-27 00:15:56 +01:00
q . in . policy_handle = r - > in . policy_handle ;
q . in . info = r - > in . info ;
2011-07-15 11:18:00 +02:00
q . in . auth_info_internal = & auth_info ;
2009-10-27 00:15:56 +01:00
q . in . access_mask = r - > in . access_mask ;
q . out . trustdom_handle = r - > out . trustdom_handle ;
return _lsa_CreateTrustedDomainEx2 ( p , & q ) ;
}
2005-05-31 13:46:45 +00:00
/***************************************************************************
2009-07-16 14:34:06 +02:00
_lsa_CreateTrustedDomain
2005-05-31 13:46:45 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_CreateTrustedDomain ( struct pipes_struct * p ,
struct lsa_CreateTrustedDomain * r )
2005-05-31 13:46:45 +00:00
{
2009-07-16 14:34:06 +02:00
struct lsa_CreateTrustedDomainEx2 c ;
struct lsa_TrustDomainInfoInfoEx info ;
struct lsa_TrustDomainInfoAuthInfoInternal auth_info ;
ZERO_STRUCT ( auth_info ) ;
info . domain_name = r - > in . info - > name ;
info . netbios_name = r - > in . info - > name ;
info . sid = r - > in . info - > sid ;
info . trust_direction = LSA_TRUST_DIRECTION_OUTBOUND ;
info . trust_type = LSA_TRUST_TYPE_DOWNLEVEL ;
info . trust_attributes = 0 ;
c . in . policy_handle = r - > in . policy_handle ;
c . in . info = & info ;
2011-07-15 17:26:16 +02:00
c . in . auth_info_internal = & auth_info ;
2009-07-16 14:34:06 +02:00
c . in . access_mask = r - > in . access_mask ;
c . out . trustdom_handle = r - > out . trustdom_handle ;
return _lsa_CreateTrustedDomainEx2 ( p , & c ) ;
2005-05-31 13:46:45 +00:00
}
2009-07-16 02:27:51 +02:00
/***************************************************************************
_lsa_DeleteTrustedDomain
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS _lsa_DeleteTrustedDomain ( struct pipes_struct * p ,
struct lsa_DeleteTrustedDomain * r )
{
NTSTATUS status ;
struct lsa_info * handle ;
2010-08-30 18:09:12 +02:00
struct pdb_trusted_domain * td ;
2009-07-16 02:27:51 +02:00
/* find the connection policy handle. */
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & handle ) ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( handle - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( ! ( handle - > access & LSA_POLICY_TRUST_ADMIN ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
2010-08-30 18:09:12 +02:00
status = pdb_get_trusted_domain_by_sid ( p - > mem_ctx , r - > in . dom_sid , & td ) ;
2009-07-16 02:27:51 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2010-08-30 18:09:12 +02:00
if ( td - > netbios_name = = NULL | | * td - > netbios_name = = ' \0 ' ) {
2018-12-08 15:27:24 +01:00
struct dom_sid_buf buf ;
2010-08-30 18:09:12 +02:00
DEBUG ( 10 , ( " Missing netbios name for for trusted domain %s. \n " ,
2018-12-08 15:27:24 +01:00
dom_sid_str_buf ( r - > in . dom_sid , & buf ) ) ) ;
2010-08-30 18:09:12 +02:00
return NT_STATUS_UNSUCCESSFUL ;
}
status = pdb_del_trusted_domain ( td - > netbios_name ) ;
2010-08-20 09:28:29 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2009-07-16 02:27:51 +02:00
}
return NT_STATUS_OK ;
}
2009-10-29 16:15:22 +01:00
/***************************************************************************
_lsa_CloseTrustedDomainEx
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS _lsa_CloseTrustedDomainEx ( struct pipes_struct * p ,
struct lsa_CloseTrustedDomainEx * r )
{
return NT_STATUS_NOT_IMPLEMENTED ;
}
2009-07-16 03:00:13 +02:00
/***************************************************************************
_lsa_QueryTrustedDomainInfo
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-06 16:06:54 +02:00
static NTSTATUS pdb_trusted_domain_2_info_ex ( TALLOC_CTX * mem_ctx ,
struct pdb_trusted_domain * td ,
struct lsa_TrustDomainInfoInfoEx * info_ex )
{
if ( td - > domain_name = = NULL | |
td - > netbios_name = = NULL | |
is_null_sid ( & td - > security_identifier ) ) {
return NT_STATUS_INVALID_PARAMETER ;
}
info_ex - > domain_name . string = talloc_strdup ( mem_ctx , td - > domain_name ) ;
info_ex - > netbios_name . string = talloc_strdup ( mem_ctx , td - > netbios_name ) ;
info_ex - > sid = dom_sid_dup ( mem_ctx , & td - > security_identifier ) ;
if ( info_ex - > domain_name . string = = NULL | |
info_ex - > netbios_name . string = = NULL | |
info_ex - > sid = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
info_ex - > trust_direction = td - > trust_direction ;
info_ex - > trust_type = td - > trust_type ;
info_ex - > trust_attributes = td - > trust_attributes ;
return NT_STATUS_OK ;
}
2009-07-16 03:00:13 +02:00
NTSTATUS _lsa_QueryTrustedDomainInfo ( struct pipes_struct * p ,
struct lsa_QueryTrustedDomainInfo * r )
{
NTSTATUS status ;
struct lsa_info * handle ;
union lsa_TrustedDomainInfo * info ;
2010-08-24 18:18:00 +02:00
struct pdb_trusted_domain * td ;
2009-07-16 03:00:13 +02:00
uint32_t acc_required ;
/* find the connection policy handle. */
if ( ! find_policy_by_hnd ( p , r - > in . trustdom_handle , ( void * * ) ( void * ) & handle ) ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( handle - > type ! = LSA_HANDLE_TRUST_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
switch ( r - > in . level ) {
case LSA_TRUSTED_DOMAIN_INFO_NAME :
acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS :
acc_required = LSA_TRUSTED_QUERY_CONTROLLERS ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET :
acc_required = LSA_TRUSTED_QUERY_POSIX ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_PASSWORD :
acc_required = LSA_TRUSTED_QUERY_AUTH ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_BASIC :
acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_INFO_EX :
acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO :
acc_required = LSA_TRUSTED_QUERY_AUTH ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO :
acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
LSA_TRUSTED_QUERY_POSIX |
LSA_TRUSTED_QUERY_AUTH ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL :
acc_required = LSA_TRUSTED_QUERY_AUTH ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL :
acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
LSA_TRUSTED_QUERY_POSIX |
LSA_TRUSTED_QUERY_AUTH ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL :
acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL :
acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
LSA_TRUSTED_QUERY_POSIX |
LSA_TRUSTED_QUERY_AUTH ;
break ;
case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES :
acc_required = LSA_TRUSTED_QUERY_POSIX ;
break ;
default :
return NT_STATUS_INVALID_PARAMETER ;
}
if ( ! ( handle - > access & acc_required ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
2010-08-24 18:18:00 +02:00
status = pdb_get_trusted_domain_by_sid ( p - > mem_ctx , & handle - > sid , & td ) ;
2009-07-16 03:00:13 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2011-06-07 11:44:43 +10:00
info = talloc_zero ( p - > mem_ctx , union lsa_TrustedDomainInfo ) ;
2009-07-16 03:00:13 +02:00
if ( ! info ) {
return NT_STATUS_NO_MEMORY ;
}
switch ( r - > in . level ) {
case LSA_TRUSTED_DOMAIN_INFO_NAME :
2010-08-24 18:18:00 +02:00
init_lsa_StringLarge ( & info - > name . netbios_name , td - > netbios_name ) ;
2009-07-16 03:00:13 +02:00
break ;
case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS :
return NT_STATUS_INVALID_PARAMETER ;
case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET :
2011-07-06 16:06:54 +02:00
info - > posix_offset . posix_offset = * td - > trust_posix_offset ;
2009-07-16 03:00:13 +02:00
break ;
case LSA_TRUSTED_DOMAIN_INFO_PASSWORD :
return NT_STATUS_INVALID_INFO_CLASS ;
case LSA_TRUSTED_DOMAIN_INFO_BASIC :
2010-08-24 18:16:06 +02:00
return NT_STATUS_INVALID_PARAMETER ;
2009-07-16 03:00:13 +02:00
case LSA_TRUSTED_DOMAIN_INFO_INFO_EX :
2011-07-06 16:06:54 +02:00
status = pdb_trusted_domain_2_info_ex ( info , td , & info - > info_ex ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2009-07-16 03:00:13 +02:00
}
break ;
case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO :
return NT_STATUS_INVALID_INFO_CLASS ;
case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO :
2011-07-06 16:06:54 +02:00
status = pdb_trusted_domain_2_info_ex ( info , td ,
& info - > full_info . info_ex ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
info - > full_info . posix_offset . posix_offset = * td - > trust_posix_offset ;
2011-09-01 18:18:31 +02:00
status = auth_blob_2_auth_info ( p - > mem_ctx ,
td - > trust_auth_incoming ,
td - > trust_auth_outgoing ,
2011-07-06 16:06:54 +02:00
& info - > full_info . auth_info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2009-07-16 03:00:13 +02:00
break ;
case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL :
return NT_STATUS_INVALID_INFO_CLASS ;
case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL :
return NT_STATUS_INVALID_INFO_CLASS ;
case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL :
return NT_STATUS_INVALID_PARAMETER ;
case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL :
2011-07-06 16:06:54 +02:00
info - > full_info2_internal . posix_offset . posix_offset = * td - > trust_posix_offset ;
2011-09-01 18:18:31 +02:00
status = auth_blob_2_auth_info ( p - > mem_ctx ,
td - > trust_auth_incoming ,
td - > trust_auth_outgoing ,
2011-07-06 16:06:54 +02:00
& info - > full_info2_internal . auth_info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2009-07-16 03:00:13 +02:00
break ;
case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES :
2011-07-06 16:06:54 +02:00
info - > enc_types . enc_types = * td - > supported_enc_type ;
2009-07-16 03:00:13 +02:00
break ;
default :
return NT_STATUS_INVALID_PARAMETER ;
}
* r - > out . info = info ;
return NT_STATUS_OK ;
}
2009-10-20 12:48:30 +02:00
/***************************************************************************
_lsa_QueryTrustedDomainInfoBySid
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS _lsa_QueryTrustedDomainInfoBySid ( struct pipes_struct * p ,
struct lsa_QueryTrustedDomainInfoBySid * r )
{
NTSTATUS status ;
struct policy_handle trustdom_handle ;
struct lsa_OpenTrustedDomain o ;
struct lsa_QueryTrustedDomainInfo q ;
struct lsa_Close c ;
o . in . handle = r - > in . handle ;
o . in . sid = r - > in . dom_sid ;
o . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
o . out . trustdom_handle = & trustdom_handle ;
status = _lsa_OpenTrustedDomain ( p , & o ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
q . in . trustdom_handle = & trustdom_handle ;
q . in . level = r - > in . level ;
q . out . info = r - > out . info ;
status = _lsa_QueryTrustedDomainInfo ( p , & q ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
c . in . handle = & trustdom_handle ;
c . out . handle = & trustdom_handle ;
return _lsa_Close ( p , & c ) ;
}
2009-10-20 12:50:33 +02:00
/***************************************************************************
_lsa_QueryTrustedDomainInfoByName
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS _lsa_QueryTrustedDomainInfoByName ( struct pipes_struct * p ,
struct lsa_QueryTrustedDomainInfoByName * r )
{
NTSTATUS status ;
struct policy_handle trustdom_handle ;
struct lsa_OpenTrustedDomainByName o ;
struct lsa_QueryTrustedDomainInfo q ;
struct lsa_Close c ;
o . in . handle = r - > in . handle ;
o . in . name . string = r - > in . trusted_domain - > string ;
o . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
o . out . trustdom_handle = & trustdom_handle ;
status = _lsa_OpenTrustedDomainByName ( p , & o ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-08-30 15:57:36 +02:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_NO_SUCH_DOMAIN ) ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
2009-10-20 12:50:33 +02:00
return status ;
}
q . in . trustdom_handle = & trustdom_handle ;
q . in . level = r - > in . level ;
q . out . info = r - > out . info ;
status = _lsa_QueryTrustedDomainInfo ( p , & q ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
c . in . handle = & trustdom_handle ;
c . out . handle = & trustdom_handle ;
return _lsa_Close ( p , & c ) ;
}
2005-05-31 13:46:45 +00:00
/***************************************************************************
2009-10-29 23:59:57 +01:00
_lsa_CreateSecret
2005-05-31 13:46:45 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-10-29 23:59:57 +01:00
NTSTATUS _lsa_CreateSecret ( struct pipes_struct * p ,
struct lsa_CreateSecret * r )
2005-05-31 13:46:45 +00:00
{
2009-10-29 23:59:57 +01:00
NTSTATUS status ;
struct lsa_info * handle ;
uint32_t acc_granted ;
struct security_descriptor * psd ;
size_t sd_size ;
/* find the connection policy handle. */
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & handle ) ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( handle - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
/* check if the user has enough rights */
if ( ! ( handle - > access & LSA_POLICY_CREATE_SECRET ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
/* Work out max allowed. */
map_max_allowed_access ( p - > session_info - > security_token ,
p - > session_info - > unix_token ,
& r - > in . access_mask ) ;
/* map the generic bits to the lsa policy ones */
se_map_generic ( & r - > in . access_mask , & lsa_secret_mapping ) ;
status = make_lsa_object_sd ( p - > mem_ctx , & psd , & sd_size ,
& lsa_secret_mapping ,
NULL , 0 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
status = access_check_object ( psd , p - > session_info - > security_token ,
SEC_PRIV_INVALID , SEC_PRIV_INVALID , 0 ,
r - > in . access_mask ,
& acc_granted , " _lsa_CreateSecret " ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
if ( ! r - > in . name . string ) {
return NT_STATUS_INVALID_PARAMETER ;
}
if ( strlen ( r - > in . name . string ) > 128 ) {
return NT_STATUS_NAME_TOO_LONG ;
}
status = pdb_get_secret ( p - > mem_ctx , r - > in . name . string ,
NULL , NULL , NULL , NULL , NULL ) ;
if ( NT_STATUS_IS_OK ( status ) ) {
return NT_STATUS_OBJECT_NAME_COLLISION ;
}
status = pdb_set_secret ( r - > in . name . string , NULL , NULL , psd ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
status = create_lsa_policy_handle ( p - > mem_ctx , p ,
LSA_HANDLE_SECRET_TYPE ,
acc_granted ,
NULL ,
r - > in . name . string ,
psd ,
r - > out . sec_handle ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
return NT_STATUS_OK ;
2005-05-31 13:46:45 +00:00
}
/***************************************************************************
2009-10-30 00:03:21 +01:00
_lsa_SetSecret
2005-05-31 13:46:45 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-10-30 00:03:21 +01:00
NTSTATUS _lsa_SetSecret ( struct pipes_struct * p ,
struct lsa_SetSecret * r )
2005-05-31 13:46:45 +00:00
{
2009-10-30 00:03:21 +01:00
NTSTATUS status ;
struct lsa_info * info = NULL ;
DATA_BLOB blob_new , blob_old ;
DATA_BLOB cleartext_blob_new = data_blob_null ;
DATA_BLOB cleartext_blob_old = data_blob_null ;
DATA_BLOB * cleartext_blob_new_p = NULL ;
DATA_BLOB * cleartext_blob_old_p = NULL ;
2012-03-02 16:18:16 +02:00
DATA_BLOB session_key ;
2009-10-30 00:03:21 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . sec_handle , ( void * * ) ( void * ) & info ) ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( info - > type ! = LSA_HANDLE_SECRET_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( ! ( info - > access & LSA_SECRET_SET_VALUE ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
2012-03-02 16:18:16 +02:00
status = session_extract_session_key ( p - > session_info , & session_key , KEY_USE_16BYTES ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2009-10-30 00:03:21 +01:00
if ( r - > in . new_val ) {
blob_new = data_blob_const ( r - > in . new_val - > data ,
r - > in . new_val - > length ) ;
status = sess_decrypt_blob ( p - > mem_ctx , & blob_new ,
2012-03-02 16:18:16 +02:00
& session_key ,
2009-10-30 00:03:21 +01:00
& cleartext_blob_new ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
cleartext_blob_new_p = & cleartext_blob_new ;
}
if ( r - > in . old_val ) {
blob_old = data_blob_const ( r - > in . old_val - > data ,
r - > in . old_val - > length ) ;
status = sess_decrypt_blob ( p - > mem_ctx , & blob_old ,
2012-03-02 16:18:16 +02:00
& session_key ,
2009-10-30 00:03:21 +01:00
& cleartext_blob_old ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
cleartext_blob_old_p = & cleartext_blob_old ;
}
status = pdb_set_secret ( info - > name , cleartext_blob_new_p , cleartext_blob_old_p , NULL ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
# ifdef DEBUG_PASSWORD
DEBUG ( 10 , ( " _lsa_SetSecret: successfully set new secret \n " ) ) ;
dump_data ( 10 , cleartext_blob_new . data , cleartext_blob_new . length ) ;
DEBUG ( 10 , ( " _lsa_SetSecret: successfully set old secret \n " ) ) ;
dump_data ( 10 , cleartext_blob_old . data , cleartext_blob_old . length ) ;
# endif
return NT_STATUS_OK ;
2005-05-31 13:46:45 +00:00
}
2009-10-30 00:04:09 +01:00
/***************************************************************************
_lsa_QuerySecret
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS _lsa_QuerySecret ( struct pipes_struct * p ,
struct lsa_QuerySecret * r )
{
struct lsa_info * info = NULL ;
DATA_BLOB blob_new , blob_old ;
DATA_BLOB blob_new_crypt , blob_old_crypt ;
2012-03-02 16:18:16 +02:00
DATA_BLOB session_key ;
2009-10-30 00:04:09 +01:00
NTTIME nttime_new , nttime_old ;
NTSTATUS status ;
if ( ! find_policy_by_hnd ( p , r - > in . sec_handle , ( void * * ) ( void * ) & info ) ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( info - > type ! = LSA_HANDLE_SECRET_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( ! ( info - > access & LSA_SECRET_QUERY_VALUE ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
status = pdb_get_secret ( p - > mem_ctx , info - > name ,
& blob_new , & nttime_new ,
& blob_old , & nttime_old ,
NULL ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2012-03-02 16:18:16 +02:00
status = session_extract_session_key ( p - > session_info , & session_key , KEY_USE_16BYTES ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2009-10-30 00:04:09 +01:00
if ( r - > in . new_val ) {
if ( blob_new . length ) {
if ( ! r - > out . new_val - > buf ) {
r - > out . new_val - > buf = talloc_zero ( p - > mem_ctx , struct lsa_DATA_BUF ) ;
}
if ( ! r - > out . new_val - > buf ) {
return NT_STATUS_NO_MEMORY ;
}
blob_new_crypt = sess_encrypt_blob ( p - > mem_ctx , & blob_new ,
2012-03-02 16:18:16 +02:00
& session_key ) ;
2009-10-30 00:04:09 +01:00
if ( ! blob_new_crypt . length ) {
return NT_STATUS_NO_MEMORY ;
}
r - > out . new_val - > buf - > data = blob_new_crypt . data ;
r - > out . new_val - > buf - > length = blob_new_crypt . length ;
r - > out . new_val - > buf - > size = blob_new_crypt . length ;
}
}
if ( r - > in . old_val ) {
if ( blob_old . length ) {
if ( ! r - > out . old_val - > buf ) {
r - > out . old_val - > buf = talloc_zero ( p - > mem_ctx , struct lsa_DATA_BUF ) ;
}
if ( ! r - > out . old_val - > buf ) {
return NT_STATUS_NO_MEMORY ;
}
blob_old_crypt = sess_encrypt_blob ( p - > mem_ctx , & blob_old ,
2012-03-02 16:18:16 +02:00
& session_key ) ;
2009-10-30 00:04:09 +01:00
if ( ! blob_old_crypt . length ) {
return NT_STATUS_NO_MEMORY ;
}
r - > out . old_val - > buf - > data = blob_old_crypt . data ;
r - > out . old_val - > buf - > length = blob_old_crypt . length ;
r - > out . old_val - > buf - > size = blob_old_crypt . length ;
}
}
if ( r - > out . new_mtime ) {
* r - > out . new_mtime = nttime_new ;
}
if ( r - > out . old_mtime ) {
* r - > out . old_mtime = nttime_old ;
}
return NT_STATUS_OK ;
}
2005-05-31 13:46:45 +00:00
/***************************************************************************
2008-02-04 22:05:48 +01:00
_lsa_DeleteObject
2005-05-31 13:46:45 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_DeleteObject ( struct pipes_struct * p ,
2008-02-04 22:05:48 +01:00
struct lsa_DeleteObject * r )
2005-05-31 13:46:45 +00:00
{
2009-05-18 21:00:29 +02:00
NTSTATUS status ;
struct lsa_info * info = NULL ;
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & info ) ) {
return NT_STATUS_INVALID_HANDLE ;
}
2010-06-03 10:36:05 +02:00
if ( ! ( info - > access & SEC_STD_DELETE ) ) {
2009-05-18 21:00:29 +02:00
return NT_STATUS_ACCESS_DENIED ;
}
2009-07-17 13:44:55 +02:00
switch ( info - > type ) {
case LSA_HANDLE_ACCOUNT_TYPE :
status = privilege_delete_account ( & info - > sid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " _lsa_DeleteObject: privilege_delete_account gave: %s \n " ,
nt_errstr ( status ) ) ) ;
return status ;
}
break ;
2009-07-16 14:32:18 +02:00
case LSA_HANDLE_TRUST_TYPE :
if ( ! pdb_del_trusteddom_pw ( info - > name ) ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
status = NT_STATUS_OK ;
break ;
2009-10-30 00:05:07 +01:00
case LSA_HANDLE_SECRET_TYPE :
status = pdb_delete_secret ( info - > name ) ;
if ( NT_STATUS_EQUAL ( status , NT_STATUS_OBJECT_NAME_NOT_FOUND ) ) {
return NT_STATUS_INVALID_HANDLE ;
}
break ;
2009-07-17 13:44:55 +02:00
default :
return NT_STATUS_INVALID_HANDLE ;
2009-05-18 21:00:29 +02:00
}
2009-07-17 13:44:55 +02:00
close_policy_hnd ( p , r - > in . handle ) ;
ZERO_STRUCTP ( r - > out . handle ) ;
2009-05-18 21:00:29 +02:00
return status ;
2005-05-31 13:46:45 +00:00
}
2001-07-09 18:32:54 +00:00
/***************************************************************************
2008-02-11 10:19:54 +01:00
_lsa_EnumPrivs
2001-07-09 18:32:54 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_EnumPrivs ( struct pipes_struct * p ,
2008-02-11 10:19:54 +01:00
struct lsa_EnumPrivs * r )
2001-07-09 18:32:54 +00:00
{
2001-12-17 23:03:23 +00:00
struct lsa_info * handle ;
2015-05-14 18:08:27 -07:00
uint32_t i ;
uint32_t enum_context = * r - > in . resume_handle ;
2010-08-27 11:52:51 +10:00
int num_privs = num_privileges_in_short_list ( ) ;
2008-02-11 10:19:54 +01:00
struct lsa_PrivEntry * entries = NULL ;
2001-07-09 18:32:54 +00:00
2005-01-13 18:20:37 +00:00
/* remember that the enum_context starts at 0 and not 1 */
2001-07-09 18:32:54 +00:00
2005-01-13 18:20:37 +00:00
if ( enum_context > = num_privs )
2002-03-29 20:37:56 +00:00
return NT_STATUS_NO_MORE_ENTRIES ;
2008-02-14 01:53:42 +01:00
DEBUG ( 10 , ( " _lsa_EnumPrivs: enum_context:%d total entries:%d \n " ,
2005-01-13 18:20:37 +00:00
enum_context , num_privs ) ) ;
2008-02-14 01:53:42 +01:00
2008-02-11 10:19:54 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & handle ) )
2001-07-09 18:32:54 +00:00
return NT_STATUS_INVALID_HANDLE ;
2009-05-20 11:52:11 -07:00
if ( handle - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
2008-07-18 15:31:36 +02:00
/* check if the user has enough rights
2005-01-13 18:20:37 +00:00
I don ' t know if it ' s the right one . not documented . */
2001-12-17 23:03:23 +00:00
2008-02-27 15:49:31 +01:00
if ( ! ( handle - > access & LSA_POLICY_VIEW_LOCAL_INFORMATION ) )
2001-12-17 23:03:23 +00:00
return NT_STATUS_ACCESS_DENIED ;
2007-04-30 01:17:34 +00:00
if ( num_privs ) {
2011-06-07 11:58:39 +10:00
entries = talloc_zero_array ( p - > mem_ctx , struct lsa_PrivEntry , num_privs ) ;
2008-02-11 10:19:54 +01:00
if ( ! entries ) {
2007-04-30 01:17:34 +00:00
return NT_STATUS_NO_MEMORY ;
2008-02-11 10:19:54 +01:00
}
2007-04-30 01:17:34 +00:00
} else {
entries = NULL ;
}
2005-01-13 18:20:37 +00:00
for ( i = 0 ; i < num_privs ; i + + ) {
if ( i < enum_context ) {
2008-02-11 10:19:54 +01:00
init_lsa_StringLarge ( & entries [ i ] . name , NULL ) ;
entries [ i ] . luid . low = 0 ;
entries [ i ] . luid . high = 0 ;
2001-11-22 23:50:16 +00:00
} else {
2008-02-11 10:19:54 +01:00
2010-08-27 12:19:09 +10:00
init_lsa_StringLarge ( & entries [ i ] . name , sec_privilege_name_from_index ( i ) ) ;
2008-02-11 10:19:54 +01:00
2010-08-27 12:19:09 +10:00
entries [ i ] . luid . low = sec_privilege_from_index ( i ) ;
2010-08-27 11:27:57 +10:00
entries [ i ] . luid . high = 0 ;
2001-11-22 23:50:16 +00:00
}
2001-07-09 18:32:54 +00:00
}
2005-01-13 18:20:37 +00:00
enum_context = num_privs ;
2008-02-11 10:19:54 +01:00
* r - > out . resume_handle = enum_context ;
r - > out . privs - > count = num_privs ;
r - > out . privs - > privs = entries ;
2001-07-09 18:32:54 +00:00
2001-08-27 19:46:22 +00:00
return NT_STATUS_OK ;
2001-07-09 18:32:54 +00:00
}
/***************************************************************************
2008-02-11 11:57:29 +01:00
_lsa_LookupPrivDisplayName
2001-07-09 18:32:54 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_LookupPrivDisplayName ( struct pipes_struct * p ,
2008-02-11 11:57:29 +01:00
struct lsa_LookupPrivDisplayName * r )
2001-07-09 18:32:54 +00:00
{
2001-12-17 23:03:23 +00:00
struct lsa_info * handle ;
2005-01-17 15:23:11 +00:00
const char * description ;
2008-02-11 11:57:29 +01:00
struct lsa_StringLarge * lsa_name ;
2001-07-09 18:32:54 +00:00
2008-02-11 11:57:29 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & handle ) )
2001-07-09 18:32:54 +00:00
return NT_STATUS_INVALID_HANDLE ;
2009-05-20 11:52:11 -07:00
if ( handle - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
2008-07-18 15:31:36 +02:00
/* check if the user has enough rights */
2001-12-17 23:03:23 +00:00
/*
* I don ' t know if it ' s the right one . not documented .
*/
2008-02-27 15:49:31 +01:00
if ( ! ( handle - > access & LSA_POLICY_VIEW_LOCAL_INFORMATION ) )
2001-12-17 23:03:23 +00:00
return NT_STATUS_ACCESS_DENIED ;
2008-02-11 11:57:29 +01:00
DEBUG ( 10 , ( " _lsa_LookupPrivDisplayName: name = %s \n " , r - > in . name - > string ) ) ;
2001-07-09 18:32:54 +00:00
2008-02-11 11:57:29 +01:00
description = get_privilege_dispname ( r - > in . name - > string ) ;
if ( ! description ) {
DEBUG ( 10 , ( " _lsa_LookupPrivDisplayName: doesn't exist \n " ) ) ;
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
2001-07-09 18:32:54 +00:00
2008-02-11 11:57:29 +01:00
DEBUG ( 10 , ( " _lsa_LookupPrivDisplayName: display name = %s \n " , description ) ) ;
2001-07-09 18:32:54 +00:00
2011-06-07 11:44:43 +10:00
lsa_name = talloc_zero ( p - > mem_ctx , struct lsa_StringLarge ) ;
2008-02-11 11:57:29 +01:00
if ( ! lsa_name ) {
return NT_STATUS_NO_MEMORY ;
2001-11-22 17:19:59 +00:00
}
2008-02-11 11:57:29 +01:00
init_lsa_StringLarge ( lsa_name , description ) ;
* r - > out . returned_language_id = r - > in . language_id ;
* r - > out . disp_name = lsa_name ;
return NT_STATUS_OK ;
2001-07-09 18:32:54 +00:00
}
/***************************************************************************
2008-02-14 01:16:03 +01:00
_lsa_EnumAccounts
2001-07-09 18:32:54 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_EnumAccounts ( struct pipes_struct * p ,
2008-02-14 01:16:03 +01:00
struct lsa_EnumAccounts * r )
2001-07-09 18:32:54 +00:00
{
2001-12-17 23:03:23 +00:00
struct lsa_info * handle ;
2010-05-21 11:25:01 +10:00
struct dom_sid * sid_list ;
2005-01-13 18:20:37 +00:00
int i , j , num_entries ;
2008-02-14 01:16:03 +01:00
NTSTATUS status ;
struct lsa_SidPtr * sids = NULL ;
2001-07-09 18:32:54 +00:00
2008-02-14 01:16:03 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & handle ) )
2001-07-09 18:32:54 +00:00
return NT_STATUS_INVALID_HANDLE ;
2009-05-20 11:52:11 -07:00
if ( handle - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
2008-02-27 15:49:31 +01:00
if ( ! ( handle - > access & LSA_POLICY_VIEW_LOCAL_INFORMATION ) )
2001-12-17 23:03:23 +00:00
return NT_STATUS_ACCESS_DENIED ;
2005-01-13 18:20:37 +00:00
sid_list = NULL ;
num_entries = 0 ;
/* The only way we can currently find out all the SIDs that have been
privileged is to scan all privileges */
2008-02-14 01:16:03 +01:00
status = privilege_enumerate_accounts ( & sid_list , & num_entries ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2003-11-24 17:31:38 +00:00
}
2001-07-09 18:32:54 +00:00
2008-02-14 01:16:03 +01:00
if ( * r - > in . resume_handle > = num_entries ) {
2001-11-23 15:11:22 +00:00
return NT_STATUS_NO_MORE_ENTRIES ;
2008-02-14 01:16:03 +01:00
}
2001-11-23 15:11:22 +00:00
2008-02-14 01:16:03 +01:00
if ( num_entries - * r - > in . resume_handle ) {
2011-06-07 11:58:39 +10:00
sids = talloc_zero_array ( p - > mem_ctx , struct lsa_SidPtr ,
2008-02-14 01:16:03 +01:00
num_entries - * r - > in . resume_handle ) ;
if ( ! sids ) {
2009-04-02 18:47:51 +02:00
talloc_free ( sid_list ) ;
2007-04-30 01:17:34 +00:00
return NT_STATUS_NO_MEMORY ;
}
2007-08-04 10:18:33 +00:00
2008-02-14 01:16:03 +01:00
for ( i = * r - > in . resume_handle , j = 0 ; i < num_entries ; i + + , j + + ) {
2010-08-26 17:21:39 +02:00
sids [ j ] . sid = dom_sid_dup ( p - > mem_ctx , & sid_list [ i ] ) ;
2008-02-14 01:16:03 +01:00
if ( ! sids [ j ] . sid ) {
2009-04-02 18:47:51 +02:00
talloc_free ( sid_list ) ;
2008-02-14 01:16:03 +01:00
return NT_STATUS_NO_MEMORY ;
}
2007-08-04 10:18:33 +00:00
}
2001-07-09 18:32:54 +00:00
}
2007-04-29 19:20:48 +00:00
talloc_free ( sid_list ) ;
2001-07-09 18:32:54 +00:00
2008-02-14 01:16:03 +01:00
* r - > out . resume_handle = num_entries ;
r - > out . sids - > num_sids = num_entries ;
r - > out . sids - > sids = sids ;
2001-07-09 18:32:54 +00:00
2001-08-27 19:46:22 +00:00
return NT_STATUS_OK ;
2001-07-09 18:32:54 +00:00
}
2008-02-11 20:29:31 +01:00
/***************************************************************************
_lsa_GetUserName
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-07-09 18:32:54 +00:00
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_GetUserName ( struct pipes_struct * p ,
2008-02-11 20:29:31 +01:00
struct lsa_GetUserName * r )
2001-06-29 23:12:55 +00:00
{
2006-07-15 17:55:01 +00:00
const char * username , * domname ;
2008-02-11 20:29:31 +01:00
struct lsa_String * account_name = NULL ;
struct lsa_String * authority_name = NULL ;
2012-06-25 18:45:35 +02:00
if ( p - > transport ! = NCACN_NP & & p - > transport ! = NCALRPC ) {
p - > fault_state = DCERPC_FAULT_ACCESS_DENIED ;
return NT_STATUS_ACCESS_DENIED ;
}
2008-10-21 01:19:49 +02:00
if ( r - > in . account_name & &
* r - > in . account_name ) {
return NT_STATUS_INVALID_PARAMETER ;
}
if ( r - > in . authority_name & &
* r - > in . authority_name ) {
return NT_STATUS_INVALID_PARAMETER ;
}
2011-07-19 11:57:05 +10:00
if ( security_session_user_level ( p - > session_info , NULL ) < SECURITY_USER ) {
2006-07-15 17:55:01 +00:00
/*
* I ' m 99 % sure this is not the right place to do this ,
* global_sid_Anonymous should probably be put into the token
* instead of the guest id - - vl
*/
if ( ! lookup_sid ( p - > mem_ctx , & global_sid_Anonymous ,
& domname , & username , NULL ) ) {
return NT_STATUS_NO_MEMORY ;
}
} else {
2011-07-15 15:55:31 +10:00
username = p - > session_info - > unix_info - > sanitized_username ;
2011-07-18 12:58:25 +10:00
domname = p - > session_info - > info - > domain_name ;
2006-07-15 17:55:01 +00:00
}
2001-06-29 23:12:55 +00:00
2011-06-07 11:38:41 +10:00
account_name = talloc ( p - > mem_ctx , struct lsa_String ) ;
2008-02-11 20:29:31 +01:00
if ( ! account_name ) {
return NT_STATUS_NO_MEMORY ;
}
2008-10-21 01:19:49 +02:00
init_lsa_String ( account_name , username ) ;
2001-06-29 23:12:55 +00:00
2008-10-21 01:19:49 +02:00
if ( r - > out . authority_name ) {
2011-06-07 11:38:41 +10:00
authority_name = talloc ( p - > mem_ctx , struct lsa_String ) ;
2008-10-21 01:19:49 +02:00
if ( ! authority_name ) {
return NT_STATUS_NO_MEMORY ;
}
init_lsa_String ( authority_name , domname ) ;
2008-02-11 20:29:31 +01:00
}
* r - > out . account_name = account_name ;
2008-10-21 01:19:49 +02:00
if ( r - > out . authority_name ) {
* r - > out . authority_name = authority_name ;
}
2008-02-11 20:29:31 +01:00
return NT_STATUS_OK ;
2001-06-29 23:12:55 +00:00
}
2001-07-09 18:32:54 +00:00
/***************************************************************************
2008-02-06 18:58:11 +01:00
_lsa_CreateAccount
2001-07-09 18:32:54 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_CreateAccount ( struct pipes_struct * p ,
2008-02-06 18:58:11 +01:00
struct lsa_CreateAccount * r )
2001-07-09 18:32:54 +00:00
{
2009-07-16 18:45:29 +02:00
NTSTATUS status ;
2001-12-17 23:03:23 +00:00
struct lsa_info * handle ;
2009-07-16 18:45:29 +02:00
uint32_t acc_granted ;
struct security_descriptor * psd ;
2009-07-25 13:21:57 -04:00
size_t sd_size ;
2012-04-17 12:30:15 -07:00
uint32_t owner_access = ( LSA_ACCOUNT_ALL_ACCESS &
~ ( LSA_ACCOUNT_ADJUST_PRIVILEGES |
LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS |
SEC_STD_DELETE ) ) ;
2001-07-09 18:32:54 +00:00
2005-01-13 18:20:37 +00:00
/* find the connection policy handle. */
2008-02-06 18:58:11 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & handle ) )
2005-01-13 18:20:37 +00:00
return NT_STATUS_INVALID_HANDLE ;
2009-05-20 11:52:11 -07:00
if ( handle - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
2008-07-18 15:31:36 +02:00
/* check if the user has enough rights */
2005-01-13 18:20:37 +00:00
2009-07-16 18:45:29 +02:00
if ( ! ( handle - > access & LSA_POLICY_CREATE_ACCOUNT ) ) {
2005-01-14 21:05:54 +00:00
return NT_STATUS_ACCESS_DENIED ;
2009-07-16 18:45:29 +02:00
}
2009-10-20 15:54:40 +02:00
/* Work out max allowed. */
2011-02-21 10:25:52 +01:00
map_max_allowed_access ( p - > session_info - > security_token ,
2011-07-15 14:59:14 +10:00
p - > session_info - > unix_token ,
2009-10-20 15:54:40 +02:00
& r - > in . access_mask ) ;
2009-07-16 18:45:29 +02:00
/* map the generic bits to the lsa policy ones */
se_map_generic ( & r - > in . access_mask , & lsa_account_mapping ) ;
status = make_lsa_object_sd ( p - > mem_ctx , & psd , & sd_size ,
& lsa_account_mapping ,
2012-04-17 12:30:15 -07:00
r - > in . sid , owner_access ) ;
2009-07-16 18:45:29 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2011-02-21 10:25:52 +01:00
status = access_check_object ( psd , p - > session_info - > security_token ,
2010-08-30 13:30:38 +10:00
SEC_PRIV_INVALID , SEC_PRIV_INVALID , 0 , r - > in . access_mask ,
2009-10-26 23:37:21 +01:00
& acc_granted , " _lsa_CreateAccount " ) ;
2009-07-16 18:45:29 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2008-02-14 13:12:28 +01:00
2008-02-06 18:58:11 +01:00
if ( is_privileged_sid ( r - > in . sid ) )
2005-01-18 18:29:28 +00:00
return NT_STATUS_OBJECT_NAME_COLLISION ;
2005-01-14 21:05:54 +00:00
2009-10-30 11:09:52 +01:00
status = create_lsa_policy_handle ( p - > mem_ctx , p ,
LSA_HANDLE_ACCOUNT_TYPE ,
acc_granted ,
r - > in . sid ,
NULL ,
psd ,
r - > out . acct_handle ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2005-01-13 18:20:37 +00:00
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
2009-10-30 11:09:52 +01:00
}
2005-01-13 18:20:37 +00:00
2009-10-30 11:09:52 +01:00
return privilege_create_account ( r - > in . sid ) ;
2005-01-13 18:20:37 +00:00
}
/***************************************************************************
2008-02-06 19:19:29 +01:00
_lsa_OpenAccount
2005-01-13 18:20:37 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_OpenAccount ( struct pipes_struct * p ,
2008-02-06 19:19:29 +01:00
struct lsa_OpenAccount * r )
2005-01-13 18:20:37 +00:00
{
struct lsa_info * handle ;
2010-05-18 10:29:34 +02:00
struct security_descriptor * psd = NULL ;
2009-05-20 11:52:11 -07:00
size_t sd_size ;
uint32_t des_access = r - > in . access_mask ;
uint32_t acc_granted ;
2012-04-17 12:30:15 -07:00
uint32_t owner_access = ( LSA_ACCOUNT_ALL_ACCESS &
~ ( LSA_ACCOUNT_ADJUST_PRIVILEGES |
LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS |
SEC_STD_DELETE ) ) ;
2009-05-20 11:52:11 -07:00
NTSTATUS status ;
2001-07-09 18:32:54 +00:00
/* find the connection policy handle. */
2008-02-06 19:19:29 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & handle ) )
2001-07-09 18:32:54 +00:00
return NT_STATUS_INVALID_HANDLE ;
2009-05-20 11:52:11 -07:00
if ( handle - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
2001-12-17 23:03:23 +00:00
2009-05-20 11:52:11 -07:00
/* des_access is for the account here, not the policy
2011-02-08 14:17:14 +01:00
* handle - so don ' t check against policy handle . */
2009-05-20 11:52:11 -07:00
/* Work out max allowed. */
2011-02-21 10:25:52 +01:00
map_max_allowed_access ( p - > session_info - > security_token ,
2011-07-15 14:59:14 +10:00
p - > session_info - > unix_token ,
2009-06-29 20:34:03 +02:00
& des_access ) ;
2009-05-20 11:52:11 -07:00
/* map the generic bits to the lsa account ones */
se_map_generic ( & des_access , & lsa_account_mapping ) ;
/* get the generic lsa account SD until we store it */
status = make_lsa_object_sd ( p - > mem_ctx , & psd , & sd_size ,
& lsa_account_mapping ,
2012-04-17 12:30:15 -07:00
r - > in . sid , owner_access ) ;
2009-05-20 11:52:11 -07:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2011-02-21 10:25:52 +01:00
status = access_check_object ( psd , p - > session_info - > security_token ,
2010-08-30 13:30:38 +10:00
SEC_PRIV_INVALID , SEC_PRIV_INVALID , 0 , des_access ,
2009-10-26 23:37:21 +01:00
& acc_granted , " _lsa_OpenAccount " ) ;
2009-05-20 11:52:11 -07:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2001-12-17 23:03:23 +00:00
2005-01-13 18:20:37 +00:00
/* TODO: Fis the parsing routine before reenabling this check! */
#if 0
if ( ! lookup_sid ( & handle - > sid , dom_name , name , & type ) )
return NT_STATUS_ACCESS_DENIED ;
# endif
2001-07-09 18:32:54 +00:00
2009-10-30 11:09:52 +01:00
status = create_lsa_policy_handle ( p - > mem_ctx , p ,
LSA_HANDLE_ACCOUNT_TYPE ,
acc_granted ,
r - > in . sid ,
NULL ,
psd ,
r - > out . acct_handle ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2001-07-09 18:32:54 +00:00
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
2009-10-30 11:09:52 +01:00
}
2001-07-09 18:32:54 +00:00
2005-01-13 18:20:37 +00:00
return NT_STATUS_OK ;
2001-07-09 18:32:54 +00:00
}
/***************************************************************************
2008-02-14 01:53:00 +01:00
_lsa_EnumPrivsAccount
2001-11-23 15:11:22 +00:00
For a given SID , enumerate all the privilege this account has .
2001-07-09 18:32:54 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_EnumPrivsAccount ( struct pipes_struct * p ,
2008-02-14 01:53:00 +01:00
struct lsa_EnumPrivsAccount * r )
2001-07-09 18:32:54 +00:00
{
2008-02-14 01:53:00 +01:00
NTSTATUS status = NT_STATUS_OK ;
2001-07-09 18:32:54 +00:00
struct lsa_info * info = NULL ;
2010-08-30 15:38:18 +10:00
PRIVILEGE_SET * privileges ;
2008-02-14 01:53:00 +01:00
struct lsa_PrivilegeSet * priv_set = NULL ;
2018-12-14 21:48:48 +01:00
struct dom_sid_buf buf ;
2001-07-09 18:32:54 +00:00
/* find the connection policy handle. */
2008-02-14 01:53:00 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & info ) )
2001-07-09 18:32:54 +00:00
return NT_STATUS_INVALID_HANDLE ;
2009-05-20 11:52:11 -07:00
if ( info - > type ! = LSA_HANDLE_ACCOUNT_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( ! ( info - > access & LSA_ACCOUNT_VIEW ) )
2008-10-17 15:24:15 -07:00
return NT_STATUS_ACCESS_DENIED ;
2010-08-30 15:38:18 +10:00
status = get_privileges_for_sid_as_set ( p - > mem_ctx , & privileges , & info - > sid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2009-06-16 13:17:24 -07:00
}
2011-06-07 11:44:43 +10:00
* r - > out . privs = priv_set = talloc_zero ( p - > mem_ctx , struct lsa_PrivilegeSet ) ;
2010-08-30 15:38:18 +10:00
if ( ! priv_set ) {
return NT_STATUS_NO_MEMORY ;
2005-01-17 15:23:11 +00:00
}
2001-07-09 18:32:54 +00:00
2010-08-30 15:38:18 +10:00
DEBUG ( 10 , ( " _lsa_EnumPrivsAccount: %s has %d privileges \n " ,
2018-12-14 21:48:48 +01:00
dom_sid_str_buf ( & info - > sid , & buf ) ,
2010-08-30 15:38:18 +10:00
privileges - > count ) ) ;
2009-06-16 13:17:24 -07:00
2010-08-30 15:38:18 +10:00
priv_set - > count = privileges - > count ;
priv_set - > unknown = 0 ;
priv_set - > set = talloc_move ( priv_set , & privileges - > set ) ;
2005-01-17 15:23:11 +00:00
2008-02-14 01:53:00 +01:00
return status ;
2001-07-09 18:32:54 +00:00
}
/***************************************************************************
2008-02-08 18:54:02 +01:00
_lsa_GetSystemAccessAccount
2001-07-09 18:32:54 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_GetSystemAccessAccount ( struct pipes_struct * p ,
2008-02-08 18:54:02 +01:00
struct lsa_GetSystemAccessAccount * r )
2001-07-09 18:32:54 +00:00
{
2009-05-18 21:05:08 +02:00
NTSTATUS status ;
struct lsa_info * info = NULL ;
struct lsa_EnumPrivsAccount e ;
struct lsa_PrivilegeSet * privset ;
2001-07-09 18:32:54 +00:00
/* find the connection policy handle. */
2005-01-13 18:20:37 +00:00
2008-02-08 18:54:02 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & info ) )
2001-07-09 18:32:54 +00:00
return NT_STATUS_INVALID_HANDLE ;
2009-05-20 11:52:11 -07:00
if ( info - > type ! = LSA_HANDLE_ACCOUNT_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( ! ( info - > access & LSA_ACCOUNT_VIEW ) )
2008-10-17 15:24:15 -07:00
return NT_STATUS_ACCESS_DENIED ;
2009-05-18 21:05:08 +02:00
privset = talloc_zero ( p - > mem_ctx , struct lsa_PrivilegeSet ) ;
if ( ! privset ) {
return NT_STATUS_NO_MEMORY ;
}
e . in . handle = r - > in . handle ;
e . out . privs = & privset ;
status = _lsa_EnumPrivsAccount ( p , & e ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " _lsa_GetSystemAccessAccount: "
" failed to call _lsa_EnumPrivsAccount(): %s \n " ,
nt_errstr ( status ) ) ) ;
return status ;
}
/* Samba4 would iterate over the privset to merge the policy mode bits,
* not sure samba3 can do the same here , so just return what we did in
* the past - gd */
2001-11-29 16:05:05 +00:00
/*
0x01 - > Log on locally
0x02 - > Access this computer from network
0x04 - > Log on as a batch job
0x10 - > Log on as a service
2008-02-14 13:12:28 +01:00
2001-11-29 16:05:05 +00:00
they can be ORed together
*/
2009-04-30 12:30:10 +02:00
* r - > out . access_mask = LSA_POLICY_MODE_INTERACTIVE |
LSA_POLICY_MODE_NETWORK ;
2001-07-09 18:32:54 +00:00
2005-01-13 18:20:37 +00:00
return NT_STATUS_OK ;
2001-07-09 18:32:54 +00:00
}
2001-11-29 16:05:05 +00:00
/***************************************************************************
update the systemaccount information
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_SetSystemAccessAccount ( struct pipes_struct * p ,
2008-02-08 18:32:05 +01:00
struct lsa_SetSystemAccessAccount * r )
2001-11-29 16:05:05 +00:00
{
struct lsa_info * info = NULL ;
2011-09-26 17:55:47 -04:00
NTSTATUS status ;
GROUP_MAP * map ;
2001-11-29 16:05:05 +00:00
/* find the connection policy handle. */
2008-02-08 18:32:05 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & info ) )
2001-11-29 16:05:05 +00:00
return NT_STATUS_INVALID_HANDLE ;
2009-05-20 11:52:11 -07:00
if ( info - > type ! = LSA_HANDLE_ACCOUNT_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
2008-02-14 13:12:28 +01:00
2009-05-20 11:52:11 -07:00
if ( ! ( info - > access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS ) ) {
2005-01-14 21:05:54 +00:00
return NT_STATUS_ACCESS_DENIED ;
2009-05-20 11:52:11 -07:00
}
2005-01-14 21:05:54 +00:00
2011-09-26 17:55:47 -04:00
map = talloc_zero ( p - > mem_ctx , GROUP_MAP ) ;
if ( ! map ) {
return NT_STATUS_NO_MEMORY ;
}
if ( ! pdb_getgrsid ( map , info - > sid ) ) {
TALLOC_FREE ( map ) ;
2001-11-29 16:05:05 +00:00
return NT_STATUS_NO_SUCH_GROUP ;
2011-09-26 17:55:47 -04:00
}
2001-11-29 16:05:05 +00:00
2011-09-26 17:55:47 -04:00
status = pdb_update_group_mapping_entry ( map ) ;
TALLOC_FREE ( map ) ;
return status ;
2001-11-29 16:05:05 +00:00
}
/***************************************************************************
2008-02-14 13:50:32 +01:00
_lsa_AddPrivilegesToAccount
2001-11-29 16:05:05 +00:00
For a given SID , add some privileges .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_AddPrivilegesToAccount ( struct pipes_struct * p ,
2008-02-14 13:50:32 +01:00
struct lsa_AddPrivilegesToAccount * r )
2001-11-29 16:05:05 +00:00
{
2003-10-06 01:38:46 +00:00
struct lsa_info * info = NULL ;
2008-02-14 13:50:32 +01:00
struct lsa_PrivilegeSet * set = NULL ;
2001-11-29 16:05:05 +00:00
/* find the connection policy handle. */
2008-02-14 13:50:32 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & info ) )
2001-11-29 16:05:05 +00:00
return NT_STATUS_INVALID_HANDLE ;
2008-02-14 13:12:28 +01:00
2009-05-20 11:52:11 -07:00
if ( info - > type ! = LSA_HANDLE_ACCOUNT_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
2008-02-14 13:12:28 +01:00
2009-05-20 11:52:11 -07:00
if ( ! ( info - > access & LSA_ACCOUNT_ADJUST_PRIVILEGES ) ) {
2005-01-14 21:05:54 +00:00
return NT_STATUS_ACCESS_DENIED ;
2005-01-28 16:55:09 +00:00
}
2001-11-29 16:05:05 +00:00
2008-02-14 13:50:32 +01:00
set = r - > in . privs ;
2005-01-13 18:20:37 +00:00
2010-08-30 15:27:40 +10:00
if ( ! grant_privilege_set ( & info - > sid , set ) ) {
2018-12-14 21:48:48 +01:00
struct dom_sid_buf buf ;
2010-08-30 15:27:40 +10:00
DEBUG ( 3 , ( " _lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed! \n " ,
2018-12-14 21:48:48 +01:00
dom_sid_str_buf ( & info - > sid , & buf ) ) ) ;
2005-01-17 15:23:11 +00:00
return NT_STATUS_NO_SUCH_PRIVILEGE ;
2001-11-29 16:05:05 +00:00
}
2005-01-13 18:20:37 +00:00
return NT_STATUS_OK ;
2001-11-29 16:05:05 +00:00
}
/***************************************************************************
2008-02-14 13:50:32 +01:00
_lsa_RemovePrivilegesFromAccount
2001-11-29 16:05:05 +00:00
For a given SID , remove some privileges .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_RemovePrivilegesFromAccount ( struct pipes_struct * p ,
2008-02-14 13:50:32 +01:00
struct lsa_RemovePrivilegesFromAccount * r )
2001-11-29 16:05:05 +00:00
{
2003-10-06 01:38:46 +00:00
struct lsa_info * info = NULL ;
2008-02-14 13:50:32 +01:00
struct lsa_PrivilegeSet * set = NULL ;
2001-11-29 16:05:05 +00:00
/* find the connection policy handle. */
2008-02-14 13:50:32 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & info ) )
2001-11-29 16:05:05 +00:00
return NT_STATUS_INVALID_HANDLE ;
2009-05-20 11:52:11 -07:00
if ( info - > type ! = LSA_HANDLE_ACCOUNT_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
2008-02-14 13:12:28 +01:00
2009-05-20 11:52:11 -07:00
if ( ! ( info - > access & LSA_ACCOUNT_ADJUST_PRIVILEGES ) ) {
2005-01-14 21:05:54 +00:00
return NT_STATUS_ACCESS_DENIED ;
2005-01-28 16:55:09 +00:00
}
2005-01-14 21:05:54 +00:00
2008-02-14 13:50:32 +01:00
set = r - > in . privs ;
2001-11-29 16:05:05 +00:00
2010-08-30 15:27:40 +10:00
if ( ! revoke_privilege_set ( & info - > sid , set ) ) {
2018-12-14 21:48:48 +01:00
struct dom_sid_buf buf ;
2008-02-14 13:50:32 +01:00
DEBUG ( 3 , ( " _lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed! \n " ,
2018-12-14 21:48:48 +01:00
dom_sid_str_buf ( & info - > sid , & buf ) ) ) ;
2005-01-17 15:23:11 +00:00
return NT_STATUS_NO_SUCH_PRIVILEGE ;
2001-11-29 16:05:05 +00:00
}
2005-01-13 18:20:37 +00:00
return NT_STATUS_OK ;
2001-11-29 16:05:05 +00:00
}
2009-07-16 18:32:53 +02:00
/***************************************************************************
_lsa_LookupPrivName
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_LookupPrivName ( struct pipes_struct * p ,
2009-07-16 18:32:53 +02:00
struct lsa_LookupPrivName * r )
{
struct lsa_info * info = NULL ;
const char * name ;
struct lsa_StringLarge * lsa_name ;
/* find the connection policy handle. */
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & info ) ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( info - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( ! ( info - > access & LSA_POLICY_VIEW_LOCAL_INFORMATION ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
2010-08-30 13:17:48 +10:00
if ( r - > in . luid - > high ! = 0 ) {
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
name = sec_privilege_name ( r - > in . luid - > low ) ;
2009-07-16 18:32:53 +02:00
if ( ! name ) {
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
2011-06-07 11:44:43 +10:00
lsa_name = talloc_zero ( p - > mem_ctx , struct lsa_StringLarge ) ;
2009-07-16 18:32:53 +02:00
if ( ! lsa_name ) {
return NT_STATUS_NO_MEMORY ;
}
lsa_name - > string = talloc_strdup ( lsa_name , name ) ;
if ( ! lsa_name - > string ) {
TALLOC_FREE ( lsa_name ) ;
return NT_STATUS_NO_MEMORY ;
}
* r - > out . name = lsa_name ;
return NT_STATUS_OK ;
}
2001-12-14 17:31:48 +00:00
/***************************************************************************
2008-02-04 21:13:19 +01:00
_lsa_QuerySecurity
2001-12-14 17:31:48 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_QuerySecurity ( struct pipes_struct * p ,
2008-02-04 21:13:19 +01:00
struct lsa_QuerySecurity * r )
2001-12-14 17:31:48 +00:00
{
2001-12-17 23:03:23 +00:00
struct lsa_info * handle = NULL ;
2010-05-18 10:29:34 +02:00
struct security_descriptor * psd = NULL ;
2011-02-21 17:35:45 +01:00
size_t sd_size = 0 ;
2001-12-17 23:03:23 +00:00
NTSTATUS status ;
2001-12-14 17:31:48 +00:00
/* find the connection policy handle. */
2008-02-04 21:13:19 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & handle ) )
2001-12-14 17:31:48 +00:00
return NT_STATUS_INVALID_HANDLE ;
2009-10-29 12:36:30 +01:00
switch ( handle - > type ) {
case LSA_HANDLE_POLICY_TYPE :
case LSA_HANDLE_ACCOUNT_TYPE :
2010-07-01 22:33:17 +02:00
case LSA_HANDLE_TRUST_TYPE :
2010-07-01 22:25:16 +02:00
case LSA_HANDLE_SECRET_TYPE :
2009-10-30 00:05:32 +01:00
psd = handle - > sd ;
sd_size = ndr_size_security_descriptor ( psd , 0 ) ;
status = NT_STATUS_OK ;
2009-10-29 12:36:30 +01:00
break ;
default :
2009-05-20 11:52:11 -07:00
status = NT_STATUS_INVALID_HANDLE ;
2009-10-29 12:36:30 +01:00
break ;
2009-05-20 11:52:11 -07:00
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2001-12-17 23:03:23 +00:00
2009-07-16 18:37:19 +02:00
* r - > out . sdbuf = make_sec_desc_buf ( p - > mem_ctx , sd_size , psd ) ;
if ( ! * r - > out . sdbuf ) {
return NT_STATUS_NO_MEMORY ;
2001-12-14 17:31:48 +00:00
}
2008-02-04 21:13:19 +01:00
return status ;
2001-12-14 17:31:48 +00:00
}
2005-01-15 02:20:30 +00:00
/***************************************************************************
2008-02-14 14:21:49 +01:00
_lsa_AddAccountRights
2005-01-15 02:20:30 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_AddAccountRights ( struct pipes_struct * p ,
2008-02-14 14:21:49 +01:00
struct lsa_AddAccountRights * r )
2005-01-15 02:20:30 +00:00
{
struct lsa_info * info = NULL ;
int i = 0 ;
2009-05-20 11:52:11 -07:00
uint32_t acc_granted = 0 ;
2010-05-18 10:29:34 +02:00
struct security_descriptor * psd = NULL ;
2009-05-20 11:52:11 -07:00
size_t sd_size ;
2010-05-21 11:25:01 +10:00
struct dom_sid sid ;
2009-05-20 11:52:11 -07:00
NTSTATUS status ;
2005-01-15 02:20:30 +00:00
/* find the connection policy handle. */
2008-02-14 14:21:49 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & info ) )
2005-01-15 02:20:30 +00:00
return NT_STATUS_INVALID_HANDLE ;
2008-02-14 13:12:28 +01:00
2009-05-20 11:52:11 -07:00
if ( info - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
2005-02-14 01:13:14 +00:00
}
2005-01-15 02:20:30 +00:00
2009-05-20 11:52:11 -07:00
/* get the generic lsa account SD for this SID until we store it */
status = make_lsa_object_sd ( p - > mem_ctx , & psd , & sd_size ,
& lsa_account_mapping ,
2012-04-17 12:30:15 -07:00
NULL , 0 ) ;
2009-05-20 11:52:11 -07:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
/*
* From the MS DOCs . If the sid doesn ' t exist , ask for LSA_POLICY_CREATE_ACCOUNT
2011-02-08 14:17:14 +01:00
* on the policy handle . If it does , ask for
* LSA_ACCOUNT_ADJUST_PRIVILEGES | LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS | LSA_ACCOUNT_VIEW ,
* on the account sid . We don ' t check here so just use the latter . JRA .
*/
2009-05-20 11:52:11 -07:00
2011-02-21 10:25:52 +01:00
status = access_check_object ( psd , p - > session_info - > security_token ,
2010-08-30 13:30:38 +10:00
SEC_PRIV_INVALID , SEC_PRIV_INVALID , 0 ,
2009-10-26 23:37:21 +01:00
LSA_ACCOUNT_ADJUST_PRIVILEGES | LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS | LSA_ACCOUNT_VIEW ,
& acc_granted , " _lsa_AddAccountRights " ) ;
2009-05-20 11:52:11 -07:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2005-01-15 02:20:30 +00:00
/* according to an NT4 PDC, you can add privileges to SIDs even without
call_lsa_create_account ( ) first . And you can use any arbitrary SID . */
2008-02-14 13:12:28 +01:00
2008-02-14 14:21:49 +01:00
sid_copy ( & sid , r - > in . sid ) ;
2008-02-14 13:12:28 +01:00
2008-02-14 14:21:49 +01:00
for ( i = 0 ; i < r - > in . rights - > count ; i + + ) {
2008-02-14 13:12:28 +01:00
2008-02-14 14:21:49 +01:00
const char * privname = r - > in . rights - > names [ i ] . string ;
2005-03-26 06:52:56 +00:00
2005-01-15 02:20:30 +00:00
/* only try to add non-null strings */
2005-03-26 06:52:56 +00:00
2008-02-14 14:21:49 +01:00
if ( ! privname )
2005-03-26 06:52:56 +00:00
continue ;
if ( ! grant_privilege_by_name ( & sid , privname ) ) {
2008-02-14 14:21:49 +01:00
DEBUG ( 2 , ( " _lsa_AddAccountRights: Failed to add privilege [%s] \n " ,
privname ) ) ;
2005-01-15 02:20:30 +00:00
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
}
return NT_STATUS_OK ;
}
/***************************************************************************
2008-02-14 15:20:18 +01:00
_lsa_RemoveAccountRights
2005-01-15 02:20:30 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_RemoveAccountRights ( struct pipes_struct * p ,
2008-02-14 15:20:18 +01:00
struct lsa_RemoveAccountRights * r )
2005-01-15 02:20:30 +00:00
{
struct lsa_info * info = NULL ;
int i = 0 ;
2010-05-18 10:29:34 +02:00
struct security_descriptor * psd = NULL ;
2009-05-20 11:52:11 -07:00
size_t sd_size ;
2010-05-21 11:25:01 +10:00
struct dom_sid sid ;
2008-02-14 15:20:18 +01:00
const char * privname = NULL ;
2009-05-20 11:52:11 -07:00
uint32_t acc_granted = 0 ;
NTSTATUS status ;
2005-01-15 02:20:30 +00:00
/* find the connection policy handle. */
2008-02-14 15:20:18 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & info ) )
2005-01-15 02:20:30 +00:00
return NT_STATUS_INVALID_HANDLE ;
2008-02-14 13:12:28 +01:00
2009-05-20 11:52:11 -07:00
if ( info - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
2005-02-14 01:13:14 +00:00
}
2005-01-15 02:20:30 +00:00
2009-05-20 11:52:11 -07:00
/* get the generic lsa account SD for this SID until we store it */
status = make_lsa_object_sd ( p - > mem_ctx , & psd , & sd_size ,
& lsa_account_mapping ,
2012-04-17 12:30:15 -07:00
NULL , 0 ) ;
2009-05-20 11:52:11 -07:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
/*
* From the MS DOCs . We need
* LSA_ACCOUNT_ADJUST_PRIVILEGES | LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS | LSA_ACCOUNT_VIEW
* and DELETE on the account sid .
2011-02-08 14:17:14 +01:00
*/
2009-05-20 11:52:11 -07:00
2011-02-21 10:25:52 +01:00
status = access_check_object ( psd , p - > session_info - > security_token ,
2010-08-30 13:30:38 +10:00
SEC_PRIV_INVALID , SEC_PRIV_INVALID , 0 ,
2009-10-26 23:37:21 +01:00
LSA_ACCOUNT_ADJUST_PRIVILEGES | LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS |
2010-06-03 10:36:05 +02:00
LSA_ACCOUNT_VIEW | SEC_STD_DELETE ,
2009-10-26 23:47:01 +01:00
& acc_granted , " _lsa_RemoveAccountRights " ) ;
2009-05-20 11:52:11 -07:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2008-02-14 15:20:18 +01:00
sid_copy ( & sid , r - > in . sid ) ;
2005-01-15 02:20:30 +00:00
2008-02-14 15:20:18 +01:00
if ( r - > in . remove_all ) {
2008-02-14 13:12:28 +01:00
if ( ! revoke_all_privileges ( & sid ) )
2005-01-15 02:20:30 +00:00
return NT_STATUS_ACCESS_DENIED ;
2008-02-14 13:12:28 +01:00
2005-01-15 02:20:30 +00:00
return NT_STATUS_OK ;
}
2008-02-14 13:12:28 +01:00
2008-02-14 15:20:18 +01:00
for ( i = 0 ; i < r - > in . rights - > count ; i + + ) {
2008-02-14 13:12:28 +01:00
2008-02-14 15:20:18 +01:00
privname = r - > in . rights - > names [ i ] . string ;
2005-03-26 06:52:56 +00:00
2005-01-15 02:20:30 +00:00
/* only try to add non-null strings */
2005-03-26 06:52:56 +00:00
2008-02-14 15:20:18 +01:00
if ( ! privname )
2005-03-26 06:52:56 +00:00
continue ;
if ( ! revoke_privilege_by_name ( & sid , privname ) ) {
2008-02-14 15:20:18 +01:00
DEBUG ( 2 , ( " _lsa_RemoveAccountRights: Failed to revoke privilege [%s] \n " ,
privname ) ) ;
2005-01-15 02:20:30 +00:00
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
}
return NT_STATUS_OK ;
}
2008-02-14 15:02:31 +01:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS init_lsa_right_set ( TALLOC_CTX * mem_ctx ,
struct lsa_RightSet * r ,
PRIVILEGE_SET * privileges )
{
2015-05-14 18:08:27 -07:00
uint32_t i ;
2008-02-14 15:02:31 +01:00
const char * privname ;
const char * * privname_array = NULL ;
2014-11-14 14:12:26 +01:00
size_t num_priv = 0 ;
2008-02-14 15:02:31 +01:00
for ( i = 0 ; i < privileges - > count ; i + + ) {
2010-08-30 13:17:48 +10:00
if ( privileges - > set [ i ] . luid . high ) {
continue ;
}
privname = sec_privilege_name ( privileges - > set [ i ] . luid . low ) ;
2008-02-14 15:02:31 +01:00
if ( privname ) {
if ( ! add_string_to_array ( mem_ctx , privname ,
& privname_array , & num_priv ) ) {
return NT_STATUS_NO_MEMORY ;
}
}
}
if ( num_priv ) {
2011-06-07 11:58:39 +10:00
r - > names = talloc_zero_array ( mem_ctx , struct lsa_StringLarge ,
2008-02-14 15:02:31 +01:00
num_priv ) ;
if ( ! r - > names ) {
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < num_priv ; i + + ) {
init_lsa_StringLarge ( & r - > names [ i ] , privname_array [ i ] ) ;
}
r - > count = num_priv ;
}
return NT_STATUS_OK ;
}
2005-01-15 02:20:30 +00:00
2005-03-26 06:52:56 +00:00
/***************************************************************************
2008-02-14 15:02:31 +01:00
_lsa_EnumAccountRights
2005-03-26 06:52:56 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_EnumAccountRights ( struct pipes_struct * p ,
2008-02-14 15:02:31 +01:00
struct lsa_EnumAccountRights * r )
2005-01-15 03:54:03 +00:00
{
2008-02-14 15:02:31 +01:00
NTSTATUS status ;
2005-01-15 03:54:03 +00:00
struct lsa_info * info = NULL ;
2010-08-30 15:38:18 +10:00
PRIVILEGE_SET * privileges ;
2018-12-14 21:48:48 +01:00
struct dom_sid_buf buf ;
2008-02-14 13:12:28 +01:00
2005-01-15 03:54:03 +00:00
/* find the connection policy handle. */
2008-02-14 13:12:28 +01:00
2008-02-14 15:02:31 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & info ) )
2005-01-15 03:54:03 +00:00
return NT_STATUS_INVALID_HANDLE ;
2008-02-14 13:12:28 +01:00
2009-05-20 11:52:11 -07:00
if ( info - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( ! ( info - > access & LSA_ACCOUNT_VIEW ) ) {
2008-10-17 15:24:15 -07:00
return NT_STATUS_ACCESS_DENIED ;
2009-05-20 11:52:11 -07:00
}
2008-10-17 15:24:15 -07:00
2005-01-15 03:54:03 +00:00
/* according to an NT4 PDC, you can add privileges to SIDs even without
call_lsa_create_account ( ) first . And you can use any arbitrary SID . */
2008-02-14 13:12:28 +01:00
2009-06-23 11:16:23 +02:00
/* according to MS-LSAD 3.1.4.5.10 it is required to return
* NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
* the lsa database */
2005-01-17 15:23:11 +00:00
2010-08-30 15:38:18 +10:00
status = get_privileges_for_sid_as_set ( p - > mem_ctx , & privileges , r - > in . sid ) ;
2009-06-23 11:16:23 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2005-01-15 03:54:03 +00:00
2009-06-16 13:17:24 -07:00
DEBUG ( 10 , ( " _lsa_EnumAccountRights: %s has %d privileges \n " ,
2018-12-14 21:48:48 +01:00
dom_sid_str_buf ( r - > in . sid , & buf ) ,
privileges - > count ) ) ;
2005-01-15 03:54:03 +00:00
2010-08-30 15:38:18 +10:00
status = init_lsa_right_set ( p - > mem_ctx , r - > out . rights , privileges ) ;
2005-01-15 03:54:03 +00:00
2008-02-14 15:02:31 +01:00
return status ;
2005-01-15 03:54:03 +00:00
}
2005-03-26 06:52:56 +00:00
/***************************************************************************
2008-02-14 13:25:42 +01:00
_lsa_LookupPrivValue
2005-03-26 06:52:56 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_LookupPrivValue ( struct pipes_struct * p ,
2008-02-14 13:25:42 +01:00
struct lsa_LookupPrivValue * r )
2005-03-10 18:50:47 +00:00
{
struct lsa_info * info = NULL ;
2008-02-14 13:25:42 +01:00
const char * name = NULL ;
2008-02-14 13:12:28 +01:00
2005-03-10 18:50:47 +00:00
/* find the connection policy handle. */
2008-02-14 13:12:28 +01:00
2008-02-14 13:25:42 +01:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & info ) )
2005-03-10 18:50:47 +00:00
return NT_STATUS_INVALID_HANDLE ;
2008-02-14 13:12:28 +01:00
2009-05-20 11:52:11 -07:00
if ( info - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( ! ( info - > access & LSA_POLICY_LOOKUP_NAMES ) )
2008-10-17 15:24:15 -07:00
return NT_STATUS_ACCESS_DENIED ;
2008-02-14 13:25:42 +01:00
name = r - > in . name - > string ;
2008-02-14 13:12:28 +01:00
2005-06-29 16:35:32 +00:00
DEBUG ( 10 , ( " _lsa_lookup_priv_value: name = %s \n " , name ) ) ;
2005-03-10 18:50:47 +00:00
2010-08-27 12:12:10 +10:00
r - > out . luid - > low = sec_privilege_id ( name ) ;
r - > out . luid - > high = 0 ;
2010-08-30 14:00:50 +10:00
if ( r - > out . luid - > low = = SEC_PRIV_INVALID ) {
2005-03-10 18:50:47 +00:00
return NT_STATUS_NO_SUCH_PRIVILEGE ;
2010-08-27 12:12:10 +10:00
}
2005-03-10 18:50:47 +00:00
return NT_STATUS_OK ;
}
2006-10-10 08:39:11 +00:00
2009-07-16 02:25:43 +02:00
/***************************************************************************
_lsa_EnumAccountsWithUserRight
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_EnumAccountsWithUserRight ( struct pipes_struct * p ,
2009-07-16 02:25:43 +02:00
struct lsa_EnumAccountsWithUserRight * r )
{
NTSTATUS status ;
struct lsa_info * info = NULL ;
struct dom_sid * sids = NULL ;
int num_sids = 0 ;
uint32_t i ;
2010-08-30 14:17:02 +10:00
enum sec_privilege privilege ;
2009-07-16 02:25:43 +02:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & info ) ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( info - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( ! ( info - > access & LSA_POLICY_LOOKUP_NAMES ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
if ( ! r - > in . name | | ! r - > in . name - > string ) {
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
2010-08-30 14:17:02 +10:00
privilege = sec_privilege_id ( r - > in . name - > string ) ;
if ( privilege = = SEC_PRIV_INVALID ) {
2009-07-16 02:25:43 +02:00
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
2010-08-30 14:17:02 +10:00
status = privilege_enum_sids ( privilege , p - > mem_ctx ,
2009-07-16 02:25:43 +02:00
& sids , & num_sids ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
r - > out . sids - > num_sids = num_sids ;
r - > out . sids - > sids = talloc_array ( p - > mem_ctx , struct lsa_SidPtr ,
r - > out . sids - > num_sids ) ;
for ( i = 0 ; i < r - > out . sids - > num_sids ; i + + ) {
2010-08-26 17:21:39 +02:00
r - > out . sids - > sids [ i ] . sid = dom_sid_dup ( r - > out . sids - > sids ,
2009-07-16 02:25:43 +02:00
& sids [ i ] ) ;
if ( ! r - > out . sids - > sids [ i ] . sid ) {
TALLOC_FREE ( r - > out . sids - > sids ) ;
r - > out . sids - > num_sids = 0 ;
return NT_STATUS_NO_MEMORY ;
}
}
return NT_STATUS_OK ;
}
2009-07-16 01:05:25 +02:00
/***************************************************************************
_lsa_Delete
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_Delete ( struct pipes_struct * p ,
2009-07-16 01:05:25 +02:00
struct lsa_Delete * r )
{
return NT_STATUS_NOT_SUPPORTED ;
}
2011-06-28 14:37:44 +02:00
static NTSTATUS info_ex_2_pdb_trusted_domain (
struct lsa_TrustDomainInfoInfoEx * info_ex ,
struct pdb_trusted_domain * td )
{
if ( info_ex - > domain_name . string = = NULL | |
info_ex - > netbios_name . string = = NULL | |
info_ex - > sid = = NULL ) {
return NT_STATUS_INVALID_PARAMETER ;
}
td - > domain_name = talloc_strdup ( td , info_ex - > domain_name . string ) ;
td - > netbios_name = talloc_strdup ( td , info_ex - > netbios_name . string ) ;
sid_copy ( & td - > security_identifier , info_ex - > sid ) ;
if ( td - > domain_name = = NULL | |
td - > netbios_name = = NULL | |
is_null_sid ( & td - > security_identifier ) ) {
return NT_STATUS_NO_MEMORY ;
}
td - > trust_direction = info_ex - > trust_direction ;
td - > trust_type = info_ex - > trust_type ;
td - > trust_attributes = info_ex - > trust_attributes ;
return NT_STATUS_OK ;
}
static NTSTATUS setInfoTrustedDomain_base ( struct pipes_struct * p ,
TALLOC_CTX * mem_ctx ,
struct lsa_info * policy ,
enum lsa_TrustDomInfoEnum level ,
union lsa_TrustedDomainInfo * info )
{
struct lsa_TrustDomainInfoAuthInfoInternal * auth_info_int = NULL ;
DATA_BLOB auth_blob ;
struct trustDomainPasswords auth_struct ;
NTSTATUS nt_status ;
struct pdb_trusted_domain * td ;
struct pdb_trusted_domain * orig_td ;
td = talloc_zero ( mem_ctx , struct pdb_trusted_domain ) ;
if ( td = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
switch ( level ) {
case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET :
if ( ! ( policy - > access & LSA_TRUSTED_SET_POSIX ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
td - > trust_posix_offset = & info - > posix_offset . posix_offset ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_INFO_EX :
if ( ! ( policy - > access & LSA_TRUSTED_SET_POSIX ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
nt_status = info_ex_2_pdb_trusted_domain ( & info - > info_ex , td ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
break ;
case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO :
if ( ! ( policy - > access & LSA_TRUSTED_SET_AUTH ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
2011-09-01 18:18:31 +02:00
nt_status = auth_info_2_auth_blob ( td , & info - > auth_info ,
& td - > trust_auth_incoming ,
& td - > trust_auth_outgoing ) ;
2011-06-28 14:37:44 +02:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
break ;
case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO :
if ( ! ( policy - > access & ( LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX ) ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
td - > trust_posix_offset = & info - > full_info . posix_offset . posix_offset ;
nt_status = info_ex_2_pdb_trusted_domain ( & info - > full_info . info_ex ,
td ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
2011-09-01 18:18:31 +02:00
nt_status = auth_info_2_auth_blob ( td ,
& info - > full_info . auth_info ,
& td - > trust_auth_incoming ,
& td - > trust_auth_outgoing ) ;
2011-06-28 14:37:44 +02:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
break ;
case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL :
if ( ! ( policy - > access & LSA_TRUSTED_SET_AUTH ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
auth_info_int = & info - > auth_info_internal ;
break ;
case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL :
if ( ! ( policy - > access & ( LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX ) ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
td - > trust_posix_offset = & info - > full_info_internal . posix_offset . posix_offset ;
nt_status = info_ex_2_pdb_trusted_domain ( & info - > full_info_internal . info_ex ,
td ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
auth_info_int = & info - > full_info_internal . auth_info ;
break ;
case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES :
if ( ! ( policy - > access & LSA_TRUSTED_SET_POSIX ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
td - > supported_enc_type = & info - > enc_types . enc_types ;
break ;
default :
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 ( p , mem_ctx ,
& auth_blob , & auth_struct ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
} else {
memset ( & auth_struct , 0 , sizeof ( auth_struct ) ) ;
}
/* TODO: verify only one object matches the dns/netbios/sid triplet and that
* this is the one we already have */
/* TODO: check if the trust direction is changed and we need to add or remove
* auth data */
/* TODO: check if trust type shall be changed and return an error in this case
* */
nt_status = pdb_get_trusted_domain_by_sid ( p - > mem_ctx , & policy - > sid ,
& orig_td ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
/* TODO: should we fetch previous values from the existing entry
* and append them ? */
if ( auth_struct . incoming . count ) {
nt_status = get_trustauth_inout_blob ( mem_ctx ,
& auth_struct . incoming ,
& td - > trust_auth_incoming ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
} else {
ZERO_STRUCT ( td - > trust_auth_incoming ) ;
}
if ( auth_struct . outgoing . count ) {
nt_status = get_trustauth_inout_blob ( mem_ctx ,
& auth_struct . outgoing ,
& td - > trust_auth_outgoing ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
} else {
ZERO_STRUCT ( td - > trust_auth_outgoing ) ;
}
nt_status = pdb_set_trusted_domain ( orig_td - > domain_name , td ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
return NT_STATUS_OK ;
}
NTSTATUS _lsa_SetTrustedDomainInfo ( struct pipes_struct * p ,
struct lsa_SetTrustedDomainInfo * r )
{
NTSTATUS status ;
struct policy_handle trustdom_handle ;
struct lsa_OpenTrustedDomain o ;
struct lsa_SetInformationTrustedDomain s ;
struct lsa_Close c ;
o . in . handle = r - > in . handle ;
o . in . sid = r - > in . dom_sid ;
o . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
o . out . trustdom_handle = & trustdom_handle ;
status = _lsa_OpenTrustedDomain ( p , & o ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
s . in . trustdom_handle = & trustdom_handle ;
s . in . level = r - > in . level ;
s . in . info = r - > in . info ;
status = _lsa_SetInformationTrustedDomain ( p , & s ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
c . in . handle = & trustdom_handle ;
c . out . handle = & trustdom_handle ;
return _lsa_Close ( p , & c ) ;
}
NTSTATUS _lsa_SetTrustedDomainInfoByName ( struct pipes_struct * p ,
struct lsa_SetTrustedDomainInfoByName * r )
{
NTSTATUS status ;
struct policy_handle trustdom_handle ;
struct lsa_OpenTrustedDomainByName o ;
struct lsa_SetInformationTrustedDomain s ;
struct lsa_Close c ;
o . in . handle = r - > in . handle ;
o . in . name . string = r - > in . trusted_domain - > string ;
o . in . access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
o . out . trustdom_handle = & trustdom_handle ;
status = _lsa_OpenTrustedDomainByName ( p , & o ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
if ( NT_STATUS_EQUAL ( status , NT_STATUS_NO_SUCH_DOMAIN ) ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
return status ;
}
s . in . trustdom_handle = & trustdom_handle ;
s . in . level = r - > in . level ;
s . in . info = r - > in . info ;
status = _lsa_SetInformationTrustedDomain ( p , & s ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
c . in . handle = & trustdom_handle ;
c . out . handle = & trustdom_handle ;
return _lsa_Close ( p , & c ) ;
}
NTSTATUS _lsa_SetInformationTrustedDomain ( struct pipes_struct * p ,
struct lsa_SetInformationTrustedDomain * r )
{
struct lsa_info * policy ;
if ( ! find_policy_by_hnd ( p , r - > in . trustdom_handle , ( void * * ) ( void * ) & policy ) ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( policy - > type ! = LSA_HANDLE_TRUST_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
return setInfoTrustedDomain_base ( p , p - > mem_ctx , policy ,
r - > in . level , r - > in . info ) ;
}
2006-10-10 08:39:11 +00:00
/*
* From here on the server routines are just dummy ones to make smbd link with
* librpc / gen_ndr / srv_lsa . c . These routines are actually never called , we are
* pulling the server stubs across one by one .
2008-02-14 13:12:28 +01:00
*/
2006-10-10 08:39:11 +00:00
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_SetSecObj ( struct pipes_struct * p , struct lsa_SetSecObj * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_ChangePassword ( struct pipes_struct * p ,
struct lsa_ChangePassword * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_SetInfoPolicy ( struct pipes_struct * p , struct lsa_SetInfoPolicy * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_ClearAuditLog ( struct pipes_struct * p , struct lsa_ClearAuditLog * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_GetQuotasForAccount ( struct pipes_struct * p ,
struct lsa_GetQuotasForAccount * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_SetQuotasForAccount ( struct pipes_struct * p ,
struct lsa_SetQuotasForAccount * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_StorePrivateData ( struct pipes_struct * p ,
struct lsa_StorePrivateData * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_RetrievePrivateData ( struct pipes_struct * p ,
struct lsa_RetrievePrivateData * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_SetInfoPolicy2 ( struct pipes_struct * p ,
struct lsa_SetInfoPolicy2 * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_EnumTrustedDomainsEx ( struct pipes_struct * p ,
struct lsa_EnumTrustedDomainsEx * r )
2006-10-10 08:39:11 +00:00
{
2010-08-23 11:20:37 +02:00
struct lsa_info * info ;
uint32_t count ;
struct pdb_trusted_domain * * domains ;
struct lsa_TrustDomainInfoInfoEx * entries ;
int i ;
NTSTATUS nt_status ;
2011-02-17 14:37:32 +01:00
/* bail out early if pdb backend is not capable of ex trusted domains,
2015-07-26 23:02:57 +02:00
* if we don ' t do that , the client might not call
2011-02-17 14:37:32 +01:00
* _lsa_EnumTrustedDomains ( ) afterwards - gd */
if ( ! ( pdb_capabilities ( ) & PDB_CAP_TRUSTED_DOMAINS_EX ) ) {
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2011-02-17 14:37:32 +01:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-08-23 11:20:37 +02:00
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & info ) )
return NT_STATUS_INVALID_HANDLE ;
if ( info - > type ! = LSA_HANDLE_POLICY_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
/* check if the user has enough rights */
if ( ! ( info - > access & LSA_POLICY_VIEW_LOCAL_INFORMATION ) )
return NT_STATUS_ACCESS_DENIED ;
become_root ( ) ;
nt_status = pdb_enum_trusted_domains ( p - > mem_ctx , & count , & domains ) ;
unbecome_root ( ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
2011-06-07 11:58:39 +10:00
entries = talloc_zero_array ( p - > mem_ctx , struct lsa_TrustDomainInfoInfoEx ,
2010-08-23 11:20:37 +02:00
count ) ;
if ( ! entries ) {
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < count ; i + + ) {
2012-09-28 18:03:25 +02:00
init_lsa_StringLarge ( & entries [ i ] . domain_name ,
domains [ i ] - > domain_name ) ;
2010-08-23 11:20:37 +02:00
init_lsa_StringLarge ( & entries [ i ] . netbios_name ,
domains [ i ] - > netbios_name ) ;
entries [ i ] . sid = & domains [ i ] - > security_identifier ;
2012-09-28 18:03:25 +02:00
entries [ i ] . trust_direction = domains [ i ] - > trust_direction ;
entries [ i ] . trust_type = domains [ i ] - > trust_type ;
entries [ i ] . trust_attributes = domains [ i ] - > trust_attributes ;
2010-08-23 11:20:37 +02:00
}
if ( * r - > in . resume_handle > = count ) {
* r - > out . resume_handle = - 1 ;
TALLOC_FREE ( entries ) ;
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 ,
( r - > in . max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER ) ) ;
r - > out . domains - > domains = entries + * r - > in . resume_handle ;
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 ;
}
/* 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 ;
return NT_STATUS_OK ;
2006-10-10 08:39:11 +00:00
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_QueryDomainInformationPolicy ( struct pipes_struct * p ,
struct lsa_QueryDomainInformationPolicy * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_SetDomainInformationPolicy ( struct pipes_struct * p ,
struct lsa_SetDomainInformationPolicy * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_TestCall ( struct pipes_struct * p , struct lsa_TestCall * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_CREDRWRITE ( struct pipes_struct * p , struct lsa_CREDRWRITE * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_CREDRREAD ( struct pipes_struct * p , struct lsa_CREDRREAD * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_CREDRENUMERATE ( struct pipes_struct * p , struct lsa_CREDRENUMERATE * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS ( struct pipes_struct * p ,
struct lsa_CREDRWRITEDOMAINCREDENTIALS * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS ( struct pipes_struct * p ,
struct lsa_CREDRREADDOMAINCREDENTIALS * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_CREDRDELETE ( struct pipes_struct * p , struct lsa_CREDRDELETE * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_CREDRGETTARGETINFO ( struct pipes_struct * p ,
struct lsa_CREDRGETTARGETINFO * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_CREDRPROFILELOADED ( struct pipes_struct * p ,
struct lsa_CREDRPROFILELOADED * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_CREDRGETSESSIONTYPES ( struct pipes_struct * p ,
struct lsa_CREDRGETSESSIONTYPES * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_LSARREGISTERAUDITEVENT ( struct pipes_struct * p ,
struct lsa_LSARREGISTERAUDITEVENT * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_LSARGENAUDITEVENT ( struct pipes_struct * p ,
struct lsa_LSARGENAUDITEVENT * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT ( struct pipes_struct * p ,
struct lsa_LSARUNREGISTERAUDITEVENT * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_lsaRQueryForestTrustInformation ( struct pipes_struct * p ,
struct lsa_lsaRQueryForestTrustInformation * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-09-02 18:13:38 +02: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 ;
if ( l1 = = l2 ) {
2011-05-13 20:21:30 +02:00
if ( strcasecmp_m ( s1 , s2 ) = = 0 ) {
2010-09-02 18:13:38 +02:00
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 ;
}
2011-05-13 20:21:30 +02:00
if ( strcasecmp_m ( & p1 [ t1 - t2 ] , p2 ) = = 0 ) {
2010-09-02 18:13:38 +02:00
return cret ;
}
return DNS_CMP_NO_MATCH ;
}
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 ;
2017-11-19 17:57:29 +00:00
rec - > type = ( enum ForestTrustInfoRecordType ) lrec - > type ;
2010-09-02 18:13:38 +02:00
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 = NULL ;
struct dom_sid * sid = NULL ;
const char * tname = NULL ;
size_t dns_len = 0 ;
size_t tlen = 0 ;
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 = false ;
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 ;
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 ;
2011-03-30 06:41:18 +02:00
break ;
2011-03-27 11:11:07 +02:00
default :
return NT_STATUS_INVALID_PARAMETER ;
2010-09-02 18:13:38 +02:00
}
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 ;
}
2017-10-13 11:12:43 +02:00
FALL_THROUGH ;
2010-09-02 18:13:38 +02:00
case DNS_CMP_FIRST_IS_CHILD :
case DNS_CMP_SECOND_IS_CHILD :
tln_conflict = true ;
2017-10-13 11:12:43 +02:00
FALL_THROUGH ;
2010-09-02 18:13:38 +02:00
default :
break ;
}
/* explicit exclusion, no dns name conflict here */
if ( exclusion ) {
tln_conflict = false ;
}
if ( trec - > type ! = FOREST_TRUST_DOMAIN_INFO ) {
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 ) & &
2011-05-13 20:21:30 +02:00
strcasecmp_m ( trec - > data . info . netbios_name . string ,
2010-09-02 18:13:38 +02:00
nb_name ) = = 0 ) {
nb_conflict = true ;
}
}
if ( tln_conflict ) {
2012-06-19 10:09:45 -07:00
( void ) add_collision ( c_info , new_fti_idx ,
2010-09-02 18:13:38 +02:00
collision_type ,
LSA_TLN_DISABLED_CONFLICT ,
tdo_name ) ;
}
if ( sid_conflict ) {
2012-06-19 10:09:45 -07:00
( void ) add_collision ( c_info , new_fti_idx ,
2010-09-02 18:13:38 +02:00
collision_type ,
LSA_SID_DISABLED_CONFLICT ,
tdo_name ) ;
}
if ( nb_conflict ) {
2012-06-19 10:09:45 -07:00
( void ) add_collision ( c_info , new_fti_idx ,
2010-09-02 18:13:38 +02:00
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 ;
2015-02-04 18:00:44 +00:00
es [ i ] - > flags = conflict_type ;
2010-09-02 18:13:38 +02:00
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 ;
}
static NTSTATUS get_ft_info ( TALLOC_CTX * mem_ctx ,
struct pdb_trusted_domain * td ,
struct ForestTrustInfo * info )
{
enum ndr_err_code ndr_err ;
if ( td - > trust_forest_trust_info . length = = 0 | |
td - > trust_forest_trust_info . data = = NULL ) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
ndr_err = ndr_pull_struct_blob_all ( & td - > trust_forest_trust_info , mem_ctx ,
info ,
( 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 pdb_domain_info * dom_info ,
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 ;
2017-11-19 17:57:29 +00:00
rec - > type = FOREST_TRUST_TOP_LEVEL_NAME ;
2010-09-02 18:13:38 +02:00
rec - > data . name . string = talloc_strdup ( fti , dom_info - > dns_forest ) ;
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 ;
2017-11-19 17:57:29 +00:00
rec - > type = FOREST_TRUST_DOMAIN_INFO ;
2010-09-02 18:13:38 +02:00
info = & rec - > data . info ;
info - > sid = dom_info - > sid ;
info - > dns_name . string = talloc_strdup ( fti , dom_info - > dns_domain ) ;
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 , dom_info - > name ) ;
if ( ! info - > netbios_name . string ) {
return NT_STATUS_NO_MEMORY ;
}
info - > netbios_name . size = strlen ( info - > netbios_name . string ) ;
return NT_STATUS_OK ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_lsaRSetForestTrustInformation ( struct pipes_struct * p ,
struct lsa_lsaRSetForestTrustInformation * r )
2006-10-10 08:39:11 +00:00
{
2010-09-02 18:13:38 +02:00
NTSTATUS status ;
int i ;
int j ;
struct lsa_info * handle ;
uint32_t num_domains ;
struct pdb_trusted_domain * * domains ;
struct ForestTrustInfo * nfti ;
struct ForestTrustInfo * fti ;
struct lsa_ForestTrustCollisionInfo * c_info ;
struct pdb_domain_info * dom_info ;
enum ndr_err_code ndr_err ;
if ( ! IS_DC ) {
return NT_STATUS_NOT_SUPPORTED ;
}
if ( ! find_policy_by_hnd ( p , r - > in . handle , ( void * * ) ( void * ) & handle ) ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( handle - > type ! = LSA_HANDLE_TRUST_TYPE ) {
return NT_STATUS_INVALID_HANDLE ;
}
if ( ! ( handle - > access & LSA_TRUSTED_SET_AUTH ) ) {
return NT_STATUS_ACCESS_DENIED ;
}
status = pdb_enum_trusted_domains ( p - > mem_ctx , & num_domains , & domains ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
if ( num_domains = = 0 ) {
return NT_STATUS_NO_SUCH_DOMAIN ;
}
for ( i = 0 ; i < num_domains ; i + + ) {
if ( domains [ i ] - > domain_name = = NULL ) {
return NT_STATUS_INVALID_DOMAIN_STATE ;
}
2011-05-13 20:21:30 +02:00
if ( strcasecmp_m ( domains [ i ] - > domain_name ,
2010-09-02 18:13:38 +02:00
r - > in . trusted_domain_name - > string ) = = 0 ) {
break ;
}
}
if ( i > = num_domains ) {
return NT_STATUS_NO_SUCH_DOMAIN ;
}
if ( ! ( domains [ i ] - > trust_attributes &
LSA_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 ;
}
/* The following section until COPY_END is a copy from
* source4 / rpmc_server / lsa / scesrc_lsa . c */
nfti = talloc ( p - > mem_ctx , struct ForestTrustInfo ) ;
if ( ! nfti ) {
return NT_STATUS_NO_MEMORY ;
}
status = make_ft_info ( nfti , r - > in . forest_trust_info , nfti ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return 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 ( p - > mem_ctx , struct ForestTrustInfo ) ;
if ( ! fti ) {
return NT_STATUS_NO_MEMORY ;
}
dom_info = pdb_get_domain_info ( p - > mem_ctx ) ;
status = own_ft_info ( dom_info , fti ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
status = check_ft_info ( c_info , dom_info - > dns_domain , fti , nfti , c_info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
for ( j = 0 ; j < num_domains ; j + + ) {
fti = talloc ( p - > mem_ctx , struct ForestTrustInfo ) ;
if ( ! fti ) {
return NT_STATUS_NO_MEMORY ;
}
status = get_ft_info ( p - > mem_ctx , domains [ j ] , fti ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
if ( NT_STATUS_EQUAL ( status ,
NT_STATUS_OBJECT_NAME_NOT_FOUND ) ) {
continue ;
}
return status ;
}
if ( domains [ j ] - > domain_name = = NULL ) {
return NT_STATUS_INVALID_DOMAIN_STATE ;
}
status = check_ft_info ( c_info , domains [ j ] - > domain_name ,
fti , nfti , c_info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
}
2015-03-11 16:39:05 +01:00
if ( c_info - > count ! = 0 ) {
* r - > out . collision_info = c_info ;
}
2010-09-02 18:13:38 +02:00
if ( r - > in . check_only ! = 0 ) {
return NT_STATUS_OK ;
}
/* COPY_END */
ndr_err = ndr_push_struct_blob ( & domains [ i ] - > trust_forest_trust_info ,
p - > mem_ctx , nfti ,
( ndr_push_flags_fn_t ) ndr_push_ForestTrustInfo ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
return NT_STATUS_INVALID_PARAMETER ;
}
status = pdb_set_trusted_domain ( domains [ i ] - > domain_name , domains [ i ] ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
return NT_STATUS_OK ;
2006-10-10 08:39:11 +00:00
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_CREDRRENAME ( struct pipes_struct * p ,
struct lsa_CREDRRENAME * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_LSAROPENPOLICYSCE ( struct pipes_struct * p ,
struct lsa_LSAROPENPOLICYSCE * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE ( struct pipes_struct * p ,
struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE ( struct pipes_struct * p ,
struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}
2010-07-28 09:48:42 +02:00
NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT ( struct pipes_struct * p ,
struct lsa_LSARADTREPORTSECURITYEVENT * r )
2006-10-10 08:39:11 +00:00
{
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-10-10 08:39:11 +00:00
return NT_STATUS_NOT_IMPLEMENTED ;
}