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

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    msDS-ManagedPassword attribute for Group Managed Service Accounts
       4             : 
       5             :    Copyright (C) Catalyst.Net Ltd 2024
       6             : 
       7             :    This program is free software: you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation, either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <https://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include <talloc.h>
      23             : #include <ldb.h>
      24             : #include <ldb_module.h>
      25             : #include <ldb_errors.h>
      26             : #include <ldb_private.h>
      27             : #include "lib/crypto/gmsa.h"
      28             : #include "lib/util/time.h"
      29             : #include "librpc/gen_ndr/ndr_gkdi.h"
      30             : #include "librpc/gen_ndr/ndr_gmsa.h"
      31             : #include "dsdb/gmsa/util.h"
      32             : #include "dsdb/samdb/ldb_modules/managed_pwd.h"
      33             : #include "dsdb/samdb/ldb_modules/util.h"
      34             : #include "dsdb/samdb/samdb.h"
      35             : 
      36             : #undef strcasecmp
      37             : 
      38        4877 : static int gmsa_managed_password(struct ldb_context *const ldb,
      39             :                                  struct ldb_message *msg,
      40             :                                  struct ldb_request *req,
      41             :                                  struct ldb_reply *ares)
      42             : {
      43        4877 :         TALLOC_CTX *tmp_ctx = NULL;
      44        4877 :         const struct dsdb_encrypted_connection_state *conn_state = NULL;
      45        4877 :         int ret = LDB_SUCCESS;
      46        4877 :         NTSTATUS status = NT_STATUS_OK;
      47          12 :         NTTIME current_time;
      48        4877 :         struct gmsa_update *gmsa_update = NULL;
      49          12 :         struct gmsa_return_pwd return_pwd;
      50          12 :         bool ok;
      51             : 
      52             :         /*
      53             :          * Prevent viewing msDS-ManagedPassword over an insecure connection. The
      54             :          * opaque is added in the ldap backend init.
      55             :          */
      56        4877 :         conn_state = ldb_get_opaque(
      57             :                 ldb, DSDB_OPAQUE_ENCRYPTED_CONNECTION_STATE_NAME);
      58        4877 :         if (conn_state != NULL && !conn_state->using_encrypted_connection) {
      59           0 :                 ret = dsdb_werror(ldb,
      60             :                                   LDB_ERR_OPERATIONS_ERROR,
      61             :                                   WERR_DS_CONFIDENTIALITY_REQUIRED,
      62             :                                   "Viewing msDS-ManagedPassword requires an "
      63             :                                   "encrypted connection");
      64           0 :                 goto out;
      65             :         }
      66             : 
      67             :         {
      68             :                 /* Is the account a Group Managed Service Account? */
      69        4877 :                 const bool is_gmsa = dsdb_account_is_gmsa(ldb, msg);
      70        4877 :                 if (!is_gmsa) {
      71             :                         /* It’s not a GMSA — we’re done here. */
      72        4835 :                         ret = LDB_SUCCESS;
      73        4835 :                         goto out;
      74             :                 }
      75             :         }
      76             : 
      77             :         {
      78          42 :                 bool am_rodc = true;
      79             : 
      80             :                 /* Are we operating as an RODC? */
      81          42 :                 ret = samdb_rodc(ldb, &am_rodc);
      82          42 :                 if (ret != LDB_SUCCESS) {
      83           0 :                         DBG_WARNING("unable to tell if we are an RODC\n");
      84           0 :                         goto out;
      85             :                 }
      86             : 
      87          42 :                 if (am_rodc) {
      88             :                         /* TODO: forward the request to a writable DC. */
      89           0 :                         ret = ldb_error(
      90             :                                 ldb,
      91             :                                 LDB_ERR_OPERATIONS_ERROR,
      92             :                                 "msDS-ManagedPassword may only be viewed on a "
      93             :                                 "writeable DC, not an RODC");
      94           0 :                         goto out;
      95             :                 }
      96             :         }
      97             : 
      98          42 :         tmp_ctx = talloc_new(msg);
      99          42 :         if (tmp_ctx == NULL) {
     100           0 :                 ret = ldb_oom(ldb);
     101           0 :                 goto out;
     102             :         }
     103             : 
     104             :         {
     105           0 :                 struct dom_sid account_sid;
     106          42 :                 bool allowed_to_view = false;
     107             : 
     108          42 :                 ret = samdb_result_dom_sid_buf(msg, "objectSid", &account_sid);
     109          42 :                 if (ret) {
     110           7 :                         goto out;
     111             :                 }
     112             : 
     113          42 :                 ret = gmsa_allowed_to_view_managed_password(
     114             :                         tmp_ctx, ldb, msg, &account_sid, &allowed_to_view);
     115          42 :                 if (ret) {
     116           0 :                         goto out;
     117             :                 }
     118             : 
     119          42 :                 if (!allowed_to_view) {
     120             :                         /* Sorry, you can’t view the password. */
     121           7 :                         goto out;
     122             :                 }
     123             :         }
     124             : 
     125          35 :         ok = dsdb_gmsa_current_time(ldb, &current_time);
     126          35 :         if (!ok) {
     127           0 :                 ret = ldb_operr(ldb);
     128           0 :                 goto out;
     129             :         }
     130             : 
     131          35 :         ret = gmsa_recalculate_managed_pwd(
     132             :                 tmp_ctx, ldb, msg, current_time, &gmsa_update, &return_pwd);
     133          35 :         if (ret) {
     134           0 :                 goto out;
     135             :         }
     136             : 
     137          35 :         SMB_ASSERT(return_pwd.new_pwd != NULL);
     138             : 
     139             :         {
     140          35 :                 DATA_BLOB packed_blob = {};
     141             : 
     142          23 :                 status = gmsa_pack_managed_pwd(
     143             :                         tmp_ctx,
     144          35 :                         return_pwd.new_pwd->buf,
     145          35 :                         return_pwd.prev_pwd != NULL ? return_pwd.prev_pwd->buf
     146             :                                                     : NULL,
     147             :                         return_pwd.query_interval,
     148             :                         return_pwd.unchanged_interval,
     149             :                         &packed_blob);
     150          35 :                 if (!NT_STATUS_IS_OK(status)) {
     151           0 :                         ret = ldb_operr(ldb);
     152           0 :                         goto out;
     153             :                 }
     154             : 
     155          35 :                 ret = ldb_msg_add_steal_value(msg,
     156             :                                               "msDS-ManagedPassword",
     157             :                                               &packed_blob);
     158          35 :                 if (ret) {
     159           0 :                         goto out;
     160             :                 }
     161             :         }
     162             : 
     163        4865 : out:
     164        4877 :         TALLOC_FREE(tmp_ctx);
     165        4877 :         return ret;
     166             : }
     167             : 
     168        4877 : int constructed_msds_managed_password(struct ldb_module *module,
     169             :                                       struct ldb_message *msg,
     170             :                                       enum ldb_scope scope,
     171             :                                       struct ldb_request *parent,
     172             :                                       struct ldb_reply *ares)
     173             : {
     174        4877 :         return gmsa_managed_password(ldb_module_get_ctx(module),
     175             :                                      msg,
     176             :                                      parent,
     177             :                                      ares);
     178             : }

Generated by: LCOV version 1.14