1 /* Socks Server 5
2 * Copyright (C) 2002 - 2011 by Matteo Ricchetti - <matteo.ricchetti@libero.it>
3
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #include"SS5Main.h"
20 #include"SS5Mod_authorization.h"
21 #include"SS5OpenLdap.h"
22 #include"SS5Mod_log.h"
23
24 #ifdef SOLARIS
25 #include<lber.h>
26 #define LDAP_DEPRECATED
27 #endif
28
29 #include <ldap.h>
30
31
DirectoryCheck(char * group,char * user)32 UINT DirectoryCheck( char *group, char *user )
33 {
34 register UINT idx1;
35 register UINT idx2;
36
37 char ntbdomain[64];
38 char ntbuser[64];
39 char swap[64];
40
41 UINT count;
42
43 int err = ERR;
44 int pos = 0,
45 gss = 0;
46
47 pid_t pid;
48
49 /*
50 * Get child/thread pid
51 */
52 if( NOTTHREADED() )
53 pid = getpid();
54 else
55 pid = (UINT)(uintmax_t)pthread_self();
56
57 /*
58 * Get netbios domain from username
59 */
60 ntbdomain[0]='\0';
61 ntbuser[0] ='\0';
62 swap[0] ='\0';
63
64 for(idx1 = 0, idx2 = 0; user[idx1] && (idx1 < (sizeof(ntbuser) - 1)); idx1++ ) {
65 if( user[idx1] == '\\' || user[idx1] == '@' ) {
66 ntbdomain[idx1] = '\0';
67 pos = 1;
68 gss++;
69 idx1++;
70 }
71
72 if( pos == 0 ) {
73 ntbdomain[idx1] = user[idx1];
74 ntbuser[idx1] = user[idx1];
75 ntbuser[idx1 + 1] = '\0';
76 }
77 else if( pos == 1 ) {
78 ntbuser[idx2++] = user[idx1];
79 ntbuser[idx2] = '\0';
80 }
81 }
82
83 /*
84 * If username in the form user@domain.dom ss5 supposes
85 * a GSS authentication request
86 */
87 if( gss ) {
88 strncpy(swap,ntbuser,sizeof(swap));
89 strncpy(ntbuser,ntbdomain,sizeof(ntbuser));
90 strncpy(ntbdomain,swap,sizeof(ntbdomain));
91 }
92 /*
93 * Look for user into all UserStore
94 */
95 for( count = 0; (err == ERR) && (count < NLdapStore); count++ ) {
96 if( SS5SocksOpt.LdapNetbiosDomain ) {
97 /*
98 * Look for only if user netbios domain and directory netbios domain match
99 */
100 if( STREQ(S5Ldap[count].NtbDomain,"DEF",sizeof("DEF") -1) ) {
101 err = DirectoryQuery(pid, group, ntbuser, count);
102 }
103 else if( STRCASEEQ(S5Ldap[count].NtbDomain,ntbdomain,sizeof(ntbdomain) -1) )
104 err = DirectoryQuery(pid, group, ntbuser, count);
105 }
106 /*
107 * Look for in order of configuration
108 */
109 else {
110 err = DirectoryQuery( pid, group, ntbuser, count);
111 }
112 }
113 return err;
114 }
115
DirectoryQuery(pid_t pid,char * group,char * user,int dirid)116 UINT DirectoryQuery( pid_t pid, char *group, char *user, int dirid )
117 {
118 register UINT idx1,idx2;
119
120 UINT i,l;
121
122 struct timeval oldapTimeout;
123
124 char searchFilter[128]="\0";
125 char baseDn[128] ="\0";
126 char baseTmp[128] ="\0";
127 char ldap_uri[128] ="\0";
128
129 char *attrsList[] = {"dn", NULL };
130
131 LDAP *ld = NULL;
132
133 LDAPMessage *result;
134
135 int rc;
136 int protocolVersion = LDAP_VERSION3;
137
138 char logString[256]="\0";
139
140 /*
141 * Set timeout for ldap query
142 */
143 oldapTimeout.tv_sec = SS5SocksOpt.LdapTimeout;
144 oldapTimeout.tv_usec = 0;
145
146 /*
147 * build "searchFilter" for ldap query
148 */
149 if( LDAPBASE() ) {
150 strncpy(searchFilter,S5Ldap[dirid].Filter,sizeof(searchFilter));
151 STRSCAT(searchFilter,"=");
152 STRSCAT(searchFilter,user);
153 }
154 else if( LDAPFILTER() ) {
155 strncpy(searchFilter,"(&(",sizeof(searchFilter));
156 STRSCAT(searchFilter,S5Ldap[dirid].Filter);
157 STRSCAT(searchFilter,"=");
158 STRSCAT(searchFilter,user);
159 STRSCAT(searchFilter,")(");
160 STRSCAT(searchFilter,S5Ldap[dirid].Attribute);
161 STRSCAT(searchFilter,"=");
162 STRSCAT(searchFilter,group);
163 STRSCAT(searchFilter,"))");
164 }
165 /*
166 * build "base" for ldap query
167 */
168 for(idx1 = 0; (baseDn[idx1] = S5Ldap[dirid].Base[idx1]) != '%' && idx1 < strlen(S5Ldap[dirid].Base); idx1++);
169 baseDn[idx1] = '\0';
170 if( (idx1++) < strlen(S5Ldap[dirid].Base) ) {
171 for(idx2 = 0; (baseTmp[idx2] = S5Ldap[dirid].Base[idx1]) != '\0' && idx1 < strlen(S5Ldap[dirid].Base); idx2++, idx1++);
172 baseTmp[idx2] = '\0';
173
174 STRSCAT(baseDn,group);
175 STRSCAT(baseDn,baseTmp);
176 }
177
178 /*
179 * Initialize ldap environment
180 */
181 #ifdef LDAP_DEPRECATED
182 ld = (LDAP *)ldap_init( S5Ldap[dirid].IP, atoi(S5Ldap[dirid].Port) );
183 if ( ld == NULL ) {
184 ERRNO(pid)
185
186 return ERR;
187 }
188 #else
189 sprintf(ldap_uri,"ldap://%s:%d/",S5Ldap[dirid].IP,atoi(S5Ldap[dirid].Port));
190 if( ldap_initialize( &ld, ldap_uri) != LDAP_SUCCESS ) {
191 ERRNO(pid)
192
193 return ERR;
194 }
195 #endif
196
197 ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &protocolVersion );
198 ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
199 /*
200 * Try to bind into directory
201 */
202 if (( rc = ldap_bind_s( ld, S5Ldap[dirid].Dn, S5Ldap[dirid].Pass, LDAP_AUTH_SIMPLE )) != LDAP_SUCCESS ) {
203 ERRNOLDAP(pid,rc)
204
205 ldap_unbind( ld );
206 return ERR;
207 }
208 /*
209 * Search for username into directory
210 */
211 if (( rc = ldap_search_st( ld, baseDn, LDAP_SCOPE_SUBTREE, searchFilter, attrsList, 0, &oldapTimeout, &result )) != LDAP_SUCCESS ) {
212 ERRNOLDAP(pid,rc)
213
214 ldap_msgfree( result );
215 ldap_unbind( ld );
216
217 return ERR;
218 }
219 else {
220 /*
221 * Count entries, if zero NOT FOUND!
222 */
223 if( ldap_count_entries( ld, result ) ) {
224 ldap_msgfree( result );
225 ldap_unbind( ld );
226
227 return OK;
228 }
229 }
230
231 ldap_msgfree( result );
232 ldap_unbind( ld );
233
234 return ERR;
235 }
236
237