summaryrefslogtreecommitdiffstats
path: root/server/responder
diff options
context:
space:
mode:
authorSimo Sorce <ssorce@redhat.com>2009-04-06 15:54:00 -0400
committerSimo Sorce <ssorce@redhat.com>2009-04-07 14:27:18 -0400
commit65f90758d4df5581bc94746d47a1548ed8ff738b (patch)
tree754b1c1ae79db7d74190b69f69d10405f445d111 /server/responder
parent1e13ce7e631f8e5ab0de0b5d1abaa6496259a552 (diff)
downloadsssd-65f90758d4df5581bc94746d47a1548ed8ff738b.tar.gz
sssd-65f90758d4df5581bc94746d47a1548ed8ff738b.tar.xz
sssd-65f90758d4df5581bc94746d47a1548ed8ff738b.zip
Unify name parsing and reposnder headers
Use common sss_parse_name function in all responders Simplify responder headers by combining common,cmd,dp in one header and add name parse structure as part of the common responder context.
Diffstat (limited to 'server/responder')
-rw-r--r--server/responder/common/responder.h (renamed from server/responder/common/responder_cmd.h)38
-rw-r--r--server/responder/common/responder_cmd.c2
-rw-r--r--server/responder/common/responder_common.c136
-rw-r--r--server/responder/common/responder_common.h26
-rw-r--r--server/responder/common/responder_dp.c2
-rw-r--r--server/responder/common/responder_dp.h3
-rw-r--r--server/responder/nss/nsssrv.c28
-rw-r--r--server/responder/nss/nsssrv.h10
-rw-r--r--server/responder/nss/nsssrv_cmd.c257
-rw-r--r--server/responder/pam/pamsrv.c2
-rw-r--r--server/responder/pam/pamsrv.h2
-rw-r--r--server/responder/pam/pamsrv_cmd.c65
12 files changed, 328 insertions, 243 deletions
diff --git a/server/responder/common/responder_cmd.h b/server/responder/common/responder.h
index eb3bd082e..4b6bfeee1 100644
--- a/server/responder/common/responder_cmd.h
+++ b/server/responder/common/responder.h
@@ -19,14 +19,17 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef __SSSSRV_CMD_H__
-#define __SSSSRV_CMD_H__
+#ifndef __SSS_RESPONDER_H__
+#define __SSS_RESPONDER_H__
#include <stdint.h>
#include <sys/un.h>
+#include <pcre.h>
+#include "config.h"
#include "talloc.h"
#include "tevent.h"
#include "ldb.h"
+#include "sbus/sssd_dbus.h"
#include "../sss_client/sss_cli.h"
#include "util/btreemap.h"
@@ -40,6 +43,13 @@ struct cli_request {
struct sss_packet *out;
};
+struct sss_names_ctx {
+ char *re_pattern;
+ char *fq_fmt;
+
+ pcre *re;
+};
+
struct resp_ctx {
struct tevent_context *ev;
struct tevent_fd *lfde;
@@ -62,6 +72,8 @@ struct resp_ctx {
const char *confdb_service_path;
struct sbus_method *dp_methods;
+ struct sss_names_ctx *names;
+
void *pvt_ctx;
};
@@ -80,8 +92,28 @@ struct sss_cmd_table {
int (*fn)(struct cli_ctx *cctx);
};
+/* responder_common.c */
+int sss_process_init(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct confdb_ctx *cdb,
+ struct sbus_method sss_sbus_methods[],
+ struct sss_cmd_table sss_cmds[],
+ const char *sss_pipe_name,
+ const char *sss_priv_pipe_name,
+ const char *confdb_service_path,
+ struct sbus_method dp_methods[],
+ struct resp_ctx **responder_ctx);
+
+int sss_parse_name(TALLOC_CTX *memctx,
+ struct sss_names_ctx *snctx,
+ const char *orig, char **domain, char **name);
+
+/* responder_cmd.c */
int sss_cmd_execute(struct cli_ctx *cctx, struct sss_cmd_table *sss_cmds);
void sss_cmd_done(struct cli_ctx *cctx, void *freectx);
int sss_cmd_get_version(struct cli_ctx *cctx);
-#endif /* __SSSSRV_CMD_H__ */
+/* responder_dp.c */
+int sss_dp_init(struct resp_ctx *rctx, struct sbus_method dp_methods[]);
+
+#endif /* __SSS_RESPONDER_H__ */
diff --git a/server/responder/common/responder_cmd.c b/server/responder/common/responder_cmd.c
index a434b3e12..33caa032b 100644
--- a/server/responder/common/responder_cmd.c
+++ b/server/responder/common/responder_cmd.c
@@ -20,7 +20,7 @@
*/
#include <errno.h>
#include "util/util.h"
-#include "responder/common/responder_cmd.h"
+#include "responder/common/responder.h"
#include "responder/common/responder_packet.h"
diff --git a/server/responder/common/responder_common.c b/server/responder/common/responder_common.c
index fa024d53e..855c78a71 100644
--- a/server/responder/common/responder_common.c
+++ b/server/responder/common/responder_common.c
@@ -36,15 +36,15 @@
#include "dbus/dbus.h"
#include "sbus/sssd_dbus.h"
#include "util/btreemap.h"
-#include "responder/common/responder_common.h"
+#include "responder/common/responder.h"
#include "responder/common/responder_packet.h"
-#include "responder/common/responder_cmd.h"
-#include "responder/common/responder_dp.h"
#include "providers/data_provider.h"
#include "monitor/monitor_sbus.h"
#include "monitor/monitor_interfaces.h"
#include "sbus/sbus_client.h"
+#define NAMES_CONFIG "config/names"
+
static void set_nonblocking(int fd)
{
unsigned v;
@@ -487,6 +487,62 @@ done:
return retval;
}
+int sss_names_init(struct resp_ctx *rctx)
+{
+ struct sss_names_ctx *ctx;
+ const char *errstr;
+ int errval;
+ int errpos;
+ int ret;
+
+ ctx = talloc_zero(rctx, struct sss_names_ctx);
+ if (!ctx) return ENOMEM;
+
+ ret = confdb_get_string(rctx->cdb, ctx, NAMES_CONFIG,
+ "re-expression", NULL, &ctx->re_pattern);
+ if (ret != EOK) goto done;
+
+ if (!ctx->re_pattern) {
+ ctx->re_pattern = talloc_strdup(ctx,
+ "(?<name>[^@]+)@?(?<domain>[^@]*$)");
+ if (!ctx->re_pattern) {
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
+ ret = confdb_get_string(rctx->cdb, ctx, NAMES_CONFIG,
+ "full-name-format", NULL, &ctx->fq_fmt);
+ if (ret != EOK) goto done;
+
+ if (!ctx->fq_fmt) {
+ ctx->fq_fmt = talloc_strdup(ctx, "%1$s@%2$s");
+ if (!ctx->fq_fmt) {
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
+ ctx->re = pcre_compile2(ctx->re_pattern,
+ PCRE_DUPNAMES | PCRE_EXTENDED,
+ &errval, &errstr, &errpos, NULL);
+ if (!ctx->re) {
+ DEBUG(1, ("Invalid Regular Expression pattern at position %d."
+ " (Error: %d [%s])\n", errpos, errval, errstr));
+ ret = EFAULT;
+ goto done;
+ }
+
+ rctx->names = ctx;
+ ret = EOK;
+
+done:
+ if (ret != EOK) {
+ talloc_free(ctx);
+ }
+ return ret;
+}
+
int sss_process_init(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct confdb_ctx *cdb,
@@ -539,6 +595,12 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
return ret;
}
+ ret = sss_names_init(rctx);
+ if (ret != EOK) {
+ DEBUG(0, ("fatal error initializing regex data\n"));
+ return ret;
+ }
+
/* after all initializations we are ready to listen on our socket */
ret = set_unix_socket(rctx);
if (ret != EOK) {
@@ -553,33 +615,55 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
}
int sss_parse_name(TALLOC_CTX *memctx,
- const char *fullname,
- struct btreemap *domain_map,
- const char **domain, const char **name) {
- char *delim;
- struct btreemap *node;
- int ret;
+ struct sss_names_ctx *snctx,
+ const char *orig, char **domain, char **name)
+{
+ pcre *re = snctx->re;
+ const char *result;
+ int ovec[30];
+ int origlen;
+ int ret, strnum;
- if ((delim = strchr(fullname, SSS_DOMAIN_DELIM)) != NULL) {
-
- /* Check for registered domain */
- ret = btreemap_search_key(domain_map, (void *)(delim+1), &node);
- if (ret != BTREEMAP_FOUND) {
- /* No such domain was registered. Return EINVAL.
- * TODO: alternative approach?
- * Alternatively, we could simply fail down to
- * below, treating the entire construct as the
- * full name if the domain is unspecified.
- */
- return EINVAL;
- }
+ origlen = strlen(orig);
+
+ ret = pcre_exec(re, NULL, orig, origlen, 0, PCRE_NOTEMPTY, ovec, 30);
+ if (ret < 0) {
+ DEBUG(2, ("PCRE Matching error, %d\n", ret));
+ return EINVAL;
+ }
- *name = talloc_strndup(memctx, fullname, delim-fullname);
- *domain = talloc_strdup(memctx, delim+1);
+ if (ret == 0) {
+ DEBUG(1, ("Too many matches, the pattern is invalid.\n"));
}
- else {
- *name = talloc_strdup(memctx, fullname);
+
+ strnum = ret;
+
+ result = NULL;
+ ret = pcre_get_named_substring(re, orig, ovec, strnum, "name", &result);
+ if (ret < 0 || !result) {
+ DEBUG(2, ("Name not found!\n"));
+ return EINVAL;
+ }
+ *name = talloc_strdup(memctx, result);
+ pcre_free_substring(result);
+ if (!*name) return ENOMEM;
+
+
+ result = NULL;
+ ret = pcre_get_named_substring(re, orig, ovec, strnum, "domain", &result);
+ if (ret < 0 || !result) {
+ DEBUG(4, ("Domain not provided!\n"));
*domain = NULL;
+ } else {
+ /* ignore "" string */
+ if (*result) {
+ *domain = talloc_strdup(memctx, result);
+ pcre_free_substring(result);
+ if (!*domain) return ENOMEM;
+ } else {
+ pcre_free_substring(result);
+ *domain = NULL;
+ }
}
return EOK;
diff --git a/server/responder/common/responder_common.h b/server/responder/common/responder_common.h
deleted file mode 100644
index 8a7af08ad..000000000
--- a/server/responder/common/responder_common.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#include "config.h"
-#include "sbus/sssd_dbus.h"
-#include "responder/common/responder_cmd.h"
-#include "util/btreemap.h"
-
-/* SSS_DOMAIN_DELIM can be specified in config.h */
-#ifndef SSS_DOMAIN_DELIM
-#define SSS_DOMAIN_DELIM '@'
-#endif
-
-
-int sss_process_init(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct confdb_ctx *cdb,
- struct sbus_method sss_sbus_methods[],
- struct sss_cmd_table sss_cmds[],
- const char *sss_pipe_name,
- const char *sss_priv_pipe_name,
- const char *confdb_service_path,
- struct sbus_method dp_methods[],
- struct resp_ctx **responder_ctx);
-
-int sss_parse_name(TALLOC_CTX *memctx,
- const char *fullname,
- struct btreemap *domain_map,
- const char **domain, const char **name);
diff --git a/server/responder/common/responder_dp.c b/server/responder/common/responder_dp.c
index 937b48dc6..7fc7e0b3c 100644
--- a/server/responder/common/responder_dp.c
+++ b/server/responder/common/responder_dp.c
@@ -3,7 +3,7 @@
#include <time.h>
#include "util/util.h"
#include "responder/common/responder_packet.h"
-#include "responder/common/responder_common.h"
+#include "responder/common/responder.h"
#include "providers/data_provider.h"
#include "sbus/sbus_client.h"
#include "providers/dp_sbus.h"
diff --git a/server/responder/common/responder_dp.h b/server/responder/common/responder_dp.h
deleted file mode 100644
index 528490fc5..000000000
--- a/server/responder/common/responder_dp.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "sbus/sssd_dbus.h"
-
-int sss_dp_init(struct resp_ctx *rctx, struct sbus_method dp_methods[]);
diff --git a/server/responder/nss/nsssrv.c b/server/responder/nss/nsssrv.c
index 4f9713b17..834c42d95 100644
--- a/server/responder/nss/nsssrv.c
+++ b/server/responder/nss/nsssrv.c
@@ -123,7 +123,7 @@ static int nss_get_config(struct nss_ctx *nctx,
struct confdb_ctx *cdb)
{
TALLOC_CTX *tmpctx;
- const char *domain, *name;
+ char *domain, *name;
const char **domains;
char **filter_list;
int ret, num, i, j;
@@ -150,8 +150,8 @@ static int nss_get_config(struct nss_ctx *nctx,
"filterUsers", &filter_list);
if (ret != EOK) goto done;
for (i = 0; filter_list[i]; i++) {
- ret = nss_parse_name(tmpctx, nctx, filter_list[i],
- &domain, &name);
+ ret = sss_parse_name(tmpctx, nctx->rctx->names,
+ filter_list[i], &domain, &name);
if (ret != EOK) {
DEBUG(1, ("Invalid name in filterUsers list: [%s] (%d)\n",
filter_list[i], ret));
@@ -192,8 +192,8 @@ static int nss_get_config(struct nss_ctx *nctx,
"filterGroups", &filter_list);
if (ret != EOK) goto done;
for (i = 0; filter_list[i]; i++) {
- ret = nss_parse_name(tmpctx, nctx, filter_list[i],
- &domain, &name);
+ ret = sss_parse_name(tmpctx, nctx->rctx->names,
+ filter_list[i], &domain, &name);
if (ret != EOK) {
DEBUG(1, ("Invalid name in filterGroups list: [%s] (%d)\n",
filter_list[i], ret));
@@ -235,22 +235,6 @@ done:
return ret;
}
-static void *nss_pcre_malloc(size_t size)
-{
- return talloc_named_const(NULL, size, "nss_pcre_malloc");
-}
-
-static void nss_pcre_free(void *ctx)
-{
- talloc_free(ctx);
-}
-
-void nss_pcre_setup(void)
-{
- pcre_malloc = nss_pcre_malloc;
- pcre_free = nss_pcre_free;
-}
-
int nss_process_init(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct confdb_ctx *cdb)
@@ -260,8 +244,6 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
struct nss_ctx *nctx;
int ret;
- nss_pcre_setup();
-
nctx = talloc_zero(mem_ctx, struct nss_ctx);
if (!nctx) {
DEBUG(0, ("fatal error initializing nss_ctx\n"));
diff --git a/server/responder/nss/nsssrv.h b/server/responder/nss/nsssrv.h
index 093f795b4..37d3735d0 100644
--- a/server/responder/nss/nsssrv.h
+++ b/server/responder/nss/nsssrv.h
@@ -32,20 +32,14 @@
#include "dbus/dbus.h"
#include "sbus/sssd_dbus.h"
#include "responder/common/responder_packet.h"
-#include "responder/common/responder_cmd.h"
+#include "responder/common/responder.h"
#include "responder/nss/nsssrv_nc.h"
-#include <pcre.h>
#define NSS_SBUS_SERVICE_VERSION 0x0001
#define NSS_SBUS_SERVICE_NAME "nss"
#define NSS_PACKET_MAX_RECV_SIZE 1024
-/* NSS_DOMAIN_DELIM can be specified in config.h */
-#ifndef NSS_DOMAIN_DELIM
-#define NSS_DOMAIN_DELIM '@'
-#endif
-
#define NSS_ENUM_USERS 0x01
#define NSS_ENUM_GROUPS 0x02
#define NSS_ENUM_ALL 0x03
@@ -67,8 +61,6 @@ struct nss_ctx {
struct getent_ctx *pctx;
struct getent_ctx *gctx;
-
- pcre *parse_name_re;
};
struct nss_packet;
diff --git a/server/responder/nss/nsssrv_cmd.c b/server/responder/nss/nsssrv_cmd.c
index 26c51fac8..d090b9d18 100644
--- a/server/responder/nss/nsssrv_cmd.c
+++ b/server/responder/nss/nsssrv_cmd.c
@@ -27,7 +27,7 @@
struct nss_cmd_ctx {
struct cli_ctx *cctx;
- const char *name;
+ char *name;
uint32_t id;
bool immediate;
@@ -79,77 +79,6 @@ static int nss_cmd_send_error(struct nss_cmd_ctx *cmdctx, int err)
return; \
} while(0)
-int nss_parse_name(TALLOC_CTX *memctx,
- struct nss_ctx *nctx,
- const char *origname,
- const char **domain, const char **name)
-{
- pcre *re = nctx->parse_name_re;
- const char *errstr;
- const char *pattern = "(?<name>[^@]+)@?(?<domain>[^@]*$)";
- const char *result;
- int options;
- int errpos;
- int errval;
- int ovec[30];
- int origlen;
- int ret, strnum;
-
- options = PCRE_DUPNAMES | PCRE_EXTENDED;
-
- if (!re) {
- re = pcre_compile2(pattern, options, &errval, &errstr, &errpos, NULL);
- if (!re) {
- DEBUG(1, ("Invalid Regular Expression pattern at position %d. (%d [%s])\n",
- errpos, errstr));
- return EFAULT;
- }
- }
- nctx->parse_name_re = re;
-
- origlen = strlen(origname);
- options = PCRE_NOTEMPTY;
-
- ret = pcre_exec(re, NULL, origname, origlen, 0, options, ovec, 30);
- if (ret < 0) {
- DEBUG(2, ("PCRE Matching error, %d\n", ret));
- return EINVAL;
- }
-
- if (ret == 0) {
- DEBUG(1, ("Too many matches, the pattern is invalid.\n"));
- }
-
- strnum = ret;
-
- result = NULL;
- ret = pcre_get_named_substring(re, origname, ovec, strnum, "name", &result);
- if (ret < 0 || !result) {
- DEBUG(2, ("Name not found!\n"));
- return EINVAL;
- }
- *name = talloc_steal(memctx, result);
- if (!*name) return ENOMEM;
-
-
- result = NULL;
- ret = pcre_get_named_substring(re, origname, ovec, strnum, "domain", &result);
- if (ret < 0 || !result) {
- DEBUG(4, ("Domain not provided!\n"));
- *domain = NULL;
- } else {
- /* ignore "" string */
- if (*result) {
- *domain = talloc_steal(memctx, result);
- if (!*domain) return ENOMEM;
- } else {
- *domain = NULL;
- }
- }
-
- return EOK;
-}
-
static int nss_dom_ctx_init(struct nss_dom_ctx *dctx,
struct btreemap *domain_map, const char *domain)
{
@@ -189,12 +118,14 @@ static int fill_pwent(struct sss_packet *packet,
size_t rsize, rp, blen;
size_t s1, s2, s3, s4;
size_t dom_len = 0;
- int i, ret, num;
+ int delim = 1;
+ int i, ret, num, t;
bool add_domain = info->fqnames;
const char *domain = info->name;
+ const char *namefmt = nctx->rctx->names->fq_fmt;
int ncret;
- if (add_domain) dom_len = strlen(domain) +1;
+ if (add_domain) dom_len = strlen(domain);
/* first 2 fields (len and reserved), filled up later */
ret = sss_packet_grow(packet, 2*sizeof(uint32_t));
@@ -245,8 +176,9 @@ static int fill_pwent(struct sss_packet *packet,
s2 = strlen(gecos) + 1;
s3 = strlen(homedir) + 1;
s4 = strlen(shell) + 1;
+ if (add_domain) s1 += delim + dom_len;
+
rsize = 2*sizeof(uint32_t) +s1 + 2 + s2 + s3 +s4;
- if (add_domain) rsize += dom_len;
ret = sss_packet_grow(packet, rsize);
if (ret != EOK) {
@@ -258,13 +190,35 @@ static int fill_pwent(struct sss_packet *packet,
((uint32_t *)(&body[rp]))[0] = uid;
((uint32_t *)(&body[rp]))[1] = gid;
rp += 2*sizeof(uint32_t);
- memcpy(&body[rp], name, s1);
- rp += s1;
+
if (add_domain) {
- body[rp-1] = NSS_DOMAIN_DELIM;
- memcpy(&body[rp], domain, dom_len);
- rp += dom_len;
+ ret = snprintf(&body[rp], s1, namefmt, name, domain);
+ if (ret >= s1) {
+ /* need more space, got creative with the print format ? */
+ t = ret - s1 + 1;
+ ret = sss_packet_grow(packet, t);
+ if (ret != EOK) {
+ num = 0;
+ goto done;
+ }
+ delim += t;
+ s1 += t;
+ sss_packet_get_body(packet, &body, &blen);
+
+ /* retry */
+ ret = snprintf(&body[rp], s1, namefmt, name, domain);
+ }
+
+ if (ret != s1-1) {
+ DEBUG(1, ("Failed to generate a fully qualified name for user "
+ "[%s] in [%s]! Skipping user.\n", name, domain));
+ continue;
+ }
+ } else {
+ memcpy(&body[rp], name, s1);
}
+ rp += s1;
+
memcpy(&body[rp], "x", 2);
rp += 2;
memcpy(&body[rp], gecos, s2);
@@ -493,8 +447,8 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx)
struct sss_domain_info *info;
struct nss_ctx *nctx;
const char **domains;
- const char *domname;
const char *rawname;
+ char *domname;
uint8_t *body;
size_t blen;
int ret, num, i;
@@ -519,7 +473,7 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx)
rawname = (const char *)body;
domname = NULL;
- ret = nss_parse_name(cmdctx, nctx, rawname,
+ ret = sss_parse_name(cmdctx, cctx->rctx->names, rawname,
&domname, &cmdctx->name);
if (ret != EOK) {
DEBUG(2, ("Invalid name received [%s]\n", rawname));
@@ -1332,16 +1286,18 @@ static int fill_grent(struct sss_packet *packet,
const char *name;
uint32_t gid, uid;
size_t rsize, rp, blen, mnump;
- int i, j, n, ret, num, memnum;
+ int i, j, n, t, ret, num, memnum;
bool get_members;
bool skip_members;
size_t dom_len = 0;
size_t name_len;
+ int delim = 1;
bool add_domain = info->fqnames;
const char *domain = info->name;
+ const char *namefmt = nctx->rctx->names->fq_fmt;
int ncret;
- if (add_domain) dom_len = strlen(domain) +1;
+ if (add_domain) dom_len = strlen(domain);
/* first 2 fields (len and reserved), filled up later */
ret = sss_packet_grow(packet, 2*sizeof(uint32_t));
@@ -1396,11 +1352,15 @@ static int fill_grent(struct sss_packet *packet,
}
/* 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;
- if (add_domain) rsize += dom_len;
+ name_len = strlen(name) + 1;
+ if (add_domain) name_len += delim + dom_len;
+ rsize = 2 * sizeof(uint32_t) + name_len + 2;
ret = sss_packet_grow(packet, rsize);
+ if (ret != EOK) {
+ num = 0;
+ goto done;
+ }
sss_packet_get_body(packet, &body, &blen);
/* 0-3: 64bit number gid */
@@ -1414,13 +1374,34 @@ static int fill_grent(struct sss_packet *packet,
rp += sizeof(uint32_t);
/* 8-X: sequence of strings (name, passwd, mem..) */
- memcpy(&body[rp], name, name_len);
- rp += name_len;
if (add_domain) {
- body[rp-1] = NSS_DOMAIN_DELIM;
- memcpy(&body[rp], domain, dom_len);
- rp += dom_len;
+ ret = snprintf(&body[rp], name_len, namefmt, name, domain);
+ if (ret >= name_len) {
+ /* need more space, got creative with the print format ? */
+ t = ret - name_len + 1;
+ ret = sss_packet_grow(packet, t);
+ if (ret != EOK) {
+ num = 0;
+ goto done;
+ }
+ delim += t;
+ name_len += t;
+ sss_packet_get_body(packet, &body, &blen);
+
+ /* retry */
+ ret = snprintf(&body[rp], name_len, namefmt, name, domain);
+ }
+
+ if (ret != name_len-1) {
+ DEBUG(1, ("Failed to generate a fully qualified name for user "
+ "[%s] in [%s]! Skipping user.\n", name, domain));
+ continue;
+ }
+ } else {
+ memcpy(&body[rp], name, name_len);
}
+ rp += name_len;
+
body[rp] = 'x'; /* group passwd field */
body[rp+1] = '\0';
@@ -1435,20 +1416,21 @@ static int fill_grent(struct sss_packet *packet,
n = 0;
for (j = 0; j < memnum; j++) {
+ name = (char *)el->values[j].data;
+
ncret = nss_ncache_check_user(nctx->ncache,
- nctx->neg_timeout, domain,
- (char *)el->values[j].data);
+ nctx->neg_timeout,
+ domain, name);
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;
- rsize += dom_len;
- }
+ name_len = el->values[j].length + 1;
+ if (add_domain) name_len += delim + dom_len;
+
+ rsize = name_len;
ret = sss_packet_grow(packet, rsize);
if (ret != EOK) {
num = 0;
@@ -1457,12 +1439,34 @@ static int fill_grent(struct sss_packet *packet,
sss_packet_get_body(packet, &body, &blen);
rp = blen - rsize;
- memcpy(&body[rp], el->values[j].data, el->values[j].length);
+
if (add_domain) {
- rp += name_len;
- body[rp-1] = NSS_DOMAIN_DELIM;
- memcpy(&body[rp], domain, dom_len);
+ ret = snprintf(&body[rp], name_len, namefmt, name, domain);
+ if (ret >= name_len) {
+ /* need more space, got creative with the print format ? */
+ t = ret - name_len + 1;
+ ret = sss_packet_grow(packet, t);
+ if (ret != EOK) {
+ num = 0;
+ goto done;
+ }
+ delim += t;
+ name_len += t;
+ sss_packet_get_body(packet, &body, &blen);
+
+ /* retry */
+ ret = snprintf(&body[rp], name_len, namefmt, name, domain);
+ }
+
+ if (ret != name_len-1) {
+ DEBUG(1, ("Failed to generate a fully qualified name for user "
+ "[%s] in [%s]! Skipping user.\n", name, domain));
+ continue;
+ }
+ } else {
+ memcpy(&body[rp], name, name_len);
}
+ rp += name_len;
body[blen-1] = '\0';
n++;
@@ -1514,12 +1518,10 @@ static int fill_grent(struct sss_packet *packet,
continue;
}
- rsize = strlen(name) + 1;
- if (add_domain) {
- name_len = rsize;
- rsize += dom_len;
- }
+ name_len = strlen(name) + 1;
+ if (add_domain) name_len += delim + dom_len;
+ rsize = name_len;
ret = sss_packet_grow(packet, rsize);
if (ret != EOK) {
num = 0;
@@ -1527,13 +1529,34 @@ static int fill_grent(struct sss_packet *packet,
}
sss_packet_get_body(packet, &body, &blen);
rp = blen - rsize;
- memcpy(&body[rp], name, rsize);
+
if (add_domain) {
- body[rp-1] = NSS_DOMAIN_DELIM;
- memcpy(&body[rp], domain, dom_len);
- rp += dom_len;
- }
+ ret = snprintf(&body[rp], name_len, namefmt, name, domain);
+ if (ret >= name_len) {
+ /* need more space, got creative with the print format ? */
+ t = ret - name_len + 1;
+ ret = sss_packet_grow(packet, t);
+ if (ret != EOK) {
+ num = 0;
+ goto done;
+ }
+ delim += t;
+ name_len += t;
+ sss_packet_get_body(packet, &body, &blen);
+
+ /* retry */
+ ret = snprintf(&body[rp], name_len, namefmt, name, domain);
+ }
+ if (ret != name_len-1) {
+ DEBUG(1, ("Failed to generate a fully qualified name for user "
+ "[%s] in [%s]! Skipping user.\n", name, domain));
+ continue;
+ }
+ } else {
+ memcpy(&body[rp], name, name_len);
+ }
+ rp += name_len;
memnum++;
continue;
@@ -1752,8 +1775,8 @@ static int nss_cmd_getgrnam(struct cli_ctx *cctx)
struct sss_domain_info *info;
struct nss_ctx *nctx;
const char **domains;
- const char *domname;
const char *rawname;
+ char *domname;
uint8_t *body;
size_t blen;
int ret, num, i;
@@ -1777,7 +1800,7 @@ static int nss_cmd_getgrnam(struct cli_ctx *cctx)
rawname = (const char *)body;
domname = NULL;
- ret = nss_parse_name(cmdctx, nctx, rawname,
+ ret = sss_parse_name(cmdctx, cctx->rctx->names, rawname,
&domname, &cmdctx->name);
if (ret != EOK) {
DEBUG(2, ("Invalid name received [%s]\n", rawname));
@@ -2844,8 +2867,8 @@ static int nss_cmd_initgroups(struct cli_ctx *cctx)
struct sss_domain_info *info;
struct nss_ctx *nctx;
const char **domains;
- const char *domname;
const char *rawname;
+ char *domname;
uint8_t *body;
size_t blen;
int ret, num, i;
@@ -2869,7 +2892,7 @@ static int nss_cmd_initgroups(struct cli_ctx *cctx)
rawname = (const char *)body;
domname = NULL;
- ret = nss_parse_name(cmdctx, nctx, rawname,
+ ret = sss_parse_name(cmdctx, cctx->rctx->names, rawname,
&domname, &cmdctx->name);
if (ret != EOK) {
DEBUG(2, ("Invalid name received [%s]\n", rawname));
diff --git a/server/responder/pam/pamsrv.c b/server/responder/pam/pamsrv.c
index d653a008b..2f74a4ac3 100644
--- a/server/responder/pam/pamsrv.c
+++ b/server/responder/pam/pamsrv.c
@@ -37,8 +37,6 @@
#include "sbus/sssd_dbus.h"
#include "util/btreemap.h"
#include "responder/common/responder_packet.h"
-#include "responder/common/responder_cmd.h"
-#include "responder/common/responder_common.h"
#include "providers/data_provider.h"
#include "monitor/monitor_sbus.h"
#include "monitor/monitor_interfaces.h"
diff --git a/server/responder/pam/pamsrv.h b/server/responder/pam/pamsrv.h
index ac29cb16e..077b495d4 100644
--- a/server/responder/pam/pamsrv.h
+++ b/server/responder/pam/pamsrv.h
@@ -4,7 +4,7 @@
#include "util/util.h"
#include "sbus/sssd_dbus.h"
-#include "responder/common/responder_cmd.h"
+#include "responder/common/responder.h"
#define PAM_DP_TIMEOUT 5000
diff --git a/server/responder/pam/pamsrv_cmd.c b/server/responder/pam/pamsrv_cmd.c
index 69f198c62..8f74e96f6 100644
--- a/server/responder/pam/pamsrv_cmd.c
+++ b/server/responder/pam/pamsrv_cmd.c
@@ -4,55 +4,55 @@
#include "util/util.h"
#include "confdb/confdb.h"
#include "responder/pam/pam_LOCAL_domain.h"
-#include "responder/common/responder_common.h"
-#include "responder/common/responder_cmd.h"
-#include "responder/common/responder_packet.h"
#include "responder/pam/pamsrv.h"
-static int pam_parse_in_data(uint8_t *body, size_t blen, struct pam_data *pd) {
+static int pam_parse_in_data(struct sss_names_ctx *snctx,
+ struct pam_data *pd,
+ uint8_t *body, size_t blen)
+{
int start;
int end;
- int last=blen-1;
- char *delim;
+ int last;
+ int ret;
- start = end = 0;
- while ( end < last && body[end++]!='\0');
- pd->user = (char *) &body[start];
+ last = blen - 1;
+ end = 0;
- delim = strchr(pd->user, SSS_DOMAIN_DELIM);
- if (delim != NULL ) {
- *delim = '\0';
- pd->domain = delim+1;
- } else {
- pd->domain = NULL;
- }
+ /* user name */
+ for (start = end; end < last; end++) if (body[end] == '\0') break;
+ if (body[end++] != '\0') return EINVAL;
- start = end;
- while ( end < last && body[end++]!='\0');
+ ret = sss_parse_name(pd, snctx, &body[start], &pd->domain, &pd->user);
+ if (ret != EOK) return ret;
+
+ for (start = end; end < last; end++) if (body[end] == '\0') break;
+ if (body[end++] != '\0') return EINVAL;
pd->service = (char *) &body[start];
- start = end;
- while ( end < last && body[end++]!='\0');
+ for (start = end; end < last; end++) if (body[end] == '\0') break;
+ if (body[end++] != '\0') return EINVAL;
pd->tty = (char *) &body[start];
- start = end;
- while ( end < last && body[end++]!='\0');
+ for (start = end; end < last; end++) if (body[end] == '\0') break;
+ if (body[end++] != '\0') return EINVAL;
pd->ruser = (char *) &body[start];
- start = end;
- while ( end < last && body[end++]!='\0');
+ for (start = end; end < last; end++) if (body[end] == '\0') break;
+ if (body[end++] != '\0') return EINVAL;
pd->rhost = (char *) &body[start];
start = end;
pd->authtok_type = (int) body[start];
+
start += sizeof(uint32_t);
pd->authtok_size = (int) body[start];
+
start += sizeof(uint32_t);
- end = start+pd->authtok_size;
- if ( pd->authtok_size == 0 ) {
+ end = start + pd->authtok_size;
+ if (pd->authtok_size == 0) {
pd->authtok = NULL;
} else {
- if ( end <= blen ) {
+ if (end <= blen) {
pd->authtok = (uint8_t *) &body[start];
} else {
DEBUG(1, ("Invalid authtok size: %d\n", pd->authtok_size));
@@ -62,14 +62,17 @@ static int pam_parse_in_data(uint8_t *body, size_t blen, struct pam_data *pd) {
start = end;
pd->newauthtok_type = (int) body[start];
+
start += sizeof(uint32_t);
pd->newauthtok_size = (int) body[start];
+
start += sizeof(uint32_t);
- end = start+pd->newauthtok_size;
- if ( pd->newauthtok_size == 0 ) {
+ end = start + pd->newauthtok_size;
+
+ if (pd->newauthtok_size == 0) {
pd->newauthtok = NULL;
} else {
- if ( end <= blen ) {
+ if (end <= blen) {
pd->newauthtok = (uint8_t *) &body[start];
} else {
DEBUG(1, ("Invalid newauthtok size: %d\n", pd->newauthtok_size));
@@ -213,7 +216,7 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
pd->cmd = pam_cmd;
pd->cctx = cctx;
- ret=pam_parse_in_data(body, blen, pd);
+ ret=pam_parse_in_data(cctx->rctx->names, pd, body, blen);
if( ret != 0 ) {
talloc_free(pd);
return EINVAL;