diff --git a/ChangeLog b/ChangeLog index 011d20b1..0b125166 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4341,6 +4341,10 @@ v0.33.19 26-Oct-2001 Ask Date of Birth now only is asked if set in configuration. Fixes for Sparc systems. + mbpasswd: + Added more checks to see if it's legal invoked. + Password change on FreeBSD finally works. + mbcico: Removed IEMSI support since mbsebbs doesn't support it anymore. diff --git a/mbsebbs/Makefile b/mbsebbs/Makefile index cad8c627..b4e1bcb3 100644 --- a/mbsebbs/Makefile +++ b/mbsebbs/Makefile @@ -12,7 +12,7 @@ SRCS = bank.c commonio.c filesub.c language.c mbtoberep.c \ exitinfo.c mball.c mbsebbs.c menu.c nextuser.c pop3.c lastcallers.c \ safe.c timeout.c chat.c file.c getdef.c mbchat.c mbstat.c misc.c \ offline.c putpwent.c salt.c user.c mbnewusr.c input.c whoson.c \ - door.c dispfile.c userlist.c timestats.c logentry.c + door.c dispfile.c userlist.c timestats.c logentry.c pw_util.c HDRS = bank.h commonio.h filesub.h language.h mbsebbs.h misc.h offline.h \ putpwent.h salt.h timeout.h bbslist.h email.h fsedit.h lineedit.h \ mbstat.h msgutil.h oneline.h sgetpwent.h user.h bye.h morefile.h \ @@ -20,7 +20,7 @@ HDRS = bank.h commonio.h filesub.h language.h mbsebbs.h misc.h offline.h \ xmalloc.h change.h exitinfo.h mball.h mbuseradd.h newuser.h \ pinfo.h rad64.h chat.h file.h getdef.h mbpasswd.h menu.h \ nextuser.h pop3.h safe.h timecheck.h mbnewusr.h input.h whoson.h \ - door.h dispfile.h userlist.h timestats.h logentry.h lastcallers.h + door.h dispfile.h userlist.h timestats.h logentry.h lastcallers.h pw_util.h MBSEBBS_OBJS = bank.o bbslist.o chat.o file.o funcs.o mail.o menu.o \ misc.o pinfo.o nextuser.o oneline.o page.o fsedit.o \ bye.o change.o mbsebbs.o safe.o timeout.o user.o timecheck.o \ @@ -48,7 +48,7 @@ MBUSER_OBJS = mbuser.o MBUSER_LIBS = ../lib/libmemwatch.a ../lib/libclcomm.a ../lib/libcommon.a ../lib/libdbase.a MBUSERADD_OBJS = mbuseradd.o MBPASSWD_OBJS = mbpasswd.o commonio.o pwio.o shadowio.o sgetpwent.o \ - xmalloc.o myname.o rad64.o salt.o getdef.o encrypt.o putpwent.o + xmalloc.o myname.o rad64.o salt.o getdef.o encrypt.o putpwent.o pw_util.o OTHER = Makefile TARGET = mbsebbs mbnewusr mball mblang mbchat mbstat mbtoberep mbuser mbuseradd mbpasswd @@ -171,7 +171,7 @@ bye.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/clco encrypt.o: ../config.h encrypt.h funcs.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/msgtext.h ../lib/msg.h ../lib/clcomm.h funcs.h mail.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/msgtext.h ../lib/clcomm.h ../lib/msg.h mail.h funcs.h input.h language.h misc.h timeout.h oneline.h exitinfo.h lineedit.h fsedit.h filesub.h msgutil.h pop3.h email.h whoson.h -mbpasswd.o: ../config.h encrypt.h rad64.h myname.h xmalloc.h pwio.h shadowio.h mbpasswd.h +mbpasswd.o: ../config.h encrypt.h rad64.h myname.h xmalloc.h pwio.h shadowio.h pw_util.h mbpasswd.h mbuseradd.o: ../config.h mbuseradd.h newuser.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/clcomm.h ../lib/common.h funcs.h input.h newuser.h language.h timeout.h change.h dispfile.h pinfo.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h pinfo.h input.h @@ -205,4 +205,5 @@ dispfile.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib userlist.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h userlist.h language.h input.h timeout.h timestats.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h timestats.h funcs.h language.h input.h exitinfo.h logentry.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h logentry.h +pw_util.o: pw_util.h # End of generated dependencies diff --git a/mbsebbs/mbpasswd.c b/mbsebbs/mbpasswd.c index 06abed63..2224f099 100644 --- a/mbsebbs/mbpasswd.c +++ b/mbsebbs/mbpasswd.c @@ -61,6 +61,7 @@ #include "xmalloc.h" #include "pwio.h" #include "shadowio.h" +#include "pw_util.h" #include "mbpasswd.h" @@ -172,10 +173,8 @@ static char *insert_crypt_passwd(const char *string, char *passwd) #endif return xstrdup(passwd); } -#endif /* FreeBSD */ -#ifndef __FreeBSD__ static char *update_crypt_pw(char *cp) { if (do_update_pwd) @@ -183,7 +182,6 @@ static char *update_crypt_pw(char *cp) return cp; } -#endif @@ -243,7 +241,7 @@ void pwd_init(void) umask(077); } - +#endif /* not FreeBSD */ /* @@ -723,16 +721,19 @@ static void update_shadow(void) */ int main(int argc, char *argv[]) { +#ifndef __FreeBSD__ const struct passwd *pw; const struct group *gr; #ifdef SHADOW_PASSWORD const struct spwd *sp; #endif - char *cp; -#ifdef __FreeBSD__ - char temp[81]; - char cmd[256]; +#else + static struct passwd *pw; + static struct group *gr; + int pfd, tfd; #endif + char *cp; + /* * Get my username @@ -771,10 +772,30 @@ int main(int argc, char *argv[]) exit(E_FAILURE); } - if (strncmp(argv[1], "-f", 2) == 0) + if (strncmp(argv[1], "-f", 2) == 0) { + /* + * This is a new user setting his password, + * this program runs under account mbse. + */ force = 1; - else + if (strcmp(pw->pw_name, (char *)"mbse")) { + fprintf(stderr, "mbpasswd: only user \"mbse\" may do this.\n"); + exit(E_NOPERM); + } + } else if (strncmp(argv[1], "-n", 2) == 0) { + /* + * Normal password change by user, check + * caller is the user. + */ force = 0; + if (strcmp(pw->pw_name, argv[2])) { + fprintf(stderr, "mbpasswd: only owner may do this.\n"); + exit(E_NOPERM); + } + } else { + fprintf(stderr, "mbpasswd: wrong option switch.\n"); + exit(E_FAILURE); + } /* * Check stringlengths @@ -788,13 +809,19 @@ int main(int argc, char *argv[]) exit(E_FAILURE); } + /* + * We don't log into MBSE BBS logfiles but to the system logfiles, + * because we are modifying system files not belonging to MBSE BBS. + */ + openlog("mbpasswd", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH); + name = strdup(argv[2]); if ((pw = getpwnam(name)) == NULL) { + syslog(LOG_ERR, "mbpasswd: Unknown user %s", name); fprintf(stderr, "mbpasswd: Unknown user %s\n", name); exit(E_FAILURE); } - openlog("mbpasswd", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH); #ifdef SHADOW_PASSWORD sp = getspnam(name); @@ -831,7 +858,11 @@ int main(int argc, char *argv[]) * to root to protect against unexpected signals. Any * keyboard signals are set to be ignored. */ +#ifndef __FreeBSD__ pwd_init(); +#else + pw_init(); +#endif if (setuid(0)) { fprintf(stderr, "Cannot change ID to root.\n"); @@ -855,33 +886,23 @@ int main(int argc, char *argv[]) #endif /* !HAVE_USERSEC_H */ #else /* __FreeBSD__ */ - /* - * FreeBSD has no interface (that I know of) to change the users password, - * but they do have a utility that does it. We will use that. + * FreeBSD password change, borrowed from the original FreeBSD sources */ - if ((access("/usr/bin/chpass", X_OK)) == 0) - strcpy(temp, "/usr/bin/chpass"); - else if ((access("/usr/sbin/chpass", X_OK)) == 0) - strcpy(temp, "/usr/sbin/chpass"); - else if ((access("/bin/chpass", X_OK)) == 0) - strcpy(temp, "/bin/chpass"); - else if ((access("/sbin/chpass", X_OK)) == 0) - strcpy(temp, "/sbin/chpass"); - else { - fprintf(stderr, "mbpasswd: Can't find chpass\n"); - syslog(LOG_ERR, "Can't find chpass"); - closelog(); - exit(E_FAILURE); - } - sprintf(cmd, "%s -p \"%s\" %s", temp, crypt_passwd, name); - if (system(cmd) != 0) { - perror("mbpasswd: failed to change password\n"); - syslog(LOG_ERR, "password change for `%s' failed", name); - closelog(); - exit(E_FAILURE); - } + /* + * Get the new password. Reset passwd change time to zero by + * default. + */ + pw->pw_change = 0; + pw->pw_passwd = crypt_passwd; + + pfd = pw_lock(); + tfd = pw_tmp(); + pw_copy(pfd, tfd, pw); + + if (!pw_mkdb(pw->pw_name)) + pw_error((char *)NULL, 0, 1); #endif /* __FreeBSD__ */ diff --git a/mbsebbs/pw_util.c b/mbsebbs/pw_util.c new file mode 100644 index 00000000..48d499e2 --- /dev/null +++ b/mbsebbs/pw_util.c @@ -0,0 +1,309 @@ +/***************************************************************************** + * + * $Id$ + * Purpose ...............: FreeBSD password utilities. + * Remark ................: Taken from FreeBSD and modified for MBSE BBS. + * + ***************************************************************************** + * Copyright (C) 1997-2001 + * + * Michiel Broek FIDO: 2:280/2802 + * Beekmansbos 10 + * 1971 BV IJmuiden + * the Netherlands + * + * This file is part of MBSE BBS. + * + * This BBS is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * MBSE BBS is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MBSE BBS; see the file COPYING. If not, write to the Free + * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + *****************************************************************************/ + +/* + * Copyright (c) 1990, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef __FreeBSD__ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pw_util.h" + +char *tempname; +static int lockfd; + + + +void pw_init() +{ + struct rlimit rlim; + + /* Unlimited resource limits. */ + rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY; + (void)setrlimit(RLIMIT_CPU, &rlim); + (void)setrlimit(RLIMIT_FSIZE, &rlim); + (void)setrlimit(RLIMIT_STACK, &rlim); + (void)setrlimit(RLIMIT_DATA, &rlim); + (void)setrlimit(RLIMIT_RSS, &rlim); + + /* Don't drop core (not really necessary, but GP's). */ + rlim.rlim_cur = rlim.rlim_max = 0; + (void)setrlimit(RLIMIT_CORE, &rlim); + + /* Turn off signals. */ + (void)signal(SIGALRM, SIG_IGN); + (void)signal(SIGHUP, SIG_IGN); + (void)signal(SIGINT, SIG_IGN); + (void)signal(SIGPIPE, SIG_IGN); + (void)signal(SIGQUIT, SIG_IGN); + (void)signal(SIGTERM, SIG_IGN); + + /* Create with exact permissions. */ + (void)umask(0); +} + + +int pw_lock() +{ + /* + * If the master password file doesn't exist, the system is hosed. + * Might as well try to build one. Set the close-on-exec bit so + * that users can't get at the encrypted passwords while editing. + * Open should allow flock'ing the file; see 4.4BSD. XXX + */ + for (;;) { + struct stat st; + + lockfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0); + if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1) { + syslog(LOG_ERR, "%s", _PATH_MASTERPASSWD); + fprintf(stderr, "%s: %s\n", strerror(errno), _PATH_MASTERPASSWD); + exit(1); + } + if (flock(lockfd, LOCK_EX|LOCK_NB)) { + syslog(LOG_ERR, "the password db file is busy"); + fprintf(stderr, "the password db file is busy\n"); + exit(1); + } + + /* + * If the password file was replaced while we were trying to + * get the lock, our hardlink count will be 0 and we have to + * close and retry. + */ + if (fstat(lockfd, &st) < 0) { + syslog(LOG_ERR, "fstat() failed"); + fprintf(stderr, "%s: %s\n", strerror(errno), "fstat() failed"); + exit(1); + } + if (st.st_nlink != 0) + break; + close(lockfd); + lockfd = -1; + } + return (lockfd); +} + + +int pw_tmp() +{ + static char path[MAXPATHLEN] = _PATH_MASTERPASSWD; + int fd; + char *p; + + if ((p = strrchr(path, '/'))) + ++p; + else + p = path; + strcpy(p, "pw.XXXXXX"); + if ((fd = mkstemp(path)) == -1) { + syslog(LOG_ERR, "%s", path); + fprintf(stderr, "%s: %s\n", strerror(errno), path); + exit(1); + } + tempname = path; + return (fd); +} + + + +int pw_mkdb(char *username) +{ + int pstat; + pid_t pid; + + (void)fflush(stderr); + if (!(pid = fork())) { + if(!username) { + syslog(LOG_WARNING, "rebuilding the database..."); + execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL); + } else { + syslog(LOG_WARNING, "updating the database..."); + execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-u", username, tempname, NULL); + } + pw_error((char *)_PATH_PWD_MKDB, 1, 1); + } + pid = waitpid(pid, &pstat, 0); + if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0) + return (0); + syslog(LOG_WARNING, "done"); + return (1); +} + + + +void pw_error(char *name, int errn, int eval) +{ +#ifdef YP + extern int _use_yp; +#endif /* YP */ + if (errn) + syslog(LOG_WARNING, name); +#ifdef YP + if (_use_yp) + syslog(LOG_WARNING, "NIS information unchanged"); + else +#endif /* YP */ + syslog(LOG_WARNING, "%s: unchanged", _PATH_MASTERPASSWD); + (void)unlink(tempname); + exit(eval); +} + + +void pw_copy(int ffd, int tfd, struct passwd *pw) +{ + FILE *from, *to; + int done; + char *p, buf[8192]; + char uidstr[20]; + char gidstr[20]; + char chgstr[20]; + char expstr[20]; + + snprintf(uidstr, sizeof(uidstr), "%d", pw->pw_uid); + snprintf(gidstr, sizeof(gidstr), "%d", pw->pw_gid); + snprintf(chgstr, sizeof(chgstr), "%ld", (long)pw->pw_change); + snprintf(expstr, sizeof(expstr), "%ld", (long)pw->pw_expire); + + if (!(from = fdopen(ffd, "r"))) + pw_error((char *)_PATH_MASTERPASSWD, 1, 1); + if (!(to = fdopen(tfd, "w"))) + pw_error(tempname, 1, 1); + + for (done = 0; fgets(buf, sizeof(buf), from);) { + if (!strchr(buf, '\n')) { + syslog(LOG_WARNING, "%s: line too long", _PATH_MASTERPASSWD); + pw_error(NULL, 0, 1); + } + if (done) { + (void)fprintf(to, "%s", buf); + if (ferror(to)) + goto err; + continue; + } + if (!(p = strchr(buf, ':'))) { + syslog(LOG_WARNING, "%s: corrupted entry", _PATH_MASTERPASSWD); + pw_error(NULL, 0, 1); + } + *p = '\0'; + if (strcmp(buf, pw->pw_name)) { + *p = ':'; + (void)fprintf(to, "%s", buf); + if (ferror(to)) + goto err; + continue; + } + (void)fprintf(to, "%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n", + pw->pw_name, pw->pw_passwd, + pw->pw_fields & _PWF_UID ? uidstr : "", + pw->pw_fields & _PWF_GID ? gidstr : "", + pw->pw_class, + pw->pw_fields & _PWF_CHANGE ? chgstr : "", + pw->pw_fields & _PWF_EXPIRE ? expstr : "", + pw->pw_gecos, pw->pw_dir, pw->pw_shell); + done = 1; + if (ferror(to)) + goto err; + } + if (!done) { +#ifdef YP + /* Ultra paranoid: shouldn't happen. */ + if (getuid()) { + syslog(LOG_WARNING, "%s: not found in %s -- permission denied", + pw->pw_name, _PATH_MASTERPASSWD); + pw_error(NULL, 0, 1); + } else +#endif /* YP */ + (void)fprintf(to, "%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n", + pw->pw_name, pw->pw_passwd, + pw->pw_fields & _PWF_UID ? uidstr : "", + pw->pw_fields & _PWF_GID ? gidstr : "", + pw->pw_class, + pw->pw_fields & _PWF_CHANGE ? chgstr : "", + pw->pw_fields & _PWF_EXPIRE ? expstr : "", + pw->pw_gecos, pw->pw_dir, pw->pw_shell); + } + + if (ferror(to)) +err: pw_error(NULL, 1, 1); + (void)fclose(to); +} + + +#endif + diff --git a/mbsebbs/pw_util.h b/mbsebbs/pw_util.h new file mode 100644 index 00000000..de72fdd9 --- /dev/null +++ b/mbsebbs/pw_util.h @@ -0,0 +1,52 @@ +/* $Id$ + * + * Copyright (c) 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)pw_util.h 8.2 (Berkeley) 4/1/94 + */ + +#ifndef _PW_UTIL_H +#define _PW_UTIL_H + +#ifdef __FreeBSD__ + +void pw_error __P((char *, int, int)); +void pw_init __P((void)); +int pw_lock __P((void)); +int pw_mkdb __P((char *)); +int pw_tmp __P((void)); +void pw_copy __P((int, int, struct passwd *)); + +#endif + +#endif + diff --git a/mbsebbs/pwio.c b/mbsebbs/pwio.c index e004710f..8e99a713 100644 --- a/mbsebbs/pwio.c +++ b/mbsebbs/pwio.c @@ -31,6 +31,7 @@ * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. *****************************************************************************/ +#ifndef __FreeBSD__ #include "../config.h" #include @@ -168,10 +169,12 @@ int pw_name(const char *filename) +#ifndef __FreeBSD__ int pw_lock(void) { return commonio_lock(&passwd_db); } +#endif @@ -243,4 +246,5 @@ void __pw_del_entry(const struct commonio_entry *ent) commonio_del_entry(&passwd_db, ent); } +#endif diff --git a/mbsebbs/pwio.h b/mbsebbs/pwio.h index aeea9031..8800894c 100644 --- a/mbsebbs/pwio.h +++ b/mbsebbs/pwio.h @@ -1,6 +1,10 @@ +/* $Id$ */ + #ifndef _PWIO_H #define _PWIO_H +#ifndef __FreeBSD__ + #ifndef PASSWD_FILE #define PASSWD_FILE "/etc/passwd" #endif @@ -25,3 +29,5 @@ int pw_update (const struct passwd *); #endif +#endif +