summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/include/asn_1.h1
-rw-r--r--source3/libsmb/asn1.c7
-rw-r--r--source3/utils/net_ads_cldap.c98
3 files changed, 91 insertions, 15 deletions
diff --git a/source3/include/asn_1.h b/source3/include/asn_1.h
index 090c5459d1..7783ab4c2f 100644
--- a/source3/include/asn_1.h
+++ b/source3/include/asn_1.h
@@ -45,6 +45,7 @@ typedef struct {
#define ASN1_BOOLEAN 0x1
#define ASN1_INTEGER 0x2
#define ASN1_ENUMERATED 0xa
+#define ASN1_SET 0x31
#define ASN1_MAX_OIDS 20
diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c
index c8f832f3df..358c23c146 100644
--- a/source3/libsmb/asn1.c
+++ b/source3/libsmb/asn1.c
@@ -254,15 +254,12 @@ BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag)
asn1_read_uint8(data, &b);
if (b & 0x80) {
int n = b & 0x7f;
- if (n > 2) {
- data->has_error = True;
- return False;
- }
asn1_read_uint8(data, &b);
nesting->taglen = b;
- if (n == 2) {
+ while (n > 1) {
asn1_read_uint8(data, &b);
nesting->taglen = (nesting->taglen << 8) | b;
+ n--;
}
} else {
nesting->taglen = b;
diff --git a/source3/utils/net_ads_cldap.c b/source3/utils/net_ads_cldap.c
index f707f6beac..77a51d3b7c 100644
--- a/source3/utils/net_ads_cldap.c
+++ b/source3/utils/net_ads_cldap.c
@@ -23,16 +23,20 @@
#ifdef HAVE_ADS
+struct cldap_netlogon_reply {
+ uint32 i1;
+};
+
/*
do a cldap netlogon query
*/
-int ads_cldap_netlogon(ADS_STRUCT *ads)
+static int send_cldap_netlogon(int sock, const char *domain,
+ const char *hostname, unsigned ntversion)
{
ASN1_DATA data;
char ntver[4];
- int sock;
- SIVAL(ntver, 0, 6);
+ SIVAL(ntver, 0, ntversion);
memset(&data, 0, sizeof(data));
@@ -49,15 +53,14 @@ int ads_cldap_netlogon(ADS_STRUCT *ads)
asn1_push_tag(&data, ASN1_CONTEXT(3));
asn1_write_OctetString(&data, "DnsDomain", 9);
- asn1_write_OctetString(&data, ads->config.realm, strlen(ads->config.realm));
+ asn1_write_OctetString(&data, domain, strlen(domain));
asn1_pop_tag(&data);
asn1_push_tag(&data, ASN1_CONTEXT(3));
asn1_write_OctetString(&data, "Host", 4);
- asn1_write_OctetString(&data, "blu", 3);
+ asn1_write_OctetString(&data, hostname, strlen(hostname));
asn1_pop_tag(&data);
-
asn1_push_tag(&data, ASN1_CONTEXT(3));
asn1_write_OctetString(&data, "NtVer", 5);
asn1_write_OctetString(&data, ntver, 4);
@@ -77,6 +80,75 @@ int ads_cldap_netlogon(ADS_STRUCT *ads)
return -1;
}
+ if (write(sock, data.data, data.length) != data.length) {
+ d_printf("failed to send cldap query (%s)\n", strerror(errno));
+ }
+
+ file_save("cldap_query.dat", data.data, data.length);
+ asn1_free(&data);
+
+ return 0;
+}
+
+
+/*
+ receive a cldap netlogon reply
+*/
+static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply)
+{
+ int ret;
+ ASN1_DATA data;
+ DATA_BLOB blob;
+ DATA_BLOB os1, os2, os3;
+
+ blob = data_blob(NULL, 8192);
+
+ ret = read(sock, blob.data, blob.length);
+ if (ret <= 0) {
+ d_printf("no reply to cldap netlogon\n");
+ return -1;
+ }
+ blob.length = ret;
+
+ file_save("cldap_reply.dat", blob.data, blob.length);
+
+ asn1_load(&data, blob);
+ asn1_start_tag(&data, ASN1_SEQUENCE(0));
+ asn1_read_Integer(&data, &reply->i1);
+ asn1_start_tag(&data, ASN1_APPLICATION(4));
+ asn1_read_OctetString(&data, &os1);
+ asn1_start_tag(&data, ASN1_SEQUENCE(0));
+ asn1_start_tag(&data, ASN1_SEQUENCE(0));
+ asn1_read_OctetString(&data, &os2);
+ asn1_start_tag(&data, ASN1_SET);
+ asn1_read_OctetString(&data, &os3);
+ asn1_end_tag(&data);
+ asn1_end_tag(&data);
+ asn1_end_tag(&data);
+ asn1_end_tag(&data);
+ asn1_end_tag(&data);
+
+ file_save("cldap_reply_core.dat", os3.data, os3.length);
+
+ data_blob_free(&os1);
+ data_blob_free(&os2);
+ data_blob_free(&os3);
+ data_blob_free(&blob);
+
+ return 0;
+}
+
+
+/*
+ do a cldap netlogon query
+*/
+int ads_cldap_netlogon(ADS_STRUCT *ads)
+{
+ int sock;
+ int ret;
+ extern pstring global_myname;
+ struct cldap_netlogon_reply reply;
+
sock = open_udp_socket(inet_ntoa(ads->ldap_ip), ads->ldap_port);
if (sock == -1) {
d_printf("Failed to open udp socket to %s:%u\n",
@@ -85,10 +157,16 @@ int ads_cldap_netlogon(ADS_STRUCT *ads)
return -1;
}
- write(sock, data.data, data.length);
- file_save("cldap_query.dat", data.data, data.length);
- asn1_free(&data);
- return 0;
+ ret = send_cldap_netlogon(sock, ads->config.realm, global_myname, 6);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = recv_cldap_netlogon(sock, &reply);
+
+ close(sock);
+
+ return ret;
}