]>
Commit | Line | Data |
---|---|---|
8000a965 | 1 | /* |
bbc27441 | 2 | * Copyright (C) 1996-2014 The Squid Software Foundation and contributors |
8000a965 | 3 | * |
bbc27441 AJ |
4 | * Squid software is distributed under GPLv2+ license and includes |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
8000a965 | 7 | */ |
8 | ||
bbc27441 AJ |
9 | /* DEBUG: section 28 Access Control */ |
10 | ||
582c2af2 | 11 | #include "squid.h" |
3ad63615 | 12 | #include "acl/Checklist.h" |
602d9612 A |
13 | #include "acl/UserData.h" |
14 | #include "ConfigParser.h" | |
582c2af2 | 15 | #include "Debug.h" |
8000a965 | 16 | |
8000a965 | 17 | template<class T> |
18 | inline void | |
19 | xRefFree(T &thing) | |
20 | { | |
21 | xfree (thing); | |
22 | } | |
23 | ||
24 | ACLUserData::~ACLUserData() | |
25 | { | |
26 | if (names) | |
62e76326 | 27 | names->destroy(xRefFree); |
28 | } | |
8000a965 | 29 | |
079b4b63 | 30 | static int |
31 | splaystrcasecmp (char * const &l, char * const &r) | |
8000a965 | 32 | { |
33 | return strcasecmp ((char *)l,(char *)r); | |
34 | } | |
35 | ||
079b4b63 | 36 | static int |
37 | splaystrcmp (char * const &l, char * const &r) | |
8000a965 | 38 | { |
39 | return strcmp ((char *)l,(char *)r); | |
40 | } | |
41 | ||
42 | bool | |
43 | ACLUserData::match(char const *user) | |
44 | { | |
45 | SplayNode<char *> *Top = names; | |
46 | ||
bf8fe701 | 47 | debugs(28, 7, "aclMatchUser: user is " << user << ", case_insensitive is " << flags.case_insensitive); |
48 | debugs(28, 8, "Top is " << Top << ", Top->data is " << ((char *) (Top != NULL ? (Top)->data : "Unavailable"))); | |
8000a965 | 49 | |
72aa8f18 | 50 | if (user == NULL || strcmp(user, "-") == 0) |
62e76326 | 51 | return 0; |
8000a965 | 52 | |
53 | if (flags.required) { | |
bf8fe701 | 54 | debugs(28, 7, "aclMatchUser: user REQUIRED and auth-info present."); |
62e76326 | 55 | return 1; |
8000a965 | 56 | } |
62e76326 | 57 | |
8000a965 | 58 | if (flags.case_insensitive) |
62e76326 | 59 | Top = Top->splay((char *)user, splaystrcasecmp); |
8000a965 | 60 | else |
62e76326 | 61 | Top = Top->splay((char *)user, splaystrcmp); |
62 | ||
8000a965 | 63 | /* Top=splay_splay(user,Top,(splayNode::SPLAYCMP *)dumping_strcmp); */ |
bf8fe701 | 64 | debugs(28, 7, "aclMatchUser: returning " << !splayLastResult << ",Top is " << |
65 | Top << ", Top->data is " << ((char *) (Top ? Top->data : "Unavailable"))); | |
62e76326 | 66 | |
8000a965 | 67 | names = Top; |
62e76326 | 68 | |
8000a965 | 69 | return !splayLastResult; |
70 | } | |
71 | ||
72 | static void | |
73 | aclDumpUserListWalkee(char * const & node_data, void *outlist) | |
74 | { | |
8966008b FC |
75 | /* outlist is really a SBufList* */ |
76 | static_cast<SBufList *>(outlist)->push_back(SBuf(node_data)); | |
8000a965 | 77 | } |
78 | ||
8966008b | 79 | SBufList |
4f8ca96e | 80 | ACLUserData::dump() const |
8000a965 | 81 | { |
8966008b | 82 | SBufList sl; |
62e76326 | 83 | |
8000a965 | 84 | if (flags.case_insensitive) |
8966008b | 85 | sl.push_back(SBuf("-i")); |
62e76326 | 86 | |
8000a965 | 87 | /* damn this is VERY inefficient for long ACL lists... filling |
519bae94 | 88 | * a SBufList this way costs Sum(1,N) iterations. For instance |
8000a965 | 89 | * a 1000-elements list will be filled in 499500 iterations. |
90 | */ | |
91 | if (flags.required) | |
8966008b | 92 | sl.push_back(SBuf("REQUIRED")); |
8000a965 | 93 | else if (names) |
8966008b | 94 | names->walk(aclDumpUserListWalkee, &sl); |
62e76326 | 95 | |
8966008b | 96 | return sl; |
8000a965 | 97 | } |
98 | ||
99 | void | |
100 | ACLUserData::parse() | |
101 | { | |
bf8fe701 | 102 | debugs(28, 2, "aclParseUserList: parsing user list"); |
8000a965 | 103 | char *t = NULL; |
62e76326 | 104 | |
d295d770 | 105 | if ((t = ConfigParser::strtokFile())) { |
bf8fe701 | 106 | debugs(28, 5, "aclParseUserList: First token is " << t); |
62e76326 | 107 | |
108 | if (strcmp("-i", t) == 0) { | |
bf8fe701 | 109 | debugs(28, 5, "aclParseUserList: Going case-insensitive"); |
3dd52a0b | 110 | flags.case_insensitive = true; |
62e76326 | 111 | } else if (strcmp("REQUIRED", t) == 0) { |
bf8fe701 | 112 | debugs(28, 5, "aclParseUserList: REQUIRED-type enabled"); |
3dd52a0b | 113 | flags.required = true; |
62e76326 | 114 | } else { |
115 | if (flags.case_insensitive) | |
116 | Tolower(t); | |
117 | ||
118 | names = names->insert(xstrdup(t), splaystrcmp); | |
119 | } | |
8000a965 | 120 | } |
62e76326 | 121 | |
bf8fe701 | 122 | debugs(28, 3, "aclParseUserList: Case-insensitive-switch is " << flags.case_insensitive); |
8000a965 | 123 | /* we might inherit from a previous declaration */ |
124 | ||
bf8fe701 | 125 | debugs(28, 4, "aclParseUserList: parsing user list"); |
62e76326 | 126 | |
d295d770 | 127 | while ((t = ConfigParser::strtokFile())) { |
bf8fe701 | 128 | debugs(28, 6, "aclParseUserList: Got token: " << t); |
62e76326 | 129 | |
130 | if (flags.case_insensitive) | |
131 | Tolower(t); | |
132 | ||
133 | names = names->insert(xstrdup(t), splaystrcmp); | |
8000a965 | 134 | } |
135 | } | |
225b7b10 | 136 | |
65092baf | 137 | bool |
138 | ACLUserData::empty() const | |
139 | { | |
290eb6b9 | 140 | return names->empty() && !flags.required; |
65092baf | 141 | } |
142 | ||
5dee515e | 143 | ACLData<char const *> * |
225b7b10 | 144 | ACLUserData::clone() const |
145 | { | |
146 | /* Splay trees don't clone yet. */ | |
147 | assert (!names); | |
148 | return new ACLUserData; | |
149 | } |