summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2004-01-13 17:55:43 +0000
committerGerald Carter <jerry@samba.org>2004-01-13 17:55:43 +0000
commit0c9adb69858c7572320d18c0fd187dd6e885f17d (patch)
treed58b1ad6bbc5ca0e9f71d17ebdaa9905268fa1d4 /source3/smbd
parent60079bd15bee7fe71dd43cb131f6198ca28f74eb (diff)
downloadsamba-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.c81
-rw-r--r--source3/smbd/quotas.c159
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__) */