passdb/secrets.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    Copyright (C) Andrew Tridgell 1992-2001
00004    Copyright (C) Andrew Bartlett      2002
00005    Copyright (C) Rafal Szczesniak     2002
00006    Copyright (C) Tim Potter           2001
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012    
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017    
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021 */
00022 
00023 /* the Samba secrets database stores any generated, private information
00024    such as the local SID and machine trust password */
00025 
00026 #include "includes.h"
00027 
00028 #undef DBGC_CLASS
00029 #define DBGC_CLASS DBGC_PASSDB
00030 
00031 static TDB_CONTEXT *tdb;
00032 
00033 /* Urrrg. global.... */
00034 BOOL global_machine_password_needs_changing;
00035 
00036 /**
00037  * Use a TDB to store an incrementing random seed.
00038  *
00039  * Initialised to the current pid, the very first time Samba starts,
00040  * and incremented by one each time it is needed.  
00041  * 
00042  * @note Not called by systems with a working /dev/urandom.
00043  */
00044 static void get_rand_seed(int *new_seed) 
00045 {
00046         *new_seed = sys_getpid();
00047         if (tdb) {
00048                 tdb_change_int32_atomic(tdb, "INFO/random_seed", new_seed, 1);
00049         }
00050 }
00051 
00052 /* open up the secrets database */
00053 BOOL secrets_init(void)
00054 {
00055         pstring fname;
00056         unsigned char dummy;
00057 
00058         if (tdb)
00059                 return True;
00060 
00061         pstrcpy(fname, lp_private_dir());
00062         pstrcat(fname,"/secrets.tdb");
00063 
00064         tdb = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
00065 
00066         if (!tdb) {
00067                 DEBUG(0,("Failed to open %s\n", fname));
00068                 return False;
00069         }
00070 
00071         /**
00072          * Set a reseed function for the crypto random generator 
00073          * 
00074          * This avoids a problem where systems without /dev/urandom
00075          * could send the same challenge to multiple clients
00076          */
00077         set_rand_reseed_callback(get_rand_seed);
00078 
00079         /* Ensure that the reseed is done now, while we are root, etc */
00080         generate_random_buffer(&dummy, sizeof(dummy));
00081 
00082         return True;
00083 }
00084 
00085 /* read a entry from the secrets database - the caller must free the result
00086    if size is non-null then the size of the entry is put in there
00087  */
00088 void *secrets_fetch(const char *key, size_t *size)
00089 {
00090         TDB_DATA dbuf;
00091         secrets_init();
00092         if (!tdb)
00093                 return NULL;
00094         dbuf = tdb_fetch(tdb, string_tdb_data(key));
00095         if (size)
00096                 *size = dbuf.dsize;
00097         return dbuf.dptr;
00098 }
00099 
00100 /* store a secrets entry 
00101  */
00102 BOOL secrets_store(const char *key, const void *data, size_t size)
00103 {
00104         secrets_init();
00105         if (!tdb)
00106                 return False;
00107         return tdb_trans_store(tdb, string_tdb_data(key),
00108                                make_tdb_data((const char *)data, size),
00109                                TDB_REPLACE) == 0;
00110 }
00111 
00112 
00113 /* delete a secets database entry
00114  */
00115 BOOL secrets_delete(const char *key)
00116 {
00117         secrets_init();
00118         if (!tdb)
00119                 return False;
00120         return tdb_delete(tdb, string_tdb_data(key)) == 0;
00121 }
00122 
00123 BOOL secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
00124 {
00125         fstring key;
00126         BOOL ret;
00127 
00128         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_SID, domain);
00129         strupper_m(key);
00130         ret = secrets_store(key, sid, sizeof(DOM_SID));
00131 
00132         /* Force a re-query, in case we modified our domain */
00133         if (ret)
00134                 reset_global_sam_sid();
00135         return ret;
00136 }
00137 
00138 BOOL secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
00139 {
00140         DOM_SID *dyn_sid;
00141         fstring key;
00142         size_t size = 0;
00143 
00144         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_SID, domain);
00145         strupper_m(key);
00146         dyn_sid = (DOM_SID *)secrets_fetch(key, &size);
00147 
00148         if (dyn_sid == NULL)
00149                 return False;
00150 
00151         if (size != sizeof(DOM_SID)) { 
00152                 SAFE_FREE(dyn_sid);
00153                 return False;
00154         }
00155 
00156         *sid = *dyn_sid;
00157         SAFE_FREE(dyn_sid);
00158         return True;
00159 }
00160 
00161 BOOL secrets_store_domain_guid(const char *domain, struct GUID *guid)
00162 {
00163         fstring key;
00164 
00165         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
00166         strupper_m(key);
00167         return secrets_store(key, guid, sizeof(struct GUID));
00168 }
00169 
00170 BOOL secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
00171 {
00172         struct GUID *dyn_guid;
00173         fstring key;
00174         size_t size = 0;
00175         struct GUID new_guid;
00176 
00177         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
00178         strupper_m(key);
00179         dyn_guid = (struct GUID *)secrets_fetch(key, &size);
00180 
00181         if (!dyn_guid) {
00182                 if (lp_server_role() == ROLE_DOMAIN_PDC) {
00183                         smb_uuid_generate_random(&new_guid);
00184                         if (!secrets_store_domain_guid(domain, &new_guid))
00185                                 return False;
00186                         dyn_guid = (struct GUID *)secrets_fetch(key, &size);
00187                 }
00188                 if (dyn_guid == NULL) {
00189                         return False;
00190                 }
00191         }
00192 
00193         if (size != sizeof(struct GUID)) { 
00194                 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
00195                 SAFE_FREE(dyn_guid);
00196                 return False;
00197         }
00198 
00199         *guid = *dyn_guid;
00200         SAFE_FREE(dyn_guid);
00201         return True;
00202 }
00203 
00204 /**
00205  * Form a key for fetching the machine trust account password
00206  *
00207  * @param domain domain name
00208  *
00209  * @return stored password's key
00210  **/
00211 static const char *trust_keystr(const char *domain)
00212 {
00213         static fstring keystr;
00214 
00215         slprintf(keystr,sizeof(keystr)-1,"%s/%s", 
00216                  SECRETS_MACHINE_ACCT_PASS, domain);
00217         strupper_m(keystr);
00218 
00219         return keystr;
00220 }
00221 
00222 /**
00223  * Form a key for fetching a trusted domain password
00224  *
00225  * @param domain trusted domain name
00226  *
00227  * @return stored password's key
00228  **/
00229 static char *trustdom_keystr(const char *domain)
00230 {
00231         static pstring keystr;
00232 
00233         pstr_sprintf(keystr, "%s/%s", SECRETS_DOMTRUST_ACCT_PASS, domain);
00234         strupper_m(keystr);
00235                 
00236         return keystr;
00237 }
00238 
00239 /************************************************************************
00240  Lock the trust password entry.
00241 ************************************************************************/
00242 
00243 BOOL secrets_lock_trust_account_password(const char *domain, BOOL dolock)
00244 {
00245         if (!tdb)
00246                 return False;
00247 
00248         if (dolock)
00249                 return (tdb_lock_bystring(tdb, trust_keystr(domain)) == 0);
00250         else
00251                 tdb_unlock_bystring(tdb, trust_keystr(domain));
00252         return True;
00253 }
00254 
00255 /************************************************************************
00256  Routine to get the default secure channel type for trust accounts
00257 ************************************************************************/
00258 
00259 uint32 get_default_sec_channel(void) 
00260 {
00261         if (lp_server_role() == ROLE_DOMAIN_BDC || 
00262             lp_server_role() == ROLE_DOMAIN_PDC) {
00263                 return SEC_CHAN_BDC;
00264         } else {
00265                 return SEC_CHAN_WKSTA;
00266         }
00267 }
00268 
00269 /************************************************************************
00270  Routine to get the trust account password for a domain.
00271  This only tries to get the legacy hashed version of the password.
00272  The user of this function must have locked the trust password file using
00273  the above secrets_lock_trust_account_password().
00274 ************************************************************************/
00275 
00276 BOOL secrets_fetch_trust_account_password_legacy(const char *domain,
00277                                                  uint8 ret_pwd[16],
00278                                                  time_t *pass_last_set_time,
00279                                                  uint32 *channel)
00280 {
00281         struct machine_acct_pass *pass;
00282         size_t size = 0;
00283 
00284         if (!(pass = (struct machine_acct_pass *)secrets_fetch(
00285                       trust_keystr(domain), &size))) {
00286                 DEBUG(5, ("secrets_fetch failed!\n"));
00287                 return False;
00288         }
00289         
00290         if (size != sizeof(*pass)) {
00291                 DEBUG(0, ("secrets were of incorrect size!\n"));
00292                 return False;
00293         }
00294 
00295         if (pass_last_set_time) {
00296                 *pass_last_set_time = pass->mod_time;
00297         }
00298         memcpy(ret_pwd, pass->hash, 16);
00299 
00300         if (channel) {
00301                 *channel = get_default_sec_channel();
00302         }
00303 
00304         /* Test if machine password has expired and needs to be changed */
00305         if (lp_machine_password_timeout()) {
00306                 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
00307                                 (time_t)lp_machine_password_timeout())) {
00308                         global_machine_password_needs_changing = True;
00309                 }
00310         }
00311 
00312         SAFE_FREE(pass);
00313         return True;
00314 }
00315 
00316 /************************************************************************
00317  Routine to get the trust account password for a domain.
00318  The user of this function must have locked the trust password file using
00319  the above secrets_lock_trust_account_password().
00320 ************************************************************************/
00321 
00322 BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
00323                                           time_t *pass_last_set_time,
00324                                           uint32 *channel)
00325 {
00326         char *plaintext;
00327 
00328         plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
00329                                                    channel);
00330         if (plaintext) {
00331                 DEBUG(4,("Using cleartext machine password\n"));
00332                 E_md4hash(plaintext, ret_pwd);
00333                 SAFE_FREE(plaintext);
00334                 return True;
00335         }
00336 
00337         return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
00338                                                            pass_last_set_time,
00339                                                            channel);
00340 }
00341 
00342 /**
00343  * Pack SID passed by pointer
00344  *
00345  * @param pack_buf pointer to buffer which is to be filled with packed data
00346  * @param bufsize size of packing buffer
00347  * @param sid pointer to sid to be packed
00348  *
00349  * @return length of the packed representation of the whole structure
00350  **/
00351 static size_t tdb_sid_pack(char* pack_buf, int bufsize, DOM_SID* sid)
00352 {
00353         int idx;
00354         size_t len = 0;
00355         
00356         if (!sid || !pack_buf) return -1;
00357         
00358         len += tdb_pack(pack_buf + len, bufsize - len, "bb", sid->sid_rev_num,
00359                         sid->num_auths);
00360         
00361         for (idx = 0; idx < 6; idx++) {
00362                 len += tdb_pack(pack_buf + len, bufsize - len, "b",
00363                                 sid->id_auth[idx]);
00364         }
00365         
00366         for (idx = 0; idx < MAXSUBAUTHS; idx++) {
00367                 len += tdb_pack(pack_buf + len, bufsize - len, "d",
00368                                 sid->sub_auths[idx]);
00369         }
00370         
00371         return len;
00372 }
00373 
00374 /**
00375  * Unpack SID into a pointer
00376  *
00377  * @param pack_buf pointer to buffer with packed representation
00378  * @param bufsize size of the buffer
00379  * @param sid pointer to sid structure to be filled with unpacked data
00380  *
00381  * @return size of structure unpacked from buffer
00382  **/
00383 static size_t tdb_sid_unpack(char* pack_buf, int bufsize, DOM_SID* sid)
00384 {
00385         int idx, len = 0;
00386         
00387         if (!sid || !pack_buf) return -1;
00388 
00389         len += tdb_unpack(pack_buf + len, bufsize - len, "bb",
00390                           &sid->sid_rev_num, &sid->num_auths);
00391                           
00392         for (idx = 0; idx < 6; idx++) {
00393                 len += tdb_unpack(pack_buf + len, bufsize - len, "b",
00394                                   &sid->id_auth[idx]);
00395         }
00396         
00397         for (idx = 0; idx < MAXSUBAUTHS; idx++) {
00398                 len += tdb_unpack(pack_buf + len, bufsize - len, "d",
00399                                   &sid->sub_auths[idx]);
00400         }
00401         
00402         return len;
00403 }
00404 
00405 /**
00406  * Pack TRUSTED_DOM_PASS passed by pointer
00407  *
00408  * @param pack_buf pointer to buffer which is to be filled with packed data
00409  * @param bufsize size of the buffer
00410  * @param pass pointer to trusted domain password to be packed
00411  *
00412  * @return length of the packed representation of the whole structure
00413  **/
00414 static size_t tdb_trusted_dom_pass_pack(char* pack_buf, int bufsize,
00415                                         TRUSTED_DOM_PASS* pass)
00416 {
00417         int idx, len = 0;
00418         
00419         if (!pack_buf || !pass) return -1;
00420         
00421         /* packing unicode domain name and password */
00422         len += tdb_pack(pack_buf + len, bufsize - len, "d",
00423                         pass->uni_name_len);
00424         
00425         for (idx = 0; idx < 32; idx++)
00426                 len +=  tdb_pack(pack_buf + len, bufsize - len, "w",
00427                                  pass->uni_name[idx]);
00428         
00429         len += tdb_pack(pack_buf + len, bufsize - len, "dPd", pass->pass_len,
00430                              pass->pass, pass->mod_time);
00431 
00432         /* packing SID structure */
00433         len += tdb_sid_pack(pack_buf + len, bufsize - len, &pass->domain_sid);
00434 
00435         return len;
00436 }
00437 
00438 
00439 /**
00440  * Unpack TRUSTED_DOM_PASS passed by pointer
00441  *
00442  * @param pack_buf pointer to buffer with packed representation
00443  * @param bufsize size of the buffer
00444  * @param pass pointer to trusted domain password to be filled with unpacked data
00445  *
00446  * @return size of structure unpacked from buffer
00447  **/
00448 static size_t tdb_trusted_dom_pass_unpack(char* pack_buf, int bufsize,
00449                                           TRUSTED_DOM_PASS* pass)
00450 {
00451         int idx, len = 0;
00452         
00453         if (!pack_buf || !pass) return -1;
00454 
00455         /* unpack unicode domain name and plaintext password */
00456         len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len);
00457         
00458         for (idx = 0; idx < 32; idx++)
00459                 len +=  tdb_unpack(pack_buf + len, bufsize - len, "w",
00460                                    &pass->uni_name[idx]);
00461 
00462         len += tdb_unpack(pack_buf + len, bufsize - len, "dPd",
00463                           &pass->pass_len, &pass->pass, &pass->mod_time);
00464         
00465         /* unpack domain sid */
00466         len += tdb_sid_unpack(pack_buf + len, bufsize - len,
00467                               &pass->domain_sid);
00468         
00469         return len;     
00470 }
00471 
00472 /************************************************************************
00473  Routine to get account password to trusted domain
00474 ************************************************************************/
00475 
00476 BOOL secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
00477                                            DOM_SID *sid, time_t *pass_last_set_time)
00478 {
00479         struct trusted_dom_pass pass;
00480         size_t size = 0;
00481         
00482         /* unpacking structures */
00483         char* pass_buf;
00484         int pass_len = 0;
00485 
00486         ZERO_STRUCT(pass);
00487 
00488         /* fetching trusted domain password structure */
00489         if (!(pass_buf = (char *)secrets_fetch(trustdom_keystr(domain),
00490                                                &size))) {
00491                 DEBUG(5, ("secrets_fetch failed!\n"));
00492                 return False;
00493         }
00494 
00495         /* unpack trusted domain password */
00496         pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
00497         SAFE_FREE(pass_buf);
00498 
00499         if (pass_len != size) {
00500                 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
00501                 return False;
00502         }
00503                         
00504         /* the trust's password */      
00505         if (pwd) {
00506                 *pwd = SMB_STRDUP(pass.pass);
00507                 if (!*pwd) {
00508                         return False;
00509                 }
00510         }
00511 
00512         /* last change time */
00513         if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
00514 
00515         /* domain sid */
00516         if (sid != NULL) sid_copy(sid, &pass.domain_sid);
00517                 
00518         return True;
00519 }
00520 
00521 /**
00522  * Routine to store the password for trusted domain
00523  *
00524  * @param domain remote domain name
00525  * @param pwd plain text password of trust relationship
00526  * @param sid remote domain sid
00527  *
00528  * @return true if succeeded
00529  **/
00530 
00531 BOOL secrets_store_trusted_domain_password(const char* domain, const char* pwd,
00532                                            const DOM_SID *sid)
00533 {
00534         smb_ucs2_t *uni_dom_name;
00535 
00536         /* packing structures */
00537         pstring pass_buf;
00538         int pass_len = 0;
00539         int pass_buf_len = sizeof(pass_buf);
00540         
00541         struct trusted_dom_pass pass;
00542         ZERO_STRUCT(pass);
00543 
00544         if (push_ucs2_allocate(&uni_dom_name, domain) == (size_t)-1) {
00545                 DEBUG(0, ("Could not convert domain name %s to unicode\n",
00546                           domain));
00547                 return False;
00548         }
00549         
00550         strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
00551         pass.uni_name_len = strlen_w(uni_dom_name)+1;
00552         SAFE_FREE(uni_dom_name);
00553 
00554         /* last change time */
00555         pass.mod_time = time(NULL);
00556 
00557         /* password of the trust */
00558         pass.pass_len = strlen(pwd);
00559         fstrcpy(pass.pass, pwd);
00560 
00561         /* domain sid */
00562         sid_copy(&pass.domain_sid, sid);
00563         
00564         pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_buf_len, &pass);
00565 
00566         return secrets_store(trustdom_keystr(domain), (void *)&pass_buf, pass_len);
00567 }
00568 
00569 /************************************************************************
00570  Routine to set the plaintext machine account password for a realm
00571 the password is assumed to be a null terminated ascii string
00572 ************************************************************************/
00573 
00574 BOOL secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
00575 {
00576         char *key = NULL;
00577         BOOL ret;
00578         uint32 last_change_time;
00579         uint32 sec_channel_type;
00580 
00581         asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
00582         if (!key) 
00583                 return False;
00584         strupper_m(key);
00585 
00586         ret = secrets_store(key, pass, strlen(pass)+1);
00587         SAFE_FREE(key);
00588 
00589         if (!ret)
00590                 return ret;
00591         
00592         asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
00593         if (!key) 
00594                 return False;
00595         strupper_m(key);
00596 
00597         SIVAL(&last_change_time, 0, time(NULL));
00598         ret = secrets_store(key, &last_change_time, sizeof(last_change_time));
00599         SAFE_FREE(key);
00600 
00601         asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
00602         if (!key) 
00603                 return False;
00604         strupper_m(key);
00605 
00606         SIVAL(&sec_channel_type, 0, sec_channel);
00607         ret = secrets_store(key, &sec_channel_type, sizeof(sec_channel_type));
00608         SAFE_FREE(key);
00609 
00610         return ret;
00611 }
00612 
00613 /************************************************************************
00614  Routine to fetch the plaintext machine account password for a realm
00615  the password is assumed to be a null terminated ascii string.
00616 ************************************************************************/
00617 
00618 char *secrets_fetch_machine_password(const char *domain, 
00619                                      time_t *pass_last_set_time,
00620                                      uint32 *channel)
00621 {
00622         char *key = NULL;
00623         char *ret;
00624         asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
00625         strupper_m(key);
00626         ret = (char *)secrets_fetch(key, NULL);
00627         SAFE_FREE(key);
00628         
00629         if (pass_last_set_time) {
00630                 size_t size;
00631                 uint32 *last_set_time;
00632                 asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
00633                 strupper_m(key);
00634                 last_set_time = (unsigned int *)secrets_fetch(key, &size);
00635                 if (last_set_time) {
00636                         *pass_last_set_time = IVAL(last_set_time,0);
00637                         SAFE_FREE(last_set_time);
00638                 } else {
00639                         *pass_last_set_time = 0;
00640                 }
00641                 SAFE_FREE(key);
00642         }
00643         
00644         if (channel) {
00645                 size_t size;
00646                 uint32 *channel_type;
00647                 asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
00648                 strupper_m(key);
00649                 channel_type = (unsigned int *)secrets_fetch(key, &size);
00650                 if (channel_type) {
00651                         *channel = IVAL(channel_type,0);
00652                         SAFE_FREE(channel_type);
00653                 } else {
00654                         *channel = get_default_sec_channel();
00655                 }
00656                 SAFE_FREE(key);
00657         }
00658         
00659         return ret;
00660 }
00661 
00662 BOOL is_trusted_domain_situation(const char *domain_name)
00663 {
00664         return IS_DC &&
00665                 lp_allow_trusted_domains() &&
00666                 !strequal(domain_name, lp_workgroup());
00667 }
00668  
00669 /*******************************************************************
00670  Wrapper around retrieving the clear text trust account password.
00671  appropriate account name is stored in account_name.
00672  Caller must free password, but not account_name.
00673 *******************************************************************/
00674 
00675 BOOL get_trust_pw_clear(const char *domain, char **ret_pwd,
00676                         const char **account_name, uint32 *channel)
00677 {
00678         char *pwd;
00679         time_t last_set_time;
00680 
00681         /* if we are a DC and this is not our domain, then lookup an account
00682          * for the domain trust */
00683 
00684         if (is_trusted_domain_situation(domain)) {
00685                 if (!secrets_fetch_trusted_domain_password(domain, ret_pwd,
00686                                                            NULL, &last_set_time))
00687                 {
00688                         DEBUG(0, ("get_trust_pw: could not fetch trust "
00689                                 "account password for trusted domain %s\n",
00690                                 domain));
00691                         return False;
00692                 }
00693 
00694                 if (channel != NULL) {
00695                         *channel = SEC_CHAN_DOMAIN;
00696                 }
00697 
00698                 if (account_name != NULL) {
00699                         *account_name = lp_workgroup();
00700                 }
00701 
00702                 return True;
00703         }
00704 
00705         /* Here we are a domain member server.  We can only be a member
00706            of one domain so ignore the request domain and assume our own */
00707 
00708         pwd = secrets_fetch_machine_password(lp_workgroup(), &last_set_time, 
00709                                              channel);
00710 
00711         if (pwd != NULL) {
00712                 *ret_pwd = pwd;
00713                 if (account_name != NULL) {
00714                         *account_name = global_myname();
00715                 }
00716 
00717                 return True;
00718         }
00719 
00720         DEBUG(5, ("get_trust_pw_clear: could not fetch clear text trust "
00721                   "account password for domain %s\n", domain));
00722         return False;
00723 }
00724 
00725 /*******************************************************************
00726  Wrapper around retrieving the trust account password.
00727  appropriate account name is stored in account_name.
00728 *******************************************************************/
00729 
00730 BOOL get_trust_pw_hash(const char *domain, uint8 ret_pwd[16],
00731                        const char **account_name, uint32 *channel)
00732 {
00733         char *pwd = NULL;
00734         time_t last_set_time;
00735 
00736         if (get_trust_pw_clear(domain, &pwd, account_name, channel)) {
00737                 E_md4hash(pwd, ret_pwd);
00738                 SAFE_FREE(pwd);
00739                 return True;
00740         } else if (is_trusted_domain_situation(domain)) {
00741                 return False;
00742         }
00743 
00744         /* as a fallback, try to get the hashed pwd directly from the tdb... */
00745 
00746         if (secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
00747                                                         &last_set_time,
00748                                                         channel))
00749         {
00750                 if (account_name != NULL) {
00751                         *account_name = global_myname();
00752                 }
00753 
00754                 return True;
00755         }
00756 
00757         DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
00758                 "password for domain %s\n", domain));
00759         return False;
00760 }
00761 
00762 /************************************************************************
00763  Routine to delete the password for trusted domain
00764 ************************************************************************/
00765 
00766 BOOL trusted_domain_password_delete(const char *domain)
00767 {
00768         return secrets_delete(trustdom_keystr(domain));
00769 }
00770 
00771 BOOL secrets_store_ldap_pw(const char* dn, char* pw)
00772 {
00773         char *key = NULL;
00774         BOOL ret;
00775         
00776         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
00777                 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
00778                 return False;
00779         }
00780                 
00781         ret = secrets_store(key, pw, strlen(pw)+1);
00782         
00783         SAFE_FREE(key);
00784         return ret;
00785 }
00786 
00787 /*******************************************************************
00788  Find the ldap password.
00789 ******************************************************************/
00790 
00791 BOOL fetch_ldap_pw(char **dn, char** pw)
00792 {
00793         char *key = NULL;
00794         size_t size = 0;
00795         
00796         *dn = smb_xstrdup(lp_ldap_admin_dn());
00797         
00798         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
00799                 SAFE_FREE(*dn);
00800                 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
00801         }
00802         
00803         *pw=(char *)secrets_fetch(key, &size);
00804         SAFE_FREE(key);
00805 
00806         if (!size) {
00807                 /* Upgrade 2.2 style entry */
00808                 char *p;
00809                 char* old_style_key = SMB_STRDUP(*dn);
00810                 char *data;
00811                 fstring old_style_pw;
00812                 
00813                 if (!old_style_key) {
00814                         DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
00815                         return False;
00816                 }
00817 
00818                 for (p=old_style_key; *p; p++)
00819                         if (*p == ',') *p = '/';
00820         
00821                 data=(char *)secrets_fetch(old_style_key, &size);
00822                 if (!size && size < sizeof(old_style_pw)) {
00823                         DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
00824                         SAFE_FREE(old_style_key);
00825                         SAFE_FREE(*dn);
00826                         return False;
00827                 }
00828 
00829                 size = MIN(size, sizeof(fstring)-1);
00830                 strncpy(old_style_pw, data, size);
00831                 old_style_pw[size] = 0;
00832 
00833                 SAFE_FREE(data);
00834 
00835                 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
00836                         DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
00837                         SAFE_FREE(old_style_key);
00838                         SAFE_FREE(*dn);
00839                         return False;                   
00840                 }
00841                 if (!secrets_delete(old_style_key)) {
00842                         DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
00843                 }
00844 
00845                 SAFE_FREE(old_style_key);
00846 
00847                 *pw = smb_xstrdup(old_style_pw);                
00848         }
00849         
00850         return True;
00851 }
00852 
00853 /**
00854  * Get trusted domains info from secrets.tdb.
00855  **/ 
00856 
00857 NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
00858                                  struct trustdom_info ***domains)
00859 {
00860         TDB_LIST_NODE *keys, *k;
00861         char *pattern;
00862         TALLOC_CTX *tmp_ctx;
00863 
00864         if (!(tmp_ctx = talloc_new(mem_ctx))) {
00865                 return NT_STATUS_NO_MEMORY;
00866         }
00867 
00868         if (!secrets_init()) return NT_STATUS_ACCESS_DENIED;
00869         
00870         /* generate searching pattern */
00871         pattern = talloc_asprintf(tmp_ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS);
00872         if (pattern == NULL) {
00873                 DEBUG(0, ("secrets_trusted_domains: talloc_asprintf() "
00874                           "failed!\n"));
00875                 TALLOC_FREE(tmp_ctx);
00876                 return NT_STATUS_NO_MEMORY;
00877         }
00878 
00879         *num_domains = 0;
00880 
00881         /*
00882          * Make sure that a talloc context for the trustdom_info structs
00883          * exists
00884          */
00885 
00886         if (!(*domains = TALLOC_ARRAY(mem_ctx, struct trustdom_info *, 1))) {
00887                 TALLOC_FREE(tmp_ctx);
00888                 return NT_STATUS_NO_MEMORY;
00889         }
00890 
00891         /* fetching trusted domains' data and collecting them in a list */
00892         keys = tdb_search_keys(tdb, pattern);
00893 
00894         /* searching for keys in secrets db -- way to go ... */
00895         for (k = keys; k; k = k->next) {
00896                 char *packed_pass;
00897                 size_t size = 0, packed_size = 0;
00898                 struct trusted_dom_pass pass;
00899                 char *secrets_key;
00900                 struct trustdom_info *dom_info;
00901                 
00902                 /* important: ensure null-termination of the key string */
00903                 secrets_key = talloc_strndup(tmp_ctx,
00904                                              k->node_key.dptr,
00905                                              k->node_key.dsize);
00906                 if (!secrets_key) {
00907                         DEBUG(0, ("strndup failed!\n"));
00908                         tdb_search_list_free(keys);
00909                         TALLOC_FREE(tmp_ctx);
00910                         return NT_STATUS_NO_MEMORY;
00911                 }
00912 
00913                 packed_pass = (char *)secrets_fetch(secrets_key, &size);
00914                 packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size,
00915                                                           &pass);
00916                 /* packed representation isn't needed anymore */
00917                 SAFE_FREE(packed_pass);
00918                 
00919                 if (size != packed_size) {
00920                         DEBUG(2, ("Secrets record %s is invalid!\n",
00921                                   secrets_key));
00922                         continue;
00923                 }
00924 
00925                 if (pass.domain_sid.num_auths != 4) {
00926                         DEBUG(0, ("SID %s is not a domain sid, has %d "
00927                                   "auths instead of 4\n",
00928                                   sid_string_static(&pass.domain_sid),
00929                                   pass.domain_sid.num_auths));
00930                         continue;
00931                 }
00932 
00933                 if (!(dom_info = TALLOC_P(*domains, struct trustdom_info))) {
00934                         DEBUG(0, ("talloc failed\n"));
00935                         tdb_search_list_free(keys);
00936                         TALLOC_FREE(tmp_ctx);
00937                         return NT_STATUS_NO_MEMORY;
00938                 }
00939 
00940                 if (pull_ucs2_talloc(dom_info, &dom_info->name,
00941                                      pass.uni_name) == (size_t)-1) {
00942                         DEBUG(2, ("pull_ucs2_talloc failed\n"));
00943                         tdb_search_list_free(keys);
00944                         TALLOC_FREE(tmp_ctx);
00945                         return NT_STATUS_NO_MEMORY;
00946                 }
00947 
00948                 sid_copy(&dom_info->sid, &pass.domain_sid);
00949 
00950                 ADD_TO_ARRAY(*domains, struct trustdom_info *, dom_info,
00951                              domains, num_domains);
00952 
00953                 if (*domains == NULL) {
00954                         tdb_search_list_free(keys);
00955                         TALLOC_FREE(tmp_ctx);
00956                         return NT_STATUS_NO_MEMORY;
00957                 }
00958         }
00959         
00960         DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n",
00961                   *num_domains));
00962 
00963         /* free the results of searching the keys */
00964         tdb_search_list_free(keys);
00965         TALLOC_FREE(tmp_ctx);
00966 
00967         return NT_STATUS_OK;
00968 }
00969 
00970 /*******************************************************************************
00971  Lock the secrets tdb based on a string - this is used as a primitive form of mutex
00972  between smbd instances.
00973 *******************************************************************************/
00974 
00975 BOOL secrets_named_mutex(const char *name, unsigned int timeout)
00976 {
00977         int ret = 0;
00978 
00979         if (!secrets_init())
00980                 return False;
00981 
00982         ret = tdb_lock_bystring_with_timeout(tdb, name, timeout);
00983         if (ret == 0)
00984                 DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
00985 
00986         return (ret == 0);
00987 }
00988 
00989 /*******************************************************************************
00990  Unlock a named mutex.
00991 *******************************************************************************/
00992 
00993 void secrets_named_mutex_release(const char *name)
00994 {
00995         tdb_unlock_bystring(tdb, name);
00996         DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
00997 }
00998 
00999 /*******************************************************************************
01000  Store a complete AFS keyfile into secrets.tdb.
01001 *******************************************************************************/
01002 
01003 BOOL secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
01004 {
01005         fstring key;
01006 
01007         if ((cell == NULL) || (keyfile == NULL))
01008                 return False;
01009 
01010         if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
01011                 return False;
01012 
01013         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
01014         return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
01015 }
01016 
01017 /*******************************************************************************
01018  Fetch the current (highest) AFS key from secrets.tdb
01019 *******************************************************************************/
01020 BOOL secrets_fetch_afs_key(const char *cell, struct afs_key *result)
01021 {
01022         fstring key;
01023         struct afs_keyfile *keyfile;
01024         size_t size = 0;
01025         uint32 i;
01026 
01027         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
01028 
01029         keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
01030 
01031         if (keyfile == NULL)
01032                 return False;
01033 
01034         if (size != sizeof(struct afs_keyfile)) {
01035                 SAFE_FREE(keyfile);
01036                 return False;
01037         }
01038 
01039         i = ntohl(keyfile->nkeys);
01040 
01041         if (i > SECRETS_AFS_MAXKEYS) {
01042                 SAFE_FREE(keyfile);
01043                 return False;
01044         }
01045 
01046         *result = keyfile->entry[i-1];
01047 
01048         result->kvno = ntohl(result->kvno);
01049 
01050         return True;
01051 }
01052 
01053 /******************************************************************************
01054   When kerberos is not available, choose between anonymous or
01055   authenticated connections.  
01056 
01057   We need to use an authenticated connection if DCs have the
01058   RestrictAnonymous registry entry set > 0, or the "Additional
01059   restrictions for anonymous connections" set in the win2k Local
01060   Security Policy.
01061 
01062   Caller to free() result in domain, username, password
01063 *******************************************************************************/
01064 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
01065 {
01066         *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
01067         *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
01068         *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
01069         
01070         if (*username && **username) {
01071 
01072                 if (!*domain || !**domain)
01073                         *domain = smb_xstrdup(lp_workgroup());
01074                 
01075                 if (!*password || !**password)
01076                         *password = smb_xstrdup("");
01077 
01078                 DEBUG(3, ("IPC$ connections done by user %s\\%s\n", 
01079                           *domain, *username));
01080 
01081         } else {
01082                 DEBUG(3, ("IPC$ connections done anonymously\n"));
01083                 *username = smb_xstrdup("");
01084                 *domain = smb_xstrdup("");
01085                 *password = smb_xstrdup("");
01086         }
01087 }
01088 
01089 /******************************************************************************
01090  Open or create the schannel session store tdb.
01091 *******************************************************************************/
01092 
01093 static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
01094 {
01095         TDB_DATA vers;
01096         uint32 ver;
01097         TDB_CONTEXT *tdb_sc = NULL;
01098         char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
01099 
01100         if (!fname) {
01101                 return NULL;
01102         }
01103 
01104         tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
01105 
01106         if (!tdb_sc) {
01107                 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
01108                 TALLOC_FREE(fname);
01109                 return NULL;
01110         }
01111 
01112         vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
01113         if (vers.dptr == NULL) {
01114                 /* First opener, no version. */
01115                 SIVAL(&ver,0,1);
01116                 vers.dptr = (char *)&ver;
01117                 vers.dsize = 4;
01118                 tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
01119                 vers.dptr = NULL;
01120         } else if (vers.dsize == 4) {
01121                 ver = IVAL(vers.dptr,0);
01122                 if (ver != 1) {
01123                         tdb_close(tdb_sc);
01124                         tdb_sc = NULL;
01125                         DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
01126                                 (int)ver, fname ));
01127                 }
01128         } else {
01129                 tdb_close(tdb_sc);
01130                 tdb_sc = NULL;
01131                 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
01132                         (int)vers.dsize, fname ));
01133         }
01134 
01135         SAFE_FREE(vers.dptr);
01136         TALLOC_FREE(fname);
01137 
01138         return tdb_sc;
01139 }
01140 
01141 /******************************************************************************
01142  Store the schannel state after an AUTH2 call.
01143  Note we must be root here.
01144 *******************************************************************************/
01145 
01146 BOOL secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
01147                                 const char *remote_machine,
01148                                 const struct dcinfo *pdc)
01149 {
01150         TDB_CONTEXT *tdb_sc = NULL;
01151         TDB_DATA value;
01152         BOOL ret;
01153         char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
01154                                 remote_machine);
01155         if (!keystr) {
01156                 return False;
01157         }
01158 
01159         strupper_m(keystr);
01160 
01161         /* Work out how large the record is. */
01162         value.dsize = tdb_pack(NULL, 0, "dBBBBBfff",
01163                                 pdc->sequence,
01164                                 8, pdc->seed_chal.data,
01165                                 8, pdc->clnt_chal.data,
01166                                 8, pdc->srv_chal.data,
01167                                 16, pdc->sess_key,
01168                                 16, pdc->mach_pw,
01169                                 pdc->mach_acct,
01170                                 pdc->remote_machine,
01171                                 pdc->domain);
01172 
01173         value.dptr = (char *)TALLOC(mem_ctx, value.dsize);
01174         if (!value.dptr) {
01175                 TALLOC_FREE(keystr);
01176                 return False;
01177         }
01178 
01179         value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff",
01180                                 pdc->sequence,
01181                                 8, pdc->seed_chal.data,
01182                                 8, pdc->clnt_chal.data,
01183                                 8, pdc->srv_chal.data,
01184                                 16, pdc->sess_key,
01185                                 16, pdc->mach_pw,
01186                                 pdc->mach_acct,
01187                                 pdc->remote_machine,
01188                                 pdc->domain);
01189 
01190         tdb_sc = open_schannel_session_store(mem_ctx);
01191         if (!tdb_sc) {
01192                 TALLOC_FREE(keystr);
01193                 TALLOC_FREE(value.dptr);
01194                 return False;
01195         }
01196 
01197         ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False);
01198 
01199         DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
01200                 keystr ));
01201 
01202         tdb_close(tdb_sc);
01203         TALLOC_FREE(keystr);
01204         TALLOC_FREE(value.dptr);
01205         return ret;
01206 }
01207 
01208 /******************************************************************************
01209  Restore the schannel state on a client reconnect.
01210  Note we must be root here.
01211 *******************************************************************************/
01212 
01213 BOOL secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
01214                                 const char *remote_machine,
01215                                 struct dcinfo **ppdc)
01216 {
01217         TDB_CONTEXT *tdb_sc = NULL;
01218         TDB_DATA value;
01219         unsigned char *pseed_chal = NULL;
01220         unsigned char *pclnt_chal = NULL;
01221         unsigned char *psrv_chal = NULL;
01222         unsigned char *psess_key = NULL;
01223         unsigned char *pmach_pw = NULL;
01224         uint32 l1, l2, l3, l4, l5;
01225         int ret;
01226         struct dcinfo *pdc = NULL;
01227         char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
01228                                 remote_machine);
01229 
01230         *ppdc = NULL;
01231 
01232         if (!keystr) {
01233                 return False;
01234         }
01235 
01236         strupper_m(keystr);
01237 
01238         tdb_sc = open_schannel_session_store(mem_ctx);
01239         if (!tdb_sc) {
01240                 TALLOC_FREE(keystr);
01241                 return False;
01242         }
01243 
01244         value = tdb_fetch_bystring(tdb_sc, keystr);
01245         if (!value.dptr) {
01246                 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
01247                         keystr ));
01248                 tdb_close(tdb_sc);
01249                 return False;
01250         }
01251 
01252         pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
01253 
01254         /* Retrieve the record. */
01255         ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
01256                                 &pdc->sequence,
01257                                 &l1, &pseed_chal,
01258                                 &l2, &pclnt_chal,
01259                                 &l3, &psrv_chal,
01260                                 &l4, &psess_key,
01261                                 &l5, &pmach_pw,
01262                                 &pdc->mach_acct,
01263                                 &pdc->remote_machine,
01264                                 &pdc->domain);
01265 
01266         if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) {
01267                 /* Bad record - delete it. */
01268                 tdb_delete_bystring(tdb_sc, keystr);
01269                 tdb_close(tdb_sc);
01270                 TALLOC_FREE(keystr);
01271                 TALLOC_FREE(pdc);
01272                 SAFE_FREE(pseed_chal);
01273                 SAFE_FREE(pclnt_chal);
01274                 SAFE_FREE(psrv_chal);
01275                 SAFE_FREE(psess_key);
01276                 SAFE_FREE(pmach_pw);
01277                 SAFE_FREE(value.dptr);
01278                 return False;
01279         }
01280 
01281         tdb_close(tdb_sc);
01282 
01283         memcpy(pdc->seed_chal.data, pseed_chal, 8);
01284         memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
01285         memcpy(pdc->srv_chal.data, psrv_chal, 8);
01286         memcpy(pdc->sess_key, psess_key, 16);
01287         memcpy(pdc->mach_pw, pmach_pw, 16);
01288 
01289         /* We know these are true so didn't bother to store them. */
01290         pdc->challenge_sent = True;
01291         pdc->authenticated = True;
01292 
01293         DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
01294                 keystr ));
01295 
01296         SAFE_FREE(pseed_chal);
01297         SAFE_FREE(pclnt_chal);
01298         SAFE_FREE(psrv_chal);
01299         SAFE_FREE(psess_key);
01300         SAFE_FREE(pmach_pw);
01301 
01302         TALLOC_FREE(keystr);
01303         SAFE_FREE(value.dptr);
01304 
01305         *ppdc = pdc;
01306 
01307         return True;
01308 }
01309 
01310 BOOL secrets_store_generic(const char *owner, const char *key, const char *secret)
01311 {
01312         char *tdbkey = NULL;
01313         BOOL ret;
01314         
01315         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
01316                 DEBUG(0, ("asprintf failed!\n"));
01317                 return False;
01318         }
01319                 
01320         ret = secrets_store(tdbkey, secret, strlen(secret)+1);
01321         
01322         SAFE_FREE(tdbkey);
01323         return ret;
01324 }
01325 
01326 /*******************************************************************
01327  Find the ldap password.
01328 ******************************************************************/
01329 
01330 char *secrets_fetch_generic(const char *owner, const char *key)
01331 {
01332         char *secret = NULL;
01333         char *tdbkey = NULL;
01334 
01335         if (( ! owner) || ( ! key)) {
01336                 DEBUG(1, ("Invalid Paramters"));
01337                 return NULL;
01338         }
01339 
01340         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
01341                 DEBUG(0, ("Out of memory!\n"));
01342                 return NULL;
01343         }
01344         
01345         secret = (char *)secrets_fetch(tdbkey, NULL);
01346         SAFE_FREE(tdbkey);
01347 
01348         return secret;
01349 }
01350 

Sambaに対してSat Aug 29 21:23:13 2009に生成されました。  doxygen 1.4.7