From: Stefan Metzmacher Date: Thu, 7 Mar 2024 11:03:05 +0000 (+0100) Subject: lib/addns: rewrite signed dns update code to use gensec instead of plain gssapi X-Git-Tag: tdb-1.4.11~756 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c95a2785e209cbd0fcec5f6a553a95e12ff19fa1;p=thirdparty%2Fsamba.git lib/addns: rewrite signed dns update code to use gensec instead of plain gssapi Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider --- diff --git a/lib/addns/dns.h b/lib/addns/dns.h index 2c311e72a00..abf0906fdab 100644 --- a/lib/addns/dns.h +++ b/lib/addns/dns.h @@ -347,20 +347,16 @@ const char *dns_errstr(DNS_ERROR err); /* from dnsgss.c */ -#ifdef HAVE_GSSAPI - -void display_status( const char *msg, OM_uint32 maj_stat, OM_uint32 min_stat ); -DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm, - const char *servername, - const char *keyname, - gss_ctx_id_t *gss_ctx, - enum dns_ServerType srv_type ); +struct gensec_security; + +DNS_ERROR dns_negotiate_sec_ctx(const char *servername, + const char *keyname, + struct gensec_security *gensec, + enum dns_ServerType srv_type); DNS_ERROR dns_sign_update(struct dns_update_request *req, - gss_ctx_id_t gss_ctx, + struct gensec_security *gensec, const char *keyname, const char *algorithmname, time_t time_signed, uint16_t fudge); -#endif /* HAVE_GSSAPI */ - #endif /* _DNS_H */ diff --git a/lib/addns/dnsgss.c b/lib/addns/dnsgss.c index a315b804df4..8800ac24c8a 100644 --- a/lib/addns/dnsgss.c +++ b/lib/addns/dnsgss.c @@ -22,110 +22,51 @@ License along with this library; if not, see . */ -#include "dns.h" -#include - - -#ifdef HAVE_GSSAPI - -/********************************************************************* -*********************************************************************/ - -#ifndef HAVE_STRUPR -static int strupr( char *szDomainName ) -{ - if ( !szDomainName ) { - return ( 0 ); - } - while ( *szDomainName != '\0' ) { - *szDomainName = toupper( *szDomainName ); - szDomainName++; - } - return ( 0 ); -} -#endif - -#if 0 -/********************************************************************* -*********************************************************************/ - -static void display_status_1( const char *m, OM_uint32 code, int type ) -{ - OM_uint32 maj_stat, min_stat; - gss_buffer_desc msg; - OM_uint32 msg_ctx; - - msg_ctx = 0; - while ( 1 ) { - maj_stat = gss_display_status( &min_stat, code, - type, GSS_C_NULL_OID, - &msg_ctx, &msg ); - fprintf( stdout, "GSS-API error %s: %s\n", m, - ( char * ) msg.value ); - ( void ) gss_release_buffer( &min_stat, &msg ); - - if ( !msg_ctx ) - break; - } -} +#include "replace.h" +#include +#include "lib/util/talloc_stack.h" +#include "lib/util/data_blob.h" +#include "lib/util/time.h" +#include "lib/util/charset/charset.h" +#include "libcli/util/ntstatus.h" +#include "auth/gensec/gensec.h" -/********************************************************************* -*********************************************************************/ +#include "dns.h" -void display_status( const char *msg, OM_uint32 maj_stat, OM_uint32 min_stat ) -{ - display_status_1( msg, maj_stat, GSS_C_GSS_CODE ); - display_status_1( msg, min_stat, GSS_C_MECH_CODE ); -} -#endif - -static DNS_ERROR dns_negotiate_gss_ctx_int( TALLOC_CTX *mem_ctx, - struct dns_connection *conn, - const char *keyname, - const gss_name_t target_name, - gss_ctx_id_t *ctx, - enum dns_ServerType srv_type ) +static DNS_ERROR dns_negotiate_gss_ctx_int(struct dns_connection *conn, + const char *keyname, + struct gensec_security *gensec, + enum dns_ServerType srv_type) { - struct gss_buffer_desc_struct input_desc, *input_ptr, output_desc; - OM_uint32 major, minor; - OM_uint32 ret_flags; + TALLOC_CTX *frame = talloc_stackframe(); struct dns_request *req = NULL; struct dns_buffer *buf = NULL; + DATA_BLOB in = { .length = 0, }; + DATA_BLOB out = { .length = 0, }; + NTSTATUS status; DNS_ERROR err; - gss_OID_desc krb5_oid_desc = - { 9, discard_const("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") }; - - *ctx = GSS_C_NO_CONTEXT; - input_ptr = NULL; - do { - major = gss_init_sec_context( - &minor, NULL, ctx, target_name, &krb5_oid_desc, - GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | - GSS_C_CONF_FLAG | - GSS_C_INTEG_FLAG, - 0, NULL, input_ptr, NULL, &output_desc, - &ret_flags, NULL ); - - if (input_ptr != NULL) { - TALLOC_FREE(input_desc.value); + status = gensec_update(gensec, frame, in, &out); + data_blob_free(&in); + if (GENSEC_UPDATE_IS_NTERROR(status)) { + err = ERROR_DNS_GSS_ERROR; + goto error; } - if (output_desc.length != 0) { - + if (out.length != 0) { struct dns_rrec *rec; time_t t = time(NULL); - err = dns_create_query(mem_ctx, keyname, QTYPE_TKEY, + err = dns_create_query(frame, keyname, QTYPE_TKEY, DNS_CLASS_IN, &req); if (!ERR_DNS_IS_OK(err)) goto error; err = dns_create_tkey_record( req, keyname, "gss.microsoft.com", t, t + 86400, DNS_TKEY_MODE_GSSAPI, 0, - output_desc.length, (uint8_t *)output_desc.value, + out.length, out.data, &rec ); if (!ERR_DNS_IS_OK(err)) goto error; @@ -143,7 +84,7 @@ static DNS_ERROR dns_negotiate_gss_ctx_int( TALLOC_CTX *mem_ctx, if (!ERR_DNS_IS_OK(err)) goto error; - err = dns_marshall_request(mem_ctx, req, &buf); + err = dns_marshall_request(frame, req, &buf); if (!ERR_DNS_IS_OK(err)) goto error; err = dns_send(conn, buf); @@ -151,24 +92,21 @@ static DNS_ERROR dns_negotiate_gss_ctx_int( TALLOC_CTX *mem_ctx, TALLOC_FREE(buf); TALLOC_FREE(req); - } - - gss_release_buffer(&minor, &output_desc); - if ((major != GSS_S_COMPLETE) && - (major != GSS_S_CONTINUE_NEEDED)) { - return ERROR_DNS_GSS_ERROR; + err = dns_receive(frame, conn, &buf); + if (!ERR_DNS_IS_OK(err)) goto error; } - if (major == GSS_S_CONTINUE_NEEDED) { - + if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { struct dns_request *resp; struct dns_tkey_record *tkey; struct dns_rrec *tkey_answer = NULL; uint16_t i; - err = dns_receive(mem_ctx, conn, &buf); - if (!ERR_DNS_IS_OK(err)) goto error; + if (buf == NULL) { + err = ERROR_DNS_BAD_RESPONSE; + goto error; + } err = dns_unmarshall_request(buf, buf, &resp); if (!ERR_DNS_IS_OK(err)) goto error; @@ -191,18 +129,15 @@ static DNS_ERROR dns_negotiate_gss_ctx_int( TALLOC_CTX *mem_ctx, } err = dns_unmarshall_tkey_record( - mem_ctx, resp->answers[0], &tkey); + frame, resp->answers[0], &tkey); if (!ERR_DNS_IS_OK(err)) goto error; - input_desc.length = tkey->key_length; - input_desc.value = talloc_move(mem_ctx, &tkey->key); - - input_ptr = &input_desc; + in = data_blob_const(tkey->key, tkey->key_length); TALLOC_FREE(buf); } - } while ( major == GSS_S_CONTINUE_NEEDED ); + } while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)); /* If we arrive here, we have a valid security context */ @@ -210,94 +145,54 @@ static DNS_ERROR dns_negotiate_gss_ctx_int( TALLOC_CTX *mem_ctx, error: - TALLOC_FREE(buf); - TALLOC_FREE(req); + TALLOC_FREE(frame); return err; } -DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm, - const char *servername, - const char *keyname, - gss_ctx_id_t *gss_ctx, - enum dns_ServerType srv_type ) +DNS_ERROR dns_negotiate_sec_ctx(const char *servername, + const char *keyname, + struct gensec_security *gensec, + enum dns_ServerType srv_type) { - OM_uint32 major, minor; - - char *upcaserealm, *targetname; + TALLOC_CTX *frame = talloc_stackframe(); DNS_ERROR err; + struct dns_connection *conn = NULL; - gss_buffer_desc input_name; - struct dns_connection *conn; - - gss_name_t targ_name; - - gss_OID_desc nt_host_oid_desc = - {10, discard_const("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01")}; - - TALLOC_CTX *mem_ctx; - - if (!(mem_ctx = talloc_init("dns_negotiate_sec_ctx"))) { - return ERROR_DNS_NO_MEMORY; - } - - err = dns_open_connection( servername, DNS_TCP, mem_ctx, &conn ); + err = dns_open_connection( servername, DNS_TCP, frame, &conn ); if (!ERR_DNS_IS_OK(err)) goto error; - if (!(upcaserealm = talloc_strdup(mem_ctx, target_realm))) { - err = ERROR_DNS_NO_MEMORY; - goto error; - } - - strupr(upcaserealm); - - if (!(targetname = talloc_asprintf(mem_ctx, "dns/%s@%s", - servername, upcaserealm))) { - err = ERROR_DNS_NO_MEMORY; - goto error; - } - - input_name.value = targetname; - input_name.length = strlen(targetname); - - major = gss_import_name( &minor, &input_name, - &nt_host_oid_desc, &targ_name ); - - if (major) { - err = ERROR_DNS_GSS_ERROR; - goto error; - } - - err = dns_negotiate_gss_ctx_int(mem_ctx, conn, keyname, - targ_name, gss_ctx, srv_type ); - - gss_release_name( &minor, &targ_name ); + err = dns_negotiate_gss_ctx_int(conn, keyname, + gensec, + srv_type); + if (!ERR_DNS_IS_OK(err)) goto error; error: - TALLOC_FREE(mem_ctx); + TALLOC_FREE(frame); return err; } DNS_ERROR dns_sign_update(struct dns_update_request *req, - gss_ctx_id_t gss_ctx, + struct gensec_security *gensec, const char *keyname, const char *algorithmname, time_t time_signed, uint16_t fudge) { + TALLOC_CTX *frame = talloc_stackframe(); struct dns_buffer *buf; DNS_ERROR err; struct dns_domain_name *key, *algorithm; - struct gss_buffer_desc_struct msg, mic; - OM_uint32 major, minor; struct dns_rrec *rec; + DATA_BLOB mic = { .length = 0, }; + NTSTATUS status; - err = dns_marshall_update_request(req, req, &buf); + err = dns_marshall_update_request(frame, req, &buf); if (!ERR_DNS_IS_OK(err)) return err; - err = dns_domain_name_from_string(buf, keyname, &key); + err = dns_domain_name_from_string(frame, keyname, &key); if (!ERR_DNS_IS_OK(err)) goto error; - err = dns_domain_name_from_string(buf, algorithmname, &algorithm); + err = dns_domain_name_from_string(frame, algorithmname, &algorithm); if (!ERR_DNS_IS_OK(err)) goto error; dns_marshall_domain_name(buf, key); @@ -313,32 +208,31 @@ DNS_ERROR dns_sign_update(struct dns_update_request *req, err = buf->error; if (!ERR_DNS_IS_OK(buf->error)) goto error; - msg.value = (void *)buf->data; - msg.length = buf->offset; - - major = gss_get_mic(&minor, gss_ctx, 0, &msg, &mic); - if (major != 0) { + status = gensec_sign_packet(gensec, + frame, + buf->data, + buf->offset, + buf->data, + buf->offset, + &mic); + if (!NT_STATUS_IS_OK(status)) { err = ERROR_DNS_GSS_ERROR; goto error; } if (mic.length > 0xffff) { - gss_release_buffer(&minor, &mic); err = ERROR_DNS_GSS_ERROR; goto error; } - err = dns_create_tsig_record(buf, keyname, algorithmname, time_signed, - fudge, mic.length, (uint8_t *)mic.value, + err = dns_create_tsig_record(frame, keyname, algorithmname, time_signed, + fudge, mic.length, mic.data, req->id, 0, &rec); - gss_release_buffer(&minor, &mic); if (!ERR_DNS_IS_OK(err)) goto error; err = dns_add_rrec(req, rec, &req->num_additionals, &req->additional); error: - TALLOC_FREE(buf); + TALLOC_FREE(frame); return err; } - -#endif /* HAVE_GSSAPI */ diff --git a/lib/addns/wscript_build b/lib/addns/wscript_build index cc72b35b437..694d71b732e 100644 --- a/lib/addns/wscript_build +++ b/lib/addns/wscript_build @@ -11,6 +11,6 @@ bld.SAMBA_LIBRARY('addns', error.c dnsquery_srv.c ''', - public_deps='samba-util gssapi ndr resolv dns_lookup', + public_deps='samba-util gensec ndr resolv dns_lookup', private_library=True, vars=locals()) diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 4350e5e9b41..d7ddef60e39 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -1997,6 +1997,7 @@ static int net_ads_dns_register(struct net_context *c, int argc, const char **ar ntstatus = net_update_dns_ext(c, tmp_ctx, ads, + c->creds, hostname, addrs, num_addrs, @@ -2063,6 +2064,7 @@ static int net_ads_dns_unregister(struct net_context *c, ntstatus = net_update_dns_ext(c, tmp_ctx, ads, + c->creds, hostname, NULL, 0, diff --git a/source3/utils/net_ads_join_dns.c b/source3/utils/net_ads_join_dns.c index 97f767aba66..617a0d94246 100644 --- a/source3/utils/net_ads_join_dns.c +++ b/source3/utils/net_ads_join_dns.c @@ -23,7 +23,7 @@ #include "includes.h" #include "utils/net.h" #include "../lib/addns/dnsquery.h" -#include "secrets.h" +#include "passdb.h" #include "krb5_env.h" #include "utils/net_dns.h" #include "lib/util/string_wrappers.h" @@ -44,7 +44,9 @@ void use_in_memory_ccache(void) { } static NTSTATUS net_update_dns_internal(struct net_context *c, - TALLOC_CTX *ctx, ADS_STRUCT *ads, + TALLOC_CTX *ctx, + ADS_STRUCT *ads, + struct cli_credentials *creds, const char *machine_name, const struct sockaddr_storage *addrs, int num_addrs, bool remove_host) @@ -85,7 +87,7 @@ static NTSTATUS net_update_dns_internal(struct net_context *c, ADS_STATUS ads_status; if ( !ads->ldap.ld ) { - ads_status = ads_connect( ads ); + ads_status = ads_connect_creds(ads, creds); if ( !ADS_ERR_OK(ads_status) ) { DEBUG(0,("net_update_dns_internal: Failed to connect to our DC!\n")); status = ads_ntstatus(ads_status); @@ -163,6 +165,7 @@ static NTSTATUS net_update_dns_internal(struct net_context *c, dns_err = DoDNSUpdate(dns_server, dnsdomain, machine_name, + creds, addrs, num_addrs, flags, @@ -195,7 +198,9 @@ done: } NTSTATUS net_update_dns_ext(struct net_context *c, - TALLOC_CTX *mem_ctx, ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + ADS_STRUCT *ads, + struct cli_credentials *creds, const char *hostname, struct sockaddr_storage *iplist, int num_addrs, bool remove_host) @@ -231,29 +236,27 @@ NTSTATUS net_update_dns_ext(struct net_context *c, iplist = iplist_alloc; } - status = net_update_dns_internal(c, mem_ctx, ads, machine_name, - iplist, num_addrs, remove_host); + status = net_update_dns_internal(c, + mem_ctx, + ads, + creds, + machine_name, + iplist, + num_addrs, + remove_host); SAFE_FREE(iplist_alloc); return status; } -static NTSTATUS net_update_dns(struct net_context *c, TALLOC_CTX *mem_ctx, ADS_STRUCT *ads, const char *hostname) -{ - NTSTATUS status; - - status = net_update_dns_ext(c, mem_ctx, ads, hostname, NULL, 0, false); - return status; -} #endif void net_ads_join_dns_updates(struct net_context *c, TALLOC_CTX *ctx, struct libnet_JoinCtx *r) { #if defined(HAVE_KRB5) ADS_STRUCT *ads_dns = NULL; - int ret; + struct cli_credentials *creds = NULL; NTSTATUS status; - char *machine_password = NULL; /* * In a clustered environment, don't do dynamic dns updates: @@ -283,7 +286,7 @@ void net_ads_join_dns_updates(struct net_context *c, TALLOC_CTX *ctx, struct lib ads_dns = ads_init(ctx, lp_realm(), - NULL, + lp_workgroup(), r->in.dc_name, ADS_SASL_PLAIN); if (ads_dns == NULL) { @@ -291,45 +294,24 @@ void net_ads_join_dns_updates(struct net_context *c, TALLOC_CTX *ctx, struct lib goto done; } - use_in_memory_ccache(); - - ads_dns->auth.user_name = talloc_asprintf(ads_dns, - "%s$", - lp_netbios_name()); - if (ads_dns->auth.user_name == NULL) { - d_fprintf(stderr, _("DNS update failed: out of memory\n")); - goto done; - } - - machine_password = secrets_fetch_machine_password( - r->out.netbios_domain_name, NULL, NULL); - if (machine_password != NULL) { - ads_dns->auth.password = talloc_strdup(ads_dns, - machine_password); - SAFE_FREE(machine_password); - if (ads_dns->auth.password == NULL) { - d_fprintf(stderr, - _("DNS update failed: out of memory\n")); - goto done; - } - } - - ads_dns->auth.realm = talloc_asprintf_strupper_m(ads_dns, "%s", r->out.dns_domain_name); - if (ads_dns->auth.realm == NULL) { - d_fprintf(stderr, _("talloc_asprintf_strupper_m %s failed\n"), - ads_dns->auth.realm); - goto done; - } - - ret = ads_kinit_password(ads_dns); - if (ret != 0) { - d_fprintf(stderr, - _("DNS update failed: kinit failed: %s\n"), - error_message(ret)); + status = pdb_get_trust_credentials(ads_dns->server.workgroup, + ads_dns->server.realm, + ads_dns, + &creds); + if (!NT_STATUS_IS_OK(status)) { + d_fprintf(stderr, "pdb_get_trust_credentials() failed: %s\n", + nt_errstr(status)); goto done; } - status = net_update_dns(c, ctx, ads_dns, NULL); + status = net_update_dns_ext(c, + ads_dns, + ads_dns, + creds, + NULL, + NULL, + 0, + false); if (!NT_STATUS_IS_OK(status)) { d_fprintf( stderr, _("DNS update failed: %s\n"), nt_errstr(status)); diff --git a/source3/utils/net_dns.c b/source3/utils/net_dns.c index 9850ba40299..486f1752b10 100644 --- a/source3/utils/net_dns.c +++ b/source3/utils/net_dns.c @@ -23,15 +23,81 @@ #include "utils/net.h" #include "../lib/addns/dns.h" #include "utils/net_dns.h" +#include "auth/gensec/gensec.h" +#include "auth_generic.h" #if defined(HAVE_KRB5) /********************************************************************* *********************************************************************/ +static DNS_ERROR DoDNSUpdateNegotiateGensec(const char *pszServerName, + const char *pszDomainName, + const char *keyname, + enum dns_ServerType srv_type, + struct cli_credentials *creds, + TALLOC_CTX *mem_ctx, + struct gensec_security **_gensec) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct auth_generic_state *ans = NULL; + NTSTATUS status; + DNS_ERROR err; + + status = auth_generic_client_prepare(mem_ctx, &ans); + if (!NT_STATUS_IS_OK(status)) { + err = ERROR_DNS_GSS_ERROR; + goto error; + } + talloc_steal(frame, ans); + + status = auth_generic_set_creds(ans, creds); + if (!NT_STATUS_IS_OK(status)) { + err = ERROR_DNS_GSS_ERROR; + goto error; + } + + status = gensec_set_target_service(ans->gensec_security, + "dns"); + if (!NT_STATUS_IS_OK(status)) { + err = ERROR_DNS_GSS_ERROR; + goto error; + } + + status = gensec_set_target_hostname(ans->gensec_security, + pszServerName); + if (!NT_STATUS_IS_OK(status)) { + err = ERROR_DNS_GSS_ERROR; + goto error; + } + + gensec_want_feature(ans->gensec_security, GENSEC_FEATURE_SIGN); + + status = auth_generic_client_start(ans, GENSEC_OID_KERBEROS5); + if (!NT_STATUS_IS_OK(status)) { + err = ERROR_DNS_GSS_ERROR; + goto error; + } + + err = dns_negotiate_sec_ctx(pszServerName, + keyname, + ans->gensec_security, + srv_type); + if (!ERR_DNS_IS_OK(err)) { + goto error; + } + + *_gensec = talloc_move(mem_ctx, &ans->gensec_security); + error: + TALLOC_FREE(frame); + + return err; +} + DNS_ERROR DoDNSUpdate(char *pszServerName, const char *pszDomainName, const char *pszHostName, + struct cli_credentials *creds, const struct sockaddr_storage *sslist, size_t num_addrs, uint32_t flags, @@ -41,7 +107,6 @@ DNS_ERROR DoDNSUpdate(char *pszServerName, DNS_ERROR err; struct dns_connection *conn; TALLOC_CTX *mem_ctx; - OM_uint32 minor; struct dns_update_request *req, *resp; DEBUG(10,("DoDNSUpdate called with flags: 0x%08x\n", flags)); @@ -121,8 +186,8 @@ DNS_ERROR DoDNSUpdate(char *pszServerName, * Okay, we have to try with signing */ if (flags & DNS_UPDATE_SIGNED) { - gss_ctx_id_t gss_context; - char *keyname; + struct gensec_security *gensec = NULL; + char *keyname = NULL; err = dns_create_update_request(mem_ctx, pszDomainName, @@ -138,24 +203,31 @@ DNS_ERROR DoDNSUpdate(char *pszServerName, goto error; } - err = dns_negotiate_sec_ctx( pszDomainName, pszServerName, - keyname, &gss_context, DNS_SRV_ANY ); + err = DoDNSUpdateNegotiateGensec(pszServerName, + pszDomainName, + keyname, + DNS_SRV_ANY, + creds, + mem_ctx, + &gensec); /* retry using the Windows 2000 DNS hack */ if (!ERR_DNS_IS_OK(err)) { - err = dns_negotiate_sec_ctx( pszDomainName, pszServerName, - keyname, &gss_context, - DNS_SRV_WIN2000 ); + err = DoDNSUpdateNegotiateGensec(pszServerName, + pszDomainName, + keyname, + DNS_SRV_WIN2000, + creds, + mem_ctx, + &gensec); } if (!ERR_DNS_IS_OK(err)) goto error; - err = dns_sign_update(req, gss_context, keyname, + err = dns_sign_update(req, gensec, 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); diff --git a/source3/utils/net_dns.h b/source3/utils/net_dns.h index 4569e1c3328..508aff9d97a 100644 --- a/source3/utils/net_dns.h +++ b/source3/utils/net_dns.h @@ -32,9 +32,12 @@ #include "../lib/addns/dns.h" +struct cli_credentials; + DNS_ERROR DoDNSUpdate(char *pszServerName, const char *pszDomainName, const char *pszHostName, + struct cli_credentials *creds, const struct sockaddr_storage *sslist, size_t num_addrs, uint32_t flags, diff --git a/source3/utils/net_proto.h b/source3/utils/net_proto.h index ccfa89ae105..cabbc751aaf 100644 --- a/source3/utils/net_proto.h +++ b/source3/utils/net_proto.h @@ -57,7 +57,9 @@ int net_ads(struct net_context *c, int argc, const char **argv); /* The following definitions come from utils/net_ads_join_dns.c */ void use_in_memory_ccache(void); NTSTATUS net_update_dns_ext(struct net_context *c, - TALLOC_CTX *mem_ctx, ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + ADS_STRUCT *ads, + struct cli_credentials *creds, const char *hostname, struct sockaddr_storage *iplist, int num_addrs, bool remove_host);