20
20
#include "includes.h"
21
22
#include "../libcli/auth/libcli_auth.h"
23
#include "../librpc/gen_ndr/ndr_netlogon.h"
24
#include "librpc/gen_ndr/ndr_schannel.h"
25
#include "rpc_client/cli_pipe.h"
26
#include "rpc_client/cli_netlogon.h"
29
#include "tldap_util.h"
24
32
#define DBGC_CLASS DBGC_AUTH
34
static bool secrets_store_local_schannel_creds(
35
const struct netlogon_creds_CredentialState *creds)
38
enum ndr_err_code ndr_err;
41
ndr_err = ndr_push_struct_blob(
42
&blob, talloc_tos(), creds,
43
(ndr_push_flags_fn_t)ndr_push_netlogon_creds_CredentialState);
44
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
45
DEBUG(10, ("ndr_push_netlogon_creds_CredentialState failed: "
46
"%s\n", ndr_errstr(ndr_err)));
49
ret = secrets_store(SECRETS_LOCAL_SCHANNEL_KEY,
50
blob.data, blob.length);
51
data_blob_free(&blob);
55
static struct netlogon_creds_CredentialState *
56
secrets_fetch_local_schannel_creds(TALLOC_CTX *mem_ctx)
58
struct netlogon_creds_CredentialState *creds;
59
enum ndr_err_code ndr_err;
62
blob.data = (uint8_t *)secrets_fetch(SECRETS_LOCAL_SCHANNEL_KEY,
64
if (blob.data == NULL) {
65
DEBUG(10, ("secrets_fetch failed\n"));
69
creds = talloc(mem_ctx, struct netlogon_creds_CredentialState);
71
DEBUG(10, ("talloc failed\n"));
75
ndr_err = ndr_pull_struct_blob(
77
(ndr_pull_flags_fn_t)ndr_pull_netlogon_creds_CredentialState);
79
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
80
DEBUG(10, ("ndr_pull_netlogon_creds_CredentialState failed: "
81
"%s\n", ndr_errstr(ndr_err)));
26
89
static NTSTATUS netlogond_validate(TALLOC_CTX *mem_ctx,
27
90
const struct auth_context *auth_context,
28
91
const char *ncalrpc_sockname,
29
uint8_t schannel_key[16],
30
const auth_usersupplied_info *user_info,
92
struct netlogon_creds_CredentialState *creds,
93
const struct auth_usersupplied_info *user_info,
31
94
struct netr_SamInfo3 **pinfo3,
32
95
NTSTATUS *schannel_bind_result)
34
97
struct rpc_pipe_client *p = NULL;
35
struct cli_pipe_auth_data *auth = NULL;
98
struct pipe_auth_data *auth = NULL;
36
99
struct netr_SamInfo3 *info3 = NULL;
79
132
status = rpccli_netlogon_sam_network_logon_ex(
81
user_info->logon_parameters,/* flags such as 'allow
82
* workstation logon' */
83
global_myname(), /* server name */
84
user_info->smb_name, /* user name logging on. */
85
user_info->client_domain, /* domain name */
86
user_info->wksta_name, /* workstation name */
134
user_info->logon_parameters, /* flags such as 'allow
135
* workstation logon' */
136
global_myname(), /* server name */
137
user_info->client.account_name, /* user name logging on. */
138
user_info->client.domain_name, /* domain name */
139
user_info->workstation_name, /* workstation name */
87
140
(uchar *)auth_context->challenge.data, /* 8 byte challenge. */
88
3, /* validation level */
89
user_info->lm_resp, /* lanman 24 byte response */
90
user_info->nt_resp, /* nt 24 byte response */
91
&info3); /* info3 out */
141
3, /* validation level */
142
user_info->password.response.lanman, /* lanman 24 byte response */
143
user_info->password.response.nt, /* nt 24 byte response */
144
&info3); /* info3 out */
93
146
DEBUG(10, ("rpccli_netlogon_sam_network_logon_ex returned %s\n",
94
147
nt_errstr(status)));
104
157
return NT_STATUS_OK;
107
static char *mymachinepw(TALLOC_CTX *mem_ctx)
111
char *to_free = NULL;
115
script = lp_parm_const_string(
116
GLOBAL_SECTION_SNUM, "auth_netlogond", "machinepwscript",
119
if (script == NULL) {
120
to_free = talloc_asprintf(talloc_tos(), "%s/%s",
121
get_dyn_SBINDIR(), "mymachinepw");
124
if (script == NULL) {
128
ret = smbrun(script, &fd);
129
DEBUG(ret ? 0 : 3, ("mymachinepw: Running the command `%s' gave %d\n",
131
TALLOC_FREE(to_free);
137
nread = read(fd, pwd, sizeof(pwd)-1);
141
DEBUG(3, ("mymachinepwd: Could not read password\n"));
147
if (pwd[nread-1] == '\n') {
151
return talloc_strdup(mem_ctx, pwd);
160
static NTSTATUS get_ldapi_ctx(TALLOC_CTX *mem_ctx, struct tldap_context **pld)
162
struct tldap_context *ld;
163
struct sockaddr_un addr;
169
sockaddr = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
171
if (sockaddr == NULL) {
172
DEBUG(10, ("talloc failed\n"));
173
return NT_STATUS_NO_MEMORY;
177
addr.sun_family = AF_UNIX;
178
strncpy(addr.sun_path, sockaddr, sizeof(addr.sun_path));
179
TALLOC_FREE(sockaddr);
181
status = open_socket_out((struct sockaddr_storage *)(void *)&addr,
183
if (!NT_STATUS_IS_OK(status)) {
184
DEBUG(10, ("Could not connect to %s: %s\n", addr.sun_path,
188
set_blocking(fd, false);
190
ld = tldap_context_create(mem_ctx, fd);
193
return NT_STATUS_NO_MEMORY;
195
res = tldap_fetch_rootdse(ld);
196
if (res != TLDAP_SUCCESS) {
197
DEBUG(10, ("tldap_fetch_rootdse failed: %s\n",
198
tldap_errstr(talloc_tos(), ld, res)));
200
return NT_STATUS_LDAP(res);
203
return NT_STATUS_OK;;
206
static NTSTATUS mymachinepw(uint8_t pwd[16])
208
TALLOC_CTX *frame = talloc_stackframe();
209
struct tldap_context *ld = NULL;
210
struct tldap_message *rootdse, **msg;
211
const char *attrs[1] = { "unicodePwd" };
212
char *default_nc, *myname;
217
status = get_ldapi_ctx(talloc_tos(), &ld);
218
if (!NT_STATUS_IS_OK(status)) {
221
rootdse = tldap_rootdse(ld);
222
if (rootdse == NULL) {
223
DEBUG(10, ("Could not get rootdse\n"));
224
status = NT_STATUS_INTERNAL_ERROR;
227
default_nc = tldap_talloc_single_attribute(
228
rootdse, "defaultNamingContext", talloc_tos());
229
if (default_nc == NULL) {
230
DEBUG(10, ("Could not get defaultNamingContext\n"));
231
status = NT_STATUS_NO_MEMORY;
234
DEBUG(10, ("default_nc = %s\n", default_nc));
236
myname = talloc_asprintf_strupper_m(talloc_tos(), "%s$",
238
if (myname == NULL) {
239
DEBUG(10, ("talloc failed\n"));
240
status = NT_STATUS_NO_MEMORY;
244
rc = tldap_search_fmt(
245
ld, default_nc, TLDAP_SCOPE_SUB, attrs, ARRAY_SIZE(attrs), 0,
247
"(&(sAMAccountName=%s)(objectClass=computer))", myname);
248
if (rc != TLDAP_SUCCESS) {
249
DEBUG(10, ("Could not retrieve our account: %s\n",
250
tldap_errstr(talloc_tos(), ld, rc)));
251
status = NT_STATUS_LDAP(rc);
254
num_msg = talloc_array_length(msg);
256
DEBUG(10, ("Got %d accounts, expected one\n", num_msg));
257
status = NT_STATUS_INTERNAL_DB_CORRUPTION;
260
if (!tldap_get_single_valueblob(msg[0], "unicodePwd", &pwdblob)) {
262
tldap_entry_dn(msg[0], &dn);
263
DEBUG(10, ("No unicodePwd attribute in %s\n",
264
dn ? dn : "<unknown DN>"));
265
status = NT_STATUS_INTERNAL_DB_CORRUPTION;
268
if (pwdblob.length != 16) {
269
DEBUG(10, ("Password hash hash has length %d, expected 16\n",
270
(int)pwdblob.length));
271
status = NT_STATUS_INTERNAL_DB_CORRUPTION;
274
memcpy(pwd, pwdblob.data, 16);
154
281
static NTSTATUS check_netlogond_security(const struct auth_context *auth_context,
155
282
void *my_private_data,
156
283
TALLOC_CTX *mem_ctx,
157
const auth_usersupplied_info *user_info,
158
auth_serversupplied_info **server_info)
284
const struct auth_usersupplied_info *user_info,
285
struct auth_serversupplied_info **server_info)
160
287
TALLOC_CTX *frame = talloc_stackframe();
161
288
struct netr_SamInfo3 *info3 = NULL;
162
289
struct rpc_pipe_client *p = NULL;
163
struct cli_pipe_auth_data *auth = NULL;
290
struct pipe_auth_data *auth = NULL;
164
291
uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
165
char *plaintext_machinepw = NULL;
166
292
uint8_t machine_password[16];
167
uint8_t schannel_key[16];
293
struct netlogon_creds_CredentialState *creds;
168
294
NTSTATUS schannel_bind_result, status;
169
295
struct named_mutex *mutex = NULL;
170
296
const char *ncalrpcsock;
298
DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name));
172
300
ncalrpcsock = lp_parm_const_string(
173
301
GLOBAL_SECTION_SNUM, "auth_netlogond", "socket", NULL);