/* * When we (re)create a new file we must mark the current file as recycled * so active clients will abandon its use asap. * We unlink the current file and make a new one */ static errno_t sss_mc_create_file(struct sss_mc_ctx *mc_ctx) { mode_t old_mask; int ofd; int ret; ofd = open(mc_ctx->file, O_RDWR); if (ofd != -1) { ret = sss_mc_set_recycled(ofd); if (ret) { DEBUG(SSSDBG_TRACE_FUNC, ("Failed to mark mmap file %s as" " recycled: %d(%s)\n", mc_ctx->file, ret, strerror(ret))); } close(ofd); } errno = 0; ret = unlink(mc_ctx->file); if (ret == -1) { ret = errno; DEBUG(SSSDBG_TRACE_FUNC, ("Failed to rm mmap file %s: %d(%s)\n", mc_ctx->file, ret, strerror(ret))); } /* temporarily relax umask as we need the file to be readable * by everyone for now */ old_mask = umask(0022); ret = 0; mc_ctx->fd = open(mc_ctx->file, O_CREAT | O_EXCL | O_RDWR, 0644); if (mc_ctx->fd == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to open mmap file %s: %d(%s)\n", mc_ctx->file, ret, strerror(ret))); } /* reset mask back */ umask(old_mask); return ret; }
errno_t sss_memcache_invalidate(const char *mc_filename) { int mc_fd = -1; errno_t ret; errno_t pret; useconds_t t = 50000; int retries = 2; if (!mc_filename) { return EINVAL; } mc_fd = open(mc_filename, O_RDWR); if (mc_fd == -1) { ret = errno; if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC,"Memory cache file %s " "does not exist.\n", mc_filename); return EOK; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to open file %s: %s\n", mc_filename, strerror(ret)); return ret; } } ret = sss_br_lock_file(mc_fd, 0, 1, retries, t); if (ret == EACCES) { DEBUG(SSSDBG_TRACE_FUNC, "File %s already locked by someone else.\n", mc_filename); goto done; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to lock file %s.\n", mc_filename); goto done; } /* Mark the mc file as recycled. */ ret = sss_mc_set_recycled(mc_fd); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to mark memory cache file %s " "as recycled.\n", mc_filename); goto done; } ret = EOK; done: if (mc_fd != -1) { /* Closing the file also releases the lock */ close(mc_fd); /* Only unlink the file if invalidation was successful */ if (ret == EOK) { pret = unlink(mc_filename); if (pret == -1) { pret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "Failed to unlink file %s, %d [%s]. " "Will be unlinked later by sssd_nss.\n", mc_filename, pret, strerror(pret)); } } } return ret; }