2
Samba Unix/Linux SMB client library
3
net ads cldap functions
4
Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
5
Copyright (C) 2003 Jim McDonough (jmcd@us.ibm.com)
6
Copyright (C) 2008 Guenther Deschner (gd@samba.org)
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program. If not, see <http://www.gnu.org/licenses/>.
25
do a cldap netlogon query
27
static int send_cldap_netlogon(TALLOC_CTX *mem_ctx, int sock, const char *domain,
28
const char *hostname, unsigned ntversion)
32
#ifdef CLDAP_USER_QUERY
35
SIVAL(aac, 0, 0x00000180);
37
SIVAL(ntver, 0, ntversion);
39
data = asn1_init(mem_ctx);
44
asn1_push_tag(data,ASN1_SEQUENCE(0));
45
asn1_write_Integer(data, 4);
46
asn1_push_tag(data, ASN1_APPLICATION(3));
47
asn1_write_OctetString(data, NULL, 0);
48
asn1_write_enumerated(data, 0);
49
asn1_write_enumerated(data, 0);
50
asn1_write_Integer(data, 0);
51
asn1_write_Integer(data, 0);
52
asn1_write_BOOLEAN(data, False);
53
asn1_push_tag(data, ASN1_CONTEXT(0));
56
asn1_push_tag(data, ASN1_CONTEXT(3));
57
asn1_write_OctetString(data, "DnsDomain", 9);
58
asn1_write_OctetString(data, domain, strlen(domain));
62
asn1_push_tag(data, ASN1_CONTEXT(3));
63
asn1_write_OctetString(data, "Host", 4);
64
asn1_write_OctetString(data, hostname, strlen(hostname));
67
#ifdef CLDAP_USER_QUERY
68
asn1_push_tag(data, ASN1_CONTEXT(3));
69
asn1_write_OctetString(data, "User", 4);
70
asn1_write_OctetString(data, "SAMBA$", 6);
73
asn1_push_tag(data, ASN1_CONTEXT(3));
74
asn1_write_OctetString(data, "AAC", 4);
75
asn1_write_OctetString(data, aac, 4);
79
asn1_push_tag(data, ASN1_CONTEXT(3));
80
asn1_write_OctetString(data, "NtVer", 5);
81
asn1_write_OctetString(data, ntver, 4);
86
asn1_push_tag(data,ASN1_SEQUENCE(0));
87
asn1_write_OctetString(data, "NetLogon", 8);
92
if (data->has_error) {
93
DEBUG(2,("Failed to build cldap netlogon at offset %d\n", (int)data->ofs));
98
if (write(sock, data->data, data->length) != (ssize_t)data->length) {
99
DEBUG(2,("failed to send cldap query (%s)\n", strerror(errno)));
110
receive a cldap netlogon reply
112
static int recv_cldap_netlogon(TALLOC_CTX *mem_ctx,
115
struct netlogon_samlogon_response **reply)
119
DATA_BLOB blob = data_blob_null;
120
DATA_BLOB os1 = data_blob_null;
121
DATA_BLOB os2 = data_blob_null;
122
DATA_BLOB os3 = data_blob_null;
124
struct netlogon_samlogon_response *r = NULL;
128
struct timeval timeout;
130
blob = data_blob(NULL, 8192);
131
if (blob.data == NULL) {
132
DEBUG(1, ("data_blob failed\n"));
138
FD_SET(sock, &r_fds);
141
* half the time of a regular ldap timeout, not less than 3 seconds.
143
timeout.tv_sec = MAX(3,lp_ldap_timeout()/2);
146
ret = sys_select(sock+1, &r_fds, NULL, NULL, &timeout);
148
DEBUG(10, ("select failed: %s\n", strerror(errno)));
149
data_blob_free(&blob);
154
DEBUG(1,("no reply received to cldap netlogon "
155
"(select timeout %u sec)\n",
156
(unsigned int)timeout.tv_sec));
157
data_blob_free(&blob);
161
ret = read(sock, blob.data, blob.length);
163
DEBUG(1,("no reply received to cldap netlogon "
164
"(ret = %d: Error = %s)\n",
166
ret == -1 ? strerror(errno) : "" ));
167
data_blob_free(&blob);
172
data = asn1_init(mem_ctx);
174
data_blob_free(&blob);
178
asn1_load(data, blob);
179
asn1_start_tag(data, ASN1_SEQUENCE(0));
180
asn1_read_Integer(data, &i1);
181
asn1_start_tag(data, ASN1_APPLICATION(4));
182
asn1_read_OctetString(data, NULL, &os1);
183
asn1_start_tag(data, ASN1_SEQUENCE(0));
184
asn1_start_tag(data, ASN1_SEQUENCE(0));
185
asn1_read_OctetString(data, NULL, &os2);
186
asn1_start_tag(data, ASN1_SET);
187
asn1_read_OctetString(data, NULL, &os3);
194
if (data->has_error) {
195
data_blob_free(&blob);
196
data_blob_free(&os1);
197
data_blob_free(&os2);
198
data_blob_free(&os3);
200
DEBUG(1,("Failed to parse cldap reply\n"));
204
r = TALLOC_ZERO_P(mem_ctx, struct netlogon_samlogon_response);
207
data_blob_free(&os1);
208
data_blob_free(&os2);
209
data_blob_free(&os3);
210
data_blob_free(&blob);
215
status = pull_netlogon_samlogon_response(&os3, mem_ctx, NULL, r);
216
if (!NT_STATUS_IS_OK(status)) {
217
data_blob_free(&os1);
218
data_blob_free(&os2);
219
data_blob_free(&os3);
220
data_blob_free(&blob);
226
map_netlogon_samlogon_response(r);
228
data_blob_free(&os1);
229
data_blob_free(&os2);
230
data_blob_free(&os3);
231
data_blob_free(&blob);
244
/*******************************************************************
245
do a cldap netlogon query. Always 389/udp
246
*******************************************************************/
248
bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx,
252
struct netlogon_samlogon_response **reply)
257
sock = open_udp_socket(server, LDAP_PORT );
259
DEBUG(2,("ads_cldap_netlogon: Failed to open udp socket to %s. "
266
ret = send_cldap_netlogon(mem_ctx, sock, realm, global_myname(), nt_version);
271
ret = recv_cldap_netlogon(mem_ctx, sock, nt_version, reply);
281
/*******************************************************************
282
do a cldap netlogon query. Always 389/udp
283
*******************************************************************/
285
bool ads_cldap_netlogon_5(TALLOC_CTX *mem_ctx,
288
struct NETLOGON_SAM_LOGON_RESPONSE_EX *reply5)
290
uint32_t nt_version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
291
struct netlogon_samlogon_response *reply = NULL;
294
ret = ads_cldap_netlogon(mem_ctx, server, realm, nt_version, &reply);
299
if (reply->ntver != NETLOGON_NT_VERSION_5EX) {
300
DEBUG(0,("ads_cldap_netlogon_5: nt_version mismatch: 0x%08x\n",
305
*reply5 = reply->data.nt5_ex;