ifpsrv_cmd.c revision 4084ccd3442917c7aa88ba4d76ba1e71e67d3846
/*
Authors:
Jakub Hrozek <jhrozek@redhat.com>
Copyright (C) 2013 Red Hat
InfoPipe responder: the responder commands
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/ifp/ifp_private.h"
struct ifp_attr_req {
const char *name;
const char **attrs;
int nattrs;
};
static struct tevent_req *
enum sss_dp_acct_type search_type,
struct tevent_req *req,
struct ldb_result **_res);
static errno_t
static errno_t
{
struct ifp_attr_req *attr_req;
struct tevent_req *req;
}
}
}
return ret; /* handled internally */
}
}
return EOK;
}
static errno_t
{
bool parsed;
char **attrs;
int nattrs;
int i, ai;
if (parsed == false) {
return EOK; /* handled */
}
/* Copy the attributes to maintain memory hierarchy with talloc */
return ENOMEM;
}
ai = 0;
for (i = 0; i < nattrs; i++) {
"Attribute %s not present in the whitelist, skipping\n",
attrs[i]);
continue;
}
return ENOMEM;
}
ai++;
}
return EOK;
}
{
struct ifp_attr_req *attr_req;
"No such user\n"));
return;
"Failed to read user attribute\n"));
return;
}
"Failed to build a reply\n"));
return;
}
}
static errno_t
{
struct ldb_message_element *el;
int ai;
/* Construct a reply */
if (!reply) {
}
&iter_dict);
if (!dbret) {
}
"Attribute %s not present or has no values\n",
continue;
}
"Cannot add attribute %s to message\n",
continue;
}
}
}
if (!dbret) {
}
}
struct ldb_result *res);
{
struct ifp_attr_req *group_req;
struct tevent_req *req;
}
}
}
}
}
}
return EOK;
}
{
struct ifp_attr_req *group_req;
struct ldb_result *res;
"No such user\n"));
return;
"Failed to read attribute\n"));
return;
}
"Failed to build a reply\n"));
return;
}
}
static errno_t
{
int i, num;
const char *name;
const char **groupnames;
/* one less, the first one is the user entry */
if (groupnames == NULL) {
}
for (i = 0; i < num; i++) {
continue;
}
groupnames[i] = name;
}
groupnames, num);
}
struct ifp_user_get_attr_state {
const char *inp;
const char **attrs;
struct ldb_result *res;
enum sss_dp_acct_type search_type;
char *name;
char *domname;
struct sss_domain_info *dom;
bool check_next;
bool check_provider;
struct sss_nc_ctx *ncache;
int neg_timeout;
};
enum sss_dp_acct_type search_type,
unsigned int cache_refresh_percent,
void *pvt);
static struct tevent_req *
enum sss_dp_acct_type search_type,
{
struct tevent_req *req;
struct tevent_req *subreq;
struct ifp_user_get_attr_state *state;
return NULL;
}
goto done;
}
done:
}
return req;
}
static void
{
struct tevent_req);
struct ifp_user_get_attr_state);
return;
}
/* this is a search in one domain */
return;
}
state->check_next = false;
} else {
/* this is a multidomain search */
state->check_next = true;
}
/* All set up, do the search! */
/* The data was cached. Just quit */
return;
return;
}
/* Execution will resume in ifp_dp_callback */
}
{
struct ifp_user_get_attr_state);
while (dom) {
/* if it is a domainless search, skip domains that require fully
* qualified names instead */
}
if (!dom) break;
/* make sure we reset the check_provider flag when we check
* a new domain */
}
/* make sure to update the cache_req if we changed domain */
/* verify this user has not yet been negatively cached,
* or has been permanently filtered */
/* if neg cached, return we didn't find it */
"User [%s] does not exist in [%s]! (negative cache)\n",
/* if a multidomain search, try with next */
if (state->check_next) {
continue;
}
/* There are no further domains or this was a
* fully-qualified user request.
*/
return ENOENT;
}
switch (state->search_type) {
case SSS_DP_USER:
break;
case SSS_DP_INITGROUPS:
break;
default:
return EIO;
}
"Failed to make request to our cache!\n");
return EIO;
}
"getpwnam call returned more than one result !?!\n");
return ENOENT;
}
}
/* set negative cache only if not result of cache check */
/* Not fatal */
}
/* if a multidomain search, try with next */
if (state->check_next) {
if (dom) continue;
}
return ENOENT;
}
/* if this is a caching provider (or if we haven't checked the cache
* yet) then verify that the cache is uptodate */
if (state->check_provider) {
ifp_dp_callback, 0, req);
/* Anything but EOK means we should reenter the mainloop
* because we may be refreshing the cache
*/
return ret;
}
}
/* One result found */
return EOK;
}
return ENOENT;
}
enum sss_dp_acct_type search_type,
unsigned int cache_refresh_percent,
void *pvt)
{
uint64_t cache_expire = 0;
int ret;
struct tevent_req *req;
"cache search call returned more than one result! "
"DB Corrupted?\n");
return ENOENT;
}
if (search_type == SSS_DP_USER) {
SYSDB_CACHE_EXPIRE, 0);
} else {
SYSDB_INITGR_EXPIRE, 0);
}
/* if we have any reply let's check cache validity */
return EOK;
return ret;
}
} else {
/* No replies */
}
/* EAGAIN (off band) or ENOENT (cache miss) -> check cache */
/* No callback required
* This was an out-of-band update. We'll return EOK
* so the calling function can return the cached entry
* immediately.
*/
NULL);
"Out of memory sending out-of-band data provider "
"request\n");
/* This is non-fatal, so we'll continue here */
} else {
}
/* We don't need to listen for a reply, so we will free the
* request here.
*/
} else {
/* This is a cache miss. Or the cache is expired.
* We need to get the updated user information before returning it.
*/
/* dont loop forever; mark the provider as checked */
state->check_provider = false;
"Out of memory sending data provider request\n");
return ENOMEM;
}
return ENOMEM;
}
return EAGAIN;
}
return EOK;
}
{
struct dp_callback_ctx *cb_ctx =
char *err_msg;
&err_msg);
/* report error with callback */
}
}
{
if (err_maj) {
"Unable to get information from Data Provider\n"
"Error: %u, %u, %s\n"
"Will try to return what we have in cache\n",
}
/* Backend was updated successfully. Check again */
/* Another search in progress */
return;
return;
}
}
static errno_t
struct tevent_req *req,
struct ldb_result **_res)
{
struct ifp_user_get_attr_state);
/* Did the request end with success but with no data? */
return ENOENT;
}
if (_res) {
}
return EOK;
}
struct cli_protocol_version *register_cli_protocol_version(void)
{
static struct cli_protocol_version ssh_cli_protocol_version[] = {
};
return ssh_cli_protocol_version;
}
/* This is a throwaway method to ease the review of the patch.
* It will be removed later */
{
static const char *pong = "PONG";
const char *request;
}
}
return EOK; /* handled */
}
"Ping() only accepts ping as a param\n");
}
}