summaryrefslogtreecommitdiff
path: root/source3/utils/net_ads.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/utils/net_ads.c')
-rw-r--r--source3/utils/net_ads.c179
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},