root/source3/passdb/secrets.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_rand_seed
  2. secrets_init
  3. secrets_db_ctx
  4. secrets_shutdown
  5. secrets_fetch
  6. secrets_store
  7. secrets_delete
  8. domain_sid_keystr
  9. secrets_store_domain_sid
  10. secrets_fetch_domain_sid
  11. secrets_store_domain_guid
  12. secrets_fetch_domain_guid
  13. secrets_store_local_schannel_key
  14. secrets_fetch_local_schannel_key
  15. machine_sec_channel_type_keystr
  16. machine_last_change_time_keystr
  17. machine_password_keystr
  18. trust_keystr
  19. trustdom_keystr
  20. secrets_get_trust_account_lock
  21. get_default_sec_channel
  22. secrets_fetch_trust_account_password_legacy
  23. secrets_fetch_trust_account_password
  24. tdb_sid_pack
  25. tdb_sid_unpack
  26. tdb_trusted_dom_pass_pack
  27. tdb_trusted_dom_pass_unpack
  28. secrets_fetch_trusted_domain_password
  29. secrets_store_trusted_domain_password
  30. secrets_delete_machine_password
  31. secrets_delete_machine_password_ex
  32. secrets_delete_domain_sid
  33. secrets_store_machine_password
  34. secrets_fetch_machine_password
  35. trusted_domain_password_delete
  36. secrets_store_ldap_pw
  37. fetch_ldap_pw
  38. list_trusted_domain
  39. secrets_trusted_domains
  40. secrets_store_afs_keyfile
  41. secrets_fetch_afs_key
  42. secrets_fetch_ipc_userpass
  43. open_schannel_session_store
  44. secrets_store_schannel_session_info
  45. secrets_restore_schannel_session_info
  46. secrets_store_generic
  47. secrets_fetch_generic

   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 
  27 #undef DBGC_CLASS
  28 #define DBGC_CLASS DBGC_PASSDB
  29 
  30 static struct db_context *db_ctx;
  31 
  32 /* Urrrg. global.... */
  33 bool global_machine_password_needs_changing;
  34 
  35 /**
  36  * Use a TDB to store an incrementing random seed.
  37  *
  38  * Initialised to the current pid, the very first time Samba starts,
  39  * and incremented by one each time it is needed.
  40  *
  41  * @note Not called by systems with a working /dev/urandom.
  42  */
  43 static void get_rand_seed(void *userdata, int *new_seed)
     /* [<][>][^][v][top][bottom][index][help] */
  44 {
  45         *new_seed = sys_getpid();
  46         if (db_ctx) {
  47                 dbwrap_change_int32_atomic(db_ctx, "INFO/random_seed",
  48                                            new_seed, 1);
  49         }
  50 }
  51 
  52 /* open up the secrets database */
  53 bool secrets_init(void)
     /* [<][>][^][v][top][bottom][index][help] */
  54 {
  55         char *fname = NULL;
  56         unsigned char dummy;
  57 
  58         if (db_ctx != NULL)
  59                 return True;
  60 
  61         fname = talloc_asprintf(talloc_tos(), "%s/secrets.tdb",
  62                                 lp_private_dir());
  63         if (fname == NULL) {
  64                 return false;
  65         }
  66 
  67         db_ctx = db_open(NULL, fname, 0,
  68                          TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
  69 
  70         if (db_ctx == NULL) {
  71                 DEBUG(0,("Failed to open %s\n", fname));
  72                 TALLOC_FREE(fname);
  73                 return False;
  74         }
  75 
  76         TALLOC_FREE(fname);
  77 
  78         /**
  79          * Set a reseed function for the crypto random generator
  80          *
  81          * This avoids a problem where systems without /dev/urandom
  82          * could send the same challenge to multiple clients
  83          */
  84         set_rand_reseed_callback(get_rand_seed, NULL);
  85 
  86         /* Ensure that the reseed is done now, while we are root, etc */
  87         generate_random_buffer(&dummy, sizeof(dummy));
  88 
  89         return True;
  90 }
  91 
  92 struct db_context *secrets_db_ctx(void)
     /* [<][>][^][v][top][bottom][index][help] */
  93 {
  94         if (!secrets_init()) {
  95                 return NULL;
  96         }
  97 
  98         return db_ctx;
  99 }
 100 
 101 /*
 102  * close secrets.tdb
 103  */
 104 void secrets_shutdown(void)
     /* [<][>][^][v][top][bottom][index][help] */
 105 {
 106         TALLOC_FREE(db_ctx);
 107 }
 108 
 109 /* read a entry from the secrets database - the caller must free the result
 110    if size is non-null then the size of the entry is put in there
 111  */
 112 void *secrets_fetch(const char *key, size_t *size)
     /* [<][>][^][v][top][bottom][index][help] */
 113 {
 114         TDB_DATA dbuf;
 115         void *result;
 116 
 117         if (!secrets_init()) {
 118                 return NULL;
 119         }
 120 
 121         if (db_ctx->fetch(db_ctx, talloc_tos(), string_tdb_data(key),
 122                           &dbuf) != 0) {
 123                 return NULL;
 124         }
 125 
 126         result = memdup(dbuf.dptr, dbuf.dsize);
 127         if (result == NULL) {
 128                 return NULL;
 129         }
 130         TALLOC_FREE(dbuf.dptr);
 131 
 132         if (size) {
 133                 *size = dbuf.dsize;
 134         }
 135 
 136         return result;
 137 }
 138 
 139 /* store a secrets entry
 140  */
 141 bool secrets_store(const char *key, const void *data, size_t size)
     /* [<][>][^][v][top][bottom][index][help] */
 142 {
 143         NTSTATUS status;
 144 
 145         if (!secrets_init()) {
 146                 return false;
 147         }
 148 
 149         status = dbwrap_trans_store(db_ctx, string_tdb_data(key),
 150                                     make_tdb_data((const uint8 *)data, size),
 151                                     TDB_REPLACE);
 152         return NT_STATUS_IS_OK(status);
 153 }
 154 
 155 
 156 /* delete a secets database entry
 157  */
 158 bool secrets_delete(const char *key)
     /* [<][>][^][v][top][bottom][index][help] */
 159 {
 160         NTSTATUS status;
 161         if (!secrets_init()) {
 162                 return false;
 163         }
 164 
 165         status = dbwrap_trans_delete(db_ctx, string_tdb_data(key));
 166 
 167         return NT_STATUS_IS_OK(status);
 168 }
 169 
 170 /**
 171  * Form a key for fetching the domain sid
 172  *
 173  * @param domain domain name
 174  *
 175  * @return keystring
 176  **/
 177 static const char *domain_sid_keystr(const char *domain)
     /* [<][>][^][v][top][bottom][index][help] */
 178 {
 179         char *keystr;
 180 
 181         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
 182                                             SECRETS_DOMAIN_SID, domain);
 183         SMB_ASSERT(keystr != NULL);
 184         return keystr;
 185 }
 186 
 187 bool secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
     /* [<][>][^][v][top][bottom][index][help] */
 188 {
 189         bool ret;
 190 
 191         ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(DOM_SID));
 192 
 193         /* Force a re-query, in case we modified our domain */
 194         if (ret)
 195                 reset_global_sam_sid();
 196         return ret;
 197 }
 198 
 199 bool secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
     /* [<][>][^][v][top][bottom][index][help] */
 200 {
 201         DOM_SID *dyn_sid;
 202         size_t size = 0;
 203 
 204         dyn_sid = (DOM_SID *)secrets_fetch(domain_sid_keystr(domain), &size);
 205 
 206         if (dyn_sid == NULL)
 207                 return False;
 208 
 209         if (size != sizeof(DOM_SID)) {
 210                 SAFE_FREE(dyn_sid);
 211                 return False;
 212         }
 213 
 214         *sid = *dyn_sid;
 215         SAFE_FREE(dyn_sid);
 216         return True;
 217 }
 218 
 219 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
     /* [<][>][^][v][top][bottom][index][help] */
 220 {
 221         fstring key;
 222 
 223         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
 224         strupper_m(key);
 225         return secrets_store(key, guid, sizeof(struct GUID));
 226 }
 227 
 228 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
     /* [<][>][^][v][top][bottom][index][help] */
 229 {
 230         struct GUID *dyn_guid;
 231         fstring key;
 232         size_t size = 0;
 233         struct GUID new_guid;
 234 
 235         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
 236         strupper_m(key);
 237         dyn_guid = (struct GUID *)secrets_fetch(key, &size);
 238 
 239         if (!dyn_guid) {
 240                 if (lp_server_role() == ROLE_DOMAIN_PDC) {
 241                         new_guid = GUID_random();
 242                         if (!secrets_store_domain_guid(domain, &new_guid))
 243                                 return False;
 244                         dyn_guid = (struct GUID *)secrets_fetch(key, &size);
 245                 }
 246                 if (dyn_guid == NULL) {
 247                         return False;
 248                 }
 249         }
 250 
 251         if (size != sizeof(struct GUID)) {
 252                 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
 253                 SAFE_FREE(dyn_guid);
 254                 return False;
 255         }
 256 
 257         *guid = *dyn_guid;
 258         SAFE_FREE(dyn_guid);
 259         return True;
 260 }
 261 
 262 bool secrets_store_local_schannel_key(uint8_t schannel_key[16])
     /* [<][>][^][v][top][bottom][index][help] */
 263 {
 264         return secrets_store(SECRETS_LOCAL_SCHANNEL_KEY, schannel_key, 16);
 265 }
 266 
 267 bool secrets_fetch_local_schannel_key(uint8_t schannel_key[16])
     /* [<][>][^][v][top][bottom][index][help] */
 268 {
 269         size_t size = 0;
 270         uint8_t *key;
 271 
 272         key = (uint8_t *)secrets_fetch(SECRETS_LOCAL_SCHANNEL_KEY, &size);
 273         if (key == NULL) {
 274                 return false;
 275         }
 276 
 277         if (size != 16) {
 278                 SAFE_FREE(key);
 279                 return false;
 280         }
 281 
 282         memcpy(schannel_key, key, 16);
 283         SAFE_FREE(key);
 284         return true;
 285 }
 286 
 287 /**
 288  * Form a key for fetching the machine trust account sec channel type
 289  *
 290  * @param domain domain name
 291  *
 292  * @return keystring
 293  **/
 294 static const char *machine_sec_channel_type_keystr(const char *domain)
     /* [<][>][^][v][top][bottom][index][help] */
 295 {
 296         char *keystr;
 297 
 298         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
 299                                             SECRETS_MACHINE_SEC_CHANNEL_TYPE,
 300                                             domain);
 301         SMB_ASSERT(keystr != NULL);
 302         return keystr;
 303 }
 304 
 305 /**
 306  * Form a key for fetching the machine trust account last change time
 307  *
 308  * @param domain domain name
 309  *
 310  * @return keystring
 311  **/
 312 static const char *machine_last_change_time_keystr(const char *domain)
     /* [<][>][^][v][top][bottom][index][help] */
 313 {
 314         char *keystr;
 315 
 316         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
 317                                             SECRETS_MACHINE_LAST_CHANGE_TIME,
 318                                             domain);
 319         SMB_ASSERT(keystr != NULL);
 320         return keystr;
 321 }
 322 
 323 
 324 /**
 325  * Form a key for fetching the machine trust account password
 326  *
 327  * @param domain domain name
 328  *
 329  * @return keystring
 330  **/
 331 static const char *machine_password_keystr(const char *domain)
     /* [<][>][^][v][top][bottom][index][help] */
 332 {
 333         char *keystr;
 334 
 335         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
 336                                             SECRETS_MACHINE_PASSWORD, domain);
 337         SMB_ASSERT(keystr != NULL);
 338         return keystr;
 339 }
 340 
 341 /**
 342  * Form a key for fetching the machine trust account password
 343  *
 344  * @param domain domain name
 345  *
 346  * @return stored password's key
 347  **/
 348 static const char *trust_keystr(const char *domain)
     /* [<][>][^][v][top][bottom][index][help] */
 349 {
 350         char *keystr;
 351 
 352         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
 353                                             SECRETS_MACHINE_ACCT_PASS, domain);
 354         SMB_ASSERT(keystr != NULL);
 355         return keystr;
 356 }
 357 
 358 /**
 359  * Form a key for fetching a trusted domain password
 360  *
 361  * @param domain trusted domain name
 362  *
 363  * @return stored password's key
 364  **/
 365 static char *trustdom_keystr(const char *domain)
     /* [<][>][^][v][top][bottom][index][help] */
 366 {
 367         char *keystr;
 368 
 369         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
 370                                             SECRETS_DOMTRUST_ACCT_PASS,
 371                                             domain);
 372         SMB_ASSERT(keystr != NULL);
 373         return keystr;
 374 }
 375 
 376 /************************************************************************
 377  Lock the trust password entry.
 378 ************************************************************************/
 379 
 380 void *secrets_get_trust_account_lock(TALLOC_CTX *mem_ctx, const char *domain)
     /* [<][>][^][v][top][bottom][index][help] */
 381 {
 382         if (!secrets_init()) {
 383                 return NULL;
 384         }
 385 
 386         return db_ctx->fetch_locked(
 387                 db_ctx, mem_ctx, string_term_tdb_data(trust_keystr(domain)));
 388 }
 389 
 390 /************************************************************************
 391  Routine to get the default secure channel type for trust accounts
 392 ************************************************************************/
 393 
 394 uint32 get_default_sec_channel(void)
     /* [<][>][^][v][top][bottom][index][help] */
 395 {
 396         if (lp_server_role() == ROLE_DOMAIN_BDC ||
 397             lp_server_role() == ROLE_DOMAIN_PDC) {
 398                 return SEC_CHAN_BDC;
 399         } else {
 400                 return SEC_CHAN_WKSTA;
 401         }
 402 }
 403 
 404 /************************************************************************
 405  Routine to get the trust account password for a domain.
 406  This only tries to get the legacy hashed version of the password.
 407  The user of this function must have locked the trust password file using
 408  the above secrets_lock_trust_account_password().
 409 ************************************************************************/
 410 
 411 bool secrets_fetch_trust_account_password_legacy(const char *domain,
     /* [<][>][^][v][top][bottom][index][help] */
 412                                                  uint8 ret_pwd[16],
 413                                                  time_t *pass_last_set_time,
 414                                                  uint32 *channel)
 415 {
 416         struct machine_acct_pass *pass;
 417         size_t size = 0;
 418 
 419         if (!(pass = (struct machine_acct_pass *)secrets_fetch(
 420                       trust_keystr(domain), &size))) {
 421                 DEBUG(5, ("secrets_fetch failed!\n"));
 422                 return False;
 423         }
 424 
 425         if (size != sizeof(*pass)) {
 426                 DEBUG(0, ("secrets were of incorrect size!\n"));
 427                 SAFE_FREE(pass);
 428                 return False;
 429         }
 430 
 431         if (pass_last_set_time) {
 432                 *pass_last_set_time = pass->mod_time;
 433         }
 434         memcpy(ret_pwd, pass->hash, 16);
 435 
 436         if (channel) {
 437                 *channel = get_default_sec_channel();
 438         }
 439 
 440         /* Test if machine password has expired and needs to be changed */
 441         if (lp_machine_password_timeout()) {
 442                 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
 443                                 (time_t)lp_machine_password_timeout())) {
 444                         global_machine_password_needs_changing = True;
 445                 }
 446         }
 447 
 448         SAFE_FREE(pass);
 449         return True;
 450 }
 451 
 452 /************************************************************************
 453  Routine to get the trust account password for a domain.
 454  The user of this function must have locked the trust password file using
 455  the above secrets_lock_trust_account_password().
 456 ************************************************************************/
 457 
 458 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
     /* [<][>][^][v][top][bottom][index][help] */
 459                                           time_t *pass_last_set_time,
 460                                           uint32 *channel)
 461 {
 462         char *plaintext;
 463 
 464         plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
 465                                                    channel);
 466         if (plaintext) {
 467                 DEBUG(4,("Using cleartext machine password\n"));
 468                 E_md4hash(plaintext, ret_pwd);
 469                 SAFE_FREE(plaintext);
 470                 return True;
 471         }
 472 
 473         return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
 474                                                            pass_last_set_time,
 475                                                            channel);
 476 }
 477 
 478 /**
 479  * Pack SID passed by pointer
 480  *
 481  * @param pack_buf pointer to buffer which is to be filled with packed data
 482  * @param bufsize size of packing buffer
 483  * @param sid pointer to sid to be packed
 484  *
 485  * @return length of the packed representation of the whole structure
 486  **/
 487 static size_t tdb_sid_pack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
     /* [<][>][^][v][top][bottom][index][help] */
 488 {
 489         int idx;
 490         size_t len = 0;
 491         uint8 *p = pack_buf;
 492         int remaining_space = pack_buf ? bufsize : 0;
 493 
 494         if (!sid) {
 495                 return -1;
 496         }
 497 
 498         len += tdb_pack(p, remaining_space, "bb", sid->sid_rev_num,
 499                         sid->num_auths);
 500         if (pack_buf) {
 501                 p = pack_buf + len;
 502                 remaining_space = bufsize - len;
 503         }
 504 
 505         for (idx = 0; idx < 6; idx++) {
 506                 len += tdb_pack(p, remaining_space, "b",
 507                                 sid->id_auth[idx]);
 508                 if (pack_buf) {
 509                         p = pack_buf + len;
 510                         remaining_space = bufsize - len;
 511                 }
 512         }
 513 
 514         for (idx = 0; idx < MAXSUBAUTHS; idx++) {
 515                 len += tdb_pack(p, remaining_space, "d",
 516                                 sid->sub_auths[idx]);
 517                 if (pack_buf) {
 518                         p = pack_buf + len;
 519                         remaining_space = bufsize - len;
 520                 }
 521         }
 522 
 523         return len;
 524 }
 525 
 526 /**
 527  * Unpack SID into a pointer
 528  *
 529  * @param pack_buf pointer to buffer with packed representation
 530  * @param bufsize size of the buffer
 531  * @param sid pointer to sid structure to be filled with unpacked data
 532  *
 533  * @return size of structure unpacked from buffer
 534  **/
 535 static size_t tdb_sid_unpack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
     /* [<][>][^][v][top][bottom][index][help] */
 536 {
 537         int idx, len = 0;
 538 
 539         if (!sid || !pack_buf) return -1;
 540 
 541         len += tdb_unpack(pack_buf + len, bufsize - len, "bb",
 542                           &sid->sid_rev_num, &sid->num_auths);
 543 
 544         for (idx = 0; idx < 6; idx++) {
 545                 len += tdb_unpack(pack_buf + len, bufsize - len, "b",
 546                                   &sid->id_auth[idx]);
 547         }
 548 
 549         for (idx = 0; idx < MAXSUBAUTHS; idx++) {
 550                 len += tdb_unpack(pack_buf + len, bufsize - len, "d",
 551                                   &sid->sub_auths[idx]);
 552         }
 553 
 554         return len;
 555 }
 556 
 557 /**
 558  * Pack TRUSTED_DOM_PASS passed by pointer
 559  *
 560  * @param pack_buf pointer to buffer which is to be filled with packed data
 561  * @param bufsize size of the buffer
 562  * @param pass pointer to trusted domain password to be packed
 563  *
 564  * @return length of the packed representation of the whole structure
 565  **/
 566 static size_t tdb_trusted_dom_pass_pack(uint8 *pack_buf, int bufsize,
     /* [<][>][^][v][top][bottom][index][help] */
 567                                         TRUSTED_DOM_PASS* pass)
 568 {
 569         int idx, len = 0;
 570         uint8 *p = pack_buf;
 571         int remaining_space = pack_buf ? bufsize : 0;
 572 
 573         if (!pass) {
 574                 return -1;
 575         }
 576 
 577         /* packing unicode domain name and password */
 578         len += tdb_pack(p, remaining_space, "d",
 579                         pass->uni_name_len);
 580         if (pack_buf) {
 581                 p = pack_buf + len;
 582                 remaining_space = bufsize - len;
 583         }
 584 
 585         for (idx = 0; idx < 32; idx++) {
 586                 len += tdb_pack(p, remaining_space, "w",
 587                                  pass->uni_name[idx]);
 588                 if (pack_buf) {
 589                         p = pack_buf + len;
 590                         remaining_space = bufsize - len;
 591                 }
 592         }
 593 
 594         len += tdb_pack(p, remaining_space, "dPd", pass->pass_len,
 595                              pass->pass, pass->mod_time);
 596         if (pack_buf) {
 597                 p = pack_buf + len;
 598                 remaining_space = bufsize - len;
 599         }
 600 
 601         /* packing SID structure */
 602         len += tdb_sid_pack(p, remaining_space, &pass->domain_sid);
 603         if (pack_buf) {
 604                 p = pack_buf + len;
 605                 remaining_space = bufsize - len;
 606         }
 607 
 608         return len;
 609 }
 610 
 611 
 612 /**
 613  * Unpack TRUSTED_DOM_PASS passed by pointer
 614  *
 615  * @param pack_buf pointer to buffer with packed representation
 616  * @param bufsize size of the buffer
 617  * @param pass pointer to trusted domain password to be filled with unpacked data
 618  *
 619  * @return size of structure unpacked from buffer
 620  **/
 621 static size_t tdb_trusted_dom_pass_unpack(uint8 *pack_buf, int bufsize,
     /* [<][>][^][v][top][bottom][index][help] */
 622                                           TRUSTED_DOM_PASS* pass)
 623 {
 624         int idx, len = 0;
 625         char *passp = NULL;
 626 
 627         if (!pack_buf || !pass) return -1;
 628 
 629         /* unpack unicode domain name and plaintext password */
 630         len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len);
 631 
 632         for (idx = 0; idx < 32; idx++)
 633                 len +=  tdb_unpack(pack_buf + len, bufsize - len, "w",
 634                                    &pass->uni_name[idx]);
 635 
 636         len += tdb_unpack(pack_buf + len, bufsize - len, "dPd",
 637                           &pass->pass_len, &passp, &pass->mod_time);
 638         if (passp) {
 639                 fstrcpy(pass->pass, passp);
 640         }
 641         SAFE_FREE(passp);
 642 
 643         /* unpack domain sid */
 644         len += tdb_sid_unpack(pack_buf + len, bufsize - len,
 645                               &pass->domain_sid);
 646 
 647         return len;
 648 }
 649 
 650 /************************************************************************
 651  Routine to get account password to trusted domain
 652 ************************************************************************/
 653 
 654 bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
     /* [<][>][^][v][top][bottom][index][help] */
 655                                            DOM_SID *sid, time_t *pass_last_set_time)
 656 {
 657         struct trusted_dom_pass pass;
 658         size_t size = 0;
 659 
 660         /* unpacking structures */
 661         uint8 *pass_buf;
 662         int pass_len = 0;
 663 
 664         ZERO_STRUCT(pass);
 665 
 666         /* fetching trusted domain password structure */
 667         if (!(pass_buf = (uint8 *)secrets_fetch(trustdom_keystr(domain),
 668                                                &size))) {
 669                 DEBUG(5, ("secrets_fetch failed!\n"));
 670                 return False;
 671         }
 672 
 673         /* unpack trusted domain password */
 674         pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
 675         SAFE_FREE(pass_buf);
 676 
 677         if (pass_len != size) {
 678                 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
 679                 return False;
 680         }
 681 
 682         /* the trust's password */
 683         if (pwd) {
 684                 *pwd = SMB_STRDUP(pass.pass);
 685                 if (!*pwd) {
 686                         return False;
 687                 }
 688         }
 689 
 690         /* last change time */
 691         if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
 692 
 693         /* domain sid */
 694         if (sid != NULL) sid_copy(sid, &pass.domain_sid);
 695 
 696         return True;
 697 }
 698 
 699 /**
 700  * Routine to store the password for trusted domain
 701  *
 702  * @param domain remote domain name
 703  * @param pwd plain text password of trust relationship
 704  * @param sid remote domain sid
 705  *
 706  * @return true if succeeded
 707  **/
 708 
 709 bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
     /* [<][>][^][v][top][bottom][index][help] */
 710                                            const DOM_SID *sid)
 711 {
 712         smb_ucs2_t *uni_dom_name;
 713         bool ret;
 714         size_t converted_size;
 715 
 716         /* packing structures */
 717         uint8 *pass_buf = NULL;
 718         int pass_len = 0;
 719 
 720         struct trusted_dom_pass pass;
 721         ZERO_STRUCT(pass);
 722 
 723         if (!push_ucs2_allocate(&uni_dom_name, domain, &converted_size)) {
 724                 DEBUG(0, ("Could not convert domain name %s to unicode\n",
 725                           domain));
 726                 return False;
 727         }
 728 
 729         strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
 730         pass.uni_name_len = strlen_w(uni_dom_name)+1;
 731         SAFE_FREE(uni_dom_name);
 732 
 733         /* last change time */
 734         pass.mod_time = time(NULL);
 735 
 736         /* password of the trust */
 737         pass.pass_len = strlen(pwd);
 738         fstrcpy(pass.pass, pwd);
 739 
 740         /* domain sid */
 741         sid_copy(&pass.domain_sid, sid);
 742 
 743         /* Calculate the length. */
 744         pass_len = tdb_trusted_dom_pass_pack(NULL, 0, &pass);
 745         pass_buf = SMB_MALLOC_ARRAY(uint8, pass_len);
 746         if (!pass_buf) {
 747                 return false;
 748         }
 749         pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_len, &pass);
 750         ret = secrets_store(trustdom_keystr(domain), (void *)pass_buf,
 751                         pass_len);
 752         SAFE_FREE(pass_buf);
 753         return ret;
 754 }
 755 
 756 /************************************************************************
 757  Routine to delete the plaintext machine account password
 758 ************************************************************************/
 759 
 760 bool secrets_delete_machine_password(const char *domain)
     /* [<][>][^][v][top][bottom][index][help] */
 761 {
 762         return secrets_delete(machine_password_keystr(domain));
 763 }
 764 
 765 /************************************************************************
 766  Routine to delete the plaintext machine account password, sec channel type and
 767  last change time from secrets database
 768 ************************************************************************/
 769 
 770 bool secrets_delete_machine_password_ex(const char *domain)
     /* [<][>][^][v][top][bottom][index][help] */
 771 {
 772         if (!secrets_delete(machine_password_keystr(domain))) {
 773                 return false;
 774         }
 775         if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
 776                 return false;
 777         }
 778         return secrets_delete(machine_last_change_time_keystr(domain));
 779 }
 780 
 781 /************************************************************************
 782  Routine to delete the domain sid
 783 ************************************************************************/
 784 
 785 bool secrets_delete_domain_sid(const char *domain)
     /* [<][>][^][v][top][bottom][index][help] */
 786 {
 787         return secrets_delete(domain_sid_keystr(domain));
 788 }
 789 
 790 /************************************************************************
 791  Routine to set the plaintext machine account password for a realm
 792 the password is assumed to be a null terminated ascii string
 793 ************************************************************************/
 794 
 795 bool secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
     /* [<][>][^][v][top][bottom][index][help] */
 796 {
 797         bool ret;
 798         uint32 last_change_time;
 799         uint32 sec_channel_type;
 800 
 801         ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
 802         if (!ret)
 803                 return ret;
 804 
 805         SIVAL(&last_change_time, 0, time(NULL));
 806         ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
 807 
 808         SIVAL(&sec_channel_type, 0, sec_channel);
 809         ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
 810 
 811         return ret;
 812 }
 813 
 814 /************************************************************************
 815  Routine to fetch the plaintext machine account password for a realm
 816  the password is assumed to be a null terminated ascii string.
 817 ************************************************************************/
 818 
 819 char *secrets_fetch_machine_password(const char *domain,
     /* [<][>][^][v][top][bottom][index][help] */
 820                                      time_t *pass_last_set_time,
 821                                      uint32 *channel)
 822 {
 823         char *ret;
 824         ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
 825 
 826         if (pass_last_set_time) {
 827                 size_t size;
 828                 uint32 *last_set_time;
 829                 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
 830                 if (last_set_time) {
 831                         *pass_last_set_time = IVAL(last_set_time,0);
 832                         SAFE_FREE(last_set_time);
 833                 } else {
 834                         *pass_last_set_time = 0;
 835                 }
 836         }
 837 
 838         if (channel) {
 839                 size_t size;
 840                 uint32 *channel_type;
 841                 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
 842                 if (channel_type) {
 843                         *channel = IVAL(channel_type,0);
 844                         SAFE_FREE(channel_type);
 845                 } else {
 846                         *channel = get_default_sec_channel();
 847                 }
 848         }
 849 
 850         return ret;
 851 }
 852 
 853 /************************************************************************
 854  Routine to delete the password for trusted domain
 855 ************************************************************************/
 856 
 857 bool trusted_domain_password_delete(const char *domain)
     /* [<][>][^][v][top][bottom][index][help] */
 858 {
 859         return secrets_delete(trustdom_keystr(domain));
 860 }
 861 
 862 bool secrets_store_ldap_pw(const char* dn, char* pw)
     /* [<][>][^][v][top][bottom][index][help] */
 863 {
 864         char *key = NULL;
 865         bool ret;
 866 
 867         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
 868                 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
 869                 return False;
 870         }
 871 
 872         ret = secrets_store(key, pw, strlen(pw)+1);
 873 
 874         SAFE_FREE(key);
 875         return ret;
 876 }
 877 
 878 /*******************************************************************
 879  Find the ldap password.
 880 ******************************************************************/
 881 
 882 bool fetch_ldap_pw(char **dn, char** pw)
     /* [<][>][^][v][top][bottom][index][help] */
 883 {
 884         char *key = NULL;
 885         size_t size = 0;
 886 
 887         *dn = smb_xstrdup(lp_ldap_admin_dn());
 888 
 889         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
 890                 SAFE_FREE(*dn);
 891                 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
 892         }
 893 
 894         *pw=(char *)secrets_fetch(key, &size);
 895         SAFE_FREE(key);
 896 
 897         if (!size) {
 898                 /* Upgrade 2.2 style entry */
 899                 char *p;
 900                 char* old_style_key = SMB_STRDUP(*dn);
 901                 char *data;
 902                 fstring old_style_pw;
 903 
 904                 if (!old_style_key) {
 905                         DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
 906                         return False;
 907                 }
 908 
 909                 for (p=old_style_key; *p; p++)
 910                         if (*p == ',') *p = '/';
 911 
 912                 data=(char *)secrets_fetch(old_style_key, &size);
 913                 if ((data == NULL) || (size < sizeof(old_style_pw))) {
 914                         DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
 915                         SAFE_FREE(old_style_key);
 916                         SAFE_FREE(*dn);
 917                         SAFE_FREE(data);
 918                         return False;
 919                 }
 920 
 921                 size = MIN(size, sizeof(fstring)-1);
 922                 strncpy(old_style_pw, data, size);
 923                 old_style_pw[size] = 0;
 924 
 925                 SAFE_FREE(data);
 926 
 927                 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
 928                         DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
 929                         SAFE_FREE(old_style_key);
 930                         SAFE_FREE(*dn);
 931                         return False;
 932                 }
 933                 if (!secrets_delete(old_style_key)) {
 934                         DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
 935                 }
 936 
 937                 SAFE_FREE(old_style_key);
 938 
 939                 *pw = smb_xstrdup(old_style_pw);
 940         }
 941 
 942         return True;
 943 }
 944 
 945 /**
 946  * Get trusted domains info from secrets.tdb.
 947  **/
 948 
 949 struct list_trusted_domains_state {
 950         uint32 num_domains;
 951         struct trustdom_info **domains;
 952 };
 953 
 954 static int list_trusted_domain(struct db_record *rec, void *private_data)
     /* [<][>][^][v][top][bottom][index][help] */
 955 {
 956         const size_t prefix_len = strlen(SECRETS_DOMTRUST_ACCT_PASS);
 957         size_t converted_size, packed_size = 0;
 958         struct trusted_dom_pass pass;
 959         struct trustdom_info *dom_info;
 960 
 961         struct list_trusted_domains_state *state =
 962                 (struct list_trusted_domains_state *)private_data;
 963 
 964         if ((rec->key.dsize < prefix_len)
 965             || (strncmp((char *)rec->key.dptr, SECRETS_DOMTRUST_ACCT_PASS,
 966                         prefix_len) != 0)) {
 967                 return 0;
 968         }
 969 
 970         packed_size = tdb_trusted_dom_pass_unpack(
 971                 rec->value.dptr, rec->value.dsize, &pass);
 972 
 973         if (rec->value.dsize != packed_size) {
 974                 DEBUG(2, ("Secrets record is invalid!\n"));
 975                 return 0;
 976         }
 977 
 978         if (pass.domain_sid.num_auths != 4) {
 979                 DEBUG(0, ("SID %s is not a domain sid, has %d "
 980                           "auths instead of 4\n",
 981                           sid_string_dbg(&pass.domain_sid),
 982                           pass.domain_sid.num_auths));
 983                 return 0;
 984         }
 985 
 986         if (!(dom_info = TALLOC_P(state->domains, struct trustdom_info))) {
 987                 DEBUG(0, ("talloc failed\n"));
 988                 return 0;
 989         }
 990 
 991         if (!pull_ucs2_talloc(dom_info, &dom_info->name, pass.uni_name,
 992                               &converted_size)) {
 993                 DEBUG(2, ("pull_ucs2_talloc failed\n"));
 994                 TALLOC_FREE(dom_info);
 995                 return 0;
 996         }
 997 
 998         sid_copy(&dom_info->sid, &pass.domain_sid);
 999 
1000         ADD_TO_ARRAY(state->domains, struct trustdom_info *, dom_info,
1001                      &state->domains, &state->num_domains);
1002 
1003         if (state->domains == NULL) {
1004                 state->num_domains = 0;
1005                 return -1;
1006         }
1007         return 0;
1008 }
1009 
1010 NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
     /* [<][>][^][v][top][bottom][index][help] */
1011                                  struct trustdom_info ***domains)
1012 {
1013         struct list_trusted_domains_state state;
1014 
1015         secrets_init();
1016 
1017         if (db_ctx == NULL) {
1018                 return NT_STATUS_ACCESS_DENIED;
1019         }
1020 
1021         state.num_domains = 0;
1022 
1023         /*
1024          * Make sure that a talloc context for the trustdom_info structs
1025          * exists
1026          */
1027 
1028         if (!(state.domains = TALLOC_ARRAY(
1029                       mem_ctx, struct trustdom_info *, 1))) {
1030                 return NT_STATUS_NO_MEMORY;
1031         }
1032 
1033         db_ctx->traverse_read(db_ctx, list_trusted_domain, (void *)&state);
1034 
1035         *num_domains = state.num_domains;
1036         *domains = state.domains;
1037         return NT_STATUS_OK;
1038 }
1039 
1040 /*******************************************************************************
1041  Store a complete AFS keyfile into secrets.tdb.
1042 *******************************************************************************/
1043 
1044 bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
     /* [<][>][^][v][top][bottom][index][help] */
1045 {
1046         fstring key;
1047 
1048         if ((cell == NULL) || (keyfile == NULL))
1049                 return False;
1050 
1051         if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
1052                 return False;
1053 
1054         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1055         return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
1056 }
1057 
1058 /*******************************************************************************
1059  Fetch the current (highest) AFS key from secrets.tdb
1060 *******************************************************************************/
1061 bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
     /* [<][>][^][v][top][bottom][index][help] */
1062 {
1063         fstring key;
1064         struct afs_keyfile *keyfile;
1065         size_t size = 0;
1066         uint32 i;
1067 
1068         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1069 
1070         keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
1071 
1072         if (keyfile == NULL)
1073                 return False;
1074 
1075         if (size != sizeof(struct afs_keyfile)) {
1076                 SAFE_FREE(keyfile);
1077                 return False;
1078         }
1079 
1080         i = ntohl(keyfile->nkeys);
1081 
1082         if (i > SECRETS_AFS_MAXKEYS) {
1083                 SAFE_FREE(keyfile);
1084                 return False;
1085         }
1086 
1087         *result = keyfile->entry[i-1];
1088 
1089         result->kvno = ntohl(result->kvno);
1090 
1091         SAFE_FREE(keyfile);
1092 
1093         return True;
1094 }
1095 
1096 /******************************************************************************
1097   When kerberos is not available, choose between anonymous or
1098   authenticated connections.
1099 
1100   We need to use an authenticated connection if DCs have the
1101   RestrictAnonymous registry entry set > 0, or the "Additional
1102   restrictions for anonymous connections" set in the win2k Local
1103   Security Policy.
1104 
1105   Caller to free() result in domain, username, password
1106 *******************************************************************************/
1107 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
     /* [<][>][^][v][top][bottom][index][help] */
1108 {
1109         *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
1110         *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
1111         *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
1112 
1113         if (*username && **username) {
1114 
1115                 if (!*domain || !**domain)
1116                         *domain = smb_xstrdup(lp_workgroup());
1117 
1118                 if (!*password || !**password)
1119                         *password = smb_xstrdup("");
1120 
1121                 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
1122                           *domain, *username));
1123 
1124         } else {
1125                 DEBUG(3, ("IPC$ connections done anonymously\n"));
1126                 *username = smb_xstrdup("");
1127                 *domain = smb_xstrdup("");
1128                 *password = smb_xstrdup("");
1129         }
1130 }
1131 
1132 /******************************************************************************
1133  Open or create the schannel session store tdb.
1134 *******************************************************************************/
1135 
1136 static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
1137 {
1138         TDB_DATA vers;
1139         uint32 ver;
1140         TDB_CONTEXT *tdb_sc = NULL;
1141         char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
1142 
1143         if (!fname) {
1144                 return NULL;
1145         }
1146 
1147         tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
1148 
1149         if (!tdb_sc) {
1150                 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
1151                 TALLOC_FREE(fname);
1152                 return NULL;
1153         }
1154 
1155         vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
1156         if (vers.dptr == NULL) {
1157                 /* First opener, no version. */
1158                 SIVAL(&ver,0,1);
1159                 vers.dptr = (uint8 *)&ver;
1160                 vers.dsize = 4;
1161                 tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
1162                 vers.dptr = NULL;
1163         } else if (vers.dsize == 4) {
1164                 ver = IVAL(vers.dptr,0);
1165                 if (ver != 1) {
1166                         tdb_close(tdb_sc);
1167                         tdb_sc = NULL;
1168                         DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
1169                                 (int)ver, fname ));
1170                 }
1171         } else {
1172                 tdb_close(tdb_sc);
1173                 tdb_sc = NULL;
1174                 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
1175                         (int)vers.dsize, fname ));
1176         }
1177 
1178         SAFE_FREE(vers.dptr);
1179         TALLOC_FREE(fname);
1180 
1181         return tdb_sc;
1182 }
1183 
1184 /******************************************************************************
1185  Store the schannel state after an AUTH2 call.
1186  Note we must be root here.
1187 *******************************************************************************/
1188 
1189 bool secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1190                                 const char *remote_machine,
1191                                 const struct dcinfo *pdc)
1192 {
1193         TDB_CONTEXT *tdb_sc = NULL;
1194         TDB_DATA value;
1195         bool ret;
1196         char *keystr = talloc_asprintf_strupper_m(mem_ctx, "%s/%s",
1197                                                   SECRETS_SCHANNEL_STATE,
1198                                                   remote_machine);
1199         if (!keystr) {
1200                 return False;
1201         }
1202 
1203         /* Work out how large the record is. */
1204         value.dsize = tdb_pack(NULL, 0, "dBBBBBfff",
1205                                 pdc->sequence,
1206                                 8, pdc->seed_chal.data,
1207                                 8, pdc->clnt_chal.data,
1208                                 8, pdc->srv_chal.data,
1209                                 16, pdc->sess_key,
1210                                 16, pdc->mach_pw,
1211                                 pdc->mach_acct,
1212                                 pdc->remote_machine,
1213                                 pdc->domain);
1214 
1215         value.dptr = TALLOC_ARRAY(mem_ctx, uint8, value.dsize);
1216         if (!value.dptr) {
1217                 TALLOC_FREE(keystr);
1218                 return False;
1219         }
1220 
1221         value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff",
1222                                 pdc->sequence,
1223                                 8, pdc->seed_chal.data,
1224                                 8, pdc->clnt_chal.data,
1225                                 8, pdc->srv_chal.data,
1226                                 16, pdc->sess_key,
1227                                 16, pdc->mach_pw,
1228                                 pdc->mach_acct,
1229                                 pdc->remote_machine,
1230                                 pdc->domain);
1231 
1232         tdb_sc = open_schannel_session_store(mem_ctx);
1233         if (!tdb_sc) {
1234                 TALLOC_FREE(keystr);
1235                 TALLOC_FREE(value.dptr);
1236                 return False;
1237         }
1238 
1239         ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False);
1240 
1241         DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
1242                 keystr ));
1243 
1244         tdb_close(tdb_sc);
1245         TALLOC_FREE(keystr);
1246         TALLOC_FREE(value.dptr);
1247         return ret;
1248 }
1249 
1250 /******************************************************************************
1251  Restore the schannel state on a client reconnect.
1252  Note we must be root here.
1253 *******************************************************************************/
1254 
1255 bool secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1256                                 const char *remote_machine,
1257                                 struct dcinfo **ppdc)
1258 {
1259         TDB_CONTEXT *tdb_sc = NULL;
1260         TDB_DATA value;
1261         unsigned char *pseed_chal = NULL;
1262         unsigned char *pclnt_chal = NULL;
1263         unsigned char *psrv_chal = NULL;
1264         unsigned char *psess_key = NULL;
1265         unsigned char *pmach_pw = NULL;
1266         uint32 l1, l2, l3, l4, l5;
1267         int ret;
1268         struct dcinfo *pdc = NULL;
1269         char *keystr = talloc_asprintf_strupper_m(mem_ctx, "%s/%s",
1270                                                   SECRETS_SCHANNEL_STATE,
1271                                                   remote_machine);
1272 
1273         *ppdc = NULL;
1274 
1275         if (!keystr) {
1276                 return False;
1277         }
1278 
1279         tdb_sc = open_schannel_session_store(mem_ctx);
1280         if (!tdb_sc) {
1281                 TALLOC_FREE(keystr);
1282                 return False;
1283         }
1284 
1285         value = tdb_fetch_bystring(tdb_sc, keystr);
1286         if (!value.dptr) {
1287                 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
1288                         keystr ));
1289                 tdb_close(tdb_sc);
1290                 return False;
1291         }
1292 
1293         pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
1294 
1295         /* Retrieve the record. */
1296         ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
1297                                 &pdc->sequence,
1298                                 &l1, &pseed_chal,
1299                                 &l2, &pclnt_chal,
1300                                 &l3, &psrv_chal,
1301                                 &l4, &psess_key,
1302                                 &l5, &pmach_pw,
1303                                 &pdc->mach_acct,
1304                                 &pdc->remote_machine,
1305                                 &pdc->domain);
1306 
1307         if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) {
1308                 /* Bad record - delete it. */
1309                 tdb_delete_bystring(tdb_sc, keystr);
1310                 tdb_close(tdb_sc);
1311                 TALLOC_FREE(keystr);
1312                 TALLOC_FREE(pdc);
1313                 SAFE_FREE(pseed_chal);
1314                 SAFE_FREE(pclnt_chal);
1315                 SAFE_FREE(psrv_chal);
1316                 SAFE_FREE(psess_key);
1317                 SAFE_FREE(pmach_pw);
1318                 SAFE_FREE(value.dptr);
1319                 return False;
1320         }
1321 
1322         tdb_close(tdb_sc);
1323 
1324         memcpy(pdc->seed_chal.data, pseed_chal, 8);
1325         memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
1326         memcpy(pdc->srv_chal.data, psrv_chal, 8);
1327         memcpy(pdc->sess_key, psess_key, 16);
1328         memcpy(pdc->mach_pw, pmach_pw, 16);
1329 
1330         /* We know these are true so didn't bother to store them. */
1331         pdc->challenge_sent = True;
1332         pdc->authenticated = True;
1333 
1334         DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
1335                 keystr ));
1336 
1337         SAFE_FREE(pseed_chal);
1338         SAFE_FREE(pclnt_chal);
1339         SAFE_FREE(psrv_chal);
1340         SAFE_FREE(psess_key);
1341         SAFE_FREE(pmach_pw);
1342 
1343         TALLOC_FREE(keystr);
1344         SAFE_FREE(value.dptr);
1345 
1346         *ppdc = pdc;
1347 
1348         return True;
1349 }
1350 
1351 bool secrets_store_generic(const char *owner, const char *key, const char *secret)
     /* [<][>][^][v][top][bottom][index][help] */
1352 {
1353         char *tdbkey = NULL;
1354         bool ret;
1355 
1356         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1357                 DEBUG(0, ("asprintf failed!\n"));
1358                 return False;
1359         }
1360 
1361         ret = secrets_store(tdbkey, secret, strlen(secret)+1);
1362 
1363         SAFE_FREE(tdbkey);
1364         return ret;
1365 }
1366 
1367 /*******************************************************************
1368  Find the ldap password.
1369 ******************************************************************/
1370 
1371 char *secrets_fetch_generic(const char *owner, const char *key)
     /* [<][>][^][v][top][bottom][index][help] */
1372 {
1373         char *secret = NULL;
1374         char *tdbkey = NULL;
1375 
1376         if (( ! owner) || ( ! key)) {
1377                 DEBUG(1, ("Invalid Paramters"));
1378                 return NULL;
1379         }
1380 
1381         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1382                 DEBUG(0, ("Out of memory!\n"));
1383                 return NULL;
1384         }
1385 
1386         secret = (char *)secrets_fetch(tdbkey, NULL);
1387         SAFE_FREE(tdbkey);
1388 
1389         return secret;
1390 }
1391 

/* [<][>][^][v][top][bottom][index][help] */