1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-08 21:18:16 +03:00

s3:auth: Split auth3_generate_session_info_pac() into functions

This gets rid of the multiple goto and just have a single destructor
goto.
Best view this commit with `git show -b <sha> --color-moved=zebra`

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
Andreas Schneider 2024-04-11 10:21:16 +02:00 committed by Andrew Bartlett
parent 20c546f928
commit b58395e5c3

View File

@ -38,44 +38,14 @@
#include "librpc/gen_ndr/dcerpc.h"
#include "source3/lib/substitute.h"
static NTSTATUS auth3_generate_session_info_pac(
struct auth4_context *auth_ctx,
static NTSTATUS generate_pac_session_info(
TALLOC_CTX *mem_ctx,
struct smb_krb5_context *smb_krb5_context,
DATA_BLOB *pac_blob,
const char *princ_name,
const struct tsocket_address *remote_address,
uint32_t session_info_flags,
struct auth_session_info **session_info)
const char *rhost,
DATA_BLOB *pac_blob,
struct auth_session_info **psession_info)
{
enum server_role server_role = lp_server_role();
TALLOC_CTX *tmp_ctx;
bool is_mapped;
bool is_guest;
char *ntuser;
char *ntdomain;
char *username;
const char *rhost;
struct passwd *pw;
NTSTATUS status;
tmp_ctx = talloc_new(mem_ctx);
if (!tmp_ctx) {
return NT_STATUS_NO_MEMORY;
}
if (tsocket_address_is_inet(remote_address, "ip")) {
rhost = tsocket_address_inet_addr_string(remote_address,
tmp_ctx);
if (rhost == NULL) {
status = NT_STATUS_NO_MEMORY;
goto done;
}
} else {
rhost = "127.0.0.1";
}
if (server_role != ROLE_STANDALONE) {
struct wbcAuthUserParams params = {0};
struct wbcAuthUserInfo *info = NULL;
struct wbcAuthErrorInfo *err = NULL;
@ -84,15 +54,6 @@ static NTSTATUS auth3_generate_session_info_pac(
char *p = NULL;
wbcErr wbc_err;
if (pac_blob == NULL) {
/*
* This should already be caught at the main
* gensec layer, but better check twice
*/
status = NT_STATUS_INTERNAL_ERROR;
goto done;
}
/*
* Let winbind decode the PAC.
* This will also store the user
@ -127,20 +88,17 @@ static NTSTATUS auth3_generate_session_info_pac(
DBG_ERR("winbindd not running - "
"but required as domain member: %s\n",
nt_errstr(status));
goto done;
return status;
case WBC_ERR_AUTH_ERROR:
status = NT_STATUS(err->nt_status);
wbcFreeMemory(err);
goto done;
return NT_STATUS(err->nt_status);
case WBC_ERR_NO_MEMORY:
status = NT_STATUS_NO_MEMORY;
goto done;
return NT_STATUS_NO_MEMORY;
default:
status = NT_STATUS_LOGON_FAILURE;
goto done;
return NT_STATUS_LOGON_FAILURE;
}
status = make_server_info_wbcAuthUserInfo(tmp_ctx,
status = make_server_info_wbcAuthUserInfo(mem_ctx,
info->account_name,
info->domain_name,
info,
@ -149,7 +107,7 @@ static NTSTATUS auth3_generate_session_info_pac(
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("make_server_info_wbcAuthUserInfo failed: %s\n",
nt_errstr(status)));
goto done;
return status;
}
/* We skip doing this step if the caller asked us not to */
@ -165,7 +123,7 @@ static NTSTATUS auth3_generate_session_info_pac(
DEBUG(3, ("check_ntlm_password: PAM Account for user [%s] "
"FAILED with error %s\n",
unix_username, nt_errstr(status)));
goto done;
return status;
}
DEBUG(5, ("check_ntlm_password: PAM Account for user [%s] "
@ -178,33 +136,41 @@ static NTSTATUS auth3_generate_session_info_pac(
if (!p) {
DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
princ_name));
status = NT_STATUS_LOGON_FAILURE;
goto done;
return NT_STATUS_LOGON_FAILURE;
}
original_user_name = talloc_strndup(tmp_ctx,
original_user_name = talloc_strndup(mem_ctx,
princ_name,
p - princ_name);
if (original_user_name == NULL) {
status = NT_STATUS_NO_MEMORY;
goto done;
return NT_STATUS_NO_MEMORY;
}
status = create_local_token(mem_ctx,
server_info,
NULL,
original_user_name,
session_info);
status = create_local_token(
mem_ctx, server_info, NULL, original_user_name, psession_info);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("create_local_token failed: %s\n",
nt_errstr(status)));
goto done;
return status;
}
goto session_info_ready;
return NT_STATUS_OK;
}
/* This is the standalone legacy code path */
static NTSTATUS generate_krb5_session_info(
TALLOC_CTX *mem_ctx,
const char *princ_name,
const char *rhost,
DATA_BLOB *pac_blob,
struct auth_session_info **psession_info)
{
bool is_mapped = false;
bool is_guest = false;
char *ntuser = NULL;
char *ntdomain = NULL;
char *username = NULL;
struct passwd *pw = NULL;
NTSTATUS status;
if (pac_blob != NULL) {
/*
@ -213,14 +179,11 @@ static NTSTATUS auth3_generate_session_info_pac(
*/
status = NT_STATUS_BAD_TOKEN_TYPE;
DBG_WARNING("Unexpected PAC for [%s] in standalone mode - %s\n",
princ_name,
nt_errstr(status));
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
princ_name, nt_errstr(status));
return status;
}
status = get_user_from_kerberos_info(tmp_ctx,
status = get_user_from_kerberos_info(mem_ctx,
rhost,
princ_name,
&is_mapped,
@ -231,10 +194,8 @@ static NTSTATUS auth3_generate_session_info_pac(
&pw);
if (!NT_STATUS_IS_OK(status)) {
DBG_NOTICE("Failed to map kerberos principal to system user "
"(%s)\n",
nt_errstr(status));
status = NT_STATUS_ACCESS_DENIED;
goto done;
"(%s)\n", nt_errstr(status));
return NT_STATUS_ACCESS_DENIED;
}
status = make_session_info_krb5(mem_ctx,
@ -244,31 +205,88 @@ static NTSTATUS auth3_generate_session_info_pac(
pw,
is_guest,
is_mapped,
session_info);
psession_info);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n",
nt_errstr(status)));
status = nt_status_squash(status);
return status;
}
return NT_STATUS_OK;
}
static NTSTATUS auth3_generate_session_info_pac(
struct auth4_context *auth_ctx,
TALLOC_CTX *mem_ctx,
struct smb_krb5_context *smb_krb5_context,
DATA_BLOB *pac_blob,
const char *princ_name,
const struct tsocket_address *remote_address,
uint32_t session_info_flags,
struct auth_session_info **psession_info)
{
enum server_role server_role = lp_server_role();
struct auth_session_info *session_info = NULL;
const char *rhost;
NTSTATUS status;
TALLOC_CTX *tmp_ctx = NULL;
tmp_ctx = talloc_new(mem_ctx);
if (tmp_ctx == NULL) {
return NT_STATUS_NO_MEMORY;
}
if (tsocket_address_is_inet(remote_address, "ip")) {
rhost = tsocket_address_inet_addr_string(remote_address,
tmp_ctx);
if (rhost == NULL) {
status = NT_STATUS_NO_MEMORY;
goto done;
}
} else {
rhost = "127.0.0.1";
}
switch (server_role) {
case ROLE_DOMAIN_MEMBER:
case ROLE_DOMAIN_BDC:
case ROLE_DOMAIN_PDC:
case ROLE_ACTIVE_DIRECTORY_DC:
case ROLE_IPA_DC:
/* This requires a complete MS-PAC including logon_info */
status = generate_pac_session_info(
tmp_ctx, princ_name, rhost, pac_blob, &session_info);
break;
case ROLE_STANDALONE:
status = generate_krb5_session_info(
tmp_ctx, princ_name, rhost, pac_blob, &session_info);
break;
default:
status = NT_STATUS_INVALID_PARAMETER;
goto done;
}
session_info_ready:
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
/* setup the string used by %U */
set_current_user_info((*session_info)->unix_info->sanitized_username,
(*session_info)->unix_info->unix_name,
(*session_info)->info->domain_name);
set_current_user_info(session_info->unix_info->sanitized_username,
session_info->unix_info->unix_name,
session_info->info->domain_name);
/* reload services so that the new %U is taken into account */
lp_load_with_shares(get_dyn_CONFIGFILE());
DEBUG(5, (__location__ "OK: user: %s domain: %s client: %s\n",
(*session_info)->info->account_name,
(*session_info)->info->domain_name,
session_info->info->account_name,
session_info->info->domain_name,
rhost));
status = NT_STATUS_OK;
*psession_info = talloc_move(mem_ctx, &session_info);
status = NT_STATUS_OK;
done:
TALLOC_FREE(tmp_ctx);
return status;