LCOV - code coverage report
Current view: top level - source3/passdb - machine_account_secrets.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 527 1008 52.3 %
Date: 2024-06-13 04:01:37 Functions: 36 45 80.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Copyright (C) Andrew Tridgell 1992-2001
       4             :    Copyright (C) Andrew Bartlett      2002
       5             :    Copyright (C) Rafal Szczesniak     2002
       6             :    Copyright (C) Tim Potter           2001
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : /* the Samba secrets database stores any generated, private information
      23             :    such as the local SID and machine trust password */
      24             : 
      25             : #include "includes.h"
      26             : #include "passdb.h"
      27             : #include "../libcli/auth/libcli_auth.h"
      28             : #include "secrets.h"
      29             : #include "dbwrap/dbwrap.h"
      30             : #include "../librpc/ndr/libndr.h"
      31             : #include "util_tdb.h"
      32             : #include "libcli/security/security.h"
      33             : 
      34             : #include "librpc/gen_ndr/libnet_join.h"
      35             : #include "librpc/gen_ndr/ndr_secrets.h"
      36             : #include "lib/crypto/crypto.h"
      37             : #include "lib/krb5_wrap/krb5_samba.h"
      38             : #include "lib/util/time_basic.h"
      39             : #include "../libds/common/flags.h"
      40             : #include "lib/util/string_wrappers.h"
      41             : 
      42             : #undef DBGC_CLASS
      43             : #define DBGC_CLASS DBGC_PASSDB
      44             : 
      45             : static char *domain_info_keystr(const char *domain);
      46             : 
      47             : static char *des_salt_key(const char *realm);
      48             : 
      49             : /**
      50             :  * Form a key for fetching the domain sid
      51             :  *
      52             :  * @param domain domain name
      53             :  *
      54             :  * @return keystring
      55             :  **/
      56        7506 : static const char *domain_sid_keystr(const char *domain)
      57             : {
      58             :         char *keystr;
      59             : 
      60        7506 :         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
      61             :                                             SECRETS_DOMAIN_SID, domain);
      62        7506 :         SMB_ASSERT(keystr != NULL);
      63        7506 :         return keystr;
      64             : }
      65             : 
      66        4070 : static const char *domain_guid_keystr(const char *domain)
      67             : {
      68             :         char *keystr;
      69             : 
      70        4070 :         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
      71             :                                             SECRETS_DOMAIN_GUID, domain);
      72        4070 :         SMB_ASSERT(keystr != NULL);
      73        4070 :         return keystr;
      74             : }
      75             : 
      76         743 : static const char *protect_ids_keystr(const char *domain)
      77             : {
      78             :         char *keystr;
      79             : 
      80         743 :         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
      81             :                                             SECRETS_PROTECT_IDS, domain);
      82         743 :         SMB_ASSERT(keystr != NULL);
      83         743 :         return keystr;
      84             : }
      85             : 
      86             : /* N O T E: never use this outside of passdb modules that store the SID on their own */
      87         129 : bool secrets_mark_domain_protected(const char *domain)
      88             : {
      89             :         bool ret;
      90             : 
      91         129 :         ret = secrets_store(protect_ids_keystr(domain), "TRUE", 5);
      92         129 :         if (!ret) {
      93           0 :                 DEBUG(0, ("Failed to protect the Domain IDs\n"));
      94             :         }
      95         129 :         return ret;
      96             : }
      97             : 
      98         129 : bool secrets_clear_domain_protection(const char *domain)
      99             : {
     100             :         bool ret;
     101         129 :         void *protection = secrets_fetch(protect_ids_keystr(domain), NULL);
     102             : 
     103         129 :         if (protection) {
     104          39 :                 SAFE_FREE(protection);
     105          39 :                 ret = secrets_delete_entry(protect_ids_keystr(domain));
     106          39 :                 if (!ret) {
     107           0 :                         DEBUG(0, ("Failed to remove Domain IDs protection\n"));
     108             :                 }
     109          39 :                 return ret;
     110             :         }
     111          90 :         return true;
     112             : }
     113             : 
     114         354 : bool secrets_store_domain_sid(const char *domain, const struct dom_sid  *sid)
     115             : {
     116             :         char *protect_ids;
     117             :         bool ret;
     118         354 :         struct dom_sid clean_sid = { 0 };
     119             : 
     120         354 :         protect_ids = secrets_fetch(protect_ids_keystr(domain), NULL);
     121         354 :         if (protect_ids) {
     122          48 :                 if (strncmp(protect_ids, "TRUE", 4)) {
     123           0 :                         DEBUG(0, ("Refusing to store a Domain SID, "
     124             :                                   "it has been marked as protected!\n"));
     125           0 :                         SAFE_FREE(protect_ids);
     126           0 :                         return false;
     127             :                 }
     128             :         }
     129         354 :         SAFE_FREE(protect_ids);
     130             : 
     131             :         /*
     132             :          * use a copy to prevent uninitialized memory from being carried over
     133             :          * to the tdb
     134             :          */
     135         354 :         sid_copy(&clean_sid, sid);
     136             : 
     137         354 :         ret = secrets_store(domain_sid_keystr(domain),
     138             :                             &clean_sid,
     139             :                             sizeof(struct dom_sid));
     140             : 
     141             :         /* Force a re-query, in the case where we modified our domain */
     142         354 :         if (ret) {
     143         354 :                 if (dom_sid_equal(get_global_sam_sid(), sid) == false) {
     144         167 :                         reset_global_sam_sid();
     145             :                 }
     146             :         }
     147         354 :         return ret;
     148             : }
     149             : 
     150        7121 : bool secrets_fetch_domain_sid(const char *domain, struct dom_sid  *sid)
     151             : {
     152             :         struct dom_sid  *dyn_sid;
     153        7121 :         size_t size = 0;
     154             : 
     155        7121 :         dyn_sid = (struct dom_sid  *)secrets_fetch(domain_sid_keystr(domain), &size);
     156             : 
     157        7121 :         if (dyn_sid == NULL)
     158         171 :                 return False;
     159             : 
     160        6950 :         if (size != sizeof(struct dom_sid)) {
     161           0 :                 SAFE_FREE(dyn_sid);
     162           0 :                 return False;
     163             :         }
     164             : 
     165        6950 :         *sid = *dyn_sid;
     166        6950 :         SAFE_FREE(dyn_sid);
     167        6950 :         return True;
     168             : }
     169             : 
     170          92 : bool secrets_store_domain_guid(const char *domain, const struct GUID *guid)
     171             : {
     172             :         char *protect_ids;
     173             :         const char *key;
     174             : 
     175          92 :         protect_ids = secrets_fetch(protect_ids_keystr(domain), NULL);
     176          92 :         if (protect_ids) {
     177           0 :                 if (strncmp(protect_ids, "TRUE", 4)) {
     178           0 :                         DEBUG(0, ("Refusing to store a Domain SID, "
     179             :                                   "it has been marked as protected!\n"));
     180           0 :                         SAFE_FREE(protect_ids);
     181           0 :                         return false;
     182             :                 }
     183             :         }
     184          92 :         SAFE_FREE(protect_ids);
     185             : 
     186          92 :         key = domain_guid_keystr(domain);
     187          92 :         return secrets_store(key, guid, sizeof(struct GUID));
     188             : }
     189             : 
     190        3947 : bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
     191             : {
     192             :         struct GUID *dyn_guid;
     193             :         const char *key;
     194        3947 :         size_t size = 0;
     195             :         struct GUID new_guid;
     196             : 
     197        3947 :         key = domain_guid_keystr(domain);
     198        3947 :         dyn_guid = (struct GUID *)secrets_fetch(key, &size);
     199             : 
     200        3947 :         if (!dyn_guid) {
     201         144 :                 if (lp_server_role() == ROLE_DOMAIN_PDC ||
     202          72 :                     lp_server_role() == ROLE_IPA_DC) {
     203           0 :                         new_guid = GUID_random();
     204           0 :                         if (!secrets_store_domain_guid(domain, &new_guid))
     205           0 :                                 return False;
     206           0 :                         dyn_guid = (struct GUID *)secrets_fetch(key, &size);
     207             :                 }
     208          72 :                 if (dyn_guid == NULL) {
     209          72 :                         return False;
     210             :                 }
     211             :         }
     212             : 
     213        3875 :         if (size != sizeof(struct GUID)) {
     214           0 :                 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
     215           0 :                 SAFE_FREE(dyn_guid);
     216           0 :                 return False;
     217             :         }
     218             : 
     219        3875 :         *guid = *dyn_guid;
     220        3875 :         SAFE_FREE(dyn_guid);
     221        3875 :         return True;
     222             : }
     223             : 
     224             : /**
     225             :  * Form a key for fetching the machine trust account sec channel type
     226             :  *
     227             :  * @param domain domain name
     228             :  *
     229             :  * @return keystring
     230             :  **/
     231         273 : static const char *machine_sec_channel_type_keystr(const char *domain)
     232             : {
     233             :         char *keystr;
     234             : 
     235         273 :         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
     236             :                                             SECRETS_MACHINE_SEC_CHANNEL_TYPE,
     237             :                                             domain);
     238         273 :         SMB_ASSERT(keystr != NULL);
     239         273 :         return keystr;
     240             : }
     241             : 
     242             : /**
     243             :  * Form a key for fetching the machine trust account last change time
     244             :  *
     245             :  * @param domain domain name
     246             :  *
     247             :  * @return keystring
     248             :  **/
     249        3634 : static const char *machine_last_change_time_keystr(const char *domain)
     250             : {
     251             :         char *keystr;
     252             : 
     253        3634 :         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
     254             :                                             SECRETS_MACHINE_LAST_CHANGE_TIME,
     255             :                                             domain);
     256        3634 :         SMB_ASSERT(keystr != NULL);
     257        3634 :         return keystr;
     258             : }
     259             : 
     260             : 
     261             : /**
     262             :  * Form a key for fetching the machine previous trust account password
     263             :  *
     264             :  * @param domain domain name
     265             :  *
     266             :  * @return keystring
     267             :  **/
     268         237 : static const char *machine_prev_password_keystr(const char *domain)
     269             : {
     270             :         char *keystr;
     271             : 
     272         237 :         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
     273             :                                             SECRETS_MACHINE_PASSWORD_PREV, domain);
     274         237 :         SMB_ASSERT(keystr != NULL);
     275         237 :         return keystr;
     276             : }
     277             : 
     278             : /**
     279             :  * Form a key for fetching the machine trust account password
     280             :  *
     281             :  * @param domain domain name
     282             :  *
     283             :  * @return keystring
     284             :  **/
     285         301 : static const char *machine_password_keystr(const char *domain)
     286             : {
     287             :         char *keystr;
     288             : 
     289         301 :         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
     290             :                                             SECRETS_MACHINE_PASSWORD, domain);
     291         301 :         SMB_ASSERT(keystr != NULL);
     292         301 :         return keystr;
     293             : }
     294             : 
     295             : /**
     296             :  * Form a key for fetching the machine trust account password
     297             :  *
     298             :  * @param domain domain name
     299             :  *
     300             :  * @return stored password's key
     301             :  **/
     302           1 : static const char *trust_keystr(const char *domain)
     303             : {
     304             :         char *keystr;
     305             : 
     306           1 :         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
     307             :                                             SECRETS_MACHINE_ACCT_PASS, domain);
     308           1 :         SMB_ASSERT(keystr != NULL);
     309           1 :         return keystr;
     310             : }
     311             : 
     312             : /************************************************************************
     313             :  Routine to get the default secure channel type for trust accounts
     314             : ************************************************************************/
     315             : 
     316           3 : enum netr_SchannelType get_default_sec_channel(void)
     317             : {
     318           3 :         if (IS_DC) {
     319           1 :                 return SEC_CHAN_BDC;
     320             :         } else {
     321           2 :                 return SEC_CHAN_WKSTA;
     322             :         }
     323             : }
     324             : 
     325             : /************************************************************************
     326             :  Routine to get the trust account password for a domain.
     327             :  This only tries to get the legacy hashed version of the password.
     328             :  The user of this function must have locked the trust password file using
     329             :  the above secrets_lock_trust_account_password().
     330             : ************************************************************************/
     331             : 
     332           1 : bool secrets_fetch_trust_account_password_legacy(const char *domain,
     333             :                                                  uint8_t ret_pwd[16],
     334             :                                                  time_t *pass_last_set_time,
     335             :                                                  enum netr_SchannelType *channel)
     336             : {
     337             :         struct machine_acct_pass *pass;
     338           1 :         size_t size = 0;
     339             : 
     340           1 :         if (!(pass = (struct machine_acct_pass *)secrets_fetch(
     341             :                       trust_keystr(domain), &size))) {
     342           1 :                 DEBUG(5, ("secrets_fetch failed!\n"));
     343           1 :                 return False;
     344             :         }
     345             : 
     346           0 :         if (size != sizeof(*pass)) {
     347           0 :                 DEBUG(0, ("secrets were of incorrect size!\n"));
     348           0 :                 SAFE_FREE(pass);
     349           0 :                 return False;
     350             :         }
     351             : 
     352           0 :         if (pass_last_set_time) {
     353           0 :                 *pass_last_set_time = pass->mod_time;
     354             :         }
     355           0 :         memcpy(ret_pwd, pass->hash, 16);
     356             : 
     357           0 :         if (channel) {
     358           0 :                 *channel = get_default_sec_channel();
     359             :         }
     360             : 
     361           0 :         SAFE_FREE(pass);
     362           0 :         return True;
     363             : }
     364             : 
     365             : /************************************************************************
     366             :  Routine to get the trust account password for a domain.
     367             :  The user of this function must have locked the trust password file using
     368             :  the above secrets_lock_trust_account_password().
     369             : ************************************************************************/
     370             : 
     371           0 : bool secrets_fetch_trust_account_password(const char *domain, uint8_t ret_pwd[16],
     372             :                                           time_t *pass_last_set_time,
     373             :                                           enum netr_SchannelType *channel)
     374             : {
     375             :         char *plaintext;
     376             : 
     377           0 :         plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
     378             :                                                    channel);
     379           0 :         if (plaintext) {
     380           0 :                 DEBUG(4,("Using cleartext machine password\n"));
     381           0 :                 E_md4hash(plaintext, ret_pwd);
     382           0 :                 SAFE_FREE(plaintext);
     383           0 :                 return True;
     384             :         }
     385             : 
     386           0 :         return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
     387             :                                                            pass_last_set_time,
     388             :                                                            channel);
     389             : }
     390             : 
     391             : /************************************************************************
     392             :  Routine to delete all information related to the domain joined machine.
     393             : ************************************************************************/
     394             : 
     395          31 : bool secrets_delete_machine_password_ex(const char *domain, const char *realm)
     396             : {
     397          31 :         const char *tmpkey = NULL;
     398             :         bool ok;
     399             : 
     400          31 :         tmpkey = domain_info_keystr(domain);
     401          31 :         ok = secrets_delete(tmpkey);
     402          31 :         if (!ok) {
     403           0 :                 return false;
     404             :         }
     405             : 
     406          31 :         if (realm != NULL) {
     407          30 :                 tmpkey = des_salt_key(domain);
     408          30 :                 ok = secrets_delete(tmpkey);
     409          30 :                 if (!ok) {
     410           0 :                         return false;
     411             :                 }
     412             :         }
     413             : 
     414          31 :         tmpkey = domain_guid_keystr(domain);
     415          31 :         ok = secrets_delete(tmpkey);
     416          31 :         if (!ok) {
     417           0 :                 return false;
     418             :         }
     419             : 
     420          31 :         tmpkey = machine_prev_password_keystr(domain);
     421          31 :         ok = secrets_delete(tmpkey);
     422          31 :         if (!ok) {
     423           0 :                 return false;
     424             :         }
     425             : 
     426          31 :         tmpkey = machine_password_keystr(domain);
     427          31 :         ok = secrets_delete(tmpkey);
     428          31 :         if (!ok) {
     429           0 :                 return false;
     430             :         }
     431             : 
     432          31 :         tmpkey = machine_sec_channel_type_keystr(domain);
     433          31 :         ok = secrets_delete(tmpkey);
     434          31 :         if (!ok) {
     435           0 :                 return false;
     436             :         }
     437             : 
     438          31 :         tmpkey = machine_last_change_time_keystr(domain);
     439          31 :         ok = secrets_delete(tmpkey);
     440          31 :         if (!ok) {
     441           0 :                 return false;
     442             :         }
     443             : 
     444          31 :         tmpkey = domain_sid_keystr(domain);
     445          31 :         ok = secrets_delete(tmpkey);
     446          31 :         if (!ok) {
     447           0 :                 return false;
     448             :         }
     449             : 
     450          31 :         return true;
     451             : }
     452             : 
     453             : /************************************************************************
     454             :  Routine to delete the domain sid
     455             : ************************************************************************/
     456             : 
     457           0 : bool secrets_delete_domain_sid(const char *domain)
     458             : {
     459           0 :         return secrets_delete_entry(domain_sid_keystr(domain));
     460             : }
     461             : 
     462             : /************************************************************************
     463             :  Set the machine trust account password, the old pw and last change
     464             :  time, domain SID and salting principals based on values passed in
     465             :  (added to support the secrets_tdb_sync module on secrets.ldb)
     466             : ************************************************************************/
     467             : 
     468         198 : bool secrets_store_machine_pw_sync(const char *pass, const char *oldpass, const char *domain,
     469             :                                    const char *realm,
     470             :                                    const char *salting_principal, uint32_t supported_enc_types,
     471             :                                    const struct dom_sid *domain_sid, uint32_t last_change_time,
     472             :                                    uint32_t secure_channel_type,
     473             :                                    bool delete_join)
     474             : {
     475             :         bool ret;
     476             :         uint8_t last_change_time_store[4];
     477         198 :         TALLOC_CTX *frame = talloc_stackframe();
     478             :         uint8_t sec_channel_bytes[4];
     479             : 
     480         198 :         if (delete_join) {
     481           0 :                 secrets_delete_machine_password_ex(domain, realm);
     482           0 :                 TALLOC_FREE(frame);
     483           0 :                 return true;
     484             :         }
     485             : 
     486         198 :         ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
     487         198 :         if (!ret) {
     488           0 :                 TALLOC_FREE(frame);
     489           0 :                 return ret;
     490             :         }
     491             : 
     492         198 :         if (oldpass) {
     493          39 :                 ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
     494             :         } else {
     495         159 :                 ret = secrets_delete(machine_prev_password_keystr(domain));
     496             :         }
     497         198 :         if (!ret) {
     498           0 :                 TALLOC_FREE(frame);
     499           0 :                 return ret;
     500             :         }
     501             : 
     502         198 :         if (secure_channel_type == 0) {
     503             :                 /* We delete this and instead have the read code fall back to
     504             :                  * a default based on server role, as our caller can't specify
     505             :                  * this with any more certainty */
     506           0 :                 ret = secrets_delete(machine_sec_channel_type_keystr(domain));
     507           0 :                 if (!ret) {
     508           0 :                         TALLOC_FREE(frame);
     509           0 :                         return ret;
     510             :                 }
     511             :         } else {
     512         198 :                 SIVAL(&sec_channel_bytes, 0, secure_channel_type);
     513         198 :                 ret = secrets_store(machine_sec_channel_type_keystr(domain),
     514             :                                     &sec_channel_bytes, sizeof(sec_channel_bytes));
     515         198 :                 if (!ret) {
     516           0 :                         TALLOC_FREE(frame);
     517           0 :                         return ret;
     518             :                 }
     519             :         }
     520             : 
     521         198 :         SIVAL(&last_change_time_store, 0, last_change_time);
     522         198 :         ret = secrets_store(machine_last_change_time_keystr(domain),
     523             :                             &last_change_time_store, sizeof(last_change_time));
     524             : 
     525         198 :         if (!ret) {
     526           0 :                 TALLOC_FREE(frame);
     527           0 :                 return ret;
     528             :         }
     529             : 
     530         198 :         ret = secrets_store_domain_sid(domain, domain_sid);
     531             : 
     532         198 :         if (!ret) {
     533           0 :                 TALLOC_FREE(frame);
     534           0 :                 return ret;
     535             :         }
     536             : 
     537         198 :         if (realm != NULL) {
     538         197 :                 char *key = des_salt_key(realm);
     539             : 
     540         197 :                 if (salting_principal != NULL) {
     541         197 :                         ret = secrets_store(key,
     542             :                                             salting_principal,
     543         197 :                                             strlen(salting_principal)+1);
     544             :                 } else {
     545           0 :                         ret = secrets_delete(key);
     546             :                 }
     547             :         }
     548             : 
     549         198 :         TALLOC_FREE(frame);
     550         198 :         return ret;
     551             : }
     552             : 
     553             : /************************************************************************
     554             :  Return the standard DES salt key
     555             : ************************************************************************/
     556             : 
     557          26 : char* kerberos_standard_des_salt( void )
     558             : {
     559             :         fstring salt;
     560             : 
     561          26 :         fstr_sprintf( salt, "host/%s.%s@", lp_netbios_name(), lp_realm() );
     562          26 :         (void)strlower_m( salt );
     563          26 :         fstrcat( salt, lp_realm() );
     564             : 
     565          26 :         return SMB_STRDUP( salt );
     566             : }
     567             : 
     568             : /************************************************************************
     569             : ************************************************************************/
     570             : 
     571         235 : static char *des_salt_key(const char *realm)
     572             : {
     573             :         char *keystr;
     574             : 
     575         235 :         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/DES/%s",
     576             :                                             SECRETS_SALTING_PRINCIPAL,
     577             :                                             realm);
     578         235 :         SMB_ASSERT(keystr != NULL);
     579         235 :         return keystr;
     580             : }
     581             : 
     582             : /************************************************************************
     583             : ************************************************************************/
     584             : 
     585           0 : bool kerberos_secrets_store_des_salt( const char* salt )
     586             : {
     587             :         char* key;
     588             :         bool ret;
     589             : 
     590           0 :         key = des_salt_key(lp_realm());
     591           0 :         if (key == NULL) {
     592           0 :                 DEBUG(0,("kerberos_secrets_store_des_salt: failed to generate key!\n"));
     593           0 :                 return False;
     594             :         }
     595             : 
     596           0 :         if ( !salt ) {
     597           0 :                 DEBUG(8,("kerberos_secrets_store_des_salt: deleting salt\n"));
     598           0 :                 secrets_delete_entry( key );
     599           0 :                 return True;
     600             :         }
     601             : 
     602           0 :         DEBUG(3,("kerberos_secrets_store_des_salt: Storing salt \"%s\"\n", salt));
     603             : 
     604           0 :         ret = secrets_store( key, salt, strlen(salt)+1 );
     605             : 
     606           0 :         TALLOC_FREE(key);
     607             : 
     608           0 :         return ret;
     609             : }
     610             : 
     611             : /************************************************************************
     612             : ************************************************************************/
     613             : 
     614             : static
     615           8 : char* kerberos_secrets_fetch_des_salt( void )
     616             : {
     617             :         char *salt, *key;
     618             : 
     619           8 :         key = des_salt_key(lp_realm());
     620           8 :         if (key == NULL) {
     621           0 :                 DEBUG(0,("kerberos_secrets_fetch_des_salt: failed to generate key!\n"));
     622           0 :                 return NULL;
     623             :         }
     624             : 
     625           8 :         salt = (char*)secrets_fetch( key, NULL );
     626             : 
     627           8 :         TALLOC_FREE(key);
     628             : 
     629           8 :         return salt;
     630             : }
     631             : 
     632             : /************************************************************************
     633             :  Routine to get the salting principal for this service.
     634             :  Caller must free if return is not null.
     635             :  ************************************************************************/
     636             : 
     637           8 : char *kerberos_secrets_fetch_salt_princ(void)
     638             : {
     639             :         char *salt_princ_s;
     640             :         /* lookup new key first */
     641             : 
     642           8 :         salt_princ_s = kerberos_secrets_fetch_des_salt();
     643           8 :         if (salt_princ_s == NULL) {
     644             :                 /* fall back to host/machine.realm@REALM */
     645           0 :                 salt_princ_s = kerberos_standard_des_salt();
     646             :         }
     647             : 
     648           8 :         return salt_princ_s;
     649             : }
     650             : 
     651             : /************************************************************************
     652             :  Routine to fetch the previous plaintext machine account password for a realm
     653             :  the password is assumed to be a null terminated ascii string.
     654             : ************************************************************************/
     655             : 
     656           8 : char *secrets_fetch_prev_machine_password(const char *domain)
     657             : {
     658           8 :         return (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
     659             : }
     660             : 
     661             : /************************************************************************
     662             :  Routine to fetch the last change time of the machine account password
     663             :   for a realm
     664             : ************************************************************************/
     665             : 
     666        3405 : time_t secrets_fetch_pass_last_set_time(const char *domain)
     667             : {
     668             :         uint32_t *last_set_time;
     669             :         time_t pass_last_set_time;
     670             : 
     671        3405 :         last_set_time = secrets_fetch(machine_last_change_time_keystr(domain),
     672             :                                       NULL);
     673        3405 :         if (last_set_time) {
     674        3379 :                 pass_last_set_time = IVAL(last_set_time,0);
     675        3379 :                 SAFE_FREE(last_set_time);
     676             :         } else {
     677          26 :                 pass_last_set_time = 0;
     678             :         }
     679             : 
     680        3405 :         return pass_last_set_time;
     681             : }
     682             : 
     683             : /************************************************************************
     684             :  Routine to fetch the plaintext machine account password for a realm
     685             :  the password is assumed to be a null terminated ascii string.
     686             : ************************************************************************/
     687             : 
     688          72 : char *secrets_fetch_machine_password(const char *domain,
     689             :                                      time_t *pass_last_set_time,
     690             :                                      enum netr_SchannelType *channel)
     691             : {
     692             :         char *ret;
     693          72 :         ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
     694             : 
     695          72 :         if (pass_last_set_time) {
     696          44 :                 *pass_last_set_time = secrets_fetch_pass_last_set_time(domain);
     697             :         }
     698             : 
     699          72 :         if (channel) {
     700             :                 size_t size;
     701             :                 uint32_t *channel_type;
     702          44 :                 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
     703          44 :                 if (channel_type) {
     704          43 :                         *channel = IVAL(channel_type,0);
     705          43 :                         SAFE_FREE(channel_type);
     706             :                 } else {
     707           1 :                         *channel = get_default_sec_channel();
     708             :                 }
     709             :         }
     710             : 
     711          72 :         return ret;
     712             : }
     713             : 
     714        3406 : static char *domain_info_keystr(const char *domain)
     715             : {
     716             :         char *keystr;
     717             : 
     718        3406 :         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
     719             :                                             SECRETS_MACHINE_DOMAIN_INFO,
     720             :                                             domain);
     721        3406 :         SMB_ASSERT(keystr != NULL);
     722        3406 :         return keystr;
     723             : }
     724             : 
     725             : /************************************************************************
     726             :  Routine to get account password to trusted domain
     727             : ************************************************************************/
     728             : 
     729        3340 : static NTSTATUS secrets_fetch_domain_info1_by_key(const char *key,
     730             :                                 TALLOC_CTX *mem_ctx,
     731             :                                 struct secrets_domain_info1 **_info1)
     732             : {
     733        3340 :         struct secrets_domain_infoB sdib = { .version = 0, };
     734             :         enum ndr_err_code ndr_err;
     735             :         /* unpacking structures */
     736             :         DATA_BLOB blob;
     737             : 
     738             :         /* fetching trusted domain password structure */
     739        3340 :         blob.data = (uint8_t *)secrets_fetch(key, &blob.length);
     740        3340 :         if (blob.data == NULL) {
     741           8 :                 DBG_NOTICE("secrets_fetch failed!\n");
     742           8 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
     743             :         }
     744             : 
     745             :         /* unpack trusted domain password */
     746        3332 :         ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sdib,
     747             :                         (ndr_pull_flags_fn_t)ndr_pull_secrets_domain_infoB);
     748        3332 :         SAFE_FREE(blob.data);
     749        3332 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     750           0 :                 DBG_ERR("ndr_pull_struct_blob failed - %s!\n",
     751             :                         ndr_errstr(ndr_err));
     752           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     753             :         }
     754             : 
     755        3332 :         if (sdib.version != SECRETS_DOMAIN_INFO_VERSION_1) {
     756           0 :                 DBG_ERR("sdib.version = %u\n", (unsigned)sdib.version);
     757           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     758             :         }
     759             : 
     760        3332 :         *_info1 = sdib.info.info1;
     761        3332 :         return NT_STATUS_OK;;
     762             : }
     763             : 
     764        3340 : static NTSTATUS secrets_fetch_domain_info(const char *domain,
     765             :                                           TALLOC_CTX *mem_ctx,
     766             :                                           struct secrets_domain_info1 **pinfo)
     767             : {
     768        3340 :         char *key = domain_info_keystr(domain);
     769        3340 :         return secrets_fetch_domain_info1_by_key(key, mem_ctx, pinfo);
     770             : }
     771             : 
     772          35 : void secrets_debug_domain_info(int lvl, const struct secrets_domain_info1 *info1,
     773             :                                const char *name)
     774             : {
     775          35 :         struct secrets_domain_infoB sdib = {
     776             :                 .version = SECRETS_DOMAIN_INFO_VERSION_1,
     777             :         };
     778             : 
     779          35 :         sdib.info.info1 = discard_const_p(struct secrets_domain_info1, info1);
     780             : 
     781          35 :         NDR_PRINT_DEBUG_LEVEL(lvl, secrets_domain_infoB, &sdib);
     782          35 : }
     783             : 
     784           1 : char *secrets_domain_info_string(TALLOC_CTX *mem_ctx, const struct secrets_domain_info1 *info1,
     785             :                                  const char *name, bool include_secrets)
     786             : {
     787           1 :         TALLOC_CTX *frame = talloc_stackframe();
     788           1 :         struct secrets_domain_infoB sdib = {
     789             :                 .version = SECRETS_DOMAIN_INFO_VERSION_1,
     790             :         };
     791           1 :         struct ndr_print *ndr = NULL;
     792           1 :         char *ret = NULL;
     793             : 
     794           1 :         sdib.info.info1 = discard_const_p(struct secrets_domain_info1, info1);
     795             : 
     796           1 :         ndr = talloc_zero(frame, struct ndr_print);
     797           1 :         if (ndr == NULL) {
     798           0 :                 TALLOC_FREE(frame);
     799           0 :                 return NULL;
     800             :         }
     801           1 :         ndr->private_data = talloc_strdup(ndr, "");
     802           1 :         if (ndr->private_data == NULL) {
     803           0 :                 TALLOC_FREE(frame);
     804           0 :                 return NULL;
     805             :         }
     806           1 :         ndr->print = ndr_print_string_helper;
     807           1 :         ndr->depth = 1;
     808           1 :         ndr->print_secrets = include_secrets;
     809             : 
     810           1 :         ndr_print_secrets_domain_infoB(ndr, name, &sdib);
     811           1 :         ret = talloc_steal(mem_ctx, (char *)ndr->private_data);
     812           1 :         TALLOC_FREE(frame);
     813           1 :         return ret;
     814             : }
     815             : 
     816          31 : static NTSTATUS secrets_store_domain_info1_by_key(const char *key,
     817             :                                         const struct secrets_domain_info1 *info1)
     818             : {
     819          31 :         struct secrets_domain_infoB sdib = {
     820             :                 .version = SECRETS_DOMAIN_INFO_VERSION_1,
     821             :         };
     822             :         /* packing structures */
     823             :         DATA_BLOB blob;
     824             :         enum ndr_err_code ndr_err;
     825             :         bool ok;
     826             : 
     827          31 :         sdib.info.info1 = discard_const_p(struct secrets_domain_info1, info1);
     828             : 
     829          31 :         ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &sdib,
     830             :                         (ndr_push_flags_fn_t)ndr_push_secrets_domain_infoB);
     831          31 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     832           0 :                 return ndr_map_error2ntstatus(ndr_err);
     833             :         }
     834             : 
     835          31 :         ok = secrets_store(key, blob.data, blob.length);
     836          31 :         data_blob_clear_free(&blob);
     837          31 :         if (!ok) {
     838           0 :                 return NT_STATUS_INTERNAL_DB_ERROR;
     839             :         }
     840             : 
     841          31 :         return NT_STATUS_OK;
     842             : }
     843             : 
     844          35 : static NTSTATUS secrets_store_domain_info(const struct secrets_domain_info1 *info,
     845             :                                           bool upgrade)
     846             : {
     847          35 :         TALLOC_CTX *frame = talloc_stackframe();
     848          35 :         const char *domain = info->domain_info.name.string;
     849          35 :         const char *realm = info->domain_info.dns_domain.string;
     850          35 :         char *key = domain_info_keystr(domain);
     851          35 :         struct db_context *db = NULL;
     852             :         struct timeval last_change_tv;
     853          35 :         const DATA_BLOB *cleartext_blob = NULL;
     854          35 :         DATA_BLOB pw_blob = data_blob_null;
     855          35 :         DATA_BLOB old_pw_blob = data_blob_null;
     856          35 :         const char *pw = NULL;
     857          35 :         const char *old_pw = NULL;
     858             :         bool ok;
     859             :         NTSTATUS status;
     860             :         int ret;
     861          35 :         int role = lp_server_role();
     862             : 
     863          35 :         switch (info->secure_channel_type) {
     864          31 :         case SEC_CHAN_WKSTA:
     865             :         case SEC_CHAN_BDC:
     866          31 :                 if (!upgrade && role >= ROLE_ACTIVE_DIRECTORY_DC) {
     867           0 :                         DBG_ERR("AD_DC not supported for %s\n",
     868             :                                 domain);
     869           0 :                         TALLOC_FREE(frame);
     870           0 :                         return NT_STATUS_INTERNAL_ERROR;
     871             :                 }
     872             : 
     873          31 :                 break;
     874           4 :         default:
     875           4 :                 DBG_ERR("SEC_CHAN_* not supported for %s\n",
     876             :                         domain);
     877           4 :                 TALLOC_FREE(frame);
     878           4 :                 return NT_STATUS_INTERNAL_ERROR;
     879             :         }
     880             : 
     881          31 :         db = secrets_db_ctx();
     882             : 
     883          31 :         ret = dbwrap_transaction_start(db);
     884          31 :         if (ret != 0) {
     885           0 :                 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
     886             :                         domain);
     887           0 :                 TALLOC_FREE(frame);
     888           0 :                 return NT_STATUS_INTERNAL_DB_ERROR;
     889             :         }
     890             : 
     891          31 :         ok = secrets_clear_domain_protection(domain);
     892          31 :         if (!ok) {
     893           0 :                 DBG_ERR("secrets_clear_domain_protection(%s) failed\n",
     894             :                         domain);
     895           0 :                 dbwrap_transaction_cancel(db);
     896           0 :                 TALLOC_FREE(frame);
     897           0 :                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     898             :         }
     899             : 
     900          31 :         ok = secrets_delete_machine_password_ex(domain, realm);
     901          31 :         if (!ok) {
     902           0 :                 DBG_ERR("secrets_delete_machine_password_ex(%s) failed\n",
     903             :                         domain);
     904           0 :                 dbwrap_transaction_cancel(db);
     905           0 :                 TALLOC_FREE(frame);
     906           0 :                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     907             :         }
     908             : 
     909          31 :         status = secrets_store_domain_info1_by_key(key, info);
     910          31 :         if (!NT_STATUS_IS_OK(status)) {
     911           0 :                 DBG_ERR("secrets_store_domain_info1_by_key() failed "
     912             :                         "for %s - %s\n", domain, nt_errstr(status));
     913           0 :                 dbwrap_transaction_cancel(db);
     914           0 :                 TALLOC_FREE(frame);
     915           0 :                 return status;
     916             :         }
     917             : 
     918             :         /*
     919             :          * We use info->password_last_change instead
     920             :          * of info->password.change_time because
     921             :          * we may want to defer the next change approach
     922             :          * if the server rejected the change the last time,
     923             :          * e.g. due to RefusePasswordChange=1.
     924             :          */
     925          31 :         nttime_to_timeval(&last_change_tv, info->password_last_change);
     926             : 
     927          31 :         cleartext_blob = &info->password->cleartext_blob;
     928          50 :         ok = convert_string_talloc(frame, CH_UTF16MUNGED, CH_UNIX,
     929          31 :                                    cleartext_blob->data,
     930          12 :                                    cleartext_blob->length,
     931             :                                    (void **)&pw_blob.data,
     932             :                                    &pw_blob.length);
     933          31 :         if (!ok) {
     934           0 :                 status = NT_STATUS_UNMAPPABLE_CHARACTER;
     935           0 :                 if (errno == ENOMEM) {
     936           0 :                         status = NT_STATUS_NO_MEMORY;
     937             :                 }
     938           0 :                 DBG_ERR("convert_string_talloc(CH_UTF16MUNGED, CH_UNIX) "
     939             :                         "failed for pw of %s - %s\n",
     940             :                         domain, nt_errstr(status));
     941           0 :                 dbwrap_transaction_cancel(db);
     942           0 :                 TALLOC_FREE(frame);
     943           0 :                 return status;
     944             :         }
     945          31 :         pw = (const char *)pw_blob.data;
     946          31 :         if (info->old_password != NULL) {
     947           9 :                 cleartext_blob = &info->old_password->cleartext_blob;
     948          16 :                 ok = convert_string_talloc(frame, CH_UTF16MUNGED, CH_UNIX,
     949           9 :                                            cleartext_blob->data,
     950           2 :                                            cleartext_blob->length,
     951             :                                            (void **)&old_pw_blob.data,
     952             :                                            &old_pw_blob.length);
     953           9 :                 if (!ok) {
     954           0 :                         status = NT_STATUS_UNMAPPABLE_CHARACTER;
     955           0 :                         if (errno == ENOMEM) {
     956           0 :                                 status = NT_STATUS_NO_MEMORY;
     957             :                         }
     958           0 :                         DBG_ERR("convert_string_talloc(CH_UTF16MUNGED, CH_UNIX) "
     959             :                                 "failed for old_pw of %s - %s\n",
     960             :                                 domain, nt_errstr(status));
     961           0 :                         dbwrap_transaction_cancel(db);
     962           0 :                         data_blob_clear_free(&pw_blob);
     963           0 :                         TALLOC_FREE(frame);
     964           0 :                         return status;
     965             :                 }
     966           9 :                 old_pw = (const char *)old_pw_blob.data;
     967             :         }
     968             : 
     969          50 :         ok = secrets_store_machine_pw_sync(pw, old_pw,
     970             :                                            domain, realm,
     971          12 :                                            info->salt_principal,
     972          12 :                                            info->supported_enc_types,
     973          31 :                                            info->domain_info.sid,
     974          31 :                                            last_change_tv.tv_sec,
     975          31 :                                            info->secure_channel_type,
     976             :                                            false); /* delete_join */
     977          31 :         data_blob_clear_free(&pw_blob);
     978          31 :         data_blob_clear_free(&old_pw_blob);
     979          31 :         if (!ok) {
     980           0 :                 DBG_ERR("secrets_store_machine_pw_sync(%s) failed\n",
     981             :                         domain);
     982           0 :                 dbwrap_transaction_cancel(db);
     983           0 :                 TALLOC_FREE(frame);
     984           0 :                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     985             :         }
     986             : 
     987          31 :         if (!GUID_all_zero(&info->domain_info.domain_guid)) {
     988          27 :                 ok = secrets_store_domain_guid(domain,
     989             :                                 &info->domain_info.domain_guid);
     990          27 :                 if (!ok) {
     991           0 :                         DBG_ERR("secrets_store_domain_guid(%s) failed\n",
     992             :                                 domain);
     993           0 :                         dbwrap_transaction_cancel(db);
     994           0 :                         TALLOC_FREE(frame);
     995           0 :                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     996             :                 }
     997             :         }
     998             : 
     999          31 :         ok = secrets_mark_domain_protected(domain);
    1000          31 :         if (!ok) {
    1001           0 :                 DBG_ERR("secrets_mark_domain_protected(%s) failed\n",
    1002             :                         domain);
    1003           0 :                 dbwrap_transaction_cancel(db);
    1004           0 :                 TALLOC_FREE(frame);
    1005           0 :                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
    1006             :         }
    1007             : 
    1008          31 :         ret = dbwrap_transaction_commit(db);
    1009          31 :         if (ret != 0) {
    1010           0 :                 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
    1011             :                         domain);
    1012           0 :                 TALLOC_FREE(frame);
    1013           0 :                 return NT_STATUS_INTERNAL_DB_ERROR;
    1014             :         }
    1015             : 
    1016          31 :         TALLOC_FREE(frame);
    1017          31 :         return NT_STATUS_OK;
    1018             : }
    1019             : 
    1020          39 : static int secrets_domain_info_kerberos_keys(struct secrets_domain_info1_password *p,
    1021             :                                              const char *salt_principal)
    1022             : {
    1023             : #ifdef HAVE_ADS
    1024             :         krb5_error_code krb5_ret;
    1025          39 :         krb5_context krb5_ctx = NULL;
    1026          39 :         DATA_BLOB cleartext_utf8_b = data_blob_null;
    1027             :         krb5_data cleartext_utf8;
    1028             :         krb5_data salt;
    1029             :         krb5_keyblock key;
    1030          39 :         DATA_BLOB aes_256_b = data_blob_null;
    1031          39 :         DATA_BLOB aes_128_b = data_blob_null;
    1032             :         bool ok;
    1033             : #endif /* HAVE_ADS */
    1034          39 :         DATA_BLOB arc4_b = data_blob_null;
    1035          39 :         const uint16_t max_keys = 4;
    1036          39 :         struct secrets_domain_info1_kerberos_key *keys = NULL;
    1037          39 :         uint16_t idx = 0;
    1038          39 :         char *salt_data = NULL;
    1039             : 
    1040             :         /*
    1041             :          * We calculate:
    1042             :          * ENCTYPE_AES256_CTS_HMAC_SHA1_96
    1043             :          * ENCTYPE_AES128_CTS_HMAC_SHA1_96
    1044             :          * ENCTYPE_ARCFOUR_HMAC
    1045             :          * ENCTYPE_DES_CBC_MD5
    1046             :          *
    1047             :          * We don't include ENCTYPE_DES_CBC_CRC
    1048             :          * as W2008R2 also doesn't store it anymore.
    1049             :          *
    1050             :          * Note we store all enctypes we support,
    1051             :          * including the weak encryption types,
    1052             :          * but that's no problem as we also
    1053             :          * store the cleartext password anyway.
    1054             :          *
    1055             :          * Which values are then used to construct
    1056             :          * a keytab is configured at runtime and the
    1057             :          * configuration of msDS-SupportedEncryptionTypes.
    1058             :          *
    1059             :          * If we don't have kerberos support or no
    1060             :          * salt, we only generate an entry for arcfour-hmac-md5.
    1061             :          */
    1062          39 :         keys = talloc_zero_array(p,
    1063             :                                  struct secrets_domain_info1_kerberos_key,
    1064             :                                  max_keys);
    1065          39 :         if (keys == NULL) {
    1066           0 :                 return ENOMEM;
    1067             :         }
    1068             : 
    1069          39 :         arc4_b = data_blob_talloc(keys,
    1070             :                                   p->nt_hash.hash,
    1071             :                                   sizeof(p->nt_hash.hash));
    1072          39 :         if (arc4_b.data == NULL) {
    1073           0 :                 DBG_ERR("data_blob_talloc failed for arcfour-hmac-md5.\n");
    1074           0 :                 TALLOC_FREE(keys);
    1075           0 :                 return ENOMEM;
    1076             :         }
    1077             : 
    1078             : #ifdef HAVE_ADS
    1079          39 :         if (salt_principal == NULL) {
    1080           1 :                 goto no_kerberos;
    1081             :         }
    1082             : 
    1083          38 :         krb5_ret = smb_krb5_init_context_common(&krb5_ctx);
    1084          38 :         if (krb5_ret != 0) {
    1085           0 :                 DBG_ERR("kerberos init context failed (%s)\n",
    1086             :                         error_message(krb5_ret));
    1087           0 :                 TALLOC_FREE(keys);
    1088           0 :                 return krb5_ret;
    1089             :         }
    1090             : 
    1091          38 :         krb5_ret = smb_krb5_salt_principal2data(krb5_ctx, salt_principal,
    1092             :                                                 p, &salt_data);
    1093          38 :         if (krb5_ret != 0) {
    1094           0 :                 DBG_ERR("smb_krb5_salt_principal2data(%s) failed: %s\n",
    1095             :                         salt_principal,
    1096             :                         smb_get_krb5_error_message(krb5_ctx, krb5_ret, keys));
    1097           0 :                 krb5_free_context(krb5_ctx);
    1098           0 :                 TALLOC_FREE(keys);
    1099           0 :                 return krb5_ret;
    1100             :         }
    1101             : 
    1102          38 :         salt = (krb5_data) {
    1103          25 :                 .data = discard_const(salt_data),
    1104          38 :                 .length = strlen(salt_data),
    1105             :         };
    1106             : 
    1107          63 :         ok = convert_string_talloc(keys, CH_UTF16MUNGED, CH_UTF8,
    1108          38 :                                    p->cleartext_blob.data,
    1109             :                                    p->cleartext_blob.length,
    1110             :                                    (void **)&cleartext_utf8_b.data,
    1111             :                                    &cleartext_utf8_b.length);
    1112          38 :         if (!ok) {
    1113           0 :                 if (errno != 0) {
    1114           0 :                         krb5_ret = errno;
    1115             :                 } else {
    1116           0 :                         krb5_ret = EINVAL;
    1117             :                 }
    1118           0 :                 krb5_free_context(krb5_ctx);
    1119           0 :                 TALLOC_FREE(keys);
    1120           0 :                 return krb5_ret;
    1121             :         }
    1122          38 :         cleartext_utf8.data = (void *)cleartext_utf8_b.data;
    1123          38 :         cleartext_utf8.length = cleartext_utf8_b.length;
    1124             : 
    1125          38 :         krb5_ret = smb_krb5_create_key_from_string(krb5_ctx,
    1126             :                                                    NULL,
    1127             :                                                    &salt,
    1128             :                                                    &cleartext_utf8,
    1129             :                                                    ENCTYPE_AES256_CTS_HMAC_SHA1_96,
    1130             :                                                    &key);
    1131          38 :         if (krb5_ret != 0) {
    1132           0 :                 DBG_ERR("generation of a aes256-cts-hmac-sha1-96 key failed: %s\n",
    1133             :                         smb_get_krb5_error_message(krb5_ctx, krb5_ret, keys));
    1134           0 :                 krb5_free_context(krb5_ctx);
    1135           0 :                 TALLOC_FREE(keys);
    1136           0 :                 TALLOC_FREE(salt_data);
    1137           0 :                 return krb5_ret;
    1138             :         }
    1139          38 :         aes_256_b = data_blob_talloc(keys,
    1140             :                                      KRB5_KEY_DATA(&key),
    1141             :                                      KRB5_KEY_LENGTH(&key));
    1142          38 :         krb5_free_keyblock_contents(krb5_ctx, &key);
    1143          38 :         if (aes_256_b.data == NULL) {
    1144           0 :                 DBG_ERR("data_blob_talloc failed for aes-256.\n");
    1145           0 :                 krb5_free_context(krb5_ctx);
    1146           0 :                 TALLOC_FREE(keys);
    1147           0 :                 TALLOC_FREE(salt_data);
    1148           0 :                 return ENOMEM;
    1149             :         }
    1150             : 
    1151          38 :         krb5_ret = smb_krb5_create_key_from_string(krb5_ctx,
    1152             :                                                    NULL,
    1153             :                                                    &salt,
    1154             :                                                    &cleartext_utf8,
    1155             :                                                    ENCTYPE_AES128_CTS_HMAC_SHA1_96,
    1156             :                                                    &key);
    1157          38 :         if (krb5_ret != 0) {
    1158           0 :                 DBG_ERR("generation of a aes128-cts-hmac-sha1-96 key failed: %s\n",
    1159             :                         smb_get_krb5_error_message(krb5_ctx, krb5_ret, keys));
    1160           0 :                 krb5_free_context(krb5_ctx);
    1161           0 :                 TALLOC_FREE(keys);
    1162           0 :                 TALLOC_FREE(salt_data);
    1163           0 :                 return krb5_ret;
    1164             :         }
    1165          38 :         aes_128_b = data_blob_talloc(keys,
    1166             :                                      KRB5_KEY_DATA(&key),
    1167             :                                      KRB5_KEY_LENGTH(&key));
    1168          38 :         krb5_free_keyblock_contents(krb5_ctx, &key);
    1169          38 :         if (aes_128_b.data == NULL) {
    1170           0 :                 DBG_ERR("data_blob_talloc failed for aes-128.\n");
    1171           0 :                 krb5_free_context(krb5_ctx);
    1172           0 :                 TALLOC_FREE(keys);
    1173           0 :                 TALLOC_FREE(salt_data);
    1174           0 :                 return ENOMEM;
    1175             :         }
    1176             : 
    1177          38 :         krb5_free_context(krb5_ctx);
    1178          39 : no_kerberos:
    1179             : 
    1180          39 :         if (aes_256_b.length != 0) {
    1181          38 :                 keys[idx].keytype               = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
    1182          38 :                 keys[idx].iteration_count       = 4096;
    1183          38 :                 keys[idx].value                 = aes_256_b;
    1184          38 :                 idx += 1;
    1185             :         }
    1186             : 
    1187          39 :         if (aes_128_b.length != 0) {
    1188          38 :                 keys[idx].keytype               = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
    1189          38 :                 keys[idx].iteration_count       = 4096;
    1190          38 :                 keys[idx].value                 = aes_128_b;
    1191          38 :                 idx += 1;
    1192             :         }
    1193             : 
    1194             : #endif /* HAVE_ADS */
    1195             : 
    1196          39 :         keys[idx].keytype               = ENCTYPE_ARCFOUR_HMAC;
    1197          39 :         keys[idx].iteration_count       = 4096;
    1198          39 :         keys[idx].value                 = arc4_b;
    1199          39 :         idx += 1;
    1200             : 
    1201          39 :         p->salt_data = salt_data;
    1202          39 :         p->default_iteration_count = 4096;
    1203          39 :         p->num_keys = idx;
    1204          39 :         p->keys = keys;
    1205          39 :         return 0;
    1206             : }
    1207             : 
    1208          39 : static NTSTATUS secrets_domain_info_password_create(TALLOC_CTX *mem_ctx,
    1209             :                                 const char *cleartext_unix,
    1210             :                                 const char *salt_principal,
    1211             :                                 NTTIME change_time,
    1212             :                                 const char *change_server,
    1213             :                                 struct secrets_domain_info1_password **_p)
    1214             : {
    1215          39 :         struct secrets_domain_info1_password *p = NULL;
    1216             :         bool ok;
    1217             :         size_t len;
    1218             :         int ret;
    1219             : 
    1220          39 :         if (change_server == NULL) {
    1221           0 :                 return NT_STATUS_INVALID_PARAMETER_MIX;
    1222             :         }
    1223             : 
    1224          39 :         p = talloc_zero(mem_ctx, struct secrets_domain_info1_password);
    1225          39 :         if (p == NULL) {
    1226           0 :                 return NT_STATUS_NO_MEMORY;
    1227             :         }
    1228          39 :         p->change_time = change_time;
    1229          39 :         p->change_server = talloc_strdup(p, change_server);
    1230          39 :         if (p->change_server == NULL) {
    1231           0 :                 TALLOC_FREE(p);
    1232           0 :                 return NT_STATUS_NO_MEMORY;
    1233             :         }
    1234          39 :         len = strlen(cleartext_unix);
    1235          65 :         ok = convert_string_talloc(p, CH_UNIX, CH_UTF16,
    1236             :                                    cleartext_unix, len,
    1237          39 :                                    (void **)&p->cleartext_blob.data,
    1238             :                                    &p->cleartext_blob.length);
    1239          39 :         if (!ok) {
    1240           0 :                 NTSTATUS status = NT_STATUS_UNMAPPABLE_CHARACTER;
    1241           0 :                 if (errno == ENOMEM) {
    1242           0 :                         status = NT_STATUS_NO_MEMORY;
    1243             :                 }
    1244           0 :                 TALLOC_FREE(p);
    1245           0 :                 return status;
    1246             :         }
    1247          65 :         mdfour(p->nt_hash.hash,
    1248          39 :                p->cleartext_blob.data,
    1249          39 :                p->cleartext_blob.length);
    1250             : 
    1251          39 :         ret = secrets_domain_info_kerberos_keys(p, salt_principal);
    1252          39 :         if (ret != 0) {
    1253           0 :                 NTSTATUS status = krb5_to_nt_status(ret);
    1254           0 :                 TALLOC_FREE(p);
    1255           0 :                 return status;
    1256             :         }
    1257             : 
    1258          39 :         *_p = p;
    1259          39 :         return NT_STATUS_OK;
    1260             : }
    1261             : 
    1262        3358 : NTSTATUS secrets_fetch_or_upgrade_domain_info(const char *domain,
    1263             :                                         TALLOC_CTX *mem_ctx,
    1264             :                                         struct secrets_domain_info1 **pinfo)
    1265             : {
    1266        3358 :         TALLOC_CTX *frame = NULL;
    1267        3358 :         struct secrets_domain_info1 *old = NULL;
    1268        3358 :         struct secrets_domain_info1 *info = NULL;
    1269        3358 :         const char *dns_domain = NULL;
    1270        3358 :         const char *server = NULL;
    1271        3358 :         struct db_context *db = NULL;
    1272             :         time_t last_set_time;
    1273             :         NTTIME last_set_nt;
    1274             :         enum netr_SchannelType channel;
    1275        3358 :         char *pw = NULL;
    1276        3358 :         char *old_pw = NULL;
    1277             :         struct dom_sid domain_sid;
    1278             :         struct GUID domain_guid;
    1279             :         bool ok;
    1280             :         NTSTATUS status;
    1281             :         int ret;
    1282             : 
    1283        3358 :         ok = strequal(domain, lp_workgroup());
    1284        3358 :         if (ok) {
    1285        3358 :                 dns_domain = lp_dnsdomain();
    1286             : 
    1287        3358 :                 if (dns_domain != NULL && dns_domain[0] == '\0') {
    1288           2 :                         dns_domain = NULL;
    1289             :                 }
    1290             :         }
    1291             : 
    1292        3358 :         last_set_time = secrets_fetch_pass_last_set_time(domain);
    1293        3358 :         if (last_set_time == 0) {
    1294          22 :                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
    1295             :         }
    1296        3336 :         unix_to_nt_time(&last_set_nt, last_set_time);
    1297             : 
    1298        3336 :         frame = talloc_stackframe();
    1299             : 
    1300        3336 :         status = secrets_fetch_domain_info(domain, frame, &old);
    1301        3336 :         if (NT_STATUS_IS_OK(status)) {
    1302        3328 :                 if (old->password_last_change >= last_set_nt) {
    1303        3328 :                         *pinfo = talloc_move(mem_ctx, &old);
    1304        3328 :                         TALLOC_FREE(frame);
    1305        3328 :                         return NT_STATUS_OK;
    1306             :                 }
    1307           0 :                 TALLOC_FREE(old);
    1308             :         }
    1309             : 
    1310           8 :         info = talloc_zero(frame, struct secrets_domain_info1);
    1311           8 :         if (info == NULL) {
    1312           0 :                 DBG_ERR("talloc_zero failed\n");
    1313           0 :                 TALLOC_FREE(frame);
    1314           0 :                 return NT_STATUS_NO_MEMORY;
    1315             :         }
    1316             : 
    1317           8 :         db = secrets_db_ctx();
    1318             : 
    1319           8 :         ret = dbwrap_transaction_start(db);
    1320           8 :         if (ret != 0) {
    1321           0 :                 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
    1322             :                         domain);
    1323           0 :                 TALLOC_FREE(frame);
    1324           0 :                 return NT_STATUS_INTERNAL_DB_ERROR;
    1325             :         }
    1326             : 
    1327           8 :         pw = secrets_fetch_machine_password(domain,
    1328             :                                             &last_set_time,
    1329             :                                             &channel);
    1330           8 :         if (pw == NULL) {
    1331           0 :                 DBG_ERR("secrets_fetch_machine_password(%s) failed\n",
    1332             :                         domain);
    1333           0 :                 dbwrap_transaction_cancel(db);
    1334           0 :                 TALLOC_FREE(frame);
    1335           0 :                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
    1336             :         }
    1337           8 :         unix_to_nt_time(&last_set_nt, last_set_time);
    1338             : 
    1339           8 :         old_pw = secrets_fetch_prev_machine_password(domain);
    1340             : 
    1341           8 :         ok = secrets_fetch_domain_sid(domain, &domain_sid);
    1342           8 :         if (!ok) {
    1343           0 :                 DBG_ERR("secrets_fetch_domain_sid(%s) failed\n",
    1344             :                         domain);
    1345           0 :                 dbwrap_transaction_cancel(db);
    1346           0 :                 SAFE_FREE(old_pw);
    1347           0 :                 SAFE_FREE(pw);
    1348           0 :                 TALLOC_FREE(frame);
    1349           0 :                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
    1350             :         }
    1351             : 
    1352           8 :         ok = secrets_fetch_domain_guid(domain, &domain_guid);
    1353           8 :         if (!ok) {
    1354           3 :                 domain_guid = GUID_zero();
    1355             :         }
    1356             : 
    1357           8 :         info->computer_name = lp_netbios_name();
    1358           8 :         info->account_name = talloc_asprintf(frame, "%s$", info->computer_name);
    1359           8 :         if (info->account_name == NULL) {
    1360           0 :                 DBG_ERR("talloc_asprintf(%s$) failed\n", info->computer_name);
    1361           0 :                 dbwrap_transaction_cancel(db);
    1362           0 :                 SAFE_FREE(old_pw);
    1363           0 :                 SAFE_FREE(pw);
    1364           0 :                 TALLOC_FREE(frame);
    1365           0 :                 return NT_STATUS_NO_MEMORY;
    1366             :         }
    1367           8 :         info->secure_channel_type = channel;
    1368             : 
    1369           8 :         info->domain_info.name.string = domain;
    1370           8 :         info->domain_info.dns_domain.string = dns_domain;
    1371           8 :         info->domain_info.dns_forest.string = dns_domain;
    1372           8 :         info->domain_info.domain_guid = domain_guid;
    1373           8 :         info->domain_info.sid = &domain_sid;
    1374             : 
    1375           8 :         info->trust_flags = NETR_TRUST_FLAG_PRIMARY;
    1376           8 :         info->trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
    1377             : 
    1378           8 :         if (dns_domain != NULL) {
    1379             :                 /*
    1380             :                  * We just assume all AD domains are
    1381             :                  * NETR_TRUST_FLAG_NATIVE these days.
    1382             :                  *
    1383             :                  * This isn't used anyway for now.
    1384             :                  */
    1385           8 :                 info->trust_flags |= NETR_TRUST_FLAG_NATIVE;
    1386             : 
    1387           8 :                 info->trust_type = LSA_TRUST_TYPE_UPLEVEL;
    1388             : 
    1389           8 :                 server = info->domain_info.dns_domain.string;
    1390             :         } else {
    1391           0 :                 info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
    1392             : 
    1393           0 :                 server = talloc_asprintf(info,
    1394             :                                          "%s#%02X",
    1395             :                                          domain,
    1396             :                                          NBT_NAME_PDC);
    1397           0 :                 if (server == NULL) {
    1398           0 :                         DBG_ERR("talloc_asprintf(%s#%02X) failed\n",
    1399             :                                 domain, NBT_NAME_PDC);
    1400           0 :                         dbwrap_transaction_cancel(db);
    1401           0 :                         SAFE_FREE(pw);
    1402           0 :                         SAFE_FREE(old_pw);
    1403           0 :                         TALLOC_FREE(frame);
    1404           0 :                         return NT_STATUS_NO_MEMORY;
    1405             :                 }
    1406             :         }
    1407           8 :         info->trust_attributes = LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL;
    1408             : 
    1409           8 :         info->join_time = 0;
    1410             : 
    1411             :         /*
    1412             :          * We don't have enough information about the configured
    1413             :          * enctypes.
    1414             :          */
    1415           8 :         info->supported_enc_types = 0;
    1416           8 :         info->salt_principal = NULL;
    1417           8 :         if (info->trust_type == LSA_TRUST_TYPE_UPLEVEL) {
    1418           8 :                 char *p = NULL;
    1419             : 
    1420           8 :                 p = kerberos_secrets_fetch_salt_princ();
    1421           8 :                 if (p == NULL) {
    1422           0 :                         dbwrap_transaction_cancel(db);
    1423           0 :                         SAFE_FREE(old_pw);
    1424           0 :                         SAFE_FREE(pw);
    1425           0 :                         TALLOC_FREE(frame);
    1426           0 :                         return NT_STATUS_INTERNAL_ERROR;
    1427             :                 }
    1428           8 :                 info->salt_principal = talloc_strdup(info, p);
    1429           8 :                 SAFE_FREE(p);
    1430           8 :                 if (info->salt_principal == NULL) {
    1431           0 :                         dbwrap_transaction_cancel(db);
    1432           0 :                         SAFE_FREE(pw);
    1433           0 :                         SAFE_FREE(old_pw);
    1434           0 :                         TALLOC_FREE(frame);
    1435           0 :                         return NT_STATUS_NO_MEMORY;
    1436             :                 }
    1437             :         }
    1438             : 
    1439           8 :         info->password_last_change = last_set_nt;
    1440           8 :         info->password_changes = 1;
    1441           8 :         info->next_change = NULL;
    1442             : 
    1443          15 :         status = secrets_domain_info_password_create(info,
    1444             :                                                      pw,
    1445           8 :                                                      info->salt_principal,
    1446             :                                                      last_set_nt, server,
    1447           8 :                                                      &info->password);
    1448           8 :         SAFE_FREE(pw);
    1449           8 :         if (!NT_STATUS_IS_OK(status)) {
    1450           0 :                 DBG_ERR("secrets_domain_info_password_create(pw) failed "
    1451             :                         "for %s - %s\n", domain, nt_errstr(status));
    1452           0 :                 dbwrap_transaction_cancel(db);
    1453           0 :                 SAFE_FREE(old_pw);
    1454           0 :                 TALLOC_FREE(frame);
    1455           0 :                 return status;
    1456             :         }
    1457             : 
    1458             :         /*
    1459             :          * After a join we don't have old passwords.
    1460             :          */
    1461           8 :         if (old_pw != NULL) {
    1462           7 :                 status = secrets_domain_info_password_create(info,
    1463             :                                                              old_pw,
    1464           4 :                                                              info->salt_principal,
    1465             :                                                              0, server,
    1466           4 :                                                              &info->old_password);
    1467           4 :                 SAFE_FREE(old_pw);
    1468           4 :                 if (!NT_STATUS_IS_OK(status)) {
    1469           0 :                         DBG_ERR("secrets_domain_info_password_create(old) failed "
    1470             :                                 "for %s - %s\n", domain, nt_errstr(status));
    1471           0 :                         dbwrap_transaction_cancel(db);
    1472           0 :                         TALLOC_FREE(frame);
    1473           0 :                         return status;
    1474             :                 }
    1475           4 :                 info->password_changes += 1;
    1476             :         } else {
    1477           4 :                 info->old_password = NULL;
    1478             :         }
    1479           8 :         info->older_password = NULL;
    1480             : 
    1481           8 :         secrets_debug_domain_info(DBGLVL_INFO, info, "upgrade");
    1482             : 
    1483           8 :         status = secrets_store_domain_info(info, true /* upgrade */);
    1484           8 :         if (!NT_STATUS_IS_OK(status)) {
    1485           4 :                 DBG_ERR("secrets_store_domain_info() failed "
    1486             :                         "for %s - %s\n", domain, nt_errstr(status));
    1487           4 :                 dbwrap_transaction_cancel(db);
    1488           4 :                 TALLOC_FREE(frame);
    1489           4 :                 return status;
    1490             :         }
    1491             : 
    1492             :         /*
    1493             :          * We now reparse it.
    1494             :          */
    1495           4 :         status = secrets_fetch_domain_info(domain, frame, &info);
    1496           4 :         if (!NT_STATUS_IS_OK(status)) {
    1497           0 :                 DBG_ERR("secrets_fetch_domain_info() failed "
    1498             :                         "for %s - %s\n", domain, nt_errstr(status));
    1499           0 :                 dbwrap_transaction_cancel(db);
    1500           0 :                 TALLOC_FREE(frame);
    1501           0 :                 return status;
    1502             :         }
    1503             : 
    1504           4 :         ret = dbwrap_transaction_commit(db);
    1505           4 :         if (ret != 0) {
    1506           0 :                 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
    1507             :                         domain);
    1508           0 :                 dbwrap_transaction_cancel(db);
    1509           0 :                 TALLOC_FREE(frame);
    1510           0 :                 return NT_STATUS_INTERNAL_DB_ERROR;
    1511             :         }
    1512             : 
    1513           4 :         *pinfo = talloc_move(mem_ctx, &info);
    1514           4 :         TALLOC_FREE(frame);
    1515           4 :         return NT_STATUS_OK;
    1516             : }
    1517             : 
    1518          27 : NTSTATUS secrets_store_JoinCtx(const struct libnet_JoinCtx *r)
    1519             : {
    1520          27 :         TALLOC_CTX *frame = talloc_stackframe();
    1521          27 :         struct secrets_domain_info1 *old = NULL;
    1522          27 :         struct secrets_domain_info1 *info = NULL;
    1523          27 :         struct db_context *db = NULL;
    1524          27 :         struct timeval tv = timeval_current();
    1525          27 :         NTTIME now = timeval_to_nttime(&tv);
    1526          27 :         const char *domain = r->out.netbios_domain_name;
    1527             :         NTSTATUS status;
    1528             :         int ret;
    1529             : 
    1530          27 :         info = talloc_zero(frame, struct secrets_domain_info1);
    1531          27 :         if (info == NULL) {
    1532           0 :                 DBG_ERR("talloc_zero failed\n");
    1533           0 :                 TALLOC_FREE(frame);
    1534           0 :                 return NT_STATUS_NO_MEMORY;
    1535             :         }
    1536             : 
    1537          27 :         info->computer_name = r->in.machine_name;
    1538          27 :         info->account_name = r->out.account_name;
    1539          27 :         info->secure_channel_type = r->in.secure_channel_type;
    1540             : 
    1541          27 :         info->domain_info.name.string =
    1542          27 :                 r->out.netbios_domain_name;
    1543          27 :         info->domain_info.dns_domain.string =
    1544          27 :                 r->out.dns_domain_name;
    1545          27 :         info->domain_info.dns_forest.string =
    1546          27 :                 r->out.forest_name;
    1547          27 :         info->domain_info.domain_guid = r->out.domain_guid;
    1548          27 :         info->domain_info.sid = r->out.domain_sid;
    1549             : 
    1550          27 :         info->trust_flags = NETR_TRUST_FLAG_PRIMARY;
    1551          27 :         info->trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
    1552          27 :         if (r->out.domain_is_ad) {
    1553             :                 /*
    1554             :                  * We just assume all AD domains are
    1555             :                  * NETR_TRUST_FLAG_NATIVE these days.
    1556             :                  *
    1557             :                  * This isn't used anyway for now.
    1558             :                  */
    1559          26 :                 info->trust_flags |= NETR_TRUST_FLAG_NATIVE;
    1560             : 
    1561          26 :                 info->trust_type = LSA_TRUST_TYPE_UPLEVEL;
    1562             :         } else {
    1563           1 :                 info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
    1564             :         }
    1565          27 :         info->trust_attributes = LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL;
    1566             : 
    1567          27 :         info->join_time = now;
    1568             : 
    1569          27 :         info->supported_enc_types = r->out.set_encryption_types;
    1570          27 :         info->salt_principal = r->out.krb5_salt;
    1571             : 
    1572          27 :         if (info->salt_principal == NULL && r->out.domain_is_ad) {
    1573           0 :                 char *p = NULL;
    1574             : 
    1575           0 :                 ret = smb_krb5_salt_principal_str(info->domain_info.dns_domain.string,
    1576             :                                                   info->account_name,
    1577             :                                                   NULL /* userPrincipalName */,
    1578             :                                                   UF_WORKSTATION_TRUST_ACCOUNT,
    1579             :                                                   info, &p);
    1580           0 :                 if (ret != 0) {
    1581           0 :                         status = krb5_to_nt_status(ret);
    1582           0 :                         DBG_ERR("smb_krb5_salt_principal() failed "
    1583             :                                 "for %s - %s\n", domain, nt_errstr(status));
    1584           0 :                         TALLOC_FREE(frame);
    1585           0 :                         return status;
    1586             :                 }
    1587           0 :                 info->salt_principal = p;
    1588             :         }
    1589             : 
    1590          27 :         info->password_last_change = now;
    1591          27 :         info->password_changes = 1;
    1592          27 :         info->next_change = NULL;
    1593             : 
    1594          27 :         status = secrets_domain_info_password_create(info,
    1595          11 :                                                      r->in.machine_password,
    1596             :                                                      info->salt_principal,
    1597          11 :                                                      now, r->in.dc_name,
    1598             :                                                      &info->password);
    1599          27 :         if (!NT_STATUS_IS_OK(status)) {
    1600           0 :                 DBG_ERR("secrets_domain_info_password_create(pw) failed "
    1601             :                         "for %s - %s\n", domain, nt_errstr(status));
    1602           0 :                 TALLOC_FREE(frame);
    1603           0 :                 return status;
    1604             :         }
    1605             : 
    1606          27 :         db = secrets_db_ctx();
    1607             : 
    1608          27 :         ret = dbwrap_transaction_start(db);
    1609          27 :         if (ret != 0) {
    1610           0 :                 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
    1611             :                         domain);
    1612           0 :                 TALLOC_FREE(frame);
    1613           0 :                 return NT_STATUS_INTERNAL_DB_ERROR;
    1614             :         }
    1615             : 
    1616          27 :         status = secrets_fetch_or_upgrade_domain_info(domain, frame, &old);
    1617          27 :         if (NT_STATUS_EQUAL(status, NT_STATUS_CANT_ACCESS_DOMAIN_INFO)) {
    1618          22 :                 DBG_DEBUG("no old join for domain(%s) available\n",
    1619             :                           domain);
    1620          22 :                 old = NULL;
    1621           5 :         } else if (!NT_STATUS_IS_OK(status)) {
    1622           0 :                 DBG_ERR("secrets_fetch_or_upgrade_domain_info(%s) failed\n",
    1623             :                         domain);
    1624           0 :                 dbwrap_transaction_cancel(db);
    1625           0 :                 TALLOC_FREE(frame);
    1626           0 :                 return status;
    1627             :         }
    1628             : 
    1629             :         /*
    1630             :          * We reuse values from an old join, so that
    1631             :          * we still accept already granted kerberos tickets.
    1632             :          */
    1633          27 :         if (old != NULL) {
    1634           5 :                 info->old_password = old->password;
    1635           5 :                 info->older_password = old->old_password;
    1636             :         }
    1637             : 
    1638          27 :         secrets_debug_domain_info(DBGLVL_INFO, info, "join");
    1639             : 
    1640          27 :         status = secrets_store_domain_info(info, false /* upgrade */);
    1641          27 :         if (!NT_STATUS_IS_OK(status)) {
    1642           0 :                 DBG_ERR("secrets_store_domain_info() failed "
    1643             :                         "for %s - %s\n", domain, nt_errstr(status));
    1644           0 :                 dbwrap_transaction_cancel(db);
    1645           0 :                 TALLOC_FREE(frame);
    1646           0 :                 return status;
    1647             :         }
    1648             : 
    1649          27 :         ret = dbwrap_transaction_commit(db);
    1650          27 :         if (ret != 0) {
    1651           0 :                 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
    1652             :                         domain);
    1653           0 :                 TALLOC_FREE(frame);
    1654           0 :                 return NT_STATUS_INTERNAL_DB_ERROR;
    1655             :         }
    1656             : 
    1657          27 :         TALLOC_FREE(frame);
    1658          27 :         return NT_STATUS_OK;
    1659             : }
    1660             : 
    1661           0 : NTSTATUS secrets_prepare_password_change(const char *domain, const char *dcname,
    1662             :                                          const char *cleartext_unix,
    1663             :                                          TALLOC_CTX *mem_ctx,
    1664             :                                          struct secrets_domain_info1 **pinfo,
    1665             :                                          struct secrets_domain_info1_change **pprev)
    1666             : {
    1667           0 :         TALLOC_CTX *frame = talloc_stackframe();
    1668           0 :         struct db_context *db = NULL;
    1669           0 :         struct secrets_domain_info1 *info = NULL;
    1670           0 :         struct secrets_domain_info1_change *prev = NULL;
    1671           0 :         struct secrets_domain_info1_change *next = NULL;
    1672           0 :         struct timeval tv = timeval_current();
    1673           0 :         NTTIME now = timeval_to_nttime(&tv);
    1674             :         NTSTATUS status;
    1675             :         int ret;
    1676             : 
    1677           0 :         db = secrets_db_ctx();
    1678             : 
    1679           0 :         ret = dbwrap_transaction_start(db);
    1680           0 :         if (ret != 0) {
    1681           0 :                 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
    1682             :                         domain);
    1683           0 :                 TALLOC_FREE(frame);
    1684           0 :                 return NT_STATUS_INTERNAL_DB_ERROR;
    1685             :         }
    1686             : 
    1687           0 :         status = secrets_fetch_or_upgrade_domain_info(domain, frame, &info);
    1688           0 :         if (!NT_STATUS_IS_OK(status)) {
    1689           0 :                 DBG_ERR("secrets_fetch_or_upgrade_domain_info(%s) failed\n",
    1690             :                         domain);
    1691           0 :                 dbwrap_transaction_cancel(db);
    1692           0 :                 TALLOC_FREE(frame);
    1693           0 :                 return status;
    1694             :         }
    1695             : 
    1696           0 :         prev = info->next_change;
    1697           0 :         info->next_change = NULL;
    1698             : 
    1699           0 :         next = talloc_zero(frame, struct secrets_domain_info1_change);
    1700           0 :         if (next == NULL) {
    1701           0 :                 DBG_ERR("talloc_zero failed\n");
    1702           0 :                 TALLOC_FREE(frame);
    1703           0 :                 return NT_STATUS_NO_MEMORY;
    1704             :         }
    1705             : 
    1706           0 :         if (prev != NULL) {
    1707           0 :                 *next = *prev;
    1708             :         } else {
    1709           0 :                 status = secrets_domain_info_password_create(next,
    1710             :                                                              cleartext_unix,
    1711           0 :                                                              info->salt_principal,
    1712             :                                                              now, dcname,
    1713             :                                                              &next->password);
    1714           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1715           0 :                         DBG_ERR("secrets_domain_info_password_create(next) failed "
    1716             :                                 "for %s - %s\n", domain, nt_errstr(status));
    1717           0 :                         dbwrap_transaction_cancel(db);
    1718           0 :                         TALLOC_FREE(frame);
    1719           0 :                         return status;
    1720             :                 }
    1721             :         }
    1722             : 
    1723           0 :         next->local_status = NT_STATUS_OK;
    1724           0 :         next->remote_status = NT_STATUS_NOT_COMMITTED;
    1725           0 :         next->change_time = now;
    1726           0 :         next->change_server = dcname;
    1727             : 
    1728           0 :         info->next_change = next;
    1729             : 
    1730           0 :         secrets_debug_domain_info(DBGLVL_INFO, info, "prepare_change");
    1731             : 
    1732           0 :         status = secrets_store_domain_info(info, false /* upgrade */);
    1733           0 :         if (!NT_STATUS_IS_OK(status)) {
    1734           0 :                 DBG_ERR("secrets_store_domain_info() failed "
    1735             :                         "for %s - %s\n", domain, nt_errstr(status));
    1736           0 :                 dbwrap_transaction_cancel(db);
    1737           0 :                 TALLOC_FREE(frame);
    1738           0 :                 return status;
    1739             :         }
    1740             : 
    1741             :         /*
    1742             :          * We now reparse it.
    1743             :          */
    1744           0 :         status = secrets_fetch_domain_info(domain, frame, &info);
    1745           0 :         if (!NT_STATUS_IS_OK(status)) {
    1746           0 :                 DBG_ERR("secrets_fetch_domain_info(%s) failed\n", domain);
    1747           0 :                 dbwrap_transaction_cancel(db);
    1748           0 :                 TALLOC_FREE(frame);
    1749           0 :                 return status;
    1750             :         }
    1751             : 
    1752           0 :         ret = dbwrap_transaction_commit(db);
    1753           0 :         if (ret != 0) {
    1754           0 :                 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
    1755             :                         domain);
    1756           0 :                 TALLOC_FREE(frame);
    1757           0 :                 return NT_STATUS_INTERNAL_DB_ERROR;
    1758             :         }
    1759             : 
    1760           0 :         *pinfo = talloc_move(mem_ctx, &info);
    1761           0 :         if (prev != NULL) {
    1762           0 :                 *pprev = talloc_move(mem_ctx, &prev);
    1763             :         } else {
    1764           0 :                 *pprev = NULL;
    1765             :         }
    1766             : 
    1767           0 :         TALLOC_FREE(frame);
    1768           0 :         return NT_STATUS_OK;
    1769             : }
    1770             : 
    1771           0 : static NTSTATUS secrets_check_password_change(const struct secrets_domain_info1 *cookie,
    1772             :                                               TALLOC_CTX *mem_ctx,
    1773             :                                               struct secrets_domain_info1 **pstored)
    1774             : {
    1775           0 :         const char *domain = cookie->domain_info.name.string;
    1776           0 :         struct secrets_domain_info1 *stored = NULL;
    1777           0 :         struct secrets_domain_info1_change *sn = NULL;
    1778           0 :         struct secrets_domain_info1_change *cn = NULL;
    1779             :         NTSTATUS status;
    1780             :         bool cmp;
    1781             : 
    1782           0 :         if (cookie->next_change == NULL) {
    1783           0 :                 DBG_ERR("cookie->next_change == NULL for %s.\n", domain);
    1784           0 :                 return NT_STATUS_INTERNAL_ERROR;
    1785             :         }
    1786             : 
    1787           0 :         if (cookie->next_change->password == NULL) {
    1788           0 :                 DBG_ERR("cookie->next_change->password == NULL for %s.\n", domain);
    1789           0 :                 return NT_STATUS_INTERNAL_ERROR;
    1790             :         }
    1791             : 
    1792           0 :         if (cookie->password == NULL) {
    1793           0 :                 DBG_ERR("cookie->password == NULL for %s.\n", domain);
    1794           0 :                 return NT_STATUS_INTERNAL_ERROR;
    1795             :         }
    1796             : 
    1797             :         /*
    1798             :          * Here we check that the given strucure still contains the
    1799             :          * same secrets_domain_info1_change as currently stored.
    1800             :          *
    1801             :          * There's always a gap between secrets_prepare_password_change()
    1802             :          * and the callers of secrets_check_password_change().
    1803             :          */
    1804             : 
    1805           0 :         status = secrets_fetch_domain_info(domain, mem_ctx, &stored);
    1806           0 :         if (!NT_STATUS_IS_OK(status)) {
    1807           0 :                 DBG_ERR("secrets_fetch_domain_info(%s) failed\n", domain);
    1808           0 :                 return status;
    1809             :         }
    1810             : 
    1811           0 :         if (stored->next_change == NULL) {
    1812             :                 /*
    1813             :                  * We hit a race..., the administrator
    1814             :                  * rejoined or something similar happened.
    1815             :                  */
    1816           0 :                 DBG_ERR("stored->next_change == NULL for %s.\n", domain);
    1817           0 :                 TALLOC_FREE(stored);
    1818           0 :                 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
    1819             :         }
    1820             : 
    1821           0 :         if (stored->password_last_change != cookie->password_last_change) {
    1822             :                 struct timeval store_tv;
    1823             :                 struct timeval_buf store_buf;
    1824             :                 struct timeval cookie_tv;
    1825             :                 struct timeval_buf cookie_buf;
    1826             : 
    1827           0 :                 nttime_to_timeval(&store_tv, stored->password_last_change);
    1828           0 :                 nttime_to_timeval(&cookie_tv, cookie->password_last_change);
    1829             : 
    1830           0 :                 DBG_ERR("password_last_change differs %s != %s for %s.\n",
    1831             :                         timeval_str_buf(&store_tv, false, false, &store_buf),
    1832             :                         timeval_str_buf(&cookie_tv, false, false, &cookie_buf),
    1833             :                         domain);
    1834           0 :                 TALLOC_FREE(stored);
    1835           0 :                 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
    1836             :         }
    1837             : 
    1838           0 :         sn = stored->next_change;
    1839           0 :         cn = cookie->next_change;
    1840             : 
    1841           0 :         if (sn->change_time != cn->change_time) {
    1842             :                 struct timeval store_tv;
    1843             :                 struct timeval_buf store_buf;
    1844             :                 struct timeval cookie_tv;
    1845             :                 struct timeval_buf cookie_buf;
    1846             : 
    1847           0 :                 nttime_to_timeval(&store_tv, sn->change_time);
    1848           0 :                 nttime_to_timeval(&cookie_tv, cn->change_time);
    1849             : 
    1850           0 :                 DBG_ERR("next change_time differs %s != %s for %s.\n",
    1851             :                         timeval_str_buf(&store_tv, false, false, &store_buf),
    1852             :                         timeval_str_buf(&cookie_tv, false, false, &cookie_buf),
    1853             :                         domain);
    1854           0 :                 TALLOC_FREE(stored);
    1855           0 :                 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
    1856             :         }
    1857             : 
    1858           0 :         if (sn->password->change_time != cn->password->change_time) {
    1859             :                 struct timeval store_tv;
    1860             :                 struct timeval_buf store_buf;
    1861             :                 struct timeval cookie_tv;
    1862             :                 struct timeval_buf cookie_buf;
    1863             : 
    1864           0 :                 nttime_to_timeval(&store_tv, sn->password->change_time);
    1865           0 :                 nttime_to_timeval(&cookie_tv, cn->password->change_time);
    1866             : 
    1867           0 :                 DBG_ERR("next password.change_time differs %s != %s for %s.\n",
    1868             :                         timeval_str_buf(&store_tv, false, false, &store_buf),
    1869             :                         timeval_str_buf(&cookie_tv, false, false, &cookie_buf),
    1870             :                         domain);
    1871           0 :                 TALLOC_FREE(stored);
    1872           0 :                 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
    1873             :         }
    1874             : 
    1875           0 :         cmp = mem_equal_const_time(sn->password->nt_hash.hash,
    1876           0 :                                    cn->password->nt_hash.hash,
    1877             :                                    16);
    1878           0 :         if (!cmp) {
    1879           0 :                 DBG_ERR("next password.nt_hash differs for %s.\n",
    1880             :                         domain);
    1881           0 :                 TALLOC_FREE(stored);
    1882           0 :                 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
    1883             :         }
    1884             : 
    1885           0 :         cmp = mem_equal_const_time(stored->password->nt_hash.hash,
    1886           0 :                                    cookie->password->nt_hash.hash,
    1887             :                                    16);
    1888           0 :         if (!cmp) {
    1889           0 :                 DBG_ERR("password.nt_hash differs for %s.\n",
    1890             :                         domain);
    1891           0 :                 TALLOC_FREE(stored);
    1892           0 :                 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
    1893             :         }
    1894             : 
    1895           0 :         *pstored = stored;
    1896           0 :         return NT_STATUS_OK;
    1897             : }
    1898             : 
    1899           0 : static NTSTATUS secrets_abort_password_change(const char *change_server,
    1900             :                                 NTSTATUS local_status,
    1901             :                                 NTSTATUS remote_status,
    1902             :                                 const struct secrets_domain_info1 *cookie,
    1903             :                                 bool defer)
    1904             : {
    1905           0 :         const char *domain = cookie->domain_info.name.string;
    1906           0 :         TALLOC_CTX *frame = talloc_stackframe();
    1907           0 :         struct db_context *db = NULL;
    1908           0 :         struct secrets_domain_info1 *info = NULL;
    1909           0 :         const char *reason = defer ? "defer_change" : "failed_change";
    1910           0 :         struct timeval tv = timeval_current();
    1911           0 :         NTTIME now = timeval_to_nttime(&tv);
    1912             :         NTSTATUS status;
    1913             :         int ret;
    1914             : 
    1915           0 :         db = secrets_db_ctx();
    1916             : 
    1917           0 :         ret = dbwrap_transaction_start(db);
    1918           0 :         if (ret != 0) {
    1919           0 :                 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
    1920             :                         domain);
    1921           0 :                 TALLOC_FREE(frame);
    1922           0 :                 return NT_STATUS_INTERNAL_DB_ERROR;
    1923             :         }
    1924             : 
    1925             :         /*
    1926             :          * secrets_check_password_change()
    1927             :          * checks that cookie->next_change
    1928             :          * is valid and the same as store
    1929             :          * in the database.
    1930             :          */
    1931           0 :         status = secrets_check_password_change(cookie, frame, &info);
    1932           0 :         if (!NT_STATUS_IS_OK(status)) {
    1933           0 :                 DBG_ERR("secrets_check_password_change(%s) failed\n", domain);
    1934           0 :                 dbwrap_transaction_cancel(db);
    1935           0 :                 TALLOC_FREE(frame);
    1936           0 :                 return status;
    1937             :         }
    1938             : 
    1939             :         /*
    1940             :          * Remember the last server and error.
    1941             :          */
    1942           0 :         info->next_change->change_server = change_server;
    1943           0 :         info->next_change->change_time = now;
    1944           0 :         info->next_change->local_status = local_status;
    1945           0 :         info->next_change->remote_status = remote_status;
    1946             : 
    1947             :         /*
    1948             :          * Make sure the next automatic change is deferred.
    1949             :          */
    1950           0 :         if (defer) {
    1951           0 :                 info->password_last_change = now;
    1952             :         }
    1953             : 
    1954           0 :         secrets_debug_domain_info(DBGLVL_WARNING, info, reason);
    1955             : 
    1956           0 :         status = secrets_store_domain_info(info, false /* upgrade */);
    1957           0 :         if (!NT_STATUS_IS_OK(status)) {
    1958           0 :                 DBG_ERR("secrets_store_domain_info() failed "
    1959             :                         "for %s - %s\n", domain, nt_errstr(status));
    1960           0 :                 dbwrap_transaction_cancel(db);
    1961           0 :                 TALLOC_FREE(frame);
    1962           0 :                 return status;
    1963             :         }
    1964             : 
    1965           0 :         ret = dbwrap_transaction_commit(db);
    1966           0 :         if (ret != 0) {
    1967           0 :                 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
    1968             :                         domain);
    1969           0 :                 TALLOC_FREE(frame);
    1970           0 :                 return NT_STATUS_INTERNAL_DB_ERROR;
    1971             :         }
    1972             : 
    1973           0 :         TALLOC_FREE(frame);
    1974           0 :         return NT_STATUS_OK;
    1975             : }
    1976             : 
    1977           0 : NTSTATUS secrets_failed_password_change(const char *change_server,
    1978             :                                         NTSTATUS local_status,
    1979             :                                         NTSTATUS remote_status,
    1980             :                                         const struct secrets_domain_info1 *cookie)
    1981             : {
    1982             :         static const bool defer = false;
    1983           0 :         return secrets_abort_password_change(change_server,
    1984             :                                              local_status,
    1985             :                                              remote_status,
    1986             :                                              cookie, defer);
    1987             : }
    1988             : 
    1989           0 : NTSTATUS secrets_defer_password_change(const char *change_server,
    1990             :                                        NTSTATUS local_status,
    1991             :                                        NTSTATUS remote_status,
    1992             :                                        const struct secrets_domain_info1 *cookie)
    1993             : {
    1994             :         static const bool defer = true;
    1995           0 :         return secrets_abort_password_change(change_server,
    1996             :                                              local_status,
    1997             :                                              remote_status,
    1998             :                                              cookie, defer);
    1999             : }
    2000             : 
    2001           0 : NTSTATUS secrets_finish_password_change(const char *change_server,
    2002             :                                         NTTIME change_time,
    2003             :                                         const struct secrets_domain_info1 *cookie)
    2004             : {
    2005           0 :         const char *domain = cookie->domain_info.name.string;
    2006           0 :         TALLOC_CTX *frame = talloc_stackframe();
    2007           0 :         struct db_context *db = NULL;
    2008           0 :         struct secrets_domain_info1 *info = NULL;
    2009           0 :         struct secrets_domain_info1_change *nc = NULL;
    2010             :         NTSTATUS status;
    2011             :         int ret;
    2012             : 
    2013           0 :         db = secrets_db_ctx();
    2014             : 
    2015           0 :         ret = dbwrap_transaction_start(db);
    2016           0 :         if (ret != 0) {
    2017           0 :                 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
    2018             :                         domain);
    2019           0 :                 TALLOC_FREE(frame);
    2020           0 :                 return NT_STATUS_INTERNAL_DB_ERROR;
    2021             :         }
    2022             : 
    2023             :         /*
    2024             :          * secrets_check_password_change() checks that cookie->next_change is
    2025             :          * valid and the same as store in the database.
    2026             :          */
    2027           0 :         status = secrets_check_password_change(cookie, frame, &info);
    2028           0 :         if (!NT_STATUS_IS_OK(status)) {
    2029           0 :                 DBG_ERR("secrets_check_password_change(%s) failed\n", domain);
    2030           0 :                 dbwrap_transaction_cancel(db);
    2031           0 :                 TALLOC_FREE(frame);
    2032           0 :                 return status;
    2033             :         }
    2034             : 
    2035           0 :         nc = info->next_change;
    2036             : 
    2037           0 :         nc->password->change_server = change_server;
    2038           0 :         nc->password->change_time = change_time;
    2039             : 
    2040           0 :         info->password_last_change = change_time;
    2041           0 :         info->password_changes += 1;
    2042           0 :         info->next_change = NULL;
    2043             : 
    2044           0 :         info->older_password = info->old_password;
    2045           0 :         info->old_password = info->password;
    2046           0 :         info->password = nc->password;
    2047             : 
    2048           0 :         secrets_debug_domain_info(DBGLVL_WARNING, info, "finish_change");
    2049             : 
    2050           0 :         status = secrets_store_domain_info(info, false /* upgrade */);
    2051           0 :         if (!NT_STATUS_IS_OK(status)) {
    2052           0 :                 DBG_ERR("secrets_store_domain_info() failed "
    2053             :                         "for %s - %s\n", domain, nt_errstr(status));
    2054           0 :                 dbwrap_transaction_cancel(db);
    2055           0 :                 TALLOC_FREE(frame);
    2056           0 :                 return status;
    2057             :         }
    2058             : 
    2059           0 :         ret = dbwrap_transaction_commit(db);
    2060           0 :         if (ret != 0) {
    2061           0 :                 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
    2062             :                         domain);
    2063           0 :                 TALLOC_FREE(frame);
    2064           0 :                 return NT_STATUS_INTERNAL_DB_ERROR;
    2065             :         }
    2066             : 
    2067           0 :         TALLOC_FREE(frame);
    2068           0 :         return NT_STATUS_OK;
    2069             : }

Generated by: LCOV version 1.13