From f3dab068fce37270e5e4e1a00e5a44e30f00baf7 Mon Sep 17 00:00:00 2001 From: Cameron Katri Date: Sun, 2 May 2021 16:00:07 -0400 Subject: 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]) --- libutil/_secure_path.c | 74 ++++++++++++++++++++++ libutil/gr_util.c | 7 ++- libutil/libutil.h | 28 +-------- libutil/login_cap.c | 4 ++ libutil/login_cap.h | 164 +++++++++++++++++++++++++++++++++++++++++++++++++ libutil/login_crypt.c | 2 - libutil/pw_util.c | 10 ++- 7 files changed, 257 insertions(+), 32 deletions(-) create mode 100644 libutil/_secure_path.c create mode 100644 libutil/login_cap.h (limited to 'libutil') 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 +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include +#include + +/* + * 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 #include #include +#include #include #include #include #include #include +#include +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 #include -#include - -#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 +#include #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 #include +#include +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 + * David Nugent + * 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 +__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 #include +#include +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); } /* -- cgit v1.2.3-56-ge451