diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/asn_1.h | 1 | ||||
-rw-r--r-- | source3/libsmb/asn1.c | 7 | ||||
-rw-r--r-- | source3/utils/net_ads_cldap.c | 98 |
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; } |