summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCameron Katri <me@cameronkatri.com>2021-05-02 16:00:07 -0400
committerCameron Katri <me@cameronkatri.com>2021-05-02 16:00:07 -0400
commitf3dab068fce37270e5e4e1a00e5a44e30f00baf7 (patch)
treed6b8c70074d440e56c1d7cdbfc7b68d8b96bda96
parent6b46c62f4663c84790120a4e74e155a6ef16b41c (diff)
downloadpw-darwin-f3dab068fce37270e5e4e1a00e5a44e30f00baf7.tar.gz
pw-darwin-f3dab068fce37270e5e4e1a00e5a44e30f00baf7.tar.zst
pw-darwin-f3dab068fce37270e5e4e1a00e5a44e30f00baf7.zip
Recommit everything, add chpass, improve history (except for a few files that git-filter-repo dislikes for some reason [_secure_path.c and login_cap.h])
-rw-r--r--.clang-format194
-rw-r--r--.gitignore3
-rw-r--r--Makefile9
-rw-r--r--adduser/Makefile22
-rw-r--r--adduser/adduser.conf.54
-rw-r--r--adduser/adduser.sh2
-rw-r--r--adduser/rmuser.sh2
-rw-r--r--chpass/Makefile87
-rw-r--r--chpass/chpass.c62
-rw-r--r--ent.xml11
-rw-r--r--libc/gen/pw_scan.c27
-rw-r--r--libutil/_secure_path.c74
-rw-r--r--libutil/gr_util.c7
-rw-r--r--libutil/libutil.h28
-rw-r--r--libutil/login_cap.c4
-rw-r--r--libutil/login_cap.h164
-rw-r--r--libutil/login_crypt.c2
-rw-r--r--libutil/pw_util.c10
-rw-r--r--pw/Makefile63
-rw-r--r--pw/cpdir.c2
-rw-r--r--pw/pw.86
-rw-r--r--pw/pw_conf.c4
-rw-r--r--pw/pw_log.c1
-rw-r--r--pw/pw_user.c207
-rw-r--r--pw/pwupd.c2
25 files changed, 790 insertions, 207 deletions
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..06709b7
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,194 @@
+# $FreeBSD$
+# Basic .clang-format
+---
+BasedOnStyle: WebKit
+AlignAfterOpenBracket: DontAlign
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Left
+AlignOperands: false
+AlignTrailingComments: true
+AllowAllArgumentsOnNextLine: false
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortBlocksOnASingleLine: Never
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: InlineOnly
+AllowShortIfStatementsOnASingleLine: Never
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterReturnType: TopLevelDefinitions
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: MultiLine
+BinPackArguments: true
+BinPackParameters: true
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: WebKit
+BreakBeforeTernaryOperators: false
+# TODO: BreakStringLiterals can cause very strange formatting so turn it off?
+BreakStringLiterals: false
+# Prefer:
+# some_var = function(arg1,
+# arg2)
+# over:
+# some_var =
+# function(arg1, arg2)
+PenaltyBreakAssignment: 100
+# Prefer:
+# some_long_function(arg1, arg2
+# arg3)
+# over:
+# some_long_function(
+# arg1, arg2, arg3)
+PenaltyBreakBeforeFirstCallParameter: 100
+CompactNamespaces: true
+DerivePointerAlignment: false
+DisableFormat: false
+ForEachMacros:
+ - ARB_ARRFOREACH
+ - ARB_ARRFOREACH_REVWCOND
+ - ARB_ARRFOREACH_REVERSE
+ - ARB_FOREACH
+ - ARB_FOREACH_FROM
+ - ARB_FOREACH_SAFE
+ - ARB_FOREACH_REVERSE
+ - ARB_FOREACH_REVERSE_FROM
+ - ARB_FOREACH_REVERSE_SAFE
+ - CPU_FOREACH
+ - FOREACH_THREAD_IN_PROC
+ - FOREACH_PROC_IN_SYSTEM
+ - FOREACH_PRISON_CHILD
+ - FOREACH_PRISON_DESCENDANT
+ - FOREACH_PRISON_DESCENDANT_LOCKED
+ - FOREACH_PRISON_DESCENDANT_LOCKED_LEVEL
+ - MNT_VNODE_FOREACH_ALL
+ - MNT_VNODE_FOREACH_ACTIVE
+ - RB_FOREACH
+ - RB_FOREACH_FROM
+ - RB_FOREACH_SAFE
+ - RB_FOREACH_REVERSE
+ - RB_FOREACH_REVERSE_FROM
+ - RB_FOREACH_REVERSE_SAFE
+ - SLIST_FOREACH
+ - SLIST_FOREACH_FROM
+ - SLIST_FOREACH_FROM_SAFE
+ - SLIST_FOREACH_SAFE
+ - SLIST_FOREACH_PREVPTR
+ - SPLAY_FOREACH
+ - LIST_FOREACH
+ - LIST_FOREACH_FROM
+ - LIST_FOREACH_FROM_SAFE
+ - LIST_FOREACH_SAFE
+ - STAILQ_FOREACH
+ - STAILQ_FOREACH_FROM
+ - STAILQ_FOREACH_FROM_SAFE
+ - STAILQ_FOREACH_SAFE
+ - TAILQ_FOREACH
+ - TAILQ_FOREACH_FROM
+ - TAILQ_FOREACH_FROM_SAFE
+ - TAILQ_FOREACH_REVERSE
+ - TAILQ_FOREACH_REVERSE_FROM
+ - TAILQ_FOREACH_REVERSE_FROM_SAFE
+ - TAILQ_FOREACH_REVERSE_SAFE
+ - TAILQ_FOREACH_SAFE
+ - VM_MAP_ENTRY_FOREACH
+ - VM_PAGE_DUMP_FOREACH
+IndentCaseLabels: false
+IndentPPDirectives: None
+Language: Cpp
+NamespaceIndentation: None
+PointerAlignment: Right
+ContinuationIndentWidth: 4
+IndentWidth: 8
+TabWidth: 8
+ColumnLimit: 80
+UseTab: Always
+SpaceAfterCStyleCast: false
+IncludeBlocks: Regroup
+IncludeCategories:
+ - Regex: '^\"opt_.*\.h\"'
+ Priority: 1
+ SortPriority: 10
+ - Regex: '^<sys/cdefs\.h>'
+ Priority: 2
+ SortPriority: 20
+ - Regex: '^<sys/types\.h>'
+ Priority: 2
+ SortPriority: 21
+ - Regex: '^<sys/param\.h>'
+ Priority: 2
+ SortPriority: 22
+ - Regex: '^<sys/systm\.h>'
+ Priority: 2
+ SortPriority: 23
+ - Regex: '^<sys.*/'
+ Priority: 2
+ SortPriority: 24
+ - Regex: '^<vm/vm\.h>'
+ Priority: 3
+ SortPriority: 30
+ - Regex: '^<vm/'
+ Priority: 3
+ SortPriority: 31
+ - Regex: '^<machine/'
+ Priority: 4
+ SortPriority: 40
+ - Regex: '^<(x86|amd64|i386|xen)/'
+ Priority: 5
+ SortPriority: 50
+ - Regex: '^<dev/'
+ Priority: 6
+ SortPriority: 60
+ - Regex: '^<net.*/'
+ Priority: 7
+ SortPriority: 70
+ - Regex: '^<protocols/'
+ Priority: 7
+ SortPriority: 71
+ - Regex: '^<(fs|nfs(|client|server)|ufs)/'
+ Priority: 8
+ SortPriority: 80
+ - Regex: '^<[^/].*\.h'
+ Priority: 9
+ SortPriority: 90
+ - Regex: '^\".*\.h\"'
+ Priority: 10
+ SortPriority: 100
+# LLVM's header include ordering style is almost the exact opposite of ours.
+# Unfortunately, they have hard-coded their preferences into clang-format.
+# Clobbering this regular expression to avoid matching prevents non-system
+# headers from being forcibly moved to the top of the include list.
+# http://llvm.org/docs/CodingStandards.html#include-style
+IncludeIsMainRegex: 'BLAH_DONT_MATCH_ANYTHING'
+SortIncludes: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+TypenameMacros:
+ - ARB_ELMTYPE
+ - ARB_HEAD
+ - ARB8_HEAD
+ - ARB16_HEAD
+ - ARB32_HEAD
+ - ARB_ENTRY
+ - ARB8_ENTRY
+ - ARB16_ENTRY
+ - ARB32_ENTRY
+ - LIST_CLASS_ENTRY
+ - LIST_CLASS_HEAD
+ - LIST_ENTRY
+ - LIST_HEAD
+ - QUEUE_TYPEOF
+ - RB_ENTRY
+ - RB_HEAD
+ - SLIST_CLASS_HEAD
+ - SLIST_CLASS_ENTRY
+ - SLIST_HEAD
+ - SLIST_ENTRY
+ - SMR_POINTER
+ - SPLAY_ENTRY
+ - SPLAY_HEAD
+ - STAILQ_CLASS_ENTRY
+ - STAILQ_CLASS_HEAD
+ - STAILQ_ENTRY
+ - STAILQ_HEAD
+ - TAILQ_CLASS_ENTRY
+ - TAILQ_CLASS_HEAD
+ - TAILQ_ENTRY
+ - TAILQ_HEAD
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..270dfe1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+*.o
+pw/pw
+chpass/chpass
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..1fb123d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,9 @@
+TOPTARGETS := all clean install
+SUBDIRS := adduser chpass pw
+
+$(TOPTARGETS): $(SUBDIRS)
+
+$(SUBDIRS):
+ $(MAKE) -C $@ $(MAKECMDGOALS)
+
+.PHONY: $(TOPTARGETS) $(SUBDIRS)
diff --git a/adduser/Makefile b/adduser/Makefile
new file mode 100644
index 0000000..7d67923
--- /dev/null
+++ b/adduser/Makefile
@@ -0,0 +1,22 @@
+GINSTALL ?= install
+PREFIX ?= /usr
+DESTDIR ?=
+
+all:
+ @echo "Nothing to build"
+
+clean:
+ @echo "Nothing to clean"
+
+install: install-adduser install-rmuser
+
+install-adduser: adduser.sh adduser.8 adduser.conf.5
+ $(GINSTALL) -Dm755 adduser.sh $(DESTDIR)/$(PREFIX)/sbin/adduser
+ $(GINSTALL) -Dm644 adduser.8 $(DESTDIR)/$(PREFIX)/share/man/man8/adduser.8
+ $(GINSTALL) -Dm644 adduser.conf.5 $(DESTDIR)/$(PREFIX)/share/man/man5/adduser.conf.5
+
+install-rmuser: rmuser.sh rmuser.8
+ $(GINSTALL) -Dm755 rmuser.sh $(DESTDIR)/$(PREFIX)/sbin/rmuser
+ $(GINSTALL) -Dm644 rmuser.8 $(DESTDIR)/$(PREFIX)/share/man/man8/rmuser.8
+
+.PHONY: all install install-adduser install-rmuser clean
diff --git a/adduser/adduser.conf.5 b/adduser/adduser.conf.5
index af9fe22..42ccaa0 100644
--- a/adduser/adduser.conf.5
+++ b/adduser/adduser.conf.5
@@ -120,7 +120,7 @@ read in
.Xr adduser 8 .
.It Va homeprefix
The default home directory prefix, usually
-.Pa /home .
+.Pa /var .
.It Va defaultshell
The user's default shell which may be any of the shells listed in
.Xr shells 5 .
@@ -190,7 +190,7 @@ defaultLgroup=
defaultclass=
defaultgroups=
passwdtype=yes
-homeprefix=/home
+homeprefix=/var
defaultshell=/bin/csh
udotdir=/usr/share/skel
msgfile=/etc/adduser.msg
diff --git a/adduser/adduser.sh b/adduser/adduser.sh
index 91a1b4b..b9abd81 100644
--- a/adduser/adduser.sh
+++ b/adduser/adduser.sh
@@ -877,7 +877,7 @@ disableflag=
Dflag=
Sflag=
readconfig="yes"
-homeprefix="/home"
+homeprefix="/var"
randompass=
fileline=
savedpwtype=
diff --git a/adduser/rmuser.sh b/adduser/rmuser.sh
index abaf004..e2308d0 100644
--- a/adduser/rmuser.sh
+++ b/adduser/rmuser.sh
@@ -156,7 +156,7 @@ rm_ipc() {
for i in s m q; do
ipcs -$i |
awk -v i=$i -v login=$1 '$1 == i && $5 == login { print $2 }' |
- xargs -n 1 ipcrm -$i
+ xargs -r -n 1 ipcrm -$i
done
verbose && echo '.'
}
diff --git a/chpass/Makefile b/chpass/Makefile
index bd5baa3..1f88e51 100644
--- a/chpass/Makefile
+++ b/chpass/Makefile
@@ -1,45 +1,42 @@
-# @(#)Makefile 8.2 (Berkeley) 4/2/94
-# $FreeBSD$
-
-.include <src.opts.mk>
-
-.PATH: ${SRCTOP}/lib/libc/gen
-
-PROG= chpass
-SRCS= chpass.c edit.c field.c pw_scan.c table.c util.c
-BINOWN= root
-BINMODE=4555
-PRECIOUSPROG=
-.if ${MK_NIS} != "no"
-CFLAGS+= -DYP
-.endif
-#Some people need this, uncomment to activate
-#CFLAGS+=-DRESTRICT_FULLNAME_CHANGE
-CFLAGS+=-I${SRCTOP}/lib/libc/gen -I.
-
-LIBADD= crypt util
-.if ${MK_NIS} != "no"
-LIBADD+= ypclnt
-.endif
-
-SYMLINKS= chpass ${BINDIR}/chfn
-SYMLINKS+= chpass ${BINDIR}/chsh
-.if ${MK_NIS} != "no"
-SYMLINKS+= chpass ${BINDIR}/ypchfn
-SYMLINKS+= chpass ${BINDIR}/ypchpass
-SYMLINKS+= chpass ${BINDIR}/ypchsh
-.endif
-
-MLINKS= chpass.1 chfn.1 chpass.1 chsh.1
-.if ${MK_NIS} != "no"
-MLINKS+= chpass.1 ypchpass.1 chpass.1 ypchfn.1 chpass.1 ypchsh.1
-.endif
-
-beforeinstall:
-.for i in chpass chfn chsh ypchpass ypchfn ypchsh
-.if exists(${DESTDIR}${BINDIR}/$i)
- -chflags noschg ${DESTDIR}${BINDIR}/$i
-.endif
-.endfor
-
-.include <bsd.prog.mk>
+CC ?= aarch64-apple-darwin-clang
+STRIP ?= aarch64-apple-darwin-strip
+LDID ?= ldid
+CFLAGS ?= -arch arm64 -isysroot /home/cameron/Documents/SDK/iPhoneOS14.3.sdk -miphoneos-version-min=13.0
+LDFLAGS ?=
+GINSTALL ?= install
+PREFIX ?= /usr
+DESTDIR ?=
+
+SRC := chpass.c \
+ edit.c \
+ field.c \
+ table.c \
+ util.c \
+ ../libutil/pw_util.c \
+ ../libutil/flopen.c \
+ ../libc/gen/pw_scan.c
+
+all: chpass
+
+install: install-chpass
+
+chpass: $(SRC:%.c=%.o) ../ent.xml
+ $(CC) $(LDFLAGS) -o $@ -lcrypt $(SRC:%.c=%.o)
+ $(STRIP) $@
+ $(LDID) -S../ent.xml $@
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c -o $@ $< -I. -I../libutil -I../libc/gen
+
+install-chpass: chpass chpass.1
+ $(GINSTALL) -Dm4555 chpass $(DESTDIR)/$(PREFIX)/bin/chpass
+ ln -sf chpass $(DESTDIR)/$(PREFIX)/bin/chfn
+ ln -sf chpass $(DESTDIR)/$(PREFIX)/bin/chsh
+ $(GINSTALL) -Dm644 chpass.1 $(DESTDIR)/$(PREFIX)/share/man/man1/chpass.1
+ ln -sf chpass.1 $(DESTDIR)/$(PREFIX)/share/man/man1/chfn.1
+ ln -sf chpass.1 $(DESTDIR)/$(PREFIX)/share/man/man1/chsh.1
+
+clean:
+ rm -f chpass $(SRC:%.c=%.o)
+
+.PHONY: all install install-chpass clean
diff --git a/chpass/chpass.c b/chpass/chpass.c
index 643b0f3..3b3a41f 100644
--- a/chpass/chpass.c
+++ b/chpass/chpass.c
@@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$");
#include <pw_scan.h>
#include <libutil.h>
+#include <crypt.h>
#include "chpass.h"
@@ -237,51 +238,26 @@ main(int argc, char *argv[])
password = "";
}
- if (old_pw != NULL)
- pw->pw_fields |= (old_pw->pw_fields & _PWF_SOURCE);
- switch (pw->pw_fields & _PWF_SOURCE) {
-#ifdef YP
- case _PWF_NIS:
- ypclnt = ypclnt_new(yp_domain, "passwd.byname", yp_host);
- if (ypclnt == NULL) {
- warnx("ypclnt_new failed");
- exit(1);
- }
- if (ypclnt_connect(ypclnt) == -1 ||
- ypclnt_passwd(ypclnt, pw, password) == -1) {
- warnx("%s", ypclnt->error);
- ypclnt_free(ypclnt);
- exit(1);
- }
- ypclnt_free(ypclnt);
- errx(0, "NIS user information updated");
-#endif /* YP */
- case 0:
- case _PWF_FILES:
- if (pw_init(NULL, NULL))
- err(1, "pw_init()");
- if ((pfd = pw_lock()) == -1) {
- pw_fini();
- err(1, "pw_lock()");
- }
- if ((tfd = pw_tmp(-1)) == -1) {
- pw_fini();
- err(1, "pw_tmp()");
- }
- if (pw_copy(pfd, tfd, pw, old_pw) == -1) {
- pw_fini();
- err(1, "pw_copy");
- }
- if (pw_mkdb(pw->pw_name) == -1) {
- pw_fini();
- err(1, "pw_mkdb()");
- }
+ if (pw_init(NULL, NULL))
+ err(1, "pw_init()");
+ if ((pfd = pw_lock()) == -1) {
+ pw_fini();
+ err(1, "pw_lock()");
+ }
+ if ((tfd = pw_tmp(-1)) == -1) {
+ pw_fini();
+ err(1, "pw_tmp()");
+ }
+ if (pw_copy(pfd, tfd, pw, old_pw) == -1) {
+ pw_fini();
+ err(1, "pw_copy");
+ }
+ if (pw_mkdb(pw->pw_name) == -1) {
pw_fini();
- errx(0, "user information updated");
- break;
- default:
- errx(1, "unsupported passwd source");
+ err(1, "pw_mkdb()");
}
+ pw_fini();
+ errx(0, "user information updated");
}
static void
diff --git a/ent.xml b/ent.xml
new file mode 100644
index 0000000..82c18f9
--- /dev/null
+++ b/ent.xml
@@ -0,0 +1,11 @@
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>platform-application</key>
+ <true/>
+ <key>com.apple.private.security.no-container</key>
+ <true/>
+ <key>com.apple.private.skip-library-validation</key>
+ <true/>
+</dict>
+</plist>
diff --git a/libc/gen/pw_scan.c b/libc/gen/pw_scan.c
index 619092d..f680a90 100644
--- a/libc/gen/pw_scan.c
+++ b/libc/gen/pw_scan.c
@@ -92,23 +92,17 @@ __pw_scan(char *bp, struct passwd *pw, int flags)
if (pw_big_ids_warning == -1)
pw_big_ids_warning = getenv("PW_SCAN_BIG_IDS") == NULL ? 1 : 0;
- pw->pw_fields = 0;
if (!(pw->pw_name = strsep(&bp, ":"))) /* login */
goto fmt;
root = !strcmp(pw->pw_name, "root");
- if (pw->pw_name[0] && (pw->pw_name[0] != '+' || pw->pw_name[1] == '\0'))
- pw->pw_fields |= _PWF_NAME;
if (!(pw->pw_passwd = strsep(&bp, ":"))) /* passwd */
goto fmt;
- if (pw->pw_passwd[0])
- pw->pw_fields |= _PWF_PASSWD;
if (!(p = strsep(&bp, ":"))) /* uid */
goto fmt;
- if (p[0])
- pw->pw_fields |= _PWF_UID;
- else {
+ if (p[0]) {
+ } else {
if (pw->pw_name[0] != '+' && pw->pw_name[0] != '-') {
if (flags & _PWSCAN_WARN)
warnx("no uid for user %s", pw->pw_name);
@@ -141,9 +135,8 @@ __pw_scan(char *bp, struct passwd *pw, int flags)
if (!(p = strsep(&bp, ":"))) /* gid */
goto fmt;
- if (p[0])
- pw->pw_fields |= _PWF_GID;
- else {
+ if (p[0]) {
+ } else {
if (pw->pw_name[0] != '+' && pw->pw_name[0] != '-') {
if (flags & _PWSCAN_WARN)
warnx("no gid for user %s", pw->pw_name);
@@ -172,30 +165,20 @@ __pw_scan(char *bp, struct passwd *pw, int flags)
if (flags & _PWSCAN_MASTER ) {
if (!(pw->pw_class = strsep(&bp, ":"))) /* class */
goto fmt;
- if (pw->pw_class[0])
- pw->pw_fields |= _PWF_CLASS;
if (!(p = strsep(&bp, ":"))) /* change */
goto fmt;
- if (p[0])
- pw->pw_fields |= _PWF_CHANGE;
pw->pw_change = atol(p);
if (!(p = strsep(&bp, ":"))) /* expire */
goto fmt;
- if (p[0])
- pw->pw_fields |= _PWF_EXPIRE;
pw->pw_expire = atol(p);
}
if (!(pw->pw_gecos = strsep(&bp, ":"))) /* gecos */
goto fmt;
- if (pw->pw_gecos[0])
- pw->pw_fields |= _PWF_GECOS;
if (!(pw->pw_dir = strsep(&bp, ":"))) /* directory */
goto fmt;
- if (pw->pw_dir[0])
- pw->pw_fields |= _PWF_DIR;
if (!(pw->pw_shell = strsep(&bp, ":"))) /* shell */
goto fmt;
@@ -213,8 +196,6 @@ __pw_scan(char *bp, struct passwd *pw, int flags)
}
endusershell();
}
- if (p[0])
- pw->pw_fields |= _PWF_SHELL;
if ((p = strsep(&bp, ":"))) { /* too many */
fmt:
diff --git a/libutil/_secure_path.c b/libutil/_secure_path.c
new file mode 100644
index 0000000..363378b
--- /dev/null
+++ b/libutil/_secure_path.c
@@ -0,0 +1,74 @@
+/*-
+ * Based on code copyright (c) 1995,1997 by
+ * Berkeley Software Design, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. This work was done expressly for inclusion into FreeBSD. Other use
+ * is permitted provided this notation is included.
+ * 4. Absolutely no warranty of function or purpose is made by the authors.
+ * 5. Modifications may be freely made to this file providing the above
+ * conditions are met.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <libutil.h>
+#include <stddef.h>
+#include <syslog.h>
+
+/*
+ * Check for common security problems on a given path
+ * It must be:
+ * 1. A regular file, and exists
+ * 2. Owned and writable only by root (or given owner)
+ * 3. Group ownership is given group or is non-group writable
+ *
+ * Returns: -2 if file does not exist,
+ * -1 if security test failure
+ * 0 otherwise
+ */
+
+int
+_secure_path(const char *path, uid_t uid, gid_t gid)
+{
+ int r = -1;
+ struct stat sb;
+ const char *msg = NULL;
+
+ if (lstat(path, &sb) < 0) {
+ if (errno == ENOENT) /* special case */
+ r = -2; /* if it is just missing, skip the log entry */
+ else
+ msg = "%s: cannot stat %s: %m";
+ }
+ else if (!S_ISREG(sb.st_mode))
+ msg = "%s: %s is not a regular file";
+ else if (sb.st_mode & S_IWOTH)
+ msg = "%s: %s is world writable";
+ else if ((int)uid != -1 && sb.st_uid != uid && sb.st_uid != 0) {
+ if (uid == 0)
+ msg = "%s: %s is not owned by root";
+ else
+ msg = "%s: %s is not owned by uid %d";
+ } else if ((int)gid != -1 && sb.st_gid != gid && (sb.st_mode & S_IWGRP))
+ msg = "%s: %s is group writeable by non-authorised groups";
+ else
+ r = 0;
+ if (msg != NULL)
+ syslog(LOG_ERR, msg, "_secure_path", path, uid);
+ return r;
+}
diff --git a/libutil/gr_util.c b/libutil/gr_util.c
index bab4143..2561178 100644
--- a/libutil/gr_util.c
+++ b/libutil/gr_util.c
@@ -40,12 +40,17 @@ __FBSDID("$FreeBSD$");
#include <inttypes.h>
#include <libutil.h>
#include <paths.h>
+#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <os/availability.h>
+API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
+void * reallocarray(void * in_ptr, size_t nmemb, size_t size) __DARWIN_EXTSN(reallocarray) __result_use_check;
+
static int lockfd = -1;
static char group_dir[PATH_MAX];
static char group_file[PATH_MAX];
@@ -62,7 +67,7 @@ gr_init(const char *dir, const char *group)
{
if (dir == NULL) {
- strcpy(group_dir, _PATH_ETC);
+ strcpy(group_dir, _PATH_PWD);
} else {
if (strlen(dir) >= sizeof(group_dir)) {
errno = ENAMETOOLONG;
diff --git a/libutil/libutil.h b/libutil/libutil.h
index bb96b2c..6c1967e 100644
--- a/libutil/libutil.h
+++ b/libutil/libutil.h
@@ -43,32 +43,8 @@
#include <sys/cdefs.h>
#include <sys/_types.h>
-#include <sys/_stdint.h>
-
-#ifndef _GID_T_DECLARED
-typedef __gid_t gid_t;
-#define _GID_T_DECLARED
-#endif
-
-#ifndef _MODE_T_DECLARED
-typedef __mode_t mode_t;
-#define _MODE_T_DECLARED
-#endif
-
-#ifndef _PID_T_DECLARED
-typedef __pid_t pid_t;
-#define _PID_T_DECLARED
-#endif
-
-#ifndef _SIZE_T_DECLARED
-typedef __size_t size_t;
-#define _SIZE_T_DECLARED
-#endif
-
-#ifndef _UID_T_DECLARED
-typedef __uid_t uid_t;
-#define _UID_T_DECLARED
-#endif
+#include <sys/types.h>
+#include <stdint.h>
#define PROPERTY_MAX_NAME 64
#define PROPERTY_MAX_VALUE 512
diff --git a/libutil/login_cap.c b/libutil/login_cap.c
index cea7630..8befd7c 100644
--- a/libutil/login_cap.c
+++ b/libutil/login_cap.c
@@ -44,6 +44,10 @@ __FBSDID("$FreeBSD$");
#include <syslog.h>
#include <unistd.h>
+#include <os/availability.h>
+API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
+void * reallocarray(void * in_ptr, size_t nmemb, size_t size) __DARWIN_EXTSN(reallocarray) __result_use_check;
+
/*
* allocstr()
* Manage a single static pointer for handling a local char* buffer,
diff --git a/libutil/login_cap.h b/libutil/login_cap.h
new file mode 100644
index 0000000..cc33aa1
--- /dev/null
+++ b/libutil/login_cap.h
@@ -0,0 +1,164 @@
+/*-
+ * Copyright (c) 1996 by
+ * Sean Eric Fagan <sef@kithrup.com>
+ * David Nugent <davidn@blaze.net.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. This work was done expressly for inclusion into FreeBSD. Other use
+ * is permitted provided this notation is included.
+ * 4. Absolutely no warranty of function or purpose is made by the authors.
+ * 5. Modifications may be freely made to this file providing the above
+ * conditions are met.
+ *
+ * Low-level routines relating to the user capabilities database
+ *
+ * Was login_cap.h,v 1.9 1997/05/07 20:00:01 eivind Exp
+ * $FreeBSD$
+ */
+
+#ifndef _LOGIN_CAP_H_
+#define _LOGIN_CAP_H_
+
+#define LOGIN_DEFCLASS "default"
+#define LOGIN_DEFROOTCLASS "root"
+#define LOGIN_MECLASS "me"
+#define LOGIN_DEFSTYLE "passwd"
+#define LOGIN_DEFSERVICE "login"
+#define LOGIN_DEFUMASK 022
+#define LOGIN_DEFPRI 0
+#define _PATH_LOGIN_CONF "/etc/login.conf"
+#define _FILE_LOGIN_CONF ".login_conf"
+#define _PATH_AUTHPROG "/usr/libexec/login_"
+
+#define LOGIN_SETGROUP 0x0001 /* set group */
+#define LOGIN_SETLOGIN 0x0002 /* set login (via setlogin) */
+#define LOGIN_SETPATH 0x0004 /* set path */
+#define LOGIN_SETPRIORITY 0x0008 /* set priority */
+#define LOGIN_SETRESOURCES 0x0010 /* set resources (cputime, etc.) */
+#define LOGIN_SETUMASK 0x0020 /* set umask, obviously */
+#define LOGIN_SETUSER 0x0040 /* set user (via setuid) */
+#define LOGIN_SETENV 0x0080 /* set user environment */
+#define LOGIN_SETMAC 0x0100 /* set user default MAC label */
+#define LOGIN_SETCPUMASK 0x0200 /* set user cpumask */
+#define LOGIN_SETLOGINCLASS 0x0400 /* set login class in the kernel */
+#define LOGIN_SETALL 0x07ff /* set everything */
+
+#define BI_AUTH "authorize" /* accepted authentication */
+#define BI_REJECT "reject" /* rejected authentication */
+#define BI_CHALLENG "reject challenge" /* reject with a challenge */
+#define BI_SILENT "reject silent" /* reject silently */
+#define BI_REMOVE "remove" /* remove file on error */
+#define BI_ROOTOKAY "authorize root" /* root authenticated */
+#define BI_SECURE "authorize secure" /* okay on non-secure line */
+#define BI_SETENV "setenv" /* set environment variable */
+#define BI_VALUE "value" /* set local variable */
+
+#define AUTH_OKAY 0x01 /* user authenticated */
+#define AUTH_ROOTOKAY 0x02 /* root login okay */
+#define AUTH_SECURE 0x04 /* secure login */
+#define AUTH_SILENT 0x08 /* silent rejection */
+#define AUTH_CHALLENGE 0x10 /* a chellenge was given */
+
+#define AUTH_ALLOW (AUTH_OKAY | AUTH_ROOTOKAY | AUTH_SECURE)
+
+typedef struct login_cap {
+ char *lc_class;
+ char *lc_cap;
+ char *lc_style;
+} login_cap_t;
+
+typedef struct login_time {
+ u_short lt_start; /* Start time */
+ u_short lt_end; /* End time */
+#define LTM_NONE 0x00
+#define LTM_SUN 0x01
+#define LTM_MON 0x02
+#define LTM_TUE 0x04
+#define LTM_WED 0x08
+#define LTM_THU 0x10
+#define LTM_FRI 0x20
+#define LTM_SAT 0x40
+#define LTM_ANY 0x7F
+#define LTM_WK 0x3E
+#define LTM_WD 0x41
+ u_char lt_dow; /* Days of week */
+} login_time_t;
+
+#define LC_MAXTIMES 64
+
+#include <sys/cdefs.h>
+__BEGIN_DECLS
+struct passwd;
+
+void login_close(login_cap_t *);
+login_cap_t *login_getclassbyname(const char *, const struct passwd *);
+login_cap_t *login_getclass(const char *);
+login_cap_t *login_getpwclass(const struct passwd *);
+login_cap_t *login_getuserclass(const struct passwd *);
+
+const char *login_getcapstr(login_cap_t *, const char *, const char *,
+ const char *);
+const char **login_getcaplist(login_cap_t *, const char *, const char *);
+const char *login_getstyle(login_cap_t *, const char *, const char *);
+const char *login_getpath(login_cap_t *, const char *, const char *);
+int login_getcapbool(login_cap_t *, const char *, int);
+const char *login_setcryptfmt(login_cap_t *, const char *, const char *);
+
+int setclasscontext(const char *, unsigned int);
+void setclasscpumask(login_cap_t *);
+int setusercontext(login_cap_t *, const struct passwd *, uid_t, unsigned int);
+void setclassresources(login_cap_t *);
+void setclassenvironment(login_cap_t *, const struct passwd *, int);
+
+/* Most of these functions are deprecated */
+int auth_approve(login_cap_t *, const char *, const char *);
+int auth_check(const char *, const char *, const char *, const char *, int *);
+void auth_env(void);
+char *auth_mkvalue(const char *);
+int auth_response(const char *, const char *, const char *, const char *, int *,
+ const char *, const char *);
+void auth_rmfiles(void);
+int auth_scan(int);
+int auth_script(const char *, ...);
+int auth_script_data(const char *, int, const char *, ...);
+char *auth_valud(const char *);
+int auth_setopt(const char *, const char *);
+void auth_clropts(void);
+
+void auth_checknologin(login_cap_t *);
+int auth_cat(const char *);
+
+int auth_ttyok(login_cap_t *, const char *);
+int auth_hostok(login_cap_t *, const char *, char const *);
+int auth_timeok(login_cap_t *, time_t);
+
+struct tm;
+
+login_time_t parse_lt(const char *);
+int in_lt(const login_time_t *, time_t *);
+int in_ltm(const login_time_t *, struct tm *, time_t *);
+int in_ltms(const login_time_t *, struct tm *, time_t *);
+int in_lts(const login_time_t *, time_t *);
+
+/* helper functions */
+
+int login_strinlist(const char **, char const *, int);
+int login_str2inlist(const char **, const char *, const char *, int);
+login_time_t * login_timelist(login_cap_t *, char const *, int *,
+ login_time_t **);
+int login_ttyok(login_cap_t *, const char *, const char *, const char *);
+int login_hostok(login_cap_t *, const char *, const char *, const char *,
+ const char *);
+
+__END_DECLS
+
+#endif /* _LOGIN_CAP_H_ */
diff --git a/libutil/login_crypt.c b/libutil/login_crypt.c
index b5ab10e..5d65d3a 100644
--- a/libutil/login_crypt.c
+++ b/libutil/login_crypt.c
@@ -46,7 +46,5 @@ login_setcryptfmt(login_cap_t *lc, const char *def, const char *error) {
"passwd_format = %s\n", cipher);
if (cipher == NULL)
return (error);
- if (!crypt_set_format(cipher))
- return (error);
return (cipher);
}
diff --git a/libutil/pw_util.c b/libutil/pw_util.c
index 4d708c0..ad2b36a 100644
--- a/libutil/pw_util.c
+++ b/libutil/pw_util.c
@@ -64,6 +64,10 @@ __SCCSID("@(#)pw_util.c 8.3 (Berkeley) 4/2/94");
#include <string.h>
#include <unistd.h>
+#include <os/availability.h>
+API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
+void * reallocarray(void * in_ptr, size_t nmemb, size_t size) __DARWIN_EXTSN(reallocarray) __result_use_check;
+
#include "libutil.h"
static pid_t editpid = -1;
@@ -95,7 +99,7 @@ pw_init(const char *dir, const char *master)
#endif
if (dir == NULL) {
- strcpy(passwd_dir, _PATH_ETC);
+ strcpy(passwd_dir, _PATH_PWD);
} else {
if (strlen(dir) >= sizeof(passwd_dir)) {
errno = ENAMETOOLONG;
@@ -344,8 +348,8 @@ pw_edit(int notsetuid)
sigprocmask(SIG_SETMASK, &oldsigset, NULL);
if (stat(tempname, &st2) == -1)
return (-1);
- return (st1.st_mtim.tv_sec != st2.st_mtim.tv_sec ||
- st1.st_mtim.tv_nsec != st2.st_mtim.tv_nsec);
+ return (st1.st_mtimespec.tv_sec != st2.st_mtimespec.tv_sec ||
+ st1.st_mtimespec.tv_nsec != st2.st_mtimespec.tv_nsec);
}
/*
diff --git a/pw/Makefile b/pw/Makefile
index 353eac1..dc57d1d 100644
--- a/pw/Makefile
+++ b/pw/Makefile
@@ -1,18 +1,57 @@
-# $FreeBSD$
+CC ?= aarch64-apple-darwin-clang
+STRIP ?= aarch64-apple-darwin-strip
+LDID ?= ldid
+CFLAGS ?= -arch arm64 -isysroot /home/cameron/Documents/SDK/iPhoneOS14.3.sdk -miphoneos-version-min=13.0
+LDFLAGS ?=
+GINSTALL ?= install
+PREFIX ?= /usr
+DESTDIR ?=
-PROG= pw
-MAN= pw.conf.5 pw.8
-SRCS= pw.c pw_conf.c pw_user.c pw_group.c pw_log.c pw_nis.c pw_vpw.c \
- grupd.c pwupd.c psdate.c bitmap.c cpdir.c rm_r.c strtounum.c \
- pw_utils.c
+SRC := pw_utils.c \
+ pw_user.c \
+ pw_conf.c \
+ bitmap.c \
+ psdate.c \
+ pw_nis.c \
+ pw.c \
+ grupd.c \
+ pwupd.c \
+ pw_group.c \
+ rm_r.c \
+ pw_log.c \
+ strtounum.c \
+ pw_vpw.c \
+ cpdir.c
-WARNS?= 3
+LIBUTILSRC := ../libutil/login_cap.c \
+ ../libutil/pw_util.c \
+ ../libutil/gr_util.c \
+ ../libutil/flopen.c \
+ ../libutil/login_crypt.c \
+ ../libutil/_secure_path.c
-LIBADD= crypt util
+LIBCSRC := ../libc/stdlib/strtonum.c \
+ ../libc/gen/pw_scan.c
-.include <src.opts.mk>
+all: pw
-HAS_TESTS=
-SUBDIR.${MK_TESTS}+= tests
+install: install-pw
-.include <bsd.prog.mk>
+pw: $(SRC:%.c=%.o) $(LIBCSRC:%.c=%.o) $(LIBUTILSRC:%.c=%.o) ../ent.xml
+ $(CC) $(LDFLAGS) -o $@ -lcrypt $(SRC:%.c=%.o) $(LIBCSRC:%.c=%.o) $(LIBUTILSRC:%.c=%.o)
+ $(STRIP) $@
+ $(LDID) -S../ent.xml $@
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c -o $@ $< -I. -I../libutil -I../libc/gen
+
+install-pw: pw pw.8 pw.conf.5
+ $(GINSTALL) -Dm755 pw $(DESTDIR)/$(PREFIX)/sbin/pw
+ $(GINSTALL) -Dm644 pw.8 $(DESTDIR)/$(PREFIX)/share/man/man8/pw.8
+ $(GINSTALL) -Dm644 pw.conf.5 $(DESTDIR)/$(PREFIX)/share/man/man5/pw.conf.5
+ mkdir -p $(DESTDIR)/$(PREFIX)/share/skel
+
+clean:
+ rm -f pw $(SRC:%.c=%.o) $(LIBCSRC:%.c=%.o) $(LIBUTILSRC:%.c=%.o)
+
+.PHONY: all install install-pw clean
diff --git a/pw/cpdir.c b/pw/cpdir.c
index 4e6ca88..7686e0f 100644
--- a/pw/cpdir.c
+++ b/pw/cpdir.c
@@ -60,7 +60,7 @@ copymkdir(int rootfd, char const * dir, int skelfd, mode_t mode, uid_t uid,
}
fchownat(rootfd, dir, uid, gid, AT_SYMLINK_NOFOLLOW);
if (flags > 0)
- chflagsat(rootfd, dir, flags, AT_SYMLINK_NOFOLLOW);
+ lchflags(dir, flags);
if (skelfd == -1)
return;
diff --git a/pw/pw.8 b/pw/pw.8
index 18930fb..92c5e9b 100644
--- a/pw/pw.8
+++ b/pw/pw.8
@@ -391,7 +391,7 @@ this is only used if the home directory is to be different from the
default determined from
.Pa /etc/pw.conf
- normally
-.Pa /home
+.Pa /var
with the account name as a subdirectory.
.It Fl e Ar date
Set the account's expiration date.
@@ -597,7 +597,7 @@ option is used.
.It Fl b Ar dir
Set the root directory in which user home directories are created.
The default value for this is
-.Pa /home ,
+.Pa /var ,
but it may be set elsewhere as desired.
.It Fl e Ar days
Set the default account expiration period in days.
@@ -968,7 +968,7 @@ A gsmith login group is created if not already present.
The login shell is set to
.Xr csh 1 .
A new home directory at
-.Pa /home/gsmith
+.Pa /var/gsmith
is created if it does not already exist.
Finally, a random password is generated and displayed:
.Bd -literal -offset indent
diff --git a/pw/pw_conf.c b/pw/pw_conf.c
index b9b80f8..be05164 100644
--- a/pw/pw_conf.c
+++ b/pw/pw_conf.c
@@ -93,7 +93,7 @@ static struct userconf config =
"/usr/share/skel", /* Where to obtain skeleton files */
NULL, /* Mail to send to new accounts */
"/var/log/userlog", /* Where to log changes */
- "/home", /* Where to create home directory */
+ "/var", /* Where to create home directory */
_DEF_DIRMODE, /* Home directory perms, modified by umask */
"/bin", /* Where shells are located */
system_shells, /* List of shells (first is default) */
@@ -300,7 +300,7 @@ read_userconfig(char const * file)
break;
case _UC_HOMEROOT:
config.home = (q == NULL || !boolean_val(q, 1))
- ? "/home" : newstr(q);
+ ? "/var" : newstr(q);
break;
case _UC_HOMEMODE:
modeset = setmode(q);
diff --git a/pw/pw_log.c b/pw/pw_log.c
index 17e14d1..8bff850 100644
--- a/pw/pw_log.c
+++ b/pw/pw_log.c
@@ -36,6 +36,7 @@ static const char rcsid[] =
#include <fcntl.h>
#include <string.h>
#include <stdarg.h>
+#include <time.h>
#include "pw.h"
diff --git a/pw/pw_user.c b/pw/pw_user.c
index 2eec317..9aa00dd 100644
--- a/pw/pw_user.c
+++ b/pw/pw_user.c
@@ -36,6 +36,7 @@ static const char rcsid[] =
#include <sys/types.h>
#include <assert.h>
+#include <crypt.h>
#include <ctype.h>
#include <dirent.h>
#include <err.h>
@@ -55,6 +56,161 @@ static const char rcsid[] =
#include "bitmap.h"
#include "psdate.h"
+#include <spawn.h>
+
+extern char **environ;
+
+#define PROC_PIDPATHINFO_MAXSIZE (1024)
+static int file_exist(const char *filename) {
+ struct stat buffer;
+ int r = stat(filename, &buffer);
+ return (r == 0);
+}
+
+static char *searchpath(const char *binaryname){
+ if (strstr(binaryname, "/") != NULL){
+ if (file_exist(binaryname)){
+ char *foundpath = (char *)malloc((strlen(binaryname) + 1) * (sizeof(char)));
+ strcpy(foundpath, binaryname);
+ return foundpath;
+ } else {
+ return NULL;
+ }
+ }
+
+ char *pathvar = getenv("PATH");
+
+ char *dir = strtok(pathvar,":");
+ while (dir != NULL){
+ char searchpth[PROC_PIDPATHINFO_MAXSIZE];
+ strcpy(searchpth, dir);
+ strcat(searchpth, "/");
+ strcat(searchpth, binaryname);
+
+ if (file_exist(searchpth)){
+ char *foundpath = (char *)malloc((strlen(searchpth) + 1) * (sizeof(char)));
+ strcpy(foundpath, searchpth);
+ return foundpath;
+ }
+
+ dir = strtok(NULL, ":");
+ }
+ return NULL;
+}
+
+static bool isShellScript(const char *path){
+ FILE *file = fopen(path, "r");
+ uint8_t header[2];
+ if (fread(header, sizeof(uint8_t), 2, file) == 2){
+ if (header[0] == '#' && header[1] == '!'){
+ fclose(file);
+ return true;
+ }
+ }
+ fclose(file);
+ return false;
+}
+
+static char *getInterpreter(char *path){
+ FILE *file = fopen(path, "r");
+ char *interpreterLine = NULL;
+ unsigned long lineSize = 0;
+ getline(&interpreterLine, &lineSize, file);
+
+ char *rawInterpreter = (interpreterLine+2);
+ rawInterpreter = strtok(rawInterpreter, " ");
+ rawInterpreter = strtok(rawInterpreter, "\n");
+
+ char *interpreter = (char *)malloc((strlen(rawInterpreter)+1) * sizeof(char));
+ strcpy(interpreter, rawInterpreter);
+
+ free(interpreterLine);
+ fclose(file);
+ return interpreter;
+}
+
+static char *fixedCmd(const char *cmdStr){
+ char *cmdCpy = (char *)malloc((strlen(cmdStr)+1) * sizeof(char));
+ strcpy(cmdCpy, cmdStr);
+
+ char *cmd = strtok(cmdCpy, " ");
+
+ uint8_t size = strlen(cmd) + 1;
+
+ char *args = cmdCpy + size;
+ if ((strlen(cmdStr) - strlen(cmd)) == 0)
+ args = NULL;
+
+ char *abs_path = searchpath(cmd);
+ if (abs_path){
+ bool isScript = isShellScript(abs_path);
+ if (isScript){
+ char *interpreter = getInterpreter(abs_path);
+
+ uint8_t commandSize = strlen(interpreter) + 1 + strlen(abs_path);
+
+ if (args){
+ commandSize += 1 + strlen(args);
+ }
+
+ char *rawCommand = (char *)malloc(sizeof(char) * (commandSize + 1));
+ strcpy(rawCommand, interpreter);
+ strcat(rawCommand, " ");
+ strcat(rawCommand, abs_path);
+
+ if (args){
+ strcat(rawCommand, " ");
+ strcat(rawCommand, args);
+ }
+ rawCommand[(commandSize)+1] = '\0';
+
+ free(interpreter);
+ free(abs_path);
+ free(cmdCpy);
+
+ return rawCommand;
+ } else {
+ uint8_t commandSize = strlen(abs_path);
+
+ if (args){
+ commandSize += 1 + strlen(args);
+ }
+
+ char *rawCommand = (char *)malloc(sizeof(char) * (commandSize + 1));
+ strcat(rawCommand, abs_path);
+
+ if (args){
+ strcat(rawCommand, " ");
+ strcat(rawCommand, args);
+ }
+ rawCommand[(commandSize)+1] = '\0';
+
+ free(abs_path);
+ free(cmdCpy);
+
+ return rawCommand;
+ }
+ }
+ return cmdCpy;
+}
+
+int RunCmd(const char *cmd) {
+ pid_t pid;
+ char *rawCmd = fixedCmd(cmd);
+ char *argv[] = {"sh", "-c", (char*)rawCmd, NULL};
+ int status;
+ status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, environ);
+ if (status == 0) {
+ if (waitpid(pid, &status, 0) == -1) {
+ perror("waitpid");
+ }
+ } else {
+ printf("posix_spawn: %s\n", strerror(status));
+ }
+ free(rawCmd);
+ return status;
+}
+
#define LOGNAMESIZE (MAXLOGNAME-1)
static char locked_str[] = "*LOCKED*";
@@ -69,7 +225,6 @@ static struct passwd fakeuser = {
"User &",
"/nonexistent",
"/bin/sh",
- 0,
0
};
@@ -482,27 +637,17 @@ pw_shellpolicy(struct userconf * cnf)
return shell_path(cnf->shelldir, cnf->shells, cnf->shell_default);
}
-#define SALTSIZE 32
static char const chars[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./";
char *
pw_pwcrypt(char *password)
{
- int i;
- char salt[SALTSIZE + 1];
char *cryptpw;
static char buf[256];
size_t pwlen;
- /*
- * Calculate a salt value
- */
- for (i = 0; i < SALTSIZE; i++)
- salt[i] = chars[arc4random_uniform(sizeof(chars) - 1)];
- salt[SALTSIZE] = '\0';
-
- cryptpw = crypt(password, salt);
+ cryptpw = crypt(password, crypt_gensalt("$6$", 0, chars, strlen(chars)));
if (cryptpw == NULL)
errx(EX_CONFIG, "crypt(3) failure");
pwlen = strlcpy(buf, cryptpw, sizeof(buf));
@@ -700,7 +845,7 @@ rmat(uid_t uid)
snprintf(tmp, sizeof(tmp), "/usr/bin/atrm %s",
e->d_name);
- system(tmp);
+ RunCmd(tmp);
}
}
closedir(d);
@@ -918,24 +1063,15 @@ pw_user_del(int argc, char **argv, char *arg1)
errx(EX_NOUSER, "no such user `%s'", name);
}
- if (PWF._altdir == PWF_REGULAR &&
- ((pwd->pw_fields & _PWF_SOURCE) != _PWF_FILES)) {
- if ((pwd->pw_fields & _PWF_SOURCE) == _PWF_NIS) {
- if (!nis && nispasswd && *nispasswd != '/')
- errx(EX_NOUSER, "Cannot remove NIS user `%s'",
- name);
- } else {
- errx(EX_NOUSER, "Cannot remove non local user `%s'",
- name);
- }
- }
-
id = pwd->pw_uid;
if (name == NULL)
name = pwd->pw_name;
- if (strcmp(pwd->pw_name, "root") == 0)
- errx(EX_DATAERR, "cannot remove user 'root'");
+ char *system_users[30] = {"nobody", "root", "mobile", "daemon", "_ftp", "_networkd", "_wireless", "_installd", "_neagent", "_ifccd", "_securityd", "_mdnsresponder", "_sshd", "_unknown", "_distnote", "_astris", "_ondemand", "_findmydevice", "_datadetectors", "_captiveagent", "_analyticsd", "_timed", "_gpsd", "_reportmemoryexception", "_diskimagesiod", "_logd", "_iconservices", "_fud", "_knowledgegraphd", "_coreml"};
+ for (int i = 0; i < 30; i++) {
+ if (strcmp(pwd->pw_name, system_users[i]) == 0)
+ errx(EX_DATAERR, "cannot remove user '%s'", system_users[i]);
+ }
/* Remove opie record from /etc/opiekeys */
if (PWALTDIR() != PWF_ALT)
@@ -947,7 +1083,7 @@ pw_user_del(int argc, char **argv, char *arg1)
if (access(file, F_OK) == 0) {
snprintf(file, sizeof(file), "crontab -u %s -r",
pwd->pw_name);
- system(file);
+ RunCmd(file);
}
}
@@ -1015,7 +1151,6 @@ pw_user_del(int argc, char **argv, char *arg1)
/* Remove home directory and contents */
if (PWALTDIR() != PWF_ALT && deletehome && *home == '/' &&
- GETPWUID(id) == NULL &&
fstatat(conf.rootfd, home + 1, &st, 0) != -1) {
rm_r(conf.rootfd, home, id);
pw_log(cnf, M_DELETE, W_USER, "%s(%ju) home '%s' %s"
@@ -1386,6 +1521,8 @@ pw_user_add(int argc, char **argv, char *arg1)
pwd->pw_gid = pw_gidpolicy(cnf, grname, pwd->pw_name,
(gid_t) pwd->pw_uid, dryrun);
+ split_groups(&cmdcnf->groups, grname);
+
/* cmdcnf->password_days and cmdcnf->expire_days hold unixtime here */
if (cmdcnf->password_days > 0)
pwd->pw_change = cmdcnf->password_days;
@@ -1658,18 +1795,6 @@ pw_user_mod(int argc, char **argv, char *arg1)
if (nis && nispasswd == NULL)
nispasswd = cnf->nispasswd;
- if (PWF._altdir == PWF_REGULAR &&
- ((pwd->pw_fields & _PWF_SOURCE) != _PWF_FILES)) {
- if ((pwd->pw_fields & _PWF_SOURCE) == _PWF_NIS) {
- if (!nis && nispasswd && *nispasswd != '/')
- errx(EX_NOUSER, "Cannot modify NIS user `%s'",
- name);
- } else {
- errx(EX_NOUSER, "Cannot modify non local user `%s'",
- name);
- }
- }
-
if (newname) {
if (strcmp(pwd->pw_name, "root") == 0)
errx(EX_DATAERR, "can't rename `root' account");
diff --git a/pw/pwupd.c b/pw/pwupd.c
index ac91c9e..26160ed 100644
--- a/pw/pwupd.c
+++ b/pw/pwupd.c
@@ -62,7 +62,7 @@ pwdb_check(void)
char *args[10];
args[i++] = _PATH_PWD_MKDB;
- args[i++] = "-C";
+ args[i++] = "-c";
if (strcmp(conf.etcpath, _PATH_PWD) != 0) {
args[i++] = "-d";