Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/auth/session.c

    r414 r740  
    33   Authentication utility functions
    44   Copyright (C) Andrew Tridgell 1992-1998
    5    Copyright (C) Andrew Bartlett 2001
     5   Copyright (C) Andrew Bartlett 2001-2010
    66   Copyright (C) Jeremy Allison 2000-2001
    77   Copyright (C) Rafal Szczesniak 2002
     
    2424#include "includes.h"
    2525#include "auth/auth.h"
     26#include "auth/auth_sam.h"
     27#include "auth/credentials/credentials.h"
     28#include "auth/credentials/credentials_krb5.h"
    2629#include "libcli/security/security.h"
    2730#include "libcli/auth/libcli_auth.h"
    2831#include "dsdb/samdb/samdb.h"
    29 #include "auth/credentials/credentials.h"
    30 #include "param/param.h"
    3132#include "auth/session_proto.h"
     33#include "system/kerberos.h"
     34#include <gssapi/gssapi.h>
    3235
    3336_PUBLIC_ struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx,
    34                                             struct tevent_context *event_ctx,
    35                                             struct loadparm_context *lp_ctx)
     37                                            struct loadparm_context *lp_ctx)
    3638{
    3739        NTSTATUS nt_status;
    3840        struct auth_session_info *session_info = NULL;
    39         nt_status = auth_anonymous_session_info(mem_ctx, event_ctx, lp_ctx, &session_info);
     41        nt_status = auth_anonymous_session_info(mem_ctx, lp_ctx, &session_info);
    4042        if (!NT_STATUS_IS_OK(nt_status)) {
    4143                return NULL;
     
    4446}
    4547
    46 _PUBLIC_ NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx,
    47                                      struct tevent_context *event_ctx,
    48                                      struct loadparm_context *lp_ctx,
    49                                      struct auth_session_info **_session_info)
    50 {
    51         NTSTATUS nt_status;
    52         struct auth_serversupplied_info *server_info = NULL;
    53         struct auth_session_info *session_info = NULL;
    54         TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
    55        
    56         nt_status = auth_anonymous_server_info(mem_ctx,
    57                                                lp_netbios_name(lp_ctx),
    58                                                &server_info);
    59         if (!NT_STATUS_IS_OK(nt_status)) {
    60                 talloc_free(mem_ctx);
    61                 return nt_status;
    62         }
    63 
    64         /* references the server_info into the session_info */
    65         nt_status = auth_generate_session_info(parent_ctx, event_ctx, lp_ctx, server_info, &session_info);
    66         talloc_free(mem_ctx);
    67 
    68         NT_STATUS_NOT_OK_RETURN(nt_status);
    69 
    70         session_info->credentials = cli_credentials_init(session_info);
    71         if (!session_info->credentials) {
    72                 return NT_STATUS_NO_MEMORY;
    73         }
    74 
    75         cli_credentials_set_conf(session_info->credentials, lp_ctx);
    76         cli_credentials_set_anonymous(session_info->credentials);
    77        
    78         *_session_info = session_info;
    79 
    80         return NT_STATUS_OK;
    81 }
    82 
    83 _PUBLIC_ NTSTATUS auth_anonymous_server_info(TALLOC_CTX *mem_ctx,
    84                                     const char *netbios_name,
    85                                     struct auth_serversupplied_info **_server_info)
    86 {
    87         struct auth_serversupplied_info *server_info;
    88         server_info = talloc(mem_ctx, struct auth_serversupplied_info);
    89         NT_STATUS_HAVE_NO_MEMORY(server_info);
    90 
    91         server_info->account_sid = dom_sid_parse_talloc(server_info, SID_NT_ANONYMOUS);
    92         NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid);
    93 
    94         /* is this correct? */
    95         server_info->primary_group_sid = dom_sid_parse_talloc(server_info, SID_BUILTIN_GUESTS);
    96         NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid);
    97 
    98         server_info->n_domain_groups = 0;
    99         server_info->domain_groups = NULL;
    100 
    101         /* annoying, but the Anonymous really does have a session key... */
    102         server_info->user_session_key = data_blob_talloc(server_info, NULL, 16);
    103         NT_STATUS_HAVE_NO_MEMORY(server_info->user_session_key.data);
    104 
    105         server_info->lm_session_key = data_blob_talloc(server_info, NULL, 16);
    106         NT_STATUS_HAVE_NO_MEMORY(server_info->lm_session_key.data);
    107 
    108         /*  and it is all zeros! */
    109         data_blob_clear(&server_info->user_session_key);
    110         data_blob_clear(&server_info->lm_session_key);
    111 
    112         server_info->account_name = talloc_strdup(server_info, "ANONYMOUS LOGON");
    113         NT_STATUS_HAVE_NO_MEMORY(server_info->account_name);
    114 
    115         server_info->domain_name = talloc_strdup(server_info, "NT AUTHORITY");
    116         NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
    117 
    118         server_info->full_name = talloc_strdup(server_info, "Anonymous Logon");
    119         NT_STATUS_HAVE_NO_MEMORY(server_info->full_name);
    120 
    121         server_info->logon_script = talloc_strdup(server_info, "");
    122         NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script);
    123 
    124         server_info->profile_path = talloc_strdup(server_info, "");
    125         NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path);
    126 
    127         server_info->home_directory = talloc_strdup(server_info, "");
    128         NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory);
    129 
    130         server_info->home_drive = talloc_strdup(server_info, "");
    131         NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive);
    132 
    133         server_info->logon_server = talloc_strdup(server_info, netbios_name);
    134         NT_STATUS_HAVE_NO_MEMORY(server_info->logon_server);
    135 
    136         server_info->last_logon = 0;
    137         server_info->last_logoff = 0;
    138         server_info->acct_expiry = 0;
    139         server_info->last_password_change = 0;
    140         server_info->allow_password_change = 0;
    141         server_info->force_password_change = 0;
    142 
    143         server_info->logon_count = 0;
    144         server_info->bad_password_count = 0;
    145 
    146         server_info->acct_flags = ACB_NORMAL;
    147 
    148         server_info->authenticated = false;
    149 
    150         *_server_info = server_info;
    151 
    152         return NT_STATUS_OK;
    153 }
    154 
    155 _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
    156                                     struct tevent_context *event_ctx,
    157                                     struct loadparm_context *lp_ctx,
    158                                     struct auth_serversupplied_info *server_info,
    159                                     struct auth_session_info **_session_info)
     48_PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
     49                                             struct loadparm_context *lp_ctx, /* Optional, if you don't want privilages */
     50                                             struct ldb_context *sam_ctx, /* Optional, if you don't want local groups */
     51                                             struct auth_user_info_dc *user_info_dc,
     52                                             uint32_t session_info_flags,
     53                                             struct auth_session_info **_session_info)
    16054{
    16155        struct auth_session_info *session_info;
    16256        NTSTATUS nt_status;
    163 
    164         session_info = talloc(mem_ctx, struct auth_session_info);
    165         NT_STATUS_HAVE_NO_MEMORY(session_info);
    166 
    167         session_info->server_info = talloc_reference(session_info, server_info);
     57        unsigned int i, num_sids = 0;
     58
     59        const char *filter;
     60
     61        struct dom_sid *sids = NULL;
     62        const struct dom_sid *anonymous_sid, *system_sid;
     63
     64        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     65        NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
     66
     67        session_info = talloc(tmp_ctx, struct auth_session_info);
     68        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info, tmp_ctx);
     69
     70        session_info->info = talloc_reference(session_info, user_info_dc->info);
     71
     72        session_info->torture = talloc_zero(session_info, struct auth_user_info_torture);
     73        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->torture, tmp_ctx);
     74        session_info->torture->num_dc_sids = user_info_dc->num_sids;
     75        session_info->torture->dc_sids = talloc_reference(session_info, user_info_dc->sids);
     76        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->torture->dc_sids, tmp_ctx);
    16877
    16978        /* unless set otherwise, the session key is the user session
    17079         * key from the auth subsystem */
    171         session_info->session_key = server_info->user_session_key;
     80        session_info->session_key = data_blob_talloc(session_info, user_info_dc->user_session_key.data, user_info_dc->user_session_key.length);
     81        if (!session_info->session_key.data && session_info->session_key.length) {
     82                NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->session_key.data, tmp_ctx);
     83        }
     84
     85        anonymous_sid = dom_sid_parse_talloc(tmp_ctx, SID_NT_ANONYMOUS);
     86        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(anonymous_sid, tmp_ctx);
     87
     88        system_sid = dom_sid_parse_talloc(tmp_ctx, SID_NT_SYSTEM);
     89        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(system_sid, tmp_ctx);
     90
     91        sids = talloc_array(tmp_ctx, struct dom_sid, user_info_dc->num_sids);
     92        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sids, tmp_ctx);
     93        if (!sids) {
     94                talloc_free(tmp_ctx);
     95                return NT_STATUS_NO_MEMORY;
     96        }
     97
     98        num_sids = user_info_dc->num_sids;
     99
     100        for (i=0; i < user_info_dc->num_sids; i++) {
     101                sids[i] = user_info_dc->sids[i];
     102        }
     103
     104        if (user_info_dc->num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(anonymous_sid, &user_info_dc->sids[PRIMARY_USER_SID_INDEX])) {
     105                /* Don't expand nested groups of system, anonymous etc*/
     106        } else if (user_info_dc->num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(system_sid, &user_info_dc->sids[PRIMARY_USER_SID_INDEX])) {
     107                /* Don't expand nested groups of system, anonymous etc*/
     108        } else if (sam_ctx) {
     109                filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
     110                                         GROUP_TYPE_BUILTIN_LOCAL_GROUP);
     111
     112                /* Search for each group in the token */
     113                for (i = 0; i < user_info_dc->num_sids; i++) {
     114                        char *sid_string;
     115                        const char *sid_dn;
     116                        DATA_BLOB sid_blob;
     117                       
     118                        sid_string = dom_sid_string(tmp_ctx,
     119                                                      &user_info_dc->sids[i]);
     120                        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, user_info_dc);
     121                       
     122                        sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
     123                        talloc_free(sid_string);
     124                        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, user_info_dc);
     125                        sid_blob = data_blob_string_const(sid_dn);
     126                       
     127                        /* This function takes in memberOf values and expands
     128                         * them, as long as they meet the filter - so only
     129                         * builtin groups
     130                         *
     131                         * We already have the SID in the token, so set
     132                         * 'only childs' flag to true */
     133                        nt_status = dsdb_expand_nested_groups(sam_ctx, &sid_blob, true, filter,
     134                                                              tmp_ctx, &sids, &num_sids);
     135                        if (!NT_STATUS_IS_OK(nt_status)) {
     136                                talloc_free(tmp_ctx);
     137                                return nt_status;
     138                        }
     139                }
     140        }
    172141
    173142        nt_status = security_token_create(session_info,
    174                                           event_ctx,
    175143                                          lp_ctx,
    176                                           server_info->account_sid,
    177                                           server_info->primary_group_sid,
    178                                           server_info->n_domain_groups,
    179                                           server_info->domain_groups,
    180                                           server_info->authenticated,
     144                                          num_sids,
     145                                          sids,
     146                                          session_info_flags,
    181147                                          &session_info->security_token);
    182         NT_STATUS_NOT_OK_RETURN(nt_status);
     148        NT_STATUS_NOT_OK_RETURN_AND_FREE(nt_status, tmp_ctx);
    183149
    184150        session_info->credentials = NULL;
    185151
     152        talloc_steal(mem_ctx, session_info);
    186153        *_session_info = session_info;
     154        talloc_free(tmp_ctx);
    187155        return NT_STATUS_OK;
     156}
     157
     158/* Create a session_info structure from the
     159 * auth_session_info_transport we were forwarded over named pipe
     160 * forwarding.
     161 *
     162 * NOTE: The stucture members of session_info_transport are stolen
     163 * with talloc_move() into auth_session_info for long term use
     164 */
     165struct auth_session_info *auth_session_info_from_transport(TALLOC_CTX *mem_ctx,
     166                                                           struct auth_session_info_transport *session_info_transport,
     167                                                           struct loadparm_context *lp_ctx,
     168                                                           const char **reason)
     169{
     170        struct auth_session_info *session_info;
     171        session_info = talloc_zero(mem_ctx, struct auth_session_info);
     172        if (!session_info) {
     173                *reason = "failed to allocate session_info";
     174                return NULL;
     175        }
     176
     177        session_info->security_token = talloc_move(session_info, &session_info_transport->security_token);
     178        session_info->info = talloc_move(session_info, &session_info_transport->info);
     179        session_info->session_key = session_info_transport->session_key;
     180        session_info->session_key.data = talloc_move(session_info, &session_info_transport->session_key.data);
     181
     182        if (session_info_transport->exported_gssapi_credentials.length) {
     183                struct cli_credentials *creds;
     184                OM_uint32 minor_status;
     185                gss_buffer_desc cred_token;
     186                gss_cred_id_t cred_handle;
     187                const char *error_string;
     188                int ret;
     189
     190                DEBUG(10, ("Delegated credentials supplied by client\n"));
     191
     192                cred_token.value = session_info_transport->exported_gssapi_credentials.data;
     193                cred_token.length = session_info_transport->exported_gssapi_credentials.length;
     194
     195                ret = gss_import_cred(&minor_status,
     196                                      &cred_token,
     197                                      &cred_handle);
     198                if (ret != GSS_S_COMPLETE) {
     199                        *reason = "Internal error in gss_import_cred()";
     200                        return NULL;
     201                }
     202
     203                creds = cli_credentials_init(session_info);
     204                if (!creds) {
     205                        *reason = "Out of memory in cli_credentials_init()";
     206                        return NULL;
     207                }
     208                session_info->credentials = creds;
     209
     210                cli_credentials_set_conf(creds, lp_ctx);
     211                /* Just so we don't segfault trying to get at a username */
     212                cli_credentials_set_anonymous(creds);
     213
     214                ret = cli_credentials_set_client_gss_creds(creds,
     215                                                           lp_ctx,
     216                                                           cred_handle,
     217                                                           CRED_SPECIFIED,
     218                                                           &error_string);
     219                if (ret) {
     220                        *reason = talloc_asprintf(mem_ctx,
     221                                                  "Failed to set pipe forwarded"
     222                                                  "creds: %s\n", error_string);
     223                        return NULL;
     224                }
     225
     226                /* This credential handle isn't useful for password
     227                 * authentication, so ensure nobody tries to do that */
     228                cli_credentials_set_kerberos_state(creds,
     229                                                   CRED_MUST_USE_KERBEROS);
     230
     231        }
     232
     233        return session_info;
     234}
     235
     236
     237/* Create a auth_session_info_transport from an auth_session_info.
     238 *
     239 * NOTE: Members of the auth_session_info_transport structure are not talloc_referenced, but simply assigned.  They are only valid for the lifetime of the struct auth_session_info
     240 *
     241 * This isn't normally an issue, as the auth_session_info has a very long typical life
     242 */
     243NTSTATUS auth_session_info_transport_from_session(TALLOC_CTX *mem_ctx,
     244                                                  struct auth_session_info *session_info,
     245                                                  struct tevent_context *event_ctx,
     246                                                  struct loadparm_context *lp_ctx,
     247                                                  struct auth_session_info_transport **transport_out)
     248{
     249
     250        struct auth_session_info_transport *session_info_transport = talloc_zero(mem_ctx, struct auth_session_info_transport);
     251        session_info_transport->security_token = talloc_reference(session_info, session_info->security_token);
     252        NT_STATUS_HAVE_NO_MEMORY(session_info_transport->security_token);
     253
     254        session_info_transport->info = talloc_reference(session_info, session_info->info);
     255        NT_STATUS_HAVE_NO_MEMORY(session_info_transport->info);
     256
     257        session_info_transport->session_key = session_info->session_key;
     258        session_info_transport->session_key.data = talloc_reference(session_info, session_info->session_key.data);
     259        if (!session_info_transport->session_key.data && session_info->session_key.length) {
     260                return NT_STATUS_NO_MEMORY;
     261        }
     262
     263        if (session_info->credentials) {
     264                struct gssapi_creds_container *gcc;
     265                OM_uint32 gret;
     266                OM_uint32 minor_status;
     267                gss_buffer_desc cred_token;
     268                const char *error_string;
     269                int ret;
     270
     271                ret = cli_credentials_get_client_gss_creds(session_info->credentials,
     272                                                           event_ctx,
     273                                                           lp_ctx,
     274                                                           &gcc, &error_string);
     275                if (ret != 0) {
     276                        *transport_out = session_info_transport;
     277                        return NT_STATUS_OK;
     278                }
     279
     280                gret = gss_export_cred(&minor_status,
     281                                       gcc->creds,
     282                                       &cred_token);
     283                if (gret != GSS_S_COMPLETE) {
     284                        return NT_STATUS_INTERNAL_ERROR;
     285                }
     286
     287                if (cred_token.length) {
     288                        session_info_transport->exported_gssapi_credentials
     289                                = data_blob_talloc(session_info_transport,
     290                                                   cred_token.value,
     291                                                   cred_token.length);
     292                        gss_release_buffer(&minor_status, &cred_token);
     293                        NT_STATUS_HAVE_NO_MEMORY(session_info_transport->exported_gssapi_credentials.data);
     294                }
     295        }
     296        *transport_out = session_info_transport;
     297        return NT_STATUS_OK;
     298}
     299
     300
     301/* Produce a session_info for an arbitary DN or principal in the local
     302 * DB, assuming the local DB holds all the groups
     303 *
     304 * Supply either a principal or a DN
     305 */
     306NTSTATUS authsam_get_session_info_principal(TALLOC_CTX *mem_ctx,
     307                                            struct loadparm_context *lp_ctx,
     308                                            struct ldb_context *sam_ctx,
     309                                            const char *principal,
     310                                            struct ldb_dn *user_dn,
     311                                            uint32_t session_info_flags,
     312                                            struct auth_session_info **session_info)
     313{
     314        NTSTATUS nt_status;
     315        struct auth_user_info_dc *user_info_dc;
     316        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     317        if (!tmp_ctx) {
     318                return NT_STATUS_NO_MEMORY;
     319        }
     320        nt_status = authsam_get_user_info_dc_principal(tmp_ctx, lp_ctx, sam_ctx,
     321                                                      principal, user_dn,
     322                                                      &user_info_dc);
     323        if (!NT_STATUS_IS_OK(nt_status)) {
     324                talloc_free(tmp_ctx);
     325                return nt_status;
     326        }
     327
     328        nt_status = auth_generate_session_info(tmp_ctx, lp_ctx, sam_ctx,
     329                                               user_info_dc, session_info_flags,
     330                                               session_info);
     331
     332        if (NT_STATUS_IS_OK(nt_status)) {
     333                talloc_steal(mem_ctx, *session_info);
     334        }
     335        talloc_free(tmp_ctx);
     336        return nt_status;
    188337}
    189338
     
    199348        }
    200349
    201         security_token_debug(dbg_lev, session_info->security_token);
    202 }
    203 
     350        security_token_debug(0, dbg_lev, session_info->security_token);
     351}
     352
Note: See TracChangeset for help on using the changeset viewer.