[480] | 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"
|
---|
[745] | 26 | #include "system/filesys.h"
|
---|
| 27 | #include "passdb.h"
|
---|
[480] | 28 | #include "../libcli/auth/libcli_auth.h"
|
---|
| 29 | #include "librpc/gen_ndr/ndr_secrets.h"
|
---|
[745] | 30 | #include "secrets.h"
|
---|
| 31 | #include "dbwrap.h"
|
---|
| 32 | #include "../libcli/security/security.h"
|
---|
| 33 | #include "util_tdb.h"
|
---|
[480] | 34 |
|
---|
| 35 | #undef DBGC_CLASS
|
---|
| 36 | #define DBGC_CLASS DBGC_PASSDB
|
---|
| 37 |
|
---|
| 38 | static struct db_context *db_ctx;
|
---|
| 39 |
|
---|
| 40 | /**
|
---|
| 41 | * Use a TDB to store an incrementing random seed.
|
---|
| 42 | *
|
---|
| 43 | * Initialised to the current pid, the very first time Samba starts,
|
---|
| 44 | * and incremented by one each time it is needed.
|
---|
| 45 | *
|
---|
| 46 | * @note Not called by systems with a working /dev/urandom.
|
---|
| 47 | */
|
---|
| 48 | static void get_rand_seed(void *userdata, int *new_seed)
|
---|
| 49 | {
|
---|
| 50 | *new_seed = sys_getpid();
|
---|
| 51 | if (db_ctx) {
|
---|
| 52 | dbwrap_trans_change_int32_atomic(db_ctx, "INFO/random_seed",
|
---|
| 53 | new_seed, 1);
|
---|
| 54 | }
|
---|
| 55 | }
|
---|
| 56 |
|
---|
| 57 | /* open up the secrets database */
|
---|
| 58 | bool secrets_init(void)
|
---|
| 59 | {
|
---|
| 60 | char *fname = NULL;
|
---|
| 61 | unsigned char dummy;
|
---|
| 62 |
|
---|
| 63 | if (db_ctx != NULL)
|
---|
| 64 | return True;
|
---|
| 65 |
|
---|
| 66 | fname = talloc_asprintf(talloc_tos(), "%s/secrets.tdb",
|
---|
| 67 | lp_private_dir());
|
---|
| 68 | if (fname == NULL) {
|
---|
| 69 | return false;
|
---|
| 70 | }
|
---|
| 71 |
|
---|
| 72 | db_ctx = db_open(NULL, fname, 0,
|
---|
| 73 | TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
|
---|
| 74 |
|
---|
| 75 | if (db_ctx == NULL) {
|
---|
| 76 | DEBUG(0,("Failed to open %s\n", fname));
|
---|
| 77 | TALLOC_FREE(fname);
|
---|
| 78 | return False;
|
---|
| 79 | }
|
---|
| 80 |
|
---|
| 81 | TALLOC_FREE(fname);
|
---|
| 82 |
|
---|
| 83 | /**
|
---|
| 84 | * Set a reseed function for the crypto random generator
|
---|
| 85 | *
|
---|
| 86 | * This avoids a problem where systems without /dev/urandom
|
---|
| 87 | * could send the same challenge to multiple clients
|
---|
| 88 | */
|
---|
| 89 | set_rand_reseed_callback(get_rand_seed, NULL);
|
---|
| 90 |
|
---|
| 91 | /* Ensure that the reseed is done now, while we are root, etc */
|
---|
| 92 | generate_random_buffer(&dummy, sizeof(dummy));
|
---|
| 93 |
|
---|
| 94 | return True;
|
---|
| 95 | }
|
---|
| 96 |
|
---|
| 97 | struct db_context *secrets_db_ctx(void)
|
---|
| 98 | {
|
---|
| 99 | if (!secrets_init()) {
|
---|
| 100 | return NULL;
|
---|
| 101 | }
|
---|
| 102 |
|
---|
| 103 | return db_ctx;
|
---|
| 104 | }
|
---|
| 105 |
|
---|
| 106 | /*
|
---|
| 107 | * close secrets.tdb
|
---|
| 108 | */
|
---|
| 109 | void secrets_shutdown(void)
|
---|
| 110 | {
|
---|
| 111 | TALLOC_FREE(db_ctx);
|
---|
| 112 | }
|
---|
| 113 |
|
---|
| 114 | /* read a entry from the secrets database - the caller must free the result
|
---|
| 115 | if size is non-null then the size of the entry is put in there
|
---|
| 116 | */
|
---|
| 117 | void *secrets_fetch(const char *key, size_t *size)
|
---|
| 118 | {
|
---|
| 119 | TDB_DATA dbuf;
|
---|
| 120 | void *result;
|
---|
| 121 |
|
---|
| 122 | if (!secrets_init()) {
|
---|
| 123 | return NULL;
|
---|
| 124 | }
|
---|
| 125 |
|
---|
| 126 | if (db_ctx->fetch(db_ctx, talloc_tos(), string_tdb_data(key),
|
---|
| 127 | &dbuf) != 0) {
|
---|
| 128 | return NULL;
|
---|
| 129 | }
|
---|
| 130 |
|
---|
| 131 | result = memdup(dbuf.dptr, dbuf.dsize);
|
---|
| 132 | if (result == NULL) {
|
---|
| 133 | return NULL;
|
---|
| 134 | }
|
---|
| 135 | TALLOC_FREE(dbuf.dptr);
|
---|
| 136 |
|
---|
| 137 | if (size) {
|
---|
| 138 | *size = dbuf.dsize;
|
---|
| 139 | }
|
---|
| 140 |
|
---|
| 141 | return result;
|
---|
| 142 | }
|
---|
| 143 |
|
---|
| 144 | /* store a secrets entry
|
---|
| 145 | */
|
---|
| 146 | bool secrets_store(const char *key, const void *data, size_t size)
|
---|
| 147 | {
|
---|
| 148 | NTSTATUS status;
|
---|
| 149 |
|
---|
| 150 | if (!secrets_init()) {
|
---|
| 151 | return false;
|
---|
| 152 | }
|
---|
| 153 |
|
---|
| 154 | status = dbwrap_trans_store(db_ctx, string_tdb_data(key),
|
---|
| 155 | make_tdb_data((const uint8 *)data, size),
|
---|
| 156 | TDB_REPLACE);
|
---|
| 157 | return NT_STATUS_IS_OK(status);
|
---|
| 158 | }
|
---|
| 159 |
|
---|
| 160 |
|
---|
| 161 | /* delete a secets database entry
|
---|
| 162 | */
|
---|
| 163 | bool secrets_delete(const char *key)
|
---|
| 164 | {
|
---|
| 165 | NTSTATUS status;
|
---|
| 166 | if (!secrets_init()) {
|
---|
| 167 | return false;
|
---|
| 168 | }
|
---|
| 169 |
|
---|
| 170 | status = dbwrap_trans_delete(db_ctx, string_tdb_data(key));
|
---|
| 171 |
|
---|
| 172 | return NT_STATUS_IS_OK(status);
|
---|
| 173 | }
|
---|
| 174 |
|
---|
| 175 | /**
|
---|
| 176 | * Form a key for fetching a trusted domain password
|
---|
| 177 | *
|
---|
| 178 | * @param domain trusted domain name
|
---|
| 179 | *
|
---|
| 180 | * @return stored password's key
|
---|
| 181 | **/
|
---|
| 182 | static char *trustdom_keystr(const char *domain)
|
---|
| 183 | {
|
---|
| 184 | char *keystr;
|
---|
| 185 |
|
---|
| 186 | keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
|
---|
| 187 | SECRETS_DOMTRUST_ACCT_PASS,
|
---|
| 188 | domain);
|
---|
| 189 | SMB_ASSERT(keystr != NULL);
|
---|
| 190 | return keystr;
|
---|
| 191 | }
|
---|
| 192 |
|
---|
| 193 | /************************************************************************
|
---|
| 194 | Routine to get account password to trusted domain
|
---|
| 195 | ************************************************************************/
|
---|
| 196 |
|
---|
| 197 | bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
|
---|
[745] | 198 | struct dom_sid *sid, time_t *pass_last_set_time)
|
---|
[480] | 199 | {
|
---|
| 200 | struct TRUSTED_DOM_PASS pass;
|
---|
| 201 | enum ndr_err_code ndr_err;
|
---|
| 202 |
|
---|
| 203 | /* unpacking structures */
|
---|
| 204 | DATA_BLOB blob;
|
---|
| 205 |
|
---|
| 206 | /* fetching trusted domain password structure */
|
---|
| 207 | if (!(blob.data = (uint8_t *)secrets_fetch(trustdom_keystr(domain),
|
---|
| 208 | &blob.length))) {
|
---|
| 209 | DEBUG(5, ("secrets_fetch failed!\n"));
|
---|
| 210 | return False;
|
---|
| 211 | }
|
---|
| 212 |
|
---|
| 213 | /* unpack trusted domain password */
|
---|
[745] | 214 | ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &pass,
|
---|
[480] | 215 | (ndr_pull_flags_fn_t)ndr_pull_TRUSTED_DOM_PASS);
|
---|
[745] | 216 |
|
---|
| 217 | SAFE_FREE(blob.data);
|
---|
| 218 |
|
---|
[480] | 219 | if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
---|
| 220 | return false;
|
---|
| 221 | }
|
---|
| 222 |
|
---|
| 223 |
|
---|
| 224 | /* the trust's password */
|
---|
| 225 | if (pwd) {
|
---|
| 226 | *pwd = SMB_STRDUP(pass.pass);
|
---|
| 227 | if (!*pwd) {
|
---|
| 228 | return False;
|
---|
| 229 | }
|
---|
| 230 | }
|
---|
| 231 |
|
---|
| 232 | /* last change time */
|
---|
| 233 | if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
|
---|
| 234 |
|
---|
| 235 | /* domain sid */
|
---|
| 236 | if (sid != NULL) sid_copy(sid, &pass.domain_sid);
|
---|
| 237 |
|
---|
| 238 | return True;
|
---|
| 239 | }
|
---|
| 240 |
|
---|
| 241 | /**
|
---|
| 242 | * Routine to store the password for trusted domain
|
---|
| 243 | *
|
---|
| 244 | * @param domain remote domain name
|
---|
| 245 | * @param pwd plain text password of trust relationship
|
---|
| 246 | * @param sid remote domain sid
|
---|
| 247 | *
|
---|
| 248 | * @return true if succeeded
|
---|
| 249 | **/
|
---|
| 250 |
|
---|
| 251 | bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
|
---|
[745] | 252 | const struct dom_sid *sid)
|
---|
[480] | 253 | {
|
---|
| 254 | bool ret;
|
---|
| 255 |
|
---|
| 256 | /* packing structures */
|
---|
| 257 | DATA_BLOB blob;
|
---|
| 258 | enum ndr_err_code ndr_err;
|
---|
| 259 | struct TRUSTED_DOM_PASS pass;
|
---|
| 260 | ZERO_STRUCT(pass);
|
---|
| 261 |
|
---|
| 262 | pass.uni_name = domain;
|
---|
| 263 | pass.uni_name_len = strlen(domain)+1;
|
---|
| 264 |
|
---|
| 265 | /* last change time */
|
---|
| 266 | pass.mod_time = time(NULL);
|
---|
| 267 |
|
---|
| 268 | /* password of the trust */
|
---|
| 269 | pass.pass_len = strlen(pwd);
|
---|
| 270 | pass.pass = pwd;
|
---|
| 271 |
|
---|
| 272 | /* domain sid */
|
---|
| 273 | sid_copy(&pass.domain_sid, sid);
|
---|
| 274 |
|
---|
[745] | 275 | ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &pass,
|
---|
[480] | 276 | (ndr_push_flags_fn_t)ndr_push_TRUSTED_DOM_PASS);
|
---|
| 277 | if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
---|
| 278 | return false;
|
---|
| 279 | }
|
---|
| 280 |
|
---|
| 281 | ret = secrets_store(trustdom_keystr(domain), blob.data, blob.length);
|
---|
| 282 |
|
---|
| 283 | data_blob_free(&blob);
|
---|
| 284 |
|
---|
| 285 | return ret;
|
---|
| 286 | }
|
---|
| 287 |
|
---|
| 288 | /************************************************************************
|
---|
| 289 | Routine to delete the password for trusted domain
|
---|
| 290 | ************************************************************************/
|
---|
| 291 |
|
---|
| 292 | bool trusted_domain_password_delete(const char *domain)
|
---|
| 293 | {
|
---|
| 294 | return secrets_delete(trustdom_keystr(domain));
|
---|
| 295 | }
|
---|
| 296 |
|
---|
| 297 | bool secrets_store_ldap_pw(const char* dn, char* pw)
|
---|
| 298 | {
|
---|
| 299 | char *key = NULL;
|
---|
| 300 | bool ret;
|
---|
| 301 |
|
---|
| 302 | if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
|
---|
| 303 | DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
|
---|
| 304 | return False;
|
---|
| 305 | }
|
---|
| 306 |
|
---|
| 307 | ret = secrets_store(key, pw, strlen(pw)+1);
|
---|
| 308 |
|
---|
| 309 | SAFE_FREE(key);
|
---|
| 310 | return ret;
|
---|
| 311 | }
|
---|
| 312 |
|
---|
| 313 | /*******************************************************************
|
---|
| 314 | Find the ldap password.
|
---|
| 315 | ******************************************************************/
|
---|
| 316 |
|
---|
| 317 | bool fetch_ldap_pw(char **dn, char** pw)
|
---|
| 318 | {
|
---|
| 319 | char *key = NULL;
|
---|
| 320 | size_t size = 0;
|
---|
| 321 |
|
---|
| 322 | *dn = smb_xstrdup(lp_ldap_admin_dn());
|
---|
| 323 |
|
---|
| 324 | if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
|
---|
| 325 | SAFE_FREE(*dn);
|
---|
| 326 | DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
|
---|
| 327 | return false;
|
---|
| 328 | }
|
---|
| 329 |
|
---|
| 330 | *pw=(char *)secrets_fetch(key, &size);
|
---|
| 331 | SAFE_FREE(key);
|
---|
| 332 |
|
---|
| 333 | if (!size) {
|
---|
| 334 | /* Upgrade 2.2 style entry */
|
---|
| 335 | char *p;
|
---|
| 336 | char* old_style_key = SMB_STRDUP(*dn);
|
---|
| 337 | char *data;
|
---|
| 338 | fstring old_style_pw;
|
---|
| 339 |
|
---|
| 340 | if (!old_style_key) {
|
---|
| 341 | DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
|
---|
| 342 | return False;
|
---|
| 343 | }
|
---|
| 344 |
|
---|
| 345 | for (p=old_style_key; *p; p++)
|
---|
| 346 | if (*p == ',') *p = '/';
|
---|
| 347 |
|
---|
| 348 | data=(char *)secrets_fetch(old_style_key, &size);
|
---|
| 349 | if ((data == NULL) || (size < sizeof(old_style_pw))) {
|
---|
| 350 | DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
|
---|
| 351 | SAFE_FREE(old_style_key);
|
---|
| 352 | SAFE_FREE(*dn);
|
---|
| 353 | SAFE_FREE(data);
|
---|
| 354 | return False;
|
---|
| 355 | }
|
---|
| 356 |
|
---|
| 357 | size = MIN(size, sizeof(fstring)-1);
|
---|
| 358 | strncpy(old_style_pw, data, size);
|
---|
| 359 | old_style_pw[size] = 0;
|
---|
| 360 |
|
---|
| 361 | SAFE_FREE(data);
|
---|
| 362 |
|
---|
| 363 | if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
|
---|
| 364 | DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
|
---|
| 365 | SAFE_FREE(old_style_key);
|
---|
| 366 | SAFE_FREE(*dn);
|
---|
| 367 | return False;
|
---|
| 368 | }
|
---|
| 369 | if (!secrets_delete(old_style_key)) {
|
---|
| 370 | DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
|
---|
| 371 | }
|
---|
| 372 |
|
---|
| 373 | SAFE_FREE(old_style_key);
|
---|
| 374 |
|
---|
| 375 | *pw = smb_xstrdup(old_style_pw);
|
---|
| 376 | }
|
---|
| 377 |
|
---|
| 378 | return True;
|
---|
| 379 | }
|
---|
| 380 |
|
---|
| 381 | /**
|
---|
| 382 | * Get trusted domains info from secrets.tdb.
|
---|
| 383 | **/
|
---|
| 384 |
|
---|
| 385 | struct list_trusted_domains_state {
|
---|
| 386 | uint32 num_domains;
|
---|
| 387 | struct trustdom_info **domains;
|
---|
| 388 | };
|
---|
| 389 |
|
---|
| 390 | static int list_trusted_domain(struct db_record *rec, void *private_data)
|
---|
| 391 | {
|
---|
| 392 | const size_t prefix_len = strlen(SECRETS_DOMTRUST_ACCT_PASS);
|
---|
| 393 | struct TRUSTED_DOM_PASS pass;
|
---|
| 394 | enum ndr_err_code ndr_err;
|
---|
| 395 | DATA_BLOB blob;
|
---|
| 396 | struct trustdom_info *dom_info;
|
---|
| 397 |
|
---|
| 398 | struct list_trusted_domains_state *state =
|
---|
| 399 | (struct list_trusted_domains_state *)private_data;
|
---|
| 400 |
|
---|
| 401 | if ((rec->key.dsize < prefix_len)
|
---|
| 402 | || (strncmp((char *)rec->key.dptr, SECRETS_DOMTRUST_ACCT_PASS,
|
---|
| 403 | prefix_len) != 0)) {
|
---|
| 404 | return 0;
|
---|
| 405 | }
|
---|
| 406 |
|
---|
| 407 | blob = data_blob_const(rec->value.dptr, rec->value.dsize);
|
---|
| 408 |
|
---|
[745] | 409 | ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &pass,
|
---|
[480] | 410 | (ndr_pull_flags_fn_t)ndr_pull_TRUSTED_DOM_PASS);
|
---|
| 411 | if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
---|
| 412 | return false;
|
---|
| 413 | }
|
---|
| 414 |
|
---|
| 415 | if (pass.domain_sid.num_auths != 4) {
|
---|
| 416 | DEBUG(0, ("SID %s is not a domain sid, has %d "
|
---|
| 417 | "auths instead of 4\n",
|
---|
| 418 | sid_string_dbg(&pass.domain_sid),
|
---|
| 419 | pass.domain_sid.num_auths));
|
---|
| 420 | return 0;
|
---|
| 421 | }
|
---|
| 422 |
|
---|
| 423 | if (!(dom_info = TALLOC_P(state->domains, struct trustdom_info))) {
|
---|
| 424 | DEBUG(0, ("talloc failed\n"));
|
---|
| 425 | return 0;
|
---|
| 426 | }
|
---|
| 427 |
|
---|
| 428 | dom_info->name = talloc_strdup(dom_info, pass.uni_name);
|
---|
| 429 | if (!dom_info->name) {
|
---|
| 430 | TALLOC_FREE(dom_info);
|
---|
| 431 | return 0;
|
---|
| 432 | }
|
---|
| 433 |
|
---|
| 434 | sid_copy(&dom_info->sid, &pass.domain_sid);
|
---|
| 435 |
|
---|
| 436 | ADD_TO_ARRAY(state->domains, struct trustdom_info *, dom_info,
|
---|
| 437 | &state->domains, &state->num_domains);
|
---|
| 438 |
|
---|
| 439 | if (state->domains == NULL) {
|
---|
| 440 | state->num_domains = 0;
|
---|
| 441 | return -1;
|
---|
| 442 | }
|
---|
| 443 | return 0;
|
---|
| 444 | }
|
---|
| 445 |
|
---|
| 446 | NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
|
---|
| 447 | struct trustdom_info ***domains)
|
---|
| 448 | {
|
---|
| 449 | struct list_trusted_domains_state state;
|
---|
| 450 |
|
---|
[745] | 451 | if (!secrets_init()) {
|
---|
[480] | 452 | return NT_STATUS_ACCESS_DENIED;
|
---|
| 453 | }
|
---|
| 454 |
|
---|
| 455 | state.num_domains = 0;
|
---|
| 456 |
|
---|
| 457 | /*
|
---|
| 458 | * Make sure that a talloc context for the trustdom_info structs
|
---|
| 459 | * exists
|
---|
| 460 | */
|
---|
| 461 |
|
---|
| 462 | if (!(state.domains = TALLOC_ARRAY(
|
---|
| 463 | mem_ctx, struct trustdom_info *, 1))) {
|
---|
| 464 | return NT_STATUS_NO_MEMORY;
|
---|
| 465 | }
|
---|
| 466 |
|
---|
| 467 | db_ctx->traverse_read(db_ctx, list_trusted_domain, (void *)&state);
|
---|
| 468 |
|
---|
| 469 | *num_domains = state.num_domains;
|
---|
| 470 | *domains = state.domains;
|
---|
| 471 | return NT_STATUS_OK;
|
---|
| 472 | }
|
---|
| 473 |
|
---|
| 474 | /*******************************************************************************
|
---|
| 475 | Store a complete AFS keyfile into secrets.tdb.
|
---|
| 476 | *******************************************************************************/
|
---|
| 477 |
|
---|
| 478 | bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
|
---|
| 479 | {
|
---|
| 480 | fstring key;
|
---|
| 481 |
|
---|
| 482 | if ((cell == NULL) || (keyfile == NULL))
|
---|
| 483 | return False;
|
---|
| 484 |
|
---|
| 485 | if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
|
---|
| 486 | return False;
|
---|
| 487 |
|
---|
| 488 | slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
|
---|
| 489 | return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
|
---|
| 490 | }
|
---|
| 491 |
|
---|
| 492 | /*******************************************************************************
|
---|
| 493 | Fetch the current (highest) AFS key from secrets.tdb
|
---|
| 494 | *******************************************************************************/
|
---|
| 495 | bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
|
---|
| 496 | {
|
---|
| 497 | fstring key;
|
---|
| 498 | struct afs_keyfile *keyfile;
|
---|
| 499 | size_t size = 0;
|
---|
| 500 | uint32 i;
|
---|
| 501 |
|
---|
| 502 | slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
|
---|
| 503 |
|
---|
| 504 | keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
|
---|
| 505 |
|
---|
| 506 | if (keyfile == NULL)
|
---|
| 507 | return False;
|
---|
| 508 |
|
---|
| 509 | if (size != sizeof(struct afs_keyfile)) {
|
---|
| 510 | SAFE_FREE(keyfile);
|
---|
| 511 | return False;
|
---|
| 512 | }
|
---|
| 513 |
|
---|
| 514 | i = ntohl(keyfile->nkeys);
|
---|
| 515 |
|
---|
| 516 | if (i > SECRETS_AFS_MAXKEYS) {
|
---|
| 517 | SAFE_FREE(keyfile);
|
---|
| 518 | return False;
|
---|
| 519 | }
|
---|
| 520 |
|
---|
| 521 | *result = keyfile->entry[i-1];
|
---|
| 522 |
|
---|
| 523 | result->kvno = ntohl(result->kvno);
|
---|
| 524 |
|
---|
| 525 | SAFE_FREE(keyfile);
|
---|
| 526 |
|
---|
| 527 | return True;
|
---|
| 528 | }
|
---|
| 529 |
|
---|
| 530 | /******************************************************************************
|
---|
| 531 | When kerberos is not available, choose between anonymous or
|
---|
| 532 | authenticated connections.
|
---|
| 533 |
|
---|
| 534 | We need to use an authenticated connection if DCs have the
|
---|
| 535 | RestrictAnonymous registry entry set > 0, or the "Additional
|
---|
| 536 | restrictions for anonymous connections" set in the win2k Local
|
---|
| 537 | Security Policy.
|
---|
| 538 |
|
---|
| 539 | Caller to free() result in domain, username, password
|
---|
| 540 | *******************************************************************************/
|
---|
| 541 | void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
|
---|
| 542 | {
|
---|
| 543 | *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
|
---|
| 544 | *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
|
---|
| 545 | *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
|
---|
| 546 |
|
---|
| 547 | if (*username && **username) {
|
---|
| 548 |
|
---|
| 549 | if (!*domain || !**domain)
|
---|
| 550 | *domain = smb_xstrdup(lp_workgroup());
|
---|
| 551 |
|
---|
| 552 | if (!*password || !**password)
|
---|
| 553 | *password = smb_xstrdup("");
|
---|
| 554 |
|
---|
| 555 | DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
|
---|
| 556 | *domain, *username));
|
---|
| 557 |
|
---|
| 558 | } else {
|
---|
| 559 | DEBUG(3, ("IPC$ connections done anonymously\n"));
|
---|
| 560 | *username = smb_xstrdup("");
|
---|
| 561 | *domain = smb_xstrdup("");
|
---|
| 562 | *password = smb_xstrdup("");
|
---|
| 563 | }
|
---|
| 564 | }
|
---|
| 565 |
|
---|
| 566 | bool secrets_store_generic(const char *owner, const char *key, const char *secret)
|
---|
| 567 | {
|
---|
| 568 | char *tdbkey = NULL;
|
---|
| 569 | bool ret;
|
---|
| 570 |
|
---|
| 571 | if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
|
---|
| 572 | DEBUG(0, ("asprintf failed!\n"));
|
---|
| 573 | return False;
|
---|
| 574 | }
|
---|
| 575 |
|
---|
| 576 | ret = secrets_store(tdbkey, secret, strlen(secret)+1);
|
---|
| 577 |
|
---|
| 578 | SAFE_FREE(tdbkey);
|
---|
| 579 | return ret;
|
---|
| 580 | }
|
---|
| 581 |
|
---|
| 582 | bool secrets_delete_generic(const char *owner, const char *key)
|
---|
| 583 | {
|
---|
| 584 | char *tdbkey = NULL;
|
---|
| 585 | bool ret;
|
---|
| 586 |
|
---|
| 587 | if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
|
---|
| 588 | DEBUG(0, ("asprintf failed!\n"));
|
---|
| 589 | return False;
|
---|
| 590 | }
|
---|
| 591 |
|
---|
| 592 | ret = secrets_delete(tdbkey);
|
---|
| 593 |
|
---|
| 594 | SAFE_FREE(tdbkey);
|
---|
| 595 | return ret;
|
---|
| 596 | }
|
---|
| 597 |
|
---|
| 598 | /*******************************************************************
|
---|
| 599 | Find the ldap password.
|
---|
| 600 | ******************************************************************/
|
---|
| 601 |
|
---|
| 602 | char *secrets_fetch_generic(const char *owner, const char *key)
|
---|
| 603 | {
|
---|
| 604 | char *secret = NULL;
|
---|
| 605 | char *tdbkey = NULL;
|
---|
| 606 |
|
---|
| 607 | if (( ! owner) || ( ! key)) {
|
---|
[745] | 608 | DEBUG(1, ("Invalid Parameters"));
|
---|
[480] | 609 | return NULL;
|
---|
| 610 | }
|
---|
| 611 |
|
---|
| 612 | if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
|
---|
| 613 | DEBUG(0, ("Out of memory!\n"));
|
---|
| 614 | return NULL;
|
---|
| 615 | }
|
---|
| 616 |
|
---|
| 617 | secret = (char *)secrets_fetch(tdbkey, NULL);
|
---|
| 618 | SAFE_FREE(tdbkey);
|
---|
| 619 |
|
---|
| 620 | return secret;
|
---|
| 621 | }
|
---|
| 622 |
|
---|