]> git.ipfire.org Git - thirdparty/squid.git/blob - helpers/basic_auth/SMB/basic_smb_auth.cc
Sync with trunk rev.13542
[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 #include <cstring>
49
50 #define NMB_UNICAST 1
51 #define NMB_BROADCAST 2
52
53 struct SMBDOMAIN {
54 const char *name; /* domain name */
55 const char *sname; /* match this with user input */
56 const char *passthrough; /* pass-through authentication */
57 const char *nmbaddr; /* name service address */
58 int nmbcast; /* broadcast or unicast */
59 char *authshare; /* share name of auth file */
60 const char *authfile; /* pathname of auth file */
61 struct SMBDOMAIN *next; /* linked list */
62 };
63
64 struct SMBDOMAIN *firstdom = NULL;
65 struct SMBDOMAIN *lastdom = NULL;
66
67 /*
68 * escape the backslash character, since it has a special meaning
69 * to the read command of the bourne shell.
70 */
71
72 void
73 print_esc(FILE * p, char *s)
74 {
75 char buf[HELPER_INPUT_BUFFER];
76 char *t;
77 int i = 0;
78
79 for (t = s; *t != '\0'; ++t) {
80 /*
81 * NP: The shell escaping permits 'i' to jump up to 2 octets per loop,
82 * so ensure we have at least 3 free.
83 */
84 if (i > HELPER_INPUT_BUFFER-3) {
85 buf[i] = '\0';
86 (void) fputs(buf, p);
87 i = 0;
88 }
89 if (*t == '\\')
90 buf[i++] = '\\';
91
92 buf[i] = *t;
93 ++i;
94 }
95
96 if (i > 0) {
97 buf[i] = '\0';
98 (void) fputs(buf, p);
99 }
100 }
101
102 int
103 main(int argc, char *argv[])
104 {
105 int i;
106 char buf[HELPER_INPUT_BUFFER];
107 struct SMBDOMAIN *dom;
108 char *s;
109 char *user;
110 char *pass;
111 char *domname;
112 FILE *p;
113 const char *shcmd;
114
115 /* make standard output line buffered */
116 if (setvbuf(stdout, NULL, _IOLBF, 0) != 0)
117 return 1;
118
119 /* parse command line arguments */
120 for (i = 1; i < argc; ++i) {
121 if (strcmp(argv[i], "-d") == 0) {
122 debug_enabled = 1;
123 continue;
124 }
125 /* the next options require an argument */
126 if (i + 1 == argc)
127 break;
128
129 if (strcmp(argv[i], "-W") == 0) {
130 if ((dom = (struct SMBDOMAIN *) malloc(sizeof(struct SMBDOMAIN))) == NULL)
131 return 1;
132
133 dom->name = dom->sname = argv[++i];
134 dom->passthrough = "";
135 dom->nmbaddr = "";
136 dom->nmbcast = NMB_BROADCAST;
137 dom->authshare = (char *)"NETLOGON";
138 dom->authfile = "proxyauth";
139 dom->next = NULL;
140
141 /* append to linked list */
142 if (lastdom != NULL)
143 lastdom->next = dom;
144 else
145 firstdom = dom;
146
147 lastdom = dom;
148 continue;
149 }
150 if (strcmp(argv[i], "-w") == 0) {
151 if (lastdom != NULL)
152 lastdom->sname = argv[++i];
153 continue;
154 }
155 if (strcmp(argv[i], "-P") == 0) {
156 if (lastdom != NULL)
157 lastdom->passthrough = argv[++i];
158 continue;
159 }
160 if (strcmp(argv[i], "-B") == 0) {
161 if (lastdom != NULL) {
162 lastdom->nmbaddr = argv[++i];
163 lastdom->nmbcast = NMB_BROADCAST;
164 }
165 continue;
166 }
167 if (strcmp(argv[i], "-U") == 0) {
168 if (lastdom != NULL) {
169 lastdom->nmbaddr = argv[++i];
170 lastdom->nmbcast = NMB_UNICAST;
171 }
172 continue;
173 }
174 if (strcmp(argv[i], "-S") == 0) {
175 if (lastdom != NULL) {
176 if ((lastdom->authshare = xstrdup(argv[++i])) == NULL)
177 return 1;
178
179 /* convert backslashes to forward slashes */
180 for (s = lastdom->authshare; *s != '\0'; ++s)
181 if (*s == '\\')
182 *s = '/';
183
184 /* strip leading forward slash from share name */
185 if (*lastdom->authshare == '/')
186 ++lastdom->authshare;
187
188 if ((s = strchr(lastdom->authshare, '/')) != NULL) {
189 *s = '\0';
190 lastdom->authfile = s + 1;
191 }
192 }
193 continue;
194 }
195 }
196
197 shcmd = debug_enabled ? HELPERSCRIPT : HELPERSCRIPT " > /dev/null 2>&1";
198
199 while (fgets(buf, HELPER_INPUT_BUFFER, stdin) != NULL) {
200
201 if ((s = strchr(buf, '\n')) == NULL)
202 continue;
203 *s = '\0';
204
205 if ((s = strchr(buf, ' ')) == NULL) {
206 SEND_ERR("");
207 continue;
208 }
209 *s = '\0';
210
211 user = buf;
212 pass = s + 1;
213 domname = NULL;
214
215 rfc1738_unescape(user);
216 rfc1738_unescape(pass);
217
218 if ((s = strchr(user, '\\')) != NULL) {
219 *s = '\0';
220 domname = user;
221 user = s + 1;
222 }
223 /* match domname with linked list */
224 if (domname != NULL && strlen(domname) > 0) {
225 for (dom = firstdom; dom != NULL; dom = dom->next)
226 if (strcasecmp(dom->sname, domname) == 0)
227 break;
228 } else
229 dom = firstdom;
230
231 if (dom == NULL) {
232 SEND_ERR("");
233 continue;
234 }
235 if ((p = popen(shcmd, "w")) == NULL) {
236 SEND_ERR("");
237 continue;
238 }
239 (void) fprintf(p, "%s\n", dom->name);
240 (void) fprintf(p, "%s\n", dom->passthrough);
241 (void) fprintf(p, "%s\n", dom->nmbaddr);
242 (void) fprintf(p, "%d\n", dom->nmbcast);
243 (void) fprintf(p, "%s\n", dom->authshare);
244 (void) fprintf(p, "%s\n", dom->authfile);
245 (void) fprintf(p, "%s\n", user);
246 /* the password can contain special characters */
247 print_esc(p, pass);
248 (void) fputc('\n', p);
249 (void) fflush(p);
250
251 if (pclose(p) == 0)
252 SEND_OK("");
253 else
254 SEND_ERR("");
255 } /* while (1) */
256 return 0;
257 }