diff options
author | Gerald Carter <jerry@samba.org> | 2004-01-13 17:55:43 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2004-01-13 17:55:43 +0000 |
commit | 0c9adb69858c7572320d18c0fd187dd6e885f17d (patch) | |
tree | d58b1ad6bbc5ca0e9f71d17ebdaa9905268fa1d4 /source3/smbd | |
parent | 60079bd15bee7fe71dd43cb131f6198ca28f74eb (diff) | |
download | samba-0c9adb69858c7572320d18c0fd187dd6e885f17d.tar.gz samba-0c9adb69858c7572320d18c0fd187dd6e885f17d.tar.bz2 samba-0c9adb69858c7572320d18c0fd187dd6e885f17d.zip |
sync HEAD with recent changes in 3.0
(This used to be commit c98399e3c9d74e19b7c9d806ca8028b48866931e)
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/chgpasswd.c | 81 | ||||
-rw-r--r-- | source3/smbd/quotas.c | 159 |
2 files changed, 154 insertions, 86 deletions
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index e6117245e7..692e82680d 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -49,6 +49,16 @@ #include "includes.h" +#ifdef HAVE_WORKING_CRACKLIB +#include <crack.h> + +#ifndef HAVE_CRACKLIB_DICTPATH +#ifndef CRACKLIB_DICTPATH +#define CRACKLIB_DICTPATH SAMBA_CRACKLIB_DICTPATH +#endif +#endif +#endif + extern struct passdb_ops pdb_ops; static NTSTATUS check_oem_password(const char *user, @@ -441,25 +451,14 @@ while we were waiting\n", WTERMSIG(wstat))); return (chstat); } -BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL as_root) +BOOL chgpasswd(const char *name, const struct passwd *pass, + const char *oldpass, const char *newpass, BOOL as_root) { pstring passwordprogram; pstring chatsequence; size_t i; size_t len; - struct passwd *pass; - - if (!name) { - DEBUG(1, ("chgpasswd: NULL username specfied !\n")); - } - - pass = Get_Pwnam(name); - if (!pass) { - DEBUG(1, ("chgpasswd: Username does not exist in system !\n")); - return False; - } - if (!oldpass) { oldpass = ""; } @@ -471,13 +470,6 @@ BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL #endif /* Take the passed information and test it for minimum criteria */ - /* Minimum password length */ - if (strlen(newpass) < lp_min_passwd_length()) { - /* too short, must be at least MINPASSWDLENGTH */ - DEBUG(0, ("chgpasswd: Password Change: user %s, New password is shorter than minimum password length = %d\n", - name, lp_min_passwd_length())); - return (False); /* inform the user */ - } /* Password is same as old password */ if (strcmp(oldpass, newpass) == 0) { @@ -570,7 +562,8 @@ the string %%u, and the given string %s does not.\n", passwordprogram )); #else /* ALLOW_CHANGE_PASSWORD */ -BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL as_root) +BOOL chgpasswd(const char *name, const struct passwd *pass, + const char *oldpass, const char *newpass, BOOL as_root) { DEBUG(0, ("chgpasswd: Password changing not compiled in (user=%s)\n", name)); return (False); @@ -909,6 +902,8 @@ static NTSTATUS check_oem_password(const char *user, NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passwd, BOOL as_root) { + struct passwd *pass; + BOOL ret; uint32 min_len; @@ -936,7 +931,47 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw /* return NT_STATUS_PWD_TOO_SHORT; */ } - /* TODO: Add cracklib support here */ + pass = Get_Pwnam(pdb_get_username(hnd)); + if (!pass) { + DEBUG(1, ("check_oem_password: Username does not exist in system !?!\n")); + } + +#ifdef HAVE_WORKING_CRACKLIB + if (pass) { + /* if we can, become the user to overcome internal cracklib sillyness */ + if (!push_sec_ctx()) + return NT_STATUS_UNSUCCESSFUL; + + set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL); + set_re_uid(); + } + + if (lp_use_cracklib()) { + const char *crack_check_reason; + DEBUG(4, ("change_oem_password: Checking password for user [%s]" + " against cracklib. \n", pdb_get_username(hnd))); + DEBUGADD(4, ("If this is your last message, then something is " + "wrong with cracklib, it might be missing it's " + "dictionaries at %s\n", + CRACKLIB_DICTPATH)); + dbgflush(); + + crack_check_reason = FascistCheck(new_passwd, (char *)CRACKLIB_DICTPATH); + if (crack_check_reason) { + DEBUG(1, ("Password Change: user [%s], " + "New password failed cracklib test - %s\n", + pdb_get_username(hnd), crack_check_reason)); + + /* get back to where we should be */ + if (pass) + pop_sec_ctx(); + return NT_STATUS_PASSWORD_RESTRICTION; + } + } + + if (pass) + pop_sec_ctx(); +#endif /* * If unix password sync was requested, attempt to change @@ -951,7 +986,7 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw */ if(lp_unix_password_sync() && - !chgpasswd(pdb_get_username(hnd), old_passwd, new_passwd, as_root)) { + !chgpasswd(pdb_get_username(hnd), pass, old_passwd, new_passwd, as_root)) { return NT_STATUS_ACCESS_DENIED; } diff --git a/source3/smbd/quotas.c b/source3/smbd/quotas.c index 46f688a219..19f225e973 100644 --- a/source3/smbd/quotas.c +++ b/source3/smbd/quotas.c @@ -50,33 +50,16 @@ BOOL disk_quotas_vxfs(const pstring name, char *path, SMB_BIG_UINT *bsize, SMB_B #ifdef LINUX #include <sys/types.h> -#include <asm/types.h> +#include <mntent.h> /* * This shouldn't be neccessary - it should be /usr/include/sys/quota.h - * Unfortunately, RH7.1 ships with a different quota system using struct mem_dqblk - * rather than the struct dqblk defined in /usr/include/sys/quota.h. - * This means we must include linux/quota.h to have a hope of working on - * RH7.1 systems. And it also means this breaks if the kernel is upgraded - * to a Linus 2.4.x (where x > the minor number shipped with RH7.1) until - * Linus synchronises with the AC patches. Sometimes I *hate* Linux :-). JRA. + * So we include all the files has *should* be in the system into a large, + * grungy samba_linux_quoatas.h Sometimes I *hate* Linux :-). JRA. */ -#include <linux/quota.h> -#ifdef HAVE_LINUX_XQM_H -#include <linux/xqm.h> -#else -#ifdef HAVE_XFS_XQM_H -#include <xfs/xqm.h> -#define HAVE_LINUX_XQM_H -#endif -#endif - -#include <mntent.h> -#include <linux/unistd.h> - - -#define LINUX_QUOTAS_2 +#include "samba_linux_quota.h" +#include "samba_xfs_quota.h" typedef struct _LINUX_SMB_DISK_QUOTA { SMB_BIG_UINT bsize; @@ -92,22 +75,20 @@ typedef struct _LINUX_SMB_DISK_QUOTA { Abstract out the XFS Quota Manager quota get call. ****************************************************************************/ -static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp) +static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp) { - int ret = -1; -#ifdef HAVE_LINUX_XQM_H struct fs_disk_quota D; + int ret; ZERO_STRUCT(D); - ret = quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D); + ret = quotactl(QCMD(Q_XGETQUOTA,XFS_USER_QUOTA), path, euser_id, (caddr_t)&D); - /* As XFS has group quotas, if getting the user quota fails, try getting the group instead. */ - if (ret) { - ret = quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), path, getegid(), (caddr_t)&D); - if (ret) - return ret; - } + if (ret) + ret = quotactl(QCMD(Q_XGETQUOTA,XFS_GROUP_QUOTA), path, egrp_id, (caddr_t)&D); + + if (ret) + return ret; dp->bsize = (SMB_BIG_UINT)512; dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit; @@ -116,7 +97,7 @@ static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QU dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit; dp->curinodes = (SMB_BIG_UINT)D.d_icount; dp->curblocks = (SMB_BIG_UINT)D.d_bcount; -#endif + return ret; } @@ -124,48 +105,90 @@ static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QU Abstract out the old and new Linux quota get calls. ****************************************************************************/ -static int get_smb_linux_vfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp) +static int get_smb_linux_v1_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp) { - int ret = 0; -#ifdef LINUX_QUOTAS_1 - struct dqblk D; + struct v1_kern_dqblk D; + int ret; + ZERO_STRUCT(D); - dp->bsize = (SMB_BIG_UINT)1024; -#else /* LINUX_QUOTAS_2 */ - struct mem_dqblk D; + + ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D); + + if (ret && errno != EDQUOT) + ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), path, egrp_id, (caddr_t)&D); + + if (ret && errno != EDQUOT) + return ret; + + dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; + dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit; + dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit; + dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit; + dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit; + dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes; + dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks; + + return ret; +} + +static int get_smb_linux_v2_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp) +{ + struct v2_kern_dqblk D; + int ret; + ZERO_STRUCT(D); -#ifndef QUOTABLOCK_SIZE -#define QUOTABLOCK_SIZE 1024 -#endif + + ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D); + + if (ret && errno != EDQUOT) + ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), path, egrp_id, (caddr_t)&D); + + if (ret && errno != EDQUOT) + return ret; + dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; -#endif + dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit; + dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit; + dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit; + dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit; + dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes; + dp->curblocks = ((SMB_BIG_UINT)D.dqb_curspace) / dp->bsize; + + return ret; +} + +/**************************************************************************** + Brand-new generic quota interface. +****************************************************************************/ + +static int get_smb_linux_gen_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp) +{ + struct if_dqblk D; + int ret; + + ZERO_STRUCT(D); ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D); - /* Linux can have group quotas, if getting the user quota fails, try getting the group instead. */ - if (ret) { - ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), path, getegid(), (caddr_t)&D); - if (ret) - return ret; - } + if (ret && errno != EDQUOT) + ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), path, egrp_id, (caddr_t)&D); + if (ret && errno != EDQUOT) + return ret; + + dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit; dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit; dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit; dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit; dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes; - -#ifdef LINUX_QUOTAS_1 - dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks; -#else /* LINUX_QUOTAS_2 */ - dp->curblocks = ((SMB_BIG_UINT)D.dqb_curspace)/ dp->bsize; -#endif + dp->curblocks = ((SMB_BIG_UINT)D.dqb_curspace) / dp->bsize; return ret; } /**************************************************************************** -try to get the disk space from disk quotas (LINUX version) + Try to get the disk space from disk quotas (LINUX version). ****************************************************************************/ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) @@ -178,9 +201,11 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB SMB_DEV_T devno; int found; uid_t euser_id; + gid_t egrp_id; euser_id = geteuid(); - + egrp_id = getegid(); + /* find the block device file */ if ( sys_stat(path, &S) == -1 ) @@ -208,10 +233,18 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB save_re_uid(); set_effective_uid(0); - if (strcmp(mnt->mnt_type, "xfs") == 0) - r=get_smb_linux_xfs_quota(mnt->mnt_fsname, euser_id, &D); - else - r=get_smb_linux_vfs_quota(mnt->mnt_fsname, euser_id, &D); + + if (strcmp(mnt->mnt_type, "xfs")==0) { + r=get_smb_linux_xfs_quota(mnt->mnt_fsname, euser_id, egrp_id, &D); + } else { + r=get_smb_linux_gen_quota(mnt->mnt_fsname, euser_id, egrp_id, &D); + if (r == -1 && errno != EDQUOT) { + r=get_smb_linux_v2_quota(mnt->mnt_fsname, euser_id, egrp_id, &D); + if (r == -1 && errno != EDQUOT) + r=get_smb_linux_v1_quota(mnt->mnt_fsname, euser_id, egrp_id, &D); + } + } + restore_re_uid(); /* Use softlimit to determine disk space, except when it has been exceeded */ @@ -920,8 +953,8 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB if ((sys_stat(path, &S)<0) || (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 1)<0)) #else if ((sys_stat(path, &S)<0) || (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 0)<0)) -#endif /* ifdef HPUX */ return (False); +#endif /* ifdef HPUX */ #endif /* !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__) */ |