summaryrefslogtreecommitdiff
path: root/source3/utils/net_dns.c
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2006-11-17 21:46:26 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:15:53 -0500
commitc2aae726ea3f697c50f8d2304e2a9e69c56ab90f (patch)
tree0c05a34d585fa27282a3a106863c99e24237957f /source3/utils/net_dns.c
parent9a88644bb5834b526085fad7536a02e333bf8c3c (diff)
downloadsamba-c2aae726ea3f697c50f8d2304e2a9e69c56ab90f.tar.gz
samba-c2aae726ea3f697c50f8d2304e2a9e69c56ab90f.tar.bz2
samba-c2aae726ea3f697c50f8d2304e2a9e69c56ab90f.zip
r19762: libaddns/*[ch] code fixes donated by Centeris Corporation
(http://www.centeris.com/) under my copyright. * Rework error reporting to use DNS_ERROR instead of int32 * Convert memory allocation to use talloc() * Generalize the DNS request/response packet marshalling * Fix the secure update requests (This used to be commit c78798333616c3f823514df0f58da2eb3a30a988)
Diffstat (limited to 'source3/utils/net_dns.c')
-rw-r--r--source3/utils/net_dns.c141
1 files changed, 117 insertions, 24 deletions
diff --git a/source3/utils/net_dns.c b/source3/utils/net_dns.c
index cb83b000ca..d372211a5f 100644
--- a/source3/utils/net_dns.c
+++ b/source3/utils/net_dns.c
@@ -30,41 +30,115 @@
/*********************************************************************
*********************************************************************/
-int DoDNSUpdate( char *pszServerName, const char *pszDomainName,
- char *pszHostName, struct in_addr *iplist, int num_addrs )
+DNS_ERROR DoDNSUpdate(ADS_STRUCT *ads, char *pszServerName,
+ const char *pszDomainName, const char *pszHostName,
+ const struct in_addr *iplist, int num_addrs )
{
- int32 dwError = 0;
- DNS_ERROR dns_status;
- HANDLE hDNSServer = ( HANDLE ) NULL;
- int32 dwResponseCode = 0;
- DNS_UPDATE_RESPONSE *pDNSUpdateResponse = NULL;
-#if 0
- DNS_UPDATE_RESPONSE *pDNSSecureUpdateResponse = NULL;
-#endif
+ DNS_ERROR err;
+ struct dns_connection *conn;
+ TALLOC_CTX *mem_ctx;
+ OM_uint32 minor;
+ struct dns_update_request *req, *resp;
if ( (num_addrs <= 0) || !iplist ) {
- return -1;
+ return ERROR_DNS_INVALID_PARAMETER;
+ }
+
+ if (!(mem_ctx = talloc_init("DoDNSUpdate"))) {
+ return ERROR_DNS_NO_MEMORY;
}
- dns_status = DNSOpen( pszServerName, DNS_TCP, &hDNSServer );
- BAIL_ON_DNS_ERROR( dns_status );
+ err = dns_open( pszServerName, DNS_TCP, mem_ctx, &conn );
+ if (!ERR_DNS_IS_OK(err)) {
+ goto error;
+ }
+
+ /*
+ * Probe if everything's fine
+ */
+
+ err = dns_create_probe(mem_ctx, pszDomainName, pszHostName,
+ num_addrs, iplist, &req);
+ if (!ERR_DNS_IS_OK(err)) goto error;
+
+ err = dns_update_transaction(mem_ctx, conn, req, &resp);
+ if (!ERR_DNS_IS_OK(err)) goto error;
+
+ if (dns_response_code(resp->flags) == DNS_NO_ERROR) {
+ TALLOC_FREE(mem_ctx);
+ return ERROR_DNS_SUCCESS;
+ }
+
+ /*
+ * First try without signing
+ */
- dwError = DNSSendUpdate( hDNSServer, pszDomainName, pszHostName,
- iplist, num_addrs, &pDNSUpdateResponse );
- BAIL_ON_ERROR( dwError );
+ err = dns_create_update_request(mem_ctx, pszDomainName, pszHostName,
+ iplist[0].s_addr, &req);
+ if (!ERR_DNS_IS_OK(err)) goto error;
- dwError = DNSUpdateGetResponseCode( pDNSUpdateResponse,
- &dwResponseCode );
- if ( dwResponseCode == DNS_REFUSED ) {
- dwError = -1;
+ err = dns_update_transaction(mem_ctx, conn, req, &resp);
+ if (!ERR_DNS_IS_OK(err)) goto error;
+
+ if (dns_response_code(resp->flags) == DNS_NO_ERROR) {
+ TALLOC_FREE(mem_ctx);
+ return ERROR_DNS_SUCCESS;
+ }
+
+ /*
+ * Okay, we have to try with signing
+ */
+ {
+ ADS_STRUCT *ads_s;
+ gss_ctx_id_t gss_context;
+ int res;
+ char *keyname;
+
+ if (!(keyname = dns_generate_keyname( mem_ctx ))) {
+ err = ERROR_DNS_NO_MEMORY;
+ goto error;
+ }
+
+ if (!(ads_s = ads_init(ads->server.realm, ads->server.workgroup,
+ ads->server.ldap_server))) {
+ return ERROR_DNS_NO_MEMORY;
+ }
+
+ /* kinit with the machine password */
+ setenv(KRB5_ENV_CCNAME, "MEMORY:net_ads", 1);
+ 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() );
+ res = ads_kinit_password( ads_s );
+ ads_destroy(&ads_s);
+ if (res) {
+ err = ERROR_DNS_GSS_ERROR;
+ goto error;
+ }
+
+ err = dns_negotiate_sec_ctx( pszDomainName, pszServerName,
+ keyname, &gss_context );
+ if (!ERR_DNS_IS_OK(err)) goto error;
+
+ err = dns_sign_update(req, gss_context, keyname,
+ "gss.microsoft.com", time(NULL), 3600);
+
+ gss_delete_sec_context(&minor, &gss_context, GSS_C_NO_BUFFER);
+
+ if (!ERR_DNS_IS_OK(err)) goto error;
+
+ err = dns_update_transaction(mem_ctx, conn, req, &resp);
+ if (!ERR_DNS_IS_OK(err)) goto error;
+
+ err = (dns_response_code(resp->flags) == DNS_NO_ERROR) ?
+ ERROR_DNS_SUCCESS : ERROR_DNS_UPDATE_FAILED;
}
- BAIL_ON_ERROR( dwError );
-cleanup:
- return dwError;
error:
- goto cleanup;
+ TALLOC_FREE(mem_ctx);
+ return err;
}
/*********************************************************************
@@ -96,4 +170,23 @@ int get_my_ip_address( struct in_addr **ips )
return count;
}
+DNS_ERROR do_gethostbyname(const char *server, const char *host)
+{
+ struct dns_connection *conn;
+ struct dns_request *req, *resp;
+ DNS_ERROR err;
+
+ err = dns_open(server, DNS_UDP, NULL, &conn);
+ if (!ERR_DNS_IS_OK(err)) goto error;
+
+ err = dns_create_query(conn, host, QTYPE_A, DNS_CLASS_IN, &req);
+ if (!ERR_DNS_IS_OK(err)) goto error;
+
+ err = dns_transaction(conn, conn, req, &resp);
+
+ error:
+ TALLOC_FREE(conn);
+ return err;
+}
+
#endif /* defined(WITH_DNS_UPDATES) */