]> git.ipfire.org Git - thirdparty/squid.git/blame - src/auth/basic/SMB/basic_smb_auth.cc
Source Format Enforcement (#1234)
[thirdparty/squid.git] / src / auth / basic / SMB / basic_smb_auth.cc
CommitLineData
5b95b903 1/*
b8ae064d 2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
5b95b903
AJ
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
94439e4e 9/*
5a48ed18 10 * basic_smb_auth - SMB proxy authentication module
94439e4e 11 * Copyright (C) 1998 Richard Huveneers <richard@hekkihek.hacom.nl>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
94439e4e 25 */
5b95b903 26
f7f3304a 27#include "squid.h"
079b1d0f 28#include "helper/protocol_defines.h"
5a48ed18
AJ
29#include "rfc1738.h"
30#include "util.h"
94439e4e 31
074d6a40 32#include <cstring>
94439e4e 33
f53969cc
SM
34#define NMB_UNICAST 1
35#define NMB_BROADCAST 2
94439e4e 36
37struct SMBDOMAIN {
f53969cc
SM
38 const char *name; /* domain name */
39 const char *sname; /* match this with user input */
40 const char *passthrough; /* pass-through authentication */
41 const char *nmbaddr; /* name service address */
42 int nmbcast; /* broadcast or unicast */
43 char *authshare; /* share name of auth file */
44 const char *authfile; /* pathname of auth file */
45 struct SMBDOMAIN *next; /* linked list */
94439e4e 46};
47
aee3523a
AR
48struct SMBDOMAIN *firstdom = nullptr;
49struct SMBDOMAIN *lastdom = nullptr;
94439e4e 50
51/*
52 * escape the backslash character, since it has a special meaning
53 * to the read command of the bourne shell.
54 */
55
7a3fb70d 56static void
94439e4e 57print_esc(FILE * p, char *s)
58{
e673ba3a 59 char buf[HELPER_INPUT_BUFFER];
94439e4e 60 char *t;
61 int i = 0;
62
755494da 63 for (t = s; *t != '\0'; ++t) {
1137dfd5
AJ
64 /*
65 * NP: The shell escaping permits 'i' to jump up to 2 octets per loop,
66 * so ensure we have at least 3 free.
67 */
68 if (i > HELPER_INPUT_BUFFER-3) {
26ac0430
AJ
69 buf[i] = '\0';
70 (void) fputs(buf, p);
71 i = 0;
72 }
73 if (*t == '\\')
74 buf[i++] = '\\';
94439e4e 75
f207fe64
FC
76 buf[i] = *t;
77 ++i;
94439e4e 78 }
79
80 if (i > 0) {
26ac0430
AJ
81 buf[i] = '\0';
82 (void) fputs(buf, p);
94439e4e 83 }
84}
85
86int
87main(int argc, char *argv[])
88{
89 int i;
e673ba3a 90 char buf[HELPER_INPUT_BUFFER];
94439e4e 91 struct SMBDOMAIN *dom;
92 char *s;
93 char *user;
94 char *pass;
95 char *domname;
96 FILE *p;
4327acf1 97 const char *shcmd;
94439e4e 98
99 /* make standard output line buffered */
aee3523a 100 if (setvbuf(stdout, nullptr, _IOLBF, 0) != 0)
24885773 101 exit(EXIT_FAILURE);
94439e4e 102
103 /* parse command line arguments */
755494da 104 for (i = 1; i < argc; ++i) {
26ac0430 105 if (strcmp(argv[i], "-d") == 0) {
e673ba3a 106 debug_enabled = 1;
26ac0430
AJ
107 continue;
108 }
109 /* the next options require an argument */
110 if (i + 1 == argc)
111 break;
94439e4e 112
26ac0430 113 if (strcmp(argv[i], "-W") == 0) {
c14fb378 114 dom = static_cast<struct SMBDOMAIN *>(xmalloc(sizeof(struct SMBDOMAIN)));
94439e4e 115
26ac0430
AJ
116 dom->name = dom->sname = argv[++i];
117 dom->passthrough = "";
118 dom->nmbaddr = "";
119 dom->nmbcast = NMB_BROADCAST;
4327acf1 120 dom->authshare = (char *)"NETLOGON";
26ac0430 121 dom->authfile = "proxyauth";
aee3523a 122 dom->next = nullptr;
94439e4e 123
26ac0430 124 /* append to linked list */
aee3523a 125 if (lastdom != nullptr)
26ac0430
AJ
126 lastdom->next = dom;
127 else
128 firstdom = dom;
94439e4e 129
26ac0430
AJ
130 lastdom = dom;
131 continue;
132 }
133 if (strcmp(argv[i], "-w") == 0) {
aee3523a 134 if (lastdom != nullptr)
26ac0430
AJ
135 lastdom->sname = argv[++i];
136 continue;
137 }
138 if (strcmp(argv[i], "-P") == 0) {
aee3523a 139 if (lastdom != nullptr)
26ac0430
AJ
140 lastdom->passthrough = argv[++i];
141 continue;
142 }
143 if (strcmp(argv[i], "-B") == 0) {
aee3523a 144 if (lastdom != nullptr) {
26ac0430
AJ
145 lastdom->nmbaddr = argv[++i];
146 lastdom->nmbcast = NMB_BROADCAST;
147 }
148 continue;
149 }
150 if (strcmp(argv[i], "-U") == 0) {
aee3523a 151 if (lastdom != nullptr) {
26ac0430
AJ
152 lastdom->nmbaddr = argv[++i];
153 lastdom->nmbcast = NMB_UNICAST;
154 }
155 continue;
156 }
157 if (strcmp(argv[i], "-S") == 0) {
aee3523a
AR
158 if (lastdom != nullptr) {
159 if ((lastdom->authshare = xstrdup(argv[++i])) == nullptr)
24885773 160 exit(EXIT_FAILURE);
94439e4e 161
26ac0430 162 /* convert backslashes to forward slashes */
755494da 163 for (s = lastdom->authshare; *s != '\0'; ++s)
26ac0430
AJ
164 if (*s == '\\')
165 *s = '/';
94439e4e 166
26ac0430
AJ
167 /* strip leading forward slash from share name */
168 if (*lastdom->authshare == '/')
755494da 169 ++lastdom->authshare;
94439e4e 170
aee3523a 171 if ((s = strchr(lastdom->authshare, '/')) != nullptr) {
26ac0430
AJ
172 *s = '\0';
173 lastdom->authfile = s + 1;
174 }
175 }
176 continue;
177 }
94439e4e 178 }
179
e673ba3a 180 shcmd = debug_enabled ? HELPERSCRIPT : HELPERSCRIPT " > /dev/null 2>&1";
94439e4e 181
aee3523a 182 while (fgets(buf, HELPER_INPUT_BUFFER, stdin) != nullptr) {
94439e4e 183
aee3523a 184 if ((s = strchr(buf, '\n')) == nullptr)
26ac0430
AJ
185 continue;
186 *s = '\0';
94439e4e 187
aee3523a 188 if ((s = strchr(buf, ' ')) == nullptr) {
e673ba3a 189 SEND_ERR("");
26ac0430
AJ
190 continue;
191 }
192 *s = '\0';
94439e4e 193
26ac0430
AJ
194 user = buf;
195 pass = s + 1;
aee3523a 196 domname = nullptr;
94439e4e 197
26ac0430
AJ
198 rfc1738_unescape(user);
199 rfc1738_unescape(pass);
25858293 200
aee3523a 201 if ((s = strchr(user, '\\')) != nullptr) {
26ac0430
AJ
202 *s = '\0';
203 domname = user;
204 user = s + 1;
205 }
206 /* match domname with linked list */
aee3523a
AR
207 if (domname != nullptr && strlen(domname) > 0) {
208 for (dom = firstdom; dom != nullptr; dom = dom->next)
26ac0430
AJ
209 if (strcasecmp(dom->sname, domname) == 0)
210 break;
211 } else
212 dom = firstdom;
94439e4e 213
aee3523a 214 if (dom == nullptr) {
e673ba3a 215 SEND_ERR("");
26ac0430
AJ
216 continue;
217 }
aee3523a 218 if ((p = popen(shcmd, "w")) == nullptr) {
e673ba3a 219 SEND_ERR("");
26ac0430
AJ
220 continue;
221 }
222 (void) fprintf(p, "%s\n", dom->name);
223 (void) fprintf(p, "%s\n", dom->passthrough);
224 (void) fprintf(p, "%s\n", dom->nmbaddr);
225 (void) fprintf(p, "%d\n", dom->nmbcast);
226 (void) fprintf(p, "%s\n", dom->authshare);
227 (void) fprintf(p, "%s\n", dom->authfile);
228 (void) fprintf(p, "%s\n", user);
229 /* the password can contain special characters */
230 print_esc(p, pass);
231 (void) fputc('\n', p);
232 (void) fflush(p);
94439e4e 233
26ac0430 234 if (pclose(p) == 0)
e673ba3a 235 SEND_OK("");
26ac0430 236 else
e673ba3a 237 SEND_ERR("");
f53969cc 238 } /* while (1) */
24885773
AJ
239
240 return EXIT_SUCCESS;
94439e4e 241}
f53969cc 242