]> 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-2014 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 "ident/AclIdent.h"
22 #include "ident/Ident.h"
23
24 ACLIdent::~ACLIdent()
25 {
26 delete data;
27 }
28
29 ACLIdent::ACLIdent(ACLData<char const *> *newData, char const *newType) : data (newData), type_ (newType) {}
30
31 ACLIdent::ACLIdent (ACLIdent const &old) : data (old.data->clone()), type_ (old.type_)
32 {}
33
34 ACLIdent &
35 ACLIdent::operator= (ACLIdent const &rhs)
36 {
37 data = rhs.data->clone();
38 type_ = rhs.type_;
39 return *this;
40 }
41
42 char const *
43 ACLIdent::typeString() const
44 {
45 return type_;
46 }
47
48 void
49 ACLIdent::parse()
50 {
51 if (!data) {
52 debugs(28, 3, HERE << "current is null. Creating");
53 data = new ACLUserData;
54 }
55
56 data->parse();
57 }
58
59 int
60 ACLIdent::match(ACLChecklist *cl)
61 {
62 ACLFilledChecklist *checklist = Filled(cl);
63 if (checklist->rfc931[0]) {
64 return data->match(checklist->rfc931);
65 } else if (checklist->conn() != NULL && checklist->conn()->clientConnection != NULL && checklist->conn()->clientConnection->rfc931[0]) {
66 return data->match(checklist->conn()->clientConnection->rfc931);
67 } else if (checklist->conn() != NULL && Comm::IsConnOpen(checklist->conn()->clientConnection)) {
68 if (checklist->goAsync(IdentLookup::Instance())) {
69 debugs(28, 3, "switching to ident lookup state");
70 return -1;
71 }
72 // else fall through to ACCESS_DUNNO failure below
73 } else {
74 debugs(28, DBG_IMPORTANT, HERE << "Can't start ident lookup. No client connection" );
75 // fall through to ACCESS_DUNNO failure below
76 }
77
78 checklist->markFinished(ACCESS_DUNNO, "cannot start ident lookup");
79 return -1;
80 }
81
82 SBufList
83 ACLIdent::dump() const
84 {
85 return data->dump();
86 }
87
88 bool
89 ACLIdent::empty () const
90 {
91 return data->empty();
92 }
93
94 ACL *
95 ACLIdent::clone() const
96 {
97 return new ACLIdent(*this);
98 }
99
100 IdentLookup IdentLookup::instance_;
101
102 IdentLookup *
103 IdentLookup::Instance()
104 {
105 return &instance_;
106 }
107
108 void
109 IdentLookup::checkForAsync(ACLChecklist *cl)const
110 {
111 ACLFilledChecklist *checklist = Filled(cl);
112 const ConnStateData *conn = checklist->conn();
113 // check that ACLIdent::match() tested this lookup precondition
114 assert(conn && Comm::IsConnOpen(conn->clientConnection));
115 debugs(28, 3, HERE << "Doing ident lookup" );
116 Ident::Start(checklist->conn()->clientConnection, LookupDone, checklist);
117 }
118
119 void
120 IdentLookup::LookupDone(const char *ident, void *data)
121 {
122 ACLFilledChecklist *checklist = Filled(static_cast<ACLChecklist*>(data));
123
124 if (ident) {
125 xstrncpy(checklist->rfc931, ident, USER_IDENT_SZ);
126 } else {
127 xstrncpy(checklist->rfc931, dash_str, USER_IDENT_SZ);
128 }
129
130 /*
131 * Cache the ident result in the connection, to avoid redoing ident lookup
132 * over and over on persistent connections
133 */
134 if (checklist->conn() != NULL && checklist->conn()->clientConnection != NULL && !checklist->conn()->clientConnection->rfc931[0])
135 xstrncpy(checklist->conn()->clientConnection->rfc931, checklist->rfc931, USER_IDENT_SZ);
136
137 checklist->resumeNonBlockingCheck(IdentLookup::Instance());
138 }
139
140 #endif /* USE_IDENT */
141