summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/db/sysdb.h5
-rw-r--r--server/db/sysdb_search.c2
-rw-r--r--server/providers/data_provider.c8
-rw-r--r--server/providers/proxy.c76
-rw-r--r--server/responder/nss/nsssrv_cmd.c119
5 files changed, 160 insertions, 50 deletions
diff --git a/server/db/sysdb.h b/server/db/sysdb.h
index 9e2cb39d..ec87ec07 100644
--- a/server/db/sysdb.h
+++ b/server/db/sysdb.h
@@ -107,11 +107,12 @@
SYSDB_USERPIC, \
SYSDB_LAST_UPDATE, \
NULL}
-#define SYSDB_GRNAM_ATTRS {SYSDB_NAME, SYSDB_GIDNUM, \
+#define SYSDB_GRSRC_ATTRS {SYSDB_NAME, SYSDB_GIDNUM, \
SYSDB_LAST_UPDATE, SYSDB_LEGACY_MEMBER, \
"objectClass", \
NULL}
-#define SYSDB_GRPW_ATTRS {SYSDB_NAME, SYSDB_LAST_UPDATE, \
+#define SYSDB_GRPW_ATTRS {SYSDB_NAME, SYSDB_UIDNUM, \
+ SYSDB_LAST_UPDATE, \
"objectClass", \
NULL}
diff --git a/server/db/sysdb_search.c b/server/db/sysdb_search.c
index 42470b63..7dd467e8 100644
--- a/server/db/sysdb_search.c
+++ b/server/db/sysdb_search.c
@@ -481,7 +481,7 @@ static int get_grp_callback(struct ldb_request *req,
static void grp_search(struct sysdb_req *sysreq, void *ptr)
{
struct sysdb_search_ctx *sctx;
- static const char *attrs[] = SYSDB_GRNAM_ATTRS;
+ static const char *attrs[] = SYSDB_GRSRC_ATTRS;
struct ldb_request *req;
struct ldb_dn *base_dn;
int ret;
diff --git a/server/providers/data_provider.c b/server/providers/data_provider.c
index 183fdc4e..4614250c 100644
--- a/server/providers/data_provider.c
+++ b/server/providers/data_provider.c
@@ -604,14 +604,6 @@ static int dp_get_account_info(DBusMessage *message, struct sbus_conn_ctx *sconn
goto respond;
}
- /* nothing to do for local */
- if (strcasecmp(domain, "LOCAL") == 0) {
- dpret = DP_ERR_OK;
- errmsg = "Success";
- ret = EOK;
- goto respond;
- }
-
/* all domains, fire off a request for each backend */
if (strcmp(domain, "*") == 0) {
dpreq = talloc(dpcli->dpctx, struct dp_request);
diff --git a/server/providers/proxy.c b/server/providers/proxy.c
index cc1da169..c87b482f 100644
--- a/server/providers/proxy.c
+++ b/server/providers/proxy.c
@@ -310,6 +310,13 @@ static void get_pw_name(struct be_req *req, char *name)
break;
case NSS_STATUS_SUCCESS:
+ /* FIXME: verify user does not have uid=0 or gid=0 as these are invalid
+ * values */
+ if (data->pwd->pw_uid == 0 || data->pwd->pw_gid == 0) {
+ ret = sysdb_transaction(data, req->be_ctx->sysdb, del_db_entry, data);
+ break;
+ }
+
ret = sysdb_transaction(data, req->be_ctx->sysdb, set_pw_name, data);
break;
@@ -360,6 +367,14 @@ static void get_pw_uid(struct be_req *req, uid_t uid)
break;
case NSS_STATUS_SUCCESS:
+ /* FIXME: verify user does not have gid=0 as these are invalid values */
+ if (data->pwd->pw_gid == 0) {
+ data->dn = sysdb_user_dn(req->be_ctx->sysdb, data,
+ req->be_ctx->domain, data->pwd->pw_name);
+ ret = sysdb_transaction(data, req->be_ctx->sysdb, del_db_entry, data);
+ break;
+ }
+
ret = sysdb_transaction(data, req->be_ctx->sysdb, set_pw_name, data);
break;
@@ -427,6 +442,12 @@ retry:
break;
case NSS_STATUS_SUCCESS:
+ /* FIXME: verify user does not have uid=0 or gid=0 as these are invalid
+ * values */
+ if (data->pwd->pw_uid == 0 || data->pwd->pw_gid == 0) {
+ goto retry; /* skip */
+ }
+
ret = sysdb_legacy_store_user(req, data->req->be_ctx->domain,
data->pwd->pw_name,
data->pwd->pw_passwd,
@@ -486,7 +507,7 @@ static void enum_users(struct be_req *req)
}
}
-static void del_gr_uid(struct sysdb_req *req, void *pvt)
+static void del_gr_gid(struct sysdb_req *req, void *pvt)
{
struct proxy_data *data = talloc_get_type(pvt, struct proxy_data);
struct sysdb_ctx *ctx;
@@ -561,6 +582,12 @@ static void get_gr_name(struct be_req *req, char *name)
break;
case NSS_STATUS_SUCCESS:
+ /* FIXME: verify group does not have gid=0 as this is invalid */
+ if (data->grp->gr_gid == 0) {
+ ret = sysdb_transaction(data, req->be_ctx->sysdb, del_db_entry, data);
+ break;
+ }
+
ret = sysdb_transaction(data, req->be_ctx->sysdb, set_gr_name, data);
break;
@@ -607,10 +634,18 @@ static void get_gr_gid(struct be_req *req, gid_t gid)
switch (status) {
case NSS_STATUS_NOTFOUND:
data->grp->gr_gid = gid;
- ret = sysdb_transaction(data, req->be_ctx->sysdb, del_gr_uid, data);
+ ret = sysdb_transaction(data, req->be_ctx->sysdb, del_gr_gid, data);
break;
case NSS_STATUS_SUCCESS:
+ /* FIXME: verify group does not have gid=0 as this is invalid */
+ if (data->grp->gr_gid == 0) {
+ data->dn = sysdb_group_dn(req->be_ctx->sysdb, data,
+ req->be_ctx->domain, data->grp->gr_name);
+ ret = sysdb_transaction(data, req->be_ctx->sysdb, del_db_entry, data);
+ break;
+ }
+
ret = sysdb_transaction(data, req->be_ctx->sysdb, set_gr_name, data);
break;
@@ -676,6 +711,10 @@ retry:
break;
case NSS_STATUS_SUCCESS:
+ /* FIXME: verify group does not have gid=0 as this is invalid */
+ if (data->grp->gr_gid == 0) {
+ goto retry;
+ }
ret = sysdb_legacy_store_group(req, data->req->be_ctx->domain,
data->grp->gr_name,
data->grp->gr_gid,
@@ -835,14 +874,13 @@ static void get_user_groups(void *pvt, int error, struct ldb_result *ignore)
return proxy_return(data, ENOMEM, NULL);
gid = data->pwd->pw_gid;
- name = talloc_strdup(data, data->pwd->pw_name);
- if (!name)
- return proxy_return(data, ENOMEM, NULL);
+ name = data->pwd->pw_name;
retry:
status = data->ctx->ops.initgroups_dyn(name, gid,
&start, &num,
&data->groups, limit, &ret);
+
switch (status) {
case NSS_STATUS_TRYAGAIN:
/* buffer too small ? */
@@ -916,9 +954,24 @@ static void get_initgr_user(struct be_req *req, char *name)
break;
case NSS_STATUS_SUCCESS:
- data->next_fn = get_user_groups;
- ret = sysdb_transaction(data, req->be_ctx->sysdb, set_pw_name, data);
- break;
+ /* FIXME: verify user does not have uid=0 or gid=0 as these are invalid
+ * values */
+ if (data->pwd->pw_uid == 0 || data->pwd->pw_gid == 0) {
+ ret = sysdb_transaction(data, req->be_ctx->sysdb, del_db_entry, data);
+ break;
+ }
+
+ if (ctx->ops.initgroups_dyn) {
+ data->next_fn = get_user_groups;
+ ret = sysdb_transaction(data, req->be_ctx->sysdb, set_pw_name, data);
+ } else {
+ status = ctx->ops.setgrent();
+ if (status != NSS_STATUS_SUCCESS)
+ return proxy_reply(req, EIO, "Operation failed");
+
+ ret = sysdb_transaction(data, req->be_ctx->sysdb, get_gr_entry, data);
+ break;
+ }
default:
DEBUG(2, ("proxy -> getpwnam_r failed for '%s' (%d)[%s]\n",
@@ -1181,9 +1234,10 @@ int sssm_proxy_init(struct be_ctx *bectx, struct be_mod_ops **ops, void **pvt_da
ctx->ops.initgroups_dyn = proxy_dlsym(handle, "_nss_%s_initgroups_dyn",
libname);
if (!ctx->ops.initgroups_dyn) {
- DEBUG(0, ("Failed to load NSS fns, error: %s\n", dlerror()));
- ret = ELIBBAD;
- goto done;
+ DEBUG(1, ("The '%s' library does not provides the "
+ "_nss_XXX_initgroups_dyn function!\n"
+ "initgroups will be slow as it will require "
+ "full groups enumeration!\n", libname));
}
*ops = &proxy_mod_ops;
diff --git a/server/responder/nss/nsssrv_cmd.c b/server/responder/nss/nsssrv_cmd.c
index 0a4703c9..26c51fac 100644
--- a/server/responder/nss/nsssrv_cmd.c
+++ b/server/responder/nss/nsssrv_cmd.c
@@ -192,6 +192,7 @@ static int fill_pwent(struct sss_packet *packet,
int i, ret, num;
bool add_domain = info->fqnames;
const char *domain = info->name;
+ int ncret;
if (add_domain) dom_len = strlen(domain) +1;
@@ -214,16 +215,24 @@ static int fill_pwent(struct sss_packet *packet,
}
if (filter_users) {
- ret = nss_ncache_check_user(nctx->ncache,
+ ncret = nss_ncache_check_user(nctx->ncache,
nctx->neg_timeout,
domain, name);
- if (ret == EEXIST) {
+ if (ncret == EEXIST) {
DEBUG(4, ("User [%s@%s] filtered out! (negative cache)\n",
name, domain));
continue;
}
}
+ /* check that the uid is valid for this domain */
+ if ((info->id_min && (uid < info->id_min)) ||
+ (info->id_max && (uid > info->id_max))) {
+ DEBUG(4, ("User [%s@%s] filtered out! (id out of range)\n",
+ name, domain));
+ continue;
+ }
+
gecos = ldb_msg_find_attr_as_string(msg, SYSDB_GECOS, NULL);
homedir = ldb_msg_find_attr_as_string(msg, SYSDB_HOMEDIR, NULL);
shell = ldb_msg_find_attr_as_string(msg, SYSDB_SHELL, NULL);
@@ -489,6 +498,7 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx)
uint8_t *body;
size_t blen;
int ret, num, i;
+ int ncret;
nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx);
@@ -522,9 +532,9 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx)
if (domname) {
/* verify this user has not yet been negatively cached,
* or has been permanently filtered */
- ret = nss_ncache_check_user(nctx->ncache, nctx->neg_timeout,
+ ncret = nss_ncache_check_user(nctx->ncache, nctx->neg_timeout,
domname, cmdctx->name);
- if (ret != ENOENT) {
+ if (ncret != ENOENT) {
DEBUG(3, ("User [%s] does not exist! (negative cache)\n",
rawname));
ret = ENOENT;
@@ -568,9 +578,9 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx)
for (i = 0; i < num; i++) {
/* verify this user has not yet been negatively cached,
* or has been permanently filtered */
- ret = nss_ncache_check_user(nctx->ncache, nctx->neg_timeout,
+ ncret = nss_ncache_check_user(nctx->ncache, nctx->neg_timeout,
domains[i], cmdctx->name);
- if (ret != ENOENT) {
+ if (ncret != ENOENT) {
DEBUG(3, ("User [%s] does not exist! (neg cache)\n",
rawname));
continue;
@@ -850,6 +860,7 @@ static int nss_cmd_getpwuid(struct cli_ctx *cctx)
uint8_t *body;
size_t blen;
int i, num, ret;
+ int ncret;
nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx);
@@ -885,9 +896,9 @@ static int nss_cmd_getpwuid(struct cli_ctx *cctx)
for (i = 0; i < num; i++) {
/* verify this user has not yet been negatively cached,
* or has been permanently filtered */
- ret = nss_ncache_check_uid(nctx->ncache, nctx->neg_timeout,
+ ncret = nss_ncache_check_uid(nctx->ncache, nctx->neg_timeout,
cmdctx->id);
- if (ret != ENOENT) {
+ if (ncret != ENOENT) {
DEBUG(3, ("Uid [%lu] does not exist! (negative cache)\n",
(unsigned long)cmdctx->id));
continue;
@@ -895,6 +906,15 @@ static int nss_cmd_getpwuid(struct cli_ctx *cctx)
info = btreemap_get_value(cctx->rctx->domain_map, domains[i]);
+ /* check that the uid is valid for this domain */
+ if ((info->id_min && (cmdctx->id < info->id_min)) ||
+ (info->id_max && (cmdctx->id > info->id_max))) {
+ DEBUG(4, ("Uid [%lu] does not exist in domain [%s]! "
+ "(id out of range)\n",
+ (unsigned long)cmdctx->id, domains[i]));
+ continue;
+ }
+
cmdctx->nr++;
dctx = talloc_zero(cmdctx, struct nss_dom_ctx);
@@ -1310,15 +1330,16 @@ static int fill_grent(struct sss_packet *packet,
struct ldb_message *msg;
uint8_t *body;
const char *name;
- uint32_t gid;
+ uint32_t gid, uid;
size_t rsize, rp, blen, mnump;
- int i, j, ret, num, memnum;
+ int i, j, n, ret, num, memnum;
bool get_members;
bool skip_members;
size_t dom_len = 0;
size_t name_len;
bool add_domain = info->fqnames;
const char *domain = info->name;
+ int ncret;
if (add_domain) dom_len = strlen(domain) +1;
@@ -1355,9 +1376,9 @@ static int fill_grent(struct sss_packet *packet,
skip_members = false;
if (filter_groups) {
- ret = nss_ncache_check_group(nctx->ncache,
+ ncret = nss_ncache_check_group(nctx->ncache,
nctx->neg_timeout, domain, name);
- if (ret == EEXIST) {
+ if (ncret == EEXIST) {
DEBUG(4, ("Group [%s@%s] filtered out! (negative cache)\n",
name, domain));
skip_members = true;
@@ -1365,6 +1386,15 @@ static int fill_grent(struct sss_packet *packet,
}
}
+ /* check that the gid is valid for this domain */
+ if ((info->id_min && (gid < info->id_min)) ||
+ (info->id_max && (gid > info->id_max))) {
+ DEBUG(4, ("User [%s@%s] filtered out! (id out of range)\n",
+ name, domain));
+ skip_members = true;
+ continue;
+ }
+
/* fill in gid and name and set pointer for number of members */
name_len = strlen(name)+1;
rsize = 2 * sizeof(uint32_t) + name_len +2;
@@ -1402,8 +1432,18 @@ static int fill_grent(struct sss_packet *packet,
if (el) {
/* legacy */
memnum = el->num_values;
-
+ n = 0;
for (j = 0; j < memnum; j++) {
+
+ ncret = nss_ncache_check_user(nctx->ncache,
+ nctx->neg_timeout, domain,
+ (char *)el->values[j].data);
+ if (ncret == EEXIST) {
+ DEBUG(4, ("User [%s@%s] filtered out! (negative cache)\n",
+ name, domain));
+ continue;
+ }
+
rsize = el->values[j].length + 1;
if (add_domain) {
name_len = rsize;
@@ -1424,10 +1464,12 @@ static int fill_grent(struct sss_packet *packet,
memcpy(&body[rp], domain, dom_len);
}
body[blen-1] = '\0';
+
+ n++;
}
sss_packet_get_body(packet, &body, &blen);
- ((uint32_t *)(&body[mnump]))[0] = memnum; /* num members */
+ ((uint32_t *)(&body[mnump]))[0] = n; /* num members */
} else {
get_members = true;
@@ -1449,20 +1491,29 @@ static int fill_grent(struct sss_packet *packet,
SYSDB_USER_CLASS)) {
name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
- if (!name) {
+ uid = ldb_msg_find_attr_as_uint64(msg, SYSDB_UIDNUM, 0);
+ if (!name || !uid) {
DEBUG(1, ("Incomplete user object! Aborting\n"));
num = 0;
goto done;
}
- ret = nss_ncache_check_user(nctx->ncache,
+ ncret = nss_ncache_check_user(nctx->ncache,
nctx->neg_timeout, domain, name);
- if (ret == EEXIST) {
+ if (ncret == EEXIST) {
DEBUG(4, ("User [%s@%s] filtered out! (negative cache)\n",
name, domain));
continue;
}
+ /* check that the uid is valid for this domain */
+ if ((info->id_min && (uid < info->id_min)) ||
+ (info->id_max && (uid > info->id_max))) {
+ DEBUG(4, ("User [%s@%s] filtered out! (id out of range)\n",
+ name, domain));
+ continue;
+ }
+
rsize = strlen(name) + 1;
if (add_domain) {
name_len = rsize;
@@ -1706,6 +1757,7 @@ static int nss_cmd_getgrnam(struct cli_ctx *cctx)
uint8_t *body;
size_t blen;
int ret, num, i;
+ int ncret;
nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx);
@@ -1738,9 +1790,9 @@ static int nss_cmd_getgrnam(struct cli_ctx *cctx)
if (domname) {
/* verify this user has not yet been negatively cached,
* or has been permanently filtered */
- ret = nss_ncache_check_group(nctx->ncache, nctx->neg_timeout,
+ ncret = nss_ncache_check_group(nctx->ncache, nctx->neg_timeout,
domname, cmdctx->name);
- if (ret != ENOENT) {
+ if (ncret != ENOENT) {
DEBUG(3, ("Group [%s] does not exist! (negative cache)\n",
rawname));
ret = ENOENT;
@@ -1783,9 +1835,9 @@ static int nss_cmd_getgrnam(struct cli_ctx *cctx)
for (i = 0; i < num; i++) {
/* verify this user has not yet been negatively cached,
* or has been permanently filtered */
- ret = nss_ncache_check_group(nctx->ncache, nctx->neg_timeout,
+ ncret = nss_ncache_check_group(nctx->ncache, nctx->neg_timeout,
domains[i], cmdctx->name);
- if (ret != ENOENT) {
+ if (ncret != ENOENT) {
DEBUG(3, ("Group [%s] does not exist! (negative cache)\n",
rawname));
continue;
@@ -2046,6 +2098,7 @@ static int nss_cmd_getgrgid(struct cli_ctx *cctx)
uint8_t *body;
size_t blen;
int i, num, ret;
+ int ncret;
nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx);
@@ -2081,9 +2134,9 @@ static int nss_cmd_getgrgid(struct cli_ctx *cctx)
for (i = 0; i < num; i++) {
/* verify this user has not yet been negatively cached,
* or has been permanently filtered */
- ret = nss_ncache_check_gid(nctx->ncache, nctx->neg_timeout,
+ ncret = nss_ncache_check_gid(nctx->ncache, nctx->neg_timeout,
cmdctx->id);
- if (ret != ENOENT) {
+ if (ncret != ENOENT) {
DEBUG(3, ("Gid [%lu] does not exist! (negative cache)\n",
(unsigned long)cmdctx->id));
continue;
@@ -2091,6 +2144,15 @@ static int nss_cmd_getgrgid(struct cli_ctx *cctx)
info = btreemap_get_value(cctx->rctx->domain_map, domains[i]);
+ /* check that the uid is valid for this domain */
+ if ((info->id_min && (cmdctx->id < info->id_min)) ||
+ (info->id_max && (cmdctx->id > info->id_max))) {
+ DEBUG(4, ("Gid [%lu] does not exist! (id out of range)\n",
+ (unsigned long)cmdctx->id));
+ continue;
+ }
+
+
cmdctx->nr++;
dctx = talloc_zero(cmdctx, struct nss_dom_ctx);
@@ -2787,6 +2849,7 @@ static int nss_cmd_initgroups(struct cli_ctx *cctx)
uint8_t *body;
size_t blen;
int ret, num, i;
+ int ncret;
nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx);
@@ -2813,14 +2876,14 @@ static int nss_cmd_initgroups(struct cli_ctx *cctx)
goto done;
}
DEBUG(4, ("Requesting info for [%s] from [%s]\n",
- cmdctx->name, dctx->domain->name));
+ cmdctx->name, domname ? : "<ALL>"));
if (domname) {
/* verify this user has not yet been negatively cached,
* or has been permanently filtered */
- ret = nss_ncache_check_user(nctx->ncache, nctx->neg_timeout,
+ ncret = nss_ncache_check_user(nctx->ncache, nctx->neg_timeout,
domname, cmdctx->name);
- if (ret != ENOENT) {
+ if (ncret != ENOENT) {
DEBUG(3, ("User [%s] does not exist! (negative cache)\n",
rawname));
ret = ENOENT;
@@ -2864,9 +2927,9 @@ static int nss_cmd_initgroups(struct cli_ctx *cctx)
for (i = 0; i < num; i++) {
/* verify this user has not yet been negatively cached,
* or has been permanently filtered */
- ret = nss_ncache_check_user(nctx->ncache, nctx->neg_timeout,
+ ncret = nss_ncache_check_user(nctx->ncache, nctx->neg_timeout,
domains[i], cmdctx->name);
- if (ret != ENOENT) {
+ if (ncret != ENOENT) {
DEBUG(3, ("User does not exist! (neg cache)\n"));
continue;
}