source: branches/samba-3.0/source/lib/sysquotas_4A.c

Last change on this file was 1, checked in by Paul Smedley, 18 years ago

Initial code import

File size: 8.9 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 System QUOTA function wrappers for QUOTACTL_4A
4 Copyright (C) Stefan (metze) Metzmacher 2003
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21
22#include "includes.h"
23
24#undef DBGC_CLASS
25#define DBGC_CLASS DBGC_QUOTA
26
27#ifndef HAVE_SYS_QUOTAS
28#ifdef HAVE_QUOTACTL_4A
29#undef HAVE_QUOTACTL_4A
30#endif
31#endif
32
33#ifdef HAVE_QUOTACTL_4A
34/* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */
35/* this is used by: HPUX,IRIX */
36
37#ifdef HAVE_SYS_TYPES_H
38#include <sys/types.h>
39#endif
40
41#ifdef HAVE_ASM_TYPES_H
42#include <asm/types.h>
43#endif
44
45#ifdef HAVE_SYS_QUOTA_H
46#include <sys/quota.h>
47#endif
48
49#ifndef Q_SETQLIM
50#define Q_SETQLIM Q_SETQUOTA
51#endif
52
53#ifndef QCMD
54#define QCMD(x,y) x
55#endif
56
57#ifndef QCMD
58#define QCMD(x,y) x
59#endif
60
61#ifdef GRPQUOTA
62#define HAVE_GROUP_QUOTA
63#endif
64
65#ifndef QUOTABLOCK_SIZE
66#define QUOTABLOCK_SIZE DEV_BSIZE
67#endif
68
69#ifdef HAVE_DQB_FSOFTLIMIT
70#define dqb_isoftlimit dqb_fsoftlimit
71#define dqb_ihardlimit dqb_fhardlimit
72#define dqb_curinodes dqb_curfiles
73#endif
74
75#ifdef INITQFNAMES
76#define USERQUOTAFILE_EXTENSION ".user"
77#else
78#define USERQUOTAFILE_EXTENSION ""
79#endif
80
81#if !defined(QUOTAFILENAME) && defined(QFILENAME)
82#define QUOTAFILENAME QFILENAME
83#endif
84
85/****************************************************************************
86 Abstract out the quotactl_4A get calls.
87****************************************************************************/
88int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
89{
90 int ret = -1;
91 uint32 qflags = 0;
92 struct dqblk D;
93 SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
94
95 ZERO_STRUCT(D);
96 ZERO_STRUCT(*dp);
97 dp->qtype = qtype;
98
99 switch (qtype) {
100 case SMB_USER_QUOTA_TYPE:
101 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
102 path, bdev, (unsigned)id.uid));
103
104 if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D))&&errno != EDQUOT) {
105 return ret;
106 }
107
108 if ((D.dqb_curblocks==0)&&
109 (D.dqb_bsoftlimit==0)&&
110 (D.dqb_bhardlimit==0)) {
111 /* the upper layer functions don't want empty quota records...*/
112 return -1;
113 }
114
115 break;
116#ifdef HAVE_GROUP_QUOTA
117 case SMB_GROUP_QUOTA_TYPE:
118 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
119 path, bdev, (unsigned)id.gid));
120
121 if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D))&&errno != EDQUOT) {
122 return ret;
123 }
124
125 if ((D.dqb_curblocks==0)&&
126 (D.dqb_bsoftlimit==0)&&
127 (D.dqb_bhardlimit==0)) {
128 /* the upper layer functions don't want empty quota records...*/
129 return -1;
130 }
131
132 break;
133#endif /* HAVE_GROUP_QUOTA */
134 case SMB_USER_FS_QUOTA_TYPE:
135 id.uid = getuid();
136
137 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
138 path, (caddr_t)bdev, (unsigned)id.uid));
139
140 if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D))==0) {
141 qflags |= QUOTAS_DENY_DISK;
142 }
143
144 ret = 0;
145 break;
146#ifdef HAVE_GROUP_QUOTA
147 case SMB_GROUP_FS_QUOTA_TYPE:
148 id.gid = getgid();
149
150 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
151 path, bdev, (unsigned)id.gid));
152
153 if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D))==0) {
154 qflags |= QUOTAS_DENY_DISK;
155 }
156
157 ret = 0;
158 break;
159#endif /* HAVE_GROUP_QUOTA */
160 default:
161 errno = ENOSYS;
162 return -1;
163 }
164
165 dp->bsize = bsize;
166 dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
167 dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
168 dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
169 dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit;
170 dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
171 dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks;
172
173
174 dp->qflags = qflags;
175
176 return ret;
177}
178
179/****************************************************************************
180 Abstract out the quotactl_4A set calls.
181****************************************************************************/
182int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
183{
184 int ret = -1;
185 uint32 qflags = 0;
186 uint32 oldqflags = 0;
187 struct dqblk D;
188 SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
189
190 ZERO_STRUCT(D);
191
192 if (bsize == dp->bsize) {
193 D.dqb_bsoftlimit = dp->softlimit;
194 D.dqb_bhardlimit = dp->hardlimit;
195 D.dqb_ihardlimit = dp->ihardlimit;
196 D.dqb_isoftlimit = dp->isoftlimit;
197 } else {
198 D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize;
199 D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize;
200 D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize;
201 D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize;
202 }
203
204 qflags = dp->qflags;
205
206 switch (qtype) {
207 case SMB_USER_QUOTA_TYPE:
208 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
209 path, bdev, (unsigned)id.uid));
210
211 ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D);
212 break;
213#ifdef HAVE_GROUP_QUOTA
214 case SMB_GROUP_QUOTA_TYPE:
215 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
216 path, bdev, (unsigned)id.gid));
217
218 ret = quotactl(QCMD(Q_SETQLIM,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D);
219 break;
220#endif /* HAVE_GROUP_QUOTA */
221 case SMB_USER_FS_QUOTA_TYPE:
222 /* this stuff didn't work as it should:
223 * switching on/off quota via quotactl()
224 * didn't work!
225 * So we just return 0
226 * --metze
227 *
228 * On HPUX we didn't have the mount path,
229 * we need to fix sys_path_to_bdev()
230 *
231 */
232 id.uid = getuid();
233 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
234 path, bdev, (unsigned)id.uid));
235
236#if 0
237 ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D);
238
239 if ((qflags&QUOTAS_DENY_DISK)||(qflags&QUOTAS_ENABLED)) {
240 if (ret == 0) {
241 char *quota_file = NULL;
242
243 asprintf(&quota_file,"/%s/%s%s",path, QUOTAFILENAME,USERQUOTAFILE_EXTENSION);
244 if (quota_file == NULL) {
245 DEBUG(0,("asprintf() failed!\n"));
246 errno = ENOMEM;
247 return -1;
248 }
249
250 ret = quotactl(QCMD(Q_QUOTAON,USRQUOTA), (caddr_t)bdev, -1,(void *)quota_file);
251 } else {
252 ret = 0;
253 }
254 } else {
255 if (ret != 0) {
256 /* turn off */
257 ret = quotactl(QCMD(Q_QUOTAOFF,USRQUOTA), (caddr_t)bdev, -1, (void *)0);
258 } else {
259 ret = 0;
260 }
261 }
262
263 DEBUG(0,("sys_set_vfs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
264 ret,errno,strerror(errno),id.uid,bdev));
265#else
266 if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D))==0) {
267 oldqflags |= QUOTAS_DENY_DISK;
268 }
269
270 if (oldqflags == qflags) {
271 ret = 0;
272 } else {
273 ret = -1;
274 }
275#endif
276 break;
277#ifdef HAVE_GROUP_QUOTA
278 case SMB_GROUP_FS_QUOTA_TYPE:
279 /* this stuff didn't work as it should:
280 * switching on/off quota via quotactl()
281 * didn't work!
282 * So we just return 0
283 * --metze
284 *
285 * On HPUX we didn't have the mount path,
286 * we need to fix sys_path_to_bdev()
287 *
288 */
289 id.gid = getgid();
290 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
291 path, bdev, (unsigned)id.gid));
292
293#if 0
294 ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id, (void *)&D);
295
296 if ((qflags&QUOTAS_DENY_DISK)||(qflags&QUOTAS_ENABLED)) {
297 if (ret == 0) {
298 char *quota_file = NULL;
299
300 asprintf(&quota_file,"/%s/%s%s",path, QUOTAFILENAME,GROUPQUOTAFILE_EXTENSION);
301 if (quota_file == NULL) {
302 DEBUG(0,("asprintf() failed!\n"));
303 errno = ENOMEM;
304 return -1;
305 }
306
307 ret = quotactl(QCMD(Q_QUOTAON,GRPQUOTA), (caddr_t)bdev, -1,(void *)quota_file);
308 } else {
309 ret = 0;
310 }
311 } else {
312 if (ret != 0) {
313 /* turn off */
314 ret = quotactl(QCMD(Q_QUOTAOFF,GRPQUOTA), (caddr_t)bdev, -1, (void *)0);
315 } else {
316 ret = 0;
317 }
318 }
319
320 DEBUG(0,("sys_set_vfs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
321 ret,errno,strerror(errno),id.gid,bdev));
322#else
323 if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D))==0) {
324 oldqflags |= QUOTAS_DENY_DISK;
325 }
326
327 if (oldqflags == qflags) {
328 ret = 0;
329 } else {
330 ret = -1;
331 }
332#endif
333 break;
334#endif /* HAVE_GROUP_QUOTA */
335 default:
336 errno = ENOSYS;
337 return -1;
338 }
339
340 return ret;
341}
342
343#else /* HAVE_QUOTACTL_4A */
344 void dummy_sysquotas_4A(void);
345
346 void dummy_sysquotas_4A(void){}
347#endif /* HAVE_QUOTACTL_4A */
Note: See TracBrowser for help on using the repository browser.