nsssrv_cmd.c revision 1a9f66352070d71a6b998c5afbc268ba6fddc51c
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder NSS Responder
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder Copyright (C) Simo Sorce <ssorce@redhat.com> 2008
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder This program is free software; you can redistribute it and/or modify
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder it under the terms of the GNU General Public License as published by
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder the Free Software Foundation; either version 3 of the License, or
f3a94a197960e548ecd6520bb768cb0d547457bbChristian Maeder (at your option) any later version.
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder This program is distributed in the hope that it will be useful,
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder but WITHOUT ANY WARRANTY; without even the implied warranty of
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder GNU General Public License for more details.
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder You should have received a copy of the GNU General Public License
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder along with this program. If not, see <http://www.gnu.org/licenses/>.
54a0a1e10bd93721cf52dbd9b816c8f108997ec0Christian Maeder#include "responder/nss/nsssrv_mmap_cache.h"
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maederstatic int nss_cmd_send_error(struct nss_cmd_ctx *cmdctx, int err)
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder return sss_cmd_send_error(cmdctx->cctx, err);
54a0a1e10bd93721cf52dbd9b816c8f108997ec0Christian Maederstatic int nss_cmd_send_empty(struct nss_cmd_ctx *cmdctx)
54a0a1e10bd93721cf52dbd9b816c8f108997ec0Christian Maederint nss_cmd_done(struct nss_cmd_ctx *cmdctx, int ret)
54a0a1e10bd93721cf52dbd9b816c8f108997ec0Christian Maeder /* all fine, just return here */
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder /* async processing, just return here */
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder /* very bad error */
54a0a1e10bd93721cf52dbd9b816c8f108997ec0Christian Maeder/***************************
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder * Enumeration procedures *
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder ***************************/
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maedererrno_t nss_setent_add_ref(TALLOC_CTX *memctx,
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder return setent_add_ref(memctx, getent_ctx, &getent_ctx->reqs, req);
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maedervoid nss_setent_notify_error(struct getent_ctx *getent_ctx, errno_t ret)
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder return setent_notify(&getent_ctx->reqs, ret);
e220b2051a2342a9291721e6c7f408860bed01b7Jorina Freya Gerkenvoid nss_setent_notify_done(struct getent_ctx *getent_ctx)
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder return setent_notify_done(&getent_ctx->reqs);
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder/****************************************************************************
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder * PASSWD db related functions
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder ***************************************************************************/
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maedervoid nss_update_pw_memcache(struct nss_ctx *nctx)
e953bea49e7f0e1a43bccf2a66c5e2a2b50848e0Christian Maeder for (dom = nctx->rctx->domains; dom; dom = get_next_domain(dom, false)) {
e953bea49e7f0e1a43bccf2a66c5e2a2b50848e0Christian Maeder ret = sysdb_enumpwent_with_views(nctx, dom, &res);
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder "Failed to enumerate users for domain [%s]\n", dom->name);
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder exp = ldb_msg_find_attr_as_uint64(res->msgs[i],
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder /* names require more manipulation (build up fqname conditionally),
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder * but uidNumber is unique and always resolvable too, so we use
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder * that to update the cache, as it points to the same entry */
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder id = sss_view_ldb_msg_find_attr_as_string(dom, res->msgs[i],
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder "Failed to find uidNumber in %s.\n",
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder ret = sss_mmap_cache_pw_invalidate(nctx->pwd_mc_ctx, &key);
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder "Internal failure in memory cache code: %d [%s]\n",
54a0a1e10bd93721cf52dbd9b816c8f108997ec0Christian Maederstatic gid_t get_gid_override(struct ldb_message *msg,
e953bea49e7f0e1a43bccf2a66c5e2a2b50848e0Christian Maeder ldb_msg_find_attr_as_uint64(msg, SYSDB_GIDNUM, 0);
54a0a1e10bd93721cf52dbd9b816c8f108997ec0Christian Maederstatic const char *get_homedir_override(TALLOC_CTX *mem_ctx,
e953bea49e7f0e1a43bccf2a66c5e2a2b50848e0Christian Maeder const char *orig_name = homedir_ctx->username;
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder homedir = sss_view_ldb_msg_find_attr_as_string(dom, msg, SYSDB_HOMEDIR,
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder /* Subdomain users store FQDN in their name attribute */
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder ret = sss_parse_name_const(mem_ctx, dom->names, orig_name,
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder DEBUG(SSSDBG_MINOR_FAILURE, "Could not parse [%s] into "
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder /* Check to see which homedir_prefix to use. */
e220b2051a2342a9291721e6c7f408860bed01b7Jorina Freya Gerken homedir_ctx->config_homedir_substr = dom->homedir_substr;
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder homedir_ctx->config_homedir_substr = nctx->homedir_substr;
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder /* Check whether we are unconditionally overriding the server
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder * for home directory locations.
e509b6f97f98f96ef258c1c3f7968241da8bde5dTill Mossakowski return expand_homedir_template(mem_ctx, dom->override_homedir,
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder return expand_homedir_template(mem_ctx, nctx->override_homedir,
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder /* In the case of a NULL or empty homedir, check to see if
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder * we have a fallback homedir to use.
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder return expand_homedir_template(mem_ctx, dom->fallback_homedir,
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder return expand_homedir_template(mem_ctx, nctx->fallback_homedir,
e953bea49e7f0e1a43bccf2a66c5e2a2b50848e0Christian Maeder /* Provider can also return template, try to expand it.*/
878d0086bd0aae2d7ad64451035c4e78047b1cffChristian Maeder return expand_homedir_template(mem_ctx, homedir, homedir_ctx);
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maederstatic const char *get_shell_override(TALLOC_CTX *mem_ctx,
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder /* Check whether we are unconditionally overriding the server
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder * for the login shell.
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder user_shell = sss_view_ldb_msg_find_attr_as_string(dom, msg, SYSDB_SHELL,
e953bea49e7f0e1a43bccf2a66c5e2a2b50848e0Christian Maeder /* Check whether there is a default shell specified */
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder return talloc_strdup(mem_ctx, dom->default_shell);
e953bea49e7f0e1a43bccf2a66c5e2a2b50848e0Christian Maeder return talloc_strdup(mem_ctx, nctx->default_shell);
e953bea49e7f0e1a43bccf2a66c5e2a2b50848e0Christian Maeder if (!nctx->allowed_shells && !nctx->vetoed_shells) return talloc_strdup(mem_ctx, user_shell);
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder if (strcmp(nctx->vetoed_shells[i], user_shell) == 0) {
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder DEBUG(SSSDBG_FUNC_DATA, "The shell '%s' is vetoed. "
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder return talloc_strdup(mem_ctx, nctx->shell_fallback);
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder if (strcmp(user_shell, nctx->etc_shells[i]) == 0) {
120eec9ff1748e1ae786e2ab073234198bc0f701Christian Maeder DEBUG(SSSDBG_TRACE_ALL, "Shell %s found in /etc/shells\n",
int *count)
const char *upn;
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++) {
NULL);
add_domain = true;
gid = 0;
NULL);
if (gid == 0) {
if (filter_users) {
if (!packet_initialized) {
packet_initialized = true;
NULL);
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;
if (refresh_expired_interval == 0) {
switch (req_type) {
case SSS_DP_NETGR:
int req_type,
const char *opt_name,
const char *extra,
void *pvt)
return ENOENT;
if (cacheExpire == 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 ret;
return ENOMEM;
return ENOMEM;
return EIO;
return ENOENT;
if (dom) continue;
return ENOENT;
return ret;
return EOK;
return ENOENT;
int ret;
return ENOMEM;
case SSS_NSS_GETPWNAM:
case SSS_NSS_INITGR:
return ret;
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_GETORIGBYNAME:
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_GETORIGBYNAME:
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:
case SSS_NSS_GETORIGBYNAME:
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:
case SSS_NSS_GETORIGBYNAME:
done:
goto 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:
case SSS_NSS_GETORIGBYNAME:
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;
int fq_len = 0;
num = 0;
goto done;
rsize = 0;
for (i = 0; i < *count; i++) {
rsize = 0;
NULL);
add_domain = true;
NULL);
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) {
num = 0;
goto done;
&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;
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) {
SYSDB_GIDNUM, 0);
orig_primary_gid = 0;
for (i = 0; i < num; i++) {
SYSDB_GIDNUM, 0);
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;
const char *sysdb_name;
size_t c;
while (dom) {
if (!dom) break;
return ENOMEM;
return ENOENT;
return EIO;
return ret;
return EINVAL;
return ret;
return EIO;
if (dom) continue;
return ENOENT;
return ret;
return EOK;
return ENOENT;
int ret;
int err;
const char **attrs;
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;
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 *tmp_str;
size_t c;
NULL};
return ENOMEM;
for(extra_attrs_count = 0;
goto done;
sum = 0;
found = 0;
found++;
for (c = 0; c < extra_attrs_count; c++) {
found++;
goto done;
for (c = 0; c < found; c++) {
done:
return ret;
bool apply_no_view,
int ret;
const char *cased_name;
const char *fq_name;
if (apply_no_view) {
NULL);
NULL);
add_domain = true;
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:
case SSS_NSS_GETORIGBYNAME:
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;