📄 secrets.c
字号:
/* set proper status code to return */ if (k->next) { /* there are yet some entries to enumerate */ status = STATUS_MORE_ENTRIES; } else { /* this is the last entry in the whole enumeration */ status = NT_STATUS_OK; } } else { DEBUG(18, ("Secret is outside the required range.\n \ start_idx = %d, max_num_domains = %d. Not added to returned array\n", start_idx, max_num_domains)); } idx++; } DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n", *num_domains)); /* free the results of searching the keys */ tdb_search_list_free(keys); return status;}/******************************************************************************* Lock the secrets tdb based on a string - this is used as a primitive form of mutex between smbd instances.*******************************************************************************/BOOL secrets_named_mutex(const char *name, unsigned int timeout){ int ret = 0; if (!secrets_init()) return False; ret = tdb_lock_bystring(tdb, name, timeout); if (ret == 0) DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name )); return (ret == 0);}/******************************************************************************* Unlock a named mutex.*******************************************************************************/void secrets_named_mutex_release(const char *name){ tdb_unlock_bystring(tdb, name); DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));}/********************************************************* Check to see if we must talk to the PDC to avoid sam sync delays ********************************************************/ BOOL must_use_pdc( const char *domain ){ time_t now = time(NULL); time_t last_change_time; unsigned char passwd[16]; if ( !secrets_fetch_trust_account_password(domain, passwd, &last_change_time, NULL) ) return False; /* * If the time the machine password has changed * was less than about 15 minutes then we need to contact * the PDC only, as we cannot be sure domain replication * has yet taken place. Bug found by Gerald (way to go * Gerald !). JRA. */ if ( now - last_change_time < SAM_SYNC_WINDOW ) return True; return False;}/******************************************************************************* Store a complete AFS keyfile into secrets.tdb.*******************************************************************************/BOOL secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile){ fstring key; if ((cell == NULL) || (keyfile == NULL)) return False; if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS) return False; slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell); return secrets_store(key, keyfile, sizeof(struct afs_keyfile));}/******************************************************************************* Fetch the current (highest) AFS key from secrets.tdb*******************************************************************************/BOOL secrets_fetch_afs_key(const char *cell, struct afs_key *result){ fstring key; struct afs_keyfile *keyfile; size_t size = 0; uint32 i; slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell); keyfile = (struct afs_keyfile *)secrets_fetch(key, &size); if (keyfile == NULL) return False; if (size != sizeof(struct afs_keyfile)) { SAFE_FREE(keyfile); return False; } i = ntohl(keyfile->nkeys); if (i > SECRETS_AFS_MAXKEYS) { SAFE_FREE(keyfile); return False; } *result = keyfile->entry[i-1]; result->kvno = ntohl(result->kvno); return True;}/****************************************************************************** When kerberos is not available, choose between anonymous or authenticated connections. We need to use an authenticated connection if DCs have the RestrictAnonymous registry entry set > 0, or the "Additional restrictions for anonymous connections" set in the win2k Local Security Policy. Caller to free() result in domain, username, password*******************************************************************************/void secrets_fetch_ipc_userpass(char **username, char **domain, char **password){ *username = secrets_fetch(SECRETS_AUTH_USER, NULL); *domain = secrets_fetch(SECRETS_AUTH_DOMAIN, NULL); *password = secrets_fetch(SECRETS_AUTH_PASSWORD, NULL); if (*username && **username) { if (!*domain || !**domain) *domain = smb_xstrdup(lp_workgroup()); if (!*password || !**password) *password = smb_xstrdup(""); DEBUG(3, ("IPC$ connections done by user %s\\%s\n", *domain, *username)); } else { DEBUG(3, ("IPC$ connections done anonymously\n")); *username = smb_xstrdup(""); *domain = smb_xstrdup(""); *password = smb_xstrdup(""); }}/****************************************************************************** Open or create the schannel session store tdb.*******************************************************************************/static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx){ TDB_DATA vers; uint32 ver; TDB_CONTEXT *tdb_sc = NULL; char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir()); if (!fname) { return NULL; } tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); if (!tdb_sc) { DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname)); talloc_free(fname); return NULL; } vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION"); if (vers.dptr == NULL) { /* First opener, no version. */ SIVAL(&ver,0,1); vers.dptr = (char *)&ver; vers.dsize = 4; tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE); vers.dptr = NULL; } else if (vers.dsize == 4) { ver = IVAL(vers.dptr,0); if (ver != 1) { tdb_close(tdb_sc); tdb_sc = NULL; DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n", (int)ver, fname )); } } else { tdb_close(tdb_sc); tdb_sc = NULL; DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n", (int)vers.dsize, fname )); } SAFE_FREE(vers.dptr); talloc_free(fname); return tdb_sc;}/****************************************************************************** Store the schannel state after an AUTH2 call. Note we must be root here.*******************************************************************************/BOOL secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx, const struct dcinfo *pdc){ TDB_CONTEXT *tdb_sc = NULL; TDB_DATA value; BOOL ret; char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE, pdc->remote_machine); if (!keystr) { return False; } strupper_m(keystr); /* Work out how large the record is. */ value.dsize = tdb_pack(NULL, 0, "dBBBBBfff", pdc->sequence, 8, pdc->seed_chal.data, 8, pdc->clnt_chal.data, 8, pdc->srv_chal.data, 8, pdc->sess_key, 16, pdc->mach_pw, pdc->mach_acct, pdc->remote_machine, pdc->domain); value.dptr = TALLOC(mem_ctx, value.dsize); if (!value.dptr) { talloc_free(keystr); return False; } value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff", pdc->sequence, 8, pdc->seed_chal.data, 8, pdc->clnt_chal.data, 8, pdc->srv_chal.data, 8, pdc->sess_key, 16, pdc->mach_pw, pdc->mach_acct, pdc->remote_machine, pdc->domain); tdb_sc = open_schannel_session_store(mem_ctx); if (!tdb_sc) { talloc_free(keystr); talloc_free(value.dptr); return False; } ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False); DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n", keystr )); tdb_close(tdb_sc); talloc_free(keystr); talloc_free(value.dptr); return ret;}/****************************************************************************** Restore the schannel state on a client reconnect. Note we must be root here.*******************************************************************************/BOOL secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx, const char *remote_machine, struct dcinfo *pdc){ TDB_CONTEXT *tdb_sc = NULL; TDB_DATA value; unsigned char *pseed_chal = NULL; unsigned char *pclnt_chal = NULL; unsigned char *psrv_chal = NULL; unsigned char *psess_key = NULL; unsigned char *pmach_pw = NULL; uint32 l1, l2, l3, l4, l5; int ret; char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE, remote_machine); ZERO_STRUCTP(pdc); if (!keystr) { return False; } strupper_m(keystr); tdb_sc = open_schannel_session_store(mem_ctx); if (!tdb_sc) { talloc_free(keystr); return False; } value = tdb_fetch_bystring(tdb_sc, keystr); if (!value.dptr) { DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n", keystr )); tdb_close(tdb_sc); return False; } tdb_close(tdb_sc); /* Retrieve the record. */ ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff", &pdc->sequence, &l1, &pseed_chal, &l2, &pclnt_chal, &l3, &psrv_chal, &l4, &psess_key, &l5, &pmach_pw, &pdc->mach_acct, &pdc->remote_machine, &pdc->domain); if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 8 || l5 != 16) { talloc_free(keystr); SAFE_FREE(pseed_chal); SAFE_FREE(pclnt_chal); SAFE_FREE(psrv_chal); SAFE_FREE(psess_key); SAFE_FREE(pmach_pw); SAFE_FREE(value.dptr); ZERO_STRUCTP(pdc); return False; } memcpy(pdc->seed_chal.data, pseed_chal, 8); memcpy(pdc->clnt_chal.data, pclnt_chal, 8); memcpy(pdc->srv_chal.data, psrv_chal, 8); memcpy(pdc->sess_key, psess_key, 8); memcpy(pdc->mach_pw, pmach_pw, 16); /* We know these are true so didn't bother to store them. */ pdc->challenge_sent = True; pdc->authenticated = True; DEBUG(3,("secrets_store_schannel_session_info: restored schannel info key %s\n", keystr )); SAFE_FREE(pseed_chal); SAFE_FREE(pclnt_chal); SAFE_FREE(psrv_chal); SAFE_FREE(psess_key); SAFE_FREE(pmach_pw); talloc_free(keystr); SAFE_FREE(value.dptr); return True;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -