Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/passdb/secrets.c

    r480 r745  
    2424
    2525#include "includes.h"
     26#include "system/filesys.h"
     27#include "passdb.h"
    2628#include "../libcli/auth/libcli_auth.h"
    2729#include "librpc/gen_ndr/ndr_secrets.h"
     30#include "secrets.h"
     31#include "dbwrap.h"
     32#include "../libcli/security/security.h"
     33#include "util_tdb.h"
    2834
    2935#undef DBGC_CLASS
     
    3137
    3238static struct db_context *db_ctx;
    33 
    34 /* Urrrg. global.... */
    35 bool global_machine_password_needs_changing;
    3639
    3740/**
     
    171174
    172175/**
    173  * Form a key for fetching the domain sid
    174  *
    175  * @param domain domain name
    176  *
    177  * @return keystring
    178  **/
    179 static const char *domain_sid_keystr(const char *domain)
    180 {
    181         char *keystr;
    182 
    183         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
    184                                             SECRETS_DOMAIN_SID, domain);
    185         SMB_ASSERT(keystr != NULL);
    186         return keystr;
    187 }
    188 
    189 bool secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
    190 {
    191         bool ret;
    192 
    193         ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(DOM_SID));
    194 
    195         /* Force a re-query, in case we modified our domain */
    196         if (ret)
    197                 reset_global_sam_sid();
    198         return ret;
    199 }
    200 
    201 bool secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
    202 {
    203         DOM_SID *dyn_sid;
    204         size_t size = 0;
    205 
    206         dyn_sid = (DOM_SID *)secrets_fetch(domain_sid_keystr(domain), &size);
    207 
    208         if (dyn_sid == NULL)
    209                 return False;
    210 
    211         if (size != sizeof(DOM_SID)) {
    212                 SAFE_FREE(dyn_sid);
    213                 return False;
    214         }
    215 
    216         *sid = *dyn_sid;
    217         SAFE_FREE(dyn_sid);
    218         return True;
    219 }
    220 
    221 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
    222 {
    223         fstring key;
    224 
    225         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
    226         strupper_m(key);
    227         return secrets_store(key, guid, sizeof(struct GUID));
    228 }
    229 
    230 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
    231 {
    232         struct GUID *dyn_guid;
    233         fstring key;
    234         size_t size = 0;
    235         struct GUID new_guid;
    236 
    237         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
    238         strupper_m(key);
    239         dyn_guid = (struct GUID *)secrets_fetch(key, &size);
    240 
    241         if (!dyn_guid) {
    242                 if (lp_server_role() == ROLE_DOMAIN_PDC) {
    243                         new_guid = GUID_random();
    244                         if (!secrets_store_domain_guid(domain, &new_guid))
    245                                 return False;
    246                         dyn_guid = (struct GUID *)secrets_fetch(key, &size);
    247                 }
    248                 if (dyn_guid == NULL) {
    249                         return False;
    250                 }
    251         }
    252 
    253         if (size != sizeof(struct GUID)) {
    254                 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
    255                 SAFE_FREE(dyn_guid);
    256                 return False;
    257         }
    258 
    259         *guid = *dyn_guid;
    260         SAFE_FREE(dyn_guid);
    261         return True;
    262 }
    263 
    264 bool secrets_store_local_schannel_key(uint8_t schannel_key[16])
    265 {
    266         return secrets_store(SECRETS_LOCAL_SCHANNEL_KEY, schannel_key, 16);
    267 }
    268 
    269 bool secrets_fetch_local_schannel_key(uint8_t schannel_key[16])
    270 {
    271         size_t size = 0;
    272         uint8_t *key;
    273 
    274         key = (uint8_t *)secrets_fetch(SECRETS_LOCAL_SCHANNEL_KEY, &size);
    275         if (key == NULL) {
    276                 return false;
    277         }
    278 
    279         if (size != 16) {
    280                 SAFE_FREE(key);
    281                 return false;
    282         }
    283 
    284         memcpy(schannel_key, key, 16);
    285         SAFE_FREE(key);
    286         return true;
    287 }
    288 
    289 /**
    290  * Form a key for fetching the machine trust account sec channel type
    291  *
    292  * @param domain domain name
    293  *
    294  * @return keystring
    295  **/
    296 static const char *machine_sec_channel_type_keystr(const char *domain)
    297 {
    298         char *keystr;
    299 
    300         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
    301                                             SECRETS_MACHINE_SEC_CHANNEL_TYPE,
    302                                             domain);
    303         SMB_ASSERT(keystr != NULL);
    304         return keystr;
    305 }
    306 
    307 /**
    308  * Form a key for fetching the machine trust account last change time
    309  *
    310  * @param domain domain name
    311  *
    312  * @return keystring
    313  **/
    314 static const char *machine_last_change_time_keystr(const char *domain)
    315 {
    316         char *keystr;
    317 
    318         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
    319                                             SECRETS_MACHINE_LAST_CHANGE_TIME,
    320                                             domain);
    321         SMB_ASSERT(keystr != NULL);
    322         return keystr;
    323 }
    324 
    325 
    326 /**
    327  * Form a key for fetching the machine previous trust account password
    328  *
    329  * @param domain domain name
    330  *
    331  * @return keystring
    332  **/
    333 static const char *machine_prev_password_keystr(const char *domain)
    334 {
    335         char *keystr;
    336 
    337         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
    338                                             SECRETS_MACHINE_PASSWORD_PREV, domain);
    339         SMB_ASSERT(keystr != NULL);
    340         return keystr;
    341 }
    342 
    343 /**
    344  * Form a key for fetching the machine trust account password
    345  *
    346  * @param domain domain name
    347  *
    348  * @return keystring
    349  **/
    350 static const char *machine_password_keystr(const char *domain)
    351 {
    352         char *keystr;
    353 
    354         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
    355                                             SECRETS_MACHINE_PASSWORD, domain);
    356         SMB_ASSERT(keystr != NULL);
    357         return keystr;
    358 }
    359 
    360 /**
    361  * Form a key for fetching the machine trust account password
    362  *
    363  * @param domain domain name
    364  *
    365  * @return stored password's key
    366  **/
    367 static const char *trust_keystr(const char *domain)
    368 {
    369         char *keystr;
    370 
    371         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
    372                                             SECRETS_MACHINE_ACCT_PASS, domain);
    373         SMB_ASSERT(keystr != NULL);
    374         return keystr;
    375 }
    376 
    377 /**
    378176 * Form a key for fetching a trusted domain password
    379177 *
     
    394192
    395193/************************************************************************
    396  Lock the trust password entry.
    397 ************************************************************************/
    398 
    399 void *secrets_get_trust_account_lock(TALLOC_CTX *mem_ctx, const char *domain)
    400 {
    401         if (!secrets_init()) {
    402                 return NULL;
    403         }
    404 
    405         return db_ctx->fetch_locked(
    406                 db_ctx, mem_ctx, string_term_tdb_data(trust_keystr(domain)));
    407 }
    408 
    409 /************************************************************************
    410  Routine to get the default secure channel type for trust accounts
    411 ************************************************************************/
    412 
    413 enum netr_SchannelType get_default_sec_channel(void)
    414 {
    415         if (lp_server_role() == ROLE_DOMAIN_BDC ||
    416             lp_server_role() == ROLE_DOMAIN_PDC) {
    417                 return SEC_CHAN_BDC;
    418         } else {
    419                 return SEC_CHAN_WKSTA;
    420         }
    421 }
    422 
    423 /************************************************************************
    424  Routine to get the trust account password for a domain.
    425  This only tries to get the legacy hashed version of the password.
    426  The user of this function must have locked the trust password file using
    427  the above secrets_lock_trust_account_password().
    428 ************************************************************************/
    429 
    430 bool secrets_fetch_trust_account_password_legacy(const char *domain,
    431                                                  uint8 ret_pwd[16],
    432                                                  time_t *pass_last_set_time,
    433                                                  enum netr_SchannelType *channel)
    434 {
    435         struct machine_acct_pass *pass;
    436         size_t size = 0;
    437 
    438         if (!(pass = (struct machine_acct_pass *)secrets_fetch(
    439                       trust_keystr(domain), &size))) {
    440                 DEBUG(5, ("secrets_fetch failed!\n"));
    441                 return False;
    442         }
    443 
    444         if (size != sizeof(*pass)) {
    445                 DEBUG(0, ("secrets were of incorrect size!\n"));
    446                 SAFE_FREE(pass);
    447                 return False;
    448         }
    449 
    450         if (pass_last_set_time) {
    451                 *pass_last_set_time = pass->mod_time;
    452         }
    453         memcpy(ret_pwd, pass->hash, 16);
    454 
    455         if (channel) {
    456                 *channel = get_default_sec_channel();
    457         }
    458 
    459         /* Test if machine password has expired and needs to be changed */
    460         if (lp_machine_password_timeout()) {
    461                 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
    462                                 (time_t)lp_machine_password_timeout())) {
    463                         global_machine_password_needs_changing = True;
    464                 }
    465         }
    466 
    467         SAFE_FREE(pass);
    468         return True;
    469 }
    470 
    471 /************************************************************************
    472  Routine to get the trust account password for a domain.
    473  The user of this function must have locked the trust password file using
    474  the above secrets_lock_trust_account_password().
    475 ************************************************************************/
    476 
    477 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
    478                                           time_t *pass_last_set_time,
    479                                           enum netr_SchannelType *channel)
    480 {
    481         char *plaintext;
    482 
    483         plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
    484                                                    channel);
    485         if (plaintext) {
    486                 DEBUG(4,("Using cleartext machine password\n"));
    487                 E_md4hash(plaintext, ret_pwd);
    488                 SAFE_FREE(plaintext);
    489                 return True;
    490         }
    491 
    492         return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
    493                                                            pass_last_set_time,
    494                                                            channel);
    495 }
    496 
    497 /************************************************************************
    498194 Routine to get account password to trusted domain
    499195************************************************************************/
    500196
    501197bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
    502                                            DOM_SID *sid, time_t *pass_last_set_time)
     198                                           struct dom_sid *sid, time_t *pass_last_set_time)
    503199{
    504200        struct TRUSTED_DOM_PASS pass;
     
    516212
    517213        /* unpack trusted domain password */
    518         ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), NULL, &pass,
     214        ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &pass,
    519215                        (ndr_pull_flags_fn_t)ndr_pull_TRUSTED_DOM_PASS);
     216
     217        SAFE_FREE(blob.data);
     218
    520219        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    521220                return false;
    522221        }
    523222
    524         SAFE_FREE(blob.data);
    525223
    526224        /* the trust's password */
     
    552250
    553251bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
    554                                            const DOM_SID *sid)
     252                                           const struct dom_sid *sid)
    555253{
    556254        bool ret;
     
    575273        sid_copy(&pass.domain_sid, sid);
    576274
    577         ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), NULL, &pass,
     275        ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &pass,
    578276                        (ndr_push_flags_fn_t)ndr_push_TRUSTED_DOM_PASS);
    579277        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     
    584282
    585283        data_blob_free(&blob);
    586 
    587         return ret;
    588 }
    589 
    590 /************************************************************************
    591  Routine to delete the old plaintext machine account password if any
    592 ************************************************************************/
    593 
    594 static bool secrets_delete_prev_machine_password(const char *domain)
    595 {
    596         char *oldpass = (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
    597         if (oldpass == NULL) {
    598                 return true;
    599         }
    600         SAFE_FREE(oldpass);
    601         return secrets_delete(machine_prev_password_keystr(domain));
    602 }
    603 
    604 /************************************************************************
    605  Routine to delete the plaintext machine account password and old
    606  password if any
    607 ************************************************************************/
    608 
    609 bool secrets_delete_machine_password(const char *domain)
    610 {
    611         if (!secrets_delete_prev_machine_password(domain)) {
    612                 return false;
    613         }
    614         return secrets_delete(machine_password_keystr(domain));
    615 }
    616 
    617 /************************************************************************
    618  Routine to delete the plaintext machine account password, old password,
    619  sec channel type and last change time from secrets database
    620 ************************************************************************/
    621 
    622 bool secrets_delete_machine_password_ex(const char *domain)
    623 {
    624         if (!secrets_delete_prev_machine_password(domain)) {
    625                 return false;
    626         }
    627         if (!secrets_delete(machine_password_keystr(domain))) {
    628                 return false;
    629         }
    630         if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
    631                 return false;
    632         }
    633         return secrets_delete(machine_last_change_time_keystr(domain));
    634 }
    635 
    636 /************************************************************************
    637  Routine to delete the domain sid
    638 ************************************************************************/
    639 
    640 bool secrets_delete_domain_sid(const char *domain)
    641 {
    642         return secrets_delete(domain_sid_keystr(domain));
    643 }
    644 
    645 /************************************************************************
    646  Routine to store the previous machine password (by storing the current password
    647  as the old)
    648 ************************************************************************/
    649 
    650 static bool secrets_store_prev_machine_password(const char *domain)
    651 {
    652         char *oldpass;
    653         bool ret;
    654 
    655         oldpass = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
    656         if (oldpass == NULL) {
    657                 return true;
    658         }
    659         ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
    660         SAFE_FREE(oldpass);
    661         return ret;
    662 }
    663 
    664 /************************************************************************
    665  Routine to set the plaintext machine account password for a realm
    666  the password is assumed to be a null terminated ascii string.
    667  Before storing
    668 ************************************************************************/
    669 
    670 bool secrets_store_machine_password(const char *pass, const char *domain,
    671                                     enum netr_SchannelType sec_channel)
    672 {
    673         bool ret;
    674         uint32 last_change_time;
    675         uint32 sec_channel_type;
    676 
    677         if (!secrets_store_prev_machine_password(domain)) {
    678                 return false;
    679         }
    680 
    681         ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
    682         if (!ret)
    683                 return ret;
    684 
    685         SIVAL(&last_change_time, 0, time(NULL));
    686         ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
    687 
    688         SIVAL(&sec_channel_type, 0, sec_channel);
    689         ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
    690 
    691         return ret;
    692 }
    693 
    694 
    695 /************************************************************************
    696  Routine to fetch the previous plaintext machine account password for a realm
    697  the password is assumed to be a null terminated ascii string.
    698 ************************************************************************/
    699 
    700 char *secrets_fetch_prev_machine_password(const char *domain)
    701 {
    702         return (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
    703 }
    704 
    705 /************************************************************************
    706  Routine to fetch the plaintext machine account password for a realm
    707  the password is assumed to be a null terminated ascii string.
    708 ************************************************************************/
    709 
    710 char *secrets_fetch_machine_password(const char *domain,
    711                                      time_t *pass_last_set_time,
    712                                      enum netr_SchannelType *channel)
    713 {
    714         char *ret;
    715         ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
    716 
    717         if (pass_last_set_time) {
    718                 size_t size;
    719                 uint32 *last_set_time;
    720                 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
    721                 if (last_set_time) {
    722                         *pass_last_set_time = IVAL(last_set_time,0);
    723                         SAFE_FREE(last_set_time);
    724                 } else {
    725                         *pass_last_set_time = 0;
    726                 }
    727         }
    728 
    729         if (channel) {
    730                 size_t size;
    731                 uint32 *channel_type;
    732                 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
    733                 if (channel_type) {
    734                         *channel = IVAL(channel_type,0);
    735                         SAFE_FREE(channel_type);
    736                 } else {
    737                         *channel = get_default_sec_channel();
    738                 }
    739         }
    740284
    741285        return ret;
     
    863407        blob = data_blob_const(rec->value.dptr, rec->value.dsize);
    864408
    865         ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), NULL, &pass,
     409        ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &pass,
    866410                        (ndr_pull_flags_fn_t)ndr_pull_TRUSTED_DOM_PASS);
    867411        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     
    905449        struct list_trusted_domains_state state;
    906450
    907         secrets_init();
    908 
    909         if (db_ctx == NULL) {
     451        if (!secrets_init()) {
    910452                return NT_STATUS_ACCESS_DENIED;
    911453        }
     
    1064606
    1065607        if (( ! owner) || ( ! key)) {
    1066                 DEBUG(1, ("Invalid Paramters"));
     608                DEBUG(1, ("Invalid Parameters"));
    1067609                return NULL;
    1068610        }
Note: See TracChangeset for help on using the changeset viewer.