]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ident/AclIdent.cc
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / ident / AclIdent.cc
1 /*
2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
3 *
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.
7 */
8
9 /* DEBUG: section 28 Access Control */
10
11 #include "squid.h"
12
13 #if USE_IDENT
14
15 #include "acl/FilledChecklist.h"
16 #include "acl/RegexData.h"
17 #include "acl/UserData.h"
18 #include "client_side.h"
19 #include "comm/Connection.h"
20 #include "globals.h"
21 #include "http/Stream.h"
22 #include "ident/AclIdent.h"
23 #include "ident/Ident.h"
24
25 ACLIdent::~ACLIdent()
26 {
27 delete data;
28 }
29
30 ACLIdent::ACLIdent(ACLData<char const *> *newData, char const *newType) : data (newData), type_ (newType) {}
31
32 ACLIdent::ACLIdent (ACLIdent const &old) : data (old.data->clone()), type_ (old.type_)
33 {}
34
35 ACLIdent &
36 ACLIdent::operator= (ACLIdent const &rhs)
37 {
38 data = rhs.data->clone();
39 type_ = rhs.type_;
40 return *this;
41 }
42
43 char const *
44 ACLIdent::typeString() const
45 {
46 return type_;
47 }
48
49 void
50 ACLIdent::parseFlags()
51 {
52 ParseFlags(Acl::NoOptions(), data->supportedFlags());
53 }
54
55 void
56 ACLIdent::parse()
57 {
58 if (!data) {
59 debugs(28, 3, HERE << "current is null. Creating");
60 data = new ACLUserData;
61 }
62
63 data->parse();
64 }
65
66 int
67 ACLIdent::match(ACLChecklist *cl)
68 {
69 ACLFilledChecklist *checklist = Filled(cl);
70 if (checklist->rfc931[0]) {
71 return data->match(checklist->rfc931);
72 } else if (checklist->conn() != NULL && checklist->conn()->clientConnection != NULL && checklist->conn()->clientConnection->rfc931[0]) {
73 return data->match(checklist->conn()->clientConnection->rfc931);
74 } else if (checklist->conn() != NULL && Comm::IsConnOpen(checklist->conn()->clientConnection)) {
75 if (checklist->goAsync(IdentLookup::Instance())) {
76 debugs(28, 3, "switching to ident lookup state");
77 return -1;
78 }
79 // else fall through to ACCESS_DUNNO failure below
80 } else {
81 debugs(28, DBG_IMPORTANT, HERE << "Can't start ident lookup. No client connection" );
82 // fall through to ACCESS_DUNNO failure below
83 }
84
85 checklist->markFinished(ACCESS_DUNNO, "cannot start ident lookup");
86 return -1;
87 }
88
89 SBufList
90 ACLIdent::dump() const
91 {
92 return data->dump();
93 }
94
95 bool
96 ACLIdent::empty () const
97 {
98 return data->empty();
99 }
100
101 ACL *
102 ACLIdent::clone() const
103 {
104 return new ACLIdent(*this);
105 }
106
107 IdentLookup IdentLookup::instance_;
108
109 IdentLookup *
110 IdentLookup::Instance()
111 {
112 return &instance_;
113 }
114
115 void
116 IdentLookup::checkForAsync(ACLChecklist *cl)const
117 {
118 ACLFilledChecklist *checklist = Filled(cl);
119 const ConnStateData *conn = checklist->conn();
120 // check that ACLIdent::match() tested this lookup precondition
121 assert(conn && Comm::IsConnOpen(conn->clientConnection));
122 debugs(28, 3, HERE << "Doing ident lookup" );
123 Ident::Start(checklist->conn()->clientConnection, LookupDone, checklist);
124 }
125
126 void
127 IdentLookup::LookupDone(const char *ident, void *data)
128 {
129 ACLFilledChecklist *checklist = Filled(static_cast<ACLChecklist*>(data));
130
131 if (ident) {
132 xstrncpy(checklist->rfc931, ident, USER_IDENT_SZ);
133 } else {
134 xstrncpy(checklist->rfc931, dash_str, USER_IDENT_SZ);
135 }
136
137 /*
138 * Cache the ident result in the connection, to avoid redoing ident lookup
139 * over and over on persistent connections
140 */
141 if (checklist->conn() != NULL && checklist->conn()->clientConnection != NULL && !checklist->conn()->clientConnection->rfc931[0])
142 xstrncpy(checklist->conn()->clientConnection->rfc931, checklist->rfc931, USER_IDENT_SZ);
143
144 checklist->resumeNonBlockingCheck(IdentLookup::Instance());
145 }
146
147 #endif /* USE_IDENT */
148