From owner-svn-src-stable@FreeBSD.ORG Sun Dec 11 16:57:28 2011 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 26841106564A; Sun, 11 Dec 2011 16:57:28 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 0CAB28FC0A; Sun, 11 Dec 2011 16:57:28 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id pBBGvRHj060662; Sun, 11 Dec 2011 16:57:27 GMT (envelope-from des@svn.freebsd.org) Received: (from des@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pBBGvRVF060660; Sun, 11 Dec 2011 16:57:27 GMT (envelope-from des@svn.freebsd.org) Message-Id: <201112111657.pBBGvRVF060660@svn.freebsd.org> From: Dag-Erling Smorgrav Date: Sun, 11 Dec 2011 16:57:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r228410 - stable/9/lib/libpam/modules/pam_ssh X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 11 Dec 2011 16:57:28 -0000 Author: des Date: Sun Dec 11 16:57:27 2011 New Revision: 228410 URL: http://svn.freebsd.org/changeset/base/228410 Log: MFH r227757: check for null passphrases, since openssl doesn't Approved by: re (kib) Security: prevents users with unencrypted ssh keys (prohibited unless the nullok option is specified) from logging in by providing a bogus non-null passphrase. Modified: stable/9/lib/libpam/modules/pam_ssh/pam_ssh.c Directory Properties: stable/9/lib/libpam/ (props changed) Modified: stable/9/lib/libpam/modules/pam_ssh/pam_ssh.c ============================================================================== --- stable/9/lib/libpam/modules/pam_ssh/pam_ssh.c Sun Dec 11 14:01:11 2011 (r228409) +++ stable/9/lib/libpam/modules/pam_ssh/pam_ssh.c Sun Dec 11 16:57:27 2011 (r228410) @@ -91,7 +91,8 @@ static char *const pam_ssh_agent_envp[] * struct pam_ssh_key containing the key and its comment. */ static struct pam_ssh_key * -pam_ssh_load_key(const char *dir, const char *kfn, const char *passphrase) +pam_ssh_load_key(const char *dir, const char *kfn, const char *passphrase, + int nullok) { struct pam_ssh_key *psk; char fn[PATH_MAX]; @@ -101,7 +102,21 @@ pam_ssh_load_key(const char *dir, const if (snprintf(fn, sizeof(fn), "%s/%s", dir, kfn) > (int)sizeof(fn)) return (NULL); comment = NULL; - key = key_load_private(fn, passphrase, &comment); + /* + * If the key is unencrypted, OpenSSL ignores the passphrase, so + * it will seem like the user typed in the right one. This allows + * a user to circumvent nullok by providing a dummy passphrase. + * Verify that the key really *is* encrypted by trying to load it + * with an empty passphrase, and if the key is not encrypted, + * accept only an empty passphrase. + */ + key = key_load_private(fn, NULL, &comment); + if (key != NULL && !(*passphrase == '\0' && nullok)) { + key_free(key); + return (NULL); + } + if (key == NULL) + key = key_load_private(fn, passphrase, &comment); if (key == NULL) { openpam_log(PAM_LOG_DEBUG, "failed to load key from %s", fn); return (NULL); @@ -168,9 +183,6 @@ pam_sm_authenticate(pam_handle_t *pamh, if (pam_err != PAM_SUCCESS) return (pam_err); - if (*passphrase == '\0' && !nullok) - goto skip_keys; - /* switch to user credentials */ pam_err = openpam_borrow_cred(pamh, pwd); if (pam_err != PAM_SUCCESS) @@ -178,7 +190,7 @@ pam_sm_authenticate(pam_handle_t *pamh, /* try to load keys from all keyfiles we know of */ for (kfn = pam_ssh_keyfiles; *kfn != NULL; ++kfn) { - psk = pam_ssh_load_key(pwd->pw_dir, *kfn, passphrase); + psk = pam_ssh_load_key(pwd->pw_dir, *kfn, passphrase, nullok); if (psk != NULL) { pam_set_data(pamh, *kfn, psk, pam_ssh_free_key); ++nkeys; @@ -188,7 +200,6 @@ pam_sm_authenticate(pam_handle_t *pamh, /* switch back to arbitrator credentials */ openpam_restore_cred(pamh); - skip_keys: /* * If we tried an old token and didn't get anything, and * try_first_pass was specified, try again after prompting the From owner-svn-src-stable@FreeBSD.ORG Sun Dec 11 20:38:37 2011 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 377FA1065672; Sun, 11 Dec 2011 20:38:37 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 1D78A8FC0A; Sun, 11 Dec 2011 20:38:37 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id pBBKcb2f067990; Sun, 11 Dec 2011 20:38:37 GMT (envelope-from des@svn.freebsd.org) Received: (from des@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pBBKcaWD067988; Sun, 11 Dec 2011 20:38:37 GMT (envelope-from des@svn.freebsd.org) Message-Id: <201112112038.pBBKcaWD067988@svn.freebsd.org> From: Dag-Erling Smorgrav Date: Sun, 11 Dec 2011 20:38:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r228420 - stable/8/lib/libpam/modules/pam_ssh X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 11 Dec 2011 20:38:37 -0000 Author: des Date: Sun Dec 11 20:38:36 2011 New Revision: 228420 URL: http://svn.freebsd.org/changeset/base/228420 Log: MFH r227757: check for null passphrases, since openssl doesn't Security: prevents users with unencrypted ssh keys (prohibited unless the nullok option is specified) from logging in by providing a bogus non-null passphrase. Modified: stable/8/lib/libpam/modules/pam_ssh/pam_ssh.c Directory Properties: stable/8/lib/libpam/ (props changed) Modified: stable/8/lib/libpam/modules/pam_ssh/pam_ssh.c ============================================================================== --- stable/8/lib/libpam/modules/pam_ssh/pam_ssh.c Sun Dec 11 20:01:37 2011 (r228419) +++ stable/8/lib/libpam/modules/pam_ssh/pam_ssh.c Sun Dec 11 20:38:36 2011 (r228420) @@ -91,7 +91,8 @@ static char *const pam_ssh_agent_envp[] * struct pam_ssh_key containing the key and its comment. */ static struct pam_ssh_key * -pam_ssh_load_key(const char *dir, const char *kfn, const char *passphrase) +pam_ssh_load_key(const char *dir, const char *kfn, const char *passphrase, + int nullok) { struct pam_ssh_key *psk; char fn[PATH_MAX]; @@ -101,7 +102,21 @@ pam_ssh_load_key(const char *dir, const if (snprintf(fn, sizeof(fn), "%s/%s", dir, kfn) > (int)sizeof(fn)) return (NULL); comment = NULL; - key = key_load_private(fn, passphrase, &comment); + /* + * If the key is unencrypted, OpenSSL ignores the passphrase, so + * it will seem like the user typed in the right one. This allows + * a user to circumvent nullok by providing a dummy passphrase. + * Verify that the key really *is* encrypted by trying to load it + * with an empty passphrase, and if the key is not encrypted, + * accept only an empty passphrase. + */ + key = key_load_private(fn, NULL, &comment); + if (key != NULL && !(*passphrase == '\0' && nullok)) { + key_free(key); + return (NULL); + } + if (key == NULL) + key = key_load_private(fn, passphrase, &comment); if (key == NULL) { openpam_log(PAM_LOG_DEBUG, "failed to load key from %s\n", fn); return (NULL); @@ -168,9 +183,6 @@ pam_sm_authenticate(pam_handle_t *pamh, if (pam_err != PAM_SUCCESS) return (pam_err); - if (*passphrase == '\0' && !nullok) - goto skip_keys; - /* switch to user credentials */ pam_err = openpam_borrow_cred(pamh, pwd); if (pam_err != PAM_SUCCESS) @@ -178,7 +190,7 @@ pam_sm_authenticate(pam_handle_t *pamh, /* try to load keys from all keyfiles we know of */ for (kfn = pam_ssh_keyfiles; *kfn != NULL; ++kfn) { - psk = pam_ssh_load_key(pwd->pw_dir, *kfn, passphrase); + psk = pam_ssh_load_key(pwd->pw_dir, *kfn, passphrase, nullok); if (psk != NULL) { pam_set_data(pamh, *kfn, psk, pam_ssh_free_key); ++nkeys; @@ -188,7 +200,6 @@ pam_sm_authenticate(pam_handle_t *pamh, /* switch back to arbitrator credentials */ openpam_restore_cred(pamh); - skip_keys: /* * If we tried an old token and didn't get anything, and * try_first_pass was specified, try again after prompting the From owner-svn-src-stable@FreeBSD.ORG Sun Dec 11 20:40:24 2011 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2CE4F1065670; Sun, 11 Dec 2011 20:40:24 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 132238FC13; Sun, 11 Dec 2011 20:40:24 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id pBBKeNZL068091; Sun, 11 Dec 2011 20:40:23 GMT (envelope-from des@svn.freebsd.org) Received: (from des@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pBBKeNOa068089; Sun, 11 Dec 2011 20:40:23 GMT (envelope-from des@svn.freebsd.org) Message-Id: <201112112040.pBBKeNOa068089@svn.freebsd.org> From: Dag-Erling Smorgrav Date: Sun, 11 Dec 2011 20:40:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r228421 - stable/7/lib/libpam/modules/pam_ssh X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 11 Dec 2011 20:40:24 -0000 Author: des Date: Sun Dec 11 20:40:23 2011 New Revision: 228421 URL: http://svn.freebsd.org/changeset/base/228421 Log: MFH r227757: check for null passphrases, since openssl doesn't Security: prevents users with unencrypted ssh keys (prohibited unless the nullok option is specified) from logging in by providing a bogus non-null passphrase. Modified: stable/7/lib/libpam/modules/pam_ssh/pam_ssh.c Directory Properties: stable/7/lib/libpam/ (props changed) Modified: stable/7/lib/libpam/modules/pam_ssh/pam_ssh.c ============================================================================== --- stable/7/lib/libpam/modules/pam_ssh/pam_ssh.c Sun Dec 11 20:38:36 2011 (r228420) +++ stable/7/lib/libpam/modules/pam_ssh/pam_ssh.c Sun Dec 11 20:40:23 2011 (r228421) @@ -88,7 +88,8 @@ static char *const pam_ssh_agent_envp[] * struct pam_ssh_key containing the key and its comment. */ static struct pam_ssh_key * -pam_ssh_load_key(const char *dir, const char *kfn, const char *passphrase) +pam_ssh_load_key(const char *dir, const char *kfn, const char *passphrase, + int nullok) { struct pam_ssh_key *psk; char fn[PATH_MAX]; @@ -98,7 +99,21 @@ pam_ssh_load_key(const char *dir, const if (snprintf(fn, sizeof(fn), "%s/%s", dir, kfn) > (int)sizeof(fn)) return (NULL); comment = NULL; - key = key_load_private(fn, passphrase, &comment); + /* + * If the key is unencrypted, OpenSSL ignores the passphrase, so + * it will seem like the user typed in the right one. This allows + * a user to circumvent nullok by providing a dummy passphrase. + * Verify that the key really *is* encrypted by trying to load it + * with an empty passphrase, and if the key is not encrypted, + * accept only an empty passphrase. + */ + key = key_load_private(fn, NULL, &comment); + if (key != NULL && !(*passphrase == '\0' && nullok)) { + key_free(key); + return (NULL); + } + if (key == NULL) + key = key_load_private(fn, passphrase, &comment); if (key == NULL) { openpam_log(PAM_LOG_DEBUG, "failed to load key from %s\n", fn); return (NULL); @@ -165,9 +180,6 @@ pam_sm_authenticate(pam_handle_t *pamh, if (pam_err != PAM_SUCCESS) return (pam_err); - if (*passphrase == '\0' && !nullok) - goto skip_keys; - /* switch to user credentials */ pam_err = openpam_borrow_cred(pamh, pwd); if (pam_err != PAM_SUCCESS) @@ -175,7 +187,7 @@ pam_sm_authenticate(pam_handle_t *pamh, /* try to load keys from all keyfiles we know of */ for (kfn = pam_ssh_keyfiles; *kfn != NULL; ++kfn) { - psk = pam_ssh_load_key(pwd->pw_dir, *kfn, passphrase); + psk = pam_ssh_load_key(pwd->pw_dir, *kfn, passphrase, nullok); if (psk != NULL) { pam_set_data(pamh, *kfn, psk, pam_ssh_free_key); ++nkeys; @@ -185,7 +197,6 @@ pam_sm_authenticate(pam_handle_t *pamh, /* switch back to arbitrator credentials */ openpam_restore_cred(pamh); - skip_keys: /* * If we tried an old token and didn't get anything, and * try_first_pass was specified, try again after prompting the From owner-svn-src-stable@FreeBSD.ORG Mon Dec 12 17:33:39 2011 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 36BB11065675; Mon, 12 Dec 2011 17:33:39 +0000 (UTC) (envelope-from pho@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 239278FC08; Mon, 12 Dec 2011 17:33:39 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id pBCHXdCq011172; Mon, 12 Dec 2011 17:33:39 GMT (envelope-from pho@svn.freebsd.org) Received: (from pho@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pBCHXcfc011168; Mon, 12 Dec 2011 17:33:38 GMT (envelope-from pho@svn.freebsd.org) Message-Id: <201112121733.pBCHXcfc011168@svn.freebsd.org> From: Peter Holm Date: Mon, 12 Dec 2011 17:33:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r228439 - in stable/8/sys: conf kern sys X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 12 Dec 2011 17:33:39 -0000 Author: pho Date: Mon Dec 12 17:33:38 2011 New Revision: 228439 URL: http://svn.freebsd.org/changeset/base/228439 Log: MFC: r228218, r228219, 228220, 228221 Rename copyin_timeout32 to umtx_copyin_timeout32 and move parameter check here. Include check for negative seconds value. Add umtx_copyin_timeout() and move parameter checks here. Add declaration of umtx_copyin_timeout() Use umtx_copyin_timeout() to copy and check timeout parameteri in kern_thr_suspend(). Modified: stable/8/sys/kern/kern_thr.c stable/8/sys/kern/kern_umtx.c stable/8/sys/sys/umtx.h Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/conf/ldscript.mips.octeon1.32 (props changed) stable/8/sys/conf/ldscript.mips.octeon1.64 (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) Modified: stable/8/sys/kern/kern_thr.c ============================================================================== --- stable/8/sys/kern/kern_thr.c Mon Dec 12 13:12:55 2011 (r228438) +++ stable/8/sys/kern/kern_thr.c Mon Dec 12 17:33:38 2011 (r228439) @@ -428,8 +428,7 @@ thr_suspend(struct thread *td, struct th tsp = NULL; if (uap->timeout != NULL) { - error = copyin((const void *)uap->timeout, (void *)&ts, - sizeof(struct timespec)); + error = umtx_copyin_timeout(uap->timeout, &ts); if (error != 0) return (error); tsp = &ts; @@ -445,9 +444,6 @@ kern_thr_suspend(struct thread *td, stru int error = 0, hz = 0; if (tsp != NULL) { - if (tsp->tv_sec < 0 || tsp->tv_nsec < 0 || - tsp->tv_nsec > 1000000000) - return (EINVAL); if (tsp->tv_sec == 0 && tsp->tv_nsec == 0) return (ETIMEDOUT); TIMESPEC_TO_TIMEVAL(&tv, tsp); Modified: stable/8/sys/kern/kern_umtx.c ============================================================================== --- stable/8/sys/kern/kern_umtx.c Mon Dec 12 13:12:55 2011 (r228438) +++ stable/8/sys/kern/kern_umtx.c Mon Dec 12 17:33:38 2011 (r228439) @@ -2740,6 +2740,21 @@ _umtx_unlock(struct thread *td, struct _ return do_unlock_umtx(td, uap->umtx, td->td_tid); } +inline int +umtx_copyin_timeout(const void *addr, struct timespec *tsp) +{ + int error; + + error = copyin(addr, tsp, sizeof(struct timespec)); + if (error == 0) { + if (tsp->tv_sec < 0 || + tsp->tv_nsec >= 1000000000 || + tsp->tv_nsec < 0) + error = EINVAL; + } + return (error); +} + static int __umtx_op_lock_umtx(struct thread *td, struct _umtx_op_args *uap) { @@ -2750,13 +2765,9 @@ __umtx_op_lock_umtx(struct thread *td, s if (uap->uaddr2 == NULL) ts = NULL; else { - error = copyin(uap->uaddr2, &timeout, sizeof(timeout)); + error = umtx_copyin_timeout(uap->uaddr2, &timeout); if (error != 0) return (error); - if (timeout.tv_nsec >= 1000000000 || - timeout.tv_nsec < 0) { - return (EINVAL); - } ts = &timeout; } return (do_lock_umtx(td, uap->obj, uap->val, ts)); @@ -2777,12 +2788,9 @@ __umtx_op_wait(struct thread *td, struct if (uap->uaddr2 == NULL) ts = NULL; else { - error = copyin(uap->uaddr2, &timeout, sizeof(timeout)); + error = umtx_copyin_timeout(uap->uaddr2, &timeout); if (error != 0) return (error); - if (timeout.tv_nsec >= 1000000000 || - timeout.tv_nsec < 0) - return (EINVAL); ts = &timeout; } return do_wait(td, uap->obj, uap->val, ts, 0, 0); @@ -2797,12 +2805,9 @@ __umtx_op_wait_uint(struct thread *td, s if (uap->uaddr2 == NULL) ts = NULL; else { - error = copyin(uap->uaddr2, &timeout, sizeof(timeout)); + error = umtx_copyin_timeout(uap->uaddr2, &timeout); if (error != 0) return (error); - if (timeout.tv_nsec >= 1000000000 || - timeout.tv_nsec < 0) - return (EINVAL); ts = &timeout; } return do_wait(td, uap->obj, uap->val, ts, 1, 0); @@ -2817,12 +2822,9 @@ __umtx_op_wait_uint_private(struct threa if (uap->uaddr2 == NULL) ts = NULL; else { - error = copyin(uap->uaddr2, &timeout, sizeof(timeout)); + error = umtx_copyin_timeout(uap->uaddr2, &timeout); if (error != 0) return (error); - if (timeout.tv_nsec >= 1000000000 || - timeout.tv_nsec < 0) - return (EINVAL); ts = &timeout; } return do_wait(td, uap->obj, uap->val, ts, 1, 1); @@ -2850,14 +2852,9 @@ __umtx_op_lock_umutex(struct thread *td, if (uap->uaddr2 == NULL) ts = NULL; else { - error = copyin(uap->uaddr2, &timeout, - sizeof(timeout)); + error = umtx_copyin_timeout(uap->uaddr2, &timeout); if (error != 0) return (error); - if (timeout.tv_nsec >= 1000000000 || - timeout.tv_nsec < 0) { - return (EINVAL); - } ts = &timeout; } return do_lock_umutex(td, uap->obj, ts, 0); @@ -2879,14 +2876,9 @@ __umtx_op_wait_umutex(struct thread *td, if (uap->uaddr2 == NULL) ts = NULL; else { - error = copyin(uap->uaddr2, &timeout, - sizeof(timeout)); + error = umtx_copyin_timeout(uap->uaddr2, &timeout); if (error != 0) return (error); - if (timeout.tv_nsec >= 1000000000 || - timeout.tv_nsec < 0) { - return (EINVAL); - } ts = &timeout; } return do_lock_umutex(td, uap->obj, ts, _UMUTEX_WAIT); @@ -2920,14 +2912,9 @@ __umtx_op_cv_wait(struct thread *td, str if (uap->uaddr2 == NULL) ts = NULL; else { - error = copyin(uap->uaddr2, &timeout, - sizeof(timeout)); + error = umtx_copyin_timeout(uap->uaddr2, &timeout); if (error != 0) return (error); - if (timeout.tv_nsec >= 1000000000 || - timeout.tv_nsec < 0) { - return (EINVAL); - } ts = &timeout; } return (do_cv_wait(td, uap->obj, uap->uaddr1, ts, uap->val)); @@ -2955,14 +2942,9 @@ __umtx_op_rw_rdlock(struct thread *td, s if (uap->uaddr2 == NULL) { error = do_rw_rdlock(td, uap->obj, uap->val, 0); } else { - error = copyin(uap->uaddr2, &timeout, - sizeof(timeout)); + error = umtx_copyin_timeout(uap->uaddr2, &timeout); if (error != 0) return (error); - if (timeout.tv_nsec >= 1000000000 || - timeout.tv_nsec < 0) { - return (EINVAL); - } error = do_rw_rdlock2(td, uap->obj, uap->val, &timeout); } return (error); @@ -2978,14 +2960,9 @@ __umtx_op_rw_wrlock(struct thread *td, s if (uap->uaddr2 == NULL) { error = do_rw_wrlock(td, uap->obj, 0); } else { - error = copyin(uap->uaddr2, &timeout, - sizeof(timeout)); + error = umtx_copyin_timeout(uap->uaddr2, &timeout); if (error != 0) return (error); - if (timeout.tv_nsec >= 1000000000 || - timeout.tv_nsec < 0) { - return (EINVAL); - } error = do_rw_wrlock2(td, uap->obj, &timeout); } @@ -3051,15 +3028,21 @@ struct timespec32 { }; static inline int -copyin_timeout32(void *addr, struct timespec *tsp) +umtx_copyin_timeout32(void *addr, struct timespec *tsp) { struct timespec32 ts32; int error; error = copyin(addr, &ts32, sizeof(struct timespec32)); if (error == 0) { - tsp->tv_sec = ts32.tv_sec; - tsp->tv_nsec = ts32.tv_nsec; + if (ts32.tv_sec < 0 || + ts32.tv_nsec >= 1000000000 || + ts32.tv_nsec < 0) + error = EINVAL; + else { + tsp->tv_sec = ts32.tv_sec; + tsp->tv_nsec = ts32.tv_nsec; + } } return (error); } @@ -3074,13 +3057,9 @@ __umtx_op_lock_umtx_compat32(struct thre if (uap->uaddr2 == NULL) ts = NULL; else { - error = copyin_timeout32(uap->uaddr2, &timeout); + error = umtx_copyin_timeout32(uap->uaddr2, &timeout); if (error != 0) return (error); - if (timeout.tv_nsec >= 1000000000 || - timeout.tv_nsec < 0) { - return (EINVAL); - } ts = &timeout; } return (do_lock_umtx32(td, uap->obj, uap->val, ts)); @@ -3101,12 +3080,9 @@ __umtx_op_wait_compat32(struct thread *t if (uap->uaddr2 == NULL) ts = NULL; else { - error = copyin_timeout32(uap->uaddr2, &timeout); + error = umtx_copyin_timeout32(uap->uaddr2, &timeout); if (error != 0) return (error); - if (timeout.tv_nsec >= 1000000000 || - timeout.tv_nsec < 0) - return (EINVAL); ts = &timeout; } return do_wait(td, uap->obj, uap->val, ts, 1, 0); @@ -3122,12 +3098,9 @@ __umtx_op_lock_umutex_compat32(struct th if (uap->uaddr2 == NULL) ts = NULL; else { - error = copyin_timeout32(uap->uaddr2, &timeout); + error = umtx_copyin_timeout32(uap->uaddr2, &timeout); if (error != 0) return (error); - if (timeout.tv_nsec >= 1000000000 || - timeout.tv_nsec < 0) - return (EINVAL); ts = &timeout; } return do_lock_umutex(td, uap->obj, ts, 0); @@ -3143,12 +3116,9 @@ __umtx_op_wait_umutex_compat32(struct th if (uap->uaddr2 == NULL) ts = NULL; else { - error = copyin_timeout32(uap->uaddr2, &timeout); + error = umtx_copyin_timeout32(uap->uaddr2, &timeout); if (error != 0) return (error); - if (timeout.tv_nsec >= 1000000000 || - timeout.tv_nsec < 0) - return (EINVAL); ts = &timeout; } return do_lock_umutex(td, uap->obj, ts, _UMUTEX_WAIT); @@ -3164,12 +3134,9 @@ __umtx_op_cv_wait_compat32(struct thread if (uap->uaddr2 == NULL) ts = NULL; else { - error = copyin_timeout32(uap->uaddr2, &timeout); + error = umtx_copyin_timeout32(uap->uaddr2, &timeout); if (error != 0) return (error); - if (timeout.tv_nsec >= 1000000000 || - timeout.tv_nsec < 0) - return (EINVAL); ts = &timeout; } return (do_cv_wait(td, uap->obj, uap->uaddr1, ts, uap->val)); @@ -3185,13 +3152,9 @@ __umtx_op_rw_rdlock_compat32(struct thre if (uap->uaddr2 == NULL) { error = do_rw_rdlock(td, uap->obj, uap->val, 0); } else { - error = copyin_timeout32(uap->uaddr2, &timeout); + error = umtx_copyin_timeout32(uap->uaddr2, &timeout); if (error != 0) return (error); - if (timeout.tv_nsec >= 1000000000 || - timeout.tv_nsec < 0) { - return (EINVAL); - } error = do_rw_rdlock2(td, uap->obj, uap->val, &timeout); } return (error); @@ -3207,13 +3170,9 @@ __umtx_op_rw_wrlock_compat32(struct thre if (uap->uaddr2 == NULL) { error = do_rw_wrlock(td, uap->obj, 0); } else { - error = copyin_timeout32(uap->uaddr2, &timeout); + error = umtx_copyin_timeout32(uap->uaddr2, &timeout); if (error != 0) return (error); - if (timeout.tv_nsec >= 1000000000 || - timeout.tv_nsec < 0) { - return (EINVAL); - } error = do_rw_wrlock2(td, uap->obj, &timeout); } @@ -3229,12 +3188,9 @@ __umtx_op_wait_uint_private_compat32(str if (uap->uaddr2 == NULL) ts = NULL; else { - error = copyin_timeout32(uap->uaddr2, &timeout); + error = umtx_copyin_timeout32(uap->uaddr2, &timeout); if (error != 0) return (error); - if (timeout.tv_nsec >= 1000000000 || - timeout.tv_nsec < 0) - return (EINVAL); ts = &timeout; } return do_wait(td, uap->obj, uap->val, ts, 1, 1); Modified: stable/8/sys/sys/umtx.h ============================================================================== --- stable/8/sys/sys/umtx.h Mon Dec 12 13:12:55 2011 (r228438) +++ stable/8/sys/sys/umtx.h Mon Dec 12 17:33:38 2011 (r228439) @@ -241,6 +241,7 @@ umtx_key_match(const struct umtx_key *k1 k1->info.both.b == k2->info.both.b); } +int umtx_copyin_timeout(const void *, struct timespec *); int umtx_key_get(void *, int, int, struct umtx_key *); void umtx_key_release(struct umtx_key *); struct umtx_q *umtxq_alloc(void); From owner-svn-src-stable@FreeBSD.ORG Tue Dec 13 12:59:39 2011 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BDF81106566B; Tue, 13 Dec 2011 12:59:39 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id AC39E8FC0A; Tue, 13 Dec 2011 12:59:39 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id pBDCxduh050689; Tue, 13 Dec 2011 12:59:39 GMT (envelope-from des@svn.freebsd.org) Received: (from des@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pBDCxduA050687; Tue, 13 Dec 2011 12:59:39 GMT (envelope-from des@svn.freebsd.org) Message-Id: <201112131259.pBDCxduA050687@svn.freebsd.org> From: Dag-Erling Smorgrav Date: Tue, 13 Dec 2011 12:59:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r228464 - stable/9/contrib/openpam/lib X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Dec 2011 12:59:39 -0000 Author: des Date: Tue Dec 13 12:59:39 2011 New Revision: 228464 URL: http://svn.freebsd.org/changeset/base/228464 Log: MFH r228384: validate the service name Approved by: re (kib) Security: some poorly thought out programs allow the user to specify the service name; this patch makes it harder to trick these programs into loading and executing arbitrary code. Modified: stable/9/contrib/openpam/lib/openpam_configure.c Directory Properties: stable/9/contrib/openpam/ (props changed) Modified: stable/9/contrib/openpam/lib/openpam_configure.c ============================================================================== --- stable/9/contrib/openpam/lib/openpam_configure.c Tue Dec 13 11:54:51 2011 (r228463) +++ stable/9/contrib/openpam/lib/openpam_configure.c Tue Dec 13 12:59:39 2011 (r228464) @@ -285,6 +285,13 @@ openpam_load_chain(pam_handle_t *pamh, size_t len; int r; + /* don't allow to escape from policy_path */ + if (strchr(service, '/')) { + openpam_log(PAM_LOG_ERROR, "invalid service name: %s", + service); + return (-PAM_SYSTEM_ERR); + } + for (path = openpam_policy_path; *path != NULL; ++path) { len = strlen(*path); if ((*path)[len - 1] == '/') { From owner-svn-src-stable@FreeBSD.ORG Tue Dec 13 13:02:53 2011 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0C18C1065670; Tue, 13 Dec 2011 13:02:53 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id EE6488FC0A; Tue, 13 Dec 2011 13:02:52 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id pBDD2q80050895; Tue, 13 Dec 2011 13:02:52 GMT (envelope-from des@svn.freebsd.org) Received: (from des@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pBDD2qn6050893; Tue, 13 Dec 2011 13:02:52 GMT (envelope-from des@svn.freebsd.org) Message-Id: <201112131302.pBDD2qn6050893@svn.freebsd.org> From: Dag-Erling Smorgrav Date: Tue, 13 Dec 2011 13:02:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r228466 - stable/8/contrib/openpam/lib X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Dec 2011 13:02:53 -0000 Author: des Date: Tue Dec 13 13:02:52 2011 New Revision: 228466 URL: http://svn.freebsd.org/changeset/base/228466 Log: MFH r228384: validate the service name Security: some poorly thought out programs allow the user to specify the service name; this patch makes it harder to trick these programs into loading and executing arbitrary code. Modified: stable/8/contrib/openpam/lib/openpam_configure.c Directory Properties: stable/8/contrib/openpam/ (props changed) Modified: stable/8/contrib/openpam/lib/openpam_configure.c ============================================================================== --- stable/8/contrib/openpam/lib/openpam_configure.c Tue Dec 13 13:02:31 2011 (r228465) +++ stable/8/contrib/openpam/lib/openpam_configure.c Tue Dec 13 13:02:52 2011 (r228466) @@ -285,6 +285,13 @@ openpam_load_chain(pam_handle_t *pamh, size_t len; int r; + /* don't allow to escape from policy_path */ + if (strchr(service, '/')) { + openpam_log(PAM_LOG_ERROR, "invalid service name: %s", + service); + return (-PAM_SYSTEM_ERR); + } + for (path = openpam_policy_path; *path != NULL; ++path) { len = strlen(*path); if ((*path)[len - 1] == '/') { From owner-svn-src-stable@FreeBSD.ORG Tue Dec 13 13:03:11 2011 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6FBEA1065675; Tue, 13 Dec 2011 13:03:11 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 5DF038FC0C; Tue, 13 Dec 2011 13:03:11 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id pBDD3BtR050940; Tue, 13 Dec 2011 13:03:11 GMT (envelope-from des@svn.freebsd.org) Received: (from des@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pBDD3Bdp050938; Tue, 13 Dec 2011 13:03:11 GMT (envelope-from des@svn.freebsd.org) Message-Id: <201112131303.pBDD3Bdp050938@svn.freebsd.org> From: Dag-Erling Smorgrav Date: Tue, 13 Dec 2011 13:03:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r228467 - stable/7/contrib/openpam/lib X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Dec 2011 13:03:11 -0000 Author: des Date: Tue Dec 13 13:03:11 2011 New Revision: 228467 URL: http://svn.freebsd.org/changeset/base/228467 Log: MFH r228384: validate the service name Security: some poorly thought out programs allow the user to specify the service name; this patch makes it harder to trick these programs into loading and executing arbitrary code. Modified: stable/7/contrib/openpam/lib/openpam_configure.c Directory Properties: stable/7/contrib/openpam/ (props changed) Modified: stable/7/contrib/openpam/lib/openpam_configure.c ============================================================================== --- stable/7/contrib/openpam/lib/openpam_configure.c Tue Dec 13 13:02:52 2011 (r228466) +++ stable/7/contrib/openpam/lib/openpam_configure.c Tue Dec 13 13:03:11 2011 (r228467) @@ -285,6 +285,13 @@ openpam_load_chain(pam_handle_t *pamh, size_t len; int r; + /* don't allow to escape from policy_path */ + if (strchr(service, '/')) { + openpam_log(PAM_LOG_ERROR, "invalid service name: %s", + service); + return (-PAM_SYSTEM_ERR); + } + for (path = openpam_policy_path; *path != NULL; ++path) { len = strlen(*path); if ((*path)[len - 1] == '/') { From owner-svn-src-stable@FreeBSD.ORG Thu Dec 15 16:39:48 2011 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A95391065676; Thu, 15 Dec 2011 16:39:48 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 97AB08FC25; Thu, 15 Dec 2011 16:39:48 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id pBFGdmdV058119; Thu, 15 Dec 2011 16:39:48 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pBFGdmdq058117; Thu, 15 Dec 2011 16:39:48 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201112151639.pBFGdmdq058117@svn.freebsd.org> From: John Baldwin Date: Thu, 15 Dec 2011 16:39:48 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r228534 - stable/8/usr.sbin/mfiutil X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 15 Dec 2011 16:39:48 -0000 Author: jhb Date: Thu Dec 15 16:39:48 2011 New Revision: 228534 URL: http://svn.freebsd.org/changeset/base/228534 Log: MFC 225168: If a drive is not part of the array (i.e. missing) we need to print the new line after the pd state information as well, so move it to the outside of the block. Modified: stable/8/usr.sbin/mfiutil/mfi_show.c Directory Properties: stable/8/usr.sbin/mfiutil/ (props changed) Modified: stable/8/usr.sbin/mfiutil/mfi_show.c ============================================================================== --- stable/8/usr.sbin/mfiutil/mfi_show.c Thu Dec 15 15:17:19 2011 (r228533) +++ stable/8/usr.sbin/mfiutil/mfi_show.c Thu Dec 15 16:39:48 2011 (r228534) @@ -335,8 +335,8 @@ show_config(int ac, char **av) mfi_pdstate(ar->pd[j].fw_state)); else print_pd(&pinfo, -1); - printf("\n"); } + printf("\n"); } p += config->array_size; } From owner-svn-src-stable@FreeBSD.ORG Fri Dec 16 12:53:16 2011 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 004E5106564A; Fri, 16 Dec 2011 12:53:15 +0000 (UTC) (envelope-from pho@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id E283A8FC08; Fri, 16 Dec 2011 12:53:15 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id pBGCrFeg007555; Fri, 16 Dec 2011 12:53:15 GMT (envelope-from pho@svn.freebsd.org) Received: (from pho@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pBGCrF5C007553; Fri, 16 Dec 2011 12:53:15 GMT (envelope-from pho@svn.freebsd.org) Message-Id: <201112161253.pBGCrF5C007553@svn.freebsd.org> From: Peter Holm Date: Fri, 16 Dec 2011 12:53:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r228573 - in stable/8/sys: conf kern X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Dec 2011 12:53:16 -0000 Author: pho Date: Fri Dec 16 12:53:15 2011 New Revision: 228573 URL: http://svn.freebsd.org/changeset/base/228573 Log: MFC: r228360 Move cpu_set_upcall(newtd, td) up before the first call of thread_free(newtd). This to avoid a possible page fault in cpu_thread_clean() as seen on amd64 with syscall fuzzing. Modified: stable/8/sys/kern/kern_thr.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/conf/ldscript.mips.octeon1.32 (props changed) stable/8/sys/conf/ldscript.mips.octeon1.64 (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) Modified: stable/8/sys/kern/kern_thr.c ============================================================================== --- stable/8/sys/kern/kern_thr.c Fri Dec 16 12:42:02 2011 (r228572) +++ stable/8/sys/kern/kern_thr.c Fri Dec 16 12:53:15 2011 (r228573) @@ -188,6 +188,8 @@ create_thread(struct thread *td, mcontex if (newtd == NULL) return (ENOMEM); + cpu_set_upcall(newtd, td); + /* * Try the copyout as soon as we allocate the td so we don't * have to tear things down in a failure case below. @@ -215,8 +217,6 @@ create_thread(struct thread *td, mcontex newtd->td_proc = td->td_proc; newtd->td_ucred = crhold(td->td_ucred); - cpu_set_upcall(newtd, td); - if (ctx != NULL) { /* old way to set user context */ error = set_mcontext(newtd, ctx); if (error != 0) { From owner-svn-src-stable@FreeBSD.ORG Fri Dec 16 23:44:16 2011 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 91EC9106564A; Fri, 16 Dec 2011 23:44:16 +0000 (UTC) (envelope-from dougb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 7E8CA8FC15; Fri, 16 Dec 2011 23:44:16 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id pBGNiGmw032764; Fri, 16 Dec 2011 23:44:16 GMT (envelope-from dougb@svn.freebsd.org) Received: (from dougb@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pBGNiGbN032761; Fri, 16 Dec 2011 23:44:16 GMT (envelope-from dougb@svn.freebsd.org) Message-Id: <201112162344.pBGNiGbN032761@svn.freebsd.org> From: Doug Barton Date: Fri, 16 Dec 2011 23:44:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r228608 - stable/7/usr.sbin/tzsetup X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Dec 2011 23:44:16 -0000 Author: dougb Date: Fri Dec 16 23:44:16 2011 New Revision: 228608 URL: http://svn.freebsd.org/changeset/base/228608 Log: MFC: r179530 - Replace rcsid with __FBSDID. - Remove paths.h and embed it in the source. - Remove stale alpha support. - Clean up compiler warnings and fix style(9) bugs. Not MFC'ed by: jkim MFC: r195339 Add a new options (-s) that, when specified, skips the question about adjusting the clock to UTC. That avoids to write on /etc/wall_cmos_clock which is useful in some cases (example: host user in a jail). Not MFC'ed by: attilio MFC: r198254 When tzsetup is run as non-root and the "CMOS clock question on UTC" is answered as No, it would abort without properly ending the dialog session. Not MFC'ed by: edwin MFC: r198267 Instead of having to know which timezone was picked last time, you now can run "tzsetup -r" which will reinstall the last choice. This data is recorded in /var/db/zoneinfo. Not MFC'ed by: edwin MFC: r198350 - Add support for chrooted installs. - Add examples to the man-page. Not MFC'ed by: edwin MFC: r208830 When there is a problem with writing, also bail out. Not MFC'ed by: edwin MFC: r208831 Add comment that this value is unused. It is obvious that it isn't used, but both clang and Coverity talk about it. Not MFC'ed by: edwin MFC: r209190 Use literal format strings. Found by clang. Not MFC'ed by: emaste MFC: r210243 Fix support for chrooted installs. Not MFC'ed by: nork While mentored by: imp MFC: r220172 Add a menu entry for UTC in the main menu. Not MFC'ed by: edwin MFC: r222139 - add missing options and arguments to program's usage() and sync it with manpage's SYNOPSIS - generally clean up a manpage's formatting Not MFC'ed by: ru MFC: r227011 If the user is moving from any other time zone to UTC we need to delete any old /var/db/zoneinfo file that may exist so that tzsetup -r does the right thing. Deleted: stable/7/usr.sbin/tzsetup/paths.h Modified: stable/7/usr.sbin/tzsetup/tzsetup.8 stable/7/usr.sbin/tzsetup/tzsetup.c Directory Properties: stable/7/usr.sbin/tzsetup/ (props changed) Modified: stable/7/usr.sbin/tzsetup/tzsetup.8 ============================================================================== --- stable/7/usr.sbin/tzsetup/tzsetup.8 Fri Dec 16 23:43:58 2011 (r228607) +++ stable/7/usr.sbin/tzsetup/tzsetup.8 Fri Dec 16 23:44:16 2011 (r228608) @@ -23,7 +23,8 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd September 05, 2009 +.\" +.Dd October 21, 2009 .Dt TZSETUP 8 .Os .Sh NAME @@ -31,8 +32,9 @@ .Nd set local timezone .Sh SYNOPSIS .Nm -.Op Fl ns -.Op Ar default +.Op Fl nrs +.Op Fl C Ar chroot_directory +.Op Ar zoneinfo_file | zoneinfo_name .Sh DESCRIPTION The .Nm @@ -49,17 +51,27 @@ the hardware clock does not keep .Pp The following option is available: .Bl -tag -offset indent -width Fl +.It Fl C Ar chroot_directory +Open all files and directories relative to +.Ar chroot_directory . .It Fl n Do not create or copy files. +.It Fl r +Reinstall the zoneinfo file installed last time. +The name is obtained from +.Pa /var/db/zoneinfo . .It Fl s Skip the initial question about adjusting the clock if not set to .Tn UTC . .El .Pp -It is possible to short-circuit the menu system by specifying a -.Ar default -on the command line; this is intended mainly for pre-configured -installation scripts. +It is possible to short-circuit the menu system by specifying the +location of a +.Ar zoneinfo_file +or the name of the +.Ar zoneinfo_name +on the command line; this is intended mainly for pre-configured installation +scripts or people who know which zoneinfo they want to install. .Sh TIMEZONE DATABASE The contents of the timezone database are indexed by .Pa /usr/share/zoneinfo/zone.tab . @@ -91,12 +103,12 @@ The source code to the database contains many additional comments and documentation references for the historically minded. .Sh FILES -.Bl -tag -width /usr/share/zoneinfo/zone.tab -compact +.Bl -tag -width ".Pa /usr/share/zoneinfo/zone.tab" -compact .It Pa /etc/localtime current time zone file .It Pa /etc/wall_cmos_clock see -.Xr adjkerntz 8 . +.Xr adjkerntz 8 .It Pa /usr/share/misc/iso3166 mapping of .Tn ISO @@ -105,7 +117,27 @@ mapping of directory for zoneinfo files .It Pa /usr/share/zoneinfo/zone.tab mapping of timezone file to country and location +.It Pa /var/db/zoneinfo +saved name of the timezone file installed last .El +.Sh EXAMPLES +Normal usage, to select the right zoneinfo file via the dialog-based +user interface: +.Dl tzsetup +.Pp +Install the file +.Pa /usr/share/zoneinfo/Australia/Sydney : +.Dl "tzsetup /usr/share/zoneinfo/Australia/Sydney" +.Pp +Install the zoneinfo file for Australia/Sydney, assumed to be located +in +.Pa /usr/share/zoneinfo : +.Dl "tzsetup Australia/Sydney" +.Pp +After a reinstall of the zoneinfo files, you can reinstall the +latest installed zoneinfo file (as specified in +.Pa /var/db/zoneinfo ) : +.Dl "tzsetup -r" .Sh SEE ALSO .Xr date 1 , .Xr adjtime 2 , Modified: stable/7/usr.sbin/tzsetup/tzsetup.c ============================================================================== --- stable/7/usr.sbin/tzsetup/tzsetup.c Fri Dec 16 23:43:58 2011 (r228607) +++ stable/7/usr.sbin/tzsetup/tzsetup.c Fri Dec 16 23:44:16 2011 (r228608) @@ -12,7 +12,7 @@ * no representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied * warranty. - * + * * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF @@ -32,12 +32,9 @@ * files provided in newer tzdata releases. */ -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ +#include +__FBSDID("$FreeBSD$"); -#include #include #include #include @@ -48,112 +45,145 @@ static const char rcsid[] = #include #include +#include #include #include -#include "paths.h" +#define _PATH_ZONETAB "/usr/share/zoneinfo/zone.tab" +#define _PATH_ISO3166 "/usr/share/misc/iso3166" +#define _PATH_ZONEINFO "/usr/share/zoneinfo" +#define _PATH_LOCALTIME "/etc/localtime" +#define _PATH_DB "/var/db/zoneinfo" +#define _PATH_WALL_CMOS_CLOCK "/etc/wall_cmos_clock" + +static char path_zonetab[MAXPATHLEN], path_iso3166[MAXPATHLEN], + path_zoneinfo[MAXPATHLEN], path_localtime[MAXPATHLEN], + path_db[MAXPATHLEN], path_wall_cmos_clock[MAXPATHLEN]; static int reallydoit = 1; - -static int continent_country_menu(dialogMenuItem *); -static int set_zone_multi(dialogMenuItem *); -static int set_zone_whole_country(dialogMenuItem *); -static int set_zone_menu(dialogMenuItem *); +static int reinstall = 0; +static int usedialog = 1; +static char *chrootenv = NULL; + +static void usage(void); +static int confirm_zone(const char *filename); +static int continent_country_menu(dialogMenuItem *); +static int install_zoneinfo_file(const char *zoneinfo_file); +static int set_zone_multi(dialogMenuItem *); +static int set_zone_whole_country(dialogMenuItem *); +static int set_zone_menu(dialogMenuItem *); +static int set_zone_utc(void); struct continent { dialogMenuItem *menu; - int nitems; - int ch; - int sc; + int nitems; + int ch; + int sc; }; -static struct continent africa, america, antarctica, arctic, asia, atlantic; -static struct continent australia, europe, indian, pacific; +static struct continent africa, america, antarctica, arctic, asia, atlantic; +static struct continent australia, europe, indian, pacific, utc; static struct continent_names { - char *name; + const char *name; struct continent *continent; } continent_names[] = { - { "Africa", &africa }, { "America", &america }, - { "Antarctica", &antarctica }, { "Arctic", &arctic }, - { "Asia", &asia }, - { "Atlantic", &atlantic }, { "Australia", &australia }, - { "Europe", &europe }, { "Indian", &indian }, { "Pacific", &pacific } + { "Africa", &africa }, + { "America", &america }, + { "Antarctica", &antarctica }, + { "Arctic", &arctic }, + { "Asia", &asia }, + { "Atlantic", &atlantic }, + { "Australia", &australia }, + { "Europe", &europe }, + { "Indian", &indian }, + { "Pacific", &pacific }, + { "UTC", &utc } }; -static dialogMenuItem continents[] = { - { "1", "Africa", 0, continent_country_menu, 0, &africa }, - { "2", "America -- North and South", 0, continent_country_menu, 0, - &america }, - { "3", "Antarctica", 0, continent_country_menu, 0, &antarctica }, - { "4", "Arctic Ocean", 0, continent_country_menu, 0, &arctic }, - { "5", "Asia", 0, continent_country_menu, 0, &asia }, - { "6", "Atlantic Ocean", 0, continent_country_menu, 0, &atlantic }, - { "7", "Australia", 0, continent_country_menu, 0, &australia }, - { "8", "Europe", 0, continent_country_menu, 0, &europe }, - { "9", "Indian Ocean", 0, continent_country_menu, 0, &indian }, - { "0", "Pacific Ocean", 0, continent_country_menu, 0, &pacific } +static struct continent_items { + char prompt[2]; + char title[30]; +} continent_items[] = { + { "1", "Africa" }, + { "2", "America -- North and South" }, + { "3", "Antarctica" }, + { "4", "Arctic Ocean" }, + { "5", "Asia" }, + { "6", "Atlantic Ocean" }, + { "7", "Australia" }, + { "8", "Europe" }, + { "9", "Indian Ocean" }, + { "0", "Pacific Ocean" }, + { "a", "UTC" } }; -#define NCONTINENTS (int)((sizeof continents)/(sizeof continents[0])) -#define OCEANP(x) ((x) == 3 || (x) == 5 || (x) == 8 || (x) == 9) + +#define NCONTINENTS \ + (int)((sizeof(continent_items)) / (sizeof(continent_items[0]))) +static dialogMenuItem continents[NCONTINENTS]; + +#define OCEANP(x) ((x) == 3 || (x) == 5 || (x) == 8 || (x) == 9) static int continent_country_menu(dialogMenuItem *continent) { - int rv; + char title[64], prompt[64]; struct continent *contp = continent->data; - char title[256]; - int isocean = OCEANP(continent - continents); - int menulen; + int isocean = OCEANP(continent - continents); + int menulen; + int rv; + + if (strcmp(continent->title, "UTC") == 0) + return set_zone_utc(); /* Short cut -- if there's only one country, don't post a menu. */ if (contp->nitems == 1) return (contp->menu[0].fire(&contp->menu[0])); /* It's amazing how much good grammar really matters... */ - if (!isocean) - snprintf(title, sizeof title, "Countries in %s", - continent->title); - else - snprintf(title, sizeof title, "Islands and groups in the %s", - continent->title); + if (!isocean) { + snprintf(title, sizeof(title), "Countries in %s", + continent->title); + snprintf(prompt, sizeof(prompt), "Select a country or region"); + } else { + snprintf(title, sizeof(title), "Islands and groups in the %s", + continent->title); + snprintf(prompt, sizeof(prompt), "Select an island or group"); + } menulen = contp->nitems < 16 ? contp->nitems : 16; - rv = dialog_menu(title, (isocean ? "Select an island or group" - : "Select a country or region"), -1, -1, menulen, - -contp->nitems, contp->menu, 0, &contp->ch, - &contp->sc); + rv = dialog_menu(title, prompt, -1, -1, menulen, -contp->nitems, + contp->menu, 0, &contp->ch, &contp->sc); if (rv == 0) - return DITEM_LEAVE_MENU; - return DITEM_RECREATE; + return (DITEM_LEAVE_MENU); + return (DITEM_RECREATE); } static struct continent * find_continent(const char *name) { - int i; + int i; - for (i = 0; i < NCONTINENTS; i++) { + for (i = 0; i < NCONTINENTS; i++) if (strcmp(name, continent_names[i].name) == 0) - return continent_names[i].continent; - } - return 0; + return (continent_names[i].continent); + return (0); } struct country { - char *name; - char *tlc; - int nzones; - char *filename; /* use iff nzones < 0 */ - struct continent *continent; /* use iff nzones < 0 */ - TAILQ_HEAD(, zone) zones; /* use iff nzones > 0 */ - dialogMenuItem *submenu; /* use iff nzones > 0 */ + char *name; + char *tlc; + int nzones; + char *filename; /* use iff nzones < 0 */ + struct continent *continent; /* use iff nzones < 0 */ + TAILQ_HEAD(, zone) zones; /* use iff nzones > 0 */ + dialogMenuItem *submenu; /* use iff nzones > 0 */ }; struct zone { TAILQ_ENTRY(zone) link; - char *descr; - char *filename; + char *descr; + char *filename; struct continent *continent; }; @@ -162,9 +192,10 @@ struct zone { * of the two-letter variety, so we just size this array to suit. * Beats worrying about dynamic allocation. */ -#define NCOUNTRIES (26*26) +#define NCOUNTRIES (26 * 26) static struct country countries[NCOUNTRIES]; -#define CODE2INT(s) ((s[0] - 'A') * 26 + (s[1] - 'A')) + +#define CODE2INT(s) ((s[0] - 'A') * 26 + (s[1] - 'A')) /* * Read the ISO 3166 country code database in _PATH_ISO3166 @@ -173,21 +204,21 @@ static struct country countries[NCOUNTRI static void read_iso3166_table(void) { - FILE *fp; - char *s, *t, *name; - size_t len; - int lineno; - struct country *cp; + FILE *fp; + struct country *cp; + size_t len; + char *s, *t, *name; + int lineno; - fp = fopen(_PATH_ISO3166, "r"); + fp = fopen(path_iso3166, "r"); if (!fp) - err(1, _PATH_ISO3166); + err(1, "%s", path_iso3166); lineno = 0; while ((s = fgetln(fp, &len)) != 0) { lineno++; if (s[len - 1] != '\n') - errx(1, _PATH_ISO3166 ":%d: invalid format", lineno); + errx(1, "%s:%d: invalid format", path_iso3166, lineno); s[len - 1] = '\0'; if (s[0] == '#' || strspn(s, " \t") == len - 1) continue; @@ -195,26 +226,25 @@ read_iso3166_table(void) /* Isolate the two-letter code. */ t = strsep(&s, "\t"); if (t == 0 || strlen(t) != 2) - errx(1, _PATH_ISO3166 ":%d: invalid format", lineno); + errx(1, "%s:%d: invalid format", path_iso3166, lineno); if (t[0] < 'A' || t[0] > 'Z' || t[1] < 'A' || t[1] > 'Z') - errx(1, _PATH_ISO3166 ":%d: invalid code `%s'", - lineno, t); + errx(1, "%s:%d: invalid code `%s'", path_iso3166, + lineno, t); /* Now skip past the three-letter and numeric codes. */ - name = strsep(&s, "\t"); /* 3-let */ + name = strsep(&s, "\t"); /* 3-let */ if (name == 0 || strlen(name) != 3) - errx(1, _PATH_ISO3166 ":%d: invalid format", lineno); - name = strsep(&s, "\t"); /* numeric */ + errx(1, "%s:%d: invalid format", path_iso3166, lineno); + name = strsep(&s, "\t"); /* numeric */ if (name == 0 || strlen(name) != 3) - errx(1, _PATH_ISO3166 ":%d: invalid format", lineno); + errx(1, "%s:%d: invalid format", path_iso3166, lineno); name = s; cp = &countries[CODE2INT(t)]; if (cp->name) - errx(1, _PATH_ISO3166 - ":%d: country code `%s' multiply defined: %s", - lineno, t, cp->name); + errx(1, "%s:%d: country code `%s' multiply defined: %s", + path_iso3166, lineno, t, cp->name); cp->name = strdup(name); if (cp->name == NULL) errx(1, "malloc failed"); @@ -228,28 +258,28 @@ read_iso3166_table(void) static void add_zone_to_country(int lineno, const char *tlc, const char *descr, - const char *file, struct continent *cont) + const char *file, struct continent *cont) { - struct zone *zp; - struct country *cp; + struct zone *zp; + struct country *cp; if (tlc[0] < 'A' || tlc[0] > 'Z' || tlc[1] < 'A' || tlc[1] > 'Z') - errx(1, _PATH_ZONETAB ":%d: country code `%s' invalid", - lineno, tlc); + errx(1, "%s:%d: country code `%s' invalid", path_zonetab, + lineno, tlc); cp = &countries[CODE2INT(tlc)]; if (cp->name == 0) - errx(1, _PATH_ZONETAB ":%d: country code `%s' unknown", - lineno, tlc); + errx(1, "%s:%d: country code `%s' unknown", path_zonetab, + lineno, tlc); if (descr) { if (cp->nzones < 0) - errx(1, _PATH_ZONETAB - ":%d: conflicting zone definition", lineno); + errx(1, "%s:%d: conflicting zone definition", + path_zonetab, lineno); - zp = malloc(sizeof *zp); + zp = malloc(sizeof(*zp)); if (zp == 0) - errx(1, "malloc(%lu)", (unsigned long)sizeof *zp); + errx(1, "malloc(%zu)", sizeof(*zp)); if (cp->nzones == 0) TAILQ_INIT(&cp->zones); @@ -265,11 +295,11 @@ add_zone_to_country(int lineno, const ch cp->nzones++; } else { if (cp->nzones > 0) - errx(1, _PATH_ZONETAB - ":%d: zone must have description", lineno); + errx(1, "%s:%d: zone must have description", + path_zonetab, lineno); if (cp->nzones < 0) - errx(1, _PATH_ZONETAB - ":%d: zone multiply defined", lineno); + errx(1, "%s:%d: zone multiply defined", + path_zonetab, lineno); cp->nzones = -1; cp->filename = strdup(file); if (cp->filename == NULL) @@ -289,13 +319,13 @@ compare_countries(const void *xa, const const struct country *a = xa, *b = xb; if (a->name == 0 && b->name == 0) - return 0; + return (0); if (a->name == 0 && b->name != 0) - return 1; + return (1); if (b->name == 0) - return -1; + return (-1); - return strcmp(a->name, b->name); + return (strcmp(a->name, b->name)); } /* @@ -305,51 +335,51 @@ compare_countries(const void *xa, const static void sort_countries(void) { - qsort(countries, NCOUNTRIES, sizeof countries[0], compare_countries); + + qsort(countries, NCOUNTRIES, sizeof(countries[0]), compare_countries); } static void read_zones(void) { - FILE *fp; - char *line; - size_t len; - int lineno; - char *tlc, *coord, *file, *descr, *p; - char contbuf[16]; + char contbuf[16]; + FILE *fp; struct continent *cont; + size_t len; + char *line, *tlc, *coord, *file, *descr, *p; + int lineno; - fp = fopen(_PATH_ZONETAB, "r"); + fp = fopen(path_zonetab, "r"); if (!fp) - err(1, _PATH_ZONETAB); + err(1, "%s", path_zonetab); lineno = 0; while ((line = fgetln(fp, &len)) != 0) { lineno++; if (line[len - 1] != '\n') - errx(1, _PATH_ZONETAB ":%d: invalid format", lineno); + errx(1, "%s:%d: invalid format", path_zonetab, lineno); line[len - 1] = '\0'; if (line[0] == '#') continue; tlc = strsep(&line, "\t"); if (strlen(tlc) != 2) - errx(1, _PATH_ZONETAB ":%d: invalid country code `%s'", - lineno, tlc); - coord = strsep(&line, "\t"); + errx(1, "%s:%d: invalid country code `%s'", + path_zonetab, lineno, tlc); + coord = strsep(&line, "\t"); /* Unused */ file = strsep(&line, "\t"); p = strchr(file, '/'); if (p == 0) - errx(1, _PATH_ZONETAB ":%d: invalid zone name `%s'", - lineno, file); + errx(1, "%s:%d: invalid zone name `%s'", path_zonetab, + lineno, file); contbuf[0] = '\0'; strncat(contbuf, file, p - file); cont = find_continent(contbuf); if (!cont) - errx(1, _PATH_ZONETAB ":%d: invalid region `%s'", - lineno, contbuf); + errx(1, "%s:%d: invalid region `%s'", path_zonetab, + lineno, contbuf); - descr = (line && *line) ? line : 0; + descr = (line != NULL && *line != '\0') ? line : NULL; add_zone_to_country(lineno, tlc, descr, file, cont); } @@ -359,11 +389,11 @@ read_zones(void) static void make_menus(void) { - struct country *cp; - struct zone *zp, *zp2; + struct country *cp; + struct zone *zp, *zp2; struct continent *cont; - dialogMenuItem *dmi; - int i; + dialogMenuItem *dmi; + int i; /* * First, count up all the countries in each continent/ocean. @@ -380,8 +410,8 @@ make_menus(void) TAILQ_FOREACH(zp, &cp->zones, link) { cont = zp->continent; for (zp2 = TAILQ_FIRST(&cp->zones); - zp2->continent != cont; - zp2 = TAILQ_NEXT(zp2, link)) + zp2->continent != cont; + zp2 = TAILQ_NEXT(zp2, link)) ; if (zp2 == zp) zp->continent->nitems++; @@ -390,17 +420,22 @@ make_menus(void) } /* - * Now allocate memory for the country menus. We set - * nitems back to zero so that we can use it for counting - * again when we actually build the menus. + * Now allocate memory for the country menus and initialize + * continent menus. We set nitems back to zero so that we can + * use it for counting again when we actually build the menus. */ + memset(continents, 0, sizeof(continents)); for (i = 0; i < NCONTINENTS; i++) { continent_names[i].continent->menu = - malloc(sizeof(dialogMenuItem) * - continent_names[i].continent->nitems); + malloc(sizeof(dialogMenuItem) * + continent_names[i].continent->nitems); if (continent_names[i].continent->menu == 0) errx(1, "malloc for continent menu"); continent_names[i].continent->nitems = 0; + continents[i].prompt = continent_items[i].prompt; + continents[i].title = continent_items[i].title; + continents[i].fire = continent_country_menu; + continents[i].data = continent_names[i].continent; } /* @@ -413,25 +448,23 @@ make_menus(void) continue; if (cp->nzones < 0) { dmi = &cp->continent->menu[cp->continent->nitems]; - memset(dmi, 0, sizeof *dmi); - asprintf(&dmi->prompt, "%d", - ++cp->continent->nitems); + memset(dmi, 0, sizeof(*dmi)); + asprintf(&dmi->prompt, "%d", ++cp->continent->nitems); dmi->title = cp->name; dmi->checked = 0; dmi->fire = set_zone_whole_country; dmi->selected = 0; dmi->data = cp; } else { - cp->submenu = malloc(cp->nzones * sizeof *dmi); + cp->submenu = malloc(cp->nzones * sizeof(*dmi)); if (cp->submenu == 0) errx(1, "malloc for submenu"); cp->nzones = 0; TAILQ_FOREACH(zp, &cp->zones, link) { cont = zp->continent; dmi = &cp->submenu[cp->nzones]; - memset(dmi, 0, sizeof *dmi); - asprintf(&dmi->prompt, "%d", - ++cp->nzones); + memset(dmi, 0, sizeof(*dmi)); + asprintf(&dmi->prompt, "%d", ++cp->nzones); dmi->title = zp->descr; dmi->checked = 0; dmi->fire = set_zone_multi; @@ -439,14 +472,14 @@ make_menus(void) dmi->data = zp; for (zp2 = TAILQ_FIRST(&cp->zones); - zp2->continent != cont; - zp2 = TAILQ_NEXT(zp2, link)) + zp2->continent != cont; + zp2 = TAILQ_NEXT(zp2, link)) ; if (zp2 != zp) continue; dmi = &cont->menu[cont->nitems]; - memset(dmi, 0, sizeof *dmi); + memset(dmi, 0, sizeof(*dmi)); asprintf(&dmi->prompt, "%d", ++cont->nitems); dmi->title = cp->name; dmi->checked = 0; @@ -461,202 +494,288 @@ make_menus(void) static int set_zone_menu(dialogMenuItem *dmi) { - int rv; - char buf[256]; - struct country *cp = dmi->data; - int menulen; - - snprintf(buf, sizeof buf, "%s Time Zones", cp->name); + char title[64], prompt[64]; + struct country *cp = dmi->data; + int menulen; + int rv; + + snprintf(title, sizeof(title), "%s Time Zones", cp->name); + snprintf(prompt, sizeof(prompt), + "Select a zone which observes the same time as your locality."); menulen = cp->nzones < 16 ? cp->nzones : 16; - rv = dialog_menu(buf, "Select a zone which observes the same time as " - "your locality.", -1, -1, menulen, -cp->nzones, - cp->submenu, 0, 0, 0); + rv = dialog_menu(title, prompt, -1, -1, menulen, -cp->nzones, + cp->submenu, 0, 0, 0); if (rv != 0) - return DITEM_RECREATE; - return DITEM_LEAVE_MENU; + return (DITEM_RECREATE); + return (DITEM_LEAVE_MENU); +} + +int +set_zone_utc(void) +{ + if (!confirm_zone(NULL)) + return (DITEM_FAILURE | DITEM_RECREATE); + + return (install_zoneinfo_file(NULL)); } static int -install_zone_file(const char *filename) +install_zoneinfo_file(const char *zoneinfo_file) { - struct stat sb; - int fd1, fd2; - int copymode; - char *msg; - ssize_t len; - char buf[1024]; + char buf[1024]; + char title[64], prompt[64]; + struct stat sb; + ssize_t len; + int fd1, fd2, copymode; - if (lstat(_PATH_LOCALTIME, &sb) < 0) + if (lstat(path_localtime, &sb) < 0) { /* Nothing there yet... */ copymode = 1; - else if(S_ISLNK(sb.st_mode)) + } else if (S_ISLNK(sb.st_mode)) copymode = 0; else copymode = 1; #ifdef VERBOSE if (copymode) - asprintf(&msg, "Copying %s to " _PATH_LOCALTIME, filename); + snprintf(prompt, sizeof(prompt), + "Copying %s to %s", zoneinfo_file, path_localtime); else - asprintf(&msg, "Creating symbolic link " _PATH_LOCALTIME - " to %s", filename); - - dialog_notify(msg); - free(msg); + snprintf(prompt, sizeof(prompt), + "Creating symbolic link %s to %s", + path_localtime, + zoneinfo_file == NULL ? "(UTC)" : zoneinfo_file); + if (usedialog) + dialog_notify(prompt); + else + fprintf(stderr, "%s\n", prompt); #endif if (reallydoit) { + if (zoneinfo_file == NULL) { + if (unlink(path_localtime) < 0 && errno != ENOENT) { + snprintf(title, sizeof(title), "Error"); + snprintf(prompt, sizeof(prompt), + "Could not delete %s: %s", path_localtime, + strerror(errno)); + if (usedialog) + dialog_mesgbox(title, prompt, 8, 72); + else + fprintf(stderr, "%s\n", prompt); + + return (DITEM_FAILURE | DITEM_RECREATE); + } + if (unlink(path_db) < 0 && errno != ENOENT) { + snprintf(title, sizeof(title), "Error"); + snprintf(prompt, sizeof(prompt), + "Could not delete %s: %s", path_db, + strerror(errno)); + if (usedialog) + dialog_mesgbox(title, prompt, 8, 72); + else + fprintf(stderr, "%s\n", prompt); + + return (DITEM_FAILURE | DITEM_RECREATE); + } + return (DITEM_LEAVE_MENU); + } + if (copymode) { - fd1 = open(filename, O_RDONLY, 0); + fd1 = open(zoneinfo_file, O_RDONLY, 0); if (fd1 < 0) { - asprintf(&msg, "Could not open %s: %s", - filename, strerror(errno)); - dialog_mesgbox("Error", msg, 8, 72); - free(msg); - return DITEM_FAILURE | DITEM_RECREATE; + snprintf(title, sizeof(title), "Error"); + snprintf(prompt, sizeof(prompt), + "Could not open %s: %s", zoneinfo_file, + strerror(errno)); + if (usedialog) + dialog_mesgbox(title, prompt, 8, 72); + else + fprintf(stderr, "%s\n", prompt); + return (DITEM_FAILURE | DITEM_RECREATE); } - unlink(_PATH_LOCALTIME); - fd2 = open(_PATH_LOCALTIME, - O_CREAT|O_EXCL|O_WRONLY, - S_IRUSR|S_IRGRP|S_IROTH); + unlink(path_localtime); + fd2 = open(path_localtime, O_CREAT | O_EXCL | O_WRONLY, + S_IRUSR | S_IRGRP | S_IROTH); if (fd2 < 0) { - asprintf(&msg, "Could not open " - _PATH_LOCALTIME ": %s", - strerror(errno)); - dialog_mesgbox("Error", msg, 8, 72); - free(msg); - return DITEM_FAILURE | DITEM_RECREATE; + snprintf(title, sizeof(title), "Error"); + snprintf(prompt, sizeof(prompt), + "Could not open %s: %s", + path_localtime, strerror(errno)); + if (usedialog) + dialog_mesgbox(title, prompt, 8, 72); + else + fprintf(stderr, "%s\n", prompt); + return (DITEM_FAILURE | DITEM_RECREATE); } - while ((len = read(fd1, buf, sizeof buf)) > 0) - len = write(fd2, buf, len); + while ((len = read(fd1, buf, sizeof(buf))) > 0) + if ((len = write(fd2, buf, len)) < 0) + break; if (len == -1) { - asprintf(&msg, "Error copying %s to " - _PATH_LOCALTIME ": %s", - filename, strerror(errno)); - dialog_mesgbox("Error", msg, 8, 72); - free(msg); + snprintf(title, sizeof(title), "Error"); + snprintf(prompt, sizeof(prompt), + "Error copying %s to %s %s", zoneinfo_file, + path_localtime, strerror(errno)); + if (usedialog) + dialog_mesgbox(title, prompt, 8, 72); + else + fprintf(stderr, "%s\n", prompt); /* Better to leave none than a corrupt one. */ - unlink(_PATH_LOCALTIME); - return DITEM_FAILURE | DITEM_RECREATE; + unlink(path_localtime); + return (DITEM_FAILURE | DITEM_RECREATE); } close(fd1); close(fd2); } else { - if (access(filename, R_OK) != 0) { - asprintf(&msg, "Cannot access %s: %s", - filename, strerror(errno)); - dialog_mesgbox("Error", msg, 8, 72); - free(msg); - return DITEM_FAILURE | DITEM_RECREATE; - } - unlink(_PATH_LOCALTIME); - if (symlink(filename, _PATH_LOCALTIME) < 0) { - asprintf(&msg, "Cannot create symbolic link " - _PATH_LOCALTIME " to %s: %s", - filename, strerror(errno)); - dialog_mesgbox("Error", msg, 8, 72); - free(msg); - return DITEM_FAILURE | DITEM_RECREATE; + if (access(zoneinfo_file, R_OK) != 0) { + snprintf(title, sizeof(title), "Error"); + snprintf(prompt, sizeof(prompt), + "Cannot access %s: %s", zoneinfo_file, + strerror(errno)); + if (usedialog) + dialog_mesgbox(title, prompt, 8, 72); + else + fprintf(stderr, "%s\n", prompt); + return (DITEM_FAILURE | DITEM_RECREATE); + } + unlink(path_localtime); + if (symlink(zoneinfo_file, path_localtime) < 0) { + snprintf(title, sizeof(title), "Error"); + snprintf(prompt, sizeof(prompt), + "Cannot create symbolic link %s to %s: %s", + path_localtime, zoneinfo_file, + strerror(errno)); + if (usedialog) + dialog_mesgbox(title, prompt, 8, 72); + else + fprintf(stderr, "%s\n", prompt); + return (DITEM_FAILURE | DITEM_RECREATE); } } } #ifdef VERBOSE + snprintf(title, sizeof(title), "Done"); if (copymode) - asprintf(&msg, "Copied timezone file from %s to " - _PATH_LOCALTIME, filename); + snprintf(prompt, sizeof(prompt), + "Copied timezone file from %s to %s", zoneinfo_file, + path_localtime); else - asprintf(&msg, "Created symbolic link from " _PATH_LOCALTIME - " to %s", filename); - - dialog_mesgbox("Done", msg, 8, 72); - free(msg); + snprintf(prompt, sizeof(prompt), + "Created symbolic link from %s to %s", zoneinfo_file, + path_localtime); + if (usedialog) + dialog_mesgbox(title, prompt, 8, 72); + else + fprintf(stderr, "%s\n", prompt); #endif - return DITEM_LEAVE_MENU; + + return (DITEM_LEAVE_MENU); +} + +static int +install_zoneinfo(const char *zoneinfo) +{ + int rv; + FILE *f; + char path_zoneinfo_file[MAXPATHLEN]; + + sprintf(path_zoneinfo_file, "%s/%s", path_zoneinfo, zoneinfo); + rv = install_zoneinfo_file(path_zoneinfo_file); + + /* Save knowledge for later */ + if ((f = fopen(path_db, "w")) != NULL) { + fprintf(f, "%s\n", zoneinfo); + fclose(f); + } + + return (rv); } static int confirm_zone(const char *filename) { - char *msg; - struct tm *tm; - time_t t = time(0); - int rv; + char title[64], prompt[64]; + time_t t = time(0); + struct tm *tm; + int rv; - setenv("TZ", filename, 1); + setenv("TZ", filename == NULL ? "" : filename, 1); tzset(); tm = localtime(&t); - asprintf(&msg, "Does the abbreviation `%s' look reasonable?", - tm->tm_zone); - rv = !dialog_yesno("Confirmation", msg, 5, 72); - free(msg); - return rv; + snprintf(title, sizeof(title), "Confirmation"); + snprintf(prompt, sizeof(prompt), + "Does the abbreviation `%s' look reasonable?", tm->tm_zone); + rv = !dialog_yesno(title, prompt, 5, 72); + return (rv); } static int set_zone_multi(dialogMenuItem *dmi) { - char *fn; - struct zone *zp = dmi->data; - int rv; + struct zone *zp = dmi->data; + int rv; if (!confirm_zone(zp->filename)) - return DITEM_FAILURE | DITEM_RECREATE; + return (DITEM_FAILURE | DITEM_RECREATE); - asprintf(&fn, "%s/%s", _PATH_ZONEINFO, zp->filename); - rv = install_zone_file(fn); - free(fn); - return rv; + rv = install_zoneinfo(zp->filename); + return (rv); } static int set_zone_whole_country(dialogMenuItem *dmi) { - char *fn; - struct country *cp = dmi->data; - int rv; + struct country *cp = dmi->data; + int rv; if (!confirm_zone(cp->filename)) - return DITEM_FAILURE | DITEM_RECREATE; + return (DITEM_FAILURE | DITEM_RECREATE); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***