smb_pwdutil.c revision 7b59d02d2a384be9a08087b14defadd214b3c1dd
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
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 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
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 * CDDL HEADER END
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use is subject to license terms.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#pragma ident "%Z%%M% %I% %E% SMI"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwtypedef enum {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0, /* l_type */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0, /* l_whence */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0, /* l_start */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0, /* l_len */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0, /* l_sysid */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0 /* l_pid */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic pid_t lck_pid = 0; /* process's pid at last lock */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic thread_t lck_tid = 0; /* thread that holds the lock */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwtypedef struct smb_pwbuf {
7b59d02d2a384be9a08087b14defadd214b3c1ddjbstatic struct {
7b59d02d2a384be9a08087b14defadd214b3c1ddjb int (*smb_pwd_setpasswd)(const char *name, const char *password);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int smb_pwd_lock(void);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int smb_pwd_unlock(void);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int smb_pwd_flck(void);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int smb_pwd_fulck(void);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic smb_pwbuf_t *smb_pwd_fgetent(FILE *, smb_pwbuf_t *, char *, size_t);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int smb_pwd_chgpwent(smb_passwd_t *, const char *, int);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int smb_pwd_update(const char *, const char *, int);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb smb_pwd_hdl = dlopen(SMB_LIB_ALT, RTLD_NOW | RTLD_LOCAL);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return; /* interposition library not found */
7b59d02d2a384be9a08087b14defadd214b3c1ddjb (smb_passwd_t *(*)())dlsym(smb_pwd_hdl, "smb_pwd_getpasswd");
7b59d02d2a384be9a08087b14defadd214b3c1ddjb /* If error or function(s) are missing, use original lib */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_pwd_get
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns a smb password structure for the given user name.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smbpw is a pointer to a buffer allocated by the caller.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns NULL upon failure.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (smb_pwd_fgetent(fp, &pwbuf, buf, sizeof (buf)) != NULL) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_pwd_set
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Update/add the given user to the smbpasswd file.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_pwd_setpasswd(const char *name, const char *password)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_pwd_setcntl
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Change the account state. This can be making the account
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * disable/enable or removing its LM hash.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_pwd_update(const char *name, const char *password, int control)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((tempfd = open(SMB_PASSTEMP, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as if (smb_config_getnum(SMB_CI_LM_LEVEL, &lm_level) != SMBD_SMF_OK)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * copy old password entries to temporary file while replacing
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the entry that matches "name"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (smb_pwd_fgetent(src, &pwbuf, buf, sizeof (buf)) != NULL) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Rename temp to passwd */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (unlink(SMB_OPASSWD) && access(SMB_OPASSWD, 0) == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_getpwent
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 * <user-name>:<user-id>:<LM hash>:<NTLM hash>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns a pointer to the password structure on success,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * otherwise returns NULL.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_pwd_fgetent(FILE *fp, smb_pwbuf_t *pwbuf, char *buf, size_t bufsize)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw for (i = 0; i < SMB_PWD_NARG; ++i) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((*argv[SMB_PWD_NAME] == '\0') || (*argv[SMB_PWD_UID] == '\0'))
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (strcmp(argv[SMB_PWD_LMHASH], SMB_PWD_DISABLE) == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) hextobin(argv[SMB_PWD_LMHASH], SMBAUTH_HEXHASH_SZ,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else if (lm_len != 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) hextobin(argv[SMB_PWD_NTHASH], SMBAUTH_HEXHASH_SZ,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else if (nt_len != 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_pwd_chgpwent(smb_passwd_t *smbpw, const char *password, int control)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) strcpy((char *)smbpw->pw_lmhash, SMB_PWD_DISABLE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) strcpy((char *)smbpw->pw_nthash, SMB_PWD_DISABLE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* No password update if account is disabled */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) smb_auth_lm_hash((char *)password, smbpw->pw_lmhash);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) smb_auth_ntlm_hash((char *)password, smbpw->pw_nthash);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_putpwent
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 rc = fprintf(fp, "%s:%d:%s:%s\n", pwbuf->pw_name, pw->pw_uid,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (errno) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw for (;;) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* somebody forked */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (lck_tid == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * For compatibility with the past, pretend
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * that we were interrupted by SIGALRM.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (-1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (-1);