/*
SSSD
Authors:
Stephen Gallagher <sgallagh@redhat.com>
Copyright (C) 2010 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 "config.h"
#include "util/sss_format.h"
#include "util/strtonum.h"
/* =Getpwnam-wrapper======================================================*/
const char *alias);
static int
static int
struct sss_domain_info *dom,
const char *i_name)
{
char *buffer;
int ret;
bool del_user;
char *shortname_or_alias;
if (!tmpctx) {
return ENOMEM;
}
goto done;
}
if (!pwd) {
goto done;
}
if (!buffer) {
goto done;
}
/* FIXME: should we move this call outside the transaction to keep the
* transaction as short as possible ? */
if (ret) {
goto done;
}
if (del_user) {
goto done;
}
/* Canonicalize the username in case it was actually an alias */
if (ctx->fast_alias == true) {
/* Non-fatal, attempt to canonicalize online */
}
SYSDB_NAME, NULL);
if (!real_name) {
}
}
}
if (ret) {
goto done;
}
goto done;
}
}
if (del_user) {
goto done;
}
/* Both lookups went fine, we can save the user now */
done:
if (ret) {
"proxy -> getpwnam_r failed for '%s' <%d>: %s\n",
}
return ret;
}
static int
{
if (!del_user) {
return EINVAL;
}
*del_user = false;
switch (status) {
case NSS_STATUS_NOTFOUND:
*del_user = true;
break;
case NSS_STATUS_SUCCESS:
/* uid=0 or gid=0 are invalid values */
/* also check that the id is in the valid range for this domain */
"User filtered out! (id out of range)\n");
*del_user = true;
break;
}
break;
case NSS_STATUS_UNAVAIL:
"Remote back end is not available. Entering offline mode\n");
break;
default:
break;
}
return ret;
}
static int
{
"User %s does not exist (or is invalid) on remote server,"
" deleting!\n", name);
}
return ret;
}
static int
bool case_sensitive,
const char *real_name, /* already_qualified */
const char *alias, /* already qualified */
struct sysdb_attrs **attrs)
{
goto done;
}
}
}
if (!case_sensitive) {
goto done;
}
goto done;
}
}
if (cased_alias == NULL) {
goto done;
}
/* Add the alias only if it differs from lowercased pw_name */
goto done;
}
}
}
done:
return ret;
}
const char *real_name, /* already qualified */
const char *alias) /* already qualified */
{
const char *shell;
const char *gecos;
} else {
}
} else {
}
goto done;
}
NULL,
NULL,
0);
if (ret) {
goto done;
}
done:
return ret;
}
/* =Getpwuid-wrapper======================================================*/
struct sss_domain_info *dom,
{
char *buffer;
bool del_user = false;
int ret;
char *name;
if (!tmpctx) {
return ENOMEM;
}
if (!pwd) {
goto done;
}
if (!buffer) {
goto done;
}
if (ret) {
goto done;
}
if (del_user) {
goto done;
}
goto done;
}
done:
if (ret) {
}
return ret;
}
/* =Getpwent-wrapper======================================================*/
struct proxy_id_ctx *ctx,
struct sss_domain_info *dom)
{
bool in_transaction = false;
char *buffer;
char *newbuf;
int ret;
bool again;
char *name;
if (!tmpctx) {
return ENOMEM;
}
if (!pwd) {
goto done;
}
if (!buffer) {
goto done;
}
if (ret) {
goto done;
}
in_transaction = true;
if (status != NSS_STATUS_SUCCESS) {
goto done;
}
do {
again = false;
/* always zero out the pwd structure */
/* get entry */
switch (status) {
case NSS_STATUS_TRYAGAIN:
/* buffer too small ? */
if (buflen < MAX_BUF_SIZE) {
buflen *= 2;
}
if (buflen > MAX_BUF_SIZE) {
}
if (!newbuf) {
goto done;
}
again = true;
break;
case NSS_STATUS_NOTFOUND:
/* we are done here */
goto done;
}
in_transaction = false;
break;
case NSS_STATUS_SUCCESS:
/* uid=0 or gid=0 are invalid values */
/* also check that the id is in the valid range for this domain
*/
again = true;
break;
}
"failed to create internal name '%s'\n",
goto done;
}
if (ret) {
/* Do not fail completely on errors.
* Just report the failure to save and go on */
}
again = true;
break;
case NSS_STATUS_UNAVAIL:
/* "remote" backend unavailable. Enter offline mode */
break;
default:
break;
}
} while (again);
done:
if (in_transaction) {
}
}
return ret;
}
/* =Save-group-utilities=================================================*/
do { \
if (DEBUG_IS_SET(level)) { \
} else { \
int i = 0; \
/* count */ \
i++; \
} \
} \
} \
} while(0)
struct sss_domain_info *domain,
struct sysdb_attrs *group_attrs,
const char *const*fq_gr_mem,
const char *real_name, /* already qualified */
const char *alias) /* already qualified */
{
bool in_transaction = false;
char **fq_gr_mem;
if (!tmp_ctx) {
return ENOMEM;
}
goto done;
}
in_transaction = true;
if (!attrs) {
goto done;
}
goto done;
}
(const char *const *) fq_gr_mem);
if (ret) {
goto done;
}
/* Create ghost users */
goto done;
}
}
goto done;
}
now);
if (ret) {
goto done;
}
"Could not commit transaction: [%s]\n",
goto done;
}
in_transaction = false;
done:
if (in_transaction) {
}
}
return ret;
}
struct sss_domain_info *domain,
struct sysdb_attrs *group_attrs,
const char *const*fq_gr_mem,
{
size_t i;
for (i = 0; fq_gr_mem[i]; i++) {
/* Member already exists in the cache */
"Member [%s] already cached\n", fq_gr_mem[i]);
/* clean up */
continue;
/* No entry for this user. Create a ghost user */
"Member [%s] not cached, creating ghost user entry\n",
fq_gr_mem[i]);
"Cannot store ghost user entry: [%d]: %s\n",
goto done;
}
} else {
/* Unexpected error */
"Error searching cache for user [%s]: [%s]\n",
goto done;
}
}
done:
return ret;
}
/* =Getgrnam-wrapper======================================================*/
static char *
{
char *newbuf;
if (*buflen == 0) {
}
if (*buflen < MAX_BUF_SIZE) {
*buflen *= 2;
}
if (*buflen > MAX_BUF_SIZE) {
*buflen = MAX_BUF_SIZE;
}
if (!newbuf) {
return NULL;
}
return *buffer;
}
static errno_t
struct sss_domain_info *dom,
bool *delete_group)
{
switch (status) {
case NSS_STATUS_TRYAGAIN:
return EAGAIN;
case NSS_STATUS_NOTFOUND:
*delete_group = true;
break;
case NSS_STATUS_SUCCESS:
/* gid=0 is an invalid value */
/* also check that the id is in the valid range for this domain */
"Group filtered out! (id out of range)\n");
*delete_group = true;
break;
}
break;
case NSS_STATUS_UNAVAIL:
"Remote back end is not available. Entering offline mode\n");
return ENXIO;
default:
return EIO;
}
return EOK;
}
struct sss_domain_info *dom,
const char *i_name)
{
char *buffer = 0;
bool delete_group = false;
int ret;
char *shortname_or_alias;
if (!tmpctx) {
return ENOMEM;
}
goto done;
}
if (!grp) {
"proxy -> getgrnam_r failed for '%s': [%d] %s\n",
goto done;
}
do {
/* always zero out the grp structure */
if (!buffer) {
goto done;
}
goto done;
}
if (delete_group) {
"Group %s does not exist (or is invalid) on remote server,"
" deleting!\n", i_name);
}
goto done;
}
/* Canonicalize the group name in case it was actually an alias */
if (ctx->fast_alias == true) {
/* Non-fatal, attempt to canonicalize online */
}
SYSDB_NAME, NULL);
if (!real_name) {
}
}
}
buflen = 0;
do {
if (!buffer) {
goto done;
}
goto done;
}
goto done;
}
}
if (delete_group) {
"Group %s does not exist (or is invalid) on remote server,"
" deleting!\n", i_name);
}
goto done;
}
if (ret) {
goto done;
}
done:
if (ret) {
"proxy -> getgrnam_r failed for '%s' <%d>: %s\n",
}
return ret;
}
/* =Getgrgid-wrapper======================================================*/
struct proxy_id_ctx *ctx,
struct sss_domain_info *dom,
{
bool delete_group = false;
int ret;
char *name;
if (!tmpctx) {
return ENOMEM;
}
if (!grp) {
goto done;
}
do {
/* always zero out the grp structure */
if (!buffer) {
goto done;
}
goto done;
}
if (delete_group) {
"server, deleting!\n", gid);
}
goto done;
}
goto done;
}
if (ret) {
goto done;
}
done:
if (ret) {
}
return ret;
}
/* =Getgrent-wrapper======================================================*/
struct proxy_id_ctx *ctx,
struct sss_domain_info *dom)
{
bool in_transaction = false;
char *buffer;
char *newbuf;
int ret;
bool again;
char *name;
if (!tmpctx) {
return ENOMEM;
}
if (!grp) {
goto done;
}
if (!buffer) {
goto done;
}
if (ret) {
goto done;
}
in_transaction = true;
if (status != NSS_STATUS_SUCCESS) {
goto done;
}
do {
again = false;
/* always zero out the grp structure */
/* get entry */
switch (status) {
case NSS_STATUS_TRYAGAIN:
/* buffer too small ? */
if (buflen < MAX_BUF_SIZE) {
buflen *= 2;
}
if (buflen > MAX_BUF_SIZE) {
}
if (!newbuf) {
goto done;
}
again = true;
break;
case NSS_STATUS_NOTFOUND:
/* we are done here */
goto done;
}
in_transaction = false;
break;
case NSS_STATUS_SUCCESS:
/* gid=0 is an invalid value */
/* also check that the id is in the valid range for this domain
*/
again = true;
break;
}
"Ignoring\n");
}
if (ret) {
/* Do not fail completely on errors.
* Just report the failure to save and go on */
"Ignoring\n");
}
again = true;
break;
case NSS_STATUS_UNAVAIL:
/* "remote" backend unavailable. Enter offline mode */
break;
default:
break;
}
} while (again);
done:
if (in_transaction) {
}
}
return ret;
}
/* =Initgroups-wrapper====================================================*/
struct proxy_id_ctx *ctx,
struct sss_domain_info *dom,
struct proxy_id_ctx *ctx,
struct sss_domain_info *dom,
const char *i_name)
{
bool in_transaction = false;
char *buffer;
int ret;
bool del_user;
char *shortname_or_alias;
if (!tmpctx) {
return ENOMEM;
}
goto done;
}
if (!pwd) {
goto fail;
}
if (!buffer) {
goto fail;
}
if (ret) {
goto fail;
}
in_transaction = true;
/* FIXME: should we move this call outside the transaction to keep the
* transaction as short as possible ? */
if (ret) {
goto fail;
}
if (del_user) {
if (ret) {
goto fail;
}
goto done;
}
/* Canonicalize the username in case it was actually an alias */
if (ctx->fast_alias == true) {
/* Non-fatal, attempt to canonicalize online */
}
SYSDB_NAME, NULL);
if (!real_name) {
}
}
}
if (ret) {
goto done;
}
goto done;
}
}
if (del_user) {
if (ret) {
goto fail;
}
goto done;
}
if (ret) {
goto fail;
}
goto fail;
}
done:
if (ret) {
goto fail;
}
in_transaction = false;
fail:
if (in_transaction) {
}
}
return ret;
}
struct proxy_id_ctx *ctx,
struct sss_domain_info *dom,
{
long int limit;
long int size;
long int num;
long int num_gids;
int ret;
int i;
num_gids = 0;
limit = 4096;
num = 4096;
if (!gids) {
return ENOMEM;
}
/* nss modules may skip the primary group when we pass it in so always add
* it in advance */
num_gids++;
/* FIXME: should we move this call outside the transaction to keep the
* transaction as short as possible ? */
do {
if (status == NSS_STATUS_TRYAGAIN) {
/* buffer too small ? */
if (size < MAX_BUF_SIZE) {
num *= 2;
}
if (size > MAX_BUF_SIZE) {
size = MAX_BUF_SIZE;
}
if (!gids) {
return ENOMEM;
}
}
} while(status == NSS_STATUS_TRYAGAIN);
switch (status) {
case NSS_STATUS_NOTFOUND:
"Assume the user is only member of its "
/* fall through */
case NSS_STATUS_SUCCESS:
for (i = 0; i < num_gids; i++) {
if (ret) {
return ret;
}
}
break;
default:
break;
}
return ret;
}
/* =Proxy_Id-Functions====================================================*/
static struct dp_reply_std
struct proxy_id_ctx *ctx,
struct dp_id_data *data,
struct sss_domain_info *domain)
{
char *endptr;
/* For now we support only core attrs. */
return reply;
}
/* Proxy provider does not support security ID lookups. */
"Security lookups are not supported");
return reply;
}
case BE_REQ_USER: /* user */
switch (data->filter_type) {
case BE_FILTER_ENUM:
break;
case BE_FILTER_NAME:
break;
case BE_FILTER_IDNUM:
"Invalid attr type");
return reply;
}
break;
default:
"Invalid filter type");
return reply;
}
break;
case BE_REQ_GROUP: /* group */
switch (data->filter_type) {
case BE_FILTER_ENUM:
break;
case BE_FILTER_NAME:
break;
case BE_FILTER_IDNUM:
"Invalid attr type");
return reply;
}
break;
default:
"Invalid filter type");
return reply;
}
break;
case BE_REQ_INITGROUPS: /* init groups for user */
"Invalid filter type");
return reply;
}
"Initgroups call not supported");
return reply;
}
break;
case BE_REQ_NETGROUP:
"Invalid filter type");
return reply;
}
"Netgroups are not supported");
return reply;
}
break;
case BE_REQ_SERVICES:
switch (data->filter_type) {
case BE_FILTER_NAME:
"Services are not supported");
return reply;
}
data->extra_value);
break;
case BE_FILTER_IDNUM:
"Services are not supported");
return reply;
}
data->extra_value);
break;
case BE_FILTER_ENUM:
"Services are not supported");
return reply;
}
break;
default:
"Invalid filter type");
return reply;
}
break;
default: /*fail*/
"Invalid filter type");
return reply;
}
if (ret) {
"proxy returned UNAVAIL error, going offline!\n");
}
return reply;
}
return reply;
}
struct proxy_account_info_handler_state {
};
struct tevent_req *
struct proxy_id_ctx *id_ctx,
struct dp_id_data *data,
struct dp_req_params *params)
{
struct proxy_account_info_handler_state);
return NULL;
}
/* TODO For backward compatibility we always return EOK to DP now. */
return req;
}
struct tevent_req *req,
struct dp_reply_std *data)
{
return EOK;
}