smbd/ntquotas.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    NT QUOTA suppport
00004    Copyright (C) Stefan (metze) Metzmacher      2003
00005    
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015    
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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                 /* we have to make sure that a overflow didn't set NO_LIMIT */
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                 /* we overflow */
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 }

Sambaに対してSat Aug 29 21:23:24 2009に生成されました。  doxygen 1.4.7