messaging: Pass "ev" to messaging_dispatch_rec
[kai/samba-autobuild/.git] / source3 / lib / sysquotas_linux.c
1 /* 
2    Unix SMB/CIFS implementation.
3    System QUOTA function wrappers for LINUX
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_LINUX
28 #undef HAVE_QUOTACTL_LINUX
29 #endif
30 #endif
31
32 #ifdef HAVE_QUOTACTL_LINUX
33
34 #include <sys/quota.h>
35
36 /****************************************************************************
37  Linux quota get calls.
38 ****************************************************************************/
39 int sys_get_vfs_quota(const char *path, const char *bdev,
40                       enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
41 {
42         int ret = -1;
43         uint32_t qflags = 0;
44         struct dqblk D;
45         uint64_t bsize = (uint64_t)QUOTABLOCK_SIZE;
46
47         if (!path || !bdev || !dp) {
48                 smb_panic("sys_get_vfs_quota: called with NULL pointer");
49         }
50
51         ZERO_STRUCT(*dp);
52         dp->qtype = qtype;
53
54         ZERO_STRUCT(D);
55
56         switch (qtype) {
57                 case SMB_USER_QUOTA_TYPE:
58                         DEBUG(10, ("sys_get_vfs_quota: path[%s] bdev[%s] "
59                                    "SMB_USER_QUOTA_TYPE uid[%u]\n",
60                                    path, bdev, (unsigned)id.uid));
61
62                         if ((ret = quotactl(QCMD(Q_GETQUOTA, USRQUOTA), bdev,
63                                             id.uid, (caddr_t)&D))) {
64                                 return ret;
65                         }
66
67                         break;
68                 case SMB_GROUP_QUOTA_TYPE:
69                         DEBUG(10, ("sys_get_vfs_quota: path[%s] bdev[%s] "
70                                    "SMB_GROUP_QUOTA_TYPE gid[%u]\n",
71                                    path, bdev, (unsigned)id.gid));
72
73                         if ((ret = quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), bdev,
74                                             id.gid, (caddr_t)&D))) {
75                                 return ret;
76                         }
77
78                         break;
79                 case SMB_USER_FS_QUOTA_TYPE:
80                         DEBUG(10, ("sys_get_vfs_quota: path[%s] bdev[%s] "
81                                    "SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
82                                    path, bdev, (unsigned)geteuid()));
83
84                         if ((ret = quotactl(QCMD(Q_GETQUOTA, USRQUOTA), bdev,
85                                             geteuid(), (caddr_t)&D)) == 0) {
86                                 qflags |= QUOTAS_DENY_DISK;
87                         }
88
89                         ret = 0;
90
91                         break;
92                 case SMB_GROUP_FS_QUOTA_TYPE:
93                         DEBUG(10, ("sys_get_vfs_quota: path[%s] bdev[%s] "
94                                    "SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
95                                    path, bdev, (unsigned)getgid()));
96
97                         if ((ret = quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), bdev,
98                                             getgid(), (caddr_t)&D)) == 0) {
99                                 qflags |= QUOTAS_DENY_DISK;
100                         }
101
102                         ret = 0;
103                         break;
104                 default:
105                         errno = ENOSYS;
106                         return -1;
107         }
108
109         dp->bsize = bsize;
110         dp->softlimit = (uint64_t)D.dqb_bsoftlimit;
111         dp->hardlimit = (uint64_t)D.dqb_bhardlimit;
112         dp->ihardlimit = (uint64_t)D.dqb_ihardlimit;
113         dp->isoftlimit = (uint64_t)D.dqb_isoftlimit;
114         dp->curinodes = (uint64_t)D.dqb_curinodes;
115         dp->curblocks = (uint64_t)D.dqb_curspace/bsize;
116
117
118         dp->qflags = qflags;
119
120         return ret;
121 }
122
123 /****************************************************************************
124  Linux quota set calls.
125 ****************************************************************************/
126 int sys_set_vfs_quota(const char *path, const char *bdev,
127                       enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
128 {
129         int ret = -1;
130         struct dqblk D;
131         uint64_t bsize = (uint64_t)QUOTABLOCK_SIZE;
132         bool cur_enf, new_enf;
133
134         if (!path || !bdev || !dp) {
135                 smb_panic("sys_set_vfs_quota: called with NULL pointer");
136         }
137
138         ZERO_STRUCT(D);
139
140         if (bsize == dp->bsize) {
141                 D.dqb_bsoftlimit = dp->softlimit;
142                 D.dqb_bhardlimit = dp->hardlimit;
143                 D.dqb_ihardlimit = dp->ihardlimit;
144                 D.dqb_isoftlimit = dp->isoftlimit;
145         } else {
146                 D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize;
147                 D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize;
148                 D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize;
149                 D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize;
150         }
151         D.dqb_valid = QIF_LIMITS;
152
153         switch (qtype) {
154                 case SMB_USER_QUOTA_TYPE:
155                         DEBUG(10, ("sys_set_vfs_quota: path[%s] bdev[%s] "
156                                    "SMB_USER_QUOTA_TYPE uid[%u]\n",
157                                    path, bdev, (unsigned)id.uid));
158
159                         ret = quotactl(QCMD(Q_SETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D);
160                         break;
161                 case SMB_GROUP_QUOTA_TYPE:
162                         DEBUG(10, ("sys_set_vfs_quota: path[%s] bdev[%s] "
163                                    "SMB_GROUP_QUOTA_TYPE gid[%u]\n",
164                                    path, bdev, (unsigned)id.gid));
165
166                         ret = quotactl(QCMD(Q_SETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D);
167                         break;
168                 case SMB_USER_FS_QUOTA_TYPE:
169                         DEBUG(10, ("sys_set_vfs_quota: path[%s] bdev[%s] "
170                                    "SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
171                                    path, bdev, (unsigned)geteuid()));
172
173                         ret = quotactl(QCMD(Q_GETQUOTA, USRQUOTA), bdev,
174                                        geteuid(), (caddr_t)&D);
175                         cur_enf = (ret == 0);
176                         new_enf = ((dp->qflags & QUOTAS_DENY_DISK) != 0);
177                         /* We're not changing quota enforcement, so return
178                          * success
179                          * IFF the wanted state is identical to the current
180                          * state */
181                         if (cur_enf == new_enf) {
182                                 ret = 0;
183                         } else {
184                                 errno = EPERM;
185                                 ret = -1;
186                         }
187
188                         break;
189                 case SMB_GROUP_FS_QUOTA_TYPE:
190                         DEBUG(10, ("sys_set_vfs_quota: path[%s] bdev[%s] "
191                                    "SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
192                                    path, bdev, (unsigned)getgid()));
193
194                         ret = quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), bdev,
195                                        getgid(), (caddr_t)&D);
196                         cur_enf = (ret == 0);
197                         new_enf = ((dp->qflags & QUOTAS_DENY_DISK) != 0);
198                         /* We're not changing quota enforcement, so return
199                          * success
200                          * IFF the wanted state is identical to the current
201                          * state */
202                         if (cur_enf == new_enf) {
203                                 ret = 0;
204                         } else {
205                                 errno = EPERM;
206                                 ret = -1;
207                         }
208
209                         break;
210                 default:
211                         errno = ENOSYS;
212                         return -1;
213         }
214
215         return ret;
216 }
217
218 #else /* HAVE_QUOTACTL_LINUX */
219  void dummy_sysquotas_linux(void);
220
221  void dummy_sysquotas_linux(void){}
222 #endif /* HAVE_QUOTACTL_LINUX */