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

Generated by: LCOV version 1.14