mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
s4:auth Change auth_generate_session_info to take flags
This allows us to control what groups should be added in what use cases, and in particular to more carefully control the introduction of the 'authenticated' group. In particular, in the 'service_named_pipe' protocol, we do not have control over the addition of the authenticated users group, so we key of 'is this user the anonymous SID'. This also takes more care to allocate the right length ptoken->sids Andrew Bartlett
This commit is contained in:
parent
3ff2766231
commit
9c6b637ce8
@ -48,6 +48,10 @@ struct loadparm_context;
|
||||
#define USER_INFO_DONT_CHECK_UNIX_ACCOUNT 0x04 /* don't check unix account status */
|
||||
#define USER_INFO_INTERACTIVE_LOGON 0x08 /* don't check unix account status */
|
||||
|
||||
#define AUTH_SESSION_INFO_DEFAULT_GROUPS 0x01 /* Add the user to the default world and network groups */
|
||||
#define AUTH_SESSION_INFO_AUTHENTICATED 0x02 /* Add the user to the 'authenticated users' group */
|
||||
#define AUTH_SESSION_INFO_ENTERPRISE_DC 0x04 /* Add the user to the 'enterprise DC' group */
|
||||
|
||||
enum auth_password_state {
|
||||
AUTH_PASSWORD_RESPONSE,
|
||||
AUTH_PASSWORD_HASH,
|
||||
@ -211,6 +215,7 @@ struct auth_context {
|
||||
NTSTATUS (*generate_session_info)(TALLOC_CTX *mem_ctx,
|
||||
struct auth_context *auth_context,
|
||||
struct auth_serversupplied_info *server_info,
|
||||
uint32_t session_info_flags,
|
||||
struct auth_session_info **session_info);
|
||||
};
|
||||
|
||||
|
@ -1327,8 +1327,14 @@ NTSTATUS gensec_generate_session_info(TALLOC_CTX *mem_ctx,
|
||||
{
|
||||
NTSTATUS nt_status;
|
||||
if (gensec_security->auth_context) {
|
||||
uint32_t flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
|
||||
if (server_info->authenticated) {
|
||||
flags |= AUTH_SESSION_INFO_AUTHENTICATED;
|
||||
}
|
||||
nt_status = gensec_security->auth_context->generate_session_info(mem_ctx, gensec_security->auth_context,
|
||||
server_info, session_info);
|
||||
server_info,
|
||||
flags,
|
||||
session_info);
|
||||
} else {
|
||||
nt_status = auth_generate_simple_session_info(mem_ctx,
|
||||
server_info, session_info);
|
||||
|
@ -87,8 +87,14 @@ _PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
if (session_info) {
|
||||
uint32_t flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
|
||||
if (server_info->authenticated) {
|
||||
flags |= AUTH_SESSION_INFO_AUTHENTICATED;
|
||||
}
|
||||
nt_status = auth_context->generate_session_info(tmp_ctx, auth_context,
|
||||
server_info, session_info);
|
||||
server_info,
|
||||
flags,
|
||||
session_info);
|
||||
|
||||
if (NT_STATUS_IS_OK(nt_status)) {
|
||||
talloc_steal(mem_ctx, *session_info);
|
||||
|
@ -45,6 +45,7 @@ _PUBLIC_ struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx,
|
||||
_PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
|
||||
struct auth_context *auth_context,
|
||||
struct auth_serversupplied_info *server_info,
|
||||
uint32_t session_info_flags,
|
||||
struct auth_session_info **_session_info)
|
||||
{
|
||||
struct auth_session_info *session_info;
|
||||
@ -61,7 +62,6 @@ _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
|
||||
|
||||
struct dom_sid **groupSIDs = NULL;
|
||||
const struct dom_sid *dom_sid;
|
||||
bool is_enterprise_dc = false;
|
||||
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
|
||||
NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
|
||||
@ -82,7 +82,7 @@ _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
|
||||
dom_sid = samdb_domain_sid(auth_context->sam_ctx);
|
||||
if (dom_sid) {
|
||||
if (dom_sid_in_domain(dom_sid, server_info->account_sid)) {
|
||||
is_enterprise_dc = true;
|
||||
session_info_flags |= AUTH_SESSION_INFO_ENTERPRISE_DC;
|
||||
} else {
|
||||
DEBUG(2, ("DC %s is not in our domain. "
|
||||
"It will not have Enterprise Domain Controllers membership on this server",
|
||||
@ -201,8 +201,7 @@ _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
|
||||
server_info->primary_group_sid,
|
||||
num_groupSIDs,
|
||||
groupSIDs,
|
||||
server_info->authenticated,
|
||||
is_enterprise_dc,
|
||||
session_info_flags,
|
||||
&session_info->security_token);
|
||||
NT_STATUS_NOT_OK_RETURN_AND_FREE(nt_status, tmp_ctx);
|
||||
|
||||
|
@ -50,6 +50,7 @@ NTSTATUS auth_anonymous_server_info(TALLOC_CTX *mem_ctx,
|
||||
NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
|
||||
struct auth_context *auth_context,
|
||||
struct auth_serversupplied_info *server_info,
|
||||
uint32_t session_info_flags,
|
||||
struct auth_session_info **_session_info);
|
||||
|
||||
NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx,
|
||||
|
@ -36,12 +36,12 @@
|
||||
* @note Specialised version for system sessions that doesn't use the SAM.
|
||||
*/
|
||||
static NTSTATUS create_token(TALLOC_CTX *mem_ctx,
|
||||
struct dom_sid *user_sid,
|
||||
struct dom_sid *group_sid,
|
||||
unsigned int n_groupSIDs,
|
||||
struct dom_sid **groupSIDs,
|
||||
bool is_authenticated,
|
||||
struct security_token **token)
|
||||
struct dom_sid *user_sid,
|
||||
struct dom_sid *group_sid,
|
||||
unsigned int n_groupSIDs,
|
||||
struct dom_sid **groupSIDs,
|
||||
bool is_authenticated,
|
||||
struct security_token **token)
|
||||
{
|
||||
struct security_token *ptoken;
|
||||
unsigned int i;
|
||||
|
@ -149,6 +149,7 @@ static int construct_token_groups(struct ldb_module *module,
|
||||
ldb_module_oom(module);
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
} else if (!NT_STATUS_IS_OK(status)) {
|
||||
ldb_set_errstring(ldb, "Cannot provide tokenGroups attribute, could not create authContext");
|
||||
talloc_free(tmp_ctx);
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
@ -158,30 +159,29 @@ static int construct_token_groups(struct ldb_module *module,
|
||||
talloc_free(tmp_ctx);
|
||||
ldb_module_oom(module);
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
} else if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
|
||||
/* Not a user, we have no tokenGroups */
|
||||
talloc_free(tmp_ctx);
|
||||
return LDB_SUCCESS;
|
||||
} else if (!NT_STATUS_IS_OK(status)) {
|
||||
talloc_free(tmp_ctx);
|
||||
ldb_asprintf_errstring(ldb, "Cannot provide tokenGroups attribute: auth_get_server_info_principal failed: %s", nt_errstr(status));
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
status = auth_generate_session_info(tmp_ctx, auth_context, server_info, &session_info);
|
||||
status = auth_generate_session_info(tmp_ctx, auth_context, server_info, 0, &session_info);
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MEMORY)) {
|
||||
talloc_free(tmp_ctx);
|
||||
ldb_module_oom(module);
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
} else if (!NT_STATUS_IS_OK(status)) {
|
||||
talloc_free(tmp_ctx);
|
||||
ldb_asprintf_errstring(ldb, "Cannot provide tokenGroups attribute: auth_generate_session_info failed: %s", nt_errstr(status));
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
ret = samdb_msg_add_dom_sid(ldb, msg, msg,
|
||||
"tokenGroups",
|
||||
session_info->security_token->group_sid);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
talloc_free(tmp_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < session_info->security_token->num_sids; i++) {
|
||||
/* We start at 1, as the first SID is the user's SID, not included in the tokenGroups */
|
||||
for (i = 1; i < session_info->security_token->num_sids; i++) {
|
||||
ret = samdb_msg_add_dom_sid(ldb, msg, msg,
|
||||
"tokenGroups",
|
||||
session_info->security_token->sids[i]);
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "lib/events/events.h"
|
||||
#include "auth/credentials/credentials.h"
|
||||
#include "param/secrets.h"
|
||||
#include "auth/auth.h"
|
||||
|
||||
char *samdb_relative_path(struct ldb_context *ldb,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
@ -146,8 +147,7 @@ NTSTATUS security_token_create(TALLOC_CTX *mem_ctx,
|
||||
struct dom_sid *group_sid,
|
||||
unsigned int n_groupSIDs,
|
||||
struct dom_sid **groupSIDs,
|
||||
bool is_authenticated,
|
||||
bool is_dc,
|
||||
uint32_t session_info_flags,
|
||||
struct security_token **token)
|
||||
{
|
||||
struct security_token *ptoken;
|
||||
@ -157,36 +157,61 @@ NTSTATUS security_token_create(TALLOC_CTX *mem_ctx,
|
||||
ptoken = security_token_initialise(mem_ctx);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ptoken);
|
||||
|
||||
ptoken->sids = talloc_array(ptoken, struct dom_sid *, n_groupSIDs + 6);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
|
||||
|
||||
ptoken->user_sid = talloc_reference(ptoken, user_sid);
|
||||
ptoken->group_sid = talloc_reference(ptoken, group_sid);
|
||||
ptoken->privilege_mask = 0;
|
||||
|
||||
ptoken->sids = talloc_array(ptoken, struct dom_sid *, n_groupSIDs + 6 /* over-allocate */);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
|
||||
|
||||
ptoken->num_sids = 1;
|
||||
|
||||
ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid *, ptoken->num_sids + 1);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
|
||||
|
||||
ptoken->sids[0] = ptoken->user_sid;
|
||||
ptoken->sids[1] = ptoken->group_sid;
|
||||
ptoken->num_sids++;
|
||||
|
||||
/*
|
||||
* Finally add the "standard" SIDs.
|
||||
* The only difference between guest and "anonymous"
|
||||
* is the addition of Authenticated_Users.
|
||||
*/
|
||||
ptoken->sids[2] = dom_sid_parse_talloc(ptoken->sids, SID_WORLD);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[2]);
|
||||
ptoken->sids[3] = dom_sid_parse_talloc(ptoken->sids, SID_NT_NETWORK);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[3]);
|
||||
ptoken->num_sids = 4;
|
||||
|
||||
if (is_authenticated) {
|
||||
if (session_info_flags & AUTH_SESSION_INFO_DEFAULT_GROUPS) {
|
||||
ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid *, ptoken->num_sids + 1);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
|
||||
|
||||
ptoken->sids[ptoken->num_sids] = dom_sid_parse_talloc(ptoken->sids, SID_WORLD);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[ptoken->num_sids]);
|
||||
ptoken->num_sids++;
|
||||
|
||||
ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid *, ptoken->num_sids + 1);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
|
||||
|
||||
ptoken->sids[ptoken->num_sids] = dom_sid_parse_talloc(ptoken->sids, SID_NT_NETWORK);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[ptoken->num_sids]);
|
||||
ptoken->num_sids++;
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (session_info_flags & AUTH_SESSION_INFO_AUTHENTICATED) {
|
||||
ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid *, ptoken->num_sids + 1);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
|
||||
|
||||
ptoken->sids[ptoken->num_sids] = dom_sid_parse_talloc(ptoken->sids, SID_NT_AUTHENTICATED_USERS);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[4]);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[ptoken->num_sids]);
|
||||
ptoken->num_sids++;
|
||||
}
|
||||
|
||||
if (is_dc) {
|
||||
if (session_info_flags & AUTH_SESSION_INFO_ENTERPRISE_DC) {
|
||||
ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid *, ptoken->num_sids + 1);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
|
||||
|
||||
ptoken->sids[ptoken->num_sids] = dom_sid_parse_talloc(ptoken->sids, SID_NT_ENTERPRISE_DCS);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[4]);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[ptoken->num_sids]);
|
||||
ptoken->num_sids++;
|
||||
}
|
||||
|
||||
@ -201,7 +226,13 @@ NTSTATUS security_token_create(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
if (check_sid_idx == ptoken->num_sids) {
|
||||
ptoken->sids[ptoken->num_sids++] = talloc_reference(ptoken->sids, groupSIDs[i]);
|
||||
ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid *, ptoken->num_sids + 1);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
|
||||
|
||||
ptoken->sids[ptoken->num_sids] = talloc_reference(ptoken->sids, groupSIDs[i]);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[ptoken->num_sids]);
|
||||
ptoken->num_sids++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,15 +71,20 @@ static void sesssetup_old_send(struct tevent_req *subreq)
|
||||
struct auth_session_info *session_info;
|
||||
struct smbsrv_session *smb_sess;
|
||||
NTSTATUS status;
|
||||
uint32_t flags;
|
||||
|
||||
status = auth_check_password_recv(subreq, req, &server_info);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!NT_STATUS_IS_OK(status)) goto failed;
|
||||
|
||||
flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
|
||||
if (server_info->authenticated) {
|
||||
flags |= AUTH_SESSION_INFO_AUTHENTICATED;
|
||||
}
|
||||
/* This references server_info into session_info */
|
||||
status = req->smb_conn->negotiate.auth_context->generate_session_info(req,
|
||||
req->smb_conn->negotiate.auth_context,
|
||||
server_info, &session_info);
|
||||
server_info, flags, &session_info);
|
||||
if (!NT_STATUS_IS_OK(status)) goto failed;
|
||||
|
||||
/* allocate a new session */
|
||||
@ -196,16 +201,23 @@ static void sesssetup_nt1_send(struct tevent_req *subreq)
|
||||
struct auth_session_info *session_info;
|
||||
struct smbsrv_session *smb_sess;
|
||||
|
||||
uint32_t flags;
|
||||
NTSTATUS status;
|
||||
|
||||
status = auth_check_password_recv(subreq, req, &server_info);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!NT_STATUS_IS_OK(status)) goto failed;
|
||||
|
||||
flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
|
||||
if (server_info->authenticated) {
|
||||
flags |= AUTH_SESSION_INFO_AUTHENTICATED;
|
||||
}
|
||||
|
||||
/* This references server_info into session_info */
|
||||
status = state->auth_context->generate_session_info(req,
|
||||
state->auth_context,
|
||||
server_info,
|
||||
flags,
|
||||
&session_info);
|
||||
if (!NT_STATUS_IS_OK(status)) goto failed;
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "libcli/raw/smb.h"
|
||||
#include "auth/credentials/credentials.h"
|
||||
#include "auth/credentials/credentials_krb5.h"
|
||||
#include "libcli/security/dom_sid.h"
|
||||
|
||||
struct named_pipe_socket {
|
||||
const char *pipe_name;
|
||||
@ -164,6 +165,8 @@ static void named_pipe_auth_request(struct tevent_req *subreq)
|
||||
struct named_pipe_auth_req pipe_request;
|
||||
struct named_pipe_auth_rep pipe_reply;
|
||||
struct auth_context *auth_context;
|
||||
uint32_t session_flags = 0;
|
||||
struct dom_sid *anonymous_sid;
|
||||
NTSTATUS status;
|
||||
int ret;
|
||||
|
||||
@ -264,11 +267,23 @@ static void named_pipe_auth_request(struct tevent_req *subreq)
|
||||
goto reply;
|
||||
}
|
||||
|
||||
anonymous_sid = dom_sid_parse_talloc(auth_context, SID_NT_ANONYMOUS);
|
||||
if (anonymous_sid == NULL) {
|
||||
named_pipe_terminate_connection(pipe_conn, "Failed to parse Anonymous SID ");
|
||||
talloc_free(auth_context);
|
||||
return;
|
||||
}
|
||||
|
||||
session_flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
|
||||
if (!dom_sid_equal(anonymous_sid, server_info->account_sid)) {
|
||||
session_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
|
||||
}
|
||||
|
||||
/* setup the session_info on the connection */
|
||||
pipe_reply.status = auth_context->generate_session_info(conn,
|
||||
auth_context,
|
||||
server_info,
|
||||
session_flags,
|
||||
&conn->session_info);
|
||||
talloc_free(auth_context);
|
||||
if (!NT_STATUS_IS_OK(pipe_reply.status)) {
|
||||
@ -315,9 +330,22 @@ static void named_pipe_auth_request(struct tevent_req *subreq)
|
||||
goto reply;
|
||||
}
|
||||
|
||||
anonymous_sid = dom_sid_parse_talloc(auth_context, SID_NT_ANONYMOUS);
|
||||
if (anonymous_sid == NULL) {
|
||||
named_pipe_terminate_connection(pipe_conn, "Failed to parse Anonymous SID ");
|
||||
talloc_free(auth_context);
|
||||
return;
|
||||
}
|
||||
|
||||
session_flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
|
||||
if (!dom_sid_equal(anonymous_sid, server_info->account_sid)) {
|
||||
session_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
|
||||
}
|
||||
|
||||
pipe_reply.status = auth_context->generate_session_info(conn,
|
||||
auth_context,
|
||||
server_info,
|
||||
session_flags,
|
||||
&conn->session_info);
|
||||
talloc_free(auth_context);
|
||||
if (!NT_STATUS_IS_OK(pipe_reply.status)) {
|
||||
@ -405,10 +433,23 @@ static void named_pipe_auth_request(struct tevent_req *subreq)
|
||||
goto reply;
|
||||
}
|
||||
|
||||
anonymous_sid = dom_sid_parse_talloc(auth_context, SID_NT_ANONYMOUS);
|
||||
if (anonymous_sid == NULL) {
|
||||
named_pipe_terminate_connection(pipe_conn, "Failed to parse Anonymous SID ");
|
||||
talloc_free(auth_context);
|
||||
return;
|
||||
}
|
||||
|
||||
session_flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
|
||||
if (!dom_sid_equal(anonymous_sid, server_info->account_sid)) {
|
||||
session_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
|
||||
}
|
||||
|
||||
/* setup the session_info on the connection */
|
||||
pipe_reply.status = auth_context->generate_session_info(conn,
|
||||
auth_context,
|
||||
server_info,
|
||||
session_flags,
|
||||
&conn->session_info);
|
||||
talloc_free(auth_context);
|
||||
if (!NT_STATUS_IS_OK(pipe_reply.status)) {
|
||||
|
Loading…
Reference in New Issue
Block a user