2 Unix SMB/CIFS implementation.
4 Copyright (C) Stefan (metze) Metzmacher 2003
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 2 of the License, or
9 (at your option) any later version.
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.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #define DBGC_CLASS DBGC_QUOTA
26 static SMB_BIG_UINT
limit_nt2unix(SMB_BIG_UINT in
, SMB_BIG_UINT bsize
)
28 SMB_BIG_UINT ret
= (SMB_BIG_UINT
)0;
30 ret
= (SMB_BIG_UINT
)(in
/bsize
);
32 /* we have to make sure that a overflow didn't set NO_LIMIT */
33 ret
= (SMB_BIG_UINT
)1;
36 if (in
== SMB_NTQUOTAS_NO_LIMIT
)
37 ret
= SMB_QUOTAS_NO_LIMIT
;
38 else if (in
== SMB_NTQUOTAS_NO_SPACE
)
39 ret
= SMB_QUOTAS_NO_SPACE
;
40 else if (in
== SMB_NTQUOTAS_NO_ENTRY
)
41 ret
= SMB_QUOTAS_NO_LIMIT
;
46 static SMB_BIG_UINT
limit_unix2nt(SMB_BIG_UINT in
, SMB_BIG_UINT bsize
)
48 SMB_BIG_UINT ret
= (SMB_BIG_UINT
)0;
50 ret
= (SMB_BIG_UINT
)(in
*bsize
);
54 ret
= SMB_NTQUOTAS_NO_LIMIT
;
57 if (in
== SMB_QUOTAS_NO_LIMIT
)
58 ret
= SMB_NTQUOTAS_NO_LIMIT
;
63 static SMB_BIG_UINT
limit_blk2inodes(SMB_BIG_UINT in
)
65 SMB_BIG_UINT ret
= (SMB_BIG_UINT
)0;
67 ret
= (SMB_BIG_UINT
)(in
/2);
69 if (ret
== 0 && in
!= 0)
70 ret
= (SMB_BIG_UINT
)1;
75 int vfs_get_ntquota(files_struct
*fsp
, enum SMB_QUOTA_TYPE qtype
, DOM_SID
*psid
, SMB_NTQUOTA_STRUCT
*qt
)
83 if (!fsp
||!fsp
->conn
||!qt
)
90 if (psid
&& !NT_STATUS_IS_OK(sid_to_uid(psid
, &id
.uid
))) {
91 DEBUG(0,("sid_to_uid: failed, SID[%s]\n",
92 sid_string_static(psid
)));
95 ret
= SMB_VFS_GET_QUOTA(fsp
->conn
, qtype
, id
, &D
);
104 qt
->usedspace
= (SMB_BIG_UINT
)D
.curblocks
*D
.bsize
;
105 qt
->softlim
= limit_unix2nt(D
.softlimit
, D
.bsize
);
106 qt
->hardlim
= limit_unix2nt(D
.hardlimit
, D
.bsize
);
107 qt
->qflags
= D
.qflags
;
113 int vfs_set_ntquota(files_struct
*fsp
, enum SMB_QUOTA_TYPE qtype
, DOM_SID
*psid
, SMB_NTQUOTA_STRUCT
*qt
)
120 if (!fsp
||!fsp
->conn
||!qt
)
125 D
.bsize
= (SMB_BIG_UINT
)QUOTABLOCK_SIZE
;
127 D
.softlimit
= limit_nt2unix(qt
->softlim
,D
.bsize
);
128 D
.hardlimit
= limit_nt2unix(qt
->hardlim
,D
.bsize
);
129 D
.qflags
= qt
->qflags
;
131 D
.isoftlimit
= limit_blk2inodes(D
.softlimit
);
132 D
.ihardlimit
= limit_blk2inodes(D
.hardlimit
);
134 if (psid
&& !NT_STATUS_IS_OK(sid_to_uid(psid
, &id
.uid
))) {
135 DEBUG(0,("sid_to_uid: failed, SID[%s]\n",
136 sid_string_static(psid
)));
139 ret
= SMB_VFS_SET_QUOTA(fsp
->conn
, qtype
, id
, &D
);
144 static BOOL
allready_in_quota_list(SMB_NTQUOTA_LIST
*qt_list
, uid_t uid
)
146 SMB_NTQUOTA_LIST
*tmp_list
= NULL
;
151 for (tmp_list
=qt_list
;tmp_list
!=NULL
;tmp_list
=tmp_list
->next
) {
152 if (tmp_list
->uid
== uid
) {
160 int vfs_get_user_ntquota_list(files_struct
*fsp
, SMB_NTQUOTA_LIST
**qt_list
)
163 TALLOC_CTX
*mem_ctx
= NULL
;
165 if (!fsp
||!fsp
->conn
||!qt_list
)
170 if ((mem_ctx
=talloc_init("SMB_USER_QUOTA_LIST"))==NULL
) {
171 DEBUG(0,("talloc_init() failed\n"));
176 while ((usr
= sys_getpwent()) != NULL
) {
177 SMB_NTQUOTA_STRUCT tmp_qt
;
178 SMB_NTQUOTA_LIST
*tmp_list_ent
;
183 if (allready_in_quota_list((*qt_list
),usr
->pw_uid
)) {
184 DEBUG(5,("record for uid[%ld] allready in the list\n",(long)usr
->pw_uid
));
188 if (!NT_STATUS_IS_OK(uid_to_sid(&sid
, usr
->pw_uid
))) {
189 DEBUG(0,("uid_to_sid failed for %ld\n",(long)usr
->pw_uid
));
193 if (vfs_get_ntquota(fsp
, SMB_USER_QUOTA_TYPE
, &sid
, &tmp_qt
)!=0) {
194 DEBUG(5,("no quota entry for sid[%s] path[%s]\n",
195 sid_string_static(&sid
),fsp
->conn
->connectpath
));
199 DEBUG(15,("quota entry for id[%s] path[%s]\n",
200 sid_string_static(&sid
),fsp
->conn
->connectpath
));
202 if ((tmp_list_ent
=(SMB_NTQUOTA_LIST
*)talloc_zero(mem_ctx
,sizeof(SMB_NTQUOTA_LIST
)))==NULL
) {
203 DEBUG(0,("talloc_zero() failed\n"));
205 talloc_destroy(mem_ctx
);
209 if ((tmp_list_ent
->quotas
=(SMB_NTQUOTA_STRUCT
*)talloc_zero(mem_ctx
,sizeof(SMB_NTQUOTA_STRUCT
)))==NULL
) {
210 DEBUG(0,("talloc_zero() failed\n"));
212 talloc_destroy(mem_ctx
);
216 tmp_list_ent
->uid
= usr
->pw_uid
;
217 memcpy(tmp_list_ent
->quotas
,&tmp_qt
,sizeof(tmp_qt
));
218 tmp_list_ent
->mem_ctx
= mem_ctx
;
220 DLIST_ADD((*qt_list
),tmp_list_ent
);
228 void *init_quota_handle(TALLOC_CTX
*mem_ctx
)
230 SMB_NTQUOTA_HANDLE
*qt_handle
;
235 qt_handle
= (SMB_NTQUOTA_HANDLE
*)talloc_zero(mem_ctx
,sizeof(SMB_NTQUOTA_HANDLE
));
236 if (qt_handle
==NULL
) {
237 DEBUG(0,("talloc_zero() failed\n"));
241 return (void *)qt_handle
;
244 void destroy_quota_handle(void **pqt_handle
)
246 SMB_NTQUOTA_HANDLE
*qt_handle
= NULL
;
247 if (!pqt_handle
||!(*pqt_handle
))
250 qt_handle
= (*pqt_handle
);
253 if (qt_handle
->quota_list
)
254 free_ntquota_list(&qt_handle
->quota_list
);
256 qt_handle
->quota_list
= NULL
;
257 qt_handle
->tmp_list
= NULL
;