]> git.ipfire.org Git - thirdparty/squid.git/blob - helpers/basic_auth/SMB/basic_smb_auth.cc
Merged from trunk
[thirdparty/squid.git] / helpers / basic_auth / SMB / basic_smb_auth.cc
1 /*
2 * basic_smb_auth - SMB proxy authentication module
3 * Copyright (C) 1998 Richard Huveneers <richard@hekkihek.hacom.nl>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * SQUID Web Proxy Cache http://www.squid-cache.org/
18 * ----------------------------------------------------------
19 *
20 * Squid is the result of efforts by numerous individuals from
21 * the Internet community; see the CONTRIBUTORS file for full
22 * details. Many organizations have provided support for Squid's
23 * development; see the SPONSORS file for full details. Squid is
24 * Copyrighted (C) 2001 by the Regents of the University of
25 * California; see the COPYRIGHT file for full details. Squid
26 * incorporates software developed and/or copyrighted by other
27 * sources; see the CREDITS file for full details.
28 *
29 * This program is free software; you can redistribute it and/or modify
30 * it under the terms of the GNU General Public License as published by
31 * the Free Software Foundation; either version 2 of the License, or
32 * (at your option) any later version.
33 *
34 * This program is distributed in the hope that it will be useful,
35 * but WITHOUT ANY WARRANTY; without even the implied warranty of
36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 * GNU General Public License for more details.
38 *
39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
42 */
43 #include "squid.h"
44 #include "helpers/defines.h"
45 #include "rfc1738.h"
46 #include "util.h"
47
48 #if HAVE_STDIO_H
49 #include <stdio.h>
50 #endif
51 #if HAVE_STRING_H
52 #include <string.h>
53 #endif
54
55 #define NMB_UNICAST 1
56 #define NMB_BROADCAST 2
57
58 struct SMBDOMAIN {
59 const char *name; /* domain name */
60 const char *sname; /* match this with user input */
61 const char *passthrough; /* pass-through authentication */
62 const char *nmbaddr; /* name service address */
63 int nmbcast; /* broadcast or unicast */
64 char *authshare; /* share name of auth file */
65 const char *authfile; /* pathname of auth file */
66 struct SMBDOMAIN *next; /* linked list */
67 };
68
69 struct SMBDOMAIN *firstdom = NULL;
70 struct SMBDOMAIN *lastdom = NULL;
71
72 /*
73 * escape the backslash character, since it has a special meaning
74 * to the read command of the bourne shell.
75 */
76
77 void
78 print_esc(FILE * p, char *s)
79 {
80 char buf[HELPER_INPUT_BUFFER];
81 char *t;
82 int i = 0;
83
84 for (t = s; *t != '\0'; ++t) {
85 /*
86 * NP: The shell escaping permits 'i' to jump up to 2 octets per loop,
87 * so ensure we have at least 3 free.
88 */
89 if (i > HELPER_INPUT_BUFFER-3) {
90 buf[i] = '\0';
91 (void) fputs(buf, p);
92 i = 0;
93 }
94 if (*t == '\\')
95 buf[i++] = '\\';
96
97 buf[i] = *t;
98 ++i;
99 }
100
101 if (i > 0) {
102 buf[i] = '\0';
103 (void) fputs(buf, p);
104 }
105 }
106
107 int
108 main(int argc, char *argv[])
109 {
110 int i;
111 char buf[HELPER_INPUT_BUFFER];
112 struct SMBDOMAIN *dom;
113 char *s;
114 char *user;
115 char *pass;
116 char *domname;
117 FILE *p;
118 const char *shcmd;
119
120 /* make standard output line buffered */
121 if (setvbuf(stdout, NULL, _IOLBF, 0) != 0)
122 return 1;
123
124 /* parse command line arguments */
125 for (i = 1; i < argc; ++i) {
126 if (strcmp(argv[i], "-d") == 0) {
127 debug_enabled = 1;
128 continue;
129 }
130 /* the next options require an argument */
131 if (i + 1 == argc)
132 break;
133
134 if (strcmp(argv[i], "-W") == 0) {
135 if ((dom = (struct SMBDOMAIN *) malloc(sizeof(struct SMBDOMAIN))) == NULL)
136 return 1;
137
138 dom->name = dom->sname = argv[++i];
139 dom->passthrough = "";
140 dom->nmbaddr = "";
141 dom->nmbcast = NMB_BROADCAST;
142 dom->authshare = (char *)"NETLOGON";
143 dom->authfile = "proxyauth";
144 dom->next = NULL;
145
146 /* append to linked list */
147 if (lastdom != NULL)
148 lastdom->next = dom;
149 else
150 firstdom = dom;
151
152 lastdom = dom;
153 continue;
154 }
155 if (strcmp(argv[i], "-w") == 0) {
156 if (lastdom != NULL)
157 lastdom->sname = argv[++i];
158 continue;
159 }
160 if (strcmp(argv[i], "-P") == 0) {
161 if (lastdom != NULL)
162 lastdom->passthrough = argv[++i];
163 continue;
164 }
165 if (strcmp(argv[i], "-B") == 0) {
166 if (lastdom != NULL) {
167 lastdom->nmbaddr = argv[++i];
168 lastdom->nmbcast = NMB_BROADCAST;
169 }
170 continue;
171 }
172 if (strcmp(argv[i], "-U") == 0) {
173 if (lastdom != NULL) {
174 lastdom->nmbaddr = argv[++i];
175 lastdom->nmbcast = NMB_UNICAST;
176 }
177 continue;
178 }
179 if (strcmp(argv[i], "-S") == 0) {
180 if (lastdom != NULL) {
181 if ((lastdom->authshare = xstrdup(argv[++i])) == NULL)
182 return 1;
183
184 /* convert backslashes to forward slashes */
185 for (s = lastdom->authshare; *s != '\0'; ++s)
186 if (*s == '\\')
187 *s = '/';
188
189 /* strip leading forward slash from share name */
190 if (*lastdom->authshare == '/')
191 ++lastdom->authshare;
192
193 if ((s = strchr(lastdom->authshare, '/')) != NULL) {
194 *s = '\0';
195 lastdom->authfile = s + 1;
196 }
197 }
198 continue;
199 }
200 }
201
202 shcmd = debug_enabled ? HELPERSCRIPT : HELPERSCRIPT " > /dev/null 2>&1";
203
204 while (fgets(buf, HELPER_INPUT_BUFFER, stdin) != NULL) {
205
206 if ((s = strchr(buf, '\n')) == NULL)
207 continue;
208 *s = '\0';
209
210 if ((s = strchr(buf, ' ')) == NULL) {
211 SEND_ERR("");
212 continue;
213 }
214 *s = '\0';
215
216 user = buf;
217 pass = s + 1;
218 domname = NULL;
219
220 rfc1738_unescape(user);
221 rfc1738_unescape(pass);
222
223 if ((s = strchr(user, '\\')) != NULL) {
224 *s = '\0';
225 domname = user;
226 user = s + 1;
227 }
228 /* match domname with linked list */
229 if (domname != NULL && strlen(domname) > 0) {
230 for (dom = firstdom; dom != NULL; dom = dom->next)
231 if (strcasecmp(dom->sname, domname) == 0)
232 break;
233 } else
234 dom = firstdom;
235
236 if (dom == NULL) {
237 SEND_ERR("");
238 continue;
239 }
240 if ((p = popen(shcmd, "w")) == NULL) {
241 SEND_ERR("");
242 continue;
243 }
244 (void) fprintf(p, "%s\n", dom->name);
245 (void) fprintf(p, "%s\n", dom->passthrough);
246 (void) fprintf(p, "%s\n", dom->nmbaddr);
247 (void) fprintf(p, "%d\n", dom->nmbcast);
248 (void) fprintf(p, "%s\n", dom->authshare);
249 (void) fprintf(p, "%s\n", dom->authfile);
250 (void) fprintf(p, "%s\n", user);
251 /* the password can contain special characters */
252 print_esc(p, pass);
253 (void) fputc('\n', p);
254 (void) fflush(p);
255
256 if (pclose(p) == 0)
257 SEND_OK("");
258 else
259 SEND_ERR("");
260 } /* while (1) */
261 return 0;
262 }