1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
|
/* MODULE HTACL.c
** ACCESS CONTROL LIST ROUTINES
**
** AUTHORS:
** AL Ari Luotonen luotonen@dxcern.cern.ch
** MD Mark Donszelmann duns@vxdeop.cern.ch
**
** HISTORY:
** 8 Nov 93 MD (VMS only) case insensitive compare reading acl entry, filename
**
**
** BUGS:
**
**
*/
#include "HTUtils.h"
/*#include <stdio.h> included by HTUtils.h -- FM *//* FILE */
#include <string.h>
#include "HTAAFile.h" /* File routines */
#include "HTGroup.h" /* GroupDef */
#include "HTACL.h" /* Implemented here */
#include "LYLeaks.h"
/* PUBLIC HTAA_getAclFilename()
** RESOLVE THE FULL PATHNAME OF ACL FILE FOR A GIVEN FILE
** ON ENTRY:
** path is the pathname of the file for which to
** ACL file should be found.
**
** ACL filename is computed by replacing
** the filename by .www_acl in the pathname
** (this is done to a local copy, of course).
**
** ON EXIT:
** returns the absolute pathname of ACL file
** (which is automatically freed next time
** this fuction is called).
*/
PUBLIC char *HTAA_getAclFilename ARGS1(CONST char *, pathname)
{
static char * local_copy = NULL;
static char * acl_path = NULL;
char * directory = NULL;
char * filename = NULL;
StrAllocCopy(local_copy, pathname); /* Also frees local_copy */
/* from previous call. */
directory = local_copy;
filename = strrchr(directory, '/');
if (!filename) { /* No path in front of filename */
directory = "."; /* So use current directory */
filename = local_copy; /* and the pathname itself is the filename */
}
else {
*filename = '\0'; /* Truncate filename off from directory path */
filename++; /* and the filename begins from the next character */
}
StrAllocCopy(acl_path, directory); /* Also frees acl_path */
/* from previous call. */
StrAllocCat(acl_path, "/");
StrAllocCat(acl_path, ACL_FILE_NAME);
return acl_path;
}
/* PUBLIC HTAA_openAcl()
** OPEN THE ACL FILE FOR THE GIVEN DOCUMENT
** ON ENTRY:
** pathname is the absolute pathname of
** the file to be accessed.
**
** ON EXIT:
** returns the FILE* to open ACL.
** NULL, if ACL not found.
*/
PUBLIC FILE *HTAA_openAcl ARGS1(CONST char *, pathname)
{
return fopen(HTAA_getAclFilename(pathname), "r");
}
/* PUBLIC HTAA_closeAcl()
** CLOSE ACL FILE
** ON ENTRY:
** acl_file is Access Control List file to close.
**
** ON EXIT:
** returns nothing.
*/
PUBLIC void HTAA_closeAcl ARGS1(FILE *, acl_file)
{
if (acl_file) fclose(acl_file);
}
/* PUBLIC HTAA_getAclEntry()
** CONSULT THE ACCESS CONTROL LIST AND
** GIVE A LIST OF GROUPS (AND USERS)
** AUTHORIZED TO ACCESS A GIVEN FILE
** ON ENTRY:
** acl_file is an open ACL file.
** pathname is the absolute pathname of
** the file to be accessed.
** method is the method for which access is wanted.
**
** ALC FILE FORMAT:
**
** template : method, method, ... : group@addr, user, group, ...
**
** The last item is in fact in exactly the same format as
** group definition in group file, i.e. everything that
** follows the 'groupname:' part,
** e.g.
** user, group, user@address, group@address,
** (user,group,...)@(address, address, ...)
**
** ON EXIT:
** returns NULL, if there is no entry for the file in the ACL,
** or ACL doesn't exist.
** If there is, a GroupDef object containing the
** group and user names allowed to access the file
** is returned (this is automatically freed
** next time this function is called).
** IMPORTANT:
** Returns the first entry with matching template and
** method. This function should be called multiple times
** to process all the valid entries (until it returns NULL).
** This is because there can be multiple entries like:
**
** *.html : get,put : ari,timbl,robert
** *.html : get : jim,james,jonathan,jojo
**
** NOTE:
** The returned group definition may well contain references
** to groups defined in group file. Therefore these references
** must be resolved according to that rule file by function
** HTAA_resolveGroupReferences() (group file is read in by
** HTAA_readGroupFile()) and after that access authorization
** can be checked with function HTAA_userAndInetGroup().
*/
PUBLIC GroupDef *HTAA_getAclEntry ARGS3(FILE *, acl_file,
CONST char *, pathname,
HTAAMethod, method)
{
static GroupDef * group_def = NULL;
CONST char * filename;
int len;
char *buf;
if (!acl_file) return NULL; /* ACL doesn't exist */
if (group_def) {
GroupDef_delete(group_def); /* From previous call */
group_def = NULL;
}
if (!(filename = strrchr(pathname, '/')))
filename = pathname;
else filename++; /* Skip slash */
len = strlen(filename);
if (!(buf = (char*)malloc((strlen(filename)+2)*sizeof(char))))
outofmem(__FILE__, "HTAA_getAuthorizedGroups");
while (EOF != HTAAFile_readField(acl_file, buf, len+1)) {
#ifdef VMS
if (HTAA_templateCaseMatch(buf, filename)) {
#else /* not VMS */
if (HTAA_templateMatch(buf, filename)) {
#endif /* not VMS */
HTList *methods = HTList_new();
HTAAFile_readList(acl_file, methods, MAX_METHODNAME_LEN);
if (TRACE) {
fprintf(stderr,
"Filename '%s' matched template '%s', allowed methods:",
filename, buf);
}
if (HTAAMethod_inList(method, methods)) { /* right method? */
if (TRACE)
fprintf(stderr, " METHOD OK\n");
HTList_delete(methods);
methods = NULL;
FREE(buf);
group_def = HTAA_parseGroupDef(acl_file);
/*
** HTAA_parseGroupDef() already reads the record
** separator so we don't call HTAAFile_nextRec().
*/
return group_def;
} else if (TRACE) {
fprintf(stderr, " METHOD NOT FOUND\n");
}
HTList_delete(methods);
methods = NULL;
} /* if template match */
else {
if (TRACE) {
fprintf(stderr,
"Filename '%s' didn't match template '%s'\n",
filename, buf);
}
}
HTAAFile_nextRec(acl_file);
} /* while not eof */
FREE(buf);
return NULL; /* No entry for requested file */
/* (or an empty entry). */
}
|