Coverage Report

Created: 2026-02-14 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/source3/lib/sysquotas_4A.c
Line
Count
Source
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 ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), (caddr_t)bdev, id.uid, (void *)&D))==0) {
224
        oldqflags |= QUOTAS_DENY_DISK;
225
      }
226
227
      if (oldqflags == qflags) {
228
        ret = 0;
229
      } else {
230
        ret = -1;
231
      }
232
      break;
233
#ifdef HAVE_GROUP_QUOTA
234
    case SMB_GROUP_FS_QUOTA_TYPE:
235
      /* this stuff didn't work as it should:
236
       * switching on/off quota via quotactl()
237
       * didn't work!
238
       * So we just return 0
239
       * --metze
240
       *
241
       * On HPUX we didn't have the mount path,
242
       * we need to fix sys_path_to_bdev()
243
       *
244
       */
245
      id.gid = getgid();
246
      DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
247
        path, bdev, (unsigned)id.gid));
248
249
      if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), (caddr_t)bdev, id.gid, (void *)&D))==0) {
250
        oldqflags |= QUOTAS_DENY_DISK;
251
      }
252
253
      if (oldqflags == qflags) {
254
        ret = 0;
255
      } else {
256
        ret = -1;
257
      }
258
      break;
259
#endif /* HAVE_GROUP_QUOTA */
260
    default:
261
      errno = ENOSYS;
262
      return -1;
263
  }
264
265
  return ret;
266
}
267
268
#else /* HAVE_QUOTACTL_4A */
269
 void dummy_sysquotas_4A(void);
270
271
0
 void dummy_sysquotas_4A(void){}
272
#endif /* HAVE_QUOTACTL_4A */