summaryrefslogtreecommitdiffstats
path: root/src/kadmin/server/schpw.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kadmin/server/schpw.c')
-rw-r--r--src/kadmin/server/schpw.c431
1 files changed, 216 insertions, 215 deletions
diff --git a/src/kadmin/server/schpw.c b/src/kadmin/server/schpw.c
index c3b7fa1e3e..c1b2217325 100644
--- a/src/kadmin/server/schpw.c
+++ b/src/kadmin/server/schpw.c
@@ -1,7 +1,8 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
#include "k5-int.h"
#include <kadm5/admin.h>
#include <syslog.h>
-#include <adm_proto.h> /* krb5_klog_syslog */
+#include <adm_proto.h> /* krb5_klog_syslog */
#include <stdio.h>
#include <errno.h>
@@ -11,19 +12,19 @@
#define GETSOCKNAME_ARG3_TYPE int
#endif
-#define RFC3244_VERSION 0xff80
+#define RFC3244_VERSION 0xff80
krb5_error_code
process_chpw_request(context, server_handle, realm, keytab,
- local_faddr, remote_faddr, req, rep)
- krb5_context context;
- void *server_handle;
- char *realm;
- krb5_keytab keytab;
- krb5_fulladdr *local_faddr;
- krb5_fulladdr *remote_faddr;
- krb5_data *req;
- krb5_data *rep;
+ local_faddr, remote_faddr, req, rep)
+ krb5_context context;
+ void *server_handle;
+ char *realm;
+ krb5_keytab keytab;
+ krb5_fulladdr *local_faddr;
+ krb5_fulladdr *remote_faddr;
+ krb5_data *req;
+ krb5_data *rep;
{
krb5_error_code ret;
char *ptr;
@@ -58,12 +59,12 @@ process_chpw_request(context, server_handle, realm, keytab,
cipher.length = 0;
if (req->length < 4) {
- /* either this, or the server is printing bad messages,
- or the caller passed in garbage */
- ret = KRB5KRB_AP_ERR_MODIFIED;
- numresult = KRB5_KPASSWD_MALFORMED;
- strlcpy(strresult, "Request was truncated", sizeof(strresult));
- goto chpwfail;
+ /* either this, or the server is printing bad messages,
+ or the caller passed in garbage */
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ numresult = KRB5_KPASSWD_MALFORMED;
+ strlcpy(strresult, "Request was truncated", sizeof(strresult));
+ goto chpwfail;
}
ptr = req->data;
@@ -74,7 +75,7 @@ process_chpw_request(context, server_handle, realm, keytab,
plen = (plen<<8) | (*ptr++ & 0xff);
if (plen != req->length)
- return(KRB5KRB_AP_ERR_MODIFIED);
+ return(KRB5KRB_AP_ERR_MODIFIED);
/* verify version number */
@@ -82,11 +83,11 @@ process_chpw_request(context, server_handle, realm, keytab,
vno = (vno<<8) | (*ptr++ & 0xff);
if (vno != 1 && vno != RFC3244_VERSION) {
- ret = KRB5KDC_ERR_BAD_PVNO;
- numresult = KRB5_KPASSWD_BAD_VERSION;
- snprintf(strresult, sizeof(strresult),
- "Request contained unknown protocol version number %d", vno);
- goto chpwfail;
+ ret = KRB5KDC_ERR_BAD_PVNO;
+ numresult = KRB5_KPASSWD_BAD_VERSION;
+ snprintf(strresult, sizeof(strresult),
+ "Request contained unknown protocol version number %d", vno);
+ goto chpwfail;
}
/* read, check ap-req length */
@@ -95,11 +96,11 @@ process_chpw_request(context, server_handle, realm, keytab,
ap_req.length = (ap_req.length<<8) | (*ptr++ & 0xff);
if (ptr + ap_req.length >= req->data + req->length) {
- ret = KRB5KRB_AP_ERR_MODIFIED;
- numresult = KRB5_KPASSWD_MALFORMED;
- strlcpy(strresult, "Request was truncated in AP-REQ",
- sizeof(strresult));
- goto chpwfail;
+ ret = KRB5KRB_AP_ERR_MODIFIED;
+ numresult = KRB5_KPASSWD_MALFORMED;
+ strlcpy(strresult, "Request was truncated in AP-REQ",
+ sizeof(strresult));
+ goto chpwfail;
}
/* verify ap_req */
@@ -109,38 +110,38 @@ process_chpw_request(context, server_handle, realm, keytab,
ret = krb5_auth_con_init(context, &auth_context);
if (ret) {
- numresult = KRB5_KPASSWD_HARDERROR;
- strlcpy(strresult, "Failed initializing auth context",
- sizeof(strresult));
- goto chpwfail;
+ numresult = KRB5_KPASSWD_HARDERROR;
+ strlcpy(strresult, "Failed initializing auth context",
+ sizeof(strresult));
+ goto chpwfail;
}
ret = krb5_auth_con_setflags(context, auth_context,
- KRB5_AUTH_CONTEXT_DO_SEQUENCE);
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE);
if (ret) {
- numresult = KRB5_KPASSWD_HARDERROR;
- strlcpy(strresult, "Failed initializing auth context",
- sizeof(strresult));
- goto chpwfail;
+ numresult = KRB5_KPASSWD_HARDERROR;
+ strlcpy(strresult, "Failed initializing auth context",
+ sizeof(strresult));
+ goto chpwfail;
}
-
+
ret = krb5_build_principal(context, &changepw, strlen(realm), realm,
- "kadmin", "changepw", NULL);
+ "kadmin", "changepw", NULL);
if (ret) {
- numresult = KRB5_KPASSWD_HARDERROR;
- strlcpy(strresult, "Failed building kadmin/changepw principal",
- sizeof(strresult));
- goto chpwfail;
+ numresult = KRB5_KPASSWD_HARDERROR;
+ strlcpy(strresult, "Failed building kadmin/changepw principal",
+ sizeof(strresult));
+ goto chpwfail;
}
ret = krb5_rd_req(context, &auth_context, &ap_req, changepw, keytab,
- NULL, &ticket);
+ NULL, &ticket);
if (ret) {
- numresult = KRB5_KPASSWD_AUTHERROR;
- strlcpy(strresult, "Failed reading application request",
- sizeof(strresult));
- goto chpwfail;
+ numresult = KRB5_KPASSWD_AUTHERROR;
+ strlcpy(strresult, "Failed reading application request",
+ sizeof(strresult));
+ goto chpwfail;
}
/* mk_priv requires that the local address be set.
@@ -158,22 +159,22 @@ process_chpw_request(context, server_handle, realm, keytab,
is specified. Are we having fun yet? */
ret = krb5_auth_con_setaddrs(context, auth_context, NULL,
- remote_faddr->address);
+ remote_faddr->address);
if (ret) {
- numresult = KRB5_KPASSWD_HARDERROR;
- strlcpy(strresult, "Failed storing client internet address",
- sizeof(strresult));
- goto chpwfail;
+ numresult = KRB5_KPASSWD_HARDERROR;
+ strlcpy(strresult, "Failed storing client internet address",
+ sizeof(strresult));
+ goto chpwfail;
}
/* construct the ap-rep */
ret = krb5_mk_rep(context, auth_context, &ap_rep);
if (ret) {
- numresult = KRB5_KPASSWD_AUTHERROR;
- strlcpy(strresult, "Failed replying to application request",
- sizeof(strresult));
- goto chpwfail;
+ numresult = KRB5_KPASSWD_AUTHERROR;
+ strlcpy(strresult, "Failed replying to application request",
+ sizeof(strresult));
+ goto chpwfail;
}
/* decrypt the ChangePasswdData */
@@ -183,57 +184,57 @@ process_chpw_request(context, server_handle, realm, keytab,
ret = krb5_rd_priv(context, auth_context, &cipher, &clear, &replay);
if (ret) {
- numresult = KRB5_KPASSWD_HARDERROR;
- strlcpy(strresult, "Failed decrypting request", sizeof(strresult));
- goto chpwfail;
+ numresult = KRB5_KPASSWD_HARDERROR;
+ strlcpy(strresult, "Failed decrypting request", sizeof(strresult));
+ goto chpwfail;
}
client = ticket->enc_part2->client;
/* decode ChangePasswdData for setpw requests */
if (vno == RFC3244_VERSION) {
- krb5_data *clear_data;
-
- ret = decode_krb5_setpw_req(&clear, &clear_data, &target);
- if (ret != 0) {
- numresult = KRB5_KPASSWD_MALFORMED;
- strlcpy(strresult, "Failed decoding ChangePasswdData",
- sizeof(strresult));
- goto chpwfail;
- }
-
- memset(clear.data, 0, clear.length);
- free(clear.data);
-
- clear = *clear_data;
- free(clear_data);
-
- if (target != NULL) {
- ret = krb5_unparse_name(context, target, &targetstr);
- if (ret != 0) {
- numresult = KRB5_KPASSWD_HARDERROR;
- strlcpy(strresult, "Failed unparsing target name for log",
- sizeof(strresult));
- goto chpwfail;
- }
- }
+ krb5_data *clear_data;
+
+ ret = decode_krb5_setpw_req(&clear, &clear_data, &target);
+ if (ret != 0) {
+ numresult = KRB5_KPASSWD_MALFORMED;
+ strlcpy(strresult, "Failed decoding ChangePasswdData",
+ sizeof(strresult));
+ goto chpwfail;
+ }
+
+ memset(clear.data, 0, clear.length);
+ free(clear.data);
+
+ clear = *clear_data;
+ free(clear_data);
+
+ if (target != NULL) {
+ ret = krb5_unparse_name(context, target, &targetstr);
+ if (ret != 0) {
+ numresult = KRB5_KPASSWD_HARDERROR;
+ strlcpy(strresult, "Failed unparsing target name for log",
+ sizeof(strresult));
+ goto chpwfail;
+ }
+ }
}
ret = krb5_unparse_name(context, client, &clientstr);
if (ret) {
- numresult = KRB5_KPASSWD_HARDERROR;
- strlcpy(strresult, "Failed unparsing client name for log",
- sizeof(strresult));
- goto chpwfail;
+ numresult = KRB5_KPASSWD_HARDERROR;
+ strlcpy(strresult, "Failed unparsing client name for log",
+ sizeof(strresult));
+ goto chpwfail;
}
/* for cpw, verify that this is an AS_REQ ticket */
if (vno == 1 &&
- (ticket->enc_part2->flags & TKT_FLG_INITIAL) == 0) {
- numresult = KRB5_KPASSWD_INITIAL_FLAG_NEEDED;
- strlcpy(strresult, "Ticket must be derived from a password",
- sizeof(strresult));
- goto chpwfail;
+ (ticket->enc_part2->flags & TKT_FLG_INITIAL) == 0) {
+ numresult = KRB5_KPASSWD_INITIAL_FLAG_NEEDED;
+ strlcpy(strresult, "Ticket must be derived from a password",
+ sizeof(strresult));
+ goto chpwfail;
}
/* change the password */
@@ -243,10 +244,10 @@ process_chpw_request(context, server_handle, realm, keytab,
ptr[clear.length] = '\0';
ret = schpw_util_wrapper(server_handle, client, target,
- (ticket->enc_part2->flags & TKT_FLG_INITIAL) != 0,
- ptr, NULL, strresult, sizeof(strresult));
+ (ticket->enc_part2->flags & TKT_FLG_INITIAL) != 0,
+ ptr, NULL, strresult, sizeof(strresult));
if (ret)
- errmsg = krb5_get_error_message(context, ret);
+ errmsg = krb5_get_error_message(context, ret);
/* zap the password */
memset(clear.data, 0, clear.length);
@@ -260,81 +261,81 @@ process_chpw_request(context, server_handle, realm, keytab,
switch (addr->addrtype) {
case ADDRTYPE_INET: {
- struct sockaddr_in *sin = ss2sin(&ss);
+ struct sockaddr_in *sin = ss2sin(&ss);
- sin->sin_family = AF_INET;
- memcpy(&sin->sin_addr, addr->contents, addr->length);
- sin->sin_port = htons(remote_faddr->port);
- salen = sizeof(*sin);
- break;
+ sin->sin_family = AF_INET;
+ memcpy(&sin->sin_addr, addr->contents, addr->length);
+ sin->sin_port = htons(remote_faddr->port);
+ salen = sizeof(*sin);
+ break;
}
case ADDRTYPE_INET6: {
- struct sockaddr_in6 *sin6 = ss2sin6(&ss);
+ struct sockaddr_in6 *sin6 = ss2sin6(&ss);
- sin6->sin6_family = AF_INET6;
- memcpy(&sin6->sin6_addr, addr->contents, addr->length);
- sin6->sin6_port = htons(remote_faddr->port);
- salen = sizeof(*sin6);
- break;
+ sin6->sin6_family = AF_INET6;
+ memcpy(&sin6->sin6_addr, addr->contents, addr->length);
+ sin6->sin6_port = htons(remote_faddr->port);
+ salen = sizeof(*sin6);
+ break;
}
default: {
- struct sockaddr *sa = ss2sa(&ss);
+ struct sockaddr *sa = ss2sa(&ss);
- sa->sa_family = AF_UNSPEC;
- salen = sizeof(*sa);
- break;
+ sa->sa_family = AF_UNSPEC;
+ salen = sizeof(*sa);
+ break;
}
}
if (getnameinfo(ss2sa(&ss), salen,
- addrbuf, sizeof(addrbuf), NULL, 0,
- NI_NUMERICHOST | NI_NUMERICSERV) != 0)
- strlcpy(addrbuf, "<unprintable>", sizeof(addrbuf));
+ addrbuf, sizeof(addrbuf), NULL, 0,
+ NI_NUMERICHOST | NI_NUMERICSERV) != 0)
+ strlcpy(addrbuf, "<unprintable>", sizeof(addrbuf));
if (vno == RFC3244_VERSION) {
- size_t tlen;
- char *tdots;
- const char *targetp;
-
- if (target == NULL) {
- tlen = clen;
- tdots = cdots;
- targetp = targetstr;
- } else {
- tlen = strlen(targetstr);
- trunc_name(&tlen, &tdots);
- targetp = clientstr;
- }
-
- krb5_klog_syslog(LOG_NOTICE, "setpw request from %s by %.*s%s for %.*s%s: %s",
- addrbuf,
- (int) clen, clientstr, cdots,
- (int) tlen, targetp, tdots,
- errmsg ? errmsg : "success");
+ size_t tlen;
+ char *tdots;
+ const char *targetp;
+
+ if (target == NULL) {
+ tlen = clen;
+ tdots = cdots;
+ targetp = targetstr;
+ } else {
+ tlen = strlen(targetstr);
+ trunc_name(&tlen, &tdots);
+ targetp = clientstr;
+ }
+
+ krb5_klog_syslog(LOG_NOTICE, "setpw request from %s by %.*s%s for %.*s%s: %s",
+ addrbuf,
+ (int) clen, clientstr, cdots,
+ (int) tlen, targetp, tdots,
+ errmsg ? errmsg : "success");
} else {
- krb5_klog_syslog(LOG_NOTICE, "chpw request from %s for %.*s%s: %s",
- addrbuf,
- (int) clen, clientstr, cdots,
- errmsg ? errmsg : "success");
+ krb5_klog_syslog(LOG_NOTICE, "chpw request from %s for %.*s%s: %s",
+ addrbuf,
+ (int) clen, clientstr, cdots,
+ errmsg ? errmsg : "success");
}
switch (ret) {
case KADM5_AUTH_CHANGEPW:
- numresult = KRB5_KPASSWD_ACCESSDENIED;
- break;
+ numresult = KRB5_KPASSWD_ACCESSDENIED;
+ break;
case KADM5_PASS_Q_TOOSHORT:
case KADM5_PASS_REUSE:
case KADM5_PASS_Q_CLASS:
case KADM5_PASS_Q_DICT:
case KADM5_PASS_TOOSOON:
- numresult = KRB5_KPASSWD_HARDERROR;
- break;
+ numresult = KRB5_KPASSWD_HARDERROR;
+ break;
case 0:
- numresult = KRB5_KPASSWD_SUCCESS;
- strlcpy(strresult, "", sizeof(strresult));
- break;
+ numresult = KRB5_KPASSWD_SUCCESS;
+ strlcpy(strresult, "", sizeof(strresult));
+ break;
default:
- numresult = KRB5_KPASSWD_SOFTERROR;
- break;
+ numresult = KRB5_KPASSWD_SOFTERROR;
+ break;
}
chpwfail:
@@ -352,66 +353,66 @@ chpwfail:
cipher.length = 0;
if (ap_rep.length) {
- ret = krb5_auth_con_setaddrs(context, auth_context,
- local_faddr->address, NULL);
- if (ret) {
- numresult = KRB5_KPASSWD_HARDERROR;
- strlcpy(strresult,
- "Failed storing client and server internet addresses",
- sizeof(strresult));
- } else {
- ret = krb5_mk_priv(context, auth_context, &clear, &cipher,
- &replay);
- if (ret) {
- numresult = KRB5_KPASSWD_HARDERROR;
- strlcpy(strresult, "Failed encrypting reply",
- sizeof(strresult));
- }
- }
+ ret = krb5_auth_con_setaddrs(context, auth_context,
+ local_faddr->address, NULL);
+ if (ret) {
+ numresult = KRB5_KPASSWD_HARDERROR;
+ strlcpy(strresult,
+ "Failed storing client and server internet addresses",
+ sizeof(strresult));
+ } else {
+ ret = krb5_mk_priv(context, auth_context, &clear, &cipher,
+ &replay);
+ if (ret) {
+ numresult = KRB5_KPASSWD_HARDERROR;
+ strlcpy(strresult, "Failed encrypting reply",
+ sizeof(strresult));
+ }
+ }
}
/* if no KRB-PRIV was constructed, then we need a KRB-ERROR.
if this fails, just bail. there's nothing else we can do. */
if (cipher.length == 0) {
- /* clear out ap_rep now, so that it won't be inserted in the
+ /* clear out ap_rep now, so that it won't be inserted in the
reply */
- if (ap_rep.length) {
- free(ap_rep.data);
- ap_rep.length = 0;
- }
-
- krberror.ctime = 0;
- krberror.cusec = 0;
- krberror.susec = 0;
- ret = krb5_timeofday(context, &krberror.stime);
- if (ret)
- goto bailout;
-
- /* this is really icky. but it's what all the other callers
- to mk_error do. */
- krberror.error = ret;
- krberror.error -= ERROR_TABLE_BASE_krb5;
- if (krberror.error < 0 || krberror.error > 128)
- krberror.error = KRB_ERR_GENERIC;
-
- krberror.client = NULL;
-
- ret = krb5_build_principal(context, &krberror.server,
- strlen(realm), realm,
- "kadmin", "changepw", NULL);
- if (ret)
- goto bailout;
- krberror.text.length = 0;
- krberror.e_data = clear;
-
- ret = krb5_mk_error(context, &krberror, &cipher);
-
- krb5_free_principal(context, krberror.server);
-
- if (ret)
- goto bailout;
+ if (ap_rep.length) {
+ free(ap_rep.data);
+ ap_rep.length = 0;
+ }
+
+ krberror.ctime = 0;
+ krberror.cusec = 0;
+ krberror.susec = 0;
+ ret = krb5_timeofday(context, &krberror.stime);
+ if (ret)
+ goto bailout;
+
+ /* this is really icky. but it's what all the other callers
+ to mk_error do. */
+ krberror.error = ret;
+ krberror.error -= ERROR_TABLE_BASE_krb5;
+ if (krberror.error < 0 || krberror.error > 128)
+ krberror.error = KRB_ERR_GENERIC;
+
+ krberror.client = NULL;
+
+ ret = krb5_build_principal(context, &krberror.server,
+ strlen(realm), realm,
+ "kadmin", "changepw", NULL);
+ if (ret)
+ goto bailout;
+ krberror.text.length = 0;
+ krberror.e_data = clear;
+
+ ret = krb5_mk_error(context, &krberror, &cipher);
+
+ krb5_free_principal(context, krberror.server);
+
+ if (ret)
+ goto bailout;
}
/* construct the reply */
@@ -419,9 +420,9 @@ chpwfail:
rep->length = 6 + ap_rep.length + cipher.length;
rep->data = (char *) malloc(rep->length);
if (rep->data == NULL) {
- rep->length = 0; /* checked by caller */
- ret = ENOMEM;
- goto bailout;
+ rep->length = 0; /* checked by caller */
+ ret = ENOMEM;
+ goto bailout;
}
ptr = rep->data;
@@ -443,8 +444,8 @@ chpwfail:
/* ap-rep data */
if (ap_rep.length) {
- memcpy(ptr, ap_rep.data, ap_rep.length);
- ptr += ap_rep.length;
+ memcpy(ptr, ap_rep.data, ap_rep.length);
+ ptr += ap_rep.length;
}
/* krb-priv or krb-error */
@@ -453,25 +454,25 @@ chpwfail:
bailout:
if (auth_context)
- krb5_auth_con_free(context, auth_context);
+ krb5_auth_con_free(context, auth_context);
if (changepw)
- krb5_free_principal(context, changepw);
+ krb5_free_principal(context, changepw);
if (ap_rep.length)
- free(ap_rep.data);
+ free(ap_rep.data);
if (ticket)
- krb5_free_ticket(context, ticket);
+ krb5_free_ticket(context, ticket);
if (clear.length)
- free(clear.data);
+ free(clear.data);
if (cipher.length)
- free(cipher.data);
+ free(cipher.data);
if (target)
- krb5_free_principal(context, target);
+ krb5_free_principal(context, target);
if (targetstr)
- krb5_free_unparsed_name(context, targetstr);
+ krb5_free_unparsed_name(context, targetstr);
if (clientstr)
- krb5_free_unparsed_name(context, clientstr);
+ krb5_free_unparsed_name(context, clientstr);
if (errmsg)
- krb5_free_error_message(context, errmsg);
+ krb5_free_error_message(context, errmsg);
return(ret);
}