source: vendor/current/source3/lib/sysquotas_4A.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

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