main() { if (getuid() != 0) { #if (defined(AIX) && defined(USE_SETREUID)) /* setreuid is badly broken on AIX 4.1, we avoid it completely */ fprintf(stderr,"avoiding possibly broken setreuid\n"); exit(1); #endif /* if not running as root then at least check to see if we get ENOSYS - this handles Linux 2.0.x with glibc 2.1 */ fprintf(stderr,"not running as root: checking for ENOSYS\n"); exit(have_syscall()); } gain_root_privilege(); gain_root_group_privilege(); set_effective_gid(1); set_effective_uid(1); save_re_uid(); restore_re_uid(); gain_root_privilege(); gain_root_group_privilege(); become_user_permanently(1, 1); setuid(0); if (getuid() == 0) { fprintf(stderr,"uid not set permanently\n"); exit(1); } printf("OK\n"); exit(0); }
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { int r, save_errno; struct dqblk D; SMB_STRUCT_STAT S; uid_t euser_id; /* * This code presumes that OSF1 will only * give out quota info when the real uid * matches the effective uid. JRA. */ euser_id = geteuid(); save_re_uid(); if (set_re_uid() != 0) return False; r= quotactl(path,QCMD(Q_GETQUOTA, USRQUOTA),euser_id,(char *) &D); if (r) { save_errno = errno; } restore_re_uid(); *bsize = DEV_BSIZE; if (r) { if (save_errno == EDQUOT) /* disk quota exceeded */ { *dfree = 0; *dsize = D.dqb_curblocks; return (True); } else return (False); } /* If softlimit is zero, set it equal to hardlimit. */ if (D.dqb_bsoftlimit==0) D.dqb_bsoftlimit = D.dqb_bhardlimit; /* Use softlimit to determine disk space, except when it has been exceeded */ if (D.dqb_bsoftlimit==0) return(False); if ((D.dqb_curblocks>D.dqb_bsoftlimit)) { *dfree = 0; *dsize = D.dqb_curblocks; } else { *dfree = D.dqb_bsoftlimit - D.dqb_curblocks; *dsize = D.dqb_bsoftlimit; } return (True); }
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { int r; struct dqblk D; uid_t euser_id; #if !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__) char dev_disk[256]; SMB_STRUCT_STAT S; /* find the block device file */ #ifdef HPUX /* Need to set the cache flag to 1 for HPUX. Seems * to have a significant performance boost when * lstat calls on /dev access this function. */ 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)) return (False); #endif /* ifdef HPUX */ #endif /* !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__) */ euser_id = geteuid(); #ifdef HPUX /* for HPUX, real uid must be same as euid to execute quotactl for euid */ save_re_uid(); if (set_re_uid() != 0) return False; r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D); restore_re_uid(); #else #if defined(__FreeBSD__) || defined(__OpenBSD__) { /* FreeBSD patches from Marty Moll <*****@*****.**> */ gid_t egrp_id; save_re_uid(); set_effective_uid(0); egrp_id = getegid(); r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D); /* As FreeBSD has group quotas, if getting the user quota fails, try getting the group instead. */ if (r) { r= quotactl(path,QCMD(Q_GETQUOTA,GRPQUOTA),egrp_id,(char *) &D); } restore_re_uid(); } #elif defined(AIX) /* AIX has both USER and GROUP quotas: Get the USER quota ([email protected]) */ r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D); #else /* !__FreeBSD__ && !AIX && !__OpenBSD__ */ r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D); #endif /* !__FreeBSD__ && !AIX && !__OpenBSD__ */ #endif /* HPUX */ /* Use softlimit to determine disk space, except when it has been exceeded */ #if defined(__FreeBSD__) || defined(__OpenBSD__) *bsize = DEV_BSIZE; #else /* !__FreeBSD__ && !__OpenBSD__ */ *bsize = 1024; #endif /*!__FreeBSD__ && !__OpenBSD__ */ if (r) { if (errno == EDQUOT) { *dfree =0; *dsize =D.dqb_curblocks; return (True); } else return(False); } /* If softlimit is zero, set it equal to hardlimit. */ if (D.dqb_bsoftlimit==0) D.dqb_bsoftlimit = D.dqb_bhardlimit; if (D.dqb_bsoftlimit==0) return(False); /* Use softlimit to determine disk space, except when it has been exceeded */ if ((D.dqb_curblocks>D.dqb_bsoftlimit) #if !defined(__FreeBSD__) && !defined(__OpenBSD__) ||((D.dqb_curfiles>D.dqb_fsoftlimit) && (D.dqb_fsoftlimit != 0)) #endif ) { *dfree = 0; *dsize = D.dqb_curblocks; } else { *dfree = D.dqb_bsoftlimit - D.dqb_curblocks; *dsize = D.dqb_bsoftlimit; } return (True); }
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { uid_t euser_id; int r; struct dqblk D; struct fs_disk_quota F; SMB_STRUCT_STAT S; FILE *fp; struct mntent *mnt; SMB_DEV_T devno; int found; /* find the block device file */ if ( sys_stat(path, &S) == -1 ) { return(False) ; } devno = S.st_dev ; fp = setmntent(MOUNTED,"r"); found = False ; while ((mnt = getmntent(fp))) { if ( sys_stat(mnt->mnt_dir,&S) == -1 ) continue ; if (S.st_dev == devno) { found = True ; break ; } } endmntent(fp) ; if (!found) { return(False); } euser_id=geteuid(); save_re_uid(); set_effective_uid(0); /* Use softlimit to determine disk space, except when it has been exceeded */ *bsize = 512; if ( 0 == strcmp ( mnt->mnt_type, "efs" )) { r=quotactl (Q_GETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &D); restore_re_uid(); if (r==-1) return(False); /* Use softlimit to determine disk space, except when it has been exceeded */ if ( (D.dqb_bsoftlimit && D.dqb_curblocks>=D.dqb_bsoftlimit) || (D.dqb_bhardlimit && D.dqb_curblocks>=D.dqb_bhardlimit) || (D.dqb_fsoftlimit && D.dqb_curfiles>=D.dqb_fsoftlimit) || (D.dqb_fhardlimit && D.dqb_curfiles>=D.dqb_fhardlimit) ) { *dfree = 0; *dsize = D.dqb_curblocks; } else if (D.dqb_bsoftlimit==0 && D.dqb_bhardlimit==0) { return(False); } else { *dfree = D.dqb_bsoftlimit - D.dqb_curblocks; *dsize = D.dqb_bsoftlimit; } } else if ( 0 == strcmp ( mnt->mnt_type, "xfs" )) { r=quotactl (Q_XGETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &F); restore_re_uid(); if (r==-1) return(False); /* Use softlimit to determine disk space, except when it has been exceeded */ if ( (F.d_blk_softlimit && F.d_bcount>=F.d_blk_softlimit) || (F.d_blk_hardlimit && F.d_bcount>=F.d_blk_hardlimit) || (F.d_ino_softlimit && F.d_icount>=F.d_ino_softlimit) || (F.d_ino_hardlimit && F.d_icount>=F.d_ino_hardlimit) ) { *dfree = 0; *dsize = F.d_bcount; } else if (F.d_blk_softlimit==0 && F.d_blk_hardlimit==0) { return(False); } else { *dfree = (F.d_blk_softlimit - F.d_bcount); *dsize = F.d_blk_softlimit; } } else { restore_re_uid(); return(False); } return (True); }
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { uid_t euser_id; int ret; struct dqblk D; #if defined(SUNOS5) struct quotctl command; int file; static struct mnttab mnt; static pstring name; pstring devopt; #else /* SunOS4 */ struct mntent *mnt; static pstring name; #endif FILE *fd; SMB_STRUCT_STAT sbuf; SMB_DEV_T devno ; static SMB_DEV_T devno_cached = 0 ; static int found ; euser_id = geteuid(); if ( sys_stat(path,&sbuf) == -1 ) return(False) ; devno = sbuf.st_dev ; DEBUG(5,("disk_quotas: looking for path \"%s\" devno=%x\n", path,(unsigned int)devno)); if ( devno != devno_cached ) { devno_cached = devno ; #if defined(SUNOS5) if ((fd = sys_fopen(MNTTAB, "r")) == NULL) return(False) ; found = False ; slprintf(devopt, sizeof(devopt) - 1, "dev=%x", (unsigned int)devno); while (getmntent(fd, &mnt) == 0) { if( !hasmntopt(&mnt, devopt) ) continue; DEBUG(5,("disk_quotas: testing \"%s\" %s\n", mnt.mnt_mountp,devopt)); /* quotas are only on vxfs, UFS or NFS */ if ( strcmp( mnt.mnt_fstype, MNTTYPE_UFS ) == 0 || strcmp( mnt.mnt_fstype, "nfs" ) == 0 || strcmp( mnt.mnt_fstype, "vxfs" ) == 0 ) { found = True ; break; } } pstrcpy(name,mnt.mnt_mountp) ; pstrcat(name,"/quotas") ; fclose(fd) ; #else /* SunOS4 */ if ((fd = setmntent(MOUNTED, "r")) == NULL) return(False) ; found = False ; while ((mnt = getmntent(fd)) != NULL) { if ( sys_stat(mnt->mnt_dir,&sbuf) == -1 ) continue ; DEBUG(5,("disk_quotas: testing \"%s\" devno=%x\n", mnt->mnt_dir,(unsigned int)sbuf.st_dev)); if (sbuf.st_dev == devno) { found = True ; break; } } pstrcpy(name,mnt->mnt_fsname) ; endmntent(fd) ; #endif } if ( ! found ) return(False) ; save_re_uid(); set_effective_uid(0); #if defined(SUNOS5) if ( strcmp( mnt.mnt_fstype, "nfs" ) == 0) { BOOL retval; DEBUG(5,("disk_quotas: looking for mountpath (NFS) \"%s\"\n", mnt.mnt_special)); retval = nfs_quotas(mnt.mnt_special, euser_id, bsize, dfree, dsize); restore_re_uid(); return retval; } DEBUG(5,("disk_quotas: looking for quotas file \"%s\"\n", name)); if((file=sys_open(name, O_RDONLY,0))<0) { restore_re_uid(); return(False); } command.op = Q_GETQUOTA; command.uid = euser_id; command.addr = (caddr_t) &D; ret = ioctl(file, Q_QUOTACTL, &command); close(file); #else DEBUG(5,("disk_quotas: trying quotactl on device \"%s\"\n", name)); ret = quotactl(Q_GETQUOTA, name, euser_id, &D); #endif restore_re_uid(); if (ret < 0) { DEBUG(5,("disk_quotas ioctl (Solaris) failed. Error = %s\n", strerror(errno) )); #if defined(SUNOS5) && defined(VXFS_QUOTA) /* If normal quotactl() fails, try vxfs private calls */ set_effective_uid(euser_id); DEBUG(5,("disk_quotas: mount type \"%s\"\n", mnt.mnt_fstype)); if ( 0 == strcmp ( mnt.mnt_fstype, "vxfs" )) { BOOL retval; retval = disk_quotas_vxfs(name, path, bsize, dfree, dsize); return(retval); } #else return(False); #endif } /* If softlimit is zero, set it equal to hardlimit. */ if (D.dqb_bsoftlimit==0) D.dqb_bsoftlimit = D.dqb_bhardlimit; /* Use softlimit to determine disk space. A user exceeding the quota is told * that there's no space left. Writes might actually work for a bit if the * hardlimit is set higher than softlimit. Effectively the disk becomes * made of rubber latex and begins to expand to accommodate the user :-) */ if (D.dqb_bsoftlimit==0) return(False); *bsize = DEV_BSIZE; *dsize = D.dqb_bsoftlimit; if (D.dqb_curblocks > D.dqb_bsoftlimit) { *dfree = 0; *dsize = D.dqb_curblocks; } else *dfree = D.dqb_bsoftlimit - D.dqb_curblocks; DEBUG(5,("disk_quotas for path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n", path,(double)*bsize,(double)*dfree,(double)*dsize)); return(True); }
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { int r; SMB_STRUCT_STAT S; FILE *fp; LINUX_SMB_DISK_QUOTA D; struct mntent *mnt; SMB_DEV_T devno; int found; uid_t euser_id; euser_id = geteuid(); /* find the block device file */ if ( sys_stat(path, &S) == -1 ) return(False) ; devno = S.st_dev ; fp = setmntent(MOUNTED,"r"); found = False ; while ((mnt = getmntent(fp))) { if ( sys_stat(mnt->mnt_dir,&S) == -1 ) continue ; if (S.st_dev == devno) { found = True ; break; } } endmntent(fp) ; if (!found) return(False); save_re_uid(); set_effective_uid(0); if (strcmp(mnt->mnt_type, "xfs")) { r=get_smb_linux_gen_quota(mnt->mnt_fsname, euser_id, &D); if (r == -1) { r=get_smb_linux_v2_quota(mnt->mnt_fsname, euser_id, &D); if (r == -1) r=get_smb_linux_v1_quota(mnt->mnt_fsname, euser_id, &D); } } else { r=get_smb_linux_xfs_quota(mnt->mnt_fsname, euser_id, &D); } restore_re_uid(); /* Use softlimit to determine disk space, except when it has been exceeded */ *bsize = D.bsize; if (r == -1) { if (errno == EDQUOT) { *dfree =0; *dsize =D.curblocks; return (True); } else { return(False); } } /* Use softlimit to determine disk space, except when it has been exceeded */ if ( (D.softlimit && D.curblocks >= D.softlimit) || (D.hardlimit && D.curblocks >= D.hardlimit) || (D.isoftlimit && D.curinodes >= D.isoftlimit) || (D.ihardlimit && D.curinodes>=D.ihardlimit) ) { *dfree = 0; *dsize = D.curblocks; } else if (D.softlimit==0 && D.hardlimit==0) { return(False); } else { if (D.softlimit == 0) D.softlimit = D.hardlimit; *dfree = D.softlimit - D.curblocks; *dsize = D.softlimit; } return (True); }
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { int r; struct dqblk D; uid_t euser_id; #if !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__) && !defined(__DragonFly__) char dev_disk[256]; SMB_STRUCT_STAT S; /* find the block device file */ #ifdef HPUX /* Need to set the cache flag to 1 for HPUX. Seems * to have a significant performance boost when * lstat calls on /dev access this function. */ 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)) return (False); #endif /* ifdef HPUX */ #endif /* !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__) && !defined(__DragonFly__) */ euser_id = geteuid(); #ifdef HPUX /* for HPUX, real uid must be same as euid to execute quotactl for euid */ save_re_uid(); if (set_re_uid() != 0) return False; r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D); restore_re_uid(); #else #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) { /* FreeBSD patches from Marty Moll <*****@*****.**> */ gid_t egrp_id; #if defined(__FreeBSD__) || defined(__DragonFly__) SMB_DEV_T devno; struct statfs *mnts; SMB_STRUCT_STAT st; int mntsize, i; if (sys_stat(path,&st) < 0) return False; devno = st.st_dev; mntsize = getmntinfo(&mnts,MNT_NOWAIT); if (mntsize <= 0) return False; for (i = 0; i < mntsize; i++) { if (sys_stat(mnts[i].f_mntonname,&st) < 0) return False; if (st.st_dev == devno) break; } if (i == mntsize) return False; #endif become_root(); #if defined(__FreeBSD__) || defined(__DragonFly__) if (strcmp(mnts[i].f_fstypename,"nfs") == 0) { BOOL retval; retval = nfs_quotas(mnts[i].f_mntfromname,euser_id,bsize,dfree,dsize); unbecome_root(); return retval; } #endif egrp_id = getegid(); r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D); /* As FreeBSD has group quotas, if getting the user quota fails, try getting the group instead. */ if (r) { r= quotactl(path,QCMD(Q_GETQUOTA,GRPQUOTA),egrp_id,(char *) &D); } unbecome_root(); } #elif defined(AIX) /* AIX has both USER and GROUP quotas: Get the USER quota ([email protected]) */ #ifdef _AIXVERSION_530 { struct statfs statbuf; quota64_t user_quota; if (statfs(path,&statbuf) != 0) return False; if(statbuf.f_vfstype == MNT_J2) { /* For some reason we need to be root for jfs2 */ become_root(); r = quotactl(path,QCMD(Q_J2GETQUOTA,USRQUOTA),euser_id,(char *) &user_quota); unbecome_root(); /* Copy results to old struct to let the following code work as before */ D.dqb_curblocks = user_quota.bused; D.dqb_bsoftlimit = user_quota.bsoft; D.dqb_bhardlimit = user_quota.bhard; } else if(statbuf.f_vfstype == MNT_JFS) { #endif /* AIX 5.3 */ save_re_uid(); if (set_re_uid() != 0) return False; r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D); restore_re_uid(); #ifdef _AIXVERSION_530 } else r = 1; /* Fail for other FS-types */ } #endif /* AIX 5.3 */ #else /* !__FreeBSD__ && !AIX && !__OpenBSD__ && !__DragonFly__ */ r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D); #endif /* !__FreeBSD__ && !AIX && !__OpenBSD__ && !__DragonFly__ */ #endif /* HPUX */ /* Use softlimit to determine disk space, except when it has been exceeded */ #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) *bsize = DEV_BSIZE; #else /* !__FreeBSD__ && !__OpenBSD__ && !__DragonFly__ */ *bsize = 1024; #endif /*!__FreeBSD__ && !__OpenBSD__ && !__DragonFly__ */ if (r) { if (errno == EDQUOT) { *dfree =0; *dsize =D.dqb_curblocks; return (True); } else return(False); } /* If softlimit is zero, set it equal to hardlimit. */ if (D.dqb_bsoftlimit==0) D.dqb_bsoftlimit = D.dqb_bhardlimit; if (D.dqb_bsoftlimit==0) return(False); /* Use softlimit to determine disk space, except when it has been exceeded */ if ((D.dqb_curblocks>D.dqb_bsoftlimit) #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__) ||((D.dqb_curfiles>D.dqb_fsoftlimit) && (D.dqb_fsoftlimit != 0)) #endif ) { *dfree = 0; *dsize = D.dqb_curblocks; } else { *dfree = D.dqb_bsoftlimit - D.dqb_curblocks; *dsize = D.dqb_bsoftlimit; } return (True); }