[PATCH] More CLDAP changes (last round hopefully)
Chere Zhou
qzhou at isilon.com
Thu Feb 27 21:38:50 GMT 2003
This patch works for me. Thanks a lot!
But I do have to manually edit the file, because long lines got wrapped in
the email.
Chere
On Thursday 27 February 2003 12:20 pm, Anthony Liguori wrote:
> Last round of changes to the Samba CLDAP code. Every byte is now
> accounted for in the response packet so we shouldn't have anymore parsing
> errors. It should apply cleanly against HEAD.
>
> Index: source/utils/net_ads_cldap.c
> ===================================================================
> RCS file: /cvsroot/samba/source/utils/net_ads_cldap.c,v
> retrieving revision 1.6
> diff -u -r1.6 net_ads_cldap.c
> --- source/utils/net_ads_cldap.c 12 Nov 2002 23:15:52 -0000 1.6
> +++ source/utils/net_ads_cldap.c 26 Feb 2003 22:57:53 -0000
> @@ -2,6 +2,7 @@
> Samba Unix/Linux SMB client library
> net ads cldap functions
> Copyright (C) 2001 Andrew Tridgell (tridge at samba.org)
> + Copyright (C) 2003 Jim McDonough (jmcd at us.ibm.com)
>
> This program is free software; you can redistribute it and/or modify
> it under the terms of the GNU General Public License as published by
> @@ -23,60 +24,69 @@
>
> #ifdef HAVE_ADS
>
> +struct netlogon_string {
> + uint32 comp_len;
> + char **component;
> + uint8 extra_flag;
> +};
> +
> struct cldap_netlogon_reply {
> - uint32 version;
> + uint32 type;
> uint32 flags;
> GUID guid;
> - char *domain;
> - char *server_name;
> - char *domain_flatname;
> - char *server_flatname;
> - char *dns_name;
> - uint32 unknown2[2];
> -};
>
> + struct netlogon_string forest;
> + struct netlogon_string domain;
> + struct netlogon_string hostname;
>
> -/*
> - pull a length prefixed string from a packet
> - return number of bytes consumed
> -*/
> -static unsigned pull_len_string(char **ret, const char *p)
> -{
> - unsigned len = *p;
> - (*ret) = NULL;
> - if (len == 0) return 1;
> - (*ret) = smb_xstrndup(p+1, len);
> - return len+1;
> -}
> + struct netlogon_string netbios_domain;
> + struct netlogon_string netbios_hostname;
> +
> + struct netlogon_string user_name;
> + struct netlogon_string site_name;
> +
> + struct netlogon_string unk0;
> +
> + uint32 version;
> + uint16 lmnt_token;
> + uint16 lm20_token;
> +};
>
> /*
> - pull a dotted string from a packet
> - return number of bytes consumed
> + These strings are rather interesting... They are composed of a series
> of
> + length encoded strings, terminated by either 1) a zero length string or
> 2)
> + a 0xc0 byte with what appears to be a one byte flags immediately
> following.
> */
> -static unsigned pull_dotted_string(char **ret, const char *p)
> +static unsigned pull_netlogon_string(struct netlogon_string *ret,const
> char *d)
> {
> - char *s;
> - unsigned len, total_len=0;
> + char *s, *p = (char *)d;
>
> - (*ret) = NULL;
> + ZERO_STRUCTP(ret);
>
> - while ((len = pull_len_string(&s, p)) > 1) {
> - if (total_len) {
> - char *s2;
> - asprintf(&s2, "%s.%s", *ret, s);
> - SAFE_FREE(*ret);
> - (*ret) = s2;
> + do {
> + unsigned len = (unsigned char)*p;
> + p++;
> +
> + if (len > 0 && len != 0xc0) {
> + ret->component = realloc(ret->component,
> + ++ret->comp_len *
> + sizeof(char *));
> +
> + ret->component[ret->comp_len - 1] =
> + smb_xstrndup(p, len);
> + p += len;
> } else {
> - (*ret) = s;
> + if (len == 0xc0) {
> + ret->extra_flag = *p;
> + p++;
> + };
> + break;
> }
> - total_len += len;
> - p += len;
> - }
> + } while (1);
>
> - return total_len + 1;
> + return (p - d);
> }
>
> -
> /*
> do a cldap netlogon query
> */
> @@ -190,19 +200,25 @@
>
> p = os3.data;
>
> - reply->version = IVAL(p, 0); p += 4;
> + reply->type = IVAL(p, 0); p += 4;
> reply->flags = IVAL(p, 0); p += 4;
> +
> memcpy(&reply->guid.info, p, GUID_SIZE);
> p += GUID_SIZE;
> - p += pull_dotted_string(&reply->domain, p);
> - p += 2; /* 0xc018 - whats this? */
> - p += pull_len_string(&reply->server_name, p);
> - p += 2; /* 0xc018 - whats this? */
> - p += pull_len_string(&reply->domain_flatname, p);
> - p += 1;
> - p += pull_len_string(&reply->server_flatname, p);
> - p += 2;
> - p += pull_len_string(&reply->dns_name, p);
> +
> + p += pull_netlogon_string(&reply->forest, p);
> + p += pull_netlogon_string(&reply->domain, p);
> + p += pull_netlogon_string(&reply->hostname, p);
> + p += pull_netlogon_string(&reply->netbios_domain, p);
> + p += pull_netlogon_string(&reply->netbios_hostname, p);
> + p += pull_netlogon_string(&reply->user_name, p);
> + p += pull_netlogon_string(&reply->site_name, p);
> +
> + p += pull_netlogon_string(&reply->unk0, p);
> +
> + reply->version = IVAL(p, 0);
> + reply->lmnt_token = SVAL(p, 4);
> + reply->lm20_token = SVAL(p, 6);
>
> data_blob_free(&os1);
> data_blob_free(&os2);
> @@ -212,17 +228,49 @@
> return 0;
> }
>
> +/*
> + free a netlogon string
> +*/
> +static void netlogon_string_free(struct netlogon_string *str)
> +{
> + int i;
> +
> + for (i = 0; i < str->comp_len; ++i) {
> + SAFE_FREE(str->component[i]);
> + }
> + SAFE_FREE(str->component);
> +}
>
> /*
> free a cldap reply packet
> */
> static void cldap_reply_free(struct cldap_netlogon_reply *reply)
> {
> - SAFE_FREE(reply->domain);
> - SAFE_FREE(reply->server_name);
> - SAFE_FREE(reply->domain_flatname);
> - SAFE_FREE(reply->server_flatname);
> - SAFE_FREE(reply->dns_name);
> + netlogon_string_free(&reply->forest);
> + netlogon_string_free(&reply->domain);
> + netlogon_string_free(&reply->hostname);
> + netlogon_string_free(&reply->netbios_domain);
> + netlogon_string_free(&reply->netbios_hostname);
> + netlogon_string_free(&reply->user_name);
> + netlogon_string_free(&reply->site_name);
> + netlogon_string_free(&reply->unk0);
> +}
> +
> +void d_print_netlogon_string(const char *label, struct netlogon_string
> *str)
> +{
> + int i;
> +
> + if (str->comp_len) {
> + d_printf("%s", label);
> + if (str->extra_flag) {
> + d_printf("[%d]", str->extra_flag);
> + }
> + d_printf(": ");
> + for (i = 0; i < str->comp_len; ++i) {
> + d_printf("%s%s", (i ? "." : ""),
> str->component[i]);
> + }
> + d_printf("\n");
> + }
> }
>
> /*
> @@ -246,7 +294,6 @@
> if (ret != 0) {
> return ret;
> }
> -
> ret = recv_cldap_netlogon(sock, &reply);
> close(sock);
>
> @@ -254,15 +301,48 @@
> return -1;
> }
>
> - d_printf("Version: 0x%x\n", reply.version);
> + d_printf("Information for Domain Controller: %s\n\n",
> + ads->config.ldap_server_name);
> +
> + d_printf("Response Type: 0x%x\n", reply.type);
> d_printf("GUID: ");
> print_guid(&reply.guid);
> - d_printf("Flags: 0x%x\n", reply.flags);
> - d_printf("Domain: %s\n", reply.domain);
> - d_printf("Server Name: %s\n", reply.server_name);
> - d_printf("Flatname: %s\n", reply.domain_flatname);
> - d_printf("Server Name2: %s\n", reply.server_flatname);
> - d_printf("DNS Name: %s\n", reply.dns_name);
> + d_printf("Flags:\n"
> + "\tIs a PDC: %s\n"
> + "\tIs a GC of the forest: %s\n"
> + "\tIs an LDAP server: %s\n"
> + "\tSupports DS: %s\n"
> + "\tIs running a KDC: %s\n"
> + "\tIs running time services: %s\n"
> + "\tIs the closest DC: %s\n"
> + "\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");
> +
> + d_print_netlogon_string("Forest", &reply.forest);
> + d_print_netlogon_string("Domain", &reply.domain);
> + d_print_netlogon_string("Hostname", &reply.hostname);
> +
> + d_print_netlogon_string("Pre-Win2k Domain",
> &reply.netbios_domain);
> + d_print_netlogon_string("Pre-Win2k Hostname",
> &reply.netbios_hostname);
> +
> + d_print_netlogon_string("User name", &reply.user_name);
> + d_print_netlogon_string("Site Name", &reply.site_name);
> + d_print_netlogon_string("Unknown Field", &reply.unk0);
> +
> + d_printf("NT Version: %d\n", reply.version);
> + d_printf("LMNT Token: %0.2x\n", reply.lmnt_token);
> + d_printf("LM20 Token: %0.2x\n", reply.lm20_token);
>
> cldap_reply_free(&reply);
>
>
> Anthony Liguori
> Linux/Active Directory Interoperability
> Linux Technology Center (LTC) - IBM Austin
> E-mail: aliguor at us.ibm.com
> Phone: (512) 838-1208
> Tie Line: 678-1208
More information about the samba-technical
mailing list