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/*
96a62ada8aa6cb19b04270da282e7e21ba74b808joyce mcintosh * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use is subject to license terms.
12b65585e720714b31036daaa2b30eb76014048eGordon Ross *
12b65585e720714b31036daaa2b30eb76014048eGordon Ross * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States#include <syslog.h>
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>
3db3f65c6274eb042354801a308c8e9bc4994553amw#include <sys/avl.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <fcntl.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <thread.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <pwd.h>
7b59d02d2a384be9a08087b14defadd214b3c1ddjb#include <dlfcn.h>
7b59d02d2a384be9a08087b14defadd214b3c1ddjb#include <link.h>
3db3f65c6274eb042354801a308c8e9bc4994553amw#include <assert.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"
3db3f65c6274eb042354801a308c8e9bc4994553amw
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
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic struct flock flock = { 0, 0, 0, 0, 0, 0 };
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;
7b59d02d2a384be9a08087b14defadd214b3c1ddjbstatic void *smb_pwd_hdl = NULL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
7b59d02d2a384be9a08087b14defadd214b3c1ddjbstatic struct {
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego smb_passwd_t *(*pwop_getpwnam)(const char *, smb_passwd_t *);
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego smb_passwd_t *(*pwop_getpwuid)(uid_t, smb_passwd_t *);
3db3f65c6274eb042354801a308c8e9bc4994553amw int (*pwop_setcntl)(const char *, int);
3db3f65c6274eb042354801a308c8e9bc4994553amw int (*pwop_setpasswd)(const char *, const char *);
3db3f65c6274eb042354801a308c8e9bc4994553amw int (*pwop_num)(void);
3db3f65c6274eb042354801a308c8e9bc4994553amw int (*pwop_iteropen)(smb_pwditer_t *);
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_luser_t *(*pwop_iterate)(smb_pwditer_t *);
3db3f65c6274eb042354801a308c8e9bc4994553amw void (*pwop_iterclose)(smb_pwditer_t *);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb} smb_pwd_ops;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
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
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * buffer structure used by smb_pwd_fgetent/smb_pwd_fputent
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwtypedef struct smb_pwbuf {
3db3f65c6274eb042354801a308c8e9bc4994553amw char pw_buf[SMB_PWD_BUFSIZE];
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_passwd_t *pw_pwd;
3db3f65c6274eb042354801a308c8e9bc4994553amw} smb_pwbuf_t;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * flag values used with smb_pwd_fgetent
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amw#define SMB_PWD_GETF_ALL 1 /* get all the account info */
3db3f65c6274eb042354801a308c8e9bc4994553amw#define SMB_PWD_GETF_NOPWD 2 /* password is not needed */
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic smb_pwbuf_t *smb_pwd_fgetent(FILE *, smb_pwbuf_t *, uint32_t);
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightstatic int smb_pwd_fputent(FILE *, const 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
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * Local Users Cache
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Simplifying assumptions
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * o smbpasswd is a service private file and shouldn't be edited manually
3db3f65c6274eb042354801a308c8e9bc4994553amw * o accounts are only added/modified via passwd and/or smbadm CLIs
3db3f65c6274eb042354801a308c8e9bc4994553amw * o accounts are not removed but disabled using smbadm CLI
3db3f65c6274eb042354801a308c8e9bc4994553amw * o editing smbpasswd manually might result in cache inconsistency
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Cache is created and populated upon service startup.
3db3f65c6274eb042354801a308c8e9bc4994553amw * Cache is updated each time users list is requested if there's been
3db3f65c6274eb042354801a308c8e9bc4994553amw * any change in smbpasswd file. The change criteria is smbpasswd's
3db3f65c6274eb042354801a308c8e9bc4994553amw * modification timestamp.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * User cache handle
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwtypedef struct smb_uchandle {
3db3f65c6274eb042354801a308c8e9bc4994553amw avl_tree_t uc_cache;
3db3f65c6274eb042354801a308c8e9bc4994553amw rwlock_t uc_cache_lck;
3db3f65c6274eb042354801a308c8e9bc4994553amw timestruc_t uc_timestamp;
3db3f65c6274eb042354801a308c8e9bc4994553amw uint32_t uc_refcnt;
3db3f65c6274eb042354801a308c8e9bc4994553amw uint32_t uc_state;
3db3f65c6274eb042354801a308c8e9bc4994553amw mutex_t uc_mtx;
3db3f65c6274eb042354801a308c8e9bc4994553amw cond_t uc_cv;
3db3f65c6274eb042354801a308c8e9bc4994553amw} smb_uchandle_t;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw#define SMB_UCHS_NOCACHE 0
3db3f65c6274eb042354801a308c8e9bc4994553amw#define SMB_UCHS_CREATED 1
3db3f65c6274eb042354801a308c8e9bc4994553amw#define SMB_UCHS_UPDATING 2
3db3f65c6274eb042354801a308c8e9bc4994553amw#define SMB_UCHS_UPDATED 3
3db3f65c6274eb042354801a308c8e9bc4994553amw#define SMB_UCHS_DESTROYING 4
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * User cache node
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwtypedef struct smb_ucnode {
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_luser_t cn_user;
3db3f65c6274eb042354801a308c8e9bc4994553amw avl_node_t cn_link;
3db3f65c6274eb042354801a308c8e9bc4994553amw} smb_ucnode_t;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic void smb_lucache_create(void);
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic void smb_lucache_destroy(void);
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic void smb_lucache_update(void);
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic int smb_lucache_num(void);
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic int smb_lucache_lock(void);
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic void smb_lucache_unlock(void);
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic int smb_lucache_do_update(void);
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic void smb_lucache_flush(void);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic smb_uchandle_t smb_uch;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_pwd_init
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Initializes the cache if requested.
3db3f65c6274eb042354801a308c8e9bc4994553amw * Checks to see if a password management utility library
3db3f65c6274eb042354801a308c8e9bc4994553amw * is interposed. If yes then it'll initializes smb_pwd_ops
3db3f65c6274eb042354801a308c8e9bc4994553amw * structure with function pointers from this library.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
7b59d02d2a384be9a08087b14defadd214b3c1ddjbvoid
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_pwd_init(boolean_t create_cache)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb{
3db3f65c6274eb042354801a308c8e9bc4994553amw if (create_cache) {
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_lucache_create();
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier#if 0
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier /*
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier * This pre-loading of the cache results in idmapd requests.
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier * With the change to allow idmapd to call into libsmb to
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier * map names and SIDs, this creates a circular startup
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier * dependency. This call has been temporarily disabled to
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier * avoid this issue. It can be enabled when the name/SID
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier * lookup can be done directly on the LSA service.
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier */
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_lucache_update();
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier#endif
3db3f65c6274eb042354801a308c8e9bc4994553amw }
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown smb_pwd_hdl = smb_dlopen();
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (smb_pwd_hdl == NULL)
3db3f65c6274eb042354801a308c8e9bc4994553amw return;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
7b59d02d2a384be9a08087b14defadd214b3c1ddjb bzero((void *)&smb_pwd_ops, sizeof (smb_pwd_ops));
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego smb_pwd_ops.pwop_getpwnam =
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego (smb_passwd_t *(*)())dlsym(smb_pwd_hdl, "smb_pwd_getpwnam");
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego smb_pwd_ops.pwop_getpwuid =
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego (smb_passwd_t *(*)())dlsym(smb_pwd_hdl, "smb_pwd_getpwuid");
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_pwd_ops.pwop_setcntl =
7b59d02d2a384be9a08087b14defadd214b3c1ddjb (int (*)())dlsym(smb_pwd_hdl, "smb_pwd_setcntl");
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_pwd_ops.pwop_setpasswd =
7b59d02d2a384be9a08087b14defadd214b3c1ddjb (int (*)())dlsym(smb_pwd_hdl, "smb_pwd_setpasswd");
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_pwd_ops.pwop_num =
3db3f65c6274eb042354801a308c8e9bc4994553amw (int (*)())dlsym(smb_pwd_hdl, "smb_pwd_num");
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_pwd_ops.pwop_iteropen =
3db3f65c6274eb042354801a308c8e9bc4994553amw (int (*)())dlsym(smb_pwd_hdl, "smb_pwd_iteropen");
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_pwd_ops.pwop_iterclose =
3db3f65c6274eb042354801a308c8e9bc4994553amw (void (*)())dlsym(smb_pwd_hdl, "smb_pwd_iterclose");
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_pwd_ops.pwop_iterate =
3db3f65c6274eb042354801a308c8e9bc4994553amw (smb_luser_t *(*)())dlsym(smb_pwd_hdl, "smb_pwd_iterate");
3db3f65c6274eb042354801a308c8e9bc4994553amw
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego if (smb_pwd_ops.pwop_getpwnam == NULL ||
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego smb_pwd_ops.pwop_getpwuid == NULL ||
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_pwd_ops.pwop_setcntl == NULL ||
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_pwd_ops.pwop_setpasswd == NULL ||
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_pwd_ops.pwop_num == NULL ||
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_pwd_ops.pwop_iteropen == NULL ||
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_pwd_ops.pwop_iterclose == NULL ||
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_pwd_ops.pwop_iterate == NULL) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown smb_dlclose(smb_pwd_hdl);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb smb_pwd_hdl = NULL;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
7b59d02d2a384be9a08087b14defadd214b3c1ddjb /* If error or function(s) are missing, use original lib */
7b59d02d2a384be9a08087b14defadd214b3c1ddjb bzero((void *)&smb_pwd_ops, sizeof (smb_pwd_ops));
7b59d02d2a384be9a08087b14defadd214b3c1ddjb }
7b59d02d2a384be9a08087b14defadd214b3c1ddjb}
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_pwd_fini
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Destroys the cache.
3db3f65c6274eb042354801a308c8e9bc4994553amw * Closes interposed library.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
7b59d02d2a384be9a08087b14defadd214b3c1ddjbvoid
7b59d02d2a384be9a08087b14defadd214b3c1ddjbsmb_pwd_fini(void)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb{
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_lucache_destroy();
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown smb_dlclose(smb_pwd_hdl);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown smb_pwd_hdl = NULL;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown bzero((void *)&smb_pwd_ops, sizeof (smb_pwd_ops));
7b59d02d2a384be9a08087b14defadd214b3c1ddjb}
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * smb_pwd_getpwnam
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 *
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borregosmb_pwd_getpwnam(const char *name, smb_passwd_t *smbpw)
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego{
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego boolean_t found = B_FALSE;
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego smb_pwbuf_t pwbuf;
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego FILE *fp;
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego int err;
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego if (smb_pwd_ops.pwop_getpwnam != NULL)
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego return (smb_pwd_ops.pwop_getpwnam(name, smbpw));
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego err = smb_pwd_lock();
12b65585e720714b31036daaa2b30eb76014048eGordon Ross if (err != SMB_PWE_SUCCESS) {
12b65585e720714b31036daaa2b30eb76014048eGordon Ross syslog(LOG_WARNING, "smb_pwdutil: lock failed, err=%d", err);
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego return (NULL);
12b65585e720714b31036daaa2b30eb76014048eGordon Ross }
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego if ((fp = fopen(SMB_PASSWD, "rF")) == NULL) {
12b65585e720714b31036daaa2b30eb76014048eGordon Ross syslog(LOG_WARNING, "smb_pwdutil: open failed, %m");
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego (void) smb_pwd_unlock();
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego return (NULL);
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego }
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego pwbuf.pw_pwd = smbpw;
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego while (smb_pwd_fgetent(fp, &pwbuf, SMB_PWD_GETF_ALL) != NULL) {
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego if (strcmp(name, smbpw->pw_name) == 0) {
12b65585e720714b31036daaa2b30eb76014048eGordon Ross found = B_TRUE;
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego break;
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego }
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego }
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego (void) fclose(fp);
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego (void) smb_pwd_unlock();
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego if (!found) {
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego bzero(smbpw, sizeof (smb_passwd_t));
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego return (NULL);
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego }
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego return (smbpw);
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego}
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego/*
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * smb_pwd_getpwuid
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego *
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * Returns a smb password structure for the given UID
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * smbpw is a pointer to a buffer allocated by the caller.
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego *
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego * Returns NULL upon failure.
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego */
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borregosmb_passwd_t *
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borregosmb_pwd_getpwuid(uid_t uid, smb_passwd_t *smbpw)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw boolean_t found = B_FALSE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_pwbuf_t pwbuf;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw FILE *fp;
3db3f65c6274eb042354801a308c8e9bc4994553amw int err;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego if (smb_pwd_ops.pwop_getpwuid != NULL)
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego return (smb_pwd_ops.pwop_getpwuid(uid, smbpw));
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw err = smb_pwd_lock();
12b65585e720714b31036daaa2b30eb76014048eGordon Ross if (err != SMB_PWE_SUCCESS) {
12b65585e720714b31036daaa2b30eb76014048eGordon Ross syslog(LOG_WARNING, "smb_pwdutil: lock failed, err=%d", err);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
12b65585e720714b31036daaa2b30eb76014048eGordon Ross }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((fp = fopen(SMB_PASSWD, "rF")) == NULL) {
12b65585e720714b31036daaa2b30eb76014048eGordon Ross syslog(LOG_WARNING, "smb_pwdutil: open failed, %m");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) smb_pwd_unlock();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw pwbuf.pw_pwd = smbpw;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
3db3f65c6274eb042354801a308c8e9bc4994553amw while (smb_pwd_fgetent(fp, &pwbuf, SMB_PWD_GETF_ALL) != NULL) {
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego if (uid == smbpw->pw_uid) {
12b65585e720714b31036daaa2b30eb76014048eGordon Ross 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/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_pwd_setpasswd
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Update/add the given user to the smbpasswd file.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_pwd_setpasswd(const char *name, const char *password)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
3db3f65c6274eb042354801a308c8e9bc4994553amw if (smb_pwd_ops.pwop_setpasswd != NULL)
3db3f65c6274eb042354801a308c8e9bc4994553amw return (smb_pwd_ops.pwop_setpasswd(name, password));
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
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{
3db3f65c6274eb042354801a308c8e9bc4994553amw if (smb_pwd_ops.pwop_setcntl != NULL)
3db3f65c6274eb042354801a308c8e9bc4994553amw return (smb_pwd_ops.pwop_setcntl(name, control));
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (control == 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (SMB_PWE_SUCCESS);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (smb_pwd_update(name, NULL, control));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_pwd_num
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Returns the number of cached local users
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwint
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_pwd_num(void)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
3db3f65c6274eb042354801a308c8e9bc4994553amw if (smb_pwd_ops.pwop_num != NULL)
3db3f65c6274eb042354801a308c8e9bc4994553amw return (smb_pwd_ops.pwop_num());
3db3f65c6274eb042354801a308c8e9bc4994553amw
96a62ada8aa6cb19b04270da282e7e21ba74b808joyce mcintosh smb_lucache_update();
96a62ada8aa6cb19b04270da282e7e21ba74b808joyce mcintosh
3db3f65c6274eb042354801a308c8e9bc4994553amw return (smb_lucache_num());
3db3f65c6274eb042354801a308c8e9bc4994553amw}
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_pwd_iteropen
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Initalizes the given iterator handle.
3db3f65c6274eb042354801a308c8e9bc4994553amw * This handle will be used to iterate the users cache
3db3f65c6274eb042354801a308c8e9bc4994553amw * by the caller. The cache will be locked for read and it
3db3f65c6274eb042354801a308c8e9bc4994553amw * will remain locked until smb_pwd_iterclose() is called.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwint
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_pwd_iteropen(smb_pwditer_t *iter)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
3db3f65c6274eb042354801a308c8e9bc4994553amw if (iter == NULL)
3db3f65c6274eb042354801a308c8e9bc4994553amw return (SMB_PWE_INVALID_PARAM);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw if (smb_pwd_ops.pwop_iteropen != NULL)
3db3f65c6274eb042354801a308c8e9bc4994553amw return (smb_pwd_ops.pwop_iteropen(iter));
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw iter->spi_next = NULL;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_lucache_update();
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw return (smb_lucache_lock());
3db3f65c6274eb042354801a308c8e9bc4994553amw}
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_pwd_iterate
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Scans through users cache using the given iterator
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_luser_t *
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_pwd_iterate(smb_pwditer_t *iter)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_ucnode_t *ucnode;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw if (iter == NULL)
3db3f65c6274eb042354801a308c8e9bc4994553amw return (NULL);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw if (smb_pwd_ops.pwop_iterate != NULL)
3db3f65c6274eb042354801a308c8e9bc4994553amw return (smb_pwd_ops.pwop_iterate(iter));
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw if (iter->spi_next == NULL)
3db3f65c6274eb042354801a308c8e9bc4994553amw ucnode = avl_first(&smb_uch.uc_cache);
3db3f65c6274eb042354801a308c8e9bc4994553amw else
3db3f65c6274eb042354801a308c8e9bc4994553amw ucnode = AVL_NEXT(&smb_uch.uc_cache, iter->spi_next);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw if ((iter->spi_next = ucnode) != NULL)
3db3f65c6274eb042354801a308c8e9bc4994553amw return (&ucnode->cn_user);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw return (NULL);
3db3f65c6274eb042354801a308c8e9bc4994553amw}
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_pwd_iterclose
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Closes the given iterator. Effectively it only unlocks the cache
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwvoid
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_pwd_iterclose(smb_pwditer_t *iter)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
3db3f65c6274eb042354801a308c8e9bc4994553amw if (smb_pwd_ops.pwop_iterclose != NULL) {
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_pwd_ops.pwop_iterclose(iter);
3db3f65c6274eb042354801a308c8e9bc4994553amw return;
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw if (iter != NULL)
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_lucache_unlock();
3db3f65c6274eb042354801a308c8e9bc4994553amw}
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_pwd_update
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Updates the password entry of the given user if the user already
3db3f65c6274eb042354801a308c8e9bc4994553amw * has an entry, otherwise it'll add an entry for the user with
3db3f65c6274eb042354801a308c8e9bc4994553amw * given password and control information.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
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 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;
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as int64_t lm_level;
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
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as if (smb_config_getnum(SMB_CI_LM_LEVEL, &lm_level) != SMBD_SMF_OK)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lm_level = 4;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (lm_level >= 4)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw control |= SMB_PWC_NOLM;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
3db3f65c6274eb042354801a308c8e9bc4994553amw pwbuf.pw_pwd = &smbpw;
3db3f65c6274eb042354801a308c8e9bc4994553amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * copy old password entries to temporary file while replacing
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the entry that matches "name"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
3db3f65c6274eb042354801a308c8e9bc4994553amw while (smb_pwd_fgetent(src, &pwbuf, SMB_PWD_GETF_ALL) != NULL) {
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego if (strcmp(smbpw.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))) {
3db3f65c6274eb042354801a308c8e9bc4994553amw bzero(&smbpw, sizeof (smb_passwd_t));
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego (void) strlcpy(smbpw.pw_name, uxpw.pw_name,
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego sizeof (smbpw.pw_name));
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/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_pwd_fgetent
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 *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Returns a pointer to the passed pwbuf structure on success,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * otherwise returns NULL.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic smb_pwbuf_t *
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_pwd_fgetent(FILE *fp, smb_pwbuf_t *pwbuf, uint32_t flags)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *argv[SMB_PWD_NARG];
3db3f65c6274eb042354801a308c8e9bc4994553amw char *pwentry;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_passwd_t *pw;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_pwdarg_t i;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int lm_len, nt_len;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
3db3f65c6274eb042354801a308c8e9bc4994553amw pwentry = pwbuf->pw_buf;
3db3f65c6274eb042354801a308c8e9bc4994553amw if (fgets(pwentry, SMB_PWD_BUFSIZE, fp) == NULL)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) trim_whitespace(pwentry);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw for (i = 0; i < SMB_PWD_NARG; ++i) {
3db3f65c6274eb042354801a308c8e9bc4994553amw if ((argv[i] = strsep((char **)&pwentry, ":")) == NULL)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((*argv[SMB_PWD_NAME] == '\0') || (*argv[SMB_PWD_UID] == '\0'))
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw pw = pwbuf->pw_pwd;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw bzero(pw, sizeof (smb_passwd_t));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw pw->pw_uid = strtoul(argv[SMB_PWD_UID], 0, 10);
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego (void) strlcpy(pw->pw_name, argv[SMB_PWD_NAME], sizeof (pw->pw_name));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (strcmp(argv[SMB_PWD_LMHASH], SMB_PWD_DISABLE) == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw pw->pw_flags |= SMB_PWF_DISABLE;
3db3f65c6274eb042354801a308c8e9bc4994553amw if (flags != SMB_PWD_GETF_NOPWD) {
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) strcpy((char *)pw->pw_lmhash, SMB_PWD_DISABLE);
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) strcpy((char *)pw->pw_nthash, SMB_PWD_DISABLE);
3db3f65c6274eb042354801a308c8e9bc4994553amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (pwbuf);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
3db3f65c6274eb042354801a308c8e9bc4994553amw if (flags == SMB_PWD_GETF_NOPWD)
3db3f65c6274eb042354801a308c8e9bc4994553amw return (pwbuf);
3db3f65c6274eb042354801a308c8e9bc4994553amw
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
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_pwd_chgpwent
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Updates the given smb_passwd_t structure with given password and
3db3f65c6274eb042354801a308c8e9bc4994553amw * control information.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_pwd_chgpwent(smb_passwd_t *smbpw, const char *password, int control)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (control & SMB_PWC_DISABLE) {
3db3f65c6274eb042354801a308c8e9bc4994553amw /* disable the user */
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);
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw if ((control & SMB_PWC_ENABLE) && (smbpw->pw_flags & SMB_PWF_DISABLE)) {
3db3f65c6274eb042354801a308c8e9bc4994553amw /* enable the user if it's been disabled */
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
3db3f65c6274eb042354801a308c8e9bc4994553amw /* This call was just to update the control flags */
3db3f65c6274eb042354801a308c8e9bc4994553amw if (password == NULL)
3db3f65c6274eb042354801a308c8e9bc4994553amw return (SMB_PWE_SUCCESS);
3db3f65c6274eb042354801a308c8e9bc4994553amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (control & SMB_PWC_NOLM) {
3db3f65c6274eb042354801a308c8e9bc4994553amw /* LM hash should not be present */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smbpw->pw_flags &= ~SMB_PWF_LM;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *smbpw->pw_lmhash = '\0';
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smbpw->pw_flags |= SMB_PWF_LM;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright (void) smb_auth_lm_hash(password, smbpw->pw_lmhash);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smbpw->pw_flags |= SMB_PWF_NT;
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wright (void) smb_auth_ntlm_hash(password, smbpw->pw_nthash);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (SMB_PWE_SUCCESS);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_pwd_fputent
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * If LM/NTLM hash are present, converts them to hex string
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and write them along with user's name and Id to the smbpasswd
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int
29bd28862cfb8abbd3a0f0a4b17e08bbc3652836Alan Wrightsmb_pwd_fputent(FILE *fp, const 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
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego rc = fprintf(fp, "%s:%u:%s:%s\n", pw->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
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_pwd_lock
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * A wrapper around smb_pwd_flck() which locks smb password
3db3f65c6274eb042354801a308c8e9bc4994553amw * file so that only one thread at a time is operational.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
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
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
96a62ada8aa6cb19b04270da282e7e21ba74b808joyce mcintosh * smb_pwd_unlock
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * A wrapper around smb_pwd_fulck() which unlocks
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb password file.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
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
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_pwd_flck
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Creates a lock file and grabs an exclusive (write) lock on it.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
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
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_pwd_fulck
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Unlocks smb password file for operations done via
3db3f65c6274eb042354801a308c8e9bc4994553amw * this library APIs.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
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}
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * Local User Cache Functions
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Local user cache is implemented using AVL tree
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_lucache_cmp
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * AVL compare function, the key is username.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic int
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_lucache_cmp(const void *p1, const void *p2)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_ucnode_t *u1 = (smb_ucnode_t *)p1;
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_ucnode_t *u2 = (smb_ucnode_t *)p2;
3db3f65c6274eb042354801a308c8e9bc4994553amw int rc;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw rc = strcmp(u1->cn_user.su_name, u2->cn_user.su_name);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw if (rc < 0)
3db3f65c6274eb042354801a308c8e9bc4994553amw return (-1);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw if (rc > 0)
3db3f65c6274eb042354801a308c8e9bc4994553amw return (1);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw return (0);
3db3f65c6274eb042354801a308c8e9bc4994553amw}
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_lucache_update
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Updates the cache if needed. Whether an update is needed
3db3f65c6274eb042354801a308c8e9bc4994553amw * is determined based on smbpasswd file modification timestamp
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic void
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_lucache_update(void)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
3db3f65c6274eb042354801a308c8e9bc4994553amw struct stat64 stbuf;
3db3f65c6274eb042354801a308c8e9bc4994553amw int rc;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_lock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw switch (smb_uch.uc_state) {
3db3f65c6274eb042354801a308c8e9bc4994553amw default:
3db3f65c6274eb042354801a308c8e9bc4994553amw case SMB_UCHS_NOCACHE:
3db3f65c6274eb042354801a308c8e9bc4994553amw assert(0);
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw return;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw case SMB_UCHS_CREATED:
3db3f65c6274eb042354801a308c8e9bc4994553amw case SMB_UCHS_UPDATED:
3db3f65c6274eb042354801a308c8e9bc4994553amw break;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw case SMB_UCHS_UPDATING:
3db3f65c6274eb042354801a308c8e9bc4994553amw /* Want only one thread executing this function at a time */
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw return;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw case SMB_UCHS_DESTROYING:
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw return;
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw /*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_pwd_lock() is not called here so it can
3db3f65c6274eb042354801a308c8e9bc4994553amw * be checked quickly whether an updated is needed
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amw if (stat64(SMB_PASSWD, &stbuf) < 0) {
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw if (errno != ENOENT)
3db3f65c6274eb042354801a308c8e9bc4994553amw return;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw /* no smbpasswd file; empty the cache */
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_lucache_flush();
3db3f65c6274eb042354801a308c8e9bc4994553amw return;
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw if (stbuf.st_size == 0) {
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw /* empty smbpasswd file; empty the cache */
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_lucache_flush();
3db3f65c6274eb042354801a308c8e9bc4994553amw return;
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw if ((smb_uch.uc_timestamp.tv_sec == stbuf.st_mtim.tv_sec) &&
3db3f65c6274eb042354801a308c8e9bc4994553amw (smb_uch.uc_timestamp.tv_nsec == stbuf.st_mtim.tv_nsec)) {
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw /* No changes since the last cache update */
3db3f65c6274eb042354801a308c8e9bc4994553amw return;
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_uch.uc_state = SMB_UCHS_UPDATING;
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_uch.uc_refcnt++;
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw rc = smb_lucache_do_update();
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_lock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw if ((rc == SMB_PWE_SUCCESS) && (stat64(SMB_PASSWD, &stbuf) == 0))
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_uch.uc_timestamp = stbuf.st_mtim;
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_uch.uc_state = SMB_UCHS_UPDATED;
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_uch.uc_refcnt--;
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) cond_broadcast(&smb_uch.uc_cv);
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw}
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_lucache_do_update
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * This function takes care of updating the AVL tree.
3db3f65c6274eb042354801a308c8e9bc4994553amw * If an entry has been updated, it'll be modified in place.
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * New entries will be added to a temporary AVL tree then
3db3f65c6274eb042354801a308c8e9bc4994553amw * passwod file is unlocked and all the new entries will
3db3f65c6274eb042354801a308c8e9bc4994553amw * be transferred to the main cache from the temporary tree.
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * This function MUST NOT be called directly
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic int
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_lucache_do_update(void)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
3db3f65c6274eb042354801a308c8e9bc4994553amw avl_tree_t tmp_cache;
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_pwbuf_t pwbuf;
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_passwd_t smbpw;
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_ucnode_t uc_node;
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_ucnode_t *uc_newnode;
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_luser_t *user;
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_sid_t *sid;
3db3f65c6274eb042354801a308c8e9bc4994553amw idmap_stat idm_stat;
3db3f65c6274eb042354801a308c8e9bc4994553amw int rc = SMB_PWE_SUCCESS;
3db3f65c6274eb042354801a308c8e9bc4994553amw void *cookie = NULL;
3db3f65c6274eb042354801a308c8e9bc4994553amw FILE *fp;
3db3f65c6274eb042354801a308c8e9bc4994553amw
12b65585e720714b31036daaa2b30eb76014048eGordon Ross if ((rc = smb_pwd_lock()) != SMB_PWE_SUCCESS) {
12b65585e720714b31036daaa2b30eb76014048eGordon Ross syslog(LOG_WARNING, "smb_pwdutil: lock failed, err=%d", rc);
3db3f65c6274eb042354801a308c8e9bc4994553amw return (rc);
12b65585e720714b31036daaa2b30eb76014048eGordon Ross }
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw if ((fp = fopen(SMB_PASSWD, "rF")) == NULL) {
12b65585e720714b31036daaa2b30eb76014048eGordon Ross syslog(LOG_WARNING, "smb_pwdutil: open failed, %m");
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) smb_pwd_unlock();
3db3f65c6274eb042354801a308c8e9bc4994553amw return (SMB_PWE_OPEN_FAILED);
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw avl_create(&tmp_cache, smb_lucache_cmp,
3db3f65c6274eb042354801a308c8e9bc4994553amw sizeof (smb_ucnode_t), offsetof(smb_ucnode_t, cn_link));
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw bzero(&pwbuf, sizeof (smb_pwbuf_t));
3db3f65c6274eb042354801a308c8e9bc4994553amw pwbuf.pw_pwd = &smbpw;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) rw_rdlock(&smb_uch.uc_cache_lck);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw while (smb_pwd_fgetent(fp, &pwbuf, SMB_PWD_GETF_NOPWD) != NULL) {
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego uc_node.cn_user.su_name = smbpw.pw_name;
3db3f65c6274eb042354801a308c8e9bc4994553amw uc_newnode = avl_find(&smb_uch.uc_cache, &uc_node, NULL);
3db3f65c6274eb042354801a308c8e9bc4994553amw if (uc_newnode) {
3db3f65c6274eb042354801a308c8e9bc4994553amw /* update the node info */
3db3f65c6274eb042354801a308c8e9bc4994553amw uc_newnode->cn_user.su_ctrl = smbpw.pw_flags;
3db3f65c6274eb042354801a308c8e9bc4994553amw continue;
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw /* create a new node */
3db3f65c6274eb042354801a308c8e9bc4994553amw if ((uc_newnode = malloc(sizeof (smb_ucnode_t))) == NULL) {
3db3f65c6274eb042354801a308c8e9bc4994553amw rc = SMB_PWE_NO_MEMORY;
3db3f65c6274eb042354801a308c8e9bc4994553amw break;
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw bzero(uc_newnode, sizeof (smb_ucnode_t));
3db3f65c6274eb042354801a308c8e9bc4994553amw user = &uc_newnode->cn_user;
3db3f65c6274eb042354801a308c8e9bc4994553amw user->su_ctrl = smbpw.pw_flags;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw idm_stat = smb_idmap_getsid(smbpw.pw_uid, SMB_IDMAP_USER, &sid);
3db3f65c6274eb042354801a308c8e9bc4994553amw if (idm_stat != IDMAP_SUCCESS) {
3db3f65c6274eb042354801a308c8e9bc4994553amw syslog(LOG_WARNING, "smb_pwdutil: couldn't obtain SID "
3db3f65c6274eb042354801a308c8e9bc4994553amw "for uid=%u (%d)", smbpw.pw_uid, idm_stat);
3db3f65c6274eb042354801a308c8e9bc4994553amw free(uc_newnode);
3db3f65c6274eb042354801a308c8e9bc4994553amw continue;
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) smb_sid_getrid(sid, &user->su_rid);
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_sid_free(sid);
3db3f65c6274eb042354801a308c8e9bc4994553amw
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego user->su_name = strdup(smbpw.pw_name);
3db3f65c6274eb042354801a308c8e9bc4994553amw if (user->su_name == NULL) {
3db3f65c6274eb042354801a308c8e9bc4994553amw rc = SMB_PWE_NO_MEMORY;
3db3f65c6274eb042354801a308c8e9bc4994553amw free(uc_newnode);
3db3f65c6274eb042354801a308c8e9bc4994553amw break;
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw avl_add(&tmp_cache, uc_newnode);
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) rw_unlock(&smb_uch.uc_cache_lck);
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) fclose(fp);
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) smb_pwd_unlock();
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw /* Destroy the temporary list */
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) rw_wrlock(&smb_uch.uc_cache_lck);
3db3f65c6274eb042354801a308c8e9bc4994553amw while ((uc_newnode = avl_destroy_nodes(&tmp_cache, &cookie)) != NULL) {
3db3f65c6274eb042354801a308c8e9bc4994553amw avl_add(&smb_uch.uc_cache, uc_newnode);
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) rw_unlock(&smb_uch.uc_cache_lck);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw avl_destroy(&tmp_cache);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw return (rc);
3db3f65c6274eb042354801a308c8e9bc4994553amw}
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_lucache_create
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Creates the AVL tree and initializes the global user cache handle.
3db3f65c6274eb042354801a308c8e9bc4994553amw * This function doesn't populate the cache.
3db3f65c6274eb042354801a308c8e9bc4994553amw * User cache is only created by smbd at startup
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic void
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_lucache_create(void)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_lock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw if (smb_uch.uc_state != SMB_UCHS_NOCACHE) {
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw return;
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw avl_create(&smb_uch.uc_cache, smb_lucache_cmp,
3db3f65c6274eb042354801a308c8e9bc4994553amw sizeof (smb_ucnode_t), offsetof(smb_ucnode_t, cn_link));
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_uch.uc_state = SMB_UCHS_CREATED;
3db3f65c6274eb042354801a308c8e9bc4994553amw bzero(&smb_uch.uc_timestamp, sizeof (timestruc_t));
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_uch.uc_refcnt = 0;
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw}
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_lucache_flush
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Removes and frees all the cache entries
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic void
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_lucache_flush(void)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
3db3f65c6274eb042354801a308c8e9bc4994553amw void *cookie = NULL;
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_ucnode_t *ucnode;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) rw_wrlock(&smb_uch.uc_cache_lck);
3db3f65c6274eb042354801a308c8e9bc4994553amw while ((ucnode = avl_destroy_nodes(&smb_uch.uc_cache, &cookie))
3db3f65c6274eb042354801a308c8e9bc4994553amw != NULL) {
3db3f65c6274eb042354801a308c8e9bc4994553amw free(ucnode->cn_user.su_name);
3db3f65c6274eb042354801a308c8e9bc4994553amw free(ucnode->cn_user.su_fullname);
3db3f65c6274eb042354801a308c8e9bc4994553amw free(ucnode->cn_user.su_desc);
3db3f65c6274eb042354801a308c8e9bc4994553amw free(ucnode);
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) rw_unlock(&smb_uch.uc_cache_lck);
3db3f65c6274eb042354801a308c8e9bc4994553amw}
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_lucache_destroy
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Destroys the cache.
3db3f65c6274eb042354801a308c8e9bc4994553amw * This function is only called in smb_pwd_fini()
3db3f65c6274eb042354801a308c8e9bc4994553amw * User cache is only destroyed by smbd upon shutdown
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic void
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_lucache_destroy(void)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_lock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw switch (smb_uch.uc_state) {
3db3f65c6274eb042354801a308c8e9bc4994553amw case SMB_UCHS_NOCACHE:
3db3f65c6274eb042354801a308c8e9bc4994553amw case SMB_UCHS_DESTROYING:
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw return;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw default:
3db3f65c6274eb042354801a308c8e9bc4994553amw break;
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_uch.uc_state = SMB_UCHS_DESTROYING;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw while (smb_uch.uc_refcnt > 0)
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) cond_wait(&smb_uch.uc_cv, &smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_lucache_flush();
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw avl_destroy(&smb_uch.uc_cache);
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_uch.uc_state = SMB_UCHS_NOCACHE;
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw}
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_lucache_lock
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Locks the user cache for reading and also
3db3f65c6274eb042354801a308c8e9bc4994553amw * increment the handle reference count.
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic int
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_lucache_lock(void)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_lock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw switch (smb_uch.uc_state) {
3db3f65c6274eb042354801a308c8e9bc4994553amw case SMB_UCHS_NOCACHE:
3db3f65c6274eb042354801a308c8e9bc4994553amw assert(0);
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw return (SMB_PWE_DENIED);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw case SMB_UCHS_DESTROYING:
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw return (SMB_PWE_DENIED);
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_uch.uc_refcnt++;
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) rw_rdlock(&smb_uch.uc_cache_lck);
3db3f65c6274eb042354801a308c8e9bc4994553amw return (SMB_PWE_SUCCESS);
3db3f65c6274eb042354801a308c8e9bc4994553amw}
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_lucache_unlock
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Unlock the cache
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic void
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_lucache_unlock(void)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) rw_unlock(&smb_uch.uc_cache_lck);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_lock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw smb_uch.uc_refcnt--;
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) cond_broadcast(&smb_uch.uc_cv);
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw}
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw/*
3db3f65c6274eb042354801a308c8e9bc4994553amw * smb_lucache_num
3db3f65c6274eb042354801a308c8e9bc4994553amw *
3db3f65c6274eb042354801a308c8e9bc4994553amw * Returns the number of cache entries
3db3f65c6274eb042354801a308c8e9bc4994553amw */
3db3f65c6274eb042354801a308c8e9bc4994553amwstatic int
3db3f65c6274eb042354801a308c8e9bc4994553amwsmb_lucache_num(void)
3db3f65c6274eb042354801a308c8e9bc4994553amw{
3db3f65c6274eb042354801a308c8e9bc4994553amw int num;
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_lock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw switch (smb_uch.uc_state) {
3db3f65c6274eb042354801a308c8e9bc4994553amw case SMB_UCHS_NOCACHE:
3db3f65c6274eb042354801a308c8e9bc4994553amw assert(0);
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw return (0);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw case SMB_UCHS_DESTROYING:
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw return (0);
3db3f65c6274eb042354801a308c8e9bc4994553amw }
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) mutex_unlock(&smb_uch.uc_mtx);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) rw_rdlock(&smb_uch.uc_cache_lck);
3db3f65c6274eb042354801a308c8e9bc4994553amw num = (int)avl_numnodes(&smb_uch.uc_cache);
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) rw_unlock(&smb_uch.uc_cache_lck);
3db3f65c6274eb042354801a308c8e9bc4994553amw
3db3f65c6274eb042354801a308c8e9bc4994553amw return (num);
3db3f65c6274eb042354801a308c8e9bc4994553amw}