mirror of
https://github.com/samba-team/samba.git
synced 2025-02-25 17:57:42 +03:00
CVE-2021-20251 auth4: Split authsam_calculate_lastlogon_sync_interval() out
authsam_calculate_lastlogon_sync_interval() is split out of authsam_update_lastlogon_timestamp() Based on work by Gary Lockyer <gary@catalyst.net.nz> BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611 Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz> Reviewed-by: Andreas Schneider <asn@samba.org>
This commit is contained in:
parent
b954acfde2
commit
55147335ae
@ -1247,18 +1247,8 @@ error:
|
||||
|
||||
}
|
||||
|
||||
static NTSTATUS authsam_update_lastlogon_timestamp(struct ldb_context *sam_ctx,
|
||||
struct ldb_message *msg_mod,
|
||||
struct ldb_dn *domain_dn,
|
||||
NTTIME old_timestamp,
|
||||
NTTIME now)
|
||||
{
|
||||
/*
|
||||
* We only set lastLogonTimestamp if the current value is older than
|
||||
* now - msDS-LogonTimeSyncInterval days.
|
||||
*
|
||||
* msDS-LogonTimeSyncInterval is an int32_t number of days, while
|
||||
* lastLogonTimestamp is in the 64 bit 100ns NTTIME format.
|
||||
/*
|
||||
* msDS-LogonTimeSyncInterval is an int32_t number of days.
|
||||
*
|
||||
* The docs say: "the initial update, after the domain functional
|
||||
* level is raised to DS_BEHAVIOR_WIN2003 or higher, is calculated as
|
||||
@ -1269,18 +1259,24 @@ static NTSTATUS authsam_update_lastlogon_timestamp(struct ldb_context *sam_ctx,
|
||||
* Dochelp referred us to the following blog post:
|
||||
* http://blogs.technet.com/b/askds/archive/2009/04/15/the-lastlogontimestamp-attribute-what-it-was-designed-for-and-how-it-works.aspx
|
||||
*
|
||||
* en msDS-LogonTimeSyncInterval is zero, the lastLogonTimestamp is
|
||||
* when msDS-LogonTimeSyncInterval is zero, the lastLogonTimestamp is
|
||||
* not changed.
|
||||
*/
|
||||
|
||||
static NTSTATUS authsam_calculate_lastlogon_sync_interval(
|
||||
struct ldb_context *sam_ctx,
|
||||
TALLOC_CTX *ctx,
|
||||
struct ldb_dn *domain_dn,
|
||||
NTTIME *sync_interval_nt)
|
||||
{
|
||||
static const char *attrs[] = { "msDS-LogonTimeSyncInterval",
|
||||
NULL };
|
||||
int ret;
|
||||
struct ldb_result *domain_res = NULL;
|
||||
TALLOC_CTX *mem_ctx = NULL;
|
||||
int32_t sync_interval;
|
||||
NTTIME sync_interval_nt;
|
||||
uint32_t sync_interval;
|
||||
|
||||
mem_ctx = talloc_new(msg_mod);
|
||||
mem_ctx = talloc_new(ctx);
|
||||
if (mem_ctx == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
@ -1296,15 +1292,7 @@ static NTSTATUS authsam_update_lastlogon_timestamp(struct ldb_context *sam_ctx,
|
||||
"msDS-LogonTimeSyncInterval",
|
||||
14);
|
||||
DEBUG(5, ("sync interval is %d\n", sync_interval));
|
||||
if (sync_interval == 0){
|
||||
/*
|
||||
* Setting msDS-LogonTimeSyncInterval to zero is how you ask
|
||||
* that nothing happens here.
|
||||
*/
|
||||
TALLOC_FREE(mem_ctx);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
else if (sync_interval >= 5){
|
||||
if (sync_interval >= 5){
|
||||
/*
|
||||
* Subtract "a random percentage of 5" days. Presumably this
|
||||
* percentage is between 0 and 100, and modulus is accurate
|
||||
@ -1312,17 +1300,47 @@ static NTSTATUS authsam_update_lastlogon_timestamp(struct ldb_context *sam_ctx,
|
||||
*/
|
||||
uint32_t r = generate_random() % 6;
|
||||
sync_interval -= r;
|
||||
DEBUG(5, ("randomised sync interval is %d (-%d)\n", sync_interval, r));
|
||||
DBG_INFO("randomised sync interval is %d (-%d)\n", sync_interval, r);
|
||||
}
|
||||
/* In the case where sync_interval < 5 there is no randomisation */
|
||||
|
||||
sync_interval_nt = sync_interval * 24LL * 3600LL * 10000000LL;
|
||||
/*
|
||||
* msDS-LogonTimeSyncInterval is an int32_t number of days,
|
||||
* while lastLogonTimestamp (to be updated) is in the 64 bit
|
||||
* 100ns NTTIME format so we must convert.
|
||||
*/
|
||||
*sync_interval_nt = sync_interval * 24LL * 3600LL * 10000000LL;
|
||||
TALLOC_FREE(mem_ctx);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We only set lastLogonTimestamp if the current value is older than
|
||||
* now - msDS-LogonTimeSyncInterval days.
|
||||
*
|
||||
* lastLogonTimestamp is in the 64 bit 100ns NTTIME format
|
||||
*/
|
||||
static NTSTATUS authsam_update_lastlogon_timestamp(struct ldb_context *sam_ctx,
|
||||
struct ldb_message *msg_mod,
|
||||
struct ldb_dn *domain_dn,
|
||||
NTTIME old_timestamp,
|
||||
NTTIME now,
|
||||
NTTIME sync_interval_nt)
|
||||
{
|
||||
int ret;
|
||||
DEBUG(5, ("old timestamp is %lld, threshold %lld, diff %lld\n",
|
||||
(long long int)old_timestamp,
|
||||
(long long int)(now - sync_interval_nt),
|
||||
(long long int)(old_timestamp - now + sync_interval_nt)));
|
||||
|
||||
if (sync_interval_nt == 0){
|
||||
/*
|
||||
* Setting msDS-LogonTimeSyncInterval to zero is how you ask
|
||||
* that nothing happens here.
|
||||
*/
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
if (old_timestamp > now){
|
||||
DEBUG(0, ("lastLogonTimestamp is in the future! (%lld > %lld)\n",
|
||||
(long long int)old_timestamp, (long long int)now));
|
||||
@ -1337,11 +1355,9 @@ static NTSTATUS authsam_update_lastlogon_timestamp(struct ldb_context *sam_ctx,
|
||||
"lastLogonTimestamp", now);
|
||||
|
||||
if (ret != LDB_SUCCESS) {
|
||||
TALLOC_FREE(mem_ctx);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
TALLOC_FREE(mem_ctx);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
@ -1550,8 +1566,23 @@ get_transaction:
|
||||
}
|
||||
|
||||
if (!am_rodc) {
|
||||
status = authsam_update_lastlogon_timestamp(sam_ctx, msg_mod, domain_dn,
|
||||
lastLogonTimestamp, now);
|
||||
NTTIME sync_interval_nt;
|
||||
|
||||
status = authsam_calculate_lastlogon_sync_interval(
|
||||
sam_ctx, mem_ctx, domain_dn, &sync_interval_nt);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
status = NT_STATUS_INTERNAL_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
status = authsam_update_lastlogon_timestamp(
|
||||
sam_ctx,
|
||||
msg_mod,
|
||||
domain_dn,
|
||||
lastLogonTimestamp,
|
||||
now,
|
||||
sync_interval_nt);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
status = NT_STATUS_NO_MEMORY;
|
||||
goto error;
|
||||
|
Loading…
x
Reference in New Issue
Block a user