]> git.cameronkatri.com Git - pw-darwin.git/commitdiff
Recommit everything, add chpass, improve history (except for a few files that git...
authorCameron Katri <me@cameronkatri.com>
Sun, 2 May 2021 20:00:07 +0000 (16:00 -0400)
committerCameron Katri <me@cameronkatri.com>
Sun, 2 May 2021 20:00:07 +0000 (16:00 -0400)
25 files changed:
.clang-format [new file with mode: 0644]
.gitignore [new file with mode: 0644]
Makefile [new file with mode: 0644]
adduser/Makefile [new file with mode: 0644]
adduser/adduser.conf.5
adduser/adduser.sh
adduser/rmuser.sh
chpass/Makefile
chpass/chpass.c
ent.xml [new file with mode: 0644]
libc/gen/pw_scan.c
libutil/_secure_path.c [new file with mode: 0644]
libutil/gr_util.c
libutil/libutil.h
libutil/login_cap.c
libutil/login_cap.h [new file with mode: 0644]
libutil/login_crypt.c
libutil/pw_util.c
pw/Makefile
pw/cpdir.c
pw/pw.8
pw/pw_conf.c
pw/pw_log.c
pw/pw_user.c
pw/pwupd.c

diff --git a/.clang-format b/.clang-format
new file mode 100644 (file)
index 0000000..06709b7
--- /dev/null
@@ -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 (file)
index 0000000..270dfe1
--- /dev/null
@@ -0,0 +1,3 @@
+*.o
+pw/pw
+chpass/chpass
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
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 (file)
index 0000000..7d67923
--- /dev/null
@@ -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
index af9fe22cfb3a92952b5142b8e23b3dc8c924e0ea..42ccaa0731b9e3c168470b38d021d6ca68c605be 100644 (file)
@@ -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
index 91a1b4b4cf016aa4a048a2fea2487d65112274e7..b9abd81e9eca9380e63e9cdfa86d907d342cb6e8 100644 (file)
@@ -877,7 +877,7 @@ disableflag=
 Dflag=
 Sflag=
 readconfig="yes"
-homeprefix="/home"
+homeprefix="/var"
 randompass=
 fileline=
 savedpwtype=
index abaf004e7f6699962c7b8b675f76f9c7c6741b0d..e2308d01b1d14196d43286a380c0dc3bc6967398 100644 (file)
@@ -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 '.'
 }
index bd5baa3c4d0755f2ac45df682509666c84ad577b..1f88e5165f3f2b6bfe69c1dd80c036a908577da0 100644 (file)
@@ -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
index 643b0f387c3a8c35c0f1e439108295d02877dd37..3b3a41f4ddf66d8694c52185bffd324bfd0d54f8 100644 (file)
@@ -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 (file)
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> 
index 619092d3d4bcd728e1a0cadbb3c355e873f89a61..f680a90c7eafa4ef00412e571c268261936835b0 100644 (file)
@@ -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 (file)
index 0000000..363378b
--- /dev/null
@@ -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;
+}
index bab4143be73142795baba00a648b703f7ec31a72..2561178797ef6b9101da9d9ad752e51b9ea48081 100644 (file)
@@ -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;
index bb96b2caa5027a525f770488f3e67bc2cfefe3f0..6c1967e946122805edfcb2426f5da00b0526d749 100644 (file)
 
 #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
index cea7630698af708063f6ef1b01e36a73a2abd610..8befd7c87b1d7bfb8dc97dbf915a612a06d85236 100644 (file)
@@ -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 (file)
index 0000000..cc33aa1
--- /dev/null
@@ -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_ */
index b5ab10e6be85cf9bbe54501fd056a6f40e2e0069..5d65d3aabedd70874d78d7af6306d2b3f93f0fed 100644 (file)
@@ -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);
 }
index 4d708c007f448b2395d90ced530300d689ac8d82..ad2b36ab765df472687f9f6210b3277a97e0476d 100644 (file)
@@ -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);
 }
 
 /*
index 353eac132c7d2cb25933336abb36574ebc258022..dc57d1d2f10dd9e1084b70d4ebfa34790be3d95b 100644 (file)
@@ -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
index 4e6ca8828b913263dcefe602d98e896e7310b30b..7686e0f1b799678cb35b000863de854ac801f849 100644 (file)
@@ -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 18930fbf22855f7c05b5f28548061bb3e2487ba7..92c5e9be28d3a968087d258eeeff50567a7f1400 100644 (file)
--- 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
index b9b80f85cd488a2988e81589f99367deec1d6952..be051648e214186abf5fba2755de996c3311ba7b 100644 (file)
@@ -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);
index 17e14d1e44eded51a01dd6d14b8e7a5df9fb681d..8bff850d78bb73e87ea528bf763e3807584b1247 100644 (file)
@@ -36,6 +36,7 @@ static const char rcsid[] =
 #include <fcntl.h>
 #include <string.h>
 #include <stdarg.h>
+#include <time.h>
 
 #include "pw.h"
 
index 2eec317b5e5b55253d00fb0e887ce6b9ca743048..9aa00dd48f0aed8a2a33b46d745308e8f4804216 100644 (file)
@@ -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");
index ac91c9e4c1bb38ea63bc81b610fca1f7024b4147..26160ed27e95effc74405e694f00911e3488eb85 100644 (file)
@@ -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";