mirror of
https://github.com/samba-team/samba.git
synced 2025-11-11 00:23:51 +03:00
r1030: added server side schannel support
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
ee6c17f373
commit
2ac79dfba0
@@ -23,6 +23,17 @@ interface dcerpc
|
|||||||
dcerpc_syntax_id transfer_syntaxes[num_transfer_syntaxes];
|
dcerpc_syntax_id transfer_syntaxes[num_transfer_syntaxes];
|
||||||
} dcerpc_ctx_list;
|
} dcerpc_ctx_list;
|
||||||
|
|
||||||
|
/*
|
||||||
|
a schannel bind blob - used in auth_info
|
||||||
|
on a schannel bind
|
||||||
|
*/
|
||||||
|
typedef [public] struct {
|
||||||
|
uint32 unknown1;
|
||||||
|
uint32 unknown2;
|
||||||
|
astring domain;
|
||||||
|
astring hostname;
|
||||||
|
} dcerpc_bind_schannel;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16 max_xmit_frag;
|
uint16 max_xmit_frag;
|
||||||
uint16 max_recv_frag;
|
uint16 max_recv_frag;
|
||||||
|
|||||||
@@ -50,6 +50,11 @@
|
|||||||
*/
|
*/
|
||||||
#define ascstr_noterm [flag(STR_NOTERM|STR_ASCII|STR_SIZE4|STR_LEN4)] string
|
#define ascstr_noterm [flag(STR_NOTERM|STR_ASCII|STR_SIZE4|STR_LEN4)] string
|
||||||
|
|
||||||
|
/*
|
||||||
|
a null terminated ascii string
|
||||||
|
*/
|
||||||
|
#define astring [flag(STR_ASCII|STR_NULLTERM)] string
|
||||||
|
|
||||||
|
|
||||||
#define NDR_NOALIGN LIBNDR_FLAG_NOALIGN
|
#define NDR_NOALIGN LIBNDR_FLAG_NOALIGN
|
||||||
#define NDR_REMAINING LIBNDR_FLAG_REMAINING
|
#define NDR_REMAINING LIBNDR_FLAG_REMAINING
|
||||||
|
|||||||
@@ -497,6 +497,17 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
|
|||||||
(*s) = as;
|
(*s) = as;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM:
|
||||||
|
len1 = strnlen(ndr->data+ndr->offset, (ndr->data_size - ndr->offset));
|
||||||
|
if (len1+1 <= ndr->data_size - ndr->offset) {
|
||||||
|
len1++;
|
||||||
|
}
|
||||||
|
NDR_ALLOC_N(ndr, as, (len1+1));
|
||||||
|
NDR_CHECK(ndr_pull_bytes(ndr, as, len1));
|
||||||
|
as[len1] = 0;
|
||||||
|
(*s) = as;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
|
return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
|
||||||
ndr->flags & LIBNDR_STRING_FLAGS);
|
ndr->flags & LIBNDR_STRING_FLAGS);
|
||||||
@@ -639,6 +650,18 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
|
|||||||
ndr->offset += c_len + 1;
|
ndr->offset += c_len + 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM:
|
||||||
|
NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
|
||||||
|
ret = convert_string(CH_UNIX, CH_DOS,
|
||||||
|
s, s_len+1,
|
||||||
|
ndr->data+ndr->offset, c_len + 1);
|
||||||
|
if (ret == -1) {
|
||||||
|
return ndr_push_error(ndr, NDR_ERR_CHARCNV,
|
||||||
|
"Bad character conversion");
|
||||||
|
}
|
||||||
|
ndr->offset += c_len + 1;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return ndr_push_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
|
return ndr_push_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
|
||||||
ndr->flags & LIBNDR_STRING_FLAGS);
|
ndr->flags & LIBNDR_STRING_FLAGS);
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ NTSTATUS dcerpc_bind_auth_schannel_key(struct dcerpc_pipe *p,
|
|||||||
uint8_t full_session_key[16];
|
uint8_t full_session_key[16];
|
||||||
struct schannel_state *schannel_state;
|
struct schannel_state *schannel_state;
|
||||||
const char *workgroup, *workstation;
|
const char *workgroup, *workstation;
|
||||||
|
struct dcerpc_bind_schannel bind_schannel;
|
||||||
|
|
||||||
memcpy(full_session_key, session_key, 8);
|
memcpy(full_session_key, session_key, 8);
|
||||||
memset(full_session_key+8, 0, 8);
|
memset(full_session_key+8, 0, 8);
|
||||||
@@ -203,21 +204,17 @@ NTSTATUS dcerpc_bind_auth_schannel_key(struct dcerpc_pipe *p,
|
|||||||
p->auth_info->auth_context_id = random();
|
p->auth_info->auth_context_id = random();
|
||||||
p->security_state = NULL;
|
p->security_state = NULL;
|
||||||
|
|
||||||
p->auth_info->credentials = data_blob_talloc(p->mem_ctx,
|
/* TODO: what are these?? */
|
||||||
NULL,
|
bind_schannel.unknown1 = 0;
|
||||||
8 +
|
bind_schannel.unknown2 = 3;
|
||||||
strlen(workgroup)+1 +
|
bind_schannel.domain = workgroup;
|
||||||
strlen(workstation)+1);
|
bind_schannel.hostname = workstation;
|
||||||
if (!p->auth_info->credentials.data) {
|
|
||||||
return NT_STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* oh, this is ugly! */
|
status = ndr_push_struct_blob(&p->auth_info->credentials, p->mem_ctx, &bind_schannel,
|
||||||
SIVAL(p->auth_info->credentials.data, 0, 0);
|
(ndr_push_flags_fn_t)ndr_push_dcerpc_bind_schannel);
|
||||||
SIVAL(p->auth_info->credentials.data, 4, 3);
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
memcpy(p->auth_info->credentials.data+8, workgroup, strlen(workgroup)+1);
|
goto done;
|
||||||
memcpy(p->auth_info->credentials.data+8+strlen(workgroup)+1,
|
}
|
||||||
workstation, strlen(workstation)+1);
|
|
||||||
|
|
||||||
/* send the authenticated bind request */
|
/* send the authenticated bind request */
|
||||||
status = dcerpc_bind_byuuid(p, p->mem_ctx, uuid, version);
|
status = dcerpc_bind_byuuid(p, p->mem_ctx, uuid, version);
|
||||||
|
|||||||
@@ -483,7 +483,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **p,
|
|||||||
(*p)->flags = binding->flags;
|
(*p)->flags = binding->flags;
|
||||||
|
|
||||||
if (binding->flags & DCERPC_SCHANNEL) {
|
if (binding->flags & DCERPC_SCHANNEL) {
|
||||||
const char *trust_password = secrets_fetch_machine_password();
|
const char *trust_password = NULL; // samdb_fetch_member_password();
|
||||||
if (!trust_password) {
|
if (!trust_password) {
|
||||||
DEBUG(0,("Unable to fetch machine password\n"));
|
DEBUG(0,("Unable to fetch machine password\n"));
|
||||||
goto done;
|
goto done;
|
||||||
@@ -635,9 +635,9 @@ NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **p,
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
create a secondary dcerpc connection on SMB
|
create a secondary dcerpc connection from a primary SMB connection
|
||||||
the secondary connection will be on the same SMB connection, but
|
|
||||||
use a new fnum
|
the secondary connection will be on the same SMB connection, but use a new fnum
|
||||||
*/
|
*/
|
||||||
NTSTATUS dcerpc_secondary_smb(struct dcerpc_pipe *p, struct dcerpc_pipe **p2,
|
NTSTATUS dcerpc_secondary_smb(struct dcerpc_pipe *p, struct dcerpc_pipe **p2,
|
||||||
const char *pipe_name,
|
const char *pipe_name,
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ ADD_OBJ_FILES = \
|
|||||||
rpc_server/dcesrv_auth.o \
|
rpc_server/dcesrv_auth.o \
|
||||||
rpc_server/dcesrv_crypto.o \
|
rpc_server/dcesrv_crypto.o \
|
||||||
rpc_server/dcesrv_crypto_ntlmssp.o \
|
rpc_server/dcesrv_crypto_ntlmssp.o \
|
||||||
|
rpc_server/dcesrv_crypto_schannel.o \
|
||||||
rpc_server/handles.o
|
rpc_server/handles.o
|
||||||
#
|
#
|
||||||
# End SUBSYSTEM DCERPC
|
# End SUBSYSTEM DCERPC
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ struct dcesrv_handle {
|
|||||||
struct dcesrv_crypto_ops {
|
struct dcesrv_crypto_ops {
|
||||||
const char *name;
|
const char *name;
|
||||||
uint8 auth_type;
|
uint8 auth_type;
|
||||||
NTSTATUS (*start)(struct dcesrv_auth *auth);
|
NTSTATUS (*start)(struct dcesrv_auth *auth, DATA_BLOB *auth_blob);
|
||||||
NTSTATUS (*update)(struct dcesrv_auth *auth, TALLOC_CTX *out_mem_ctx,
|
NTSTATUS (*update)(struct dcesrv_auth *auth, TALLOC_CTX *out_mem_ctx,
|
||||||
const DATA_BLOB in, DATA_BLOB *out);
|
const DATA_BLOB in, DATA_BLOB *out);
|
||||||
NTSTATUS (*session_info)(struct dcesrv_auth *auth, struct auth_session_info **session_info);
|
NTSTATUS (*session_info)(struct dcesrv_auth *auth, struct auth_session_info **session_info);
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ BOOL dcesrv_auth_bind(struct dcesrv_call_state *call)
|
|||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = dcesrv_crypto_start(&dce_conn->auth_state);
|
status = dcesrv_crypto_start(&dce_conn->auth_state, &dce_conn->auth_state.auth_info->credentials);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,9 +68,9 @@ NTSTATUS dcesrv_crypto_select_type(struct dcesrv_connection *dce_conn,
|
|||||||
/*
|
/*
|
||||||
start crypto state
|
start crypto state
|
||||||
*/
|
*/
|
||||||
NTSTATUS dcesrv_crypto_start(struct dcesrv_auth *auth)
|
NTSTATUS dcesrv_crypto_start(struct dcesrv_auth *auth, DATA_BLOB *auth_blob)
|
||||||
{
|
{
|
||||||
return auth->crypto_ctx.ops->start(auth);
|
return auth->crypto_ctx.ops->start(auth, auth_blob);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -138,10 +138,8 @@ void dcesrv_crypto_end(struct dcesrv_auth *auth)
|
|||||||
const struct dcesrv_crypto_ops *dcesrv_crypto_backend_bytype(uint8_t auth_type)
|
const struct dcesrv_crypto_ops *dcesrv_crypto_backend_bytype(uint8_t auth_type)
|
||||||
{
|
{
|
||||||
switch (auth_type) {
|
switch (auth_type) {
|
||||||
#if 0
|
|
||||||
case DCERPC_AUTH_TYPE_SCHANNEL:
|
case DCERPC_AUTH_TYPE_SCHANNEL:
|
||||||
return dcesrv_crypto_schannel_get_ops();
|
return dcesrv_crypto_schannel_get_ops();
|
||||||
#endif
|
|
||||||
case DCERPC_AUTH_TYPE_NTLMSSP:
|
case DCERPC_AUTH_TYPE_NTLMSSP:
|
||||||
return dcesrv_crypto_ntlmssp_get_ops();
|
return dcesrv_crypto_ntlmssp_get_ops();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
this provides a crypto interface to the various backends (such as
|
this provides the NTLMSSP backend for server side rpc
|
||||||
NTLMSSP and SCHANNEL) for the rpc server code
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
@@ -32,11 +31,15 @@
|
|||||||
/*
|
/*
|
||||||
start crypto state
|
start crypto state
|
||||||
*/
|
*/
|
||||||
static NTSTATUS dcesrv_crypto_ntlmssp_start(struct dcesrv_auth *auth)
|
static NTSTATUS dcesrv_crypto_ntlmssp_start(struct dcesrv_auth *auth, DATA_BLOB *auth_blob)
|
||||||
{
|
{
|
||||||
struct auth_ntlmssp_state *ntlmssp = NULL;
|
struct auth_ntlmssp_state *ntlmssp = NULL;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
|
/* TODO: we should parse the auth_blob and remember the client
|
||||||
|
hostname and target domain, then check against the auth3
|
||||||
|
bind packet */
|
||||||
|
|
||||||
status = auth_ntlmssp_start(&ntlmssp);
|
status = auth_ntlmssp_start(&ntlmssp);
|
||||||
|
|
||||||
auth->crypto_ctx.private_data = ntlmssp;
|
auth->crypto_ctx.private_data = ntlmssp;
|
||||||
|
|||||||
170
source/rpc_server/dcesrv_crypto_schannel.c
Normal file
170
source/rpc_server/dcesrv_crypto_schannel.c
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
Unix SMB/CIFS implementation.
|
||||||
|
|
||||||
|
server side dcerpc authentication code - schannel auth/crypto code
|
||||||
|
|
||||||
|
Copyright (C) Andrew Tridgell 2004
|
||||||
|
|
||||||
|
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
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
|
||||||
|
struct srv_schannel_state {
|
||||||
|
TALLOC_CTX *mem_ctx;
|
||||||
|
struct dcerpc_bind_schannel bind_info;
|
||||||
|
struct schannel_state *state;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
start crypto state
|
||||||
|
*/
|
||||||
|
static NTSTATUS dcesrv_crypto_schannel_start(struct dcesrv_auth *auth, DATA_BLOB *auth_blob)
|
||||||
|
{
|
||||||
|
struct srv_schannel_state *schannel = NULL;
|
||||||
|
NTSTATUS status;
|
||||||
|
TALLOC_CTX *mem_ctx;
|
||||||
|
uint8_t session_key[16];
|
||||||
|
|
||||||
|
mem_ctx = talloc_init("schannel_start");
|
||||||
|
if (!mem_ctx) {
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
schannel = talloc_p(mem_ctx, struct srv_schannel_state);
|
||||||
|
if (!schannel) {
|
||||||
|
talloc_destroy(mem_ctx);
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
schannel->mem_ctx = mem_ctx;
|
||||||
|
|
||||||
|
/* parse the schannel startup blob */
|
||||||
|
status = ndr_pull_struct_blob(auth_blob, mem_ctx, &schannel->bind_info,
|
||||||
|
(ndr_pull_flags_fn_t)ndr_pull_dcerpc_bind_schannel);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
talloc_destroy(mem_ctx);
|
||||||
|
return NT_STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pull the session key for this client */
|
||||||
|
status = schannel_fetch_session_key(mem_ctx, schannel->bind_info.hostname, session_key);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
talloc_destroy(mem_ctx);
|
||||||
|
return NT_STATUS_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* start up the schannel server code */
|
||||||
|
status = schannel_start(&schannel->state, session_key, False);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
talloc_destroy(mem_ctx);
|
||||||
|
return NT_STATUS_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
auth->crypto_ctx.private_data = schannel;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
update crypto state
|
||||||
|
*/
|
||||||
|
static NTSTATUS dcesrv_crypto_schannel_update(struct dcesrv_auth *auth, TALLOC_CTX *out_mem_ctx,
|
||||||
|
const DATA_BLOB in, DATA_BLOB *out)
|
||||||
|
{
|
||||||
|
return NT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
seal a packet
|
||||||
|
*/
|
||||||
|
static NTSTATUS dcesrv_crypto_schannel_seal(struct dcesrv_auth *auth, TALLOC_CTX *sig_mem_ctx,
|
||||||
|
uint8_t *data, size_t length, DATA_BLOB *sig)
|
||||||
|
{
|
||||||
|
struct srv_schannel_state *srv_schannel_state = auth->crypto_ctx.private_data;
|
||||||
|
|
||||||
|
return schannel_seal_packet(srv_schannel_state->state, sig_mem_ctx, data, length, sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
sign a packet
|
||||||
|
*/
|
||||||
|
static NTSTATUS dcesrv_crypto_schannel_sign(struct dcesrv_auth *auth, TALLOC_CTX *sig_mem_ctx,
|
||||||
|
const uint8_t *data, size_t length, DATA_BLOB *sig)
|
||||||
|
{
|
||||||
|
struct srv_schannel_state *srv_schannel_state = auth->crypto_ctx.private_data;
|
||||||
|
|
||||||
|
return schannel_sign_packet(srv_schannel_state->state, sig_mem_ctx, data, length, sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
check a packet signature
|
||||||
|
*/
|
||||||
|
static NTSTATUS dcesrv_crypto_schannel_check_sig(struct dcesrv_auth *auth, TALLOC_CTX *sig_mem_ctx,
|
||||||
|
const uint8_t *data, size_t length, const DATA_BLOB *sig)
|
||||||
|
{
|
||||||
|
struct srv_schannel_state *srv_schannel_state = auth->crypto_ctx.private_data;
|
||||||
|
|
||||||
|
return schannel_check_packet(srv_schannel_state->state, data, length, sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
unseal a packet
|
||||||
|
*/
|
||||||
|
static NTSTATUS dcesrv_crypto_schannel_unseal(struct dcesrv_auth *auth, TALLOC_CTX *sig_mem_ctx,
|
||||||
|
uint8_t *data, size_t length, DATA_BLOB *sig)
|
||||||
|
{
|
||||||
|
struct srv_schannel_state *srv_schannel_state = auth->crypto_ctx.private_data;
|
||||||
|
|
||||||
|
return schannel_unseal_packet(srv_schannel_state->state, sig_mem_ctx, data, length, sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
end crypto state
|
||||||
|
*/
|
||||||
|
static void dcesrv_crypto_schannel_end(struct dcesrv_auth *auth)
|
||||||
|
{
|
||||||
|
struct srv_schannel_state *srv_schannel_state = auth->crypto_ctx.private_data;
|
||||||
|
|
||||||
|
if (srv_schannel_state == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
schannel_end(&srv_schannel_state->state);
|
||||||
|
|
||||||
|
talloc_destroy(srv_schannel_state->mem_ctx);
|
||||||
|
|
||||||
|
auth->crypto_ctx.private_data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dcesrv_crypto_ops dcesrv_crypto_schannel_ops = {
|
||||||
|
.name = "schannel",
|
||||||
|
.auth_type = DCERPC_AUTH_TYPE_SCHANNEL,
|
||||||
|
.start = dcesrv_crypto_schannel_start,
|
||||||
|
.update = dcesrv_crypto_schannel_update,
|
||||||
|
.seal = dcesrv_crypto_schannel_seal,
|
||||||
|
.sign = dcesrv_crypto_schannel_sign,
|
||||||
|
.check_sig = dcesrv_crypto_schannel_check_sig,
|
||||||
|
.unseal = dcesrv_crypto_schannel_unseal,
|
||||||
|
.end = dcesrv_crypto_schannel_end
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
startup the cryptographic side of an authenticated dcerpc server
|
||||||
|
*/
|
||||||
|
const struct dcesrv_crypto_ops *dcesrv_crypto_schannel_get_ops(void)
|
||||||
|
{
|
||||||
|
return &dcesrv_crypto_schannel_ops;
|
||||||
|
}
|
||||||
@@ -88,13 +88,17 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx,
|
|||||||
ldb_msg_add_value(ldb, &msg, "sessionKey", &val);
|
ldb_msg_add_value(ldb, &msg, "sessionKey", &val);
|
||||||
ldb_msg_add_string(ldb, &msg, "expiry", s);
|
ldb_msg_add_string(ldb, &msg, "expiry", s);
|
||||||
|
|
||||||
|
ldb_delete(ldb, msg.dn);
|
||||||
|
|
||||||
ret = ldb_add(ldb, &msg);
|
ret = ldb_add(ldb, &msg);
|
||||||
ldb_close(ldb);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
DEBUG(1,("Unable to add %s to session key db - %s\n", msg.dn, ldb_errstring(ldb)));
|
||||||
|
ldb_close(ldb);
|
||||||
return NT_STATUS_INTERNAL_DB_CORRUPTION;
|
return NT_STATUS_INTERNAL_DB_CORRUPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ldb_close(ldb);
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,13 +114,20 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
|
|||||||
struct ldb_message **res;
|
struct ldb_message **res;
|
||||||
int ret;
|
int ret;
|
||||||
const struct ldb_val *val;
|
const struct ldb_val *val;
|
||||||
|
char *expr=NULL;
|
||||||
|
|
||||||
ldb = schannel_db_connect(mem_ctx);
|
ldb = schannel_db_connect(mem_ctx);
|
||||||
if (ldb == NULL) {
|
if (ldb == NULL) {
|
||||||
return NT_STATUS_NO_MEMORY;
|
return NT_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ldb_search(ldb, NULL, LDB_SCOPE_SUBTREE, "(dn=%s)", NULL, &res);
|
expr = talloc_asprintf(mem_ctx, "(dn=%s)", computer_name);
|
||||||
|
if (expr == NULL) {
|
||||||
|
ldb_close(ldb);
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ldb_search(ldb, NULL, LDB_SCOPE_SUBTREE, expr, NULL, &res);
|
||||||
if (ret != 1) {
|
if (ret != 1) {
|
||||||
ldb_close(ldb);
|
ldb_close(ldb);
|
||||||
return NT_STATUS_INVALID_HANDLE;
|
return NT_STATUS_INVALID_HANDLE;
|
||||||
|
|||||||
Reference in New Issue
Block a user