smb_pwdutil.c revision da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The contents of this file are subject to the terms of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common Development and Distribution License (the "License").
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You may not use this file except in compliance with the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * or http://www.opensolaris.org/os/licensing.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * When distributing Covered Code, include this CDDL HEADER in each
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If applicable, add the following below this CDDL HEADER, with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fields enclosed by brackets "[]" replaced with your own identifying
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * information: Portions Copyright [yyyy] [name of copyright owner]
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use is subject to license terms.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#pragma ident "%Z%%M% %I% %E% SMI"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <stdlib.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <unistd.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <limits.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <strings.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <synch.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <errno.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <sys/types.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <sys/stat.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <fcntl.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <thread.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <pwd.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/libsmb.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#define SMB_PASSWD "/var/smb/smbpasswd"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#define SMB_OPASSWD "/var/smb/osmbpasswd"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#define SMB_PASSTEMP "/var/smb/ptmp"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#define SMB_PASSLCK "/var/smb/.pwd.lock"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#define SMB_PWD_DISABLE "*DIS*"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#define SMB_PWD_BUFSIZE 256
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#define S_WAITTIME 15
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwtypedef enum {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_PWD_NAME = 0,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_PWD_UID,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_PWD_LMHASH,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_PWD_NTHASH,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_PWD_NARG
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw} smb_pwdarg_t;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic struct flock flock = {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0, /* l_type */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0, /* l_whence */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0, /* l_start */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0, /* l_len */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0, /* l_sysid */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0 /* l_pid */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw };
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic pid_t lck_pid = 0; /* process's pid at last lock */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic thread_t lck_tid = 0; /* thread that holds the lock */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int fildes = -1;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic mutex_t lck_lock = DEFAULTMUTEX;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwtypedef struct smb_pwbuf {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *pw_name;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_passwd_t *pw_pwd;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw} smb_pwbuf_t;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int smb_pwd_lock(void);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int smb_pwd_unlock(void);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int smb_pwd_flck(void);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int smb_pwd_fulck(void);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic smb_pwbuf_t *smb_pwd_fgetent(FILE *, smb_pwbuf_t *, char *, size_t);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int smb_pwd_fputent(FILE *, smb_pwbuf_t *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int smb_pwd_chgpwent(smb_passwd_t *, const char *, int);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int smb_pwd_update(const char *, const char *, int);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_pwd_get
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns a smb password structure for the given user name.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smbpw is a pointer to a buffer allocated by the caller.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns NULL upon failure.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_passwd_t *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_pwd_getpasswd(const char *name, smb_passwd_t *smbpw)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char buf[SMB_PWD_BUFSIZE];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw boolean_t found = B_FALSE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_pwbuf_t pwbuf;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int err;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw FILE *fp;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = smb_pwd_lock();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (err != SMB_PWE_SUCCESS)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((fp = fopen(SMB_PASSWD, "rF")) == NULL) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) smb_pwd_unlock();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw pwbuf.pw_name = NULL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw pwbuf.pw_pwd = smbpw;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (smb_pwd_fgetent(fp, &pwbuf, buf, sizeof (buf)) != NULL) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (strcmp(name, pwbuf.pw_name) == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((smbpw->pw_flags & (SMB_PWF_LM | SMB_PWF_NT)))
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw found = B_TRUE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) fclose(fp);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) smb_pwd_unlock();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!found) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw bzero(smbpw, sizeof (smb_passwd_t));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (smbpw);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_pwd_set
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Update/add the given user to the smbpasswd file.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_pwd_setpasswd(const char *name, const char *password)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (smb_pwd_update(name, password, 0));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_pwd_setcntl
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Change the account state. This can be making the account
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * disable/enable or removing its LM hash.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_pwd_setcntl(const char *name, int control)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (control == 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (SMB_PWE_SUCCESS);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (smb_pwd_update(name, NULL, control));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_pwd_update(const char *name, const char *password, int control)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct stat64 stbuf;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw FILE *src, *dst;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int tempfd;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char buf[SMB_PWD_BUFSIZE];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int err = SMB_PWE_SUCCESS;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_pwbuf_t pwbuf;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_passwd_t smbpw;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw boolean_t newent = B_TRUE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw boolean_t user_disable = B_FALSE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char uxbuf[1024];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct passwd uxpw;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int lm_level;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *lm_str;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = smb_pwd_lock();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (err != SMB_PWE_SUCCESS)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (err);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (stat64(SMB_PASSWD, &stbuf) < 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = SMB_PWE_STAT_FAILED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto passwd_exit;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((tempfd = open(SMB_PASSTEMP, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = SMB_PWE_OPEN_FAILED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto passwd_exit;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((dst = fdopen(tempfd, "wF")) == NULL) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = SMB_PWE_OPEN_FAILED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto passwd_exit;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((src = fopen(SMB_PASSWD, "rF")) == NULL) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = SMB_PWE_OPEN_FAILED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) fclose(dst);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) unlink(SMB_PASSTEMP);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto passwd_exit;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lm_str = smb_config_getenv(SMB_CI_LM_LEVEL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (lm_str) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lm_level = strtoul(lm_str, 0, 10);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw free(lm_str);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lm_level = 4;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (lm_level >= 4)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw control |= SMB_PWC_NOLM;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * copy old password entries to temporary file while replacing
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the entry that matches "name"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw pwbuf.pw_name = NULL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw pwbuf.pw_pwd = &smbpw;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (smb_pwd_fgetent(src, &pwbuf, buf, sizeof (buf)) != NULL) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (strcmp(pwbuf.pw_name, name) == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = smb_pwd_chgpwent(&smbpw, password, control);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (err == SMB_PWE_USER_DISABLE)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw user_disable = B_TRUE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = smb_pwd_fputent(dst, &pwbuf);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw newent = B_FALSE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = smb_pwd_fputent(dst, &pwbuf);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (err != SMB_PWE_SUCCESS) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) fclose(src);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) fclose(dst);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto passwd_exit;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (newent) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (getpwnam_r(name, &uxpw, uxbuf, sizeof (uxbuf))) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw pwbuf.pw_name = uxpw.pw_name;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smbpw.pw_flags = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smbpw.pw_uid = uxpw.pw_uid;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) smb_pwd_chgpwent(&smbpw, password, control);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = smb_pwd_fputent(dst, &pwbuf);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = SMB_PWE_USER_UNKNOWN;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (err != SMB_PWE_SUCCESS) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) fclose(src);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) fclose(dst);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto passwd_exit;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) fclose(src);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (fclose(dst) != 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = SMB_PWE_CLOSE_FAILED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto passwd_exit; /* Don't trust the temporary file */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Rename temp to passwd */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (unlink(SMB_OPASSWD) && access(SMB_OPASSWD, 0) == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = SMB_PWE_UPDATE_FAILED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) unlink(SMB_PASSTEMP);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto passwd_exit;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (link(SMB_PASSWD, SMB_OPASSWD) == -1) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = SMB_PWE_UPDATE_FAILED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) unlink(SMB_PASSTEMP);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto passwd_exit;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rename(SMB_PASSTEMP, SMB_PASSWD) == -1) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = SMB_PWE_UPDATE_FAILED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) unlink(SMB_PASSTEMP);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto passwd_exit;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) chmod(SMB_PASSWD, 0400);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwpasswd_exit:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) smb_pwd_unlock();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((err == SMB_PWE_SUCCESS) && user_disable)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = SMB_PWE_USER_DISABLE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (err);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_getpwent
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Parse the buffer in the passed pwbuf and fill in the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb password structure to point to the parsed information.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The entry format is:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * <user-name>:<user-id>:<LM hash>:<NTLM hash>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns a pointer to the password structure on success,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * otherwise returns NULL.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic smb_pwbuf_t *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_pwd_fgetent(FILE *fp, smb_pwbuf_t *pwbuf, char *buf, size_t bufsize)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *argv[SMB_PWD_NARG];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_passwd_t *pw;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_pwdarg_t i;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int lm_len, nt_len;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (fgets(buf, bufsize, fp) == NULL)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) trim_whitespace(buf);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw for (i = 0; i < SMB_PWD_NARG; ++i) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((argv[i] = strsep((char **)&buf, ":")) == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((*argv[SMB_PWD_NAME] == '\0') || (*argv[SMB_PWD_UID] == '\0'))
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw pwbuf->pw_name = argv[SMB_PWD_NAME];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw pw = pwbuf->pw_pwd;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw bzero(pw, sizeof (smb_passwd_t));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw pw->pw_uid = strtoul(argv[SMB_PWD_UID], 0, 10);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (strcmp(argv[SMB_PWD_LMHASH], SMB_PWD_DISABLE) == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw pw->pw_flags |= SMB_PWF_DISABLE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) strcpy((char *)pw->pw_lmhash, SMB_PWD_DISABLE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) strcpy((char *)pw->pw_nthash, SMB_PWD_DISABLE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (pwbuf);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lm_len = strlen(argv[SMB_PWD_LMHASH]);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (lm_len == SMBAUTH_HEXHASH_SZ) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) hextobin(argv[SMB_PWD_LMHASH], SMBAUTH_HEXHASH_SZ,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (char *)pw->pw_lmhash, SMBAUTH_HASH_SZ);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw pw->pw_flags |= SMB_PWF_LM;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else if (lm_len != 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw nt_len = strlen(argv[SMB_PWD_NTHASH]);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (nt_len == SMBAUTH_HEXHASH_SZ) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) hextobin(argv[SMB_PWD_NTHASH], SMBAUTH_HEXHASH_SZ,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (char *)pw->pw_nthash, SMBAUTH_HASH_SZ);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw pw->pw_flags |= SMB_PWF_NT;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else if (nt_len != 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (pwbuf);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_pwd_chgpwent(smb_passwd_t *smbpw, const char *password, int control)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (control & SMB_PWC_DISABLE) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smbpw->pw_flags |= SMB_PWF_DISABLE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) strcpy((char *)smbpw->pw_lmhash, SMB_PWD_DISABLE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) strcpy((char *)smbpw->pw_nthash, SMB_PWD_DISABLE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smbpw->pw_flags &= ~(SMB_PWF_LM | SMB_PWF_NT);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (SMB_PWE_SUCCESS);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else if ((control & SMB_PWC_ENABLE) &&
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (smbpw->pw_flags & SMB_PWF_DISABLE)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *smbpw->pw_lmhash = '\0';
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *smbpw->pw_nthash = '\0';
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smbpw->pw_flags &= ~(SMB_PWF_LM | SMB_PWF_NT);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (SMB_PWE_SUCCESS);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* No password update if account is disabled */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (smbpw->pw_flags & SMB_PWF_DISABLE)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (SMB_PWE_USER_DISABLE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (control & SMB_PWC_NOLM) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smbpw->pw_flags &= ~SMB_PWF_LM;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *smbpw->pw_lmhash = '\0';
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smbpw->pw_flags |= SMB_PWF_LM;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) smb_auth_lm_hash((char *)password, smbpw->pw_lmhash);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smbpw->pw_flags |= SMB_PWF_NT;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) smb_auth_ntlm_hash((char *)password, smbpw->pw_nthash);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (SMB_PWE_SUCCESS);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_putpwent
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Creates LM and NTLM hash from the given plain text password
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and write them along with user's name and Id to the smbpasswd
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_pwd_fputent(FILE *fp, smb_pwbuf_t *pwbuf)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_passwd_t *pw = pwbuf->pw_pwd;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char hex_nthash[SMBAUTH_HEXHASH_SZ+1];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char hex_lmhash[SMBAUTH_HEXHASH_SZ+1];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((pw->pw_flags & SMB_PWF_LM) == SMB_PWF_LM) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) bintohex((char *)pw->pw_lmhash, SMBAUTH_HASH_SZ,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw hex_lmhash, SMBAUTH_HEXHASH_SZ);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw hex_lmhash[SMBAUTH_HEXHASH_SZ] = '\0';
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) strcpy(hex_lmhash, (char *)pw->pw_lmhash);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((pw->pw_flags & SMB_PWF_NT) == SMB_PWF_NT) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) bintohex((char *)pw->pw_nthash, SMBAUTH_HASH_SZ,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw hex_nthash, SMBAUTH_HEXHASH_SZ);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw hex_nthash[SMBAUTH_HEXHASH_SZ] = '\0';
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) strcpy(hex_nthash, (char *)pw->pw_nthash);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = fprintf(fp, "%s:%d:%s:%s\n", pwbuf->pw_name, pw->pw_uid,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw hex_lmhash, hex_nthash);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc <= 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (SMB_PWE_WRITE_FAILED);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (SMB_PWE_SUCCESS);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_pwd_lock(void)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int res;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (smb_pwd_flck()) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (errno) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case EINTR:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw res = SMB_PWE_BUSY;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case EACCES:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw res = SMB_PWE_DENIED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case 0:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw res = SMB_PWE_SUCCESS;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw res = SMB_PWE_SUCCESS;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (res);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_pwd_unlock(void)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (smb_pwd_fulck())
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (SMB_PWE_SYSTEM_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (SMB_PWE_SUCCESS);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_pwd_flck(void)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int seconds = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) mutex_lock(&lck_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw for (;;) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (lck_pid != 0 && lck_pid != getpid()) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* somebody forked */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lck_pid = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lck_tid = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (lck_tid == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((fildes = creat(SMB_PASSLCK, 0600)) == -1)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw flock.l_type = F_WRLCK;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (fcntl(fildes, F_SETLK, &flock) != -1) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lck_pid = getpid();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lck_tid = thr_self();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) mutex_unlock(&lck_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) close(fildes);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw fildes = -1;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (seconds++ >= S_WAITTIME) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * For compatibility with the past, pretend
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * that we were interrupted by SIGALRM.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw errno = EINTR;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) mutex_unlock(&lck_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) sleep(1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) mutex_lock(&lck_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) mutex_unlock(&lck_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (-1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_pwd_fulck(void)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) mutex_lock(&lck_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (lck_tid == thr_self() && fildes >= 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw flock.l_type = F_UNLCK;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) fcntl(fildes, F_SETLK, &flock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) close(fildes);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw fildes = -1;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lck_pid = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lck_tid = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) mutex_unlock(&lck_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) mutex_unlock(&lck_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (-1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}