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,
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 <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
+#include "smb_krb5.h"
#ifdef HAVE_KRB5
char* c;
char* princ;
- ASN1_DATA req;
+ ASN1_DATA *req;
DATA_BLOB ret;
realm = c;
} else {
/* We must have a realm component. */
- return data_blob(NULL, 0);
+ return data_blob_null;
}
- 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);
+ req = asn1_init(talloc_tos());
+ if (req == NULL) {
+ return data_blob_null;
+ }
+
+ 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(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(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_push_tag(req, ASN1_CONTEXT(1));
+ asn1_push_tag(req, ASN1_SEQUENCE(0));
if (princ_part1) {
- asn1_write_GeneralString(&req, 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);
- asn1_pop_tag(&req);
+ asn1_write_GeneralString(req, princ_part2);
+ 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);
+ 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);
+ ret = data_blob(req->data, req->length);
+ asn1_free(req);
free(princ);
krb5_data *ap_req,
const char *princ,
const char *passwd,
- BOOL use_tcp,
+ bool use_tcp,
krb5_data *packet)
{
krb5_error_code ret;
}
}
static krb5_error_code parse_setpw_reply(krb5_context context,
- BOOL use_tcp,
+ bool use_tcp,
krb5_auth_context auth_context,
krb5_data *packet)
{
return KRB5KRB_AP_ERR_MODIFIED;
}
- p = packet->data;
+ p = (char *)packet->data;
/*
** see if it is an error
*/
return KRB5KRB_AP_ERR_MODIFIED;
}
- p = clearresult.data;
+ p = (char *)clearresult.data;
res_code = RSVAL(p, 0);
krb5_data ap_req, chpw_req, chpw_rep;
int ret, sock;
socklen_t addr_len;
- struct sockaddr remote_addr, local_addr;
- struct in_addr *addr = interpret_addr2(kdc_host);
+ struct sockaddr_storage remote_addr, local_addr;
+ struct sockaddr_storage addr;
krb5_address local_kaddr, remote_kaddr;
- BOOL use_tcp = False;
+ 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) {
if (!use_tcp) {
sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT);
-
+ 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);
+ }
} else {
-
- sock = open_socket_out(SOCK_STREAM, addr, DEFAULT_KPASSWD_PORT,
- LONG_CONNECT_TIMEOUT);
+ NTSTATUS status;
+ status = open_socket_out(&addr, DEFAULT_KPASSWD_PORT,
+ LONG_CONNECT_TIMEOUT, &sock);
+ if (!NT_STATUS_IS_OK(status)) {
+ 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,
+ nt_errstr(status)));
+ return ADS_ERROR_NT(status);
+ }
}
- if (sock == -1) {
- int rc = errno;
+ addr_len = sizeof(remote_addr);
+ 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,("failed to open kpasswd socket to %s (%s)\n",
- kdc_host, strerror(errno)));
- return ADS_ERROR_SYSTEM(rc);
+ DEBUG(1,("getpeername() failed (%s)\n", error_message(errno)));
+ return ADS_ERROR_SYSTEM(errno);
}
-
- 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);
-
+ 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: "
+ "Failed to setup addresses.\n"));
+ close(sock);
+ SAFE_FREE(ap_req.data);
+ krb5_auth_con_free(context, auth_context);
+ errno = EINVAL;
+ return ADS_ERROR_SYSTEM(EINVAL);
+ }
+
ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL);
if (ret) {
close(sock);
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) {
}
realm++;
- asprintf(&princ_name, "kadmin/changepw@%s", realm);
+ if (asprintf(&princ_name, "kadmin/changepw@%s", realm) == -1) {
+ krb5_cc_close(context, ccache);
+ krb5_free_context(context);
+ DEBUG(1,("asprintf failed\n"));
+ return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+
ret = smb_krb5_parse_name(context, princ_name, &creds.server);
if (ret) {
krb5_cc_close(context, ccache);
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);
+ strncpy((char *)prompts[0].reply->data,
+ (const char *)data,
+ prompts[0].reply->length-1);
+ prompts[0].reply->length = strlen((const char *)prompts[0].reply->data);
} else {
prompts[0].reply->length = 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));
+ if (asprintf(&chpw_princ, "kadmin/changepw@%s",
+ (char *) krb5_princ_realm(context, princ)) == -1) {
+ krb5_free_context(context);
+ DEBUG(1,("ads_krb5_chg_password: asprintf fail\n"));
+ return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+
password = SMB_STRDUP(oldpw);
ret = krb5_get_init_creds_password(context, &creds, princ, password,
kerb_prompter, NULL,
as otherwise the server might end up setting the password for a user
instead
*/
- asprintf(&principal, "%s@%s", machine_account, ads->config.realm);
+ if (asprintf(&principal, "%s@%s", machine_account, ads->config.realm) < 0) {
+ return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
status = ads_krb5_set_password(ads->auth.kdc_server, principal,
password, ads->auth.time_offset);
- free(principal);
-
+ SAFE_FREE(principal);
return status;
}
-
-
-
#endif