nsssrv_cmd.c revision 21bc143c2855638242e9dfe01ea66198b5883b8a
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd NSS Responder
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd Copyright (C) Simo Sorce <ssorce@redhat.com> 2008
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd This program is free software; you can redistribute it and/or modify
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd it under the terms of the GNU General Public License as published by
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd the Free Software Foundation; either version 3 of the License, or
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd (at your option) any later version.
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd This program is distributed in the hope that it will be useful,
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd but WITHOUT ANY WARRANTY; without even the implied warranty of
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27e52281f1522522b170cafc76b08b58aa70ccaand GNU General Public License for more details.
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd You should have received a copy of the GNU General Public License
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd along with this program. If not, see <http://www.gnu.org/licenses/>.
6116c12fdd3ed06d388fe6572e50a22e9320dfa5ndstatic int nss_cmd_send_error(struct nss_cmd_ctx *cmdctx, int err)
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd switch (ret) {
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd /* all fine, just return here */
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd /* async processing, just return here */
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd /* very bad error */
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd/***************************
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd * Enumeration procedures *
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd ***************************/
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd return setent_add_ref(memctx, getent_ctx, &getent_ctx->reqs, req);
6116c12fdd3ed06d388fe6572e50a22e9320dfa5ndvoid nss_setent_notify_error(struct getent_ctx *getent_ctx, errno_t ret)
6116c12fdd3ed06d388fe6572e50a22e9320dfa5ndvoid nss_setent_notify_done(struct getent_ctx *getent_ctx)
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd/****************************************************************************
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd * PASSWD db related functions
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd ***************************************************************************/
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd const char *id;
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd for (dom = nctx->rctx->domains; dom; dom = get_next_domain(dom, false)) {
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd "Failed to enumerate users for domain [%s]\n", dom->name);
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd /* names require more manipulation (build up fqname conditionally),
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd * but uidNumber is unique and always resolvable too, so we use
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd * that to update the cache, as it points to the same entry */
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd id = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_UIDNUM, NULL);
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd "Failed to find uidNumber in %s.\n",
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd ret = sss_mmap_cache_pw_invalidate(nctx->pwd_mc_ctx, &key);
71fccc298df6a1540d408151a26aa22beed55d0bnd "Internal failure in memory cache code: %d [%s]\n",
6116c12fdd3ed06d388fe6572e50a22e9320dfa5ndstatic const char *get_homedir_override(TALLOC_CTX *mem_ctx,
909ce17e2bd0faef7b1c294f2307f009793fd493nd const char *homedir;
42af92a661a06b3cebc88d585aad75064a309d51nd homedir = ldb_msg_find_attr_as_string(msg, SYSDB_HOMEDIR, NULL);
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd /* Subdomain users store FQDN in their name attribute */
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd ret = sss_parse_name_const(mem_ctx, dom->names, orig_name,
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd /* Check to see which homedir_prefix to use. */
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd homedir_ctx->config_homedir_substr = dom->homedir_substr;
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd homedir_ctx->config_homedir_substr = nctx->homedir_substr;
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd /* Check whether we are unconditionally overriding the server
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd * for home directory locations.
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd return expand_homedir_template(mem_ctx, dom->override_homedir,
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd return expand_homedir_template(mem_ctx, nctx->override_homedir,
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd /* In the case of a NULL or empty homedir, check to see if
4b5981e276e93df97c34e4da05ca5cf8bbd937dand * we have a fallback homedir to use.
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd return expand_homedir_template(mem_ctx, dom->fallback_homedir,
d2b809e5d72658bff23819d8b77f20e4939af541nd return expand_homedir_template(mem_ctx, nctx->fallback_homedir,
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd /* Provider can also return template, try to expand it.*/
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd return expand_homedir_template(mem_ctx, homedir, homedir_ctx);
a43bfa789f4e52dde53ae8e53fa0427b5c1cf977ndstatic const char *get_shell_override(TALLOC_CTX *mem_ctx,
f772e8f448c223e5ea306f1bf92d97d968f972d5jim const char *user_shell;
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd /* Check whether we are unconditionally overriding the server
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd * for the login shell.
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd user_shell = ldb_msg_find_attr_as_string(msg, SYSDB_SHELL, NULL);
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd /* Check whether there is a default shell specified */
6116c12fdd3ed06d388fe6572e50a22e9320dfa5nd if (!nctx->allowed_shells && !nctx->vetoed_shells) return talloc_strdup(mem_ctx, user_shell);
ad74a0524a06bfe11b7de9e3b4ce7233ab3bd3f7nd DEBUG(SSSDBG_TRACE_ALL, "Shell %s found in /etc/shells\n",
6eed902e5b4d3e016e220bfbf8769a87c4cb242enoodl DEBUG(SSSDBG_TRACE_ALL, "Using original shell '%s'\n", user_shell);
int *count)
const char *tmpstr;
const char *orig_name;
int fq_len = 0;
bool packet_initialized = false;
int ncret;
num = 0;
for (i = 0; i < *count; i++) {
if (filter_users) {
if (!packet_initialized) {
packet_initialized = true;
if (!tmpstr) {
if (!tmpstr) {
if (!tmpstr) {
if (add_domain) {
if (fq_len >= 0) {
fq_len = 0;
num = 0;
goto done;
if (add_domain) {
num++;
done:
*count = i;
return EOK;
int ret;
return EFAULT;
if (ret) {
return ret;
return EOK;
int req_type,
const char *opt_name,
void *pvt)
return ENOENT;
if (cacheExpire == 0) {
SYSDB_CACHE_EXPIRE, 0);
return EOK;
goto error;
if (!req) {
if (!req) {
goto error;
if(!cb_ctx) {
goto error;
return EAGAIN;
return EOK;
return EOK;
char *err_msg;
&err_msg);
int ret;
return ENOMEM;
goto done;
goto done;
done:
return ret;
int ret;
while (dom) {
if (!dom) break;
return ENOMEM;
return ENOENT;
return EIO;
return EIO;
return ENOENT;
if (dom) continue;
return ENOENT;
dctx);
return ret;
return EOK;
return ENOENT;
int ret;
bool check_subdomains;
if (err_maj) {
case SSS_NSS_GETPWNAM:
case SSS_NSS_GETGRNAM:
case SSS_NSS_INITGR:
case SSS_NSS_GETPWUID:
case SSS_NSS_GETGRGID:
case SSS_NSS_GETNAMEBYSID:
case SSS_NSS_GETIDBYSID:
case SSS_NSS_GETSIDBYNAME:
case SSS_NSS_GETSIDBYID:
goto done;
case SSS_NSS_GETPWUID:
case SSS_NSS_GETGRGID:
case SSS_NSS_GETSIDBYID:
check_subdomains = true;
check_subdomains = false;
goto done;
case SSS_NSS_GETPWNAM:
case SSS_NSS_GETGRNAM:
case SSS_NSS_INITGR:
case SSS_NSS_GETPWUID:
case SSS_NSS_GETGRGID:
case SSS_NSS_GETNAMEBYSID:
case SSS_NSS_GETIDBYSID:
case SSS_NSS_GETSIDBYNAME:
case SSS_NSS_GETSIDBYID:
done:
if (ret) {
const char *full_name)
const char *wk_sid;
int ret;
return ret;
return ret;
return ENOMEM;
return EOK;
const char *rawname;
char *domname;
int ret;
switch(cmd) {
case SSS_NSS_GETPWNAM:
case SSS_NSS_GETGRNAM:
case SSS_NSS_INITGR:
case SSS_NSS_GETSIDBYNAME:
return EINVAL;
if (!cmdctx) {
return ENOMEM;
if (!dctx) {
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
if (domname) {
goto done;
goto done;
case SSS_NSS_GETPWNAM:
case SSS_NSS_GETGRNAM:
case SSS_NSS_INITGR:
case SSS_NSS_GETSIDBYNAME:
done:
goto done;
goto done;
if (domname) {
goto done;
case SSS_NSS_GETPWNAM:
case SSS_NSS_GETGRNAM:
case SSS_NSS_INITGR:
case SSS_NSS_GETSIDBYNAME:
done:
int ret;
int err;
while (dom) {
goto done;
goto done;
goto done;
goto done;
goto done;
dctx);
goto done;
goto done;
done:
return ret;
int ret;
switch (cmd) {
case SSS_NSS_GETPWUID:
case SSS_NSS_GETGRGID:
case SSS_NSS_GETSIDBYID:
return EINVAL;
if (!cmdctx) {
return ENOMEM;
if (!dctx) {
goto done;
goto done;
case SSS_NSS_GETPWUID:
goto done;
case SSS_NSS_GETGRGID:
goto done;
case SSS_NSS_GETSIDBYID:
goto done;
goto done;
goto done;
case SSS_NSS_GETPWUID:
case SSS_NSS_GETGRGID:
case SSS_NSS_GETSIDBYID:
done:
goto done;
case SSS_NSS_GETPWUID:
case SSS_NSS_GETGRGID:
case SSS_NSS_GETNAMEBYSID:
case SSS_NSS_GETIDBYSID:
goto done;
case SSS_NSS_GETSIDBYID:
done:
if (!cmdctx) {
return ENOMEM;
if (!req) {
goto done;
done:
if (!req) {
return NULL;
goto error;
goto error;
return NULL;
return req;
goto error;
if (!step_ctx) {
goto error;
return req;
return req;
void *pvt);
while (dom) {
if (!dom) break;
return EIO;
if (!dpreq) {
if(!cb_ctx) {
return ENOMEM;
return EAGAIN;
return ENOMEM;
if (!te) {
return EAGAIN;
return EOK;
void *pvt)
int ret;
if (err_maj) {
return EOK;
if (!cmdctx) {
return ENOMEM;
if (!req) {
return EIO;
return EOK;
int ret;
return EINVAL;
return ret;
return EOK;
true, false, msgs, &n);
none:
return ret;
int ret;
return ret;
done:
return EOK;
const char *id;
int ret;
SYSDB_CACHE_EXPIRE, 0);
if (!id) {
#define GID_ROFFSET 0
char *username;
char *domname;
const char *use_member;
bool add_domain;
return ret;
add_domain = false;
add_domain = true;
return EOK;
int *_memnum)
const char *tmpstr;
int nlen = 0;
bool add_domain;
return ENOMEM;
goto done;
if (add_domain) {
if (nlen >= 0) {
nlen = 0;
goto done;
if (add_domain) {
goto done;
memnum++;
ret = 0;
done:
return ret;
int *count)
const char *tmpstr;
const char *orig_name;
int fq_len = 0;
num = 0;
goto done;
rsize = 0;
for (i = 0; i < *count; i++) {
rsize = 0;
if (filter_groups) {
if (add_domain) {
if (fq_len >= 0) {
fq_len = 0;
num = 0;
goto done;
if (add_domain) {
num = 0;
goto done;
rsize = 0;
memnum = 0;
if (el) {
&memnum);
num = 0;
goto done;
if (el) {
&memnum);
num = 0;
goto done;
if (memnum) {
num++;
done:
*count = i;
if (num == 0) {
return ENOENT;
return EOK;
int ret;
return EFAULT;
if (ret) {
return ret;
return EOK;
int ret;
while (dom) {
if (!dom) break;
return ENOMEM;
return ENOENT;
return EIO;
return EIO;
return ENOENT;
if (dom) continue;
return ENOENT;
dctx);
return ret;
return EOK;
return ENOENT;
int ret;
int err;
while (dom) {
goto done;
goto done;
goto done;
goto done;
goto done;
dctx);
goto done;
goto done;
done:
return ret;
if (!cmdctx) {
return ENOMEM;
if (!req) {
goto done;
done:
if (!req) {
return NULL;
goto error;
goto error;
return NULL;
return req;
goto error;
if (!step_ctx) {
goto error;
return req;
return req;
void *pvt);
while (dom) {
if (!dom) break;
return EIO;
if (!dpreq) {
if(!cb_ctx) {
return ENOMEM;
return EAGAIN;
return ENOMEM;
if (!te) {
return EAGAIN;
return EOK;
void *pvt)
int ret;
if (err_maj) {
return EOK;
none:
return ret;
int ret;
return EINVAL;
return ret;
return EOK;
if (!cmdctx) {
return ENOMEM;
if (!req) {
return EIO;
return EOK;
int ret;
return ret;
done:
return EOK;
bool changed = false;
int ret;
goto done;
changed = true;
if (id == 0) {
for (j = 0; j < gnum; j++) {
gids[j] = 0;
if (j >= gnum) {
changed = true;
if (!changed) {
for (j = 0; j < gnum; j++) {
if (gids[j] != 0) {
changed = true;
if (changed) {
for (i = 0; i < gnum; i++) {
done:
int skipped = 0;
const char *posix;
return ENOENT;
return ret;
if (orig_primary_gid != 0) {
orig_primary_gid = 0;
for (i = 0; i < num; i++) {
if (!gid) {
skipped++;
return EFAULT;
orig_primary_gid = 0;
if (orig_primary_gid != 0) {
num++;
return ret;
return EOK;
int ret;
return EFAULT;
if (ret) {
return ret;
return EOK;
int ret;
while (dom) {
if (!dom) break;
return ENOMEM;
return ENOENT;
return EIO;
return EIO;
if (dom) continue;
return ENOENT;
dctx);
return ret;
return EOK;
return ENOENT;
int ret;
int err;
bool user_found = false;
bool group_found = false;
char *req_name;
int req_type;
while (dom) {
goto done;
if (!dom) break;
goto done;
goto done;
goto done;
goto done;
goto done;
&msg);
goto done;
user_found = true;
&msg);
goto done;
group_found = true;
goto done;
user_found = true;
goto done;
group_found = true;
goto done;
goto done;
goto done;
req_id = 0;
if (user_found) {
} else if (group_found) {
dctx);
goto done;
goto done;
done:
return ret;
int ret;
return EIO;
return EIO;
return ENOENT;
return ENOENT;
dctx);
return ret;
return EOK;
bool mpg,
size_t c;
return EINVAL;
if (mpg) {
return EOK;
int ret;
const char *sid_str;
return EINVAL;
return ret;
return EOK;
int ret;
const char *orig_name;
const char *cased_name;
const char *fq_name;
return EINVAL;
return ENOMEM;
goto done;
if (add_domain) {
goto done;
goto done;
done:
return ret;
int ret;
return EINVAL;
return ret;
return EOK;
int ret;
return EINVAL;
return ENOENT;
return EFAULT;
if (ret != 0) {
return ret;
case SSS_NSS_GETNAMEBYSID:
case SSS_NSS_GETIDBYSID:
case SSS_NSS_GETSIDBYNAME:
case SSS_NSS_GETSIDBYID:
return EINVAL;
return ret;
return EOK;
const char *wk_name;
const char *wk_dom_name;
int ret;
return ret;
return EINVAL;
return ENOMEM;
return ENOMEM;
return EOK;
const char *sid_str;
int ret;
return EINVAL;
if (!cmdctx) {
return ENOMEM;
if (!dctx) {
goto done;
goto done;
body);
goto done;
goto done;
goto done;
goto done;
goto done;
done:
return nss_cli_protocol_version;
return nss_cmds;