/*
SSSD
Authors:
Fabiano FidĂȘncio <fidencio@redhat.com>
Copyright (C) 2017 Red Hat
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "providers/ipa/ipa_deskprofile_rules_util.h"
#include "providers/ipa/ipa_deskprofile_private.h"
#include "providers/ipa/ipa_rules_common.h"
#include <ctype.h>
#include <fcntl.h>
enum deskprofile_name {
RULES_DIR = 0,
USER,
HOST,
};
/*
* The rule's filename has to follow a global policy, used by FleetCommander
* client that shows how the profile should be applied.
*
* This global policy is represented by an integer from 1 to 24 (inclusive) and
* has the following meaning:
* 1 = user, group, host, hostgroup
* 2 = user, group, hostgroup, host
* 3 = user, host, group, hostgroup
* 4 = user, host, hostgroup, group
* 5 = user, hostgroup, group, host
* 6 = user, hostgroup, host, group
* 7 = group, user, host, hostgroup
* 8 = group, user, hostgroup, host
* 9 = group, host, user, hostgroup
* 10 = group, host, hostgroup, user
* 11 = group, hostgroup, user, host
* 12 = group, hostgroup, host, user
* 13 = host, user, group, hostgroup
* 14 = host, user, hostgroup, group
* 15 = host, group, user, hostgroup
* 16 = host, group, hostgroup, user
* 17 = host, hostgroup, user, group
* 18 = host, hostgroup, group, user
* 19 = hostgroup, user, group, host
* 20 = hostgroup, user, host, group
* 21 = hostgroup, group, user, host
* 22 = hostgroup, group, host, user
* 23 = hostgroup, host, user, group
* 24 = hostgroup, host, group, user
*
* Having the table above in mind and considering the following example:
* - rule name: testrule
* - policy: 22
* - priority: 420
* - client's machine matches: host and group
*
* So, the filename will be: "000420_000000_000420_000420_000000_testrule.json"
*
* The function below not only helps us to create this filename in the correct
* format, but also create the whole path for this rule's file.
*
* An example of the full path would be:
* "/var/lib/sss/deskprofile/ipa.example/user_foobar/000420_000000_000420_000420_000000_testrule.json"
* | RULES DIR | DOMAIN | USERNAME | | |GROUP | HOST | USER | |
* PRIORITY RULE NAME
* HOSTGROUP EXTENSION
*
* - deskprofile_name enum;
* - permuts's matrix;
* - vals array;
*/
static errno_t
const char *rules_dir,
const char *domain,
const char *username,
const char *priority,
const char *user_priority,
const char *group_priority,
const char *host_priority,
const char *hostgroup_priority,
const char *rule_name,
const char *extension,
char **_filename_path)
{
};
const char *vals[] = {
NULL,
};
char *result;
return ENOMEM;
}
"The configuration priority has an invalid value: %d!\n",
goto done;
}
goto done;
}
for (int i = 0; i < DESKPROFILE_NAME_SENTINEL; i++) {
switch(perms[i]) {
case RULES_DIR:
case DOMAIN:
case USERNAME:
break;
case PRIORITY:
case USER:
case GROUP:
case HOST:
case HOSTGROUP:
break;
case RULE_NAME:
break;
case EXTENSION:
break;
default:
"This situation should never happen\n");
goto done;
}
goto done;
}
}
done:
return ret;
}
const char *username, /* fully-qualified */
{
char *shortname;
char *domain;
char *domain_dir;
return ENOMEM;
}
"sss_parse_internal_fqname() failed [%d]: %s\n",
goto done;
}
"Failed to create the directory \"%s/%s\" that would be used to "
"store the Desktop Profile rules users' directory [%d]: %s\n",
goto done;
}
domain);
if (domain_dir == NULL) {
goto done;
}
/* In order to read, create and traverse the directory, we need to have its
* permissions set as 'rwx------' (700). */
"Failed to create the directory \"%s/%s/%s\" that would be used "
"to store the Desktop Profile rules for the user \"%s\" [%d]: "
"%s\n",
goto done;
}
done:
return ret;
}
static errno_t
const char *name,
char **_rule_name)
{
buffer_len = 0;
char character;
bool replace;
replace = false;
char next_character;
continue;
}
replace = true;
}
buffer_len++;
}
if (*_rule_name == NULL) {
return ENOMEM;
}
return EOK;
}
static errno_t
struct sss_domain_info *domain,
struct sysdb_attrs *rule,
const char *rule_name,
const char *rule_prio,
const char *base_dn,
const char *username, /* fully-qualified */
char **_user_prio,
char **_group_prio)
{
char *shortname;
char *domainname;
char *data;
char *memberuser;
char *membergroup;
char *user_prio;
char *group_prio;
bool user = false;
bool group = false;
return ENOMEM;
}
&shortname, &domainname);
"sss_parse_internal_fqname() failed [%d]: %s\n",
goto done;
}
"sysdb_initgroups() failed [%d]: %s\n",
goto done;
}
/* This really should NOT happen at this point */
"User [%s] not found in cache\n", username);
goto done;
}
goto done;
}
num_groups = 0;
/* Start counting from 1 to exclude the user entry */
NULL);
if (fqgroupname == NULL) {
"Skipping malformed entry [%s]\n",
continue;
}
"Malformed name %s, skipping!\n", fqgroupname);
continue;
}
num_groups++;
}
"Failed to get the Desktop Profile Rule memberUser for rule "
"\"%s\" [%d]: %s\n",
goto done;
}
if (memberuser == NULL) {
goto done;
}
break;
}
"Desktop Profile rule \"%s\" matches with the user \"%s\" "
"for the \"%s\" domain!\n",
user = true;
continue;
}
"cn=%s,cn=groups,cn=accounts,%s",
if (membergroup == NULL) {
"Failed to allocate membergroup\n");
goto done;
}
"Desktop Profile rule \"%s\" matches with (at least) "
"the group \"%s\" for the \"%s\" domain!\n",
group = true;
}
}
}
}
goto done;
}
if (group_prio == NULL) {
goto done;
}
done:
return ret;
}
static errno_t
struct sss_domain_info *domain,
struct sysdb_attrs *rule,
const char *rule_name,
const char *rule_prio,
const char *base_dn,
const char *hostname,
char **_host_prio,
char **_hostgroup_prio)
{
char *data;
char *memberhost;
char *memberhostgroup;
char *name;
char *host_prio;
char *hostgroup_prio;
bool host = false;
bool hostgroup = false;
return ENOMEM;
}
goto done;
}
memberhostgroups[0] = NULL;
goto done;
} else if (count > 1) {
"More than one result for a BASE search!\n");
goto done;
} else { /* ret == EOK && count == 1 */
char *,
}
if (el_orig_memberof != NULL) {
num_memberhostgroup = 0;
&name);
/* ERR_UNEXPECTED_ENTRY_TYPE means we had a memberOf entry that
* wasn't a host group, thus we'll just ignore those.
*/
"Skipping malformed entry [%s]\n",
data);
continue;
}
}
}
"Failed to get the Desktop Profile Rule memberHost for rule "
"\"%s\" [%d]: %s\n",
goto done;
}
if (memberhost == NULL) {
goto done;
}
break;
}
host = true;
"Desktop Profile rule \"%s\" matches with the host \"%s\" "
"for the \"%s\" domain!\n",
continue;
}
"cn=%s,cn=hostgroups,cn=accounts,%s",
memberhostgroups[j], base_dn);
if (memberhostgroup == NULL) {
"Failed to allocate memberhostgroup\n");
goto done;
}
hostgroup = true;
"Desktop Profile rule \"%s\" matches with (at least) "
"the hostgroup \"%s\" for the \"%s\" domain!\n",
continue;
}
}
}
}
goto done;
}
if (hostgroup_prio == NULL) {
goto done;
}
done:
return ret;
}
struct sysdb_attrs *rule,
struct sss_domain_info *domain,
const char *hostname,
const char *username, /* fully-qualified */
{
const char *rule_name;
const char *data;
const char *hostcat;
const char *usercat;
char *shortname;
char *domainname;
char *base_dn;
char *rule_prio;
char *user_prio;
char *group_prio;
char *host_prio;
char *hostgroup_prio;
return ENOMEM;
}
"Failed to get the Desktop Profile Rule name [%d]: %s\n",
goto done;
}
"Failed to get the Desktop Profile Rule priority for rule "
"\"%s\" [%d]: %s\n",
goto done;
}
"Failed to get the Desktop Profile Rule host category for rule "
"\"%s\" [%d]: %s\n",
goto done;
}
"Failed to get the Desktop Profile Rule user category for rule "
"\"%s\" [%d]: %s\n",
goto done;
}
goto done;
}
"Failed to get the Desktop Profile Rule data for rule \"%s\" "
"[%d]: %s\n",
goto done;
}
"sss_parse_internal_fqname() failed [%d]: %s\n",
goto done;
}
goto done;
}
"Failed to allocate the user priority "
"when user category is \"all\"\n");
goto done;
}
if (group_prio == NULL) {
"Failed to allocate the group priority "
"when user category is \"all\"\n");
goto done;
}
} else {
&user_prio, &group_prio);
"ipa_deskprofile_rule_check_memberuser() failed [%d]: %s\n",
goto done;
}
}
"Failed to allocate the host priority "
"when host category is \"all\"\n");
goto done;
}
if (hostgroup_prio == NULL) {
"Failed to allocate the hostgroup priority "
"when host category is \"all\"\n");
goto done;
}
} else {
&host_prio, &hostgroup_prio);
"ipa_deskprofile_rule_check_memberhost() failed [%d]: %s\n",
goto done;
}
}
"ipa_deskprofile_get_normalized_rule_name() failed [%d]: %s\n",
goto done;
}
"ipa_deskprofile_get_filename_path() failed [%d]: %s\n",
goto done;
}
if (ret == -1) {
"process [%d]: %s\n",
goto done;
}
if (ret == -1) {
"process [%d]: %s\n",
goto done;
}
if (fd == -1) {
"Failed to create the Desktop Profile rule file \"%s\" "
"[%d]: %s\n",
goto done;
}
if (ret < 0) {
"Failed to write the content of the Desktop Profile rule for "
"the \"%s\" file.\n",
goto done;
}
if (ret == -1) {
"process [%d]: %s\n",
goto done;
}
if (ret == -1) {
"process [%d]: %s\n",
goto done;
}
done:
if (fd != -1) {
}
if (ret == -1) {
"domain's process [%d]: %s\n",
"Sending SIGUSR2 to the process: %d\n", getpid());
}
}
if (ret == -1) {
"domain's process. Let's have the process restartd!\n",
orig_gid);
"Sending SIGUSR2 to the process: %d\n", getpid());
}
}
return ret;
}
{
if (ret == -1) {
"process [%d]: %s\n",
goto done;
}
if (ret == -1) {
"process [%d]: %s\n",
goto done;
}
"Cannot remove \"%s\" directory [%d]: %s\n",
goto done;
}
if (ret == -1) {
"process [%d]: %s\n",
goto done;
}
if (ret == -1) {
"process [%d]: %s\n",
goto done;
}
"Cannot remove \"%s\" directory [%d]: %s\n",
goto done;
}
done:
if (ret == -1) {
"domain's process [%d]: %s\n",
"Sending SIGUSR2 to the process: %d\n", getpid());
}
}
if (ret == -1) {
"domain's process [%d]: %s\n",
"Sending SIGUSR2 to the process: %d\n", getpid());
}
}
return ret;
}
{
return ENOMEM;
}
"sysdb_search_custom_by_name() failed [%d]: %s\n",
goto done;
}
if (resp_count != 1) {
"sysdb_search_custom_by_name() got more attributes than "
"expected. Expected (1), got (%zu)\n", resp_count);
goto done;
}
0);
done:
return ret;
}
const char **
{
goto done;
}
attrs[0] = OBJECTCLASS;
done:
return attrs;
}