1%%	options
2
3copyright owner	=	Dirk Krause
4copyright year	=	2015-xxxx
5SPDX-License-Identifier:	BSD-3-Clause
6
7
8
9%%	header
10
11/**	@file
12	Open file with additional security
13	checks, file name is specified in dkChar characters.
14*/
15
16#ifndef	DK4CONF_H_INCLUDED
17#if DK4_BUILDING_DKTOOLS4
18#include "dk4conf.h"
19#else
20#include <dktools-4/dk4conf.h>
21#endif
22#endif
23
24#ifndef	DK4FOPC8_H_INCLUDED
25#if DK4_BUILDING_DKTOOLS4
26#include <libdk4c/dk4fopc8.h>
27#else
28#include <dktools-4/dk4fopc8.h>
29#endif
30#endif
31
32#if DK4_CHAR_SIZE > 1
33#ifndef	DK4FOPWC_H_INCLUDED
34#if DK4_BUILDING_DKTOOLS4
35#include <libdk4c/dk4fopwc.h>
36#else
37#include <dktools-4/dk4fopwc.h>
38#endif
39#endif
40#endif
41
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47/**	Open a file after doing security checks.
48	CRT on Windows: Required.
49	@param	name	File name to open.
50	@param	mode	Opening mode.
51	@param	tests	Set of tests, see dk4fopc8.h.
52	@param	erp	Error report, may be NULL.
53	@return	Pointer to open file on success, NULL on error.
54
55	Error codes:
56	- DK4_E_INVALID_ARGUMENTS<br>
57	  if name is NULL,
58	- DK4_E_SYNTAX<br>
59	  if name does not refer to a regular file,
60	- DK4_E_SEC_CHECK<br>
61	  with failed check id in iDetails1 if access is denied by additional
62	  security checks,
63	- DK4_E_OPEN_WRITE_FAILED<br>
64	  or DK4_E_OPEN_READ_FAILED with errno value in iDetails1 if fopen()
65	  failed.
66
67*/
68FILE *
69dk4fopen(const dkChar *name, const dkChar *mode, int tests, dk4_er_t *erp);
70
71/**	Check whether we can allow to open the file.
72	The file must be a regular file.
73	Only POSIX: For root we deny opening for writing via symlink.
74	For all users we deny opening for writing via symlink
75	if the link owner is not the real file owner.
76
77	CRT on Windows: Required.
78	@param	name	File name to check.
79	@param	ww	Flag: Write access wanted.
80	@param	tests	Set of tests.
81	@param	erp	Error report, may be NULL.
82	@return	1 if opening the file is allowed, 0 otherwise.
83
84	Error codes:
85	- DK4_E_INVALID_ARGUMENTS<br>
86	  if name is NULL,
87	- DK4_E_SYNTAX<br>
88	  if name is not a regular file,
89	- DK4_E_SEC_CHECK<br>
90	  if access to a symlink target is denied symlink owner and target
91	  owner differ.
92
93*/
94int
95dk4fopen_check(const dkChar *name, int ww, int tests, dk4_er_t *erp);
96
97#ifdef __cplusplus
98}
99#endif
100
101%%	module
102
103#include "dk4conf.h"
104#include <libdk4c/dk4fopd.h>
105
106#if DK4_HAVE_ASSERT_H
107#ifndef	ASSERT_H_INCLUDED
108#include <assert.h>
109#define	ASSERT_H_INCLUDED 1
110#endif
111#endif
112
113
114
115FILE *
116dk4fopen(const dkChar *name, const dkChar *mode, int tests, dk4_er_t *erp)
117{
118#if	DK4_USE_ASSERT
119  assert(NULL != name);
120  assert(NULL != mode);
121#endif
122#if DK4_CHAR_SIZE > 1
123  return (dk4fopen_wc(name, mode, tests, erp));
124#else
125  return (dk4fopen_c8(name, mode, tests, erp));
126#endif
127}
128
129int
130dk4fopen_check(const dkChar *name, int ww, int tests, dk4_er_t *erp)
131{
132#if	DK4_USE_ASSERT
133  assert(NULL != name);
134#endif
135#if DK4_CHAR_SIZE > 1
136  return (dk4fopen_check_wc(name, ww, tests, erp));
137#else
138  return (dk4fopen_check_c8(name, ww, tests, erp));
139#endif
140}
141
142