LCOV - code coverage report
Current view: top level - source3/passdb - machine_account_secrets.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 651 1105 58.9 %
Date: 2024-04-21 15:09:00 Functions: 39 46 84.8 %

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

Generated by: LCOV version 1.14