s3:utils: let smbstatus report anonymous signing/encryption explicitly
[samba.git] / source3 / lib / sysquotas_jfs2.c
1 /*
2  * Unix SMB/CIFS implementation.
3  * System QUOTA function wrappers for JFS2 on AIX
4
5  * Copyright (C) 2019 Bjoern Jacke
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22
23 #include "includes.h"
24
25 #undef DBGC_CLASS
26 #define DBGC_CLASS DBGC_QUOTA
27
28 #if defined(HAVE_JFS_QUOTA_H)
29 #include <jfs/quota.h>
30
31 #if defined(Q_J2GETQUOTA) /* when have JFS2 */
32
33 /* int quotactl(const char *path, int cmd, int id, char *addr)
34  *
35  * This is very similar to sysquotas_4B but JFS2 has different quota cmds
36  * (why?) and for some reason wants root even for querying your own quota,
37  * which seems to be an AIX bug because the docs say root is only
38  * required for querying other users' quota
39  */
40
41
42 #ifdef HAVE_SYS_TYPES_H
43 #include <sys/types.h>
44 #endif
45
46 #ifdef HAVE_JFS_QUOTA_H
47 #include <jfs/quota.h>
48 #endif
49
50
51 static int sys_quotactl_JFS2(const char * path, int cmd,
52                 int id, quota64_t *quota)
53 {
54         int ret;
55
56         /* NB: We must test GRPQUOTA here, because USRQUOTA is 0. */
57         DEBUG(10, ("%s quota for %s ID %u on %s\n",
58                     (cmd & QCMD(Q_J2GETQUOTA, 0)) ? "getting" : "setting",
59                     (cmd & QCMD(0, GRPQUOTA)) ? "group" : "user",
60                     (unsigned)id, path));
61
62         become_root();
63
64         ret = quotactl((char *) path, cmd, id, (char *) quota);
65         if (ret == -1) {
66                 /* ENOTSUP means quota support is not compiled in. EINVAL
67                  * means that quotas are not configured (commonly).
68                  */
69                 if (errno != ENOTSUP && errno != EINVAL) {
70                         DEBUG(0, ("failed to %s quota for %s ID %u on %s: %s\n",
71                                     (cmd & QCMD(Q_J2GETQUOTA, 0)) ? "get" : "set",
72                                     (cmd & QCMD(0, GRPQUOTA)) ? "group" : "user",
73                                     (unsigned)id, path, strerror(errno)));
74                 }
75         }
76
77         unbecome_root();
78
79         return ret;
80 }
81
82
83 int sys_get_jfs2_quota(const char *path, const char *bdev,
84         enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
85 {
86         int ret;
87         quota64_t quota;
88
89         ZERO_STRUCT(quota);
90
91         switch (qtype) {
92         case SMB_USER_QUOTA_TYPE:
93                 /* Get quota for provided UID. */
94                 ret = sys_quotactl_JFS2(path, QCMD(Q_J2GETQUOTA, USRQUOTA),
95                                         id.uid, &quota);
96                 break;
97         case SMB_USER_FS_QUOTA_TYPE:
98                 /* Get quota for current UID. */
99                 ret = sys_quotactl_JFS2(path, QCMD(Q_J2GETQUOTA, USRQUOTA),
100                                         geteuid(), &quota);
101                 break;
102         case SMB_GROUP_QUOTA_TYPE:
103                 /* Get quota for provided GID. */
104                 ret = sys_quotactl_JFS2(path, QCMD(Q_J2GETQUOTA, GRPQUOTA),
105                                         id.gid, &quota);
106                 break;
107         case SMB_GROUP_FS_QUOTA_TYPE:
108                 /* Get quota for current GID. */
109                 ret = sys_quotactl_JFS2(path, QCMD(Q_J2GETQUOTA, GRPQUOTA),
110                                         getegid(), &quota);
111                 break;
112         default:
113                 DEBUG(0, ("cannot get unsupported quota type: %u\n",
114                             (unsigned)qtype));
115                 errno = ENOSYS;
116                 return -1;
117         }
118
119         if (ret == -1) {
120                 return -1;
121         }
122
123         dp->softlimit = quota.bsoft;
124         dp->hardlimit = quota.bhard;
125         dp->ihardlimit = quota.ihard;
126         dp->isoftlimit = quota.isoft;
127         dp->curinodes = quota.iused;
128         dp->curblocks = quota.bused;
129
130         dp->qflags = QUOTAS_ENABLED | QUOTAS_DENY_DISK;
131         dp->qtype = qtype;
132         dp->bsize = QUOTABLOCK_SIZE;
133
134         return ret;
135 }
136
137 int sys_set_jfs2_quota(const char *path, const char *bdev,
138         enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
139 {
140         /* JFS2 supports fancy quota limit classes for setting user quota.
141          * Unfortunately, this makes them quite unmanagable for Samba.
142          */
143         DEBUG(1, ("cannot set quota on JFS2!\n"));
144         errno = ENOSYS;
145         return -1;
146 }
147
148
149 #endif /* JFS2 */
150 #endif /* AIX quotas */