2011-02-09 08:05:54 +03:00
/*
2005-06-29 17:55:09 +04:00
Unix SMB / CIFS implementation .
Convert a server info struct into the form for PAC and NETLOGON replies
2011-07-18 16:26:31 +04:00
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2004 - 2011
2005-06-29 17:55:09 +04:00
Copyright ( C ) Stefan Metzmacher < metze @ samba . org > 2005
2011-02-09 08:05:54 +03:00
2005-06-29 17:55:09 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2005-06-29 17:55:09 +04:00
( at your option ) any later version .
2011-02-09 08:05:54 +03:00
2005-06-29 17:55:09 +04: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 .
2011-02-09 08:05:54 +03:00
2005-06-29 17:55:09 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-06-29 17:55:09 +04:00
*/
# include "includes.h"
2011-02-09 08:05:54 +03:00
# include "librpc/gen_ndr/auth.h"
2006-04-02 16:02:01 +04:00
# include "libcli/security/security.h"
2008-10-20 20:59:51 +04:00
# include "auth/auth_sam_reply.h"
2005-06-29 17:55:09 +04:00
2022-12-02 00:49:20 +03:00
/* Returns true if this SID belongs in SamBaseInfo, otherwise false. */
static bool is_base_sid ( const struct auth_SidAttr * sid ,
const struct dom_sid * domain_sid )
{
if ( sid - > attrs & SE_GROUP_RESOURCE ) {
/*
* Resource groups don ' t belong in the base
* RIDs , they ' re handled elsewhere .
*/
return false ;
}
/*
* This SID belongs in the base structure only if it ' s in the account ' s
* domain .
*/
return dom_sid_in_domain ( domain_sid , & sid - > sid ) ;
}
/* Stores a SID in a previously allocated array. */
static NTSTATUS store_extra_sid ( struct netr_SidAttr * sids ,
uint32_t * sidcount ,
const uint32_t allocated_sids ,
const struct auth_SidAttr * sid )
{
/* Check we aren't about to overflow our allocation. */
if ( * sidcount > = allocated_sids ) {
return NT_STATUS_INVALID_PARAMETER ;
}
sids [ * sidcount ] . sid = dom_sid_dup ( sids , & sid - > sid ) ;
if ( sids [ * sidcount ] . sid = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
sids [ * sidcount ] . attributes = sid - > attrs ;
* sidcount + = 1 ;
return NT_STATUS_OK ;
}
/*
* Stores a resource SID in a previously allocated array , either Extra SIDs or
* Resource SIDs . Any SID within the domain of the first SID so added is stored
* there , while remaining SIDs are stored in Extra SIDs .
*/
static NTSTATUS store_resource_sid ( struct netr_SidAttr * sids ,
uint32_t * sidcount ,
const uint32_t allocated_sids ,
const struct auth_SidAttr * sid ,
struct PAC_DOMAIN_GROUP_MEMBERSHIP * resource_groups ,
const uint32_t allocated_resource_groups )
{
NTSTATUS status ;
struct dom_sid * resource_domain = NULL ;
uint32_t rid ;
if ( resource_groups = = NULL ) {
return NT_STATUS_INVALID_PARAMETER ;
}
/* Split the SID into domain and RID. */
status = dom_sid_split_rid ( resource_groups , & sid - > sid , & resource_domain , & rid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
if ( resource_groups - > domain_sid = = NULL ) {
/*
* There is no domain SID set . Set it to the domain of this SID .
*/
resource_groups - > domain_sid = resource_domain ;
} else {
/*
* A domain SID has already been set . Check whether this SID ' s
* domain matches .
*
* Assuming that resource SIDs have been obtained with
* dsdb_expand_nested_groups ( ) , they should all be within the
* same domain ( ours ) , so unless something has gone horribly
* wrong , we should always find that they match .
*/
bool match = dom_sid_equal ( resource_groups - > domain_sid , resource_domain ) ;
talloc_free ( resource_domain ) ;
if ( ! match ) {
/*
* It doesn ' t match , so we can ' t store this SID here . It
* will have to go in Extra SIDs .
*/
return store_extra_sid ( sids , sidcount , allocated_sids , sid ) ;
}
}
/* Store the SID in Resource SIDs. */
/* Check we aren't about to overflow our allocation. */
if ( resource_groups - > groups . count > = allocated_resource_groups ) {
return NT_STATUS_INVALID_PARAMETER ;
}
resource_groups - > groups . rids [ resource_groups - > groups . count ] . rid = rid ;
resource_groups - > groups . rids [ resource_groups - > groups . count ] . attributes = sid - > attrs ;
resource_groups - > groups . count + + ;
return NT_STATUS_OK ;
}
/*
* Stores a SID in a previously allocated array , or excludes it if we are not
* storing resource groups . It will be placed in either Extra SIDs or Resource
* SIDs , depending on which is appropriate .
*/
static NTSTATUS store_sid ( struct netr_SidAttr * sids ,
uint32_t * sidcount ,
const uint32_t allocated_sids ,
const struct auth_SidAttr * sid ,
struct PAC_DOMAIN_GROUP_MEMBERSHIP * resource_groups ,
const uint32_t allocated_resource_groups ,
const enum auth_group_inclusion group_inclusion )
{
/* See if it's a resource SID. */
if ( sid - > attrs & SE_GROUP_RESOURCE ) {
/*
* If this is the SID of a resource group , determine whether it
* should be included or filtered out .
*/
switch ( group_inclusion ) {
case AUTH_INCLUDE_RESOURCE_GROUPS :
/* Include this SID in Extra SIDs. */
break ;
case AUTH_INCLUDE_RESOURCE_GROUPS_COMPRESSED :
/*
* Try to include this SID in Resource Groups . If this
* can ' t be arranged , we shall fall back to Extra
* SIDs .
*/
return store_resource_sid ( sids ,
sidcount ,
allocated_sids ,
sid ,
resource_groups ,
allocated_resource_groups ) ;
case AUTH_EXCLUDE_RESOURCE_GROUPS :
/* Ignore this SID. */
return NT_STATUS_OK ;
default :
/* This means we have a bug. */
DBG_ERR ( " invalid group inclusion parameter: %u \n " , group_inclusion ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
}
/* Just store the SID in Extra SIDs. */
return store_extra_sid ( sids ,
sidcount ,
allocated_sids ,
sid ) ;
}
2016-01-07 18:06:25 +03:00
static NTSTATUS auth_convert_user_info_dc_sambaseinfo ( TALLOC_CTX * mem_ctx ,
const struct auth_user_info_dc * user_info_dc ,
struct netr_SamBaseInfo * sam )
2005-06-29 17:55:09 +04:00
{
2011-01-20 15:39:37 +03:00
NTSTATUS status ;
2016-01-07 18:06:25 +03:00
const struct auth_user_info * info ;
ZERO_STRUCTP ( sam ) ;
2005-06-29 17:55:09 +04:00
2011-02-08 08:53:13 +03:00
if ( user_info_dc - > num_sids > PRIMARY_USER_SID_INDEX ) {
2022-09-27 05:13:12 +03:00
status = dom_sid_split_rid ( sam , & user_info_dc - > sids [ PRIMARY_USER_SID_INDEX ] . sid ,
2011-01-20 15:39:37 +03:00
& sam - > domain_sid , & sam - > rid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
} else {
return NT_STATUS_INVALID_PARAMETER ;
}
2011-02-08 08:53:13 +03:00
if ( user_info_dc - > num_sids > PRIMARY_GROUP_SID_INDEX ) {
2022-09-27 05:13:12 +03:00
status = dom_sid_split_rid ( NULL , & user_info_dc - > sids [ PRIMARY_GROUP_SID_INDEX ] . sid ,
2011-01-20 15:39:37 +03:00
NULL , & sam - > primary_gid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
} else {
/* if we have to encode something like SYSTEM (with no
* second SID in the token ) then this is the only
* choice */
sam - > primary_gid = sam - > rid ;
}
2005-10-24 11:11:40 +04:00
2011-02-08 08:53:13 +03:00
info = user_info_dc - > info ;
2011-10-22 00:10:43 +04:00
sam - > logon_time = info - > last_logon ;
sam - > logoff_time = info - > last_logoff ;
sam - > kickoff_time = info - > acct_expiry ;
2011-02-08 08:53:13 +03:00
sam - > last_password_change = info - > last_password_change ;
sam - > allow_password_change = info - > allow_password_change ;
sam - > force_password_change = info - > force_password_change ;
2016-01-07 17:46:10 +03:00
# define _COPY_STRING_TALLOC(src_name, dst_name) do { \
if ( info - > src_name ! = NULL ) { \
2016-01-07 18:06:25 +03:00
sam - > dst_name . string = talloc_strdup ( mem_ctx , info - > src_name ) ; \
2016-01-07 17:46:10 +03:00
if ( sam - > dst_name . string = = NULL ) { \
return NT_STATUS_NO_MEMORY ; \
} \
} \
} while ( 0 )
_COPY_STRING_TALLOC ( account_name , account_name ) ;
_COPY_STRING_TALLOC ( full_name , full_name ) ;
_COPY_STRING_TALLOC ( logon_script , logon_script ) ;
_COPY_STRING_TALLOC ( profile_path , profile_path ) ;
_COPY_STRING_TALLOC ( home_directory , home_directory ) ;
_COPY_STRING_TALLOC ( home_drive , home_drive ) ;
_COPY_STRING_TALLOC ( logon_server , logon_server ) ;
_COPY_STRING_TALLOC ( domain_name , logon_domain ) ;
# undef _COPY_STRING_TALLOC
2011-02-08 08:53:13 +03:00
sam - > logon_count = info - > logon_count ;
2011-02-09 02:46:21 +03:00
sam - > bad_password_count = info - > bad_password_count ;
2005-06-29 17:55:09 +04:00
sam - > groups . count = 0 ;
sam - > groups . rids = NULL ;
2022-12-12 23:04:47 +03:00
if ( user_info_dc - > num_sids > REMAINING_SIDS_INDEX ) {
2010-04-12 16:34:28 +04:00
size_t i ;
2016-01-07 18:06:25 +03:00
sam - > groups . rids = talloc_array ( mem_ctx , struct samr_RidWithAttribute ,
2011-02-08 08:53:13 +03:00
user_info_dc - > num_sids ) ;
2005-06-29 17:55:09 +04:00
if ( sam - > groups . rids = = NULL )
return NT_STATUS_NO_MEMORY ;
2022-12-12 23:04:47 +03:00
for ( i = REMAINING_SIDS_INDEX ; i < user_info_dc - > num_sids ; i + + ) {
2022-09-27 05:13:12 +03:00
struct auth_SidAttr * group_sid = & user_info_dc - > sids [ i ] ;
2022-12-02 00:49:20 +03:00
bool belongs_in_base = is_base_sid ( group_sid , sam - > domain_sid ) ;
if ( ! belongs_in_base ) {
2005-10-24 11:11:40 +04:00
/* We handle this elsewhere */
continue ;
}
2005-06-29 17:55:09 +04:00
sam - > groups . rids [ sam - > groups . count ] . rid =
2022-09-27 05:13:12 +03:00
group_sid - > sid . sub_auths [ group_sid - > sid . num_auths - 1 ] ;
2011-02-09 08:05:54 +03:00
2022-09-27 05:13:12 +03:00
sam - > groups . rids [ sam - > groups . count ] . attributes = group_sid - > attrs ;
2005-06-29 17:55:09 +04:00
sam - > groups . count + = 1 ;
}
2022-12-22 02:50:26 +03:00
if ( sam - > groups . count = = 0 ) {
TALLOC_FREE ( sam - > groups . rids ) ;
}
2005-06-29 17:55:09 +04:00
}
2022-12-12 00:50:01 +03:00
sam - > user_flags = info - > user_flags ; /* w2k3 uses NETLOGON_EXTRA_SIDS | NETLOGON_NTLMV2_ENABLED */
2011-02-08 08:53:13 +03:00
sam - > acct_flags = user_info_dc - > info - > acct_flags ;
2011-10-22 00:10:43 +04:00
sam - > sub_auth_status = 0 ;
sam - > last_successful_logon = 0 ;
sam - > last_failed_logon = 0 ;
sam - > failed_logon_count = 0 ;
sam - > reserved = 0 ;
2005-06-29 17:55:09 +04:00
ZERO_STRUCT ( sam - > key ) ;
2011-02-08 08:53:13 +03:00
if ( user_info_dc - > user_session_key . length = = sizeof ( sam - > key . key ) ) {
memcpy ( sam - > key . key , user_info_dc - > user_session_key . data , sizeof ( sam - > key . key ) ) ;
2005-06-29 17:55:09 +04:00
}
ZERO_STRUCT ( sam - > LMSessKey ) ;
2011-02-08 08:53:13 +03:00
if ( user_info_dc - > lm_session_key . length = = sizeof ( sam - > LMSessKey . key ) ) {
memcpy ( sam - > LMSessKey . key , user_info_dc - > lm_session_key . data ,
2005-06-29 17:55:09 +04:00
sizeof ( sam - > LMSessKey . key ) ) ;
}
2011-02-09 08:05:54 +03:00
2005-06-29 17:55:09 +04:00
return NT_STATUS_OK ;
2011-02-09 08:05:54 +03:00
}
2005-06-29 17:55:09 +04:00
2022-12-02 00:49:20 +03:00
/* Note that the validity of the _sam6 and resource_groups structures is only as
* long as the user_info_dc it was generated from */
2016-01-07 17:15:14 +03:00
NTSTATUS auth_convert_user_info_dc_saminfo6 ( TALLOC_CTX * mem_ctx ,
const struct auth_user_info_dc * user_info_dc ,
2022-09-27 04:51:54 +03:00
enum auth_group_inclusion group_inclusion ,
2022-12-02 00:49:20 +03:00
struct netr_SamInfo6 * * _sam6 ,
struct PAC_DOMAIN_GROUP_MEMBERSHIP * * _resource_groups )
2005-07-05 14:57:39 +04:00
{
2005-10-24 11:11:40 +04:00
NTSTATUS status ;
2016-01-07 17:15:14 +03:00
struct netr_SamInfo6 * sam6 = NULL ;
2022-12-02 00:49:20 +03:00
struct PAC_DOMAIN_GROUP_MEMBERSHIP * resource_groups = NULL ;
2010-04-12 16:34:28 +04:00
size_t i ;
2005-07-05 14:57:39 +04:00
2022-12-02 00:49:20 +03:00
const uint32_t allocated_sids = user_info_dc - > num_sids ;
uint32_t allocated_resource_groups = 0 ;
2016-01-07 17:15:14 +03:00
sam6 = talloc_zero ( mem_ctx , struct netr_SamInfo6 ) ;
if ( sam6 = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2022-12-02 00:49:20 +03:00
if ( _resource_groups = = NULL ) {
if ( group_inclusion = = AUTH_INCLUDE_RESOURCE_GROUPS_COMPRESSED ) {
DBG_ERR ( " _resource_groups parameter not provided to receive resource groups! \n " ) ;
TALLOC_FREE ( sam6 ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
} else if ( group_inclusion = = AUTH_INCLUDE_RESOURCE_GROUPS_COMPRESSED ) {
* _resource_groups = NULL ;
/* Allocate resource groups structure. */
resource_groups = talloc_zero ( mem_ctx , struct PAC_DOMAIN_GROUP_MEMBERSHIP ) ;
if ( resource_groups = = NULL ) {
TALLOC_FREE ( sam6 ) ;
return NT_STATUS_NO_MEMORY ;
}
/*
* Allocate enough space to store user_info_dc - > num_sids
* RIDs in the worst case .
*/
allocated_resource_groups = user_info_dc - > num_sids ;
resource_groups - > groups . rids = talloc_zero_array ( resource_groups ,
struct samr_RidWithAttribute ,
allocated_resource_groups ) ;
if ( resource_groups - > groups . rids = = NULL ) {
TALLOC_FREE ( sam6 ) ;
TALLOC_FREE ( resource_groups ) ;
return NT_STATUS_NO_MEMORY ;
}
} else {
/* No resource groups will be provided. */
* _resource_groups = NULL ;
}
2016-01-07 18:06:25 +03:00
status = auth_convert_user_info_dc_sambaseinfo ( sam6 ,
user_info_dc ,
& sam6 - > base ) ;
2005-10-24 11:11:40 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2016-01-07 17:15:14 +03:00
TALLOC_FREE ( sam6 ) ;
2022-12-02 00:49:20 +03:00
TALLOC_FREE ( resource_groups ) ;
2005-10-24 11:11:40 +04:00
return status ;
2005-08-04 03:14:38 +04:00
}
2011-02-09 08:05:54 +03:00
2022-12-02 00:49:20 +03:00
/*
* Allocate enough space to store user_info_dc - > num_sids SIDs in the
* worst case .
*/
sam6 - > sids = talloc_zero_array ( sam6 , struct netr_SidAttr ,
allocated_sids ) ;
2016-01-07 17:15:14 +03:00
if ( sam6 - > sids = = NULL ) {
TALLOC_FREE ( sam6 ) ;
2022-12-02 00:49:20 +03:00
TALLOC_FREE ( resource_groups ) ;
2014-02-13 08:51:11 +04:00
return NT_STATUS_NO_MEMORY ;
}
2011-01-20 15:39:37 +03:00
/* We don't put the user and group SIDs in there */
2022-12-16 02:08:41 +03:00
for ( i = REMAINING_SIDS_INDEX ; i < user_info_dc - > num_sids ; i + + ) {
2022-12-02 00:49:20 +03:00
struct auth_SidAttr * group_sid = & user_info_dc - > sids [ i ] ;
bool belongs_in_base = is_base_sid ( group_sid , sam6 - > base . domain_sid ) ;
if ( belongs_in_base ) {
/* We already handled this in the base. */
2005-10-24 11:11:40 +04:00
continue ;
2005-07-05 14:57:39 +04:00
}
2022-12-02 00:49:20 +03:00
status = store_sid ( sam6 - > sids ,
& sam6 - > sidcount ,
allocated_sids ,
group_sid ,
resource_groups ,
allocated_resource_groups ,
group_inclusion ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2016-01-07 17:15:14 +03:00
TALLOC_FREE ( sam6 ) ;
2022-12-02 00:49:20 +03:00
TALLOC_FREE ( resource_groups ) ;
return status ;
2014-02-13 08:51:11 +04:00
}
2005-10-24 11:11:40 +04:00
}
2016-01-07 17:15:14 +03:00
if ( sam6 - > sidcount ) {
sam6 - > base . user_flags | = NETLOGON_EXTRA_SIDS ;
2005-10-24 11:11:40 +04:00
} else {
2023-02-27 05:56:40 +03:00
sam6 - > base . user_flags & = ~ NETLOGON_EXTRA_SIDS ;
2022-12-22 02:50:26 +03:00
TALLOC_FREE ( sam6 - > sids ) ;
2005-07-05 14:57:39 +04:00
}
2016-01-07 17:15:14 +03:00
if ( user_info_dc - > info - > dns_domain_name ! = NULL ) {
sam6 - > dns_domainname . string = talloc_strdup ( sam6 ,
user_info_dc - > info - > dns_domain_name ) ;
if ( sam6 - > dns_domainname . string = = NULL ) {
TALLOC_FREE ( sam6 ) ;
2022-12-02 00:49:20 +03:00
TALLOC_FREE ( resource_groups ) ;
2016-01-07 17:15:14 +03:00
return NT_STATUS_NO_MEMORY ;
}
}
if ( user_info_dc - > info - > user_principal_name ! = NULL ) {
sam6 - > principal_name . string = talloc_strdup ( sam6 ,
user_info_dc - > info - > user_principal_name ) ;
if ( sam6 - > principal_name . string = = NULL ) {
TALLOC_FREE ( sam6 ) ;
2022-12-02 00:49:20 +03:00
TALLOC_FREE ( resource_groups ) ;
2016-01-07 17:15:14 +03:00
return NT_STATUS_NO_MEMORY ;
}
}
* _sam6 = sam6 ;
2022-12-02 00:49:20 +03:00
if ( resource_groups ! = NULL ) {
if ( resource_groups - > groups . count > 0 ) {
* _resource_groups = resource_groups ;
} else {
TALLOC_FREE ( resource_groups ) ;
}
}
2016-01-07 17:15:14 +03:00
return NT_STATUS_OK ;
}
2016-01-07 17:23:56 +03:00
/* Note that the validity of the _sam2 structure is only as long as
* the user_info_dc it was generated from */
NTSTATUS auth_convert_user_info_dc_saminfo2 ( TALLOC_CTX * mem_ctx ,
const struct auth_user_info_dc * user_info_dc ,
2022-09-27 04:51:54 +03:00
enum auth_group_inclusion group_inclusion ,
2016-01-07 17:23:56 +03:00
struct netr_SamInfo2 * * _sam2 )
{
NTSTATUS status ;
struct netr_SamInfo6 * sam6 = NULL ;
struct netr_SamInfo2 * sam2 = NULL ;
sam2 = talloc_zero ( mem_ctx , struct netr_SamInfo2 ) ;
if ( sam2 = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2022-09-27 04:51:54 +03:00
status = auth_convert_user_info_dc_saminfo6 ( sam2 , user_info_dc ,
2022-12-02 00:49:20 +03:00
group_inclusion , & sam6 ,
NULL ) ;
2016-01-07 17:23:56 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
TALLOC_FREE ( sam2 ) ;
return status ;
}
sam2 - > base = sam6 - > base ;
2022-12-15 04:07:06 +03:00
/*
* We have nowhere to put sam6 - > sids , so we follow Windows here and drop
2023-09-05 07:02:59 +03:00
* it . Any resource groups it happened to contain are lost .
2022-12-15 04:07:06 +03:00
*/
sam2 - > base . user_flags & = ~ NETLOGON_EXTRA_SIDS ;
TALLOC_FREE ( sam6 - > sids ) ;
2016-01-07 17:23:56 +03:00
* _sam2 = sam2 ;
return NT_STATUS_OK ;
}
2016-01-07 17:15:14 +03:00
/* Note that the validity of the _sam3 structure is only as long as
* the user_info_dc it was generated from */
NTSTATUS auth_convert_user_info_dc_saminfo3 ( TALLOC_CTX * mem_ctx ,
const struct auth_user_info_dc * user_info_dc ,
2022-09-27 04:51:54 +03:00
enum auth_group_inclusion group_inclusion ,
2022-12-02 00:49:20 +03:00
struct netr_SamInfo3 * * _sam3 ,
struct PAC_DOMAIN_GROUP_MEMBERSHIP * * _resource_groups )
2016-01-07 17:15:14 +03:00
{
NTSTATUS status ;
struct netr_SamInfo6 * sam6 = NULL ;
struct netr_SamInfo3 * sam3 = NULL ;
sam3 = talloc_zero ( mem_ctx , struct netr_SamInfo3 ) ;
if ( sam3 = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2022-09-27 04:51:54 +03:00
status = auth_convert_user_info_dc_saminfo6 ( sam3 , user_info_dc ,
2022-12-02 00:49:20 +03:00
group_inclusion , & sam6 ,
_resource_groups ) ;
2016-01-07 17:15:14 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
TALLOC_FREE ( sam3 ) ;
return status ;
}
sam3 - > base = sam6 - > base ;
sam3 - > sidcount = sam6 - > sidcount ;
sam3 - > sids = sam6 - > sids ;
* _sam3 = sam3 ;
2005-07-05 14:57:39 +04:00
return NT_STATUS_OK ;
2011-02-09 08:05:54 +03:00
}
2005-07-05 14:57:39 +04:00
2011-07-18 07:55:20 +04:00
/**
* Make a user_info struct from the info3 or similar returned by a domain logon .
*
* The netr_SamInfo3 is also a key structure in the source3 auth subsystem
*/
NTSTATUS make_user_info_SamBaseInfo ( TALLOC_CTX * mem_ctx ,
const char * account_name ,
2016-01-07 16:50:27 +03:00
const struct netr_SamBaseInfo * base ,
2011-07-18 07:55:20 +04:00
bool authenticated ,
struct auth_user_info * * _user_info )
{
struct auth_user_info * info ;
info = talloc_zero ( mem_ctx , struct auth_user_info ) ;
2023-05-11 01:40:27 +03:00
if ( info = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2011-07-18 07:55:20 +04:00
if ( base - > account_name . string ) {
2011-07-18 08:00:14 +04:00
info - > account_name = talloc_strdup ( info , base - > account_name . string ) ;
2011-07-18 07:55:20 +04:00
} else {
info - > account_name = talloc_strdup ( info , account_name ) ;
}
2023-05-11 01:40:27 +03:00
if ( info - > account_name = = NULL ) {
talloc_free ( info ) ;
return NT_STATUS_NO_MEMORY ;
}
2011-07-18 07:55:20 +04:00
2011-10-22 00:10:43 +04:00
if ( base - > logon_domain . string ) {
info - > domain_name = talloc_strdup ( info , base - > logon_domain . string ) ;
2023-05-11 01:40:27 +03:00
if ( info - > domain_name = = NULL ) {
talloc_free ( info ) ;
return NT_STATUS_NO_MEMORY ;
}
2011-07-18 08:00:14 +04:00
}
if ( base - > full_name . string ) {
info - > full_name = talloc_strdup ( info , base - > full_name . string ) ;
2023-05-11 01:40:27 +03:00
if ( info - > full_name = = NULL ) {
talloc_free ( info ) ;
return NT_STATUS_NO_MEMORY ;
}
2011-07-18 08:00:14 +04:00
}
if ( base - > logon_script . string ) {
info - > logon_script = talloc_strdup ( info , base - > logon_script . string ) ;
2023-05-11 01:40:27 +03:00
if ( info - > logon_script = = NULL ) {
talloc_free ( info ) ;
return NT_STATUS_NO_MEMORY ;
}
2011-07-18 08:00:14 +04:00
}
if ( base - > profile_path . string ) {
info - > profile_path = talloc_strdup ( info , base - > profile_path . string ) ;
2023-05-11 01:40:27 +03:00
if ( info - > profile_path = = NULL ) {
talloc_free ( info ) ;
return NT_STATUS_NO_MEMORY ;
}
2011-07-18 08:00:14 +04:00
}
if ( base - > home_directory . string ) {
info - > home_directory = talloc_strdup ( info , base - > home_directory . string ) ;
2023-05-11 01:40:27 +03:00
if ( info - > home_directory = = NULL ) {
talloc_free ( info ) ;
return NT_STATUS_NO_MEMORY ;
}
2011-07-18 08:00:14 +04:00
}
if ( base - > home_drive . string ) {
info - > home_drive = talloc_strdup ( info , base - > home_drive . string ) ;
2023-05-11 01:40:27 +03:00
if ( info - > home_drive = = NULL ) {
talloc_free ( info ) ;
return NT_STATUS_NO_MEMORY ;
}
2011-07-18 08:00:14 +04:00
}
if ( base - > logon_server . string ) {
info - > logon_server = talloc_strdup ( info , base - > logon_server . string ) ;
2023-05-11 01:40:27 +03:00
if ( info - > logon_server = = NULL ) {
talloc_free ( info ) ;
return NT_STATUS_NO_MEMORY ;
}
2011-07-18 08:00:14 +04:00
}
2011-10-22 00:10:43 +04:00
info - > last_logon = base - > logon_time ;
info - > last_logoff = base - > logoff_time ;
info - > acct_expiry = base - > kickoff_time ;
2011-07-18 07:55:20 +04:00
info - > last_password_change = base - > last_password_change ;
info - > allow_password_change = base - > allow_password_change ;
info - > force_password_change = base - > force_password_change ;
info - > logon_count = base - > logon_count ;
info - > bad_password_count = base - > bad_password_count ;
info - > acct_flags = base - > acct_flags ;
2022-12-12 00:50:01 +03:00
info - > user_flags = base - > user_flags ;
if ( ! authenticated ) {
/*
* We only consider the user authenticated if NETLOGON_GUEST is
* not set , and authenticated is set
*/
info - > user_flags | = NETLOGON_GUEST ;
}
2011-07-18 07:55:20 +04:00
* _user_info = info ;
return NT_STATUS_OK ;
}
2018-03-06 18:38:10 +03:00
struct auth_user_info * auth_user_info_copy ( TALLOC_CTX * mem_ctx ,
const struct auth_user_info * src )
{
struct auth_user_info * dst = NULL ;
dst = talloc_zero ( mem_ctx , struct auth_user_info ) ;
if ( dst = = NULL ) {
return NULL ;
}
* dst = * src ;
# define _COPY_STRING(_mem, _str) do { \
if ( ( _str ) ! = NULL ) { \
( _str ) = talloc_strdup ( ( _mem ) , ( _str ) ) ; \
if ( ( _str ) = = NULL ) { \
TALLOC_FREE ( dst ) ; \
return NULL ; \
} \
} \
} while ( 0 )
_COPY_STRING ( dst , dst - > account_name ) ;
_COPY_STRING ( dst , dst - > user_principal_name ) ;
_COPY_STRING ( dst , dst - > domain_name ) ;
_COPY_STRING ( dst , dst - > dns_domain_name ) ;
_COPY_STRING ( dst , dst - > full_name ) ;
_COPY_STRING ( dst , dst - > logon_script ) ;
_COPY_STRING ( dst , dst - > profile_path ) ;
_COPY_STRING ( dst , dst - > home_directory ) ;
_COPY_STRING ( dst , dst - > home_drive ) ;
_COPY_STRING ( dst , dst - > logon_server ) ;
# undef _COPY_STRING
return dst ;
}
2009-01-21 12:43:15 +03:00
/**
2011-02-08 08:53:13 +03:00
* Make a user_info_dc struct from the info3 returned by a domain logon
2009-01-21 12:43:15 +03:00
*/
2011-02-08 08:53:13 +03:00
NTSTATUS make_user_info_dc_netlogon_validation ( TALLOC_CTX * mem_ctx ,
2009-01-21 12:43:15 +03:00
const char * account_name ,
uint16_t validation_level ,
2016-01-07 16:50:27 +03:00
const union netr_Validation * validation ,
2011-07-18 07:55:20 +04:00
bool authenticated ,
2011-02-08 08:53:13 +03:00
struct auth_user_info_dc * * _user_info_dc )
2009-01-21 12:43:15 +03:00
{
2011-07-18 07:55:20 +04:00
NTSTATUS status ;
2016-01-07 17:06:46 +03:00
struct auth_user_info_dc * user_info_dc = NULL ;
const struct netr_SamBaseInfo * base = NULL ;
uint32_t sidcount = 0 ;
const struct netr_SidAttr * sids = NULL ;
const char * dns_domainname = NULL ;
const char * principal = NULL ;
2010-04-12 16:34:28 +04:00
uint32_t i ;
2009-01-21 12:43:15 +03:00
switch ( validation_level ) {
case 2 :
if ( ! validation | | ! validation - > sam2 ) {
return NT_STATUS_INVALID_PARAMETER ;
}
base = & validation - > sam2 - > base ;
break ;
case 3 :
if ( ! validation | | ! validation - > sam3 ) {
return NT_STATUS_INVALID_PARAMETER ;
}
base = & validation - > sam3 - > base ;
2016-01-07 17:06:46 +03:00
sidcount = validation - > sam3 - > sidcount ;
sids = validation - > sam3 - > sids ;
2009-01-21 12:43:15 +03:00
break ;
case 6 :
if ( ! validation | | ! validation - > sam6 ) {
return NT_STATUS_INVALID_PARAMETER ;
}
base = & validation - > sam6 - > base ;
2016-01-07 17:06:46 +03:00
sidcount = validation - > sam6 - > sidcount ;
sids = validation - > sam6 - > sids ;
dns_domainname = validation - > sam6 - > dns_domainname . string ;
principal = validation - > sam6 - > principal_name . string ;
2009-01-21 12:43:15 +03:00
break ;
default :
return NT_STATUS_INVALID_LEVEL ;
}
2022-06-10 10:18:07 +03:00
user_info_dc = talloc_zero ( mem_ctx , struct auth_user_info_dc ) ;
2023-05-11 01:40:27 +03:00
if ( user_info_dc = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2009-01-21 12:43:15 +03:00
/*
Here is where we should check the list of
2011-02-09 08:05:54 +03:00
trusted domains , and verify that the SID
2009-01-21 12:43:15 +03:00
matches .
*/
2011-01-20 15:39:37 +03:00
if ( ! base - > domain_sid ) {
2023-07-31 07:06:56 +03:00
DEBUG ( 0 , ( " Cannot operate on a Netlogon Validation without a domain SID \n " ) ) ;
2023-05-11 01:40:27 +03:00
talloc_free ( user_info_dc ) ;
2011-01-20 15:39:37 +03:00
return NT_STATUS_INVALID_PARAMETER ;
}
2009-01-21 12:43:15 +03:00
2011-01-20 15:39:37 +03:00
/* The IDL layer would be a better place to check this, but to
* guard the integer addition below , we double - check */
if ( base - > groups . count > 65535 ) {
2023-05-11 01:40:27 +03:00
talloc_free ( user_info_dc ) ;
2011-01-20 15:39:37 +03:00
return NT_STATUS_INVALID_PARAMETER ;
}
2009-01-21 12:43:15 +03:00
2022-12-16 02:08:41 +03:00
user_info_dc - > num_sids = PRIMARY_SIDS_COUNT ;
2009-01-21 12:43:15 +03:00
2022-09-27 05:13:12 +03:00
user_info_dc - > sids = talloc_array ( user_info_dc , struct auth_SidAttr , user_info_dc - > num_sids + base - > groups . count ) ;
2023-05-11 01:40:27 +03:00
if ( user_info_dc - > sids = = NULL ) {
talloc_free ( user_info_dc ) ;
return NT_STATUS_NO_MEMORY ;
}
2011-01-20 15:39:37 +03:00
2022-09-27 05:13:12 +03:00
user_info_dc - > sids [ PRIMARY_USER_SID_INDEX ] . sid = * base - > domain_sid ;
if ( ! sid_append_rid ( & user_info_dc - > sids [ PRIMARY_USER_SID_INDEX ] . sid , base - > rid ) ) {
2023-05-11 01:40:27 +03:00
talloc_free ( user_info_dc ) ;
2011-01-20 15:39:37 +03:00
return NT_STATUS_INVALID_PARAMETER ;
}
2022-12-15 01:58:11 +03:00
user_info_dc - > sids [ PRIMARY_USER_SID_INDEX ] . attrs = SE_GROUP_DEFAULT_FLAGS ;
2011-01-20 15:39:37 +03:00
2022-09-27 05:13:12 +03:00
user_info_dc - > sids [ PRIMARY_GROUP_SID_INDEX ] . sid = * base - > domain_sid ;
if ( ! sid_append_rid ( & user_info_dc - > sids [ PRIMARY_GROUP_SID_INDEX ] . sid , base - > primary_gid ) ) {
2023-05-11 01:40:27 +03:00
talloc_free ( user_info_dc ) ;
2011-01-20 15:39:37 +03:00
return NT_STATUS_INVALID_PARAMETER ;
2009-01-21 12:43:15 +03:00
}
2022-09-27 05:13:12 +03:00
/*
* This attribute value might be wrong if the primary group is a
* resource group . But a resource group is not meant to be in a primary
* group in the first place , and besides , these attributes will never
* make their way into a PAC .
*/
2022-12-15 01:58:11 +03:00
user_info_dc - > sids [ PRIMARY_GROUP_SID_INDEX ] . attrs = SE_GROUP_DEFAULT_FLAGS ;
2009-01-21 12:43:15 +03:00
for ( i = 0 ; i < base - > groups . count ; i + + ) {
2022-09-27 05:13:12 +03:00
user_info_dc - > sids [ user_info_dc - > num_sids ] . sid = * base - > domain_sid ;
if ( ! sid_append_rid ( & user_info_dc - > sids [ user_info_dc - > num_sids ] . sid , base - > groups . rids [ i ] . rid ) ) {
2023-05-11 01:40:27 +03:00
talloc_free ( user_info_dc ) ;
2011-01-20 15:39:37 +03:00
return NT_STATUS_INVALID_PARAMETER ;
}
2022-09-27 05:13:12 +03:00
user_info_dc - > sids [ user_info_dc - > num_sids ] . attrs = base - > groups . rids [ i ] . attributes ;
2011-02-08 08:53:13 +03:00
user_info_dc - > num_sids + + ;
2009-01-21 12:43:15 +03:00
}
/* Copy 'other' sids. We need to do sid filtering here to
2011-02-09 08:05:54 +03:00
prevent possible elevation of privileges . See :
2009-01-21 12:43:15 +03:00
http : //www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
*/
2016-01-07 17:06:46 +03:00
/*
* The IDL layer would be a better place to check this , but to
* guard the integer addition below , we double - check
*/
if ( sidcount > UINT16_MAX ) {
2023-05-11 01:40:27 +03:00
talloc_free ( user_info_dc ) ;
2016-01-07 17:06:46 +03:00
return NT_STATUS_INVALID_PARAMETER ;
}
if ( sidcount > 0 ) {
2022-09-27 05:13:12 +03:00
struct auth_SidAttr * dgrps = user_info_dc - > sids ;
2016-01-07 17:06:46 +03:00
size_t dgrps_count ;
2011-01-20 15:39:37 +03:00
2016-01-07 17:06:46 +03:00
dgrps_count = user_info_dc - > num_sids + sidcount ;
2022-09-27 05:13:12 +03:00
dgrps = talloc_realloc ( user_info_dc , dgrps , struct auth_SidAttr ,
2016-01-07 17:06:46 +03:00
dgrps_count ) ;
if ( dgrps = = NULL ) {
2023-05-11 01:40:27 +03:00
talloc_free ( user_info_dc ) ;
2016-01-07 17:06:46 +03:00
return NT_STATUS_NO_MEMORY ;
2011-01-20 15:39:37 +03:00
}
2009-01-21 12:43:15 +03:00
2016-01-07 17:06:46 +03:00
for ( i = 0 ; i < sidcount ; i + + ) {
if ( sids [ i ] . sid ) {
2022-09-27 05:13:12 +03:00
dgrps [ user_info_dc - > num_sids ] . sid = * sids [ i ] . sid ;
dgrps [ user_info_dc - > num_sids ] . attrs = sids [ i ] . attributes ;
2016-01-07 17:06:46 +03:00
user_info_dc - > num_sids + + ;
2009-01-21 12:43:15 +03:00
}
}
2011-02-08 08:53:13 +03:00
user_info_dc - > sids = dgrps ;
2009-01-21 12:43:15 +03:00
/* Where are the 'global' sids?... */
}
2011-07-18 07:55:20 +04:00
status = make_user_info_SamBaseInfo ( user_info_dc , account_name , base , authenticated , & user_info_dc - > info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2023-05-11 01:40:27 +03:00
talloc_free ( user_info_dc ) ;
2011-07-18 07:55:20 +04:00
return status ;
2009-01-21 12:43:15 +03:00
}
2016-01-07 17:06:46 +03:00
if ( dns_domainname ! = NULL ) {
user_info_dc - > info - > dns_domain_name = talloc_strdup ( user_info_dc - > info ,
dns_domainname ) ;
if ( user_info_dc - > info - > dns_domain_name = = NULL ) {
2023-05-11 01:40:27 +03:00
talloc_free ( user_info_dc ) ;
2016-01-07 17:06:46 +03:00
return NT_STATUS_NO_MEMORY ;
}
}
if ( principal ! = NULL ) {
user_info_dc - > info - > user_principal_name = talloc_strdup ( user_info_dc - > info ,
principal ) ;
if ( user_info_dc - > info - > user_principal_name = = NULL ) {
2023-05-11 01:40:27 +03:00
talloc_free ( user_info_dc ) ;
2016-01-07 17:06:46 +03:00
return NT_STATUS_NO_MEMORY ;
}
}
2009-01-21 12:43:15 +03:00
/* ensure we are never given NULL session keys */
if ( all_zero ( base - > key . key , sizeof ( base - > key . key ) ) ) {
2011-02-08 08:53:13 +03:00
user_info_dc - > user_session_key = data_blob ( NULL , 0 ) ;
2009-01-21 12:43:15 +03:00
} else {
2011-02-08 08:53:13 +03:00
user_info_dc - > user_session_key = data_blob_talloc ( user_info_dc , base - > key . key , sizeof ( base - > key . key ) ) ;
2023-05-11 01:40:27 +03:00
if ( user_info_dc - > user_session_key . data = = NULL ) {
talloc_free ( user_info_dc ) ;
return NT_STATUS_NO_MEMORY ;
}
2009-01-21 12:43:15 +03:00
}
if ( all_zero ( base - > LMSessKey . key , sizeof ( base - > LMSessKey . key ) ) ) {
2011-02-08 08:53:13 +03:00
user_info_dc - > lm_session_key = data_blob ( NULL , 0 ) ;
2009-01-21 12:43:15 +03:00
} else {
2011-02-08 08:53:13 +03:00
user_info_dc - > lm_session_key = data_blob_talloc ( user_info_dc , base - > LMSessKey . key , sizeof ( base - > LMSessKey . key ) ) ;
2023-05-11 01:40:27 +03:00
if ( user_info_dc - > lm_session_key . data = = NULL ) {
talloc_free ( user_info_dc ) ;
return NT_STATUS_NO_MEMORY ;
}
2009-01-21 12:43:15 +03:00
}
2011-02-08 08:53:13 +03:00
* _user_info_dc = user_info_dc ;
2009-01-21 12:43:15 +03:00
return NT_STATUS_OK ;
}
2010-10-01 23:09:42 +04:00
/**
2022-12-02 00:49:20 +03:00
* Make a user_info_dc struct from the PAC_LOGON_INFO supplied in the krb5
* logon . For group_inclusion , pass AUTH_INCLUDE_RESOURCE_GROUPS if SIDs from
* the resource groups are to be included in the resulting structure , and pass
* AUTH_EXCLUDE_RESOURCE_GROUPS otherwise .
2010-10-01 23:09:42 +04:00
*/
2011-02-08 08:53:13 +03:00
NTSTATUS make_user_info_dc_pac ( TALLOC_CTX * mem_ctx ,
2016-01-07 16:50:27 +03:00
const struct PAC_LOGON_INFO * pac_logon_info ,
2016-01-07 16:55:07 +03:00
const struct PAC_UPN_DNS_INFO * pac_upn_dns_info ,
2022-12-02 00:49:20 +03:00
const enum auth_group_inclusion group_inclusion ,
2011-02-08 08:53:13 +03:00
struct auth_user_info_dc * * _user_info_dc )
2010-10-01 23:09:42 +04:00
{
uint32_t i ;
NTSTATUS nt_status ;
union netr_Validation validation ;
2011-02-08 08:53:13 +03:00
struct auth_user_info_dc * user_info_dc ;
2016-05-20 15:16:35 +03:00
const struct PAC_DOMAIN_GROUP_MEMBERSHIP * rg = NULL ;
size_t sidcount ;
2016-01-07 16:50:27 +03:00
validation . sam3 = discard_const_p ( struct netr_SamInfo3 , & pac_logon_info - > info3 ) ;
2010-10-01 23:09:42 +04:00
2011-07-18 07:55:20 +04:00
nt_status = make_user_info_dc_netlogon_validation ( mem_ctx , " " , 3 , & validation ,
true , /* This user was authenticated */
& user_info_dc ) ;
2010-10-01 23:09:42 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
}
2016-05-20 15:16:35 +03:00
if ( pac_logon_info - > info3 . base . user_flags & NETLOGON_RESOURCE_GROUPS ) {
2022-12-02 00:49:20 +03:00
switch ( group_inclusion ) {
case AUTH_INCLUDE_RESOURCE_GROUPS :
/* Take resource groups from the PAC. */
rg = & pac_logon_info - > resource_groups ;
break ;
case AUTH_EXCLUDE_RESOURCE_GROUPS :
/*
* The PAC is from a TGT , or we don ' t want to process
* its resource groups .
*/
break ;
default :
DBG_ERR ( " invalid group inclusion parameter: %u \n " , group_inclusion ) ;
2023-05-11 01:40:27 +03:00
talloc_free ( user_info_dc ) ;
2022-12-02 00:49:20 +03:00
return NT_STATUS_INVALID_PARAMETER ;
}
2016-05-20 15:16:35 +03:00
}
2022-11-07 09:37:12 +03:00
if ( rg ! = NULL & & rg - > groups . count > 0 ) {
2011-01-20 15:39:37 +03:00
/* The IDL layer would be a better place to check this, but to
* guard the integer addition below , we double - check */
2016-05-20 15:16:35 +03:00
if ( rg - > groups . count > 65535 ) {
2011-02-08 08:53:13 +03:00
talloc_free ( user_info_dc ) ;
2011-01-20 15:39:37 +03:00
return NT_STATUS_INVALID_PARAMETER ;
}
/*
Here is where we should check the list of
trusted domains , and verify that the SID
matches .
*/
2016-05-20 15:16:35 +03:00
if ( rg - > domain_sid = = NULL ) {
talloc_free ( user_info_dc ) ;
2023-07-31 07:06:56 +03:00
DEBUG ( 0 , ( " Cannot operate on a PAC without a resource domain SID \n " ) ) ;
2011-01-20 15:39:37 +03:00
return NT_STATUS_INVALID_PARAMETER ;
}
2016-05-20 15:16:35 +03:00
sidcount = user_info_dc - > num_sids + rg - > groups . count ;
2011-02-08 08:53:13 +03:00
user_info_dc - > sids
2022-09-27 05:13:12 +03:00
= talloc_realloc ( user_info_dc , user_info_dc - > sids , struct auth_SidAttr , sidcount ) ;
2014-02-13 08:51:11 +04:00
if ( user_info_dc - > sids = = NULL ) {
TALLOC_FREE ( user_info_dc ) ;
return NT_STATUS_NO_MEMORY ;
}
2010-10-01 23:09:42 +04:00
2016-05-20 15:16:35 +03:00
for ( i = 0 ; i < rg - > groups . count ; i + + ) {
bool ok ;
2022-09-27 05:13:12 +03:00
user_info_dc - > sids [ user_info_dc - > num_sids ] . sid = * rg - > domain_sid ;
ok = sid_append_rid ( & user_info_dc - > sids [ user_info_dc - > num_sids ] . sid ,
2016-05-20 15:16:35 +03:00
rg - > groups . rids [ i ] . rid ) ;
if ( ! ok ) {
2023-05-11 01:40:27 +03:00
talloc_free ( user_info_dc ) ;
2011-01-20 15:39:37 +03:00
return NT_STATUS_INVALID_PARAMETER ;
}
2022-09-27 05:13:12 +03:00
user_info_dc - > sids [ user_info_dc - > num_sids ] . attrs = rg - > groups . rids [ i ] . attributes ;
2011-02-08 08:53:13 +03:00
user_info_dc - > num_sids + + ;
2010-10-01 23:09:42 +04:00
}
}
2016-01-07 16:55:07 +03:00
if ( pac_upn_dns_info ! = NULL ) {
2022-02-22 04:15:43 +03:00
if ( pac_upn_dns_info - > upn_name ! = NULL ) {
user_info_dc - > info - > user_principal_name =
talloc_strdup ( user_info_dc - > info ,
pac_upn_dns_info - > upn_name ) ;
if ( user_info_dc - > info - > user_principal_name = = NULL ) {
2023-05-11 01:40:27 +03:00
talloc_free ( user_info_dc ) ;
2022-02-22 04:15:43 +03:00
return NT_STATUS_NO_MEMORY ;
}
2016-01-07 16:55:07 +03:00
}
user_info_dc - > info - > dns_domain_name =
talloc_strdup ( user_info_dc - > info ,
pac_upn_dns_info - > dns_domain_name ) ;
if ( user_info_dc - > info - > dns_domain_name = = NULL ) {
2023-05-11 01:40:27 +03:00
talloc_free ( user_info_dc ) ;
2016-01-07 16:55:07 +03:00
return NT_STATUS_NO_MEMORY ;
}
if ( pac_upn_dns_info - > flags & PAC_UPN_DNS_FLAG_CONSTRUCTED ) {
user_info_dc - > info - > user_principal_constructed = true ;
}
}
2011-02-08 08:53:13 +03:00
* _user_info_dc = user_info_dc ;
2010-10-01 23:09:42 +04:00
return NT_STATUS_OK ;
}