libsmb/trustdom_cache.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003 
00004    Trusted domain names cache on top of gencache.
00005 
00006    Copyright (C) Rafal Szczesniak       2002
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 #include "includes.h"
00024 
00025 #undef DBGC_CLASS
00026 #define DBGC_CLASS DBGC_ALL     /* there's no proper class yet */
00027 
00028 #define TDOMKEY_FMT  "TDOM/%s"
00029 #define TDOMTSKEY    "TDOMCACHE/TIMESTAMP"
00030 
00031 
00032 /**
00033  * @file trustdom_cache.c
00034  *
00035  * Implementation of trusted domain names cache useful when
00036  * samba acts as domain member server. In such case, caching
00037  * domain names currently trusted gives a performance gain
00038  * because there's no need to query PDC each time we need
00039  * list of trusted domains
00040  **/
00041 
00042  
00043 /**
00044  * Initialise trustdom name caching system. Call gencache
00045  * initialisation routine to perform necessary activities.
00046  *
00047  * @return true upon successful cache initialisation or
00048  *         false if cache init failed
00049  **/
00050  
00051 BOOL trustdom_cache_enable(void)
00052 {
00053         /* Init trustdom cache by calling gencache initialisation */
00054         if (!gencache_init()) {
00055                 DEBUG(2, ("trustdomcache_enable: Couldn't initialise trustdom cache on top of gencache.\n"));
00056                 return False;
00057         }
00058 
00059         return True;
00060 }
00061 
00062 
00063 /**
00064  * Shutdown trustdom name caching system. Calls gencache
00065  * shutdown function.
00066  *
00067  * @return true upon successful cache close or
00068  *         false if it failed
00069  **/
00070  
00071 BOOL trustdom_cache_shutdown(void)
00072 {
00073         /* Close trustdom cache by calling gencache shutdown */
00074         if (!gencache_shutdown()) {
00075                 DEBUG(2, ("trustdomcache_shutdown: Couldn't shutdown trustdom cache on top of gencache.\n"));
00076                 return False;
00077         }
00078         
00079         return True;
00080 }
00081 
00082 
00083 /**
00084  * Form up trustdom name key. It is based only
00085  * on domain name now.
00086  *
00087  * @param name trusted domain name
00088  * @return cache key for use in gencache mechanism
00089  **/
00090 
00091 static char* trustdom_cache_key(const char* name)
00092 {
00093         char* keystr = NULL;
00094         asprintf(&keystr, TDOMKEY_FMT, strupper_static(name));
00095         
00096         return keystr;
00097 }
00098 
00099 
00100 /**
00101  * Store trusted domain in gencache as the domain name (key)
00102  * and ip address of domain controller (value)
00103  *
00104  * @param name trusted domain name
00105  * @param alt_name alternative trusted domain name (used in ADS domains)
00106  * @param sid trusted domain's SID
00107  * @param timeout cache entry expiration time
00108  * @return true upon successful value storing or
00109  *         false if store attempt failed
00110  **/
00111  
00112 BOOL trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid,
00113                           time_t timeout)
00114 {
00115         char *key, *alt_key;
00116         fstring sid_string;
00117         BOOL ret;
00118 
00119         /*
00120          * we use gecache call to avoid annoying debug messages
00121          * about initialised trustdom 
00122          */
00123         if (!gencache_init())
00124                 return False;
00125 
00126         DEBUG(5, ("trustdom_store: storing SID %s of domain %s\n",
00127                   sid_string_static(sid), name));
00128 
00129         key = trustdom_cache_key(name);
00130         alt_key = alt_name ? trustdom_cache_key(alt_name) : NULL;
00131 
00132         /* Generate string representation domain SID */
00133         sid_to_string(sid_string, sid);
00134 
00135         /*
00136          * try to put the names in the cache
00137          */
00138         if (alt_key) {
00139                 ret = gencache_set(alt_key, sid_string, timeout);
00140                 if ( ret ) {
00141                         ret = gencache_set(key, sid_string, timeout);
00142                 }
00143                 SAFE_FREE(alt_key);
00144                 SAFE_FREE(key);
00145                 return ret;
00146         }
00147 
00148         ret = gencache_set(key, sid_string, timeout);
00149         SAFE_FREE(key);
00150         return ret;
00151 }
00152 
00153 
00154 /**
00155  * Fetch trusted domain's dc from the gencache.
00156  * This routine can also be used to check whether given
00157  * domain is currently trusted one.
00158  *
00159  * @param name trusted domain name
00160  * @param sid trusted domain's SID to be returned
00161  * @return true if entry is found or
00162  *         false if has expired/doesn't exist
00163  **/
00164  
00165 BOOL trustdom_cache_fetch(const char* name, DOM_SID* sid)
00166 {
00167         char *key = NULL, *value = NULL;
00168         time_t timeout;
00169 
00170         /* init the cache */
00171         if (!gencache_init())
00172                 return False;
00173         
00174         /* exit now if null pointers were passed as they're required further */
00175         if (!sid)
00176                 return False;
00177 
00178         /* prepare a key and get the value */
00179         key = trustdom_cache_key(name);
00180         if (!key)
00181                 return False;
00182         
00183         if (!gencache_get(key, &value, &timeout)) {
00184                 DEBUG(5, ("no entry for trusted domain %s found.\n", name));
00185                 SAFE_FREE(key);
00186                 return False;
00187         } else {
00188                 SAFE_FREE(key);
00189                 DEBUG(5, ("trusted domain %s found (%s)\n", name, value));
00190         }
00191 
00192         /* convert ip string representation into in_addr structure */
00193         if(! string_to_sid(sid, value)) {
00194                 sid = NULL;
00195                 SAFE_FREE(value);
00196                 return False;
00197         }
00198         
00199         SAFE_FREE(value);
00200         return True;
00201 }
00202 
00203 
00204 /*******************************************************************
00205  fetch the timestamp from the last update 
00206 *******************************************************************/
00207 
00208 uint32 trustdom_cache_fetch_timestamp( void )
00209 {
00210         char *value = NULL;
00211         time_t timeout;
00212         uint32 timestamp;
00213 
00214         /* init the cache */
00215         if (!gencache_init()) 
00216                 return False;
00217                 
00218         if (!gencache_get(TDOMTSKEY, &value, &timeout)) {
00219                 DEBUG(5, ("no timestamp for trusted domain cache located.\n"));
00220                 SAFE_FREE(value);
00221                 return 0;
00222         } 
00223 
00224         timestamp = atoi(value);
00225                 
00226         SAFE_FREE(value);
00227         return timestamp;
00228 }
00229 
00230 /*******************************************************************
00231  store the timestamp from the last update 
00232 *******************************************************************/
00233 
00234 BOOL trustdom_cache_store_timestamp( uint32 t, time_t timeout )
00235 {
00236         fstring value;
00237 
00238         /* init the cache */
00239         if (!gencache_init()) 
00240                 return False;
00241                 
00242         fstr_sprintf(value, "%d", t );
00243                 
00244         if (!gencache_set(TDOMTSKEY, value, timeout)) {
00245                 DEBUG(5, ("failed to set timestamp for trustdom_cache\n"));
00246                 return False;
00247         } 
00248 
00249         return True;
00250 }
00251 
00252 
00253 /**
00254  * Delete single trustdom entry. Look at the
00255  * gencache_iterate definition.
00256  *
00257  **/
00258 
00259 static void flush_trustdom_name(const char* key, const char *value, time_t timeout, void* dptr)
00260 {
00261         gencache_del(key);
00262         DEBUG(5, ("Deleting entry %s\n", key));
00263 }
00264 
00265 
00266 /**
00267  * Flush all the trusted domains entries from the cache.
00268  **/
00269 
00270 void trustdom_cache_flush(void)
00271 {
00272         if (!gencache_init())
00273                 return;
00274 
00275         /* 
00276          * iterate through each TDOM cache's entry and flush it
00277          * by flush_trustdom_name function
00278          */
00279         gencache_iterate(flush_trustdom_name, NULL, trustdom_cache_key("*"));
00280         DEBUG(5, ("Trusted domains cache flushed\n"));
00281 }
00282 
00283 /********************************************************************
00284  update the trustdom_cache if needed 
00285 ********************************************************************/
00286 #define TRUSTDOM_UPDATE_INTERVAL        600
00287 
00288 void update_trustdom_cache( void )
00289 {
00290         char **domain_names;
00291         DOM_SID *dom_sids;
00292         uint32 num_domains;
00293         uint32 last_check;
00294         int time_diff;
00295         TALLOC_CTX *mem_ctx = NULL;
00296         time_t now = time(NULL);
00297         int i;
00298         
00299         /* get the timestamp.  We have to initialise it if the last timestamp == 0 */   
00300         if ( (last_check = trustdom_cache_fetch_timestamp()) == 0 ) 
00301                 trustdom_cache_store_timestamp(0, now+TRUSTDOM_UPDATE_INTERVAL);
00302 
00303         time_diff = (int) (now - last_check);
00304         
00305         if ( (time_diff > 0) && (time_diff < TRUSTDOM_UPDATE_INTERVAL) ) {
00306                 DEBUG(10,("update_trustdom_cache: not time to update trustdom_cache yet\n"));
00307                 return;
00308         }
00309 
00310         /* note that we don't lock the timestamp. This prevents this
00311            smbd from blocking all other smbd daemons while we
00312            enumerate the trusted domains */
00313         trustdom_cache_store_timestamp(now, now+TRUSTDOM_UPDATE_INTERVAL);
00314                 
00315         if ( !(mem_ctx = talloc_init("update_trustdom_cache")) ) {
00316                 DEBUG(0,("update_trustdom_cache: talloc_init() failed!\n"));
00317                 goto done;
00318         }
00319 
00320         /* get the domains and store them */
00321         
00322         if ( enumerate_domain_trusts(mem_ctx, lp_workgroup(), &domain_names, 
00323                 &num_domains, &dom_sids)) {
00324                 for ( i=0; i<num_domains; i++ ) {
00325                         trustdom_cache_store( domain_names[i], NULL, &dom_sids[i], 
00326                                 now+TRUSTDOM_UPDATE_INTERVAL);
00327                 }               
00328         } else {
00329                 /* we failed to fetch the list of trusted domains - restore the old
00330                    timestamp */
00331                 trustdom_cache_store_timestamp(last_check, 
00332                                                last_check+TRUSTDOM_UPDATE_INTERVAL);
00333         }
00334 
00335 done:   
00336         talloc_destroy( mem_ctx );
00337         
00338         return;
00339 }

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