Loading source3/smbd/quotas.c +203 −1 Original line number Diff line number Diff line Loading @@ -933,6 +933,176 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB #include <devnm.h> #endif #if defined(__FreeBSD__) #include <rpc/rpc.h> #include <rpc/types.h> #include <rpcsvc/rquota.h> #include <rpc/nettype.h> #include <rpc/xdr.h> static int quotastat; static int my_xdr_getquota_args(XDR *xdrsp, struct getquota_args *args) { if (!xdr_string(xdrsp, &args->gqa_pathp, RQ_PATHLEN )) return(0); if (!xdr_int(xdrsp, &args->gqa_uid)) return(0); return (1); } static int my_xdr_getquota_rslt(XDR *xdrsp, struct getquota_rslt *gqr) { if (!xdr_int(xdrsp, "astat)) { DEBUG(6,("nfs_quotas: Status bad or zero\n")); return 0; } if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_bsize)) { DEBUG(6,("nfs_quotas: Block size bad or zero\n")); return 0; } if (!xdr_bool(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_active)) { DEBUG(6,("nfs_quotas: Active bad or zero\n")); return 0; } if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_bhardlimit)) { DEBUG(6,("nfs_quotas: Hardlimit bad or zero\n")); return 0; } if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_bsoftlimit)) { DEBUG(6,("nfs_quotas: Softlimit bad or zero\n")); return 0; } if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_curblocks)) { DEBUG(6,("nfs_quotas: Currentblocks bad or zero\n")); return 0; } return (1); } /* Works on FreeBSD, too. :-) */ static BOOL nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { uid_t uid = euser_id; struct dqblk D; char *mnttype = nfspath; CLIENT *clnt; struct getquota_rslt gqr; struct getquota_args args; char *cutstr, *pathname, *host, *testpath; int len; static struct timeval timeout = {2,0}; enum clnt_stat clnt_stat; BOOL ret = True; *bsize = *dfree = *dsize = (SMB_BIG_UINT)0; len=strcspn(mnttype, ":"); pathname=strstr(mnttype, ":"); cutstr = (char *) malloc(len+1); if (!cutstr) return False; memset(cutstr, '\0', len+1); host = strncat(cutstr,mnttype, sizeof(char) * len ); DEBUG(5,("nfs_quotas: looking for mount on \"%s\"\n", cutstr)); DEBUG(5,("nfs_quotas: of path \"%s\"\n", mnttype)); testpath=strchr_m(mnttype, ':'); args.gqa_pathp = testpath+1; args.gqa_uid = uid; DEBUG(5,("nfs_quotas: Asking for host \"%s\" rpcprog \"%i\" rpcvers \"%i\" network \"%s\"\n", host, RQUOTAPROG, RQUOTAVERS, "udp")); if ((clnt = clnt_create(host, RQUOTAPROG, RQUOTAVERS, "udp")) == NULL) { ret = False; goto out; } clnt->cl_auth = authunix_create_default(); DEBUG(9,("nfs_quotas: auth_success\n")); 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); if (clnt_stat != RPC_SUCCESS) { DEBUG(9,("nfs_quotas: clnt_call fail\n")); ret = False; goto out; } /* * quotastat returns 0 if the rpc call fails, 1 if quotas exist, 2 if there is * no quota set, and 3 if no permission to get the quota. If 0 or 3 return * something sensible. */ switch ( quotastat ) { case 0: DEBUG(9,("nfs_quotas: Remote Quotas Failed! Error \"%i\" \n", quotastat )); ret = False; goto out; case 1: DEBUG(9,("nfs_quotas: Good quota data\n")); D.dqb_bsoftlimit = gqr.getquota_rslt_u.gqr_rquota.rq_bsoftlimit; D.dqb_bhardlimit = gqr.getquota_rslt_u.gqr_rquota.rq_bhardlimit; D.dqb_curblocks = gqr.getquota_rslt_u.gqr_rquota.rq_curblocks; break; case 2: case 3: D.dqb_bsoftlimit = 1; D.dqb_curblocks = 1; DEBUG(9,("nfs_quotas: Remote Quotas returned \"%i\" \n", quotastat )); break; default: DEBUG(9,("nfs_quotas: Remote Quotas Questionable! Error \"%i\" \n", quotastat )); break; } 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", quotastat, gqr.getquota_rslt_u.gqr_rquota.rq_bsize, gqr.getquota_rslt_u.gqr_rquota.rq_active, gqr.getquota_rslt_u.gqr_rquota.rq_bhardlimit, gqr.getquota_rslt_u.gqr_rquota.rq_bsoftlimit, gqr.getquota_rslt_u.gqr_rquota.rq_curblocks)); if (D.dqb_bsoftlimit == 0) D.dqb_bsoftlimit = D.dqb_bhardlimit; if (D.dqb_bsoftlimit == 0) return False; *bsize = gqr.getquota_rslt_u.gqr_rquota.rq_bsize; *dsize = D.dqb_bsoftlimit; if (D.dqb_curblocks == D.dqb_curblocks == 1) *bsize = DEV_BSIZE; if (D.dqb_curblocks > D.dqb_bsoftlimit) { *dfree = 0; *dsize = D.dqb_curblocks; } else *dfree = D.dqb_bsoftlimit - D.dqb_curblocks; out: if (clnt) { if (clnt->cl_auth) auth_destroy(clnt->cl_auth); clnt_destroy(clnt); } DEBUG(5,("nfs_quotas: For path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n",args.gqa_pathp,(double)*bsize,(double)*dfree,(double)*dsize)); SAFE_FREE(cutstr); DEBUG(10,("nfs_quotas: End of nfs_quotas\n" )); return ret; } #endif /**************************************************************************** try to get the disk space from disk quotas - default version ****************************************************************************/ Loading Loading @@ -976,10 +1146,42 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB { /* FreeBSD patches from Marty Moll <martym@arbor.edu> */ gid_t egrp_id; #if defined(__FreeBSD__) 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 save_re_uid(); set_effective_uid(0); #if defined(__FreeBSD__) if (strcmp(mnts[i].f_fstypename,"nfs") == 0) { BOOL retval; retval = nfs_quotas(mnts[i].f_mntfromname,euser_id,bsize,dfree,dsize); restore_re_uid(); return retval; } #endif egrp_id = getegid(); r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D); Loading Loading
source3/smbd/quotas.c +203 −1 Original line number Diff line number Diff line Loading @@ -933,6 +933,176 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB #include <devnm.h> #endif #if defined(__FreeBSD__) #include <rpc/rpc.h> #include <rpc/types.h> #include <rpcsvc/rquota.h> #include <rpc/nettype.h> #include <rpc/xdr.h> static int quotastat; static int my_xdr_getquota_args(XDR *xdrsp, struct getquota_args *args) { if (!xdr_string(xdrsp, &args->gqa_pathp, RQ_PATHLEN )) return(0); if (!xdr_int(xdrsp, &args->gqa_uid)) return(0); return (1); } static int my_xdr_getquota_rslt(XDR *xdrsp, struct getquota_rslt *gqr) { if (!xdr_int(xdrsp, "astat)) { DEBUG(6,("nfs_quotas: Status bad or zero\n")); return 0; } if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_bsize)) { DEBUG(6,("nfs_quotas: Block size bad or zero\n")); return 0; } if (!xdr_bool(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_active)) { DEBUG(6,("nfs_quotas: Active bad or zero\n")); return 0; } if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_bhardlimit)) { DEBUG(6,("nfs_quotas: Hardlimit bad or zero\n")); return 0; } if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_bsoftlimit)) { DEBUG(6,("nfs_quotas: Softlimit bad or zero\n")); return 0; } if (!xdr_int(xdrsp, &gqr->getquota_rslt_u.gqr_rquota.rq_curblocks)) { DEBUG(6,("nfs_quotas: Currentblocks bad or zero\n")); return 0; } return (1); } /* Works on FreeBSD, too. :-) */ static BOOL nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { uid_t uid = euser_id; struct dqblk D; char *mnttype = nfspath; CLIENT *clnt; struct getquota_rslt gqr; struct getquota_args args; char *cutstr, *pathname, *host, *testpath; int len; static struct timeval timeout = {2,0}; enum clnt_stat clnt_stat; BOOL ret = True; *bsize = *dfree = *dsize = (SMB_BIG_UINT)0; len=strcspn(mnttype, ":"); pathname=strstr(mnttype, ":"); cutstr = (char *) malloc(len+1); if (!cutstr) return False; memset(cutstr, '\0', len+1); host = strncat(cutstr,mnttype, sizeof(char) * len ); DEBUG(5,("nfs_quotas: looking for mount on \"%s\"\n", cutstr)); DEBUG(5,("nfs_quotas: of path \"%s\"\n", mnttype)); testpath=strchr_m(mnttype, ':'); args.gqa_pathp = testpath+1; args.gqa_uid = uid; DEBUG(5,("nfs_quotas: Asking for host \"%s\" rpcprog \"%i\" rpcvers \"%i\" network \"%s\"\n", host, RQUOTAPROG, RQUOTAVERS, "udp")); if ((clnt = clnt_create(host, RQUOTAPROG, RQUOTAVERS, "udp")) == NULL) { ret = False; goto out; } clnt->cl_auth = authunix_create_default(); DEBUG(9,("nfs_quotas: auth_success\n")); 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); if (clnt_stat != RPC_SUCCESS) { DEBUG(9,("nfs_quotas: clnt_call fail\n")); ret = False; goto out; } /* * quotastat returns 0 if the rpc call fails, 1 if quotas exist, 2 if there is * no quota set, and 3 if no permission to get the quota. If 0 or 3 return * something sensible. */ switch ( quotastat ) { case 0: DEBUG(9,("nfs_quotas: Remote Quotas Failed! Error \"%i\" \n", quotastat )); ret = False; goto out; case 1: DEBUG(9,("nfs_quotas: Good quota data\n")); D.dqb_bsoftlimit = gqr.getquota_rslt_u.gqr_rquota.rq_bsoftlimit; D.dqb_bhardlimit = gqr.getquota_rslt_u.gqr_rquota.rq_bhardlimit; D.dqb_curblocks = gqr.getquota_rslt_u.gqr_rquota.rq_curblocks; break; case 2: case 3: D.dqb_bsoftlimit = 1; D.dqb_curblocks = 1; DEBUG(9,("nfs_quotas: Remote Quotas returned \"%i\" \n", quotastat )); break; default: DEBUG(9,("nfs_quotas: Remote Quotas Questionable! Error \"%i\" \n", quotastat )); break; } 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", quotastat, gqr.getquota_rslt_u.gqr_rquota.rq_bsize, gqr.getquota_rslt_u.gqr_rquota.rq_active, gqr.getquota_rslt_u.gqr_rquota.rq_bhardlimit, gqr.getquota_rslt_u.gqr_rquota.rq_bsoftlimit, gqr.getquota_rslt_u.gqr_rquota.rq_curblocks)); if (D.dqb_bsoftlimit == 0) D.dqb_bsoftlimit = D.dqb_bhardlimit; if (D.dqb_bsoftlimit == 0) return False; *bsize = gqr.getquota_rslt_u.gqr_rquota.rq_bsize; *dsize = D.dqb_bsoftlimit; if (D.dqb_curblocks == D.dqb_curblocks == 1) *bsize = DEV_BSIZE; if (D.dqb_curblocks > D.dqb_bsoftlimit) { *dfree = 0; *dsize = D.dqb_curblocks; } else *dfree = D.dqb_bsoftlimit - D.dqb_curblocks; out: if (clnt) { if (clnt->cl_auth) auth_destroy(clnt->cl_auth); clnt_destroy(clnt); } DEBUG(5,("nfs_quotas: For path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n",args.gqa_pathp,(double)*bsize,(double)*dfree,(double)*dsize)); SAFE_FREE(cutstr); DEBUG(10,("nfs_quotas: End of nfs_quotas\n" )); return ret; } #endif /**************************************************************************** try to get the disk space from disk quotas - default version ****************************************************************************/ Loading Loading @@ -976,10 +1146,42 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB { /* FreeBSD patches from Marty Moll <martym@arbor.edu> */ gid_t egrp_id; #if defined(__FreeBSD__) 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 save_re_uid(); set_effective_uid(0); #if defined(__FreeBSD__) if (strcmp(mnts[i].f_fstypename,"nfs") == 0) { BOOL retval; retval = nfs_quotas(mnts[i].f_mntfromname,euser_id,bsize,dfree,dsize); restore_re_uid(); return retval; } #endif egrp_id = getegid(); r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D); Loading