LCOV - code coverage report
Current view: top level - source4/auth - session.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 260 369 70.5 %
Date: 2024-04-21 15:09:00 Functions: 11 12 91.7 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Authentication utility functions
       4             :    Copyright (C) Andrew Tridgell 1992-1998
       5             :    Copyright (C) Andrew Bartlett 2001-2010
       6             :    Copyright (C) Jeremy Allison 2000-2001
       7             :    Copyright (C) Rafal Szczesniak 2002
       8             :    Copyright (C) Stefan Metzmacher 2005
       9             : 
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             : 
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "includes.h"
      25             : #include "auth/auth.h"
      26             : #include "auth/auth_sam.h"
      27             : #include "auth/credentials/credentials.h"
      28             : #include "auth/credentials/credentials_krb5.h"
      29             : #include "libcli/security/security.h"
      30             : #include "libcli/security/claims-conversions.h"
      31             : #include "libcli/auth/libcli_auth.h"
      32             : #include "librpc/gen_ndr/claims.h"
      33             : #include "librpc/gen_ndr/ndr_claims.h"
      34             : #include "dsdb/samdb/samdb.h"
      35             : #include "auth/session_proto.h"
      36             : #include "system/kerberos.h"
      37             : #include <gssapi/gssapi.h>
      38             : #include "libcli/wbclient/wbclient.h"
      39             : 
      40             : #undef DBGC_CLASS
      41             : #define DBGC_CLASS DBGC_AUTH
      42             : 
      43           7 : _PUBLIC_ struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx,
      44             :                                             struct loadparm_context *lp_ctx)
      45             : {
      46           0 :         NTSTATUS nt_status;
      47           7 :         struct auth_session_info *session_info = NULL;
      48           7 :         nt_status = auth_anonymous_session_info(mem_ctx, lp_ctx, &session_info);
      49           7 :         if (!NT_STATUS_IS_OK(nt_status)) {
      50           0 :                 return NULL;
      51             :         }
      52           7 :         return session_info;
      53             : }
      54             : 
      55       95967 : _PUBLIC_ NTSTATUS auth_generate_security_token(TALLOC_CTX *mem_ctx,
      56             :                                                struct loadparm_context *lp_ctx, /* Optional, if you don't want privileges */
      57             :                                                struct ldb_context *sam_ctx, /* Optional, if you don't want local groups */
      58             :                                                const struct auth_user_info_dc *user_info_dc,
      59             :                                                const struct auth_user_info_dc *device_info_dc,
      60             :                                                const struct auth_claims auth_claims,
      61             :                                                uint32_t session_info_flags,
      62             :                                                struct security_token **_security_token)
      63             : {
      64       95967 :         struct security_token *security_token = NULL;
      65        2164 :         NTSTATUS nt_status;
      66        2164 :         uint32_t i;
      67       95967 :         uint32_t num_sids = 0;
      68       95967 :         uint32_t num_device_sids = 0;
      69       95967 :         const char *filter = NULL;
      70       95967 :         struct auth_SidAttr *sids = NULL;
      71       95967 :         struct auth_SidAttr *device_sids = NULL;
      72             : 
      73       95967 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
      74       95967 :         if (tmp_ctx == NULL) {
      75           0 :                 return NT_STATUS_NO_MEMORY;
      76             :         }
      77             : 
      78       95967 :         sids = talloc_array(tmp_ctx, struct auth_SidAttr, user_info_dc->num_sids);
      79       95967 :         if (sids == NULL) {
      80           0 :                 TALLOC_FREE(tmp_ctx);
      81           0 :                 return NT_STATUS_NO_MEMORY;
      82             :         }
      83             : 
      84       95967 :         num_sids = user_info_dc->num_sids;
      85             : 
      86      531519 :         for (i=0; i < user_info_dc->num_sids; i++) {
      87      435552 :                 sids[i] = user_info_dc->sids[i];
      88             :         }
      89             : 
      90             :         /*
      91             :          * Finally add the "standard" sids.
      92             :          * The only difference between guest and "anonymous"
      93             :          * is the addition of Authenticated_Users.
      94             :          */
      95             : 
      96       95967 :         if (session_info_flags & AUTH_SESSION_INFO_DEFAULT_GROUPS) {
      97       47601 :                 sids = talloc_realloc(tmp_ctx, sids, struct auth_SidAttr, num_sids + 2);
      98       47601 :                 if (sids == NULL) {
      99           0 :                         TALLOC_FREE(tmp_ctx);
     100           0 :                         return NT_STATUS_NO_MEMORY;
     101             :                 }
     102             : 
     103       47601 :                 sid_copy(&sids[num_sids].sid, &global_sid_World);
     104       47601 :                 sids[num_sids].attrs = SE_GROUP_DEFAULT_FLAGS;
     105       47601 :                 num_sids++;
     106             : 
     107       47601 :                 sid_copy(&sids[num_sids].sid, &global_sid_Network);
     108       47601 :                 sids[num_sids].attrs = SE_GROUP_DEFAULT_FLAGS;
     109       47601 :                 num_sids++;
     110             :         }
     111             : 
     112       95967 :         if (session_info_flags & AUTH_SESSION_INFO_AUTHENTICATED) {
     113       47449 :                 sids = talloc_realloc(tmp_ctx, sids, struct auth_SidAttr, num_sids + 1);
     114       47449 :                 if (sids == NULL) {
     115           0 :                         TALLOC_FREE(tmp_ctx);
     116           0 :                         return NT_STATUS_NO_MEMORY;
     117             :                 }
     118             : 
     119       47449 :                 sid_copy(&sids[num_sids].sid, &global_sid_Authenticated_Users);
     120       47449 :                 sids[num_sids].attrs = SE_GROUP_DEFAULT_FLAGS;
     121       47449 :                 num_sids++;
     122             :         }
     123             : 
     124       95967 :         if (session_info_flags & AUTH_SESSION_INFO_NTLM) {
     125       12464 :                 sids = talloc_realloc(tmp_ctx, sids, struct auth_SidAttr, num_sids + 1);
     126       12464 :                 if (sids == NULL) {
     127           0 :                         TALLOC_FREE(tmp_ctx);
     128           0 :                         return NT_STATUS_NO_MEMORY;
     129             :                 }
     130             : 
     131       12464 :                 if (!dom_sid_parse(SID_NT_NTLM_AUTHENTICATION, &sids[num_sids].sid)) {
     132           0 :                         TALLOC_FREE(tmp_ctx);
     133           0 :                         return NT_STATUS_INTERNAL_ERROR;
     134             :                 }
     135       12464 :                 sids[num_sids].attrs = SE_GROUP_DEFAULT_FLAGS;
     136       12464 :                 num_sids++;
     137             :         }
     138             : 
     139             : 
     140       95967 :         if (num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(&global_sid_Anonymous, &sids[PRIMARY_USER_SID_INDEX].sid)) {
     141             :                 /* Don't expand nested groups of system, anonymous etc*/
     142       53040 :         } else if (num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(&global_sid_System, &sids[PRIMARY_USER_SID_INDEX].sid)) {
     143             :                 /* Don't expand nested groups of system, anonymous etc*/
     144       47156 :         } else if (sam_ctx != NULL) {
     145       44799 :                 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:"LDB_OID_COMPARATOR_AND":=%u))",
     146             :                                          GROUP_TYPE_BUILTIN_LOCAL_GROUP);
     147             : 
     148             :                 /* Search for each group in the token */
     149      685109 :                 for (i = 0; i < num_sids; i++) {
     150       15261 :                         struct dom_sid_buf buf;
     151       15261 :                         const char *sid_dn;
     152       15261 :                         DATA_BLOB sid_blob;
     153             : 
     154      639259 :                         sid_dn = talloc_asprintf(
     155             :                                 tmp_ctx,
     156             :                                 "<SID=%s>",
     157      639259 :                                 dom_sid_str_buf(&sids[i].sid, &buf));
     158      639259 :                         if (sid_dn == NULL) {
     159           0 :                                 TALLOC_FREE(tmp_ctx);
     160           0 :                                 return NT_STATUS_NO_MEMORY;
     161             :                         }
     162      639259 :                         sid_blob = data_blob_string_const(sid_dn);
     163             : 
     164             :                         /* This function takes in memberOf values and expands
     165             :                          * them, as long as they meet the filter - so only
     166             :                          * builtin groups
     167             :                          *
     168             :                          * We already have the SID in the token, so set
     169             :                          * 'only childs' flag to true */
     170      639259 :                         nt_status = dsdb_expand_nested_groups(sam_ctx, &sid_blob, true, filter,
     171             :                                                               tmp_ctx, &sids, &num_sids);
     172      639259 :                         if (!NT_STATUS_IS_OK(nt_status)) {
     173           0 :                                 talloc_free(tmp_ctx);
     174           0 :                                 return nt_status;
     175             :                         }
     176             :                 }
     177             :         }
     178             : 
     179       95967 :         if (device_info_dc != NULL) {
     180             :                 /*
     181             :                  * Make a copy of the device SIDs in case we need to add extra SIDs on
     182             :                  * the end. One can never have too much copying.
     183             :                  */
     184         233 :                 num_device_sids = device_info_dc->num_sids;
     185         233 :                 device_sids = talloc_array(tmp_ctx,
     186             :                                     struct auth_SidAttr,
     187             :                                     num_device_sids);
     188         233 :                 if (device_sids == NULL) {
     189           0 :                         TALLOC_FREE(tmp_ctx);
     190           0 :                         return NT_STATUS_NO_MEMORY;
     191             :                 }
     192             : 
     193        1361 :                 for (i = 0; i < num_device_sids; i++) {
     194        1128 :                         device_sids[i] = device_info_dc->sids[i];
     195             :                 }
     196             : 
     197         233 :                 if (session_info_flags & AUTH_SESSION_INFO_DEVICE_DEFAULT_GROUPS) {
     198         233 :                         device_sids = talloc_realloc(tmp_ctx,
     199             :                                                      device_sids,
     200             :                                                      struct auth_SidAttr,
     201             :                                                      num_device_sids + 2);
     202         233 :                         if (device_sids == NULL) {
     203           0 :                                 TALLOC_FREE(tmp_ctx);
     204           0 :                                 return NT_STATUS_NO_MEMORY;
     205             :                         }
     206             : 
     207         233 :                         device_sids[num_device_sids++] = (struct auth_SidAttr) {
     208             :                                 .sid = global_sid_World,
     209             :                                 .attrs = SE_GROUP_DEFAULT_FLAGS,
     210             :                         };
     211         233 :                         device_sids[num_device_sids++] = (struct auth_SidAttr) {
     212             :                                 .sid = global_sid_Network,
     213             :                                 .attrs = SE_GROUP_DEFAULT_FLAGS,
     214             :                         };
     215             :                 }
     216             : 
     217         233 :                 if (session_info_flags & AUTH_SESSION_INFO_DEVICE_AUTHENTICATED) {
     218         233 :                         device_sids = talloc_realloc(tmp_ctx,
     219             :                                                      device_sids,
     220             :                                                      struct auth_SidAttr,
     221             :                                                      num_device_sids + 1);
     222         233 :                         if (device_sids == NULL) {
     223           0 :                                 TALLOC_FREE(tmp_ctx);
     224           0 :                                 return NT_STATUS_NO_MEMORY;
     225             :                         }
     226             : 
     227         233 :                         device_sids[num_device_sids++] = (struct auth_SidAttr) {
     228             :                                 .sid = global_sid_Authenticated_Users,
     229             :                                 .attrs = SE_GROUP_DEFAULT_FLAGS,
     230             :                         };
     231             :                 }
     232             :         }
     233             : 
     234       95967 :         nt_status = security_token_create(mem_ctx,
     235             :                                           lp_ctx,
     236             :                                           num_sids,
     237             :                                           sids,
     238             :                                           num_device_sids,
     239             :                                           device_sids,
     240             :                                           auth_claims,
     241             :                                           session_info_flags,
     242             :                                           &security_token);
     243       95967 :         if (!NT_STATUS_IS_OK(nt_status)) {
     244          17 :                 TALLOC_FREE(tmp_ctx);
     245          17 :                 return nt_status;
     246             :         }
     247             : 
     248       95950 :         talloc_steal(mem_ctx, security_token);
     249       95950 :         *_security_token = security_token;
     250       95950 :         talloc_free(tmp_ctx);
     251       95950 :         return NT_STATUS_OK;
     252             : }
     253             : 
     254       95191 : _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
     255             :                                              struct loadparm_context *lp_ctx, /* Optional, if you don't want privileges */
     256             :                                              struct ldb_context *sam_ctx, /* Optional, if you don't want local groups */
     257             :                                              const struct auth_user_info_dc *user_info_dc,
     258             :                                              uint32_t session_info_flags,
     259             :                                              struct auth_session_info **_session_info)
     260             : {
     261        2164 :         struct auth_session_info *session_info;
     262        2164 :         NTSTATUS nt_status;
     263             : 
     264       95191 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     265       95191 :         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
     266             : 
     267       95191 :         session_info = talloc_zero(tmp_ctx, struct auth_session_info);
     268       95191 :         if (session_info == NULL) {
     269           0 :                 TALLOC_FREE(tmp_ctx);
     270           0 :                 return NT_STATUS_NO_MEMORY;
     271             :         }
     272             : 
     273       95191 :         session_info->info = talloc_reference(session_info, user_info_dc->info);
     274       95191 :         if (session_info->info == NULL) {
     275           0 :                 TALLOC_FREE(tmp_ctx);
     276           0 :                 return NT_STATUS_NO_MEMORY;
     277             :         }
     278             : 
     279       95191 :         session_info->torture = talloc_zero(session_info, struct auth_user_info_torture);
     280       95191 :         if (session_info->torture == NULL) {
     281           0 :                 TALLOC_FREE(tmp_ctx);
     282           0 :                 return NT_STATUS_NO_MEMORY;
     283             :         }
     284       95191 :         session_info->torture->num_dc_sids = user_info_dc->num_sids;
     285       95191 :         session_info->torture->dc_sids = talloc_reference(session_info, user_info_dc->sids);
     286       95191 :         if (session_info->torture->dc_sids == NULL) {
     287           0 :                 TALLOC_FREE(tmp_ctx);
     288           0 :                 return NT_STATUS_NO_MEMORY;
     289             :         }
     290             : 
     291             :         /* unless set otherwise, the session key is the user session
     292             :          * key from the auth subsystem */
     293       95191 :         session_info->session_key = data_blob_talloc(session_info, user_info_dc->user_session_key.data, user_info_dc->user_session_key.length);
     294       95191 :         if (!session_info->session_key.data && user_info_dc->user_session_key.length) {
     295           0 :                 TALLOC_FREE(tmp_ctx);
     296           0 :                 return NT_STATUS_NO_MEMORY;
     297             :         }
     298             : 
     299       95191 :         nt_status = auth_generate_security_token(session_info,
     300             :                                                  lp_ctx,
     301             :                                                  sam_ctx,
     302             :                                                  user_info_dc,
     303             :                                                  NULL /*device_info_dc */,
     304       95191 :                                                  (struct auth_claims) {},
     305             :                                                  session_info_flags,
     306             :                                                  &session_info->security_token);
     307       95191 :         if (!NT_STATUS_IS_OK(nt_status)) {
     308           0 :                 TALLOC_FREE(tmp_ctx);
     309           0 :                 return nt_status;
     310             :         }
     311             : 
     312       95191 :         session_info->unique_session_token = GUID_random();
     313             : 
     314       95191 :         session_info->credentials = NULL;
     315             : 
     316       95191 :         session_info->ticket_type = user_info_dc->ticket_type;
     317             : 
     318       95191 :         talloc_steal(mem_ctx, session_info);
     319       95191 :         *_session_info = session_info;
     320       95191 :         talloc_free(tmp_ctx);
     321       95191 :         return NT_STATUS_OK;
     322             : }
     323             : 
     324             : 
     325             : /* Fill out the auth_session_info with a cli_credentials based on the
     326             :  * auth_session_info we were forwarded over named pipe forwarding.
     327             :  *
     328             :  * NOTE: The structure members of session_info_transport are stolen
     329             :  * with talloc_move() into auth_session_info for long term use
     330             :  */
     331        7813 : struct auth_session_info *auth_session_info_from_transport(TALLOC_CTX *mem_ctx,
     332             :                                                            struct auth_session_info_transport *session_info_transport,
     333             :                                                            struct loadparm_context *lp_ctx,
     334             :                                                            const char **reason)
     335             : {
     336         628 :         struct auth_session_info *session_info;
     337        7813 :         session_info = talloc_steal(mem_ctx, session_info_transport->session_info);
     338             :         /*
     339             :          * This is to allow us to check the type of this pointer using
     340             :          * talloc_get_type()
     341             :          */
     342        7813 :         talloc_set_name(session_info, "struct auth_session_info");
     343             : #ifdef HAVE_GSS_IMPORT_CRED
     344        7813 :         if (session_info_transport->exported_gssapi_credentials.length) {
     345           0 :                 struct cli_credentials *creds;
     346           0 :                 OM_uint32 minor_status;
     347           0 :                 gss_buffer_desc cred_token;
     348           0 :                 gss_cred_id_t cred_handle;
     349           0 :                 const char *error_string;
     350           0 :                 int ret;
     351           0 :                 bool ok;
     352             : 
     353        1123 :                 DEBUG(10, ("Delegated credentials supplied by client\n"));
     354             : 
     355        1123 :                 cred_token.value = session_info_transport->exported_gssapi_credentials.data;
     356        1123 :                 cred_token.length = session_info_transport->exported_gssapi_credentials.length;
     357             : 
     358        1123 :                 ret = gss_import_cred(&minor_status,
     359             :                                       &cred_token,
     360             :                                       &cred_handle);
     361        1123 :                 if (ret != GSS_S_COMPLETE) {
     362           0 :                         *reason = "Internal error in gss_import_cred()";
     363           0 :                         return NULL;
     364             :                 }
     365             : 
     366        1123 :                 creds = cli_credentials_init(session_info);
     367        1123 :                 if (!creds) {
     368           0 :                         *reason = "Out of memory in cli_credentials_init()";
     369           0 :                         return NULL;
     370             :                 }
     371        1123 :                 session_info->credentials = creds;
     372             : 
     373        1123 :                 ok = cli_credentials_set_conf(creds, lp_ctx);
     374        1123 :                 if (!ok) {
     375           0 :                         *reason = "Failed to load smb.conf";
     376           0 :                         return NULL;
     377             :                 }
     378             : 
     379             :                 /* Just so we don't segfault trying to get at a username */
     380        1123 :                 cli_credentials_set_anonymous(creds);
     381             : 
     382        1123 :                 ret = cli_credentials_set_client_gss_creds(creds,
     383             :                                                            lp_ctx,
     384             :                                                            cred_handle,
     385             :                                                            CRED_SPECIFIED,
     386             :                                                            &error_string);
     387        1123 :                 if (ret) {
     388           0 :                         *reason = talloc_asprintf(mem_ctx,
     389             :                                                   "Failed to set pipe forwarded "
     390             :                                                   "creds: %s\n", error_string);
     391           0 :                         return NULL;
     392             :                 }
     393             : 
     394             :                 /* This credential handle isn't useful for password
     395             :                  * authentication, so ensure nobody tries to do that */
     396        1123 :                 cli_credentials_set_kerberos_state(creds,
     397             :                                                    CRED_USE_KERBEROS_REQUIRED,
     398             :                                                    CRED_SPECIFIED);
     399             : 
     400             :         }
     401             : #endif
     402        7185 :         return session_info;
     403             : }
     404             : 
     405             : 
     406             : /* Create a auth_session_info_transport from an auth_session_info.
     407             :  *
     408             :  * NOTE: Members of the auth_session_info_transport structure are
     409             :  * talloc_referenced() into this structure, and should not be changed.
     410             :  */
     411        1330 : NTSTATUS auth_session_info_transport_from_session(TALLOC_CTX *mem_ctx,
     412             :                                                   struct auth_session_info *session_info,
     413             :                                                   struct tevent_context *event_ctx,
     414             :                                                   struct loadparm_context *lp_ctx,
     415             :                                                   struct auth_session_info_transport **transport_out)
     416             : {
     417             : 
     418           0 :         struct auth_session_info_transport *session_info_transport
     419        1330 :                 = talloc_zero(mem_ctx, struct auth_session_info_transport);
     420        1330 :         if (!session_info_transport) {
     421           0 :                 return NT_STATUS_NO_MEMORY;
     422           0 :         };
     423        1330 :         session_info_transport->session_info = talloc_reference(session_info_transport, session_info);
     424        1330 :         if (!session_info_transport->session_info) {
     425           0 :                 return NT_STATUS_NO_MEMORY;
     426           0 :         };
     427             : #ifdef HAVE_GSS_EXPORT_CRED
     428        1330 :         if (session_info->credentials) {
     429           0 :                 struct gssapi_creds_container *gcc;
     430           0 :                 OM_uint32 gret;
     431           0 :                 OM_uint32 minor_status;
     432           0 :                 gss_buffer_desc cred_token;
     433           0 :                 const char *error_string;
     434           0 :                 int ret;
     435             : 
     436        1207 :                 ret = cli_credentials_get_client_gss_creds(session_info->credentials,
     437             :                                                            event_ctx,
     438             :                                                            lp_ctx,
     439             :                                                            &gcc, &error_string);
     440        1207 :                 if (ret != 0) {
     441           0 :                         *transport_out = session_info_transport;
     442           0 :                         return NT_STATUS_OK;
     443             :                 }
     444             : 
     445        1207 :                 gret = gss_export_cred(&minor_status,
     446        1207 :                                        gcc->creds,
     447             :                                        &cred_token);
     448        1207 :                 if (gret != GSS_S_COMPLETE) {
     449           0 :                         return NT_STATUS_INTERNAL_ERROR;
     450             :                 }
     451             : 
     452        1207 :                 if (cred_token.length) {
     453           0 :                         session_info_transport->exported_gssapi_credentials
     454        1207 :                                 = data_blob_talloc(session_info_transport,
     455             :                                                    cred_token.value,
     456             :                                                    cred_token.length);
     457        1207 :                         gss_release_buffer(&minor_status, &cred_token);
     458        1207 :                         NT_STATUS_HAVE_NO_MEMORY(session_info_transport->exported_gssapi_credentials.data);
     459             :                 }
     460             :         }
     461             : #endif
     462        1330 :         *transport_out = session_info_transport;
     463        1330 :         return NT_STATUS_OK;
     464             : }
     465             : 
     466             : 
     467             : /* Produce a session_info for an arbitrary DN or principal in the local
     468             :  * DB, assuming the local DB holds all the groups
     469             :  *
     470             :  * Supply either a principal or a DN
     471             :  */
     472         471 : NTSTATUS authsam_get_session_info_principal(TALLOC_CTX *mem_ctx,
     473             :                                             struct loadparm_context *lp_ctx,
     474             :                                             struct ldb_context *sam_ctx,
     475             :                                             const char *principal,
     476             :                                             struct ldb_dn *user_dn,
     477             :                                             uint32_t session_info_flags,
     478             :                                             struct auth_session_info **session_info)
     479             : {
     480          41 :         NTSTATUS nt_status;
     481          41 :         struct auth_user_info_dc *user_info_dc;
     482         471 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     483         471 :         if (!tmp_ctx) {
     484           0 :                 return NT_STATUS_NO_MEMORY;
     485             :         }
     486         471 :         nt_status = authsam_get_user_info_dc_principal(tmp_ctx, lp_ctx, sam_ctx,
     487             :                                                       principal, user_dn,
     488             :                                                       &user_info_dc);
     489         471 :         if (!NT_STATUS_IS_OK(nt_status)) {
     490           0 :                 talloc_free(tmp_ctx);
     491           0 :                 return nt_status;
     492             :         }
     493             : 
     494         471 :         nt_status = auth_generate_session_info(tmp_ctx, lp_ctx, sam_ctx,
     495             :                                                user_info_dc,
     496             :                                                session_info_flags,
     497             :                                                session_info);
     498             : 
     499         471 :         if (NT_STATUS_IS_OK(nt_status)) {
     500         471 :                 talloc_steal(mem_ctx, *session_info);
     501             :         }
     502         471 :         talloc_free(tmp_ctx);
     503         471 :         return nt_status;
     504             : }
     505             : 
     506             : /**
     507             :  * prints a struct auth_session_info security token to debug output.
     508             :  */
     509           0 : void auth_session_info_debug(int dbg_lev,
     510             :                              const struct auth_session_info *session_info)
     511             : {
     512           0 :         if (!session_info) {
     513           0 :                 DEBUG(dbg_lev, ("Session Info: (NULL)\n"));
     514           0 :                 return;
     515             :         }
     516             : 
     517           0 :         security_token_debug(DBGC_AUTH, dbg_lev,
     518           0 :                              session_info->security_token);
     519             : }
     520             : 
     521         324 : NTSTATUS encode_claims_set(TALLOC_CTX *mem_ctx,
     522             :                            struct CLAIMS_SET *claims_set,
     523             :                            DATA_BLOB *claims_blob)
     524             : {
     525         324 :         TALLOC_CTX *tmp_ctx = NULL;
     526           0 :         enum ndr_err_code ndr_err;
     527         324 :         struct CLAIMS_SET_NDR *claims_set_info = NULL;
     528         324 :         struct CLAIMS_SET_METADATA *metadata = NULL;
     529         324 :         struct CLAIMS_SET_METADATA_NDR *metadata_ndr = NULL;
     530             : 
     531         324 :         if (claims_blob == NULL) {
     532           0 :                 return NT_STATUS_INVALID_PARAMETER_3;
     533             :         }
     534             : 
     535         324 :         tmp_ctx = talloc_new(mem_ctx);
     536         324 :         if (tmp_ctx == NULL) {
     537           0 :                 return NT_STATUS_NO_MEMORY;
     538             :         }
     539             : 
     540         324 :         metadata_ndr = talloc(tmp_ctx, struct CLAIMS_SET_METADATA_NDR);
     541         324 :         if (metadata_ndr == NULL) {
     542           0 :                 talloc_free(tmp_ctx);
     543           0 :                 return NT_STATUS_NO_MEMORY;
     544             :         }
     545             : 
     546         324 :         metadata = talloc(metadata_ndr, struct CLAIMS_SET_METADATA);
     547         324 :         if (metadata == NULL) {
     548           0 :                 talloc_free(tmp_ctx);
     549           0 :                 return NT_STATUS_NO_MEMORY;
     550             :         }
     551             : 
     552         324 :         claims_set_info = talloc(metadata, struct CLAIMS_SET_NDR);
     553         324 :         if (claims_set_info == NULL) {
     554           0 :                 talloc_free(tmp_ctx);
     555           0 :                 return NT_STATUS_NO_MEMORY;
     556             :         }
     557             : 
     558         324 :         *metadata_ndr = (struct CLAIMS_SET_METADATA_NDR) {
     559             :                 .claims.metadata = metadata,
     560             :         };
     561             : 
     562         324 :         *metadata = (struct CLAIMS_SET_METADATA) {
     563             :                 .claims_set = claims_set_info,
     564             :                 .compression_format = CLAIMS_COMPRESSION_FORMAT_XPRESS_HUFF,
     565             :         };
     566             : 
     567         324 :         *claims_set_info = (struct CLAIMS_SET_NDR) {
     568             :                 .claims.claims = claims_set,
     569             :         };
     570             : 
     571         324 :         ndr_err = ndr_push_struct_blob(claims_blob, mem_ctx, metadata_ndr,
     572             :                                        (ndr_push_flags_fn_t)ndr_push_CLAIMS_SET_METADATA_NDR);
     573         324 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     574           0 :                 NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err);
     575           0 :                 DBG_ERR("CLAIMS_SET_METADATA_NDR push failed: %s\n",
     576             :                         nt_errstr(nt_status));
     577             : 
     578           0 :                 talloc_free(tmp_ctx);
     579           0 :                 return nt_status;
     580             :         }
     581             : 
     582         324 :         talloc_free(tmp_ctx);
     583         324 :         return NT_STATUS_OK;
     584             : }
     585             : 
     586             : /*
     587             :  * Construct a ‘claims_data’ structure from a claims blob, such as is found in a
     588             :  * PAC.
     589             :  */
     590         341 : NTSTATUS claims_data_from_encoded_claims_set(TALLOC_CTX *claims_data_ctx,
     591             :                                              const DATA_BLOB *encoded_claims_set,
     592             :                                              struct claims_data **out)
     593             : {
     594         341 :         struct claims_data *claims_data = NULL;
     595         341 :         DATA_BLOB data = {};
     596             : 
     597         341 :         if (out == NULL) {
     598           0 :                 return NT_STATUS_INVALID_PARAMETER;
     599             :         }
     600             : 
     601         341 :         *out = NULL;
     602             : 
     603         341 :         claims_data = talloc(claims_data_ctx, struct claims_data);
     604         341 :         if (claims_data == NULL) {
     605           0 :                 return NT_STATUS_NO_MEMORY;
     606             :         }
     607             : 
     608         341 :         if (encoded_claims_set != NULL) {
     609             :                 /*
     610             :                  * We make a copy of the data, for it might not be
     611             :                  * talloc‐allocated — we might have obtained it directly with
     612             :                  * krb5_pac_get_buffer().
     613             :                  */
     614         341 :                 data = data_blob_dup_talloc(claims_data, *encoded_claims_set);
     615         341 :                 if (data.length != encoded_claims_set->length) {
     616           0 :                         talloc_free(claims_data);
     617           0 :                         return NT_STATUS_NO_MEMORY;
     618             :                 }
     619             :         }
     620             : 
     621         341 :         *claims_data = (struct claims_data) {
     622             :                 .encoded_claims_set = data,
     623             :                 .flags = CLAIMS_DATA_ENCODED_CLAIMS_PRESENT,
     624             :         };
     625             : 
     626         341 :         *out = claims_data;
     627             : 
     628         341 :         return NT_STATUS_OK;
     629             : }
     630             : 
     631             : /*
     632             :  * Construct a ‘claims_data’ structure from a talloc‐allocated claims set, such
     633             :  * as we might build from searching the database. If this function returns
     634             :  * successfully, it assumes ownership of the claims set.
     635             :  */
     636         324 : NTSTATUS claims_data_from_claims_set(TALLOC_CTX *claims_data_ctx,
     637             :                                      struct CLAIMS_SET *claims_set,
     638             :                                      struct claims_data **out)
     639             : {
     640         324 :         struct claims_data *claims_data = NULL;
     641             : 
     642         324 :         if (out == NULL) {
     643           0 :                 return NT_STATUS_INVALID_PARAMETER;
     644             :         }
     645             : 
     646         324 :         *out = NULL;
     647             : 
     648         324 :         claims_data = talloc(claims_data_ctx, struct claims_data);
     649         324 :         if (claims_data == NULL) {
     650           0 :                 return NT_STATUS_NO_MEMORY;
     651             :         }
     652         324 :         *claims_data = (struct claims_data) {
     653         324 :                 .claims_set = talloc_steal(claims_data, claims_set),
     654             :                 .flags = CLAIMS_DATA_CLAIMS_PRESENT,
     655             :         };
     656             : 
     657         324 :         *out = claims_data;
     658             : 
     659         324 :         return NT_STATUS_OK;
     660             : }
     661             : 
     662             : /*
     663             :  * From a ‘claims_data’ structure, return an encoded claims blob that can be put
     664             :  * into a PAC.
     665             :  */
     666       31144 : NTSTATUS claims_data_encoded_claims_set(TALLOC_CTX *mem_ctx,
     667             :                                         struct claims_data *claims_data,
     668             :                                         DATA_BLOB *encoded_claims_set_out)
     669             : {
     670       31144 :         uint8_t *data = NULL;
     671        1170 :         size_t len;
     672             : 
     673       31144 :         if (encoded_claims_set_out == NULL) {
     674           0 :                 return NT_STATUS_INVALID_PARAMETER;
     675             :         }
     676             : 
     677       31144 :         *encoded_claims_set_out = data_blob_null;
     678             : 
     679       31144 :         if (claims_data == NULL) {
     680       30794 :                 return NT_STATUS_OK;
     681             :         }
     682             : 
     683         350 :         if (!(claims_data->flags & CLAIMS_DATA_ENCODED_CLAIMS_PRESENT)) {
     684           0 :                 NTSTATUS status;
     685             : 
     686             :                 /* See whether we have a claims set that we can encode. */
     687         324 :                 if (!(claims_data->flags & CLAIMS_DATA_CLAIMS_PRESENT)) {
     688           0 :                         return NT_STATUS_OK;
     689             :                 }
     690             : 
     691         324 :                 status = encode_claims_set(claims_data,
     692             :                                            claims_data->claims_set,
     693             :                                            &claims_data->encoded_claims_set);
     694         324 :                 if (!NT_STATUS_IS_OK(status)) {
     695           0 :                         return status;
     696             :                 }
     697             : 
     698         324 :                 claims_data->flags |= CLAIMS_DATA_ENCODED_CLAIMS_PRESENT;
     699             :         }
     700             : 
     701         350 :         if (claims_data->encoded_claims_set.data != NULL) {
     702         350 :                 data = talloc_reference(mem_ctx, claims_data->encoded_claims_set.data);
     703         350 :                 if (data == NULL) {
     704           0 :                         return NT_STATUS_NO_MEMORY;
     705             :                 }
     706             :         }
     707         350 :         len = claims_data->encoded_claims_set.length;
     708             : 
     709         350 :         *encoded_claims_set_out = data_blob_const(data, len);
     710         350 :         return NT_STATUS_OK;
     711             : }
     712             : 
     713             : /*
     714             :  * From a ‘claims_data’ structure, return an array of security claims that can
     715             :  * be put in a security token for access checks.
     716             :  */
     717       33425 : NTSTATUS claims_data_security_claims(TALLOC_CTX *mem_ctx,
     718             :                                      struct claims_data *claims_data,
     719             :                                      struct CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1 **security_claims_out,
     720             :                                      uint32_t *n_security_claims_out)
     721             : {
     722       33425 :         struct CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1 *security_claims = NULL;
     723         881 :         uint32_t n_security_claims;
     724         881 :         NTSTATUS status;
     725             : 
     726       33425 :         if (security_claims_out == NULL) {
     727           0 :                 return NT_STATUS_INVALID_PARAMETER;
     728             :         }
     729             : 
     730       33425 :         if (n_security_claims_out == NULL) {
     731           0 :                 return NT_STATUS_INVALID_PARAMETER;
     732             :         }
     733             : 
     734       33425 :         *security_claims_out = NULL;
     735       33425 :         *n_security_claims_out = 0;
     736             : 
     737       33425 :         if (claims_data == NULL) {
     738       33127 :                 return NT_STATUS_OK;
     739             :         }
     740             : 
     741         298 :         if (!(claims_data->flags & CLAIMS_DATA_SECURITY_CLAIMS_PRESENT)) {
     742         298 :                 struct CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1 *decoded_claims = NULL;
     743         298 :                 uint32_t n_decoded_claims = 0;
     744             : 
     745             :                 /* See whether we have a claims set that we can convert. */
     746         298 :                 if (!(claims_data->flags & CLAIMS_DATA_CLAIMS_PRESENT)) {
     747             : 
     748             :                         /*
     749             :                          * See whether we have an encoded claims set that we can
     750             :                          * decode.
     751             :                          */
     752         298 :                         if (!(claims_data->flags & CLAIMS_DATA_ENCODED_CLAIMS_PRESENT)) {
     753             :                                 /* We don’t have anything. */
     754           0 :                                 return NT_STATUS_OK;
     755             :                         }
     756             : 
     757             :                         /* Decode an existing claims set. */
     758             : 
     759         298 :                         if (claims_data->encoded_claims_set.length) {
     760         298 :                                 TALLOC_CTX *tmp_ctx = NULL;
     761           0 :                                 struct CLAIMS_SET_METADATA_NDR claims;
     762         298 :                                 const struct CLAIMS_SET_METADATA *metadata = NULL;
     763           0 :                                 enum ndr_err_code ndr_err;
     764             : 
     765         298 :                                 tmp_ctx = talloc_new(claims_data);
     766         298 :                                 if (tmp_ctx == NULL) {
     767           0 :                                         return NT_STATUS_NO_MEMORY;
     768             :                                 }
     769             : 
     770         298 :                                 ndr_err = ndr_pull_struct_blob(&claims_data->encoded_claims_set,
     771             :                                                                tmp_ctx,
     772             :                                                                &claims,
     773             :                                                                (ndr_pull_flags_fn_t)ndr_pull_CLAIMS_SET_METADATA_NDR);
     774         298 :                                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     775           0 :                                         status = ndr_map_error2ntstatus(ndr_err);
     776           0 :                                         DBG_ERR("Failed to parse encoded claims set: %s\n",
     777             :                                                 nt_errstr(status));
     778           0 :                                         talloc_free(tmp_ctx);
     779           0 :                                         return status;
     780             :                                 }
     781             : 
     782         298 :                                 metadata = claims.claims.metadata;
     783         298 :                                 if (metadata != NULL) {
     784         298 :                                         struct CLAIMS_SET_NDR *claims_set_ndr = metadata->claims_set;
     785         298 :                                         if (claims_set_ndr != NULL) {
     786         298 :                                                 struct CLAIMS_SET **claims_set = &claims_set_ndr->claims.claims;
     787             : 
     788         298 :                                                 claims_data->claims_set = talloc_move(claims_data, claims_set);
     789             :                                         }
     790             :                                 }
     791             : 
     792         298 :                                 talloc_free(tmp_ctx);
     793             :                         }
     794             : 
     795         298 :                         claims_data->flags |= CLAIMS_DATA_CLAIMS_PRESENT;
     796             :                 }
     797             : 
     798             :                 /*
     799             :                  * Convert the decoded claims set to the security attribute
     800             :                  * claims format.
     801             :                  */
     802         298 :                 status = token_claims_to_claims_v1(claims_data,
     803         298 :                                                    claims_data->claims_set,
     804             :                                                    &decoded_claims,
     805             :                                                    &n_decoded_claims);
     806         298 :                 if (!NT_STATUS_IS_OK(status)) {
     807          17 :                         return status;
     808             :                 }
     809             : 
     810         281 :                 claims_data->security_claims = decoded_claims;
     811         281 :                 claims_data->n_security_claims = n_decoded_claims;
     812             : 
     813         281 :                 claims_data->flags |= CLAIMS_DATA_SECURITY_CLAIMS_PRESENT;
     814             :         }
     815             : 
     816         281 :         if (claims_data->security_claims != NULL) {
     817         281 :                 security_claims = talloc_reference(mem_ctx, claims_data->security_claims);
     818         281 :                 if (security_claims == NULL) {
     819           0 :                         return NT_STATUS_NO_MEMORY;
     820             :                 }
     821             :         }
     822         281 :         n_security_claims = claims_data->n_security_claims;
     823             : 
     824         281 :         *security_claims_out = security_claims;
     825         281 :         *n_security_claims_out = n_security_claims;
     826             : 
     827         281 :         return NT_STATUS_OK;
     828             : }

Generated by: LCOV version 1.14