82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek tools_mc_util - interface to the memcache for userspace tools
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek Copyright (C) Red Hat 2013
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek This program is free software; you can redistribute it and/or modify
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek it under the terms of the GNU General Public License as published by
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek the Free Software Foundation; either version 3 of the License, or
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek (at your option) any later version.
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek This program is distributed in the hope that it will be useful,
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek but WITHOUT ANY WARRANTY; without even the implied warranty of
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek GNU General Public License for more details.
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek You should have received a copy of the GNU General Public License
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek along with this program. If not, see <http://www.gnu.org/licenses/>.
714ba5f50551a42df324714358dc379b351d4a53Michal Zidek/* This is a copy of sss_mc_set_recycled present in
714ba5f50551a42df324714358dc379b351d4a53Michal Zidek * src/responder/nss/nsssrv_mmap_cache.c. If you modify this function,
714ba5f50551a42df324714358dc379b351d4a53Michal Zidek * you should modify the original function too. */
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek /* What do we do now ? */
8e44ddfccebe61728d8a2c1dafce36dfa944bc90Jakub Hrozek written = sss_atomic_write_s(fd, (uint8_t *)&w, sizeof(h.status));
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek /* Write error */
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozekerrno_t sss_memcache_invalidate(const char *mc_filename)
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC,"Memory cache file %s "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to open file %s: %s\n",
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek ret = sss_br_lock_file(mc_fd, 0, 1, retries, t);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "File %s already locked by someone else.\n", mc_filename);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Failed to lock file %s.\n", mc_filename);
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek /* Mark the mc file as recycled. */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Failed to mark memory cache file %s "
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek /* Closing the file also releases the lock */
1091c0ae2f1596ceb161e5b765a91c23c413b369Yuri Chornoivan /* Only unlink the file if invalidation was successful */
bc7991db97482eb2ac77f7105ee4bb3d329acff7Lukas Slebodnik "Failed to unlink file %s, %d [%s]. "
bc7991db97482eb2ac77f7105ee4bb3d329acff7Lukas Slebodnik "Will be unlinked later by sssd_nss.\n",
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozekstatic int clear_fastcache(bool *sssd_nss_is_off)
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek ret = sss_memcache_invalidate(SSS_NSS_MCACHE_DIR"/passwd");
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek ret = sss_memcache_invalidate(SSS_NSS_MCACHE_DIR"/group");
b08bcc387ad99b9c408183960c127dc77975b6ffLukas Slebodnik ret = sss_memcache_invalidate(SSS_NSS_MCACHE_DIR"/initgroups");
32c6db689a0206e062b799dfd32c34ba878ff044Lukas Slebodnikstatic errno_t wait_till_nss_responder_invalidate_cache(void)
32c6db689a0206e062b799dfd32c34ba878ff044Lukas Slebodnik const time_t max_wait = 1000000; /* 1 second */
32c6db689a0206e062b799dfd32c34ba878ff044Lukas Slebodnik const time_t step_time = 5000; /* 5 miliseconds */
32c6db689a0206e062b799dfd32c34ba878ff044Lukas Slebodnik const size_t steps_count = max_wait / step_time;
32c6db689a0206e062b799dfd32c34ba878ff044Lukas Slebodnik ret = stat(SSS_NSS_MCACHE_DIR "/" CLEAR_MC_FLAG, &stat_buf);
32c6db689a0206e062b799dfd32c34ba878ff044Lukas Slebodnik /* nss responder has already invalidated memory caches */
32c6db689a0206e062b799dfd32c34ba878ff044Lukas Slebodnik "stat failed: %s (%d)\n", sss_strerror(ret), ret);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Failed to clear caches.\n");
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek /* sssd_nss is running -> signal monitor to invalidate fastcache */
82dc11348718bf8e2ff07da696f91f6703293c24Jakub Hrozek clear_mc_flag = fopen(SSS_NSS_MCACHE_DIR"/"CLEAR_MC_FLAG, "w");
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Failed to create clear_mc_flag file. "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Memory cache will not be cleared.\n");
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Unable to close file descriptor: %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "Sending SIGHUP to monitor.\n");
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Failed to send SIGHUP to monitor.\n");
32c6db689a0206e062b799dfd32c34ba878ff044Lukas Slebodnik ret = wait_till_nss_responder_invalidate_cache();
32c6db689a0206e062b799dfd32c34ba878ff044Lukas Slebodnik ERROR("The fast memory caches was not invalidated by NSS "
32c6db689a0206e062b799dfd32c34ba878ff044Lukas Slebodnik "responder.\n");
543676afec3c08fdc0a5a794976adc8dfdca974bJakub Hrozekstatic errno_t sss_mc_refresh_ent(const char *name, enum sss_tools_ent ent)
11e8f3ecdddf8edd8b1bbe9f41b49ce8b709b92aPetr Cech DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d][%s] to refresh\n",
543676afec3c08fdc0a5a794976adc8dfdca974bJakub Hrozek nret = sss_nss_make_request(cmd, &rd, &repbuf, &replen, &ret);
543676afec3c08fdc0a5a794976adc8dfdca974bJakub Hrozek if (nret != NSS_STATUS_SUCCESS && nret != NSS_STATUS_NOTFOUND) {
543676afec3c08fdc0a5a794976adc8dfdca974bJakub Hrozekerrno_t sss_mc_refresh_user(const char *username)
543676afec3c08fdc0a5a794976adc8dfdca974bJakub Hrozek return sss_mc_refresh_ent(username, SSS_TOOLS_USER);
543676afec3c08fdc0a5a794976adc8dfdca974bJakub Hrozekerrno_t sss_mc_refresh_group(const char *groupname)
543676afec3c08fdc0a5a794976adc8dfdca974bJakub Hrozek return sss_mc_refresh_ent(groupname, SSS_TOOLS_GROUP);
cb54dbad6be907d277ce6aa39524338643e2f5a4Michal Židekstatic errno_t sss_mc_refresh_nested_group(struct tools_ctx *tctx,
cb54dbad6be907d277ce6aa39524338643e2f5a4Michal Židek internal_name = sss_create_internal_fqname(tmpctx, shortname,
cb54dbad6be907d277ce6aa39524338643e2f5a4Michal Židek "Cannot refresh group %s from memory cache\n", shortname);
7a92ae1598735ff69e36c72a7be60292ccad41d3Jakub Hrozek /* try to carry on */
cb54dbad6be907d277ce6aa39524338643e2f5a4Michal Židek ret = sysdb_search_group_by_name(tmpctx, tctx->local, internal_name, attrs,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Search failed: %s (%d)\n", strerror(ret), ret);
7a92ae1598735ff69e36c72a7be60292ccad41d3Jakub Hrozek el = ldb_msg_find_element(msg, SYSDB_MEMBEROF);
cb54dbad6be907d277ce6aa39524338643e2f5a4Michal Židek DEBUG(SSSDBG_TRACE_INTERNAL, "Group %s has no parents\n",
7a92ae1598735ff69e36c72a7be60292ccad41d3Jakub Hrozek /* This group is nested. We need to invalidate all its parents, too */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "Malformed DN [%s]? Skipping\n",
cb54dbad6be907d277ce6aa39524338643e2f5a4Michal Židek parent_outname = sss_output_name(tmpctx, parent_internal_name,
cb54dbad6be907d277ce6aa39524338643e2f5a4Michal Židek "Cannot refresh group %s from memory cache\n", parent_outname);
7a92ae1598735ff69e36c72a7be60292ccad41d3Jakub Hrozek /* try to carry on */
7a92ae1598735ff69e36c72a7be60292ccad41d3Jakub Hrozekerrno_t sss_mc_refresh_grouplist(struct tools_ctx *tctx,
2bb2eadf2b1b7854f430e37689b3e7a25bedfebdJakub Hrozek for (i = 0; groupnames[i]; i++) {
7a92ae1598735ff69e36c72a7be60292ccad41d3Jakub Hrozek ret = sss_mc_refresh_nested_group(tctx, groupnames[i]);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Cannot refresh group %s from memory cache\n",