s3:utils: let smbstatus report anonymous signing/encryption explicitly
[samba.git] / source3 / modules / vfs_error_inject.c
index 9ead2c26727feaa18960610f7050f466d715dbf0..529504fd8d5e9d60ad621dd0114a2c6e152790f0 100644 (file)
@@ -31,6 +31,7 @@ struct unix_error_map {
        {       "EBADF",        EBADF   },
        {       "EINTR",        EINTR   },
        {       "EACCES",       EACCES  },
+       {       "EROFS",        EROFS   },
 };
 
 static int find_unix_error_from_string(const char *err_str)
@@ -51,29 +52,29 @@ static int find_unix_error_from_string(const char *err_str)
 static int inject_unix_error(const char *vfs_func, vfs_handle_struct *handle)
 {
        const char *err_str;
+       int error;
 
        err_str = lp_parm_const_string(SNUM(handle->conn),
                                       "error_inject", vfs_func, NULL);
+       if (err_str == NULL) {
+               return 0;
+       }
 
-       if (err_str != NULL) {
-               int error;
-
-               error = find_unix_error_from_string(err_str);
-               if (error != 0) {
-                       DBG_WARNING("Returning error %s for VFS function %s\n",
-                                   err_str, vfs_func);
-                       return error;
-               }
-
-               if (strequal(err_str, "panic")) {
-                       DBG_ERR("Panic in VFS function %s\n", vfs_func);
-                       smb_panic("error_inject");
-               }
+       error = find_unix_error_from_string(err_str);
+       if (error != 0) {
+               DBG_WARNING("Returning error %s for VFS function %s\n",
+                           err_str, vfs_func);
+               return error;
+       }
 
-               DBG_ERR("Unknown error inject %s requested "
-                       "for vfs function %s\n", err_str, vfs_func);
+       if (strequal(err_str, "panic")) {
+               DBG_ERR("Panic in VFS function %s\n", vfs_func);
+               smb_panic("error_inject");
        }
 
+       DBG_ERR("Unknown error inject %s requested "
+               "for vfs function %s\n", err_str, vfs_func);
+
        return 0;
 }
 
@@ -112,10 +113,10 @@ static int vfs_error_inject_openat(struct vfs_handle_struct *handle,
                                   const struct files_struct *dirfsp,
                                   const struct smb_filename *smb_fname,
                                   files_struct *fsp,
-                                  int flags,
-                                  mode_t mode)
+                                  const struct vfs_open_how *how)
 {
        int error = inject_unix_error("openat", handle);
+       int create_error = inject_unix_error("openat_create", handle);
        int dirfsp_flags = (O_NOFOLLOW|O_DIRECTORY);
        bool return_error;
 
@@ -127,15 +128,33 @@ static int vfs_error_inject_openat(struct vfs_handle_struct *handle,
 #endif
 #endif
 
+       if ((create_error != 0) && (how->flags & O_CREAT)) {
+               struct stat_ex st = {
+                       .st_ex_nlink = 0,
+               };
+               int ret;
+
+               ret = SMB_VFS_FSTATAT(handle->conn,
+                                     dirfsp,
+                                     smb_fname,
+                                     &st,
+                                     AT_SYMLINK_NOFOLLOW);
+
+               if ((ret == -1) && (errno == ENOENT)) {
+                       errno = create_error;
+                       return -1;
+               }
+       }
+
        return_error = (error != 0);
        return_error &= !fsp->fsp_flags.is_pathref;
-       return_error &= ((flags & dirfsp_flags) != dirfsp_flags);
+       return_error &= ((how->flags & dirfsp_flags) != dirfsp_flags);
 
        if (return_error) {
                errno = error;
                return -1;
        }
-       return SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode);
+       return SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, how);
 }
 
 static int vfs_error_inject_unlinkat(struct vfs_handle_struct *handle,