root/source3/smbd/ntquotas.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. limit_nt2unix
  2. limit_unix2nt
  3. limit_blk2inodes
  4. vfs_get_ntquota
  5. vfs_set_ntquota
  6. allready_in_quota_list
  7. vfs_get_user_ntquota_list
  8. quota_handle_destructor
  9. init_quota_handle

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    NT QUOTA suppport
   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 #include "includes.h"
  21 
  22 #undef DBGC_CLASS
  23 #define DBGC_CLASS DBGC_QUOTA
  24 
  25 static uint64_t limit_nt2unix(uint64_t in, uint64_t bsize)
     /* [<][>][^][v][top][bottom][index][help] */
  26 {
  27         uint64_t ret = (uint64_t)0;
  28 
  29         ret =   (uint64_t)(in/bsize);
  30         if (in>0 && ret==0) {
  31                 /* we have to make sure that a overflow didn't set NO_LIMIT */
  32                 ret = (uint64_t)1;
  33         }
  34 
  35         if (in == SMB_NTQUOTAS_NO_LIMIT)
  36                 ret = SMB_QUOTAS_NO_LIMIT;
  37         else if (in == SMB_NTQUOTAS_NO_SPACE)
  38                 ret = SMB_QUOTAS_NO_SPACE;
  39         else if (in == SMB_NTQUOTAS_NO_ENTRY)
  40                 ret = SMB_QUOTAS_NO_LIMIT;
  41 
  42         return ret;
  43 }
  44 
  45 static uint64_t limit_unix2nt(uint64_t in, uint64_t bsize)
     /* [<][>][^][v][top][bottom][index][help] */
  46 {
  47         uint64_t ret = (uint64_t)0;
  48 
  49         ret = (uint64_t)(in*bsize);
  50         
  51         if (ret < in) {
  52                 /* we overflow */
  53                 ret = SMB_NTQUOTAS_NO_LIMIT;
  54         }
  55 
  56         if (in == SMB_QUOTAS_NO_LIMIT)
  57                 ret = SMB_NTQUOTAS_NO_LIMIT;
  58 
  59         return ret;
  60 }
  61 
  62 static uint64_t limit_blk2inodes(uint64_t in)
     /* [<][>][^][v][top][bottom][index][help] */
  63 {
  64         uint64_t ret = (uint64_t)0;
  65         
  66         ret = (uint64_t)(in/2);
  67         
  68         if (ret == 0 && in != 0)
  69                 ret = (uint64_t)1;
  70 
  71         return ret;     
  72 }
  73 
  74 int vfs_get_ntquota(files_struct *fsp, enum SMB_QUOTA_TYPE qtype, DOM_SID *psid, SMB_NTQUOTA_STRUCT *qt)
     /* [<][>][^][v][top][bottom][index][help] */
  75 {
  76         int ret;
  77         SMB_DISK_QUOTA D;
  78         unid_t id;
  79 
  80         ZERO_STRUCT(D);
  81 
  82         if (!fsp||!fsp->conn||!qt)
  83                 return (-1);
  84 
  85         ZERO_STRUCT(*qt);
  86 
  87         id.uid = -1;
  88 
  89         if (psid && !sid_to_uid(psid, &id.uid)) {
  90                 DEBUG(0,("sid_to_uid: failed, SID[%s]\n",
  91                          sid_string_dbg(psid)));
  92         }
  93 
  94         ret = SMB_VFS_GET_QUOTA(fsp->conn, qtype, id, &D);
  95 
  96         if (psid)
  97                 qt->sid    = *psid;
  98 
  99         if (ret!=0) {
 100                 return ret;
 101         }
 102                 
 103         qt->usedspace = (uint64_t)D.curblocks*D.bsize;
 104         qt->softlim = limit_unix2nt(D.softlimit, D.bsize);
 105         qt->hardlim = limit_unix2nt(D.hardlimit, D.bsize);
 106         qt->qflags = D.qflags;
 107 
 108         
 109         return 0;
 110 }
 111 
 112 int vfs_set_ntquota(files_struct *fsp, enum SMB_QUOTA_TYPE qtype, DOM_SID *psid, SMB_NTQUOTA_STRUCT *qt)
     /* [<][>][^][v][top][bottom][index][help] */
 113 {
 114         int ret;
 115         SMB_DISK_QUOTA D;
 116         unid_t id;
 117         ZERO_STRUCT(D);
 118 
 119         if (!fsp||!fsp->conn||!qt)
 120                 return (-1);
 121 
 122         id.uid = -1;
 123 
 124         D.bsize     = (uint64_t)QUOTABLOCK_SIZE;
 125 
 126         D.softlimit = limit_nt2unix(qt->softlim,D.bsize);
 127         D.hardlimit = limit_nt2unix(qt->hardlim,D.bsize);
 128         D.qflags     = qt->qflags;
 129 
 130         D.isoftlimit = limit_blk2inodes(D.softlimit);
 131         D.ihardlimit = limit_blk2inodes(D.hardlimit);
 132 
 133         if (psid && !sid_to_uid(psid, &id.uid)) {
 134                 DEBUG(0,("sid_to_uid: failed, SID[%s]\n",
 135                          sid_string_dbg(psid)));
 136         }
 137 
 138         ret = SMB_VFS_SET_QUOTA(fsp->conn, qtype, id, &D);
 139         
 140         return ret;
 141 }
 142 
 143 static bool allready_in_quota_list(SMB_NTQUOTA_LIST *qt_list, uid_t uid)
     /* [<][>][^][v][top][bottom][index][help] */
 144 {
 145         SMB_NTQUOTA_LIST *tmp_list = NULL;
 146         
 147         if (!qt_list)
 148                 return False;
 149 
 150         for (tmp_list=qt_list;tmp_list!=NULL;tmp_list=tmp_list->next) {
 151                 if (tmp_list->uid == uid) {
 152                         return True;    
 153                 }
 154         }
 155 
 156         return False;
 157 }
 158 
 159 int vfs_get_user_ntquota_list(files_struct *fsp, SMB_NTQUOTA_LIST **qt_list)
     /* [<][>][^][v][top][bottom][index][help] */
 160 {
 161         struct passwd *usr;
 162         TALLOC_CTX *mem_ctx = NULL;
 163 
 164         if (!fsp||!fsp->conn||!qt_list)
 165                 return (-1);
 166 
 167         *qt_list = NULL;
 168 
 169         if ((mem_ctx=talloc_init("SMB_USER_QUOTA_LIST"))==NULL) {
 170                 DEBUG(0,("talloc_init() failed\n"));
 171                 return (-1);
 172         }
 173 
 174         sys_setpwent();
 175         while ((usr = sys_getpwent()) != NULL) {
 176                 SMB_NTQUOTA_STRUCT tmp_qt;
 177                 SMB_NTQUOTA_LIST *tmp_list_ent;
 178                 DOM_SID sid;
 179 
 180                 ZERO_STRUCT(tmp_qt);
 181 
 182                 if (allready_in_quota_list((*qt_list),usr->pw_uid)) {
 183                         DEBUG(5,("record for uid[%ld] allready in the list\n",(long)usr->pw_uid));
 184                         continue;
 185                 }
 186 
 187                 uid_to_sid(&sid, usr->pw_uid);
 188 
 189                 if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &tmp_qt)!=0) {
 190                         DEBUG(5,("no quota entry for sid[%s] path[%s]\n",
 191                                  sid_string_dbg(&sid),
 192                                  fsp->conn->connectpath));
 193                         continue;
 194                 }
 195 
 196                 DEBUG(15,("quota entry for id[%s] path[%s]\n",
 197                           sid_string_dbg(&sid), fsp->conn->connectpath));
 198 
 199                 if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) {
 200                         DEBUG(0,("TALLOC_ZERO() failed\n"));
 201                         *qt_list = NULL;
 202                         talloc_destroy(mem_ctx);
 203                         return (-1);
 204                 }
 205 
 206                 if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) {
 207                         DEBUG(0,("TALLOC_ZERO() failed\n"));
 208                         *qt_list = NULL;
 209                         talloc_destroy(mem_ctx);
 210                         return (-1);
 211                 }
 212 
 213                 tmp_list_ent->uid = usr->pw_uid;
 214                 memcpy(tmp_list_ent->quotas,&tmp_qt,sizeof(tmp_qt));
 215                 tmp_list_ent->mem_ctx = mem_ctx;
 216 
 217                 DLIST_ADD((*qt_list),tmp_list_ent);
 218                 
 219         }
 220         sys_endpwent();
 221 
 222         return 0;
 223 }
 224 
 225 static int quota_handle_destructor(SMB_NTQUOTA_HANDLE *handle)
     /* [<][>][^][v][top][bottom][index][help] */
 226 {
 227         if (handle->quota_list)
 228                 free_ntquota_list(&handle->quota_list);
 229         return 0;
 230 }
 231 
 232 void *init_quota_handle(TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 233 {
 234         SMB_NTQUOTA_HANDLE *qt_handle;
 235 
 236         if (!mem_ctx)
 237                 return False;
 238 
 239         qt_handle = TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_HANDLE);
 240         if (qt_handle==NULL) {
 241                 DEBUG(0,("TALLOC_ZERO() failed\n"));
 242                 return NULL;
 243         }
 244 
 245         talloc_set_destructor(qt_handle, quota_handle_destructor);
 246         return (void *)qt_handle;
 247 }

/* [<][>][^][v][top][bottom][index][help] */