From ad2974cd05b4d08c8b92f505bf95aa8e8533235f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 24 Nov 2001 14:16:41 +0000 Subject: added "net join" command this completes the first stage of the smbd ADS support (This used to be commit 058a5aee901e6609969ef7e1d482a720a84a4a12) --- source3/libads/krb5_setpw.c | 352 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 352 insertions(+) create mode 100644 source3/libads/krb5_setpw.c (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c new file mode 100644 index 0000000000..5cb3de1bb5 --- /dev/null +++ b/source3/libads/krb5_setpw.c @@ -0,0 +1,352 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + krb5 set password implementation + Copyright (C) Andrew Tridgell 2001 + + 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" + +#if HAVE_KRB5 + +#define DEFAULT_KPASSWD_PORT 464 +#define KRB5_KPASSWD_VERS_CHANGEPW 1 +#define KRB5_KPASSWD_VERS_SETPW 0xff80 +#define KRB5_KPASSWD_ACCESSDENIED 5 +#define KRB5_KPASSWD_BAD_VERSION 6 + +/* This implements the Kerb password change protocol as specifed in + * kerb-chg-password-02.txt + */ +static DATA_BLOB encode_krb5_setpw(const char *hostname, + const char *realm, const char *password) +{ + ASN1_DATA req; + DATA_BLOB ret; + + memset(&req, 0, sizeof(req)); + + asn1_push_tag(&req, ASN1_SEQUENCE(0)); + asn1_push_tag(&req, ASN1_CONTEXT(0)); + asn1_write_OctetString(&req, password, strlen(password)); + asn1_pop_tag(&req); + + asn1_push_tag(&req, ASN1_CONTEXT(1)); + asn1_push_tag(&req, ASN1_SEQUENCE(0)); + + asn1_push_tag(&req, ASN1_CONTEXT(0)); + asn1_write_Integer(&req, 1); + asn1_pop_tag(&req); + + asn1_push_tag(&req, ASN1_CONTEXT(1)); + asn1_push_tag(&req, ASN1_SEQUENCE(0)); + asn1_write_GeneralString(&req, "HOST"); + asn1_write_GeneralString(&req, hostname); + asn1_pop_tag(&req); + asn1_pop_tag(&req); + asn1_pop_tag(&req); + asn1_pop_tag(&req); + + asn1_push_tag(&req, ASN1_CONTEXT(2)); + asn1_write_GeneralString(&req, realm); + asn1_pop_tag(&req); + asn1_pop_tag(&req); + + ret = data_blob(req.data, req.length); + asn1_free(&req); + + return ret; +} + +static krb5_error_code build_setpw_request(krb5_context context, + krb5_auth_context auth_context, + krb5_data *ap_req, + const char *hostname, + const char *realm, + const char *passwd, + krb5_data *packet) +{ + krb5_error_code ret; + krb5_data cipherpw; + krb5_data encoded_setpw; + krb5_replay_data replay; + char *p; + DATA_BLOB setpw; + + ret = krb5_auth_con_setflags(context, + auth_context,KRB5_AUTH_CONTEXT_DO_SEQUENCE); + if (ret) { + DEBUG(1,("krb5_auth_con_setflags failed (%s)\n", + error_message(ret))); + return ret; + } + + setpw = encode_krb5_setpw(hostname, realm, passwd); + + encoded_setpw.data = setpw.data; + encoded_setpw.length = setpw.length; + + ret = krb5_mk_priv(context, auth_context, + &encoded_setpw, &cipherpw, &replay); + if (ret) { + DEBUG(1,("krb5_mk_priv failed (%s)\n", error_message(ret))); + return ret; + } + + packet->data = (char *)malloc(ap_req->length + cipherpw.length + 6); + + /* see the RFC for details */ + p = packet->data + 2; + RSSVAL(p, 0, 0xff80); p += 2; + RSSVAL(p, 0, ap_req->length); p += 2; + memcpy(p, ap_req->data, ap_req->length); p += ap_req->length; + memcpy(p, cipherpw.data, cipherpw.length); p += cipherpw.length; + packet->length = PTR_DIFF(p,packet->data); + RSSVAL(packet->data, 0, packet->length); + + return 0; +} + +static krb5_error_code parse_setpw_reply(krb5_context context, + krb5_auth_context auth_context, + krb5_data *packet) +{ + krb5_data ap_rep; + char *p; + int vnum, ret, res_code; + krb5_data cipherresult; + krb5_data clearresult; + krb5_ap_rep_enc_part *ap_rep_enc; + krb5_replay_data replay; + + if (packet->length < 4) { + return KRB5KRB_AP_ERR_MODIFIED; + } + + p = packet->data; + + if (packet->data[0] == 0x7e || packet->data[0] == 0x5e) { + /* it's an error packet. We should parse it ... */ + DEBUG(1,("Got error packet 0x%x from kpasswd server\n", + packet->data[0])); + return KRB5KRB_AP_ERR_MODIFIED; + } + + if (RSVAL(p, 0) != packet->length) { + DEBUG(1,("Bad packet length (%d/%d) from kpasswd server\n", + RSVAL(p, 0), packet->length)); + return KRB5KRB_AP_ERR_MODIFIED; + } + + p += 2; + + vnum = RSVAL(p, 0); p += 2; + + if (vnum != KRB5_KPASSWD_VERS_SETPW && vnum != KRB5_KPASSWD_VERS_CHANGEPW) { + DEBUG(1,("Bad vnum (%d) from kpasswd server\n", vnum)); + return KRB5KDC_ERR_BAD_PVNO; + } + + ap_rep.length = RSVAL(p, 0); p += 2; + + if (p + ap_rep.length >= packet->data + packet->length) { + DEBUG(1,("ptr beyond end of packet from kpasswd server\n")); + return KRB5KRB_AP_ERR_MODIFIED; + } + + if (ap_rep.length == 0) { + DEBUG(1,("got unencrypted setpw result?!\n")); + return KRB5KRB_AP_ERR_MODIFIED; + } + + /* verify ap_rep */ + ap_rep.data = p; + p += ap_rep.length; + + ret = krb5_rd_rep(context, auth_context, &ap_rep, &ap_rep_enc); + if (ret) { + DEBUG(1,("failed to rd setpw reply (%s)\n", error_message(ret))); + return KRB5KRB_AP_ERR_MODIFIED; + } + + krb5_free_ap_rep_enc_part(context, ap_rep_enc); + + cipherresult.data = p; + cipherresult.length = (packet->data + packet->length) - p; + + ret = krb5_rd_priv(context, auth_context, &cipherresult, &clearresult, + &replay); + if (ret) { + DEBUG(1,("failed to decrypt setpw reply (%s)\n", error_message(ret))); + return KRB5KRB_AP_ERR_MODIFIED; + } + + if (clearresult.length < 2) { + ret = KRB5KRB_AP_ERR_MODIFIED; + return KRB5KRB_AP_ERR_MODIFIED; + } + + p = clearresult.data; + + res_code = RSVAL(p, 0); + + if ((res_code < KRB5_KPASSWD_SUCCESS) || + (res_code > KRB5_KPASSWD_ACCESSDENIED)) { + return KRB5KRB_AP_ERR_MODIFIED; + } + + return 0; +} + +NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, + const char *realm, const char *newpw) +{ + krb5_context context; + krb5_auth_context auth_context = NULL; + krb5_principal principal; + char *princ_name; + krb5_creds creds, *credsp; + krb5_ccache ccache; + krb5_data ap_req, chpw_req, chpw_rep; + int ret, sock, addr_len; + struct sockaddr remote_addr, local_addr; + krb5_address local_kaddr, remote_kaddr; + + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + ret = krb5_cc_default(context, &ccache); + if (ret) { + DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + ZERO_STRUCT(creds); + + asprintf(&princ_name, "kadmin/changepw@%s", realm); + ret = krb5_parse_name(context, princ_name, &creds.server); + if (ret) { + DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + free(princ_name); + + asprintf(&princ_name, "HOST/%s@%s", hostname, realm); + ret = krb5_parse_name(context, princ_name, &principal); + if (ret) { + DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + free(princ_name); + + krb5_princ_set_realm(context, creds.server, + krb5_princ_realm(context, principal)); + + ret = krb5_cc_get_principal(context, ccache, &creds.client); + if (ret) { + DEBUG(1,("Failed to get principal from ccache (%s)\n", + error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); + if (ret) { + DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, + NULL, credsp, &ap_req); + if (ret) { + DEBUG(1,("krb5_mk_req_extended failed (%s)\n", error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT); + if (sock == -1) { + DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", + kdc_host, strerror(errno))); + return NT_STATUS_UNSUCCESSFUL; + } + + addr_len = sizeof(remote_addr); + getpeername(sock, &remote_addr, &addr_len); + addr_len = sizeof(local_addr); + getsockname(sock, &local_addr, &addr_len); + + remote_kaddr.addrtype = ADDRTYPE_INET; + remote_kaddr.length = sizeof(((struct sockaddr_in *)&remote_addr)->sin_addr); + remote_kaddr.contents = (char *)&(((struct sockaddr_in *)&remote_addr)->sin_addr); + local_kaddr.addrtype = ADDRTYPE_INET; + local_kaddr.length = sizeof(((struct sockaddr_in *)&local_addr)->sin_addr); + local_kaddr.contents = (char *)&(((struct sockaddr_in *)&local_addr)->sin_addr); + + ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); + if (ret) { + DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + ret = build_setpw_request(context, auth_context, &ap_req, + hostname, realm, newpw, &chpw_req); + if (ret) { + DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + if (write(sock, chpw_req.data, chpw_req.length) != chpw_req.length) { + DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); + return NT_STATUS_UNSUCCESSFUL; + } + + free(chpw_req.data); + + chpw_rep.length = 1500; + chpw_rep.data = (char *) malloc(chpw_rep.length); + + ret = read(sock, chpw_rep.data, chpw_rep.length); + if (ret < 0) { + DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno))); + return NT_STATUS_UNSUCCESSFUL; + } + + close(sock); + chpw_rep.length = ret; + + ret = krb5_auth_con_setaddrs(context, auth_context, NULL,&remote_kaddr); + if (ret) { + DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n", + error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + ret = parse_setpw_reply(context, auth_context, &chpw_rep); + free(chpw_rep.data); + + if (ret) { + DEBUG(1,("parse_setpw_reply failed (%s)\n", + error_message(ret))); + return NT_STATUS_UNSUCCESSFUL; + } + + return NT_STATUS_OK; +} + +#endif -- cgit From f6b962fba37a1ac105301d699708e541ce34d3b4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 Nov 2001 23:54:07 +0000 Subject: fixed some krb5 ifdefs (This used to be commit 23ef22f11700bbaa5778a9678a990a2b041fcefe) --- source3/libads/krb5_setpw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 5cb3de1bb5..1c3b15d2a5 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -21,7 +21,7 @@ #include "includes.h" -#if HAVE_KRB5 +#ifdef HAVE_KRB5 #define DEFAULT_KPASSWD_PORT 464 #define KRB5_KPASSWD_VERS_CHANGEPW 1 -- cgit From 1f31ace6cb771d7bf0b64091fba1d24c466ad4e5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 19 Dec 2001 12:21:12 +0000 Subject: much better ADS error handling system (This used to be commit 05a90a28843e0d69183a49a76617c5f32817df16) --- source3/libads/krb5_setpw.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 1c3b15d2a5..b46a579263 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -212,8 +212,8 @@ static krb5_error_code parse_setpw_reply(krb5_context context, return 0; } -NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, - const char *realm, const char *newpw) +ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname, + const char *realm, const char *newpw) { krb5_context context; krb5_auth_context auth_context = NULL; @@ -229,13 +229,13 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = krb5_init_context(&context); if (ret) { DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } ret = krb5_cc_default(context, &ccache); if (ret) { DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } ZERO_STRUCT(creds); @@ -244,7 +244,7 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = krb5_parse_name(context, princ_name, &creds.server); if (ret) { DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } free(princ_name); @@ -252,7 +252,7 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = krb5_parse_name(context, princ_name, &principal); if (ret) { DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } free(princ_name); @@ -263,27 +263,28 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, if (ret) { DEBUG(1,("Failed to get principal from ccache (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); if (ret) { DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, NULL, credsp, &ap_req); if (ret) { DEBUG(1,("krb5_mk_req_extended failed (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT); if (sock == -1) { + int rc = errno; DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", kdc_host, strerror(errno))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_SYSTEM(rc); } addr_len = sizeof(remote_addr); @@ -301,19 +302,19 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); if (ret) { DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } ret = build_setpw_request(context, auth_context, &ap_req, hostname, realm, newpw, &chpw_req); if (ret) { DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } if (write(sock, chpw_req.data, chpw_req.length) != chpw_req.length) { DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR(LDAP_ENCODING_ERROR); } free(chpw_req.data); @@ -323,8 +324,7 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = read(sock, chpw_rep.data, chpw_rep.length); if (ret < 0) { - DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_SYSTEM(errno); } close(sock); @@ -334,7 +334,7 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, if (ret) { DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } ret = parse_setpw_reply(context, auth_context, &chpw_rep); @@ -343,10 +343,10 @@ NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname, if (ret) { DEBUG(1,("parse_setpw_reply failed (%s)\n", error_message(ret))); - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_KRB5(ret); } - return NT_STATUS_OK; + return ADS_SUCCESS; } #endif -- cgit From 6c7e9dfb293f1243d9d8d8a2ac50ef12d738198e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 20 Dec 2001 03:54:52 +0000 Subject: net ads password and net ads chostpass commands from Remus Koos (This used to be commit 412e79c448bf02e3097b5c14a36fe0172d8d2895) --- source3/libads/krb5_setpw.c | 145 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 131 insertions(+), 14 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index b46a579263..e15c22091d 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -3,6 +3,7 @@ Version 3.0 krb5 set password implementation Copyright (C) Andrew Tridgell 2001 + Copyright (C) Remus Koos 2001 (remuskoos@yahoo.com) 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 @@ -32,12 +33,36 @@ /* This implements the Kerb password change protocol as specifed in * kerb-chg-password-02.txt */ -static DATA_BLOB encode_krb5_setpw(const char *hostname, - const char *realm, const char *password) +static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) { + char* princ_part1 = NULL; + char* princ_part2 = NULL; + char* realm = NULL; + char* c; + char* princ; + ASN1_DATA req; DATA_BLOB ret; + + princ = strdup(principal); + + if ((c = strchr(princ, '/')) == NULL) { + c = princ; + } else { + *c = '\0'; + c++; + princ_part1 = princ; + } + + princ_part2 = c; + + if ((c = strchr(c, '@')) != NULL) { + *c = '\0'; + c++; + realm = c; + } + memset(&req, 0, sizeof(req)); asn1_push_tag(&req, ASN1_SEQUENCE(0)); @@ -54,8 +79,11 @@ static DATA_BLOB encode_krb5_setpw(const char *hostname, asn1_push_tag(&req, ASN1_CONTEXT(1)); asn1_push_tag(&req, ASN1_SEQUENCE(0)); - asn1_write_GeneralString(&req, "HOST"); - asn1_write_GeneralString(&req, hostname); + + if (princ_part1) + asn1_write_GeneralString(&req, princ_part1); + + asn1_write_GeneralString(&req, princ_part2); asn1_pop_tag(&req); asn1_pop_tag(&req); asn1_pop_tag(&req); @@ -69,14 +97,15 @@ static DATA_BLOB encode_krb5_setpw(const char *hostname, ret = data_blob(req.data, req.length); asn1_free(&req); + free(princ); + return ret; } static krb5_error_code build_setpw_request(krb5_context context, krb5_auth_context auth_context, krb5_data *ap_req, - const char *hostname, - const char *realm, + const char *princ, const char *passwd, krb5_data *packet) { @@ -95,13 +124,16 @@ static krb5_error_code build_setpw_request(krb5_context context, return ret; } - setpw = encode_krb5_setpw(hostname, realm, passwd); + setpw = encode_krb5_setpw(princ, passwd); encoded_setpw.data = setpw.data; encoded_setpw.length = setpw.length; ret = krb5_mk_priv(context, auth_context, &encoded_setpw, &cipherpw, &replay); + + data_blob_free(&setpw); /*from 'encode_krb5_setpw(...)' */ + if (ret) { DEBUG(1,("krb5_mk_priv failed (%s)\n", error_message(ret))); return ret; @@ -118,6 +150,8 @@ static krb5_error_code build_setpw_request(krb5_context context, packet->length = PTR_DIFF(p,packet->data); RSSVAL(packet->data, 0, packet->length); + free(cipherpw.data); /* from 'krb5_mk_priv(...)' */ + return 0; } @@ -196,6 +230,7 @@ static krb5_error_code parse_setpw_reply(krb5_context context, } if (clearresult.length < 2) { + free(clearresult.data); ret = KRB5KRB_AP_ERR_MODIFIED; return KRB5KRB_AP_ERR_MODIFIED; } @@ -204,21 +239,23 @@ static krb5_error_code parse_setpw_reply(krb5_context context, res_code = RSVAL(p, 0); + free(clearresult.data); + if ((res_code < KRB5_KPASSWD_SUCCESS) || - (res_code > KRB5_KPASSWD_ACCESSDENIED)) { + (res_code >= KRB5_KPASSWD_ACCESSDENIED)) { return KRB5KRB_AP_ERR_MODIFIED; } return 0; } -ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname, - const char *realm, const char *newpw) +ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw) { krb5_context context; krb5_auth_context auth_context = NULL; krb5_principal principal; char *princ_name; + char *realm; krb5_creds creds, *credsp; krb5_ccache ccache; krb5_data ap_req, chpw_req, chpw_rep; @@ -234,33 +271,40 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = krb5_cc_default(context, &ccache); if (ret) { + krb5_free_context(context); DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } ZERO_STRUCT(creds); + realm = strchr(princ, '@'); + realm++; + asprintf(&princ_name, "kadmin/changepw@%s", realm); ret = krb5_parse_name(context, princ_name, &creds.server); if (ret) { + krb5_free_context(context); DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } free(princ_name); - asprintf(&princ_name, "HOST/%s@%s", hostname, realm); - ret = krb5_parse_name(context, princ_name, &principal); + /* parse the principal we got as a function argument */ + ret = krb5_parse_name(context, princ, &principal); if (ret) { + krb5_free_context(context); DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret))); return ADS_ERROR_KRB5(ret); } - free(princ_name); krb5_princ_set_realm(context, creds.server, krb5_princ_realm(context, principal)); ret = krb5_cc_get_principal(context, ccache, &creds.client); if (ret) { + krb5_free_principal(context, principal); + krb5_free_context(context); DEBUG(1,("Failed to get principal from ccache (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); @@ -268,13 +312,21 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); if (ret) { + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } + //we might have to call krb5_free_creds(...) from now on ... ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, NULL, credsp, &ap_req); if (ret) { + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); DEBUG(1,("krb5_mk_req_extended failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } @@ -282,6 +334,11 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname, sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT); if (sock == -1) { int rc = errno; + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", kdc_host, strerror(errno))); return ADS_ERROR_SYSTEM(rc); @@ -301,18 +358,37 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); if (ret) { + close(sock); + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } ret = build_setpw_request(context, auth_context, &ap_req, - hostname, realm, newpw, &chpw_req); + princ, newpw, &chpw_req); if (ret) { + close(sock); + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } if (write(sock, chpw_req.data, chpw_req.length) != chpw_req.length) { + close(sock); + free(chpw_req.data); + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); return ADS_ERROR(LDAP_ENCODING_ERROR); } @@ -324,6 +400,14 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = read(sock, chpw_rep.data, chpw_rep.length); if (ret < 0) { + close(sock); + free(chpw_rep.data); + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); + DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno))); return ADS_ERROR_SYSTEM(errno); } @@ -332,6 +416,12 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname, ret = krb5_auth_con_setaddrs(context, auth_context, NULL,&remote_kaddr); if (ret) { + free(chpw_rep.data); + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); @@ -341,12 +431,39 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *hostname, free(chpw_rep.data); if (ret) { + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); DEBUG(1,("parse_setpw_reply failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); + return ADS_SUCCESS; } + +ADS_STATUS kerberos_set_password(const char *kpasswd_server, + const char *auth_principal, const char *auth_password, + const char *target_principal, const char *new_password) +{ + int ret; + + if ((ret = kerberos_kinit_password(auth_principal, auth_password))) { + DEBUG(1,("Failed kinit for principal %s (%s)\n", auth_principal, error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + return krb5_set_password(kpasswd_server, target_principal, new_password); +} + + #endif -- cgit From 8536aa5ef3147b5ebf29ff114797a039d02213bf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 31 Dec 2001 11:14:38 +0000 Subject: Allow this to build without LDAP, as per the example below it. Andrew Bartlett (This used to be commit f60e4450018fc06c9f8ce18e62c29fd968d55daa) --- source3/libads/krb5_setpw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index e15c22091d..3973b424f6 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -390,7 +390,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char krb5_free_principal(context, principal); krb5_free_context(context); DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); - return ADS_ERROR(LDAP_ENCODING_ERROR); + return ADS_ERROR_SYSTEM(errno); } free(chpw_req.data); -- cgit From b5666e2874a80ce5739e837e4ddc54dc68df7631 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 1 Jan 2002 02:31:32 +0000 Subject: Fix up C99 comment. // -> /* */ (This used to be commit a308abbab717df56b982adf1717da96603d2045f) --- source3/libads/krb5_setpw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 3973b424f6..78d5997c01 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -319,7 +319,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char return ADS_ERROR_KRB5(ret); } - //we might have to call krb5_free_creds(...) from now on ... + /* we might have to call krb5_free_creds(...) from now on ... */ ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, NULL, credsp, &ap_req); if (ret) { -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/libads/krb5_setpw.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 78d5997c01..ec79a8658f 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. krb5 set password implementation Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 (remuskoos@yahoo.com) -- cgit From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/libads/krb5_setpw.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index ec79a8658f..a49b6cbe3b 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -248,7 +248,8 @@ static krb5_error_code parse_setpw_reply(krb5_context context, return 0; } -ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw) +ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw, + int time_offset) { krb5_context context; krb5_auth_context auth_context = NULL; @@ -268,6 +269,10 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char return ADS_ERROR_KRB5(ret); } + if (time_offset != 0) { + krb5_set_real_time(context, time(NULL) + time_offset, 0); + } + ret = krb5_cc_default(context, &ccache); if (ret) { krb5_free_context(context); @@ -452,16 +457,17 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char ADS_STATUS kerberos_set_password(const char *kpasswd_server, const char *auth_principal, const char *auth_password, - const char *target_principal, const char *new_password) + const char *target_principal, const char *new_password, + int time_offset) { int ret; - if ((ret = kerberos_kinit_password(auth_principal, auth_password))) { + if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset))) { DEBUG(1,("Failed kinit for principal %s (%s)\n", auth_principal, error_message(ret))); return ADS_ERROR_KRB5(ret); } - return krb5_set_password(kpasswd_server, target_principal, new_password); + return krb5_set_password(kpasswd_server, target_principal, new_password, time_offset); } -- cgit From f2d1f19a66ebaf9b88d23c0faa2412536cc74cda Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 1 Oct 2002 18:26:00 +0000 Subject: syncing up with HEAD. Seems to be a lot of differences creeping in (i ignored the new SAMBA stuff, but the rest of this looks like it should have been merged already). (This used to be commit 3de09e5cf1f667e410ee8b9516a956860ce7290f) --- source3/libads/krb5_setpw.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index a49b6cbe3b..8079c0953f 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -471,4 +471,35 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, } +/** + * Set the machine account password + * @param ads connection to ads server + * @param hostname machine whose password is being set + * @param password new password + * @return status of password change + **/ +ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, + const char *hostname, + const char *password) +{ + ADS_STATUS status; + char *host = strdup(hostname); + char *principal; + + strlower(host); + + /* + we need to use the '$' form of the name here, as otherwise the + server might end up setting the password for a user instead + */ + asprintf(&principal, "%s$@%s", host, ads->auth.realm); + + status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset); + + free(host); + free(principal); + + return status; +} + #endif -- cgit From b0aadff2020886cbc2a35bf115e6c359ff28d870 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Jan 2003 06:23:49 +0000 Subject: More fixes getting us closer to full Heimdal compile.... Jeremy. (This used to be commit a7ee6ed64500a0d949849da6996b7dc837518f00) --- source3/libads/krb5_setpw.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 8079c0953f..73d370d75f 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -141,7 +141,7 @@ static krb5_error_code build_setpw_request(krb5_context context, packet->data = (char *)malloc(ap_req->length + cipherpw.length + 6); /* see the RFC for details */ - p = packet->data + 2; + p = ((char *)packet->data) + 2; RSSVAL(p, 0, 0xff80); p += 2; RSSVAL(p, 0, ap_req->length); p += 2; memcpy(p, ap_req->data, ap_req->length); p += ap_req->length; @@ -172,10 +172,10 @@ static krb5_error_code parse_setpw_reply(krb5_context context, p = packet->data; - if (packet->data[0] == 0x7e || packet->data[0] == 0x5e) { + if (((char *)packet->data)[0] == 0x7e || ((char *)packet->data)[0] == 0x5e) { /* it's an error packet. We should parse it ... */ DEBUG(1,("Got error packet 0x%x from kpasswd server\n", - packet->data[0])); + ((char *)packet->data)[0])); return KRB5KRB_AP_ERR_MODIFIED; } @@ -196,7 +196,7 @@ static krb5_error_code parse_setpw_reply(krb5_context context, ap_rep.length = RSVAL(p, 0); p += 2; - if (p + ap_rep.length >= packet->data + packet->length) { + if (p + ap_rep.length >= (char *)packet->data + packet->length) { DEBUG(1,("ptr beyond end of packet from kpasswd server\n")); return KRB5KRB_AP_ERR_MODIFIED; } @@ -219,7 +219,7 @@ static krb5_error_code parse_setpw_reply(krb5_context context, krb5_free_ap_rep_enc_part(context, ap_rep_enc); cipherresult.data = p; - cipherresult.length = (packet->data + packet->length) - p; + cipherresult.length = ((char *)packet->data + packet->length) - p; ret = krb5_rd_priv(context, auth_context, &cipherresult, &clearresult, &replay); @@ -353,12 +353,8 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char addr_len = sizeof(local_addr); getsockname(sock, &local_addr, &addr_len); - remote_kaddr.addrtype = ADDRTYPE_INET; - remote_kaddr.length = sizeof(((struct sockaddr_in *)&remote_addr)->sin_addr); - remote_kaddr.contents = (char *)&(((struct sockaddr_in *)&remote_addr)->sin_addr); - local_kaddr.addrtype = ADDRTYPE_INET; - local_kaddr.length = sizeof(((struct sockaddr_in *)&local_addr)->sin_addr); - local_kaddr.contents = (char *)&(((struct sockaddr_in *)&local_addr)->sin_addr); + setup_kaddr(&remote_kaddr, &remote_addr); + setup_kaddr(&local_kaddr, &local_addr); ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); if (ret) { -- cgit From eccae5d23a5a4e2ee63891196d27cc4938019893 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 4 Feb 2003 23:44:28 +0000 Subject: Mem alloc checks. Jeremy. (This used to be commit 46ea028169426fbcad92d3d5bf786e88be8f5112) --- source3/libads/krb5_setpw.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 73d370d75f..087b0e9a71 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -139,13 +139,19 @@ static krb5_error_code build_setpw_request(krb5_context context, } packet->data = (char *)malloc(ap_req->length + cipherpw.length + 6); + if (!packet->data) + return -1; /* see the RFC for details */ p = ((char *)packet->data) + 2; - RSSVAL(p, 0, 0xff80); p += 2; - RSSVAL(p, 0, ap_req->length); p += 2; - memcpy(p, ap_req->data, ap_req->length); p += ap_req->length; - memcpy(p, cipherpw.data, cipherpw.length); p += cipherpw.length; + RSSVAL(p, 0, 0xff80); + p += 2; + RSSVAL(p, 0, ap_req->length); + p += 2; + memcpy(p, ap_req->data, ap_req->length); + p += ap_req->length; + memcpy(p, cipherpw.data, cipherpw.length); + p += cipherpw.length; packet->length = PTR_DIFF(p,packet->data); RSSVAL(packet->data, 0, packet->length); @@ -397,6 +403,17 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char chpw_rep.length = 1500; chpw_rep.data = (char *) malloc(chpw_rep.length); + if (!chpw_rep.data) { + close(sock); + free(ap_req.data); + krb5_free_creds(context, credsp); + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); + DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); + errno = ENOMEM; + return ADS_ERROR_SYSTEM(errno); + } ret = read(sock, chpw_rep.data, chpw_rep.length); if (ret < 0) { -- cgit From d1221c9b6c369113a531063737890b58d89bf6fe Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 02:55:00 +0000 Subject: Merge from HEAD client-side authentication changes: - new kerberos code, allowing the account to change it's own password without special SD settings required - NTLMSSP client code, now seperated from cliconnect.c - NTLMv2 client code - SMB signing fixes Andrew Bartlett (This used to be commit 837680ca517982f2e5944730581a83012d4181ae) --- source3/libads/krb5_setpw.c | 429 +++++++++++++++++++++++++++++++------------- 1 file changed, 306 insertions(+), 123 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 087b0e9a71..9d8fb8d24c 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -24,13 +24,23 @@ #ifdef HAVE_KRB5 #define DEFAULT_KPASSWD_PORT 464 -#define KRB5_KPASSWD_VERS_CHANGEPW 1 -#define KRB5_KPASSWD_VERS_SETPW 0xff80 -#define KRB5_KPASSWD_ACCESSDENIED 5 -#define KRB5_KPASSWD_BAD_VERSION 6 - -/* This implements the Kerb password change protocol as specifed in - * kerb-chg-password-02.txt +#define KRB5_KPASSWD_VERS_CHANGEPW 1 +#define KRB5_KPASSWD_VERS_SETPW 2 +#define KRB5_KPASSWD_VERS_SETPW_MS 0xff80 +#define KRB5_KPASSWD_ACCESSDENIED 5 +#define KRB5_KPASSWD_BAD_VERSION 6 +#define KRB5_KPASSWD_INITIAL_FLAG_NEEDED 7 + +/* Those are defined by kerberos-set-passwd-02.txt and are probably + * not supported by M$ implementation */ +#define KRB5_KPASSWD_POLICY_REJECT 8 +#define KRB5_KPASSWD_BAD_PRINCIPAL 9 +#define KRB5_KPASSWD_ETYPE_NOSUPP 10 + +/* This implements kerberos password change protocol as specified in + * kerb-chg-password-02.txt and kerberos-set-passwd-02.txt + * as well as microsoft version of the protocol + * as specified in kerberos-set-passwd-00.txt */ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) { @@ -101,7 +111,8 @@ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) return ret; } -static krb5_error_code build_setpw_request(krb5_context context, +static krb5_error_code build_kpasswd_request(uint16 pversion, + krb5_context context, krb5_auth_context auth_context, krb5_data *ap_req, const char *princ, @@ -123,7 +134,14 @@ static krb5_error_code build_setpw_request(krb5_context context, return ret; } - setpw = encode_krb5_setpw(princ, passwd); + /* handle protocol differences in chpw and setpw */ + if (pversion == KRB5_KPASSWD_VERS_CHANGEPW) + setpw = data_blob(passwd, strlen(passwd)); + else if (pversion == KRB5_KPASSWD_VERS_SETPW || + pversion == KRB5_KPASSWD_VERS_SETPW_MS) + setpw = encode_krb5_setpw(princ, passwd); + else + return EINVAL; encoded_setpw.data = setpw.data; encoded_setpw.length = setpw.length; @@ -144,7 +162,7 @@ static krb5_error_code build_setpw_request(krb5_context context, /* see the RFC for details */ p = ((char *)packet->data) + 2; - RSSVAL(p, 0, 0xff80); + RSSVAL(p, 0, pversion); p += 2; RSSVAL(p, 0, ap_req->length); p += 2; @@ -160,6 +178,49 @@ static krb5_error_code build_setpw_request(krb5_context context, return 0; } +static krb5_error_code krb5_setpw_result_code_string(krb5_context context, + int result_code, + char **code_string) +{ + switch (result_code) { + case KRB5_KPASSWD_MALFORMED: + *code_string = "Malformed request error"; + break; + case KRB5_KPASSWD_HARDERROR: + *code_string = "Server error"; + break; + case KRB5_KPASSWD_AUTHERROR: + *code_string = "Authentication error"; + break; + case KRB5_KPASSWD_SOFTERROR: + *code_string = "Password change rejected"; + break; + case KRB5_KPASSWD_ACCESSDENIED: + *code_string = "Client does not have proper authorization"; + break; + case KRB5_KPASSWD_BAD_VERSION: + *code_string = "Protocol version not supported"; + break; + case KRB5_KPASSWD_INITIAL_FLAG_NEEDED: + *code_string = "Authorization ticket must have initial flag set"; + break; + case KRB5_KPASSWD_POLICY_REJECT: + *code_string = "Password rejected due to policy requirements"; + break; + case KRB5_KPASSWD_BAD_PRINCIPAL: + *code_string = "Target principal does not exist"; + break; + case KRB5_KPASSWD_ETYPE_NOSUPP: + *code_string = "Unsupported encryption type"; + break; + default: + *code_string = "Password change failed"; + break; + } + + return(0); +} + static krb5_error_code parse_setpw_reply(krb5_context context, krb5_auth_context auth_context, krb5_data *packet) @@ -194,8 +255,11 @@ static krb5_error_code parse_setpw_reply(krb5_context context, p += 2; vnum = RSVAL(p, 0); p += 2; - - if (vnum != KRB5_KPASSWD_VERS_SETPW && vnum != KRB5_KPASSWD_VERS_CHANGEPW) { + + /* FIXME: According to standard there is only one type of reply */ + if (vnum != KRB5_KPASSWD_VERS_SETPW && + vnum != KRB5_KPASSWD_VERS_SETPW_MS && + vnum != KRB5_KPASSWD_VERS_CHANGEPW) { DEBUG(1,("Bad vnum (%d) from kpasswd server\n", vnum)); return KRB5KDC_ERR_BAD_PVNO; } @@ -247,96 +311,57 @@ static krb5_error_code parse_setpw_reply(krb5_context context, free(clearresult.data); if ((res_code < KRB5_KPASSWD_SUCCESS) || - (res_code >= KRB5_KPASSWD_ACCESSDENIED)) { + (res_code > KRB5_KPASSWD_ETYPE_NOSUPP)) { return KRB5KRB_AP_ERR_MODIFIED; } - - return 0; + + if(res_code == KRB5_KPASSWD_SUCCESS) + return 0; + else { + char *errstr; + krb5_setpw_result_code_string(context, res_code, &errstr); + DEBUG(1, ("Error changing password: %s\n", errstr)); + + switch(res_code) { + case KRB5_KPASSWD_ACCESSDENIED: + return KRB5KDC_ERR_BADOPTION; + break; + case KRB5_KPASSWD_INITIAL_FLAG_NEEDED: + return KRB5KDC_ERR_BADOPTION; + /* return KV5M_ALT_METHOD; MIT-only define */ + break; + case KRB5_KPASSWD_ETYPE_NOSUPP: + return KRB5KDC_ERR_ETYPE_NOSUPP; + break; + case KRB5_KPASSWD_BAD_PRINCIPAL: + return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; + break; + case KRB5_KPASSWD_POLICY_REJECT: + return KRB5KDC_ERR_POLICY; + break; + default: + return KRB5KRB_ERR_GENERIC; + break; + } + } } -ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw, - int time_offset) +static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, + const char *kdc_host, + uint16 pversion, + krb5_creds *credsp, + const char *princ, + const char *newpw) { - krb5_context context; krb5_auth_context auth_context = NULL; - krb5_principal principal; - char *princ_name; - char *realm; - krb5_creds creds, *credsp; - krb5_ccache ccache; krb5_data ap_req, chpw_req, chpw_rep; int ret, sock, addr_len; struct sockaddr remote_addr, local_addr; krb5_address local_kaddr, remote_kaddr; - ret = krb5_init_context(&context); - if (ret) { - DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - if (time_offset != 0) { - krb5_set_real_time(context, time(NULL) + time_offset, 0); - } - - ret = krb5_cc_default(context, &ccache); - if (ret) { - krb5_free_context(context); - DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - ZERO_STRUCT(creds); - - realm = strchr(princ, '@'); - realm++; - - asprintf(&princ_name, "kadmin/changepw@%s", realm); - ret = krb5_parse_name(context, princ_name, &creds.server); - if (ret) { - krb5_free_context(context); - DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - free(princ_name); - - /* parse the principal we got as a function argument */ - ret = krb5_parse_name(context, princ, &principal); - if (ret) { - krb5_free_context(context); - DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - krb5_princ_set_realm(context, creds.server, - krb5_princ_realm(context, principal)); - - ret = krb5_cc_get_principal(context, ccache, &creds.client); - if (ret) { - krb5_free_principal(context, principal); - krb5_free_context(context); - DEBUG(1,("Failed to get principal from ccache (%s)\n", - error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); - if (ret) { - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); - DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - /* we might have to call krb5_free_creds(...) from now on ... */ ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, NULL, credsp, &ap_req); if (ret) { - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); DEBUG(1,("krb5_mk_req_extended failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } @@ -345,10 +370,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (sock == -1) { int rc = errno; free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", kdc_host, strerror(errno))); return ADS_ERROR_SYSTEM(rc); @@ -366,23 +388,17 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (ret) { close(sock); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } - ret = build_setpw_request(context, auth_context, &ap_req, + ret = build_kpasswd_request(pversion, context, auth_context, &ap_req, princ, newpw, &chpw_req); if (ret) { close(sock); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } @@ -391,10 +407,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char close(sock); free(chpw_req.data); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); return ADS_ERROR_SYSTEM(errno); } @@ -406,10 +419,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (!chpw_rep.data) { close(sock); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); errno = ENOMEM; return ADS_ERROR_SYSTEM(errno); @@ -420,10 +430,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char close(sock); free(chpw_rep.data); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno))); return ADS_ERROR_SYSTEM(errno); } @@ -435,10 +442,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (ret) { free(chpw_rep.data); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); @@ -449,22 +453,194 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (ret) { free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("parse_setpw_reply failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } free(ap_req.data); + krb5_auth_con_free(context, auth_context); + + return ADS_SUCCESS; +} + +ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw, + int time_offset) +{ + + ADS_STATUS aret; + krb5_error_code ret; + krb5_context context; + krb5_principal principal; + char *princ_name; + char *realm; + krb5_creds creds, *credsp; + krb5_ccache ccache; + + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + if (time_offset != 0) { + krb5_set_real_time(context, time(NULL) + time_offset, 0); + } + + ret = krb5_cc_default(context, &ccache); + if (ret) { + krb5_free_context(context); + DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + ZERO_STRUCT(creds); + + realm = strchr(princ, '@'); + realm++; + + asprintf(&princ_name, "kadmin/changepw@%s", realm); + ret = krb5_parse_name(context, princ_name, &creds.server); + if (ret) { + krb5_free_context(context); + DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + free(princ_name); + + /* parse the principal we got as a function argument */ + ret = krb5_parse_name(context, princ, &principal); + if (ret) { + krb5_free_context(context); + DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + krb5_princ_set_realm(context, creds.server, + krb5_princ_realm(context, principal)); + + ret = krb5_cc_get_principal(context, ccache, &creds.client); + if (ret) { + krb5_free_principal(context, principal); + krb5_free_context(context); + DEBUG(1,("Failed to get principal from ccache (%s)\n", + error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); + if (ret) { + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); + DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + /* we might have to call krb5_free_creds(...) from now on ... */ + + aret = do_krb5_kpasswd_request(context, kdc_host, + KRB5_KPASSWD_VERS_SETPW_MS, + credsp, princ, newpw); + krb5_free_creds(context, credsp); krb5_free_principal(context, creds.client); + krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); krb5_free_context(context); - return ADS_SUCCESS; + return aret; +} + +/* + we use a prompter to avoid a crash bug in the kerberos libs when + dealing with empty passwords + this prompter is just a string copy ... +*/ +static krb5_error_code +kerb_prompter(krb5_context ctx, void *data, + const char *name, + const char *banner, + int num_prompts, + krb5_prompt prompts[]) +{ + if (num_prompts == 0) return 0; + + memset(prompts[0].reply->data, 0, prompts[0].reply->length); + if (prompts[0].reply->length > 0) { + if (data) { + strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); + prompts[0].reply->length = strlen(prompts[0].reply->data); + } else { + prompts[0].reply->length = 0; + } + } + return 0; +} + +ADS_STATUS krb5_chg_password(const char *kdc_host, + const char *principal, + const char *oldpw, + const char *newpw, + int time_offset) +{ + ADS_STATUS aret; + krb5_error_code ret; + krb5_context context; + krb5_principal princ; + krb5_get_init_creds_opt opts; + krb5_creds creds; + char *chpw_princ = NULL, *password; + + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + if ((ret = krb5_parse_name(context, principal, + &princ))) { + krb5_free_context(context); + DEBUG(1,("Failed to parse %s (%s)\n", principal, error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + krb5_get_init_creds_opt_init(&opts); + krb5_get_init_creds_opt_set_tkt_life(&opts, 5*60); + krb5_get_init_creds_opt_set_renew_life(&opts, 0); + krb5_get_init_creds_opt_set_forwardable(&opts, 0); + krb5_get_init_creds_opt_set_proxiable(&opts, 0); + + /* We have to obtain an INITIAL changepw ticket for changing password */ + asprintf(&chpw_princ, "kadmin/changepw@%s", + (char *) krb5_princ_realm(context, princ)); + password = strdup(oldpw); + ret = krb5_get_init_creds_password(context, &creds, princ, password, + kerb_prompter, NULL, + 0, chpw_princ, &opts); + SAFE_FREE(chpw_princ); + SAFE_FREE(password); + + if (ret) { + if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) + DEBUG(1,("Password incorrect while getting initial ticket")); + else + DEBUG(1,("krb5_get_init_creds_password failed (%s)\n", error_message(ret))); + + krb5_free_principal(context, princ); + krb5_free_context(context); + return ADS_ERROR_KRB5(ret); + } + + aret = do_krb5_kpasswd_request(context, kdc_host, + KRB5_KPASSWD_VERS_CHANGEPW, + &creds, principal, newpw); + + krb5_free_principal(context, princ); + krb5_free_context(context); + + return aret; } @@ -480,7 +656,12 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, return ADS_ERROR_KRB5(ret); } - return krb5_set_password(kpasswd_server, target_principal, new_password, time_offset); + if (!strcmp(auth_principal, target_principal)) + return krb5_chg_password(kpasswd_server, target_principal, + auth_password, new_password, time_offset); + else + return krb5_set_password(kpasswd_server, target_principal, + new_password, time_offset); } @@ -515,4 +696,6 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, return status; } + + #endif -- cgit From 211dd28a7aef367b7d3c99c249a8c036370328f7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Mar 2003 01:34:34 +0000 Subject: More const fixes. Jeremy. (This used to be commit fa93763248f2043395e4cfc70b8afd81e28b2b75) --- source3/libads/krb5_setpw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 9d8fb8d24c..ac7377cd2f 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -180,7 +180,7 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, static krb5_error_code krb5_setpw_result_code_string(krb5_context context, int result_code, - char **code_string) + const char **code_string) { switch (result_code) { case KRB5_KPASSWD_MALFORMED: @@ -318,7 +318,7 @@ static krb5_error_code parse_setpw_reply(krb5_context context, if(res_code == KRB5_KPASSWD_SUCCESS) return 0; else { - char *errstr; + const char *errstr; krb5_setpw_result_code_string(context, res_code, &errstr); DEBUG(1, ("Error changing password: %s\n", errstr)); -- cgit From 83a580f49a3a7f5aff0aab3946faee0892239251 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 17 Mar 2003 22:58:24 +0000 Subject: Merge from HEAD: net ads password Heimdal compile fixes. Andrew Bartlett (This used to be commit 3aa4f923e99f453310bb4a8d43ce43757591909d) --- source3/libads/krb5_setpw.c | 66 ++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 37 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index ac7377cd2f..a5b9eee4ce 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -178,47 +178,39 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, return 0; } +static const struct kpasswd_errors { + int result_code; + const char *error_string; +} kpasswd_errors[] = { + {KRB5_KPASSWD_MALFORMED, "Malformed request error"}, + {KRB5_KPASSWD_HARDERROR, "Server error"}, + {KRB5_KPASSWD_AUTHERROR, "Authentication error"}, + {KRB5_KPASSWD_SOFTERROR, "Password change rejected"}, + {KRB5_KPASSWD_ACCESSDENIED, "Client does not have proper authorization"}, + {KRB5_KPASSWD_BAD_VERSION, "Protocol version not supported"}, + {KRB5_KPASSWD_INITIAL_FLAG_NEEDED, "Authorization ticket must have initial flag set"}, + {KRB5_KPASSWD_POLICY_REJECT, "Password rejected due to policy requirements"}, + {KRB5_KPASSWD_BAD_PRINCIPAL, "Target principal does not exist"}, + {KRB5_KPASSWD_ETYPE_NOSUPP, "Unsupported encryption type"}, + {0, NULL} +}; + static krb5_error_code krb5_setpw_result_code_string(krb5_context context, int result_code, const char **code_string) { - switch (result_code) { - case KRB5_KPASSWD_MALFORMED: - *code_string = "Malformed request error"; - break; - case KRB5_KPASSWD_HARDERROR: - *code_string = "Server error"; - break; - case KRB5_KPASSWD_AUTHERROR: - *code_string = "Authentication error"; - break; - case KRB5_KPASSWD_SOFTERROR: - *code_string = "Password change rejected"; - break; - case KRB5_KPASSWD_ACCESSDENIED: - *code_string = "Client does not have proper authorization"; - break; - case KRB5_KPASSWD_BAD_VERSION: - *code_string = "Protocol version not supported"; - break; - case KRB5_KPASSWD_INITIAL_FLAG_NEEDED: - *code_string = "Authorization ticket must have initial flag set"; - break; - case KRB5_KPASSWD_POLICY_REJECT: - *code_string = "Password rejected due to policy requirements"; - break; - case KRB5_KPASSWD_BAD_PRINCIPAL: - *code_string = "Target principal does not exist"; - break; - case KRB5_KPASSWD_ETYPE_NOSUPP: - *code_string = "Unsupported encryption type"; - break; - default: - *code_string = "Password change failed"; - break; - } - - return(0); + unsigned int idx = 0; + + while (kpasswd_errors[idx].error_string != NULL) { + if (kpasswd_errors[idx].result_code == + result_code) { + *code_string = kpasswd_errors[idx].error_string; + return 0; + } + idx++; + } + *code_string = "Password change failed"; + return (0); } static krb5_error_code parse_setpw_reply(krb5_context context, -- cgit From 06c99d15e217e265d51778268d5b859dff3c478c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 21 Apr 2003 13:10:35 +0000 Subject: Add const, static and fix a double free() (merge from HEAD). (This used to be commit 9ba88c7314168b87b72a7e9dc3c7588dcce86893) --- source3/libads/krb5_setpw.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index a5b9eee4ce..214871b3fb 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -538,7 +538,6 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char krb5_free_creds(context, credsp); krb5_free_principal(context, creds.client); - krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); krb5_free_context(context); @@ -571,11 +570,11 @@ kerb_prompter(krb5_context ctx, void *data, return 0; } -ADS_STATUS krb5_chg_password(const char *kdc_host, - const char *principal, - const char *oldpw, - const char *newpw, - int time_offset) +static ADS_STATUS krb5_chg_password(const char *kdc_host, + const char *principal, + const char *oldpw, + const char *newpw, + int time_offset) { ADS_STATUS aret; krb5_error_code ret; -- cgit From 6a19f354e5ff4e0de91783b23a8161769220e844 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 4 May 2003 02:48:11 +0000 Subject: Patch from Ken Cross to allow an ADS domain join with a username of the form user@realm, where realm might not be the realm we are joining. Andrew Bartlett (This used to be commit 00e08efb5cd21bf42be9125d3188efbf9d13b8b7) --- source3/libads/krb5_setpw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 214871b3fb..856809decc 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -677,7 +677,7 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, we need to use the '$' form of the name here, as otherwise the server might end up setting the password for a user instead */ - asprintf(&principal, "%s$@%s", host, ads->auth.realm); + asprintf(&principal, "%s$@%s", host, ads->config.realm); status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset); -- cgit From 0463fc2d77293f496a4bff8525b8671f7d5b060a Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 30 May 2003 19:51:09 +0000 Subject: Fix bug #137: krb5_set_password is already defined in MIT 1.3 libs, so we wouldn't build. (This used to be commit 0e9836c4e9e71494b10d71a5f3d5f7da2888c5ef) --- source3/libads/krb5_setpw.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 856809decc..ece305f7e8 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -457,8 +457,8 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, return ADS_SUCCESS; } -ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw, - int time_offset) +ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, + const char *newpw, int time_offset) { ADS_STATUS aret; @@ -651,8 +651,8 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, return krb5_chg_password(kpasswd_server, target_principal, auth_password, new_password, time_offset); else - return krb5_set_password(kpasswd_server, target_principal, - new_password, time_offset); + return ads_krb5_set_password(kpasswd_server, target_principal, + new_password, time_offset); } @@ -679,7 +679,8 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, */ asprintf(&principal, "%s$@%s", host, ads->config.realm); - status = krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset); + status = ads_krb5_set_password(ads->auth.kdc_server, principal, + password, ads->auth.time_offset); free(host); free(principal); -- cgit From 1f3b2790766361c8405632a5dfbfa2934ac33436 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 30 May 2003 20:03:18 +0000 Subject: More on bug 137: rename remainder of krb5_xxx functions to not start with krb5_ (This used to be commit 4169de6d8fb1b13de3892ec787886cc1543736a1) --- source3/libads/krb5_setpw.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index ece305f7e8..df749d04d3 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -195,9 +195,9 @@ static const struct kpasswd_errors { {0, NULL} }; -static krb5_error_code krb5_setpw_result_code_string(krb5_context context, - int result_code, - const char **code_string) +static krb5_error_code setpw_result_code_string(krb5_context context, + int result_code, + const char **code_string) { unsigned int idx = 0; @@ -311,7 +311,7 @@ static krb5_error_code parse_setpw_reply(krb5_context context, return 0; else { const char *errstr; - krb5_setpw_result_code_string(context, res_code, &errstr); + setpw_result_code_string(context, res_code, &errstr); DEBUG(1, ("Error changing password: %s\n", errstr)); switch(res_code) { @@ -570,11 +570,11 @@ kerb_prompter(krb5_context ctx, void *data, return 0; } -static ADS_STATUS krb5_chg_password(const char *kdc_host, - const char *principal, - const char *oldpw, - const char *newpw, - int time_offset) +static ADS_STATUS ads_krb5_chg_password(const char *kdc_host, + const char *principal, + const char *oldpw, + const char *newpw, + int time_offset) { ADS_STATUS aret; krb5_error_code ret; @@ -648,8 +648,8 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, } if (!strcmp(auth_principal, target_principal)) - return krb5_chg_password(kpasswd_server, target_principal, - auth_password, new_password, time_offset); + return ads_krb5_chg_password(kpasswd_server, target_principal, + auth_password, new_password, time_offset); else return ads_krb5_set_password(kpasswd_server, target_principal, new_password, time_offset); -- cgit From ce72beb2b558d86fb49063c6b1fa00e07952ce56 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Jul 2003 19:11:31 +0000 Subject: Removed strupper/strlower macros that automatically map to strupper_m/strlower_m. I really want people to think about when they're using multibyte strings. Jeremy. (This used to be commit ff222716a08af65d26ad842ce4c2841cc6540959) --- source3/libads/krb5_setpw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index df749d04d3..80ef6cdf01 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -671,7 +671,7 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, char *host = strdup(hostname); char *principal; - strlower(host); + strlower_m(host); /* we need to use the '$' form of the name here, as otherwise the -- cgit From aa39cc37dab9c4f8c3295d872bb8cc143890b378 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Fri, 15 Aug 2003 04:42:05 +0000 Subject: get rid of more compiler warnings (This used to be commit 398bd14fc6e2f8ab2f34211270e179b8928a6669) --- source3/libads/krb5_setpw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 80ef6cdf01..d1da118bb8 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -143,7 +143,7 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, else return EINVAL; - encoded_setpw.data = setpw.data; + encoded_setpw.data = (char *)setpw.data; encoded_setpw.length = setpw.length; ret = krb5_mk_priv(context, auth_context, -- cgit From f1be3a5c5defc2df94550b90b7dd2ed4ab0cb1f2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 19 Aug 2003 22:47:10 +0000 Subject: - Make 'net' use a single funciton for setting the 'use machine account' code. - Make winbindd try to use kerberos for connections to DCs, so that it can access RA=2 servers, particularly for netlogon. - Make rpcclient follow the new flags for the NETLOGON pipe - Make all the code that uses schannel use the centralised functions for doing so. Andrew Bartlett (This used to be commit 96b4187963cedcfe158ff02868929b8cf81c6ebf) --- source3/libads/krb5_setpw.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index d1da118bb8..9cf15221a8 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -664,25 +664,22 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, * @return status of password change **/ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, - const char *hostname, + const char *machine_account, const char *password) { ADS_STATUS status; - char *host = strdup(hostname); - char *principal; - - strlower_m(host); + char *principal = NULL; /* - we need to use the '$' form of the name here, as otherwise the - server might end up setting the password for a user instead + we need to use the '$' form of the name here (the machine account name), + as otherwise the server might end up setting the password for a user + instead */ - asprintf(&principal, "%s$@%s", host, ads->config.realm); + asprintf(&principal, "%s@%s", machine_account, ads->config.realm); status = ads_krb5_set_password(ads->auth.kdc_server, principal, password, ads->auth.time_offset); - free(host); free(principal); return status; -- cgit From 9a8e30d04b1cfc53e8c8949a56d4f1cf5aa26501 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 24 Mar 2004 17:32:55 +0000 Subject: Fix bugzilla # 1208 Winbind tickets expired. We now check the expiration time, and acquire new tickets. We couln't rely on renewing them, because if we didn't get a request before they expired, we wouldn't have renewed them. Also, there is a one-week limit in MS on renewal life, so new tickets would have been needed after a week anyway. Default is 10 hours, so we should only be acquiring them that often, unless the configuration on the DC is changed (and the minimum is 1 hour). (This used to be commit c2436c433afaab4006554a86307f76b6689d6929) --- source3/libads/krb5_setpw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 9cf15221a8..16d3df83e9 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -642,7 +642,7 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, { int ret; - if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset))) { + if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset, NULL))) { DEBUG(1,("Failed kinit for principal %s (%s)\n", auth_principal, error_message(ret))); return ADS_ERROR_KRB5(ret); } -- cgit From 63378d6f0efa4612da1aecb5dee14992ac069d0f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 7 May 2004 02:48:03 +0000 Subject: r541: fixing segfault in winbindd caused -r527 -- looks like a bug in heimdal; also initialize some pointers (This used to be commit be74e88d9a4b74fcaf25b0816e3fa8a487c91ab5) --- source3/libads/krb5_setpw.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 16d3df83e9..5c859f0e99 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -463,12 +463,12 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, ADS_STATUS aret; krb5_error_code ret; - krb5_context context; + krb5_context context = NULL; krb5_principal principal; char *princ_name; char *realm; krb5_creds creds, *credsp; - krb5_ccache ccache; + krb5_ccache ccache = NULL; ret = krb5_init_context(&context); if (ret) { @@ -578,7 +578,7 @@ static ADS_STATUS ads_krb5_chg_password(const char *kdc_host, { ADS_STATUS aret; krb5_error_code ret; - krb5_context context; + krb5_context context = NULL; krb5_principal princ; krb5_get_init_creds_opt opts; krb5_creds creds; -- cgit From 7825677b862bb62b8350b6fee458fbbecc53893f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Jun 2004 00:20:31 +0000 Subject: r1222: Valgrind memory leak fixes. Still tracking down a strange one... Can't fix the krb5 memory leaks inside that library :-(. Jeremy. (This used to be commit ad440213aaae58fb5bff6e8a6fcf811c5ba83669) --- source3/libads/krb5_setpw.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 5c859f0e99..111834e886 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -56,7 +56,7 @@ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) princ = strdup(principal); - if ((c = strchr(princ, '/')) == NULL) { + if ((c = strchr_m(princ, '/')) == NULL) { c = princ; } else { *c = '\0'; @@ -66,7 +66,7 @@ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) princ_part2 = c; - if ((c = strchr(c, '@')) != NULL) { + if ((c = strchr_m(c, '@')) != NULL) { *c = '\0'; c++; realm = c; @@ -462,14 +462,16 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, { ADS_STATUS aret; - krb5_error_code ret; + krb5_error_code ret = 0; krb5_context context = NULL; - krb5_principal principal; - char *princ_name; - char *realm; - krb5_creds creds, *credsp; + krb5_principal principal = NULL; + char *princ_name = NULL; + char *realm = NULL; + krb5_creds creds, *credsp = NULL; krb5_ccache ccache = NULL; + ZERO_STRUCT(creds); + ret = krb5_init_context(&context); if (ret) { DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); @@ -487,14 +489,19 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, return ADS_ERROR_KRB5(ret); } - ZERO_STRUCT(creds); - - realm = strchr(princ, '@'); + realm = strchr_m(princ, '@'); + if (!realm) { + krb5_cc_close(context, ccache); + krb5_free_context(context); + DEBUG(1,("Failed to get realm\n")); + return ADS_ERROR_KRB5(-1); + } realm++; asprintf(&princ_name, "kadmin/changepw@%s", realm); ret = krb5_parse_name(context, princ_name, &creds.server); if (ret) { + krb5_cc_close(context, ccache); krb5_free_context(context); DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); @@ -504,6 +511,8 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, /* parse the principal we got as a function argument */ ret = krb5_parse_name(context, princ, &principal); if (ret) { + krb5_cc_close(context, ccache); + krb5_free_principal(context, creds.server); krb5_free_context(context); DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret))); return ADS_ERROR_KRB5(ret); @@ -514,6 +523,8 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, ret = krb5_cc_get_principal(context, ccache, &creds.client); if (ret) { + krb5_cc_close(context, ccache); + krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); krb5_free_context(context); DEBUG(1,("Failed to get principal from ccache (%s)\n", @@ -523,7 +534,9 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); if (ret) { + krb5_cc_close(context, ccache); krb5_free_principal(context, creds.client); + krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); krb5_free_context(context); DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret))); @@ -538,7 +551,9 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, krb5_free_creds(context, credsp); krb5_free_principal(context, creds.client); + krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); + krb5_cc_close(context, ccache); krb5_free_context(context); return aret; -- cgit From 1f7dbded0435f4f6b3e141edb89025542b904a57 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Jun 2004 00:35:29 +0000 Subject: r1223: Fix valgrind error with realm manipulation.... Damn macros :-(. Jeremy. (This used to be commit 5a1d8c3c9b8daa435f6eb5bc1652bab138e05dbf) --- source3/libads/krb5_setpw.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 111834e886..c7e9e3fe76 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -468,6 +468,7 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, char *princ_name = NULL; char *realm = NULL; krb5_creds creds, *credsp = NULL; + krb5_data orig_realm; krb5_ccache ccache = NULL; ZERO_STRUCT(creds); @@ -518,12 +519,15 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, return ADS_ERROR_KRB5(ret); } - krb5_princ_set_realm(context, creds.server, - krb5_princ_realm(context, principal)); + /* The creds.server principal takes ownership of this memory. + Remember to set back to original value before freeing. */ + orig_realm = *krb5_princ_realm(context, creds.server); + krb5_princ_set_realm(context, creds.server, krb5_princ_realm(context, principal)); ret = krb5_cc_get_principal(context, ccache, &creds.client); if (ret) { krb5_cc_close(context, ccache); + krb5_princ_set_realm(context, creds.server, &orig_realm); krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); krb5_free_context(context); @@ -536,6 +540,7 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, if (ret) { krb5_cc_close(context, ccache); krb5_free_principal(context, creds.client); + krb5_princ_set_realm(context, creds.server, &orig_realm); krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); krb5_free_context(context); @@ -551,6 +556,7 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, krb5_free_creds(context, credsp); krb5_free_principal(context, creds.client); + krb5_princ_set_realm(context, creds.server, &orig_realm); krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); krb5_cc_close(context, ccache); -- cgit From 6106de34e56cf6a3b4655f799c88ab1c349ae4a9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jun 2004 21:35:16 +0000 Subject: r1247: Final fix to make this compile on Heimdal. Jeremy. (This used to be commit b462b8fa2f264bef62ed4cd2aaacb2f21e135068) --- source3/libads/krb5_setpw.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index c7e9e3fe76..84595212e6 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -468,7 +468,11 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, char *princ_name = NULL; char *realm = NULL; krb5_creds creds, *credsp = NULL; +#if KRB5_PRINC_REALM_RETURNS_REALM + krb5_realm orig_realm; +#else krb5_data orig_realm; +#endif krb5_ccache ccache = NULL; ZERO_STRUCT(creds); -- cgit From 0772ddbae1be394c538f1d3529ea84434eadcf97 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 29 Oct 2004 22:38:10 +0000 Subject: r3377: Merge in first part of modified patch from Nalin Dahyabhai for bug #1717.The rest of the code needed to call this patch has not yet been checked in (that's my next task). This has not yet been tested - I'll do this once the rest of the patch is integrated. Jeremy. (This used to be commit 7565019286cf44f43c8066c005b1cd5c1556435f) --- source3/libads/krb5_setpw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 84595212e6..385c1f02aa 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -667,7 +667,7 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, { int ret; - if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset, NULL))) { + if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset, NULL, NULL))) { DEBUG(1,("Failed kinit for principal %s (%s)\n", auth_principal, error_message(ret))); return ADS_ERROR_KRB5(ret); } -- cgit From 428ca3998bc84aba166adb6c0eae3f20b2ad782c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 1 Nov 2004 16:18:14 +0000 Subject: r3436: Fix build with recent heimdal-versions (0.6.3) as pointed out by Luke Mewburn and close Bugzilla #1661. Leaving the old define for KRB5_KPASSWD_VERS_SETPW (added by Antti Andreimann) as fallback when the library does not provide one. Guenther (This used to be commit 00598877dfb7aab48d1b5d58b3a69ed2dd8a36a8) --- source3/libads/krb5_setpw.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 385c1f02aa..a45bf23610 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -25,7 +25,9 @@ #define DEFAULT_KPASSWD_PORT 464 #define KRB5_KPASSWD_VERS_CHANGEPW 1 +#ifndef KRB5_KPASSWD_VERS_SETPW #define KRB5_KPASSWD_VERS_SETPW 2 +#endif #define KRB5_KPASSWD_VERS_SETPW_MS 0xff80 #define KRB5_KPASSWD_ACCESSDENIED 5 #define KRB5_KPASSWD_BAD_VERSION 6 -- cgit From a13b603b79e170683b6b5b339d3494d32a9eaf39 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 12 Nov 2004 23:13:03 +0000 Subject: r3711: Fix KRB5_SETPW-defines, no change in behaviour. A value of '2' is due to an expired internet draft, while 0xff80 comes from RFC3244. See Bugzilla #1661 for details. Thanks to Luke Mewburn for his research. Guenther (This used to be commit 3906c1623fb3823612347a0533ad49d7dfbe1b99) --- source3/libads/krb5_setpw.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index a45bf23610..9582574851 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -25,10 +25,8 @@ #define DEFAULT_KPASSWD_PORT 464 #define KRB5_KPASSWD_VERS_CHANGEPW 1 -#ifndef KRB5_KPASSWD_VERS_SETPW -#define KRB5_KPASSWD_VERS_SETPW 2 -#endif -#define KRB5_KPASSWD_VERS_SETPW_MS 0xff80 +#define KRB5_KPASSWD_VERS_SETPW 0xff80 +#define KRB5_KPASSWD_VERS_SETPW_ALT 2 #define KRB5_KPASSWD_ACCESSDENIED 5 #define KRB5_KPASSWD_BAD_VERSION 6 #define KRB5_KPASSWD_INITIAL_FLAG_NEEDED 7 @@ -140,7 +138,7 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, if (pversion == KRB5_KPASSWD_VERS_CHANGEPW) setpw = data_blob(passwd, strlen(passwd)); else if (pversion == KRB5_KPASSWD_VERS_SETPW || - pversion == KRB5_KPASSWD_VERS_SETPW_MS) + pversion == KRB5_KPASSWD_VERS_SETPW_ALT) setpw = encode_krb5_setpw(princ, passwd); else return EINVAL; @@ -252,7 +250,7 @@ static krb5_error_code parse_setpw_reply(krb5_context context, /* FIXME: According to standard there is only one type of reply */ if (vnum != KRB5_KPASSWD_VERS_SETPW && - vnum != KRB5_KPASSWD_VERS_SETPW_MS && + vnum != KRB5_KPASSWD_VERS_SETPW_ALT && vnum != KRB5_KPASSWD_VERS_CHANGEPW) { DEBUG(1,("Bad vnum (%d) from kpasswd server\n", vnum)); return KRB5KDC_ERR_BAD_PVNO; @@ -557,7 +555,7 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, /* we might have to call krb5_free_creds(...) from now on ... */ aret = do_krb5_kpasswd_request(context, kdc_host, - KRB5_KPASSWD_VERS_SETPW_MS, + KRB5_KPASSWD_VERS_SETPW, credsp, princ, newpw); krb5_free_creds(context, credsp); -- cgit From acf9d61421faa6c0055d57fdee7db300dc5431aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Dec 2004 18:25:53 +0000 Subject: r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation functions so we can funnel through some well known functions. Should help greatly with malloc checking. HEAD patch to follow. Jeremy. (This used to be commit 620f2e608f70ba92f032720c031283d295c5c06a) --- source3/libads/krb5_setpw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 9582574851..dadce2593c 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -54,7 +54,7 @@ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) DATA_BLOB ret; - princ = strdup(principal); + princ = SMB_STRDUP(principal); if ((c = strchr_m(princ, '/')) == NULL) { c = princ; @@ -156,7 +156,7 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, return ret; } - packet->data = (char *)malloc(ap_req->length + cipherpw.length + 6); + packet->data = (char *)SMB_MALLOC(ap_req->length + cipherpw.length + 6); if (!packet->data) return -1; @@ -407,7 +407,7 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, free(chpw_req.data); chpw_rep.length = 1500; - chpw_rep.data = (char *) malloc(chpw_rep.length); + chpw_rep.data = (char *) SMB_MALLOC(chpw_rep.length); if (!chpw_rep.data) { close(sock); free(ap_req.data); @@ -631,7 +631,7 @@ static ADS_STATUS ads_krb5_chg_password(const char *kdc_host, /* We have to obtain an INITIAL changepw ticket for changing password */ asprintf(&chpw_princ, "kadmin/changepw@%s", (char *) krb5_princ_realm(context, princ)); - password = strdup(oldpw); + password = SMB_STRDUP(oldpw); ret = krb5_get_init_creds_password(context, &creds, princ, password, kerb_prompter, NULL, 0, chpw_princ, &opts); -- cgit From 8c072021efba737539b46e993df0c21a6438a82a Mon Sep 17 00:00:00 2001 From: James Peach Date: Tue, 30 Aug 2005 06:41:32 +0000 Subject: r9780: Clean up a bunch of compiler warnings. (This used to be commit 623d2e69319ffead31a780a4d6156dae45f386d7) --- source3/libads/krb5_setpw.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index dadce2593c..c261d15c21 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -317,23 +317,17 @@ static krb5_error_code parse_setpw_reply(krb5_context context, switch(res_code) { case KRB5_KPASSWD_ACCESSDENIED: return KRB5KDC_ERR_BADOPTION; - break; case KRB5_KPASSWD_INITIAL_FLAG_NEEDED: return KRB5KDC_ERR_BADOPTION; /* return KV5M_ALT_METHOD; MIT-only define */ - break; case KRB5_KPASSWD_ETYPE_NOSUPP: return KRB5KDC_ERR_ETYPE_NOSUPP; - break; case KRB5_KPASSWD_BAD_PRINCIPAL: return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; - break; case KRB5_KPASSWD_POLICY_REJECT: return KRB5KDC_ERR_POLICY; - break; default: return KRB5KRB_ERR_GENERIC; - break; } } } -- cgit From 8d7c88667190fe286971ac4fffb64ee5bd9eeeb0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Oct 2005 03:24:00 +0000 Subject: r11137: Compile with only 2 warnings (I'm still working on that code) on a gcc4 x86_64 box. Jeremy. (This used to be commit d720867a788c735e56d53d63265255830ec21208) --- source3/libads/krb5_setpw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index c261d15c21..5488c5908f 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -341,7 +341,8 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, { krb5_auth_context auth_context = NULL; krb5_data ap_req, chpw_req, chpw_rep; - int ret, sock, addr_len; + int ret, sock; + socklen_t addr_len; struct sockaddr remote_addr, local_addr; krb5_address local_kaddr, remote_kaddr; -- cgit From f99b429446595944991bd2b3e9f4e6a9dd2c13cb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 7 Nov 2005 14:16:50 +0000 Subject: r11551: Add a few more initialize_krb5_error_table (This used to be commit d92c83aa42fe64a0e996094d1a983f0279c7c707) --- source3/libads/krb5_setpw.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 5488c5908f..31d0a02cad 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -472,6 +472,7 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, ZERO_STRUCT(creds); + initialize_krb5_error_table(); ret = krb5_init_context(&context); if (ret) { DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); @@ -604,6 +605,7 @@ static ADS_STATUS ads_krb5_chg_password(const char *kdc_host, krb5_creds creds; char *chpw_princ = NULL, *password; + initialize_krb5_error_table(); ret = krb5_init_context(&context); if (ret) { DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); -- cgit From 0af1500fc0bafe61019f1b2ab1d9e1d369221240 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 3 Feb 2006 22:19:41 +0000 Subject: r13316: Let the carnage begin.... Sync with trunk as off r13315 (This used to be commit 17e63ac4ed8325c0d44fe62b2442449f3298559f) --- source3/libads/krb5_setpw.c | 49 ++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 18 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 31d0a02cad..6ffd218e96 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -24,9 +24,17 @@ #ifdef HAVE_KRB5 #define DEFAULT_KPASSWD_PORT 464 + #define KRB5_KPASSWD_VERS_CHANGEPW 1 + #define KRB5_KPASSWD_VERS_SETPW 0xff80 #define KRB5_KPASSWD_VERS_SETPW_ALT 2 + +#define KRB5_KPASSWD_SUCCESS 0 +#define KRB5_KPASSWD_MALFORMED 1 +#define KRB5_KPASSWD_HARDERROR 2 +#define KRB5_KPASSWD_AUTHERROR 3 +#define KRB5_KPASSWD_SOFTERROR 4 #define KRB5_KPASSWD_ACCESSDENIED 5 #define KRB5_KPASSWD_BAD_VERSION 6 #define KRB5_KPASSWD_INITIAL_FLAG_NEEDED 7 @@ -213,6 +221,25 @@ static krb5_error_code setpw_result_code_string(krb5_context context, return (0); } + krb5_error_code kpasswd_err_to_krb5_err(krb5_error_code res_code) +{ + switch(res_code) { + case KRB5_KPASSWD_ACCESSDENIED: + return KRB5KDC_ERR_BADOPTION; + case KRB5_KPASSWD_INITIAL_FLAG_NEEDED: + return KRB5KDC_ERR_BADOPTION; + /* return KV5M_ALT_METHOD; MIT-only define */ + case KRB5_KPASSWD_ETYPE_NOSUPP: + return KRB5KDC_ERR_ETYPE_NOSUPP; + case KRB5_KPASSWD_BAD_PRINCIPAL: + return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; + case KRB5_KPASSWD_POLICY_REJECT: + case KRB5_KPASSWD_SOFTERROR: + return KRB5KDC_ERR_POLICY; + default: + return KRB5KRB_ERR_GENERIC; + } +} static krb5_error_code parse_setpw_reply(krb5_context context, krb5_auth_context auth_context, krb5_data *packet) @@ -312,23 +339,9 @@ static krb5_error_code parse_setpw_reply(krb5_context context, else { const char *errstr; setpw_result_code_string(context, res_code, &errstr); - DEBUG(1, ("Error changing password: %s\n", errstr)); - - switch(res_code) { - case KRB5_KPASSWD_ACCESSDENIED: - return KRB5KDC_ERR_BADOPTION; - case KRB5_KPASSWD_INITIAL_FLAG_NEEDED: - return KRB5KDC_ERR_BADOPTION; - /* return KV5M_ALT_METHOD; MIT-only define */ - case KRB5_KPASSWD_ETYPE_NOSUPP: - return KRB5KDC_ERR_ETYPE_NOSUPP; - case KRB5_KPASSWD_BAD_PRINCIPAL: - return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; - case KRB5_KPASSWD_POLICY_REJECT: - return KRB5KDC_ERR_POLICY; - default: - return KRB5KRB_ERR_GENERIC; - } + DEBUG(1, ("Error changing password: %s (%d)\n", errstr, res_code)); + + return kpasswd_err_to_krb5_err(res_code); } } @@ -664,7 +677,7 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, { int ret; - if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset, NULL, NULL))) { + if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset, NULL, NULL, NULL, False, 0))) { DEBUG(1,("Failed kinit for principal %s (%s)\n", auth_principal, error_message(ret))); return ADS_ERROR_KRB5(ret); } -- cgit From 5f224c2c265faa50e5495cc738f1a62c6aa70d56 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Mar 2006 18:32:18 +0000 Subject: r14170: Paranioa fix for sesssetup. Fix Coverity bug #26. Guard against NULL ref. Jeremy. (This used to be commit c0f906ac8de850f4566b6b3be4e3c7d245e6e252) --- source3/libads/krb5_setpw.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 6ffd218e96..42ca36f344 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -65,19 +65,22 @@ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) princ = SMB_STRDUP(principal); if ((c = strchr_m(princ, '/')) == NULL) { - c = princ; + c = princ; } else { - *c = '\0'; - c++; - princ_part1 = princ; + *c = '\0'; + c++; + princ_part1 = princ; } princ_part2 = c; if ((c = strchr_m(c, '@')) != NULL) { - *c = '\0'; - c++; - realm = c; + *c = '\0'; + c++; + realm = c; + } else { + /* We must have a realm component. */ + return data_blob(NULL, 0); } memset(&req, 0, sizeof(req)); @@ -97,8 +100,9 @@ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) asn1_push_tag(&req, ASN1_CONTEXT(1)); asn1_push_tag(&req, ASN1_SEQUENCE(0)); - if (princ_part1) - asn1_write_GeneralString(&req, princ_part1); + if (princ_part1) { + asn1_write_GeneralString(&req, princ_part1); + } asn1_write_GeneralString(&req, princ_part2); asn1_pop_tag(&req); @@ -151,6 +155,10 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, else return EINVAL; + if (setpw.data == NULL || setpw.length == 0) { + return EINVAL; + } + encoded_setpw.data = (char *)setpw.data; encoded_setpw.length = setpw.length; -- cgit From 485a286a65d3b37f424f5701179f73c99eb9b5b9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 20 Mar 2006 19:05:44 +0000 Subject: r14585: Tighten argument list of kerberos_kinit_password again, kerberos_kinit_password_ext provides access to more options. Guenther (This used to be commit afc519530f94b420b305fc28f83c16db671d0d7f) --- source3/libads/krb5_setpw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 42ca36f344..415c1e9229 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -685,7 +685,7 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, { int ret; - if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset, NULL, NULL, NULL, False, 0))) { + if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset, NULL))) { DEBUG(1,("Failed kinit for principal %s (%s)\n", auth_principal, error_message(ret))); return ADS_ERROR_KRB5(ret); } -- cgit From b68b05854ff5a7e75953462eba74f97753428ef1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 24 Apr 2006 15:57:54 +0000 Subject: r15210: Add wrapper functions smb_krb5_parse_name, smb_krb5_unparse_name, smb_krb5_parse_name_norealm_conv that pull/push from unix charset to utf8 (which krb5 uses on the wire). This should fix issues when the unix charset is not compatible with or set to utf8. Jeremy. (This used to be commit 37ab42afbc9a79cf5b04ce6a1bf4060e9c961199) --- source3/libads/krb5_setpw.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 415c1e9229..254ca7b2a3 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -521,7 +521,7 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, realm++; asprintf(&princ_name, "kadmin/changepw@%s", realm); - ret = krb5_parse_name(context, princ_name, &creds.server); + ret = smb_krb5_parse_name(context, princ_name, &creds.server); if (ret) { krb5_cc_close(context, ccache); krb5_free_context(context); @@ -531,7 +531,7 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, free(princ_name); /* parse the principal we got as a function argument */ - ret = krb5_parse_name(context, princ, &principal); + ret = smb_krb5_parse_name(context, princ, &principal); if (ret) { krb5_cc_close(context, ccache); krb5_free_principal(context, creds.server); @@ -633,7 +633,7 @@ static ADS_STATUS ads_krb5_chg_password(const char *kdc_host, return ADS_ERROR_KRB5(ret); } - if ((ret = krb5_parse_name(context, principal, + if ((ret = smb_krb5_parse_name(context, principal, &princ))) { krb5_free_context(context); DEBUG(1,("Failed to parse %s (%s)\n", principal, error_message(ret))); -- cgit From edcffcbe2875d749e97ddc6a685995973c09808e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 13 Jun 2006 18:09:37 +0000 Subject: r16201: Fix Klocwork 439 (This used to be commit b369d0891afe8b777b837eaac317131232568ca7) --- source3/libads/krb5_setpw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 254ca7b2a3..ec2ff5afb1 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -528,7 +528,6 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } - free(princ_name); /* parse the principal we got as a function argument */ ret = smb_krb5_parse_name(context, princ, &principal); @@ -537,9 +536,12 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, krb5_free_principal(context, creds.server); krb5_free_context(context); DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret))); + free(princ_name); return ADS_ERROR_KRB5(ret); } + free(princ_name); + /* The creds.server principal takes ownership of this memory. Remember to set back to original value before freeing. */ orig_realm = *krb5_princ_realm(context, creds.server); -- cgit From e030a9e9dcda36edee475aa9fd8772f9f74b3552 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 15 Jun 2006 21:25:57 +0000 Subject: r16268: Add TCP fallback for our implementation of the CHANGEPW kpasswd calls. This patch is mainly based on the work of Todd Stecher and has been reviewed by Jeremy. I sucessfully tested and valgrinded it with MIT 1.4.3, 1.3.5, Heimdal 0.7.2 and 0.6.1rc3. Guenther (This used to be commit 535d03cbe8b021e9aa6d74b62d81b867c494c957) --- source3/libads/krb5_setpw.c | 270 +++++++++++++++++++++++++++----------------- 1 file changed, 166 insertions(+), 104 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index ec2ff5afb1..07e6320c26 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -45,6 +45,14 @@ #define KRB5_KPASSWD_BAD_PRINCIPAL 9 #define KRB5_KPASSWD_ETYPE_NOSUPP 10 +/* + * we've got to be able to distinguish KRB_ERRORs from other + * requests - valid response for CHPW v2 replies. + */ + +#define krb5_is_krb_error(packet) \ + ( packet && packet->length && (((char *)packet->data)[0] == 0x7e || ((char *)packet->data)[0] == 0x5e)) + /* This implements kerberos password change protocol as specified in * kerb-chg-password-02.txt and kerberos-set-passwd-02.txt * as well as microsoft version of the protocol @@ -129,14 +137,16 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, krb5_data *ap_req, const char *princ, const char *passwd, + BOOL use_tcp, krb5_data *packet) { krb5_error_code ret; krb5_data cipherpw; krb5_data encoded_setpw; krb5_replay_data replay; - char *p; + char *p, *msg_start; DATA_BLOB setpw; + unsigned int msg_length; ret = krb5_auth_con_setflags(context, auth_context,KRB5_AUTH_CONTEXT_DO_SEQUENCE); @@ -172,12 +182,16 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, return ret; } - packet->data = (char *)SMB_MALLOC(ap_req->length + cipherpw.length + 6); + packet->data = (char *)SMB_MALLOC(ap_req->length + cipherpw.length + (use_tcp ? 10 : 6 )); if (!packet->data) return -1; + + /* see the RFC for details */ - p = ((char *)packet->data) + 2; + + msg_start = p = ((char *)packet->data) + (use_tcp ? 4 : 0); + p += 2; RSSVAL(p, 0, pversion); p += 2; RSSVAL(p, 0, ap_req->length); @@ -187,7 +201,12 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, memcpy(p, cipherpw.data, cipherpw.length); p += cipherpw.length; packet->length = PTR_DIFF(p,packet->data); - RSSVAL(packet->data, 0, packet->length); + msg_length = PTR_DIFF(p,msg_start); + + if (use_tcp) { + RSIVAL(packet->data, 0, msg_length); + } + RSSVAL(msg_start, 0, msg_length); free(cipherpw.data); /* from 'krb5_mk_priv(...)' */ @@ -248,7 +267,8 @@ static krb5_error_code setpw_result_code_string(krb5_context context, return KRB5KRB_ERR_GENERIC; } } -static krb5_error_code parse_setpw_reply(krb5_context context, +static krb5_error_code parse_setpw_reply(krb5_context context, + BOOL use_tcp, krb5_auth_context auth_context, krb5_data *packet) { @@ -259,23 +279,41 @@ static krb5_error_code parse_setpw_reply(krb5_context context, krb5_data clearresult; krb5_ap_rep_enc_part *ap_rep_enc; krb5_replay_data replay; - - if (packet->length < 4) { + unsigned int msg_length = packet->length; + + + if (packet->length < (use_tcp ? 8 : 4)) { return KRB5KRB_AP_ERR_MODIFIED; } p = packet->data; + /* + ** see if it is an error + */ + if (krb5_is_krb_error(packet)) { + + ret = handle_krberror_packet(context, packet); + if (ret) { + return ret; + } + } + - if (((char *)packet->data)[0] == 0x7e || ((char *)packet->data)[0] == 0x5e) { - /* it's an error packet. We should parse it ... */ - DEBUG(1,("Got error packet 0x%x from kpasswd server\n", - ((char *)packet->data)[0])); - return KRB5KRB_AP_ERR_MODIFIED; + /* tcp... */ + if (use_tcp) { + msg_length -= 4; + if (RIVAL(p, 0) != msg_length) { + DEBUG(1,("Bad TCP packet length (%d/%d) from kpasswd server\n", + RIVAL(p, 0), msg_length)); + return KRB5KRB_AP_ERR_MODIFIED; + } + + p += 4; } - if (RSVAL(p, 0) != packet->length) { + if (RSVAL(p, 0) != msg_length) { DEBUG(1,("Bad packet length (%d/%d) from kpasswd server\n", - RSVAL(p, 0), packet->length)); + RSVAL(p, 0), msg_length)); return KRB5KRB_AP_ERR_MODIFIED; } @@ -342,9 +380,9 @@ static krb5_error_code parse_setpw_reply(krb5_context context, return KRB5KRB_AP_ERR_MODIFIED; } - if(res_code == KRB5_KPASSWD_SUCCESS) - return 0; - else { + if (res_code == KRB5_KPASSWD_SUCCESS) { + return 0; + } else { const char *errstr; setpw_result_code_string(context, res_code, &errstr); DEBUG(1, ("Error changing password: %s (%d)\n", errstr, res_code)); @@ -365,7 +403,10 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, int ret, sock; socklen_t addr_len; struct sockaddr remote_addr, local_addr; + struct in_addr *addr = interpret_addr2(kdc_host); krb5_address local_kaddr, remote_kaddr; + BOOL use_tcp = False; + ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, NULL, credsp, &ap_req); @@ -373,102 +414,123 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, DEBUG(1,("krb5_mk_req_extended failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } - - sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT); - if (sock == -1) { - int rc = errno; - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", - kdc_host, strerror(errno))); - return ADS_ERROR_SYSTEM(rc); - } - - addr_len = sizeof(remote_addr); - getpeername(sock, &remote_addr, &addr_len); - addr_len = sizeof(local_addr); - getsockname(sock, &local_addr, &addr_len); - - setup_kaddr(&remote_kaddr, &remote_addr); - setup_kaddr(&local_kaddr, &local_addr); - - ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); - if (ret) { - close(sock); - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - ret = build_kpasswd_request(pversion, context, auth_context, &ap_req, - princ, newpw, &chpw_req); - if (ret) { - close(sock); - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - if (write(sock, chpw_req.data, chpw_req.length) != chpw_req.length) { - close(sock); - free(chpw_req.data); - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); - return ADS_ERROR_SYSTEM(errno); - } + do { - free(chpw_req.data); + if (!use_tcp) { - chpw_rep.length = 1500; - chpw_rep.data = (char *) SMB_MALLOC(chpw_rep.length); - if (!chpw_rep.data) { - close(sock); - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); - errno = ENOMEM; - return ADS_ERROR_SYSTEM(errno); - } + sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT); - ret = read(sock, chpw_rep.data, chpw_rep.length); - if (ret < 0) { - close(sock); - free(chpw_rep.data); - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno))); - return ADS_ERROR_SYSTEM(errno); - } + } else { - close(sock); - chpw_rep.length = ret; + sock = open_socket_out(SOCK_STREAM, addr, DEFAULT_KPASSWD_PORT, + LONG_CONNECT_TIMEOUT); + } - ret = krb5_auth_con_setaddrs(context, auth_context, NULL,&remote_kaddr); - if (ret) { - free(chpw_rep.data); - free(ap_req.data); - krb5_auth_con_free(context, auth_context); - DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n", - error_message(ret))); - return ADS_ERROR_KRB5(ret); - } + if (sock == -1) { + int rc = errno; + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", + kdc_host, strerror(errno))); + return ADS_ERROR_SYSTEM(rc); + } + + addr_len = sizeof(remote_addr); + getpeername(sock, &remote_addr, &addr_len); + addr_len = sizeof(local_addr); + getsockname(sock, &local_addr, &addr_len); + + setup_kaddr(&remote_kaddr, &remote_addr); + setup_kaddr(&local_kaddr, &local_addr); + + ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); + if (ret) { + close(sock); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + ret = build_kpasswd_request(pversion, context, auth_context, &ap_req, + princ, newpw, use_tcp, &chpw_req); + if (ret) { + close(sock); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } - ret = parse_setpw_reply(context, auth_context, &chpw_rep); - free(chpw_rep.data); + ret = write(sock, chpw_req.data, chpw_req.length); - if (ret) { - free(ap_req.data); + if (ret != chpw_req.length) { + close(sock); + SAFE_FREE(chpw_req.data); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); + return ADS_ERROR_SYSTEM(errno); + } + + SAFE_FREE(chpw_req.data); + + chpw_rep.length = 1500; + chpw_rep.data = (char *) SMB_MALLOC(chpw_rep.length); + if (!chpw_rep.data) { + close(sock); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); + errno = ENOMEM; + return ADS_ERROR_SYSTEM(errno); + } + + ret = read(sock, chpw_rep.data, chpw_rep.length); + if (ret < 0) { + close(sock); + SAFE_FREE(chpw_rep.data); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno))); + return ADS_ERROR_SYSTEM(errno); + } + + close(sock); + chpw_rep.length = ret; + + ret = krb5_auth_con_setaddrs(context, auth_context, NULL,&remote_kaddr); + if (ret) { + SAFE_FREE(chpw_rep.data); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n", + error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + ret = parse_setpw_reply(context, use_tcp, auth_context, &chpw_rep); + SAFE_FREE(chpw_rep.data); + + if (ret) { + + if (ret == KRB5KRB_ERR_RESPONSE_TOO_BIG && !use_tcp) { + DEBUG(5, ("Trying setpw with TCP!!!\n")); + use_tcp = True; + continue; + } + + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("parse_setpw_reply failed (%s)\n", + error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + SAFE_FREE(ap_req.data); krb5_auth_con_free(context, auth_context); - DEBUG(1,("parse_setpw_reply failed (%s)\n", - error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - free(ap_req.data); - krb5_auth_con_free(context, auth_context); + } while ( ret ); return ADS_SUCCESS; } -- cgit From f852fdbe06ec9f19424d6870cba9b1872a0d5d7a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Aug 2006 17:55:06 +0000 Subject: r17626: Some C++ Warnings (This used to be commit 09e7c010f03ac3c621f7a7fad44685d278c1481a) --- source3/libads/krb5_setpw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 07e6320c26..c7a4b982db 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -667,7 +667,9 @@ kerb_prompter(krb5_context ctx, void *data, memset(prompts[0].reply->data, 0, prompts[0].reply->length); if (prompts[0].reply->length > 0) { if (data) { - strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); + strncpy(prompts[0].reply->data, + (const char *)data, + prompts[0].reply->length-1); prompts[0].reply->length = strlen(prompts[0].reply->data); } else { prompts[0].reply->length = 0; -- cgit From b4a7b7a8889737e2891fc1176feabd4ce47f2737 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 May 2007 12:16:20 +0000 Subject: r22844: Introduce const DATA_BLOB data_blob_null = { NULL, 0, NULL }; and replace all data_blob(NULL, 0) calls. (This used to be commit 3d3d61687ef00181f4f04e001d42181d93ac931e) --- source3/libads/krb5_setpw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index c7a4b982db..4aab09c9f4 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -88,7 +88,7 @@ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) realm = c; } else { /* We must have a realm component. */ - return data_blob(NULL, 0); + return data_blob_null; } memset(&req, 0, sizeof(req)); -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/libads/krb5_setpw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 4aab09c9f4..735cafa524 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -6,7 +6,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/libads/krb5_setpw.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 735cafa524..24220685f3 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -15,8 +15,7 @@ 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. + along with this program. If not, see . */ #include "includes.h" -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/libads/krb5_setpw.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 24220685f3..73dffe7c1b 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -136,7 +136,7 @@ static krb5_error_code build_kpasswd_request(uint16 pversion, krb5_data *ap_req, const char *princ, const char *passwd, - BOOL use_tcp, + bool use_tcp, krb5_data *packet) { krb5_error_code ret; @@ -267,7 +267,7 @@ static krb5_error_code setpw_result_code_string(krb5_context context, } } static krb5_error_code parse_setpw_reply(krb5_context context, - BOOL use_tcp, + bool use_tcp, krb5_auth_context auth_context, krb5_data *packet) { @@ -404,7 +404,7 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, struct sockaddr remote_addr, local_addr; struct in_addr *addr = interpret_addr2(kdc_host); krb5_address local_kaddr, remote_kaddr; - BOOL use_tcp = False; + bool use_tcp = False; ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, -- cgit From f88b7a076be74a29a3bf876b4e2705f4a1ecf42b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 24 Oct 2007 14:16:54 -0700 Subject: This is a large patch (sorry). Migrate from struct in_addr to struct sockaddr_storage in most places that matter (ie. not the nmbd and NetBIOS lookups). This passes make test on an IPv4 box, but I'll have to do more work/testing on IPv6 enabled boxes. This should now give us a framework for testing and finishing the IPv6 migration. It's at the state where someone with a working IPv6 setup should (theorecically) be able to type : smbclient //ipv6-address/share and have it work. Jeremy. (This used to be commit 98e154c3125d5732c37a72d74b0eb5cd7b6155fd) --- source3/libads/krb5_setpw.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 73dffe7c1b..831a448847 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -402,11 +402,14 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, int ret, sock; socklen_t addr_len; struct sockaddr remote_addr, local_addr; - struct in_addr *addr = interpret_addr2(kdc_host); + struct sockaddr_storage addr; krb5_address local_kaddr, remote_kaddr; bool use_tcp = False; + if (!interpret_string_addr(&addr, kdc_host, 0)) { + } + ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, NULL, credsp, &ap_req); if (ret) { @@ -422,7 +425,7 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, } else { - sock = open_socket_out(SOCK_STREAM, addr, DEFAULT_KPASSWD_PORT, + sock = open_socket_out(SOCK_STREAM, &addr, DEFAULT_KPASSWD_PORT, LONG_CONNECT_TIMEOUT); } @@ -430,18 +433,29 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, int rc = errno; SAFE_FREE(ap_req.data); krb5_auth_con_free(context, auth_context); - DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", + DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", kdc_host, strerror(errno))); return ADS_ERROR_SYSTEM(rc); } - addr_len = sizeof(remote_addr); getpeername(sock, &remote_addr, &addr_len); addr_len = sizeof(local_addr); getsockname(sock, &local_addr, &addr_len); - - setup_kaddr(&remote_kaddr, &remote_addr); - setup_kaddr(&local_kaddr, &local_addr); + + /* FIXME ! How do we do IPv6 here ? JRA. */ + if (remote_addr.sa_family != AF_INET || + local_addr.sa_family != AF_INET) { + DEBUG(1,("do_krb5_kpasswd_request: " + "no IPv6 support (yet).\n")); + close(sock); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + errno = EINVAL; + return ADS_ERROR_SYSTEM(EINVAL); + } + + setup_kaddr_v4(&remote_kaddr, &remote_addr); + setup_kaddr_v4(&local_kaddr, &local_addr); ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); if (ret) { -- cgit From 32dd016353355acfb71dd773187076f95ff6e86e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 29 Oct 2007 15:03:36 -0700 Subject: Fix the setup_kaddr() call to cope with IPv6. This is the last obvious change I can see. At this point we can start claiming IPv6 support (Hurrah !:-). Jeremy. (This used to be commit bda8c0bf571c994b524a9d67eebc422033d17094) --- source3/libads/krb5_setpw.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 831a448847..852251a476 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -401,7 +401,7 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, krb5_data ap_req, chpw_req, chpw_rep; int ret, sock; socklen_t addr_len; - struct sockaddr remote_addr, local_addr; + struct sockaddr_storage remote_addr, local_addr; struct sockaddr_storage addr; krb5_address local_kaddr, remote_kaddr; bool use_tcp = False; @@ -438,15 +438,14 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, return ADS_ERROR_SYSTEM(rc); } addr_len = sizeof(remote_addr); - getpeername(sock, &remote_addr, &addr_len); + getpeername(sock, (struct sockaddr *)&remote_addr, &addr_len); addr_len = sizeof(local_addr); - getsockname(sock, &local_addr, &addr_len); + getsockname(sock, (struct sockaddr *)&local_addr, &addr_len); - /* FIXME ! How do we do IPv6 here ? JRA. */ - if (remote_addr.sa_family != AF_INET || - local_addr.sa_family != AF_INET) { + if (!setup_kaddr(&remote_kaddr, &remote_addr) || + !setup_kaddr(&local_kaddr, &local_addr)) { DEBUG(1,("do_krb5_kpasswd_request: " - "no IPv6 support (yet).\n")); + "Failed to setup addresses.\n")); close(sock); SAFE_FREE(ap_req.data); krb5_auth_con_free(context, auth_context); @@ -454,9 +453,6 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, return ADS_ERROR_SYSTEM(EINVAL); } - setup_kaddr_v4(&remote_kaddr, &remote_addr); - setup_kaddr_v4(&local_kaddr, &local_addr); - ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL); if (ret) { close(sock); @@ -465,7 +461,7 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } - + ret = build_kpasswd_request(pversion, context, auth_context, &ap_req, princ, newpw, use_tcp, &chpw_req); if (ret) { -- cgit From e06aa46b9fab1e107fea8f6453fb13deffa91e96 Mon Sep 17 00:00:00 2001 From: Marc VanHeyningen Date: Fri, 14 Mar 2008 14:26:28 -0800 Subject: Coverity fixes (This used to be commit 3fc85d22590550f0539215d020e4411bf5b14363) --- source3/libads/krb5_setpw.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'source3/libads/krb5_setpw.c') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 852251a476..719f3bd3ec 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -438,10 +438,21 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, return ADS_ERROR_SYSTEM(rc); } addr_len = sizeof(remote_addr); - getpeername(sock, (struct sockaddr *)&remote_addr, &addr_len); + if (getpeername(sock, (struct sockaddr *)&remote_addr, &addr_len) != 0) { + close(sock); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("getpeername() failed (%s)\n", error_message(errno))); + return ADS_ERROR_SYSTEM(errno); + } addr_len = sizeof(local_addr); - getsockname(sock, (struct sockaddr *)&local_addr, &addr_len); - + if (getsockname(sock, (struct sockaddr *)&local_addr, &addr_len) != 0) { + close(sock); + SAFE_FREE(ap_req.data); + krb5_auth_con_free(context, auth_context); + DEBUG(1,("getsockname() failed (%s)\n", error_message(errno))); + return ADS_ERROR_SYSTEM(errno); + } if (!setup_kaddr(&remote_kaddr, &remote_addr) || !setup_kaddr(&local_kaddr, &local_addr)) { DEBUG(1,("do_krb5_kpasswd_request: " -- cgit