runit

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 993c4102e0594ffbda6199b2b014f7e3e4ef8334
parent 480651ade4426ecd92171ed33324e98843696b63
Author: Gerrit Pape <pape@smarden.org>
Date:   Thu,  2 Nov 2006 22:59:14 +0000

  * chpst.c, uidgid.c, uidgid.h: support numerical uid gid through
    chpst -[u|U] :uid:gid...
  * man/chpst.8: adapt; clarify that users and groups are looked up in
    /etc/passwd and /etc/group only.
  * sv.c: properly wait for a service to be restarted on 'restart';
    support checks through -v for pause, cont, kill.

Diffstat:
Mman/chpst.8 | 34++++++++++++++++++++++++++++------
Mpackage/CHANGES | 9+++++++++
Msrc/chpst.c | 26++++++++++++++++++--------
Msrc/sv.c | 11+++++++++--
Msrc/uidgid.c | 45+++++++++++++++++++++++++++++++++++++++------
Msrc/uidgid.h | 6+++++-
6 files changed, 108 insertions(+), 23 deletions(-)

diff --git a/man/chpst.8 b/man/chpst.8 @@ -38,18 +38,21 @@ changes the process state according to the given options, and runs .IR prog . .SH OPTIONS .TP -.B \-u \fIuser[:group] +.B \-u \fI[:]user[:group] setuidgid. Set uid and gid to the .IR user 's -uid and gid. +uid and gid, as found in +.IR /etc/passwd . If .I user is followed by a colon and a .IR group , set the gid to .IR group 's -gid instead of +gid, as found in +.IR /etc/group , +instead of .IR user 's gid. If @@ -57,22 +60,41 @@ If consists of a colon-separated list of group names, .B chpst sets the group ids of all listed groups. +If +.I user +is prefixed with a colon, the +.I user +and all +.I group +arguments are interpreted as uid and gids respectivly, and not looked up in +the password or group file. All initial supplementary groups are removed. .TP -.B \-U \fIuser[:group] +.B \-U \fI[:]user[:group] envuidgid. Set the environment variables $UID and $GID to the .IR user 's -uid and gid. +uid and gid, as found in +.IR /etc/passwd . If .I user is followed by a colon and a .IR group , set $GID to the .IR group 's -gid instead of +gid, as found in +.IR /etc/group , +instead of .IR user 's gid. +If +.I user +is prefixed with a colon, the +.I user +and +.I group +arguments are interpreted as uid and gid respectivly, and not looked up in +the password or group file. .TP .B \-e \fIdir envdir. diff --git a/package/CHANGES b/package/CHANGES @@ -1,3 +1,12 @@ +1.8.0 + + * chpst.c, uidgid.c, uidgid.h: support numerical uid gid through + chpst -[u|U] :uid:gid... + * man/chpst.8: adapt; clarify that users and groups are looked up in + /etc/passwd and /etc/group only. + * sv.c: properly wait for a service to be restarted on 'restart'; + support checks through -v for pause, cont, kill. + 1.7.0 Sat, 07 Oct 2006 18:24:17 +0000 * svlogd.c, fmt_ptime.*, man/svlogd.8: new option -ttt: prefix log diff --git a/src/chpst.c b/src/chpst.c @@ -61,30 +61,40 @@ const char *lock =0; const char *root =0; unsigned int lockdelay; -void suidgid(char *user, unsigned int dogrp) { +void suidgid(char *user, unsigned int ext) { struct uidgid ugid; - if (! uidgid_get(&ugid, user, dogrp)) { - if (dogrp) + if (ext) { + if (! uidgids_get(&ugid, user)) { + if (*user == ':') + fatalx("invalid uid/gids", user +1); + else fatalx("unknown user/group", user); + } + } else + if (! uidgid_get(&ugid, user)) fatalx("unknown account", user); - } if (setgroups(ugid.gids, ugid.gid) == -1) fatal("unable to setgroups"); if (setgid(*ugid.gid) == -1) fatal("unable to setgid"); if (prot_uid(ugid.uid) == -1) fatal("unable to setuid"); } -void euidgid(char *user, unsigned int dogrp) { +void euidgid(char *user, unsigned int ext) { struct uidgid ugid; char bufnum[FMT_ULONG]; - if (! uidgid_get(&ugid, user, dogrp)) { - if (dogrp) + if (ext) { + if (! uidgids_get(&ugid, user)) { + if (*user == ':') + fatalx("invalid uid/gids", user +1); + else fatalx("unknown user/group", user); + } + } else + if (! uidgid_get(&ugid, user)) fatalx("unknown account", user); - } bufnum[fmt_ulong(bufnum, *ugid.gid)] =0; if (! pathexec_env("GID", bufnum)) die_nomem(); bufnum[fmt_ulong(bufnum, ugid.uid)] =0; diff --git a/src/sv.c b/src/sv.c @@ -208,6 +208,7 @@ int check(char *a) { unsigned int pid; if ((r =svstatus_get()) == -1) return(-1); + while (*a) { if (r == 0) { if (*a == 'x') return(1); return(-1); } pid =(unsigned char)svstatus[15]; pid <<=8; pid +=(unsigned char)svstatus[14]; @@ -220,8 +221,9 @@ int check(char *a) { if (!checkscript()) return(0); break; case 'd': if (pid) return(0); break; - case 'c': if (pid) if (!checkscript()) return(0); break; + case 'C': if (pid) if (!checkscript()) return(0); break; case 't': + case 'k': if (!pid && svstatus[17] == 'd') break; tai_unpack(svstatus, &tstatus); if ((tstart.sec.x > tstatus.x) || !pid || svstatus[18] || !checkscript()) @@ -231,6 +233,11 @@ int check(char *a) { tai_unpack(svstatus, &tstatus); if ((!pid && tstart.sec.x > tstatus.x) || (pid && svstatus[17] != 'd')) return(0); + break; + case 'p': if (pid && !svstatus[16]) return(0); break; + case 'c': if (pid && svstatus[16]) return(0); break; + } + ++a; } outs(OK); svstatus_print(*service); flush("\n"); return(1); @@ -297,7 +304,7 @@ int main(int argc, char **argv) { case 'T': acts ="tc"; kll =1; cbk =&check; break; case 'c': - if (!str_diff(action, "check")) { act =0; acts ="c"; cbk =&check; break; } + if (!str_diff(action, "check")) { act =0; acts ="C"; cbk =&check; break; } case 'u': case 'd': case 'o': case 't': case 'p': case 'h': case 'a': case 'i': case 'k': case 'q': case '1': case '2': action[1] =0; acts =action; break; diff --git a/src/uidgid.c b/src/uidgid.c @@ -3,20 +3,56 @@ #include <grp.h> #include "uidgid.h" #include "str.h" +#include "scan.h" -unsigned int uidgid_get(struct uidgid *u, char *ug, unsigned int dogrp) { +/* user */ +unsigned int uidgid_get(struct uidgid *u, char *ug) { + struct passwd *pwd =0; + + if (! (pwd =getpwnam(ug))) return(0); + u->gid[0] =pwd->pw_gid; u->gids =1; + u->uid =pwd->pw_uid; + return(1); +} + +/* uid:gid[:gid[:gid]...] */ +unsigned int uidgids_set(struct uidgid *u, char *ug) { + unsigned long id; + int i; + + if (*(ug +=scan_ulong(ug, &id)) != ':') return(0); + u->uid =(uid_t)id; + ++ug; + for (i =0; i < 60; ++i, ++ug) { + ug +=scan_ulong(ug, &id); + u->gid[i] =(gid_t)id; + if (*ug != ':') { ++i; break; } + } + u->gid[i] =0; + u->gids =i; + if (*ug) return(0); + return(1); +} + +/* [:]user[:group[:group]...] */ +unsigned int uidgids_get(struct uidgid *u, char *ug) { char *g =0; struct passwd *pwd =0; struct group *gr =0; int i, d =0; - if (dogrp) + if (*ug == ':') return(uidgids_set(u, ug +1)); if (ug[(d =str_chr(ug, ':'))] == ':') { ug[d] =0; g =ug +d +1; } if (! (pwd =getpwnam(ug))) { if (g) ug[d] =':'; return(0); } - if (g) { + u->uid =pwd->pw_uid; + if (! g) { + u->gid[0] =pwd->pw_gid; + u->gids =1; + return(1); + } ug[d] =':'; for (i =0; i < 60; ++i) { if (g[(d =str_chr(g, ':'))] == ':') { @@ -34,8 +70,5 @@ unsigned int uidgid_get(struct uidgid *u, char *ug, unsigned int dogrp) { } u->gid[i] =0; u->gids =i; - } - if (! g) { u->gid[0] =pwd->pw_gid; u->gids =1; } - u->uid =pwd->pw_uid; return(1); } diff --git a/src/uidgid.h b/src/uidgid.h @@ -9,6 +9,10 @@ struct uidgid { int gids; }; -extern unsigned int uidgid_get(struct uidgid *, char *, unsigned int); +/* user */ +extern unsigned int uidgid_get(struct uidgid *, char *); + +/* [:]user[:group[:group]...] */ +extern unsigned int uidgids_get(struct uidgid *, char *); #endif