diff options
author | Gerrit Pape <pape@smarden.org> | 2006-11-02 22:59:14 +0000 |
---|---|---|
committer | Gerrit Pape <pape@smarden.org> | 2006-11-02 22:59:14 +0000 |
commit | a1bbb6ddcf9119220c509c2e6424cf6a5a20d984 (patch) | |
tree | e1691179493adeaa9e59410895afc47b50f2f704 | |
parent | c09a0fe2d6721235b106745b03e2992f0d35fc24 (diff) | |
download | runit-a1bbb6ddcf9119220c509c2e6424cf6a5a20d984.tar.gz runit-a1bbb6ddcf9119220c509c2e6424cf6a5a20d984.tar.xz runit-a1bbb6ddcf9119220c509c2e6424cf6a5a20d984.zip |
* 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.
-rw-r--r-- | man/chpst.8 | 34 | ||||
-rw-r--r-- | package/CHANGES | 9 | ||||
-rw-r--r-- | src/chpst.c | 26 | ||||
-rw-r--r-- | src/sv.c | 11 | ||||
-rw-r--r-- | src/uidgid.c | 45 | ||||
-rw-r--r-- | src/uidgid.h | 6 |
6 files changed, 108 insertions, 23 deletions
diff --git a/man/chpst.8 b/man/chpst.8 index 42c23d3..c67ec65 100644 --- 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 index 4679a3a..4341bdb 100644 --- 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 index ae07e36..9df2fb6 100644 --- 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 index a9592f4..c8126a3 100644 --- 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 =✓ break; case 'c': - if (!str_diff(action, "check")) { act =0; acts ="c"; cbk =✓ break; } + if (!str_diff(action, "check")) { act =0; acts ="C"; cbk =✓ 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 index 720d2ff..718d7a9 100644 --- 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 index f8599a1..13cacbc 100644 --- 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 |