diff options
-rw-r--r-- | source3/Makefile.in | 2 | ||||
-rw-r--r-- | source3/libsmb/asn1.c | 10 | ||||
-rw-r--r-- | source3/utils/net_ads.c | 26 | ||||
-rw-r--r-- | source3/utils/net_ads_cldap.c | 95 |
4 files changed, 132 insertions, 1 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 69ac925fd7..734f6ee82a 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -376,7 +376,7 @@ CLIENT_OBJ1 = client/client.o client/clitar.o CLIENT_OBJ = $(CLIENT_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ $(READLINE_OBJ) -NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_help.o \ +NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_ads_cldap.o utils/net_help.o \ utils/net_rap.o utils/net_rpc.o \ utils/net_rpc_join.o utils/net_time.o utils/net_lookup.o diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index b4ad3ad0b8..c8f832f3df 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -174,6 +174,16 @@ BOOL asn1_write_BOOLEAN(ASN1_DATA *data, BOOL v) return !data->has_error; } +/* write a BOOLEAN - hmm, I suspect this one is the correct one, and the + above boolean is bogus. Need to check */ +BOOL asn1_write_BOOLEAN2(ASN1_DATA *data, BOOL v) +{ + asn1_push_tag(data, ASN1_BOOLEAN); + asn1_write_uint8(data, v); + asn1_pop_tag(data); + return !data->has_error; +} + /* check a BOOLEAN */ BOOL asn1_check_BOOLEAN(ASN1_DATA *data, BOOL v) { diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index ad405fe68c..16450c5b29 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -56,6 +56,31 @@ int net_ads_usage(int argc, const char **argv) } +/* + this implements the CLDAP based netlogon lookup requests + for finding the domain controller of a ADS domain +*/ +static int net_ads_lookup(int argc, const char **argv) +{ + ADS_STRUCT *ads; + + ads = ads_init(NULL, NULL, opt_host); + if (ads) { + ads->auth.no_bind = 1; + } + + ads_connect(ads); + + if (!ads || !ads->config.realm) { + d_printf("Didn't find the cldap server!\n"); + return -1; + } + + return ads_cldap_netlogon(ads); +} + + + static int net_ads_info(int argc, const char **argv) { ADS_STRUCT *ads; @@ -1009,6 +1034,7 @@ int net_ads(int argc, const char **argv) {"PRINTER", net_ads_printer}, {"SEARCH", net_ads_search}, {"WORKGROUP", net_ads_workgroup}, + {"LOOKUP", net_ads_lookup}, {"HELP", net_ads_help}, {NULL, NULL} }; diff --git a/source3/utils/net_ads_cldap.c b/source3/utils/net_ads_cldap.c new file mode 100644 index 0000000000..f707f6beac --- /dev/null +++ b/source3/utils/net_ads_cldap.c @@ -0,0 +1,95 @@ +/* + Samba Unix/Linux SMB client library + net ads cldap functions + Copyright (C) 2001 Andrew Tridgell (tridge@samba.org) + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "../utils/net.h" + +#ifdef HAVE_ADS + +/* + do a cldap netlogon query +*/ +int ads_cldap_netlogon(ADS_STRUCT *ads) +{ + ASN1_DATA data; + char ntver[4]; + int sock; + + SIVAL(ntver, 0, 6); + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data,ASN1_SEQUENCE(0)); + asn1_write_Integer(&data, 4); + asn1_push_tag(&data, ASN1_APPLICATION(3)); + asn1_write_OctetString(&data, NULL, 0); + asn1_write_enumerated(&data, 0); + asn1_write_enumerated(&data, 0); + asn1_write_Integer(&data, 0); + asn1_write_Integer(&data, 0); + asn1_write_BOOLEAN2(&data, False); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + + 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_pop_tag(&data); + + asn1_push_tag(&data, ASN1_CONTEXT(3)); + asn1_write_OctetString(&data, "Host", 4); + asn1_write_OctetString(&data, "blu", 3); + asn1_pop_tag(&data); + + + asn1_push_tag(&data, ASN1_CONTEXT(3)); + asn1_write_OctetString(&data, "NtVer", 5); + asn1_write_OctetString(&data, ntver, 4); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + + asn1_push_tag(&data,ASN1_SEQUENCE(0)); + asn1_write_OctetString(&data, "NetLogon", 8); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + if (data.has_error) { + d_printf("Failed to build cldap netlogon at offset %d\n", (int)data.ofs); + asn1_free(&data); + return -1; + } + + 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", + inet_ntoa(ads->ldap_ip), + ads->ldap_port); + return -1; + } + + write(sock, data.data, data.length); + file_save("cldap_query.dat", data.data, data.length); + asn1_free(&data); + return 0; +} + + +#endif |