From nobody Thu Aug 26 01:43:19 2021 X-Original-To: freebsd-hackers@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 70D87179866F for ; Thu, 26 Aug 2021 01:43:38 +0000 (UTC) (envelope-from asomers@gmail.com) Received: from mail-ot1-f50.google.com (mail-ot1-f50.google.com [209.85.210.50]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "smtp.gmail.com", Issuer "GTS CA 1O1" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Gw5Gd2wtWz3Fn9 for ; Thu, 26 Aug 2021 01:43:37 +0000 (UTC) (envelope-from asomers@gmail.com) Received: by mail-ot1-f50.google.com with SMTP id c19-20020a9d6153000000b0051829acbfc7so1418160otk.9 for ; Wed, 25 Aug 2021 18:43:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=mZiZmBPRNnV1kbll6jRV9aGbT8HEApo+Npt8JPAQ+pQ=; b=ixZ3wYs4lKybH5KvhBbl246vN9pij6UAZmtbQv9Th7NFmodbgsjtHQwFRT/Ta64124 0LopDRD2ZWklEe1jPbAoE4NDzVXejV2hO4jaXVFDvDK2j47/YD/JK2GbApay0A14OEWh WFXPJEpUQCHb3V87oJTi8eRSX09i/Fi11GvXE30f4P677f4BoSiViTzQEhY4lm8wVACn zLKIhZfuvJY/D00p3tShHTf1TWyffF7okL8Ignh3rOAEA+6F5HXCgulm/DVVhzR8DZqP a7HmDL4KMunFx+8LTug08tBpR8wpQ1LBQ3kyoSLoSjCC48KYVbDvY+rxrShP3Oo443OK BPzQ== X-Gm-Message-State: AOAM532bqLCkukvQ8yp6r7uXaRW/mRZyDzptW1NeNF/mZy1E9ebd+rcN tlhOIHzE6I1nI41n16AyFUo/jeFwgd8Jyac4vW4XtYl2 X-Google-Smtp-Source: ABdhPJw9edqB9Zbasnth1kusBFPnXu1LUs2ye9ce5x4gGNa4+1Tdc6qB0+KEF9eeaTSozaGr7EXZ42o46wzSWD9Bc8Y= X-Received: by 2002:a9d:d04:: with SMTP id 4mr1124649oti.251.1629942210904; Wed, 25 Aug 2021 18:43:30 -0700 (PDT) List-Id: Technical discussions relating to FreeBSD List-Archive: https://lists.freebsd.org/archives/freebsd-hackers List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-freebsd-hackers@freebsd.org MIME-Version: 1.0 References: <1B45F065-DC9D-40C9-958F-7D4D64DE8993@freebsd.am> In-Reply-To: <1B45F065-DC9D-40C9-958F-7D4D64DE8993@freebsd.am> From: Alan Somers Date: Wed, 25 Aug 2021 19:43:19 -0600 Message-ID: Subject: Re: Need advice: Better Jail integration into ps/top, setpwfile gone forever? To: antranigv Cc: "freebsd-hackers@FreeBSD.org" Content-Type: multipart/alternative; boundary="0000000000007c465e05ca6c7e06" X-Rspamd-Queue-Id: 4Gw5Gd2wtWz3Fn9 X-Spamd-Bar: / Authentication-Results: mx1.freebsd.org; dkim=none; dmarc=none; spf=pass (mx1.freebsd.org: domain of asomers@gmail.com designates 209.85.210.50 as permitted sender) smtp.mailfrom=asomers@gmail.com X-Spamd-Result: default: False [-0.12 / 15.00]; SUBJECT_ENDS_QUESTION(1.00)[]; TO_DN_EQ_ADDR_SOME(0.00)[]; FREEFALL_USER(0.00)[asomers]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; R_SPF_ALLOW(-0.20)[+ip4:209.85.128.0/17]; RCVD_TLS_ALL(0.00)[]; MIME_GOOD(-0.10)[multipart/alternative,text/plain]; PREVIOUSLY_DELIVERED(0.00)[freebsd-hackers@freebsd.org]; ARC_NA(0.00)[]; RWL_MAILSPIKE_GOOD(0.00)[209.85.210.50:from]; DMARC_NA(0.00)[freebsd.org]; NEURAL_HAM_LONG(-1.00)[-1.000]; NEURAL_SPAM_MEDIUM(0.88)[0.876]; TO_MATCH_ENVRCPT_SOME(0.00)[]; NEURAL_HAM_SHORT(-1.00)[-1.000]; RCPT_COUNT_TWO(0.00)[2]; RCVD_IN_DNSWL_NONE(0.00)[209.85.210.50:from]; FORGED_SENDER(0.30)[asomers@freebsd.org,asomers@gmail.com]; R_DKIM_NA(0.00)[]; MIME_TRACE(0.00)[0:+,1:+,2:~]; ASN(0.00)[asn:15169, ipnet:209.85.128.0/17, country:US]; FROM_NEQ_ENVFROM(0.00)[asomers@freebsd.org,asomers@gmail.com]; FREEMAIL_ENVFROM(0.00)[gmail.com]; RCVD_COUNT_TWO(0.00)[2] X-Spam: Yes X-ThisMailContainsUnwantedMimeParts: Y --0000000000007c465e05ca6c7e06 Content-Type: text/plain; charset="UTF-8" On Mon, Aug 23, 2021 at 4:03 AM antranigv wrote: > Greetings all, > > I am trying to have better integration of top(1) and ps(1) with FreeBSD > Jails. > > The main problem that I am trying to solve is displaying the correct UID > username. Here's an example. > > I have a host (srv0), it is running a Jail named "fsoc", The Jail "fsoc" > has a user named "romero" with the UID 1001. > > If I run `ps auxd` in the Jail, I get the following, > > romero@fsoc:~ $ ps auxd > USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND > root 4377 0.0 0.0 11376 956 - SsJ 14:15 0:00.38 > /usr/sbin/syslogd -ss > root 5758 0.0 0.1 13128 1352 1 IJ 18:24 0:00.02 /bin/tcsh -i > root 5763 0.0 0.0 12048 960 1 IJ 18:24 0:00.01 - su - romero > romero 5764 0.0 0.1 12120 2268 1 SJ 18:24 0:00.02 `-- -su (sh) > romero 9625 0.0 0.1 11684 2576 1 R+J 09:41 0:00.01 `-- ps auxd > > Good! > > However, if I try to run it on the host, here's what I get, > > root@srv0:~ # ps auxd -J fsoc > USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND > root 4377 0.0 0.0 11376 956 - SsJ 14:15 0:00.38 /usr/sbin/syslogd > -ss > root 5758 0.0 0.1 13128 1352 1 IJ 18:24 0:00.02 /bin/tcsh -i > root 5763 0.0 0.0 12048 960 1 IJ 18:24 0:00.01 - su - romero > 1001 5764 0.0 0.1 12124 2436 1 I+J 18:24 0:00.02 `-- -su (sh) > > As you can see, in the User field it says 1001, because the host does not > have a user with that UID. > > This seems fine, but it becomes an issue when you have multiple Jail and a > large host running. > > Here's an example if the host had a user with UID 1001, > > root@pingvinashen:~ # ps auxd -J oragir > USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND > root 949 0.0 0.0 11344 2584 - IsJ Mon19 0:01.13 > /usr/sbin/cron -s > root 1962 0.0 0.0 11428 2796 - SsJ Mon19 0:01.83 > /usr/sbin/syslogd -ss > antranigv 95342 0.0 0.0 11004 2424 - IsJ Mon19 0:00.48 daemon: > /usr/home/oragir/writefreely/writefreely[9992] (daemon) > antranigv 9992 0.0 0.4 767244 58336 - IJ Mon19 2:58.87 - > /usr/home/oragir/writefreely/writefreely > > Now, you would think that this is good, however, if you run this in the > jail, > > root@oragir:~ # ps auxd > USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND > root 949 0.0 0.0 11344 2584 - SsJ Mon15 0:01.13 > /usr/sbin/cron -s > root 1962 0.0 0.0 11428 2796 - SsJ Mon15 0:01.83 > /usr/sbin/syslogd -ss > oragir 95342 0.0 0.0 11004 2424 - IsJ Mon15 0:00.48 daemon: > /usr/home/oragir/writefreely/writefreely[9992] (daemon) > oragir 9992 0.0 0.4 767244 58336 - IJ Mon15 2:58.88 - > /usr/home/oragir/writefreely/writefreely > root 88228 0.0 0.0 13336 4004 8 SJ 09:45 0:00.01 /bin/csh -i > root 99502 0.0 0.0 11824 3140 8 R+J 09:45 0:00.00 - ps auxd > > As you can see, the UID 1001 was not `antranigv`, instead it was `oragir`. > > This has been an issue for me, so I tried writing some code to implement > the following. > > If the process is in a Jail, then change the passwd db from /etc to > /path/of/the/jail/etc. > > I thought it would be an easy thing to do, but not so much. > > Here's what I've tried. > > 1) Call jail_attach and run ps inside the Jail. Oh yeah, it's a jail! > after attaching to it there is no way to deattach :-) silly me! > > 2) Change the passwd file for getpwuid/getpwnam. I wanted to use > setpwfile(3) but turns out that \ > COMPATIBILITY > The historic function setpwfile(3), which allowed the specification of > alternate password databases, has been deprecated and is no longer > available. > > Okay, So I look into how other tools like pwd_mkdb is written and I see > that everything is defined (pun intended) the following way, > > in /usr/include/pwd.h > > #define _PATH_PWD "/etc" > #define _PATH_PASSWD "/etc/passwd" > #define _PASSWD "passwd" > #define _PATH_MASTERPASSWD "/etc/master.passwd" > #define _MASTERPASSWD "master.passwd" > > #define _PATH_MP_DB "/etc/pwd.db" > #define _MP_DB "pwd.db" > #define _PATH_SMP_DB "/etc/spwd.db" > #define _SMP_DB "spwd.db" > > #define _PATH_PWD_MKDB "/usr/sbin/pwd_mkdb" > > and pwd_mkdb does the following > > ... > strcpy(prefix, _PATH_PWD); > ... > case 'd': > dflag++; > strlcpy(prefix, optarg, sizeof(prefix)); > break; > ... > > Tuns out it parses the DB file, but I don't want to do that in ps/top! :-) > > 3) Just for fun, I played with chroot. I tried the following code. > # cat getpw.c > > #define MAXHOSTNAMELEN 255 > #define MAXPATHLEN 255 > #include > //#include > #include > #include > #include > #include > #include > #include > > int main(){ > // Just get root! > struct passwd *pwd; > printf("just root: %s\n", (getpwuid(0))->pw_name); > > // let's try with undef/define > #undef _PATH_PWD > #undef _PATH_PASSWD > #undef _PASSWD > #undef _PATH_MASTERPASSWD > #undef _MASTERPASSWD > > #undef _PATH_MP_DB > #undef _MP_DB > #undef _PATH_SMP_DB > #undef _SMP_DB > > #define _PATH_PWD "/zdata/jails/fsoc/etc" > #define _PATH_PASSWD "/zdata/jails/fsoc/etc/passwd" > #define _PASSWD "passwd" > #define _PATH_MASTERPASSWD "/zdata/jails/fsoc/etc/master.passwd" > #define _MASTERPASSWD "master.passwd" > > #define _PATH_MP_DB "/zdata/jails/fsoc/etc/pwd.db" > #define _MP_DB "pwd.db" > #define _PATH_SMP_DB "/zdata/jails/fsoc/etc/spwd.db" > #define _SMP_DB "spwd.db" > pwd = getpwuid(1001); > if (pwd == NULL) { > printf("using undef/define: no user found\n"); > } else { > printf("using undef/define: %s\n", pwd->pw_name); > } > > // let's try with chroot! > chroot("/zdata/jails/fsoc"); > pwd = getpwuid(1001); > if (pwd == NULL) { > printf("after chroot: no user found\n"); > } else { > printf("after chroot: %s\n", pwd->pw_name); > } > > // escape back the chroot ;-) > chroot("../../../../"); > pwd = getpwuid(1001); > if (pwd == NULL) { > printf("after unchroot: no user found\n"); > } else { > printf("after chroot: %s\n", pwd->pw_name); > } > > return 42; > } > > And I get the following: > > # ./getpw > just root: root > using undef/define: no user found > after chroot: romero > after unchroot: no user found > > So, any advice? should I do chroot in ps? (no I don't think that's a good > idea), should I add a new call that implements setpwfile(3)? But I really > want to know why it was removed, I'm sure there's a story there. Or is > there a better way? > > Kind regards, have a nice day! > > -- > antranigv > https://antranigv.am/ > Oof, that's a hard problem. But in fact, it's worse than you think. /etc/passwd isn't the only place that user information is stored. It could be in NIS, or LDAP, or Heimdal, or who knows where. The only reliable way to look up a user is to actually do it from within the jail. You could create a socketpair, then fork a child process and attach that to the jail, and use it to lookup jailed UIDs. It's complicated, but I can't imagine anything simpler that would work. -Alan --0000000000007c465e05ca6c7e06--