summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/db/sysdb.h33
-rw-r--r--server/responder/nss/nsssrv_cmd.c294
2 files changed, 109 insertions, 218 deletions
diff --git a/server/db/sysdb.h b/server/db/sysdb.h
index 4c92c377..a3299859 100644
--- a/server/db/sysdb.h
+++ b/server/db/sysdb.h
@@ -66,6 +66,7 @@
#define SYSDB_LAST_UPDATE "lastUpdate"
#define SYSDB_CACHE_EXPIRE "dataExpireTimestamp"
+#define SYSDB_INITGR_EXPIRE "initgrExpireTimestamp"
#define SYSDB_CACHEDPWD "cachedPassword"
@@ -101,41 +102,29 @@
#define SYSDB_GETCACHED_FILTER "(&"SYSDB_UC")("SYSDB_LAST_LOGIN">=%lu))"
+#define SYSDB_DEFAULT_ATTRS SYSDB_LAST_UPDATE, \
+ SYSDB_CACHE_EXPIRE, \
+ SYSDB_INITGR_EXPIRE, \
+ "objectClass"
+
#define SYSDB_PW_ATTRS {SYSDB_NAME, SYSDB_UIDNUM, \
SYSDB_GIDNUM, SYSDB_GECOS, \
SYSDB_HOMEDIR, SYSDB_SHELL, \
- SYSDB_LAST_UPDATE, SYSDB_CACHE_EXPIRE, \
- "objectClass", \
+ SYSDB_DEFAULT_ATTRS, \
NULL}
-#define SYSDB_USER_ATTRS {SYSDB_DEFAULTGROUP, \
- SYSDB_GECOS, \
- SYSDB_HOMEDIR, \
- SYSDB_SHELL, \
- SYSDB_FULLNAME, \
- SYSDB_LOCALE, \
- SYSDB_KEYBOARD, \
- SYSDB_SESSION, \
- SYSDB_LAST_LOGIN, \
- SYSDB_USERPIC, \
- SYSDB_LAST_UPDATE, SYSDB_CACHE_EXPIRE, \
- NULL}
#define SYSDB_GRSRC_ATTRS {SYSDB_NAME, SYSDB_GIDNUM, \
- SYSDB_LAST_UPDATE, SYSDB_CACHE_EXPIRE, \
- "objectClass", \
+ SYSDB_DEFAULT_ATTRS, \
NULL}
#define SYSDB_GRPW_ATTRS {SYSDB_NAME, SYSDB_UIDNUM, \
- SYSDB_LAST_UPDATE, SYSDB_CACHE_EXPIRE, \
- "objectClass", \
+ SYSDB_DEFAULT_ATTRS, \
NULL}
#define SYSDB_GRENT_ATTRS {SYSDB_NAME, SYSDB_UIDNUM, SYSDB_MEMBEROF, \
- SYSDB_LAST_UPDATE, SYSDB_CACHE_EXPIRE, \
- "objectClass", \
+ SYSDB_DEFAULT_ATTRS, \
NULL}
#define SYSDB_INITGR_ATTR SYSDB_MEMBEROF
#define SYSDB_INITGR_ATTRS {SYSDB_GIDNUM, \
- SYSDB_LAST_UPDATE, SYSDB_CACHE_EXPIRE, \
- "objectClass", \
+ SYSDB_DEFAULT_ATTRS, \
NULL}
#define SYSDB_TMPL_USER SYSDB_NAME"=%s,"SYSDB_TMPL_USER_BASE
diff --git a/server/responder/nss/nsssrv_cmd.c b/server/responder/nss/nsssrv_cmd.c
index b2a2035c..a029baf4 100644
--- a/server/responder/nss/nsssrv_cmd.c
+++ b/server/responder/nss/nsssrv_cmd.c
@@ -280,7 +280,7 @@ static errno_t check_cache(struct nss_dom_ctx *dctx,
int timeout;
time_t now;
uint64_t lastUpdate;
- uint64_t cacheExpire;
+ uint64_t cacheExpire = 0;
uint64_t midpoint_refresh;
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
@@ -305,8 +305,14 @@ static errno_t check_cache(struct nss_dom_ctx *dctx,
lastUpdate = ldb_msg_find_attr_as_uint64(res->msgs[0],
SYSDB_LAST_UPDATE, 0);
- cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
- SYSDB_CACHE_EXPIRE, 0);
+ if (req_type == SSS_DP_INITGROUPS) {
+ cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
+ SYSDB_INITGR_EXPIRE, 1);
+ }
+ if (cacheExpire == 0) {
+ cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
+ SYSDB_CACHE_EXPIRE, 0);
+ }
midpoint_refresh = 0;
if(nctx->cache_refresh_percent) {
@@ -2780,147 +2786,47 @@ done:
return EOK;
}
-static void nss_cmd_initgr_callback(void *ptr, int status,
- struct ldb_result *res)
+static int fill_initgr(struct sss_packet *packet, struct ldb_result *res)
{
- struct nss_cmd_ctx *cmdctx = talloc_get_type(ptr, struct nss_cmd_ctx);
- struct cli_ctx *cctx = cmdctx->cctx;
uint8_t *body;
size_t blen;
- uint32_t gid;
- uint32_t num;
- int ret, i;
+ gid_t gid;
+ int ret, i, num;
- /* create response packet */
- ret = sss_packet_new(cctx->creq, 0,
- sss_packet_get_cmd(cctx->creq->in),
- &cctx->creq->out);
- if (ret != EOK) {
- NSS_CMD_FATAL_ERROR(cctx);
+ if (res->count == 0) {
+ return ENOENT;
}
- if (status != LDB_SUCCESS) {
- sss_packet_set_error(cctx->creq->out, status);
- goto done;
- }
+ /* one less, the first one is the user entry */
+ num = res->count -1;
- num = res->count;
- ret = sss_packet_grow(cctx->creq->out, (2 + num) * sizeof(uint32_t));
+ ret = sss_packet_grow(packet, (2 + res->count) * sizeof(uint32_t));
if (ret != EOK) {
- sss_packet_set_error(cctx->creq->out, ret);
- goto done;
+ return ret;
}
- sss_packet_get_body(cctx->creq->out, &body, &blen);
+ sss_packet_get_body(packet, &body, &blen);
+ /* skip first entry, it's the user entry */
for (i = 0; i < num; i++) {
- gid = ldb_msg_find_attr_as_uint64(res->msgs[i], SYSDB_GIDNUM, 0);
+ gid = ldb_msg_find_attr_as_uint64(res->msgs[i + 1], SYSDB_GIDNUM, 0);
if (!gid) {
DEBUG(1, ("Incomplete group object for initgroups! Aborting\n"));
- sss_packet_set_error(cctx->creq->out, EIO);
- num = 0;
- goto done;
+ return EFAULT;
}
- ((uint32_t *)body)[2+i] = gid;
+ ((uint32_t *)body)[2 + i] = gid;
}
((uint32_t *)body)[0] = num; /* num results */
((uint32_t *)body)[1] = 0; /* reserved */
-done:
- sss_cmd_done(cctx, cmdctx);
-}
-
-static void nss_cmd_getinitgr_callback(uint16_t err_maj, uint32_t err_min,
- const char *err_msg, void *ptr)
-{
- struct nss_dom_ctx *dctx = talloc_get_type(ptr, struct nss_dom_ctx);
- struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
- struct cli_ctx *cctx = cmdctx->cctx;
- struct sysdb_ctx *sysdb;
- int ret;
-
- if (err_maj) {
- DEBUG(2, ("Unable to get information from Data Provider\n"
- "Error: %u, %u, %s\n"
- "Will try to return what we have in cache\n",
- (unsigned int)err_maj, (unsigned int)err_min, err_msg));
- }
-
- ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
- dctx->domain, &sysdb);
- if (ret != EOK) {
- DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
- NSS_CMD_FATAL_ERROR(cctx);
- }
- ret = sysdb_initgroups(cmdctx, sysdb,
- dctx->domain, cmdctx->name,
- nss_cmd_initgr_callback, cmdctx);
- if (ret != EOK) {
- DEBUG(1, ("Failed to make request to our cache!\n"));
-
- ret = nss_cmd_send_error(cmdctx, ret);
- if (ret != EOK) {
- NSS_CMD_FATAL_ERROR(cctx);
- }
- sss_cmd_done(cctx, cmdctx);
- }
+ return EOK;
}
-static void nss_cmd_getinit_callback(void *ptr, int status,
- struct ldb_result *res);
-
-static void nss_cmd_getinitnam_dp_callback(uint16_t err_maj, uint32_t err_min,
- const char *err_msg, void *ptr)
-{
- struct nss_dom_ctx *dctx = talloc_get_type(ptr, struct nss_dom_ctx);
- struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
- struct cli_ctx *cctx = cmdctx->cctx;
- struct sysdb_ctx *sysdb;
- int ret;
-
- if (err_maj) {
- DEBUG(2, ("Unable to get information from Data Provider\n"
- "Error: %u, %u, %s\n"
- "Will try to return what we have in cache\n",
- (unsigned int)err_maj, (unsigned int)err_min, err_msg));
-
- if (!dctx->res) {
- /* return 0 results */
- dctx->res = talloc_zero(dctx, struct ldb_result);
- if (!dctx->res) {
- ret = ENOMEM;
- goto done;
- }
- }
-
- nss_cmd_getinit_callback(dctx, LDB_SUCCESS, dctx->res);
- return;
- }
-
- ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
- dctx->domain, &sysdb);
- if (ret != EOK) {
- DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
- NSS_CMD_FATAL_ERROR(cctx);
- }
- ret = sysdb_getpwnam(cmdctx, sysdb,
- dctx->domain, cmdctx->name,
- nss_cmd_getinit_callback, dctx);
+static void nss_cmd_getinitgr_dp_callback(uint16_t err_maj, uint32_t err_min,
+ const char *err_msg, void *ptr);
-done:
- if (ret != EOK) {
- DEBUG(1, ("Failed to make request to our cache!\n"));
-
- ret = nss_cmd_send_error(cmdctx, ret);
- if (ret != EOK) {
- NSS_CMD_FATAL_ERROR(cctx);
- }
- sss_cmd_done(cctx, cmdctx);
- }
-}
-
-static void nss_cmd_getinit_callback(void *ptr, int status,
- struct ldb_result *res)
+static void nss_cmd_getinitgr_callback(void *ptr, int status,
+ struct ldb_result *res)
{
struct nss_dom_ctx *dctx = talloc_get_type(ptr, struct nss_dom_ctx);
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
@@ -2928,11 +2834,8 @@ static void nss_cmd_getinit_callback(void *ptr, int status,
struct sss_domain_info *dom;
struct sysdb_ctx *sysdb;
struct nss_ctx *nctx;
- int timeout;
- uint64_t cacheExpire;
uint8_t *body;
size_t blen;
- bool call_provider = false;
bool neghit = false;
int ncret;
int ret;
@@ -2949,55 +2852,15 @@ static void nss_cmd_getinit_callback(void *ptr, int status,
}
if (dctx->check_provider) {
- switch (res->count) {
- case 0:
- call_provider = true;
- break;
-
- case 1:
- cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
- SYSDB_CACHE_EXPIRE, 0);
- if (cacheExpire < time(NULL)) {
- call_provider = true;
- }
- break;
-
- default:
- DEBUG(1, ("getpwnam call returned more than one result !?!\n"));
- ret = nss_cmd_send_error(cmdctx, ENOENT);
- if (ret != EOK) {
- NSS_CMD_FATAL_ERROR(cctx);
- }
- sss_cmd_done(cctx, cmdctx);
- return;
- }
- }
-
- if (call_provider) {
-
- /* dont loop forever :-) */
- dctx->check_provider = false;
- timeout = SSS_CLI_SOCKET_TIMEOUT/2;
-
- /* keep around current data in case backend is offline */
- if (res->count) {
- dctx->res = talloc_steal(dctx, res);
- }
-
- ret = sss_dp_send_acct_req(cctx->rctx, cmdctx,
- nss_cmd_getinitnam_dp_callback, dctx,
- timeout, dctx->domain->name, SSS_DP_USER,
- cmdctx->name, 0);
+ ret = check_cache(dctx, nctx, res,
+ SSS_DP_INITGROUPS, cmdctx->name, 0,
+ nss_cmd_getinitgr_dp_callback);
if (ret != EOK) {
- DEBUG(3, ("Failed to dispatch request: %d(%s)\n",
- ret, strerror(ret)));
- ret = nss_cmd_send_error(cmdctx, ret);
- if (ret != EOK) {
- NSS_CMD_FATAL_ERROR(cctx);
- }
- sss_cmd_done(cctx, cmdctx);
+ /* Anything but EOK means we should reenter the mainloop
+ * because we may be refreshing the cache
+ */
+ return;
}
- return;
}
switch (res->count) {
@@ -3047,9 +2910,9 @@ static void nss_cmd_getinit_callback(void *ptr, int status,
DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
NSS_CMD_FATAL_ERROR(cctx);
}
- ret = sysdb_getpwnam(cmdctx, sysdb,
- dctx->domain, cmdctx->name,
- nss_cmd_getinit_callback, dctx);
+ ret = sysdb_initgroups(cmdctx, sysdb,
+ dctx->domain, cmdctx->name,
+ nss_cmd_getinitgr_callback, dctx);
if (ret != EOK) {
DEBUG(1, ("Failed to make request to our cache!\n"));
}
@@ -3081,35 +2944,74 @@ static void nss_cmd_getinit_callback(void *ptr, int status,
((uint32_t *)body)[1] = 0; /* reserved */
break;
- case 1:
+ default:
- timeout = SSS_CLI_SOCKET_TIMEOUT/2;
- ret = sss_dp_send_acct_req(cctx->rctx, cmdctx,
- nss_cmd_getinitgr_callback, dctx,
- timeout, dctx->domain->name,
- SSS_DP_INITGROUPS,
- cmdctx->name, 0);
+ DEBUG(6, ("Returning initgr for user [%s]\n", cmdctx->name));
+
+ ret = sss_packet_new(cctx->creq, 0,
+ sss_packet_get_cmd(cctx->creq->in),
+ &cctx->creq->out);
if (ret != EOK) {
- DEBUG(3, ("Failed to dispatch request: %d(%s)\n",
- ret, strerror(ret)));
- ret = nss_cmd_send_error(cmdctx, ret);
- if (ret != EOK) {
- NSS_CMD_FATAL_ERROR(cctx);
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ ret = fill_initgr(cctx->creq->out, res);
+ if (ret == ENOENT) {
+ ret = fill_empty(cctx->creq->out);
+ }
+ sss_packet_set_error(cctx->creq->out, ret);
+ }
+
+ sss_cmd_done(cctx, cmdctx);
+}
+
+static void nss_cmd_getinitgr_dp_callback(uint16_t err_maj, uint32_t err_min,
+ const char *err_msg, void *ptr)
+{
+ struct nss_dom_ctx *dctx = talloc_get_type(ptr, struct nss_dom_ctx);
+ struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
+ struct cli_ctx *cctx = cmdctx->cctx;
+ struct sysdb_ctx *sysdb;
+ int ret;
+
+ if (err_maj) {
+ DEBUG(2, ("Unable to get information from Data Provider\n"
+ "Error: %u, %u, %s\n"
+ "Will try to return what we have in cache\n",
+ (unsigned int)err_maj, (unsigned int)err_min, err_msg));
+
+ if (!dctx->res) {
+ /* return 0 results */
+ dctx->res = talloc_zero(dctx, struct ldb_result);
+ if (!dctx->res) {
+ ret = ENOMEM;
+ goto done;
}
- sss_cmd_done(cctx, cmdctx);
}
+ nss_cmd_getinitgr_callback(dctx, LDB_SUCCESS, dctx->res);
return;
+ }
- default:
- DEBUG(1, ("getpwnam call returned more than one result !?!\n"));
- ret = nss_cmd_send_error(cmdctx, ENOENT);
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ ret = sysdb_initgroups(cmdctx, sysdb,
+ dctx->domain, cmdctx->name,
+ nss_cmd_getinitgr_callback, dctx);
+
+done:
+ if (ret != EOK) {
+ DEBUG(1, ("Failed to make request to our cache!\n"));
+
+ ret = nss_cmd_send_error(cmdctx, ret);
if (ret != EOK) {
NSS_CMD_FATAL_ERROR(cctx);
}
+ sss_cmd_done(cctx, cmdctx);
}
-
- sss_cmd_done(cctx, cmdctx);
}
/* for now, if we are online, try to always query the backend */
@@ -3227,9 +3129,9 @@ static int nss_cmd_initgroups(struct cli_ctx *cctx)
ret = EFAULT;
goto done;
}
- ret = sysdb_getpwnam(cmdctx, sysdb,
- dctx->domain, cmdctx->name,
- nss_cmd_getinit_callback, dctx);
+ ret = sysdb_initgroups(cmdctx, sysdb,
+ dctx->domain, cmdctx->name,
+ nss_cmd_getinitgr_callback, dctx);
if (ret != EOK) {
DEBUG(1, ("Failed to make request to our cache!\n"));
}