summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2008-04-21 19:26:32 +0200
committerGünther Deschner <gd@samba.org>2008-04-21 20:21:39 +0200
commitba98dd4989db16028a2690d382ab178524ce765b (patch)
treea4e04ba422d6d10e97659450ec7d778543783e0a
parent84c87326fa70da16689f4cf465a2a99748ec4c06 (diff)
downloadsamba-ba98dd4989db16028a2690d382ab178524ce765b.tar.gz
samba-ba98dd4989db16028a2690d382ab178524ce765b.tar.bz2
samba-ba98dd4989db16028a2690d382ab178524ce765b.zip
libads: Use libnbt for CLDAP reply parsing.
Guenther (This used to be commit 751f3064a508341c0ebae45e8de9f5311d915d70)
-rw-r--r--source3/libads/cldap.c105
-rw-r--r--source3/libads/ldap.c24
-rw-r--r--source3/libsmb/dsgetdcname.c34
-rw-r--r--source3/utils/net_ads.c45
4 files changed, 61 insertions, 147 deletions
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
@@ -21,72 +21,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
*/
static int send_cldap_netlogon(int sock, const char *domain,
@@ -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;
}
diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c
index 00841f0684..531ab11622 100644
--- a/source3/libsmb/dsgetdcname.c
+++ b/source3/libsmb/dsgetdcname.c
@@ -196,7 +196,7 @@ static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx,
const char *site_name,
struct netr_DsRGetDCNameInfo *info)
{
- struct cldap_netlogon_reply r;
+ struct nbt_cldap_netlogon_5 r;
/* check if matching entry is older then 15 minutes, if yes, send
* CLDAP/MAILSLOT ping again and store the cached data */
@@ -606,12 +606,11 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx,
{
int i = 0;
bool valid_dc = false;
- struct cldap_netlogon_reply r;
+ struct nbt_cldap_netlogon_5 r;
const char *dc_hostname, *dc_domain_name;
const char *dc_address;
uint32_t dc_address_type;
uint32_t dc_flags;
- struct GUID dc_guid;
for (i=0; i<num_dcs; i++) {
@@ -621,7 +620,7 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx,
if ((ads_cldap_netlogon(dclist[i].hostname,
domain_name, &r)) &&
- (check_cldap_reply_required_flags(r.flags, flags))) {
+ (check_cldap_reply_required_flags(r.server_type, flags))) {
valid_dc = true;
break;
}
@@ -633,25 +632,25 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx,
return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
}
- dc_flags = r.flags;
+ dc_flags = r.server_type;
if (flags & DS_RETURN_FLAT_NAME) {
- if (!strlen(r.netbios_hostname) || !strlen(r.netbios_domain)) {
+ if (!strlen(r.pdc_name) || !strlen(r.domain)) {
return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
}
- dc_hostname = r.netbios_hostname;
- dc_domain_name = r.netbios_domain;
+ dc_hostname = r.pdc_name;
+ dc_domain_name = r.domain;
} else if (flags & DS_RETURN_DNS_NAME) {
- if (!strlen(r.hostname) || !strlen(r.domain)) {
+ if (!strlen(r.pdc_dns_name) || !strlen(r.dns_domain)) {
return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
}
- dc_hostname = r.hostname;
- dc_domain_name = r.domain;
+ dc_hostname = r.pdc_dns_name;
+ dc_domain_name = r.dns_domain;
dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER;
} else {
/* FIXME */
- dc_hostname = r.hostname;
- dc_domain_name = r.domain;
+ dc_hostname = r.pdc_dns_name;
+ dc_domain_name = r.dns_domain;
dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER;
}
@@ -663,11 +662,10 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx,
dc_address_type = DS_ADDRESS_TYPE_INET;
} else {
dc_address = talloc_asprintf(mem_ctx, "\\\\%s",
- r.netbios_hostname);
+ r.pdc_name);
dc_address_type = DS_ADDRESS_TYPE_NETBIOS;
}
NT_STATUS_HAVE_NO_MEMORY(dc_address);
- smb_uuid_unpack(r.guid, &dc_guid);
if (r.forest) {
dc_flags |= DS_DNS_FOREST;
@@ -677,12 +675,12 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx,
dc_hostname,
dc_address,
dc_address_type,
- &dc_guid,
+ &r.domain_uuid,
dc_domain_name,
r.forest,
dc_flags,
- r.server_site_name,
- r.client_site_name,
+ r.server_site,
+ r.client_site,
info);
}
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index c8bfc2630c..af55430fac 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -81,8 +81,7 @@ static const char *assume_own_realm(void)
static int net_ads_cldap_netlogon(ADS_STRUCT *ads)
{
char addr[INET6_ADDRSTRLEN];
- struct cldap_netlogon_reply reply;
- struct GUID tmp_guid;
+ struct nbt_cldap_netlogon_5 reply;
print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
if ( !ads_cldap_netlogon(addr, ads->server.realm, &reply ) ) {
@@ -106,8 +105,7 @@ static int net_ads_cldap_netlogon(ADS_STRUCT *ads)
break;
}
- smb_uuid_unpack(reply.guid, &tmp_guid);
- d_printf("GUID: %s\n", smb_uuid_string(talloc_tos(), tmp_guid));
+ d_printf("GUID: %s\n", smb_uuid_string(talloc_tos(), reply.domain_uuid));
d_printf("Flags:\n"
"\tIs a PDC: %s\n"
@@ -120,31 +118,30 @@ static int net_ads_cldap_netlogon(ADS_STRUCT *ads)
"\tIs writable: %s\n"
"\tHas a hardware clock: %s\n"
"\tIs a non-domain NC serviced by LDAP server: %s\n",
- (reply.flags & ADS_PDC) ? "yes" : "no",
- (reply.flags & ADS_GC) ? "yes" : "no",
- (reply.flags & ADS_LDAP) ? "yes" : "no",
- (reply.flags & ADS_DS) ? "yes" : "no",
- (reply.flags & ADS_KDC) ? "yes" : "no",
- (reply.flags & ADS_TIMESERV) ? "yes" : "no",
- (reply.flags & ADS_CLOSEST) ? "yes" : "no",
- (reply.flags & ADS_WRITABLE) ? "yes" : "no",
- (reply.flags & ADS_GOOD_TIMESERV) ? "yes" : "no",
- (reply.flags & ADS_NDNC) ? "yes" : "no");
+ (reply.server_type & ADS_PDC) ? "yes" : "no",
+ (reply.server_type & ADS_GC) ? "yes" : "no",
+ (reply.server_type & ADS_LDAP) ? "yes" : "no",
+ (reply.server_type & ADS_DS) ? "yes" : "no",
+ (reply.server_type & ADS_KDC) ? "yes" : "no",
+ (reply.server_type & ADS_TIMESERV) ? "yes" : "no",
+ (reply.server_type & ADS_CLOSEST) ? "yes" : "no",
+ (reply.server_type & ADS_WRITABLE) ? "yes" : "no",
+ (reply.server_type & ADS_GOOD_TIMESERV) ? "yes" : "no",
+ (reply.server_type & ADS_NDNC) ? "yes" : "no");
printf("Forest:\t\t\t%s\n", reply.forest);
- printf("Domain:\t\t\t%s\n", reply.domain);
- printf("Domain Controller:\t%s\n", reply.hostname);
+ printf("Domain:\t\t\t%s\n", reply.dns_domain);
+ printf("Domain Controller:\t%s\n", reply.pdc_dns_name);
- printf("Pre-Win2k Domain:\t%s\n", reply.netbios_domain);
- printf("Pre-Win2k Hostname:\t%s\n", reply.netbios_hostname);
+ printf("Pre-Win2k Domain:\t%s\n", reply.domain);
+ printf("Pre-Win2k Hostname:\t%s\n", reply.pdc_name);
- if (*reply.unk) printf("Unk:\t\t\t%s\n", reply.unk);
if (*reply.user_name) printf("User name:\t%s\n", reply.user_name);
- printf("Server Site Name :\t\t%s\n", reply.server_site_name);
- printf("Client Site Name :\t\t%s\n", reply.client_site_name);
+ printf("Server Site Name :\t\t%s\n", reply.server_site);
+ printf("Client Site Name :\t\t%s\n", reply.client_site);
- d_printf("NT Version: %d\n", reply.version);
+ d_printf("NT Version: %d\n", reply.nt_version);
d_printf("LMNT Token: %.2x\n", reply.lmnt_token);
d_printf("LM20 Token: %.2x\n", reply.lm20_token);
@@ -379,7 +376,7 @@ static int net_ads_workgroup(int argc, const char **argv)
{
ADS_STRUCT *ads;
char addr[INET6_ADDRSTRLEN];
- struct cldap_netlogon_reply reply;
+ struct nbt_cldap_netlogon_5 reply;
if (!ADS_ERR_OK(ads_startup_nobind(False, &ads))) {
d_fprintf(stderr, "Didn't find the cldap server!\n");
@@ -397,7 +394,7 @@ static int net_ads_workgroup(int argc, const char **argv)
return -1;
}
- d_printf("Workgroup: %s\n", reply.netbios_domain);
+ d_printf("Workgroup: %s\n", reply.domain);
ads_destroy(&ads);