/*
SSSD
Extended NSS Responder Interface
Authors:
Sumit Bose <sbose@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 <stdlib.h>
#include <errno.h>
#include "sss_client/sss_cli.h"
#include "sss_client/nss_mc.h"
#include "sss_client/nss_common.h"
#include "sss_client/idmap/sss_nss_idmap.h"
#include "sss_client/idmap/sss_nss_idmap_private.h"
#ifndef discard_const
#endif
struct sss_nss_initgr_rep {
long int *ngroups;
long int *start;
};
struct nss_input {
union {
const char *name;
} input;
union {
} result;
};
{
case SSS_NSS_GETPWNAM:
case SSS_NSS_GETPWNAM_EX:
break;
case SSS_NSS_GETPWUID:
case SSS_NSS_GETPWUID_EX:
break;
case SSS_NSS_GETGRNAM:
case SSS_NSS_GETGRNAM_EX:
break;
case SSS_NSS_GETGRGID:
case SSS_NSS_GETGRGID_EX:
break;
case SSS_NSS_INITGR:
case SSS_NSS_INITGR_EX:
-1 /* currently ignored */,
/* no limit so that needed size can
* be returned properly */
-1);
break;
default:
return EINVAL;
}
}
{
bool no_data = false;
/* SSS_NSS_EX_FLAG_NO_CACHE and SSS_NSS_EX_FLAG_INVALIDATE_CACHE are
* mutually exclusive */
if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0
&& (flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) {
return EINVAL;
}
*skip_mc = false;
if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0
|| (flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) {
*skip_mc = true;
}
case SSS_NSS_GETPWNAM:
case SSS_NSS_GETPWNAM_EX:
case SSS_NSS_GETPWUID:
case SSS_NSS_GETPWUID_EX:
no_data = true;
}
break;
case SSS_NSS_GETGRNAM:
case SSS_NSS_GETGRNAM_EX:
case SSS_NSS_GETGRGID:
case SSS_NSS_GETGRGID_EX:
no_data = true;
}
break;
case SSS_NSS_INITGR:
case SSS_NSS_INITGR_EX:
return EINVAL;
}
break;
default:
return EINVAL;
}
*skip_data = false;
/* Allow empty buffer with SSS_NSS_EX_FLAG_INVALIDATE_CACHE */
if (no_data) {
if ((flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) {
*skip_data = true;
} else {
return ERANGE;
}
}
return 0;
}
{
int ret;
int time_left;
int errnop;
size_t c;
bool skip_mc = false;
bool skip_data = false;
if (ret != 0) {
return ret;
}
switch (ret) {
case 0:
return 0;
case ERANGE:
return ERANGE;
case ENOENT:
/* fall through, we need to actively ask the parent
* if no entry is found */
break;
default:
/* if using the mmapped cache failed,
* fall back to socket based comms */
break;
}
}
if (ret != 0) {
return ret;
}
/* previous thread might already initialize entry in mmap cache */
switch (ret) {
case 0:
ret = 0;
goto out;
case ERANGE:
goto out;
case ENOENT:
/* fall through, we need to actively ask the parent
* if no entry is found */
break;
default:
/* if using the mmapped cache failed,
* fall back to socket based comms */
break;
}
}
if (ret != NSS_STATUS_SUCCESS) {
goto out;
}
/* Get number of results from repbuf. */
/* no results if not found */
if (num_results == 0) {
goto out;
}
if (skip_data) {
/* No data requested, just return the return code */
ret = 0;
goto out;
}
< num_results) {
* sizeof(gid_t));
if (new_groups == NULL) {
goto out;
}
}
for (c = 0; c < num_results; c++) {
}
ret = 0;
goto out;
}
/* only 1 result is accepted for this function */
if (num_results != 1) {
goto out;
}
case SSS_NSS_GETPWNAM:
case SSS_NSS_GETPWUID:
case SSS_NSS_GETPWNAM_EX:
case SSS_NSS_GETPWUID_EX:
break;
case SSS_NSS_GETGRNAM:
case SSS_NSS_GETGRGID:
case SSS_NSS_GETGRNAM_EX:
case SSS_NSS_GETGRGID_EX:
break;
default:
}
if (ret != 0) {
goto out;
}
if (len == 0) {
/* no extra data */
ret = 0;
goto out;
}
out:
return ret;
}
struct sss_cli_req_data *rd)
{
int ret;
return EINVAL;
}
if (ret != 0) {
return ret;
}
name_len++;
return ENOMEM;
}
return 0;
}
{
int ret;
if (ret != 0) {
return ret;
}
if (ret == 0) {
} else {
}
}
return ret;
}
{
int ret;
if (ret == 0) {
} else {
}
}
return ret;
}
{
int ret;
if (ret != 0) {
return ret;
}
if (ret == 0) {
} else {
}
}
return ret;
}
{
int ret;
if (ret == 0) {
} else {
}
}
return ret;
}
{
int ret;
long int new_ngroups;
.cmd = SSS_NSS_INITGR_EX};
if (ret != 0) {
return ret;
}
return ENOMEM;
}
/* inp.result.initgrrep.groups, inp.result.initgrrep.ngroups and
* inp.result.initgrrep.start might be modified by sss_get_ex() */
if (ret != 0) {
return ret;
}
} else {
ret = 0;
}
return ret;
}