s4:auth: kinit_to_ccache() should always use the canonicalized principal
[Samba.git] / source3 / lib / sysquotas_4A.c
blob674c4ee02db254a40992f0a9ca816d2d498aba29
1 /*
2 Unix SMB/CIFS implementation.
3 System QUOTA function wrappers for QUOTACTL_4A
4 Copyright (C) Stefan (metze) Metzmacher 2003
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.
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.
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/>.
21 #include "includes.h"
23 #undef DBGC_CLASS
24 #define DBGC_CLASS DBGC_QUOTA
26 #ifndef HAVE_SYS_QUOTAS
27 #ifdef HAVE_QUOTACTL_4A
28 #undef HAVE_QUOTACTL_4A
29 #endif
30 #endif
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 */
36 #ifdef HAVE_SYS_TYPES_H
37 #include <sys/types.h>
38 #endif
40 #ifdef HAVE_ASM_TYPES_H
41 #include <asm/types.h>
42 #endif
44 #ifdef HAVE_SYS_QUOTA_H
45 #include <sys/quota.h>
46 #endif
48 #ifndef Q_SETQLIM
49 #define Q_SETQLIM Q_SETQUOTA
50 #endif
52 #ifndef QCMD
53 #define QCMD(x,y) x
54 #endif
56 #ifndef QCMD
57 #define QCMD(x,y) x
58 #endif
60 #ifdef GRPQUOTA
61 #define HAVE_GROUP_QUOTA
62 #endif
64 #ifndef QUOTABLOCK_SIZE
65 #define QUOTABLOCK_SIZE DEV_BSIZE
66 #endif
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
74 #ifdef INITQFNAMES
75 #define USERQUOTAFILE_EXTENSION ".user"
76 #else
77 #define USERQUOTAFILE_EXTENSION ""
78 #endif
80 #if !defined(QUOTAFILENAME) && defined(QFILENAME)
81 #define QUOTAFILENAME QFILENAME
82 #endif
84 /****************************************************************************
85 Abstract out the quotactl_4A get calls.
86 ****************************************************************************/
87 int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
89 int ret = -1;
90 uint32_t qflags = 0;
91 struct dqblk D;
92 uint64_t bsize = (uint64_t)QUOTABLOCK_SIZE;
94 ZERO_STRUCT(D);
95 ZERO_STRUCT(*dp);
96 dp->qtype = qtype;
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));
103 if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D))&&errno != EDQUOT) {
104 return ret;
107 ret = 0;
108 break;
109 #ifdef HAVE_GROUP_QUOTA
110 case SMB_GROUP_QUOTA_TYPE:
111 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
112 path, bdev, (unsigned)id.gid));
114 if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D))&&errno != EDQUOT) {
115 return ret;
118 ret = 0;
119 break;
120 #endif /* HAVE_GROUP_QUOTA */
121 case SMB_USER_FS_QUOTA_TYPE:
122 id.uid = getuid();
124 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
125 path, (caddr_t)bdev, (unsigned)id.uid));
127 if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D))==0) {
128 qflags |= QUOTAS_DENY_DISK;
131 ret = 0;
132 break;
133 #ifdef HAVE_GROUP_QUOTA
134 case SMB_GROUP_FS_QUOTA_TYPE:
135 id.gid = getgid();
137 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
138 path, bdev, (unsigned)id.gid));
140 if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D))==0) {
141 qflags |= QUOTAS_DENY_DISK;
144 ret = 0;
145 break;
146 #endif /* HAVE_GROUP_QUOTA */
147 default:
148 errno = ENOSYS;
149 return -1;
152 dp->bsize = bsize;
153 dp->softlimit = (uint64_t)D.dqb_bsoftlimit;
154 dp->hardlimit = (uint64_t)D.dqb_bhardlimit;
155 dp->ihardlimit = (uint64_t)D.dqb_ihardlimit;
156 dp->isoftlimit = (uint64_t)D.dqb_isoftlimit;
157 dp->curinodes = (uint64_t)D.dqb_curinodes;
158 dp->curblocks = (uint64_t)D.dqb_curblocks;
161 dp->qflags = qflags;
163 return ret;
166 /****************************************************************************
167 Abstract out the quotactl_4A set calls.
168 ****************************************************************************/
169 int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
171 int ret = -1;
172 uint32_t qflags = 0;
173 uint32_t oldqflags = 0;
174 struct dqblk D;
175 uint64_t bsize = (uint64_t)QUOTABLOCK_SIZE;
177 ZERO_STRUCT(D);
179 if (bsize == dp->bsize) {
180 D.dqb_bsoftlimit = dp->softlimit;
181 D.dqb_bhardlimit = dp->hardlimit;
182 D.dqb_ihardlimit = dp->ihardlimit;
183 D.dqb_isoftlimit = dp->isoftlimit;
184 } else {
185 D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize;
186 D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize;
187 D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize;
188 D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize;
191 qflags = dp->qflags;
193 switch (qtype) {
194 case SMB_USER_QUOTA_TYPE:
195 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
196 path, bdev, (unsigned)id.uid));
198 ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D);
199 break;
200 #ifdef HAVE_GROUP_QUOTA
201 case SMB_GROUP_QUOTA_TYPE:
202 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
203 path, bdev, (unsigned)id.gid));
205 ret = quotactl(QCMD(Q_SETQLIM,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D);
206 break;
207 #endif /* HAVE_GROUP_QUOTA */
208 case SMB_USER_FS_QUOTA_TYPE:
209 /* this stuff didn't work as it should:
210 * switching on/off quota via quotactl()
211 * didn't work!
212 * So we just return 0
213 * --metze
215 * On HPUX we didn't have the mount path,
216 * we need to fix sys_path_to_bdev()
219 id.uid = getuid();
220 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
221 path, bdev, (unsigned)id.uid));
223 #if 0
224 ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D);
226 if ((qflags&QUOTAS_DENY_DISK)||(qflags&QUOTAS_ENABLED)) {
227 if (ret == 0) {
228 char *quota_file = NULL;
230 asprintf(&quota_file,"/%s/%s%s",path, QUOTAFILENAME,USERQUOTAFILE_EXTENSION);
231 if (quota_file == NULL) {
232 DEBUG(0,("asprintf() failed!\n"));
233 errno = ENOMEM;
234 return -1;
237 ret = quotactl(QCMD(Q_QUOTAON,USRQUOTA), (caddr_t)bdev, -1,(void *)quota_file);
238 } else {
239 ret = 0;
241 } else {
242 if (ret != 0) {
243 /* turn off */
244 ret = quotactl(QCMD(Q_QUOTAOFF,USRQUOTA), (caddr_t)bdev, -1, (void *)0);
245 } else {
246 ret = 0;
250 DEBUG(0,("sys_set_vfs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
251 ret,errno,strerror(errno),id.uid,bdev));
252 #else
253 if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D))==0) {
254 oldqflags |= QUOTAS_DENY_DISK;
257 if (oldqflags == qflags) {
258 ret = 0;
259 } else {
260 ret = -1;
262 #endif
263 break;
264 #ifdef HAVE_GROUP_QUOTA
265 case SMB_GROUP_FS_QUOTA_TYPE:
266 /* this stuff didn't work as it should:
267 * switching on/off quota via quotactl()
268 * didn't work!
269 * So we just return 0
270 * --metze
272 * On HPUX we didn't have the mount path,
273 * we need to fix sys_path_to_bdev()
276 id.gid = getgid();
277 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
278 path, bdev, (unsigned)id.gid));
280 #if 0
281 ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id, (void *)&D);
283 if ((qflags&QUOTAS_DENY_DISK)||(qflags&QUOTAS_ENABLED)) {
284 if (ret == 0) {
285 char *quota_file = NULL;
287 asprintf(&quota_file,"/%s/%s%s",path, QUOTAFILENAME,GROUPQUOTAFILE_EXTENSION);
288 if (quota_file == NULL) {
289 DEBUG(0,("asprintf() failed!\n"));
290 errno = ENOMEM;
291 return -1;
294 ret = quotactl(QCMD(Q_QUOTAON,GRPQUOTA), (caddr_t)bdev, -1,(void *)quota_file);
295 } else {
296 ret = 0;
298 } else {
299 if (ret != 0) {
300 /* turn off */
301 ret = quotactl(QCMD(Q_QUOTAOFF,GRPQUOTA), (caddr_t)bdev, -1, (void *)0);
302 } else {
303 ret = 0;
307 DEBUG(0,("sys_set_vfs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
308 ret,errno,strerror(errno),id.gid,bdev));
309 #else
310 if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D))==0) {
311 oldqflags |= QUOTAS_DENY_DISK;
314 if (oldqflags == qflags) {
315 ret = 0;
316 } else {
317 ret = -1;
319 #endif
320 break;
321 #endif /* HAVE_GROUP_QUOTA */
322 default:
323 errno = ENOSYS;
324 return -1;
327 return ret;
330 #else /* HAVE_QUOTACTL_4A */
331 void dummy_sysquotas_4A(void);
333 void dummy_sysquotas_4A(void){}
334 #endif /* HAVE_QUOTACTL_4A */