nsswitch/idmap_cache.c

ソースコードを見る。

データ構造

struct  idmap_cache_ctx

関数

static int idmap_cache_destructor (struct idmap_cache_ctx *cache)
idmap_cache_ctxidmap_cache_init (TALLOC_CTX *memctx)
void idmap_cache_shutdown (struct idmap_cache_ctx *cache)
NTSTATUS idmap_cache_build_sidkey (TALLOC_CTX *ctx, char **sidkey, const struct id_map *id)
NTSTATUS idmap_cache_build_idkey (TALLOC_CTX *ctx, char **idkey, const struct id_map *id)
NTSTATUS idmap_cache_set (struct idmap_cache_ctx *cache, const struct id_map *id)
NTSTATUS idmap_cache_del (struct idmap_cache_ctx *cache, const struct id_map *id)
NTSTATUS idmap_cache_set_negative_sid (struct idmap_cache_ctx *cache, const struct id_map *id)
NTSTATUS idmap_cache_set_negative_id (struct idmap_cache_ctx *cache, const struct id_map *id)
NTSTATUS idmap_cache_fill_map (struct id_map *id, const char *value)
BOOL idmap_cache_is_negative (const char *val)
NTSTATUS idmap_cache_map_sid (struct idmap_cache_ctx *cache, struct id_map *id)
NTSTATUS idmap_cache_map_id (struct idmap_cache_ctx *cache, struct id_map *id)


関数

static int idmap_cache_destructor ( struct idmap_cache_ctx cache  )  [static]

idmap_cache.c35 行で定義されています。

参照先 cachetdb_close().

参照元 idmap_cache_init().

00036 {
00037         int ret = 0;
00038 
00039         if (cache && cache->tdb) {
00040                 ret = tdb_close(cache->tdb);
00041                 cache->tdb = NULL;
00042         }
00043 
00044         return ret;
00045 }

struct idmap_cache_ctx* idmap_cache_init ( TALLOC_CTX memctx  ) 

idmap_cache.c47 行で定義されています。

参照先 cacheidmap_cache_destructor()lock_path()tdb_open_log().

参照元 idmap_init_cache().

00048 {
00049         struct idmap_cache_ctx *cache;
00050         char* cache_fname = NULL;
00051 
00052         cache = talloc(memctx, struct idmap_cache_ctx);
00053         if ( ! cache) {
00054                 DEBUG(0, ("Out of memory!\n"));
00055                 return NULL;
00056         }
00057 
00058         cache_fname = lock_path("idmap_cache.tdb");
00059 
00060         DEBUG(10, ("Opening cache file at %s\n", cache_fname));
00061 
00062         cache->tdb = tdb_open_log(cache_fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
00063 
00064         if (!cache->tdb) {
00065                 DEBUG(5, ("Attempt to open %s has failed.\n", cache_fname));
00066                 return NULL;
00067         }
00068 
00069         talloc_set_destructor(cache, idmap_cache_destructor);
00070 
00071         return cache;
00072 }

void idmap_cache_shutdown ( struct idmap_cache_ctx cache  ) 

idmap_cache.c74 行で定義されています。

参照先 cachetalloc_free().

00075 {
00076         talloc_free(cache);
00077 }

NTSTATUS idmap_cache_build_sidkey ( TALLOC_CTX ctx,
char **  sidkey,
const struct id_map id 
)

idmap_cache.c79 行で定義されています。

参照先 idsid_string_static()talloc_asprintf().

参照元 idmap_cache_del()idmap_cache_map_sid()idmap_cache_set()idmap_cache_set_negative_sid().

00080 {
00081         *sidkey = talloc_asprintf(ctx, "IDMAP/SID/%s", sid_string_static(id->sid));
00082         if ( ! *sidkey) {
00083                 DEBUG(1, ("failed to build sidkey, OOM?\n"));
00084                 return NT_STATUS_NO_MEMORY;
00085         }
00086 
00087         return NT_STATUS_OK;
00088 }

NTSTATUS idmap_cache_build_idkey ( TALLOC_CTX ctx,
char **  idkey,
const struct id_map id 
)

idmap_cache.c90 行で定義されています。

参照先 idID_TYPE_UIDtalloc_asprintf().

参照元 idmap_cache_del()idmap_cache_map_id()idmap_cache_set()idmap_cache_set_negative_id().

00091 {
00092         *idkey = talloc_asprintf(ctx, "IDMAP/%s/%lu",
00093                                 (id->xid.type==ID_TYPE_UID)?"UID":"GID",
00094                                 (unsigned long)id->xid.id);
00095         if ( ! *idkey) {
00096                 DEBUG(1, ("failed to build idkey, OOM?\n"));
00097                 return NT_STATUS_NO_MEMORY;
00098         }
00099 
00100         return NT_STATUS_OK;
00101 }

NTSTATUS idmap_cache_set ( struct idmap_cache_ctx cache,
const struct id_map id 
)

idmap_cache.c103 行で定義されています。

参照先 cacheTDB_DATA::dptrTDB_DATA::dsizeidID_TYPE_GIDID_TYPE_UIDidmap_cache_build_idkey()idmap_cache_build_sidkey()sid_check_is_in_unix_groups()sid_check_is_in_unix_users()talloc_asprintf()talloc_free()tdb_store()timeout.

参照元 idmap_set_mapping()idmap_sids_to_unixids()idmap_unixids_to_sids().

00104 {
00105         NTSTATUS ret;
00106         time_t timeout = time(NULL) + lp_idmap_cache_time();
00107         TDB_DATA keybuf, databuf;
00108         char *sidkey;
00109         char *idkey;
00110         char *valstr;
00111 
00112         /* Don't cache lookups in the S-1-22-{1,2} domain */
00113         if ( (id->xid.type == ID_TYPE_UID) && 
00114              sid_check_is_in_unix_users(id->sid) )
00115         {
00116                 return NT_STATUS_OK;
00117         }
00118         if ( (id->xid.type == ID_TYPE_GID) && 
00119              sid_check_is_in_unix_groups(id->sid) )
00120         {
00121                 return NT_STATUS_OK;
00122         }
00123         
00124 
00125         ret = idmap_cache_build_sidkey(cache, &sidkey, id);
00126         if (!NT_STATUS_IS_OK(ret)) return ret;
00127 
00128         /* use sidkey as the local memory ctx */
00129         ret = idmap_cache_build_idkey(sidkey, &idkey, id);
00130         if (!NT_STATUS_IS_OK(ret)) {
00131                 goto done;
00132         }
00133 
00134         /* save SID -> ID */
00135 
00136         /* use sidkey as the local memory ctx */
00137         valstr = talloc_asprintf(sidkey, IDMAP_CACHE_DATA_FMT, (int)timeout, idkey);
00138         if (!valstr) {
00139                 DEBUG(0, ("Out of memory!\n"));
00140                 ret = NT_STATUS_NO_MEMORY;
00141                 goto done;
00142         }
00143 
00144         keybuf.dptr = sidkey;
00145         keybuf.dsize = strlen(sidkey)+1;
00146         databuf.dptr = valstr;
00147         databuf.dsize = strlen(valstr)+1;
00148         DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout ="
00149                    " %s (%d seconds %s)\n", keybuf.dptr, valstr , ctime(&timeout),
00150                    (int)(timeout - time(NULL)), 
00151                    timeout > time(NULL) ? "ahead" : "in the past"));
00152 
00153         if (tdb_store(cache->tdb, keybuf, databuf, TDB_REPLACE) != 0) {
00154                 DEBUG(3, ("Failed to store cache entry!\n"));
00155                 ret = NT_STATUS_UNSUCCESSFUL;
00156                 goto done;
00157         }
00158 
00159         /* save ID -> SID */
00160 
00161         /* use sidkey as the local memory ctx */
00162         valstr = talloc_asprintf(sidkey, IDMAP_CACHE_DATA_FMT, (int)timeout, sidkey);
00163         if (!valstr) {
00164                 DEBUG(0, ("Out of memory!\n"));
00165                 ret = NT_STATUS_NO_MEMORY;
00166                 goto done;
00167         }
00168 
00169         keybuf.dptr = idkey;
00170         keybuf.dsize = strlen(idkey)+1;
00171         databuf.dptr = valstr;
00172         databuf.dsize = strlen(valstr)+1;
00173         DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout ="
00174                    " %s (%d seconds %s)\n", keybuf.dptr, valstr, ctime(&timeout),
00175                    (int)(timeout - time(NULL)), 
00176                    timeout > time(NULL) ? "ahead" : "in the past"));
00177 
00178         if (tdb_store(cache->tdb, keybuf, databuf, TDB_REPLACE) != 0) {
00179                 DEBUG(3, ("Failed to store cache entry!\n"));
00180                 ret = NT_STATUS_UNSUCCESSFUL;
00181                 goto done;
00182         }
00183 
00184         ret = NT_STATUS_OK;
00185 
00186 done:
00187         talloc_free(sidkey);
00188         return ret;
00189 }

NTSTATUS idmap_cache_del ( struct idmap_cache_ctx cache,
const struct id_map id 
)

idmap_cache.c191 行で定義されています。

参照先 cacheTDB_DATA::dptrTDB_DATA::dsizeidmap_cache_build_idkey()idmap_cache_build_sidkey()talloc_free()tdb_delete().

00192 {
00193         NTSTATUS ret;
00194         TDB_DATA keybuf;
00195         char *sidkey = NULL;
00196         char *idkey = NULL;
00197 
00198         ret = idmap_cache_build_sidkey(cache, &sidkey, id);
00199         if (!NT_STATUS_IS_OK(ret)) return ret;
00200 
00201         ret = idmap_cache_build_idkey(cache, &idkey, id);
00202         if (!NT_STATUS_IS_OK(ret)) {
00203                 goto done;
00204         }
00205 
00206         /* delete SID */
00207 
00208         keybuf.dptr = sidkey;
00209         keybuf.dsize = strlen(sidkey)+1;
00210         DEBUG(10, ("Deleting cache entry (key = %s)\n", keybuf.dptr));
00211 
00212         if (tdb_delete(cache->tdb, keybuf) != 0) {
00213                 DEBUG(3, ("Failed to delete cache entry!\n"));
00214         }
00215 
00216         /* delete ID */
00217 
00218         keybuf.dptr = idkey;
00219         keybuf.dsize = strlen(idkey)+1;
00220         DEBUG(10, ("Deleting cache entry (key = %s)\n", keybuf.dptr));
00221 
00222         if (tdb_delete(cache->tdb, keybuf) != 0) {
00223                 DEBUG(3, ("Failed to delete cache entry!\n"));
00224         }
00225 
00226 done:
00227         talloc_free(sidkey);
00228         talloc_free(idkey);
00229         return ret;
00230 }

NTSTATUS idmap_cache_set_negative_sid ( struct idmap_cache_ctx cache,
const struct id_map id 
)

idmap_cache.c232 行で定義されています。

参照先 cacheTDB_DATA::dptrTDB_DATA::dsizeidmap_cache_build_sidkey()talloc_asprintf()talloc_free()tdb_store()timeout.

参照元 idmap_sids_to_unixids().

00233 {
00234         NTSTATUS ret;
00235         time_t timeout = time(NULL) + lp_idmap_negative_cache_time();
00236         TDB_DATA keybuf, databuf;
00237         char *sidkey;
00238         char *valstr;
00239 
00240         ret = idmap_cache_build_sidkey(cache, &sidkey, id);
00241         if (!NT_STATUS_IS_OK(ret)) return ret;
00242 
00243         /* use sidkey as the local memory ctx */
00244         valstr = talloc_asprintf(sidkey, IDMAP_CACHE_DATA_FMT, (int)timeout, "IDMAP/NEGATIVE");
00245         if (!valstr) {
00246                 DEBUG(0, ("Out of memory!\n"));
00247                 ret = NT_STATUS_NO_MEMORY;
00248                 goto done;
00249         }
00250 
00251         keybuf.dptr = sidkey;
00252         keybuf.dsize = strlen(sidkey)+1;
00253         databuf.dptr = valstr;
00254         databuf.dsize = strlen(valstr)+1;
00255         DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout ="
00256                    " %s (%d seconds %s)\n", keybuf.dptr, valstr, ctime(&timeout),
00257                    (int)(timeout - time(NULL)), 
00258                    timeout > time(NULL) ? "ahead" : "in the past"));
00259 
00260         if (tdb_store(cache->tdb, keybuf, databuf, TDB_REPLACE) != 0) {
00261                 DEBUG(3, ("Failed to store cache entry!\n"));
00262                 ret = NT_STATUS_UNSUCCESSFUL;
00263                 goto done;
00264         }
00265 
00266 done:
00267         talloc_free(sidkey);
00268         return ret;
00269 }

NTSTATUS idmap_cache_set_negative_id ( struct idmap_cache_ctx cache,
const struct id_map id 
)

idmap_cache.c271 行で定義されています。

参照先 cacheTDB_DATA::dptrTDB_DATA::dsizeidmap_cache_build_idkey()talloc_asprintf()talloc_free()tdb_store()timeout.

参照元 idmap_unixids_to_sids().

00272 {
00273         NTSTATUS ret;
00274         time_t timeout = time(NULL) + lp_idmap_negative_cache_time();
00275         TDB_DATA keybuf, databuf;
00276         char *idkey;
00277         char *valstr;
00278 
00279         ret = idmap_cache_build_idkey(cache, &idkey, id);
00280         if (!NT_STATUS_IS_OK(ret)) return ret;
00281 
00282         /* use idkey as the local memory ctx */
00283         valstr = talloc_asprintf(idkey, IDMAP_CACHE_DATA_FMT, (int)timeout, "IDMAP/NEGATIVE");
00284         if (!valstr) {
00285                 DEBUG(0, ("Out of memory!\n"));
00286                 ret = NT_STATUS_NO_MEMORY;
00287                 goto done;
00288         }
00289 
00290         keybuf.dptr = idkey;
00291         keybuf.dsize = strlen(idkey)+1;
00292         databuf.dptr = valstr;
00293         databuf.dsize = strlen(valstr)+1;
00294         DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout ="
00295                    " %s (%d seconds %s)\n", keybuf.dptr, valstr, ctime(&timeout),
00296                    (int)(timeout - time(NULL)), 
00297                    timeout > time(NULL) ? "ahead" : "in the past"));
00298 
00299         if (tdb_store(cache->tdb, keybuf, databuf, TDB_REPLACE) != 0) {
00300                 DEBUG(3, ("Failed to store cache entry!\n"));
00301                 ret = NT_STATUS_UNSUCCESSFUL;
00302                 goto done;
00303         }
00304 
00305 done:
00306         talloc_free(idkey);
00307         return ret;
00308 }

NTSTATUS idmap_cache_fill_map ( struct id_map id,
const char *  value 
)

idmap_cache.c310 行で定義されています。

参照先 failedidID_MAPPEDID_TYPE_GIDID_TYPE_UIDID_UNKNOWNstring_to_sid().

参照元 idmap_cache_map_id()idmap_cache_map_sid().

00311 {
00312         char *rem;
00313 
00314         /* see if it is a sid */
00315         if ( ! strncmp("IDMAP/SID/", value, 10)) {
00316                 
00317                 if ( ! string_to_sid(id->sid, &value[10])) {
00318                         goto failed;
00319                 }
00320                 
00321                 id->status = ID_MAPPED;
00322 
00323                 return NT_STATUS_OK;
00324         }
00325 
00326         /* not a SID see if it is an UID or a GID */
00327         if ( ! strncmp("IDMAP/UID/", value, 10)) {
00328                 
00329                 /* a uid */
00330                 id->xid.type = ID_TYPE_UID;
00331                 
00332         } else if ( ! strncmp("IDMAP/GID/", value, 10)) {
00333                 
00334                 /* a gid */
00335                 id->xid.type = ID_TYPE_GID;
00336                 
00337         } else {
00338                 
00339                 /* a completely bogus value bail out */
00340                 goto failed;
00341         }
00342         
00343         id->xid.id = strtol(&value[10], &rem, 0);
00344         if (*rem != '\0') {
00345                 goto failed;
00346         }
00347 
00348         id->status = ID_MAPPED;
00349 
00350         return NT_STATUS_OK;
00351 
00352 failed:
00353         DEBUG(1, ("invalid value: %s\n", value));
00354         id->status = ID_UNKNOWN;
00355         return NT_STATUS_INTERNAL_DB_CORRUPTION;
00356 }

BOOL idmap_cache_is_negative ( const char *  val  ) 

idmap_cache.c358 行で定義されています。

00359 {
00360         if ( ! strcmp("IDMAP/NEGATIVE", val)) {
00361                 return True;
00362         }
00363         return False;
00364 }

NTSTATUS idmap_cache_map_sid ( struct idmap_cache_ctx cache,
struct id_map id 
)

idmap_cache.c381 行で定義されています。

参照先 cacheTDB_DATA::dptrTDB_DATA::dsizeID_EXPIREDID_UNKNOWNID_UNMAPPEDidmap_cache_build_sidkey()idmap_cache_fill_map()ttalloc_free()tdb_delete()tdb_fetch().

参照元 idmap_sids_to_unixids().

00382 {
00383         NTSTATUS ret;
00384         TDB_DATA keybuf, databuf;
00385         time_t t, now;
00386         char *sidkey;
00387         char *endptr;
00388 
00389         /* make sure it is marked as unknown by default */
00390         id->status = ID_UNKNOWN;
00391         
00392         ret = idmap_cache_build_sidkey(cache, &sidkey, id);
00393         if (!NT_STATUS_IS_OK(ret)) return ret;
00394 
00395         keybuf.dptr = sidkey;
00396         keybuf.dsize = strlen(sidkey)+1;
00397 
00398         databuf = tdb_fetch(cache->tdb, keybuf);
00399 
00400         if (databuf.dptr == NULL) {
00401                 DEBUG(10, ("Cache entry with key = %s couldn't be found\n", sidkey));
00402                 ret = NT_STATUS_NONE_MAPPED;
00403                 goto done;
00404         }
00405 
00406         t = strtol(databuf.dptr, &endptr, 10);
00407 
00408         if ((endptr == NULL) || (*endptr != '/')) {
00409                 DEBUG(2, ("Invalid gencache data format: %s\n", databuf.dptr));
00410                 /* remove the entry */
00411                 tdb_delete(cache->tdb, keybuf);
00412                 ret = NT_STATUS_NONE_MAPPED;
00413                 goto done;
00414         }
00415 
00416         now = time(NULL);
00417 
00418         /* check it is not negative */
00419         if (strcmp("IDMAP/NEGATIVE", endptr+1) != 0) {
00420 
00421                 DEBUG(10, ("Returning %s cache entry: key = %s, value = %s, "
00422                            "timeout = %s", t > now ? "valid" :
00423                            "expired", sidkey, endptr+1, ctime(&t)));
00424 
00425                 /* this call if successful will also mark the entry as mapped */
00426                 ret = idmap_cache_fill_map(id, endptr+1);
00427                 if ( ! NT_STATUS_IS_OK(ret)) {
00428                         /* if not valid form delete the entry */
00429                         tdb_delete(cache->tdb, keybuf);
00430                         ret = NT_STATUS_NONE_MAPPED;
00431                         goto done;
00432                 }
00433 
00434                 /* here ret == NT_STATUS_OK and id->status = ID_MAPPED */
00435 
00436                 if (t <= now) {
00437         
00438                         /* we have it, but it is expired */
00439                         id->status = ID_EXPIRED;
00440                                 
00441                         /* We're expired, set an error code
00442                            for upper layer */
00443                         ret = NT_STATUS_SYNCHRONIZATION_REQUIRED;
00444                 }
00445         } else {
00446                 if (t <= now) {
00447                         /* We're expired, delete the NEGATIVE entry and return
00448                            not mapped */
00449                         tdb_delete(cache->tdb, keybuf);
00450                         ret = NT_STATUS_NONE_MAPPED;
00451                 } else {
00452                         /* this is not mapped as it was a negative cache hit */
00453                         id->status = ID_UNMAPPED;
00454                         ret = NT_STATUS_OK;
00455                 }
00456         }
00457         
00458 done:
00459         SAFE_FREE(databuf.dptr);
00460         talloc_free(sidkey);
00461         return ret;
00462 }

NTSTATUS idmap_cache_map_id ( struct idmap_cache_ctx cache,
struct id_map id 
)

idmap_cache.c479 行で定義されています。

参照先 cacheTDB_DATA::dptrTDB_DATA::dsizeID_EXPIREDID_UNKNOWNID_UNMAPPEDidmap_cache_build_idkey()idmap_cache_fill_map()ttalloc_free()tdb_delete()tdb_fetch().

参照元 idmap_unixids_to_sids().

00480 {
00481         NTSTATUS ret;
00482         TDB_DATA keybuf, databuf;
00483         time_t t, now;
00484         char *idkey;
00485         char *endptr;
00486 
00487         /* make sure it is marked as unknown by default */
00488         id->status = ID_UNKNOWN;
00489         
00490         ret = idmap_cache_build_idkey(cache, &idkey, id);
00491         if (!NT_STATUS_IS_OK(ret)) return ret;
00492 
00493         keybuf.dptr = idkey;
00494         keybuf.dsize = strlen(idkey)+1;
00495 
00496         databuf = tdb_fetch(cache->tdb, keybuf);
00497 
00498         if (databuf.dptr == NULL) {
00499                 DEBUG(10, ("Cache entry with key = %s couldn't be found\n", idkey));
00500                 ret = NT_STATUS_NONE_MAPPED;
00501                 goto done;
00502         }
00503 
00504         t = strtol(databuf.dptr, &endptr, 10);
00505 
00506         if ((endptr == NULL) || (*endptr != '/')) {
00507                 DEBUG(2, ("Invalid gencache data format: %s\n", databuf.dptr));
00508                 /* remove the entry */
00509                 tdb_delete(cache->tdb, keybuf);
00510                 ret = NT_STATUS_NONE_MAPPED;
00511                 goto done;
00512         }
00513 
00514         now = time(NULL);
00515 
00516         /* check it is not negative */
00517         if (strcmp("IDMAP/NEGATIVE", endptr+1) != 0) {
00518                 
00519                 DEBUG(10, ("Returning %s cache entry: key = %s, value = %s, "
00520                            "timeout = %s", t > now ? "valid" :
00521                            "expired", idkey, endptr+1, ctime(&t)));
00522 
00523                 /* this call if successful will also mark the entry as mapped */
00524                 ret = idmap_cache_fill_map(id, endptr+1);
00525                 if ( ! NT_STATUS_IS_OK(ret)) {
00526                         /* if not valid form delete the entry */
00527                         tdb_delete(cache->tdb, keybuf);
00528                         ret = NT_STATUS_NONE_MAPPED;
00529                         goto done;
00530                 }
00531 
00532                 /* here ret == NT_STATUS_OK and id->mapped = ID_MAPPED */
00533 
00534                 if (t <= now) {
00535 
00536                         /* we have it, but it is expired */
00537                         id->status = ID_EXPIRED;
00538 
00539                         /* We're expired, set an error code
00540                            for upper layer */
00541                         ret = NT_STATUS_SYNCHRONIZATION_REQUIRED;
00542                 }
00543         } else {
00544                 if (t <= now) {
00545                         /* We're expired, delete the NEGATIVE entry and return
00546                            not mapped */
00547                         tdb_delete(cache->tdb, keybuf);
00548                         ret = NT_STATUS_NONE_MAPPED;
00549                 } else {
00550                         /* this is not mapped as it was a negative cache hit */
00551                         id->status = ID_UNMAPPED;
00552                         ret = NT_STATUS_OK;
00553                 }
00554         }
00555 done:
00556         SAFE_FREE(databuf.dptr);
00557         talloc_free(idkey);
00558         return ret;
00559 }


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