LCOV - code coverage report
Current view: top level - source4/dsdb/samdb - samdb.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 108 132 81.8 %
Date: 2024-04-21 15:09:00 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    interface functions for the sam database
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2004
       7             :    Copyright (C) Volker Lendecke 2004
       8             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006
       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 "librpc/gen_ndr/ndr_netlogon.h"
      26             : #include "librpc/gen_ndr/ndr_security.h"
      27             : #include "lib/events/events.h"
      28             : #include "lib/ldb-samba/ldb_wrap.h"
      29             : #include <ldb.h>
      30             : #include <ldb_errors.h>
      31             : #include "libcli/security/security.h"
      32             : #include "libcli/security/claims-conversions.h"
      33             : #include "libcli/auth/libcli_auth.h"
      34             : #include "libcli/ldap/ldap_ndr.h"
      35             : #include "system/time.h"
      36             : #include "system/filesys.h"
      37             : #include "ldb_wrap.h"
      38             : #include "../lib/util/util_ldb.h"
      39             : #include "dsdb/samdb/samdb.h"
      40             : #include "../libds/common/flags.h"
      41             : #include "param/param.h"
      42             : #include "lib/events/events.h"
      43             : #include "auth/credentials/credentials.h"
      44             : #include "param/secrets.h"
      45             : #include "auth/auth.h"
      46             : #include "lib/tsocket/tsocket.h"
      47             : #include "lib/param/loadparm.h"
      48             : 
      49             : /*
      50             :   connect to the SAM database specified by URL
      51             :   return an opaque context pointer on success, or NULL on failure
      52             :  */
      53      256497 : int samdb_connect_url(TALLOC_CTX *mem_ctx,
      54             :                       struct tevent_context *ev_ctx,
      55             :                       struct loadparm_context *lp_ctx,
      56             :                       struct auth_session_info *session_info,
      57             :                       unsigned int flags,
      58             :                       const char *url,
      59             :                       const struct tsocket_address *remote_address,
      60             :                       struct ldb_context **ldb_ret,
      61             :                       char **errstring)
      62             : {
      63      256497 :         struct ldb_context *ldb = NULL;
      64        8285 :         int ret;
      65      256497 :         *ldb_ret = NULL;
      66      256497 :         *errstring = NULL;
      67             : 
      68             :         /* We create sam.ldb in provision, and never anywhere else */
      69      256497 :         flags |= LDB_FLG_DONT_CREATE_DB;
      70             : 
      71      256497 :         if (remote_address == NULL) {
      72      184231 :                 ldb = ldb_wrap_find(url, ev_ctx, lp_ctx,
      73             :                                     session_info, NULL, flags);
      74      184231 :                 if (ldb != NULL) {
      75       82188 :                         *ldb_ret = talloc_reference(mem_ctx, ldb);
      76       82188 :                         if (*ldb_ret == NULL) {
      77           0 :                                 return LDB_ERR_OPERATIONS_ERROR;
      78             :                         }
      79       82188 :                         return LDB_SUCCESS;
      80             :                 }
      81             :         }
      82             : 
      83      174309 :         ldb = samba_ldb_init(mem_ctx, ev_ctx, lp_ctx, session_info, NULL);
      84             : 
      85      174309 :         if (ldb == NULL) {
      86           0 :                 *errstring = talloc_asprintf(mem_ctx,
      87             :                                              "Failed to set up Samba ldb "
      88             :                                              "wrappers with samba_ldb_init() "
      89             :                                              "to connect to %s",
      90             :                                              url);
      91           0 :                 return LDB_ERR_OPERATIONS_ERROR;
      92             :         }
      93             : 
      94      174309 :         dsdb_set_global_schema(ldb);
      95             : 
      96      174309 :         ret = samba_ldb_connect(ldb, lp_ctx, url, flags);
      97      174309 :         if (ret != LDB_SUCCESS) {
      98          20 :                 *errstring = talloc_asprintf(mem_ctx,
      99             :                                              "Failed to connect to %s: %s",
     100             :                                              url,
     101             :                                              ldb_errstring(ldb));
     102          20 :                 talloc_free(ldb);
     103          20 :                 return LDB_ERR_OPERATIONS_ERROR;
     104             :         }
     105             : 
     106             :         /*
     107             :          * If a remote_address was specified, then set it on the DB
     108             :          * and do not add to the wrap list (as we need to keep the LDB
     109             :          * pointer unique for the address).
     110             :          *
     111             :          * We use this for audit logging and for the "netlogon" attribute
     112             :          */
     113      174289 :         if (remote_address != NULL) {
     114       72266 :                 ldb_set_opaque(ldb, "remoteAddress",
     115             :                                discard_const(remote_address));
     116       72266 :                 *ldb_ret = ldb;
     117       72266 :                 return LDB_SUCCESS;
     118             :         }
     119             :                 
     120      102023 :         if (!ldb_wrap_add(url, ev_ctx, lp_ctx, session_info, NULL, flags, ldb)) {
     121           0 :                 *errstring = talloc_asprintf(mem_ctx,
     122             :                                              "Failed to add cached DB reference"
     123             :                                              " to %s",
     124             :                                              url);
     125           0 :                 talloc_free(ldb);
     126           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     127             :         }
     128             : 
     129      102023 :         *ldb_ret = ldb;
     130      102023 :         return LDB_SUCCESS;
     131             : }
     132             : 
     133             : 
     134             : /*
     135             :   connect to the SAM database
     136             :   return an opaque context pointer on success, or NULL on failure
     137             :  */
     138      192646 : struct ldb_context *samdb_connect(TALLOC_CTX *mem_ctx,
     139             :                                   struct tevent_context *ev_ctx,
     140             :                                   struct loadparm_context *lp_ctx,
     141             :                                   struct auth_session_info *session_info,
     142             :                                   const struct tsocket_address *remote_address,
     143             :                                   unsigned int flags)
     144             : {
     145        7181 :         char *errstring;
     146        7181 :         struct ldb_context *ldb;
     147      192646 :         int ret = samdb_connect_url(mem_ctx,
     148             :                                     ev_ctx,
     149             :                                     lp_ctx,
     150             :                                     session_info,
     151             :                                     flags,
     152             :                                     "sam.ldb",
     153             :                                     remote_address,
     154             :                                     &ldb,
     155             :                                     &errstring);
     156      192646 :         if (ret == LDB_SUCCESS) {
     157      192626 :                 return ldb;
     158             :         }
     159          20 :         return NULL;
     160             : }
     161             : 
     162             : /****************************************************************************
     163             :  Create the SID list for this user.
     164             : ****************************************************************************/
     165       95967 : NTSTATUS security_token_create(TALLOC_CTX *mem_ctx, 
     166             :                                struct loadparm_context *lp_ctx,
     167             :                                uint32_t num_sids,
     168             :                                const struct auth_SidAttr *sids,
     169             :                                uint32_t num_device_sids,
     170             :                                const struct auth_SidAttr *device_sids,
     171             :                                struct auth_claims auth_claims,
     172             :                                uint32_t session_info_flags,
     173             :                                struct security_token **token)
     174             : {
     175        2164 :         struct security_token *ptoken;
     176        2164 :         uint32_t i;
     177        2164 :         NTSTATUS status;
     178        2164 :         enum claims_evaluation_control evaluate_claims;
     179       95967 :         bool sids_are_valid = false;
     180       95967 :         bool device_sids_are_valid = false;
     181       95967 :         bool authentication_was_compounded = session_info_flags & AUTH_SESSION_INFO_FORCE_COMPOUNDED_AUTHENTICATION;
     182             : 
     183             :         /*
     184             :          * Some special-case callers can't supply the lp_ctx, but do
     185             :          * not interact with claims or conditional ACEs
     186             :          */
     187       95967 :         if (lp_ctx == NULL) {
     188        1254 :                 evaluate_claims = CLAIMS_EVALUATION_INVALID_STATE;
     189             :         } else {
     190       96877 :                 enum acl_claims_evaluation claims_evaultion_setting
     191       94713 :                         = lpcfg_acl_claims_evaluation(lp_ctx);
     192             : 
     193             :                 /*
     194             :                  * We are well inside the AD DC, so we do not need to check
     195             :                  * the server role etc
     196             :                  */
     197       94713 :                 switch (claims_evaultion_setting) {
     198       92549 :                 case ACL_CLAIMS_EVALUATION_AD_DC_ONLY:
     199       92549 :                         evaluate_claims = CLAIMS_EVALUATION_ALWAYS;
     200       92549 :                         break;
     201           0 :                 default:
     202           0 :                         evaluate_claims = CLAIMS_EVALUATION_NEVER;
     203             :                 }
     204             :         }
     205             : 
     206       95967 :         ptoken = security_token_initialise(mem_ctx, evaluate_claims);
     207       95967 :         NT_STATUS_HAVE_NO_MEMORY(ptoken);
     208             : 
     209       95967 :         if (num_sids > UINT32_MAX - 6) {
     210           0 :                 talloc_free(ptoken);
     211           0 :                 return NT_STATUS_INVALID_PARAMETER;
     212             :         }
     213       95967 :         ptoken->sids = talloc_array(ptoken, struct dom_sid, num_sids + 6 /* over-allocate */);
     214       95967 :         if (ptoken->sids == NULL) {
     215           0 :                 talloc_free(ptoken);
     216           0 :                 return NT_STATUS_NO_MEMORY;
     217             :         }
     218             : 
     219       95967 :         ptoken->num_sids = 0;
     220             : 
     221      810530 :         for (i = 0; i < num_sids; i++) {
     222             :                 uint32_t check_sid_idx;
     223      697351 :                 for (check_sid_idx = 0;
     224     4750793 :                      check_sid_idx < ptoken->num_sids;
     225     4036230 :                      check_sid_idx++) {
     226     4083386 :                         if (dom_sid_equal(&ptoken->sids[check_sid_idx], &sids[i].sid)) {
     227       46025 :                                 break;
     228             :                         }
     229             :                 }
     230             : 
     231      714563 :                 if (check_sid_idx == ptoken->num_sids) {
     232      667407 :                         const struct dom_sid *sid = &sids[i].sid;
     233             : 
     234      667407 :                         sids_are_valid = sids_are_valid || dom_sid_equal(
     235             :                                 sid, &global_sid_Claims_Valid);
     236      667407 :                         authentication_was_compounded = authentication_was_compounded || dom_sid_equal(
     237             :                                 sid, &global_sid_Compounded_Authentication);
     238             : 
     239      667407 :                         ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid, ptoken->num_sids + 1);
     240      667407 :                         if (ptoken->sids == NULL) {
     241           0 :                                 talloc_free(ptoken);
     242           0 :                                 return NT_STATUS_NO_MEMORY;
     243             :                         }
     244             : 
     245      667407 :                         ptoken->sids[ptoken->num_sids] = *sid;
     246      667407 :                         ptoken->num_sids++;
     247             :                 }
     248             :         }
     249             : 
     250       95967 :         if (authentication_was_compounded && num_device_sids) {
     251         233 :                 ptoken->device_sids = talloc_array(ptoken, struct dom_sid, num_device_sids);
     252         233 :                 if (ptoken->device_sids == NULL) {
     253           0 :                         talloc_free(ptoken);
     254           0 :                         return NT_STATUS_NO_MEMORY;
     255             :                 }
     256        2060 :                 for (i = 0; i < num_device_sids; i++) {
     257             :                         uint32_t check_sid_idx;
     258        1827 :                         for (check_sid_idx = 0;
     259        6755 :                              check_sid_idx < ptoken->num_device_sids;
     260        4928 :                              check_sid_idx++) {
     261        5161 :                                 if (dom_sid_equal(&ptoken->device_sids[check_sid_idx], &device_sids[i].sid)) {
     262         233 :                                         break;
     263             :                                 }
     264             :                         }
     265             : 
     266        1827 :                         if (check_sid_idx == ptoken->num_device_sids) {
     267        1594 :                                 const struct dom_sid *device_sid = &device_sids[i].sid;
     268             : 
     269        1594 :                                 device_sids_are_valid = device_sids_are_valid || dom_sid_equal(
     270             :                                         device_sid, &global_sid_Claims_Valid);
     271             : 
     272        1594 :                                 ptoken->device_sids = talloc_realloc(ptoken,
     273             :                                                                      ptoken->device_sids,
     274             :                                                                      struct dom_sid,
     275             :                                                                      ptoken->num_device_sids + 1);
     276        1594 :                                 if (ptoken->device_sids == NULL) {
     277           0 :                                         talloc_free(ptoken);
     278           0 :                                         return NT_STATUS_NO_MEMORY;
     279             :                                 }
     280             : 
     281        1594 :                                 ptoken->device_sids[ptoken->num_device_sids] = *device_sid;
     282        1594 :                                 ptoken->num_device_sids++;
     283             :                         }
     284             :                 }
     285             :         }
     286             : 
     287             :         /* The caller may have requested simple privileges, for example if there isn't a local DB */
     288       95967 :         if (session_info_flags & AUTH_SESSION_INFO_SIMPLE_PRIVILEGES) {
     289             :                 /* Shortcuts to prevent recursion and avoid lookups */
     290       51676 :                 if (ptoken->sids == NULL) {
     291           0 :                         ptoken->privilege_mask = 0;
     292       51676 :                 } else if (security_token_is_system(ptoken)) {
     293        5884 :                         ptoken->privilege_mask = ~0;
     294       45792 :                 } else if (security_token_is_anonymous(ptoken)) {
     295       42335 :                         ptoken->privilege_mask = 0;
     296        3457 :                 } else if (security_token_has_builtin_administrators(ptoken)) {
     297        1259 :                         ptoken->privilege_mask = ~0;
     298             :                 } else {
     299             :                         /* All other 'users' get a empty priv set so far */
     300        2198 :                         ptoken->privilege_mask = 0;
     301             :                 }
     302             :         } else {
     303             :                 /* setup the privilege mask for this token */
     304       44291 :                 status = samdb_privilege_setup(lp_ctx, ptoken);
     305       44291 :                 if (!NT_STATUS_IS_OK(status)) {
     306           0 :                         talloc_free(ptoken);
     307           0 :                         DEBUG(1,("Unable to access privileges database\n"));
     308           0 :                         return status;
     309             :                 }
     310             :         }
     311             : 
     312             :         /*
     313             :          * TODO: we might want to regard ‘session_info_flags’ for the device
     314             :          * SIDs as well as for the client SIDs.
     315             :          */
     316             : 
     317       95967 :         if (sids_are_valid) {
     318       33224 :                 status = claims_data_security_claims(ptoken,
     319             :                                                      auth_claims.user_claims,
     320             :                                                      &ptoken->user_claims,
     321             :                                                      &ptoken->num_user_claims);
     322       33224 :                 if (!NT_STATUS_IS_OK(status)) {
     323          17 :                         talloc_free(ptoken);
     324          17 :                         return status;
     325             :                 }
     326             :         }
     327             : 
     328       95950 :         if (device_sids_are_valid && authentication_was_compounded) {
     329         201 :                 status = claims_data_security_claims(ptoken,
     330             :                                                      auth_claims.device_claims,
     331             :                                                      &ptoken->device_claims,
     332             :                                                      &ptoken->num_device_claims);
     333         201 :                 if (!NT_STATUS_IS_OK(status)) {
     334           0 :                         talloc_free(ptoken);
     335           0 :                         return status;
     336             :                 }
     337             :         }
     338             : 
     339       95950 :         security_token_debug(0, 10, ptoken);
     340             : 
     341       95950 :         *token = ptoken;
     342             : 
     343       95950 :         return NT_STATUS_OK;
     344             : }

Generated by: LCOV version 1.14