LCOV - code coverage report
Current view: top level - source3/modules - vfs_xattr_tdb.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 191 234 81.6 %
Date: 2021-09-23 10:06:22 Functions: 16 17 94.1 %

          Line data    Source code
       1             : /*
       2             :  * Store posix-level xattrs in a tdb
       3             :  *
       4             :  * Copyright (C) Volker Lendecke, 2007
       5             :  * Copyright (C) Andrew Bartlett, 2012
       6             :  *
       7             :  * This program is free software; you can redistribute it and/or modify
       8             :  * it under the terms of the GNU General Public License as published by
       9             :  * the Free Software Foundation; either version 3 of the License, or
      10             :  * (at your option) any later version.
      11             :  *
      12             :  * This program is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :  * GNU General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU General Public License
      18             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : #include "includes.h"
      22             : #include "system/filesys.h"
      23             : #include "smbd/smbd.h"
      24             : #include "dbwrap/dbwrap.h"
      25             : #include "dbwrap/dbwrap_open.h"
      26             : #include "source3/lib/xattr_tdb.h"
      27             : #include "lib/util/tevent_unix.h"
      28             : 
      29             : #undef DBGC_CLASS
      30             : #define DBGC_CLASS DBGC_VFS
      31             : 
      32             : static bool xattr_tdb_init(int snum, TALLOC_CTX *mem_ctx, struct db_context **p_db);
      33             : 
      34       20116 : static int xattr_tdb_get_file_id(struct vfs_handle_struct *handle,
      35             :                                 const char *path, struct file_id *id)
      36             : {
      37             :         int ret;
      38       20116 :         TALLOC_CTX *frame = talloc_stackframe();
      39             :         struct smb_filename *smb_fname;
      40             : 
      41       20116 :         smb_fname = synthetic_smb_fname(frame,
      42             :                                         path,
      43             :                                         NULL,
      44             :                                         NULL,
      45             :                                         0,
      46             :                                         0);
      47       20116 :         if (smb_fname == NULL) {
      48           0 :                 TALLOC_FREE(frame);
      49           0 :                 errno = ENOMEM;
      50           0 :                 return -1;
      51             :         }
      52             : 
      53       20116 :         ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
      54             : 
      55       20116 :         if (ret == -1) {
      56           0 :                 TALLOC_FREE(frame); 
      57           0 :                 return -1;
      58             :         }
      59             : 
      60       20116 :         *id = SMB_VFS_NEXT_FILE_ID_CREATE(handle, &smb_fname->st);
      61       20116 :         TALLOC_FREE(frame);
      62       20116 :         return 0;
      63             : }
      64             : 
      65             : struct xattr_tdb_getxattrat_state {
      66             :         struct vfs_aio_state vfs_aio_state;
      67             :         ssize_t xattr_size;
      68             :         uint8_t *xattr_value;
      69             : };
      70             : 
      71       20116 : static struct tevent_req *xattr_tdb_getxattrat_send(
      72             :                         TALLOC_CTX *mem_ctx,
      73             :                         struct tevent_context *ev,
      74             :                         struct vfs_handle_struct *handle,
      75             :                         files_struct *dir_fsp,
      76             :                         const struct smb_filename *smb_fname,
      77             :                         const char *xattr_name,
      78             :                         size_t alloc_hint)
      79             : {
      80       20116 :         struct tevent_req *req = NULL;
      81       20116 :         struct xattr_tdb_getxattrat_state *state = NULL;
      82       20116 :         struct smb_filename *cwd = NULL;
      83       20116 :         struct db_context *db = NULL;
      84             :         struct file_id id;
      85             :         int ret;
      86             :         int error;
      87             :         int cwd_ret;
      88             :         DATA_BLOB xattr_blob;
      89             : 
      90       20116 :         req = tevent_req_create(mem_ctx, &state,
      91             :                                 struct xattr_tdb_getxattrat_state);
      92       20116 :         if (req == NULL) {
      93           0 :                 return NULL;
      94             :         }
      95       20116 :         state->xattr_size = -1;
      96             : 
      97       20116 :         SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
      98             :                                 if (!xattr_tdb_init(-1, state, &db)) {
      99             :                                         tevent_req_error(req, EIO);
     100             :                                         return tevent_req_post(req, ev);
     101             :                                 });
     102             : 
     103       20116 :         cwd = SMB_VFS_GETWD(dir_fsp->conn, state);
     104       20116 :         if (tevent_req_nomem(cwd, req)) {
     105           0 :                 return tevent_req_post(req, ev);
     106             :         }
     107             : 
     108       20116 :         ret = SMB_VFS_CHDIR(dir_fsp->conn, dir_fsp->fsp_name);
     109       20116 :         if (ret != 0) {
     110           0 :                 tevent_req_error(req, errno);
     111           0 :                 return tevent_req_post(req, ev);
     112             :         }
     113             : 
     114       20116 :         ret = xattr_tdb_get_file_id(handle, smb_fname->base_name, &id);
     115       20116 :         error = errno;
     116             : 
     117       20116 :         cwd_ret = SMB_VFS_CHDIR(dir_fsp->conn, cwd);
     118       20116 :         SMB_ASSERT(cwd_ret == 0);
     119             : 
     120       20116 :         if (ret == -1) {
     121           0 :                 tevent_req_error(req, error);
     122           0 :                 return tevent_req_post(req, ev);
     123             :         }
     124             : 
     125       20116 :         state->xattr_size = xattr_tdb_getattr(db,
     126             :                                               state,
     127             :                                               &id,
     128             :                                               xattr_name,
     129             :                                               &xattr_blob);
     130       20116 :         if (state->xattr_size == -1) {
     131         104 :                 tevent_req_error(req, errno);
     132         104 :                 return tevent_req_post(req, ev);
     133             :         }
     134             : 
     135       20012 :         if (alloc_hint == 0) {
     136             :                 /*
     137             :                  * The caller only wants to know the size.
     138             :                  */
     139           0 :                 tevent_req_done(req);
     140           0 :                 return tevent_req_post(req, ev);
     141             :         }
     142             : 
     143       20012 :         if (state->xattr_size == 0) {
     144             :                 /*
     145             :                  * There's no data.
     146             :                  */
     147           0 :                 tevent_req_done(req);
     148           0 :                 return tevent_req_post(req, ev);
     149             :         }
     150             : 
     151       20012 :         if (xattr_blob.length > alloc_hint) {
     152             :                 /*
     153             :                  * The data doesn't fit.
     154             :                  */
     155           0 :                 state->xattr_size = -1;
     156           0 :                 tevent_req_error(req, ERANGE);
     157           0 :                 return tevent_req_post(req, ev);
     158             :         }
     159             : 
     160             :         /*
     161             :          * take the whole blob.
     162             :          */
     163       20012 :         state->xattr_value = xattr_blob.data;
     164             : 
     165       20012 :         tevent_req_done(req);
     166       20012 :         return tevent_req_post(req, ev);
     167             : }
     168             : 
     169       20116 : static ssize_t xattr_tdb_getxattrat_recv(struct tevent_req *req,
     170             :                                          struct vfs_aio_state *aio_state,
     171             :                                          TALLOC_CTX *mem_ctx,
     172             :                                          uint8_t **xattr_value)
     173             : {
     174       20116 :         struct xattr_tdb_getxattrat_state *state = tevent_req_data(
     175             :                 req, struct xattr_tdb_getxattrat_state);
     176             :         ssize_t xattr_size;
     177             : 
     178       20116 :         if (tevent_req_is_unix_error(req, &aio_state->error)) {
     179         104 :                 tevent_req_received(req);
     180         104 :                 return -1;
     181             :         }
     182             : 
     183       20012 :         *aio_state = state->vfs_aio_state;
     184       20012 :         xattr_size = state->xattr_size;
     185       20012 :         if (xattr_value != NULL) {
     186       20012 :                 *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
     187             :         }
     188             : 
     189       20012 :         tevent_req_received(req);
     190       20012 :         return xattr_size;
     191             : }
     192             : 
     193    48494338 : static ssize_t xattr_tdb_fgetxattr(struct vfs_handle_struct *handle,
     194             :                                    struct files_struct *fsp,
     195             :                                    const char *name, void *value, size_t size)
     196             : {
     197             :         SMB_STRUCT_STAT sbuf;
     198             :         struct file_id id;
     199             :         struct db_context *db;
     200             :         ssize_t xattr_size;
     201             :         DATA_BLOB blob;
     202    48494338 :         TALLOC_CTX *frame = talloc_stackframe();
     203             : 
     204    48494338 :         SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
     205             :                                 if (!xattr_tdb_init(-1, frame, &db))
     206             :                                 {
     207             :                                         TALLOC_FREE(frame); return -1;
     208             :                                 });
     209             : 
     210    48494338 :         if (SMB_VFS_NEXT_FSTAT(handle, fsp, &sbuf) == -1) {
     211          30 :                 TALLOC_FREE(frame);
     212          30 :                 return -1;
     213             :         }
     214             : 
     215    48494308 :         id = SMB_VFS_NEXT_FILE_ID_CREATE(handle, &sbuf);
     216             : 
     217    48494308 :         xattr_size = xattr_tdb_getattr(db, frame, &id, name, &blob);
     218    48494308 :         if (xattr_size < 0) {
     219    21804079 :                 errno = ENOATTR;
     220    21804079 :                 TALLOC_FREE(frame);
     221    21622610 :                 return -1;
     222             :         }
     223             : 
     224    26690229 :         if (size == 0) {
     225          12 :                 TALLOC_FREE(frame);
     226          12 :                 return xattr_size;
     227             :         }
     228             : 
     229    26690217 :         if (blob.length > size) {
     230         174 :                 TALLOC_FREE(frame);
     231         174 :                 errno = ERANGE;
     232         174 :                 return -1;
     233             :         }
     234    26848195 :         memcpy(value, blob.data, xattr_size);
     235    26690043 :         TALLOC_FREE(frame);
     236    26531891 :         return xattr_size;
     237             : }
     238             : 
     239      777145 : static int xattr_tdb_fsetxattr(struct vfs_handle_struct *handle,
     240             :                                struct files_struct *fsp,
     241             :                                const char *name, const void *value,
     242             :                                size_t size, int flags)
     243             : {
     244             :         SMB_STRUCT_STAT sbuf;
     245             :         struct file_id id;
     246             :         struct db_context *db;
     247             :         int ret;
     248      777145 :         TALLOC_CTX *frame = talloc_stackframe();
     249             : 
     250      777145 :         SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
     251             :                                 if (!xattr_tdb_init(-1, frame, &db))
     252             :                                 {
     253             :                                         TALLOC_FREE(frame); return -1;
     254             :                                 });
     255             : 
     256      777145 :         if (SMB_VFS_NEXT_FSTAT(handle, fsp, &sbuf) == -1) {
     257           0 :                 TALLOC_FREE(frame);
     258           0 :                 return -1;
     259             :         }
     260             : 
     261      777145 :         id = SMB_VFS_NEXT_FILE_ID_CREATE(handle, &sbuf);
     262             : 
     263      777145 :         ret = xattr_tdb_setattr(db, &id, name, value, size, flags);
     264      777145 :         TALLOC_FREE(frame);
     265      775098 :         return ret;
     266             : 
     267             : }
     268             : 
     269      310259 : static ssize_t xattr_tdb_flistxattr(struct vfs_handle_struct *handle,
     270             :                                     struct files_struct *fsp, char *list,
     271             :                                     size_t size)
     272             : {
     273             :         SMB_STRUCT_STAT sbuf;
     274             :         struct file_id id;
     275             :         struct db_context *db;
     276             :         int ret;
     277      310259 :         TALLOC_CTX *frame = talloc_stackframe();
     278             : 
     279      310259 :         SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
     280             :                                 if (!xattr_tdb_init(-1, frame, &db))
     281             :                                 {
     282             :                                         TALLOC_FREE(frame); return -1;
     283             :                                 });
     284             : 
     285      310259 :         if (SMB_VFS_NEXT_FSTAT(handle, fsp, &sbuf) == -1) {
     286           2 :                 TALLOC_FREE(frame);
     287           2 :                 return -1;
     288             :         }
     289             : 
     290      310257 :         id = SMB_VFS_NEXT_FILE_ID_CREATE(handle, &sbuf);
     291             : 
     292      310257 :         ret = xattr_tdb_listattr(db, &id, list, size);
     293      310257 :         TALLOC_FREE(frame);
     294      310257 :         return ret;
     295             : }
     296             : 
     297        2052 : static int xattr_tdb_fremovexattr(struct vfs_handle_struct *handle,
     298             :                                   struct files_struct *fsp, const char *name)
     299             : {
     300             :         SMB_STRUCT_STAT sbuf;
     301             :         struct file_id id;
     302             :         struct db_context *db;
     303             :         int ret;
     304        2052 :         TALLOC_CTX *frame = talloc_stackframe();
     305             : 
     306        2052 :         SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
     307             :                                 if (!xattr_tdb_init(-1, frame, &db))
     308             :                                 {
     309             :                                         TALLOC_FREE(frame); return -1;
     310             :                                 });
     311             : 
     312        2052 :         if (SMB_VFS_NEXT_FSTAT(handle, fsp, &sbuf) == -1) {
     313           0 :                 TALLOC_FREE(frame);
     314           0 :                 return -1;
     315             :         }
     316             : 
     317        2052 :         id = SMB_VFS_NEXT_FILE_ID_CREATE(handle, &sbuf);
     318             : 
     319        2052 :         ret = xattr_tdb_removeattr(db, &id, name);
     320        2052 :         TALLOC_FREE(frame);
     321        1836 :         return ret;
     322             : }
     323             : 
     324             : /*
     325             :  * Open the tdb file upon VFS_CONNECT
     326             :  */
     327             : 
     328       84434 : static bool xattr_tdb_init(int snum, TALLOC_CTX *mem_ctx, struct db_context **p_db)
     329             : {
     330             :         struct db_context *db;
     331             :         const char *dbname;
     332             :         char *def_dbname;
     333             : 
     334       84434 :         def_dbname = state_path(talloc_tos(), "xattr.tdb");
     335       84434 :         if (def_dbname == NULL) {
     336           0 :                 errno = ENOSYS;
     337           0 :                 return false;
     338             :         }
     339             : 
     340       84434 :         dbname = lp_parm_const_string(snum, "xattr_tdb", "file", def_dbname);
     341             : 
     342             :         /* now we know dbname is not NULL */
     343             : 
     344       84434 :         become_root();
     345       84434 :         db = db_open(NULL, dbname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600,
     346             :                      DBWRAP_LOCK_ORDER_2, DBWRAP_FLAG_NONE);
     347       84434 :         unbecome_root();
     348             : 
     349       84434 :         if (db == NULL) {
     350             : #if defined(ENOTSUP)
     351           0 :                 errno = ENOTSUP;
     352             : #else
     353             :                 errno = ENOSYS;
     354             : #endif
     355           0 :                 TALLOC_FREE(def_dbname);
     356           0 :                 return false;
     357             :         }
     358             : 
     359       84434 :         *p_db = db;
     360       84434 :         TALLOC_FREE(def_dbname);
     361       83583 :         return true;
     362             : }
     363             : 
     364    10075027 : static int xattr_tdb_openat(struct vfs_handle_struct *handle,
     365             :                             const struct files_struct *dirfsp,
     366             :                             const struct smb_filename *smb_fname,
     367             :                             struct files_struct *fsp,
     368             :                             int flags,
     369             :                             mode_t mode)
     370             : {
     371    10075027 :         struct db_context *db = NULL;
     372    10075027 :         TALLOC_CTX *frame = NULL;
     373             :         SMB_STRUCT_STAT sbuf;
     374             :         int fd;
     375             :         int ret;
     376             : 
     377    10075027 :         fd = SMB_VFS_NEXT_OPENAT(handle,
     378             :                                  dirfsp,
     379             :                                  smb_fname,
     380             :                                  fsp,
     381             :                                  flags,
     382             :                                  mode);
     383             : 
     384    10075027 :         if (fd == -1) {
     385        9239 :                 return -1;
     386             :         }
     387             : 
     388    10065702 :         if ((flags & (O_CREAT|O_EXCL)) != (O_CREAT|O_EXCL)) {
     389     9846598 :                 return fd;
     390             :         }
     391             : 
     392             :         /*
     393             :          * We know we used O_CREAT|O_EXCL and it worked.
     394             :          * We must have created the file.
     395             :          */
     396             : 
     397      133595 :         fsp_set_fd(fsp, fd);
     398      133595 :         ret = SMB_VFS_FSTAT(fsp, &sbuf);
     399      133595 :         fsp_set_fd(fsp, -1);
     400      133595 :         if (ret == -1) {
     401             :                 /* Can't happen... */
     402           0 :                 DBG_WARNING("SMB_VFS_FSTAT failed on file %s (%s)\n",
     403             :                             smb_fname_str_dbg(smb_fname),
     404             :                             strerror(errno));
     405           0 :                 return -1;
     406             :         }
     407             : 
     408      133595 :         fsp->file_id = SMB_VFS_FILE_ID_CREATE(fsp->conn, &sbuf);
     409             : 
     410      133595 :         frame = talloc_stackframe();
     411             : 
     412      133595 :         SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
     413             :                                 if (!xattr_tdb_init(-1, frame, &db))
     414             :                                 {
     415             :                                         TALLOC_FREE(frame); return -1;
     416             :                                 });
     417             : 
     418      133595 :         xattr_tdb_remove_all_attrs(db, &fsp->file_id);
     419             : 
     420      133595 :         TALLOC_FREE(frame);
     421      133442 :         return fd;
     422             : }
     423             : 
     424       11030 : static int xattr_tdb_mkdirat(vfs_handle_struct *handle,
     425             :                 struct files_struct *dirfsp,
     426             :                 const struct smb_filename *smb_fname,
     427             :                 mode_t mode)
     428             : {
     429       11030 :         struct db_context *db = NULL;
     430       11030 :         TALLOC_CTX *frame = NULL;
     431             :         struct file_id fileid;
     432             :         int ret;
     433       11030 :         struct smb_filename *full_fname = NULL;
     434             : 
     435       11030 :         ret = SMB_VFS_NEXT_MKDIRAT(handle,
     436             :                                 dirfsp,
     437             :                                 smb_fname,
     438             :                                 mode);
     439       11030 :         if (ret < 0) {
     440         268 :                 return ret;
     441             :         }
     442             : 
     443       10762 :         frame = talloc_stackframe();
     444             : 
     445       10762 :         full_fname = full_path_from_dirfsp_atname(talloc_tos(),
     446             :                                                   dirfsp,
     447             :                                                   smb_fname);
     448       10762 :         if (full_fname == NULL) {
     449           0 :                 errno = ENOMEM;
     450           0 :                 return -1;
     451             :         }
     452             : 
     453             :         /* Always use LSTAT here - we just created the directory. */
     454       10762 :         ret = SMB_VFS_LSTAT(handle->conn, full_fname);
     455       10762 :         if (ret == -1) {
     456             :                 /* Rename race. Let upper level take care of it. */
     457           0 :                 TALLOC_FREE(frame);
     458           0 :                 return -1;
     459             :         }
     460       10762 :         if (!S_ISDIR(full_fname->st.st_ex_mode)) {
     461             :                 /* Rename race. Let upper level take care of it. */
     462           0 :                 TALLOC_FREE(frame);
     463           0 :                 return -1;
     464             :         }
     465             : 
     466       10762 :         fileid = SMB_VFS_FILE_ID_CREATE(handle->conn, &full_fname->st);
     467             : 
     468       10762 :         SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
     469             :                                 if (!xattr_tdb_init(-1, frame, &db))
     470             :                                 {
     471             :                                         TALLOC_FREE(frame); return -1;
     472             :                                 });
     473             : 
     474       10762 :         xattr_tdb_remove_all_attrs(db, &fileid);
     475       10762 :         TALLOC_FREE(frame);
     476       10697 :         return 0;
     477             : }
     478             : 
     479             : /*
     480             :  * On unlink we need to delete the tdb record
     481             :  */
     482      164512 : static int xattr_tdb_unlinkat(vfs_handle_struct *handle,
     483             :                         struct files_struct *dirfsp,
     484             :                         const struct smb_filename *smb_fname,
     485             :                         int flags)
     486             : {
     487      164512 :         struct smb_filename *smb_fname_tmp = NULL;
     488      164512 :         struct smb_filename *full_fname = NULL;
     489             :         struct file_id id;
     490             :         struct db_context *db;
     491      164512 :         int ret = -1;
     492      164512 :         bool remove_record = false;
     493      164512 :         TALLOC_CTX *frame = talloc_stackframe();
     494             : 
     495      164512 :         SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
     496             :                                 if (!xattr_tdb_init(-1, frame, &db))
     497             :                                 {
     498             :                                         TALLOC_FREE(frame); return -1;
     499             :                                 });
     500             : 
     501      164512 :         smb_fname_tmp = cp_smb_filename(frame, smb_fname);
     502      164512 :         if (smb_fname_tmp == NULL) {
     503           0 :                 TALLOC_FREE(frame);
     504           0 :                 errno = ENOMEM;
     505           0 :                 return -1;
     506             :         }
     507             : 
     508             :         /*
     509             :          * TODO: use SMB_VFS_STATX() once we have that
     510             :          */
     511             : 
     512      164512 :         full_fname = full_path_from_dirfsp_atname(frame,
     513             :                                                   dirfsp,
     514             :                                                   smb_fname);
     515      164512 :         if (full_fname == NULL) {
     516           0 :                 goto out;
     517             :         }
     518             : 
     519      164512 :         if (full_fname->flags & SMB_FILENAME_POSIX_PATH) {
     520         254 :                 ret = SMB_VFS_NEXT_LSTAT(handle, full_fname);
     521             :         } else {
     522      164258 :                 ret = SMB_VFS_NEXT_STAT(handle, full_fname);
     523             :         }
     524      164512 :         if (ret == -1) {
     525         300 :                 goto out;
     526             :         }
     527      164212 :         smb_fname_tmp->st = full_fname->st;
     528             : 
     529      164212 :         if (flags & AT_REMOVEDIR) {
     530             :                 /* Always remove record when removing a directory succeeds. */
     531       10178 :                 remove_record = true;
     532             :         } else {
     533      153971 :                 if (smb_fname_tmp->st.st_ex_nlink == 1) {
     534             :                         /* Only remove record on last link to file. */
     535      153950 :                         remove_record = true;
     536             :                 }
     537             :         }
     538             : 
     539      164212 :         ret = SMB_VFS_NEXT_UNLINKAT(handle,
     540             :                                 dirfsp,
     541             :                                 smb_fname_tmp,
     542             :                                 flags);
     543             : 
     544      164212 :         if (ret == -1) {
     545           8 :                 goto out;
     546             :         }
     547             : 
     548      164204 :         if (!remove_record) {
     549          20 :                 goto out;
     550             :         }
     551             : 
     552      164183 :         id = SMB_VFS_NEXT_FILE_ID_CREATE(handle, &smb_fname_tmp->st);
     553             : 
     554      164183 :         xattr_tdb_remove_all_attrs(db, &id);
     555             : 
     556      164513 :  out:
     557      164512 :         TALLOC_FREE(frame);
     558      164299 :         return ret;
     559             : }
     560             : 
     561             : /*
     562             :  * Destructor for the VFS private data
     563             :  */
     564             : 
     565       42431 : static void close_xattr_db(void **data)
     566             : {
     567       42431 :         struct db_context **p_db = (struct db_context **)data;
     568       42431 :         TALLOC_FREE(*p_db);
     569       42431 : }
     570             : 
     571       43777 : static int xattr_tdb_connect(vfs_handle_struct *handle, const char *service,
     572             :                           const char *user)
     573             : {
     574       43777 :         char *sname = NULL;
     575             :         int res, snum;
     576             :         struct db_context *db;
     577             : 
     578       43777 :         res = SMB_VFS_NEXT_CONNECT(handle, service, user);
     579       43777 :         if (res < 0) {
     580           0 :                 return res;
     581             :         }
     582             : 
     583       43777 :         snum = find_service(talloc_tos(), service, &sname);
     584       43777 :         if (snum == -1 || sname == NULL) {
     585             :                 /*
     586             :                  * Should not happen, but we should not fail just *here*.
     587             :                  */
     588        1288 :                 return 0;
     589             :         }
     590             : 
     591       42479 :         if (!xattr_tdb_init(snum, NULL, &db)) {
     592           0 :                 DEBUG(5, ("Could not init xattr tdb\n"));
     593           0 :                 lp_do_parameter(snum, "ea support", "False");
     594           0 :                 return 0;
     595             :         }
     596             : 
     597       42479 :         lp_do_parameter(snum, "ea support", "True");
     598             : 
     599       42479 :         SMB_VFS_HANDLE_SET_DATA(handle, db, close_xattr_db,
     600             :                                 struct db_context, return -1);
     601             : 
     602       42479 :         return 0;
     603             : }
     604             : 
     605             : static struct vfs_fn_pointers vfs_xattr_tdb_fns = {
     606             :         .getxattrat_send_fn = xattr_tdb_getxattrat_send,
     607             :         .getxattrat_recv_fn = xattr_tdb_getxattrat_recv,
     608             :         .fgetxattr_fn = xattr_tdb_fgetxattr,
     609             :         .fsetxattr_fn = xattr_tdb_fsetxattr,
     610             :         .flistxattr_fn = xattr_tdb_flistxattr,
     611             :         .fremovexattr_fn = xattr_tdb_fremovexattr,
     612             :         .openat_fn = xattr_tdb_openat,
     613             :         .mkdirat_fn = xattr_tdb_mkdirat,
     614             :         .unlinkat_fn = xattr_tdb_unlinkat,
     615             :         .connect_fn = xattr_tdb_connect,
     616             : };
     617             : 
     618             : static_decl_vfs;
     619       25002 : NTSTATUS vfs_xattr_tdb_init(TALLOC_CTX *ctx)
     620             : {
     621       25002 :         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "xattr_tdb",
     622             :                                 &vfs_xattr_tdb_fns);
     623             : }

Generated by: LCOV version 1.13