]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ident/AclIdent.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / ident / AclIdent.cc
1 /*
2 * Copyright (C) 1996-2017 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::parse()
51 {
52 if (!data) {
53 debugs(28, 3, HERE << "current is null. Creating");
54 data = new ACLUserData;
55 }
56
57 data->parse();
58 }
59
60 int
61 ACLIdent::match(ACLChecklist *cl)
62 {
63 ACLFilledChecklist *checklist = Filled(cl);
64 if (checklist->rfc931[0]) {
65 return data->match(checklist->rfc931);
66 } else if (checklist->conn() != NULL && checklist->conn()->clientConnection != NULL && checklist->conn()->clientConnection->rfc931[0]) {
67 return data->match(checklist->conn()->clientConnection->rfc931);
68 } else if (checklist->conn() != NULL && Comm::IsConnOpen(checklist->conn()->clientConnection)) {
69 if (checklist->goAsync(IdentLookup::Instance())) {
70 debugs(28, 3, "switching to ident lookup state");
71 return -1;
72 }
73 // else fall through to ACCESS_DUNNO failure below
74 } else {
75 debugs(28, DBG_IMPORTANT, HERE << "Can't start ident lookup. No client connection" );
76 // fall through to ACCESS_DUNNO failure below
77 }
78
79 checklist->markFinished(ACCESS_DUNNO, "cannot start ident lookup");
80 return -1;
81 }
82
83 SBufList
84 ACLIdent::dump() const
85 {
86 return data->dump();
87 }
88
89 bool
90 ACLIdent::empty () const
91 {
92 return data->empty();
93 }
94
95 ACL *
96 ACLIdent::clone() const
97 {
98 return new ACLIdent(*this);
99 }
100
101 IdentLookup IdentLookup::instance_;
102
103 IdentLookup *
104 IdentLookup::Instance()
105 {
106 return &instance_;
107 }
108
109 void
110 IdentLookup::checkForAsync(ACLChecklist *cl)const
111 {
112 ACLFilledChecklist *checklist = Filled(cl);
113 const ConnStateData *conn = checklist->conn();
114 // check that ACLIdent::match() tested this lookup precondition
115 assert(conn && Comm::IsConnOpen(conn->clientConnection));
116 debugs(28, 3, HERE << "Doing ident lookup" );
117 Ident::Start(checklist->conn()->clientConnection, LookupDone, checklist);
118 }
119
120 void
121 IdentLookup::LookupDone(const char *ident, void *data)
122 {
123 ACLFilledChecklist *checklist = Filled(static_cast<ACLChecklist*>(data));
124
125 if (ident) {
126 xstrncpy(checklist->rfc931, ident, USER_IDENT_SZ);
127 } else {
128 xstrncpy(checklist->rfc931, dash_str, USER_IDENT_SZ);
129 }
130
131 /*
132 * Cache the ident result in the connection, to avoid redoing ident lookup
133 * over and over on persistent connections
134 */
135 if (checklist->conn() != NULL && checklist->conn()->clientConnection != NULL && !checklist->conn()->clientConnection->rfc931[0])
136 xstrncpy(checklist->conn()->clientConnection->rfc931, checklist->rfc931, USER_IDENT_SZ);
137
138 checklist->resumeNonBlockingCheck(IdentLookup::Instance());
139 }
140
141 #endif /* USE_IDENT */
142