Page MenuHomeFreeBSD

D47148.1788573443.diff
No OneTemporary

Size
7 KB
Referenced Files
None
Subscribers
None

D47148.1788573443.diff

diff --git a/lib/libc/gen/getgrent.c b/lib/libc/gen/getgrent.c
--- a/lib/libc/gen/getgrent.c
+++ b/lib/libc/gen/getgrent.c
@@ -151,6 +151,8 @@
static int grp_id_func(char *, size_t *, va_list, void *);
static int grp_marshal_func(char *, size_t *, void *, va_list, void *);
static int grp_unmarshal_func(char *, size_t, void *, va_list, void *);
+static int grplist_marshal_func(char *, size_t *, void *, va_list, void *);
+static int grplist_unmarshal_func(char *, size_t, void *, va_list, void *);
static int
grp_id_func(char *buffer, size_t *buffer_size, va_list ap, void *cache_mdata)
@@ -167,15 +169,15 @@
switch (lookup_type) {
case nss_lt_name:
name = va_arg(ap, char *);
- size = strlen(name);
- desired_size = sizeof(enum nss_lookup_type) + size + 1;
+ size = strlen(name) + 1;
+ desired_size = sizeof(enum nss_lookup_type) + size;
if (desired_size > *buffer_size) {
res = NS_RETURN;
goto fin;
}
memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type));
- memcpy(buffer + sizeof(enum nss_lookup_type), name, size + 1);
+ memcpy(buffer + sizeof(enum nss_lookup_type), name, size);
res = NS_SUCCESS;
break;
@@ -191,6 +193,22 @@
memcpy(buffer + sizeof(enum nss_lookup_type), &gid,
sizeof(gid_t));
+ res = NS_SUCCESS;
+ break;
+ case nss_lt_pivot:
+ name = va_arg(ap, char *);
+ gid = va_arg(ap, gid_t);
+ size = strlen(name) + 1;
+
+ desired_size = sizeof(enum nss_lookup_type) + size + sizeof(gid_t);
+ if (desired_size > *buffer_size) {
+ res = NS_RETURN;
+ goto fin;
+ }
+
+ memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type));
+ memcpy(buffer + sizeof(enum nss_lookup_type), name, size);
+ memcpy(buffer + sizeof(enum nss_lookup_type) + size, &gid, sizeof(gid_t));
res = NS_SUCCESS;
break;
default:
@@ -203,6 +221,36 @@
return (res);
}
+static int
+grplist_marshal_func(char *buffer, size_t *buffer_size, void *retval,
+ va_list ap, void *cache_mdata)
+{
+ char *name __unused;
+ gid_t basegid __unused;
+ gid_t *groups;
+ int maxgroups __unused, *ngroups;
+ size_t desired_size;
+
+ name = va_arg(ap, char*);
+ basegid = va_arg(ap, gid_t);
+ groups = va_arg(ap, gid_t *);
+ maxgroups = va_arg(ap, int);
+ ngroups = va_arg(ap, int *);
+
+ desired_size = sizeof(int) + (sizeof(gid_t) * (*ngroups));
+
+ if (buffer == NULL || desired_size > *buffer_size) {
+ *buffer_size = desired_size;
+ return (NS_RETURN);
+ }
+
+ *buffer_size = desired_size;
+ memcpy(buffer, ngroups, sizeof(int));
+ memcpy(buffer + sizeof(int), groups, sizeof(gid_t) * (*ngroups));
+
+ return (NS_SUCCESS);
+}
+
static int
grp_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap,
void *cache_mdata)
@@ -297,6 +345,42 @@
return (NS_SUCCESS);
}
+static int
+grplist_unmarshal_func(char *buffer, size_t buffer_size, void *retval,
+ va_list ap, void *cache_mdata)
+{
+ char *name __unused;
+ gid_t basegid __unused;
+ gid_t *groups;
+ int *pngroups, maxgroups, original_ngroups;
+ int *ret_errno;
+
+ name = va_arg(ap, char *);
+ basegid = va_arg(ap, gid_t);
+ groups = va_arg(ap, gid_t *);
+ maxgroups = va_arg(ap, int);
+ pngroups = va_arg(ap, int *);
+ ret_errno = va_arg(ap, int *);
+
+ if (buffer_size < sizeof(int)) {
+ *ret_errno = 0;
+ return (NS_NOTFOUND);
+ }
+ memcpy(&original_ngroups, buffer, sizeof(int));
+ if (original_ngroups < 0 ||
+ original_ngroups >
+ (CACHED_MAX_BUFFER_SIZE - sizeof(int))/sizeof(gid_t) ||
+ buffer_size < sizeof(int) + (original_ngroups * sizeof(gid_t)))
+ {
+ return NS_UNAVAIL;
+ }
+ memcpy(groups, buffer + sizeof(int), sizeof(gid_t) *
+ ((original_ngroups > maxgroups) ? maxgroups : original_ngroups));
+ *pngroups = original_ngroups;
+ *ret_errno = 0;
+ return NS_SUCCESS;
+}
+
static int
grp_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap,
void *cache_mdata)
@@ -476,7 +560,7 @@
gid_t *groups;
gid_t agroup;
int maxgrp, *grpcnt;
- int i, rv, ret_errno;
+ int i, rv, grp_errno, *ret_errno;
/*
* As this is a fallback method, only provided src
@@ -489,6 +573,7 @@
groups = va_arg(ap, gid_t *);
maxgrp = va_arg(ap, int);
grpcnt = va_arg(ap, int *);
+ ret_errno = va_arg(ap, int *);
rv = NS_UNAVAIL;
@@ -503,12 +588,12 @@
_nsdispatch(NULL, setgrent_dtab, NSDB_GROUP, "setgrent", src, 0);
for (;;) {
do {
- ret_errno = 0;
+ grp_errno = 0;
grp_p = NULL;
rv = _nsdispatch(&grp_p, getgrent_r_dtab, NSDB_GROUP,
- "getgrent_r", src, &grp, buf, bufsize, &ret_errno);
+ "getgrent_r", src, &grp, buf, bufsize, &grp_errno);
- if (grp_p == NULL && ret_errno == ERANGE) {
+ if (grp_p == NULL && grp_errno == ERANGE) {
free(buf);
if ((bufsize << 1) > GRP_STORAGE_MAX) {
buf = NULL;
@@ -522,10 +607,10 @@
goto out;
}
}
- } while (grp_p == NULL && ret_errno == ERANGE);
+ } while (grp_p == NULL && grp_errno == ERANGE);
- if (ret_errno != 0) {
- errno = ret_errno;
+ if (grp_errno != 0) {
+ *ret_errno = grp_errno;
goto out;
}
@@ -538,6 +623,7 @@
}
}
+ *ret_errno = 0;
_nsdispatch(NULL, endgrent_dtab, NSDB_GROUP, "endgrent", src);
out:
free(buf);
@@ -665,8 +751,19 @@
__getgroupmembership(const char *uname, gid_t agroup, gid_t *groups,
int maxgrp, int *grpcnt)
{
+ int ret_errno = 0;
+#ifdef NS_CACHING
+ static const nss_cache_info cache_info =
+ NS_COMMON_CACHE_INFO_INITIALIZER(
+ group, (void *)nss_lt_pivot,
+ grp_id_func, grplist_marshal_func, grplist_unmarshal_func);
+#endif
+
static const ns_dtab dtab[] = {
NS_FALLBACK_CB(getgroupmembership_fallback)
+#ifdef NS_CACHING
+ NS_CACHE_CB(&cache_info)
+#endif
{ NULL, NULL, NULL }
};
@@ -676,9 +773,10 @@
*grpcnt = 0;
(void)_nsdispatch(NULL, dtab, NSDB_GROUP, "getgroupmembership",
- defaultsrc, uname, agroup, groups, maxgrp, grpcnt);
+ defaultsrc, uname, agroup, groups, maxgrp, grpcnt, &ret_errno);
/* too many groups found? */
+ errno = ret_errno;
return (*grpcnt > maxgrp ? -1 : 0);
}
diff --git a/lib/libc/gen/getpwent.c b/lib/libc/gen/getpwent.c
--- a/lib/libc/gen/getpwent.c
+++ b/lib/libc/gen/getpwent.c
@@ -214,15 +214,15 @@
switch (lookup_type) {
case nss_lt_name:
name = va_arg(ap, char *);
- size = strlen(name);
- desired_size = sizeof(enum nss_lookup_type) + size + 1;
+ size = strlen(name) + 1;
+ desired_size = sizeof(enum nss_lookup_type) + size;
if (desired_size > *buffer_size) {
res = NS_RETURN;
goto fin;
}
memcpy(buffer, &lookup_type, sizeof(enum nss_lookup_type));
- memcpy(buffer + sizeof(enum nss_lookup_type), name, size + 1);
+ memcpy(buffer + sizeof(enum nss_lookup_type), name, size);
res = NS_SUCCESS;
break;
diff --git a/lib/libc/include/nscachedcli.h b/lib/libc/include/nscachedcli.h
--- a/lib/libc/include/nscachedcli.h
+++ b/lib/libc/include/nscachedcli.h
@@ -73,6 +73,9 @@
typedef struct cached_connection_ *cached_mp_write_session;
typedef struct cached_connection_ *cached_mp_read_session;
+/* Max protocol transfer size, must match protocol.h in nscd */
+#define CACHED_MAX_BUFFER_SIZE (1 << 20)
+
#define INVALID_CACHED_CONNECTION (NULL)
#define INVALID_CACHED_MP_WRITE_SESSION (NULL)
#define INVALID_CACHED_MP_READ_SESSION (NULL)

File Metadata

Mime Type
text/plain
Expires
Sat, Sep 5, 1:57 AM (6 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29510252
Default Alt Text
D47148.1788573443.diff (7 KB)

Event Timeline