データ構造 | |
struct | _LINUX_SMB_DISK_QUOTA |
型定義 | |
typedef _LINUX_SMB_DISK_QUOTA | LINUX_SMB_DISK_QUOTA |
関数 | |
BOOL | disk_quotas_vxfs (const pstring name, char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) |
static int | get_smb_linux_xfs_quota (char *path, uid_t euser_id, gid_t egrp_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) |
static int | get_smb_linux_v2_quota (char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp) |
static int | get_smb_linux_gen_quota (char *path, uid_t euser_id, gid_t egrp_id, LINUX_SMB_DISK_QUOTA *dp) |
BOOL | disk_quotas (const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) |
static int | my_xdr_getquota_args (XDR *xdrsp, struct getquota_args *args) |
static int | my_xdr_getquota_rslt (XDR *xdrsp, struct getquota_rslt *gqr) |
static BOOL | nfs_quotas (char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) |
変数 | |
static int | quotastat |
static int | quotastat |
typedef struct _LINUX_SMB_DISK_QUOTA LINUX_SMB_DISK_QUOTA |
BOOL disk_quotas_vxfs | ( | const pstring | name, | |
char * | path, | |||
SMB_BIG_UINT * | bsize, | |||
SMB_BIG_UINT * | dfree, | |||
SMB_BIG_UINT * | dsize | |||
) |
参照先 errno・set_effective_uid()・strerror()・sys_open().
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 * "name" may or may not include a trailing "/quotas". 01355 * Arranging consistency of calling here in "quotas.c" may not be easy and 01356 * it might be easier to examine and adjust it here. 01357 * Fortunately, VxFS seems not to mind at present. 01358 */ 01359 pstrcpy(qfname, name) ; 01360 /* pstrcat(qfname, "/quotas") ; */ /* possibly examine and adjust "name" */ 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 /* If softlimit is zero, set it equal to hardlimit. 01387 */ 01388 01389 if (D.dqb_bsoftlimit==0) 01390 D.dqb_bsoftlimit = D.dqb_bhardlimit; 01391 01392 /* Use softlimit to determine disk space. A user exceeding the quota is told 01393 * that there's no space left. Writes might actually work for a bit if the 01394 * hardlimit is set higher than softlimit. Effectively the disk becomes 01395 * made of rubber latex and begins to expand to accommodate the user :-) 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 }
static int get_smb_linux_xfs_quota | ( | char * | path, | |
uid_t | euser_id, | |||
gid_t | egrp_id, | |||
LINUX_SMB_DISK_QUOTA * | dp | |||
) | [static] |
参照先 _LINUX_SMB_DISK_QUOTA::bsize・_LINUX_SMB_DISK_QUOTA::curblocks・_LINUX_SMB_DISK_QUOTA::curinodes・D・_LINUX_SMB_DISK_QUOTA::hardlimit・_LINUX_SMB_DISK_QUOTA::ihardlimit・_LINUX_SMB_DISK_QUOTA::isoftlimit・_LINUX_SMB_DISK_QUOTA::softlimit.
参照元 disk_quotas().
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 }
static int get_smb_linux_v1_quota | ( | char * | path, | |
uid_t | euser_id, | |||
gid_t | egrp_id, | |||
LINUX_SMB_DISK_QUOTA * | dp | |||
) | [static] |
参照先 _LINUX_SMB_DISK_QUOTA::bsize・_LINUX_SMB_DISK_QUOTA::curblocks・_LINUX_SMB_DISK_QUOTA::curinodes・D・errno・_LINUX_SMB_DISK_QUOTA::hardlimit・_LINUX_SMB_DISK_QUOTA::ihardlimit・_LINUX_SMB_DISK_QUOTA::isoftlimit・_LINUX_SMB_DISK_QUOTA::softlimit.
参照元 disk_quotas().
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 }
static int get_smb_linux_v2_quota | ( | char * | path, | |
uid_t | euser_id, | |||
gid_t | egrp_id, | |||
LINUX_SMB_DISK_QUOTA * | dp | |||
) | [static] |
参照先 _LINUX_SMB_DISK_QUOTA::bsize・_LINUX_SMB_DISK_QUOTA::curblocks・_LINUX_SMB_DISK_QUOTA::curinodes・D・errno・_LINUX_SMB_DISK_QUOTA::hardlimit・_LINUX_SMB_DISK_QUOTA::ihardlimit・_LINUX_SMB_DISK_QUOTA::isoftlimit・_LINUX_SMB_DISK_QUOTA::softlimit.
参照元 disk_quotas().
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 }
static int get_smb_linux_gen_quota | ( | char * | path, | |
uid_t | euser_id, | |||
gid_t | egrp_id, | |||
LINUX_SMB_DISK_QUOTA * | dp | |||
) | [static] |
参照先 _LINUX_SMB_DISK_QUOTA::bsize・_LINUX_SMB_DISK_QUOTA::curblocks・_LINUX_SMB_DISK_QUOTA::curinodes・D・errno・_LINUX_SMB_DISK_QUOTA::hardlimit・_LINUX_SMB_DISK_QUOTA::ihardlimit・_LINUX_SMB_DISK_QUOTA::isoftlimit・_LINUX_SMB_DISK_QUOTA::softlimit.
参照元 disk_quotas().
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 }
BOOL disk_quotas | ( | const char * | path, | |
SMB_BIG_UINT * | bsize, | |||
SMB_BIG_UINT * | dfree, | |||
SMB_BIG_UINT * | dsize | |||
) |
参照先 become_root()・D・errno・fp・get_smb_linux_gen_quota()・get_smb_linux_v1_quota()・get_smb_linux_v2_quota()・get_smb_linux_xfs_quota()・sys_stat()・unbecome_root().
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 /* find the block device file */ 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 /* Use softlimit to determine disk space, except when it has been exceeded */ 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 /* Use softlimit to determine disk space, except when it has been exceeded */ 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 }
static int my_xdr_getquota_args | ( | XDR * | xdrsp, | |
struct getquota_args * | args | |||
) | [static] |
参照元 nfs_quotas().
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 }
static int my_xdr_getquota_rslt | ( | XDR * | xdrsp, | |
struct getquota_rslt * | gqr | |||
) | [static] |
参照元 nfs_quotas().
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 }
static BOOL nfs_quotas | ( | char * | nfspath, | |
uid_t | euser_id, | |||
SMB_BIG_UINT * | bsize, | |||
SMB_BIG_UINT * | dfree, | |||
SMB_BIG_UINT * | dsize | |||
) | [static] |
参照先 host・len・my_xdr_getquota_args()・my_xdr_getquota_rslt()・strchr_m().
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 * quotastat returns 0 if the rpc call fails, 1 if quotas exist, 2 if there is 00509 * no quota set, and 3 if no permission to get the quota. If 0 or 3 return 00510 * something sensible. 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 }