import krb5-1.17-7.el8

This commit is contained in:
CentOS Sources 2019-07-26 14:51:04 -04:00 committed by Stepan Oksanichenko
commit 1abfed4787
36 changed files with 7398 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
SOURCES/krb5-1.17-pdfs.tar
SOURCES/krb5-1.17.tar.gz

2
.krb5.metadata Normal file
View File

@ -0,0 +1,2 @@
494c62bea08e5d26e01d47c409ac745b65e509c8 SOURCES/krb5-1.17-pdfs.tar
0c404b081db9c996c581f636ce450ee28778f338 SOURCES/krb5-1.17.tar.gz

View File

@ -0,0 +1,295 @@
From dd863eb4311310c23ee12961fa8e91703f29a6f5 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Thu, 22 Nov 2018 00:27:35 -0500
Subject: [PATCH] Add tests for KCM ccache type
Using a trivial Python implementation of a KCM server, run the
t_ccache.py tests against the KCM ccache type.
(cherry picked from commit f0bcb86131e385b2603ccf0f3c7d65aa3891b220)
(cherry picked from commit 5ecbe8d3ab4f53c0923a0442273bf18a9ff04fd5)
---
src/tests/kcmserver.py | 246 +++++++++++++++++++++++++++++++++++++++++
src/tests/t_ccache.py | 9 +-
2 files changed, 254 insertions(+), 1 deletion(-)
create mode 100644 src/tests/kcmserver.py
diff --git a/src/tests/kcmserver.py b/src/tests/kcmserver.py
new file mode 100644
index 000000000..57432e5a7
--- /dev/null
+++ b/src/tests/kcmserver.py
@@ -0,0 +1,246 @@
+# This is a simple KCM test server, used to exercise the KCM ccache
+# client code. It will generally throw an uncaught exception if the
+# client sends anything unexpected, so is unsuitable for production.
+# (It also imposes no namespace or access constraints, and blocks
+# while reading requests and writing responses.)
+
+# This code knows nothing about how to marshal and unmarshal principal
+# names and credentials as is required in the KCM protocol; instead,
+# it just remembers the marshalled forms and replays them to the
+# client when asked. This works because marshalled creds and
+# principal names are always the last part of marshalled request
+# arguments, and because we don't need to implement remove_cred (which
+# would need to know how to match a cred tag against previously stored
+# credentials).
+
+# The following code is useful for debugging if anything appears to be
+# going wrong in the server, since daemon output is generally not
+# visible in Python test scripts.
+#
+# import sys, traceback
+# def ehook(etype, value, tb):
+# with open('/tmp/exception', 'w') as f:
+# traceback.print_exception(etype, value, tb, file=f)
+# sys.excepthook = ehook
+
+import select
+import socket
+import struct
+import sys
+
+caches = {}
+cache_uuidmap = {}
+defname = b'default'
+next_unique = 1
+next_uuid = 1
+
+class KCMOpcodes(object):
+ GEN_NEW = 3
+ INITIALIZE = 4
+ DESTROY = 5
+ STORE = 6
+ GET_PRINCIPAL = 8
+ GET_CRED_UUID_LIST = 9
+ GET_CRED_BY_UUID = 10
+ REMOVE_CRED = 11
+ GET_CACHE_UUID_LIST = 18
+ GET_CACHE_BY_UUID = 19
+ GET_DEFAULT_CACHE = 20
+ SET_DEFAULT_CACHE = 21
+ GET_KDC_OFFSET = 22
+ SET_KDC_OFFSET = 23
+
+
+class KRB5Errors(object):
+ KRB5_CC_END = -1765328242
+ KRB5_CC_NOSUPP = -1765328137
+ KRB5_FCC_NOFILE = -1765328189
+
+
+def make_uuid():
+ global next_uuid
+ uuid = bytes(12) + struct.pack('>L', next_uuid)
+ next_uuid = next_uuid + 1
+ return uuid
+
+
+class Cache(object):
+ def __init__(self, name):
+ self.name = name
+ self.princ = None
+ self.uuid = make_uuid()
+ self.cred_uuids = []
+ self.creds = {}
+ self.time_offset = 0
+
+
+def get_cache(name):
+ if name in caches:
+ return caches[name]
+ cache = Cache(name)
+ caches[name] = cache
+ cache_uuidmap[cache.uuid] = cache
+ return cache
+
+
+def unmarshal_name(argbytes):
+ offset = argbytes.find(b'\0')
+ return argbytes[0:offset], argbytes[offset+1:]
+
+
+def op_gen_new(argbytes):
+ # Does not actually check for uniqueness.
+ global next_unique
+ name = b'unique' + str(next_unique).encode('ascii')
+ next_unique += 1
+ return 0, name + b'\0'
+
+
+def op_initialize(argbytes):
+ name, princ = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ cache.princ = princ
+ cache.cred_uuids = []
+ cache.creds = {}
+ cache.time_offset = 0
+ return 0, b''
+
+
+def op_destroy(argbytes):
+ name, rest = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ del cache_uuidmap[cache.uuid]
+ del caches[name]
+ return 0, b''
+
+
+def op_store(argbytes):
+ name, cred = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ uuid = make_uuid()
+ cache.creds[uuid] = cred
+ cache.cred_uuids.append(uuid)
+ return 0, b''
+
+
+def op_get_principal(argbytes):
+ name, rest = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ if cache.princ is None:
+ return KRB5Errors.KRB5_FCC_NOFILE, b''
+ return 0, cache.princ + b'\0'
+
+
+def op_get_cred_uuid_list(argbytes):
+ name, rest = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ return 0, b''.join(cache.cred_uuids)
+
+
+def op_get_cred_by_uuid(argbytes):
+ name, uuid = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ if uuid not in cache.creds:
+ return KRB5Errors.KRB5_CC_END, b''
+ return 0, cache.creds[uuid]
+
+
+def op_remove_cred(argbytes):
+ return KRB5Errors.KRB5_CC_NOSUPP, b''
+
+
+def op_get_cache_uuid_list(argbytes):
+ return 0, b''.join(cache_uuidmap.keys())
+
+
+def op_get_cache_by_uuid(argbytes):
+ uuid = argbytes
+ if uuid not in cache_uuidmap:
+ return KRB5Errors.KRB5_CC_END, b''
+ return 0, cache_uuidmap[uuid].name + b'\0'
+
+
+def op_get_default_cache(argbytes):
+ return 0, defname + b'\0'
+
+
+def op_set_default_cache(argbytes):
+ global defname
+ defname, rest = unmarshal_name(argbytes)
+ return 0, b''
+
+
+def op_get_kdc_offset(argbytes):
+ name, rest = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ return 0, struct.pack('>l', cache.time_offset)
+
+
+def op_set_kdc_offset(argbytes):
+ name, obytes = unmarshal_name(argbytes)
+ cache = get_cache(name)
+ cache.time_offset, = struct.unpack('>l', obytes)
+ return 0, b''
+
+
+ophandlers = {
+ KCMOpcodes.GEN_NEW : op_gen_new,
+ KCMOpcodes.INITIALIZE : op_initialize,
+ KCMOpcodes.DESTROY : op_destroy,
+ KCMOpcodes.STORE : op_store,
+ KCMOpcodes.GET_PRINCIPAL : op_get_principal,
+ KCMOpcodes.GET_CRED_UUID_LIST : op_get_cred_uuid_list,
+ KCMOpcodes.GET_CRED_BY_UUID : op_get_cred_by_uuid,
+ KCMOpcodes.REMOVE_CRED : op_remove_cred,
+ KCMOpcodes.GET_CACHE_UUID_LIST : op_get_cache_uuid_list,
+ KCMOpcodes.GET_CACHE_BY_UUID : op_get_cache_by_uuid,
+ KCMOpcodes.GET_DEFAULT_CACHE : op_get_default_cache,
+ KCMOpcodes.SET_DEFAULT_CACHE : op_set_default_cache,
+ KCMOpcodes.GET_KDC_OFFSET : op_get_kdc_offset,
+ KCMOpcodes.SET_KDC_OFFSET : op_set_kdc_offset
+}
+
+# Read and respond to a request from the socket s.
+def service_request(s):
+ lenbytes = b''
+ while len(lenbytes) < 4:
+ lenbytes += s.recv(4 - len(lenbytes))
+ if lenbytes == b'':
+ return False
+
+ reqlen, = struct.unpack('>L', lenbytes)
+ req = b''
+ while len(req) < reqlen:
+ req += s.recv(reqlen - len(req))
+
+ majver, minver, op = struct.unpack('>BBH', req[:4])
+ argbytes = req[4:]
+ code, payload = ophandlers[op](argbytes)
+
+ # The KCM response is the code (4 bytes) and the response payload.
+ # The Heimdal IPC response is the length of the KCM response (4
+ # bytes), a status code which is essentially always 0 (4 bytes),
+ # and the KCM response.
+ kcm_response = struct.pack('>l', code) + payload
+ hipc_response = struct.pack('>LL', len(kcm_response), 0) + kcm_response
+ s.sendall(hipc_response)
+ return True
+
+
+server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+server.bind(sys.argv[1])
+server.listen(5)
+select_input = [server,]
+sys.stderr.write('starting...\n')
+sys.stderr.flush()
+
+while True:
+ iready, oready, xready = select.select(select_input, [], [])
+ for s in iready:
+ if s == server:
+ client, addr = server.accept()
+ select_input.append(client)
+ else:
+ if not service_request(s):
+ select_input.remove(s)
+ s.close()
diff --git a/src/tests/t_ccache.py b/src/tests/t_ccache.py
index fcf1a611e..66804afa5 100755
--- a/src/tests/t_ccache.py
+++ b/src/tests/t_ccache.py
@@ -22,7 +22,10 @@
from k5test import *
-realm = K5Realm(create_host=False)
+kcm_socket_path = os.path.join(os.getcwd(), 'testdir', 'kcm')
+conf = {'libdefaults': {'kcm_socket': kcm_socket_path,
+ 'kcm_mach_service': '-'}}
+realm = K5Realm(create_host=False, krb5_conf=conf)
keyctl = which('keyctl')
out = realm.run([klist, '-c', 'KEYRING:process:abcd'], expected_code=1)
@@ -122,6 +125,10 @@ def collection_test(realm, ccname):
collection_test(realm, 'DIR:' + os.path.join(realm.testdir, 'cc'))
+kcmserver_path = os.path.join(srctop, 'tests', 'kcmserver.py')
+realm.start_server([sys.executable, kcmserver_path, kcm_socket_path],
+ 'starting...')
+collection_test(realm, 'KCM:')
if test_keyring:
def cleanup_keyring(anchor, name):
out = realm.run(['keyctl', 'list', anchor])

View File

@ -0,0 +1,95 @@
From 54348bbfaec50bb72d1625c015f8e5c4cfa59e0d Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sun, 30 Dec 2018 16:40:28 -0500
Subject: [PATCH] Address some optimized-out memset() calls
Ilja Van Sprundel reported a list of memset() calls which gcc
optimizes out. In krb_auth_su.c, use zap() to clear the password, and
remove two memset() calls when there is no password to clear. In
iakerb.c, remove an unnecessary memset() before setting the only two
fields of the IAKERB header structure. In svr_principal.c, use
krb5_free_key_keyblock_contents() instead of hand-freeing key data.
In asn1_k_encode.c, remove an unnecessary memset() of the kdc_req_hack
shell before returning.
(cherry picked from commit 1057b0befec1f1c0e9d4da5521a58496e2dc0997)
(cherry picked from commit 1dfff7202448a950c9133cdfe43d650092d930fd)
---
src/clients/ksu/krb_auth_su.c | 4 +---
src/lib/gssapi/krb5/iakerb.c | 1 -
src/lib/kadm5/srv/svr_principal.c | 10 ++--------
src/lib/krb5/asn.1/asn1_k_encode.c | 1 -
4 files changed, 3 insertions(+), 13 deletions(-)
diff --git a/src/clients/ksu/krb_auth_su.c b/src/clients/ksu/krb_auth_su.c
index 7af48195c..e39685fff 100644
--- a/src/clients/ksu/krb_auth_su.c
+++ b/src/clients/ksu/krb_auth_su.c
@@ -183,21 +183,19 @@ krb5_boolean ksu_get_tgt_via_passwd(context, client, options, zero_password,
if (code ) {
com_err(prog_name, code, _("while reading password for '%s'\n"),
client_name);
- memset(password, 0, sizeof(password));
return (FALSE);
}
if ( pwsize == 0) {
fprintf(stderr, _("No password given\n"));
*zero_password = TRUE;
- memset(password, 0, sizeof(password));
return (FALSE);
}
code = krb5_get_init_creds_password(context, &creds, client, password,
krb5_prompter_posix, NULL, 0, NULL,
options);
- memset(password, 0, sizeof(password));
+ zap(password, sizeof(password));
if (code) {
diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c
index bb1072fe4..47c161ec9 100644
--- a/src/lib/gssapi/krb5/iakerb.c
+++ b/src/lib/gssapi/krb5/iakerb.c
@@ -262,7 +262,6 @@ iakerb_make_token(iakerb_ctx_id_t ctx,
/*
* Assemble the IAKERB-HEADER from the realm and cookie
*/
- memset(&iah, 0, sizeof(iah));
iah.target_realm = *realm;
iah.cookie = cookie;
diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c
index 21c53ece1..9ab2c5a74 100644
--- a/src/lib/kadm5/srv/svr_principal.c
+++ b/src/lib/kadm5/srv/svr_principal.c
@@ -2093,14 +2093,8 @@ static int decrypt_key_data(krb5_context context,
ret = krb5_dbe_decrypt_key_data(context, NULL, &key_data[i], &keys[i],
NULL);
if (ret) {
- for (; i >= 0; i--) {
- if (keys[i].contents) {
- memset (keys[i].contents, 0, keys[i].length);
- free( keys[i].contents );
- }
- }
-
- memset(keys, 0, n_key_data*sizeof(krb5_keyblock));
+ for (; i >= 0; i--)
+ krb5_free_keyblock_contents(context, &keys[i]);
free(keys);
return ret;
}
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
index 65c84be2f..81a34bac9 100644
--- a/src/lib/krb5/asn.1/asn1_k_encode.c
+++ b/src/lib/krb5/asn.1/asn1_k_encode.c
@@ -528,7 +528,6 @@ decode_kdc_req_body(const taginfo *t, const uint8_t *asn1, size_t len,
if (ret) {
free_kdc_req_body(b);
free(h.server_realm.data);
- memset(&h, 0, sizeof(h));
return ret;
}
b->server->realm = h.server_realm;

View File

@ -0,0 +1,183 @@
From 0c361343839b2ff6f89f1ee9c1e01d4f05ab6ffe Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Fri, 9 Nov 2018 15:12:21 -0500
Subject: [PATCH] Become FIPS-aware (with 3DES)
A lot of the FIPS error conditions from OpenSSL are incredibly
mysterious (at best, things return NULL unexpectedly; at worst,
internal assertions are tripped; most of the time, you just get
ENOMEM). In order to cope with this, we need to have some level of
awareness of what we can and can't safely call.
This will slow down some calls slightly (FIPS_mode() takes multiple
locks), but not for any crypto we care about - which is to say that
AES is fine.
(cherry picked from commit 9f5fbf191d74cae9b28d318fff4c80d3d3e49c86)
---
src/lib/crypto/openssl/enc_provider/camellia.c | 6 ++++++
src/lib/crypto/openssl/enc_provider/des.c | 9 +++++++++
src/lib/crypto/openssl/enc_provider/des3.c | 6 ++++++
src/lib/crypto/openssl/enc_provider/rc4.c | 13 ++++++++++++-
src/lib/crypto/openssl/hash_provider/hash_evp.c | 4 ++++
src/lib/crypto/openssl/hmac.c | 6 +++++-
6 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c
index 2da691329..f79679a0b 100644
--- a/src/lib/crypto/openssl/enc_provider/camellia.c
+++ b/src/lib/crypto/openssl/enc_provider/camellia.c
@@ -304,6 +304,9 @@ krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
unsigned char blockY[CAMELLIA_BLOCK_SIZE], blockB[CAMELLIA_BLOCK_SIZE];
struct iov_cursor cursor;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
if (output->length < CAMELLIA_BLOCK_SIZE)
return KRB5_BAD_MSIZE;
@@ -331,6 +334,9 @@ static krb5_error_code
krb5int_camellia_init_state (const krb5_keyblock *key, krb5_keyusage usage,
krb5_data *state)
{
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
state->length = 16;
state->data = (void *) malloc(16);
if (state->data == NULL)
diff --git a/src/lib/crypto/openssl/enc_provider/des.c b/src/lib/crypto/openssl/enc_provider/des.c
index a662db512..7d17d287e 100644
--- a/src/lib/crypto/openssl/enc_provider/des.c
+++ b/src/lib/crypto/openssl/enc_provider/des.c
@@ -85,6 +85,9 @@ k5_des_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
@@ -133,6 +136,9 @@ k5_des_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
@@ -182,6 +188,9 @@ k5_des_cbc_mac(krb5_key key, const krb5_crypto_iov *data, size_t num_data,
DES_key_schedule sched;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0)
return ret;
diff --git a/src/lib/crypto/openssl/enc_provider/des3.c b/src/lib/crypto/openssl/enc_provider/des3.c
index 1c439c2cd..8be555a8d 100644
--- a/src/lib/crypto/openssl/enc_provider/des3.c
+++ b/src/lib/crypto/openssl/enc_provider/des3.c
@@ -84,6 +84,9 @@ k5_des3_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
@@ -133,6 +136,9 @@ k5_des3_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx;
krb5_boolean empty;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
ret = validate(key, ivec, data, num_data, &empty);
if (ret != 0 || empty)
return ret;
diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c
index 7f3c086ed..a3f2a7442 100644
--- a/src/lib/crypto/openssl/enc_provider/rc4.c
+++ b/src/lib/crypto/openssl/enc_provider/rc4.c
@@ -66,6 +66,9 @@ k5_arcfour_docrypt(krb5_key key,const krb5_data *state, krb5_crypto_iov *data,
EVP_CIPHER_CTX *ctx = NULL;
struct arcfour_state *arcstate;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
arcstate = (state != NULL) ? (struct arcfour_state *) state->data : NULL;
if (arcstate != NULL) {
ctx = arcstate->ctx;
@@ -113,7 +116,12 @@ k5_arcfour_docrypt(krb5_key key,const krb5_data *state, krb5_crypto_iov *data,
static void
k5_arcfour_free_state(krb5_data *state)
{
- struct arcfour_state *arcstate = (struct arcfour_state *) state->data;
+ struct arcfour_state *arcstate;
+
+ if (FIPS_mode())
+ return;
+
+ arcstate = (struct arcfour_state *) state->data;
EVP_CIPHER_CTX_free(arcstate->ctx);
free(arcstate);
@@ -125,6 +133,9 @@ k5_arcfour_init_state(const krb5_keyblock *key,
{
struct arcfour_state *arcstate;
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
+
/* Create a state structure with an uninitialized context. */
arcstate = calloc(1, sizeof(*arcstate));
if (arcstate == NULL)
diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
index 957ed8d9c..8c1fd7f59 100644
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
@@ -64,12 +64,16 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
static krb5_error_code
hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
{
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
return hash_evp(EVP_md4(), data, num_data, output);
}
static krb5_error_code
hash_md5(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
{
+ if (FIPS_mode())
+ return KRB5_CRYPTO_INTERNAL;
return hash_evp(EVP_md5(), data, num_data, output);
}
diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
index b2db6ec02..d94d9ac94 100644
--- a/src/lib/crypto/openssl/hmac.c
+++ b/src/lib/crypto/openssl/hmac.c
@@ -103,7 +103,11 @@ map_digest(const struct krb5_hash_provider *hash)
return EVP_sha256();
else if (!strncmp(hash->hash_name, "SHA-384",7))
return EVP_sha384();
- else if (!strncmp(hash->hash_name, "MD5", 3))
+
+ if (FIPS_mode())
+ return NULL;
+
+ if (!strncmp(hash->hash_name, "MD5", 3))
return EVP_md5();
else if (!strncmp(hash->hash_name, "MD4", 3))
return EVP_md4();

View File

@ -0,0 +1,43 @@
From 5b4467a2c47e6de814e69ec3eb4c3e7a4632119c Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Mon, 1 Apr 2019 13:13:09 -0400
Subject: [PATCH] FIPS-aware SPAKE group negotiation
(cherry picked from commit 59269fca96168aa89dc32834d188a54eea8953ac)
---
src/plugins/preauth/spake/groups.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/plugins/preauth/spake/groups.c b/src/plugins/preauth/spake/groups.c
index a195cc195..8a913cb5a 100644
--- a/src/plugins/preauth/spake/groups.c
+++ b/src/plugins/preauth/spake/groups.c
@@ -56,6 +56,8 @@
#include "trace.h"
#include "groups.h"
+#include <openssl/crypto.h>
+
#define DEFAULT_GROUPS_CLIENT "edwards25519"
#define DEFAULT_GROUPS_KDC ""
@@ -102,6 +104,9 @@ find_gdef(int32_t group)
{
size_t i;
+ if (group == builtin_edwards25519.reg->id && FIPS_mode())
+ return NULL;
+
for (i = 0; groupdefs[i] != NULL; i++) {
if (groupdefs[i]->reg->id == group)
return groupdefs[i];
@@ -116,6 +121,9 @@ find_gnum(const char *name)
{
size_t i;
+ if (strcasecmp(name, builtin_edwards25519.reg->name) == 0 && FIPS_mode())
+ return 0;
+
for (i = 0; groupdefs[i] != NULL; i++) {
if (strcasecmp(name, groupdefs[i]->reg->name) == 0)
return groupdefs[i]->reg->id;

View File

@ -0,0 +1,34 @@
From a904a5b85e8425823016b821153b37396edc2306 Mon Sep 17 00:00:00 2001
From: Corene Casper <C.Casper@Dell.com>
Date: Sat, 16 Feb 2019 00:49:26 -0500
Subject: [PATCH] Fix memory leak in 'none' replay cache type
Commit 0f06098e2ab419d02e89a1ca6bc9f2828f6bdb1e fixed part of a memory
leak in the 'none' replay cache type by freeing the outer container,
but we also need to free the mutex.
[ghudson@mit.edu: wrote commit message]
ticket: 8783
tags: pullup
target_version: 1.17-next
target_version: 1.16-next
(cherry picked from commit af2a3115cb8feb5174151b4b40223ae45aa9db17)
(cherry picked from commit ff79351c4755d6df7c3245274708454311c25731)
---
src/lib/krb5/rcache/rc_none.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lib/krb5/rcache/rc_none.c b/src/lib/krb5/rcache/rc_none.c
index e30aed09f..0b2274df7 100644
--- a/src/lib/krb5/rcache/rc_none.c
+++ b/src/lib/krb5/rcache/rc_none.c
@@ -50,6 +50,7 @@ krb5_rc_none_noargs(krb5_context ctx, krb5_rcache rc)
static krb5_error_code KRB5_CALLCONV
krb5_rc_none_close(krb5_context ctx, krb5_rcache rc)
{
+ k5_mutex_destroy(&rc->lock);
free (rc);
return 0;
}

View File

@ -0,0 +1,354 @@
From 088fd5a56e030739a31a43aee7335bc661a92b1c Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 31 Jul 2018 13:47:26 -0400
Subject: [PATCH] In FIPS mode, add plaintext fallback for RC4 usages and taint
(cherry picked from commit a327e3bf5b992ac829c7b2d3317fb7d93b1c88ef)
(cherry picked from commit 2bd85da058d2d73eb2818a8e64656fec9b21b3c3)
---
src/lib/krad/attr.c | 45 +++++++++++++++++++++++++++++-----------
src/lib/krad/attrset.c | 5 +++--
src/lib/krad/internal.h | 13 ++++++++++--
src/lib/krad/packet.c | 22 +++++++++++---------
src/lib/krad/remote.c | 10 +++++++--
src/lib/krad/t_attr.c | 3 ++-
src/lib/krad/t_attrset.c | 4 +++-
7 files changed, 72 insertions(+), 30 deletions(-)
diff --git a/src/lib/krad/attr.c b/src/lib/krad/attr.c
index 9c13d9d75..275327e67 100644
--- a/src/lib/krad/attr.c
+++ b/src/lib/krad/attr.c
@@ -30,6 +30,7 @@
#include <k5-int.h>
#include "internal.h"
+#include <openssl/crypto.h>
#include <string.h>
/* RFC 2865 */
@@ -38,7 +39,8 @@
typedef krb5_error_code
(*attribute_transform_fn)(krb5_context ctx, const char *secret,
const unsigned char *auth, const krb5_data *in,
- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen);
+ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen,
+ krb5_boolean *is_fips);
typedef struct {
const char *name;
@@ -51,12 +53,14 @@ typedef struct {
static krb5_error_code
user_password_encode(krb5_context ctx, const char *secret,
const unsigned char *auth, const krb5_data *in,
- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen);
+ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen,
+ krb5_boolean *is_fips);
static krb5_error_code
user_password_decode(krb5_context ctx, const char *secret,
const unsigned char *auth, const krb5_data *in,
- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen);
+ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen,
+ krb5_boolean *ignored);
static const attribute_record attributes[UCHAR_MAX] = {
{"User-Name", 1, MAX_ATTRSIZE, NULL, NULL},
@@ -128,7 +132,8 @@ static const attribute_record attributes[UCHAR_MAX] = {
static krb5_error_code
user_password_encode(krb5_context ctx, const char *secret,
const unsigned char *auth, const krb5_data *in,
- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen)
+ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen,
+ krb5_boolean *is_fips)
{
const unsigned char *indx;
krb5_error_code retval;
@@ -154,8 +159,14 @@ user_password_encode(krb5_context ctx, const char *secret,
for (blck = 0, indx = auth; blck * BLOCKSIZE < len; blck++) {
memcpy(tmp.data + seclen, indx, BLOCKSIZE);
- retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &tmp,
- &sum);
+ if (FIPS_mode()) {
+ /* Skip encryption here. Taint so that we won't pass it out of
+ * the machine by accident. */
+ *is_fips = TRUE;
+ sum.contents = calloc(1, BLOCKSIZE);
+ } else
+ retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &tmp,
+ &sum);
if (retval != 0) {
zap(tmp.data, tmp.length);
zap(outbuf, len);
@@ -180,7 +191,8 @@ user_password_encode(krb5_context ctx, const char *secret,
static krb5_error_code
user_password_decode(krb5_context ctx, const char *secret,
const unsigned char *auth, const krb5_data *in,
- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen)
+ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen,
+ krb5_boolean *is_fips)
{
const unsigned char *indx;
krb5_error_code retval;
@@ -204,8 +216,14 @@ user_password_decode(krb5_context ctx, const char *secret,
for (blck = 0, indx = auth; blck * BLOCKSIZE < in->length; blck++) {
memcpy(tmp.data + seclen, indx, BLOCKSIZE);
- retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0,
- &tmp, &sum);
+ if (FIPS_mode()) {
+ /* Skip encryption here. Taint so that we won't pass it out of
+ * the machine by accident. */
+ *is_fips = TRUE;
+ sum.contents = calloc(1, BLOCKSIZE);
+ } else
+ retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0,
+ &tmp, &sum);
if (retval != 0) {
zap(tmp.data, tmp.length);
zap(outbuf, in->length);
@@ -248,7 +266,7 @@ krb5_error_code
kr_attr_encode(krb5_context ctx, const char *secret,
const unsigned char *auth, krad_attr type,
const krb5_data *in, unsigned char outbuf[MAX_ATTRSIZE],
- size_t *outlen)
+ size_t *outlen, krb5_boolean *is_fips)
{
krb5_error_code retval;
@@ -265,7 +283,8 @@ kr_attr_encode(krb5_context ctx, const char *secret,
return 0;
}
- return attributes[type - 1].encode(ctx, secret, auth, in, outbuf, outlen);
+ return attributes[type - 1].encode(ctx, secret, auth, in, outbuf, outlen,
+ is_fips);
}
krb5_error_code
@@ -274,6 +293,7 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen)
{
krb5_error_code retval;
+ krb5_boolean ignored;
retval = kr_attr_valid(type, in);
if (retval != 0)
@@ -288,7 +308,8 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
return 0;
}
- return attributes[type - 1].decode(ctx, secret, auth, in, outbuf, outlen);
+ return attributes[type - 1].decode(ctx, secret, auth, in, outbuf, outlen,
+ &ignored);
}
krad_attr
diff --git a/src/lib/krad/attrset.c b/src/lib/krad/attrset.c
index 03c613716..d89982a13 100644
--- a/src/lib/krad/attrset.c
+++ b/src/lib/krad/attrset.c
@@ -167,7 +167,8 @@ krad_attrset_copy(const krad_attrset *set, krad_attrset **copy)
krb5_error_code
kr_attrset_encode(const krad_attrset *set, const char *secret,
const unsigned char *auth,
- unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen)
+ unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen,
+ krb5_boolean *is_fips)
{
unsigned char buffer[MAX_ATTRSIZE];
krb5_error_code retval;
@@ -181,7 +182,7 @@ kr_attrset_encode(const krad_attrset *set, const char *secret,
K5_TAILQ_FOREACH(a, &set->list, list) {
retval = kr_attr_encode(set->ctx, secret, auth, a->type, &a->attr,
- buffer, &attrlen);
+ buffer, &attrlen, is_fips);
if (retval != 0)
return retval;
diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h
index 996a89372..a53ce31ce 100644
--- a/src/lib/krad/internal.h
+++ b/src/lib/krad/internal.h
@@ -49,6 +49,13 @@
typedef struct krad_remote_st krad_remote;
+struct krad_packet_st {
+ char buffer[KRAD_PACKET_SIZE_MAX];
+ krad_attrset *attrset;
+ krb5_data pkt;
+ krb5_boolean is_fips;
+};
+
/* Validate constraints of an attribute. */
krb5_error_code
kr_attr_valid(krad_attr type, const krb5_data *data);
@@ -57,7 +64,8 @@ kr_attr_valid(krad_attr type, const krb5_data *data);
krb5_error_code
kr_attr_encode(krb5_context ctx, const char *secret, const unsigned char *auth,
krad_attr type, const krb5_data *in,
- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen);
+ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen,
+ krb5_boolean *is_fips);
/* Decode an attribute. */
krb5_error_code
@@ -69,7 +77,8 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
krb5_error_code
kr_attrset_encode(const krad_attrset *set, const char *secret,
const unsigned char *auth,
- unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen);
+ unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen,
+ krb5_boolean *is_fips);
/* Decode attributes from a buffer. */
krb5_error_code
diff --git a/src/lib/krad/packet.c b/src/lib/krad/packet.c
index c597174b6..794ac84c4 100644
--- a/src/lib/krad/packet.c
+++ b/src/lib/krad/packet.c
@@ -32,6 +32,7 @@
#include <string.h>
#include <arpa/inet.h>
+#include <openssl/crypto.h>
typedef unsigned char uchar;
@@ -53,12 +54,6 @@ typedef unsigned char uchar;
#define pkt_auth(p) ((uchar *)offset(&(p)->pkt, OFFSET_AUTH))
#define pkt_attr(p) ((unsigned char *)offset(&(p)->pkt, OFFSET_ATTR))
-struct krad_packet_st {
- char buffer[KRAD_PACKET_SIZE_MAX];
- krad_attrset *attrset;
- krb5_data pkt;
-};
-
typedef struct {
uchar x[(UCHAR_MAX + 1) / 8];
} idmap;
@@ -187,8 +182,13 @@ auth_generate_response(krb5_context ctx, const char *secret,
memcpy(data.data + response->pkt.length, secret, strlen(secret));
/* Hash it. */
- retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &data,
- &hash);
+ if (FIPS_mode()) {
+ /* This checksum does very little security-wise anyway, so don't
+ * taint. */
+ hash.contents = calloc(1, AUTH_FIELD_SIZE);
+ } else
+ retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &data,
+ &hash);
free(data.data);
if (retval != 0)
return retval;
@@ -276,7 +276,7 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
/* Encode the attributes. */
retval = kr_attrset_encode(set, secret, pkt_auth(pkt), pkt_attr(pkt),
- &attrset_len);
+ &attrset_len, &pkt->is_fips);
if (retval != 0)
goto error;
@@ -314,7 +314,7 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
/* Encode the attributes. */
retval = kr_attrset_encode(set, secret, pkt_auth(request), pkt_attr(pkt),
- &attrset_len);
+ &attrset_len, &pkt->is_fips);
if (retval != 0)
goto error;
@@ -451,6 +451,8 @@ krad_packet_decode_response(krb5_context ctx, const char *secret,
const krb5_data *
krad_packet_encode(const krad_packet *pkt)
{
+ if (pkt->is_fips)
+ return NULL;
return &pkt->pkt;
}
diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c
index 437f7e91a..0f90443ce 100644
--- a/src/lib/krad/remote.c
+++ b/src/lib/krad/remote.c
@@ -263,7 +263,7 @@ on_io_write(krad_remote *rr)
request *r;
K5_TAILQ_FOREACH(r, &rr->list, list) {
- tmp = krad_packet_encode(r->request);
+ tmp = &r->request->pkt;
/* If the packet has already been sent, do nothing. */
if (r->sent == tmp->length)
@@ -359,7 +359,7 @@ on_io_read(krad_remote *rr)
if (req != NULL) {
K5_TAILQ_FOREACH(r, &rr->list, list) {
if (r->request == req &&
- r->sent == krad_packet_encode(req)->length) {
+ r->sent == req->pkt.length) {
request_finish(r, 0, rsp);
break;
}
@@ -455,6 +455,12 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs,
(krad_packet_iter_cb)iterator, &r, &tmp);
if (retval != 0)
goto error;
+ else if (tmp->is_fips && rr->info->ai_family != AF_LOCAL &&
+ rr->info->ai_family != AF_UNIX) {
+ /* This would expose cleartext passwords, so abort. */
+ retval = ESOCKTNOSUPPORT;
+ goto error;
+ }
K5_TAILQ_FOREACH(r, &rr->list, list) {
if (r->request == tmp) {
diff --git a/src/lib/krad/t_attr.c b/src/lib/krad/t_attr.c
index eb2a780c8..4d285ad9d 100644
--- a/src/lib/krad/t_attr.c
+++ b/src/lib/krad/t_attr.c
@@ -50,6 +50,7 @@ main()
const char *tmp;
krb5_data in;
size_t len;
+ krb5_boolean is_fips = FALSE;
noerror(krb5_init_context(&ctx));
@@ -73,7 +74,7 @@ main()
in = string2data((char *)decoded);
retval = kr_attr_encode(ctx, secret, auth,
krad_attr_name2num("User-Password"),
- &in, outbuf, &len);
+ &in, outbuf, &len, &is_fips);
insist(retval == 0);
insist(len == sizeof(encoded));
insist(memcmp(outbuf, encoded, len) == 0);
diff --git a/src/lib/krad/t_attrset.c b/src/lib/krad/t_attrset.c
index 7928335ca..0f9576253 100644
--- a/src/lib/krad/t_attrset.c
+++ b/src/lib/krad/t_attrset.c
@@ -49,6 +49,7 @@ main()
krb5_context ctx;
size_t len = 0, encode_len;
krb5_data tmp;
+ krb5_boolean is_fips = FALSE;
noerror(krb5_init_context(&ctx));
noerror(krad_attrset_new(ctx, &set));
@@ -62,7 +63,8 @@ main()
noerror(krad_attrset_add(set, krad_attr_name2num("User-Password"), &tmp));
/* Encode attrset. */
- noerror(kr_attrset_encode(set, "foo", auth, buffer, &encode_len));
+ noerror(kr_attrset_encode(set, "foo", auth, buffer, &encode_len,
+ &is_fips));
krad_attrset_free(set);
/* Manually encode User-Name. */

View File

@ -0,0 +1,34 @@
From 11ebf658c737baddcd5ce91e018213f28c279737 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Thu, 14 Feb 2019 11:50:35 -0500
Subject: [PATCH] Properly size #ifdef in k5_cccol_lock()
The cleanup code only could get executed in the USE_CCAPI_V3 case, so
move it inside that block. Reported by Coverity.
(cherry picked from commit 444a15f9cf82b9a6c1bca3f20307f82fee91c228)
(cherry picked from commit e2a0e04fb3be9297a8c532dd35a7c1045cae88f4)
---
src/lib/krb5/ccache/ccbase.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lib/krb5/ccache/ccbase.c b/src/lib/krb5/ccache/ccbase.c
index 8198f2b9b..2702bef69 100644
--- a/src/lib/krb5/ccache/ccbase.c
+++ b/src/lib/krb5/ccache/ccbase.c
@@ -511,7 +511,6 @@ krb5_cccol_lock(krb5_context context)
#endif
#ifdef USE_CCAPI_V3
ret = krb5_stdccv3_context_lock(context);
-#endif
if (ret) {
k5_cc_mutex_unlock(context, &krb5int_mcc_mutex);
k5_cc_mutex_unlock(context, &krb5int_cc_file_mutex);
@@ -519,6 +518,7 @@ krb5_cccol_lock(krb5_context context)
k5_cc_mutex_unlock(context, &cccol_lock);
return ret;
}
+#endif
k5_mutex_unlock(&cc_typelist_lock);
return ret;
}

View File

@ -0,0 +1,41 @@
From 196ee40d489e4e6a72232a3cdbb7af19a72362b3 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Fri, 4 Jan 2019 17:00:15 -0500
Subject: [PATCH] Use openssl's PRNG in FIPS mode
(cherry picked from commit 31277d79675a76612015ea00d420b41b9a232d5a)
---
src/lib/crypto/krb/prng.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/lib/crypto/krb/prng.c b/src/lib/crypto/krb/prng.c
index cb9ca9b98..f0e9984ca 100644
--- a/src/lib/crypto/krb/prng.c
+++ b/src/lib/crypto/krb/prng.c
@@ -26,6 +26,8 @@
#include "crypto_int.h"
+#include <openssl/rand.h>
+
krb5_error_code KRB5_CALLCONV
krb5_c_random_seed(krb5_context context, krb5_data *data)
{
@@ -99,9 +101,16 @@ krb5_boolean
k5_get_os_entropy(unsigned char *buf, size_t len, int strong)
{
const char *device;
-#if defined(__linux__) && defined(SYS_getrandom)
int r;
+ /* A wild FIPS mode appeared! */
+ if (FIPS_mode()) {
+ /* The return codes on this API are not good */
+ r = RAND_bytes(buf, len);
+ return r == 1;
+ }
+
+#if defined(__linux__) && defined(SYS_getrandom)
while (len > 0) {
/*
* Pull from the /dev/urandom pool, but require it to have been seeded.

1
SOURCES/kadm5.acl Normal file
View File

@ -0,0 +1 @@
*/admin@EXAMPLE.COM *

15
SOURCES/kadmin.service Normal file
View File

@ -0,0 +1,15 @@
[Unit]
Description=Kerberos 5 Password-changing and Administration
Wants=network-online.target
After=syslog.target network.target network-online.target
AssertPathExists=!/var/kerberos/krb5kdc/kpropd.acl
[Service]
Type=forking
PIDFile=/var/run/kadmind.pid
EnvironmentFile=-/etc/sysconfig/kadmin
ExecStart=/usr/sbin/kadmind -P /var/run/kadmind.pid $KADMIND_ARGS
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target

1
SOURCES/kadmin.sysconfig Normal file
View File

@ -0,0 +1 @@
KADMIND_ARGS=

View File

@ -0,0 +1,9 @@
/var/log/kadmind.log {
missingok
notifempty
monthly
rotate 12
postrotate
/bin/kill -HUP `cat /var/run/kadmind.pid 2>/dev/null` 2> /dev/null || true
endscript
}

13
SOURCES/kdc.conf Normal file
View File

@ -0,0 +1,13 @@
[kdcdefaults]
kdc_ports = 88
kdc_tcp_ports = 88
spake_preauth_kdc_challenge = edwards25519
[realms]
EXAMPLE.COM = {
#master_key_type = aes256-cts
acl_file = /var/kerberos/krb5kdc/kadm5.acl
dict_file = /usr/share/dict/words
admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab
supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal
}

13
SOURCES/kprop.service Normal file
View File

@ -0,0 +1,13 @@
[Unit]
Description=Kerberos 5 Propagation
Wants=network-online.target
After=syslog.target network.target network-online.target
AssertPathExists=/var/kerberos/krb5kdc/kpropd.acl
[Service]
Type=forking
EnvironmentFile=-/etc/sysconfig/kprop
ExecStart=/usr/sbin/kpropd $KPROPD_ARGS
[Install]
WantedBy=multi-user.target

1
SOURCES/kprop.sysconfig Normal file
View File

@ -0,0 +1 @@
KPROPD_ARGS=

View File

@ -0,0 +1,21 @@
From 174fddfa0c7d0d5c0f12d1531bc791865b630596 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:52:01 -0400
Subject: [PATCH] krb5-1.11-kpasswdtest.patch
---
src/kadmin/testing/proto/krb5.conf.proto | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/kadmin/testing/proto/krb5.conf.proto b/src/kadmin/testing/proto/krb5.conf.proto
index 00c442978..9c4bc1de7 100644
--- a/src/kadmin/testing/proto/krb5.conf.proto
+++ b/src/kadmin/testing/proto/krb5.conf.proto
@@ -9,6 +9,7 @@
__REALM__ = {
kdc = __KDCHOST__:1750
admin_server = __KDCHOST__:1751
+ kpasswd_server = __KDCHOST__:1752
database_module = foobar_db2_module_blah
}

View File

@ -0,0 +1,44 @@
From f19ee759c49fac6477ef77eb4a0be41118add1f5 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:49:57 -0400
Subject: [PATCH] krb5-1.11-run_user_0.patch
A hack: if we're looking at creating a ccache directory directly below
the /run/user/0 directory, and /run/user/0 doesn't exist, try to create
it, too.
---
src/lib/krb5/ccache/cc_dir.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/lib/krb5/ccache/cc_dir.c b/src/lib/krb5/ccache/cc_dir.c
index 73f0fe62d..4850c0d07 100644
--- a/src/lib/krb5/ccache/cc_dir.c
+++ b/src/lib/krb5/ccache/cc_dir.c
@@ -61,6 +61,8 @@
#include <dirent.h>
+#define ROOT_SPECIAL_DCC_PARENT "/run/user/0"
+
extern const krb5_cc_ops krb5_dcc_ops;
extern const krb5_cc_ops krb5_fcc_ops;
@@ -237,6 +239,18 @@ verify_dir(krb5_context context, const char *dirname)
if (stat(dirname, &st) < 0) {
if (errno == ENOENT) {
+ if (strncmp(dirname, ROOT_SPECIAL_DCC_PARENT "/",
+ sizeof(ROOT_SPECIAL_DCC_PARENT)) == 0 &&
+ stat(ROOT_SPECIAL_DCC_PARENT, &st) < 0 &&
+ errno == ENOENT) {
+#ifdef USE_SELINUX
+ selabel = krb5int_push_fscreatecon_for(ROOT_SPECIAL_DCC_PARENT);
+#endif
+ status = mkdir(ROOT_SPECIAL_DCC_PARENT, S_IRWXU);
+#ifdef USE_SELINUX
+ krb5int_pop_fscreatecon(selabel);
+#endif
+ }
#ifdef USE_SELINUX
selabel = krb5int_push_fscreatecon_for(dirname);
#endif

View File

@ -0,0 +1,37 @@
From 3bac1a71756c634fe6b8cb3858ee9df87b1a660d Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:47:00 -0400
Subject: [PATCH] krb5-1.12-api.patch
Reference docs don't define what happens if you call krb5_realm_compare() with
malformed krb5_principal structures. Define a behavior which keeps it from
crashing if applications don't check ahead of time.
---
src/lib/krb5/krb/princ_comp.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/lib/krb5/krb/princ_comp.c b/src/lib/krb5/krb/princ_comp.c
index a6936107d..0ed78833b 100644
--- a/src/lib/krb5/krb/princ_comp.c
+++ b/src/lib/krb5/krb/princ_comp.c
@@ -36,6 +36,10 @@ realm_compare_flags(krb5_context context,
const krb5_data *realm1 = &princ1->realm;
const krb5_data *realm2 = &princ2->realm;
+ if (princ1 == NULL || princ2 == NULL)
+ return FALSE;
+ if (realm1 == NULL || realm2 == NULL)
+ return FALSE;
if (realm1->length != realm2->length)
return FALSE;
if (realm1->length == 0)
@@ -88,6 +92,9 @@ krb5_principal_compare_flags(krb5_context context,
krb5_principal upn2 = NULL;
krb5_boolean ret = FALSE;
+ if (princ1 == NULL || princ2 == NULL)
+ return FALSE;
+
if (flags & KRB5_PRINCIPAL_COMPARE_ENTERPRISE) {
/* Treat UPNs as if they were real principals */
if (princ1->type == KRB5_NT_ENTERPRISE_PRINCIPAL) {

View File

@ -0,0 +1,22 @@
From ef8aa0a18c2bd2f960942380202a5fa992e2c7b3 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:32:09 -0400
Subject: [PATCH] krb5-1.12-ksu-path.patch
Set the default PATH to the one set by login.
---
src/clients/ksu/Makefile.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in
index 5755bb58a..9d58f29b5 100644
--- a/src/clients/ksu/Makefile.in
+++ b/src/clients/ksu/Makefile.in
@@ -1,6 +1,6 @@
mydir=clients$(S)ksu
BUILDTOP=$(REL)..$(S)..
-DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /local/bin"'
+DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/usr/local/sbin /usr/local/bin /sbin /bin /usr/sbin /usr/bin"'
KSU_LIBS=@KSU_LIBS@
PAM_LIBS=@PAM_LIBS@

View File

@ -0,0 +1,366 @@
From 2ca8d242b1cac8abdb35bf0068e5d78300e07c3c Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:33:53 -0400
Subject: [PATCH] krb5-1.12-ktany.patch
Adds an "ANY" keytab type which is a list of other keytab locations to search
when searching for a specific entry. When iterated through, it only presents
the contents of the first keytab.
---
src/lib/krb5/keytab/Makefile.in | 3 +
src/lib/krb5/keytab/kt_any.c | 292 ++++++++++++++++++++++++++++++++
src/lib/krb5/keytab/ktbase.c | 7 +-
3 files changed, 301 insertions(+), 1 deletion(-)
create mode 100644 src/lib/krb5/keytab/kt_any.c
diff --git a/src/lib/krb5/keytab/Makefile.in b/src/lib/krb5/keytab/Makefile.in
index 2a8fceb00..ffd179fb2 100644
--- a/src/lib/krb5/keytab/Makefile.in
+++ b/src/lib/krb5/keytab/Makefile.in
@@ -12,6 +12,7 @@ STLIBOBJS= \
ktfr_entry.o \
ktremove.o \
ktfns.o \
+ kt_any.o \
kt_file.o \
kt_memory.o \
kt_srvtab.o \
@@ -24,6 +25,7 @@ OBJS= \
$(OUTPRE)ktfr_entry.$(OBJEXT) \
$(OUTPRE)ktremove.$(OBJEXT) \
$(OUTPRE)ktfns.$(OBJEXT) \
+ $(OUTPRE)kt_any.$(OBJEXT) \
$(OUTPRE)kt_file.$(OBJEXT) \
$(OUTPRE)kt_memory.$(OBJEXT) \
$(OUTPRE)kt_srvtab.$(OBJEXT) \
@@ -36,6 +38,7 @@ SRCS= \
$(srcdir)/ktfr_entry.c \
$(srcdir)/ktremove.c \
$(srcdir)/ktfns.c \
+ $(srcdir)/kt_any.c \
$(srcdir)/kt_file.c \
$(srcdir)/kt_memory.c \
$(srcdir)/kt_srvtab.c \
diff --git a/src/lib/krb5/keytab/kt_any.c b/src/lib/krb5/keytab/kt_any.c
new file mode 100644
index 000000000..1b9b7765b
--- /dev/null
+++ b/src/lib/krb5/keytab/kt_any.c
@@ -0,0 +1,292 @@
+/*
+ * lib/krb5/keytab/kt_any.c
+ *
+ * Copyright 1998, 1999 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ *
+ * krb5_kta_ops
+ */
+
+#include "k5-int.h"
+
+typedef struct _krb5_ktany_data {
+ char *name;
+ krb5_keytab *choices;
+ int nchoices;
+} krb5_ktany_data;
+
+typedef struct _krb5_ktany_cursor_data {
+ int which;
+ krb5_kt_cursor cursor;
+} krb5_ktany_cursor_data;
+
+static krb5_error_code krb5_ktany_resolve
+ (krb5_context,
+ const char *,
+ krb5_keytab *);
+static krb5_error_code krb5_ktany_get_name
+ (krb5_context context,
+ krb5_keytab id,
+ char *name,
+ unsigned int len);
+static krb5_error_code krb5_ktany_close
+ (krb5_context context,
+ krb5_keytab id);
+static krb5_error_code krb5_ktany_get_entry
+ (krb5_context context,
+ krb5_keytab id,
+ krb5_const_principal principal,
+ krb5_kvno kvno,
+ krb5_enctype enctype,
+ krb5_keytab_entry *entry);
+static krb5_error_code krb5_ktany_start_seq_get
+ (krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *cursorp);
+static krb5_error_code krb5_ktany_next_entry
+ (krb5_context context,
+ krb5_keytab id,
+ krb5_keytab_entry *entry,
+ krb5_kt_cursor *cursor);
+static krb5_error_code krb5_ktany_end_seq_get
+ (krb5_context context,
+ krb5_keytab id,
+ krb5_kt_cursor *cursor);
+static void cleanup
+ (krb5_context context,
+ krb5_ktany_data *data,
+ int nchoices);
+
+struct _krb5_kt_ops krb5_kta_ops = {
+ 0,
+ "ANY", /* Prefix -- this string should not appear anywhere else! */
+ krb5_ktany_resolve,
+ krb5_ktany_get_name,
+ krb5_ktany_close,
+ krb5_ktany_get_entry,
+ krb5_ktany_start_seq_get,
+ krb5_ktany_next_entry,
+ krb5_ktany_end_seq_get,
+ NULL,
+ NULL,
+ NULL,
+};
+
+static krb5_error_code
+krb5_ktany_resolve(context, name, id)
+ krb5_context context;
+ const char *name;
+ krb5_keytab *id;
+{
+ const char *p, *q;
+ char *copy;
+ krb5_error_code kerror;
+ krb5_ktany_data *data;
+ int i;
+
+ /* Allocate space for our data and remember a copy of the name. */
+ if ((data = (krb5_ktany_data *)malloc(sizeof(krb5_ktany_data))) == NULL)
+ return(ENOMEM);
+ if ((data->name = (char *)malloc(strlen(name) + 1)) == NULL) {
+ free(data);
+ return(ENOMEM);
+ }
+ strcpy(data->name, name);
+
+ /* Count the number of choices and allocate memory for them. */
+ data->nchoices = 1;
+ for (p = name; (q = strchr(p, ',')) != NULL; p = q + 1)
+ data->nchoices++;
+ if ((data->choices = (krb5_keytab *)
+ malloc(data->nchoices * sizeof(krb5_keytab))) == NULL) {
+ free(data->name);
+ free(data);
+ return(ENOMEM);
+ }
+
+ /* Resolve each of the choices. */
+ i = 0;
+ for (p = name; (q = strchr(p, ',')) != NULL; p = q + 1) {
+ /* Make a copy of the choice name so we can terminate it. */
+ if ((copy = (char *)malloc(q - p + 1)) == NULL) {
+ cleanup(context, data, i);
+ return(ENOMEM);
+ }
+ memcpy(copy, p, q - p);
+ copy[q - p] = 0;
+
+ /* Try resolving the choice name. */
+ kerror = krb5_kt_resolve(context, copy, &data->choices[i]);
+ free(copy);
+ if (kerror) {
+ cleanup(context, data, i);
+ return(kerror);
+ }
+ i++;
+ }
+ if ((kerror = krb5_kt_resolve(context, p, &data->choices[i]))) {
+ cleanup(context, data, i);
+ return(kerror);
+ }
+
+ /* Allocate and fill in an ID for the caller. */
+ if ((*id = (krb5_keytab)malloc(sizeof(**id))) == NULL) {
+ cleanup(context, data, i);
+ return(ENOMEM);
+ }
+ (*id)->ops = &krb5_kta_ops;
+ (*id)->data = (krb5_pointer)data;
+ (*id)->magic = KV5M_KEYTAB;
+
+ return(0);
+}
+
+static krb5_error_code
+krb5_ktany_get_name(context, id, name, len)
+ krb5_context context;
+ krb5_keytab id;
+ char *name;
+ unsigned int len;
+{
+ krb5_ktany_data *data = (krb5_ktany_data *)id->data;
+
+ if (len < strlen(data->name) + 1)
+ return(KRB5_KT_NAME_TOOLONG);
+ strcpy(name, data->name);
+ return(0);
+}
+
+static krb5_error_code
+krb5_ktany_close(context, id)
+ krb5_context context;
+ krb5_keytab id;
+{
+ krb5_ktany_data *data = (krb5_ktany_data *)id->data;
+
+ cleanup(context, data, data->nchoices);
+ id->ops = 0;
+ free(id);
+ return(0);
+}
+
+static krb5_error_code
+krb5_ktany_get_entry(context, id, principal, kvno, enctype, entry)
+ krb5_context context;
+ krb5_keytab id;
+ krb5_const_principal principal;
+ krb5_kvno kvno;
+ krb5_enctype enctype;
+ krb5_keytab_entry *entry;
+{
+ krb5_ktany_data *data = (krb5_ktany_data *)id->data;
+ krb5_error_code kerror = KRB5_KT_NOTFOUND;
+ int i;
+
+ for (i = 0; i < data->nchoices; i++) {
+ if ((kerror = krb5_kt_get_entry(context, data->choices[i], principal,
+ kvno, enctype, entry)) != ENOENT)
+ return kerror;
+ }
+ return kerror;
+}
+
+static krb5_error_code
+krb5_ktany_start_seq_get(context, id, cursorp)
+ krb5_context context;
+ krb5_keytab id;
+ krb5_kt_cursor *cursorp;
+{
+ krb5_ktany_data *data = (krb5_ktany_data *)id->data;
+ krb5_ktany_cursor_data *cdata;
+ krb5_error_code kerror = ENOENT;
+ int i;
+
+ if ((cdata = (krb5_ktany_cursor_data *)
+ malloc(sizeof(krb5_ktany_cursor_data))) == NULL)
+ return(ENOMEM);
+
+ /* Find a choice which can handle the serialization request. */
+ for (i = 0; i < data->nchoices; i++) {
+ if ((kerror = krb5_kt_start_seq_get(context, data->choices[i],
+ &cdata->cursor)) == 0)
+ break;
+ else if (kerror != ENOENT) {
+ free(cdata);
+ return(kerror);
+ }
+ }
+
+ if (i == data->nchoices) {
+ /* Everyone returned ENOENT, so no go. */
+ free(cdata);
+ return(kerror);
+ }
+
+ cdata->which = i;
+ *cursorp = (krb5_kt_cursor)cdata;
+ return(0);
+}
+
+static krb5_error_code
+krb5_ktany_next_entry(context, id, entry, cursor)
+ krb5_context context;
+ krb5_keytab id;
+ krb5_keytab_entry *entry;
+ krb5_kt_cursor *cursor;
+{
+ krb5_ktany_data *data = (krb5_ktany_data *)id->data;
+ krb5_ktany_cursor_data *cdata = (krb5_ktany_cursor_data *)*cursor;
+ krb5_keytab choice_id;
+
+ choice_id = data->choices[cdata->which];
+ return(krb5_kt_next_entry(context, choice_id, entry, &cdata->cursor));
+}
+
+static krb5_error_code
+krb5_ktany_end_seq_get(context, id, cursor)
+ krb5_context context;
+ krb5_keytab id;
+ krb5_kt_cursor *cursor;
+{
+ krb5_ktany_data *data = (krb5_ktany_data *)id->data;
+ krb5_ktany_cursor_data *cdata = (krb5_ktany_cursor_data *)*cursor;
+ krb5_keytab choice_id;
+ krb5_error_code kerror;
+
+ choice_id = data->choices[cdata->which];
+ kerror = krb5_kt_end_seq_get(context, choice_id, &cdata->cursor);
+ free(cdata);
+ return(kerror);
+}
+
+static void
+cleanup(context, data, nchoices)
+ krb5_context context;
+ krb5_ktany_data *data;
+ int nchoices;
+{
+ int i;
+
+ free(data->name);
+ for (i = 0; i < nchoices; i++)
+ krb5_kt_close(context, data->choices[i]);
+ free(data->choices);
+ free(data);
+}
diff --git a/src/lib/krb5/keytab/ktbase.c b/src/lib/krb5/keytab/ktbase.c
index 0d39b2940..6534d7c52 100644
--- a/src/lib/krb5/keytab/ktbase.c
+++ b/src/lib/krb5/keytab/ktbase.c
@@ -57,14 +57,19 @@ extern const krb5_kt_ops krb5_ktf_ops;
extern const krb5_kt_ops krb5_ktf_writable_ops;
extern const krb5_kt_ops krb5_kts_ops;
extern const krb5_kt_ops krb5_mkt_ops;
+extern const krb5_kt_ops krb5_kta_ops;
struct krb5_kt_typelist {
const krb5_kt_ops *ops;
const struct krb5_kt_typelist *next;
};
+static struct krb5_kt_typelist krb5_kt_typelist_any = {
+ &krb5_kta_ops,
+ NULL
+};
const static struct krb5_kt_typelist krb5_kt_typelist_srvtab = {
&krb5_kts_ops,
- NULL
+ &krb5_kt_typelist_any
};
const static struct krb5_kt_typelist krb5_kt_typelist_memory = {
&krb5_mkt_ops,

View File

@ -0,0 +1,770 @@
From 02a10f4b9a8decc8d10f3e045282a0ae7ed1c00d Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:29:58 -0400
Subject: [PATCH] krb5-1.12.1-pam.patch
Modify ksu so that it performs account and session management on behalf of
the target user account, mimicking the action of regular su. The default
service name is "ksu", because on Fedora at least the configuration used
is determined by whether or not a login shell is being opened, and so
this may need to vary, too. At run-time, ksu's behavior can be reset to
the earlier, non-PAM behavior by setting "use_pam" to false in the [ksu]
section of /etc/krb5.conf.
When enabled, ksu gains a dependency on libpam.
Originally RT#5939, though it's changed since then to perform the account
and session management before dropping privileges, and to apply on top of
changes we're proposing for how it handles cache collections.
---
src/aclocal.m4 | 67 +++++++
src/clients/ksu/Makefile.in | 8 +-
src/clients/ksu/main.c | 88 +++++++-
src/clients/ksu/pam.c | 389 ++++++++++++++++++++++++++++++++++++
src/clients/ksu/pam.h | 57 ++++++
src/configure.in | 2 +
6 files changed, 608 insertions(+), 3 deletions(-)
create mode 100644 src/clients/ksu/pam.c
create mode 100644 src/clients/ksu/pam.h
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 3752d9bd5..340546d80 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -1697,3 +1697,70 @@ AC_DEFUN(KRB5_AC_PERSISTENT_KEYRING,[
]))
])dnl
dnl
+dnl
+dnl Use PAM instead of local crypt() compare for checking local passwords,
+dnl and perform PAM account, session management, and password-changing where
+dnl appropriate.
+dnl
+AC_DEFUN(KRB5_WITH_PAM,[
+AC_ARG_WITH(pam,[AC_HELP_STRING(--with-pam,[compile with PAM support])],
+ withpam="$withval",withpam=auto)
+AC_ARG_WITH(pam-ksu-service,[AC_HELP_STRING(--with-ksu-service,[PAM service name for ksu ["ksu"]])],
+ withksupamservice="$withval",withksupamservice=ksu)
+old_LIBS="$LIBS"
+if test "$withpam" != no ; then
+ AC_MSG_RESULT([checking for PAM...])
+ PAM_LIBS=
+
+ AC_CHECK_HEADERS(security/pam_appl.h)
+ if test "x$ac_cv_header_security_pam_appl_h" != xyes ; then
+ if test "$withpam" = auto ; then
+ AC_MSG_RESULT([Unable to locate security/pam_appl.h.])
+ withpam=no
+ else
+ AC_MSG_ERROR([Unable to locate security/pam_appl.h.])
+ fi
+ fi
+
+ LIBS=
+ unset ac_cv_func_pam_start
+ AC_CHECK_FUNCS(putenv pam_start)
+ if test "x$ac_cv_func_pam_start" = xno ; then
+ unset ac_cv_func_pam_start
+ AC_CHECK_LIB(dl,dlopen)
+ AC_CHECK_FUNCS(pam_start)
+ if test "x$ac_cv_func_pam_start" = xno ; then
+ AC_CHECK_LIB(pam,pam_start)
+ unset ac_cv_func_pam_start
+ unset ac_cv_func_pam_getenvlist
+ AC_CHECK_FUNCS(pam_start pam_getenvlist)
+ if test "x$ac_cv_func_pam_start" = xyes ; then
+ PAM_LIBS="$LIBS"
+ else
+ if test "$withpam" = auto ; then
+ AC_MSG_RESULT([Unable to locate libpam.])
+ withpam=no
+ else
+ AC_MSG_ERROR([Unable to locate libpam.])
+ fi
+ fi
+ fi
+ fi
+ if test "$withpam" != no ; then
+ AC_MSG_NOTICE([building with PAM support])
+ AC_DEFINE(USE_PAM,1,[Define if Kerberos-aware tools should support PAM])
+ AC_DEFINE_UNQUOTED(KSU_PAM_SERVICE,"$withksupamservice",
+ [Define to the name of the PAM service name to be used by ksu.])
+ PAM_LIBS="$LIBS"
+ NON_PAM_MAN=".\\\" "
+ PAM_MAN=
+ else
+ PAM_MAN=".\\\" "
+ NON_PAM_MAN=
+ fi
+fi
+LIBS="$old_LIBS"
+AC_SUBST(PAM_LIBS)
+AC_SUBST(PAM_MAN)
+AC_SUBST(NON_PAM_MAN)
+])dnl
diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in
index b2fcbf240..5755bb58a 100644
--- a/src/clients/ksu/Makefile.in
+++ b/src/clients/ksu/Makefile.in
@@ -3,12 +3,14 @@ BUILDTOP=$(REL)..$(S)..
DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /local/bin"'
KSU_LIBS=@KSU_LIBS@
+PAM_LIBS=@PAM_LIBS@
SRCS = \
$(srcdir)/krb_auth_su.c \
$(srcdir)/ccache.c \
$(srcdir)/authorization.c \
$(srcdir)/main.c \
+ $(srcdir)/pam.c \
$(srcdir)/heuristic.c \
$(srcdir)/xmalloc.c \
$(srcdir)/setenv.c
@@ -17,13 +19,17 @@ OBJS = \
ccache.o \
authorization.o \
main.o \
+ pam.o \
heuristic.o \
xmalloc.o @SETENVOBJ@
all: ksu
ksu: $(OBJS) $(KRB5_BASE_DEPLIBS)
- $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS)
+ $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS) $(PAM_LIBS)
+
+pam.o: pam.c
+ $(CC) $(ALL_CFLAGS) -c $<
clean:
$(RM) ksu
diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
index d9596d948..ec06788bc 100644
--- a/src/clients/ksu/main.c
+++ b/src/clients/ksu/main.c
@@ -26,6 +26,7 @@
* KSU was writen by: Ari Medvinsky, ari@isi.edu
*/
+#include "autoconf.h"
#include "ksu.h"
#include "adm_proto.h"
#include <sys/types.h>
@@ -33,6 +34,10 @@
#include <signal.h>
#include <grp.h>
+#ifdef USE_PAM
+#include "pam.h"
+#endif
+
/* globals */
char * prog_name;
int auth_debug =0;
@@ -40,6 +45,7 @@ char k5login_path[MAXPATHLEN];
char k5users_path[MAXPATHLEN];
char * gb_err = NULL;
int quiet = 0;
+int force_fork = 0;
/***********/
#define KS_TEMPORARY_CACHE "MEMORY:_ksu"
@@ -528,6 +534,23 @@ main (argc, argv)
prog_name,target_user,client_name,
source_user,ontty());
+#ifdef USE_PAM
+ if (appl_pam_enabled(ksu_context, "ksu")) {
+ if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL,
+ NULL, source_user,
+ ttyname(STDERR_FILENO)) != 0) {
+ fprintf(stderr, "Access denied for %s.\n", target_user);
+ exit(1);
+ }
+ if (appl_pam_requires_chauthtok()) {
+ fprintf(stderr, "Password change required for %s.\n",
+ target_user);
+ exit(1);
+ }
+ force_fork++;
+ }
+#endif
+
/* Run authorization as target.*/
if (krb5_seteuid(target_uid)) {
com_err(prog_name, errno, _("while switching to target for "
@@ -588,6 +611,24 @@ main (argc, argv)
exit(1);
}
+#ifdef USE_PAM
+ } else {
+ /* we always do PAM account management, even for root */
+ if (appl_pam_enabled(ksu_context, "ksu")) {
+ if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL,
+ NULL, source_user,
+ ttyname(STDERR_FILENO)) != 0) {
+ fprintf(stderr, "Access denied for %s.\n", target_user);
+ exit(1);
+ }
+ if (appl_pam_requires_chauthtok()) {
+ fprintf(stderr, "Password change required for %s.\n",
+ target_user);
+ exit(1);
+ }
+ force_fork++;
+ }
+#endif
}
if( some_rest_copy){
@@ -645,6 +686,30 @@ main (argc, argv)
exit(1);
}
+#ifdef USE_PAM
+ if (appl_pam_enabled(ksu_context, "ksu")) {
+ if (appl_pam_session_open() != 0) {
+ fprintf(stderr, "Error opening session for %s.\n", target_user);
+ exit(1);
+ }
+#ifdef DEBUG
+ if (auth_debug){
+ printf(" Opened PAM session.\n");
+ }
+#endif
+ if (appl_pam_cred_init()) {
+ fprintf(stderr, "Error initializing credentials for %s.\n",
+ target_user);
+ exit(1);
+ }
+#ifdef DEBUG
+ if (auth_debug){
+ printf(" Initialized PAM credentials.\n");
+ }
+#endif
+ }
+#endif
+
/* set permissions */
if (setgid(target_pwd->pw_gid) < 0) {
perror("ksu: setgid");
@@ -742,7 +807,7 @@ main (argc, argv)
fprintf(stderr, "program to be execed %s\n",params[0]);
}
- if( keep_target_cache ) {
+ if( keep_target_cache && !force_fork ) {
execv(params[0], params);
com_err(prog_name, errno, _("while trying to execv %s"), params[0]);
sweep_up(ksu_context, cc_target);
@@ -772,16 +837,35 @@ main (argc, argv)
if (ret_pid == -1) {
com_err(prog_name, errno, _("while calling waitpid"));
}
- sweep_up(ksu_context, cc_target);
+ if( !keep_target_cache ) {
+ sweep_up(ksu_context, cc_target);
+ }
exit (statusp);
case -1:
com_err(prog_name, errno, _("while trying to fork."));
sweep_up(ksu_context, cc_target);
exit (1);
case 0:
+#ifdef USE_PAM
+ if (appl_pam_enabled(ksu_context, "ksu")) {
+ if (appl_pam_setenv() != 0) {
+ fprintf(stderr, "Error setting up environment for %s.\n",
+ target_user);
+ exit (1);
+ }
+#ifdef DEBUG
+ if (auth_debug){
+ printf(" Set up PAM environment.\n");
+ }
+#endif
+ }
+#endif
execv(params[0], params);
com_err(prog_name, errno, _("while trying to execv %s"),
params[0]);
+ if( keep_target_cache ) {
+ sweep_up(ksu_context, cc_target);
+ }
exit (1);
}
}
diff --git a/src/clients/ksu/pam.c b/src/clients/ksu/pam.c
new file mode 100644
index 000000000..cbfe48704
--- /dev/null
+++ b/src/clients/ksu/pam.c
@@ -0,0 +1,389 @@
+/*
+ * src/clients/ksu/pam.c
+ *
+ * Copyright 2007,2009,2010 Red Hat, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of Red Hat, Inc. nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Convenience wrappers for using PAM.
+ */
+
+#include "autoconf.h"
+#ifdef USE_PAM
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "k5-int.h"
+#include "pam.h"
+
+#ifndef MAXPWSIZE
+#define MAXPWSIZE 128
+#endif
+
+static int appl_pam_started;
+static pid_t appl_pam_starter = -1;
+static int appl_pam_session_opened;
+static int appl_pam_creds_initialized;
+static int appl_pam_pwchange_required;
+static pam_handle_t *appl_pamh;
+static struct pam_conv appl_pam_conv;
+static char *appl_pam_user;
+struct appl_pam_non_interactive_args {
+ const char *user;
+ const char *password;
+};
+
+int
+appl_pam_enabled(krb5_context context, const char *section)
+{
+ int enabled = 1;
+ if ((context != NULL) && (context->profile != NULL)) {
+ if (profile_get_boolean(context->profile,
+ section,
+ USE_PAM_CONFIGURATION_KEYWORD,
+ NULL,
+ enabled, &enabled) != 0) {
+ enabled = 1;
+ }
+ }
+ return enabled;
+}
+
+void
+appl_pam_cleanup(void)
+{
+ if (getpid() != appl_pam_starter) {
+ return;
+ }
+#ifdef DEBUG
+ printf("Called to clean up PAM.\n");
+#endif
+ if (appl_pam_creds_initialized) {
+#ifdef DEBUG
+ printf("Deleting PAM credentials.\n");
+#endif
+ pam_setcred(appl_pamh, PAM_DELETE_CRED);
+ appl_pam_creds_initialized = 0;
+ }
+ if (appl_pam_session_opened) {
+#ifdef DEBUG
+ printf("Closing PAM session.\n");
+#endif
+ pam_close_session(appl_pamh, 0);
+ appl_pam_session_opened = 0;
+ }
+ appl_pam_pwchange_required = 0;
+ if (appl_pam_started) {
+#ifdef DEBUG
+ printf("Shutting down PAM.\n");
+#endif
+ pam_end(appl_pamh, 0);
+ appl_pam_started = 0;
+ appl_pam_starter = -1;
+ free(appl_pam_user);
+ appl_pam_user = NULL;
+ }
+}
+static int
+appl_pam_interactive_converse(int num_msg, const struct pam_message **msg,
+ struct pam_response **presp, void *appdata_ptr)
+{
+ const struct pam_message *message;
+ struct pam_response *resp;
+ int i, code;
+ char *pwstring, pwbuf[MAXPWSIZE];
+ unsigned int pwsize;
+ resp = malloc(sizeof(struct pam_response) * num_msg);
+ if (resp == NULL) {
+ return PAM_BUF_ERR;
+ }
+ memset(resp, 0, sizeof(struct pam_response) * num_msg);
+ code = PAM_SUCCESS;
+ for (i = 0; i < num_msg; i++) {
+ message = &(msg[0][i]); /* XXX */
+ message = msg[i]; /* XXX */
+ pwstring = NULL;
+ switch (message->msg_style) {
+ case PAM_TEXT_INFO:
+ case PAM_ERROR_MSG:
+ printf("[%s]\n", message->msg ? message->msg : "");
+ fflush(stdout);
+ resp[i].resp = NULL;
+ resp[i].resp_retcode = PAM_SUCCESS;
+ break;
+ case PAM_PROMPT_ECHO_ON:
+ case PAM_PROMPT_ECHO_OFF:
+ if (message->msg_style == PAM_PROMPT_ECHO_ON) {
+ if (fgets(pwbuf, sizeof(pwbuf),
+ stdin) != NULL) {
+ pwbuf[strcspn(pwbuf, "\r\n")] = '\0';
+ pwstring = pwbuf;
+ }
+ } else {
+ pwstring = getpass(message->msg ?
+ message->msg :
+ "");
+ }
+ if ((pwstring != NULL) && (pwstring[0] != '\0')) {
+ pwsize = strlen(pwstring);
+ resp[i].resp = malloc(pwsize + 1);
+ if (resp[i].resp == NULL) {
+ resp[i].resp_retcode = PAM_BUF_ERR;
+ } else {
+ memcpy(resp[i].resp, pwstring, pwsize);
+ resp[i].resp[pwsize] = '\0';
+ resp[i].resp_retcode = PAM_SUCCESS;
+ }
+ } else {
+ resp[i].resp_retcode = PAM_CONV_ERR;
+ code = PAM_CONV_ERR;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ *presp = resp;
+ return code;
+}
+static int
+appl_pam_non_interactive_converse(int num_msg,
+ const struct pam_message **msg,
+ struct pam_response **presp,
+ void *appdata_ptr)
+{
+ const struct pam_message *message;
+ struct pam_response *resp;
+ int i, code;
+ unsigned int pwsize;
+ struct appl_pam_non_interactive_args *args;
+ const char *pwstring;
+ resp = malloc(sizeof(struct pam_response) * num_msg);
+ if (resp == NULL) {
+ return PAM_BUF_ERR;
+ }
+ args = appdata_ptr;
+ memset(resp, 0, sizeof(struct pam_response) * num_msg);
+ code = PAM_SUCCESS;
+ for (i = 0; i < num_msg; i++) {
+ message = &((*msg)[i]);
+ message = msg[i];
+ pwstring = NULL;
+ switch (message->msg_style) {
+ case PAM_TEXT_INFO:
+ case PAM_ERROR_MSG:
+ break;
+ case PAM_PROMPT_ECHO_ON:
+ case PAM_PROMPT_ECHO_OFF:
+ if (message->msg_style == PAM_PROMPT_ECHO_ON) {
+ /* assume "user" */
+ pwstring = args->user;
+ } else {
+ /* assume "password" */
+ pwstring = args->password;
+ }
+ if ((pwstring != NULL) && (pwstring[0] != '\0')) {
+ pwsize = strlen(pwstring);
+ resp[i].resp = malloc(pwsize + 1);
+ if (resp[i].resp == NULL) {
+ resp[i].resp_retcode = PAM_BUF_ERR;
+ } else {
+ memcpy(resp[i].resp, pwstring, pwsize);
+ resp[i].resp[pwsize] = '\0';
+ resp[i].resp_retcode = PAM_SUCCESS;
+ }
+ } else {
+ resp[i].resp_retcode = PAM_CONV_ERR;
+ code = PAM_CONV_ERR;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ *presp = resp;
+ return code;
+}
+static int
+appl_pam_start(const char *service, int interactive,
+ const char *login_username,
+ const char *non_interactive_password,
+ const char *hostname,
+ const char *ruser,
+ const char *tty)
+{
+ static int exit_handler_registered;
+ static struct appl_pam_non_interactive_args args;
+ int ret = 0;
+ if (appl_pam_started &&
+ (strcmp(login_username, appl_pam_user) != 0)) {
+ appl_pam_cleanup();
+ appl_pam_user = NULL;
+ }
+ if (!appl_pam_started) {
+#ifdef DEBUG
+ printf("Starting PAM up (service=\"%s\",user=\"%s\").\n",
+ service, login_username);
+#endif
+ memset(&appl_pam_conv, 0, sizeof(appl_pam_conv));
+ appl_pam_conv.conv = interactive ?
+ &appl_pam_interactive_converse :
+ &appl_pam_non_interactive_converse;
+ memset(&args, 0, sizeof(args));
+ args.user = strdup(login_username);
+ args.password = non_interactive_password ?
+ strdup(non_interactive_password) :
+ NULL;
+ appl_pam_conv.appdata_ptr = &args;
+ ret = pam_start(service, login_username,
+ &appl_pam_conv, &appl_pamh);
+ if (ret == 0) {
+ if (hostname != NULL) {
+#ifdef DEBUG
+ printf("Setting PAM_RHOST to \"%s\".\n", hostname);
+#endif
+ pam_set_item(appl_pamh, PAM_RHOST, hostname);
+ }
+ if (ruser != NULL) {
+#ifdef DEBUG
+ printf("Setting PAM_RUSER to \"%s\".\n", ruser);
+#endif
+ pam_set_item(appl_pamh, PAM_RUSER, ruser);
+ }
+ if (tty != NULL) {
+#ifdef DEBUG
+ printf("Setting PAM_TTY to \"%s\".\n", tty);
+#endif
+ pam_set_item(appl_pamh, PAM_TTY, tty);
+ }
+ if (!exit_handler_registered &&
+ (atexit(appl_pam_cleanup) != 0)) {
+ pam_end(appl_pamh, 0);
+ appl_pamh = NULL;
+ ret = -1;
+ } else {
+ appl_pam_started = 1;
+ appl_pam_starter = getpid();
+ appl_pam_user = strdup(login_username);
+ exit_handler_registered = 1;
+ }
+ }
+ }
+ return ret;
+}
+int
+appl_pam_acct_mgmt(const char *service, int interactive,
+ const char *login_username,
+ const char *non_interactive_password,
+ const char *hostname,
+ const char *ruser,
+ const char *tty)
+{
+ int ret;
+ appl_pam_pwchange_required = 0;
+ ret = appl_pam_start(service, interactive, login_username,
+ non_interactive_password, hostname, ruser, tty);
+ if (ret == 0) {
+#ifdef DEBUG
+ printf("Calling pam_acct_mgmt().\n");
+#endif
+ ret = pam_acct_mgmt(appl_pamh, 0);
+ switch (ret) {
+ case PAM_IGNORE:
+ ret = 0;
+ break;
+ case PAM_NEW_AUTHTOK_REQD:
+ appl_pam_pwchange_required = 1;
+ ret = 0;
+ break;
+ default:
+ break;
+ }
+ }
+ return ret;
+}
+int
+appl_pam_requires_chauthtok(void)
+{
+ return appl_pam_pwchange_required;
+}
+int
+appl_pam_session_open(void)
+{
+ int ret = 0;
+ if (appl_pam_started) {
+#ifdef DEBUG
+ printf("Opening PAM session.\n");
+#endif
+ ret = pam_open_session(appl_pamh, 0);
+ if (ret == 0) {
+ appl_pam_session_opened = 1;
+ }
+ }
+ return ret;
+}
+int
+appl_pam_setenv(void)
+{
+ int ret = 0;
+#ifdef HAVE_PAM_GETENVLIST
+#ifdef HAVE_PUTENV
+ int i;
+ char **list;
+ if (appl_pam_started) {
+ list = pam_getenvlist(appl_pamh);
+ for (i = 0; ((list != NULL) && (list[i] != NULL)); i++) {
+#ifdef DEBUG
+ printf("Setting \"%s\" in environment.\n", list[i]);
+#endif
+ putenv(list[i]);
+ }
+ }
+#endif
+#endif
+ return ret;
+}
+int
+appl_pam_cred_init(void)
+{
+ int ret = 0;
+ if (appl_pam_started) {
+#ifdef DEBUG
+ printf("Initializing PAM credentials.\n");
+#endif
+ ret = pam_setcred(appl_pamh, PAM_ESTABLISH_CRED);
+ if (ret == 0) {
+ appl_pam_creds_initialized = 1;
+ }
+ }
+ return ret;
+}
+#endif
diff --git a/src/clients/ksu/pam.h b/src/clients/ksu/pam.h
new file mode 100644
index 000000000..0ab76569c
--- /dev/null
+++ b/src/clients/ksu/pam.h
@@ -0,0 +1,57 @@
+/*
+ * src/clients/ksu/pam.h
+ *
+ * Copyright 2007,2009,2010 Red Hat, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of Red Hat, Inc. nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Convenience wrappers for using PAM.
+ */
+
+#include <krb5.h>
+#ifdef HAVE_SECURITY_PAM_APPL_H
+#include <security/pam_appl.h>
+#endif
+
+#define USE_PAM_CONFIGURATION_KEYWORD "use_pam"
+
+#ifdef USE_PAM
+int appl_pam_enabled(krb5_context context, const char *section);
+int appl_pam_acct_mgmt(const char *service, int interactive,
+ const char *local_username,
+ const char *non_interactive_password,
+ const char *hostname,
+ const char *ruser,
+ const char *tty);
+int appl_pam_requires_chauthtok(void);
+int appl_pam_session_open(void);
+int appl_pam_setenv(void);
+int appl_pam_cred_init(void);
+void appl_pam_cleanup(void);
+#endif
diff --git a/src/configure.in b/src/configure.in
index 61ef738dc..e9a12ac16 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1352,6 +1352,8 @@ AC_SUBST([VERTO_VERSION])
AC_PATH_PROG(GROFF, groff)
+KRB5_WITH_PAM
+
# Make localedir work in autoconf 2.5x.
if test "${localedir+set}" != set; then
localedir='$(datadir)/locale'

View File

@ -0,0 +1,75 @@
From 1dc051d5964aba0b8cd3d01f063ffc28253456de Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:47:44 -0400
Subject: [PATCH] krb5-1.13-dirsrv-accountlock.patch
Treat 'nsAccountLock: true' the same as 'loginDisabled: true'. Updated from
original version filed as RT#5891.
---
src/aclocal.m4 | 9 +++++++++
src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c | 17 +++++++++++++++++
.../kdb/ldap/libkdb_ldap/ldap_principal.c | 3 +++
3 files changed, 29 insertions(+)
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index db18226ed..518b1a547 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -1678,6 +1678,15 @@ if test "$with_ldap" = yes; then
AC_MSG_NOTICE(enabling OpenLDAP database backend module support)
OPENLDAP_PLUGIN=yes
fi
+AC_ARG_WITH([dirsrv-account-locking],
+[ --with-dirsrv-account-locking compile 389/Red Hat/Fedora/Netscape Directory Server database backend module],
+[case "$withval" in
+ yes | no) ;;
+ *) AC_MSG_ERROR(Invalid option value --with-dirsrv-account-locking="$withval") ;;
+esac], with_dirsrv_account_locking=no)
+if test $with_dirsrv_account_locking = yes; then
+ AC_DEFINE(HAVE_DIRSRV_ACCOUNT_LOCKING,1,[Define if LDAP KDB interface should heed 389 DS's nsAccountLock attribute.])
+fi
])dnl
dnl
dnl If libkeyutils exists (on Linux) include it and use keyring ccache
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
index 5b9d1e9fa..4e7270065 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
@@ -1652,6 +1652,23 @@ populate_krb5_db_entry(krb5_context context, krb5_ldap_context *ldap_context,
ret = krb5_dbe_update_tl_data(context, entry, &userinfo_tl_data);
if (ret)
goto cleanup;
+#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING
+ {
+ krb5_timestamp expiretime=0;
+ char *is_login_disabled=NULL;
+
+ /* LOGIN DISABLED */
+ ret = krb5_ldap_get_string(ld, ent, "nsAccountLock", &is_login_disabled,
+ &attr_present);
+ if (ret)
+ goto cleanup;
+ if (attr_present == TRUE) {
+ if (strcasecmp(is_login_disabled, "TRUE")== 0)
+ entry->attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
+ free (is_login_disabled);
+ }
+ }
+#endif
ret = krb5_read_tkt_policy(context, ldap_context, entry, tktpolname);
if (ret)
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
index d722dbfa6..5e8e9a897 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
@@ -54,6 +54,9 @@ char *principal_attributes[] = { "krbprincipalname",
"krbLastFailedAuth",
"krbLoginFailedCount",
"krbLastSuccessfulAuth",
+#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING
+ "nsAccountLock",
+#endif
"krbLastPwdChange",
"krbLastAdminUnlock",
"krbPrincipalAuthInd",

View File

@ -0,0 +1,70 @@
From 90bf9e3c4a80e7e46e6e00b9d541c6144968cad4 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:45:26 -0400
Subject: [PATCH] krb5-1.15-beta1-buildconf.patch
Build binaries in this package as RELRO PIEs, libraries as partial RELRO,
and install shared libraries with the execute bit set on them. Prune out
the -L/usr/lib* and PIE flags where they might leak out and affect
apps which just want to link with the libraries. FIXME: needs to check and
not just assume that the compiler supports using these flags.
---
src/build-tools/krb5-config.in | 7 +++++++
src/config/pre.in | 2 +-
src/config/shlib.conf | 5 +++--
3 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/build-tools/krb5-config.in b/src/build-tools/krb5-config.in
index c17cb5eb5..1891dea99 100755
--- a/src/build-tools/krb5-config.in
+++ b/src/build-tools/krb5-config.in
@@ -226,6 +226,13 @@ if test -n "$do_libs"; then
-e 's#\$(PTHREAD_CFLAGS)#'"$PTHREAD_CFLAGS"'#' \
-e 's#\$(CFLAGS)##'`
+ if test `dirname $libdir` = /usr ; then
+ lib_flags=`echo $lib_flags | sed -e "s#-L$libdir##" -e "s#$RPATH_FLAG$libdir##"`
+ fi
+ lib_flags=`echo $lib_flags | sed -e "s#-fPIE##g" -e "s#-pie##g"`
+ lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,relro##g"`
+ lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,now##g"`
+
if test $library = 'kdb'; then
lib_flags="$lib_flags -lkdb5 $KDB5_DB_LIB"
library=krb5
diff --git a/src/config/pre.in b/src/config/pre.in
index 917357df9..a8540ae2a 100644
--- a/src/config/pre.in
+++ b/src/config/pre.in
@@ -185,7 +185,7 @@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ $(INSTALL_STRIP)
INSTALL_SCRIPT=@INSTALL_PROGRAM@
INSTALL_DATA=@INSTALL_DATA@
INSTALL_SHLIB=@INSTALL_SHLIB@
-INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 -o root
+INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755
## This is needed because autoconf will sometimes define @exec_prefix@ to be
## ${prefix}.
prefix=@prefix@
diff --git a/src/config/shlib.conf b/src/config/shlib.conf
index 3e4af6c02..2b20c3fda 100644
--- a/src/config/shlib.conf
+++ b/src/config/shlib.conf
@@ -423,7 +423,7 @@ mips-*-netbsd*)
# Linux ld doesn't default to stuffing the SONAME field...
# Use objdump -x to examine the fields of the library
# UNDEF_CHECK is suppressed by --enable-asan
- LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $(UNDEF_CHECK)'
+ LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $(UNDEF_CHECK) -Wl,-z,relro -Wl,--warn-shared-textrel'
UNDEF_CHECK='-Wl,--no-undefined'
# $(EXPORT_CHECK) runs export-check.pl when in maintainer mode.
LDCOMBINE_TAIL='-Wl,--version-script binutils.versions $(EXPORT_CHECK)'
@@ -435,7 +435,8 @@ mips-*-netbsd*)
SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)'
PROFFLAGS=-pg
PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)'
- CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)'
+ CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) -pie -Wl,-z,relro -Wl,-z,now $(LDFLAGS)'
+ INSTALL_SHLIB='${INSTALL} -m755'
CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)'
CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)'
CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)'

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQIcBAABAgAGBQJcNMxOAAoJEAy6CFdfg3LfjAwP/2/oQe+4Bs/XwZTwNfakTbBl
YHSY8MNAHIKsLh6Bn+SJBQQXSE0fEsm0hYH+JWz85+mzlZk7TbNZUI+zeikhLxi6
+d8MMQBpk2mQN0dkIeWjTdfkcThGCDSL7l0fh3MuEfN5C7QPAPD1JL1ZeqXPH5AV
PSQRC9s2wiOTwwuHM2i27rZ7gdhL/xfJ3ZPUFJH4klRgszwp9j10I/nh4/XyS/wB
82umjfusFPa9VNSPzm1jm94oRmALkR3CHGvmku2XD3YOv/f5yO8C1cHWNNLxg+5h
EqVv05ddb6iLku4fRhkEjfN3VgCtEvXuMkuAXppkDJJ7wWxMBWgCIr1DS/x7LfbL
CI0ZTejn8HCUBNmRWsKkUuebgHJ7ccch8p/Fp0cV4eT1FL35N2oV51u7+/zK6R8y
1dygUF2VWFOqwm8cyczdFue7dFQVDGCw7R2eK5lXY3NpZVmJblQ/gNLMcbOxGBis
H2dOzSn+CnxlD/2LqOZnhQ1WnGBhOMxoINwX/MQsIvkwAFaM1EsdhPIP/6mSVA/g
p04+YQ2u2ag7Pq3zHsMIonC18w4ZqDPcvXvOXqCHtlQBDAMtb927XvjoTNj5W8Ei
jywxqdWuuqalmrKGPEsKVOJZN6xg7UTgaKzcvQTvW7D3gLbrTT2iM++VKB3vh9V9
SkULnR3c7fKMzFeLb/Q2
=4hZX
-----END PGP SIGNATURE-----

View File

@ -0,0 +1,22 @@
From 19f0dc268c127fb51c4bb8c106104eee67119cca Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:46:21 -0400
Subject: [PATCH] krb5-1.3.1-dns.patch
We want to be able to use --with-netlib and --enable-dns at the same time.
---
src/aclocal.m4 | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index a7afec09e..db18226ed 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -726,6 +726,7 @@ AC_HELP_STRING([--with-netlib=LIBS], use user defined resolver library),
LIBS="$LIBS $withval"
AC_MSG_RESULT("netlib will use \'$withval\'")
fi
+ KRB5_AC_ENABLE_DNS
],dnl
[AC_LIBRARY_NET]
)])dnl

View File

@ -0,0 +1,39 @@
From 56954a72afe83cce5168bc139139d7f74c3685d6 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:49:25 -0400
Subject: [PATCH] krb5-1.9-debuginfo.patch
We want to keep these y.tab.c files around because the debuginfo points to
them. It would be more elegant at the end to use symbolic links, but that
could mess up people working in the tree on other things.
---
src/kadmin/cli/Makefile.in | 5 +++++
src/plugins/kdb/ldap/ldap_util/Makefile.in | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/kadmin/cli/Makefile.in b/src/kadmin/cli/Makefile.in
index adfea6e2b..d1327e400 100644
--- a/src/kadmin/cli/Makefile.in
+++ b/src/kadmin/cli/Makefile.in
@@ -37,3 +37,8 @@ clean-unix::
# CC_LINK is not meant for compilation and this use may break in the future.
datetest: getdate.c
$(CC_LINK) $(ALL_CFLAGS) -DTEST -o datetest getdate.c
+
+%.c: %.y
+ $(RM) y.tab.c $@
+ $(YACC.y) $<
+ $(CP) y.tab.c $@
diff --git a/src/plugins/kdb/ldap/ldap_util/Makefile.in b/src/plugins/kdb/ldap/ldap_util/Makefile.in
index 8669c2436..a22f23c02 100644
--- a/src/plugins/kdb/ldap/ldap_util/Makefile.in
+++ b/src/plugins/kdb/ldap/ldap_util/Makefile.in
@@ -20,7 +20,7 @@ $(PROG): $(OBJS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIB) $(GETDATE)
getdate.c: $(GETDATE)
$(RM) getdate.c y.tab.c
$(YACC) $(GETDATE)
- $(MV) y.tab.c getdate.c
+ $(CP) y.tab.c getdate.c
install:
$(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(ADMIN_BINDIR)/$(PROG)

View File

@ -0,0 +1 @@
d /var/run/krb5kdc 0755 root root

28
SOURCES/krb5.conf Normal file
View File

@ -0,0 +1,28 @@
# To opt out of the system crypto-policies configuration of krb5, remove the
# symlink at /etc/krb5.conf.d/crypto-policies which will not be recreated.
includedir /etc/krb5.conf.d/
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
dns_lookup_realm = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
rdns = false
pkinit_anchors = FILE:/etc/pki/tls/certs/ca-bundle.crt
spake_preauth_groups = edwards25519
# default_realm = EXAMPLE.COM
[realms]
# EXAMPLE.COM = {
# kdc = kerberos.example.com
# admin_server = kerberos.example.com
# }
[domain_realm]
# .example.com = EXAMPLE.COM
# example.com = EXAMPLE.COM

View File

@ -0,0 +1,9 @@
/var/log/krb5kdc.log {
missingok
notifempty
monthly
rotate 12
postrotate
/bin/kill -HUP `cat /var/run/krb5kdc.pid 2>/dev/null` 2> /dev/null || true
endscript
}

14
SOURCES/krb5kdc.service Normal file
View File

@ -0,0 +1,14 @@
[Unit]
Description=Kerberos 5 KDC
Wants=network-online.target
After=syslog.target network.target network-online.target
[Service]
Type=forking
PIDFile=/var/run/krb5kdc.pid
EnvironmentFile=-/etc/sysconfig/krb5kdc
ExecStart=/usr/sbin/krb5kdc -P /var/run/krb5kdc.pid $KRB5KDC_ARGS
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1 @@
KRB5KDC_ARGS=

4
SOURCES/ksu.pamd Normal file
View File

@ -0,0 +1,4 @@
#%PAM-1.0
auth include su
account include su
session include su

3657
SPECS/krb5.spec Normal file

File diff suppressed because it is too large Load Diff