usertools.c revision c7d387aaaa3d3470dec55a5ca0612873e6354ba8
/*
SSSD
User tools
Copyright (C) Stephen Gallagher <sgallagh@redhat.com> 2009
This program is free software; you can redistribute it and/or modify
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 <pwd.h>
#include <pcre.h>
#include <errno.h>
#include <talloc.h>
#include "confdb/confdb.h"
#include "util/util.h"
#ifdef HAVE_LIBPCRE_LESSER_THAN_7
#define NAME_DOMAIN_PATTERN_OPTIONS (PCRE_EXTENDED)
#else
#define NAME_DOMAIN_PATTERN_OPTIONS (PCRE_DUPNAMES | PCRE_EXTENDED)
#endif
char *get_username_from_uid(TALLOC_CTX *mem_ctx, uid_t uid)
{
char *username;
struct passwd *pwd;
pwd = getpwuid(uid);
if (!pwd) return NULL;
username = talloc_strdup(mem_ctx, pwd->pw_name);
return username;
}
static int sss_names_ctx_destructor(struct sss_names_ctx *snctx)
{
if (snctx->re) {
pcre_free(snctx->re);
snctx->re = NULL;
}
return 0;
}
int sss_names_init(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, struct sss_names_ctx **out)
{
struct sss_names_ctx *ctx;
const char *errstr;
int errval;
int errpos;
int ret;
ctx = talloc_zero(mem_ctx, struct sss_names_ctx);
if (!ctx) return ENOMEM;
talloc_set_destructor(ctx, sss_names_ctx_destructor);
ret = confdb_get_string(cdb, ctx, CONFDB_MONITOR_CONF_ENTRY,
CONFDB_MONITOR_NAME_REGEX, NULL, &ctx->re_pattern);
if (ret != EOK) goto done;
if (!ctx->re_pattern) {
ctx->re_pattern = talloc_strdup(ctx,
"(?P<name>[^@]+)@?(?P<domain>[^@]*$)");
if (!ctx->re_pattern) {
ret = ENOMEM;
goto done;
}
#ifdef HAVE_LIBPCRE_LESSER_THAN_7
} else {
DEBUG(2, ("This binary was build with a version of libpcre that does "
"not support non-unique named subpatterns.\n"));
DEBUG(2, ("Please make sure that your pattern [%s] only contains "
"subpatterns with a unique name and uses "
"the Python syntax (?P<name>).\n", ctx->re_pattern));
#endif
}
ret = confdb_get_string(cdb, ctx, CONFDB_MONITOR_CONF_ENTRY,
CONFDB_MONITOR_FULL_NAME_FORMAT, NULL, &ctx->fq_fmt);
if (ret != EOK) goto done;
if (!ctx->fq_fmt) {
ctx->fq_fmt = talloc_strdup(ctx, "%1$s@%2$s");
if (!ctx->fq_fmt) {
ret = ENOMEM;
goto done;
}
}
ctx->re = pcre_compile2(ctx->re_pattern,
NAME_DOMAIN_PATTERN_OPTIONS,
&errval, &errstr, &errpos, NULL);
if (!ctx->re) {
DEBUG(1, ("Invalid Regular Expression pattern at position %d."
" (Error: %d [%s])\n", errpos, errval, errstr));
ret = EFAULT;
goto done;
}
*out = ctx;
ret = EOK;
done:
if (ret != EOK) {
talloc_free(ctx);
}
return ret;
}
int sss_parse_name(TALLOC_CTX *memctx,
struct sss_names_ctx *snctx,
const char *orig, char **domain, char **name)
{
pcre *re = snctx->re;
const char *result;
int ovec[30];
int origlen;
int ret, strnum;
origlen = strlen(orig);
ret = pcre_exec(re, NULL, orig, origlen, 0, PCRE_NOTEMPTY, ovec, 30);
if (ret < 0) {
DEBUG(2, ("PCRE Matching error, %d\n", ret));
return EINVAL;
}
if (ret == 0) {
DEBUG(1, ("Too many matches, the pattern is invalid.\n"));
}
strnum = ret;
result = NULL;
ret = pcre_get_named_substring(re, orig, ovec, strnum, "name", &result);
if (ret < 0 || !result) {
DEBUG(2, ("Name not found!\n"));
return EINVAL;
}
*name = talloc_strdup(memctx, result);
pcre_free_substring(result);
if (!*name) return ENOMEM;
result = NULL;
ret = pcre_get_named_substring(re, orig, ovec, strnum, "domain", &result);
if (ret < 0 || !result) {
DEBUG(4, ("Domain not provided!\n"));
*domain = NULL;
} else {
/* ignore "" string */
if (*result) {
*domain = talloc_strdup(memctx, result);
pcre_free_substring(result);
if (!*domain) return ENOMEM;
} else {
pcre_free_substring(result);
*domain = NULL;
}
}
return EOK;
}
char *
sss_get_cased_name(TALLOC_CTX *mem_ctx,
const char *orig_name,
bool case_sensitive)
{
return case_sensitive ? talloc_strdup(mem_ctx, orig_name) :
sss_tc_utf8_str_tolower(mem_ctx, orig_name);
}