~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/modules/vfs_default_quota.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * Store default Quotas in a specified quota record
 
3
 *
 
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
 * This module allows the default quota values,
 
22
 * in the windows explorer GUI, to be stored on a samba server.
 
23
 * The problem is that linux filesystems only store quotas
 
24
 * for users and groups, but no default quotas.
 
25
 *
 
26
 * Samba returns NO_LIMIT as the default quotas by default
 
27
 * and refuses to update them.
 
28
 *
 
29
 * With this module you can store the default quotas that are reported to
 
30
 * a windows client, in the quota record of a user. By default the root user
 
31
 * is taken because quota limits for root are typically not enforced.
 
32
 *
 
33
 * This module takes 2 parametric parameters in smb.conf:
 
34
 * (the default prefix for them is 'default_quota',
 
35
 *  it can be overwrittem when you load the module in
 
36
 *  the 'vfs objects' parameter like this:
 
37
 *  vfs objects = default_quota:myprefix)
 
38
 * 
 
39
 * "<myprefix>:uid" parameter takes a integer argument,
 
40
 *     it specifies the uid of the quota record, that will be taken for
 
41
 *     storing the default USER-quotas.
 
42
 *
 
43
 *     - default value: '0' (for root user)
 
44
 *     - e.g.: default_quota:uid = 65534
 
45
 *
 
46
 * "<myprefix>:uid nolimit" parameter takes a boolean argument,
 
47
 *     it specifies if we should report the stored default quota values,
 
48
 *     also for the user record, or if you should just report NO_LIMIT
 
49
 *     to the windows client for the user specified by the "<prefix>:uid" parameter.
 
50
 *     
 
51
 *     - default value: yes (that means to report NO_LIMIT)
 
52
 *     - e.g.: default_quota:uid nolimit = no
 
53
 * 
 
54
 * "<myprefix>:gid" parameter takes a integer argument,
 
55
 *     it's just like "<prefix>:uid" but for group quotas.
 
56
 *     (NOTE: group quotas are not supported from the windows explorer!)
 
57
 *
 
58
 *     - default value: '0' (for root group)
 
59
 *     - e.g.: default_quota:gid = 65534
 
60
 *
 
61
 * "<myprefix>:gid nolimit" parameter takes a boolean argument,
 
62
 *     it's just like "<prefix>:uid nolimit" but for group quotas.
 
63
 *     (NOTE: group quotas are not supported from the windows explorer!)
 
64
 *     
 
65
 *     - default value: yes (that means to report NO_LIMIT)
 
66
 *     - e.g.: default_quota:uid nolimit = no
 
67
 *
 
68
 */
 
69
 
 
70
#include "includes.h"
 
71
 
 
72
#undef DBGC_CLASS
 
73
#define DBGC_CLASS DBGC_QUOTA
 
74
 
 
75
#define DEFAULT_QUOTA_NAME "default_quota"
 
76
 
 
77
#define DEFAULT_QUOTA_UID_DEFAULT               0
 
78
#define DEFAULT_QUOTA_UID_NOLIMIT_DEFAULT       True
 
79
#define DEFAULT_QUOTA_GID_DEFAULT               0
 
80
#define DEFAULT_QUOTA_GID_NOLIMIT_DEFAULT       True
 
81
 
 
82
#define DEFAULT_QUOTA_UID(handle) \
 
83
        (uid_t)lp_parm_int(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"uid",DEFAULT_QUOTA_UID_DEFAULT)
 
84
 
 
85
#define DEFAULT_QUOTA_UID_NOLIMIT(handle) \
 
86
        lp_parm_bool(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"uid nolimit",DEFAULT_QUOTA_UID_NOLIMIT_DEFAULT)
 
87
 
 
88
#define DEFAULT_QUOTA_GID(handle) \
 
89
        (gid_t)lp_parm_int(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"gid",DEFAULT_QUOTA_GID_DEFAULT)
 
90
 
 
91
#define DEFAULT_QUOTA_GID_NOLIMIT(handle) \
 
92
        lp_parm_bool(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"gid nolimit",DEFAULT_QUOTA_GID_NOLIMIT_DEFAULT)
 
93
 
 
94
static int default_quota_get_quota(vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq)
 
95
{
 
96
        int ret = -1;
 
97
 
 
98
        if ((ret=SMB_VFS_NEXT_GET_QUOTA(handle, qtype, id, dq))!=0) {
 
99
                return ret;
 
100
        }
 
101
 
 
102
        switch (qtype) {
 
103
                case SMB_USER_QUOTA_TYPE:
 
104
                        /* we use id.uid == 0 for default quotas */
 
105
                        if ((id.uid==DEFAULT_QUOTA_UID(handle)) &&
 
106
                                DEFAULT_QUOTA_UID_NOLIMIT(handle)) {
 
107
                                SMB_QUOTAS_SET_NO_LIMIT(dq);
 
108
                        }
 
109
                        break;
 
110
#ifdef HAVE_GROUP_QUOTA
 
111
                case SMB_GROUP_QUOTA_TYPE:
 
112
                        /* we use id.gid == 0 for default quotas */
 
113
                        if ((id.gid==DEFAULT_QUOTA_GID(handle)) &&
 
114
                                DEFAULT_QUOTA_GID_NOLIMIT(handle)) {
 
115
                                SMB_QUOTAS_SET_NO_LIMIT(dq);
 
116
                        }
 
117
                        break;
 
118
#endif /* HAVE_GROUP_QUOTA */
 
119
                case SMB_USER_FS_QUOTA_TYPE:
 
120
                        {
 
121
                                unid_t qid;
 
122
                                uint32 qflags = dq->qflags;
 
123
                                qid.uid = DEFAULT_QUOTA_UID(handle);
 
124
                                SMB_VFS_NEXT_GET_QUOTA(handle, SMB_USER_QUOTA_TYPE, qid, dq);
 
125
                                dq->qflags = qflags;
 
126
                        }
 
127
                        break;
 
128
#ifdef HAVE_GROUP_QUOTA
 
129
                case SMB_GROUP_FS_QUOTA_TYPE:
 
130
                        {
 
131
                                unid_t qid;
 
132
                                uint32 qflags = dq->qflags;
 
133
                                qid.gid = DEFAULT_QUOTA_GID(handle);
 
134
                                SMB_VFS_NEXT_GET_QUOTA(handle, SMB_GROUP_QUOTA_TYPE, qid, dq);
 
135
                                dq->qflags = qflags;
 
136
                        }
 
137
                        break;
 
138
#endif /* HAVE_GROUP_QUOTA */
 
139
                default:
 
140
                        errno = ENOSYS;
 
141
                        return -1;
 
142
                        break;
 
143
        }
 
144
 
 
145
        return ret;
 
146
}
 
147
 
 
148
static int default_quota_set_quota(vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq)
 
149
{
 
150
        int ret = -1;
 
151
 
 
152
        switch (qtype) {
 
153
                case SMB_USER_QUOTA_TYPE:
 
154
                        /* we use id.uid == 0 for default quotas */
 
155
                        if ((id.uid==DEFAULT_QUOTA_UID(handle)) &&
 
156
                                DEFAULT_QUOTA_UID_NOLIMIT(handle)) {
 
157
                                return -1;
 
158
                        }
 
159
                        break;
 
160
#ifdef HAVE_GROUP_QUOTA
 
161
                case SMB_GROUP_QUOTA_TYPE:
 
162
                        /* we use id.gid == 0 for default quotas */
 
163
                        if ((id.gid==DEFAULT_QUOTA_GID(handle)) &&
 
164
                                DEFAULT_QUOTA_GID_NOLIMIT(handle)) {
 
165
                                return -1;
 
166
                        }
 
167
                        break;
 
168
#endif /* HAVE_GROUP_QUOTA */
 
169
                case SMB_USER_FS_QUOTA_TYPE:
 
170
                        break;
 
171
#ifdef HAVE_GROUP_QUOTA
 
172
                case SMB_GROUP_FS_QUOTA_TYPE:
 
173
                        break;
 
174
#endif /* HAVE_GROUP_QUOTA */
 
175
                default:
 
176
                        errno = ENOSYS;
 
177
                        return -1;
 
178
                        break;
 
179
        }
 
180
 
 
181
        if ((ret=SMB_VFS_NEXT_SET_QUOTA(handle, qtype, id, dq))!=0) {
 
182
                return ret;
 
183
        }
 
184
 
 
185
        switch (qtype) {
 
186
                case SMB_USER_QUOTA_TYPE:
 
187
                        break;
 
188
#ifdef HAVE_GROUP_QUOTA
 
189
                case SMB_GROUP_QUOTA_TYPE:
 
190
                        break;
 
191
#endif /* HAVE_GROUP_QUOTA */
 
192
                case SMB_USER_FS_QUOTA_TYPE:
 
193
                        {
 
194
                                unid_t qid;
 
195
                                qid.uid = DEFAULT_QUOTA_UID(handle);
 
196
                                ret = SMB_VFS_NEXT_SET_QUOTA(handle, SMB_USER_QUOTA_TYPE, qid, dq);
 
197
                        }
 
198
                        break;
 
199
#ifdef HAVE_GROUP_QUOTA
 
200
                case SMB_GROUP_FS_QUOTA_TYPE:
 
201
                        {
 
202
                                unid_t qid;
 
203
                                qid.gid = DEFAULT_QUOTA_GID(handle);
 
204
                                ret = SMB_VFS_NEXT_SET_QUOTA(handle, SMB_GROUP_QUOTA_TYPE, qid, dq);
 
205
                        }
 
206
                        break;
 
207
#endif /* HAVE_GROUP_QUOTA */
 
208
                default:
 
209
                        errno = ENOSYS;
 
210
                        return -1;
 
211
                        break;
 
212
        }
 
213
 
 
214
        return ret;
 
215
}
 
216
 
 
217
/* VFS operations structure */
 
218
 
 
219
static vfs_op_tuple default_quota_ops[] = {     
 
220
        {SMB_VFS_OP(default_quota_get_quota),   SMB_VFS_OP_GET_QUOTA,   SMB_VFS_LAYER_TRANSPARENT},
 
221
        {SMB_VFS_OP(default_quota_set_quota),   SMB_VFS_OP_SET_QUOTA,   SMB_VFS_LAYER_TRANSPARENT},
 
222
 
 
223
        {SMB_VFS_OP(NULL),                      SMB_VFS_OP_NOOP,        SMB_VFS_LAYER_NOOP}
 
224
};
 
225
 
 
226
NTSTATUS vfs_default_quota_init(void);
 
227
NTSTATUS vfs_default_quota_init(void)
 
228
{
 
229
        return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, DEFAULT_QUOTA_NAME, default_quota_ops);
 
230
}