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)
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 do a cldap netlogon query
26 static int send_cldap_netlogon(int sock
, const char *domain
,
27 const char *hostname
, unsigned ntversion
)
31 #ifdef CLDAP_USER_QUERY
34 SIVAL(aac
, 0, 0x00000180);
36 SIVAL(ntver
, 0, ntversion
);
38 memset(&data
, 0, sizeof(data
));
40 asn1_push_tag(&data
,ASN1_SEQUENCE(0));
41 asn1_write_Integer(&data
, 4);
42 asn1_push_tag(&data
, ASN1_APPLICATION(3));
43 asn1_write_OctetString(&data
, NULL
, 0);
44 asn1_write_enumerated(&data
, 0);
45 asn1_write_enumerated(&data
, 0);
46 asn1_write_Integer(&data
, 0);
47 asn1_write_Integer(&data
, 0);
48 asn1_write_BOOLEAN2(&data
, False
);
49 asn1_push_tag(&data
, ASN1_CONTEXT(0));
52 asn1_push_tag(&data
, ASN1_CONTEXT(3));
53 asn1_write_OctetString(&data
, "DnsDomain", 9);
54 asn1_write_OctetString(&data
, domain
, strlen(domain
));
58 asn1_push_tag(&data
, ASN1_CONTEXT(3));
59 asn1_write_OctetString(&data
, "Host", 4);
60 asn1_write_OctetString(&data
, hostname
, strlen(hostname
));
63 #ifdef CLDAP_USER_QUERY
64 asn1_push_tag(&data
, ASN1_CONTEXT(3));
65 asn1_write_OctetString(&data
, "User", 4);
66 asn1_write_OctetString(&data
, "SAMBA$", 6);
69 asn1_push_tag(&data
, ASN1_CONTEXT(3));
70 asn1_write_OctetString(&data
, "AAC", 4);
71 asn1_write_OctetString(&data
, aac
, 4);
75 asn1_push_tag(&data
, ASN1_CONTEXT(3));
76 asn1_write_OctetString(&data
, "NtVer", 5);
77 asn1_write_OctetString(&data
, ntver
, 4);
82 asn1_push_tag(&data
,ASN1_SEQUENCE(0));
83 asn1_write_OctetString(&data
, "NetLogon", 8);
89 DEBUG(2,("Failed to build cldap netlogon at offset %d\n", (int)data
.ofs
));
94 if (write(sock
, data
.data
, data
.length
) != (ssize_t
)data
.length
) {
95 DEBUG(2,("failed to send cldap query (%s)\n", strerror(errno
)));
105 static SIG_ATOMIC_T gotalarm
;
107 /***************************************************************
108 Signal function to tell us we timed out.
109 ****************************************************************/
111 static void gotalarm_sig(void)
117 receive a cldap netlogon reply
119 static int recv_cldap_netlogon(TALLOC_CTX
*mem_ctx
,
121 struct nbt_cldap_netlogon_5
*reply
)
125 DATA_BLOB blob
= data_blob_null
;
126 DATA_BLOB os1
= data_blob_null
;
127 DATA_BLOB os2
= data_blob_null
;
128 DATA_BLOB os3
= data_blob_null
;
130 /* half the time of a regular ldap timeout, not less than 3 seconds. */
131 unsigned int al_secs
= MAX(3,lp_ldap_timeout()/2);
132 union nbt_cldap_netlogon p
;
133 enum ndr_err_code ndr_err
;
135 blob
= data_blob(NULL
, 8192);
136 if (blob
.data
== NULL
) {
137 DEBUG(1, ("data_blob failed\n"));
144 CatchSignal(SIGALRM
, SIGNAL_CAST gotalarm_sig
);
146 /* End setup timeout. */
148 ret
= read(sock
, blob
.data
, blob
.length
);
150 /* Teardown timeout. */
151 CatchSignal(SIGALRM
, SIGNAL_CAST SIG_IGN
);
155 DEBUG(1,("no reply received to cldap netlogon\n"));
156 data_blob_free(&blob
);
161 asn1_load(&data
, blob
);
162 asn1_start_tag(&data
, ASN1_SEQUENCE(0));
163 asn1_read_Integer(&data
, &i1
);
164 asn1_start_tag(&data
, ASN1_APPLICATION(4));
165 asn1_read_OctetString(&data
, &os1
);
166 asn1_start_tag(&data
, ASN1_SEQUENCE(0));
167 asn1_start_tag(&data
, ASN1_SEQUENCE(0));
168 asn1_read_OctetString(&data
, &os2
);
169 asn1_start_tag(&data
, ASN1_SET
);
170 asn1_read_OctetString(&data
, &os3
);
177 if (data
.has_error
) {
178 data_blob_free(&blob
);
179 data_blob_free(&os1
);
180 data_blob_free(&os2
);
181 data_blob_free(&os3
);
183 DEBUG(1,("Failed to parse cldap reply\n"));
187 ndr_err
= ndr_pull_union_blob_all(&os3
, mem_ctx
, &p
, 5,
188 (ndr_pull_flags_fn_t
)ndr_pull_nbt_cldap_netlogon
);
189 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
195 if (DEBUGLEVEL
>= 10) {
196 NDR_PRINT_UNION_DEBUG(nbt_cldap_netlogon
, 5, &p
);
199 data_blob_free(&os1
);
200 data_blob_free(&os2
);
201 data_blob_free(&os3
);
202 data_blob_free(&blob
);
209 /*******************************************************************
210 do a cldap netlogon query. Always 389/udp
211 *******************************************************************/
213 bool ads_cldap_netlogon(TALLOC_CTX
*mem_ctx
,
216 struct nbt_cldap_netlogon_5
*reply
)
221 sock
= open_udp_socket(server
, LDAP_PORT
);
223 DEBUG(2,("ads_cldap_netlogon: Failed to open udp socket to %s\n",
228 ret
= send_cldap_netlogon(sock
, realm
, global_myname(), 6);
233 ret
= recv_cldap_netlogon(mem_ctx
, sock
, reply
);