Decouple ldap-ssl-ads from ldap-ssl option
[samba.git] / source3 / lib / sysquotas_4A.c
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 ****************************************************************************/
87 int 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                         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));
113
114                         if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D))&&errno != EDQUOT) {
115                                 return ret;
116                         }
117
118                         ret = 0;
119                         break;
120 #endif /* HAVE_GROUP_QUOTA */
121                 case SMB_USER_FS_QUOTA_TYPE:
122                         id.uid = getuid();
123
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));
126
127                         if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D))==0) {
128                                 qflags |= QUOTAS_DENY_DISK;
129                         }
130
131                         ret = 0;
132                         break;
133 #ifdef HAVE_GROUP_QUOTA
134                 case SMB_GROUP_FS_QUOTA_TYPE:
135                         id.gid = getgid();
136
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));
139
140                         if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D))==0) {
141                                 qflags |= QUOTAS_DENY_DISK;
142                         }
143
144                         ret = 0;
145                         break;
146 #endif /* HAVE_GROUP_QUOTA */
147                 default:
148                         errno = ENOSYS;
149                         return -1;
150         }
151
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;
159
160
161         dp->qflags = qflags;
162
163         return ret;
164 }
165
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)
170 {
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;
176
177         ZERO_STRUCT(D);
178
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;
189         }
190
191         qflags = dp->qflags;
192
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));
197
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));
204
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
214                          * 
215                          * On HPUX we didn't have the mount path,
216                          * we need to fix sys_path_to_bdev()
217                          *
218                          */
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));
222
223 #if 0
224                         ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D);
225
226                         if ((qflags&QUOTAS_DENY_DISK)||(qflags&QUOTAS_ENABLED)) {
227                                 if (ret == 0) {
228                                         char *quota_file = NULL;
229                                         
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;
235                                         }
236                                         
237                                         ret = quotactl(QCMD(Q_QUOTAON,USRQUOTA), (caddr_t)bdev, -1,(void *)quota_file);
238                                 } else {
239                                         ret = 0;        
240                                 }
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;
247                                 }               
248                         }
249
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;
255                         }
256
257                         if (oldqflags == qflags) {
258                                 ret = 0;
259                         } else {
260                                 ret = -1;
261                         }
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
271                          * 
272                          * On HPUX we didn't have the mount path,
273                          * we need to fix sys_path_to_bdev()
274                          *
275                          */
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));
279
280 #if 0
281                         ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id, (void *)&D);
282
283                         if ((qflags&QUOTAS_DENY_DISK)||(qflags&QUOTAS_ENABLED)) {
284                                 if (ret == 0) {
285                                         char *quota_file = NULL;
286                                         
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;
292                                         }
293                                         
294                                         ret = quotactl(QCMD(Q_QUOTAON,GRPQUOTA), (caddr_t)bdev, -1,(void *)quota_file);
295                                 } else {
296                                         ret = 0;        
297                                 }
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;
304                                 }               
305                         }
306
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;
312                         }
313
314                         if (oldqflags == qflags) {
315                                 ret = 0;
316                         } else {
317                                 ret = -1;
318                         }
319 #endif
320                         break;
321 #endif /* HAVE_GROUP_QUOTA */
322                 default:
323                         errno = ENOSYS;
324                         return -1;
325         }
326
327         return ret;
328 }
329
330 #else /* HAVE_QUOTACTL_4A */
331  void dummy_sysquotas_4A(void);
332
333  void dummy_sysquotas_4A(void){}
334 #endif /* HAVE_QUOTACTL_4A */