---
name: "cap_endgrent"
section: "3"
platform: "freebsd"
package: "base"
version: "16.0-CURRENT-20261027-61c70dc16a79"
release: "FreeBSD 16.0-CURRENT (2026-10-27)"
platforms: ["freebsd"]
url: "https://new.carta.tech/cap_endgrent"
---

# cap\_endgrent(3)

library for group database operations in capability mode

## NAME

**cap\_getgrent**, **cap\_getgrnam**, **cap\_getgrgid**, **cap\_getgrent\_r**, **cap\_getgrnam\_r**, **cap\_getgrgid\_r**, **cap\_setgroupent**, **cap\_setgrent**, **cap\_endgrent**, **cap\_grp\_limit\_cmds**, **cap\_grp\_limit\_fields**, **cap\_grp\_limit\_groups** – library for group database operations in capability mode

## LIBRARY

library “libcap\_grp”

## SYNOPSIS

**#include \<sys/nv.h\>**

**#include \<libcasper.h\>**

**#include \<casper/cap\_grp.h\>**

*struct group \**\

**cap\_getgrent**(*cap\_channel\_t \*chan*);

*struct group \**\

**cap\_getgrnam**(*cap\_channel\_t \*chan*, *const char \*name*);

*struct group \**\

**cap\_getgrgid**(*cap\_channel\_t \*chan*, *gid\_t gid*);

*int*\

**cap\_getgrent\_r**(*cap\_channel\_t \*chan*, *struct group \*grp*, *char \*buffer*, *size\_t bufsize*, *struct group \*\*result*);

*int*\

**cap\_getgrnam\_r**(*cap\_channel\_t \*chan*, *const char \*name*, *struct group \*grp*, *char \*buffer*, *size\_t bufsize*, *struct group \*\*result*);

*int*\

**cap\_getgrgid\_r**(*cap\_channel\_t \*chan*, *gid\_t gid*, *struct group \*grp*, *char \*buffer*, *size\_t bufsize*, *struct group \*\*result*);

*int*\

**cap\_setgroupent**(*cap\_channel\_t \*chan*, *int stayopen*);

*int*\

**cap\_setgrent**(*cap\_channel\_t \*chan*);

*void*\

**cap\_endgrent**(*cap\_channel\_t \*chan*);

*int*\

**cap\_grp\_limit\_cmds**(*cap\_channel\_t \*chan*, *const char \* const \*cmds*, *size\_t ncmds*);

*int*\

**cap\_grp\_limit\_fields**(*cap\_channel\_t \*chan*, *const char \* const \*fields*, *size\_t nfields*);

*int*\

**cap\_grp\_limit\_groups**(*cap\_channel\_t \*chan*, *const char \* const \*names*, *size\_t nnames*, *const gid\_t \*gids*, *size\_t ngids*);

## DESCRIPTION

The functions **cap\_getgrent**(), **cap\_getgrnam**(), **cap\_getgrgid**(), **cap\_getgrent\_r**(), **cap\_getgrnam\_r**(), **cap\_getgrgid\_r**(), **cap\_setgroupent**(), **cap\_setgrent**(), and **cap\_endgrent**() are respectively equivalent to [getgrent(3)](/getgrent/3.md), [getgrnam(3)](/getgrnam/3.md), [getgrgid(3)](/getgrgid/3.md), [getgrent\_r(3)](/getgrent_r/3.md), [getgrnam\_r(3)](/getgrnam_r/3.md), [getgrgid\_r(3)](/getgrgid_r/3.md), [setgroupent(3)](/setgroupent/3.md), [setgrent(3)](/setgrent/3.md), and [endgrent(3)](/endgrent/3.md) except that the connection to the **system.grp** service needs to be provided.

The **cap\_grp\_limit\_cmds**() function limits the functions allowed in the service. The *cmds* variable can be set to getgrent, getgrnam, getgrgid, getgrent\_r, getgrnam\_r, getgrgid\_r, setgroupent, setgrent, or endgrent which will allow to use the function associated with the name. The *ncmds* variable contains the number of *cmds* provided.

The **cap\_grp\_limit\_fields**() function allows limit fields returned in the structure *group*. The *fields* variable can be set to gr\_name gr\_passwd gr\_gid or gr\_mem. The field which was set as the limit will be returned, while the rest of the values not set this way will have default values. The *nfields* variable contains the number of *fields* provided.

The **cap\_grp\_limit\_groups**() function allows to limit access to groups. The *names* variable allows to limit groups by name and the *gids* variable by the group number. The *nnames* and *ngids* variables provide numbers of limited names and gids.

All of these functions are reentrant but not thread-safe. That is, they may be called from separate threads only with different *cap\_channel\_t* arguments or with synchronization.

## EXAMPLES

The following example first opens a capability to casper and then uses this capability to create the **system.grp** casper service and uses it to get a group name.

```
cap_channel_t *capcas, *capgrp;
const char *cmds[] = { "getgrgid" };
const char *fields[] = { "gr_name" };
const gid_t gid[] = { 1 };
struct group *group;
/* Open capability to Casper. */
capcas = cap_init();
if (capcas == NULL)
        err(1, "Unable to contact Casper");
/* Enter capability mode sandbox. */
if (cap_enter() < 0 && errno != ENOSYS)
        err(1, "Unable to enter capability mode");
/* Use Casper capability to create capability to the system.grp service. */
capgrp = cap_service_open(capcas, "system.grp");
if (capgrp == NULL)
        err(1, "Unable to open system.grp service");
/* Close Casper capability, we don't need it anymore. */
cap_close(capcas);
/* Limit service to one single function. */
if (cap_grp_limit_cmds(capgrp, cmds, nitems(cmds)))
	err(1, "Unable to limit access to system.grp service");
/* Limit service to one field as we only need name of the group. */
if (cap_grp_limit_fields(capgrp, fields, nitems(fields)))
	err(1, "Unable to limit access to system.grp service");
/* Limit service to one gid. */
if (cap_grp_limit_groups(capgrp, NULL, 0, gid, nitems(gid)))
	err(1, "Unable to limit access to system.grp service");
group = cap_getgrgid(capgrp, gid[0]);
if (group == NULL)
	err(1, "Unable to get name of group");
printf("GID %d is associated with name %s.\n", gid[0], group->gr_name);
cap_close(capgrp);
```

## SEE ALSO

[cap\_enter(2)](/cap_enter/2.md), [endgrent(3)](/endgrent/3.md), [err(3)](/err/3.md), [getgrent(3)](/getgrent/3.md), [getgrent\_r(3)](/getgrent_r/3.md), [getgrgid(3)](/getgrgid/3.md), [getgrgid\_r(3)](/getgrgid_r/3.md), [getgrnam(3)](/getgrnam/3.md), [getgrnam\_r(3)](/getgrnam_r/3.md), [setgrent(3)](/setgrent/3.md), [setgroupent(3)](/setgroupent/3.md), [capsicum(4)](/capsicum/4.md), [nv(9)](/nv/9.md)

## HISTORY

The **cap\_grp** service first appeared in FreeBSD 10.3.

## AUTHORS

The **cap\_grp** service was implemented by Pawel Jakub Dawidek ⟨*pawel@dawidek.net*⟩ under sponsorship from the FreeBSD Foundation.

This manual page was written by Mariusz Zaborski ⟨*oshogbo@FreeBSD.org*⟩.
