From ba98dd4989db16028a2690d382ab178524ce765b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 21 Apr 2008 19:26:32 +0200 Subject: libads: Use libnbt for CLDAP reply parsing. Guenther (This used to be commit 751f3064a508341c0ebae45e8de9f5311d915d70) --- source3/libads/cldap.c | 105 ++++++------------------------------------------- source3/libads/ldap.c | 24 +++++------ 2 files changed, 24 insertions(+), 105 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 39e736f28a..6068ca4faf 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -20,72 +20,6 @@ #include "includes.h" -/* - These seem to be strings as described in RFC1035 4.1.4 and can be: - - - a sequence of labels ending in a zero octet - - a pointer - - a sequence of labels ending with a pointer - - A label is a byte where the first two bits must be zero and the remaining - bits represent the length of the label followed by the label itself. - Therefore, the length of a label is at max 64 bytes. Under RFC1035, a - sequence of labels cannot exceed 255 bytes. - - A pointer consists of a 14 bit offset from the beginning of the data. - - struct ptr { - unsigned ident:2; // must be 11 - unsigned offset:14; // from the beginning of data - }; - - This is used as a method to compress the packet by eliminated duplicate - domain components. Since a UDP packet should probably be < 512 bytes and a - DNS name can be up to 255 bytes, this actually makes a lot of sense. -*/ -static unsigned pull_netlogon_string(char *ret, const char *ptr, - const char *data) -{ - char *pret = ret; - int followed_ptr = 0; - unsigned ret_len = 0; - - memset(pret, 0, MAX_DNS_LABEL); - do { - if ((*ptr & 0xc0) == 0xc0) { - uint16 len; - - if (!followed_ptr) { - ret_len += 2; - followed_ptr = 1; - } - len = ((ptr[0] & 0x3f) << 8) | ptr[1]; - ptr = data + len; - } else if (*ptr) { - uint8 len = (uint8)*(ptr++); - - if ((pret - ret + len + 1) >= MAX_DNS_LABEL) { - DEBUG(1,("DC returning too long DNS name\n")); - return 0; - } - - if (pret != ret) { - *pret = '.'; - pret++; - } - memcpy(pret, ptr, len); - pret += len; - ptr += len; - - if (!followed_ptr) { - ret_len += (len + 1); - } - } - } while (*ptr); - - return followed_ptr ? ret_len : ret_len + 1; -} - /* do a cldap netlogon query */ @@ -182,7 +116,7 @@ static void gotalarm_sig(void) /* receive a cldap netlogon reply */ -static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) +static int recv_cldap_netlogon(int sock, struct nbt_cldap_netlogon_5 *reply) { int ret; ASN1_DATA data; @@ -193,7 +127,8 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) int i1; /* half the time of a regular ldap timeout, not less than 3 seconds. */ unsigned int al_secs = MAX(3,lp_ldap_timeout()/2); - char *p; + union nbt_cldap_netlogon p; + enum ndr_err_code ndr_err; blob = data_blob(NULL, 8192); if (blob.data == NULL) { @@ -247,33 +182,17 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) return -1; } - p = (char *)os3.data; - - reply->type = IVAL(p, 0); p += 4; - reply->flags = IVAL(p, 0); p += 4; - - memcpy(&reply->guid.info, p, UUID_FLAT_SIZE); - p += UUID_FLAT_SIZE; - - p += pull_netlogon_string(reply->forest, p, (const char *)os3.data); - p += pull_netlogon_string(reply->domain, p, (const char *)os3.data); - p += pull_netlogon_string(reply->hostname, p, (const char *)os3.data); - p += pull_netlogon_string(reply->netbios_domain, p, (const char *)os3.data); - p += pull_netlogon_string(reply->netbios_hostname, p, (const char *)os3.data); - p += pull_netlogon_string(reply->unk, p, (const char *)os3.data); - - if (reply->type == SAMLOGON_AD_R) { - p += pull_netlogon_string(reply->user_name, p, (const char *)os3.data); - } else { - *reply->user_name = 0; + ndr_err = ndr_pull_union_blob_all(&os3, talloc_tos(), &p, 5, + (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return -1; } - p += pull_netlogon_string(reply->server_site_name, p, (const char *)os3.data); - p += pull_netlogon_string(reply->client_site_name, p, (const char *)os3.data); + *reply = p.logon5; - reply->version = IVAL(p, 0); - reply->lmnt_token = SVAL(p, 4); - reply->lm20_token = SVAL(p, 6); + if (DEBUGLEVEL >= 10) { + NDR_PRINT_UNION_DEBUG(nbt_cldap_netlogon, 5, &p); + } data_blob_free(&os1); data_blob_free(&os2); @@ -289,7 +208,7 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) do a cldap netlogon query. Always 389/udp *******************************************************************/ -bool ads_cldap_netlogon(const char *server, const char *realm, struct cldap_netlogon_reply *reply) +bool ads_cldap_netlogon(const char *server, const char *realm, struct nbt_cldap_netlogon_5 *reply) { int sock; int ret; diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a9eff48b3e..b4a977056e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -176,7 +176,7 @@ bool ads_closest_dc(ADS_STRUCT *ads) bool ads_try_connect(ADS_STRUCT *ads, const char *server ) { char *srv; - struct cldap_netlogon_reply cldap_reply; + struct nbt_cldap_netlogon_5 cldap_reply; if (!server || !*server) { return False; @@ -199,7 +199,7 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) /* Check the CLDAP reply flags */ - if ( !(cldap_reply.flags & ADS_LDAP) ) { + if ( !(cldap_reply.server_type & ADS_LDAP) ) { DEBUG(1,("ads_try_connect: %s's CLDAP reply says it is not an LDAP server!\n", srv)); SAFE_FREE( srv ); @@ -215,20 +215,20 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) SAFE_FREE(ads->config.client_site_name); SAFE_FREE(ads->server.workgroup); - ads->config.flags = cldap_reply.flags; - ads->config.ldap_server_name = SMB_STRDUP(cldap_reply.hostname); - strupper_m(cldap_reply.domain); - ads->config.realm = SMB_STRDUP(cldap_reply.domain); + ads->config.flags = cldap_reply.server_type; + ads->config.ldap_server_name = SMB_STRDUP(cldap_reply.pdc_dns_name); + ads->config.realm = SMB_STRDUP(cldap_reply.dns_domain); + strupper_m(ads->config.realm); ads->config.bind_path = ads_build_dn(ads->config.realm); - if (*cldap_reply.server_site_name) { + if (*cldap_reply.server_site) { ads->config.server_site_name = - SMB_STRDUP(cldap_reply.server_site_name); + SMB_STRDUP(cldap_reply.server_site); } - if (*cldap_reply.client_site_name) { + if (*cldap_reply.client_site) { ads->config.client_site_name = - SMB_STRDUP(cldap_reply.client_site_name); + SMB_STRDUP(cldap_reply.client_site); } - ads->server.workgroup = SMB_STRDUP(cldap_reply.netbios_domain); + ads->server.workgroup = SMB_STRDUP(cldap_reply.domain); ads->ldap.port = LDAP_PORT; if (!interpret_string_addr(&ads->ldap.ss, srv, 0)) { @@ -242,7 +242,7 @@ bool ads_try_connect(ADS_STRUCT *ads, const char *server ) SAFE_FREE(srv); /* Store our site name. */ - sitename_store( cldap_reply.domain, cldap_reply.client_site_name ); + sitename_store( cldap_reply.domain, cldap_reply.client_site); return True; } -- cgit