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\n"));
155 data_blob_free(&blob
);
159 ret
= read(sock
, blob
.data
, blob
.length
);
161 DEBUG(1,("no reply received to cldap netlogon\n"));
162 data_blob_free(&blob
);
167 data
= asn1_init(mem_ctx
);
169 data_blob_free(&blob
);
173 asn1_load(data
, blob
);
174 asn1_start_tag(data
, ASN1_SEQUENCE(0));
175 asn1_read_Integer(data
, &i1
);
176 asn1_start_tag(data
, ASN1_APPLICATION(4));
177 asn1_read_OctetString(data
, NULL
, &os1
);
178 asn1_start_tag(data
, ASN1_SEQUENCE(0));
179 asn1_start_tag(data
, ASN1_SEQUENCE(0));
180 asn1_read_OctetString(data
, NULL
, &os2
);
181 asn1_start_tag(data
, ASN1_SET
);
182 asn1_read_OctetString(data
, NULL
, &os3
);
189 if (data
->has_error
) {
190 data_blob_free(&blob
);
191 data_blob_free(&os1
);
192 data_blob_free(&os2
);
193 data_blob_free(&os3
);
195 DEBUG(1,("Failed to parse cldap reply\n"));
199 r
= TALLOC_ZERO_P(mem_ctx
, struct netlogon_samlogon_response
);
202 data_blob_free(&os1
);
203 data_blob_free(&os2
);
204 data_blob_free(&os3
);
205 data_blob_free(&blob
);
210 status
= pull_netlogon_samlogon_response(&os3
, mem_ctx
, NULL
, r
);
211 if (!NT_STATUS_IS_OK(status
)) {
212 data_blob_free(&os1
);
213 data_blob_free(&os2
);
214 data_blob_free(&os3
);
215 data_blob_free(&blob
);
221 map_netlogon_samlogon_response(r
);
223 data_blob_free(&os1
);
224 data_blob_free(&os2
);
225 data_blob_free(&os3
);
226 data_blob_free(&blob
);
239 /*******************************************************************
240 do a cldap netlogon query. Always 389/udp
241 *******************************************************************/
243 bool ads_cldap_netlogon(TALLOC_CTX
*mem_ctx
,
247 struct netlogon_samlogon_response
**reply
)
252 sock
= open_udp_socket(server
, LDAP_PORT
);
254 DEBUG(2,("ads_cldap_netlogon: Failed to open udp socket to %s\n",
259 ret
= send_cldap_netlogon(mem_ctx
, sock
, realm
, global_myname(), nt_version
);
264 ret
= recv_cldap_netlogon(mem_ctx
, sock
, nt_version
, reply
);
274 /*******************************************************************
275 do a cldap netlogon query. Always 389/udp
276 *******************************************************************/
278 bool ads_cldap_netlogon_5(TALLOC_CTX
*mem_ctx
,
281 struct NETLOGON_SAM_LOGON_RESPONSE_EX
*reply5
)
283 uint32_t nt_version
= NETLOGON_NT_VERSION_5
| NETLOGON_NT_VERSION_5EX
;
284 struct netlogon_samlogon_response
*reply
= NULL
;
287 ret
= ads_cldap_netlogon(mem_ctx
, server
, realm
, nt_version
, &reply
);
292 if (reply
->ntver
!= NETLOGON_NT_VERSION_5EX
) {
293 DEBUG(0,("ads_cldap_netlogon_5: nt_version mismatch: 0x%08x\n",
298 *reply5
= reply
->data
.nt5_ex
;