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