Resolves: rhbz#1369130 - nss_sss should not link against libpthread

Resolves: rhbz#1392916 - sssd failes to start after update
Resolves: rhbz#1398789 - SELinux is preventing sssd from 'write' accesses
                           on the directory /etc/sssd
This commit is contained in:
Lukas Slebodnik 2016-12-13 20:09:35 +01:00
parent 85427c072c
commit eb6c560542
43 changed files with 5372 additions and 1 deletions

View File

@ -0,0 +1,728 @@
From 805494c6ffec6831753891c507a773f3e43b30e5 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 17 Oct 2016 15:44:20 +0200
Subject: [PATCH 01/39] crypto: Port libcrypto code to openssl-1.1
EVP_MD_CTX and EVP_CIPHER_CTX are opaque in openssl-1.1
Reviewed-by: Tomas Mraz <tmraz@redhat.com>
(cherry picked from commit 8f1316a0c677f211eaaa1346e21a03446b8c4fb1)
(cherry picked from commit 81ebd058ab8f6ab08b05a7e35e04881812404d43)
---
Makefile.am | 1 +
src/util/cert/libcrypto/cert.c | 23 ++++++--
src/util/crypto/libcrypto/crypto_hmac_sha1.c | 33 ++++++-----
src/util/crypto/libcrypto/crypto_nite.c | 76 +++++++++++++++----------
src/util/crypto/libcrypto/crypto_obfuscate.c | 32 +++++++----
src/util/crypto/libcrypto/crypto_sha512crypt.c | 77 +++++++++++++++-----------
src/util/crypto/libcrypto/sss_openssl.h | 39 +++++++++++++
7 files changed, 190 insertions(+), 91 deletions(-)
create mode 100644 src/util/crypto/libcrypto/sss_openssl.h
diff --git a/Makefile.am b/Makefile.am
index b5f300a37..3d3500918 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -565,6 +565,7 @@ endif
dist_noinst_HEADERS = \
src/monitor/monitor.h \
src/util/crypto/sss_crypto.h \
+ src/util/crypto/libcrypto/sss_openssl.h \
src/util/cert.h \
src/util/dlinklist.h \
src/util/debug.h \
diff --git a/src/util/cert/libcrypto/cert.c b/src/util/cert/libcrypto/cert.c
index a7752d7c1..aba598d7c 100644
--- a/src/util/cert/libcrypto/cert.c
+++ b/src/util/cert/libcrypto/cert.c
@@ -182,6 +182,8 @@ errno_t cert_to_ssh_key(TALLOC_CTX *mem_ctx, const char *ca_db,
size_t c;
X509 *cert = NULL;
EVP_PKEY *cert_pub_key = NULL;
+ const BIGNUM *n;
+ const BIGNUM *e;
int modulus_len;
unsigned char modulus[OPENSSL_RSA_MAX_MODULUS_BITS/8];
int exponent_len;
@@ -208,16 +210,29 @@ errno_t cert_to_ssh_key(TALLOC_CTX *mem_ctx, const char *ca_db,
goto done;
}
- if (cert_pub_key->type != EVP_PKEY_RSA) {
+ if (EVP_PKEY_base_id(cert_pub_key) != EVP_PKEY_RSA) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Expected RSA public key, found unsupported [%d].\n",
- cert_pub_key->type);
+ EVP_PKEY_base_id(cert_pub_key));
ret = EINVAL;
goto done;
}
- modulus_len = BN_bn2bin(cert_pub_key->pkey.rsa->n, modulus);
- exponent_len = BN_bn2bin(cert_pub_key->pkey.rsa->e, exponent);
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ RSA *rsa_pub_key = NULL;
+ rsa_pub_key = EVP_PKEY_get0_RSA(cert_pub_key);
+ if (rsa_pub_key == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ RSA_get0_key(rsa_pub_key, &n, &e, NULL);
+#else
+ n = cert_pub_key->pkey.rsa->n;
+ e = cert_pub_key->pkey.rsa->e;
+#endif
+ modulus_len = BN_bn2bin(n, modulus);
+ exponent_len = BN_bn2bin(e, exponent);
size = SSH_RSA_HEADER_LEN + 3 * sizeof(uint32_t)
+ modulus_len
diff --git a/src/util/crypto/libcrypto/crypto_hmac_sha1.c b/src/util/crypto/libcrypto/crypto_hmac_sha1.c
index 37d25794e..5a4ce356e 100644
--- a/src/util/crypto/libcrypto/crypto_hmac_sha1.c
+++ b/src/util/crypto/libcrypto/crypto_hmac_sha1.c
@@ -24,6 +24,8 @@
#include <openssl/evp.h>
+#include "sss_openssl.h"
+
#define HMAC_SHA1_BLOCKSIZE 64
int sss_hmac_sha1(const unsigned char *key,
@@ -33,23 +35,26 @@ int sss_hmac_sha1(const unsigned char *key,
unsigned char *out)
{
int ret;
- EVP_MD_CTX ctx;
+ EVP_MD_CTX *ctx;
unsigned char ikey[HMAC_SHA1_BLOCKSIZE], okey[HMAC_SHA1_BLOCKSIZE];
size_t i;
unsigned char hash[SSS_SHA1_LENGTH];
unsigned int res_len;
- EVP_MD_CTX_init(&ctx);
+ ctx = EVP_MD_CTX_new();
+ if (ctx == NULL) {
+ return ENOMEM;
+ }
if (key_len > HMAC_SHA1_BLOCKSIZE) {
/* keys longer than blocksize are shortened */
- if (!EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL)) {
+ if (!EVP_DigestInit_ex(ctx, EVP_sha1(), NULL)) {
ret = EIO;
goto done;
}
- EVP_DigestUpdate(&ctx, (const unsigned char *)key, key_len);
- EVP_DigestFinal_ex(&ctx, ikey, &res_len);
+ EVP_DigestUpdate(ctx, (const unsigned char *)key, key_len);
+ EVP_DigestFinal_ex(ctx, ikey, &res_len);
memset(ikey + SSS_SHA1_LENGTH, 0, HMAC_SHA1_BLOCKSIZE - SSS_SHA1_LENGTH);
} else {
/* keys shorter than blocksize are zero-padded */
@@ -63,25 +68,25 @@ int sss_hmac_sha1(const unsigned char *key,
ikey[i] ^= 0x36;
}
- if (!EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL)) {
+ if (!EVP_DigestInit_ex(ctx, EVP_sha1(), NULL)) {
ret = EIO;
goto done;
}
- EVP_DigestUpdate(&ctx, (const unsigned char *)ikey, HMAC_SHA1_BLOCKSIZE);
- EVP_DigestUpdate(&ctx, (const unsigned char *)in, in_len);
- EVP_DigestFinal_ex(&ctx, hash, &res_len);
+ EVP_DigestUpdate(ctx, (const unsigned char *)ikey, HMAC_SHA1_BLOCKSIZE);
+ EVP_DigestUpdate(ctx, (const unsigned char *)in, in_len);
+ EVP_DigestFinal_ex(ctx, hash, &res_len);
- if (!EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL)) {
+ if (!EVP_DigestInit_ex(ctx, EVP_sha1(), NULL)) {
ret = EIO;
goto done;
}
- EVP_DigestUpdate(&ctx, (const unsigned char *)okey, HMAC_SHA1_BLOCKSIZE);
- EVP_DigestUpdate(&ctx, (const unsigned char *)hash, SSS_SHA1_LENGTH);
- EVP_DigestFinal_ex(&ctx, out, &res_len);
+ EVP_DigestUpdate(ctx, (const unsigned char *)okey, HMAC_SHA1_BLOCKSIZE);
+ EVP_DigestUpdate(ctx, (const unsigned char *)hash, SSS_SHA1_LENGTH);
+ EVP_DigestFinal_ex(ctx, out, &res_len);
ret = EOK;
done:
- EVP_MD_CTX_cleanup(&ctx);
+ EVP_MD_CTX_free(ctx);
return ret;
}
diff --git a/src/util/crypto/libcrypto/crypto_nite.c b/src/util/crypto/libcrypto/crypto_nite.c
index fa267fbcc..de562f2d2 100644
--- a/src/util/crypto/libcrypto/crypto_nite.c
+++ b/src/util/crypto/libcrypto/crypto_nite.c
@@ -33,6 +33,8 @@
#include <openssl/rand.h>
#include <openssl/crypto.h>
+#include "sss_openssl.h"
+
struct cipher_mech {
const EVP_CIPHER * (*cipher)(void);
const EVP_MD * (*digest)(void);
@@ -47,9 +49,9 @@ int sss_encrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
{
const EVP_CIPHER *cipher;
const EVP_MD *digest;
- EVP_PKEY *hmackey;
- EVP_CIPHER_CTX ctx;
- EVP_MD_CTX mdctx;
+ EVP_PKEY *hmackey = NULL;
+ EVP_CIPHER_CTX *ctx;
+ EVP_MD_CTX *mdctx = NULL;
uint8_t *out = NULL;
int evpkeylen;
int evpivlen;
@@ -86,8 +88,13 @@ int sss_encrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
RAND_bytes(out, evpivlen);
}
- EVP_CIPHER_CTX_init(&ctx);
- ret = EVP_EncryptInit_ex(&ctx, cipher, 0, key, evpivlen ? out : NULL);
+ ctx = EVP_CIPHER_CTX_new();
+ if (ctx == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = EVP_EncryptInit_ex(ctx, cipher, 0, key, evpivlen ? out : NULL);
if (ret != 1) {
ret = EFAULT;
goto done;
@@ -95,7 +102,7 @@ int sss_encrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
outlen = evpivlen;
tmplen = 0;
- ret = EVP_EncryptUpdate(&ctx, out + outlen, &tmplen, plaintext, plainlen);
+ ret = EVP_EncryptUpdate(ctx, out + outlen, &tmplen, plaintext, plainlen);
if (ret != 1) {
ret = EFAULT;
goto done;
@@ -103,7 +110,7 @@ int sss_encrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
outlen += tmplen;
- ret = EVP_EncryptFinal_ex(&ctx, out + outlen, &tmplen);
+ ret = EVP_EncryptFinal_ex(ctx, out + outlen, &tmplen);
if (ret != 1) {
ret = EFAULT;
goto done;
@@ -113,28 +120,32 @@ int sss_encrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
/* Then HMAC */
- EVP_MD_CTX_init(&mdctx);
+ mdctx = EVP_MD_CTX_new();
+ if (mdctx == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
- ret = EVP_DigestInit_ex(&mdctx, digest, NULL);
+ ret = EVP_DigestInit_ex(mdctx, digest, NULL);
if (ret != 1) {
ret = EFAULT;
goto done;
}
- ret = EVP_DigestSignInit(&mdctx, NULL, digest, NULL, hmackey);
+ ret = EVP_DigestSignInit(mdctx, NULL, digest, NULL, hmackey);
if (ret != 1) {
ret = EFAULT;
goto done;
}
- ret = EVP_DigestSignUpdate(&mdctx, out, outlen);
+ ret = EVP_DigestSignUpdate(mdctx, out, outlen);
if (ret != 1) {
ret = EFAULT;
goto done;
}
slen = hmaclen;
- ret = EVP_DigestSignFinal(&mdctx, &out[outlen], &slen);
+ ret = EVP_DigestSignFinal(mdctx, &out[outlen], &slen);
if (ret != 1) {
ret = EFAULT;
goto done;
@@ -147,8 +158,8 @@ int sss_encrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
ret = EOK;
done:
- EVP_MD_CTX_cleanup(&mdctx);
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_MD_CTX_free(mdctx);
+ EVP_CIPHER_CTX_free(ctx);
EVP_PKEY_free(hmackey);
return ret;
}
@@ -160,9 +171,9 @@ int sss_decrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
{
const EVP_CIPHER *cipher;
const EVP_MD *digest;
- EVP_PKEY *hmackey;
- EVP_CIPHER_CTX ctx;
- EVP_MD_CTX mdctx;
+ EVP_PKEY *hmackey = NULL;
+ EVP_CIPHER_CTX *ctx = NULL;
+ EVP_MD_CTX *mdctx;
const uint8_t *iv = NULL;
uint8_t *out;
int evpkeylen;
@@ -194,28 +205,32 @@ int sss_decrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
/* First check HMAC */
- EVP_MD_CTX_init(&mdctx);
+ mdctx = EVP_MD_CTX_new();
+ if (mdctx == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
- ret = EVP_DigestInit_ex(&mdctx, digest, NULL);
+ ret = EVP_DigestInit_ex(mdctx, digest, NULL);
if (ret != 1) {
ret = EFAULT;
goto done;
}
- ret = EVP_DigestSignInit(&mdctx, NULL, digest, NULL, hmackey);
+ ret = EVP_DigestSignInit(mdctx, NULL, digest, NULL, hmackey);
if (ret != 1) {
ret = EFAULT;
goto done;
}
- ret = EVP_DigestSignUpdate(&mdctx, ciphertext, cipherlen - hmaclen);
+ ret = EVP_DigestSignUpdate(mdctx, ciphertext, cipherlen - hmaclen);
if (ret != 1) {
ret = EFAULT;
goto done;
}
slen = hmaclen;
- ret = EVP_DigestSignFinal(&mdctx, out, &slen);
+ ret = EVP_DigestSignFinal(mdctx, out, &slen);
if (ret != 1) {
ret = EFAULT;
goto done;
@@ -233,14 +248,19 @@ int sss_decrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
iv = ciphertext;
}
- EVP_CIPHER_CTX_init(&ctx);
- ret = EVP_DecryptInit_ex(&ctx, cipher, 0, key, iv);
+ ctx = EVP_CIPHER_CTX_new();
+ if (ctx == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = EVP_DecryptInit_ex(ctx, cipher, 0, key, iv);
if (ret != 1) {
ret = EFAULT;
goto done;
}
- ret = EVP_DecryptUpdate(&ctx, out, &outlen,
+ ret = EVP_DecryptUpdate(ctx, out, &outlen,
ciphertext + evpivlen,
cipherlen - evpivlen - hmaclen);
if (ret != 1) {
@@ -248,7 +268,7 @@ int sss_decrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
goto done;
}
- ret = EVP_DecryptFinal_ex(&ctx, out + outlen, &tmplen);
+ ret = EVP_DecryptFinal_ex(ctx, out + outlen, &tmplen);
if (ret != 1) {
ret = EFAULT;
goto done;
@@ -261,8 +281,8 @@ int sss_decrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
ret = EOK;
done:
- EVP_MD_CTX_cleanup(&mdctx);
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_MD_CTX_free(mdctx);
+ EVP_CIPHER_CTX_free(ctx);
EVP_PKEY_free(hmackey);
return ret;
}
diff --git a/src/util/crypto/libcrypto/crypto_obfuscate.c b/src/util/crypto/libcrypto/crypto_obfuscate.c
index 85de333ec..69b622e1d 100644
--- a/src/util/crypto/libcrypto/crypto_obfuscate.c
+++ b/src/util/crypto/libcrypto/crypto_obfuscate.c
@@ -70,7 +70,7 @@ int sss_password_encrypt(TALLOC_CTX *mem_ctx, const char *password, int plen,
enum obfmethod meth, char **obfpwd)
{
int ret;
- EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX *ctx;
struct crypto_mech_data *mech_props;
TALLOC_CTX *tmp_ctx = NULL;
unsigned char *keybuf;
@@ -90,7 +90,11 @@ int sss_password_encrypt(TALLOC_CTX *mem_ctx, const char *password, int plen,
return ENOMEM;
}
- EVP_CIPHER_CTX_init(&ctx);
+ ctx = EVP_CIPHER_CTX_new();
+ if (ctx == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
mech_props = get_crypto_mech_data(meth);
if (mech_props == NULL) {
@@ -121,20 +125,20 @@ int sss_password_encrypt(TALLOC_CTX *mem_ctx, const char *password, int plen,
goto done;
}
- if (!EVP_EncryptInit_ex(&ctx, mech_props->cipher(), 0, keybuf, ivbuf)) {
+ if (!EVP_EncryptInit_ex(ctx, mech_props->cipher(), 0, keybuf, ivbuf)) {
DEBUG(SSSDBG_CRIT_FAILURE, "Failure to initialize cipher contex\n");
ret = EIO;
goto done;
}
/* sample data we'll encrypt and decrypt */
- if (!EVP_EncryptUpdate(&ctx, cryptotext, &ctlen, (const unsigned char*)password, plen)) {
+ if (!EVP_EncryptUpdate(ctx, cryptotext, &ctlen, (const unsigned char *)password, plen)) {
DEBUG(SSSDBG_CRIT_FAILURE, "Cannot execute the encryption operation\n");
ret = EIO;
goto done;
}
- if(!EVP_EncryptFinal_ex(&ctx, cryptotext+ctlen, &digestlen)) {
+ if (!EVP_EncryptFinal_ex(ctx, cryptotext + ctlen, &digestlen)) {
DEBUG(SSSDBG_CRIT_FAILURE, "Cannot finialize the encryption operation\n");
ret = EIO;
goto done;
@@ -185,7 +189,7 @@ int sss_password_encrypt(TALLOC_CTX *mem_ctx, const char *password, int plen,
done:
talloc_free(tmp_ctx);
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_CIPHER_CTX_free(ctx);
return ret;
}
@@ -193,7 +197,7 @@ int sss_password_decrypt(TALLOC_CTX *mem_ctx, char *b64encoded,
char **password)
{
int ret;
- EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX *ctx;
TALLOC_CTX *tmp_ctx = NULL;
struct crypto_mech_data *mech_props;
@@ -217,7 +221,11 @@ int sss_password_decrypt(TALLOC_CTX *mem_ctx, char *b64encoded,
return ENOMEM;
}
- EVP_CIPHER_CTX_init(&ctx);
+ ctx = EVP_CIPHER_CTX_new();
+ if (ctx == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
/* Base64 decode the incoming buffer */
obfbuf = sss_base64_decode(tmp_ctx, b64encoded, &obflen);
@@ -276,18 +284,18 @@ int sss_password_decrypt(TALLOC_CTX *mem_ctx, char *b64encoded,
goto done;
}
- if (!EVP_DecryptInit_ex(&ctx, mech_props->cipher(), 0, keybuf, ivbuf)) {
+ if (!EVP_DecryptInit_ex(ctx, mech_props->cipher(), 0, keybuf, ivbuf)) {
ret = EIO;
goto done;
}
/* sample data we'll encrypt and decrypt */
- if (!EVP_DecryptUpdate(&ctx, (unsigned char*)pwdbuf, &plainlen, cryptotext, ctsize)) {
+ if (!EVP_DecryptUpdate(ctx, (unsigned char *)pwdbuf, &plainlen, cryptotext, ctsize)) {
ret = EIO;
goto done;
}
- if(!EVP_DecryptFinal_ex(&ctx, (unsigned char*)pwdbuf+plainlen, &digestlen)) {
+ if (!EVP_DecryptFinal_ex(ctx, (unsigned char *)pwdbuf + plainlen, &digestlen)) {
ret = EIO;
goto done;
}
@@ -296,6 +304,6 @@ int sss_password_decrypt(TALLOC_CTX *mem_ctx, char *b64encoded,
ret = EOK;
done:
talloc_free(tmp_ctx);
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_CIPHER_CTX_free(ctx);
return ret;
}
diff --git a/src/util/crypto/libcrypto/crypto_sha512crypt.c b/src/util/crypto/libcrypto/crypto_sha512crypt.c
index 34547d08a..102356662 100644
--- a/src/util/crypto/libcrypto/crypto_sha512crypt.c
+++ b/src/util/crypto/libcrypto/crypto_sha512crypt.c
@@ -28,6 +28,9 @@
#include <openssl/evp.h>
#include <openssl/rand.h>
+#include "sss_openssl.h"
+
+
/* Define our magic string to mark salt for SHA512 "encryption" replacement. */
const char sha512_salt_prefix[] = "$6$";
#define SALT_PREF_SIZE (sizeof(sha512_salt_prefix) - 1)
@@ -75,8 +78,8 @@ static int sha512_crypt_r(const char *key,
unsigned char alt_result[64] __attribute__((__aligned__(ALIGN64)));
size_t rounds = ROUNDS_DEFAULT;
bool rounds_custom = false;
- EVP_MD_CTX alt_ctx;
- EVP_MD_CTX ctx;
+ EVP_MD_CTX *alt_ctx = NULL;
+ EVP_MD_CTX *ctx;
size_t salt_len;
size_t key_len;
size_t cnt;
@@ -125,75 +128,83 @@ static int sha512_crypt_r(const char *key,
salt = copied_salt = memcpy(tmp + ALIGN64 - PTR_2_INT(tmp) % ALIGN64, salt, salt_len);
}
- EVP_MD_CTX_init(&ctx);
+ ctx = EVP_MD_CTX_new();
+ if (ctx == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
- EVP_MD_CTX_init(&alt_ctx);
+ alt_ctx = EVP_MD_CTX_new();
+ if (alt_ctx == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
/* Prepare for the real work. */
- if (!EVP_DigestInit_ex(&ctx, EVP_sha512(), NULL)) {
+ if (!EVP_DigestInit_ex(ctx, EVP_sha512(), NULL)) {
ret = EIO;
goto done;
}
/* Add the key string. */
- EVP_DigestUpdate(&ctx, (const unsigned char *)key, key_len);
+ EVP_DigestUpdate(ctx, (const unsigned char *)key, key_len);
/* The last part is the salt string. This must be at most 16
* characters and it ends at the first `$' character (for
* compatibility with existing implementations). */
- EVP_DigestUpdate(&ctx, (const unsigned char *)salt, salt_len);
+ EVP_DigestUpdate(ctx, (const unsigned char *)salt, salt_len);
/* Compute alternate SHA512 sum with input KEY, SALT, and KEY.
* The final result will be added to the first context. */
- if (!EVP_DigestInit_ex(&alt_ctx, EVP_sha512(), NULL)) {
+ if (!EVP_DigestInit_ex(alt_ctx, EVP_sha512(), NULL)) {
ret = EIO;
goto done;
}
/* Add key. */
- EVP_DigestUpdate(&alt_ctx, (const unsigned char *)key, key_len);
+ EVP_DigestUpdate(alt_ctx, (const unsigned char *)key, key_len);
/* Add salt. */
- EVP_DigestUpdate(&alt_ctx, (const unsigned char *)salt, salt_len);
+ EVP_DigestUpdate(alt_ctx, (const unsigned char *)salt, salt_len);
/* Add key again. */
- EVP_DigestUpdate(&alt_ctx, (const unsigned char *)key, key_len);
+ EVP_DigestUpdate(alt_ctx, (const unsigned char *)key, key_len);
/* Now get result of this (64 bytes) and add it to the other context. */
- EVP_DigestFinal_ex(&alt_ctx, alt_result, &part);
+ EVP_DigestFinal_ex(alt_ctx, alt_result, &part);
/* Add for any character in the key one byte of the alternate sum. */
for (cnt = key_len; cnt > 64; cnt -= 64) {
- EVP_DigestUpdate(&ctx, alt_result, 64);
+ EVP_DigestUpdate(ctx, alt_result, 64);
}
- EVP_DigestUpdate(&ctx, alt_result, cnt);
+ EVP_DigestUpdate(ctx, alt_result, cnt);
/* Take the binary representation of the length of the key and for every
* 1 add the alternate sum, for every 0 the key. */
for (cnt = key_len; cnt > 0; cnt >>= 1) {
if ((cnt & 1) != 0) {
- EVP_DigestUpdate(&ctx, alt_result, 64);
+ EVP_DigestUpdate(ctx, alt_result, 64);
} else {
- EVP_DigestUpdate(&ctx, (const unsigned char *)key, key_len);
+ EVP_DigestUpdate(ctx, (const unsigned char *)key, key_len);
}
}
/* Create intermediate result. */
- EVP_DigestFinal_ex(&ctx, alt_result, &part);
+ EVP_DigestFinal_ex(ctx, alt_result, &part);
/* Start computation of P byte sequence. */
- if (!EVP_DigestInit_ex(&alt_ctx, EVP_sha512(), NULL)) {
+ if (!EVP_DigestInit_ex(alt_ctx, EVP_sha512(), NULL)) {
ret = EIO;
goto done;
}
/* For every character in the password add the entire password. */
for (cnt = 0; cnt < key_len; cnt++) {
- EVP_DigestUpdate(&alt_ctx, (const unsigned char *)key, key_len);
+ EVP_DigestUpdate(alt_ctx, (const unsigned char *)key, key_len);
}
/* Finish the digest. */
- EVP_DigestFinal_ex(&alt_ctx, temp_result, &part);
+ EVP_DigestFinal_ex(alt_ctx, temp_result, &part);
/* Create byte sequence P. */
cp = p_bytes = alloca(key_len);
@@ -203,18 +214,18 @@ static int sha512_crypt_r(const char *key,
memcpy(cp, temp_result, cnt);
/* Start computation of S byte sequence. */
- if (!EVP_DigestInit_ex(&alt_ctx, EVP_sha512(), NULL)) {
+ if (!EVP_DigestInit_ex(alt_ctx, EVP_sha512(), NULL)) {
ret = EIO;
goto done;
}
/* For every character in the password add the entire salt. */
for (cnt = 0; cnt < 16 + alt_result[0]; cnt++) {
- EVP_DigestUpdate(&alt_ctx, (const unsigned char *)salt, salt_len);
+ EVP_DigestUpdate(alt_ctx, (const unsigned char *)salt, salt_len);
}
/* Finish the digest. */
- EVP_DigestFinal_ex(&alt_ctx, temp_result, &part);
+ EVP_DigestFinal_ex(alt_ctx, temp_result, &part);
/* Create byte sequence S. */
cp = s_bytes = alloca(salt_len);
@@ -226,37 +237,37 @@ static int sha512_crypt_r(const char *key,
/* Repeatedly run the collected hash value through SHA512 to burn CPU cycles. */
for (cnt = 0; cnt < rounds; cnt++) {
- if (!EVP_DigestInit_ex(&ctx, EVP_sha512(), NULL)) {
+ if (!EVP_DigestInit_ex(ctx, EVP_sha512(), NULL)) {
ret = EIO;
goto done;
}
/* Add key or last result. */
if ((cnt & 1) != 0) {
- EVP_DigestUpdate(&ctx, (const unsigned char *)p_bytes, key_len);
+ EVP_DigestUpdate(ctx, (const unsigned char *)p_bytes, key_len);
} else {
- EVP_DigestUpdate(&ctx, alt_result, 64);
+ EVP_DigestUpdate(ctx, alt_result, 64);
}
/* Add salt for numbers not divisible by 3. */
if (cnt % 3 != 0) {
- EVP_DigestUpdate(&ctx, (const unsigned char *)s_bytes, salt_len);
+ EVP_DigestUpdate(ctx, (const unsigned char *)s_bytes, salt_len);
}
/* Add key for numbers not divisible by 7. */
if (cnt % 7 != 0) {
- EVP_DigestUpdate(&ctx, (const unsigned char *)p_bytes, key_len);
+ EVP_DigestUpdate(ctx, (const unsigned char *)p_bytes, key_len);
}
/* Add key or last result. */
if ((cnt & 1) != 0) {
- EVP_DigestUpdate(&ctx, alt_result, 64);
+ EVP_DigestUpdate(ctx, alt_result, 64);
} else {
- EVP_DigestUpdate(&ctx, (const unsigned char *)p_bytes, key_len);
+ EVP_DigestUpdate(ctx, (const unsigned char *)p_bytes, key_len);
}
/* Create intermediate result. */
- EVP_DigestFinal_ex(&ctx, alt_result, &part);
+ EVP_DigestFinal_ex(ctx, alt_result, &part);
}
/* Now we can construct the result string.
@@ -318,8 +329,8 @@ done:
* to processes or reading core dumps cannot get any information. We do it
* in this way to clear correct_words[] inside the SHA512 implementation
* as well. */
- EVP_MD_CTX_cleanup(&ctx);
- EVP_MD_CTX_cleanup(&alt_ctx);
+ EVP_MD_CTX_free(ctx);
+ EVP_MD_CTX_free(alt_ctx);
if (p_bytes) memset(p_bytes, '\0', key_len);
if (s_bytes) memset(s_bytes, '\0', salt_len);
if (copied_key) memset(copied_key, '\0', key_len);
diff --git a/src/util/crypto/libcrypto/sss_openssl.h b/src/util/crypto/libcrypto/sss_openssl.h
new file mode 100644
index 000000000..a2e2d8523
--- /dev/null
+++ b/src/util/crypto/libcrypto/sss_openssl.h
@@ -0,0 +1,39 @@
+/*
+ Authors:
+ Lukas Slebodnik <lslebodn@redhat.com>
+
+ Copyright (C) 2016 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SSS_LIBCRYTPO_SSS_OPENSSL_H_
+#define _SSS_LIBCRYTPO_SSS_OPENSSL_H_
+
+#include <openssl/evp.h>
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
+/* EVP_MD_CTX_create and EVP_MD_CTX_destroy are deprecated macros
+ * in openssl-1.1 but openssl-1.0 does not know anything about
+ * newly added functions EVP_MD_CTX_new, EVP_MD_CTX_free in 1.1
+ */
+
+# define EVP_MD_CTX_new() EVP_MD_CTX_create()
+# define EVP_MD_CTX_free(ctx) EVP_MD_CTX_destroy((ctx))
+
+#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+
+
+#endif /* _SSS_LIBCRYTPO_SSS_OPENSSL_H_ */
--
2.11.0

View File

@ -0,0 +1,32 @@
From 5a6aeb890bdf18729e45cd08cfa244e3da4ed45b Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 19 Oct 2016 16:46:44 +0200
Subject: [PATCH 02/39] libcrypto: Check right value of CRYPTO_memcmp
sss_decrypt failed even though should pass because
we were checking wrong value of CRYPTO_memcmp.
Nobody noticed that because there was not a unit test :-)
Reviewed-by: Christian Heimes <cheimes@redhat.com>
(cherry picked from commit 0c2be9700d3b54db33c1a3dd5d230b34bfaceb50)
(cherry picked from commit f4da46bd77f2eed2d04152b75c78bfc561c79354)
---
src/util/crypto/libcrypto/crypto_nite.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/util/crypto/libcrypto/crypto_nite.c b/src/util/crypto/libcrypto/crypto_nite.c
index de562f2d2..e863d3fc9 100644
--- a/src/util/crypto/libcrypto/crypto_nite.c
+++ b/src/util/crypto/libcrypto/crypto_nite.c
@@ -237,7 +237,7 @@ int sss_decrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
}
ret = CRYPTO_memcmp(&ciphertext[cipherlen - hmaclen], out, hmaclen);
- if (ret != 1) {
+ if (ret != 0) {
ret = EFAULT;
goto done;
}
--
2.11.0

View File

@ -0,0 +1,78 @@
From 398f89119f9e852df3beec3644420057746dbfd1 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 19 Oct 2016 16:38:27 +0200
Subject: [PATCH 03/39] crypto-tests: Add unit test for sss_encrypt +
sss_decrypt
Reviewed-by: Christian Heimes <cheimes@redhat.com>
(cherry picked from commit 65c85654d9b32a866caa01c28fe743eeb0bdef67)
(cherry picked from commit 8cb41367912a50d6d9309f82b718af90032d0f02)
---
src/tests/crypto-tests.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/src/tests/crypto-tests.c b/src/tests/crypto-tests.c
index ee807c6bc..a4074e474 100644
--- a/src/tests/crypto-tests.c
+++ b/src/tests/crypto-tests.c
@@ -158,6 +158,49 @@ START_TEST(test_base64_decode)
}
END_TEST
+START_TEST(test_sss_encrypt_decrypt)
+{
+ uint8_t key[] = {
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
+ 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
+ };
+ size_t key_len = sizeof(key); /* need to be 32 */
+ const char input_text[] = "Secret text";
+ const size_t input_text_len = sizeof(input_text) - 1;
+ uint8_t *cipher_text;
+ size_t cipher_text_len;
+ uint8_t *plain_text;
+ size_t plain_text_len;
+ int ret;
+
+ test_ctx = talloc_new(NULL);
+ fail_if(test_ctx == NULL);
+
+ ret = sss_encrypt(test_ctx, AES256CBC_HMAC_SHA256, key, key_len,
+ (const uint8_t *)input_text, input_text_len,
+ &cipher_text, &cipher_text_len);
+
+ fail_if(ret != 0);
+ fail_if(cipher_text_len == 0);
+
+ ret = memcmp(input_text, cipher_text, input_text_len);
+ fail_if(ret == 0, "Input and encrypted text has common prefix");
+
+ ret = sss_decrypt(test_ctx, AES256CBC_HMAC_SHA256, key, key_len,
+ cipher_text, cipher_text_len,
+ &plain_text, &plain_text_len);
+ fail_if(ret != 0);
+ fail_if(plain_text_len != input_text_len);
+
+ ret = memcmp(plain_text, input_text, input_text_len);
+ fail_if(ret != 0, "input text is not the same as de-encrypted text");
+
+ talloc_free(test_ctx);
+}
+END_TEST
+
Suite *crypto_suite(void)
{
Suite *s = suite_create("sss_crypto");
@@ -172,6 +215,7 @@ Suite *crypto_suite(void)
tcase_add_test(tc, test_hmac_sha1);
tcase_add_test(tc, test_base64_encode);
tcase_add_test(tc, test_base64_decode);
+ tcase_add_test(tc, test_sss_encrypt_decrypt);
/* Add all test cases to the test suite */
suite_add_tcase(s, tc);
--
2.11.0

View File

@ -0,0 +1,44 @@
From bb53631c770d287dfc9b130754ce3f9320c8b3d4 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 19 Oct 2016 16:55:37 +0200
Subject: [PATCH 04/39] crypto-tests: Rename encrypt decrypt test case
libsss_crypto provide 2 pairs of encrypt + decrypt functions.
sss_password_encrypt + sss_password_decrypt and more generic
sss_encrypt + sss_decrypt.
The name of one test case was a little bit confusing.
It evokes that different pair of functions were tested.
Reviewed-by: Christian Heimes <cheimes@redhat.com>
(cherry picked from commit 96d239e83e671b82525cec760cf0bcaa5ee1c249)
(cherry picked from commit 579daa9099acf848e1062a48a7cd3a5e923da349)
---
src/tests/crypto-tests.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/tests/crypto-tests.c b/src/tests/crypto-tests.c
index a4074e474..c7f0edbb3 100644
--- a/src/tests/crypto-tests.c
+++ b/src/tests/crypto-tests.c
@@ -48,7 +48,7 @@ START_TEST(test_nss_init)
END_TEST
#endif
-START_TEST(test_encrypt_decrypt)
+START_TEST(test_sss_password_encrypt_decrypt)
{
const char *password[] = { "test123", /* general */
"12345678901234567", /* just above blocksize */
@@ -211,7 +211,7 @@ Suite *crypto_suite(void)
#ifdef HAVE_NSS
tcase_add_test(tc, test_nss_init);
#endif
- tcase_add_test(tc, test_encrypt_decrypt);
+ tcase_add_test(tc, test_sss_password_encrypt_decrypt);
tcase_add_test(tc, test_hmac_sha1);
tcase_add_test(tc, test_base64_encode);
tcase_add_test(tc, test_base64_decode);
--
2.11.0

View File

@ -0,0 +1,46 @@
From 30b240137ea5c8e6927b9a4f93813735a2a477ae Mon Sep 17 00:00:00 2001
From: Sorah Fukumori <her@sorah.jp>
Date: Sun, 23 Oct 2016 01:43:05 +0900
Subject: [PATCH 05/39] BUILD: Fix installation without samba
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
winbindplugindir is defined only when BUILD_SAMBA is on. Also the file
doesn't exist when BUILD_SAMBA is off, so installation will fail.
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit 13adcd07000ba3ca1422c6ee863df17d70e2b14c)
(cherry picked from commit 1fb3cccd83ede1bbe99319254c88fce1285b352d)
---
Makefile.am | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index 3d3500918..d08e39fa4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4130,7 +4130,9 @@ install-data-hook:
if [ ! $(krb5rcachedir) = "__LIBKRB5_DEFAULTS__" ]; then \
$(MKDIR_P) $(DESTDIR)/$(krb5rcachedir) ; \
fi
+if BUILD_SAMBA
mv $(DESTDIR)/$(winbindplugindir)/winbind_idmap_sss.so $(DESTDIR)/$(winbindplugindir)/sss.so
+endif
uninstall-hook:
if [ -f $(abs_builddir)/src/config/.files2 ]; then \
@@ -4152,7 +4154,9 @@ if BUILD_PYTHON3_BINDINGS
cd $(DESTDIR)$(py3execdir) && \
rm -f pysss.so pyhbac.so pysss_murmur.so pysss_nss_idmap.so
endif
+if BUILD_SAMBA
rm $(DESTDIR)/$(winbindplugindir)/sss.so
+endif
clean-local:
if BUILD_PYTHON2_BINDINGS
--
2.11.0

View File

@ -0,0 +1,29 @@
From fe1591bf812979074f11493c74ee87efa6b92609 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 24 Oct 2016 10:03:32 +0000
Subject: [PATCH 06/39] BUILD: Accept krb5 1.15 for building the PAC plugin
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 11d2a1183d7017f3d453d0a7046004b6968fefb5)
(cherry picked from commit 6a96323fb511565908a5a7ce7b1d6e0d40aa647d)
---
src/external/pac_responder.m4 | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/external/pac_responder.m4 b/src/external/pac_responder.m4
index 928b1d295..6b400d47c 100644
--- a/src/external/pac_responder.m4
+++ b/src/external/pac_responder.m4
@@ -16,7 +16,8 @@ then
Kerberos\ 5\ release\ 1.11* | \
Kerberos\ 5\ release\ 1.12* | \
Kerberos\ 5\ release\ 1.13* | \
- Kerberos\ 5\ release\ 1.14*)
+ Kerberos\ 5\ release\ 1.14* | \
+ Kerberos\ 5\ release\ 1.15*)
krb5_version_ok=yes
AC_MSG_RESULT([yes])
;;
--
2.11.0

View File

@ -0,0 +1,41 @@
From 00efc45a2f2784b8f7bbd823dd7de6b9201d69b1 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 17 Oct 2016 21:39:57 +0200
Subject: [PATCH 07/39] dlopen-test: Use portable macro for location of .libs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Petr Čech <pcech@redhat.com>
(cherry picked from commit bacc66dc6f446d47be18b61d569721481d70386b)
(cherry picked from commit a64409a528257ee0706cc12a1b974a159edac041)
---
src/tests/dlopen-tests.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/tests/dlopen-tests.c b/src/tests/dlopen-tests.c
index 96cc4db9b..6e37dbed1 100644
--- a/src/tests/dlopen-tests.c
+++ b/src/tests/dlopen-tests.c
@@ -22,7 +22,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#define _GNU_SOURCE
+#include "config.h"
+
#include <stdbool.h>
#include <dlfcn.h>
#include <stdio.h>
@@ -31,7 +32,7 @@
#include <check.h>
#include "tests/common.h"
-#define LIBPFX ABS_BUILD_DIR"/.libs/"
+#define LIBPFX ABS_BUILD_DIR "/" LT_OBJDIR
struct so {
const char *name;
--
2.11.0

View File

@ -0,0 +1,53 @@
From f60c6cec2a432222308d5b6b05ee7e2f93c16bb0 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 17 Oct 2016 21:59:18 +0200
Subject: [PATCH 08/39] dlopen-test: Add missing libraries to the check list
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
nfsidmap plugin(sss.so) and libsss_cert.so were not checked.
Few libraries which are build for testing purposes were added to the list
otherwise we would not be able to detect unchecked libraries.
Reviewed-by: Petr Čech <pcech@redhat.com>
(cherry picked from commit 558b8f3cd2439c01e139cf5f812aea9409fe776a)
(cherry picked from commit 9b972260cb805e3537ab9464ef5347348792d7cf)
---
src/tests/dlopen-tests.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/src/tests/dlopen-tests.c b/src/tests/dlopen-tests.c
index 6e37dbed1..c980ab9f1 100644
--- a/src/tests/dlopen-tests.c
+++ b/src/tests/dlopen-tests.c
@@ -78,6 +78,7 @@ struct so {
{ "libsss_child.so", { LIBPFX"libsss_util.so",
LIBPFX"libsss_child.so", NULL } },
{ "libsss_crypt.so", { LIBPFX"libsss_crypt.so", NULL } },
+ { "libsss_cert.so", { LIBPFX"libsss_cert.so", NULL } },
{ "libsss_util.so", { LIBPFX"libsss_util.so", NULL } },
{ "libsss_simple.so", { LIBPFX"libdlopen_test_providers.so",
LIBPFX"libsss_simple.so", NULL } },
@@ -114,6 +115,18 @@ struct so {
#ifdef HAVE_CONFIG_LIB
{ "libsss_config.so", { LIBPFX"libsss_config.so", NULL } },
#endif
+#ifdef BUILD_NFS_IDMAP
+ { "sss.so", { LIBPFX"sss.so", NULL } },
+#endif
+ /* for testing purposes */
+ { "libsss_nss_idmap_tests.so", { LIBPFX"libsss_nss_idmap_tests.so",
+ NULL } },
+#ifdef BUILD_SAMBA
+ { "libdlopen_test_winbind_idmap.so",
+ { LIBPFX"libdlopen_test_winbind_idmap.so", NULL } },
+ { "libsss_ad_tests.so", { LIBPFX"libdlopen_test_providers.so",
+ LIBPFX"libsss_ad_tests.so", NULL } },
+#endif
{ NULL }
};
--
2.11.0

View File

@ -0,0 +1,63 @@
From 87ef46f4bd0745b13ee49f5487bc8a45ea2f3c1d Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 17 Oct 2016 22:17:27 +0200
Subject: [PATCH 09/39] dlopen-test: Move libraries to the right "sections"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The library winbind_idmap_sss.so is build only when building
with samba. The library libdlopen_test_providers.so was moved
to the group of libraries build for testing purposes.
Reviewed-by: Petr Čech <pcech@redhat.com>
(cherry picked from commit d708e53d0df0c1ed4cc0097bebfa2a84d7b20fad)
(cherry picked from commit a52c7df943a7b685609b66c49264c6d1805d31c2)
---
src/tests/dlopen-tests.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/tests/dlopen-tests.c b/src/tests/dlopen-tests.c
index c980ab9f1..c857dff73 100644
--- a/src/tests/dlopen-tests.c
+++ b/src/tests/dlopen-tests.c
@@ -71,9 +71,6 @@ struct so {
#ifdef HAVE_CIFS_IDMAP_PLUGIN
{ "cifs_idmap_sss.so", { LIBPFX"cifs_idmap_sss.so", NULL } },
#endif
- { "winbind_idmap_sss.so", { LIBPFX"libdlopen_test_winbind_idmap.so",
- LIBPFX"winbind_idmap_sss.so",
- NULL } },
{ "memberof.so", { LIBPFX"memberof.so", NULL } },
{ "libsss_child.so", { LIBPFX"libsss_util.so",
LIBPFX"libsss_child.so", NULL } },
@@ -87,6 +84,8 @@ struct so {
LIBPFX"libsss_ad.so", NULL } },
{ "libsss_ipa.so", { LIBPFX"libdlopen_test_providers.so",
LIBPFX"libsss_ipa.so", NULL } },
+ { "winbind_idmap_sss.so", { LIBPFX"libdlopen_test_winbind_idmap.so",
+ LIBPFX"winbind_idmap_sss.so", NULL } },
#endif /* BUILD_SAMBA */
{ "libsss_krb5.so", { LIBPFX"libdlopen_test_providers.so",
LIBPFX"libsss_krb5.so", NULL } },
@@ -98,8 +97,6 @@ struct so {
LIBPFX"libsss_ldap_common.so", NULL } },
{ "libsss_proxy.so", { LIBPFX"libdlopen_test_providers.so",
LIBPFX"libsss_proxy.so", NULL } },
- { "libdlopen_test_providers.so", { LIBPFX"libdlopen_test_providers.so",
- NULL } },
#ifdef HAVE_PYTHON2_BINDINGS
{ "_py2hbac.so", { LIBPFX"_py2hbac.so", NULL } },
{ "_py2sss.so", { LIBPFX"_py2sss.so", NULL } },
@@ -119,6 +116,8 @@ struct so {
{ "sss.so", { LIBPFX"sss.so", NULL } },
#endif
/* for testing purposes */
+ { "libdlopen_test_providers.so", { LIBPFX"libdlopen_test_providers.so",
+ NULL } },
{ "libsss_nss_idmap_tests.so", { LIBPFX"libsss_nss_idmap_tests.so",
NULL } },
#ifdef BUILD_SAMBA
--
2.11.0

View File

@ -0,0 +1,115 @@
From 916065cfed5ceccfd2ee4127a460b47161c2efd7 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 17 Oct 2016 21:44:18 +0200
Subject: [PATCH 10/39] dlopen-test: Add check for untested libraries
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Petr Čech <pcech@redhat.com>
(cherry picked from commit c7b3c43cf669e39f7ce5f4ef1a2e939b31a8b7b9)
(cherry picked from commit 7251859d8cdb2fc57c969f67ac76904fea331cd0)
---
src/tests/dlopen-tests.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
diff --git a/src/tests/dlopen-tests.c b/src/tests/dlopen-tests.c
index c857dff73..520c91f63 100644
--- a/src/tests/dlopen-tests.c
+++ b/src/tests/dlopen-tests.c
@@ -30,6 +30,7 @@
#include <stdlib.h>
#include <limits.h>
#include <check.h>
+#include <dirent.h>
#include "tests/common.h"
#define LIBPFX ABS_BUILD_DIR "/" LT_OBJDIR
@@ -154,16 +155,84 @@ static bool recursive_dlopen(const char **name, int round, char **errmsg)
return ok;
}
+static int file_so_filter(const struct dirent *ent)
+{
+ char *suffix;
+
+ suffix = rindex(ent->d_name, '.');
+ if (suffix != NULL
+ && strcmp(suffix, ".so") == 0
+ && suffix[3] == '\0') {
+ return 1;
+ }
+
+ return 0;
+}
+
+static char **get_so_files(size_t *_list_size)
+{
+ int n;
+ struct dirent **namelist;
+ char **libraries;
+
+ n = scandir(LIBPFX, &namelist, file_so_filter, alphasort);
+ fail_unless(n > 0);
+
+ libraries = calloc(n + 1, sizeof(char *));
+
+ for (int i = 0; i < n; ++i) {
+ libraries[i] = strdup(namelist[i]->d_name);
+ fail_if(libraries[i] == NULL);
+
+ free(namelist[i]);
+ }
+ free(namelist);
+
+ *_list_size = (size_t)n;
+ return libraries;
+}
+
+static void remove_library_from_list(const char *library, char **list,
+ size_t list_size)
+{
+ for (size_t i = 0; i < list_size; ++i) {
+ if (list[i] != NULL && strcmp(library, list[i]) == 0) {
+ /* found library need to be removed from list */
+ free(list[i]);
+ list[i] = NULL;
+ return;
+ }
+ }
+
+ ck_abort_msg("Cannot find expected library: %s", library);
+}
+
START_TEST(test_dlopen_base)
{
char *errmsg;
bool ok;
int i;
+ size_t found_libraries_size;
+ char **found_libraries = get_so_files(&found_libraries_size);
+ bool unchecked_library = false;
for (i = 0; so[i].name != NULL; i++) {
ok = recursive_dlopen(so[i].libs, 0, &errmsg);
fail_unless(ok, "Error opening %s: [%s]", so[i].name, errmsg);
+
+ remove_library_from_list(so[i].name, found_libraries,
+ found_libraries_size);
}
+
+ for (i = 0; i < found_libraries_size; ++i) {
+ if (found_libraries[i] != NULL) {
+ printf("Unchecked library found: %s\n", found_libraries[i]);
+ unchecked_library = true;
+ }
+ }
+ free(found_libraries);
+
+ fail_if(unchecked_library);
}
END_TEST
--
2.11.0

View File

@ -0,0 +1,202 @@
From 9b31bc45a3d5728af2523725bd5a2b4aff4f4c78 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
Date: Wed, 12 Oct 2016 13:09:37 +0200
Subject: [PATCH 11/39] sssctl: Flags for command initialization
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Allow passing flags for command specific initialization. Currently
only one flag is available to skip the confdb initialization which is
required to improve config-check command.
Resolves:
https://fedorahosted.org/sssd/ticket/3209
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit cbee11e912bb391ba254b0bac8c1159c1f634533)
(cherry picked from commit ec1829de7cd529c2c68b4bdb9b6d43ac6bb545d3)
---
src/tools/common/sss_tools.c | 91 +++++++++++++++++++++++++-------------------
src/tools/common/sss_tools.h | 14 +++++--
src/tools/sssctl/sssctl.c | 2 +-
3 files changed, 63 insertions(+), 44 deletions(-)
diff --git a/src/tools/common/sss_tools.c b/src/tools/common/sss_tools.c
index 686b53a07..0f4f46894 100644
--- a/src/tools/common/sss_tools.c
+++ b/src/tools/common/sss_tools.c
@@ -182,7 +182,6 @@ errno_t sss_tool_init(TALLOC_CTX *mem_ctx,
struct sss_tool_ctx **_tool_ctx)
{
struct sss_tool_ctx *tool_ctx;
- errno_t ret;
tool_ctx = talloc_zero(mem_ctx, struct sss_tool_ctx);
if (tool_ctx == NULL) {
@@ -192,45 +191,9 @@ errno_t sss_tool_init(TALLOC_CTX *mem_ctx,
sss_tool_common_opts(tool_ctx, argc, argv);
- /* Connect to confdb. */
- ret = sss_tool_confdb_init(tool_ctx, &tool_ctx->confdb);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to open confdb [%d]: %s\n",
- ret, sss_strerror(ret));
- goto done;
- }
+ *_tool_ctx = tool_ctx;
- /* Setup domains. */
- ret = sss_tool_domains_init(tool_ctx, tool_ctx->confdb, &tool_ctx->domains);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup domains [%d]: %s\n",
- ret, sss_strerror(ret));
- goto done;
- }
-
- ret = confdb_get_string(tool_ctx->confdb, tool_ctx,
- CONFDB_MONITOR_CONF_ENTRY,
- CONFDB_MONITOR_DEFAULT_DOMAIN,
- NULL, &tool_ctx->default_domain);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Cannot get the default domain [%d]: %s\n",
- ret, strerror(ret));
- goto done;
- }
-
- ret = EOK;
-
-done:
- switch (ret) {
- case EOK:
- case ERR_SYSDB_VERSION_TOO_OLD:
- *_tool_ctx = tool_ctx;
- break;
- default:
- break;
- }
-
- return ret;
+ return EOK;
}
static bool sss_tool_is_delimiter(struct sss_route_cmd *command)
@@ -300,6 +263,47 @@ void sss_tool_usage(const char *tool_name, struct sss_route_cmd *commands)
sss_tool_print_common_opts(min_len);
}
+static int tool_cmd_init(struct sss_tool_ctx *tool_ctx,
+ struct sss_route_cmd *command)
+{
+ int ret;
+
+ if (command->flags & SSS_TOOL_FLAG_SKIP_CMD_INIT) {
+ return EOK;
+ }
+
+ /* Connect to confdb. */
+ ret = sss_tool_confdb_init(tool_ctx, &tool_ctx->confdb);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to open confdb [%d]: %s\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ /* Setup domains. */
+ ret = sss_tool_domains_init(tool_ctx, tool_ctx->confdb, &tool_ctx->domains);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup domains [%d]: %s\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ ret = confdb_get_string(tool_ctx->confdb, tool_ctx,
+ CONFDB_MONITOR_CONF_ENTRY,
+ CONFDB_MONITOR_DEFAULT_DOMAIN,
+ NULL, &tool_ctx->default_domain);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot get the default domain [%d]: %s\n",
+ ret, strerror(ret));
+ goto done;
+ }
+
+ ret = EOK;
+
+done:
+ return ret;
+}
+
errno_t sss_tool_route(int argc, const char **argv,
struct sss_tool_ctx *tool_ctx,
struct sss_route_cmd *commands,
@@ -308,6 +312,7 @@ errno_t sss_tool_route(int argc, const char **argv,
struct sss_cmdline cmdline;
const char *cmd;
int i;
+ int ret;
if (commands == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "Bug: commands can't be NULL!\n");
@@ -339,6 +344,14 @@ errno_t sss_tool_route(int argc, const char **argv,
return tool_ctx->init_err;
}
+ ret = tool_cmd_init(tool_ctx, &commands[i]);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "Command initialization failed [%d] %s\n",
+ ret, sss_strerror(ret));
+ return ret;
+ }
+
return commands[i].fn(&cmdline, tool_ctx, pvt);
}
}
diff --git a/src/tools/common/sss_tools.h b/src/tools/common/sss_tools.h
index 6d24642ae..49da7d634 100644
--- a/src/tools/common/sss_tools.h
+++ b/src/tools/common/sss_tools.h
@@ -45,16 +45,22 @@ typedef errno_t
struct sss_tool_ctx *tool_ctx,
void *pvt);
-#define SSS_TOOL_COMMAND(cmd, msg, err, fn) {cmd, _(msg), err, fn}
-#define SSS_TOOL_COMMAND_NOMSG(cmd, err, fn) {cmd, NULL, err, fn}
-#define SSS_TOOL_DELIMITER(message) {"", _(message), 0, NULL}
-#define SSS_TOOL_LAST {NULL, NULL, 0, NULL}
+#define SSS_TOOL_COMMAND_FLAGS(cmd, msg, err, fn, flags) \
+ {cmd, _(msg), err, fn, flags}
+#define SSS_TOOL_COMMAND(cmd, msg, err, fn) \
+ {cmd, _(msg), err, fn, 0}
+#define SSS_TOOL_COMMAND_NOMSG(cmd, err, fn) {cmd, NULL, err, fn, 0}
+#define SSS_TOOL_DELIMITER(message) {"", _(message), 0, NULL, 0}
+#define SSS_TOOL_LAST {NULL, NULL, 0, NULL, 0}
+
+#define SSS_TOOL_FLAG_SKIP_CMD_INIT 0x01
struct sss_route_cmd {
const char *command;
const char *description;
errno_t handles_init_err;
sss_route_fn fn;
+ int flags;
};
void sss_tool_usage(const char *tool_name,
diff --git a/src/tools/sssctl/sssctl.c b/src/tools/sssctl/sssctl.c
index b0510e6ae..ece1e6df1 100644
--- a/src/tools/sssctl/sssctl.c
+++ b/src/tools/sssctl/sssctl.c
@@ -276,7 +276,7 @@ int main(int argc, const char **argv)
SSS_TOOL_COMMAND("logs-fetch", "Archive SSSD log files in tarball", 0, sssctl_logs_fetch),
#ifdef HAVE_LIBINI_CONFIG_V1_3
SSS_TOOL_DELIMITER("Configuration files tools:"),
- SSS_TOOL_COMMAND("config-check", "Perform static analysis of SSSD configuration", 0, sssctl_config_check),
+ SSS_TOOL_COMMAND_FLAGS("config-check", "Perform static analysis of SSSD configuration", 0, sssctl_config_check, SSS_TOOL_FLAG_SKIP_CMD_INIT),
#endif
SSS_TOOL_LAST
};
--
2.11.0

View File

@ -0,0 +1,125 @@
From 0cf03315bc74555aa70a6fec854d6d66826eb608 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 18 Oct 2016 14:59:19 +0200
Subject: [PATCH 12/39] sysdb: add parent_dom to sysdb_get_direct_parents()
Currently sysdb_get_direct_parents() only return direct parents from the
same domain as the child object. In setups with sub-domains this might
not be sufficient. A new option parent_dom is added which allows to
specify a domain the direct parents should be lookup up in. If it is
NULL the whole cache is searched.
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 3dd4c3eca80e9223a65f3318821bd0fb5b45aedd)
(cherry picked from commit 9a243dcdbf5a908d23c1a64f3fb33914eefef9e8)
---
src/db/sysdb.h | 21 +++++++++++++++++++++
src/db/sysdb_search.c | 7 ++++++-
src/providers/ldap/sdap_async_initgroups.c | 11 +++++++----
3 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 7de3acdf3..f5d3ddb84 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -1137,8 +1137,29 @@ errno_t sysdb_remove_attrs(struct sss_domain_info *domain,
enum sysdb_member_type type,
char **remove_attrs);
+/**
+ * @brief Return direct parents of an object in the cache
+ *
+ * @param[in] mem_ctx Memory context the result should be allocated
+ * on
+ * @param[in] dom domain the object is in
+ * @param[in] parent_dom domain which should be searched for direct
+ * parents if NULL all domains in the given cache
+ * are searched
+ * @param[in] mtype Type of the object, SYSDB_MEMBER_USER or
+ * SYSDB_MEMBER_GROUP
+ * @param[in] name Name of the object
+ * @param[out] _direct_parents List of names of the direct parent groups
+ *
+ *
+ * @return
+ * - EOK: success
+ * - EINVAL: wrong mtype
+ * - ENOMEM: Memory allocation failed
+ */
errno_t sysdb_get_direct_parents(TALLOC_CTX *mem_ctx,
struct sss_domain_info *dom,
+ struct sss_domain_info *parent_dom,
enum sysdb_member_type mtype,
const char *name,
char ***_direct_parents);
diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c
index cfee5784d..4d63c3838 100644
--- a/src/db/sysdb_search.c
+++ b/src/db/sysdb_search.c
@@ -1981,6 +1981,7 @@ done:
errno_t sysdb_get_direct_parents(TALLOC_CTX *mem_ctx,
struct sss_domain_info *dom,
+ struct sss_domain_info *parent_dom,
enum sysdb_member_type mtype,
const char *name,
char ***_direct_parents)
@@ -2029,7 +2030,11 @@ errno_t sysdb_get_direct_parents(TALLOC_CTX *mem_ctx,
goto done;
}
- basedn = sysdb_group_base_dn(tmp_ctx, dom);
+ if (parent_dom == NULL) {
+ basedn = sysdb_base_dn(dom->sysdb, tmp_ctx);
+ } else {
+ basedn = sysdb_group_base_dn(tmp_ctx, parent_dom);
+ }
if (!basedn) {
ret = ENOMEM;
goto done;
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index df39de3cc..7a2eef43d 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -1301,7 +1301,8 @@ sdap_initgr_store_user_memberships(struct sdap_initgr_nested_state *state)
}
}
- ret = sysdb_get_direct_parents(tmp_ctx, state->dom, SYSDB_MEMBER_USER,
+ ret = sysdb_get_direct_parents(tmp_ctx, state->dom, state->dom,
+ SYSDB_MEMBER_USER,
state->username, &sysdb_parent_name_list);
if (ret) {
DEBUG(SSSDBG_CRIT_FAILURE,
@@ -1388,7 +1389,7 @@ sdap_initgr_nested_get_membership_diff(TALLOC_CTX *mem_ctx,
goto done;
}
- ret = sysdb_get_direct_parents(tmp_ctx, dom, SYSDB_MEMBER_GROUP,
+ ret = sysdb_get_direct_parents(tmp_ctx, dom, dom, SYSDB_MEMBER_GROUP,
group_name, &sysdb_parents_names_list);
if (ret) {
DEBUG(SSSDBG_CRIT_FAILURE,
@@ -2070,7 +2071,8 @@ rfc2307bis_group_memberships_build(hash_entry_t *item, void *user_data)
goto done;
}
- ret = sysdb_get_direct_parents(tmp_ctx, mstate->dom, SYSDB_MEMBER_GROUP,
+ ret = sysdb_get_direct_parents(tmp_ctx, mstate->dom, mstate->dom,
+ SYSDB_MEMBER_GROUP,
group_name, &sysdb_parents_names_list);
if (ret) {
DEBUG(SSSDBG_CRIT_FAILURE,
@@ -2130,7 +2132,8 @@ errno_t save_rfc2307bis_user_memberships(
}
in_transaction = true;
- ret = sysdb_get_direct_parents(tmp_ctx, state->dom, SYSDB_MEMBER_USER,
+ ret = sysdb_get_direct_parents(tmp_ctx, state->dom, state->dom,
+ SYSDB_MEMBER_USER,
state->name, &sysdb_parent_name_list);
if (ret) {
DEBUG(SSSDBG_CRIT_FAILURE,
--
2.11.0

View File

@ -0,0 +1,81 @@
From 79044fc1de2dad656b2c664722b4f8568bf4f8d6 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 18 Oct 2016 18:16:30 +0200
Subject: [PATCH 13/39] sdap: make some nested group related calls public
sdap_nested_groups_store() and rfc2307bis_nested_groups_send/recv() will
be reused for domain local group lookups.
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 49d3f0a487d55571b2bdc9d3f8280b304b964b9d)
(cherry picked from commit f38c62ffe05ab845165f1b597083579d4fe3632f)
---
src/providers/ldap/sdap_async_initgroups.c | 12 ++----------
src/providers/ldap/sdap_async_private.h | 16 ++++++++++++++++
2 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index 7a2eef43d..0f56b8740 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -622,7 +622,7 @@ static int sdap_initgr_rfc2307_recv(struct tevent_req *req)
}
/* ==Common code for pure RFC2307bis and IPA/AD========================= */
-static errno_t
+errno_t
sdap_nested_groups_store(struct sysdb_ctx *sysdb,
struct sss_domain_info *domain,
struct sdap_options *opts,
@@ -1558,14 +1558,6 @@ static void sdap_initgr_rfc2307bis_process(struct tevent_req *subreq);
static void sdap_initgr_rfc2307bis_done(struct tevent_req *subreq);
errno_t save_rfc2307bis_user_memberships(
struct sdap_initgr_rfc2307bis_state *state);
-struct tevent_req *rfc2307bis_nested_groups_send(
- TALLOC_CTX *mem_ctx, struct tevent_context *ev,
- struct sdap_options *opts, struct sysdb_ctx *sysdb,
- struct sss_domain_info *dom, struct sdap_handle *sh,
- struct sdap_search_base **search_bases,
- struct sysdb_attrs **groups, size_t num_groups,
- hash_table_t *group_hash, size_t nesting);
-static errno_t rfc2307bis_nested_groups_recv(struct tevent_req *req);
static struct tevent_req *sdap_initgr_rfc2307bis_send(
TALLOC_CTX *memctx,
@@ -2616,7 +2608,7 @@ static void rfc2307bis_nested_groups_process(struct tevent_req *subreq)
tevent_req_set_callback(subreq, rfc2307bis_nested_groups_done, req);
}
-static errno_t rfc2307bis_nested_groups_recv(struct tevent_req *req)
+errno_t rfc2307bis_nested_groups_recv(struct tevent_req *req)
{
TEVENT_REQ_RETURN_ON_ERROR(req);
return EOK;
diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h
index f09ddb71f..4af4f7144 100644
--- a/src/providers/ldap/sdap_async_private.h
+++ b/src/providers/ldap/sdap_async_private.h
@@ -157,4 +157,20 @@ errno_t sdap_check_ad_group_type(struct sss_domain_info *dom,
struct sysdb_attrs *group_attrs,
const char *group_name,
bool *_need_filter);
+
+struct tevent_req *rfc2307bis_nested_groups_send(
+ TALLOC_CTX *mem_ctx, struct tevent_context *ev,
+ struct sdap_options *opts, struct sysdb_ctx *sysdb,
+ struct sss_domain_info *dom, struct sdap_handle *sh,
+ struct sdap_search_base **search_bases,
+ struct sysdb_attrs **groups, size_t num_groups,
+ hash_table_t *group_hash, size_t nesting);
+errno_t rfc2307bis_nested_groups_recv(struct tevent_req *req);
+
+errno_t sdap_nested_groups_store(struct sysdb_ctx *sysdb,
+ struct sss_domain_info *domain,
+ struct sdap_options *opts,
+ struct sysdb_attrs **groups,
+ unsigned long count);
+
#endif /* _SDAP_ASYNC_PRIVATE_H_ */
--
2.11.0

View File

@ -0,0 +1,683 @@
From b53bcb7675b6b797c4ba2a590deb4e4578d0e5ef Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 18 Oct 2016 18:18:44 +0200
Subject: [PATCH 14/39] LDAP/AD: resolve domain local groups for remote users
If a user from a trusted domain in the same forest is a direct or
indirect member of domain local groups from the local domain those
memberships must be resolved as well. Since those domain local groups
are not valid in the trusted domain a DC from the trusted domain which
is used to lookup the user data is not aware of them. As a consequence
those memberships must be resolved against a local DC in a second step.
Resolves https://fedorahosted.org/sssd/ticket/3206
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 25699846bd1c9f8bb513b6271eb4366ab682fbd2)
(cherry picked from commit c1f3b29fee6577714347673d717f71ab997c3006)
---
src/db/sysdb.h | 1 +
src/providers/ldap/sdap_async_initgroups.c | 158 +++++++++-
src/providers/ldap/sdap_async_initgroups_ad.c | 407 ++++++++++++++++++++++++++
src/providers/ldap/sdap_async_private.h | 10 +
4 files changed, 569 insertions(+), 7 deletions(-)
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index f5d3ddb84..901268390 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -225,6 +225,7 @@
SYSDB_OVERRIDE_OBJECT_DN, \
SYSDB_DEFAULT_OVERRIDE_NAME, \
SYSDB_UUID, \
+ SYSDB_ORIG_DN, \
NULL}
#define SYSDB_GRSRC_ATTRS {SYSDB_NAME, SYSDB_GIDNUM, \
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index 0f56b8740..45fc007e0 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -2317,6 +2317,7 @@ static errno_t rfc2307bis_nested_groups_step(struct tevent_req *req)
struct sdap_rfc2307bis_nested_ctx *state =
tevent_req_data(req, struct sdap_rfc2307bis_nested_ctx);
char *oc_list;
+ const char *class;
tmp_ctx = talloc_new(state);
if (!tmp_ctx) {
@@ -2324,9 +2325,21 @@ static errno_t rfc2307bis_nested_groups_step(struct tevent_req *req)
goto done;
}
- ret = sdap_get_group_primary_name(state, state->opts,
- state->groups[state->group_iter],
- state->dom, &state->primary_name);
+ ret = sysdb_attrs_get_string(state->groups[state->group_iter],
+ SYSDB_OBJECTCLASS, &class);
+ if (ret == EOK) {
+ /* If there is a objectClass attribute the object is coming from the
+ * cache and the name attribute of the object already has the primary
+ * name.
+ * If the objectClass attribute is missing the object is coming from
+ * LDAP and we have to find the primary name first. */
+ ret = sysdb_attrs_get_string(state->groups[state->group_iter],
+ SYSDB_NAME, &state->primary_name);
+ } else {
+ ret = sdap_get_group_primary_name(state, state->opts,
+ state->groups[state->group_iter],
+ state->dom, &state->primary_name);
+ }
if (ret != EOK) {
goto done;
}
@@ -3069,6 +3082,103 @@ fail:
tevent_req_error(req, ret);
}
+static void sdap_ad_check_domain_local_groups_done(struct tevent_req *subreq);
+
+errno_t sdap_ad_check_domain_local_groups(struct tevent_req *req)
+{
+ struct sdap_get_initgr_state *state = tevent_req_data(req,
+ struct sdap_get_initgr_state);
+ int ret;
+ struct sdap_domain *local_sdom;
+ const char *orig_name;
+ const char *sysdb_name;
+ struct ldb_result *res;
+ struct tevent_req *subreq;
+ struct sysdb_attrs **groups;
+
+ /* We only need to check for domain local groups in the AD case and if the
+ * user is not from our domain, i.e. if the user comes from a sub-domain.
+ */
+ if (state->opts->schema_type != SDAP_SCHEMA_AD
+ || !IS_SUBDOMAIN(state->dom)
+ || !dp_target_enabled(state->id_ctx->be->provider, "ad", DPT_ID)) {
+ return EOK;
+ }
+
+ local_sdom = sdap_domain_get(state->id_ctx->opts, state->dom->parent);
+ if (local_sdom == NULL || local_sdom->pvt == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "No ID ctx available for [%s].\n",
+ state->dom->parent->name);
+ return EINVAL;
+ }
+
+ ret = sysdb_attrs_get_string(state->orig_user, SYSDB_NAME, &orig_name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Missing name in user object.\n");
+ return ret;
+ }
+
+ sysdb_name = sss_create_internal_fqname(state, orig_name, state->dom->name);
+ if (sysdb_name == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_create_internal_fqname failed.\n");
+ return ENOMEM;
+ }
+
+ ret = sysdb_initgroups(state, state->dom, sysdb_name, &res);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_initgroups failed for user [%s].\n",
+ sysdb_name);
+ return ret;
+ }
+
+ if (res->count == 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "sysdb_initgroups returned no results for user [%s].\n",
+ sysdb_name);
+ return EINVAL;
+ }
+
+ /* The user object, the first entry in the res->msgs, is included as well
+ * to cover the case where the remote user is directly added to
+ * a domain local group. */
+ ret = sysdb_msg2attrs(state, res->count, res->msgs, &groups);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_msg2attrs failed.\n");
+ return ret;
+ }
+
+ subreq = sdap_ad_get_domain_local_groups_send(state, state->ev, local_sdom,
+ state->opts, state->sysdb, state->dom->parent,
+ groups, res->count);
+ if (subreq == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "sdap_ad_get_domain_local_groups_send failed.\n");
+ return ENOMEM;
+ }
+
+ tevent_req_set_callback(subreq, sdap_ad_check_domain_local_groups_done,
+ req);
+
+ return EAGAIN;
+}
+
+static void sdap_ad_check_domain_local_groups_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ int ret;
+
+ ret = sdap_ad_get_domain_local_groups_recv(subreq);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ tevent_req_done(req);
+
+ return;
+}
+
static void sdap_get_initgr_pgid(struct tevent_req *req);
static void sdap_get_initgr_done(struct tevent_req *subreq)
{
@@ -3201,8 +3311,6 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
if (ret == EOK) {
DEBUG(SSSDBG_TRACE_FUNC,
"Primary group already cached, nothing to do.\n");
- ret = EOK;
- goto done;
} else {
gid = talloc_asprintf(state, "%lu", (unsigned long)primary_gid);
if (gid == NULL) {
@@ -3219,10 +3327,28 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
goto done;
}
tevent_req_set_callback(subreq, sdap_get_initgr_pgid, req);
+
+ talloc_free(tmp_ctx);
+ return;
}
- talloc_free(tmp_ctx);
- return;
+ ret = sdap_ad_check_domain_local_groups(req);
+ if (ret == EAGAIN) {
+ DEBUG(SSSDBG_TRACE_ALL,
+ "Checking for domain local group memberships.\n");
+ talloc_free(tmp_ctx);
+ return;
+ } else if (ret == EOK) {
+ DEBUG(SSSDBG_TRACE_ALL,
+ "No need to check for domain local group memberships.\n");
+ } else {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sdap_ad_check_domain_local_groups failed, "
+ "meberships to domain local groups might be missing.\n");
+ /* do not let the request fail completely because we already have at
+ * least "some" groups */
+ ret = EOK;
+ }
done:
talloc_free(tmp_ctx);
@@ -3247,7 +3373,25 @@ static void sdap_get_initgr_pgid(struct tevent_req *subreq)
return;
}
+ ret = sdap_ad_check_domain_local_groups(req);
+ if (ret == EAGAIN) {
+ DEBUG(SSSDBG_TRACE_ALL,
+ "Checking for domain local group memberships.\n");
+ return;
+ } else if (ret == EOK) {
+ DEBUG(SSSDBG_TRACE_ALL,
+ "No need to check for domain local group memberships.\n");
+ } else {
+ DEBUG(SSSDBG_OP_FAILURE, "sdap_ad_check_domain_local_groups failed.\n");
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sdap_ad_check_domain_local_groups failed, "
+ "meberships to domain local groups might be missing.\n");
+ /* do not let the request fail completely because we already have at
+ * least "some" groups */
+ }
+
tevent_req_done(req);
+ return;
}
int sdap_get_initgr_recv(struct tevent_req *req)
diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c
index ad54c1fb8..1fee4ab43 100644
--- a/src/providers/ldap/sdap_async_initgroups_ad.c
+++ b/src/providers/ldap/sdap_async_initgroups_ad.c
@@ -1412,6 +1412,413 @@ static errno_t sdap_ad_tokengroups_initgr_posix_recv(struct tevent_req *req)
return EOK;
}
+struct sdap_ad_get_domain_local_groups_state {
+ struct tevent_context *ev;
+ struct sdap_id_conn_ctx *conn;
+ struct sdap_options *opts;
+ struct sdap_id_op *op;
+ struct sysdb_ctx *sysdb;
+ struct sss_domain_info *dom;
+ int dp_error;
+
+ struct sdap_search_base **search_bases;
+ struct sysdb_attrs **groups;
+ size_t num_groups;
+ hash_table_t *group_hash;
+};
+
+static void
+sdap_ad_get_domain_local_groups_connect_done(struct tevent_req *subreq);
+static void sdap_ad_get_domain_local_groups_done(struct tevent_req *subreq);
+
+struct tevent_req *
+sdap_ad_get_domain_local_groups_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sdap_domain *local_sdom,
+ struct sdap_options *opts,
+ struct sysdb_ctx *sysdb,
+ struct sss_domain_info *dom,
+ struct sysdb_attrs **groups,
+ size_t num_groups)
+{
+ struct sdap_ad_get_domain_local_groups_state *state;
+ struct tevent_req *req;
+ struct tevent_req *subreq;
+ struct ad_id_ctx *ad_id_ctx;
+ errno_t ret;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct sdap_ad_get_domain_local_groups_state);
+ if (req == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
+ return NULL;
+ }
+
+ state->ev = ev;
+ ad_id_ctx = talloc_get_type(local_sdom->pvt, struct ad_id_ctx);
+ state->conn = ad_id_ctx->ldap_ctx;
+ state->opts = opts;
+ state->sysdb = sysdb;
+ state->dom = dom;
+ state->search_bases = state->conn->id_ctx->opts->sdom->group_search_bases;
+ state->groups = groups;
+ state->num_groups = num_groups;
+
+ ret = sss_hash_create(state, 32, &state->group_hash);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_hash_create failed.\n");
+ goto fail;
+ }
+
+ state->op = sdap_id_op_create(state, state->conn->conn_cache);
+ if (state->op == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n");
+ ret = ENOMEM;
+ goto fail;
+ }
+
+ subreq = sdap_id_op_connect_send(state->op, state, &ret);
+ if (subreq == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed.\n");
+ goto fail;
+ }
+
+ tevent_req_set_callback(subreq,
+ sdap_ad_get_domain_local_groups_connect_done, req);
+
+ return req;
+
+fail:
+ tevent_req_error(req, ret);
+ tevent_req_post(req, ev);
+ return req;
+}
+
+static void
+sdap_ad_get_domain_local_groups_connect_done(struct tevent_req *subreq)
+{
+
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct sdap_ad_get_domain_local_groups_state *state = tevent_req_data(req,
+ struct sdap_ad_get_domain_local_groups_state);
+ int dp_error = DP_ERR_FATAL;
+ int ret;
+
+ ret = sdap_id_op_connect_recv(subreq, &dp_error);
+ talloc_zfree(subreq);
+
+ if (ret != EOK) {
+ state->dp_error = dp_error;
+ tevent_req_error(req, ret);
+ return;
+ }
+ subreq = rfc2307bis_nested_groups_send(state, state->ev, state->opts,
+ state->sysdb, state->dom,
+ sdap_id_op_handle(state->op),
+ state->search_bases,
+ state->groups, state->num_groups,
+ state->group_hash, 0);
+ if (subreq == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "rfc2307bis_nested_groups_send failed.\n");
+ state->dp_error = DP_ERR_FATAL;
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+
+ tevent_req_set_callback(subreq,
+ sdap_ad_get_domain_local_groups_done, req);
+
+ return;
+}
+
+struct sdap_nested_group {
+ struct sysdb_attrs *group;
+ struct sysdb_attrs **ldap_parents;
+ size_t parents_count;
+};
+
+static errno_t
+sdap_ad_get_domain_local_groups_parse_parents(TALLOC_CTX *mem_ctx,
+ struct sdap_nested_group *gr,
+ struct sss_domain_info *dom,
+ struct sysdb_ctx *sysdb,
+ struct sdap_options *opts,
+ const char **_sysdb_name,
+ enum sysdb_member_type *_type,
+ char ***_add_list,
+ char ***_del_list)
+{
+ int ret;
+ size_t c;
+ char **groupnamelist = NULL;
+ struct sysdb_attrs *groups[1];
+ enum sysdb_member_type type;
+ const char *sysdb_name;
+ const char *group_name;
+ const char *class;
+ struct sss_domain_info *obj_dom;
+ char *local_groups_base_dn;
+ char **cached_local_parents = NULL;
+ char **add_list = NULL;
+ char **del_list = NULL;
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
+ return ENOMEM;
+ }
+
+ local_groups_base_dn = talloc_asprintf(tmp_ctx, SYSDB_TMPL_GROUP_BASE,
+ dom->name);
+ if (local_groups_base_dn == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ if (gr->parents_count != 0) {
+ /* Store the parents if needed */
+ ret = sdap_nested_groups_store(sysdb, dom, opts,
+ gr->ldap_parents, gr->parents_count);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Could not save groups [%d]: %s\n",
+ ret, strerror(ret));
+ goto done;
+ }
+
+ ret = sysdb_attrs_primary_fqdn_list(dom, tmp_ctx,
+ gr->ldap_parents, gr->parents_count,
+ opts->group_map[SDAP_AT_GROUP_NAME].name,
+ &groupnamelist);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_primary_fqdn_list failed.\n");
+ goto done;
+ }
+ }
+
+ ret = sysdb_attrs_get_string(gr->group, SYSDB_NAME, &sysdb_name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sysdb_attrs_get_string failed to get SYSDB_NAME, "
+ "skipping.\n");
+ goto done;
+ }
+
+ ret = sysdb_attrs_get_string(gr->group, SYSDB_OBJECTCLASS, &class);
+ if (ret != EOK) {
+ /* If objectclass is missing gr->group is a nested parent found during
+ * the nested group lookup. It might not already stored in the cache.
+ */
+ DEBUG(SSSDBG_TRACE_LIBS,
+ "sysdb_attrs_get_string failed to get SYSDB_OBJECTCLASS "
+ "for [%s], assuming group.\n", sysdb_name);
+
+ /* make sure group exists in cache */
+ groups[0]= gr->group;
+ ret = sdap_nested_groups_store(sysdb, dom, opts, groups, 1);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Could not save groups [%d]: %s\n",
+ ret, strerror(ret));
+ goto done;
+ }
+
+ /* Since the object is coming from LDAP it cannot have the internal
+ * fully-qualified name, so we can expand it unconditionally. */
+ group_name = NULL;
+ ret = sysdb_attrs_primary_name(dom->sysdb, gr->group,
+ opts->group_map[SDAP_AT_GROUP_NAME].name,
+ &group_name);
+ if (ret != EOK || group_name == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "Could not determine primary name\n");
+ group_name = sysdb_name;
+ }
+
+ group_name = sss_create_internal_fqname(tmp_ctx, group_name,
+ dom->name);
+ if (group_name != NULL) {
+ sysdb_name = group_name;
+ }
+
+ type = SYSDB_MEMBER_GROUP;
+ } else {
+ if (class != NULL && strcmp(class, SYSDB_USER_CLASS) == 0) {
+ type = SYSDB_MEMBER_USER;
+ } else {
+ type = SYSDB_MEMBER_GROUP;
+ }
+ }
+
+ /* We need to get the cached list of groups form the local domain the
+ * object is a member of to compare them with the current list just
+ * retrieved (groupnamelist). Even if this list is empty we have to
+ * proceed because the membership might have been removed recently on the
+ * server. */
+
+ obj_dom = find_domain_by_object_name(get_domains_head(dom),
+ sysdb_name);
+ if (obj_dom == NULL) {
+ obj_dom = dom;
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot find domain for [%s], "
+ "trying with local domain [%s].\n",
+ sysdb_name, obj_dom->name);
+ }
+
+ ret = sysdb_get_direct_parents(tmp_ctx, obj_dom, dom, type, sysdb_name,
+ &cached_local_parents);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,"sysdb_get_direct_parents failed.\n");
+ goto done;
+ }
+
+ if (cached_local_parents != NULL && cached_local_parents[0] == NULL) {
+ talloc_zfree(cached_local_parents);
+ }
+
+ if (DEBUG_IS_SET(SSSDBG_TRACE_ALL)) {
+ if (cached_local_parents != NULL) {
+ for (c = 0; cached_local_parents[c] != NULL; c++) {
+ DEBUG(SSSDBG_TRACE_ALL, "[%s] cached_local_parents [%s].\n",
+ sysdb_name, cached_local_parents[c]);
+ }
+ }
+
+ if (groupnamelist != NULL) {
+ for (c = 0; groupnamelist[c] != NULL; c++) {
+ DEBUG(SSSDBG_TRACE_ALL, "[%s] groupnamelist [%s].\n",
+ sysdb_name, groupnamelist[c]);
+ }
+ }
+ }
+
+ ret = diff_string_lists(tmp_ctx, cached_local_parents, groupnamelist,
+ &del_list, &add_list, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "diff_string_lists failed.\n");
+ goto done;
+ }
+
+ if (DEBUG_IS_SET(SSSDBG_TRACE_ALL)) {
+ if (add_list != NULL) {
+ for (c = 0; add_list[c] != NULL; c++) {
+ DEBUG(SSSDBG_TRACE_ALL, "add: [%s] will be member of [%s].\n",
+ sysdb_name, add_list[c]);
+ }
+ }
+ if (del_list != NULL) {
+ for (c = 0; del_list[c] != NULL; c++) {
+ DEBUG(SSSDBG_TRACE_ALL, "del: [%s] was member of [%s].\n",
+ sysdb_name, del_list[c]);
+ }
+ }
+ }
+
+ *_type = type;
+ *_sysdb_name = talloc_steal(mem_ctx, sysdb_name);
+ *_add_list = talloc_steal(mem_ctx, groupnamelist);
+ *_del_list = talloc_steal(mem_ctx, del_list);
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+
+ return ret;
+}
+
+static void sdap_ad_get_domain_local_groups_done(struct tevent_req *subreq)
+{
+
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct sdap_ad_get_domain_local_groups_state *state = tevent_req_data(req,
+ struct sdap_ad_get_domain_local_groups_state);
+ int ret;
+ int hret;
+ unsigned long count;
+ hash_value_t *values = NULL;
+ struct sdap_nested_group *gr;
+ size_t c;
+ const char *sysdb_name = NULL;
+ enum sysdb_member_type type;
+ char **add_list = NULL;
+ char **del_list = NULL;
+
+ ret = rfc2307bis_nested_groups_recv(subreq);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ hret = hash_values(state->group_hash, &count, &values);
+ if (hret != HASH_SUCCESS) {
+ DEBUG(SSSDBG_OP_FAILURE, "hash_values failed.\n");
+ ret = EIO;
+ goto done;
+ }
+
+ for (c = 0; c < count; c++) {
+ gr = talloc_get_type(values[c].ptr,
+ struct sdap_nested_group);
+
+ /* The values from the hash are either user or group objects returned
+ * by sysdb_initgroups() which where used to start the request or
+ * nested parents found during the request. The nested parents contain
+ * the processed LDAP data and can be identified by a missing
+ * objectclass attribute. */
+ ret = sdap_ad_get_domain_local_groups_parse_parents(state, gr,
+ state->dom,
+ state->sysdb,
+ state->opts,
+ &sysdb_name,
+ &type,
+ &add_list,
+ &del_list);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sdap_ad_get_domain_local_groups_parse_parents failed.\n");
+ continue;
+ }
+
+ if ((add_list == NULL && del_list == NULL)
+ || (add_list == NULL && del_list != NULL && del_list[0] == NULL)
+ || (add_list != NULL && add_list[0] == NULL && del_list == NULL)
+ || (add_list != NULL && add_list[0] == NULL
+ && del_list != NULL && del_list[0] == NULL) ) {
+ continue;
+ }
+
+ DEBUG(SSSDBG_TRACE_INTERNAL, "Updating domain local memberships for %s\n",
+ sysdb_name);
+ ret = sysdb_update_members(state->dom, sysdb_name, type,
+ (const char *const *) add_list,
+ (const char *const *) del_list);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_update_members failed.\n");
+ goto done;
+ }
+ }
+
+ ret = EOK;
+done:
+ talloc_zfree(values);
+
+ if (ret == EOK) {
+ tevent_req_done(req);
+ } else {
+ tevent_req_error(req, ret);
+ }
+
+ return;
+}
+
+errno_t sdap_ad_get_domain_local_groups_recv(struct tevent_req *req)
+{
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+ return EOK;
+}
+
struct sdap_ad_tokengroups_initgroups_state {
bool use_id_mapping;
struct sss_domain_info *domain;
diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h
index 4af4f7144..266bc0311 100644
--- a/src/providers/ldap/sdap_async_private.h
+++ b/src/providers/ldap/sdap_async_private.h
@@ -173,4 +173,14 @@ errno_t sdap_nested_groups_store(struct sysdb_ctx *sysdb,
struct sysdb_attrs **groups,
unsigned long count);
+struct tevent_req *
+sdap_ad_get_domain_local_groups_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sdap_domain *local_sdom,
+ struct sdap_options *opts,
+ struct sysdb_ctx *sysdb,
+ struct sss_domain_info *dom,
+ struct sysdb_attrs **groups,
+ size_t num_groups);
+errno_t sdap_ad_get_domain_local_groups_recv(struct tevent_req *req);
#endif /* _SDAP_ASYNC_PRIVATE_H_ */
--
2.11.0

View File

@ -0,0 +1,121 @@
From 84946be361a17bbb593f246849bd1357aa2f79da Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 20 Oct 2016 11:48:22 +0200
Subject: [PATCH 15/39] PAM: add a test for filter_responses()
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit c8fe1d922b254aa92e74f428135ada3c8bde87a1)
(cherry picked from commit 0157678081e299660105c753f2d2ac2081960bca)
---
src/responder/pam/pamsrv.h | 3 +++
src/responder/pam/pamsrv_cmd.c | 4 ++--
src/tests/cmocka/test_pam_srv.c | 52 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h
index e686d03a4..8437d082e 100644
--- a/src/responder/pam/pamsrv.h
+++ b/src/responder/pam/pamsrv.h
@@ -99,4 +99,7 @@ errno_t
pam_set_last_online_auth_with_curr_token(struct sss_domain_info *domain,
const char *username,
uint64_t value);
+
+errno_t filter_responses(struct confdb_ctx *cdb,
+ struct response_data *resp_list);
#endif /* __PAMSRV_H__ */
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index e52fc7642..b3690d763 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -470,8 +470,8 @@ fail:
return ret;
}
-static errno_t filter_responses(struct confdb_ctx *cdb,
- struct response_data *resp_list)
+errno_t filter_responses(struct confdb_ctx *cdb,
+ struct response_data *resp_list)
{
int ret;
struct response_data *resp;
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
index 4b2dea4be..41d177233 100644
--- a/src/tests/cmocka/test_pam_srv.c
+++ b/src/tests/cmocka/test_pam_srv.c
@@ -31,6 +31,7 @@
#include "responder/pam/pam_helpers.h"
#include "sss_client/pam_message.h"
#include "sss_client/sss_cli.h"
+#include "confdb/confdb.h"
#include "util/crypto/sss_crypto.h"
#ifdef HAVE_NSS
@@ -1759,6 +1760,54 @@ void test_pam_cert_auth(void **state)
assert_int_equal(ret, EOK);
}
+void test_filter_response(void **state)
+{
+ int ret;
+ struct pam_data *pd;
+ uint8_t offline_auth_data[(sizeof(uint32_t) + sizeof(int64_t))];
+ uint32_t info_type;
+
+ struct sss_test_conf_param pam_params[] = {
+ { CONFDB_PAM_VERBOSITY, "1" },
+ { NULL, NULL }, /* Sentinel */
+ };
+
+ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb);
+ assert_int_equal(ret, EOK);
+
+ pd = talloc_zero(pam_test_ctx, struct pam_data);
+ assert_non_null(pd);
+
+ info_type = SSS_PAM_USER_INFO_OFFLINE_AUTH;
+ memset(offline_auth_data, 0, sizeof(offline_auth_data));
+ memcpy(offline_auth_data, &info_type, sizeof(uint32_t));
+ ret = pam_add_response(pd, SSS_PAM_USER_INFO,
+ sizeof(offline_auth_data), offline_auth_data);
+ assert_int_equal(ret, EOK);
+
+ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list);
+ assert_int_equal(ret, EOK);
+ assert_true(pd->resp_list->do_not_send_to_client);
+
+ pam_params[0].value = "0";
+ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb);
+ assert_int_equal(ret, EOK);
+
+ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list);
+ assert_int_equal(ret, EOK);
+ assert_true(pd->resp_list->do_not_send_to_client);
+
+ /* SSS_PAM_USER_INFO_OFFLINE_AUTH message will only be shown with
+ * pam_verbosity 2 or above if cache password never expires. */
+ pam_params[0].value = "2";
+ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb);
+ assert_int_equal(ret, EOK);
+
+ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list);
+ assert_int_equal(ret, EOK);
+ assert_false(pd->resp_list->do_not_send_to_client);
+}
+
int main(int argc, const char *argv[])
{
int rv;
@@ -1870,6 +1919,9 @@ int main(int argc, const char *argv[])
pam_test_setup_no_verification,
pam_test_teardown),
#endif /* HAVE_NSS */
+
+ cmocka_unit_test_setup_teardown(test_filter_response,
+ pam_test_setup, pam_test_teardown),
};
/* Set debug level to invalid value so we can deside if -d 0 was used. */
--
2.11.0

View File

@ -0,0 +1,501 @@
From 51cdde0ce897c62a0e29653e896e3e6d43585228 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 20 Oct 2016 18:40:01 +0200
Subject: [PATCH 16/39] PAM: add pam_response_filter option
Currently the main use-case for this new option is to not set the
KRB5CCNAME environment varible for services like 'sudo-i'.
Resolves https://fedorahosted.org/sssd/ticket/2296
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit ce43f710c9638fbbeae077559cd7514370a10c0c)
(cherry picked from commit 74711db46029415cc9590bb0e3f9cc662dac1d0c)
---
src/confdb/confdb.h | 1 +
src/config/SSSDConfig/__init__.py.in | 1 +
src/config/cfg_rules.ini | 1 +
src/config/etc/sssd.api.conf | 1 +
src/man/sssd.conf.5.xml | 45 +++++++++++
src/responder/pam/pamsrv.h | 3 +-
src/responder/pam/pamsrv_cmd.c | 111 ++++++++++++++++++++++++--
src/tests/cmocka/test_pam_srv.c | 149 +++++++++++++++++++++++++++++++++--
8 files changed, 297 insertions(+), 15 deletions(-)
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index 011792fba..2a1e58184 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -115,6 +115,7 @@
#define CONFDB_PAM_FAILED_LOGIN_DELAY "offline_failed_login_delay"
#define CONFDB_DEFAULT_PAM_FAILED_LOGIN_DELAY 5
#define CONFDB_PAM_VERBOSITY "pam_verbosity"
+#define CONFDB_PAM_RESPONSE_FILTER "pam_response_filter"
#define CONFDB_PAM_ID_TIMEOUT "pam_id_timeout"
#define CONFDB_PAM_PWD_EXPIRATION_WARNING "pam_pwd_expiration_warning"
#define CONFDB_PAM_TRUSTED_USERS "pam_trusted_users"
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index cde196478..381ff9596 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -88,6 +88,7 @@ option_strings = {
'offline_failed_login_attempts' : _('How many failed logins attempts are allowed when offline'),
'offline_failed_login_delay' : _('How long (minutes) to deny login after offline_failed_login_attempts has been reached'),
'pam_verbosity' : _('What kind of messages are displayed to the user during authentication'),
+ 'pam_response_filter' : _('Filter PAM responses send the pam_sss'),
'pam_id_timeout' : _('How many seconds to keep identity information cached for PAM requests'),
'pam_pwd_expiration_warning' : _('How many days before password expiration a warning should be displayed'),
'pam_trusted_users' : _('List of trusted uids or user\'s name'),
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
index b6316be8c..ec716b558 100644
--- a/src/config/cfg_rules.ini
+++ b/src/config/cfg_rules.ini
@@ -99,6 +99,7 @@ option = offline_credentials_expiration
option = offline_failed_login_attempts
option = offline_failed_login_delay
option = pam_verbosity
+option = pam_response_filter
option = pam_id_timeout
option = pam_pwd_expiration_warning
option = get_domains_timeout
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
index 567d52efe..be24bcea0 100644
--- a/src/config/etc/sssd.api.conf
+++ b/src/config/etc/sssd.api.conf
@@ -58,6 +58,7 @@ offline_credentials_expiration = int, None, false
offline_failed_login_attempts = int, None, false
offline_failed_login_delay = int, None, false
pam_verbosity = int, None, false
+pam_response_filter = str, None, false
pam_id_timeout = int, None, false
pam_pwd_expiration_warning = int, None, false
get_domains_timeout = int, None, false
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index 8b862eb0c..71ace5208 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -975,6 +975,51 @@ fallback_homedir = /home/%u
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term>pam_response_filter (integer)</term>
+ <listitem>
+ <para>
+ A comma separated list of strings which allows to
+ remove (filter) data send by the PAM responder to
+ pam_sss PAM module. There are different kind of
+ responses send to pam_sss e.g. messages displayed to
+ the user or environment variables which should be
+ set by pam_sss.
+ </para>
+ <para>
+ While messages already can be controlled with the
+ help of the pam_verbosity option this option allows
+ to filter out other kind of responses as well.
+ </para>
+ <para>
+ Currently the following filters are supported:
+ <variablelist>
+ <varlistentry><term>ENV</term>
+ <listitem><para>Do not sent any environment
+ variables to any service.</para></listitem>
+ </varlistentry>
+ <varlistentry><term>ENV:var_name</term>
+ <listitem><para>Do not sent environment
+ variable var_name to any
+ service.</para></listitem>
+ </varlistentry>
+ <varlistentry><term>ENV:var_name:service</term>
+ <listitem><para>Do not sent environment
+ variable var_name to
+ service.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <para>
+ Default: not set
+ </para>
+ <para>
+ Example: ENV:KRB5CCNAME:sudo-i
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term>pam_id_timeout (integer)</term>
<listitem>
diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h
index 8437d082e..75045d039 100644
--- a/src/responder/pam/pamsrv.h
+++ b/src/responder/pam/pamsrv.h
@@ -101,5 +101,6 @@ pam_set_last_online_auth_with_curr_token(struct sss_domain_info *domain,
uint64_t value);
errno_t filter_responses(struct confdb_ctx *cdb,
- struct response_data *resp_list);
+ struct response_data *resp_list,
+ struct pam_data *pd);
#endif /* __PAMSRV_H__ */
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index b3690d763..0c2e6941c 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -470,14 +470,89 @@ fail:
return ret;
}
+static errno_t filter_responses_env(struct response_data *resp,
+ struct pam_data *pd,
+ char * const *pam_filter_opts)
+{
+ size_t c;
+ const char *var_name;
+ size_t var_name_len;
+ const char *service;
+
+ if (pam_filter_opts == NULL) {
+ return EOK;
+ }
+
+ for (c = 0; pam_filter_opts[c] != NULL; c++) {
+ if (strncmp(pam_filter_opts[c], "ENV", 3) != 0) {
+ continue;
+ }
+
+ var_name = NULL;
+ var_name_len = 0;
+ service = NULL;
+ if (pam_filter_opts[c][3] != '\0') {
+ if (pam_filter_opts[c][3] != ':') {
+ /* Neither plain ENV nor ENV:, ignored */
+ continue;
+ }
+
+ var_name = pam_filter_opts[c] + 4;
+ /* check if there is a second ':' in the option and use the following
+ * data, if any, as service name. */
+ service = strchr(var_name, ':');
+ if (service == NULL) {
+ var_name_len = strlen(var_name);
+ } else {
+ var_name_len = service - var_name;
+
+ service++;
+ /* handle empty service name "ENV:var:" */
+ if (*service == '\0') {
+ service = NULL;
+ }
+ }
+ }
+ /* handle empty var name "ENV:" or "ENV::service" */
+ if (var_name_len == 0) {
+ var_name = NULL;
+ }
+
+ DEBUG(SSSDBG_TRACE_ALL,
+ "Found PAM ENV filter for variable [%.*s] and service [%s].\n",
+ (int) var_name_len, var_name, service);
+
+ if (service != NULL && pd->service != NULL
+ && strcmp(service, pd->service) != 0) {
+ /* current service does not match the filter */
+ continue;
+ }
+
+ if (var_name == NULL) {
+ /* All environment variables should be filtered */
+ resp->do_not_send_to_client = true;
+ continue;
+ }
+
+ if (resp->len > var_name_len && resp->data[var_name_len] == '='
+ && memcmp(resp->data, var_name, var_name_len) == 0) {
+ resp->do_not_send_to_client = true;
+ }
+ }
+
+ return EOK;
+}
+
errno_t filter_responses(struct confdb_ctx *cdb,
- struct response_data *resp_list)
+ struct response_data *resp_list,
+ struct pam_data *pd)
{
int ret;
struct response_data *resp;
uint32_t user_info_type;
- int64_t expire_date;
- int pam_verbosity;
+ int64_t expire_date = 0;
+ int pam_verbosity = DEFAULT_PAM_VERBOSITY;
+ char **pam_filter_opts = NULL;
ret = confdb_get_int(cdb, CONFDB_PAM_CONF_ENTRY,
CONFDB_PAM_VERBOSITY, DEFAULT_PAM_VERBOSITY,
@@ -488,12 +563,22 @@ errno_t filter_responses(struct confdb_ctx *cdb,
pam_verbosity = DEFAULT_PAM_VERBOSITY;
}
+ ret = confdb_get_string_as_list(cdb, pd, CONFDB_PAM_CONF_ENTRY,
+ CONFDB_PAM_RESPONSE_FILTER,
+ &pam_filter_opts);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CONF_SETTINGS, "[%s] not available, not fatal.\n",
+ CONFDB_PAM_RESPONSE_FILTER);
+ pam_filter_opts = NULL;
+ }
+
resp = resp_list;
while(resp != NULL) {
if (resp->type == SSS_PAM_USER_INFO) {
if (resp->len < sizeof(uint32_t)) {
DEBUG(SSSDBG_CRIT_FAILURE, "User info entry is too short.\n");
- return EINVAL;
+ ret = EINVAL;
+ goto done;
}
if (pam_verbosity == PAM_VERBOSITY_NO_MESSAGES) {
@@ -511,7 +596,8 @@ errno_t filter_responses(struct confdb_ctx *cdb,
DEBUG(SSSDBG_CRIT_FAILURE,
"User info offline auth entry is "
"too short.\n");
- return EINVAL;
+ ret = EINVAL;
+ goto done;
}
memcpy(&expire_date, resp->data + sizeof(uint32_t),
sizeof(int64_t));
@@ -528,6 +614,13 @@ errno_t filter_responses(struct confdb_ctx *cdb,
"User info type [%d] not filtered.\n",
user_info_type);
}
+ } else if (resp->type == SSS_PAM_ENV_ITEM) {
+ resp->do_not_send_to_client = false;
+ ret = filter_responses_env(resp, pd, pam_filter_opts);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "filter_responses_env failed.\n");
+ goto done;
+ }
} else if (resp->type & SSS_SERVER_INFO) {
resp->do_not_send_to_client = true;
}
@@ -535,7 +628,11 @@ errno_t filter_responses(struct confdb_ctx *cdb,
resp = resp->next;
}
- return EOK;
+ ret = EOK;
+done:
+ talloc_free(pam_filter_opts);
+
+ return ret;
}
static void pam_reply_delay(struct tevent_context *ev, struct tevent_timer *te,
@@ -782,7 +879,7 @@ static void pam_reply(struct pam_auth_req *preq)
inform_user(pd, pam_account_locked_message);
}
- ret = filter_responses(pctx->rctx->cdb, pd->resp_list);
+ ret = filter_responses(pctx->rctx->cdb, pd->resp_list, pd);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "filter_responses failed, not fatal.\n");
}
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
index 41d177233..3b8327eb3 100644
--- a/src/tests/cmocka/test_pam_srv.c
+++ b/src/tests/cmocka/test_pam_srv.c
@@ -1766,9 +1766,11 @@ void test_filter_response(void **state)
struct pam_data *pd;
uint8_t offline_auth_data[(sizeof(uint32_t) + sizeof(int64_t))];
uint32_t info_type;
+ char *env;
struct sss_test_conf_param pam_params[] = {
{ CONFDB_PAM_VERBOSITY, "1" },
+ { CONFDB_PAM_RESPONSE_FILTER, NULL },
{ NULL, NULL }, /* Sentinel */
};
@@ -1778,6 +1780,15 @@ void test_filter_response(void **state)
pd = talloc_zero(pam_test_ctx, struct pam_data);
assert_non_null(pd);
+ pd->service = discard_const("MyService");
+
+ env = talloc_asprintf(pd, "%s=%s", "MyEnv", "abcdef");
+ assert_non_null(env);
+
+ ret = pam_add_response(pd, SSS_PAM_ENV_ITEM,
+ strlen(env) + 1, (uint8_t *) env);
+ assert_int_equal(ret, EOK);
+
info_type = SSS_PAM_USER_INFO_OFFLINE_AUTH;
memset(offline_auth_data, 0, sizeof(offline_auth_data));
memcpy(offline_auth_data, &info_type, sizeof(uint32_t));
@@ -1785,27 +1796,151 @@ void test_filter_response(void **state)
sizeof(offline_auth_data), offline_auth_data);
assert_int_equal(ret, EOK);
- ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list);
+ /* pd->resp_list points to the SSS_PAM_USER_INFO and pd->resp_list->next
+ * to the SSS_PAM_ENV_ITEM message. */
+
+
+ /* Test CONFDB_PAM_VERBOSITY option */
+ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd);
assert_int_equal(ret, EOK);
assert_true(pd->resp_list->do_not_send_to_client);
+ assert_false(pd->resp_list->next->do_not_send_to_client);
+
+ /* SSS_PAM_USER_INFO_OFFLINE_AUTH message will only be shown with
+ * pam_verbosity 2 or above if cache password never expires. */
+ pam_params[0].value = "2";
+ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb);
+ assert_int_equal(ret, EOK);
+
+ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd);
+ assert_int_equal(ret, EOK);
+ assert_false(pd->resp_list->do_not_send_to_client);
+ assert_false(pd->resp_list->next->do_not_send_to_client);
pam_params[0].value = "0";
ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb);
assert_int_equal(ret, EOK);
- ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list);
+ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd);
assert_int_equal(ret, EOK);
assert_true(pd->resp_list->do_not_send_to_client);
+ assert_false(pd->resp_list->next->do_not_send_to_client);
- /* SSS_PAM_USER_INFO_OFFLINE_AUTH message will only be shown with
- * pam_verbosity 2 or above if cache password never expires. */
- pam_params[0].value = "2";
+ /* Test CONFDB_PAM_RESPONSE_FILTER option */
+ pam_params[1].value = "NoSuchOption";
ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb);
assert_int_equal(ret, EOK);
- ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list);
+ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd);
assert_int_equal(ret, EOK);
- assert_false(pd->resp_list->do_not_send_to_client);
+ assert_true(pd->resp_list->do_not_send_to_client);
+ assert_false(pd->resp_list->next->do_not_send_to_client);
+
+ pam_params[1].value = "ENV"; /* filter all environment variables */
+ /* for all services */
+ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb);
+ assert_int_equal(ret, EOK);
+
+ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd);
+ assert_int_equal(ret, EOK);
+ assert_true(pd->resp_list->do_not_send_to_client);
+ assert_true(pd->resp_list->next->do_not_send_to_client);
+
+ pam_params[1].value = "ENV:"; /* filter all environment variables */
+ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb);
+ assert_int_equal(ret, EOK);
+
+ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd);
+ assert_int_equal(ret, EOK);
+ assert_true(pd->resp_list->do_not_send_to_client);
+ assert_true(pd->resp_list->next->do_not_send_to_client);
+
+ pam_params[1].value = "ENV::"; /* filter all environment variables */
+ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb);
+ assert_int_equal(ret, EOK);
+
+ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd);
+ assert_int_equal(ret, EOK);
+ assert_true(pd->resp_list->do_not_send_to_client);
+ assert_true(pd->resp_list->next->do_not_send_to_client);
+
+ pam_params[1].value = "ENV:abc:"; /* variable name does not match */
+ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb);
+ assert_int_equal(ret, EOK);
+
+ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd);
+ assert_int_equal(ret, EOK);
+ assert_true(pd->resp_list->do_not_send_to_client);
+ assert_false(pd->resp_list->next->do_not_send_to_client);
+
+ pam_params[1].value = "ENV:abc:MyService"; /* variable name does not match */
+ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb);
+ assert_int_equal(ret, EOK);
+
+ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd);
+ assert_int_equal(ret, EOK);
+ assert_true(pd->resp_list->do_not_send_to_client);
+ assert_false(pd->resp_list->next->do_not_send_to_client);
+
+ pam_params[1].value = "ENV::abc"; /* service name does not match */
+ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb);
+ assert_int_equal(ret, EOK);
+
+ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd);
+ assert_int_equal(ret, EOK);
+ assert_true(pd->resp_list->do_not_send_to_client);
+ assert_false(pd->resp_list->next->do_not_send_to_client);
+
+ /* service name does not match */
+ pam_params[1].value = "ENV:MyEnv:abc";
+ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb);
+ assert_int_equal(ret, EOK);
+
+ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd);
+ assert_int_equal(ret, EOK);
+ assert_true(pd->resp_list->do_not_send_to_client);
+ assert_false(pd->resp_list->next->do_not_send_to_client);
+
+ pam_params[1].value = "ENV:MyEnv"; /* match */
+ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb);
+ assert_int_equal(ret, EOK);
+
+ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd);
+ assert_int_equal(ret, EOK);
+ assert_true(pd->resp_list->do_not_send_to_client);
+ assert_true(pd->resp_list->next->do_not_send_to_client);
+
+ pam_params[1].value = "ENV:MyEnv:"; /* match */
+ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb);
+ assert_int_equal(ret, EOK);
+
+ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd);
+ assert_int_equal(ret, EOK);
+ assert_true(pd->resp_list->do_not_send_to_client);
+ assert_true(pd->resp_list->next->do_not_send_to_client);
+
+ pam_params[1].value = "ENV:MyEnv:MyService"; /* match */
+ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb);
+ assert_int_equal(ret, EOK);
+
+ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd);
+ assert_int_equal(ret, EOK);
+ assert_true(pd->resp_list->do_not_send_to_client);
+ assert_true(pd->resp_list->next->do_not_send_to_client);
+
+ /* multiple rules with a match */
+ pam_params[1].value = "ENV:abc:def, "
+ "ENV:MyEnv:MyService, "
+ "ENV:stu:xyz";
+ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb);
+ assert_int_equal(ret, EOK);
+
+ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd);
+ assert_int_equal(ret, EOK);
+ assert_true(pd->resp_list->do_not_send_to_client);
+ assert_true(pd->resp_list->next->do_not_send_to_client);
+
+ talloc_free(pd);
}
int main(int argc, const char *argv[])
--
2.11.0

View File

@ -0,0 +1,343 @@
From e6c3d9e680eab264777348389b4bcda73bd5ba6d Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Fri, 28 Oct 2016 13:46:02 +0200
Subject: [PATCH 17/39] SYSDB: Split sysdb_try_to_find_expected_dn() into
smaller functions
The function sysdb_try_to_find_expected_dn was performing several matching
algorithms and thus it was getting big and hard to extend. This patch
doesn't contain any functional changes, only shuffles the code around
and splits the monolithic sysdb_try_to_find_expected_dn function into
smaller blocks.
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit e5a984093ad7921c83da75272cede2b0e52ba2d6)
(cherry picked from commit 3f3dc8c737a8e8cfc4a29d7dbaf526ec3973c7a0)
---
src/db/sysdb_subdomains.c | 278 +++++++++++++++++++++++++++++-----------------
1 file changed, 179 insertions(+), 99 deletions(-)
diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
index ff83f914f..b011bad6c 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -1145,74 +1145,29 @@ done:
return ret;
}
-errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
- const char *domain_component_name,
- struct sysdb_attrs **usr_attrs,
- size_t count,
- struct sysdb_attrs **exp_usr)
+static errno_t match_cn_users(TALLOC_CTX *tmp_ctx,
+ struct sysdb_attrs **usr_attrs,
+ size_t count,
+ const char *dom_basedn,
+ struct sysdb_attrs **_result)
{
- char *dom_basedn;
- size_t dom_basedn_len;
- char *expected_basedn;
- size_t expected_basedn_len;
- size_t dn_len;
+ errno_t ret;
const char *orig_dn;
- size_t c = 0;
- int ret;
- TALLOC_CTX *tmp_ctx;
- struct ldb_context *ldb_ctx;
- struct ldb_dn *ldb_dom_basedn;
- int dom_basedn_comp_num;
- struct ldb_dn *ldb_dn;
- int dn_comp_num;
- const char *component_name;
+ size_t dn_len;
struct sysdb_attrs *result = NULL;
const char *result_dn_str = NULL;
+ char *cn_users_basedn;
+ size_t cn_users_basedn_len;
- if (dom == NULL || domain_component_name == NULL || usr_attrs == NULL
- || count == 0) {
- return EINVAL;
- }
-
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
- return ENOMEM;
- }
-
- ret = domain_to_basedn(tmp_ctx, dom->name, &dom_basedn);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n");
- goto done;
- }
- expected_basedn = talloc_asprintf(tmp_ctx, "%s%s", "cn=users,", dom_basedn);
- if (expected_basedn == NULL) {
- ret = ENOMEM;
- goto done;
- }
-
- ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb);
- if (ldb_ctx == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n");
- ret = EINVAL;
- goto done;
- }
-
- ldb_dom_basedn = ldb_dn_new(tmp_ctx, ldb_ctx, dom_basedn);
- if (ldb_dom_basedn == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
+ cn_users_basedn = talloc_asprintf(tmp_ctx, "%s%s", "cn=users,", dom_basedn);
+ if (cn_users_basedn == NULL) {
ret = ENOMEM;
goto done;
}
+ cn_users_basedn_len = strlen(cn_users_basedn);
+ DEBUG(SSSDBG_TRACE_ALL, "cn=users baseDN is [%s].\n", cn_users_basedn);
- dom_basedn_comp_num = ldb_dn_get_comp_num(ldb_dom_basedn);
- dom_basedn_comp_num++;
-
- DEBUG(SSSDBG_TRACE_ALL, "Expected BaseDN is [%s].\n", expected_basedn);
- expected_basedn_len = strlen(expected_basedn);
- dom_basedn_len = strlen(dom_basedn);
-
- for (c = 0; c < count; c++) {
+ for (size_t c = 0; c < count; c++) {
ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
@@ -1220,9 +1175,9 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
}
dn_len = strlen(orig_dn);
- if (dn_len > expected_basedn_len
- && strcasecmp(orig_dn + (dn_len - expected_basedn_len),
- expected_basedn) == 0) {
+ if (dn_len > cn_users_basedn_len
+ && strcasecmp(orig_dn + (dn_len - cn_users_basedn_len),
+ cn_users_basedn) == 0) {
DEBUG(SSSDBG_TRACE_ALL,
"Found matching dn [%s].\n", orig_dn);
if (result != NULL) {
@@ -1237,52 +1192,177 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
}
}
- if (result == NULL) {
- for (c = 0; c < count; c++) {
- ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
+ ret = EOK;
+done:
+ *_result = result;
+ return ret;
+}
+
+static errno_t match_non_dc_comp(TALLOC_CTX *tmp_ctx,
+ struct sss_domain_info *dom,
+ struct sysdb_attrs **usr_attrs,
+ size_t count,
+ struct ldb_dn *ldb_basedn,
+ const char *basedn,
+ const char *domain_component_name,
+ struct sysdb_attrs **_result)
+{
+ errno_t ret;
+ const char *orig_dn;
+ size_t orig_dn_len;
+ size_t basedn_len;
+ struct ldb_context *ldb_ctx;
+ struct ldb_dn *ldb_orig_dn;
+ int dn_comp_num;
+ int basedn_comp_num;
+ const char *component_name;
+ struct sysdb_attrs *result = NULL;
+ const char *result_dn_str = NULL;
+
+ ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb);
+ if (ldb_ctx == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ basedn_len = strlen(basedn);
+
+ basedn_comp_num = ldb_dn_get_comp_num(ldb_basedn);
+ basedn_comp_num++;
+
+ for (size_t c = 0; c < count; c++) {
+ ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
+ goto done;
+ }
+ orig_dn_len = strlen(orig_dn);
+
+ if (orig_dn_len > basedn_len
+ /* Does the user's original DN with the non-domain part
+ * stripped match the domain base DN?
+ */
+ && strcasecmp(orig_dn + (orig_dn_len - basedn_len),
+ basedn) == 0) {
+ ldb_orig_dn = ldb_dn_new(tmp_ctx, ldb_ctx, orig_dn);
+ if (ldb_orig_dn == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed");
+ ret = ENOMEM;
goto done;
}
- dn_len = strlen(orig_dn);
-
- if (dn_len > dom_basedn_len
- && strcasecmp(orig_dn + (dn_len - dom_basedn_len),
- dom_basedn) == 0) {
- ldb_dn = ldb_dn_new(tmp_ctx, ldb_ctx, orig_dn);
- if (ldb_dn == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed");
- ret = ENOMEM;
- goto done;
- }
- dn_comp_num = ldb_dn_get_comp_num(ldb_dn);
- if (dn_comp_num > dom_basedn_comp_num) {
- component_name = ldb_dn_get_component_name(ldb_dn,
- (dn_comp_num - dom_basedn_comp_num));
- DEBUG(SSSDBG_TRACE_ALL, "Comparing [%s] and [%s].\n",
- component_name,
- domain_component_name);
- if (component_name != NULL
- && strcasecmp(component_name,
- domain_component_name) != 0) {
- DEBUG(SSSDBG_TRACE_ALL,
- "Found matching dn [%s].\n", orig_dn);
- if (result != NULL) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Found 2 matching DN [%s] and [%s], "
- "expecting only 1.\n", result_dn_str, orig_dn);
- ret = EINVAL;
- goto done;
- }
- result = usr_attrs[c];
- result_dn_str = orig_dn;
+ dn_comp_num = ldb_dn_get_comp_num(ldb_orig_dn);
+ if (dn_comp_num > basedn_comp_num) {
+ component_name = ldb_dn_get_component_name(ldb_orig_dn,
+ (dn_comp_num - basedn_comp_num));
+ DEBUG(SSSDBG_TRACE_ALL, "Comparing [%s] and [%s].\n",
+ component_name,
+ domain_component_name);
+ /* If the component is NOT a DC component, then the entry
+ * must come from our domain, perhaps from a child container.
+ * If it matched the DC component, the entry was from a child
+ * subdomain different from this one.
+ */
+ if (component_name != NULL
+ && strcasecmp(component_name,
+ domain_component_name) != 0) {
+ DEBUG(SSSDBG_TRACE_ALL,
+ "Found matching dn [%s].\n", orig_dn);
+ if (result != NULL) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Found 2 matching DN [%s] and [%s], "
+ "expecting only 1.\n", result_dn_str, orig_dn);
+ ret = EINVAL;
+ goto done;
}
+ result = usr_attrs[c];
+ result_dn_str = orig_dn;
}
}
}
}
+ ret = EOK;
+ *_result = result;
+done:
+ return ret;
+}
+
+static errno_t match_basedn(TALLOC_CTX *tmp_ctx,
+ struct sss_domain_info *dom,
+ struct sysdb_attrs **usr_attrs,
+ size_t count,
+ const char *dom_basedn,
+ const char *domain_component_name,
+ struct sysdb_attrs **_result)
+{
+ struct ldb_context *ldb_ctx;
+ struct ldb_dn *ldb_dom_basedn;
+
+ ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb);
+ if (ldb_ctx == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n");
+ return EINVAL;
+ }
+
+
+ ldb_dom_basedn = ldb_dn_new(tmp_ctx, ldb_ctx, dom_basedn);
+ if (ldb_dom_basedn == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
+ return ENOMEM;
+ }
+
+ return match_non_dc_comp(tmp_ctx, dom,
+ usr_attrs, count,
+ ldb_dom_basedn, dom_basedn,
+ domain_component_name,
+ _result);
+}
+
+errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
+ const char *domain_component_name,
+ struct sysdb_attrs **usr_attrs,
+ size_t count,
+ struct sysdb_attrs **exp_usr)
+{
+ char *dom_basedn;
+ int ret;
+ TALLOC_CTX *tmp_ctx;
+ struct sysdb_attrs *result = NULL;
+
+ if (dom == NULL || domain_component_name == NULL
+ || usr_attrs == NULL || count == 0) {
+ return EINVAL;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
+ return ENOMEM;
+ }
+
+ ret = domain_to_basedn(tmp_ctx, dom->name, &dom_basedn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ ret = match_cn_users(tmp_ctx, usr_attrs, count, dom_basedn, &result);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ if (result == NULL) {
+ ret = match_basedn(tmp_ctx, dom, usr_attrs,
+ count, dom_basedn, domain_component_name,
+ &result);
+ if (ret != EOK) {
+ goto done;
+ }
+ }
+
if (result == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "No matching DN found.\n");
ret = ENOENT;
--
2.11.0

View File

@ -0,0 +1,284 @@
From 8e08e21b64a9ef67a4c40917786536d69d7ec4d3 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Mon, 31 Oct 2016 21:39:57 +0100
Subject: [PATCH 18/39] SYSDB: Augment sysdb_try_to_find_expected_dn to match
search base as well
In cases where the domain name in sssd.conf does not match the AD
domain, our previous matching process wouldn't match. This patch
augments the matching as follows:
- the search base is known to sysdb_try_to_find_expected_dn and is
expected to be non-NULL
- the existing matching is ran first
- during the search base, matching, all the non-DC components are
stripped from the search base to 'canonicalize' the search base
- if only a single entry that matches with a non-DC DN component
(matching with a DC component would mean the DN comes from a
different domain) then this entry is a match and is returned
Resolves:
https://fedorahosted.org/sssd/ticket/3199
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 24d8c85fae253f988165c112af208198cf48eef6)
(cherry picked from commit 956fdd727f8d7a28f1456146b3b7dfee49f38626)
---
src/db/sysdb.h | 1 +
src/db/sysdb_subdomains.c | 99 ++++++++++++++++++++++++++++++
src/providers/ldap/sdap_async_initgroups.c | 8 ++-
src/tests/cmocka/test_sysdb_subdomains.c | 43 +++++++++++--
4 files changed, 144 insertions(+), 7 deletions(-)
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 901268390..5dedd97dd 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -1297,6 +1297,7 @@ errno_t sysdb_handle_original_uuid(const char *orig_name,
errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
const char *domain_component_name,
+ const char *ldap_search_base,
struct sysdb_attrs **usr_attrs,
size_t count,
struct sysdb_attrs **exp_usr);
diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
index b011bad6c..780140484 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -1320,8 +1320,97 @@ static errno_t match_basedn(TALLOC_CTX *tmp_ctx,
_result);
}
+static errno_t match_search_base(TALLOC_CTX *tmp_ctx,
+ struct sss_domain_info *dom,
+ const char *domain_component_name,
+ const char *domain_search_base,
+ struct sysdb_attrs **usr_attrs,
+ size_t count,
+ struct sysdb_attrs **_result)
+{
+ errno_t ret;
+ bool ok;
+ const char *search_base;
+ struct ldb_context *ldb_ctx;
+ struct sysdb_attrs *result = NULL;
+ struct ldb_dn *ldb_search_base;
+ int search_base_comp_num;
+ int non_dc_comp_num;
+ const char *component_name;
+
+ ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb);
+ if (ldb_ctx == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ ldb_search_base = ldb_dn_new(tmp_ctx, ldb_ctx, domain_search_base);
+ if (ldb_search_base == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ /* strip non-DC components from the search base */
+ search_base_comp_num = ldb_dn_get_comp_num(ldb_search_base);
+ for (non_dc_comp_num = 0;
+ non_dc_comp_num < search_base_comp_num;
+ non_dc_comp_num++) {
+
+ component_name = ldb_dn_get_component_name(ldb_search_base,
+ non_dc_comp_num);
+ if (strcasecmp(domain_component_name, component_name) == 0) {
+ break;
+ }
+ }
+
+ if (non_dc_comp_num == search_base_comp_num) {
+ /* The search base does not have any non-DC components, the search wouldn't
+ * match anyway
+ */
+ ret = EOK;
+ *_result = NULL;
+ goto done;
+ }
+
+ ok = ldb_dn_remove_child_components(ldb_search_base, non_dc_comp_num);
+ if (!ok) {
+ ret = EINVAL;
+ goto done;
+ }
+
+ search_base = ldb_dn_get_linearized(ldb_search_base);
+ if (search_base == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = match_cn_users(tmp_ctx, usr_attrs, count, search_base, &result);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ if (result == NULL) {
+ ret = match_non_dc_comp(tmp_ctx, dom,
+ usr_attrs, count,
+ ldb_search_base, search_base,
+ domain_component_name,
+ &result);
+ if (ret != EOK) {
+ goto done;
+ }
+ }
+
+ ret = EOK;
+ *_result = result;
+done:
+ return ret;
+}
+
errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
const char *domain_component_name,
+ const char *domain_search_base,
struct sysdb_attrs **usr_attrs,
size_t count,
struct sysdb_attrs **exp_usr)
@@ -1332,6 +1421,7 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
struct sysdb_attrs *result = NULL;
if (dom == NULL || domain_component_name == NULL
+ || domain_search_base == NULL
|| usr_attrs == NULL || count == 0) {
return EINVAL;
}
@@ -1364,6 +1454,15 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
}
if (result == NULL) {
+ ret = match_search_base(tmp_ctx, dom, domain_component_name,
+ domain_search_base, usr_attrs, count,
+ &result);
+ if (ret != EOK) {
+ goto done;
+ }
+ }
+
+ if (result == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "No matching DN found.\n");
ret = ENOENT;
goto done;
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index 45fc007e0..9b505e7fa 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -2947,7 +2947,13 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
DEBUG(SSSDBG_OP_FAILURE,
"Expected one user entry and got %zu\n", count);
- ret = sysdb_try_to_find_expected_dn(state->dom, "dc", usr_attrs, count,
+ /* When matching against a search base, it's sufficient to pick only
+ * the first search base because all bases in a single domain would
+ * have the same DC= components
+ */
+ ret = sysdb_try_to_find_expected_dn(state->dom, "dc",
+ state->sdom->search_bases[0]->basedn,
+ usr_attrs, count,
&state->orig_user);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
diff --git a/src/tests/cmocka/test_sysdb_subdomains.c b/src/tests/cmocka/test_sysdb_subdomains.c
index c9db56841..52056e043 100644
--- a/src/tests/cmocka/test_sysdb_subdomains.c
+++ b/src/tests/cmocka/test_sysdb_subdomains.c
@@ -520,7 +520,9 @@ static void test_try_to_find_expected_dn(void **state)
int ret;
struct sysdb_attrs *result;
struct sysdb_attrs *usr_attrs[10] = { NULL };
+ struct sysdb_attrs *dom_usr_attrs[10] = { NULL };
struct sss_domain_info *dom;
+ char *dom_basedn;
struct subdom_test_ctx *test_ctx =
talloc_get_type(*state, struct subdom_test_ctx);
@@ -528,6 +530,9 @@ static void test_try_to_find_expected_dn(void **state)
"child2.test_sysdb_subdomains_2", true);
assert_non_null(dom);
+ ret = domain_to_basedn(test_ctx, dom->name, &dom_basedn);
+ assert_int_equal(ret, EOK);
+
usr_attrs[0] = sysdb_new_attrs(test_ctx);
assert_non_null(usr_attrs[0]);
@@ -535,13 +540,13 @@ static void test_try_to_find_expected_dn(void **state)
"uid=user,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2");
assert_int_equal(ret, EOK);
- ret = sysdb_try_to_find_expected_dn(NULL, NULL, NULL, 0, NULL);
+ ret = sysdb_try_to_find_expected_dn(NULL, NULL, NULL, NULL, 0, NULL);
assert_int_equal(ret, EINVAL);
- ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 1, &result);
+ ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, usr_attrs, 1, &result);
assert_int_equal(ret, ENOENT);
- ret = sysdb_try_to_find_expected_dn(dom, "xy", usr_attrs, 1, &result);
+ ret = sysdb_try_to_find_expected_dn(dom, "xy", dom_basedn, usr_attrs, 1, &result);
assert_int_equal(ret, EOK);
assert_ptr_equal(result, usr_attrs[0]);
@@ -559,11 +564,11 @@ static void test_try_to_find_expected_dn(void **state)
"uid=user2,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2");
assert_int_equal(ret, EOK);
- ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 3, &result);
+ ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, usr_attrs, 3, &result);
assert_int_equal(ret, EOK);
assert_ptr_equal(result, usr_attrs[1]);
- ret = sysdb_try_to_find_expected_dn(dom, "xy", usr_attrs, 3, &result);
+ ret = sysdb_try_to_find_expected_dn(dom, "xy", dom_basedn, usr_attrs, 3, &result);
assert_int_equal(ret, EINVAL);
/* Make sure cn=users match is preferred */
@@ -575,10 +580,36 @@ static void test_try_to_find_expected_dn(void **state)
"uid=user2,cn=abc,cn=users,dc=child2,dc=test_sysdb_subdomains_2");
assert_int_equal(ret, EOK);
- ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 3, &result);
+ ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, usr_attrs, 3, &result);
assert_int_equal(ret, EOK);
assert_ptr_equal(result, usr_attrs[2]);
+ /* test a case where the domain name does not match the basedn */
+ dom->name = discard_const("default");
+ dom_usr_attrs[0] = usr_attrs[0];
+
+ ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, dom_usr_attrs, 1, &result);
+ assert_int_equal(ret, ENOENT);
+
+ dom_usr_attrs[1] = usr_attrs[1];
+ dom_usr_attrs[2] = usr_attrs[2];
+
+ /* Make sure cn=users match is preferred */
+ ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, dom_usr_attrs, 3, &result);
+ assert_int_equal(ret, EOK);
+ assert_ptr_equal(result, dom_usr_attrs[2]);
+
+ talloc_free(usr_attrs[2]);
+ usr_attrs[2] = sysdb_new_attrs(test_ctx);
+ assert_non_null(usr_attrs[2]);
+ ret = sysdb_attrs_add_string(usr_attrs[2], SYSDB_ORIG_DN,
+ "uid=user2,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2");
+ assert_int_equal(ret, EOK);
+
+ dom_usr_attrs[2] = usr_attrs[2];
+ ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, dom_usr_attrs, 3, &result);
+ assert_int_equal(ret, EOK);
+ assert_ptr_equal(result, usr_attrs[1]);
talloc_free(usr_attrs[0]);
talloc_free(usr_attrs[1]);
--
2.11.0

View File

@ -0,0 +1,55 @@
From 7186923d877605f632fa17053a674f8266fd08bb Mon Sep 17 00:00:00 2001
From: Mike Ely <github@taupehat.com>
Date: Wed, 2 Nov 2016 11:26:21 -0700
Subject: [PATCH 19/39] ad_access_filter search for nested groups
Includes instructions and example for AD nested group access
Related to https://fedorahosted.org/sssd/ticket/3218
Signed-off-by: Mike Ely <github@taupehat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit cf5357ae83cc9fe2240038b8bdccec2cb98991fc)
(cherry picked from commit e1c2aead482cd4bf83a7fe5e68630a981389e82b)
---
src/man/sssd-ad.5.xml | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml
index 8a2f4ade9..2618f8324 100644
--- a/src/man/sssd-ad.5.xml
+++ b/src/man/sssd-ad.5.xml
@@ -236,6 +236,19 @@ ad_enabled_domains = sales.example.com, eng.example.com
search bases work.
</para>
<para>
+ Nested group membership must be searched for using
+ a special OID <quote>:1.2.840.113556.1.4.1941:</quote>
+ in addition to the full DOM:domain.example.org: syntax
+ to ensure the parser does not attempt to interpret the
+ colon characters associated with the OID. If you do not
+ use this OID then nested group membership will not be
+ resolved. See usage example below and refer here
+ for further information about the OID:
+ <ulink
+ url="https://msdn.microsoft.com/en-us/library/cc223367.aspx">
+ [MS-ADTS] section LDAP extensions</ulink>
+ </para>
+ <para>
The most specific match is always used. For
example, if the option specified filter
for a domain the user is a member of and a
@@ -255,6 +268,9 @@ DOM:dom2:(memberOf=cn=admins,ou=groups,dc=dom2,dc=com)
# apply filter on forest called EXAMPLE.COM only:
FOREST:EXAMPLE.COM:(memberOf=cn=admins,ou=groups,dc=example,dc=com)
+
+# apply filter for a member of a nested group in dom1:
+DOM:dom1:(memberOf:1.2.840.113556.1.4.1941:=cn=nestedgroup,ou=groups,dc=example,dc=com)
</programlisting>
<para>
Default: Not set
--
2.11.0

View File

@ -0,0 +1,61 @@
From 90adb9afec7b3cd2f6548d7f050785777492c827 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 7 Nov 2016 11:53:21 +0100
Subject: [PATCH 20/39] BUILD: Fix linking with librt
The posix realime extensions defines timer_* functions
but it does not mention library with these functions.
http://www.unix.org/version2/whatsnew/realtime.html
The autoconf macro AC_SEARCH_LIBS firstly check the function
timer_create with no libraries, then for each library listed
in 2nd parameter. Possible libraries librt and libposix4
were used in nspr for similar detection.
Reviewed-by: Joakim Tjernlund <joakim.tjernlund@infinera.com>
(cherry picked from commit 6d11fdcd8ef05000dd20b3431f8491790f99a802)
(cherry picked from commit a3b668868a1c10be63be9151d347100172b71c6c)
---
Makefile.am | 1 +
configure.ac | 13 +++++++++++++
2 files changed, 14 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index d08e39fa4..51c67360d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -960,6 +960,7 @@ libsss_util_la_CFLAGS = \
$(SYSTEMD_LOGIN_CFLAGS) \
$(NULL)
libsss_util_la_LIBADD = \
+ $(LIBADD_TIMER) \
$(SSSD_LIBS) \
$(SYSTEMD_LOGIN_LIBS) \
$(UNICODE_LIBS) \
diff --git a/configure.ac b/configure.ac
index 3dbcf9e1f..d3ef1e162 100644
--- a/configure.ac
+++ b/configure.ac
@@ -70,6 +70,19 @@ AC_CHECK_FUNCS([ pthread_mutexattr_setrobust \
pthread_mutex_consistent_np ])
LIBS=$SAVE_LIBS
+# Check library for the timer_create function
+SAVE_LIBS=$LIBS
+LIBS=
+LIBADD_TIMER=
+AC_SEARCH_LIBS([timer_create], [rt posix4],
+ [AC_DEFINE([HAVE_LIBRT], [1],
+ [Define if you have the librt library or equivalent.])
+ LIBADD_TIMER="$LIBS"],
+ [AC_MSG_ERROR([unable to find library fot the timer_create() function])])
+
+AC_SUBST([LIBADD_TIMER])
+LIBS=$SAVE_LIBS
+
# Check for presence of modern functions for setting file timestamps
AC_CHECK_FUNCS([ utimensat \
futimens ])
--
2.11.0

View File

@ -0,0 +1,74 @@
From 287acba9b1b7d91811d8e8a22ed5e7824e8a26b3 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Mon, 7 Nov 2016 11:58:20 +0100
Subject: [PATCH 21/39] MONITOR: Do not set up watchdog for monitor
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
It makes little sense to set up watchdog for monitor because there is no
entity that would restart the monitor. Therefore we should disable the
watchdog for monitor process.
Resolves:
https://fedorahosted.org/sssd/ticket/3232
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit fbe6644aa28d93f492434950680c5618eb567712)
(cherry picked from commit 2d88a121918e800b266d018d43dad9bd374b10a7)
---
src/monitor/monitor.c | 2 ++
src/util/server.c | 11 +++++++----
src/util/util.h | 1 +
3 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 84a144e56..935febb95 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -2603,6 +2603,8 @@ int main(int argc, const char *argv[])
/* we want a pid file check */
flags |= FLAGS_PID_FILE;
+ /* the monitor should not run a watchdog on itself */
+ flags |= FLAGS_NO_WATCHDOG;
/* Open before server_setup() does to have logging
* during configuration checking */
diff --git a/src/util/server.c b/src/util/server.c
index 953cd3d61..013e572e6 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -666,10 +666,13 @@ int server_setup(const char *name, int flags,
ret, strerror(ret));
return ret;
}
- ret = setup_watchdog(ctx->event_ctx, watchdog_interval);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Watchdog setup failed.\n");
- return ret;
+
+ if ((flags & FLAGS_NO_WATCHDOG) == 0) {
+ ret = setup_watchdog(ctx->event_ctx, watchdog_interval);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Watchdog setup failed.\n");
+ return ret;
+ }
}
sss_log(SSS_LOG_INFO, "Starting up");
diff --git a/src/util/util.h b/src/util/util.h
index 9c39a5cc5..4bfccfa2b 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -88,6 +88,7 @@
#define FLAGS_INTERACTIVE 0x0002
#define FLAGS_PID_FILE 0x0004
#define FLAGS_GEN_CONF 0x0008
+#define FLAGS_NO_WATCHDOG 0x0010
#define PIPE_INIT { -1, -1 }
--
2.11.0

View File

@ -0,0 +1,107 @@
From b87ca4233342e1537fda5ce731db77cf24e422c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20=C4=8Cech?= <pcech@redhat.com>
Date: Wed, 12 Oct 2016 16:48:38 +0200
Subject: [PATCH 22/39] SYSDB: Adding lowercase sudoUser form
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If domain is not case sensitive we add lowercase form of usernames
to sudoUser attributes. So we actually able to apply sudoRule on
user Administrator@... with login admnistrator@...
Resolves:
https://fedorahosted.org/sssd/ticket/3203
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit f4a1046bb88d7a0ab3617e49ae94bfa849d10645)
(cherry picked from commit 88239b7f17f599aefa88a8a31c2d0ea44b766c87)
---
src/db/sysdb_sudo.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git a/src/db/sysdb_sudo.c b/src/db/sysdb_sudo.c
index 601fb63f2..4bd93ffc6 100644
--- a/src/db/sysdb_sudo.c
+++ b/src/db/sysdb_sudo.c
@@ -852,6 +852,65 @@ sysdb_sudo_add_sss_attrs(struct sysdb_attrs *rule,
return EOK;
}
+static errno_t sysdb_sudo_add_lowered_users(struct sss_domain_info *domain,
+ struct sysdb_attrs *rule)
+{
+ TALLOC_CTX *tmp_ctx;
+ const char **users = NULL;
+ const char *lowered = NULL;
+ errno_t ret;
+
+ if (domain->case_sensitive == true || rule == NULL) {
+ return EOK;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ ret = sysdb_attrs_get_string_array(rule, SYSDB_SUDO_CACHE_AT_USER, tmp_ctx,
+ &users);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to get %s attribute [%d]: %s\n",
+ SYSDB_SUDO_CACHE_AT_USER, ret, strerror(ret));
+ goto done;
+ }
+
+ if (users == NULL) {
+ ret = EOK;
+ goto done;
+ }
+
+ for (int i = 0; users[i] != NULL; i++) {
+ lowered = sss_tc_utf8_str_tolower(tmp_ctx, users[i]);
+ if (lowered == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot convert name to lowercase.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ if (strcmp(users[i], lowered) == 0) {
+ /* It protects us from adding duplicate. */
+ continue;
+ }
+
+ ret = sysdb_attrs_add_string(rule, SYSDB_SUDO_CACHE_AT_USER, lowered);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Unable to add %s attribute [%d]: %s\n",
+ SYSDB_SUDO_CACHE_AT_USER, ret, strerror(ret));
+ goto done;
+ }
+ }
+
+ ret = EOK;
+
+done:
+ talloc_zfree(tmp_ctx);
+ return ret;
+}
+
static errno_t
sysdb_sudo_store_rule(struct sss_domain_info *domain,
struct sysdb_attrs *rule,
@@ -868,6 +927,11 @@ sysdb_sudo_store_rule(struct sss_domain_info *domain,
DEBUG(SSSDBG_TRACE_FUNC, "Adding sudo rule %s\n", name);
+ ret = sysdb_sudo_add_lowered_users(domain, rule);
+ if (ret != EOK) {
+ return ret;
+ }
+
ret = sysdb_sudo_add_sss_attrs(rule, name, cache_timeout, now);
if (ret != EOK) {
return ret;
--
2.11.0

View File

@ -0,0 +1,225 @@
From 1cd53e7a9cdb95aeca6a3f9ae4a6e32072f74ee7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20=C4=8Cech?= <pcech@redhat.com>
Date: Thu, 13 Oct 2016 09:31:52 +0200
Subject: [PATCH 23/39] TESTS: Extending sysdb sudo store tests
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We covered diference between case sensitive and case insensitive
domains. If domain is case insensitive we add lowercase form of
sudoUser to local sysdb cache.
Resolves:
https://fedorahosted.org/sssd/ticket/3203
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit 23637e2fd2b1fe42bdd2335893a11ac8016f56bc)
(cherry picked from commit 143b1dcbbe865a139616a22b139e19bd772e46f0)
---
src/tests/cmocka/test_sysdb_sudo.c | 168 ++++++++++++++++++++++++++++++++++++-
1 file changed, 167 insertions(+), 1 deletion(-)
diff --git a/src/tests/cmocka/test_sysdb_sudo.c b/src/tests/cmocka/test_sysdb_sudo.c
index 889de7237..f21ff3655 100644
--- a/src/tests/cmocka/test_sysdb_sudo.c
+++ b/src/tests/cmocka/test_sysdb_sudo.c
@@ -44,7 +44,7 @@ struct test_user {
const char *name;
uid_t uid;
gid_t gid;
-} users[] = { { "test_user1", 1001, 1001 },
+} users[] = { { "test_USER1", 1001, 1001 },
{ "test_user2", 1002, 1002 },
{ "test_user3", 1003, 1003 } };
@@ -104,6 +104,29 @@ static void create_rule_attrs(struct sysdb_attrs *rule, int i)
assert_int_equal(ret, EOK);
}
+static void create_rule_attrs_multiple_sudoUser(struct sysdb_attrs *rule)
+{
+ errno_t ret;
+
+ ret = sysdb_attrs_add_string_safe(rule, SYSDB_SUDO_CACHE_AT_CN,
+ rules[0].name);
+ assert_int_equal(ret, EOK);
+
+ ret = sysdb_attrs_add_string_safe(rule, SYSDB_SUDO_CACHE_AT_HOST,
+ rules[0].host);
+ assert_int_equal(ret, EOK);
+
+ ret = sysdb_attrs_add_string_safe(rule, SYSDB_SUDO_CACHE_AT_RUNASUSER,
+ rules[0].as_user);
+ assert_int_equal(ret, EOK);
+
+ for (int i = 0; i < 3; i++ ) {
+ ret = sysdb_attrs_add_string_safe(rule, SYSDB_SUDO_CACHE_AT_USER,
+ users[i].name);
+ assert_int_equal(ret, EOK);
+ }
+}
+
static int get_stored_rules_count(struct sysdb_test_ctx *test_ctx)
{
errno_t ret;
@@ -217,6 +240,143 @@ void test_store_sudo(void **state)
talloc_zfree(msgs);
}
+void test_store_sudo_case_sensitive(void **state)
+{
+ errno_t ret;
+ char *filter;
+ const char *attrs[] = { SYSDB_SUDO_CACHE_AT_CN, SYSDB_SUDO_CACHE_AT_HOST,
+ SYSDB_SUDO_CACHE_AT_RUNASUSER,
+ SYSDB_SUDO_CACHE_AT_USER, NULL };
+ struct ldb_message **msgs = NULL;
+ size_t msgs_count;
+ const char *result;
+ struct ldb_message_element *element;
+ struct sysdb_attrs *rule;
+ struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state,
+ struct sysdb_test_ctx);
+ const char *lowered_name = sss_tc_utf8_str_tolower(test_ctx, users[0].name);
+
+ rule = sysdb_new_attrs(test_ctx);
+ assert_non_null(rule);
+ create_rule_attrs_multiple_sudoUser(rule);
+
+ test_ctx->tctx->dom->case_sensitive = true;
+
+ ret = sysdb_sudo_store(test_ctx->tctx->dom, &rule, 1);
+ assert_int_equal(ret, EOK);
+
+ filter = sysdb_sudo_filter_user(test_ctx, users[0].name, NULL, 0);
+ assert_non_null(filter);
+
+ ret = sysdb_search_sudo_rules(test_ctx, test_ctx->tctx->dom, filter,
+ attrs, &msgs_count, &msgs);
+ assert_int_equal(ret, EOK);
+
+ assert_int_equal(msgs_count, 1);
+
+ result = ldb_msg_find_attr_as_string(msgs[0], SYSDB_SUDO_CACHE_AT_CN, NULL);
+ assert_non_null(result);
+ assert_string_equal(result, rules[0].name);
+
+ result = ldb_msg_find_attr_as_string(msgs[0], SYSDB_SUDO_CACHE_AT_HOST,
+ NULL);
+ assert_non_null(result);
+ assert_string_equal(result, rules[0].host);
+
+ result = ldb_msg_find_attr_as_string(msgs[0], SYSDB_SUDO_CACHE_AT_RUNASUSER,
+ NULL);
+ assert_non_null(result);
+ assert_string_equal(result, rules[0].as_user);
+
+ ret = ldb_msg_check_string_attribute(msgs[0], SYSDB_SUDO_CACHE_AT_USER,
+ users[0].name);
+ assert_int_equal(ret, 1);
+
+ ret = ldb_msg_check_string_attribute(msgs[0], SYSDB_SUDO_CACHE_AT_USER,
+ lowered_name);
+ assert_int_equal(ret, 0);
+
+ ret = ldb_msg_check_string_attribute(msgs[0], SYSDB_SUDO_CACHE_AT_USER,
+ users[1].name);
+ assert_int_equal(ret, 1);
+
+ ret = ldb_msg_check_string_attribute(msgs[0], SYSDB_SUDO_CACHE_AT_USER,
+ users[2].name);
+ assert_int_equal(ret, 1);
+
+ element = ldb_msg_find_element(msgs[0], SYSDB_SUDO_CACHE_AT_USER);
+ assert_int_equal(element->num_values, 3);
+
+ talloc_zfree(lowered_name);
+ talloc_zfree(rule);
+ talloc_zfree(filter);
+ talloc_zfree(msgs);
+}
+
+void test_store_sudo_case_insensitive(void **state)
+{
+ errno_t ret;
+ char *filter;
+ const char *attrs[] = { SYSDB_SUDO_CACHE_AT_CN, SYSDB_SUDO_CACHE_AT_HOST,
+ SYSDB_SUDO_CACHE_AT_RUNASUSER,
+ SYSDB_SUDO_CACHE_AT_USER, NULL };
+ struct ldb_message **msgs = NULL;
+ size_t msgs_count;
+ const char *result;
+ struct ldb_message_element *element;
+ struct sysdb_attrs *rule;
+ struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state,
+ struct sysdb_test_ctx);
+ const char *lowered_name = sss_tc_utf8_str_tolower(test_ctx, users[0].name);
+
+ rule = sysdb_new_attrs(test_ctx);
+ assert_non_null(rule);
+ create_rule_attrs_multiple_sudoUser(rule);
+
+ test_ctx->tctx->dom->case_sensitive = false;
+
+ ret = sysdb_sudo_store(test_ctx->tctx->dom, &rule, 1);
+ assert_int_equal(ret, EOK);
+
+ filter = sysdb_sudo_filter_user(test_ctx, users[0].name, NULL, 0);
+ assert_non_null(filter);
+
+ ret = sysdb_search_sudo_rules(test_ctx, test_ctx->tctx->dom, filter,
+ attrs, &msgs_count, &msgs);
+ assert_int_equal(ret, EOK);
+
+ assert_int_equal(msgs_count, 1);
+
+ result = ldb_msg_find_attr_as_string(msgs[0], SYSDB_SUDO_CACHE_AT_CN, NULL);
+ assert_non_null(result);
+ assert_string_equal(result, rules[0].name);
+
+ result = ldb_msg_find_attr_as_string(msgs[0], SYSDB_SUDO_CACHE_AT_HOST,
+ NULL);
+ assert_non_null(result);
+ assert_string_equal(result, rules[0].host);
+
+ result = ldb_msg_find_attr_as_string(msgs[0], SYSDB_SUDO_CACHE_AT_RUNASUSER,
+ NULL);
+ assert_non_null(result);
+ assert_string_equal(result, rules[0].as_user);
+
+ for (int i = 0; i < 3; i++) {
+ ret = ldb_msg_check_string_attribute(msgs[0], SYSDB_SUDO_CACHE_AT_USER,
+ users[i].name);
+ assert_int_equal(ret, 1);
+ }
+
+ /* test there is no duplication of lowercase forms */
+ element = ldb_msg_find_element(msgs[0], SYSDB_SUDO_CACHE_AT_USER);
+ assert_int_equal(element->num_values, 4);
+
+ talloc_zfree(lowered_name);
+ talloc_zfree(rule);
+ talloc_zfree(filter);
+ talloc_zfree(msgs);
+}
+
void test_sudo_purge_by_filter(void **state)
{
errno_t ret;
@@ -648,6 +808,12 @@ int main(int argc, const char *argv[])
cmocka_unit_test_setup_teardown(test_store_sudo,
test_sysdb_setup,
test_sysdb_teardown),
+ cmocka_unit_test_setup_teardown(test_store_sudo_case_sensitive,
+ test_sysdb_setup,
+ test_sysdb_teardown),
+ cmocka_unit_test_setup_teardown(test_store_sudo_case_insensitive,
+ test_sysdb_setup,
+ test_sysdb_teardown),
/* sysdb_sudo_purge() */
cmocka_unit_test_setup_teardown(test_sudo_purge_by_filter,
--
2.11.0

View File

@ -0,0 +1,93 @@
From a859747b84125124ea794aa422f5b811bb0dba2d Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 8 Nov 2016 11:51:57 +0100
Subject: [PATCH 24/39] IPA/AD: check auth ctx before using it
In e6b6b9fa79c67d7d2698bc7e33d2e2f6bb53d483 a feature was introduced to
set the 'canonicalize' option in the system-wide Kerberos configuration
according to the settings in SSSD if the AD or IPA provider were used.
Unfortunately the patch implied that the auth provider is the same as
the id provider which might not always be the case. A different auth
provider caused a crash in the backend which is fixed by this patch.
Resolves https://fedorahosted.org/sssd/ticket/3234
Reviewed-by: Petr Cech <pcech@redhat.com>
(cherry picked from commit ea11ed3ea6291488dd762033246edc4ce3951aeb)
(cherry picked from commit 37e070c8c2ea79d8d84bae3da3a34c81212744ab)
---
src/providers/ad/ad_subdomains.c | 13 +++++++++++--
src/providers/ipa/ipa_subdomains.c | 20 +++++++++++++++++---
2 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index 52bf5361f..5e57d218c 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -618,14 +618,23 @@ static errno_t ad_subdom_reinit(struct ad_subdomains_ctx *subdoms_ctx)
{
const char *path;
errno_t ret;
- bool canonicalize;
+ bool canonicalize = false;
path = dp_opt_get_string(subdoms_ctx->ad_id_ctx->ad_options->basic,
AD_KRB5_CONFD_PATH);
- canonicalize = dp_opt_get_bool(
+ if (subdoms_ctx->ad_id_ctx->ad_options->auth_ctx != NULL
+ && subdoms_ctx->ad_id_ctx->ad_options->auth_ctx->opts != NULL) {
+ canonicalize = dp_opt_get_bool(
subdoms_ctx->ad_id_ctx->ad_options->auth_ctx->opts,
KRB5_CANONICALIZE);
+ } else {
+ DEBUG(SSSDBG_CONF_SETTINGS, "Auth provider data is not available, "
+ "most probably because the auth provider "
+ "is not 'ad'. Kerberos configuration "
+ "snippet to set the 'canonicalize' option "
+ "will not be created.\n");
+ }
ret = sss_write_krb5_conf_snippet(path, canonicalize);
if (ret != EOK) {
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
index 8653e3f46..b2e96b204 100644
--- a/src/providers/ipa/ipa_subdomains.c
+++ b/src/providers/ipa/ipa_subdomains.c
@@ -73,16 +73,30 @@ static errno_t
ipa_subdom_reinit(struct ipa_subdomains_ctx *ctx)
{
errno_t ret;
+ bool canonicalize = false;
DEBUG(SSSDBG_TRACE_INTERNAL,
"Re-initializing domain %s\n", ctx->be_ctx->domain->name);
+ if (ctx->ipa_id_ctx->ipa_options->auth_ctx != NULL
+ && ctx->ipa_id_ctx->ipa_options->auth_ctx->krb5_auth_ctx != NULL
+ && ctx->ipa_id_ctx->ipa_options->auth_ctx->krb5_auth_ctx->opts != NULL
+ ) {
+ canonicalize = dp_opt_get_bool(
+ ctx->ipa_id_ctx->ipa_options->auth_ctx->krb5_auth_ctx->opts,
+ KRB5_CANONICALIZE);
+ } else {
+ DEBUG(SSSDBG_CONF_SETTINGS, "Auth provider data is not available, "
+ "most probably because the auth provider "
+ "is not 'ipa'. Kerberos configuration "
+ "snippet to set the 'canonicalize' option "
+ "will not be created.\n");
+ }
+
ret = sss_write_krb5_conf_snippet(
dp_opt_get_string(ctx->ipa_id_ctx->ipa_options->basic,
IPA_KRB5_CONFD_PATH),
- dp_opt_get_bool(
- ctx->ipa_id_ctx->ipa_options->auth_ctx->krb5_auth_ctx->opts,
- KRB5_CANONICALIZE));
+ canonicalize);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE, "sss_write_krb5_conf_snippet failed.\n");
/* Just continue */
--
2.11.0

View File

@ -0,0 +1,50 @@
From c0a516f5d91290135c6b019a8a9d269edf8214cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
Date: Mon, 17 Oct 2016 17:07:56 +0200
Subject: [PATCH 25/39] SECRETS: Fix secrets rule in the allowed sections
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We have been matching an invalid subsection of the secrets' section,
like:
[secrets/users/]
Let's ensure that we only match the following cases:
[secrets]
[secrets/users/[0-9]+]
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit da8801c363716533f60bc78e10f3a2100cebc3a1)
(cherry picked from commit 2535993d81c7d0dbbd6c6fab6f45b338845535cf)
---
src/config/cfg_rules.ini | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
index ec716b558..24937c969 100644
--- a/src/config/cfg_rules.ini
+++ b/src/config/cfg_rules.ini
@@ -8,7 +8,7 @@ section = autofs
section = ssh
section = pac
section = ifp
-section_re = ^secrets\(/users/\([0-9]\+\)\?\)\?$
+section_re = ^secrets\(/users/[0-9]\+\)\?$
section_re = ^domain/.*$
[rule/allowed_sssd_options]
@@ -213,7 +213,7 @@ option = user_attributes
[rule/allowed_sec_options]
validator = ini_allowed_options
-section_re = ^secrets\(/users/\([0-9]\+\)\?\)\?$
+section_re = ^secrets\(/users/[0-9]\+\)\?$
option = timeout
option = debug
--
2.11.0

View File

@ -0,0 +1,70 @@
From c16214f71f8ab2a5fc122966159ce056e0e9e897 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
Date: Mon, 17 Oct 2016 18:58:50 +0200
Subject: [PATCH 26/39] SECRETS: Add allowed_sec_users_options
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There are options (the proxying related ones) that only apply to the
secrets' subsections. In order to make config API able to catch those,
let's create a new section called allowed_sec_users_options) and move
there these proxying options.
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 682c9c3467055c2149af28826f7458b857b0f8c4)
(cherry picked from commit 9d4cc96f2951412f647223dfe59060fa1e2b7b14)
---
src/config/cfg_rules.ini | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
index 24937c969..882a185d8 100644
--- a/src/config/cfg_rules.ini
+++ b/src/config/cfg_rules.ini
@@ -8,7 +8,8 @@ section = autofs
section = ssh
section = pac
section = ifp
-section_re = ^secrets\(/users/[0-9]\+\)\?$
+section = secrets
+section_re = ^secrets/users/[0-9]\+$
section_re = ^domain/.*$
[rule/allowed_sssd_options]
@@ -211,9 +212,10 @@ option = description
option = allowed_uids
option = user_attributes
+# Secrets service
[rule/allowed_sec_options]
validator = ini_allowed_options
-section_re = ^secrets\(/users/[0-9]\+\)\?$
+section_re = ^secrets$
option = timeout
option = debug
@@ -226,12 +228,15 @@ option = reconnection_retries
option = fd_limit
option = client_idle_timeout
option = description
-
-# Secrets service
-option = provider
option = containers_nest_level
option = max_secrets
+
+[rule/allowed_sec_users_options]
+validator = ini_allowed_options
+section_re = ^secrets/users/[0-9]\+$
+
# Secrets service - proxy
+option = provider
option = proxy_url
option = auth_type
option = auth_header_name
--
2.11.0

View File

@ -0,0 +1,62 @@
From 9ccd49a3bcabd8eb32a559af2cacf2b0fdcfad96 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
Date: Thu, 10 Nov 2016 15:04:57 +0100
Subject: [PATCH 27/39] ipa: Nested netgroups do not work
We lowercase the keys to the hash table used to store netgroups
but do not lowercase it when reading the table. This results
in nested netgroups not being found when they should and
the processing fails.
The lowercasing does not seem to be necessary anymore (not
sure if it ever was) so we can skip it.
Resolves:
https://fedorahosted.org/sssd/ticket/3159
Reviewed-by: Petr Cech <pcech@redhat.com>
(cherry picked from commit ff565da1011aa4312847e28e7af66e57fccf8b90)
(cherry picked from commit 7de33877c7e39f9a5cae6baf815dc18ae5a18597)
---
src/providers/ipa/ipa_netgroups.c | 15 +++------------
1 file changed, 3 insertions(+), 12 deletions(-)
diff --git a/src/providers/ipa/ipa_netgroups.c b/src/providers/ipa/ipa_netgroups.c
index a19e5e03d..17b11af5d 100644
--- a/src/providers/ipa/ipa_netgroups.c
+++ b/src/providers/ipa/ipa_netgroups.c
@@ -563,7 +563,6 @@ static void ipa_netgr_members_process(struct tevent_req *subreq)
size_t count;
int ret, i;
const char *orig_dn;
- char *orig_dn_lower;
hash_table_t *table;
hash_key_t key;
hash_value_t value;
@@ -638,20 +637,12 @@ static void ipa_netgr_members_process(struct tevent_req *subreq)
goto fail;
}
- orig_dn_lower = talloc_strdup(table, orig_dn);
- if (orig_dn_lower == NULL) {
+ key.str = talloc_strdup(table, orig_dn);
+ if (key.str == NULL) {
ret = ENOMEM;
goto fail;
}
- /* Transform the DN to lower case.
- * this is important, as the member/memberof attributes
- * have the value also in lower-case
- */
- key.str = orig_dn_lower;
- while (*orig_dn_lower != '\0') {
- *orig_dn_lower = tolower(*orig_dn_lower);
- orig_dn_lower++;
- }
+
value.ptr = entities[i];
ret = hash_enter(table, &key, &value);
if (ret != HASH_SUCCESS) {
--
2.11.0

View File

@ -0,0 +1,61 @@
From 712f064ed197063016fee16a3438fb22f08759bf Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Wed, 9 Nov 2016 11:59:10 +0100
Subject: [PATCH 28/39] Qualify ghost user attribute in case
ldap_group_nesting_level is set to 0
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When the sssd is set to not resolve nested groups with RFC2307bis, then
the LDAP provider takes a different path. We didn't qualify the ghost
users in this case.
Resolves:
https://fedorahosted.org/sssd/ticket/3236
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit 538a7f1dd8339b90e0cfc64e7919a34d1d5c10d3)
(cherry picked from commit e0b544e6f664c2ce5ddd8df866d996607ce488cc)
---
src/providers/ldap/sdap_async_groups.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index 08dfa01b1..81503798c 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -1668,7 +1668,7 @@ static void sdap_process_group_members(struct tevent_req *subreq)
struct sdap_process_group_state *state =
tevent_req_data(req, struct sdap_process_group_state);
struct ldb_message_element *el;
- uint8_t* name_string;
+ char *name_string;
state->check_count--;
DEBUG(SSSDBG_TRACE_ALL, "Members remaining: %zu\n", state->check_count);
@@ -1694,11 +1694,18 @@ static void sdap_process_group_members(struct tevent_req *subreq)
goto next;
}
- name_string = el[0].values[0].data;
+ name_string = sss_create_internal_fqname(state,
+ (const char *) el[0].values[0].data,
+ state->dom->name);
+ if (name_string == NULL) {
+ ret = ENOMEM;
+ goto next;
+ }
+
state->ghost_dns->values[state->ghost_dns->num_values].data =
- talloc_steal(state->ghost_dns->values, name_string);
+ talloc_steal(state->ghost_dns->values, (uint8_t *) name_string);
state->ghost_dns->values[state->ghost_dns->num_values].length =
- strlen((char *)name_string);
+ strlen(name_string);
state->ghost_dns->num_values++;
next:
--
2.11.0

View File

@ -0,0 +1,56 @@
From a72d7cf57143ca56834c6bb33b289ba98ed02b91 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Wed, 9 Nov 2016 11:59:34 +0100
Subject: [PATCH 29/39] tests: Add a test for group resolution with
ldap_group_nesting_level=0
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit 65e791f844b4513ca2c3ee23f8cd2979566b3719)
(cherry picked from commit a7be684411aff42e03e181dd81de921185e16c34)
---
src/tests/intg/test_ldap.py | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/src/tests/intg/test_ldap.py b/src/tests/intg/test_ldap.py
index 7f0b8ff18..bf25d9509 100644
--- a/src/tests/intg/test_ldap.py
+++ b/src/tests/intg/test_ldap.py
@@ -951,3 +951,32 @@ def test_remove_user_from_nested_group(ldap_conn,
dict(mem=ent.contains_only("user2")))
ent.assert_group_by_name("group3",
dict(mem=ent.contains_only()))
+
+
+def zero_nesting_sssd_conf(ldap_conn, schema):
+ """Format an SSSD configuration with group nesting disabled"""
+ return \
+ format_basic_conf(ldap_conn, schema) + \
+ unindent("""
+ [domain/LDAP]
+ ldap_group_nesting_level = 0
+ """).format(INTERACTIVE_TIMEOUT)
+
+
+@pytest.fixture
+def rfc2307bis_no_nesting(request, ldap_conn):
+ ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn)
+ ent_list.add_user("user1", 1001, 2001)
+ ent_list.add_group_bis("group1", 20001, member_uids=["user1"])
+ create_ldap_fixture(request, ldap_conn, ent_list)
+ create_conf_fixture(request,
+ zero_nesting_sssd_conf(
+ ldap_conn,
+ SCHEMA_RFC2307_BIS))
+ create_sssd_fixture(request)
+ return None
+
+
+def test_zero_nesting_level(ldap_conn, rfc2307bis_no_nesting):
+ ent.assert_group_by_name("group1",
+ dict(mem=ent.contains_only("user1")))
--
2.11.0

View File

@ -0,0 +1,37 @@
From bf0971190884b664ef38d8fc42199fca8e496e54 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Fri, 18 Nov 2016 12:19:02 +0100
Subject: [PATCH 30/39] BUILD: Fix a typo in inotify.m4
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This typo prevented HAVE_INOTIFY from ever being set and as an effect,
prevented /etc/resolv.conf inotify detection from working
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
(cherry picked from commit 2927dc45b9bc810f4f55bce165bb96405129e693)
(cherry picked from commit 495289cfa922b00278aa91d433489403e792304e)
---
src/external/inotify.m4 | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/external/inotify.m4 b/src/external/inotify.m4
index 9572f6d2f..25259a817 100644
--- a/src/external/inotify.m4
+++ b/src/external/inotify.m4
@@ -6,8 +6,8 @@ AC_DEFUN([AM_CHECK_INOTIFY],
AC_MSG_CHECKING([whether sys/inotify.h actually works])
AC_LINK_IFELSE(
[AC_LANG_SOURCE([
-#ifdef HAVE_SYS_INOTITY_H
-#include <sys/inotify.h>,
+#ifdef HAVE_SYS_INOTIFY_H
+#include <sys/inotify.h>
#endif
int main () {
return (-1 == inotify_init());
--
2.11.0

View File

@ -0,0 +1,48 @@
From 74fb5008403cc7324138740b327bb282aeb19a08 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20=C4=8Cech?= <pcech@redhat.com>
Date: Wed, 16 Nov 2016 10:09:18 +0100
Subject: [PATCH 31/39] SYSDB: Fixing of sudorule without a sudoUser
This patch solved a regression caused by the recent patches
to lowercase sudoUser -- in case sudoUser is missing completely,
we abort the processing of this rule and all others.
With this patch, we return ERR_MALFORMED_ENTRY and gracefully
skip the malformed rule instead.
Resolves:
https://fedorahosted.org/sssd/ticket/3241
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 7e23edbaa7a6bbd0b461d5792535896b6a77928b)
(cherry picked from commit 54f176066dafafdc12f6e0dd112ff6339308aa7c)
---
src/db/sysdb_sudo.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/db/sysdb_sudo.c b/src/db/sysdb_sudo.c
index 4bd93ffc6..f5160f190 100644
--- a/src/db/sysdb_sudo.c
+++ b/src/db/sysdb_sudo.c
@@ -874,6 +874,7 @@ static errno_t sysdb_sudo_add_lowered_users(struct sss_domain_info *domain,
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "Unable to get %s attribute [%d]: %s\n",
SYSDB_SUDO_CACHE_AT_USER, ret, strerror(ret));
+ ret = ERR_MALFORMED_ENTRY;
goto done;
}
@@ -977,6 +978,10 @@ sysdb_sudo_store(struct sss_domain_info *domain,
/* Multiple CNs are error on server side, we can just ignore this
* rule and save the others. Loud debug message is in logs. */
continue;
+ } else if (ret == ERR_MALFORMED_ENTRY) {
+ /* Attribute SYSDB_SUDO_CACHE_AT_USER is missing but we can
+ * continue with next sudoRule. */
+ continue;
} else if (ret != EOK) {
goto done;
}
--
2.11.0

View File

@ -0,0 +1,58 @@
From 2d6fe5942218ee8f24eb6ccd8ffec5fab65c170b Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lukas.slebodnik@intrak.sk>
Date: Fri, 18 Nov 2016 17:29:44 +0100
Subject: [PATCH 32/39] UTIL: Fix implicit declaration of function 'htobe32'
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Include internal wrapper header file for endian related functions.
The "util/sss_endian.h" include available header file on different
platform or it provides compatible macros in the worst case.
Breakage noticed when building SSSD on FreeBSD
CC src/util/cert/nss/libsss_cert_la-cert.lo
src/util/cert/nss/cert.c: In function 'cert_to_ssh_key':
src/util/cert/nss/cert.c:358: error: implicit declaration of function 'htobe32'
gmake[2]: *** [Makefile:12421: src/util/cert/nss/libsss_cert_la-cert.lo] Error 1
gmake[2]: Leaving directory '/root/sssd_from_git'
gmake[1]: *** [Makefile:20050: all-recursive] Error 1
gmake[1]: Leaving directory '/root/sssd_from_git'
gmake: *** [Makefile:7116: all] Error 2
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
(cherry picked from commit 58aa8d645fa95641431a2828e985f80c7fc36465)
(cherry picked from commit a70351fddb9c26763b2bf658f56ff043a7b3db6f)
---
src/util/cert/libcrypto/cert.c | 1 +
src/util/cert/nss/cert.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/src/util/cert/libcrypto/cert.c b/src/util/cert/libcrypto/cert.c
index aba598d7c..c54db86bb 100644
--- a/src/util/cert/libcrypto/cert.c
+++ b/src/util/cert/libcrypto/cert.c
@@ -22,6 +22,7 @@
#include <openssl/pem.h>
#include "util/util.h"
+#include "util/sss_endian.h"
errno_t sss_cert_der_to_pem(TALLOC_CTX *mem_ctx, const uint8_t *der_blob,
size_t der_size, char **pem, size_t *pem_size)
diff --git a/src/util/cert/nss/cert.c b/src/util/cert/nss/cert.c
index b5e0ff961..9d31cfe9b 100644
--- a/src/util/cert/nss/cert.c
+++ b/src/util/cert/nss/cert.c
@@ -31,6 +31,7 @@
#include "util/crypto/sss_crypto.h"
#include "util/crypto/nss/nss_util.h"
#include "util/cert.h"
+#include "util/sss_endian.h"
#define NS_CERT_HEADER "-----BEGIN CERTIFICATE-----"
#define NS_CERT_TRAILER "-----END CERTIFICATE-----"
--
2.11.0

View File

@ -0,0 +1,46 @@
From 99b48ffa1a525c0736f67b89c81bfc867977a99c Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lukas.slebodnik@intrak.sk>
Date: Fri, 18 Nov 2016 17:58:28 +0100
Subject: [PATCH 33/39] sssctl: Fix missing declaration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The WEXITSTATUS is defined in stdlib.h on linux.
There is a nice comment in stdlib.h:
/* Define the macros <sys/wait.h> also would define this way. */
It's better to not rely on this and use more platfom friendly
way with including "sys/wait.h". For example the libc on FreeBSD
does not provide WEXITSTATUS in stdlib.h.
I found this macro mentioned only in the manual page for wait(2)
and there is mentioned just the "sys/wait.h" and not "stdlib.h"
src/tools/sssctl/sssctl.c: In function 'sssctl_run_command':
src/tools/sssctl/sssctl.c:110: error: implicit declaration of function
'WEXITSTATUS'
gmake[2]: *** [Makefile:22383: src/tools/sssctl/sssctl-sssctl.o] Error 1
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
(cherry picked from commit 73c9330fa3de6912e45c1ab686d5290f143b8352)
(cherry picked from commit 161ddc1f24082c735801775802a483e96909152c)
---
src/tools/sssctl/sssctl.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/tools/sssctl/sssctl.c b/src/tools/sssctl/sssctl.c
index ece1e6df1..e1cf46382 100644
--- a/src/tools/sssctl/sssctl.c
+++ b/src/tools/sssctl/sssctl.c
@@ -20,6 +20,7 @@
#include <stdlib.h>
#include <stdio.h>
+#include <sys/wait.h>
#include "util/util.h"
#include "tools/sssctl/sssctl.h"
--
2.11.0

View File

@ -0,0 +1,49 @@
From 6a3c115022b54bce155c04a1c090561cf626006a Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lukas.slebodnik@intrak.sk>
Date: Fri, 18 Nov 2016 17:49:35 +0100
Subject: [PATCH 34/39] UTIL: Fix compilation of sss_utf8 with libunistring
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The internal header file "util/util.h" was removed from sss_utf8.h
as part of commit de5fa34860886ad68fba5e739987e16c342e8f14.
It was neccessary to ensure libipa_hbac can be build with C90
compatible compiler.
This header file includes many system header file and after
this change caused missing declaration of the function free()
src/util/sss_utf8.c: In function sss_utf8_free:
src/util/sss_utf8.c:40:12: error: implicit declaration of function free
[-Werror=implicit-function-declaration]
return free(ptr);
^~~~
src/util/sss_utf8.c:40:12: warning: incompatible implicit declaration
of built-in function free
src/util/sss_utf8.c:40:12: note: include <stdlib.h> or provide
a declaration of free
cc1: some warnings being treated as errors
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
(cherry picked from commit c101cb130df0705a9227dadce22554307eee54db)
(cherry picked from commit 76e2df701559d8723ea632722c94c8dfb820fc93)
---
src/util/sss_utf8.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/util/sss_utf8.c b/src/util/sss_utf8.c
index 722f28d08..e62e9c6c9 100644
--- a/src/util/sss_utf8.c
+++ b/src/util/sss_utf8.c
@@ -26,6 +26,7 @@
#include <errno.h>
#ifdef HAVE_LIBUNISTRING
+#include <stdlib.h>
#include <unistr.h>
#include <unicase.h>
#elif defined(HAVE_GLIB2)
--
2.11.0

View File

@ -0,0 +1,40 @@
From 86fa0fa9543b4f21a152bcaedbcb3d5608567aa2 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Thu, 1 Dec 2016 13:13:21 +0100
Subject: [PATCH 35/39] SIFP: Fix warning format-security
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
dbus-1.11.8 added attributes for format string check to
few functions in public header files. And therefore there is a warning.
src/lib/sifp/sss_sifp_utils.c: In function sss_sifp_set_io_error:
src/lib/sifp/sss_sifp_utils.c:44:5: error: format not a string literal
and no format arguments [-Werror=format-security]
dbus_set_error(ctx->io_error, error->name, error->message);
^~~~~~~~~~~~~~
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit 8618716d6ed4eadca2743eb2dfbbb8d11c4fb22f)
(cherry picked from commit 043862847cee673084a56f387d195deb82386de7)
---
src/lib/sifp/sss_sifp_utils.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lib/sifp/sss_sifp_utils.c b/src/lib/sifp/sss_sifp_utils.c
index ccd051838..dcac71f50 100644
--- a/src/lib/sifp/sss_sifp_utils.c
+++ b/src/lib/sifp/sss_sifp_utils.c
@@ -41,7 +41,7 @@ void sss_sifp_set_io_error(sss_sifp_ctx *ctx, DBusError *error)
{
dbus_error_free(ctx->io_error);
dbus_error_init(ctx->io_error);
- dbus_set_error(ctx->io_error, error->name, error->message);
+ dbus_set_error(ctx->io_error, error->name, "%s", error->message);
}
char * sss_sifp_strdup(sss_sifp_ctx *ctx, const char *str)
--
2.11.0

View File

@ -0,0 +1,80 @@
From e1a01adb021f7d2b3674c4d8151797e265608c20 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Thu, 24 Nov 2016 18:07:56 +0100
Subject: [PATCH 36/39] SSH: Use default_domain_suffix for users' authorized
keys
In commit eeecc48d22a28bb69da56f6ffd8824163fc9bf00 we disabled
default_domain_suffix for the SSH responder, but in a wrong way -- we
disabled the functionality completely, also for users, not only for
computers. This might have been correct at the time, since SSH keys in ID
overrides are a relatively new feature, but it's definitely not correct
in general.
Instead, this patch restores the use of default_domain_suffix, but only
for looking up public keys of users, not of computers.
Resolves:
https://fedorahosted.org/sssd/ticket/3259
Reviewed-by: Petr Cech <pcech@redhat.com>
(cherry picked from commit ed71fba97dfcf5b3f0f1834c06660c481b9ab3ce)
(cherry picked from commit 2949fe58ac344c44d756ca309d4b2b7f3590cee3)
---
src/responder/ssh/sshsrv_cmd.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/responder/ssh/sshsrv_cmd.c b/src/responder/ssh/sshsrv_cmd.c
index ab721d66e..2e64893df 100644
--- a/src/responder/ssh/sshsrv_cmd.c
+++ b/src/responder/ssh/sshsrv_cmd.c
@@ -36,7 +36,8 @@
#include "responder/ssh/sshsrv_private.h"
static errno_t
-ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx);
+ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx,
+ char *default_domain);
static errno_t
ssh_user_pubkeys_search(struct ssh_cmd_ctx *cmd_ctx);
@@ -57,7 +58,7 @@ sss_ssh_cmd_get_user_pubkeys(struct cli_ctx *cctx)
cmd_ctx->cctx = cctx;
cmd_ctx->is_user = true;
- ret = ssh_cmd_parse_request(cmd_ctx);
+ ret = ssh_cmd_parse_request(cmd_ctx, cctx->rctx->default_domain);
if (ret != EOK) {
goto done;
}
@@ -107,7 +108,7 @@ sss_ssh_cmd_get_host_pubkeys(struct cli_ctx *cctx)
cmd_ctx->cctx = cctx;
cmd_ctx->is_user = false;
- ret = ssh_cmd_parse_request(cmd_ctx);
+ ret = ssh_cmd_parse_request(cmd_ctx, NULL);
if (ret != EOK) {
goto done;
}
@@ -681,7 +682,8 @@ done:
}
static errno_t
-ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx)
+ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx,
+ char *default_domain)
{
struct cli_protocol *pctx;
struct ssh_ctx *ssh_ctx;
@@ -754,6 +756,8 @@ ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx)
return EINVAL;
}
c += domain_len;
+ } else {
+ domain = default_domain;
}
DEBUG(SSSDBG_TRACE_FUNC,
--
2.11.0

View File

@ -0,0 +1,72 @@
From d2f8e3876810cf99228827432ea4f4a59877448d Mon Sep 17 00:00:00 2001
From: Carl Henrik Lunde <chlunde@ifi.uio.no>
Date: Thu, 1 Dec 2016 00:09:00 +0100
Subject: [PATCH 37/39] Prevent use after free in fd_input_available
When both TEVENT_FD_WRITE and TEVENT_FD_READ are set, and an error/EOF
occurs when reading from the socket, we will get a use after free
in the second call ares_process_fd. The first call will free the watch
structure via a callback.
Prevent this by calling ares_process_fd only once.
Invalid read of size 4
at fd_input_available (async_resolv.c:147)
by epoll_event_loop (tevent_epoll.c:728)
by epoll_event_loop_once (tevent_epoll.c:926)
by std_event_loop_once (tevent_standard.c:114)
by _tevent_loop_once (tevent.c:533)
by tevent_common_loop_wait (tevent.c:637)
by std_event_loop_wait (tevent_standard.c:140)
by server_loop (server.c:702)
by main (data_provider_be.c:587)
Address ... is 112 bytes inside a block of size 136 free'd
at free (vg_replace_malloc.c:530)
by _talloc_free_internal (talloc.c:1116)
by _talloc_free (talloc.c:1647)
by ares__close_sockets (ares__close_sockets.c:50)
by handle_error (ares_process.c:679)
by read_tcp_data (ares_process.c:391)
by processfds (ares_process.c:138)
by fd_input_available (async_resolv.c:144)
by epoll_event_loop (tevent_epoll.c:728)
by epoll_event_loop_once (tevent_epoll.c:926)
by std_event_loop_once (tevent_standard.c:114)
by _tevent_loop_once (tevent.c:533)
by tevent_common_loop_wait (tevent.c:637)
by std_event_loop_wait (tevent_standard.c:140)
by server_loop (server.c:702)
Resolves:
https://fedorahosted.org/sssd/ticket/3250
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 9676b464dd428557ff5a648e1351a3972440396f)
(cherry picked from commit fefdd70237cbe82af7d8845131e45401e73b3b07)
---
src/resolv/async_resolv.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/resolv/async_resolv.c b/src/resolv/async_resolv.c
index e85955677..47b4db7ec 100644
--- a/src/resolv/async_resolv.c
+++ b/src/resolv/async_resolv.c
@@ -140,12 +140,9 @@ fd_input_available(struct tevent_context *ev, struct tevent_fd *fde,
return;
}
- if (flags & TEVENT_FD_READ) {
- ares_process_fd(watch->ctx->channel, watch->fd, ARES_SOCKET_BAD);
- }
- if (flags & TEVENT_FD_WRITE) {
- ares_process_fd(watch->ctx->channel, ARES_SOCKET_BAD, watch->fd);
- }
+ ares_process_fd(watch->ctx->channel,
+ flags & TEVENT_FD_READ ? watch->fd : ARES_SOCKET_BAD,
+ flags & TEVENT_FD_WRITE ? watch->fd : ARES_SOCKET_BAD);
}
static void
--
2.11.0

View File

@ -0,0 +1,39 @@
From 39fe2093254db5d4cd223e7d9c228689ba6382ca Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Mon, 28 Nov 2016 08:44:04 +0100
Subject: [PATCH 38/39] STAP: Only print transaction statistics if the script
caught some transactions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If the script measured an 'id' run from the cache, there would be no
transactions and dereferencing the aggrefate would throw an error.
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
(cherry picked from commit 150a0cc8fe1936002af136e5552ef6cdd210956f)
(cherry picked from commit e6c74de2cbc9b0b713ed6dadbfef80c7c1b5cd51)
---
contrib/systemtap/id_perf.stp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/contrib/systemtap/id_perf.stp b/contrib/systemtap/id_perf.stp
index 0ad619506..a7789750f 100644
--- a/contrib/systemtap/id_perf.stp
+++ b/contrib/systemtap/id_perf.stp
@@ -64,8 +64,10 @@ function print_report()
}
}
- printf("The most expensive transaction breakdown, per transaction:\n")
- print(@hist_linear(bts[max_trans_time_bt], 0, 500, 50))
+ if (max_trans_time > 0) {
+ printf("The most expensive transaction breakdown, per transaction:\n")
+ print(@hist_linear(bts[max_trans_time_bt], 0, 500, 50))
+ }
}
probe process("/usr/bin/id").begin
--
2.11.0

View File

@ -0,0 +1,50 @@
From f2fe644510afd2d3bc989a4fea2ce2b2a1a69e9c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Mon, 5 Dec 2016 14:37:41 +0100
Subject: [PATCH 39/39] sudo: do not store usn if no rules are found
When ldap doesn't contain any sudorule during the initial full refresh,
usn is set to 1 instead of remaining unset and we are trying to
search modifyTimestamp>=1 during smart refresh which doesn't return any result
on openldap servers.
Resolves:
https://fedorahosted.org/sssd/ticket/3257
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 46703740e83a66909974a5ee8d47df6a6e5076e7)
(cherry picked from commit 76e97affaa05ce45709efd59d120595c5992aa21)
---
src/providers/ldap/sdap_sudo_shared.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/providers/ldap/sdap_sudo_shared.c b/src/providers/ldap/sdap_sudo_shared.c
index 807226020..66b788702 100644
--- a/src/providers/ldap/sdap_sudo_shared.c
+++ b/src/providers/ldap/sdap_sudo_shared.c
@@ -129,7 +129,7 @@ sdap_sudo_new_usn(TALLOC_CTX *mem_ctx,
char *newusn;
/* We increment USN number so that we can later use simplify filter
- * (just usn >= last+1 instaed of usn >= last && usn != last).
+ * (just usn >= last+1 instead of usn >= last && usn != last).
*/
usn++;
@@ -174,6 +174,13 @@ sdap_sudo_set_usn(struct sdap_server_opts *srv_opts,
return;
}
+ if (usn_number == 0) {
+ /* Zero means that there were no rules on the server, so we have
+ * nothing to store. */
+ DEBUG(SSSDBG_TRACE_FUNC, "SUDO USN value is empty.\n");
+ return;
+ }
+
newusn = sdap_sudo_new_usn(srv_opts, usn_number, endptr);
if (newusn == NULL) {
return;
--
2.11.0

View File

@ -0,0 +1,117 @@
From 829aa39dffbe35f58b34159b962a2dd8de85fd30 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 12 Dec 2016 18:33:48 +0100
Subject: [PATCH] Partially revert "CONFIG: Use default config when none
provided"
This reverts part of commit 59744cff6edb106ae799b2321cb8731edadf409a.
Removed is copying of default configuration into /etc/sssd/sssd.conf
Sample configurations is still part of installation.
---
Makefile.am | 3 ---
src/confdb/confdb.h | 1 -
src/confdb/confdb_setup.c | 40 ++++------------------------------------
3 files changed, 4 insertions(+), 40 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index a15e68f682f6d8af301e11df8dcaef6d7f27e8c0..45d44146e737fc8460a2ed9ffc0171a6bb494b2b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -462,7 +462,6 @@ AM_CPPFLAGS = \
-DSSSDDATADIR=\"$(sssddatadir)\" \
-DSSSD_LIBEXEC_PATH=\"$(sssdlibexecdir)\" \
-DSSSD_CONF_DIR=\"$(sssdconfdir)\" \
- -DSSSD_DEFAULT_CONF_DIR=\"$(sssddefaultconfdir)\" \
-DSSS_NSS_MCACHE_DIR=\"$(mcpath)\" \
-DSSS_NSS_SOCKET_NAME=\"$(pipepath)/nss\" \
-DSSS_PAM_SOCKET_NAME=\"$(pipepath)/pam\" \
@@ -1232,8 +1231,6 @@ sssd_SOURCES = \
src/confdb/confdb_setup.c \
src/monitor/monitor_iface_generated.c \
src/util/nscd.c \
- src/tools/files.c \
- src/tools/selinux.c \
$(NULL)
sssd_LDADD = \
$(SSSD_LIBS) \
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index 12beaabf8c949bd111abbe16cb98a205490fb08f..4813072bdafb5d6c9ec56a9ccaa5db6a1120112d 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -40,7 +40,6 @@
#define CONFDB_DEFAULT_CFG_FILE_VER 2
#define CONFDB_FILE "config.ldb"
-#define SSSD_DEFAULT_CONFIG_FILE SSSD_DEFAULT_CONF_DIR"/sssd.conf"
#define SSSD_CONFIG_FILE SSSD_CONF_DIR"/sssd.conf"
#define CONFDB_DEFAULT_CONFIG_DIR SSSD_CONF_DIR"/conf.d"
#define SSSD_MIN_ID 1
diff --git a/src/confdb/confdb_setup.c b/src/confdb/confdb_setup.c
index d6feab9000d54d2c3761de6d8e990053ade7e85f..a71d9dd1202824b3c9a7e69f1d8fa905ac1b8c02 100644
--- a/src/confdb/confdb_setup.c
+++ b/src/confdb/confdb_setup.c
@@ -21,14 +21,12 @@
#include "config.h"
#include <sys/stat.h>
-#include <unistd.h>
#include "util/util.h"
#include "db/sysdb.h"
#include "confdb.h"
#include "confdb_private.h"
#include "confdb_setup.h"
#include "util/sss_ini.h"
-#include "tools/tools_util.h"
static int confdb_test(struct confdb_ctx *cdb)
@@ -161,41 +159,11 @@ static int confdb_init_db(const char *config_file, const char *config_dir,
DEBUG(SSSDBG_TRACE_FUNC,
"sss_ini_config_file_open failed: %s [%d]\n", strerror(ret),
ret);
- if (ret != ENOENT) {
- /* Anything other than ENOENT is unrecoverable */
- goto done;
- } else {
- /* Copy the default configuration file to the standard location
- * and then retry
- */
- ret = copy_file_secure(SSSD_DEFAULT_CONFIG_FILE,
- SSSD_CONFIG_FILE,
- 0600,
- getuid(),
- getgid(),
- false);
- if (ret != EOK) {
- DEBUG(SSSDBG_FATAL_FAILURE,
- "Could not copy default configuration: %s",
- sss_strerror(ret));
- /* sss specific error denoting missing configuration file */
- ret = ERR_MISSING_CONF;
- goto done;
- }
-
- /* Try again */
- ret = sss_ini_config_file_open(init_data, config_file);
- if (ret != EOK) {
- DEBUG(SSSDBG_TRACE_FUNC,
- "sss_ini_config_file_open(default) failed: %s [%d]\n",
- strerror(ret), ret);
- if (ret == ENOENT) {
- /* sss specific error denoting missing configuration file */
- ret = ERR_MISSING_CONF;
- }
- goto done;
- }
+ if (ret == ENOENT) {
+ /* sss specific error denoting missing configuration file */
+ ret = ERR_MISSING_CONF;
}
+ goto done;
}
ret = sss_ini_config_access_check(init_data);
--
2.11.0

View File

@ -0,0 +1,25 @@
From cf3b1babdbd2221b46816d4c6d5cd90d9de069ec Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 12 Dec 2016 21:56:16 +0100
Subject: [PATCH] SYSTEMD: Use capabilities
copied from selinux policy
---
src/sysv/systemd/sssd.service.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/sysv/systemd/sssd.service.in b/src/sysv/systemd/sssd.service.in
index a4f9125b58e72429cc3ac1e679271367ada27f3c..8c49c0415597b21ddcd85e0675580edc4d171a5f 100644
--- a/src/sysv/systemd/sssd.service.in
+++ b/src/sysv/systemd/sssd.service.in
@@ -11,6 +11,7 @@ ExecStart=@sbindir@/sssd -D -f
# consult systemd.service(5) for more details
Type=forking
PIDFile=@localstatedir@/run/sssd.pid
+CapabilityBoundingSet=CAP_IPC_LOCK CAP_CHOWN CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_KILL CAP_NET_ADMIN CAP_SYS_NICE CAP_FOWNER CAP_SETGID CAP_SETUID CAP_SYS_ADMIN CAP_SYS_RESOURCE CAP_BLOCK_SUSPEND
[Install]
WantedBy=multi-user.target
--
2.11.0

View File

@ -0,0 +1,179 @@
From d2f93542650c2f9613043acfa8e2f368972a70cd Mon Sep 17 00:00:00 2001
From: Howard Guo <hguo@suse.com>
Date: Tue, 11 Oct 2016 10:35:13 +0200
Subject: [PATCH] sss_client: Defer thread cancellation until completion of
nss/pam operations
The client code is not cancellation-safe, an application which
has cancelled an NSS operation will experience subtle bugs,
hence thread cancellation is deferred until completion of client
operations.
Resolves:
https://fedorahosted.org/sssd/ticket/3156
Reviewed-by: Sumit Bose <sbose@redhat.com>
Reviewed-by: Florian Weimer <fweimer@redhat.com>
---
Makefile.am | 4 ---
configure.ac | 8 -----
src/sss_client/common.c | 80 +++++--------------------------------------------
3 files changed, 7 insertions(+), 85 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index e037930ff..9f1da4d1e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -792,10 +792,6 @@ endif
CLIENT_LIBS = $(LTLIBINTL)
-if HAVE_PTHREAD
-CLIENT_LIBS += -lpthread
-endif
-
if WITH_JOURNALD
SYSLOG_LIBS = $(JOURNALD_LIBS)
endif
diff --git a/configure.ac b/configure.ac
index d3ef1e162..230524bf3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -62,14 +62,6 @@ AC_COMPILE_IFELSE(
AM_CONDITIONAL([HAVE_PTHREAD], [test x"$HAVE_PTHREAD" != "x"])
-SAVE_LIBS=$LIBS
-LIBS="$LIBS -lpthread"
-AC_CHECK_FUNCS([ pthread_mutexattr_setrobust \
- pthread_mutex_consistent \
- pthread_mutexattr_setrobust_np \
- pthread_mutex_consistent_np ])
-LIBS=$SAVE_LIBS
-
# Check library for the timer_create function
SAVE_LIBS=$LIBS
LIBS=
diff --git a/src/sss_client/common.c b/src/sss_client/common.c
index 20106b1b6..b7a5ed760 100644
--- a/src/sss_client/common.c
+++ b/src/sss_client/common.c
@@ -1070,86 +1070,28 @@ typedef void (*sss_mutex_init)(void);
struct sss_mutex {
pthread_mutex_t mtx;
- pthread_once_t once;
- sss_mutex_init init;
+ int old_cancel_state;
};
-static void sss_nss_mt_init(void);
-static void sss_pam_mt_init(void);
-static void sss_nss_mc_mt_init(void);
+static struct sss_mutex sss_nss_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER };
-static struct sss_mutex sss_nss_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER,
- .once = PTHREAD_ONCE_INIT,
- .init = sss_nss_mt_init };
+static struct sss_mutex sss_pam_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER };
-static struct sss_mutex sss_pam_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER,
- .once = PTHREAD_ONCE_INIT,
- .init = sss_pam_mt_init };
-
-static struct sss_mutex sss_nss_mc_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER,
- .once = PTHREAD_ONCE_INIT,
- .init = sss_nss_mc_mt_init };
-
-/* Wrappers for robust mutex support */
-static int sss_mutexattr_setrobust (pthread_mutexattr_t *attr)
-{
-#ifdef HAVE_PTHREAD_MUTEXATTR_SETROBUST
- return pthread_mutexattr_setrobust(attr, PTHREAD_MUTEX_ROBUST);
-#elif defined(HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP)
- return pthread_mutexattr_setrobust_np(attr, PTHREAD_MUTEX_ROBUST_NP);
-#else
-#warning Robust mutexes are not supported on this platform.
- return 0;
-#endif
-}
-
-static int sss_mutex_consistent(pthread_mutex_t *mtx)
-{
-#ifdef HAVE_PTHREAD_MUTEX_CONSISTENT
- return pthread_mutex_consistent(mtx);
-#elif defined(HAVE_PTHREAD_MUTEX_CONSISTENT_NP)
- return pthread_mutex_consistent_np(mtx);
-#else
-#warning Robust mutexes are not supported on this platform.
- return 0;
-#endif
-}
-
-/* Generic mutex init, lock, unlock functions */
-static void sss_mt_init(struct sss_mutex *m)
-{
- pthread_mutexattr_t attr;
-
- if (pthread_mutexattr_init(&attr) != 0) {
- return;
- }
- if (sss_mutexattr_setrobust(&attr) != 0) {
- return;
- }
-
- pthread_mutex_init(&m->mtx, &attr);
- pthread_mutexattr_destroy(&attr);
-}
+static struct sss_mutex sss_nss_mc_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER };
static void sss_mt_lock(struct sss_mutex *m)
{
- pthread_once(&m->once, m->init);
- if (pthread_mutex_lock(&m->mtx) == EOWNERDEAD) {
- sss_cli_close_socket();
- sss_mutex_consistent(&m->mtx);
- }
+ pthread_mutex_lock(&m->mtx);
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &m->old_cancel_state);
}
static void sss_mt_unlock(struct sss_mutex *m)
{
+ pthread_setcancelstate(m->old_cancel_state, NULL);
pthread_mutex_unlock(&m->mtx);
}
/* NSS mutex wrappers */
-static void sss_nss_mt_init(void)
-{
- sss_mt_init(&sss_nss_mtx);
-}
void sss_nss_lock(void)
{
sss_mt_lock(&sss_nss_mtx);
@@ -1160,10 +1102,6 @@ void sss_nss_unlock(void)
}
/* NSS mutex wrappers */
-static void sss_pam_mt_init(void)
-{
- sss_mt_init(&sss_pam_mtx);
-}
void sss_pam_lock(void)
{
sss_mt_lock(&sss_pam_mtx);
@@ -1174,10 +1112,6 @@ void sss_pam_unlock(void)
}
/* NSS mutex wrappers */
-static void sss_nss_mc_mt_init(void)
-{
- sss_mt_init(&sss_nss_mc_mtx);
-}
void sss_nss_mc_lock(void)
{
sss_mt_lock(&sss_nss_mc_mtx);
--
2.11.0

View File

@ -26,7 +26,7 @@
Name: sssd
Version: 1.14.2
Release: 1%{?dist}
Release: 2%{?dist}
Group: Applications/System
Summary: System Security Services Daemon
License: GPLv3+
@ -35,6 +35,48 @@ Source0: https://fedorahosted.org/released/sssd/%{name}-%{version}.tar.gz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
### Patches ###
Patch0001: 0001-crypto-Port-libcrypto-code-to-openssl-1.1.patch
Patch0002: 0002-libcrypto-Check-right-value-of-CRYPTO_memcmp.patch
Patch0003: 0003-crypto-tests-Add-unit-test-for-sss_encrypt-sss_decry.patch
Patch0004: 0004-crypto-tests-Rename-encrypt-decrypt-test-case.patch
Patch0005: 0005-BUILD-Fix-installation-without-samba.patch
Patch0006: 0006-BUILD-Accept-krb5-1.15-for-building-the-PAC-plugin.patch
Patch0007: 0007-dlopen-test-Use-portable-macro-for-location-of-.libs.patch
Patch0008: 0008-dlopen-test-Add-missing-libraries-to-the-check-list.patch
Patch0009: 0009-dlopen-test-Move-libraries-to-the-right-sections.patch
Patch0010: 0010-dlopen-test-Add-check-for-untested-libraries.patch
Patch0011: 0011-sssctl-Flags-for-command-initialization.patch
Patch0012: 0012-sysdb-add-parent_dom-to-sysdb_get_direct_parents.patch
Patch0013: 0013-sdap-make-some-nested-group-related-calls-public.patch
Patch0014: 0014-LDAP-AD-resolve-domain-local-groups-for-remote-users.patch
Patch0015: 0015-PAM-add-a-test-for-filter_responses.patch
Patch0016: 0016-PAM-add-pam_response_filter-option.patch
Patch0017: 0017-SYSDB-Split-sysdb_try_to_find_expected_dn-into-small.patch
Patch0018: 0018-SYSDB-Augment-sysdb_try_to_find_expected_dn-to-match.patch
Patch0019: 0019-ad_access_filter-search-for-nested-groups.patch
Patch0020: 0020-BUILD-Fix-linking-with-librt.patch
Patch0021: 0021-MONITOR-Do-not-set-up-watchdog-for-monitor.patch
Patch0022: 0022-SYSDB-Adding-lowercase-sudoUser-form.patch
Patch0023: 0023-TESTS-Extending-sysdb-sudo-store-tests.patch
Patch0024: 0024-IPA-AD-check-auth-ctx-before-using-it.patch
Patch0025: 0025-SECRETS-Fix-secrets-rule-in-the-allowed-sections.patch
Patch0026: 0026-SECRETS-Add-allowed_sec_users_options.patch
Patch0027: 0027-ipa-Nested-netgroups-do-not-work.patch
Patch0028: 0028-Qualify-ghost-user-attribute-in-case-ldap_group_nest.patch
Patch0029: 0029-tests-Add-a-test-for-group-resolution-with-ldap_grou.patch
Patch0030: 0030-BUILD-Fix-a-typo-in-inotify.m4.patch
Patch0031: 0031-SYSDB-Fixing-of-sudorule-without-a-sudoUser.patch
Patch0032: 0032-UTIL-Fix-implicit-declaration-of-function-htobe32.patch
Patch0033: 0033-sssctl-Fix-missing-declaration.patch
Patch0034: 0034-UTIL-Fix-compilation-of-sss_utf8-with-libunistring.patch
Patch0035: 0035-SIFP-Fix-warning-format-security.patch
Patch0036: 0036-SSH-Use-default_domain_suffix-for-users-authorized-k.patch
Patch0037: 0037-Prevent-use-after-free-in-fd_input_available.patch
Patch0038: 0038-STAP-Only-print-transaction-statistics-if-the-script.patch
Patch0039: 0039-sudo-do-not-store-usn-if-no-rules-are-found.patch
Patch0501: 0501-Partially-revert-CONFIG-Use-default-config-when-none.patch
Patch0502: 0502-SYSTEMD-Use-capabilities.patch
Patch0503: 0503-sss_client-Defer-thread-cancellation-until-completio.patch
### Dependencies ###
@ -1081,6 +1123,12 @@ fi
%{_libdir}/%{name}/modules/libwbclient.so
%changelog
* Tue Dec 13 2016 Lukas Slebodnik <lslebodn@redhat.com> - 1.14.2-2
- Resolves: rhbz#1369130 - nss_sss should not link against libpthread
- Resolves: rhbz#1392916 - sssd failes to start after update
- Resolves: rhbz#1398789 - SELinux is preventing sssd from 'write' accesses
on the directory /etc/sssd
* Thu Oct 20 2016 Lukas Slebodnik <lslebodn@redhat.com> - 1.14.2-1
- New upstream release 1.14.2
- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.14.2