/* * Lock the keyring with the given handle, or unlock if YES is false. * We ignore the handle and lock all registered files. */ int keyring_lock (KEYRING_HANDLE hd, int yes) { KR_NAME kr; int rc = 0; (void)hd; if (yes) { /* first make sure the lock handles are created */ for (kr=kr_names; kr; kr = kr->next) { if (!keyring_is_writable(kr)) continue; if (!kr->lockhd) { kr->lockhd = create_dotlock( kr->fname ); if (!kr->lockhd) { log_info ("can't allocate lock for `%s'\n", kr->fname ); rc = G10ERR_GENERAL; } } } if (rc) return rc; /* and now set the locks */ for (kr=kr_names; kr; kr = kr->next) { if (!keyring_is_writable(kr)) continue; if (kr->is_locked) ; else if (make_dotlock (kr->lockhd, -1) ) { log_info ("can't lock `%s'\n", kr->fname ); rc = G10ERR_GENERAL; } else kr->is_locked = 1; } } if (rc || !yes) { for (kr=kr_names; kr; kr = kr->next) { if (!keyring_is_writable(kr)) continue; if (!kr->is_locked) ; else if (release_dotlock (kr->lockhd)) log_info ("can't unlock `%s'\n", kr->fname ); else kr->is_locked = 0; } } return rc; }
/* * Locate the default writable key resource, so that the next * operation (which is only relevant for inserts) will be done on this * resource. */ gpg_error_t keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved) { gpg_error_t rc; (void)reserved; if (!hd) return G10ERR_INV_ARG; rc = keydb_search_reset (hd); /* this does reset hd->current */ if (rc) return rc; /* If we have a primary set, try that one first */ if (primary_keyring) { for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) { if(hd->active[hd->current].token==primary_keyring) { if(keyring_is_writable (hd->active[hd->current].token)) return 0; else break; } } rc = keydb_search_reset (hd); /* this does reset hd->current */ if (rc) return rc; } for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) { switch (hd->active[hd->current].type) { case KEYDB_RESOURCE_TYPE_NONE: BUG(); break; case KEYDB_RESOURCE_TYPE_KEYRING: if (keyring_is_writable (hd->active[hd->current].token)) return 0; /* found (hd->current is set to it) */ break; case KEYDB_RESOURCE_TYPE_KEYBOX: if (keybox_is_writable (hd->active[hd->current].token)) return 0; /* found (hd->current is set to it) */ break; } } return gpg_error (GPG_ERR_NOT_FOUND); }
/* * Rebuild the caches of all key resources. */ void keydb_rebuild_caches (int noisy) { int i, rc; for (i=0; i < used_resources; i++) { if (all_resources[i].secret) continue; if (!keyring_is_writable (all_resources[i].token)) continue; switch (all_resources[i].type) { case KEYDB_RESOURCE_TYPE_NONE: /* ignore */ case KEYDB_RESOURCE_TYPE_KEYBOX: /* ignore */ break; case KEYDB_RESOURCE_TYPE_KEYRING: rc = keyring_rebuild_cache (all_resources[i].token,noisy); if (rc) log_error (_("failed to rebuild keyring cache: %s\n"), g10_errstr (rc)); break; } } }
/* * Lock the keyring with the given handle, or unlock if YES is false. * We ignore the handle and lock all registered files. */ int keyring_lock (KEYRING_HANDLE hd, int yes) { KR_RESOURCE kr; int rc = 0; (void)hd; if (yes) { /* first make sure the lock handles are created */ for (kr=kr_resources; kr; kr = kr->next) { if (!keyring_is_writable(kr)) continue; if (!kr->lockhd) { kr->lockhd = dotlock_create (kr->fname, 0); if (!kr->lockhd) { log_info ("can't allocate lock for '%s'\n", kr->fname ); rc = GPG_ERR_GENERAL; } } } if (rc) return rc; /* and now set the locks */ for (kr=kr_resources; kr; kr = kr->next) { if (!keyring_is_writable(kr)) continue; if (kr->is_locked) continue; #ifdef HAVE_W32_SYSTEM /* Under Windows we need to CloseHandle the file before we * try to lock it. This is because another process might * have taken the lock and is using keybox_file_rename to * rename the base file. How if our dotlock_take below is * waiting for the lock but we have the base file still * open, keybox_file_rename will never succeed as we are * in a deadlock. */ iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)kr->fname); #endif /*HAVE_W32_SYSTEM*/ if (dotlock_take (kr->lockhd, -1) ) { log_info ("can't lock '%s'\n", kr->fname ); rc = GPG_ERR_GENERAL; } else kr->is_locked = 1; } } if (rc || !yes) { for (kr=kr_resources; kr; kr = kr->next) { if (!keyring_is_writable(kr)) continue; if (!kr->is_locked) continue; if (dotlock_release (kr->lockhd)) log_info ("can't unlock '%s'\n", kr->fname ); else kr->is_locked = 0; } } return rc; }