diff options
author | Gerald Carter <jerry@samba.org> | 2006-08-24 15:43:32 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:38:48 -0500 |
commit | 5693e6c599a586b1bb19eea375c6b1e22526031c (patch) | |
tree | 9190fcd83791a892aaca33debd400fd0b4124fc2 /source3/utils/net_ads.c | |
parent | 6717e0d467bea50cb7712e6b5278ddb403fdf828 (diff) | |
download | samba-5693e6c599a586b1bb19eea375c6b1e22526031c.tar.gz samba-5693e6c599a586b1bb19eea375c6b1e22526031c.tar.xz samba-5693e6c599a586b1bb19eea375c6b1e22526031c.zip |
r17798: Beginnings of a standalone libaddns library released under
the LGPL. Original code by Krishna Ganugapati <krishnag@centeris.com>.
Additional work by me.
It's still got some warts, but non-secure updates do
currently work. There are at least four things left to
really clean up.
1. Change the memory management to use talloc() rather than
malloc() and cleanup the leaks.
2. Fix the error code reporting (see initial changes to
dnserr.h)
3. Fix the secure updates
4. Define a public interface in addns.h
5. Move the code in libads/dns.c into the libaddns/ directory
(and under the LGPL).
A few notes:
* Enable the new code by compiling with --with-dnsupdate
* Also adds the command 'net ads dns register'
* Requires -luuid (included in the e2fsprogs-devel package).
* Has only been tested on Linux platforms so there may be portability
issues.
(This used to be commit 36f04674aeefd93c5a0408b8967dcd48b86fdbc1)
Diffstat (limited to 'source3/utils/net_ads.c')
-rw-r--r-- | source3/utils/net_ads.c | 179 |
1 files changed, 176 insertions, 3 deletions
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 2fbe088653..e6ad7c21b3 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -55,6 +55,9 @@ int net_ads_usage(int argc, const char **argv) d_printf(" Issue LDAP search queries using a general filter, by DN, or by SID\n"); d_printf("keytab\n"); d_printf(" Manage a local keytab file based on the machine account in AD\n"); + d_printf("dns\n"); + d_printf(" Issue a dynamic DNS update request the server's hostname\n"); + d_printf(" (using the machine credentials)\n"); return -1; } @@ -1136,7 +1139,89 @@ static BOOL net_derive_salting_principal( TALLOC_CTX *ctx, ADS_STRUCT *ads ) return kerberos_secrets_store_des_salt( salt ); } -/********************************************************* +/******************************************************************* + Send a DNS update request +*******************************************************************/ + +#if defined(WITH_DNS_UPDATES) +static BOOL net_update_dns( TALLOC_CTX *ctx, ADS_STRUCT *ads ) +{ + int num_addrs; + struct in_addr *iplist = NULL; + struct dns_rr_ns *nameservers = NULL; + int ns_count = 0; + int ret = 0; + NTSTATUS dns_status; + fstring machine_name; + fstring dns_server; + const char *dnsdomain; + ADS_STRUCT *ads_s = NULL; + + name_to_fqdn( machine_name, global_myname() ); + strlower_m( machine_name ); + + if ( (dnsdomain = strchr_m( machine_name, '.')) == NULL ) { + d_printf("No DNS domain configured for %s. Unable to perform DNS Update.\n", + machine_name); + goto done; + } + dnsdomain++; + + dns_status = ads_dns_lookup_ns( ctx, dnsdomain, &nameservers, &ns_count ); + if ( !NT_STATUS_IS_OK(dns_status) || (ns_count == 0)) { + DEBUG(3,("net_ads_join: Failed to find name server for the %s realm\n", + ads->config.realm)); + goto done; + } + + /* Get our ip address (not the 127.0.0.x address but a real ip address) */ + + num_addrs = get_my_ip_address( &iplist ); + if ( num_addrs <= 0 ) { + DEBUG(4,("net_ads_join: Failed to find my non-loopback IP addresses!\n")); + ret = -1; + goto done; + } + + /* Drop the user creds */ + + ads_kdestroy( NULL ); + + ads_s = ads_init( ads->server.realm, ads->server.workgroup, ads->server.ldap_server ); + if ( !ads_s ) { + DEBUG(1,("net_ads_join: ads_init() failed!\n")); + ret = -1; + goto done; + } + + /* kinit with the machine password */ + + asprintf( &ads_s->auth.user_name, "%s$", global_myname() ); + ads_s->auth.password = secrets_fetch_machine_password( lp_workgroup(), NULL, NULL ); + ads_s->auth.realm = SMB_STRDUP( lp_realm() ); + ads_kinit_password( ads_s ); + + /* Now perform the dns update - we'll try non-secure and if we fail, we'll + follow it up with a secure update */ + + fstrcpy( dns_server, nameservers[0].hostname ); + + ret = DoDNSUpdate(dns_server, dnsdomain, machine_name, iplist, num_addrs ); + if ( ret ) { + DEBUG(1, ("Error creating dns update!\n")); + } + +done: + SAFE_FREE( iplist ); + if ( ads_s ) + ads_destroy( &ads_s ); + + return (ret == 0); +} +#endif + + +/******************************************************************* utility function to parse an integer parameter from "parameter = value" **********************************************************/ @@ -1174,6 +1259,7 @@ int net_ads_join(int argc, const char **argv) ADS_STRUCT *ads = NULL; ADS_STATUS status; NTSTATUS nt_status; + char *machine_account = NULL; const char *short_domain_name = NULL; char *tmp_password, *password; struct cldap_netlogon_reply cldap_reply; @@ -1352,8 +1438,19 @@ int net_ads_join(int argc, const char **argv) DEBUG(1,("Error creating host keytab!\n")); } +#if defined(WITH_DNS_UPDATES) + /* We enter this block with user creds */ + + if ( !net_update_dns( ctx, ads ) ) { + d_fprintf( stderr, "DNS update failed!\n" ); + } + + /* exit from this block using machine creds */ +#endif + d_printf("Joined '%s' to realm '%s'\n", global_myname(), ads->config.realm); + SAFE_FREE(machine_account); TALLOC_FREE( ctx ); ads_destroy(&ads); @@ -1361,11 +1458,85 @@ int net_ads_join(int argc, const char **argv) fail: /* issue an overall failure message at the end. */ - d_printf("Failed to join domain: %s\n", - get_friendly_nt_error_msg(nt_status)); + d_printf("Failed to join domain: %s\n", get_friendly_nt_error_msg(nt_status)); + + SAFE_FREE(machine_account); + TALLOC_FREE( ctx ); + ads_destroy(&ads); + + return -1; + +} + +/******************************************************************* + ********************************************************************/ + +static int net_ads_dns_usage(int argc, const char **argv) +{ +#if defined(WITH_DNS_UPDATES) + d_printf("net ads dns <command>\n"); + d_printf("Valid commands:\n"); + d_printf(" register Issue a dynamic DNS update request for our hostname\n"); + + return 0; +#else + d_fprintf(stderr, "DNS update support not enabled at compile time!\n"); + return -1; +#endif +} + +/******************************************************************* + ********************************************************************/ + +static int net_ads_dns(int argc, const char **argv) +{ +#if defined(WITH_DNS_UPDATES) + ADS_STRUCT *ads; + ADS_STATUS status; + TALLOC_CTX *ctx; + BOOL register_dns = False; + int i; + + status = ads_startup(True, &ads); + if ( !ADS_ERR_OK(status) ) { + DEBUG(1, ("error on ads_startup: %s\n", ads_errstr(status))); + return -1; + } + + if (!(ctx = talloc_init("net_ads_dns"))) { + DEBUG(0, ("Could not initialise talloc context\n")); + return -1; + } + + /* process additional command line args */ + + for ( i=0; i<argc; i++ ) { + if ( strequal(argv[i], "register") ) { + register_dns = True; + } + else { + d_fprintf(stderr, "Bad option: %s\n", argv[i]); + return -1; + } + } + + if ( !net_update_dns( ctx, ads ) ) { + d_fprintf( stderr, "DNS update failed!\n" ); + ads_destroy( &ads ); + TALLOC_FREE( ctx ); + return -1; + } + + d_fprintf( stderr, "Successfully registered hostname with DNS\n" ); + ads_destroy(&ads); TALLOC_FREE( ctx ); + + return 0; +#else + d_fprintf(stderr, "DNS update support not enabled at compile time!\n"); return -1; +#endif } /******************************************************************* @@ -2026,6 +2197,7 @@ int net_ads_help(int argc, const char **argv) {"SEARCH", net_ads_search_usage}, {"INFO", net_ads_info}, {"JOIN", net_ads_join_usage}, + {"DNS", net_ads_dns_usage}, {"LEAVE", net_ads_leave}, {"STATUS", net_ads_status}, {"PASSWORD", net_ads_password}, @@ -2046,6 +2218,7 @@ int net_ads(int argc, const char **argv) {"STATUS", net_ads_status}, {"USER", net_ads_user}, {"GROUP", net_ads_group}, + {"DNS", net_ads_dns}, {"PASSWORD", net_ads_password}, {"CHANGETRUSTPW", net_ads_changetrustpw}, {"PRINTER", net_ads_printer}, |