nsssrv_netgroup.c revision a3c8390d19593b1e5277d95bfb4ab206d4785150
/*
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 "responder/nss/nsssrv_private.h"
#include "responder/nss/nsssrv_netgroup.h"
#include "responder/common/negcache.h"
char *name,
struct getent_ctx **netgr)
{
int hret;
if (hret == HASH_SUCCESS) {
return EOK;
} else if (hret == HASH_ERROR_KEY_NOT_FOUND) {
return ENOENT;
}
return EIO;
}
struct getent_ctx *netgr)
{
int hret;
return EINVAL;
}
/* Add this entry to the hash table */
return EIO;
}
return EOK;
}
const char *rawname,
struct nss_cmd_ctx *cmdctx);
{
struct nss_cmd_ctx *cmdctx;
struct tevent_req *req;
const char *rawname;
/* Reset the result cursor to zero */
client->netgrent_cur = 0;
if (!cmdctx) {
return ENOMEM;
}
/* get netgroup name to query */
/* if not terminated fail */
goto done;
}
/* If the body isn't valid UTF-8, fail */
goto done;
}
if (!req) {
DEBUG(0, "Fatal error calling setnetgrent_send\n");
goto done;
}
done:
}
{
int hret;
struct getent_ctx *netgr =
return EOK;
}
/* Remove the netgroup result object from the lookup table */
if (hret != HASH_SUCCESS) {
DEBUG(0, "Could not remove key [%s] from table! [%d][%s]\n",
return -1;
}
return 0;
}
struct setnetgrent_ctx {
struct nss_cmd_ctx *cmdctx;
struct nss_dom_ctx *dctx;
char *netgr_shortname;
struct getent_ctx *netgr;
const char *rawname;
};
const char *rawname,
struct nss_cmd_ctx *cmdctx)
{
char *domname;
struct tevent_req *req;
struct setnetgrent_ctx *state;
struct nss_dom_ctx *dctx;
if (!req) {
DEBUG(0, "Could not create tevent request for setnetgrent\n");
return NULL;
}
goto error;
}
goto error;
}
if (domname) {
goto error;
}
/* Save the netgroup name for getnetgrent */
if (!client->netgr_name) {
goto error;
}
} else {
/* this is a multidomain search */
cmdctx->check_next = true;
/* Save the netgroup name for getnetgrent */
if (!client->netgr_name) {
goto error;
}
}
/* We need to reenter the mainloop
* We may be refreshing the cache
*/
return req;
}
goto error;
}
return req;
return req;
}
{
struct setent_step_ctx *step_ctx;
struct setnetgrent_ctx *state;
struct nss_cmd_ctx *cmdctx;
struct nss_dom_ctx *dctx;
/* Is the result context already available?
* Check for existing lookups for this netgroup
*/
/* Another process already requested this netgroup
* Check whether it's ready for processing.
*/
/* Ready to process results */
} else {
}
/* Return EOK, otherwise this will be treated as
* an error
*/
return EOK;
}
/* Result object is still being constructed
* Register for notification when it's ready
*/
goto done;
}
/* Will return control below */
/* This is the first attempt to request this netgroup
*/
goto done;
}
/* Save the name used for the lookup table
* so we can remove it in the destructor
*/
client->netgr_name);
goto done;
}
/* Add a reference for ourselves */
goto done;
}
goto done;
}
/* Perform lookup */
if (!step_ctx) {
goto done;
}
/* Steal the dom_ctx onto the step_ctx so it doesn't go out of scope if
* this request is canceled while other requests are in-progress.
*/
goto done;
}
switch (ret) {
case EOK:
break;
case EMSGSIZE:
/* FALLTHROUGH */
default:
goto done;
}
/* Will return control below */
} else {
/* Unexpected error from hash_lookup */
goto done;
}
done:
return ret;
}
struct tevent_timer *te,
struct timeval current_time,
void *pvt);
/* Set up a lifetime timer for this result object
* We don't want this result object to outlive the
* entry cache refresh timeout
*/
struct setent_step_ctx *step_ctx,
struct getent_ctx *netgr)
{
struct tevent_timer *te;
netgr);
if (!te) {
DEBUG(0, "Could not set up life timer for setnetgrent result object. "
"Entries may become stale.\n");
}
}
{
struct getent_ctx *netgr;
/* Check each domain for this netgroup name */
while (dom) {
/* Netgroups are a special case. We have to ignore the
* fully-qualified name requirement because memberNisNetgroup
* entries do not have fully-qualified components and we need
* to be able to always check them. So unlike the other
* maps, here we avoid skipping over fully-qualified domains.
*/
/* make sure we reset the check_provider flag when we check
* a new domain */
}
/* make sure to update the dctx if we changed domain */
if (!name) {
return ENOMEM;
}
DEBUG(0, "Fatal: Sysdb CTX not found for this domain!\n");
return EIO;
}
/* Look up the netgroup in the cache */
"getnetgr call returned more than one result !?!\n");
return EMSGSIZE;
}
/* This netgroup was not found in this domain */
if (step_ctx->check_next) {
continue;
}
else break;
}
}
return EIO;
}
&netgr);
/* Something really bad happened! */
DEBUG(0, "Netgroup entry was lost!\n");
return ret;
}
/* Convert the result to a list of entries */
/* This netgroup was not found in this domain */
if (step_ctx->check_next) {
continue;
}
else break;
}
}
return EIO;
}
/* if this is a caching provider (or if we haven't checked the cache
* yet) then verify that the cache is uptodate */
name, 0,
step_ctx);
/* May return EAGAIN legitimately to indicate that
* we need to reenter the mainloop
*/
return ret;
}
}
/* Results found */
} else {
}
return EOK;
}
/* If we've gotten here, then no domain contained this netgroup */
} else {
return ENOMEM;
}
}
}
return ENOENT;
}
{
struct setent_step_ctx *step_ctx =
int ret;
if (err_maj) {
"Error: %u, %u, %s\n"
"Will try to return what we have in cache\n",
/* Loop to the next domain if possible */
}
}
/* ok the backend returned, search to see if we have updated results */
return;
}
}
/* We have results to return */
}
struct tevent_timer *te,
struct timeval current_time,
void *pvt)
{
struct getent_ctx *netgr =
/* Free the netgroup result context
* The destructor for the netgroup will remove itself
* from the hash table
*
* If additional getnetgrent() requests come in, they
* will invoke an implicit setnetgrent() call and
* refresh the result object
*/
}
{
return EOK;
}
{
struct sss_packet *packet;
struct nss_cmd_ctx *cmdctx =
return;
}
/* Either we succeeded or no domains were eligible */
/* Notify the caller that this entry wasn't found */
} else {
}
/* Got some results. */
/* reserved */
}
return;
}
}
struct getent_ctx *netgr);
{
struct nss_cmd_ctx *cmdctx;
struct getent_ctx *netgr;
struct tevent_req *req;
if (!cmdctx) {
return ENOMEM;
}
if (!client->netgr_name) {
/* Tried to run getnetgrent without a preceding
* setnetgrent. There is no way to determine which
* netgroup is being requested.
*/
}
/* Look up the results from the hash */
/* We need to invoke an implicit setnetgrent() to
* wait for the result object to become available.
*/
if (!req) {
}
return EOK;
}
/* Hash entry was found. Is it ready? */
/* We need to invoke an implicit setnetgrent() to
* wait for the result object to become available.
*/
if (!req) {
}
return EOK;
return ENOENT;
}
/* Read the result strings */
}
return ret;
}
{
struct getent_ctx *netgr;
struct nss_cmd_ctx *cmdctx =
/* ENOENT is acceptable, it just means there were no values
* to be returned. This will be handled gracefully in
* nss_cmd_retnetgrent later
*/
DEBUG(0, "Implicit setnetgrent failed with unexpected error "
}
/* No entries found for this netgroup */
return;
}
/* Look up the results from the hash */
/* Critical error. This should never happen */
DEBUG(0, "Implicit setnetgrent returned success without creating "
"result object.\n");
}
/* Critical error. This should never happen */
DEBUG(0, "Implicit setnetgrent returned success without creating "
"result object.\n");
}
DEBUG(0, "Immediate retrieval failed with unexpected error "
}
}
struct sysdb_netgroup_ctx **entries,
int num);
struct getent_ctx *netgr)
{
/* get max num of entries to return in one call */
return EINVAL;
}
/* create response packet */
return ret;
}
/* No entries */
}
goto done;
}
done:
return EOK;
}
struct sysdb_netgroup_ctx **entries,
int count)
{
/* first 2 fields (len and reserved), filled up later */
num = 0;
hostlen = 1;
}
userlen = 1;
}
domainlen = 1;
}
return ret;
}
if (hostlen == 1) {
} else {
hostlen);
}
if (userlen == 1) {
} else {
userlen);
}
if (domainlen == 1) {
} else {
}
continue;
}
return ret;
}
grouplen);
} else {
"Please check your cache.\n");
continue;
}
num++;
client->netgrent_cur++;
}
/* num results */
/* reserved */
return EOK;
}
{
/* create response packet */
return ret;
}
/* Reset the indices so that subsequent requests start at zero */
client->netgrent_cur = 0;
return EOK;
}
void
{
struct getent_ctx *netgr;
if (deltype != HASH_ENTRY_DESTROY) {
return;
}
if (!netgr) {
return;
}
/* So that the destructor wouldn't attempt to remove the netgroup from hash
* table */
}
{
int hret;
unsigned long mcount;
unsigned long i;
return EINVAL;
}
if (hret != HASH_SUCCESS) {
return EIO;
}
for (i = 0; i < mcount; i++) {
/* netgroup entry will be deleted by setnetgrent_result_timeout */
if (hret != HASH_SUCCESS) {
continue;
}
}
return EOK;
}