1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-08 21:18:16 +03:00

r4673: Fix the IDL for the QuerySecret LSA call.

This call uses a new IDL type, NTTIME_hyper.  This is 8-byte aligned,
as the name suggests.

Expand the QuerySecret LSA calls in RPC-SAMLOGON and RPC-LSA, to
validate the behaviour of times, and of the old secrets.

Thanks to tridge for spotting the use of HYPER!

Andrew Bartlett
(This used to be commit 1fed79cb0f)
This commit is contained in:
Andrew Bartlett 2005-01-11 05:16:43 +00:00 committed by Gerald (Jerry) Carter
parent 70071c2114
commit 462ef44745
6 changed files with 162 additions and 51 deletions

View File

@ -301,7 +301,8 @@ my %type_alignments =
"WERROR" => 4,
"boolean32" => 4,
"unsigned32" => 4,
"HYPER_T" => 8
"HYPER_T" => 8,
"NTTIME_hyper" => 8
);
sub is_scalar_type($)

View File

@ -196,14 +196,17 @@ typedef struct data_blob {
size_t length;
} DATA_BLOB;
/* 64 bit time (100 nanosec) 1601 - cifs6.txt, section 3.5, page 30 */
typedef uint64_t NTTIME;
/* 64 bit time (1 sec) 1601 - in the NDR blob but mapped to NTTIME */
#define NTTIME_1sec NTTIME
/* 8 byte aligned 'hyper' type from MS IDL */
typedef uint64_t HYPER_T;
/* 64 bit time (100 nanosec) 1601 - cifs6.txt, section 3.5, page 30 */
typedef uint64_t NTTIME;
/* 64 bit time (100 nanosec) 1601, but 8 byte aligned 'hyper' type */
#define NTTIME_hyper NTTIME
/* 64 bit time (1 sec) 1601 - in the NDR blob but mapped to NTTIME */
#define NTTIME_1sec NTTIME
/* the basic packet size, assuming no words or bytes. Does not include the NBT header */
#define MIN_SMB_SIZE 35

View File

@ -557,9 +557,9 @@
NTSTATUS lsa_QuerySecret (
[in,ref] policy_handle *handle,
[in,out] lsa_DATA_BUF_PTR *new_val,
[in,out] NTTIME *new_mtime,
[in,out] NTTIME_hyper *new_mtime,
[in,out] lsa_DATA_BUF_PTR *old_val,
[in,out] NTTIME *old_mtime
[in,out] NTTIME_hyper *old_mtime
);
/* Function: 0x1f */

View File

@ -965,7 +965,7 @@ NTSTATUS ndr_push_NTTIME_1sec(struct ndr_push *ndr, NTTIME t)
}
/*
pull a NTTIME
pull a NTTIME_1sec
*/
NTSTATUS ndr_pull_NTTIME_1sec(struct ndr_pull *ndr, NTTIME *t)
{
@ -974,6 +974,24 @@ NTSTATUS ndr_pull_NTTIME_1sec(struct ndr_pull *ndr, NTTIME *t)
return NT_STATUS_OK;
}
/*
pull a NTTIME_hyper
*/
NTSTATUS ndr_pull_NTTIME_hyper(struct ndr_pull *ndr, NTTIME_hyper *t)
{
NDR_CHECK(ndr_pull_HYPER_T(ndr, t));
return NT_STATUS_OK;
}
/*
push a NTTIME_hyper
*/
NTSTATUS ndr_push_NTTIME_hyper(struct ndr_push *ndr, NTTIME_hyper t)
{
NDR_CHECK(ndr_push_HYPER_T(ndr, t));
return NT_STATUS_OK;
}
/*
push a time_t
*/
@ -1082,7 +1100,12 @@ void ndr_print_NTTIME(struct ndr_print *ndr, const char *name, NTTIME t)
ndr->print(ndr, "%-25s: %s", name, nt_time_string(ndr, t));
}
void ndr_print_NTTIME_1sec(struct ndr_print *ndr, const char *name, NTTIME t)
void ndr_print_NTTIME_1sec(struct ndr_print *ndr, const char *name, NTTIME_1sec t)
{
ndr_print_NTTIME(ndr, name, t * 10000000);
}
void ndr_print_NTTIME_hyper(struct ndr_print *ndr, const char *name, NTTIME_hyper t)
{
ndr_print_NTTIME(ndr, name, t);
}

View File

@ -684,6 +684,7 @@ static BOOL test_CreateSecret(struct dcerpc_pipe *p,
struct lsa_Delete d;
struct lsa_DATA_BUF buf1;
struct lsa_DATA_BUF_PTR bufp1;
struct lsa_DATA_BUF_PTR bufp2;
DATA_BLOB enc_key;
BOOL ret = True;
DATA_BLOB session_key;
@ -769,24 +770,24 @@ static BOOL test_CreateSecret(struct dcerpc_pipe *p,
if (!NT_STATUS_IS_OK(status)) {
printf("QuerySecret failed - %s\n", nt_errstr(status));
ret = False;
}
if (r4.out.new_val->buf == NULL) {
printf("No secret buffer returned\n");
ret = False;
} else {
blob1.data = r4.out.new_val->buf->data;
blob1.length = r4.out.new_val->buf->length;
blob2 = data_blob(NULL, blob1.length);
secret2 = sess_decrypt_string(&blob1, &session_key);
printf("returned secret '%s'\n", secret2);
if (strcmp(secret1, secret2) != 0) {
printf("Returned secret doesn't match\n");
if (r4.out.new_val->buf == NULL) {
printf("No secret buffer returned\n");
ret = False;
} else {
blob1.data = r4.out.new_val->buf->data;
blob1.length = r4.out.new_val->buf->length;
blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length);
secret2 = sess_decrypt_string(&blob1, &session_key);
printf("returned secret '%s'\n", secret2);
if (strcmp(secret1, secret2) != 0) {
printf("Returned secret doesn't match\n");
ret = False;
}
}
}
@ -816,36 +817,60 @@ static BOOL test_CreateSecret(struct dcerpc_pipe *p,
r6.in.handle = &sec_handle;
r6.in.new_val = &bufp1;
r6.in.new_mtime = &new_mtime;
r6.in.old_val = NULL;
r6.in.old_mtime = NULL;
r6.in.old_val = &bufp2;
r6.in.old_mtime = &old_mtime;
bufp1.buf = NULL;
bufp2.buf = NULL;
status = dcerpc_lsa_QuerySecret(p, mem_ctx, &r6);
if (!NT_STATUS_IS_OK(status)) {
printf("QuerySecret failed - %s\n", nt_errstr(status));
ret = False;
}
if (r6.out.new_val->buf == NULL) {
printf("No secret buffer returned\n");
ret = False;
} else {
blob1.data = r6.out.new_val->buf->data;
blob1.length = r6.out.new_val->buf->length;
blob2 = data_blob(NULL, blob1.length);
secret4 = sess_decrypt_string(&blob1, &session_key);
printf("returned secret '%s'\n", secret3);
if (strcmp(secret3, secret4) != 0) {
printf("Returned secret %s doesn't match %s\n", secret4, secret3);
if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL
|| r6.out.new_mtime == NULL || r6.out.old_mtime == NULL) {
printf("Both secret buffers and both times not returned\n");
ret = False;
} else {
blob1.data = r6.out.new_val->buf->data;
blob1.length = r6.out.new_val->buf->length;
blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length);
secret4 = sess_decrypt_string(&blob1, &session_key);
printf("returned secret '%s'\n", secret4);
if (strcmp(secret3, secret4) != 0) {
printf("Returned NEW secret %s doesn't match %s\n", secret4, secret3);
ret = False;
}
blob1.data = r6.out.new_val->buf->data;
blob1.length = r6.out.new_val->buf->length;
blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length);
secret2 = sess_decrypt_string(&blob1, &session_key);
printf("returned OLD secret '%s'\n", secret2);
if (strcmp(secret3, secret4) != 0) {
printf("Returned secret %s doesn't match %s\n", secret2, secret1);
ret = False;
}
if (*r6.out.new_mtime == *r6.out.old_mtime) {
printf("Returned secret %s had same mtime for both secrets: %s\n",
secname[i],
nt_time_string(mem_ctx, *r6.out.new_mtime));
ret = False;
}
}
}
if (!test_Delete(p, mem_ctx, &sec_handle)) {
ret = False;
}

View File

@ -121,6 +121,7 @@ struct samsync_secret {
struct samsync_secret *prev, *next;
DATA_BLOB secret;
char *name;
NTTIME mtime;
};
struct samsync_trusted_domain {
@ -699,11 +700,14 @@ static BOOL samsync_handle_secret(TALLOC_CTX *mem_ctx, struct samsync_state *sam
struct netr_DELTA_SECRET *secret = delta->delta_union.secret;
const char *name = delta->delta_id_union.name;
struct samsync_secret *new = talloc_p(samsync_state, struct samsync_secret);
struct samsync_secret *old = talloc_p(mem_ctx, struct samsync_secret);
struct lsa_QuerySecret q;
struct lsa_OpenSecret o;
struct policy_handle sec_handle;
struct lsa_DATA_BUF_PTR bufp1;
struct lsa_DATA_BUF_PTR bufp2;
NTTIME new_mtime;
NTTIME old_mtime;
BOOL ret = True;
DATA_BLOB lsa_blob1, lsa_blob_out, session_key;
NTSTATUS status;
@ -716,9 +720,14 @@ static BOOL samsync_handle_secret(TALLOC_CTX *mem_ctx, struct samsync_state *sam
new->name = talloc_reference(new, name);
new->secret = data_blob_talloc(new, secret->current_cipher.cipher_data, secret->current_cipher.maxlen);
new->mtime = secret->current_cipher_set_time;
DLIST_ADD(samsync_state->secrets, new);
old->name = talloc_reference(old, name);
old->secret = data_blob_const(secret->old_cipher.cipher_data, secret->old_cipher.maxlen);
old->mtime = secret->old_cipher_set_time;
o.in.handle = samsync_state->lsa_handle;
o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
o.in.name.string = name;
@ -742,22 +751,63 @@ static BOOL samsync_handle_secret(TALLOC_CTX *mem_ctx, struct samsync_state *sam
ZERO_STRUCT(new_mtime);
ZERO_STRUCT(old_mtime);
/* fetch the secret back again */
q.in.handle = &sec_handle;
q.in.new_val = &bufp1;
q.in.new_mtime = &new_mtime;
q.in.old_val = NULL;
q.in.old_mtime = NULL;
q.in.old_val = &bufp2;
q.in.old_mtime = &old_mtime;
bufp1.buf = NULL;
bufp2.buf = NULL;
status = dcerpc_lsa_QuerySecret(samsync_state->p_lsa, mem_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, status)) {
/* some things are just off limits */
return True;
} else if (!NT_STATUS_IS_OK(status)) {
printf("QuerySecret failed - %s\n", nt_errstr(status));
return False;
}
if (q.out.old_val->buf == NULL) {
/* probably just not available due to ACLs */
} else {
lsa_blob1.data = q.out.old_val->buf->data;
lsa_blob1.length = q.out.old_val->buf->length;
lsa_blob_out = sess_decrypt_blob(mem_ctx, &lsa_blob1, &session_key);
if (!q.out.old_mtime) {
printf("OLD mtime not available on LSA for secret %s\n", old->name);
ret = False;
}
if (old->mtime != *q.out.old_mtime) {
printf("OLD mtime on secret %s does not match between SAMSYNC (%s) and LSA (%s)\n",
old->name, nt_time_string(mem_ctx, old->mtime),
nt_time_string(mem_ctx, *q.out.old_mtime));
ret = False;
}
if (old->secret.length != lsa_blob_out.length) {
printf("Returned secret %s doesn't match: %d != %d\n",
old->name, old->secret.length, lsa_blob_out.length);
ret = False;
} else if (memcmp(lsa_blob_out.data,
old->secret.data, old->secret.length) != 0) {
printf("Returned secret %s doesn't match: \n",
old->name);
DEBUG(1, ("SamSync Secret:\n"));
dump_data(1, old->secret.data, old->secret.length);
DEBUG(1, ("LSA Secret:\n"));
dump_data(1, lsa_blob_out.data, lsa_blob_out.length);
ret = False;
}
}
if (q.out.new_val->buf == NULL) {
/* probably just not available due to ACLs */
} else {
@ -766,13 +816,22 @@ static BOOL samsync_handle_secret(TALLOC_CTX *mem_ctx, struct samsync_state *sam
lsa_blob_out = sess_decrypt_blob(mem_ctx, &lsa_blob1, &session_key);
if (!q.out.new_mtime) {
printf("NEW mtime not available on LSA for secret %s\n", new->name);
ret = False;
}
if (new->mtime != *q.out.new_mtime) {
printf("NEW mtime on secret %s does not match between SAMSYNC (%s) and LSA (%s)\n",
new->name, nt_time_string(mem_ctx, new->mtime),
nt_time_string(mem_ctx, *q.out.new_mtime));
ret = False;
}
if (new->secret.length != lsa_blob_out.length) {
printf("Returned secret %s doesn't match: %d != %d\n",
new->name, new->secret.length, lsa_blob_out.length);
ret = False;
}
if (memcmp(lsa_blob_out.data,
} else if (memcmp(lsa_blob_out.data,
new->secret.data, new->secret.length) != 0) {
printf("Returned secret %s doesn't match: \n",
new->name);