libsmb/samlogon_cache.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    Net_sam_logon info3 helpers
00004    Copyright (C) Alexander Bokovoy              2002.
00005    Copyright (C) Andrew Bartlett                2002.
00006    Copyright (C) Gerald Carter                  2003.
00007    Copyright (C) Tim Potter                     2003.
00008    
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 2 of the License, or
00012    (at your option) any later version.
00013    
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018    
00019    You should have received a copy of the GNU General Public License
00020    along with this program; if not, write to the Free Software
00021    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00022 */
00023 
00024 #include "includes.h"
00025 
00026 #define NETSAMLOGON_TDB "netsamlogon_cache.tdb"
00027 
00028 static TDB_CONTEXT *netsamlogon_tdb = NULL;
00029 
00030 /***********************************************************************
00031  open the tdb
00032  ***********************************************************************/
00033  
00034 BOOL netsamlogon_cache_init(void)
00035 {
00036         if (!netsamlogon_tdb) {
00037                 netsamlogon_tdb = tdb_open_log(lock_path(NETSAMLOGON_TDB), 0,
00038                                                    TDB_DEFAULT, O_RDWR | O_CREAT, 0600);
00039         }
00040 
00041         return (netsamlogon_tdb != NULL);
00042 }
00043 
00044 
00045 /***********************************************************************
00046  Shutdown samlogon_cache database
00047 ***********************************************************************/
00048 
00049 BOOL netsamlogon_cache_shutdown(void)
00050 {
00051         if(netsamlogon_tdb)
00052                 return (tdb_close(netsamlogon_tdb) == 0);
00053                 
00054         return True;
00055 }
00056 
00057 /***********************************************************************
00058  Clear cache getpwnam and getgroups entries from the winbindd cache
00059 ***********************************************************************/
00060 void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user)
00061 {
00062         BOOL got_tdb = False;
00063         DOM_SID sid;
00064         fstring key_str, sid_string;
00065 
00066         /* We may need to call this function from smbd which will not have
00067            winbindd_cache.tdb open.  Open the tdb if a NULL is passed. */
00068 
00069         if (!tdb) {
00070                 tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 
00071                                    WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
00072                                    TDB_DEFAULT, O_RDWR, 0600);
00073                 if (!tdb) {
00074                         DEBUG(5, ("netsamlogon_clear_cached_user: failed to open cache\n"));
00075                         return;
00076                 }
00077                 got_tdb = True;
00078         }
00079 
00080         sid_copy(&sid, &user->dom_sid.sid);
00081         sid_append_rid(&sid, user->user_rid);
00082 
00083         /* Clear U/SID cache entry */
00084 
00085         fstr_sprintf(key_str, "U/%s", sid_to_string(sid_string, &sid));
00086 
00087         DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key_str));
00088 
00089         tdb_delete(tdb, string_tdb_data(key_str));
00090 
00091         /* Clear UG/SID cache entry */
00092 
00093         fstr_sprintf(key_str, "UG/%s", sid_to_string(sid_string, &sid));
00094 
00095         DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key_str));
00096 
00097         tdb_delete(tdb, string_tdb_data(key_str));
00098 
00099         if (got_tdb)
00100                 tdb_close(tdb);
00101 }
00102 
00103 /***********************************************************************
00104  Store a NET_USER_INFO_3 structure in a tdb for later user 
00105  username should be in UTF-8 format
00106 ***********************************************************************/
00107 
00108 BOOL netsamlogon_cache_store( const char *username, NET_USER_INFO_3 *user )
00109 {
00110         TDB_DATA        data;
00111         fstring         keystr;
00112         prs_struct      ps;
00113         BOOL            result = False;
00114         DOM_SID         user_sid;
00115         time_t          t = time(NULL);
00116         TALLOC_CTX      *mem_ctx;
00117         
00118 
00119         if (!netsamlogon_cache_init()) {
00120                 DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n", NETSAMLOGON_TDB));
00121                 return False;
00122         }
00123 
00124         sid_copy( &user_sid, &user->dom_sid.sid );
00125         sid_append_rid( &user_sid, user->user_rid );
00126 
00127         /* Prepare key as DOMAIN-SID/USER-RID string */
00128         slprintf(keystr, sizeof(keystr), "%s", sid_string_static(&user_sid));
00129 
00130         DEBUG(10,("netsamlogon_cache_store: SID [%s]\n", keystr));
00131         
00132         /* only Samba fills in the username, not sure why NT doesn't */
00133         /* so we fill it in since winbindd_getpwnam() makes use of it */
00134         
00135         if ( !user->uni_user_name.buffer ) {
00136                 init_unistr2( &user->uni_user_name, username, UNI_STR_TERMINATE );
00137                 init_uni_hdr( &user->hdr_user_name, &user->uni_user_name );
00138         }
00139                 
00140         /* Prepare data */
00141         
00142         if ( !(mem_ctx = TALLOC_P( NULL, int )) ) {
00143                 DEBUG(0,("netsamlogon_cache_store: talloc() failed!\n"));
00144                 return False;
00145         }
00146 
00147         prs_init( &ps, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
00148         
00149         {
00150                 uint32 ts = (uint32)t;
00151                 if ( !prs_uint32( "timestamp", &ps, 0, &ts ) )
00152                         return False;
00153         }
00154         
00155         if ( net_io_user_info3("", user, &ps, 0, 3, 0) ) 
00156         {
00157                 data.dsize = prs_offset( &ps );
00158                 data.dptr = prs_data_p( &ps );
00159 
00160                 if (tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_REPLACE) != -1)
00161                         result = True;
00162                 
00163                 prs_mem_free( &ps );
00164         }
00165 
00166         TALLOC_FREE( mem_ctx );
00167                 
00168         return result;
00169 }
00170 
00171 /***********************************************************************
00172  Retrieves a NET_USER_INFO_3 structure from a tdb.  Caller must 
00173  free the user_info struct (malloc()'d memory)
00174 ***********************************************************************/
00175 
00176 NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user_sid)
00177 {
00178         NET_USER_INFO_3 *user = NULL;
00179         TDB_DATA        data, key;
00180         prs_struct      ps;
00181         fstring         keystr;
00182         uint32          t;
00183         
00184         if (!netsamlogon_cache_init()) {
00185                 DEBUG(0,("netsamlogon_cache_get: cannot open %s for write!\n", NETSAMLOGON_TDB));
00186                 return False;
00187         }
00188 
00189         /* Prepare key as DOMAIN-SID/USER-RID string */
00190         slprintf(keystr, sizeof(keystr), "%s", sid_string_static(user_sid));
00191         DEBUG(10,("netsamlogon_cache_get: SID [%s]\n", keystr));
00192         key.dptr = keystr;
00193         key.dsize = strlen(keystr)+1;
00194         data = tdb_fetch( netsamlogon_tdb, key );
00195         
00196         if ( data.dptr ) {
00197 
00198                 user = TALLOC_ZERO_P(mem_ctx, NET_USER_INFO_3);
00199                 if (user == NULL) {
00200                         return NULL;
00201                 }
00202 
00203                 prs_init( &ps, 0, mem_ctx, UNMARSHALL );
00204                 prs_give_memory( &ps, data.dptr, data.dsize, True );
00205                 
00206                 if ( !prs_uint32( "timestamp", &ps, 0, &t ) ) {
00207                         prs_mem_free( &ps );
00208                         TALLOC_FREE(user);
00209                         return False;
00210                 }
00211                 
00212                 if ( !net_io_user_info3("", user, &ps, 0, 3, 0) ) {
00213                         TALLOC_FREE( user );
00214                 }
00215                         
00216                 prs_mem_free( &ps );
00217 
00218 #if 0   /* The netsamlogon cache needs to hang around.  Something about 
00219            this feels wrong, but it is the only way we can get all of the
00220            groups.  The old universal groups cache didn't expire either.
00221            --jerry */
00222         {
00223                 time_t          now = time(NULL);
00224                 uint32          time_diff;
00225            
00226                 /* is the entry expired? */
00227                 time_diff = now - t;
00228                 
00229                 if ( (time_diff < 0 ) || (time_diff > lp_winbind_cache_time()) ) {
00230                         DEBUG(10,("netsamlogon_cache_get: cache entry expired \n"));
00231                         tdb_delete( netsamlogon_tdb, key );
00232                         TALLOC_FREE( user );
00233                 }
00234 #endif
00235         }
00236         
00237         return user;
00238 }
00239 
00240 BOOL netsamlogon_cache_have(const DOM_SID *user_sid)
00241 {
00242         TALLOC_CTX *mem_ctx = talloc_init("netsamlogon_cache_have");
00243         NET_USER_INFO_3 *user = NULL;
00244         BOOL result;
00245 
00246         if (!mem_ctx)
00247                 return False;
00248 
00249         user = netsamlogon_cache_get(mem_ctx, user_sid);
00250 
00251         result = (user != NULL);
00252 
00253         talloc_destroy(mem_ctx);
00254 
00255         return result;
00256 }

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