/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <errno.h>
#include "smbfs_lib.h"
#include <netsmb/libsmbfs.h>
typedef enum {
SMBFS_PWD_UID = 0,
static int smbfs_pwd_lock(void);
static int smbfs_pwd_unlock(void);
/*
* buffer structure used by smbfs_pwd_fgetent/smbfs_pwd_fputent
*/
typedef struct smbfs_pwbuf {
/*
* Loads the smbfspasswd entries into the password keychain.
*/
int
smbfs_pwd_loadkeychain(void)
{
int err;
err = smbfs_pwd_lock();
if (err != SMB_PWE_SUCCESS)
return (err);
(void) smbfs_pwd_unlock();
return (err);
}
if (err != 0) {
(void) smbfs_pwd_unlock();
return (err);
}
}
(void) smbfs_pwd_unlock();
return (0);
}
/*
* Updates the password hashes of the given password info if the entry already
* exists, otherwise it'll add an entry with given password information.
*
* The entries are added to the file based on the uid in ascending order.
*/
int
{
int tempfd;
err = smbfs_pwd_lock();
if (err != SMB_PWE_SUCCESS)
return (err);
goto passwd_exit;
}
if ((tempfd =
goto passwd_exit;
}
goto passwd_exit;
}
(void) unlink(SMBFS_PASSTEMP);
goto passwd_exit;
}
/*
* copy old password entries to temporary file while replacing
* the entry that matches uid, domain, and user
*/
break;
if ((smb_strcasecmp(
break;
}
if (err != SMB_PWE_SUCCESS) {
goto passwd_exit;
}
}
if (err != SMB_PWE_SUCCESS) {
goto passwd_exit;
}
if (doinsert) {
/*
* a new entry was inserted before the old entry
* so now copy the old entry to the temporary
* file
*/
if (err != SMB_PWE_SUCCESS) {
goto passwd_exit;
}
}
/*
* copy any remaining old password entries to temporary file
*/
if (err != SMB_PWE_SUCCESS) {
goto passwd_exit;
}
}
goto passwd_exit; /* Don't trust the temporary file */
}
/* Rename temp to passwd */
(void) unlink(SMBFS_PASSTEMP);
goto passwd_exit;
}
(void) unlink(SMBFS_PASSTEMP);
goto passwd_exit;
}
(void) unlink(SMBFS_PASSTEMP);
goto passwd_exit;
}
(void) smbfs_pwd_unlock();
return (err);
}
int
{
int tempfd;
err = smbfs_pwd_lock();
if (err != SMB_PWE_SUCCESS)
return (err);
goto passwd_exit;
}
if ((tempfd =
goto passwd_exit;
}
goto passwd_exit;
}
(void) unlink(SMBFS_PASSTEMP);
goto passwd_exit;
}
/*
* copy password entries to temporary file while skipping
* the entry that matches uid, domain, and user
*/
if (delete_all)
continue;
if ((smb_strcasecmp(
continue;
}
if (err != SMB_PWE_SUCCESS) {
goto passwd_exit;
}
}
goto passwd_exit; /* Don't trust the temporary file */
}
/* Rename temp to passwd */
(void) unlink(SMBFS_PASSTEMP);
goto passwd_exit;
}
(void) unlink(SMBFS_PASSTEMP);
goto passwd_exit;
}
(void) unlink(SMBFS_PASSTEMP);
goto passwd_exit;
}
(void) smbfs_pwd_unlock();
return (err);
}
/*
* Parse the buffer in the passed pwbuf and fill in the
* smbfs password structure to point to the parsed information.
* The entry format is:
*
* <user-id>:<domain>:<user-name>:<LM hash>:<NTLM hash>
*
* Returns a pointer to the passed pwbuf structure on success,
* otherwise returns NULL.
*/
static smbfs_pwbuf_t *
{
char *pwentry;
return (NULL);
(void) trim_whitespace(pwentry);
for (i = 0; i < SMBFS_PWD_NARG; ++i) {
return (NULL);
}
return (NULL);
if (lm_len == SMBAUTH_HEXHASH_SZ) {
} else if (lm_len != 0) {
return (NULL);
}
if (nt_len == SMBAUTH_HEXHASH_SZ) {
} else if (nt_len != 0) {
return (NULL);
}
return (pwbuf);
}
/*
* domain, and Id to the smbfspasswd file.
*/
static int
{
int rc;
if (rc <= 0)
return (SMB_PWE_WRITE_FAILED);
return (SMB_PWE_SUCCESS);
}
/*
* A wrapper around smb_file_lock() which locks smbfs password
* file so that only one thread at a time is operational.
*/
static int
smbfs_pwd_lock(void)
{
int res;
switch (errno) {
case EINTR:
res = SMB_PWE_BUSY;
break;
case EACCES:
break;
case 0:
break;
}
} else
return (res);
}
/*
* A wrapper around smb_file_unlock() which unlocks
* smbfs password file.
*/
static int
smbfs_pwd_unlock(void)
{
if (smb_file_unlock(&lockinfo))
return (SMB_PWE_SYSTEM_ERROR);
return (SMB_PWE_SUCCESS);
}