Fix bug #7080 - Quota only shown when logged as root.
[ira/wip.git] / source3 / smbd / fake_file.c
index 17617ce443fa3f54f8594f7d68f3f681201668e3..9917481351a6b1849af438402fa441dd49fbc6d0 100644 (file)
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 
-extern struct current_user current_user;
+struct fake_file_type {
+       const char *name;
+       enum FAKE_FILE_TYPE type;
+       void *(*init_pd)(TALLOC_CTX *mem_ctx);
+};
 
-static FAKE_FILE fake_files[] = {
+static const struct fake_file_type fake_files[] = {
 #ifdef WITH_QUOTAS
-       {FAKE_FILE_NAME_QUOTA_UNIX,     FAKE_FILE_TYPE_QUOTA,   init_quota_handle,      destroy_quota_handle},
+       {FAKE_FILE_NAME_QUOTA_UNIX, FAKE_FILE_TYPE_QUOTA, init_quota_handle},
 #endif /* WITH_QUOTAS */
-       {NULL,                          FAKE_FILE_TYPE_NONE,    NULL,                   NULL }
+       {NULL, FAKE_FILE_TYPE_NONE, NULL}
 };
 
 /****************************************************************************
  Create a fake file handle
 ****************************************************************************/
 
-static struct _FAKE_FILE_HANDLE *init_fake_file_handle(enum FAKE_FILE_TYPE type)
+static struct fake_file_handle *init_fake_file_handle(enum FAKE_FILE_TYPE type)
 {
-       TALLOC_CTX *mem_ctx = NULL;
-       FAKE_FILE_HANDLE *fh = NULL;
+       struct fake_file_handle *fh = NULL;
        int i;
 
-       for (i=0;fake_files[i].name!=NULL;i++) {
+       for (i=0; fake_files[i].name!=NULL; i++) {
                if (fake_files[i].type==type) {
-                       DEBUG(5,("init_fake_file_handle: for [%s]\n",fake_files[i].name));
-
-                       if ((mem_ctx=talloc_init("fake_file_handle"))==NULL) {
-                               DEBUG(0,("talloc_init(fake_file_handle) failed.\n"));
-                               return NULL;    
-                       }
+                       break;
+               }
+       }
 
-                       if ((fh =TALLOC_ZERO_P(mem_ctx, FAKE_FILE_HANDLE))==NULL) {
-                               DEBUG(0,("TALLOC_ZERO() failed.\n"));
-                               talloc_destroy(mem_ctx);
-                               return NULL;
-                       }
+       if (fake_files[i].name == NULL) {
+               return NULL;
+       }
 
-                       fh->type = type;
-                       fh->mem_ctx = mem_ctx;
+       DEBUG(5,("init_fake_file_handle: for [%s]\n",fake_files[i].name));
 
-                       if (fake_files[i].init_pd) {
-                               fh->pd = fake_files[i].init_pd(fh->mem_ctx);
-                       }
+       fh = talloc(NULL, struct fake_file_handle);
+       if (fh == NULL) {
+               DEBUG(0,("TALLOC_ZERO() failed.\n"));
+               return NULL;
+       }
 
-                       fh->free_pd = fake_files[i].free_pd;
+       fh->type = type;
 
-                       return fh;
-               }
+       if (fake_files[i].init_pd) {
+               fh->private_data = fake_files[i].init_pd(fh);
        }
-
-       return NULL;    
+       return fh;
 }
 
 /****************************************************************************
  Does this name match a fake filename ?
 ****************************************************************************/
 
-enum FAKE_FILE_TYPE is_fake_file(const char *fname)
+enum FAKE_FILE_TYPE is_fake_file_path(const char *path)
 {
-#ifdef HAVE_SYS_QUOTAS
        int i;
-#endif
 
-       if (!fname) {
+       if (!path) {
                return FAKE_FILE_TYPE_NONE;
        }
 
-#ifdef HAVE_SYS_QUOTAS
        for (i=0;fake_files[i].name!=NULL;i++) {
-               if (strncmp(fname,fake_files[i].name,strlen(fake_files[i].name))==0) {
-                       DEBUG(5,("is_fake_file: [%s] is a fake file\n",fname));
+               if (strncmp(path,fake_files[i].name,strlen(fake_files[i].name))==0) {
+                       DEBUG(5,("is_fake_file: [%s] is a fake file\n",path));
                        return fake_files[i].type;
                }
        }
-#endif
 
        return FAKE_FILE_TYPE_NONE;
 }
 
+enum FAKE_FILE_TYPE is_fake_file(const struct smb_filename *smb_fname)
+{
+       char *fname = NULL;
+       NTSTATUS status;
+       enum FAKE_FILE_TYPE ret;
+
+       if (!smb_fname) {
+               return FAKE_FILE_TYPE_NONE;
+       }
+
+       status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               return FAKE_FILE_TYPE_NONE;
+       }
+
+       ret = is_fake_file_path(fname);
+
+       TALLOC_FREE(fname);
+
+       return ret;
+}
 
 /****************************************************************************
  Open a fake quota file with a share mode.
 ****************************************************************************/
 
-NTSTATUS open_fake_file(connection_struct *conn,
+NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn,
+                               uint16_t current_vuid,
                                enum FAKE_FILE_TYPE fake_file_type,
-                               const char *fname,
+                               const struct smb_filename *smb_fname,
                                uint32 access_mask,
                                files_struct **result)
 {
@@ -111,57 +126,50 @@ NTSTATUS open_fake_file(connection_struct *conn,
        NTSTATUS status;
 
        /* access check */
-       if (current_user.ut.uid != 0) {
-               DEBUG(1,("open_fake_file_shared: access_denied to service[%s] file[%s] user[%s]\n",
-                       lp_servicename(SNUM(conn)),fname,conn->user));
+       if (geteuid() == sec_initial_uid()) {
+               DEBUG(3, ("open_fake_file_shared: access_denied to "
+                         "service[%s] file[%s] user[%s]\n",
+                         lp_servicename(SNUM(conn)),
+                         smb_fname_str_dbg(smb_fname),
+                         conn->server_info->unix_name));
                return NT_STATUS_ACCESS_DENIED;
 
        }
 
-       status = file_new(conn, &fsp);
+       status = file_new(req, conn, &fsp);
        if(!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
        DEBUG(5,("open_fake_file_shared: fname = %s, FID = %d, access_mask = 0x%x\n",
-               fname, fsp->fnum, (unsigned int)access_mask));
+                smb_fname_str_dbg(smb_fname), fsp->fnum,
+                (unsigned int)access_mask));
 
        fsp->conn = conn;
        fsp->fh->fd = -1;
-       fsp->vuid = current_user.vuid;
+       fsp->vuid = current_vuid;
        fsp->fh->pos = -1;
        fsp->can_lock = False; /* Should this be true ? - No, JRA */
        fsp->access_mask = access_mask;
-       string_set(&fsp->fsp_name,fname);
-       
+       status = fsp_set_smb_fname(fsp, smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               file_free(req, fsp);
+               return NT_STATUS_NO_MEMORY;
+       }
+
        fsp->fake_file_handle = init_fake_file_handle(fake_file_type);
        
        if (fsp->fake_file_handle==NULL) {
-               file_free(fsp);
+               file_free(req, fsp);
                return NT_STATUS_NO_MEMORY;
        }
 
-       conn->num_files_open++;
        *result = fsp;
        return NT_STATUS_OK;
 }
 
-void destroy_fake_file_handle(FAKE_FILE_HANDLE **fh)
-{
-       if (!fh||!(*fh)) {
-               return;
-       }
-
-       if ((*fh)->free_pd) {
-               (*fh)->free_pd(&(*fh)->pd);             
-       }
-
-       talloc_destroy((*fh)->mem_ctx);
-       (*fh) = NULL;
-}
-
-NTSTATUS close_fake_file(files_struct *fsp)
+NTSTATUS close_fake_file(struct smb_request *req, files_struct *fsp)
 {
-       file_free(fsp);
+       file_free(req, fsp);
        return NT_STATUS_OK;
 }