diff --git a/active/os_rhel/p11child.patch b/active/os_rhel/p11child.patch new file mode 100644 index 0000000..2e71516 --- /dev/null +++ b/active/os_rhel/p11child.patch @@ -0,0 +1,703 @@ +From d4022a63f388f9cd0f537a4eb371e111c44b9c9c Mon Sep 17 00:00:00 2001 +From: Georgij Krajnyukov +Date: Wed, 19 Feb 2025 11:59:14 +0300 +Subject: [PATCH 1/4] P11_CHILD: Invert if statement to reduce code nesting + +Reviewed-by: Alexey Tikhonov +Reviewed-by: Sumit Bose +--- + src/p11_child/p11_child_openssl.c | 33 +++++++++++++++---------------- + 1 file changed, 16 insertions(+), 17 deletions(-) + +diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c +index 45a4930ba..8aa73c035 100644 +--- a/src/p11_child/p11_child_openssl.c ++++ b/src/p11_child/p11_child_openssl.c +@@ -1928,26 +1928,25 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, + + if (slot_id == (CK_SLOT_ID)-1) { + DEBUG(SSSDBG_TRACE_ALL, "Token not present.\n"); +- if (p11_ctx->wait_for_card) { +- /* After obtaining the module's slot list (in the loop above), this +- * call is needed to let any changes in slots take effect. */ +- rv = module->C_GetSlotList(CK_FALSE, NULL, &num_slots); +- if (rv != CKR_OK) { +- DEBUG(SSSDBG_OP_FAILURE, "C_GetSlotList failed [%lu][%s].\n", +- rv, p11_kit_strerror(rv)); +- ret = EIO; +- goto done; +- } +- +- ret = wait_for_card(module, &slot_id, &info, &token_info, uri); +- if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, "wait_for_card failed.\n"); +- goto done; +- } +- } else { ++ if (!p11_ctx->wait_for_card) { + ret = EIO; + goto done; + } ++ /* After obtaining the module's slot list (in the loop above), this ++ * call is needed to let any changes in slots take effect. */ ++ rv = module->C_GetSlotList(CK_FALSE, NULL, &num_slots); ++ if (rv != CKR_OK) { ++ DEBUG(SSSDBG_OP_FAILURE, "C_GetSlotList failed [%lu][%s].\n", ++ rv, p11_kit_strerror(rv)); ++ ret = EIO; ++ goto done; ++ } ++ ++ ret = wait_for_card(module, &slot_id, &info, &token_info, uri); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "wait_for_card failed.\n"); ++ goto done; ++ } + } + + module_id = c; +-- +2.51.0 + + +From 06ee7f46937b40da85628a03c59865fffea48e90 Mon Sep 17 00:00:00 2001 +From: Georgij Krajnyukov +Date: Tue, 4 Mar 2025 12:28:33 +0300 +Subject: [PATCH 2/4] P11_CHILD: Implement passing const args to get_pkcs11_uri + +Reviewed-by: Alexey Tikhonov +Reviewed-by: Sumit Bose +--- + src/p11_child/p11_child_openssl.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c +index 8aa73c035..30782d955 100644 +--- a/src/p11_child/p11_child_openssl.c ++++ b/src/p11_child/p11_child_openssl.c +@@ -505,9 +505,9 @@ done: + return ret; + } + +-static char *get_pkcs11_uri(TALLOC_CTX *mem_ctx, CK_INFO *module_info, +- CK_SLOT_INFO *slot_info, CK_SLOT_ID slot_id, +- CK_TOKEN_INFO *token_info, CK_ATTRIBUTE *label, ++static char *get_pkcs11_uri(TALLOC_CTX *mem_ctx, const CK_INFO *module_info, ++ const CK_SLOT_INFO *slot_info, CK_SLOT_ID slot_id, ++ const CK_TOKEN_INFO *token_info, CK_ATTRIBUTE *label, + CK_ATTRIBUTE *id) + { + P11KitUri *uri; +-- +2.51.0 + + +From 54d3110be5146ec1d6575389bc60ad7585493984 Mon Sep 17 00:00:00 2001 +From: Georgij Krajnyukov +Date: Wed, 19 Feb 2025 12:22:30 +0300 +Subject: [PATCH 3/4] P11_CHILD: Extract slot processing into separate function + +Reviewed-by: Alexey Tikhonov +Reviewed-by: Sumit Bose +--- + src/p11_child/p11_child_openssl.c | 399 ++++++++++++++++-------------- + 1 file changed, 212 insertions(+), 187 deletions(-) + +diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c +index 30782d955..b96d19f88 100644 +--- a/src/p11_child/p11_child_openssl.c ++++ b/src/p11_child/p11_child_openssl.c +@@ -1702,6 +1702,215 @@ static errno_t wait_for_card(CK_FUNCTION_LIST *module, CK_SLOT_ID *slot_id, + + #define MAX_SLOTS 64 + ++errno_t do_slot(CK_FUNCTION_LIST *module, size_t module_id, CK_SLOT_ID slot_id, ++ const CK_SLOT_INFO *info, const CK_TOKEN_INFO *token_info, ++ const CK_INFO *module_info, TALLOC_CTX *mem_ctx, ++ struct p11_ctx *p11_ctx, enum op_mode mode, const char *pin, ++ const char *module_name_in, const char *token_name_in, ++ const char *key_id_in, const char *label_in, ++ const char *uri_str, char **_multi) { ++ int ret; ++ CK_RV rv; ++ char *module_file_name = NULL; ++ char *slot_name = NULL; ++ char *token_name = NULL; ++ CK_SESSION_HANDLE session = 0; ++ struct cert_list *cert_list = NULL; ++ struct cert_list *item = NULL; ++ struct cert_list *next_item = NULL; ++ bool pkcs11_session = false; ++ bool pkcs11_login = false; ++ ++ slot_name = p11_kit_space_strdup(info->slotDescription, ++ sizeof(info->slotDescription)); ++ if (slot_name == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "p11_kit_space_strdup failed.\n"); ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ token_name = p11_kit_space_strdup(token_info->label, ++ sizeof(token_info->label)); ++ if (token_name == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "p11_kit_space_strdup failed.\n"); ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ module_file_name = p11_kit_module_get_filename(module); ++ if (module_file_name == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "p11_kit_module_get_filename failed.\n"); ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ DEBUG(SSSDBG_TRACE_ALL, "Found [%s] in slot [%s][%d] of module [%d][%s].\n", ++ token_name, slot_name, (int) slot_id, (int) module_id, ++ module_file_name); ++ ++ rv = module->C_OpenSession(slot_id, CKF_SERIAL_SESSION, NULL, NULL, ++ &session); ++ if (rv != CKR_OK) { ++ DEBUG(SSSDBG_OP_FAILURE, "C_OpenSession failed [%lu][%s].\n", ++ rv, p11_kit_strerror(rv)); ++ ret = EIO; ++ goto done; ++ } ++ pkcs11_session = true; ++ ++ /* login: do we need to check for Login Required? */ ++ if (mode == OP_AUTH) { ++ DEBUG(SSSDBG_TRACE_ALL, "Login required.\n"); ++ DEBUG(SSSDBG_TRACE_ALL, "Token flags [%lu].\n", token_info->flags); ++ if ((pin != NULL) ++ || (token_info->flags & CKF_PROTECTED_AUTHENTICATION_PATH)) { ++ ++ if (token_info->flags & CKF_PROTECTED_AUTHENTICATION_PATH) { ++ DEBUG(SSSDBG_TRACE_ALL, "Protected authentication path.\n"); ++ pin = NULL; ++ } ++ rv = module->C_Login(session, CKU_USER, discard_const(pin), ++ (pin != NULL) ? strlen(pin) : 0); ++ if (rv == CKR_PIN_LOCKED) { ++ DEBUG(SSSDBG_OP_FAILURE, "C_Login failed: PIN locked\n"); ++ ret = ERR_P11_PIN_LOCKED; ++ goto done; ++ } ++ else if (rv != CKR_OK) { ++ DEBUG(SSSDBG_OP_FAILURE, "C_Login failed [%lu][%s].\n", ++ rv, p11_kit_strerror(rv)); ++ ret = EIO; ++ goto done; ++ } ++ pkcs11_login = true; ++ } else { ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "Login required but no PIN available, continue.\n"); ++ } ++ } else { ++ DEBUG(SSSDBG_TRACE_ALL, "Login NOT required.\n"); ++ } ++ ++ ret = read_certs(mem_ctx, module, session, p11_ctx, &cert_list); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "read_certs failed.\n"); ++ goto done; ++ } ++ ++ DLIST_FOR_EACH_SAFE(item, next_item, cert_list) { ++ /* Check if we found the certificates we needed for authentication or ++ * the requested ones for pre-auth. For authentication all attributes ++ * except the label must be given and match. The label is optional for ++ * authentication but if given it must match as well. For pre-auth ++ * only the given ones must match. */ ++ DEBUG(SSSDBG_TRACE_ALL, "%s %s %s %s %s %s %s.\n", ++ module_name_in, module_file_name, token_name_in, token_name, ++ key_id_in, label_in == NULL ? "- no label given-" : label_in, ++ item->id); ++ ++ if ((mode == OP_AUTH ++ && module_name_in != NULL ++ && token_name_in != NULL ++ && key_id_in != NULL ++ && item->id != NULL ++ && strcmp(key_id_in, item->id) == 0 ++ && (label_in == NULL ++ || (label_in != NULL && item->label != NULL ++ && strcmp(label_in, item->label) == 0)) ++ && strcmp(token_name_in, token_name) == 0 ++ && strcmp(module_name_in, module_file_name) == 0) ++ || (mode == OP_PREAUTH ++ && (module_name_in == NULL ++ || (module_name_in != NULL ++ && strcmp(module_name_in, module_file_name) == 0)) ++ && (token_name_in == NULL ++ || (token_name_in != NULL ++ && strcmp(token_name_in, token_name) == 0)) ++ && (key_id_in == NULL ++ || (key_id_in != NULL && item->id != NULL ++ && strcmp(key_id_in, item->id) == 0)))) { ++ ++ item->uri = get_pkcs11_uri(mem_ctx, module_info, info, slot_id, ++ token_info, ++ &item->attributes[1] /* label */, ++ &item->attributes[0] /* id */); ++ DEBUG(SSSDBG_TRACE_ALL, "uri: %s.\n", item->uri); ++ ++ } else { ++ DLIST_REMOVE(cert_list, item); ++ talloc_free(item); ++ } ++ } ++ ++ /* TODO: check module_name_in, token_name_in, key_id_in */ ++ ++ if (cert_list == NULL) { ++ DEBUG(SSSDBG_TRACE_ALL, "No certificate found.\n"); ++ *_multi = NULL; ++ ret = EOK; ++ goto done; ++ } ++ ++ if (mode == OP_AUTH) { ++ if (cert_list->next != NULL || cert_list->prev != NULL) { ++ DEBUG(SSSDBG_FATAL_FAILURE, ++ "More than one certificate found for authentication, " ++ "aborting!\n"); ++ ret = EINVAL; ++ goto done; ++ } ++ ++ ret = sign_data(module, session, slot_id, cert_list); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "sign_data failed.\n"); ++ ret = EACCES; ++ goto done; ++ } ++ ++ DEBUG(SSSDBG_TRACE_ALL, ++ "Certificate verified and validated.\n"); ++ } ++ ++ *_multi = talloc_strdup(mem_ctx, ""); ++ if (*_multi == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create output string.\n"); ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ DLIST_FOR_EACH(item, cert_list) { ++ DEBUG(SSSDBG_TRACE_ALL, "Found certificate has key id [%s].\n", ++ item->id); ++ ++ *_multi = talloc_asprintf_append(*_multi, "%s\n%s\n%s\n%s\n%s\n", ++ token_name, module_file_name, item->id, ++ item->label, item->cert_b64); ++ } ++ ++ ret = EOK; ++done: ++ if (module != NULL) { ++ if (pkcs11_login) { ++ rv = module->C_Logout(session); ++ if (rv != CKR_OK) { ++ DEBUG(SSSDBG_OP_FAILURE, "C_Logout failed [%lu][%s].\n", ++ rv, p11_kit_strerror(rv)); ++ } ++ } ++ if (pkcs11_session) { ++ rv = module->C_CloseSession(session); ++ if (rv != CKR_OK) { ++ DEBUG(SSSDBG_OP_FAILURE, "C_CloseSession failed [%lu][%s].\n", ++ rv, p11_kit_strerror(rv)); ++ } ++ } ++ } ++ free(slot_name); ++ free(token_name); ++ free(module_file_name); ++ return ret; ++} ++ + errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, + enum op_mode mode, const char *pin, + const char *module_name_in, const char *token_name_in, +@@ -1724,16 +1933,7 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, + CK_INFO module_info; + CK_RV rv; + size_t module_id; +- char *module_file_name = NULL; +- char *slot_name = NULL; +- char *token_name = NULL; +- CK_SESSION_HANDLE session = 0; +- struct cert_list *cert_list = NULL; +- struct cert_list *item = NULL; +- struct cert_list *next_item = NULL; + char *multi = NULL; +- bool pkcs11_session = false; +- bool pkcs11_login = false; + P11KitUri *uri = NULL; + + if (uri_str != NULL) { +@@ -1950,188 +2150,13 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, + } + + module_id = c; +- slot_name = p11_kit_space_strdup(info.slotDescription, +- sizeof(info.slotDescription)); +- if (slot_name == NULL) { +- DEBUG(SSSDBG_OP_FAILURE, "p11_kit_space_strdup failed.\n"); +- ret = ENOMEM; +- goto done; +- } +- +- token_name = p11_kit_space_strdup(token_info.label, +- sizeof(token_info.label)); +- if (token_name == NULL) { +- DEBUG(SSSDBG_OP_FAILURE, "p11_kit_space_strdup failed.\n"); +- ret = ENOMEM; +- goto done; +- } +- +- module_file_name = p11_kit_module_get_filename(module); +- if (module_file_name == NULL) { +- DEBUG(SSSDBG_OP_FAILURE, "p11_kit_module_get_filename failed.\n"); +- ret = ENOMEM; +- goto done; +- } +- +- DEBUG(SSSDBG_TRACE_ALL, "Found [%s] in slot [%s][%d] of module [%d][%s].\n", +- token_name, slot_name, (int) slot_id, (int) module_id, +- module_file_name); +- +- rv = module->C_OpenSession(slot_id, CKF_SERIAL_SESSION, NULL, NULL, +- &session); +- if (rv != CKR_OK) { +- DEBUG(SSSDBG_OP_FAILURE, "C_OpenSession failed [%lu][%s].\n", +- rv, p11_kit_strerror(rv)); +- ret = EIO; +- goto done; +- } +- pkcs11_session = true; +- +- /* login: do we need to check for Login Required? */ +- if (mode == OP_AUTH) { +- DEBUG(SSSDBG_TRACE_ALL, "Login required.\n"); +- if (pin != NULL) { +- rv = module->C_Login(session, CKU_USER, discard_const(pin), +- strlen(pin)); +- if (rv == CKR_PIN_LOCKED) { +- DEBUG(SSSDBG_OP_FAILURE, "C_Login failed: PIN locked\n"); +- ret = ERR_P11_PIN_LOCKED; +- goto done; +- } +- else if (rv != CKR_OK) { +- DEBUG(SSSDBG_OP_FAILURE, "C_Login failed [%lu][%s].\n", +- rv, p11_kit_strerror(rv)); +- ret = EIO; +- goto done; +- } +- pkcs11_login = true; +- } else { +- DEBUG(SSSDBG_CRIT_FAILURE, +- "Login required but no PIN available, continue.\n"); +- } +- } else { +- DEBUG(SSSDBG_TRACE_ALL, "Login NOT required.\n"); +- } +- +- ret = read_certs(mem_ctx, module, session, p11_ctx, &cert_list); +- if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, "read_certs failed.\n"); +- goto done; +- } +- +- DLIST_FOR_EACH_SAFE(item, next_item, cert_list) { +- /* Check if we found the certificates we needed for authentication or +- * the requested ones for pre-auth. For authentication all attributes +- * except the label must be given and match. The label is optional for +- * authentication but if given it must match as well. For pre-auth +- * only the given ones must match. */ +- DEBUG(SSSDBG_TRACE_ALL, "%s %s %s %s %s %s %s.\n", +- module_name_in, module_file_name, token_name_in, token_name, +- key_id_in, label_in == NULL ? "- no label given-" : label_in, +- item->id); +- +- if ((mode == OP_AUTH +- && module_name_in != NULL +- && token_name_in != NULL +- && key_id_in != NULL +- && item->id != NULL +- && strcmp(key_id_in, item->id) == 0 +- && (label_in == NULL +- || (label_in != NULL && item->label != NULL +- && strcmp(label_in, item->label) == 0)) +- && strcmp(token_name_in, token_name) == 0 +- && strcmp(module_name_in, module_file_name) == 0) +- || (mode == OP_PREAUTH +- && (module_name_in == NULL +- || (module_name_in != NULL +- && strcmp(module_name_in, module_file_name) == 0)) +- && (token_name_in == NULL +- || (token_name_in != NULL +- && strcmp(token_name_in, token_name) == 0)) +- && (key_id_in == NULL +- || (key_id_in != NULL && item->id != NULL +- && strcmp(key_id_in, item->id) == 0)))) { +- +- item->uri = get_pkcs11_uri(mem_ctx, &module_info, &info, slot_id, +- &token_info, +- &item->attributes[1] /* label */, +- &item->attributes[0] /* id */); +- DEBUG(SSSDBG_TRACE_ALL, "uri: %s.\n", item->uri); +- +- } else { +- DLIST_REMOVE(cert_list, item); +- talloc_free(item); +- } +- } +- +- /* TODO: check module_name_in, token_name_in, key_id_in */ +- +- if (cert_list == NULL) { +- DEBUG(SSSDBG_TRACE_ALL, "No certificate found.\n"); +- *_multi = NULL; +- ret = EOK; +- goto done; +- } +- +- if (mode == OP_AUTH) { +- if (cert_list->next != NULL || cert_list->prev != NULL) { +- DEBUG(SSSDBG_FATAL_FAILURE, +- "More than one certificate found for authentication, " +- "aborting!\n"); +- ret = EINVAL; +- goto done; +- } +- +- ret = sign_data(module, session, slot_id, cert_list); +- if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, "sign_data failed.\n"); +- ret = EACCES; +- goto done; +- } +- +- DEBUG(SSSDBG_TRACE_ALL, +- "Certificate verified and validated.\n"); +- } +- +- multi = talloc_strdup(mem_ctx, ""); +- if (multi == NULL) { +- DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create output string.\n"); +- ret = ENOMEM; +- goto done; +- } +- +- DLIST_FOR_EACH(item, cert_list) { +- DEBUG(SSSDBG_TRACE_ALL, "Found certificate has key id [%s].\n", +- item->id); +- +- multi = talloc_asprintf_append(multi, "%s\n%s\n%s\n%s\n%s\n", +- token_name, module_file_name, item->id, +- item->label, item->cert_b64); +- } +- ++ ret = do_slot(module, module_id, slot_id, &info, &token_info, &module_info, ++ mem_ctx, p11_ctx, mode, pin, module_name_in, token_name_in, ++ key_id_in, label_in, uri_str, &multi); + *_multi = multi; + + ret = EOK; + done: +- if (module != NULL) { +- if (pkcs11_login) { +- rv = module->C_Logout(session); +- if (rv != CKR_OK) { +- DEBUG(SSSDBG_OP_FAILURE, "C_Logout failed [%lu][%s].\n", +- rv, p11_kit_strerror(rv)); +- } +- } +- if (pkcs11_session) { +- rv = module->C_CloseSession(session); +- if (rv != CKR_OK) { +- DEBUG(SSSDBG_OP_FAILURE, "C_CloseSession failed [%lu][%s].\n", +- rv, p11_kit_strerror(rv)); +- } +- } +- } +- free(slot_name); +- free(token_name); +- free(module_file_name); + p11_kit_modules_finalize_and_release(modules); + p11_kit_uri_free(uri); + +-- +2.51.0 + + +From 218c418e1ad34efe3922937673716c0cc657597c Mon Sep 17 00:00:00 2001 +From: Georgij Krajnyukov +Date: Fri, 14 Feb 2025 15:00:50 +0300 +Subject: [PATCH 4/4] P11_CHILD: Make p11_child iterate over all slots + +Resolves: https://github.com/SSSD/sssd/issues/5905 + +Reviewed-by: Alexey Tikhonov +Reviewed-by: Sumit Bose +--- + src/p11_child/p11_child_openssl.c | 74 +++++++++++++++++++++---------- + 1 file changed, 51 insertions(+), 23 deletions(-) + +diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c +index b96d19f88..154a3052b 100644 +--- a/src/p11_child/p11_child_openssl.c ++++ b/src/p11_child/p11_child_openssl.c +@@ -1748,6 +1748,15 @@ errno_t do_slot(CK_FUNCTION_LIST *module, size_t module_id, CK_SLOT_ID slot_id, + token_name, slot_name, (int) slot_id, (int) module_id, + module_file_name); + ++ if (mode == OP_AUTH && strcmp(token_name, token_name_in) != 0) { ++ DEBUG(SSSDBG_TRACE_ALL, "Token name [%s] does not match " ++ "token_name_in [%s]. " ++ "Skipping this token...\n", ++ token_name, token_name_in); ++ ret = EOK; ++ goto done; ++ } ++ + rv = module->C_OpenSession(slot_id, CKF_SERIAL_SESSION, NULL, NULL, + &session); + if (rv != CKR_OK) { +@@ -1846,7 +1855,6 @@ errno_t do_slot(CK_FUNCTION_LIST *module, size_t module_id, CK_SLOT_ID slot_id, + + if (cert_list == NULL) { + DEBUG(SSSDBG_TRACE_ALL, "No certificate found.\n"); +- *_multi = NULL; + ret = EOK; + goto done; + } +@@ -1871,13 +1879,6 @@ errno_t do_slot(CK_FUNCTION_LIST *module, size_t module_id, CK_SLOT_ID slot_id, + "Certificate verified and validated.\n"); + } + +- *_multi = talloc_strdup(mem_ctx, ""); +- if (*_multi == NULL) { +- DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create output string.\n"); +- ret = ENOMEM; +- goto done; +- } +- + DLIST_FOR_EACH(item, cert_list) { + DEBUG(SSSDBG_TRACE_ALL, "Found certificate has key id [%s].\n", + item->id); +@@ -1885,6 +1886,12 @@ errno_t do_slot(CK_FUNCTION_LIST *module, size_t module_id, CK_SLOT_ID slot_id, + *_multi = talloc_asprintf_append(*_multi, "%s\n%s\n%s\n%s\n%s\n", + token_name, module_file_name, item->id, + item->label, item->cert_b64); ++ if (*_multi == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "Failed to append certiticate to the output string.\n"); ++ ret = ENOMEM; ++ goto done; ++ } + } + + ret = EOK; +@@ -1933,9 +1940,14 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, + CK_INFO module_info; + CK_RV rv; + size_t module_id; +- char *multi = NULL; + P11KitUri *uri = NULL; + ++ *_multi = talloc_strdup(mem_ctx, ""); ++ if (*_multi == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create output string.\n"); ++ return ENOMEM; ++ } ++ + if (uri_str != NULL) { + uri = p11_kit_uri_new(); + if (uri == NULL) { +@@ -1986,9 +1998,17 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, + } + + DEBUG(SSSDBG_TRACE_ALL, "common name: [%s].\n", mod_name); +- DEBUG(SSSDBG_TRACE_ALL, "dll name: [%s].\n", mod_file_name); +- + free(mod_name); ++ ++ DEBUG(SSSDBG_TRACE_ALL, "dll name: [%s].\n", mod_file_name); ++ if (mode == OP_AUTH && strcmp(mod_file_name, module_name_in) != 0) { ++ DEBUG(SSSDBG_TRACE_ALL, "Module name [%s] does not match " ++ "module_name_in [%s]. " ++ "Skipping this module...\n", ++ mod_file_name, module_name_in); ++ free(mod_file_name); ++ continue; ++ } + free(mod_file_name); + + rv = modules[c]->C_GetInfo(&module_info); +@@ -2104,10 +2124,13 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, + } + + slot_id = slots[s]; +- break; +- } +- if (slot_id != (CK_SLOT_ID)-1) { +- break; ++ module_id = c; ++ ret = do_slot(module, module_id, slot_id, &info, &token_info, &module_info, ++ mem_ctx, p11_ctx, mode, pin, module_name_in, token_name_in, ++ key_id_in, label_in, uri_str, _multi); ++ if (ret != EOK) { ++ goto done; ++ } + } + } + +@@ -2126,7 +2149,7 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, + goto done; + } + +- if (slot_id == (CK_SLOT_ID)-1) { ++ if (slot_id == (CK_SLOT_ID)-1 || (mode == OP_AUTH && *_multi[0] == '\0')) { + DEBUG(SSSDBG_TRACE_ALL, "Token not present.\n"); + if (!p11_ctx->wait_for_card) { + ret = EIO; +@@ -2147,18 +2170,23 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, + DEBUG(SSSDBG_OP_FAILURE, "wait_for_card failed.\n"); + goto done; + } +- } + +- module_id = c; +- ret = do_slot(module, module_id, slot_id, &info, &token_info, &module_info, +- mem_ctx, p11_ctx, mode, pin, module_name_in, token_name_in, +- key_id_in, label_in, uri_str, &multi); +- *_multi = multi; ++ ret = do_slot(module, module_id, slot_id, &info, &token_info, &module_info, ++ mem_ctx, p11_ctx, mode, pin, module_name_in, token_name_in, ++ key_id_in, label_in, uri_str, _multi); ++ if (mode == OP_AUTH && *_multi[0] == '\0') { ++ ret = EIO; ++ } ++ } + +- ret = EOK; + done: + p11_kit_modules_finalize_and_release(modules); + p11_kit_uri_free(uri); + ++ if (ret != EOK) { ++ talloc_free(*_multi); ++ *_multi = NULL; ++ } ++ + return ret; + } +-- +2.51.0 + diff --git a/active/os_rhel/rhel8.md b/active/os_rhel/rhel8.md new file mode 100644 index 0000000..1f96070 --- /dev/null +++ b/active/os_rhel/rhel8.md @@ -0,0 +1,85 @@ +# RHEL 8 + +## Subscriptions + +```bash +# Re-up subscription +subscription-manager register +subscription-manager release --show +subscription-manager release --set=8_10 +``` + +`dnf update` will sometimes throw an error like: + +```bash +Updating Subscription Management repositories. +Red Hat Enterprise Linux 8 for x86_64 - BaseOS (RPMs) 0.0 B/s | 0 B 00:00 +Errors during downloading metadata for repository 'rhel-8-for-x86_64-baseos-rpms': + - Curl error (77): Problem with the SSL CA cert (path? access rights?) for https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/repodata/repomd.xml [error setting certificate verify locations: + CAfile: %(ca_cert_dir)sredhat-uep.pem + CApath: none] +Error: Failed to download metadata for repo 'rhel-8-for-x86_64-baseos-rpms': Cannot download repomd.xml: Curl error (77): Problem with the SSL CA cert (path? access rights?) for https://cdn.redhat.com/content/dist/rhel8/8/x86_64/baseos/os/repodata/repomd.xml [error setting certificate verify locations: + CAfile: %(ca_cert_dir)sredhat-uep.pem + CApath: none] +``` + +It can be fixed by adding the correct details to /etc/rhsm/rhsm.conf + + + +```bash +# /etc/rhsm/rhsm.conf + +[rhsm] +# Content base URL: +baseurl = https://cdn.redhat.com + +# Repository metadata GPG key URL: +repomd_gpg_url = + +# Server CA certificate location: +ca_cert_dir = /etc/rhsm/ca/ + +# Default CA cert to use when generating yum repo configs: +repo_ca_cert = %(ca_cert_dir)sredhat-uep.pem +``` + +## DNF Repo Hotfixes + +Fixes an issue where dnf would fail to install a package due to multiple +modules or "conflicting requests" or "filtered out by modular filtering". + + + +```ini +# Add this to all conflicting rpm sources in /etc/yum.repos.d +module_hotfixes=1 +``` + +## Patching an RPM + +### Creating the patch + +1. Create your patch by checking out the tag matching the rpm version of the software you want to patch +2. Cherry pick the commits you want to patch in: `git cherry-pick 3392a857c^..782a6dd54 --strategy-option=theirs` +3. Create a diff: `git format-patch 20ddeab85^..0cf92b3d4 --stdout > p11child.patch` +4. Copy the patch to your rhel instance + +### Applying the patch + +1. Enable the `codeready-builder-for-...-source-rpms` rpm source in `/etc/yum.repos.d/redhat.repo` +2. For RHEL 8: Add `module_hotfixes=1` to appstream and codebuild in `/etc/yum.repos.d/redhat.repo` +3. `dnf download --source sssd` +4. `rpm -i sssd-2.9.4-5.el8_10.2.src.rpm` +5. `cd rpmbuild/SPECS` +6. Edit `sssd.spec` and change `Release: 5%{?dist}.2` to match your release: e.g. `Release: 5%{?dist}_10.2` +7. `dnf builddep sssd.spec` +8. `rpmbuild -bb sssd.spec --nocheck` +9. `cd ~/rpmbuild/RPMS/x86_64` +10. For RHEL 8 `rpm -ivh ./sssd-2.9.4-5.el8_10.2.x86_64.rpm --force` +11. For RHEL 9 `dnf install ./sssd-2.9.4-5.el8_10.2.x86_64.rpm` + +## VM Passthrough + +If you get "device or resource busy" while trying to pass through a smart card +to a VM, you'll probably need to `systemctl stop pcscd` on the host. diff --git a/active/os_rhel/sssd-rpm.tar b/active/os_rhel/sssd-rpm.tar new file mode 100644 index 0000000..c2fb410 Binary files /dev/null and b/active/os_rhel/sssd-rpm.tar differ diff --git a/active/os_rhel/sssd.spec.patch b/active/os_rhel/sssd.spec.patch new file mode 100644 index 0000000..8dbbdc7 --- /dev/null +++ b/active/os_rhel/sssd.spec.patch @@ -0,0 +1,18 @@ +--- sssd.spec 2025-10-07 16:20:35.377452600 -0400 ++++ sssd.spec.bk 2025-10-07 16:20:23.322575768 -0400 +@@ -19,7 +19,7 @@ + + Name: sssd + Version: 2.9.4 +-Release: 5%{?dist}.2 ++Release: 5%{?dist}_10.2 + Group: Applications/System + Summary: System Security Services Daemon + License: GPLv3+ +@@ -46,6 +46,7 @@ + Patch0017: 0017-KCM-another-memory-leak-fixed.patch + Patch0018: 0018-SYSDB-don-t-add-group-members-if-ignore_group_member.patch + Patch0019: 0019-SYSDB-Use-SYSDB_NAME-from-cached-entry-when-updating.patch ++Patch0020: 0020-p11child.patch + + ### Downstream Patches ###