X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source4%2Fauth%2Fsystem_session.c;h=3b9edd779df7a466909ff6af1535d0a594ba6c3e;hb=80509dffdb7ebaa57e05589a9a896bf9a57a00e7;hp=affce26d2ed9318b3399331cddc7353f32b73449;hpb=7e298580e06a5b9a0c1210937af47f277849080e;p=samba.git diff --git a/source4/auth/system_session.c b/source4/auth/system_session.c index affce26d2ed..3b9edd779df 100644 --- a/source4/auth/system_session.c +++ b/source4/auth/system_session.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. Authentication utility functions Copyright (C) Andrew Tridgell 1992-1998 - Copyright (C) Andrew Bartlett 2001 + Copyright (C) Andrew Bartlett 2001-2010 Copyright (C) Jeremy Allison 2000-2001 Copyright (C) Rafal Szczesniak 2002 Copyright (C) Stefan Metzmacher 2005 @@ -23,163 +23,305 @@ #include "includes.h" #include "libcli/security/security.h" -#include "libcli/auth/libcli_auth.h" #include "auth/credentials/credentials.h" #include "param/param.h" -#include "auth/auth.h" /* for auth_serversupplied_info */ +#include "auth/auth.h" /* for auth_user_info_dc */ #include "auth/session.h" #include "auth/system_session_proto.h" -/** - * Create the SID list for this user. - * - * @note Specialised version for system sessions that doesn't use the SAM. + +/* + prevent the static system session being freed */ -static NTSTATUS create_token(TALLOC_CTX *mem_ctx, - struct dom_sid *user_sid, - struct dom_sid *group_sid, - int n_groupSIDs, - struct dom_sid **groupSIDs, - bool is_authenticated, - struct security_token **token) +static int system_session_destructor(struct auth_session_info *info) { - struct security_token *ptoken; - int i; - - ptoken = security_token_initialise(mem_ctx); - NT_STATUS_HAVE_NO_MEMORY(ptoken); - - ptoken->sids = talloc_array(ptoken, struct dom_sid *, n_groupSIDs + 5); - 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[0] = ptoken->user_sid; - ptoken->sids[1] = ptoken->group_sid; - - /* - * 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) { - ptoken->sids[4] = dom_sid_parse_talloc(ptoken->sids, SID_NT_AUTHENTICATED_USERS); - NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[4]); - ptoken->num_sids++; - } + return -1; +} - for (i = 0; i < n_groupSIDs; i++) { - size_t check_sid_idx; - for (check_sid_idx = 1; - check_sid_idx < ptoken->num_sids; - check_sid_idx++) { - if (dom_sid_equal(ptoken->sids[check_sid_idx], groupSIDs[i])) { - break; - } - } - - if (check_sid_idx == ptoken->num_sids) { - ptoken->sids[ptoken->num_sids++] = talloc_reference(ptoken->sids, groupSIDs[i]); - } +/* Create a security token for a session SYSTEM (the most + * trusted/prvilaged account), including the local machine account as + * the off-host credentials + */ +_PUBLIC_ struct auth_session_info *system_session(struct loadparm_context *lp_ctx) +{ + static struct auth_session_info *static_session; + NTSTATUS nt_status; + + if (static_session) { + return static_session; } - *token = ptoken; + nt_status = auth_system_session_info(talloc_autofree_context(), + lp_ctx, + &static_session); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(static_session); + static_session = NULL; + return NULL; + } + talloc_set_destructor(static_session, system_session_destructor); + return static_session; +} - /* Shortcuts to prevent recursion and avoid lookups */ - if (ptoken->user_sid == NULL) { - ptoken->privilege_mask = 0; - return NT_STATUS_OK; - } - - if (security_token_is_system(ptoken)) { - ptoken->privilege_mask = ~0; - return NT_STATUS_OK; - } +NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx, + struct loadparm_context *lp_ctx, + struct auth_session_info **_session_info) +{ + NTSTATUS nt_status; + struct auth_user_info_dc *user_info_dc = NULL; + struct auth_session_info *session_info = NULL; + TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); - if (security_token_is_anonymous(ptoken)) { - ptoken->privilege_mask = 0; - return NT_STATUS_OK; + nt_status = auth_system_user_info_dc(mem_ctx, lpcfg_netbios_name(lp_ctx), + &user_info_dc); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(mem_ctx); + return nt_status; + } + + /* references the user_info_dc into the session_info */ + nt_status = auth_generate_session_info(parent_ctx, NULL, NULL, user_info_dc, AUTH_SESSION_INFO_SIMPLE_PRIVILEGES, &session_info); + talloc_free(mem_ctx); + + NT_STATUS_NOT_OK_RETURN(nt_status); + + session_info->credentials = cli_credentials_init(session_info); + if (!session_info->credentials) { + return NT_STATUS_NO_MEMORY; } - DEBUG(0, ("Created token was not system or anonymous token!")); - *token = NULL; - return NT_STATUS_INTERNAL_ERROR; + cli_credentials_set_conf(session_info->credentials, lp_ctx); + + cli_credentials_set_machine_account_pending(session_info->credentials, lp_ctx); + *_session_info = session_info; + + return NT_STATUS_OK; } -static NTSTATUS generate_session_info(TALLOC_CTX *mem_ctx, - struct auth_serversupplied_info *server_info, - struct auth_session_info **_session_info) +NTSTATUS auth_system_user_info_dc(TALLOC_CTX *mem_ctx, const char *netbios_name, + struct auth_user_info_dc **_user_info_dc) { - struct auth_session_info *session_info; - NTSTATUS nt_status; + struct auth_user_info_dc *user_info_dc; + struct auth_user_info *info; - session_info = talloc(mem_ctx, struct auth_session_info); - NT_STATUS_HAVE_NO_MEMORY(session_info); + user_info_dc = talloc(mem_ctx, struct auth_user_info_dc); + NT_STATUS_HAVE_NO_MEMORY(user_info_dc); - session_info->server_info = talloc_reference(session_info, server_info); + /* This returns a pointer to a struct dom_sid, which is the + * same as a 1 element list of struct dom_sid */ + user_info_dc->num_sids = 1; + user_info_dc->sids = dom_sid_parse_talloc(user_info_dc, SID_NT_SYSTEM); + NT_STATUS_HAVE_NO_MEMORY(user_info_dc->sids); - /* unless set otherwise, the session key is the user session - * key from the auth subsystem */ - session_info->session_key = server_info->user_session_key; + /* annoying, but the Anonymous really does have a session key, + and it is all zeros! */ + user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16); + NT_STATUS_HAVE_NO_MEMORY(user_info_dc->user_session_key.data); - nt_status = create_token(session_info, - server_info->account_sid, - server_info->primary_group_sid, - server_info->n_domain_groups, - server_info->domain_groups, - server_info->authenticated, - &session_info->security_token); - NT_STATUS_NOT_OK_RETURN(nt_status); + user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16); + NT_STATUS_HAVE_NO_MEMORY(user_info_dc->lm_session_key.data); - session_info->credentials = NULL; + data_blob_clear(&user_info_dc->user_session_key); + data_blob_clear(&user_info_dc->lm_session_key); + + user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info); + NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info); + + info->account_name = talloc_strdup(info, "SYSTEM"); + NT_STATUS_HAVE_NO_MEMORY(info->account_name); + + info->domain_name = talloc_strdup(info, "NT AUTHORITY"); + NT_STATUS_HAVE_NO_MEMORY(info->domain_name); + + info->full_name = talloc_strdup(info, "System"); + NT_STATUS_HAVE_NO_MEMORY(info->full_name); + + info->logon_script = talloc_strdup(info, ""); + NT_STATUS_HAVE_NO_MEMORY(info->logon_script); + + info->profile_path = talloc_strdup(info, ""); + NT_STATUS_HAVE_NO_MEMORY(info->profile_path); + + info->home_directory = talloc_strdup(info, ""); + NT_STATUS_HAVE_NO_MEMORY(info->home_directory); + + info->home_drive = talloc_strdup(info, ""); + NT_STATUS_HAVE_NO_MEMORY(info->home_drive); + + info->logon_server = talloc_strdup(info, netbios_name); + NT_STATUS_HAVE_NO_MEMORY(info->logon_server); + + info->last_logon = 0; + info->last_logoff = 0; + info->acct_expiry = 0; + info->last_password_change = 0; + info->allow_password_change = 0; + info->force_password_change = 0; + + info->logon_count = 0; + info->bad_password_count = 0; + + info->acct_flags = ACB_NORMAL; + + info->authenticated = true; + + *_user_info_dc = user_info_dc; - *_session_info = session_info; return NT_STATUS_OK; } +static NTSTATUS auth_domain_admin_user_info_dc(TALLOC_CTX *mem_ctx, + const char *netbios_name, + const char *domain_name, + struct dom_sid *domain_sid, + struct auth_user_info_dc **_user_info_dc) +{ + struct auth_user_info_dc *user_info_dc; + struct auth_user_info *info; -/** - Create a system session, with machine account credentials -*/ -_PUBLIC_ struct auth_session_info *system_session(TALLOC_CTX *mem_ctx) + user_info_dc = talloc(mem_ctx, struct auth_user_info_dc); + NT_STATUS_HAVE_NO_MEMORY(user_info_dc); + + user_info_dc->num_sids = 7; + user_info_dc->sids = talloc_array(user_info_dc, struct dom_sid, user_info_dc->num_sids); + + user_info_dc->sids[PRIMARY_USER_SID_INDEX] = *domain_sid; + sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX], DOMAIN_RID_ADMINISTRATOR); + + user_info_dc->sids[PRIMARY_GROUP_SID_INDEX] = *domain_sid; + sid_append_rid(&user_info_dc->sids[PRIMARY_GROUP_SID_INDEX], DOMAIN_RID_USERS); + + user_info_dc->sids[2] = global_sid_Builtin_Administrators; + + user_info_dc->sids[3] = *domain_sid; + sid_append_rid(&user_info_dc->sids[3], DOMAIN_RID_ADMINS); + user_info_dc->sids[4] = *domain_sid; + sid_append_rid(&user_info_dc->sids[4], DOMAIN_RID_ENTERPRISE_ADMINS); + user_info_dc->sids[5] = *domain_sid; + sid_append_rid(&user_info_dc->sids[5], DOMAIN_RID_POLICY_ADMINS); + user_info_dc->sids[6] = *domain_sid; + sid_append_rid(&user_info_dc->sids[6], DOMAIN_RID_SCHEMA_ADMINS); + + /* What should the session key be?*/ + user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16); + NT_STATUS_HAVE_NO_MEMORY(user_info_dc->user_session_key.data); + + user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16); + NT_STATUS_HAVE_NO_MEMORY(user_info_dc->lm_session_key.data); + + data_blob_clear(&user_info_dc->user_session_key); + data_blob_clear(&user_info_dc->lm_session_key); + + user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info); + NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info); + + info->account_name = talloc_strdup(info, "Administrator"); + NT_STATUS_HAVE_NO_MEMORY(info->account_name); + + info->domain_name = talloc_strdup(info, domain_name); + NT_STATUS_HAVE_NO_MEMORY(info->domain_name); + + info->full_name = talloc_strdup(info, "Administrator"); + NT_STATUS_HAVE_NO_MEMORY(info->full_name); + + info->logon_script = talloc_strdup(info, ""); + NT_STATUS_HAVE_NO_MEMORY(info->logon_script); + + info->profile_path = talloc_strdup(info, ""); + NT_STATUS_HAVE_NO_MEMORY(info->profile_path); + + info->home_directory = talloc_strdup(info, ""); + NT_STATUS_HAVE_NO_MEMORY(info->home_directory); + + info->home_drive = talloc_strdup(info, ""); + NT_STATUS_HAVE_NO_MEMORY(info->home_drive); + + info->logon_server = talloc_strdup(info, netbios_name); + NT_STATUS_HAVE_NO_MEMORY(info->logon_server); + + info->last_logon = 0; + info->last_logoff = 0; + info->acct_expiry = 0; + info->last_password_change = 0; + info->allow_password_change = 0; + info->force_password_change = 0; + + info->logon_count = 0; + info->bad_password_count = 0; + + info->acct_flags = ACB_NORMAL; + + info->authenticated = true; + + *_user_info_dc = user_info_dc; + + return NT_STATUS_OK; +} + +static NTSTATUS auth_domain_admin_session_info(TALLOC_CTX *parent_ctx, + struct loadparm_context *lp_ctx, + struct dom_sid *domain_sid, + struct auth_session_info **session_info) +{ + NTSTATUS nt_status; + struct auth_user_info_dc *user_info_dc = NULL; + TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); + + NT_STATUS_HAVE_NO_MEMORY(mem_ctx); + + nt_status = auth_domain_admin_user_info_dc(mem_ctx, lpcfg_netbios_name(lp_ctx), + lpcfg_workgroup(lp_ctx), domain_sid, + &user_info_dc); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(mem_ctx); + return nt_status; + } + + nt_status = auth_generate_session_info(mem_ctx, NULL, NULL, user_info_dc, + AUTH_SESSION_INFO_SIMPLE_PRIVILEGES|AUTH_SESSION_INFO_AUTHENTICATED|AUTH_SESSION_INFO_DEFAULT_GROUPS, + session_info); + /* There is already a reference between the sesion_info and user_info_dc */ + if (NT_STATUS_IS_OK(nt_status)) { + talloc_steal(parent_ctx, *session_info); + } + talloc_free(mem_ctx); + return nt_status; +} + +_PUBLIC_ struct auth_session_info *admin_session(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct dom_sid *domain_sid) { NTSTATUS nt_status; struct auth_session_info *session_info = NULL; - nt_status = auth_system_session_info(mem_ctx, - &session_info); + nt_status = auth_domain_admin_session_info(mem_ctx, + lp_ctx, + domain_sid, + &session_info); if (!NT_STATUS_IS_OK(nt_status)) { return NULL; } return session_info; } -static NTSTATUS _auth_system_session_info(TALLOC_CTX *parent_ctx, - bool anonymous_credentials, - struct auth_session_info **_session_info) +_PUBLIC_ NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx, + struct loadparm_context *lp_ctx, + struct auth_session_info **_session_info) { NTSTATUS nt_status; - struct auth_serversupplied_info *server_info = NULL; + struct auth_user_info_dc *user_info_dc = NULL; struct auth_session_info *session_info = NULL; TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); - nt_status = auth_system_server_info(mem_ctx, lp_netbios_name(global_loadparm), - &server_info); + nt_status = auth_anonymous_user_info_dc(mem_ctx, + lpcfg_netbios_name(lp_ctx), + &user_info_dc); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; } - /* references the server_info into the session_info */ - nt_status = generate_session_info(parent_ctx, server_info, &session_info); + /* references the user_info_dc into the session_info */ + nt_status = auth_generate_session_info(parent_ctx, NULL, NULL, user_info_dc, AUTH_SESSION_INFO_SIMPLE_PRIVILEGES, &session_info); talloc_free(mem_ctx); NT_STATUS_NOT_OK_RETURN(nt_status); @@ -189,111 +331,83 @@ static NTSTATUS _auth_system_session_info(TALLOC_CTX *parent_ctx, return NT_STATUS_NO_MEMORY; } - cli_credentials_set_conf(session_info->credentials, global_loadparm); - - if (anonymous_credentials) { - cli_credentials_set_anonymous(session_info->credentials); - } else { - cli_credentials_set_machine_account_pending(session_info->credentials); - } + cli_credentials_set_conf(session_info->credentials, lp_ctx); + cli_credentials_set_anonymous(session_info->credentials); + *_session_info = session_info; return NT_STATUS_OK; } -/* - Create a system session, but with anonymous credentials (so we do not need to open secrets.ldb) -*/ -_PUBLIC_ struct auth_session_info *system_session_anon(TALLOC_CTX *mem_ctx) +_PUBLIC_ NTSTATUS auth_anonymous_user_info_dc(TALLOC_CTX *mem_ctx, + const char *netbios_name, + struct auth_user_info_dc **_user_info_dc) { - NTSTATUS nt_status; - struct auth_session_info *session_info = NULL; - nt_status = _auth_system_session_info(mem_ctx, false, &session_info); - if (!NT_STATUS_IS_OK(nt_status)) { - return NULL; - } - return session_info; -} - - - -_PUBLIC_ NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx, - struct auth_session_info **_session_info) -{ - return _auth_system_session_info(parent_ctx, - lp_parm_bool(global_loadparm, NULL, "system", "anonymous", false), - _session_info); -} + struct auth_user_info_dc *user_info_dc; + struct auth_user_info *info; + user_info_dc = talloc(mem_ctx, struct auth_user_info_dc); + NT_STATUS_HAVE_NO_MEMORY(user_info_dc); -NTSTATUS auth_system_server_info(TALLOC_CTX *mem_ctx, const char *netbios_name, - struct auth_serversupplied_info **_server_info) -{ - struct auth_serversupplied_info *server_info; - server_info = talloc(mem_ctx, struct auth_serversupplied_info); - NT_STATUS_HAVE_NO_MEMORY(server_info); + /* This returns a pointer to a struct dom_sid, which is the + * same as a 1 element list of struct dom_sid */ + user_info_dc->num_sids = 1; + user_info_dc->sids = dom_sid_parse_talloc(user_info_dc, SID_NT_ANONYMOUS); + NT_STATUS_HAVE_NO_MEMORY(user_info_dc->sids); - server_info->account_sid = dom_sid_parse_talloc(server_info, SID_NT_SYSTEM); - NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid); + /* annoying, but the Anonymous really does have a session key... */ + user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16); + NT_STATUS_HAVE_NO_MEMORY(user_info_dc->user_session_key.data); - /* is this correct? */ - server_info->primary_group_sid = dom_sid_parse_talloc(server_info, SID_BUILTIN_ADMINISTRATORS); - NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid); + user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16); + NT_STATUS_HAVE_NO_MEMORY(user_info_dc->lm_session_key.data); - server_info->n_domain_groups = 0; - server_info->domain_groups = NULL; + /* and it is all zeros! */ + data_blob_clear(&user_info_dc->user_session_key); + data_blob_clear(&user_info_dc->lm_session_key); - /* annoying, but the Anonymous really does have a session key, - and it is all zeros! */ - server_info->user_session_key = data_blob_talloc(server_info, NULL, 16); - NT_STATUS_HAVE_NO_MEMORY(server_info->user_session_key.data); + user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info); + NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info); - server_info->lm_session_key = data_blob_talloc(server_info, NULL, 16); - NT_STATUS_HAVE_NO_MEMORY(server_info->lm_session_key.data); + info->account_name = talloc_strdup(info, "ANONYMOUS LOGON"); + NT_STATUS_HAVE_NO_MEMORY(info->account_name); - data_blob_clear(&server_info->user_session_key); - data_blob_clear(&server_info->lm_session_key); + info->domain_name = talloc_strdup(info, "NT AUTHORITY"); + NT_STATUS_HAVE_NO_MEMORY(info->domain_name); - server_info->account_name = talloc_strdup(server_info, "SYSTEM"); - NT_STATUS_HAVE_NO_MEMORY(server_info->account_name); + info->full_name = talloc_strdup(info, "Anonymous Logon"); + NT_STATUS_HAVE_NO_MEMORY(info->full_name); - server_info->domain_name = talloc_strdup(server_info, "NT AUTHORITY"); - NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name); + info->logon_script = talloc_strdup(info, ""); + NT_STATUS_HAVE_NO_MEMORY(info->logon_script); - server_info->full_name = talloc_strdup(server_info, "System"); - NT_STATUS_HAVE_NO_MEMORY(server_info->full_name); + info->profile_path = talloc_strdup(info, ""); + NT_STATUS_HAVE_NO_MEMORY(info->profile_path); - server_info->logon_script = talloc_strdup(server_info, ""); - NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script); + info->home_directory = talloc_strdup(info, ""); + NT_STATUS_HAVE_NO_MEMORY(info->home_directory); - server_info->profile_path = talloc_strdup(server_info, ""); - NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path); + info->home_drive = talloc_strdup(info, ""); + NT_STATUS_HAVE_NO_MEMORY(info->home_drive); - server_info->home_directory = talloc_strdup(server_info, ""); - NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory); + info->logon_server = talloc_strdup(info, netbios_name); + NT_STATUS_HAVE_NO_MEMORY(info->logon_server); - server_info->home_drive = talloc_strdup(server_info, ""); - NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive); + info->last_logon = 0; + info->last_logoff = 0; + info->acct_expiry = 0; + info->last_password_change = 0; + info->allow_password_change = 0; + info->force_password_change = 0; - server_info->logon_server = talloc_strdup(server_info, netbios_name); - NT_STATUS_HAVE_NO_MEMORY(server_info->logon_server); + info->logon_count = 0; + info->bad_password_count = 0; - server_info->last_logon = 0; - server_info->last_logoff = 0; - server_info->acct_expiry = 0; - server_info->last_password_change = 0; - server_info->allow_password_change = 0; - server_info->force_password_change = 0; + info->acct_flags = ACB_NORMAL; - server_info->logon_count = 0; - server_info->bad_password_count = 0; + info->authenticated = false; - server_info->acct_flags = ACB_NORMAL; - - server_info->authenticated = true; - - *_server_info = server_info; + *_user_info_dc = user_info_dc; return NT_STATUS_OK; } -