4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher Stephen Gallagher <sgallagh@redhat.com>
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher Copyright (C) 2012 Red Hat
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher This program is free software; you can redistribute it and/or modify
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher it under the terms of the GNU General Public License as published by
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher the Free Software Foundation; either version 3 of the License, or
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher (at your option) any later version.
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher This program is distributed in the hope that it will be useful,
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher but WITHOUT ANY WARRANTY; without even the implied warranty of
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher GNU General Public License for more details.
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher You should have received a copy of the GNU General Public License
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher along with this program. If not, see <http://www.gnu.org/licenses/>.
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallaghersysdb_svc_remove_alias(struct sysdb_ctx *sysdb,
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher static const char *attrs[] = SYSDB_SVC_ATTRS;
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher ret = sss_filter_sanitize(tmp_ctx, name, &sanitized_name);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher ret = sss_filter_sanitize(tmp_ctx, proto, &sanitized_proto);
fd555d130dc733509347fa096a2cb858b014a196Simo Sorce subfilter = talloc_asprintf(tmp_ctx, SYSDB_SVC_BYNAME_FILTER,
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek ret = sysdb_search_services(mem_ctx, domain, subfilter,
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher static const char *attrs[] = SYSDB_SVC_ATTRS;
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher ret = sss_filter_sanitize(tmp_ctx, proto, &sanitized_proto);
fd555d130dc733509347fa096a2cb858b014a196Simo Sorce subfilter = talloc_asprintf(tmp_ctx, SYSDB_SVC_BYPORT_FILTER,
fd555d130dc733509347fa096a2cb858b014a196Simo Sorce (unsigned int) port);
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek ret = sysdb_search_services(mem_ctx, domain, subfilter,
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zideksysdb_store_service(struct sss_domain_info *domain,
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher unsigned int i;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Check that the port is unique
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * If the port appears for any service other than
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * the one matching the primary_name, we need to
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * remove them so that getservbyport() can work
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * properly. Last entry saved to the cache should
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * always "win".
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek ret = sysdb_getservbyport(tmp_ctx, domain, port, NULL, &res);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Somehow the cache has multiple entries with
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * the same port. This is corrupted. We'll delete
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * them all to sort it out.
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Corrupt cache entry [%s] detected. Deleting\n",
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher ret = sysdb_delete_entry(sysdb, res->msgs[i]->dn, true);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Could not delete corrupt cache entry [%s]\n",
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Check whether this is the same name as we're currently
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * saving to the cache.
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher name = ldb_msg_find_attr_as_string(res->msgs[0],
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher if (!name || strcmp(name, primary_name) != 0) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "A service with no name?\n");
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Corrupted */
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Either this is a corrupt entry or it's another service
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * claiming ownership of this port. In order to account
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * for port reassignments, we need to delete the old entry.
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Corrupt or replaced cache entry [%s] detected. "
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher ret = sysdb_delete_entry(sysdb, res->msgs[0]->dn, true);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Could not delete cache entry [%s]\n",
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Ok, ports should now be unique. Now look
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * the service up by name to determine if we
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * need to update existing entries or modify
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek ret = sysdb_getservbyname(tmp_ctx, domain, primary_name, NULL, &res);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher } else if (ret != ENOENT) { /* Found entries */
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Check whether this is the same name as we're currently
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * saving to the cache.
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher name = ldb_msg_find_attr_as_string(res->msgs[i],
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Corrupted */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "A service with no name?\n");
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Corrupt cache entry [%s] detected. Deleting\n",
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher ret = sysdb_delete_entry(sysdb, res->msgs[i]->dn, true);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Could not delete corrupt cache entry [%s]\n",
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher } else if (strcmp(name, primary_name) == 0) {
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* This is the same service name, so we need
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * to update this entry with the values
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Two existing services with the same name: [%s]? "
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher "Deleting both.\n",
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Delete the entry from the previous pass */
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher ret = sysdb_delete_entry(sysdb, update_dn, true);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Could not delete cache entry [%s]\n",
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Delete the new entry as well */
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher ret = sysdb_delete_entry(sysdb, res->msgs[i]->dn, true);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Could not delete cache entry [%s]\n",
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher update_dn = talloc_steal(tmp_ctx, res->msgs[i]->dn);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Another service is claiming this name as an alias.
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * In order to account for aliases being promoted to
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * primary names, we need to make sure to remove the
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * old alias entry.
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Update the existing entry */
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher ret = sysdb_svc_update(sysdb, update_dn, port, aliases, protocols);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Add a new entry */
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek ret = sysdb_svc_add(tmp_ctx, domain, primary_name, port,
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Set the cache timeout */
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE,
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher ret = sysdb_set_entry_attr(sysdb, update_dn, attrs, SYSDB_MOD_REP);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Could not remove missing attributes: [%s]\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n");
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n");
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallaghersysdb_svc_dn(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx,
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher ret = sysdb_dn_sanitize(NULL, name, &clean_name);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher dn = ldb_dn_new_fmt(mem_ctx, sysdb->ldb, SYSDB_TMPL_SVC,
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher unsigned long i;
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek msg->dn = sysdb_svc_dn(domain->sysdb, msg, domain->name, primary_name);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Objectclass */
a928f7a6bd7681db6e26cba3eb7da22d14288737Fabiano Fidêncio ret = sysdb_add_string(msg, SYSDB_OBJECTCLASS, SYSDB_SVC_CLASS);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Set the primary name */
a928f7a6bd7681db6e26cba3eb7da22d14288737Fabiano Fidêncio ret = sysdb_add_string(msg, SYSDB_NAME, primary_name);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Set the port number */
49d84c926b00ba1368372cdec255bceb58d66f43Fabiano Fidêncio ret = sysdb_add_ulong(msg, SYSDB_SVC_PORT, port);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* If this service has any aliases, include them */
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Set the name aliases */
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher lret = ldb_msg_add_empty(msg, SYSDB_NAME_ALIAS,
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher for (i=0; aliases[i]; i++) {
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher lret = ldb_msg_add_string(msg, SYSDB_NAME_ALIAS, aliases[i]);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Set the protocols */
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher lret = ldb_msg_add_empty(msg, SYSDB_SVC_PROTO,
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher for (i=0; protocols[i]; i++) {
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher lret = ldb_msg_add_string(msg, SYSDB_SVC_PROTO, protocols[i]);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* creation time */
49d84c926b00ba1368372cdec255bceb58d66f43Fabiano Fidêncio ret = sysdb_add_ulong(msg, SYSDB_CREATE_TIME, (unsigned long)time(NULL));
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher unsigned int i;
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Update the port */
49d84c926b00ba1368372cdec255bceb58d66f43Fabiano Fidêncio ret = sysdb_replace_ulong(msg, SYSDB_SVC_PORT, port);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Update the aliases */
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher lret = ldb_msg_add_empty(msg, SYSDB_NAME_ALIAS, SYSDB_MOD_REP, NULL);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher for (i = 0; aliases[i]; i++) {
d3d297c62e0340151da1d4ce1e082dcfcb45b431Jakub Hrozek lret = ldb_msg_add_string(msg, SYSDB_NAME_ALIAS, aliases[i]);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Update the protocols */
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher lret = ldb_msg_add_empty(msg, SYSDB_SVC_PROTO, SYSDB_MOD_REP, NULL);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher for (i = 0; protocols[i]; i++) {
d3d297c62e0340151da1d4ce1e082dcfcb45b431Jakub Hrozek lret = ldb_msg_add_string(msg, SYSDB_SVC_PROTO, protocols[i]);
04d138472cc086fb7961f0d378852b09961b1a33Lukas Slebodnik "ldb_modify failed: [%s](%d)[%s]\n",
04d138472cc086fb7961f0d378852b09961b1a33Lukas Slebodnik ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb));
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallaghersysdb_svc_remove_alias(struct sysdb_ctx *sysdb,
a928f7a6bd7681db6e26cba3eb7da22d14288737Fabiano Fidêncio ret = sysdb_delete_string(msg, SYSDB_NAME_ALIAS, alias);
04d138472cc086fb7961f0d378852b09961b1a33Lukas Slebodnik "ldb_modify failed: [%s](%d)[%s]\n",
04d138472cc086fb7961f0d378852b09961b1a33Lukas Slebodnik ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb));
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zideksysdb_svc_delete(struct sss_domain_info *domain,
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher unsigned int i;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek ret = sysdb_getservbyname(tmp_ctx, domain, name, proto, &res);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher if (ret != EOK && ret != ENOENT) goto done;
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Doesn't exist in the DB. Nothing to do */
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek ret = sysdb_getservbyport(tmp_ctx, domain, port, proto, &res);
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher if (ret != EOK && ret != ENOENT) goto done;
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* Doesn't exist in the DB. Nothing to do */
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher /* There should only be one matching entry,
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * but if there are multiple, we should delete
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher * them all to de-corrupt the DB.
4c1bf6607060cea867fccf667063c028dfd51e96Stephen Gallagher ret = sysdb_delete_entry(sysdb, res->msgs[i]->dn, false);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n");
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Could not cancel transaction\n");
1e7c355a2d36eb7b942b5111c96eb2a2285d49ccStephen Gallagher static const char *attrs[] = SYSDB_SVC_ATTRS;
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek ret = sysdb_search_services(mem_ctx, domain, "",
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zideksysdb_set_service_attr(struct sss_domain_info *domain,
eb29ae58117ca88868491fe2240e27393c7a9068Jakub Hrozek const char *name,
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek dn = sysdb_svc_dn(domain->sysdb, tmp_ctx, domain->name, name);
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek ret = sysdb_set_entry_attr(domain->sysdb, dn, attrs, mod_op);
d0483eefc41ac295ed4c56e08ad76ca7b5fb3b2cSimo Sorceerrno_t sysdb_search_services(TALLOC_CTX *mem_ctx,
d0483eefc41ac295ed4c56e08ad76ca7b5fb3b2cSimo Sorce const char **attrs,
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek basedn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "Failed to build base dn\n");
d0483eefc41ac295ed4c56e08ad76ca7b5fb3b2cSimo Sorce filter = talloc_asprintf(tmp_ctx, "(&(%s)%s)", SYSDB_SC, sub_filter);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "Failed to build filter\n");
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Search services with filter: %s\n", filter);
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek ret = sysdb_search_entry(mem_ctx, domain->sysdb, basedn,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "No such entry\n");
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "Error: %d (%s)\n", ret, strerror(ret));