sss_nss_ex.c revision 859bddc2bf51dc426a3dc56bd9f365e9c5722b65
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen/*
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen SSSD
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen Extended NSS Responder Interface
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen
e074ffeaee1ce283bd42f167c6810e3d013f8218Timo Sirainen Authors:
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen Sumit Bose <sbose@redhat.com>
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen Copyright (C) 2017 Red Hat
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen This program is free software; you can redistribute it and/or modify
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen it under the terms of the GNU General Public License as published by
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen the Free Software Foundation; either version 3 of the License, or
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen (at your option) any later version.
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen This program is distributed in the hope that it will be useful,
9eedd38c2985596fb692dcca62193379d34c4c5bTimo Sirainen but WITHOUT ANY WARRANTY; without even the implied warranty of
9eedd38c2985596fb692dcca62193379d34c4c5bTimo Sirainen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen GNU General Public License for more details.
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen You should have received a copy of the GNU General Public License
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen along with this program. If not, see <http://www.gnu.org/licenses/>.
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen*/
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen#include <stdlib.h>
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen#include <errno.h>
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen#include <sys/param.h> /* for MIN() */
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen#include "sss_client/sss_cli.h"
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen#include "sss_client/nss_mc.h"
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen#include "sss_client/nss_common.h"
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen#include "sss_client/idmap/sss_nss_idmap.h"
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen#include "sss_client/idmap/sss_nss_idmap_private.h"
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen#ifndef discard_const
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen#endif
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainenstruct sss_nss_initgr_rep {
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen gid_t *groups;
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen long int *ngroups;
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen long int *start;
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen};
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainenstruct nss_input {
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen union {
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen const char *name;
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen uid_t uid;
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen gid_t gid;
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen } input;
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen struct sss_cli_req_data rd;
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen enum sss_cli_command cmd;
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen union {
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen struct sss_nss_pw_rep pwrep;
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen struct sss_nss_gr_rep grrep;
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen struct sss_nss_initgr_rep initgrrep;
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen } result;
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen};
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainenerrno_t sss_nss_mc_get(struct nss_input *inp)
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen{
e80203675151ef9d4f3f850cf02041042eb13096Timo Sirainen switch(inp->cmd) {
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen case SSS_NSS_GETPWNAM:
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen case SSS_NSS_GETPWNAM_EX:
e80203675151ef9d4f3f850cf02041042eb13096Timo Sirainen return sss_nss_mc_getpwnam(inp->input.name, strlen(inp->input.name),
517d1e7142d57299c733b30423e35e7e1f8d01d6Timo Sirainen inp->result.pwrep.result,
eb05765777cf968a7fb784602c310a8a418156a1Timo Sirainen inp->result.pwrep.buffer,
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen inp->result.pwrep.buflen);
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen break;
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen case SSS_NSS_GETPWUID:
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen case SSS_NSS_GETPWUID_EX:
78ed6a99e980228a75fa59cff84327dc0ea82857Timo Sirainen return sss_nss_mc_getpwuid(inp->input.uid,
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen inp->result.pwrep.result,
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen inp->result.pwrep.buffer,
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen inp->result.pwrep.buflen);
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen break;
9eedd38c2985596fb692dcca62193379d34c4c5bTimo Sirainen case SSS_NSS_GETGRNAM:
9eedd38c2985596fb692dcca62193379d34c4c5bTimo Sirainen case SSS_NSS_GETGRNAM_EX:
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen return sss_nss_mc_getgrnam(inp->input.name, strlen(inp->input.name),
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen inp->result.grrep.result,
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen inp->result.grrep.buffer,
49e513d090753ccbf95560b2f3a21f081a5b6c51Timo Sirainen inp->result.grrep.buflen);
49e513d090753ccbf95560b2f3a21f081a5b6c51Timo Sirainen break;
e80203675151ef9d4f3f850cf02041042eb13096Timo Sirainen case SSS_NSS_GETGRGID:
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen case SSS_NSS_GETGRGID_EX:
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen return sss_nss_mc_getgrgid(inp->input.gid,
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen inp->result.grrep.result,
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen inp->result.grrep.buffer,
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen inp->result.grrep.buflen);
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen break;
5e5c6dc798670afe6b717529e0df2c94879fd112Timo Sirainen case SSS_NSS_INITGR:
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen case SSS_NSS_INITGR_EX:
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen return sss_nss_mc_initgroups_dyn(inp->input.name,
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen strlen(inp->input.name),
5e5c6dc798670afe6b717529e0df2c94879fd112Timo Sirainen -1 /* currently ignored */,
5e5c6dc798670afe6b717529e0df2c94879fd112Timo Sirainen inp->result.initgrrep.start,
5e5c6dc798670afe6b717529e0df2c94879fd112Timo Sirainen inp->result.initgrrep.ngroups,
5e5c6dc798670afe6b717529e0df2c94879fd112Timo Sirainen &(inp->result.initgrrep.groups),
5e5c6dc798670afe6b717529e0df2c94879fd112Timo Sirainen *(inp->result.initgrrep.ngroups));
5e5c6dc798670afe6b717529e0df2c94879fd112Timo Sirainen break;
5e5c6dc798670afe6b717529e0df2c94879fd112Timo Sirainen default:
5e5c6dc798670afe6b717529e0df2c94879fd112Timo Sirainen return EINVAL;
5e5c6dc798670afe6b717529e0df2c94879fd112Timo Sirainen }
5e5c6dc798670afe6b717529e0df2c94879fd112Timo Sirainen}
5e5c6dc798670afe6b717529e0df2c94879fd112Timo Sirainen
5e5c6dc798670afe6b717529e0df2c94879fd112Timo Sirainenstatic int check_flags(struct nss_input *inp, uint32_t flags,
5e5c6dc798670afe6b717529e0df2c94879fd112Timo Sirainen bool *skip_mc, bool *skip_data)
5e5c6dc798670afe6b717529e0df2c94879fd112Timo Sirainen{
5e5c6dc798670afe6b717529e0df2c94879fd112Timo Sirainen bool no_data = false;
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen /* SSS_NSS_EX_FLAG_NO_CACHE and SSS_NSS_EX_FLAG_INVALIDATE_CACHE are
9eedd38c2985596fb692dcca62193379d34c4c5bTimo Sirainen * mutually exclusive */
9eedd38c2985596fb692dcca62193379d34c4c5bTimo Sirainen if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0
9eedd38c2985596fb692dcca62193379d34c4c5bTimo Sirainen && (flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) {
9eedd38c2985596fb692dcca62193379d34c4c5bTimo Sirainen return EINVAL;
9eedd38c2985596fb692dcca62193379d34c4c5bTimo Sirainen }
657afb33796f8216c568ad813627da89970760beTimo Sirainen
9eedd38c2985596fb692dcca62193379d34c4c5bTimo Sirainen *skip_mc = false;
9eedd38c2985596fb692dcca62193379d34c4c5bTimo Sirainen if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0
49e513d090753ccbf95560b2f3a21f081a5b6c51Timo Sirainen || (flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) {
49e513d090753ccbf95560b2f3a21f081a5b6c51Timo Sirainen *skip_mc = true;
e80203675151ef9d4f3f850cf02041042eb13096Timo Sirainen }
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen switch(inp->cmd) {
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen case SSS_NSS_GETPWNAM:
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen case SSS_NSS_GETPWNAM_EX:
97c339398f1aba6f315b55a9b6ee6b020e33bea4Timo Sirainen case SSS_NSS_GETPWUID:
97c339398f1aba6f315b55a9b6ee6b020e33bea4Timo Sirainen case SSS_NSS_GETPWUID_EX:
49e513d090753ccbf95560b2f3a21f081a5b6c51Timo Sirainen if (inp->result.pwrep.buffer == NULL
e80203675151ef9d4f3f850cf02041042eb13096Timo Sirainen || inp->result.pwrep.buflen == 0) {
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen no_data = true;
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen }
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen break;
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen case SSS_NSS_GETGRNAM:
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen case SSS_NSS_GETGRNAM_EX:
a8e132559a7ebe54c8269d79ce29fa3338c76199Timo Sirainen case SSS_NSS_GETGRGID:
1e21e6be70994b1aa9e52ca0e2f51afefca6d0dfTimo Sirainen case SSS_NSS_GETGRGID_EX:
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen if (inp->result.grrep.buffer == NULL
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen || inp->result.grrep.buflen == 0) {
4ac5448461b63de9637de839fbc611a3d503287cTimo Sirainen no_data = true;
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen }
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen break;
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen case SSS_NSS_INITGR:
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen case SSS_NSS_INITGR_EX:
e03ec0b7b9d92551331bc509bcd86920544171d1Timo Sirainen if (inp->result.initgrrep.ngroups == 0
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen || inp->result.initgrrep.groups == NULL) {
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen return EINVAL;
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen }
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen break;
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen default:
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen return EINVAL;
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen }
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen *skip_data = false;
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen /* Allow empty buffer with SSS_NSS_EX_FLAG_INVALIDATE_CACHE */
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen if (no_data) {
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen if ((flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) {
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen *skip_data = true;
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen } else {
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen return ERANGE;
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen }
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen }
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen return 0;
e70d5895795732b8247ab9abb045b438e954bc46Timo Sirainen}
54bde50b7d791bd8c3d2a6581f8a4ff26d9f0834Timo Sirainen
int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout)
{
uint8_t *repbuf = NULL;
size_t replen;
size_t len;
uint32_t num_results;
int ret;
int time_left;
int errnop;
size_t c;
gid_t *new_groups;
size_t idx;
bool skip_mc = false;
bool skip_data = false;
ret = check_flags(inp, flags, &skip_mc, &skip_data);
if (ret != 0) {
return ret;
}
if (!skip_mc && !skip_data) {
ret = sss_nss_mc_get(inp);
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 mmaped cache failed,
* fall back to socket based comms */
break;
}
}
sss_nss_timedlock(timeout, &time_left);
if (!skip_mc && !skip_data) {
/* previous thread might already initialize entry in mmap cache */
ret = sss_nss_mc_get(inp);
switch (ret) {
case 0:
ret = 0;
goto out;
case ERANGE:
ret = ERANGE;
goto out;
case ENOENT:
/* fall through, we need to actively ask the parent
* if no entry is found */
break;
default:
/* if using the mmaped cache failed,
* fall back to socket based comms */
break;
}
}
ret = sss_nss_make_request_timeout(inp->cmd, &inp->rd, time_left,
&repbuf, &replen, &errnop);
if (ret != NSS_STATUS_SUCCESS) {
ret = errnop != 0 ? errnop : EIO;
goto out;
}
/* Get number of results from repbuf. */
SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL);
/* no results if not found */
if (num_results == 0) {
ret = ENOENT;
goto out;
}
if (skip_data) {
/* No data requested, just return the return code */
ret = 0;
goto out;
}
if (inp->cmd == SSS_NSS_INITGR || inp->cmd == SSS_NSS_INITGR_EX) {
if ((*(inp->result.initgrrep.ngroups) - *(inp->result.initgrrep.start))
< num_results) {
new_groups = realloc(inp->result.initgrrep.groups,
(num_results + *(inp->result.initgrrep.start))
* sizeof(gid_t));
if (new_groups == NULL) {
ret = ENOMEM;
goto out;
}
inp->result.initgrrep.groups = new_groups;
}
*(inp->result.initgrrep.ngroups) = num_results
+ *(inp->result.initgrrep.start);
idx = 2 * sizeof(uint32_t);
for (c = 0; c < num_results; c++) {
SAFEALIGN_COPY_UINT32(
&(inp->result.initgrrep.groups[*(inp->result.initgrrep.start)]),
repbuf + idx, &idx);
*(inp->result.initgrrep.start) += 1;
}
ret = 0;
goto out;
}
/* only 1 result is accepted for this function */
if (num_results != 1) {
ret = EBADMSG;
goto out;
}
len = replen - 8;
switch(inp->cmd) {
case SSS_NSS_GETPWNAM:
case SSS_NSS_GETPWUID:
case SSS_NSS_GETPWNAM_EX:
case SSS_NSS_GETPWUID_EX:
ret = sss_nss_getpw_readrep(&(inp->result.pwrep), repbuf+8, &len);
break;
case SSS_NSS_GETGRNAM:
case SSS_NSS_GETGRGID:
case SSS_NSS_GETGRNAM_EX:
case SSS_NSS_GETGRGID_EX:
ret = sss_nss_getgr_readrep(&(inp->result.grrep), repbuf+8, &len);
break;
default:
ret = EINVAL;
}
if (ret != 0) {
goto out;
}
if (len == 0) {
/* no extra data */
ret = 0;
goto out;
}
out:
free(repbuf);
sss_nss_unlock();
return ret;
}
static int make_name_flag_req_data(const char *name, uint32_t flags,
struct sss_cli_req_data *rd)
{
size_t len;
size_t name_len;
uint8_t *data;
int ret;
if (name == NULL) {
return EINVAL;
}
ret = sss_strnlen(name, SSS_NAME_MAX, &name_len);
if (ret != 0) {
return ret;
}
name_len++;
len = name_len + sizeof(uint32_t);
data = malloc(len);
if (data == NULL) {
return ENOMEM;
}
memcpy(data, name, name_len);
SAFEALIGN_COPY_UINT32(data + name_len, &flags, NULL);
rd->len = len;
rd->data = data;
return 0;
}
int sss_nss_getpwnam_timeout(const char *name, struct passwd *pwd,
char *buffer, size_t buflen,
struct passwd **result,
uint32_t flags, unsigned int timeout)
{
int ret;
struct nss_input inp = {
.input.name = name,
.cmd = SSS_NSS_GETPWNAM_EX,
.result.pwrep.result = pwd,
.result.pwrep.buffer = buffer,
.result.pwrep.buflen = buflen};
ret = make_name_flag_req_data(name, flags, &inp.rd);
if (ret != 0) {
return ret;
}
*result = NULL;
ret = sss_get_ex(&inp, flags, timeout);
free(discard_const(inp.rd.data));
if (ret == 0) {
*result = inp.result.pwrep.result;
}
return ret;
}
int sss_nss_getpwuid_timeout(uid_t uid, struct passwd *pwd,
char *buffer, size_t buflen,
struct passwd **result,
uint32_t flags, unsigned int timeout)
{
int ret;
uint32_t req_data[2];
struct nss_input inp = {
.input.uid = uid,
.cmd = SSS_NSS_GETPWUID_EX,
.rd.len = 2 * sizeof(uint32_t),
.rd.data = &req_data,
.result.pwrep.result = pwd,
.result.pwrep.buffer = buffer,
.result.pwrep.buflen = buflen};
SAFEALIGN_COPY_UINT32(&req_data[0], &uid, NULL);
SAFEALIGN_COPY_UINT32(&req_data[1], &flags, NULL);
*result = NULL;
ret = sss_get_ex(&inp, flags, timeout);
if (ret == 0) {
*result = inp.result.pwrep.result;
}
return ret;
}
int sss_nss_getgrnam_timeout(const char *name, struct group *grp,
char *buffer, size_t buflen, struct group **result,
uint32_t flags, unsigned int timeout)
{
int ret;
struct nss_input inp = {
.input.name = name,
.cmd = SSS_NSS_GETGRNAM_EX,
.result.grrep.result = grp,
.result.grrep.buffer = buffer,
.result.grrep.buflen = buflen};
ret = make_name_flag_req_data(name, flags, &inp.rd);
if (ret != 0) {
return ret;
}
*result = NULL;
ret = sss_get_ex(&inp, flags, timeout);
free(discard_const(inp.rd.data));
if (ret == 0) {
*result = inp.result.grrep.result;
}
return ret;
}
int sss_nss_getgrgid_timeout(gid_t gid, struct group *grp,
char *buffer, size_t buflen, struct group **result,
uint32_t flags, unsigned int timeout)
{
int ret;
uint32_t req_data[2];
struct nss_input inp = {
.input.gid = gid,
.cmd = SSS_NSS_GETGRGID_EX,
.rd.len = 2 * sizeof(uint32_t),
.rd.data = &req_data,
.result.grrep.result = grp,
.result.grrep.buffer = buffer,
.result.grrep.buflen = buflen};
SAFEALIGN_COPY_UINT32(&req_data[0], &gid, NULL);
SAFEALIGN_COPY_UINT32(&req_data[1], &flags, NULL);
*result = NULL;
ret = sss_get_ex(&inp, flags, timeout);
if (ret == 0) {
*result = inp.result.grrep.result;
}
return ret;
}
int sss_nss_getgrouplist_timeout(const char *name, gid_t group,
gid_t *groups, int *ngroups,
uint32_t flags, unsigned int timeout)
{
int ret;
gid_t *new_groups;
long int new_ngroups;
long int start = 1;
struct nss_input inp = {
.input.name = name,
.cmd = SSS_NSS_INITGR_EX};
ret = make_name_flag_req_data(name, flags, &inp.rd);
if (ret != 0) {
return ret;
}
new_ngroups = MAX(1, *ngroups);
new_groups = malloc(new_ngroups * sizeof(gid_t));
if (new_groups == NULL) {
free(discard_const(inp.rd.data));
return ENOMEM;
}
new_groups[0] = group;
inp.result.initgrrep.groups = new_groups,
inp.result.initgrrep.ngroups = &new_ngroups;
inp.result.initgrrep.start = &start;
ret = sss_get_ex(&inp, flags, timeout);
free(discard_const(inp.rd.data));
if (ret != 0) {
free(new_groups);
return ret;
}
memcpy(groups, new_groups, MIN(*ngroups, start) * sizeof(gid_t));
free(new_groups);
if (start > *ngroups) {
ret = ERANGE;
} else {
ret = 0;
}
*ngroups = start;
return ret;
}