smbd/quotas.c

ソースコードを見る。

データ構造

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 
)

quotas.c1343 行で定義されています。

参照先 errnoset_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 *) &quotabuf;
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]

quotas.c81 行で定義されています。

参照先 _LINUX_SMB_DISK_QUOTA::bsize_LINUX_SMB_DISK_QUOTA::curblocks_LINUX_SMB_DISK_QUOTA::curinodesD_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]

quotas.c111 行で定義されています。

参照先 _LINUX_SMB_DISK_QUOTA::bsize_LINUX_SMB_DISK_QUOTA::curblocks_LINUX_SMB_DISK_QUOTA::curinodesDerrno_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]

quotas.c137 行で定義されています。

参照先 _LINUX_SMB_DISK_QUOTA::bsize_LINUX_SMB_DISK_QUOTA::curblocks_LINUX_SMB_DISK_QUOTA::curinodesDerrno_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]

quotas.c167 行で定義されています。

参照先 _LINUX_SMB_DISK_QUOTA::bsize_LINUX_SMB_DISK_QUOTA::curblocks_LINUX_SMB_DISK_QUOTA::curinodesDerrno_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 
)

quotas.c197 行で定義されています。

参照先 become_root()Derrnofpget_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]

quotas.c420 行で定義されています。

参照元 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]

quotas.c429 行で定義されています。

参照元 nfs_quotas().

00430 {
00431         if (!xdr_int(xdrsp, &quotastat)) {
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]

quotas.c459 行で定義されています。

参照先 hostlenmy_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 }


変数

int quotastat [static]

quotas.c418 行で定義されています。

int quotastat [static]

quotas.c958 行で定義されています。


Sambaに対してSat Aug 29 21:24:28 2009に生成されました。  doxygen 1.4.7