1 /*!
2    \file lib/gis/mapset_msc.c
3 
4    \brief GIS library - Mapset user permission routines.
5 
6    (C) 1999-2014 The GRASS development team
7 
8    This program is free software under the GNU General Public License
9    (>=v2). Read the file COPYING that comes with GRASS for details.
10  */
11 
12 #include <grass/config.h>
13 #include <string.h>
14 #include <unistd.h>
15 #include <stdlib.h>
16 #include <errno.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <grass/gis.h>
20 #include <grass/glocale.h>
21 
22 static int make_mapset_element(const char *, const char *);
23 
24 /*!
25    \brief Create element in the current mapset.
26 
27    Make the specified element in the current mapset will check for the
28    existence of the element and do nothing if it is found so this
29    routine can be called even if the element already exists.
30 
31    Calls G_fatal_error() on failure.
32 
33    \param p_element element to be created in mapset
34 
35    \return 0 no element defined
36    \return 1 on success
37  */
G_make_mapset_element(const char * p_element)38 int G_make_mapset_element(const char *p_element)
39 {
40     char path[GPATH_MAX];
41 
42     G_file_name(path, NULL, NULL, G_mapset());
43     return make_mapset_element(path, p_element);
44 }
45 
46 /*!
47    \brief Create element in the temporary directory.
48 
49    See G_file_name_tmp() for details.
50 
51    \param p_element element to be created in mapset
52 
53    \return 0 no element defined
54    \return 1 on success
55  */
G_make_mapset_element_tmp(const char * p_element)56 int G_make_mapset_element_tmp(const char *p_element)
57 {
58     char path[GPATH_MAX];
59 
60     G_file_name_tmp(path, NULL, NULL, G_mapset());
61     return make_mapset_element(path, p_element);
62 }
63 
make_mapset_element(const char * p_path,const char * p_element)64 int make_mapset_element(const char *p_path, const char *p_element)
65 {
66     char path[GPATH_MAX], *p;
67     const char *element;
68 
69     element = p_element;
70     if (*element == 0)
71 	return 0;
72 
73     strncpy(path, p_path, GPATH_MAX);
74     p = path;
75     while (*p)
76 	p++;
77     /* add trailing slash if missing */
78     --p;
79     if (*p++ != '/') {
80 	*p++ = '/';
81 	*p = 0;
82     }
83 
84     /* now append element, one directory at a time, to path */
85     while (1) {
86 	if (*element == '/' || *element == 0) {
87 	    *p = 0;
88 	    if (access(path, 0) != 0) { /* directory not yet created */
89 		if (G_mkdir(path) != 0)
90 		    G_fatal_error(_("Unable to make mapset element %s (%s): %s"),
91 				  p_element, path, strerror(errno));
92 	    }
93 	    if (access(path, 0) != 0)  /* directory not accessible */
94 		G_fatal_error(_("Unable to access mapset element %s (%s): %s"),
95 			      p_element, path, strerror(errno));
96 	    if (*element == 0)
97 		return 1;
98 	}
99 	*p++ = *element++;
100     }
101 }
102 
103 /*!
104    \brief Create misc element in the current mapset.
105 
106    \param dir directory path
107    \param name element to be created in mapset
108 
109    \return 0 no element defined
110    \return 1 on success
111  */
G__make_mapset_element_misc(const char * dir,const char * name)112 int G__make_mapset_element_misc(const char *dir, const char *name)
113 {
114     char buf[GNAME_MAX * 2 + 1];
115 
116     sprintf(buf, "%s/%s", dir, name);
117     return G_make_mapset_element(buf);
118 }
119 
check_owner(const struct stat * info)120 static int check_owner(const struct stat *info)
121 {
122 #if defined(__MINGW32__) || defined(SKIP_MAPSET_OWN_CHK)
123     return 1;
124 #else
125     const char *check = getenv("GRASS_SKIP_MAPSET_OWNER_CHECK");
126     if (check && *check)
127 	return 1;
128     if (info->st_uid != getuid())
129 	return 0;
130     if (info->st_uid != geteuid())
131 	return 0;
132     return 1;
133 #endif
134 }
135 
136 /*!
137    \brief Check for user mapset permission
138 
139    \param mapset mapset name
140 
141    \return 1 mapset exists, and user has permission
142    \return 0 mapset exists, BUT user denied permission
143    \return -1 mapset does not exist
144  */
G_mapset_permissions(const char * mapset)145 int G_mapset_permissions(const char *mapset)
146 {
147     char path[GPATH_MAX];
148     struct stat info;
149 
150     G_file_name(path, "", "", mapset);
151 
152     if (G_stat(path, &info) != 0)
153 	return -1;
154     if (!S_ISDIR(info.st_mode))
155 	return -1;
156 
157     if (!check_owner(&info))
158 	return 0;
159 
160     return 1;
161 }
162 
163 /*!
164    \brief Check for user mapset permission
165 
166    \param gisdbase full path to GISDBASE
167    \param location location name
168    \param mapset mapset name
169 
170    \return 1 mapset exists, and user has permission
171    \return 0 mapset exists, BUT user denied permission
172    \return -1 mapset does not exist
173  */
G_mapset_permissions2(const char * gisdbase,const char * location,const char * mapset)174 int G_mapset_permissions2(const char *gisdbase, const char *location,
175 			   const char *mapset)
176 {
177     char path[GPATH_MAX];
178     struct stat info;
179 
180     sprintf(path, "%s/%s/%s", gisdbase, location, mapset);
181 
182     if (G_stat(path, &info) != 0)
183 	return -1;
184     if (!S_ISDIR(info.st_mode))
185 	return -1;
186 
187     if (!check_owner(&info))
188 	return 0;
189 
190     return 1;
191 }
192