LCOV - code coverage report
Current view: top level - source4/ntvfs/posix - posix_eadb.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 83 101 82.2 %
Date: 2024-06-13 04:01:37 Functions: 10 11 90.9 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    POSIX NTVFS backend - xattr support using a tdb
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2004
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "lib/tdb_wrap/tdb_wrap.h"
      24             : #ifdef WITH_NTVFS_FILESERVER
      25             : #include "vfs_posix.h"
      26             : #endif
      27             : #include "posix_eadb.h"
      28             : 
      29             : #define XATTR_LIST_ATTR ".xattr_list"
      30             : 
      31             : /*
      32             :   we need to maintain a list of attributes on each file, so that unlink
      33             :   can automatically clean them up
      34             : */
      35      198852 : static NTSTATUS posix_eadb_add_list(struct tdb_wrap *ea_tdb, TALLOC_CTX *ctx, const char *attr_name,
      36             :                                    const char *fname, int fd)
      37             : {
      38             :         DATA_BLOB blob;
      39             :         TALLOC_CTX *mem_ctx;
      40             :         const char *s;
      41             :         NTSTATUS status;
      42             :         size_t len;
      43             : 
      44      198852 :         if (strcmp(attr_name, XATTR_LIST_ATTR) == 0) {
      45       97927 :                 return NT_STATUS_OK;
      46             :         }
      47             : 
      48      100925 :         mem_ctx = talloc_new(ctx);
      49             : 
      50      100925 :         status = pull_xattr_blob_tdb_raw(ea_tdb, mem_ctx, XATTR_LIST_ATTR,
      51             :                                      fname, fd, 100, &blob);
      52      100925 :         if (!NT_STATUS_IS_OK(status)) {
      53       97346 :                 blob = data_blob(NULL, 0);
      54             :         }
      55             : 
      56      101771 :         for (s=(const char *)blob.data; s < (const char *)(blob.data+blob.length); s += strlen(s) + 1) {
      57        3844 :                 if (strcmp(attr_name, s) == 0) {
      58        2998 :                         talloc_free(mem_ctx);
      59        2998 :                         return NT_STATUS_OK;
      60             :                 }
      61             :         }
      62             : 
      63       97927 :         len = strlen(attr_name) + 1;
      64             : 
      65       97927 :         blob.data = talloc_realloc(mem_ctx, blob.data, uint8_t, blob.length + len);
      66       97927 :         if (blob.data == NULL) {
      67           0 :                 talloc_free(mem_ctx);
      68           0 :                 return NT_STATUS_NO_MEMORY;
      69             :         }
      70       97927 :         memcpy(blob.data + blob.length, attr_name, len);
      71       97927 :         blob.length += len;
      72             : 
      73       97927 :         status = push_xattr_blob_tdb_raw(ea_tdb, XATTR_LIST_ATTR, fname, fd, &blob);
      74       97927 :         talloc_free(mem_ctx);
      75             : 
      76       97927 :         return status;
      77             : }
      78             : 
      79             : /*
      80             :   form a key for using in the ea_tdb
      81             : */
      82     1989545 : static NTSTATUS get_ea_tdb_key(TALLOC_CTX *mem_ctx,
      83             :                               const char *attr_name,
      84             :                               const char *fname, int fd,
      85             :                               TDB_DATA *key)
      86             : {
      87             :         struct stat st;
      88     1989545 :         size_t len = strlen(attr_name);
      89             : 
      90     1989545 :         if (fd == -1) {
      91     1496050 :                 if (stat(fname, &st) == -1) {
      92           0 :                         return NT_STATUS_NOT_FOUND;
      93             :                 }
      94             :         } else {
      95      493495 :                 if (fstat(fd, &st) == -1) {
      96           0 :                         return NT_STATUS_NOT_FOUND;
      97             :                 }
      98             :         }
      99             : 
     100     1989545 :         key->dptr = talloc_array(mem_ctx, uint8_t, 16 + len);
     101     1989545 :         if (key->dptr == NULL) {
     102           0 :                 return NT_STATUS_NO_MEMORY;
     103             :         }
     104     1989545 :         key->dsize = 16 + len;
     105             : 
     106     1989545 :         SBVAL(key->dptr, 0, st.st_dev);
     107     1989545 :         SBVAL(key->dptr, 8, st.st_ino);
     108     1989545 :         memcpy(key->dptr+16, attr_name, len);
     109             : 
     110     1989545 :         return NT_STATUS_OK;
     111             : }
     112             : 
     113             : 
     114             : 
     115             : /*
     116             :   pull a xattr as a blob, using the ea_tdb_context tdb
     117             : */
     118     1595751 : NTSTATUS pull_xattr_blob_tdb_raw(struct tdb_wrap *ea_tdb,
     119             :                              TALLOC_CTX *mem_ctx,
     120             :                              const char *attr_name,
     121             :                              const char *fname,
     122             :                              int fd,
     123             :                              size_t estimated_size,
     124             :                              DATA_BLOB *blob)
     125             : {
     126             :         TDB_DATA tkey, tdata;
     127             :         NTSTATUS status;
     128             : 
     129     1595751 :         status = get_ea_tdb_key(mem_ctx, attr_name, fname, fd, &tkey);
     130     1595751 :         if (!NT_STATUS_IS_OK(status)) {
     131           0 :                 return status;
     132             :         }
     133             : 
     134     1595751 :         tdata = tdb_fetch(ea_tdb->tdb, tkey);
     135     1595751 :         if (tdata.dptr == NULL) {
     136     1147881 :                 return NT_STATUS_NOT_FOUND;
     137             :         }
     138             : 
     139      447870 :         *blob = data_blob_talloc(mem_ctx, tdata.dptr, tdata.dsize);
     140      447870 :         free(tdata.dptr);
     141      447870 :         if (blob->data == NULL) {
     142           0 :                 return NT_STATUS_NO_MEMORY;
     143             :         }
     144             : 
     145      447870 :         return NT_STATUS_OK;
     146             : }
     147             : 
     148             : /*
     149             :   push a xattr as a blob, using ea_tdb
     150             : */
     151      198852 : NTSTATUS push_xattr_blob_tdb_raw(struct tdb_wrap *ea_tdb,
     152             :                              const char *attr_name,
     153             :                              const char *fname,
     154             :                              int fd,
     155             :                              const DATA_BLOB *blob)
     156             : {
     157             :         TDB_DATA tkey, tdata;
     158             :         NTSTATUS status;
     159      198852 :         TALLOC_CTX *mem_ctx = talloc_new(ea_tdb);
     160      198852 :         if (!mem_ctx) {
     161           0 :                 return NT_STATUS_NO_MEMORY;
     162             :         }
     163             : 
     164      198852 :         status = get_ea_tdb_key(mem_ctx, attr_name, fname, fd, &tkey);
     165      198852 :         if (!NT_STATUS_IS_OK(status)) {
     166           0 :                 talloc_free(mem_ctx);
     167           0 :                 return status;
     168             :         }
     169             : 
     170      198852 :         tdata.dptr = blob->data;
     171      198852 :         tdata.dsize = blob->length;
     172             : 
     173      198852 :         if (tdb_chainlock(ea_tdb->tdb, tkey) != 0) {
     174           0 :                 talloc_free(mem_ctx);
     175           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     176             :         }
     177             : 
     178      198852 :         status = posix_eadb_add_list(ea_tdb,mem_ctx, attr_name, fname, fd);
     179      198852 :         if (!NT_STATUS_IS_OK(status)) {
     180           0 :                 talloc_free(mem_ctx);
     181           0 :                 goto done;
     182             :         }
     183             : 
     184      198852 :         if (tdb_store(ea_tdb->tdb, tkey, tdata, TDB_REPLACE) != 0) {
     185           0 :                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
     186             :         }
     187             : 
     188      397594 : done:
     189      198852 :         tdb_chainunlock(ea_tdb->tdb, tkey);
     190      198852 :         talloc_free(mem_ctx);
     191      198852 :         return status;
     192             : }
     193             : 
     194             : 
     195             : /*
     196             :   delete a xattr
     197             : */
     198      194942 : NTSTATUS delete_posix_eadb_raw(struct tdb_wrap *ea_tdb, const char *attr_name,
     199             :                           const char *fname, int fd)
     200             : {
     201             :         TDB_DATA tkey;
     202             :         NTSTATUS status;
     203             : 
     204      194942 :         status = get_ea_tdb_key(NULL, attr_name, fname, fd, &tkey);
     205      194942 :         if (!NT_STATUS_IS_OK(status)) {
     206           0 :                 return status;
     207             :         }
     208             : 
     209      194942 :         if (tdb_delete(ea_tdb->tdb, tkey) != 0) {
     210           5 :                 talloc_free(tkey.dptr);
     211           5 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     212             :         }
     213             : 
     214      194937 :         talloc_free(tkey.dptr);
     215      194937 :         return NT_STATUS_OK;
     216             : }
     217             : 
     218             : 
     219             : /*
     220             :   delete all xattrs for a file
     221             : */
     222      208459 : NTSTATUS unlink_posix_eadb_raw(struct tdb_wrap *ea_tdb, const char *fname, int fd)
     223             : {
     224      208459 :         TALLOC_CTX *mem_ctx = talloc_new(ea_tdb);
     225             :         DATA_BLOB blob;
     226             :         const char *s;
     227             :         NTSTATUS status;
     228             : 
     229      208459 :         status = pull_xattr_blob_tdb_raw(ea_tdb, mem_ctx, XATTR_LIST_ATTR,
     230             :                                      fname, fd, 100, &blob);
     231      208459 :         if (!NT_STATUS_IS_OK(status)) {
     232      111276 :                 talloc_free(mem_ctx);
     233      111276 :                 return NT_STATUS_OK;
     234             :         }
     235             : 
     236      194935 :         for (s=(const char *)blob.data; s < (const char *)(blob.data+blob.length); s += strlen(s) + 1) {
     237       97752 :                 delete_posix_eadb_raw(ea_tdb, s, fname, -1);
     238             :         }
     239             : 
     240       97183 :         status = delete_posix_eadb_raw(ea_tdb, XATTR_LIST_ATTR, fname, fd);
     241       97183 :         talloc_free(mem_ctx);
     242       97183 :         return status;
     243             : }
     244             : 
     245             : /*
     246             :   list all xattrs for a file
     247             : */
     248           0 : NTSTATUS list_posix_eadb_raw(struct tdb_wrap *ea_tdb, TALLOC_CTX *mem_ctx,
     249             :                             const char *fname, int fd,
     250             :                             DATA_BLOB *list)
     251             : {
     252           0 :         return pull_xattr_blob_tdb_raw(ea_tdb, mem_ctx, XATTR_LIST_ATTR,
     253             :                                      fname, fd, 100, list);
     254             : }
     255             : 
     256             : #ifdef WITH_NTVFS_FILESERVER
     257     1286367 : NTSTATUS pull_xattr_blob_tdb(struct pvfs_state *pvfs_state,
     258             :                              TALLOC_CTX *mem_ctx,
     259             :                              const char *attr_name,
     260             :                              const char *fname,
     261             :                              int fd,
     262             :                              size_t estimated_size,
     263             :                              DATA_BLOB *blob)
     264             : {
     265     1286367 :         return pull_xattr_blob_tdb_raw(pvfs_state->ea_db,mem_ctx,attr_name,fname,fd,estimated_size,blob);
     266             : }
     267             : 
     268      100736 : NTSTATUS push_xattr_blob_tdb(struct pvfs_state *pvfs_state,
     269             :                              const char *attr_name,
     270             :                              const char *fname,
     271             :                              int fd,
     272             :                              const DATA_BLOB *blob)
     273             : {
     274      100736 :         return push_xattr_blob_tdb_raw(pvfs_state->ea_db, attr_name, fname, fd, blob);
     275             : }
     276             : 
     277             : /*
     278             :   delete a xattr
     279             : */
     280           7 : NTSTATUS delete_posix_eadb(struct pvfs_state *pvfs_state, const char *attr_name,
     281             :                           const char *fname, int fd)
     282             : {
     283           7 :         return delete_posix_eadb_raw(pvfs_state->ea_db,
     284             :                                     attr_name, fname, fd);
     285             : }
     286             : 
     287             : /*
     288             :   delete all xattrs for a file
     289             : */
     290      208459 : NTSTATUS unlink_posix_eadb(struct pvfs_state *pvfs_state, const char *fname)
     291             : {
     292      208459 :         return unlink_posix_eadb_raw(pvfs_state->ea_db, fname, -1);
     293             : }
     294             : 
     295             : #endif

Generated by: LCOV version 1.13