00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "includes.h"
00029
00030 #undef DBGC_CLASS
00031 #define DBGC_CLASS DBGC_QUOTA
00032
00033 #ifndef HAVE_SYS_QUOTAS
00034
00035
00036 #ifdef QUOTABLOCK_SIZE
00037 #undef QUOTABLOCK_SIZE
00038 #endif
00039
00040 #ifdef WITH_QUOTAS
00041
00042 #if defined(VXFS_QUOTA)
00043
00044
00045
00046
00047
00048
00049 BOOL disk_quotas_vxfs(const pstring name, char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
00050
00051 #endif
00052
00053 #ifdef LINUX
00054
00055 #include <sys/types.h>
00056 #include <mntent.h>
00057
00058
00059
00060
00061
00062
00063
00064 #include "samba_linux_quota.h"
00065 #include "samba_xfs_quota.h"
00066
00067 typedef struct _LINUX_SMB_DISK_QUOTA {
00068 SMB_BIG_UINT bsize;
00069 SMB_BIG_UINT hardlimit;
00070 SMB_BIG_UINT softlimit;
00071 SMB_BIG_UINT curblocks;
00072 SMB_BIG_UINT ihardlimit;
00073 SMB_BIG_UINT isoftlimit;
00074 SMB_BIG_UINT curinodes;
00075 } LINUX_SMB_DISK_QUOTA;
00076
00077
00078
00079
00080
00081 static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp)
00082 {
00083 struct fs_disk_quota D;
00084 int ret;
00085
00086 ZERO_STRUCT(D);
00087
00088 ret = quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D);
00089
00090 if (ret)
00091 ret = quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), path, egrp_id, (caddr_t)&D);
00092
00093 if (ret)
00094 return ret;
00095
00096 dp->bsize = (SMB_BIG_UINT)512;
00097 dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit;
00098 dp->hardlimit = (SMB_BIG_UINT)D.d_blk_hardlimit;
00099 dp->ihardlimit = (SMB_BIG_UINT)D.d_ino_hardlimit;
00100 dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit;
00101 dp->curinodes = (SMB_BIG_UINT)D.d_icount;
00102 dp->curblocks = (SMB_BIG_UINT)D.d_bcount;
00103
00104 return ret;
00105 }
00106
00107
00108
00109
00110
00111 static int get_smb_linux_v1_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp)
00112 {
00113 struct v1_kern_dqblk D;
00114 int ret;
00115
00116 ZERO_STRUCT(D);
00117
00118 ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D);
00119
00120 if (ret && errno != EDQUOT)
00121 ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), path, egrp_id, (caddr_t)&D);
00122
00123 if (ret && errno != EDQUOT)
00124 return ret;
00125
00126 dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
00127 dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
00128 dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
00129 dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
00130 dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit;
00131 dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
00132 dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks;
00133
00134 return ret;
00135 }
00136
00137 static int get_smb_linux_v2_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp)
00138 {
00139 struct v2_kern_dqblk D;
00140 int ret;
00141
00142 ZERO_STRUCT(D);
00143
00144 ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D);
00145
00146 if (ret && errno != EDQUOT)
00147 ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), path, egrp_id, (caddr_t)&D);
00148
00149 if (ret && errno != EDQUOT)
00150 return ret;
00151
00152 dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
00153 dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
00154 dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
00155 dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
00156 dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit;
00157 dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
00158 dp->curblocks = ((SMB_BIG_UINT)D.dqb_curspace) / dp->bsize;
00159
00160 return ret;
00161 }
00162
00163
00164
00165
00166
00167 static int get_smb_linux_gen_quota(char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp)
00168 {
00169 struct if_dqblk D;
00170 int ret;
00171
00172 ZERO_STRUCT(D);
00173
00174 ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D);
00175
00176 if (ret && errno != EDQUOT)
00177 ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), path, egrp_id, (caddr_t)&D);
00178
00179 if (ret && errno != EDQUOT)
00180 return ret;
00181
00182 dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
00183 dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
00184 dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
00185 dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
00186 dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit;
00187 dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
00188 dp->curblocks = ((SMB_BIG_UINT)D.dqb_curspace) / dp->bsize;
00189
00190 return ret;
00191 }
00192
00193
00194
00195
00196
00197 BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
00198 {
00199 int r;
00200 SMB_STRUCT_STAT S;
00201 FILE *fp;
00202 LINUX_SMB_DISK_QUOTA D;
00203 struct mntent *mnt;
00204 SMB_DEV_T devno;
00205 int found;
00206 uid_t euser_id;
00207 gid_t egrp_id;
00208
00209 ZERO_STRUCT(D);
00210
00211 euser_id = geteuid();
00212 egrp_id = getegid();
00213
00214
00215
00216 if ( sys_stat(path, &S) == -1 )
00217 return(False) ;
00218
00219 devno = S.st_dev ;
00220
00221 if ((fp = setmntent(MOUNTED,"r")) == NULL)
00222 return(False) ;
00223
00224 found = False ;
00225
00226 while ((mnt = getmntent(fp))) {
00227 if ( sys_stat(mnt->mnt_dir,&S) == -1 )
00228 continue ;
00229
00230 if (S.st_dev == devno) {
00231 found = True ;
00232 break;
00233 }
00234 }
00235
00236 endmntent(fp) ;
00237
00238 if (!found)
00239 return(False);
00240
00241 become_root();
00242
00243 if (strcmp(mnt->mnt_type, "xfs")==0) {
00244 r=get_smb_linux_xfs_quota(mnt->mnt_fsname, euser_id, egrp_id, &D);
00245 } else {
00246 r=get_smb_linux_gen_quota(mnt->mnt_fsname, euser_id, egrp_id, &D);
00247 if (r == -1 && errno != EDQUOT) {
00248 r=get_smb_linux_v2_quota(mnt->mnt_fsname, euser_id, egrp_id, &D);
00249 if (r == -1 && errno != EDQUOT)
00250 r=get_smb_linux_v1_quota(mnt->mnt_fsname, euser_id, egrp_id, &D);
00251 }
00252 }
00253
00254 unbecome_root();
00255
00256
00257 *bsize = D.bsize;
00258 if (r == -1) {
00259 if (errno == EDQUOT) {
00260 *dfree =0;
00261 *dsize =D.curblocks;
00262 return (True);
00263 } else {
00264 return(False);
00265 }
00266 }
00267
00268
00269 if (
00270 (D.softlimit && D.curblocks >= D.softlimit) ||
00271 (D.hardlimit && D.curblocks >= D.hardlimit) ||
00272 (D.isoftlimit && D.curinodes >= D.isoftlimit) ||
00273 (D.ihardlimit && D.curinodes>=D.ihardlimit)
00274 ) {
00275 *dfree = 0;
00276 *dsize = D.curblocks;
00277 } else if (D.softlimit==0 && D.hardlimit==0) {
00278 return(False);
00279 } else {
00280 if (D.softlimit == 0)
00281 D.softlimit = D.hardlimit;
00282 *dfree = D.softlimit - D.curblocks;
00283 *dsize = D.softlimit;
00284 }
00285
00286 return (True);
00287 }
00288
00289 #elif defined(CRAY)
00290
00291 #include <sys/quota.h>
00292 #include <mntent.h>
00293
00294
00295
00296
00297
00298 BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
00299 {
00300 struct mntent *mnt;
00301 FILE *fd;
00302 SMB_STRUCT_STAT sbuf;
00303 SMB_DEV_T devno ;
00304 static SMB_DEV_T devno_cached = 0 ;
00305 static pstring name;
00306 struct q_request request ;
00307 struct qf_header header ;
00308 static int quota_default = 0 ;
00309 int found ;
00310
00311 if ( sys_stat(path,&sbuf) == -1 )
00312 return(False) ;
00313
00314 devno = sbuf.st_dev ;
00315
00316 if ( devno != devno_cached ) {
00317
00318 devno_cached = devno ;
00319
00320 if ((fd = setmntent(KMTAB)) == NULL)
00321 return(False) ;
00322
00323 found = False ;
00324
00325 while ((mnt = getmntent(fd)) != NULL) {
00326
00327 if ( sys_stat(mnt->mnt_dir,&sbuf) == -1 )
00328 continue ;
00329
00330 if (sbuf.st_dev == devno) {
00331
00332 found = True ;
00333 break ;
00334
00335 }
00336
00337 }
00338
00339 pstrcpy(name,mnt->mnt_dir) ;
00340 endmntent(fd) ;
00341
00342 if ( ! found )
00343 return(False) ;
00344 }
00345
00346 request.qf_magic = QF_MAGIC ;
00347 request.qf_entry.id = geteuid() ;
00348
00349 if (quotactl(name, Q_GETQUOTA, &request) == -1)
00350 return(False) ;
00351
00352 if ( ! request.user )
00353 return(False) ;
00354
00355 if ( request.qf_entry.user_q.f_quota == QFV_DEFAULT ) {
00356
00357 if ( ! quota_default ) {
00358
00359 if ( quotactl(name, Q_GETHEADER, &header) == -1 )
00360 return(False) ;
00361 else
00362 quota_default = header.user_h.def_fq ;
00363 }
00364
00365 *dfree = quota_default ;
00366
00367 }else if ( request.qf_entry.user_q.f_quota == QFV_PREVENT ) {
00368
00369 *dfree = 0 ;
00370
00371 }else{
00372
00373 *dfree = request.qf_entry.user_q.f_quota ;
00374
00375 }
00376
00377 *dsize = request.qf_entry.user_q.f_use ;
00378
00379 if ( *dfree < *dsize )
00380 *dfree = 0 ;
00381 else
00382 *dfree -= *dsize ;
00383
00384 *bsize = 4096 ;
00385
00386 return(True) ;
00387
00388 }
00389
00390
00391 #elif defined(SUNOS5) || defined(SUNOS4)
00392
00393 #include <fcntl.h>
00394 #include <sys/param.h>
00395 #if defined(SUNOS5)
00396 #include <sys/fs/ufs_quota.h>
00397 #include <sys/mnttab.h>
00398 #include <sys/mntent.h>
00399 #else
00400 #include <ufs/quota.h>
00401 #include <mntent.h>
00402 #endif
00403
00404 #if defined(SUNOS5)
00405
00406
00407
00408
00409
00410
00411
00412 #include <rpc/rpc.h>
00413 #include <rpc/types.h>
00414 #include <rpcsvc/rquota.h>
00415 #include <rpc/nettype.h>
00416 #include <rpc/xdr.h>
00417
00418 static int quotastat;
00419
00420 static int my_xdr_getquota_args(XDR *xdrsp, struct getquota_args *args)
00421 {
00422 if (!xdr_string(xdrsp, &args->gqa_pathp, RQ_PATHLEN ))
00423 return(0);
00424 if (!xdr_int(xdrsp, &args->gqa_uid))
00425 return(0);
00426 return (1);
00427 }
00428
00429 static int my_xdr_getquota_rslt(XDR *xdrsp, struct getquota_rslt *gqr)
00430 {
00431 if (!xdr_int(xdrsp, "astat)) {
00432 DEBUG(6,("nfs_quotas: Status bad or zero\n"));
00433 return 0;
00434 }
00435 if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_bsize)) {
00436 DEBUG(6,("nfs_quotas: Block size bad or zero\n"));
00437 return 0;
00438 }
00439 if (!xdr_bool(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_active)) {
00440 DEBUG(6,("nfs_quotas: Active bad or zero\n"));
00441 return 0;
00442 }
00443 if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_bhardlimit)) {
00444 DEBUG(6,("nfs_quotas: Hardlimit bad or zero\n"));
00445 return 0;
00446 }
00447 if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_bsoftlimit)) {
00448 DEBUG(6,("nfs_quotas: Softlimit bad or zero\n"));
00449 return 0;
00450 }
00451 if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_curblocks)) {
00452 DEBUG(6,("nfs_quotas: Currentblocks bad or zero\n"));
00453 return 0;
00454 }
00455 return (1);
00456 }
00457
00458
00459 static BOOL nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
00460 {
00461 uid_t uid = euser_id;
00462 struct dqblk D;
00463 char *mnttype = nfspath;
00464 CLIENT *clnt;
00465 struct getquota_rslt gqr;
00466 struct getquota_args args;
00467 char *cutstr, *pathname, *host, *testpath;
00468 int len;
00469 static struct timeval timeout = {2,0};
00470 enum clnt_stat clnt_stat;
00471 BOOL ret = True;
00472
00473 *bsize = *dfree = *dsize = (SMB_BIG_UINT)0;
00474
00475 len=strcspn(mnttype, ":");
00476 pathname=strstr(mnttype, ":");
00477 cutstr = (char *) SMB_MALLOC(len+1);
00478 if (!cutstr)
00479 return False;
00480
00481 memset(cutstr, '\0', len+1);
00482 host = strncat(cutstr,mnttype, sizeof(char) * len );
00483 DEBUG(5,("nfs_quotas: looking for mount on \"%s\"\n", cutstr));
00484 DEBUG(5,("nfs_quotas: of path \"%s\"\n", mnttype));
00485 testpath=strchr_m(mnttype, ':');
00486 args.gqa_pathp = testpath+1;
00487 args.gqa_uid = uid;
00488
00489 DEBUG(5,("nfs_quotas: Asking for host \"%s\" rpcprog \"%i\" rpcvers \"%i\" network \"%s\"\n", host, RQUOTAPROG, RQUOTAVERS, "udp"));
00490
00491 if ((clnt = clnt_create(host, RQUOTAPROG, RQUOTAVERS, "udp")) == NULL) {
00492 ret = False;
00493 goto out;
00494 }
00495
00496 clnt->cl_auth = authunix_create_default();
00497 DEBUG(9,("nfs_quotas: auth_success\n"));
00498
00499 clnt_stat=clnt_call(clnt, RQUOTAPROC_GETQUOTA, my_xdr_getquota_args, (caddr_t)&args, my_xdr_getquota_rslt, (caddr_t)&gqr, timeout);
00500
00501 if (clnt_stat != RPC_SUCCESS) {
00502 DEBUG(9,("nfs_quotas: clnt_call fail\n"));
00503 ret = False;
00504 goto out;
00505 }
00506
00507
00508
00509
00510
00511
00512
00513 switch ( quotastat ) {
00514 case 0:
00515 DEBUG(9,("nfs_quotas: Remote Quotas Failed! Error \"%i\" \n", quotastat ));
00516 ret = False;
00517 goto out;
00518
00519 case 1:
00520 DEBUG(9,("nfs_quotas: Good quota data\n"));
00521 D.dqb_bsoftlimit = gqr.getquota_rslt_u.gqr_rquota.rq_bsoftlimit;
00522 D.dqb_bhardlimit = gqr.getquota_rslt_u.gqr_rquota.rq_bhardlimit;
00523 D.dqb_curblocks = gqr.getquota_rslt_u.gqr_rquota.rq_curblocks;
00524 break;
00525
00526 case 2:
00527 case 3:
00528 D.dqb_bsoftlimit = 1;
00529 D.dqb_curblocks = 1;
00530 DEBUG(9,("nfs_quotas: Remote Quotas returned \"%i\" \n", quotastat ));
00531 break;
00532
00533 default:
00534 DEBUG(9,("nfs_quotas: Remote Quotas Questionable! Error \"%i\" \n", quotastat ));
00535 break;
00536 }
00537
00538 DEBUG(10,("nfs_quotas: Let`s look at D a bit closer... status \"%i\" bsize \"%i\" active? \"%i\" bhard \"%i\" bsoft \"%i\" curb \"%i\" \n",
00539 quotastat,
00540 gqr.getquota_rslt_u.gqr_rquota.rq_bsize,
00541 gqr.getquota_rslt_u.gqr_rquota.rq_active,
00542 gqr.getquota_rslt_u.gqr_rquota.rq_bhardlimit,
00543 gqr.getquota_rslt_u.gqr_rquota.rq_bsoftlimit,
00544 gqr.getquota_rslt_u.gqr_rquota.rq_curblocks));
00545
00546 *bsize = gqr.getquota_rslt_u.gqr_rquota.rq_bsize;
00547 *dsize = D.dqb_bsoftlimit;
00548
00549 if (D.dqb_curblocks == D.dqb_curblocks == 1)
00550 *bsize = 512;
00551
00552 if (D.dqb_curblocks > D.dqb_bsoftlimit) {
00553 *dfree = 0;
00554 *dsize = D.dqb_curblocks;
00555 } else
00556 *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
00557
00558 out:
00559
00560 if (clnt) {
00561 if (clnt->cl_auth)
00562 auth_destroy(clnt->cl_auth);
00563 clnt_destroy(clnt);
00564 }
00565
00566 DEBUG(5,("nfs_quotas: For path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n",args.gqa_pathp,(double)*bsize,(double)*dfree,(double)*dsize));
00567
00568 SAFE_FREE(cutstr);
00569 DEBUG(10,("nfs_quotas: End of nfs_quotas\n" ));
00570 return ret;
00571 }
00572 #endif
00573
00574
00575
00576
00577
00578
00579 BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
00580 {
00581 uid_t euser_id;
00582 int ret;
00583 struct dqblk D;
00584 #if defined(SUNOS5)
00585 struct quotctl command;
00586 int file;
00587 static struct mnttab mnt;
00588 static pstring name;
00589 #else
00590 struct mntent *mnt;
00591 static pstring name;
00592 #endif
00593 FILE *fd;
00594 SMB_STRUCT_STAT sbuf;
00595 SMB_DEV_T devno ;
00596 static SMB_DEV_T devno_cached = 0 ;
00597 static int found ;
00598
00599 euser_id = geteuid();
00600
00601 if ( sys_stat(path,&sbuf) == -1 )
00602 return(False) ;
00603
00604 devno = sbuf.st_dev ;
00605 DEBUG(5,("disk_quotas: looking for path \"%s\" devno=%x\n",
00606 path, (unsigned int)devno));
00607 if ( devno != devno_cached ) {
00608 devno_cached = devno ;
00609 #if defined(SUNOS5)
00610 if ((fd = sys_fopen(MNTTAB, "r")) == NULL)
00611 return(False) ;
00612
00613 found = False ;
00614
00615 while (getmntent(fd, &mnt) == 0) {
00616 if (sys_stat(mnt.mnt_mountp, &sbuf) == -1)
00617 continue;
00618
00619 DEBUG(5,("disk_quotas: testing \"%s\" devno=%x\n",
00620 mnt.mnt_mountp, (unsigned int)devno));
00621
00622
00623 if ( (sbuf.st_dev == devno) && (
00624 strcmp( mnt.mnt_fstype, MNTTYPE_UFS ) == 0 ||
00625 strcmp( mnt.mnt_fstype, "nfs" ) == 0 ||
00626 strcmp( mnt.mnt_fstype, "vxfs" ) == 0 )) {
00627 found = True ;
00628 break;
00629 }
00630 }
00631
00632 pstrcpy(name,mnt.mnt_mountp) ;
00633 pstrcat(name,"/quotas") ;
00634 fclose(fd) ;
00635 #else
00636 if ((fd = setmntent(MOUNTED, "r")) == NULL)
00637 return(False) ;
00638
00639 found = False ;
00640 while ((mnt = getmntent(fd)) != NULL) {
00641 if ( sys_stat(mnt->mnt_dir,&sbuf) == -1 )
00642 continue ;
00643 DEBUG(5,("disk_quotas: testing \"%s\" devno=%x\n", mnt->mnt_dir,(unsigned int)sbuf.st_dev));
00644 if (sbuf.st_dev == devno) {
00645 found = True ;
00646 break;
00647 }
00648 }
00649
00650 pstrcpy(name,mnt->mnt_fsname) ;
00651 endmntent(fd) ;
00652 #endif
00653 }
00654
00655 if ( ! found )
00656 return(False) ;
00657
00658 become_root();
00659
00660 #if defined(SUNOS5)
00661 if ( strcmp( mnt.mnt_fstype, "nfs" ) == 0) {
00662 BOOL retval;
00663 DEBUG(5,("disk_quotas: looking for mountpath (NFS) \"%s\"\n", mnt.mnt_special));
00664 retval = nfs_quotas(mnt.mnt_special, euser_id, bsize, dfree, dsize);
00665 unbecome_root();
00666 return retval;
00667 }
00668
00669 DEBUG(5,("disk_quotas: looking for quotas file \"%s\"\n", name));
00670 if((file=sys_open(name, O_RDONLY,0))<0) {
00671 unbecome_root();
00672 return(False);
00673 }
00674 command.op = Q_GETQUOTA;
00675 command.uid = euser_id;
00676 command.addr = (caddr_t) &D;
00677 ret = ioctl(file, Q_QUOTACTL, &command);
00678 close(file);
00679 #else
00680 DEBUG(5,("disk_quotas: trying quotactl on device \"%s\"\n", name));
00681 ret = quotactl(Q_GETQUOTA, name, euser_id, &D);
00682 #endif
00683
00684 unbecome_root();
00685
00686 if (ret < 0) {
00687 DEBUG(5,("disk_quotas ioctl (Solaris) failed. Error = %s\n", strerror(errno) ));
00688
00689 #if defined(SUNOS5) && defined(VXFS_QUOTA)
00690
00691 set_effective_uid(euser_id);
00692 DEBUG(5,("disk_quotas: mount type \"%s\"\n", mnt.mnt_fstype));
00693 if ( 0 == strcmp ( mnt.mnt_fstype, "vxfs" )) {
00694 BOOL retval;
00695 retval = disk_quotas_vxfs(name, path, bsize, dfree, dsize);
00696 return(retval);
00697 }
00698 #else
00699 return(False);
00700 #endif
00701 }
00702
00703
00704
00705
00706 if (D.dqb_bsoftlimit==0)
00707 D.dqb_bsoftlimit = D.dqb_bhardlimit;
00708
00709
00710
00711
00712
00713
00714
00715 if (D.dqb_bsoftlimit==0)
00716 return(False);
00717 *bsize = DEV_BSIZE;
00718 *dsize = D.dqb_bsoftlimit;
00719
00720 if (D.dqb_curblocks > D.dqb_bsoftlimit) {
00721 *dfree = 0;
00722 *dsize = D.dqb_curblocks;
00723 } else
00724 *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
00725
00726 DEBUG(5,("disk_quotas for path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n",
00727 path,(double)*bsize,(double)*dfree,(double)*dsize));
00728
00729 return(True);
00730 }
00731
00732
00733 #elif defined(OSF1)
00734 #include <ufs/quota.h>
00735
00736
00737
00738
00739
00740 BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
00741 {
00742 int r, save_errno;
00743 struct dqblk D;
00744 SMB_STRUCT_STAT S;
00745 uid_t euser_id;
00746
00747
00748
00749
00750
00751
00752 euser_id = geteuid();
00753 save_re_uid();
00754 if (set_re_uid() != 0) return False;
00755
00756 r= quotactl(path,QCMD(Q_GETQUOTA, USRQUOTA),euser_id,(char *) &D);
00757 if (r) {
00758 save_errno = errno;
00759 }
00760
00761 restore_re_uid();
00762
00763 *bsize = DEV_BSIZE;
00764
00765 if (r)
00766 {
00767 if (save_errno == EDQUOT)
00768 {
00769 *dfree = 0;
00770 *dsize = D.dqb_curblocks;
00771 return (True);
00772 }
00773 else
00774 return (False);
00775 }
00776
00777
00778
00779
00780 if (D.dqb_bsoftlimit==0)
00781 D.dqb_bsoftlimit = D.dqb_bhardlimit;
00782
00783
00784
00785 if (D.dqb_bsoftlimit==0)
00786 return(False);
00787
00788 if ((D.dqb_curblocks>D.dqb_bsoftlimit)) {
00789 *dfree = 0;
00790 *dsize = D.dqb_curblocks;
00791 } else {
00792 *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
00793 *dsize = D.dqb_bsoftlimit;
00794 }
00795 return (True);
00796 }
00797
00798 #elif defined (IRIX6)
00799
00800
00801
00802
00803 #include <sys/quota.h>
00804 #include <mntent.h>
00805
00806 BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
00807 {
00808 uid_t euser_id;
00809 int r;
00810 struct dqblk D;
00811 struct fs_disk_quota F;
00812 SMB_STRUCT_STAT S;
00813 FILE *fp;
00814 struct mntent *mnt;
00815 SMB_DEV_T devno;
00816 int found;
00817
00818
00819
00820 if ( sys_stat(path, &S) == -1 ) {
00821 return(False) ;
00822 }
00823
00824 devno = S.st_dev ;
00825
00826 fp = setmntent(MOUNTED,"r");
00827 found = False ;
00828
00829 while ((mnt = getmntent(fp))) {
00830 if ( sys_stat(mnt->mnt_dir,&S) == -1 )
00831 continue ;
00832 if (S.st_dev == devno) {
00833 found = True ;
00834 break ;
00835 }
00836 }
00837 endmntent(fp) ;
00838
00839 if (!found) {
00840 return(False);
00841 }
00842
00843 euser_id=geteuid();
00844 become_root();
00845
00846
00847
00848 *bsize = 512;
00849
00850 if ( 0 == strcmp ( mnt->mnt_type, "efs" ))
00851 {
00852 r=quotactl (Q_GETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &D);
00853
00854 unbecome_root();
00855
00856 if (r==-1)
00857 return(False);
00858
00859
00860 if (
00861 (D.dqb_bsoftlimit && D.dqb_curblocks>=D.dqb_bsoftlimit) ||
00862 (D.dqb_bhardlimit && D.dqb_curblocks>=D.dqb_bhardlimit) ||
00863 (D.dqb_fsoftlimit && D.dqb_curfiles>=D.dqb_fsoftlimit) ||
00864 (D.dqb_fhardlimit && D.dqb_curfiles>=D.dqb_fhardlimit)
00865 )
00866 {
00867 *dfree = 0;
00868 *dsize = D.dqb_curblocks;
00869 }
00870 else if (D.dqb_bsoftlimit==0 && D.dqb_bhardlimit==0)
00871 {
00872 return(False);
00873 }
00874 else
00875 {
00876 *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
00877 *dsize = D.dqb_bsoftlimit;
00878 }
00879
00880 }
00881 else if ( 0 == strcmp ( mnt->mnt_type, "xfs" ))
00882 {
00883 r=quotactl (Q_XGETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &F);
00884
00885 unbecome_root();
00886
00887 if (r==-1)
00888 {
00889 DEBUG(5, ("quotactl for uid=%u: %s", euser_id, strerror(errno)));
00890 return(False);
00891 }
00892
00893
00894 if (F.d_blk_softlimit==0 && F.d_blk_hardlimit==0)
00895 {
00896 return(False);
00897 }
00898
00899
00900 if (
00901 (F.d_blk_softlimit && F.d_bcount>=F.d_blk_softlimit) ||
00902 (F.d_blk_hardlimit && F.d_bcount>=F.d_blk_hardlimit) ||
00903 (F.d_ino_softlimit && F.d_icount>=F.d_ino_softlimit) ||
00904 (F.d_ino_hardlimit && F.d_icount>=F.d_ino_hardlimit)
00905 )
00906 {
00907 *dfree = 0;
00908 *dsize = F.d_bcount;
00909 }
00910 else
00911 {
00912 *dfree = (F.d_blk_softlimit - F.d_bcount);
00913 *dsize = F.d_blk_softlimit ? F.d_blk_softlimit : F.d_blk_hardlimit;
00914 }
00915
00916 }
00917 else
00918 {
00919 unbecome_root();
00920 return(False);
00921 }
00922
00923 return (True);
00924
00925 }
00926
00927 #else
00928
00929 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
00930 #include <ufs/ufs/quota.h>
00931 #include <machine/param.h>
00932 #elif AIX
00933
00934 #include <jfs/quota.h>
00935
00936 #define dqb_curfiles dqb_curinodes
00937 #define dqb_fhardlimit dqb_ihardlimit
00938 #define dqb_fsoftlimit dqb_isoftlimit
00939 #ifdef _AIXVERSION_530
00940 #include <sys/statfs.h>
00941 #include <sys/vmount.h>
00942 #endif
00943 #else
00944 #include <sys/quota.h>
00945 #include <devnm.h>
00946 #endif
00947
00948 #if defined(__FreeBSD__) || defined(__DragonFly__)
00949
00950 #include <rpc/rpc.h>
00951 #include <rpc/types.h>
00952 #include <rpcsvc/rquota.h>
00953 #ifdef HAVE_RPC_NETTYPE_H
00954 #include <rpc/nettype.h>
00955 #endif
00956 #include <rpc/xdr.h>
00957
00958 static int quotastat;
00959
00960 static int my_xdr_getquota_args(XDR *xdrsp, struct getquota_args *args)
00961 {
00962 if (!xdr_string(xdrsp, &args->gqa_pathp, RQ_PATHLEN ))
00963 return(0);
00964 if (!xdr_int(xdrsp, &args->gqa_uid))
00965 return(0);
00966 return (1);
00967 }
00968
00969 static int my_xdr_getquota_rslt(XDR *xdrsp, struct getquota_rslt *gqr)
00970 {
00971 if (!xdr_int(xdrsp, "astat)) {
00972 DEBUG(6,("nfs_quotas: Status bad or zero\n"));
00973 return 0;
00974 }
00975 if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_bsize)) {
00976 DEBUG(6,("nfs_quotas: Block size bad or zero\n"));
00977 return 0;
00978 }
00979 if (!xdr_bool(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_active)) {
00980 DEBUG(6,("nfs_quotas: Active bad or zero\n"));
00981 return 0;
00982 }
00983 if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_bhardlimit)) {
00984 DEBUG(6,("nfs_quotas: Hardlimit bad or zero\n"));
00985 return 0;
00986 }
00987 if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_bsoftlimit)) {
00988 DEBUG(6,("nfs_quotas: Softlimit bad or zero\n"));
00989 return 0;
00990 }
00991 if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_curblocks)) {
00992 DEBUG(6,("nfs_quotas: Currentblocks bad or zero\n"));
00993 return 0;
00994 }
00995 return (1);
00996 }
00997
00998
00999 static BOOL nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
01000 {
01001 uid_t uid = euser_id;
01002 struct dqblk D;
01003 char *mnttype = nfspath;
01004 CLIENT *clnt;
01005 struct getquota_rslt gqr;
01006 struct getquota_args args;
01007 char *cutstr, *pathname, *host, *testpath;
01008 int len;
01009 static struct timeval timeout = {2,0};
01010 enum clnt_stat clnt_stat;
01011 BOOL ret = True;
01012
01013 *bsize = *dfree = *dsize = (SMB_BIG_UINT)0;
01014
01015 len=strcspn(mnttype, ":");
01016 pathname=strstr(mnttype, ":");
01017 cutstr = (char *) SMB_MALLOC(len+1);
01018 if (!cutstr)
01019 return False;
01020
01021 memset(cutstr, '\0', len+1);
01022 host = strncat(cutstr,mnttype, sizeof(char) * len );
01023 DEBUG(5,("nfs_quotas: looking for mount on \"%s\"\n", cutstr));
01024 DEBUG(5,("nfs_quotas: of path \"%s\"\n", mnttype));
01025 testpath=strchr_m(mnttype, ':');
01026 args.gqa_pathp = testpath+1;
01027 args.gqa_uid = uid;
01028
01029 DEBUG(5,("nfs_quotas: Asking for host \"%s\" rpcprog \"%i\" rpcvers \"%i\" network \"%s\"\n", host, RQUOTAPROG, RQUOTAVERS, "udp"));
01030
01031 if ((clnt = clnt_create(host, RQUOTAPROG, RQUOTAVERS, "udp")) == NULL) {
01032 ret = False;
01033 goto out;
01034 }
01035
01036 clnt->cl_auth = authunix_create_default();
01037 DEBUG(9,("nfs_quotas: auth_success\n"));
01038
01039 clnt_stat=clnt_call(clnt, RQUOTAPROC_GETQUOTA, (const xdrproc_t) my_xdr_getquota_args, (caddr_t)&args, (const xdrproc_t) my_xdr_getquota_rslt, (caddr_t)&gqr, timeout);
01040
01041 if (clnt_stat != RPC_SUCCESS) {
01042 DEBUG(9,("nfs_quotas: clnt_call fail\n"));
01043 ret = False;
01044 goto out;
01045 }
01046
01047
01048
01049
01050
01051
01052
01053 switch ( quotastat ) {
01054 case 0:
01055 DEBUG(9,("nfs_quotas: Remote Quotas Failed! Error \"%i\" \n", quotastat ));
01056 ret = False;
01057 goto out;
01058
01059 case 1:
01060 DEBUG(9,("nfs_quotas: Good quota data\n"));
01061 D.dqb_bsoftlimit = gqr.getquota_rslt_u.gqr_rquota.rq_bsoftlimit;
01062 D.dqb_bhardlimit = gqr.getquota_rslt_u.gqr_rquota.rq_bhardlimit;
01063 D.dqb_curblocks = gqr.getquota_rslt_u.gqr_rquota.rq_curblocks;
01064 break;
01065
01066 case 2:
01067 case 3:
01068 D.dqb_bsoftlimit = 1;
01069 D.dqb_curblocks = 1;
01070 DEBUG(9,("nfs_quotas: Remote Quotas returned \"%i\" \n", quotastat ));
01071 break;
01072
01073 default:
01074 DEBUG(9,("nfs_quotas: Remote Quotas Questionable! Error \"%i\" \n", quotastat ));
01075 break;
01076 }
01077
01078 DEBUG(10,("nfs_quotas: Let`s look at D a bit closer... status \"%i\" bsize \"%i\" active? \"%i\" bhard \"%i\" bsoft \"%i\" curb \"%i\" \n",
01079 quotastat,
01080 gqr.getquota_rslt_u.gqr_rquota.rq_bsize,
01081 gqr.getquota_rslt_u.gqr_rquota.rq_active,
01082 gqr.getquota_rslt_u.gqr_rquota.rq_bhardlimit,
01083 gqr.getquota_rslt_u.gqr_rquota.rq_bsoftlimit,
01084 gqr.getquota_rslt_u.gqr_rquota.rq_curblocks));
01085
01086 if (D.dqb_bsoftlimit == 0)
01087 D.dqb_bsoftlimit = D.dqb_bhardlimit;
01088 if (D.dqb_bsoftlimit == 0)
01089 return False;
01090
01091 *bsize = gqr.getquota_rslt_u.gqr_rquota.rq_bsize;
01092 *dsize = D.dqb_bsoftlimit;
01093
01094 if (D.dqb_curblocks == D.dqb_curblocks == 1)
01095 *bsize = DEV_BSIZE;
01096
01097 if (D.dqb_curblocks > D.dqb_bsoftlimit) {
01098 *dfree = 0;
01099 *dsize = D.dqb_curblocks;
01100 } else
01101 *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
01102
01103 out:
01104
01105 if (clnt) {
01106 if (clnt->cl_auth)
01107 auth_destroy(clnt->cl_auth);
01108 clnt_destroy(clnt);
01109 }
01110
01111 DEBUG(5,("nfs_quotas: For path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n",args.gqa_pathp,(double)*bsize,(double)*dfree,(double)*dsize));
01112
01113 SAFE_FREE(cutstr);
01114 DEBUG(10,("nfs_quotas: End of nfs_quotas\n" ));
01115 return ret;
01116 }
01117
01118 #endif
01119
01120
01121
01122
01123
01124 BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
01125 {
01126 int r;
01127 struct dqblk D;
01128 uid_t euser_id;
01129 #if !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__) && !defined(__DragonFly__)
01130 char dev_disk[256];
01131 SMB_STRUCT_STAT S;
01132
01133
01134
01135 #ifdef HPUX
01136
01137
01138
01139
01140 if ((sys_stat(path, &S)<0) || (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 1)<0))
01141 #else
01142 if ((sys_stat(path, &S)<0) || (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 0)<0))
01143 return (False);
01144 #endif
01145
01146 #endif
01147
01148 euser_id = geteuid();
01149
01150 #ifdef HPUX
01151
01152 save_re_uid();
01153 if (set_re_uid() != 0) return False;
01154
01155 r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
01156
01157 restore_re_uid();
01158 #else
01159 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
01160 {
01161
01162 gid_t egrp_id;
01163 #if defined(__FreeBSD__) || defined(__DragonFly__)
01164 SMB_DEV_T devno;
01165 struct statfs *mnts;
01166 SMB_STRUCT_STAT st;
01167 int mntsize, i;
01168
01169 if (sys_stat(path,&st) < 0)
01170 return False;
01171 devno = st.st_dev;
01172
01173 mntsize = getmntinfo(&mnts,MNT_NOWAIT);
01174 if (mntsize <= 0)
01175 return False;
01176
01177 for (i = 0; i < mntsize; i++) {
01178 if (sys_stat(mnts[i].f_mntonname,&st) < 0)
01179 return False;
01180 if (st.st_dev == devno)
01181 break;
01182 }
01183 if (i == mntsize)
01184 return False;
01185 #endif
01186
01187 become_root();
01188
01189 #if defined(__FreeBSD__) || defined(__DragonFly__)
01190 if (strcmp(mnts[i].f_fstypename,"nfs") == 0) {
01191 BOOL retval;
01192 retval = nfs_quotas(mnts[i].f_mntfromname,euser_id,bsize,dfree,dsize);
01193 unbecome_root();
01194 return retval;
01195 }
01196 #endif
01197
01198 egrp_id = getegid();
01199 r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D);
01200
01201
01202
01203 if (r) {
01204 r= quotactl(path,QCMD(Q_GETQUOTA,GRPQUOTA),egrp_id,(char *) &D);
01205 }
01206
01207 unbecome_root();
01208 }
01209 #elif defined(AIX)
01210
01211
01212 #ifdef _AIXVERSION_530
01213 {
01214 struct statfs statbuf;
01215 quota64_t user_quota;
01216 if (statfs(path,&statbuf) != 0)
01217 return False;
01218 if(statbuf.f_vfstype == MNT_J2)
01219 {
01220
01221 become_root();
01222 r = quotactl(path,QCMD(Q_J2GETQUOTA,USRQUOTA),euser_id,(char *) &user_quota);
01223 unbecome_root();
01224
01225 D.dqb_curblocks = user_quota.bused;
01226 D.dqb_bsoftlimit = user_quota.bsoft;
01227 D.dqb_bhardlimit = user_quota.bhard;
01228 D.dqb_curfiles = user_quota.iused;
01229 D.dqb_fsoftlimit = user_quota.isoft;
01230 D.dqb_fhardlimit = user_quota.ihard;
01231 }
01232 else if(statbuf.f_vfstype == MNT_JFS)
01233 {
01234 #endif
01235 save_re_uid();
01236 if (set_re_uid() != 0)
01237 return False;
01238 r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D);
01239 restore_re_uid();
01240 #ifdef _AIXVERSION_530
01241 }
01242 else
01243 r = 1;
01244 }
01245 #endif
01246 #else
01247 r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
01248 #endif
01249 #endif
01250
01251
01252 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
01253 *bsize = DEV_BSIZE;
01254 #else
01255 *bsize = 1024;
01256 #endif
01257
01258 if (r)
01259 {
01260 if (errno == EDQUOT)
01261 {
01262 *dfree =0;
01263 *dsize =D.dqb_curblocks;
01264 return (True);
01265 }
01266 else return(False);
01267 }
01268
01269
01270
01271
01272 if (D.dqb_bsoftlimit==0)
01273 D.dqb_bsoftlimit = D.dqb_bhardlimit;
01274
01275 if (D.dqb_bsoftlimit==0)
01276 return(False);
01277
01278 if ((D.dqb_curblocks>D.dqb_bsoftlimit)
01279 #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__)
01280 ||((D.dqb_curfiles>D.dqb_fsoftlimit) && (D.dqb_fsoftlimit != 0))
01281 #endif
01282 ) {
01283 *dfree = 0;
01284 *dsize = D.dqb_curblocks;
01285 }
01286 else {
01287 *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
01288 *dsize = D.dqb_bsoftlimit;
01289 }
01290 return (True);
01291 }
01292
01293 #endif
01294
01295 #if defined(VXFS_QUOTA)
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332 #if defined(SUNOS5)
01333
01334 #if defined(SUNOS5)
01335 #include <sys/fs/vx_solaris.h>
01336 #endif
01337 #include <sys/fs/vx_machdep.h>
01338 #include <sys/fs/vx_layout.h>
01339 #include <sys/fs/vx_quota.h>
01340 #include <sys/fs/vx_aioctl.h>
01341 #include <sys/fs/vx_ioctl.h>
01342
01343 BOOL disk_quotas_vxfs(const pstring name, char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
01344 {
01345 uid_t user_id, euser_id;
01346 int ret;
01347 struct vx_dqblk D;
01348 struct vx_quotctl quotabuf;
01349 struct vx_genioctl genbuf;
01350 pstring qfname;
01351 int file;
01352
01353
01354
01355
01356
01357
01358
01359 pstrcpy(qfname, name) ;
01360
01361
01362 euser_id = geteuid();
01363 set_effective_uid(0);
01364
01365 DEBUG(5,("disk_quotas: looking for VxFS quotas file \"%s\"\n", qfname));
01366 if((file=sys_open(qfname, O_RDONLY,0))<0) {
01367 set_effective_uid(euser_id);
01368 return(False);
01369 }
01370 genbuf.ioc_cmd = VX_QUOTACTL;
01371 genbuf.ioc_up = (void *) "abuf;
01372
01373 quotabuf.cmd = VX_GETQUOTA;
01374 quotabuf.uid = euser_id;
01375 quotabuf.addr = (caddr_t) &D;
01376 ret = ioctl(file, VX_ADMIN_IOCTL, &genbuf);
01377 close(file);
01378
01379 set_effective_uid(euser_id);
01380
01381 if (ret < 0) {
01382 DEBUG(5,("disk_quotas ioctl (VxFS) failed. Error = %s\n", strerror(errno) ));
01383 return(False);
01384 }
01385
01386
01387
01388
01389 if (D.dqb_bsoftlimit==0)
01390 D.dqb_bsoftlimit = D.dqb_bhardlimit;
01391
01392
01393
01394
01395
01396
01397 DEBUG(5,("disk_quotas for path \"%s\" block c/s/h %ld/%ld/%ld; file c/s/h %ld/%ld/%ld\n",
01398 path, D.dqb_curblocks, D.dqb_bsoftlimit, D.dqb_bhardlimit,
01399 D.dqb_curfiles, D.dqb_fsoftlimit, D.dqb_fhardlimit));
01400
01401 if (D.dqb_bsoftlimit==0)
01402 return(False);
01403 *bsize = DEV_BSIZE;
01404 *dsize = D.dqb_bsoftlimit;
01405
01406 if (D.dqb_curblocks > D.dqb_bsoftlimit) {
01407 *dfree = 0;
01408 *dsize = D.dqb_curblocks;
01409 } else
01410 *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
01411
01412 DEBUG(5,("disk_quotas for path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n",
01413 path,(double)*bsize,(double)*dfree,(double)*dsize));
01414
01415 return(True);
01416 }
01417
01418 #endif
01419
01420 #endif
01421
01422 #else
01423
01424 BOOL disk_quotas(const char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
01425 {
01426 (*bsize) = 512;
01427
01428
01429
01430 (*dfree) = (SMB_BIG_UINT)-1;
01431 (*dsize) = (SMB_BIG_UINT)-1;
01432
01433
01434 return False;
01435 }
01436 #endif
01437
01438 #else
01439
01440
01441
01442 BOOL disk_quotas(const char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
01443 {
01444 int r;
01445 SMB_DISK_QUOTA D;
01446 unid_t id;
01447
01448 id.uid = geteuid();
01449
01450 ZERO_STRUCT(D);
01451 r=sys_get_quota(path, SMB_USER_QUOTA_TYPE, id, &D);
01452
01453
01454 *bsize = D.bsize;
01455 if (r == -1) {
01456 if (errno == EDQUOT) {
01457 *dfree =0;
01458 *dsize =D.curblocks;
01459 return (True);
01460 } else {
01461 goto try_group_quota;
01462 }
01463 }
01464
01465
01466 if (
01467 (D.softlimit && D.curblocks >= D.softlimit) ||
01468 (D.hardlimit && D.curblocks >= D.hardlimit) ||
01469 (D.isoftlimit && D.curinodes >= D.isoftlimit) ||
01470 (D.ihardlimit && D.curinodes>=D.ihardlimit)
01471 ) {
01472 *dfree = 0;
01473 *dsize = D.curblocks;
01474 } else if (D.softlimit==0 && D.hardlimit==0) {
01475 goto try_group_quota;
01476 } else {
01477 if (D.softlimit == 0)
01478 D.softlimit = D.hardlimit;
01479 *dfree = D.softlimit - D.curblocks;
01480 *dsize = D.softlimit;
01481 }
01482
01483 return True;
01484
01485 try_group_quota:
01486 id.gid = getegid();
01487
01488 ZERO_STRUCT(D);
01489 r=sys_get_quota(path, SMB_GROUP_QUOTA_TYPE, id, &D);
01490
01491
01492 *bsize = D.bsize;
01493 if (r == -1) {
01494 if (errno == EDQUOT) {
01495 *dfree =0;
01496 *dsize =D.curblocks;
01497 return (True);
01498 } else {
01499 return False;
01500 }
01501 }
01502
01503
01504 if (
01505 (D.softlimit && D.curblocks >= D.softlimit) ||
01506 (D.hardlimit && D.curblocks >= D.hardlimit) ||
01507 (D.isoftlimit && D.curinodes >= D.isoftlimit) ||
01508 (D.ihardlimit && D.curinodes>=D.ihardlimit)
01509 ) {
01510 *dfree = 0;
01511 *dsize = D.curblocks;
01512 } else if (D.softlimit==0 && D.hardlimit==0) {
01513 return False;
01514 } else {
01515 if (D.softlimit == 0)
01516 D.softlimit = D.hardlimit;
01517 *dfree = D.softlimit - D.curblocks;
01518 *dsize = D.softlimit;
01519 }
01520
01521 return (True);
01522 }
01523 #endif