55cf6e01272ec475edea32aa9b7923de2d36cb42Christian Maeder/*
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu SSSD
e9458b1a7a19a63aa4c179f9ab20f4d50681c168Jens Elkner
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu Authors:
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu Yassir Elley <yelley@redhat.com>
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu
98890889ffb2e8f6f722b00e265a211f13b5a861Corneliu-Claudiu Prodescu Copyright (C) 2014 Red Hat
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu This program is free software; you can redistribute it and/or modify
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu it under the terms of the GNU General Public License as published by
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu the Free Software Foundation; either version 3 of the License, or
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu (at your option) any later version.
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu This program is distributed in the hope that it will be useful,
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu but WITHOUT ANY WARRANTY; without even the implied warranty of
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu GNU General Public License for more details.
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu You should have received a copy of the GNU General Public License
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu along with this program. If not, see <http://www.gnu.org/licenses/>.
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu*/
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu#include "db/sysdb.h"
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu#include "db/sysdb_private.h"
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescustatic struct ldb_dn *
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescusysdb_gpo_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain,
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu const char *gpo_guid)
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu{
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu errno_t ret;
a14767aeac3e78ed100f5b75e210ba563ee10dbaChristian Maeder char *clean_gpo_guid;
a14767aeac3e78ed100f5b75e210ba563ee10dbaChristian Maeder struct ldb_dn *dn;
a14767aeac3e78ed100f5b75e210ba563ee10dbaChristian Maeder
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder ret = sysdb_dn_sanitize(NULL, gpo_guid, &clean_gpo_guid);
a14767aeac3e78ed100f5b75e210ba563ee10dbaChristian Maeder if (ret != EOK) {
a14767aeac3e78ed100f5b75e210ba563ee10dbaChristian Maeder return NULL;
a14767aeac3e78ed100f5b75e210ba563ee10dbaChristian Maeder }
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO"\n", clean_gpo_guid, domain->name);
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu dn = ldb_dn_new_fmt(mem_ctx, domain->sysdb->ldb, SYSDB_TMPL_GPO,
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu clean_gpo_guid, domain->name);
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu talloc_free(clean_gpo_guid);
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu return dn;
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu}
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescuerrno_t
a14767aeac3e78ed100f5b75e210ba563ee10dbaChristian Maedersysdb_gpo_store_gpo(struct sss_domain_info *domain,
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu const char *gpo_guid,
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu int gpo_version,
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu int cache_timeout,
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu time_t now)
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu{
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu errno_t ret, sret;
2b6aa0a0d40fe9855acdf42e62b1a5919d9b1c7dChristian Maeder int lret;
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu struct ldb_message *update_msg;
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu struct ldb_message **msgs;
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu static const char *attrs[] = SYSDB_GPO_ATTRS;
5c46e29755de01585aa7af9ea106e68ddfb012e2Mihai Codescu size_t count;
b5056cf24da461ee868c4be7b803a76b677fa21dChristian Maeder bool in_transaction = false;
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu TALLOC_CTX *tmp_ctx;
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu tmp_ctx = talloc_new(NULL);
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu if (!tmp_ctx) return ENOMEM;
06f58a67e6df999858bf4f97d5e0786956562d29Christian Maeder
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu update_msg = ldb_msg_new(tmp_ctx);
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu if (!update_msg) {
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu ret = ENOMEM;
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu goto done;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
5382091fd2a705e6f026026e8a6adcd3607bdb9fChristian Maeder
b5056cf24da461ee868c4be7b803a76b677fa21dChristian Maeder update_msg->dn = sysdb_gpo_dn(update_msg, domain, gpo_guid);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (!update_msg->dn) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder ret = ENOMEM;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder goto done;
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu }
30f8dde07878b0968841ecc0bdbc76e217607131Christian Maeder
30f8dde07878b0968841ecc0bdbc76e217607131Christian Maeder ret = sysdb_transaction_start(domain->sysdb);
30f8dde07878b0968841ecc0bdbc76e217607131Christian Maeder if (ret != EOK) {
30f8dde07878b0968841ecc0bdbc76e217607131Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu goto done;
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu }
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu
b5dec828644f9f441c6d5dc38325ac6332b6eef7Christian Maeder if (!now) {
b5dec828644f9f441c6d5dc38325ac6332b6eef7Christian Maeder now = time(NULL);
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu }
f81290abfb65662280553519c85e6ff231a38554Mihai Codescu
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu in_transaction = true;
5c46e29755de01585aa7af9ea106e68ddfb012e2Mihai Codescu
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu /* Check for an existing gpo_guid entry */
30f8dde07878b0968841ecc0bdbc76e217607131Christian Maeder ret = sysdb_search_entry(tmp_ctx, domain->sysdb, update_msg->dn,
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu LDB_SCOPE_BASE, NULL, attrs, &count, &msgs);
d58b2e1dc7d2254fa2e10d8c0b5a498ac207d6eaChristian Maeder
30f8dde07878b0968841ecc0bdbc76e217607131Christian Maeder if (ret == ENOENT) {
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu /* Create new GPO */
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_TRACE_FUNC,
30f8dde07878b0968841ecc0bdbc76e217607131Christian Maeder "Adding new GPO [gpo_guid:%s][gpo_version:%d]\n",
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu gpo_guid, gpo_version);
d58b2e1dc7d2254fa2e10d8c0b5a498ac207d6eaChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder /* Add the objectClass */
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu lret = ldb_msg_add_empty(update_msg, SYSDB_OBJECTCLASS,
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu LDB_FLAG_MOD_ADD,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder NULL);
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu if (lret != LDB_SUCCESS) {
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu ret = sysdb_error_to_errno(lret);
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu goto done;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu lret = ldb_msg_add_string(update_msg, SYSDB_OBJECTCLASS,
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder SYSDB_GPO_OC);
f81290abfb65662280553519c85e6ff231a38554Mihai Codescu if (lret != LDB_SUCCESS) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder ret = sysdb_error_to_errno(lret);
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu goto done;
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu }
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu /* Add the GPO GUID */
d58b2e1dc7d2254fa2e10d8c0b5a498ac207d6eaChristian Maeder lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_GUID_ATTR,
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu LDB_FLAG_MOD_ADD,
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu NULL);
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu if (lret != LDB_SUCCESS) {
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu ret = sysdb_error_to_errno(lret);
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu goto done;
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu }
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu
d58b2e1dc7d2254fa2e10d8c0b5a498ac207d6eaChristian Maeder lret = ldb_msg_add_string(update_msg, SYSDB_GPO_GUID_ATTR, gpo_guid);
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu if (lret != LDB_SUCCESS) {
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu ret = sysdb_error_to_errno(lret);
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu goto done;
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu }
d58b2e1dc7d2254fa2e10d8c0b5a498ac207d6eaChristian Maeder
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu /* Add the Version */
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_VERSION_ATTR,
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu LDB_FLAG_MOD_ADD,
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu NULL);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (lret != LDB_SUCCESS) {
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu ret = sysdb_error_to_errno(lret);
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu goto done;
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu }
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu lret = ldb_msg_add_fmt(update_msg, SYSDB_GPO_VERSION_ATTR,
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu "%d", gpo_version);
d58b2e1dc7d2254fa2e10d8c0b5a498ac207d6eaChristian Maeder if (lret != LDB_SUCCESS) {
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu ret = sysdb_error_to_errno(lret);
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu goto done;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder /* Add the Policy File Timeout */
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_TIMEOUT_ATTR,
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu LDB_FLAG_MOD_ADD, NULL);
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu if (lret != LDB_SUCCESS) {
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu ret = sysdb_error_to_errno(lret);
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu goto done;
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu }
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu lret = ldb_msg_add_fmt(update_msg, SYSDB_GPO_TIMEOUT_ATTR, "%lu",
d58b2e1dc7d2254fa2e10d8c0b5a498ac207d6eaChristian Maeder ((cache_timeout) ? (now + cache_timeout) : 0));
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder if (lret != LDB_SUCCESS) {
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder ret = sysdb_error_to_errno(lret);
f81290abfb65662280553519c85e6ff231a38554Mihai Codescu goto done;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu lret = ldb_add(domain->sysdb->ldb, update_msg);
d58b2e1dc7d2254fa2e10d8c0b5a498ac207d6eaChristian Maeder if (lret != LDB_SUCCESS) {
d58b2e1dc7d2254fa2e10d8c0b5a498ac207d6eaChristian Maeder DEBUG(SSSDBG_MINOR_FAILURE,
30f8dde07878b0968841ecc0bdbc76e217607131Christian Maeder "Failed to add GPO: [%s]\n",
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu ldb_strerror(lret));
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu ret = sysdb_error_to_errno(lret);
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu goto done;
30f8dde07878b0968841ecc0bdbc76e217607131Christian Maeder }
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu } else if (ret == EOK && count == 1) {
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu /* Update the existing GPO */
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu
d58b2e1dc7d2254fa2e10d8c0b5a498ac207d6eaChristian Maeder DEBUG(SSSDBG_TRACE_ALL, "Updating new GPO [%s][%s]\n", domain->name, gpo_guid);
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder /* Add the Version */
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_VERSION_ATTR,
30f8dde07878b0968841ecc0bdbc76e217607131Christian Maeder LDB_FLAG_MOD_REPLACE,
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu NULL);
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu if (lret != LDB_SUCCESS) {
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu ret = sysdb_error_to_errno(lret);
fa3f374c7da443b372c2560cbb7262edd732aa4dMihai Codescu goto done;
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
2a5b885d9350ec6dd8bc4992ee91d2f68aa592f4Christian Maeder lret = ldb_msg_add_fmt(update_msg, SYSDB_GPO_VERSION_ATTR,
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu "%d", gpo_version);
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu if (lret != LDB_SUCCESS) {
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu ret = sysdb_error_to_errno(lret);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder goto done;
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu }
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu /* Add the Policy File Timeout */
0b06cf161496343f3320e45d228ad4bc2f1f2b0fMihai Codescu lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_TIMEOUT_ATTR,
5c46e29755de01585aa7af9ea106e68ddfb012e2Mihai Codescu LDB_FLAG_MOD_REPLACE, NULL);
5c46e29755de01585aa7af9ea106e68ddfb012e2Mihai Codescu if (lret != LDB_SUCCESS) {
d58b2e1dc7d2254fa2e10d8c0b5a498ac207d6eaChristian Maeder ret = sysdb_error_to_errno(lret);
b5dec828644f9f441c6d5dc38325ac6332b6eef7Christian Maeder goto done;
b5dec828644f9f441c6d5dc38325ac6332b6eef7Christian Maeder }
b5dec828644f9f441c6d5dc38325ac6332b6eef7Christian Maeder
d58b2e1dc7d2254fa2e10d8c0b5a498ac207d6eaChristian Maeder lret = ldb_msg_add_fmt(update_msg, SYSDB_GPO_TIMEOUT_ATTR, "%lu",
d58b2e1dc7d2254fa2e10d8c0b5a498ac207d6eaChristian Maeder ((cache_timeout) ? (now + cache_timeout) : 0));
9eb39c7a0e7a1ddad1eec1d23c6d4e3a99c54023Christian Maeder if (lret != LDB_SUCCESS) {
5c46e29755de01585aa7af9ea106e68ddfb012e2Mihai Codescu ret = sysdb_error_to_errno(lret);
goto done;
}
lret = ldb_modify(domain->sysdb->ldb, update_msg);
if (lret != LDB_SUCCESS) {
DEBUG(SSSDBG_MINOR_FAILURE,
"Failed to modify GPO: [%s](%d)[%s]\n",
ldb_strerror(lret), lret, ldb_errstring(domain->sysdb->ldb));
ret = sysdb_error_to_errno(lret);
goto done;
}
} else {
ret = EIO;
goto done;
}
ret = sysdb_transaction_commit(domain->sysdb);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Could not commit transaction: [%s]\n", strerror(ret));
goto done;
}
in_transaction = false;
done:
if (in_transaction) {
sret = sysdb_transaction_cancel(domain->sysdb);
if (sret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n");
}
}
talloc_free(tmp_ctx);
return ret;
}
errno_t
sysdb_gpo_get_gpo_by_guid(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *gpo_guid,
struct ldb_result **_result)
{
errno_t ret;
int lret;
struct ldb_dn *base_dn;
TALLOC_CTX *tmp_ctx;
struct ldb_result *res;
const char *attrs[] = SYSDB_GPO_ATTRS;
tmp_ctx = talloc_new(NULL);
if (!tmp_ctx) return ENOMEM;
DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO_BASE"\n", domain->name);
base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb,
SYSDB_TMPL_GPO_BASE,
domain->name);
if (!base_dn) {
ret = ENOMEM;
goto done;
}
lret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
LDB_SCOPE_SUBTREE, attrs, SYSDB_GPO_GUID_FILTER, gpo_guid);
if (lret) {
DEBUG(SSSDBG_MINOR_FAILURE,
"Could not locate GPO: [%s]\n",
ldb_strerror(lret));
ret = sysdb_error_to_errno(lret);
goto done;
}
if (res->count > 1) {
DEBUG(SSSDBG_CRIT_FAILURE, "Search for GUID [%s] returned more than " \
"one object.\n", gpo_guid);
ret = EINVAL;
goto done;
} else if (res->count == 0) {
ret = ENOENT;
goto done;
}
*_result = talloc_steal(mem_ctx, res);
ret = EOK;
done:
if (ret == ENOENT) {
DEBUG(SSSDBG_TRACE_ALL, "No such entry.\n");
} else if (ret) {
DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret));
}
talloc_free(tmp_ctx);
return ret;
}
errno_t
sysdb_gpo_get_gpos(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
struct ldb_result **_result)
{
errno_t ret;
int lret;
struct ldb_dn *base_dn;
TALLOC_CTX *tmp_ctx;
struct ldb_result *res;
const char *attrs[] = SYSDB_GPO_ATTRS;
tmp_ctx = talloc_new(NULL);
if (!tmp_ctx) return ENOMEM;
DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO_BASE"\n", domain->name);
base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb,
SYSDB_TMPL_GPO_BASE,
domain->name);
if (!base_dn) {
ret = ENOMEM;
goto done;
}
lret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
LDB_SCOPE_SUBTREE, attrs, SYSDB_GPO_FILTER);
if (lret) {
DEBUG(SSSDBG_MINOR_FAILURE,
"Could not locate GPOs: [%s]\n",
ldb_strerror(lret));
ret = sysdb_error_to_errno(lret);
goto done;
}
if (res->count == 0) {
ret = ENOENT;
goto done;
}
*_result = talloc_steal(mem_ctx, res);
ret = EOK;
done:
if (ret == ENOENT) {
DEBUG(SSSDBG_TRACE_ALL, "No GPO entries.\n");
} else if (ret) {
DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret));
}
talloc_free(tmp_ctx);
return ret;
}
/* GPO Result */
static struct ldb_dn *
sysdb_gpo_result_dn(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *result_name)
{
errno_t ret;
char *clean_result_name;
struct ldb_dn *dn;
ret = sysdb_dn_sanitize(NULL, result_name, &clean_result_name);
if (ret != EOK) {
return NULL;
}
DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO_RESULT"\n",
clean_result_name, domain->name);
dn = ldb_dn_new_fmt(mem_ctx, domain->sysdb->ldb, SYSDB_TMPL_GPO_RESULT,
clean_result_name, domain->name);
talloc_free(clean_result_name);
return dn;
}
errno_t
sysdb_gpo_store_gpo_result_setting(struct sss_domain_info *domain,
const char *ini_key,
const char *ini_value)
{
errno_t ret, sret;
int lret;
struct ldb_message *update_msg;
struct ldb_message **msgs;
size_t count;
bool in_transaction = false;
TALLOC_CTX *tmp_ctx;
tmp_ctx = talloc_new(NULL);
if (!tmp_ctx) return ENOMEM;
update_msg = ldb_msg_new(tmp_ctx);
if (!update_msg) {
ret = ENOMEM;
goto done;
}
update_msg->dn = sysdb_gpo_result_dn(update_msg, domain, "gpo_result");
if (!update_msg->dn) {
ret = ENOMEM;
goto done;
}
ret = sysdb_transaction_start(domain->sysdb);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
goto done;
}
in_transaction = true;
/* Check for an existing GPO Result object */
ret = sysdb_search_entry(tmp_ctx, domain->sysdb, update_msg->dn,
LDB_SCOPE_BASE, NULL, NULL, &count, &msgs);
if (ret == ENOENT) {
/* Create new GPO Result object */
DEBUG(SSSDBG_TRACE_FUNC, "Storing setting: key [%s] value [%s]\n",
ini_key, ini_value);
/* Add the objectClass */
lret = ldb_msg_add_empty(update_msg, SYSDB_OBJECTCLASS,
LDB_FLAG_MOD_ADD,
NULL);
if (lret != LDB_SUCCESS) {
ret = sysdb_error_to_errno(lret);
goto done;
}
lret = ldb_msg_add_string(update_msg, SYSDB_OBJECTCLASS,
SYSDB_GPO_RESULT_OC);
if (lret != LDB_SUCCESS) {
ret = sysdb_error_to_errno(lret);
goto done;
}
/* Store the policy_setting if it is non-NULL */
if (ini_value) {
lret = ldb_msg_add_empty(update_msg, ini_key,
LDB_FLAG_MOD_ADD,
NULL);
if (lret != LDB_SUCCESS) {
ret = sysdb_error_to_errno(lret);
goto done;
}
lret = ldb_msg_add_string(update_msg, ini_key, ini_value);
if (lret != LDB_SUCCESS) {
ret = sysdb_error_to_errno(lret);
goto done;
}
}
lret = ldb_add(domain->sysdb->ldb, update_msg);
if (lret != LDB_SUCCESS) {
DEBUG(SSSDBG_MINOR_FAILURE,
"Failed to add GPO Result: [%s]\n",
ldb_strerror(lret));
ret = sysdb_error_to_errno(lret);
goto done;
}
} else if (ret == EOK && count == 1) {
/* Update existing GPO Result object*/
if (ini_value) {
DEBUG(SSSDBG_TRACE_FUNC, "Updating setting: key [%s] value [%s]\n",
ini_key, ini_value);
/* Update the policy setting */
lret = ldb_msg_add_empty(update_msg, ini_key,
LDB_FLAG_MOD_REPLACE,
NULL);
if (lret != LDB_SUCCESS) {
ret = sysdb_error_to_errno(lret);
goto done;
}
lret = ldb_msg_add_fmt(update_msg, ini_key, "%s", ini_value);
if (lret != LDB_SUCCESS) {
ret = sysdb_error_to_errno(lret);
goto done;
}
} else {
/* If the value is NULL, we need to remove it from the cache */
DEBUG(SSSDBG_TRACE_FUNC, "Removing setting: key [%s]\n", ini_key);
/* Update the policy setting */
lret = ldb_msg_add_empty(update_msg, ini_key,
LDB_FLAG_MOD_DELETE,
NULL);
if (lret != LDB_SUCCESS) {
ret = sysdb_error_to_errno(lret);
goto done;
}
}
lret = ldb_modify(domain->sysdb->ldb, update_msg);
if (lret != LDB_SUCCESS) {
DEBUG(SSSDBG_MINOR_FAILURE,
"Failed to modify GPO Result: [%s](%d)[%s]\n",
ldb_strerror(lret), lret, ldb_errstring(domain->sysdb->ldb));
ret = sysdb_error_to_errno(lret);
goto done;
}
} else {
ret = EIO;
goto done;
}
ret = sysdb_transaction_commit(domain->sysdb);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Could not commit transaction: [%s]\n", strerror(ret));
goto done;
}
in_transaction = false;
done:
if (in_transaction) {
sret = sysdb_transaction_cancel(domain->sysdb);
if (sret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n");
}
}
talloc_free(tmp_ctx);
return ret;
}
static errno_t
sysdb_gpo_get_gpo_result_object(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char **attrs,
struct ldb_result **_result)
{
errno_t ret;
int lret;
struct ldb_dn *base_dn;
TALLOC_CTX *tmp_ctx;
struct ldb_result *res;
tmp_ctx = talloc_new(NULL);
if (!tmp_ctx) return ENOMEM;
DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO_RESULT_BASE"\n", domain->name);
base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb,
SYSDB_TMPL_GPO_RESULT_BASE,
domain->name);
if (!base_dn) {
ret = ENOMEM;
goto done;
}
lret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
LDB_SCOPE_SUBTREE, attrs, SYSDB_GPO_RESULT_FILTER);
if (lret) {
DEBUG(SSSDBG_MINOR_FAILURE,
"Could not locate GPO Result object: [%s]\n",
ldb_strerror(lret));
ret = sysdb_error_to_errno(lret);
goto done;
}
if (res->count == 0) {
ret = ENOENT;
goto done;
}
*_result = talloc_steal(mem_ctx, res);
ret = EOK;
done:
if (ret == ENOENT) {
DEBUG(SSSDBG_TRACE_ALL, "No GPO Result object.\n");
} else if (ret) {
DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret));
}
talloc_free(tmp_ctx);
return ret;
}
errno_t
sysdb_gpo_get_gpo_result_setting(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *ini_key,
const char **_ini_value)
{
errno_t ret;
TALLOC_CTX *tmp_ctx;
struct ldb_result *res;
const char *ini_value;
const char *attrs[] = {ini_key, NULL};
tmp_ctx = talloc_new(NULL);
if (!tmp_ctx) return ENOMEM;
ret = sysdb_gpo_get_gpo_result_object(tmp_ctx, domain, attrs, &res);
if (ret != EOK) {
goto done;
}
ini_value = ldb_msg_find_attr_as_string(res->msgs[0],
ini_key,
NULL);
DEBUG(SSSDBG_TRACE_FUNC, "key [%s] value [%s]\n", ini_key, ini_value);
*_ini_value = talloc_strdup(mem_ctx, ini_value);
if (!*_ini_value && ini_value) {
/* If ini_value was NULL, this is expected to also be NULL */
ret = ENOMEM;
goto done;
}
ret = EOK;
done:
if (ret == ENOENT) {
DEBUG(SSSDBG_TRACE_ALL, "No setting for key [%s].\n", ini_key);
} else if (ret) {
DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret));
}
talloc_free(tmp_ctx);
return ret;
}
errno_t sysdb_gpo_delete_gpo_result_object(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain)
{
struct ldb_result *res;
errno_t ret, sret;
bool in_transaction = false;
ret = sysdb_transaction_start(domain->sysdb);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
goto done;
}
in_transaction = true;
ret = sysdb_gpo_get_gpo_result_object(mem_ctx, domain, NULL, &res);
if (ret != EOK && ret != ENOENT) {
DEBUG(SSSDBG_OP_FAILURE,
"Could not delete GPO result object: %d\n", ret);
goto done;
} else if (ret != ENOENT) {
DEBUG(SSSDBG_TRACE_FUNC, "Deleting GPO Result object\n");
ret = sysdb_delete_entry(domain->sysdb, res->msgs[0]->dn, true);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE,
"Could not delete GPO Result cache entry\n");
goto done;
}
}
ret = sysdb_transaction_commit(domain->sysdb);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Could not commit transaction: [%s]\n", strerror(ret));
goto done;
}
in_transaction = false;
done:
if (in_transaction) {
sret = sysdb_transaction_cancel(domain->sysdb);
if (sret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n");
}
}
return ret;
}