affects both the start command and the stop command.
.TP
\fBrun\-as\fR = \fIuser-id\fR
-Specifies which user to run the process(es) for this service as. The group id
-for the process will also be set to the primary group of the specified user.
+Specifies which user to run the process(es) for this service as. Specify as a
+username or numeric ID. If specified by name, the group for the process will
+also be set to the primary group of the specified user.
.TP
\fBrestart\fR = {yes | true | no | false}
Indicates whether the service should automatically restart if it stops for
access), or 666 (all users). The default is 666.
.TP
\fBsocket\-uid\fR = {\fInumeric-user-id\fR | \fIusername\fR}
-Specifies the user that should own the activation socket. If
-\fBsocket\-uid\fR is specified without also specifying \fBsocket-gid\fR, then
+Specifies the user (name or numeric ID) that should own the activation socket. If
+\fBsocket\-uid\fR is specified as a name without also specifying \fBsocket-gid\fR, then
the socket group is the primary group of the specified user (as found in the
-system user database, normally \fI/etc/passwd\fR). If the socket owner is not
-specified, the socket will be owned by the user id of the Dinit process.
+system user database, normally \fI/etc/passwd\fR). If the \fBsocket\-uid\fR setting is
+not provided, the socket will be owned by the user id of the \fBdinit\fR process.
.TP
\fBsocket\-gid\fR = {\fInumeric-group-id\fR | \fIgroup-name\fR}
Specifies the group of the activation socket. See discussion of
// Parse a userid parameter which may be a numeric user ID or a username. If a name, the
// userid is looked up via the system user database (getpwnam() function). In this case,
-// the associated group is stored in the location specified by the group_p parameter iff
-// it is not null and iff it contains the value -1.
+// the associated group is stored in the location specified by the group_p parameter if
+// it is not null.
inline uid_t parse_uid_param(const std::string ¶m, const std::string &service_name, const char *setting_name, gid_t *group_p)
{
const char * uid_err_msg = "Specified user id contains invalid numeric characters "
// a user manages to give themselves a username that parses as a number.
std::size_t ind = 0;
try {
- // POSIX does not specify whether uid_t is an signed or unsigned, but regardless
+ // POSIX does not specify whether uid_t is a signed or unsigned type, but regardless
// is is probably safe to assume that valid values are positive. We'll also assert
// that the value range fits within "unsigned long long" since it seems unlikely
// that would ever not be the case.
}
}
- if (group_p && *group_p != (gid_t)-1) {
+ if (group_p) {
*group_p = pwent->pw_gid;
}
// Note: Posix allows that uid_t and gid_t may be unsigned types, but eg chown uses -1 as an
// invalid value, so it's safe to assume that we can do the same:
uid_t socket_uid = -1;
+ gid_t socket_uid_gid = -1; // primary group of socket user if known
gid_t socket_gid = -1;
// Restart limit interval / count; default is 10 seconds, 3 restarts:
timespec restart_interval = { .tv_sec = 10, .tv_nsec = 0 };
std::string readiness_var; // environment var to hold readiness fd
uid_t run_as_uid = -1;
+ gid_t run_as_uid_gid = -1; // primary group of "run as" uid if known
gid_t run_as_gid = -1;
string chain_to_name;
char inittab_id[sizeof(utmpx().ut_id)] = {0};
char inittab_line[sizeof(utmpx().ut_line)] = {0};
#endif
+
+ // Finalise settings (after processing all setting lines)
+ void finalise()
+ {
+ // If socket_gid hasn't been explicitly set, but the socket_uid was specified as a name (and
+ // we therefore recovered the primary group), use the primary group of the specified user.
+ if (socket_gid == (gid_t)-1) socket_gid = socket_uid_gid;
+ // likewise for "run as" gid/uid.
+ if (run_as_gid == (gid_t)-1) run_as_gid = run_as_uid_gid;
+ }
};
// Process a service description line. In general, parse the setting value and record the parsed value
}
else if (setting == "socket-uid") {
string sock_uid_s = read_setting_value(i, end, nullptr);
- settings.socket_uid = parse_uid_param(sock_uid_s, name, "socket-uid", &settings.socket_gid);
+ settings.socket_uid = parse_uid_param(sock_uid_s, name, "socket-uid", &settings.socket_uid_gid);
}
else if (setting == "socket-gid") {
string sock_gid_s = read_setting_value(i, end, nullptr);
}
else if (setting == "run-as") {
string run_as_str = read_setting_value(i, end, nullptr);
- settings.run_as_uid = parse_uid_param(run_as_str, name, "run-as", &settings.run_as_gid);
+ settings.run_as_uid = parse_uid_param(run_as_str, name, "run-as", &settings.run_as_uid_gid);
}
else if (setting == "chain-to") {
settings.chain_to_name = read_setting_value(i, end, nullptr);