From e60775cb7b634f887cea2c1755ac2c417b804a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 30 Aug 2020 21:25:12 +0200 Subject: [PATCH] shared: merge {user,group}-record-nss.{c,h} They both are both short and contain similar parts and various helper will be shared between both parts of the code so it's easier to use a single file. --- src/nss-systemd/nss-systemd.c | 2 +- src/nss-systemd/userdb-glue.c | 2 +- src/shared/group-record-nss.c | 219 ---------------------------------- src/shared/group-record-nss.h | 15 --- src/shared/meson.build | 2 - src/shared/user-record-nss.c | 213 +++++++++++++++++++++++++++++++++ src/shared/user-record-nss.h | 11 +- src/shared/userdb.c | 1 - src/userdb/userwork.c | 1 - 9 files changed, 225 insertions(+), 241 deletions(-) delete mode 100644 src/shared/group-record-nss.c delete mode 100644 src/shared/group-record-nss.h diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c index 5dc5aacdff..0e8c13f7ea 100644 --- a/src/nss-systemd/nss-systemd.c +++ b/src/nss-systemd/nss-systemd.c @@ -6,13 +6,13 @@ #include "env-util.h" #include "errno-util.h" #include "fd-util.h" -#include "group-record-nss.h" #include "macro.h" #include "nss-systemd.h" #include "nss-util.h" #include "pthread-util.h" #include "signal-util.h" #include "strv.h" +#include "user-record-nss.h" #include "user-util.h" #include "userdb-glue.h" #include "userdb.h" diff --git a/src/nss-systemd/userdb-glue.c b/src/nss-systemd/userdb-glue.c index 8e5b3eba6c..2ac299d9a7 100644 --- a/src/nss-systemd/userdb-glue.c +++ b/src/nss-systemd/userdb-glue.c @@ -2,9 +2,9 @@ #include "env-util.h" #include "fd-util.h" -#include "group-record-nss.h" #include "nss-systemd.h" #include "strv.h" +#include "user-record-nss.h" #include "user-record.h" #include "userdb-glue.h" #include "userdb.h" diff --git a/src/shared/group-record-nss.c b/src/shared/group-record-nss.c deleted file mode 100644 index b018a46e18..0000000000 --- a/src/shared/group-record-nss.c +++ /dev/null @@ -1,219 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1+ */ - -#include "errno-util.h" -#include "group-record-nss.h" -#include "libcrypt-util.h" -#include "strv.h" - -int nss_group_to_group_record( - const struct group *grp, - const struct sgrp *sgrp, - GroupRecord **ret) { - - _cleanup_(group_record_unrefp) GroupRecord *g = NULL; - int r; - - assert(grp); - assert(ret); - - if (isempty(grp->gr_name)) - return -EINVAL; - - if (sgrp && !streq_ptr(sgrp->sg_namp, grp->gr_name)) - return -EINVAL; - - g = group_record_new(); - if (!g) - return -ENOMEM; - - g->group_name = strdup(grp->gr_name); - if (!g->group_name) - return -ENOMEM; - - g->members = strv_copy(grp->gr_mem); - if (!g->members) - return -ENOMEM; - - g->gid = grp->gr_gid; - - if (sgrp) { - if (looks_like_hashed_password(sgrp->sg_passwd)) { - g->hashed_password = strv_new(sgrp->sg_passwd); - if (!g->hashed_password) - return -ENOMEM; - } - - r = strv_extend_strv(&g->members, sgrp->sg_mem, 1); - if (r < 0) - return r; - - g->administrators = strv_copy(sgrp->sg_adm); - if (!g->administrators) - return -ENOMEM; - } - - r = json_build(&g->json, JSON_BUILD_OBJECT( - JSON_BUILD_PAIR("groupName", JSON_BUILD_STRING(g->group_name)), - JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(g->gid)), - JSON_BUILD_PAIR_CONDITION(!strv_isempty(g->members), "members", JSON_BUILD_STRV(g->members)), - JSON_BUILD_PAIR_CONDITION(!strv_isempty(g->hashed_password), "privileged", JSON_BUILD_OBJECT(JSON_BUILD_PAIR("hashedPassword", JSON_BUILD_STRV(g->hashed_password)))), - JSON_BUILD_PAIR_CONDITION(!strv_isempty(g->administrators), "administrators", JSON_BUILD_STRV(g->administrators)))); - if (r < 0) - return r; - - g->mask = USER_RECORD_REGULAR | - (!strv_isempty(g->hashed_password) ? USER_RECORD_PRIVILEGED : 0); - - *ret = TAKE_PTR(g); - return 0; -} - -int nss_sgrp_for_group(const struct group *grp, struct sgrp *ret_sgrp, char **ret_buffer) { - size_t buflen = 4096; - int r; - - assert(grp); - assert(ret_sgrp); - assert(ret_buffer); - - for (;;) { - _cleanup_free_ char *buf = NULL; - struct sgrp sgrp, *result; - - buf = malloc(buflen); - if (!buf) - return -ENOMEM; - - r = getsgnam_r(grp->gr_name, &sgrp, buf, buflen, &result); - if (r == 0) { - if (!result) - return -ESRCH; - - *ret_sgrp = *result; - *ret_buffer = TAKE_PTR(buf); - return 0; - } - if (r < 0) - return -EIO; /* Weird, this should not return negative! */ - if (r != ERANGE) - return -r; - - if (buflen > SIZE_MAX / 2) - return -ERANGE; - - buflen *= 2; - buf = mfree(buf); - } -} - -int nss_group_record_by_name( - const char *name, - bool with_shadow, - GroupRecord **ret) { - - _cleanup_free_ char *buf = NULL, *sbuf = NULL; - struct group grp, *result; - bool incomplete = false; - size_t buflen = 4096; - struct sgrp sgrp, *sresult = NULL; - int r; - - assert(name); - assert(ret); - - for (;;) { - buf = malloc(buflen); - if (!buf) - return -ENOMEM; - - r = getgrnam_r(name, &grp, buf, buflen, &result); - if (r == 0) { - if (!result) - return -ESRCH; - - break; - } - - if (r < 0) - return log_debug_errno(SYNTHETIC_ERRNO(EIO), "getgrnam_r() returned a negative value"); - if (r != ERANGE) - return -r; - if (buflen > SIZE_MAX / 2) - return -ERANGE; - - buflen *= 2; - buf = mfree(buf); - } - - if (with_shadow) { - r = nss_sgrp_for_group(result, &sgrp, &sbuf); - if (r < 0) { - log_debug_errno(r, "Failed to do shadow lookup for group %s, ignoring: %m", result->gr_name); - incomplete = ERRNO_IS_PRIVILEGE(r); - } else - sresult = &sgrp; - } else - incomplete = true; - - r = nss_group_to_group_record(result, sresult, ret); - if (r < 0) - return r; - - (*ret)->incomplete = incomplete; - return 0; -} - -int nss_group_record_by_gid( - gid_t gid, - bool with_shadow, - GroupRecord **ret) { - - _cleanup_free_ char *buf = NULL, *sbuf = NULL; - struct group grp, *result; - bool incomplete = false; - size_t buflen = 4096; - struct sgrp sgrp, *sresult = NULL; - int r; - - assert(ret); - - for (;;) { - buf = malloc(buflen); - if (!buf) - return -ENOMEM; - - r = getgrgid_r(gid, &grp, buf, buflen, &result); - if (r == 0) { - if (!result) - return -ESRCH; - break; - } - - if (r < 0) - return log_debug_errno(SYNTHETIC_ERRNO(EIO), "getgrgid_r() returned a negative value"); - if (r != ERANGE) - return -r; - if (buflen > SIZE_MAX / 2) - return -ERANGE; - - buflen *= 2; - buf = mfree(buf); - } - - if (with_shadow) { - r = nss_sgrp_for_group(result, &sgrp, &sbuf); - if (r < 0) { - log_debug_errno(r, "Failed to do shadow lookup for group %s, ignoring: %m", result->gr_name); - incomplete = ERRNO_IS_PRIVILEGE(r); - } else - sresult = &sgrp; - } else - incomplete = true; - - r = nss_group_to_group_record(result, sresult, ret); - if (r < 0) - return r; - - (*ret)->incomplete = incomplete; - return 0; -} diff --git a/src/shared/group-record-nss.h b/src/shared/group-record-nss.h deleted file mode 100644 index 077c22d89f..0000000000 --- a/src/shared/group-record-nss.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1+ */ -#pragma once - -#include -#include - -#include "group-record.h" - -/* Synthesize GroupRecord objects from NSS data */ - -int nss_group_to_group_record(const struct group *grp, const struct sgrp *sgrp, GroupRecord **ret); -int nss_sgrp_for_group(const struct group *grp, struct sgrp *ret_sgrp, char **ret_buffer); - -int nss_group_record_by_name(const char *name, bool with_shadow, GroupRecord **ret); -int nss_group_record_by_gid(gid_t gid, bool with_shadow, GroupRecord **ret); diff --git a/src/shared/meson.build b/src/shared/meson.build index c149ff4cd8..572ac1de64 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -113,8 +113,6 @@ shared_sources = files(''' geneve-util.h gpt.c gpt.h - group-record-nss.c - group-record-nss.h group-record.c group-record.h id128-print.c diff --git a/src/shared/user-record-nss.c b/src/shared/user-record-nss.c index b4c35b8a53..0da77dfc39 100644 --- a/src/shared/user-record-nss.c +++ b/src/shared/user-record-nss.c @@ -290,3 +290,216 @@ int nss_user_record_by_uid( (*ret)->incomplete = incomplete; return 0; } + +int nss_group_to_group_record( + const struct group *grp, + const struct sgrp *sgrp, + GroupRecord **ret) { + + _cleanup_(group_record_unrefp) GroupRecord *g = NULL; + int r; + + assert(grp); + assert(ret); + + if (isempty(grp->gr_name)) + return -EINVAL; + + if (sgrp && !streq_ptr(sgrp->sg_namp, grp->gr_name)) + return -EINVAL; + + g = group_record_new(); + if (!g) + return -ENOMEM; + + g->group_name = strdup(grp->gr_name); + if (!g->group_name) + return -ENOMEM; + + g->members = strv_copy(grp->gr_mem); + if (!g->members) + return -ENOMEM; + + g->gid = grp->gr_gid; + + if (sgrp) { + if (looks_like_hashed_password(sgrp->sg_passwd)) { + g->hashed_password = strv_new(sgrp->sg_passwd); + if (!g->hashed_password) + return -ENOMEM; + } + + r = strv_extend_strv(&g->members, sgrp->sg_mem, 1); + if (r < 0) + return r; + + g->administrators = strv_copy(sgrp->sg_adm); + if (!g->administrators) + return -ENOMEM; + } + + r = json_build(&g->json, JSON_BUILD_OBJECT( + JSON_BUILD_PAIR("groupName", JSON_BUILD_STRING(g->group_name)), + JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(g->gid)), + JSON_BUILD_PAIR_CONDITION(!strv_isempty(g->members), "members", JSON_BUILD_STRV(g->members)), + JSON_BUILD_PAIR_CONDITION(!strv_isempty(g->hashed_password), "privileged", JSON_BUILD_OBJECT(JSON_BUILD_PAIR("hashedPassword", JSON_BUILD_STRV(g->hashed_password)))), + JSON_BUILD_PAIR_CONDITION(!strv_isempty(g->administrators), "administrators", JSON_BUILD_STRV(g->administrators)))); + if (r < 0) + return r; + + g->mask = USER_RECORD_REGULAR | + (!strv_isempty(g->hashed_password) ? USER_RECORD_PRIVILEGED : 0); + + *ret = TAKE_PTR(g); + return 0; +} + +int nss_sgrp_for_group(const struct group *grp, struct sgrp *ret_sgrp, char **ret_buffer) { + size_t buflen = 4096; + int r; + + assert(grp); + assert(ret_sgrp); + assert(ret_buffer); + + for (;;) { + _cleanup_free_ char *buf = NULL; + struct sgrp sgrp, *result; + + buf = malloc(buflen); + if (!buf) + return -ENOMEM; + + r = getsgnam_r(grp->gr_name, &sgrp, buf, buflen, &result); + if (r == 0) { + if (!result) + return -ESRCH; + + *ret_sgrp = *result; + *ret_buffer = TAKE_PTR(buf); + return 0; + } + if (r < 0) + return -EIO; /* Weird, this should not return negative! */ + if (r != ERANGE) + return -r; + + if (buflen > SIZE_MAX / 2) + return -ERANGE; + + buflen *= 2; + buf = mfree(buf); + } +} + +int nss_group_record_by_name( + const char *name, + bool with_shadow, + GroupRecord **ret) { + + _cleanup_free_ char *buf = NULL, *sbuf = NULL; + struct group grp, *result; + bool incomplete = false; + size_t buflen = 4096; + struct sgrp sgrp, *sresult = NULL; + int r; + + assert(name); + assert(ret); + + for (;;) { + buf = malloc(buflen); + if (!buf) + return -ENOMEM; + + r = getgrnam_r(name, &grp, buf, buflen, &result); + if (r == 0) { + if (!result) + return -ESRCH; + + break; + } + + if (r < 0) + return log_debug_errno(SYNTHETIC_ERRNO(EIO), "getgrnam_r() returned a negative value"); + if (r != ERANGE) + return -r; + if (buflen > SIZE_MAX / 2) + return -ERANGE; + + buflen *= 2; + buf = mfree(buf); + } + + if (with_shadow) { + r = nss_sgrp_for_group(result, &sgrp, &sbuf); + if (r < 0) { + log_debug_errno(r, "Failed to do shadow lookup for group %s, ignoring: %m", result->gr_name); + incomplete = ERRNO_IS_PRIVILEGE(r); + } else + sresult = &sgrp; + } else + incomplete = true; + + r = nss_group_to_group_record(result, sresult, ret); + if (r < 0) + return r; + + (*ret)->incomplete = incomplete; + return 0; +} + +int nss_group_record_by_gid( + gid_t gid, + bool with_shadow, + GroupRecord **ret) { + + _cleanup_free_ char *buf = NULL, *sbuf = NULL; + struct group grp, *result; + bool incomplete = false; + size_t buflen = 4096; + struct sgrp sgrp, *sresult = NULL; + int r; + + assert(ret); + + for (;;) { + buf = malloc(buflen); + if (!buf) + return -ENOMEM; + + r = getgrgid_r(gid, &grp, buf, buflen, &result); + if (r == 0) { + if (!result) + return -ESRCH; + break; + } + + if (r < 0) + return log_debug_errno(SYNTHETIC_ERRNO(EIO), "getgrgid_r() returned a negative value"); + if (r != ERANGE) + return -r; + if (buflen > SIZE_MAX / 2) + return -ERANGE; + + buflen *= 2; + buf = mfree(buf); + } + + if (with_shadow) { + r = nss_sgrp_for_group(result, &sgrp, &sbuf); + if (r < 0) { + log_debug_errno(r, "Failed to do shadow lookup for group %s, ignoring: %m", result->gr_name); + incomplete = ERRNO_IS_PRIVILEGE(r); + } else + sresult = &sgrp; + } else + incomplete = true; + + r = nss_group_to_group_record(result, sresult, ret); + if (r < 0) + return r; + + (*ret)->incomplete = incomplete; + return 0; +} diff --git a/src/shared/user-record-nss.h b/src/shared/user-record-nss.h index 0eb78d5b52..e2a87f664c 100644 --- a/src/shared/user-record-nss.h +++ b/src/shared/user-record-nss.h @@ -1,15 +1,24 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +#include +#include #include #include +#include "group-record.h" #include "user-record.h" -/* Synthesizes a UserRecord object from NSS data */ +/* Synthesize UserRecord and GroupRecord objects from NSS data */ int nss_passwd_to_user_record(const struct passwd *pwd, const struct spwd *spwd, UserRecord **ret); int nss_spwd_for_passwd(const struct passwd *pwd, struct spwd *ret_spwd, char **ret_buffer); int nss_user_record_by_name(const char *name, bool with_shadow, UserRecord **ret); int nss_user_record_by_uid(uid_t uid, bool with_shadow, UserRecord **ret); + +int nss_group_to_group_record(const struct group *grp, const struct sgrp *sgrp, GroupRecord **ret); +int nss_sgrp_for_group(const struct group *grp, struct sgrp *ret_sgrp, char **ret_buffer); + +int nss_group_record_by_name(const char *name, bool with_shadow, GroupRecord **ret); +int nss_group_record_by_gid(gid_t gid, bool with_shadow, GroupRecord **ret); diff --git a/src/shared/userdb.c b/src/shared/userdb.c index 94120862df..57e58a61a9 100644 --- a/src/shared/userdb.c +++ b/src/shared/userdb.c @@ -6,7 +6,6 @@ #include "dlfcn-util.h" #include "errno-util.h" #include "fd-util.h" -#include "group-record-nss.h" #include "missing_syscall.h" #include "parse-util.h" #include "set.h" diff --git a/src/userdb/userwork.c b/src/userdb/userwork.c index d7202099be..a68011b3fc 100644 --- a/src/userdb/userwork.c +++ b/src/userdb/userwork.c @@ -7,7 +7,6 @@ #include "env-util.h" #include "fd-util.h" -#include "group-record-nss.h" #include "group-record.h" #include "io-util.h" #include "main-func.h"