proxy_id.c revision 2bc09619e5c8f8c02bcd169ade1878ef28aedb4c
306763c67bb99228487345b32ab8c5c6cd41f23cChristian Maeder Stephen Gallagher <sgallagh@redhat.com>
95c3e5d11dcee331dc3876a9bf0c1d6daa38e2caChristian Maeder Copyright (C) 2010 Red Hat
679d3f541f7a9ede4079e045f7758873bb901872Till Mossakowski This program is free software; you can redistribute it and/or modify
679d3f541f7a9ede4079e045f7758873bb901872Till Mossakowski it under the terms of the GNU General Public License as published by
306763c67bb99228487345b32ab8c5c6cd41f23cChristian Maeder the Free Software Foundation; either version 3 of the License, or
306763c67bb99228487345b32ab8c5c6cd41f23cChristian Maeder (at your option) any later version.
4c8d3c5a9e938633f6147b5a595b9b93bfca99e6Christian Maeder This program is distributed in the hope that it will be useful,
16023c23c9d17743033afd994ad11c386d17b376Christian Maeder but WITHOUT ANY WARRANTY; without even the implied warranty of
0fe1b901cec27c06b8aad7548f56a7cab4dee6a4Till Mossakowski MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
c092fcac4b8f5c524c22ca579189c4487c13edf7Christian Maeder GNU General Public License for more details.
fb7c3ffc41767729db506ad0ac1262ecfb5febf8Christian Maeder You should have received a copy of the GNU General Public License
ba904a15082557e939db689fcfba0c68c9a4f740Christian Maeder along with this program. If not, see <http://www.gnu.org/licenses/>.
c092fcac4b8f5c524c22ca579189c4487c13edf7Christian Maeder/* =Getpwnam-wrapper======================================================*/
e182d0ec56025d97d74829cac75ee31eec12b093Maciek Makowskistatic int save_user(struct sysdb_ctx *sysdb, bool lowercase,
56cd0da55d058b262b1626ddcd78db6bd9a90551Christian Maederhandle_getpw_result(enum nss_status status, struct passwd *pwd,
ba904a15082557e939db689fcfba0c68c9a4f740Christian Maeder struct sss_domain_info *dom, bool *del_user);
ff21411cdf7c6d8d3acebbdebeade1d5ac502b83Christian Maederdelete_user(struct sysdb_ctx *sysdb, const char *name, uid_t uid);
54fb645be0a806e7fd3c0eed5691c2153eb8d518Christian Maeder DEBUG(SSSDBG_TRACE_FUNC, ("Searching user by name (%s)\n", name));
ff21411cdf7c6d8d3acebbdebeade1d5ac502b83Christian Maeder /* FIXME: should we move this call outside the transaction to keep the
4fc3dccf009f8ad9522960e54ab7a5c3d601e342Klaus Luettich * transaction as short as possible ? */
4fc3dccf009f8ad9522960e54ab7a5c3d601e342Klaus Luettich status = ctx->ops.getpwnam_r(name, pwd, buffer, buflen, &ret);
4fc3dccf009f8ad9522960e54ab7a5c3d601e342Klaus Luettich ret = handle_getpw_result(status, pwd, dom, &del_user);
f0e85ee7e4accfc01f46aa0363acc59fcd248e8aTill Mossakowski ("getpwnam failed [%d]: %s\n", ret, strerror(ret)));
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder /* Canonicalize the username in case it was actually an alias */
c092fcac4b8f5c524c22ca579189c4487c13edf7Christian Maeder ret = sysdb_getpwuid(tmpctx, sysdb, uid, &cached_pwd);
ff21411cdf7c6d8d3acebbdebeade1d5ac502b83Christian Maeder /* Non-fatal, attempt to canonicalize online */
ff21411cdf7c6d8d3acebbdebeade1d5ac502b83Christian Maeder DEBUG(SSSDBG_TRACE_FUNC, ("Request to cache failed [%d]: %s\n",
ade09f8be34b77402276c524bf29f2e5df666a94Christian Maeder if (ret == EOK && cached_pwd->count == 1) {
ff21411cdf7c6d8d3acebbdebeade1d5ac502b83Christian Maeder real_name = ldb_msg_find_attr_as_string(cached_pwd->msgs[0],
f3e815e0f960f2c002904b18ad75c149a3827d9fChristian Maeder DEBUG(SSSDBG_MINOR_FAILURE, ("Cached user has no name?\n"));
4b0e0613129ebfc53e3e87985c20a537da91d18dChristian Maeder status = ctx->ops.getpwuid_r(uid, pwd, buffer, buflen, &ret);
21dae7237ac384abdb94a81e00b3f099873ec623Till Mossakowski ret = handle_getpw_result(status, pwd, dom, &del_user);
54fb645be0a806e7fd3c0eed5691c2153eb8d518Christian Maeder ("getpwuid failed [%d]: %s\n", ret, strerror(ret)));
bcd35fcdda4233c42766519772b2e9fbab57f975Christian Maeder /* Both lookups went fine, we can save the user now */
bcd35fcdda4233c42766519772b2e9fbab57f975Christian Maeder ret = save_user(sysdb, !dom->case_sensitive, pwd,
54fb645be0a806e7fd3c0eed5691c2153eb8d518Christian Maeder ("proxy -> getpwnam_r failed for '%s' <%d>: %s\n",
c092fcac4b8f5c524c22ca579189c4487c13edf7Christian Maederhandle_getpw_result(enum nss_status status, struct passwd *pwd,
254df6f22d01eacf7c57b85729e0445747b630d9Christian Maeder struct sss_domain_info *dom, bool *del_user)
17d4f8c5576d93f36cafe68161cdb960ec49ce7cChristian Maeder DEBUG(SSSDBG_MINOR_FAILURE, ("User not found.\n"));
17d4f8c5576d93f36cafe68161cdb960ec49ce7cChristian Maeder DEBUG(SSSDBG_TRACE_FUNC, ("User found: (%s, %d, %d)\n",
c092fcac4b8f5c524c22ca579189c4487c13edf7Christian Maeder /* uid=0 or gid=0 are invalid values */
c092fcac4b8f5c524c22ca579189c4487c13edf7Christian Maeder /* also check that the id is in the valid range for this domain */
54fb645be0a806e7fd3c0eed5691c2153eb8d518Christian Maeder if (OUT_OF_ID_RANGE(pwd->pw_uid, dom->id_min, dom->id_max) ||
26ed2a19326560786ff94dfc462309d6d5d862a8Heng Jiang OUT_OF_ID_RANGE(pwd->pw_gid, dom->id_min, dom->id_max)) {
1b05bdb88b90d3c947351f262d7ae7d68f0a4a6fTill Mossakowski ("User filtered out! (id out of range)\n"));
74b841a4b332085d5fd79975a13313c2681ae595Christian Maeder ("Remote back end is not available. Entering offline mode\n"));
95c3e5d11dcee331dc3876a9bf0c1d6daa38e2caChristian Maeder DEBUG(SSSDBG_OP_FAILURE, ("Unknown return code %d\n", status));
16023c23c9d17743033afd994ad11c386d17b376Christian Maederdelete_user(struct sysdb_ctx *sysdb, const char *name, uid_t uid)
4b0e0613129ebfc53e3e87985c20a537da91d18dChristian Maeder ("User %s does not exist (or is invalid) on remote server,"
1e3950d5c1f0e041dd7677856e43f07796567d5bChristian Maederstatic int save_user(struct sysdb_ctx *sysdb, bool lowercase,
16023c23c9d17743033afd994ad11c386d17b376Christian Maeder if (pwd->pw_shell && pwd->pw_shell[0] != '\0') {
ef2affdc0cdf3acd5c051597c04ab9b08a346a7dChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE, ("Allocation error ?!\n"));
3bcf8bbafdda23d3c6be2deec9e68f98223b78c1Christian Maeder lower = sss_tc_utf8_str_tolower(attrs, pwd->pw_name);
5a87ed846cc38cb0e3adf8f736d95614d3e724a3Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot convert name to lowercase\n"));
f3faf4e4346b6224a3aaeeac11bac8b5c8932a29Christian Maeder ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS, lower);
16023c23c9d17743033afd994ad11c386d17b376Christian Maeder DEBUG(SSSDBG_OP_FAILURE, ("Could not add name alias\n"));
ef2affdc0cdf3acd5c051597c04ab9b08a346a7dChristian Maeder cased_alias = sss_get_cased_name(attrs, alias, !lowercase);
46947810076241f06f3e2919edb2289ed84d6c15Christian Maeder ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS, cased_alias);
ddd8734e5b3802a1a6c908af6b1e870af76c932dChristian Maeder DEBUG(SSSDBG_OP_FAILURE, ("Could not add name alias\n"));
ddd8734e5b3802a1a6c908af6b1e870af76c932dChristian Maeder DEBUG(SSSDBG_OP_FAILURE, ("Could not add user to cache\n"));
54fb645be0a806e7fd3c0eed5691c2153eb8d518Christian Maeder/* =Getpwuid-wrapper======================================================*/
54fb645be0a806e7fd3c0eed5691c2153eb8d518Christian Maeder DEBUG(SSSDBG_TRACE_FUNC, ("Searching user by uid (%d)\n", uid));
54fb645be0a806e7fd3c0eed5691c2153eb8d518Christian Maeder status = ctx->ops.getpwuid_r(uid, pwd, buffer, buflen, &ret);
54fb645be0a806e7fd3c0eed5691c2153eb8d518Christian Maeder ret = handle_getpw_result(status, pwd, dom, &del_user);
54fb645be0a806e7fd3c0eed5691c2153eb8d518Christian Maeder ("getpwuid failed [%d]: %s\n", ret, strerror(ret)));
16023c23c9d17743033afd994ad11c386d17b376Christian Maeder ret = save_user(sysdb, !dom->case_sensitive, pwd,
fb7c3ffc41767729db506ad0ac1262ecfb5febf8Christian Maeder ("proxy -> getpwuid_r failed for '%d' <%d>: %s\n",
fb7c3ffc41767729db506ad0ac1262ecfb5febf8Christian Maeder/* =Getpwent-wrapper======================================================*/
16023c23c9d17743033afd994ad11c386d17b376Christian Maeder DEBUG(SSSDBG_TRACE_LIBS, ("Enumerating users\n"));
16023c23c9d17743033afd994ad11c386d17b376Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to start transaction\n"));
c616e681da8c052b62e14247fea522da099ac0e4Christian Maeder /* always zero out the pwd structure */
3d4e57e86d8aee818b589cd1029838e0accade55Christian Maeder /* get entry */
d21dd452cd68abade683103a5c0cfe6d02c5f17bTill Mossakowski status = ctx->ops.getpwent_r(pwd, buffer, buflen, &ret);
16023c23c9d17743033afd994ad11c386d17b376Christian Maeder /* buffer too small ? */
3d4e57e86d8aee818b589cd1029838e0accade55Christian Maeder newbuf = talloc_realloc_size(tmpctx, buffer, buflen);
37e30366abd83c00a5d5447b45694627fd783de8Cui Jian /* we are done here */
37e30366abd83c00a5d5447b45694627fd783de8Cui Jian DEBUG(SSSDBG_TRACE_LIBS, ("Enumeration completed.\n"));
876bd2c70a93981cc80f8376284616bce4a0fefcChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to commit transaction\n"));
54fb645be0a806e7fd3c0eed5691c2153eb8d518Christian Maeder DEBUG(SSSDBG_TRACE_LIBS, ("User found (%s, %d, %d)\n",
2d2826f9db2c17275f91b0104940a60a2f9fd44dChristian Maeder /* uid=0 or gid=0 are invalid values */
ef2affdc0cdf3acd5c051597c04ab9b08a346a7dChristian Maeder /* also check that the id is in the valid range for this domain
3d4e57e86d8aee818b589cd1029838e0accade55Christian Maeder if (OUT_OF_ID_RANGE(pwd->pw_uid, dom->id_min, dom->id_max) ||
3d4e57e86d8aee818b589cd1029838e0accade55Christian Maeder OUT_OF_ID_RANGE(pwd->pw_gid, dom->id_min, dom->id_max)) {
22250d2b3c9f86fe19cba665d71c301de03db142Christian Maeder DEBUG(SSSDBG_OP_FAILURE, ("User [%s] filtered out! (id out"
3d4e57e86d8aee818b589cd1029838e0accade55Christian Maeder ret = save_user(sysdb, !dom->case_sensitive, pwd,
3d4e57e86d8aee818b589cd1029838e0accade55Christian Maeder /* Do not fail completely on errors.
3d4e57e86d8aee818b589cd1029838e0accade55Christian Maeder * Just report the failure to save and go on */
3d4e57e86d8aee818b589cd1029838e0accade55Christian Maeder DEBUG(SSSDBG_OP_FAILURE, ("Failed to store user %s."
} while (again);
done:
if (in_transaction) {
return ret;
char *lower;
const char *cased_alias;
bool in_transaction = false;
if (!tmp_ctx) {
return ENOMEM;
goto done;
in_transaction = true;
if (!attrs) {
goto done;
if (ret) {
goto done;
goto done;
if (!attrs) {
if (!attrs) {
goto done;
if (!lower) {
goto done;
if (ret) {
goto done;
if (alias) {
if (!cased_alias) {
return ENOMEM;
if (ret) {
goto done;
now);
if (ret) {
goto done;
goto done;
in_transaction = false;
done:
if (in_transaction) {
return ret;
size_t i;
goto done;
goto done;
done:
return ret;
char *newbuf;
if (*buflen == 0) {
if (!newbuf) {
return NULL;
return *buffer;
static errno_t
bool *delete_group)
switch (status) {
case NSS_STATUS_TRYAGAIN:
return EAGAIN;
case NSS_STATUS_NOTFOUND:
*delete_group = true;
case NSS_STATUS_SUCCESS:
*delete_group = true;
case NSS_STATUS_UNAVAIL:
return ENXIO;
return EIO;
return EOK;
const char *name)
char *buffer = 0;
bool delete_group = false;
int ret;
if (!tmpctx) {
return ENOMEM;
if (!grp) {
goto done;
if (!buffer) {
goto done;
goto done;
if (!real_name) {
buflen = 0;
if (!buffer) {
goto done;
goto done;
if (delete_group) {
goto done;
if (ret) {
goto done;
done:
if (ret) {
return ret;
bool delete_group = false;
int ret;
if (!tmpctx) {
return ENOMEM;
if (!grp) {
goto done;
if (!buffer) {
goto done;
if (delete_group) {
goto done;
if (ret) {
goto done;
done:
if (ret) {
return ret;
bool in_transaction = false;
char *buffer;
char *newbuf;
int ret;
bool again;
if (!tmpctx) {
return ENOMEM;
if (!grp) {
goto done;
if (!buffer) {
goto done;
if (ret) {
goto done;
in_transaction = true;
goto done;
again = false;
switch (status) {
case NSS_STATUS_TRYAGAIN:
if (!newbuf) {
goto done;
again = true;
case NSS_STATUS_NOTFOUND:
goto done;
in_transaction = false;
case NSS_STATUS_SUCCESS:
again = true;
if (ret) {
again = true;
case NSS_STATUS_UNAVAIL:
} while (again);
done:
if (in_transaction) {
return ret;
const char *name)
bool in_transaction = false;
char *buffer;
int ret;
bool del_user;
if (!tmpctx) {
return ENOMEM;
if (!pwd) {
goto fail;
if (!buffer) {
goto fail;
if (ret) {
goto fail;
in_transaction = true;
if (ret) {
goto fail;
if (del_user) {
if (ret) {
goto fail;
goto done;
if (!real_name) {
if (ret) {
goto done;
if (del_user) {
if (ret) {
goto fail;
goto done;
if (ret) {
goto fail;
goto fail;
done:
if (ret) {
goto fail;
in_transaction = false;
fail:
if (in_transaction) {
return ret;
long int limit;
long int size;
long int num;
long int num_gids;
int ret;
num_gids = 0;
if (!gids) {
return ENOMEM;
if (!gids) {
return ENOMEM;
switch (status) {
case NSS_STATUS_SUCCESS:
for (i = 0; i < num_gids; i++) {
if (ret) {
return ret;
return ret;
int ret;
char *endptr;
struct proxy_id_ctx);
case BE_FILTER_ENUM:
case BE_FILTER_NAME:
case BE_FILTER_IDNUM:
case BE_FILTER_ENUM:
case BE_FILTER_NAME:
case BE_FILTER_IDNUM:
case BE_REQ_NETGROUP:
case BE_REQ_SERVICES:
case BE_FILTER_NAME:
case BE_FILTER_IDNUM:
case BE_FILTER_ENUM:
if (ret) {