00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "includes.h"
00022
00023 #undef DBGC_CLASS
00024 #define DBGC_CLASS DBGC_QUOTA
00025
00026 static SMB_BIG_UINT limit_nt2unix(SMB_BIG_UINT in, SMB_BIG_UINT bsize)
00027 {
00028 SMB_BIG_UINT ret = (SMB_BIG_UINT)0;
00029
00030 ret = (SMB_BIG_UINT)(in/bsize);
00031 if (in>0 && ret==0) {
00032
00033 ret = (SMB_BIG_UINT)1;
00034 }
00035
00036 if (in == SMB_NTQUOTAS_NO_LIMIT)
00037 ret = SMB_QUOTAS_NO_LIMIT;
00038 else if (in == SMB_NTQUOTAS_NO_SPACE)
00039 ret = SMB_QUOTAS_NO_SPACE;
00040 else if (in == SMB_NTQUOTAS_NO_ENTRY)
00041 ret = SMB_QUOTAS_NO_LIMIT;
00042
00043 return ret;
00044 }
00045
00046 static SMB_BIG_UINT limit_unix2nt(SMB_BIG_UINT in, SMB_BIG_UINT bsize)
00047 {
00048 SMB_BIG_UINT ret = (SMB_BIG_UINT)0;
00049
00050 ret = (SMB_BIG_UINT)(in*bsize);
00051
00052 if (ret < in) {
00053
00054 ret = SMB_NTQUOTAS_NO_LIMIT;
00055 }
00056
00057 if (in == SMB_QUOTAS_NO_LIMIT)
00058 ret = SMB_NTQUOTAS_NO_LIMIT;
00059
00060 return ret;
00061 }
00062
00063 static SMB_BIG_UINT limit_blk2inodes(SMB_BIG_UINT in)
00064 {
00065 SMB_BIG_UINT ret = (SMB_BIG_UINT)0;
00066
00067 ret = (SMB_BIG_UINT)(in/2);
00068
00069 if (ret == 0 && in != 0)
00070 ret = (SMB_BIG_UINT)1;
00071
00072 return ret;
00073 }
00074
00075 int vfs_get_ntquota(files_struct *fsp, enum SMB_QUOTA_TYPE qtype, DOM_SID *psid, SMB_NTQUOTA_STRUCT *qt)
00076 {
00077 int ret;
00078 SMB_DISK_QUOTA D;
00079 unid_t id;
00080
00081 ZERO_STRUCT(D);
00082
00083 if (!fsp||!fsp->conn||!qt)
00084 return (-1);
00085
00086 ZERO_STRUCT(*qt);
00087
00088 id.uid = -1;
00089
00090 if (psid && !sid_to_uid(psid, &id.uid)) {
00091 DEBUG(0,("sid_to_uid: failed, SID[%s]\n",
00092 sid_string_static(psid)));
00093 }
00094
00095 ret = SMB_VFS_GET_QUOTA(fsp->conn, qtype, id, &D);
00096
00097 if (psid)
00098 qt->sid = *psid;
00099
00100 if (ret!=0) {
00101 return ret;
00102 }
00103
00104 qt->usedspace = (SMB_BIG_UINT)D.curblocks*D.bsize;
00105 qt->softlim = limit_unix2nt(D.softlimit, D.bsize);
00106 qt->hardlim = limit_unix2nt(D.hardlimit, D.bsize);
00107 qt->qflags = D.qflags;
00108
00109
00110 return 0;
00111 }
00112
00113 int vfs_set_ntquota(files_struct *fsp, enum SMB_QUOTA_TYPE qtype, DOM_SID *psid, SMB_NTQUOTA_STRUCT *qt)
00114 {
00115 int ret;
00116 SMB_DISK_QUOTA D;
00117 unid_t id;
00118 ZERO_STRUCT(D);
00119
00120 if (!fsp||!fsp->conn||!qt)
00121 return (-1);
00122
00123 id.uid = -1;
00124
00125 D.bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
00126
00127 D.softlimit = limit_nt2unix(qt->softlim,D.bsize);
00128 D.hardlimit = limit_nt2unix(qt->hardlim,D.bsize);
00129 D.qflags = qt->qflags;
00130
00131 D.isoftlimit = limit_blk2inodes(D.softlimit);
00132 D.ihardlimit = limit_blk2inodes(D.hardlimit);
00133
00134 if (psid && !sid_to_uid(psid, &id.uid)) {
00135 DEBUG(0,("sid_to_uid: failed, SID[%s]\n",
00136 sid_string_static(psid)));
00137 }
00138
00139 ret = SMB_VFS_SET_QUOTA(fsp->conn, qtype, id, &D);
00140
00141 return ret;
00142 }
00143
00144 static BOOL allready_in_quota_list(SMB_NTQUOTA_LIST *qt_list, uid_t uid)
00145 {
00146 SMB_NTQUOTA_LIST *tmp_list = NULL;
00147
00148 if (!qt_list)
00149 return False;
00150
00151 for (tmp_list=qt_list;tmp_list!=NULL;tmp_list=tmp_list->next) {
00152 if (tmp_list->uid == uid) {
00153 return True;
00154 }
00155 }
00156
00157 return False;
00158 }
00159
00160 int vfs_get_user_ntquota_list(files_struct *fsp, SMB_NTQUOTA_LIST **qt_list)
00161 {
00162 struct passwd *usr;
00163 TALLOC_CTX *mem_ctx = NULL;
00164
00165 if (!fsp||!fsp->conn||!qt_list)
00166 return (-1);
00167
00168 *qt_list = NULL;
00169
00170 if ((mem_ctx=talloc_init("SMB_USER_QUOTA_LIST"))==NULL) {
00171 DEBUG(0,("talloc_init() failed\n"));
00172 return (-1);
00173 }
00174
00175 sys_setpwent();
00176 while ((usr = sys_getpwent()) != NULL) {
00177 SMB_NTQUOTA_STRUCT tmp_qt;
00178 SMB_NTQUOTA_LIST *tmp_list_ent;
00179 DOM_SID sid;
00180
00181 ZERO_STRUCT(tmp_qt);
00182
00183 if (allready_in_quota_list((*qt_list),usr->pw_uid)) {
00184 DEBUG(5,("record for uid[%ld] allready in the list\n",(long)usr->pw_uid));
00185 continue;
00186 }
00187
00188 uid_to_sid(&sid, usr->pw_uid);
00189
00190 if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &tmp_qt)!=0) {
00191 DEBUG(5,("no quota entry for sid[%s] path[%s]\n",
00192 sid_string_static(&sid),fsp->conn->connectpath));
00193 continue;
00194 }
00195
00196 DEBUG(15,("quota entry for id[%s] path[%s]\n",
00197 sid_string_static(&sid),fsp->conn->connectpath));
00198
00199 if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) {
00200 DEBUG(0,("TALLOC_ZERO() failed\n"));
00201 *qt_list = NULL;
00202 talloc_destroy(mem_ctx);
00203 return (-1);
00204 }
00205
00206 if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) {
00207 DEBUG(0,("TALLOC_ZERO() failed\n"));
00208 *qt_list = NULL;
00209 talloc_destroy(mem_ctx);
00210 return (-1);
00211 }
00212
00213 tmp_list_ent->uid = usr->pw_uid;
00214 memcpy(tmp_list_ent->quotas,&tmp_qt,sizeof(tmp_qt));
00215 tmp_list_ent->mem_ctx = mem_ctx;
00216
00217 DLIST_ADD((*qt_list),tmp_list_ent);
00218
00219 }
00220 sys_endpwent();
00221
00222 return 0;
00223 }
00224
00225 void *init_quota_handle(TALLOC_CTX *mem_ctx)
00226 {
00227 SMB_NTQUOTA_HANDLE *qt_handle;
00228
00229 if (!mem_ctx)
00230 return False;
00231
00232 qt_handle = TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_HANDLE);
00233 if (qt_handle==NULL) {
00234 DEBUG(0,("TALLOC_ZERO() failed\n"));
00235 return NULL;
00236 }
00237
00238 return (void *)qt_handle;
00239 }
00240
00241 void destroy_quota_handle(void **pqt_handle)
00242 {
00243 SMB_NTQUOTA_HANDLE *qt_handle = NULL;
00244 if (!pqt_handle||!(*pqt_handle))
00245 return;
00246
00247 qt_handle = (SMB_NTQUOTA_HANDLE *)(*pqt_handle);
00248
00249
00250 if (qt_handle->quota_list)
00251 free_ntquota_list(&qt_handle->quota_list);
00252
00253 qt_handle->quota_list = NULL;
00254 qt_handle->tmp_list = NULL;
00255 qt_handle = NULL;
00256
00257 return;
00258 }