Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : manipulate nbt name structures
5 :
6 : Copyright (C) Andrew Tridgell 1994-1998
7 : Copyright (C) Jeremy Allison 2007
8 : Copyright (C) Andrew Bartlett 2009.
9 :
10 : This program is free software; you can redistribute it and/or modify
11 : it under the terms of the GNU General Public License as published by
12 : the Free Software Foundation; either version 3 of the License, or
13 : (at your option) any later version.
14 :
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with this program. If not, see <http://www.gnu.org/licenses/>.
22 : */
23 :
24 : #include "includes.h"
25 : #include "lib/util/util_file.h"
26 : #include "lib/util/util_net.h"
27 : #include "system/filesys.h"
28 : #include "system/network.h"
29 : #include "../libcli/nbt/libnbt.h"
30 :
31 : /********************************************************
32 : Start parsing the lmhosts file.
33 : *********************************************************/
34 :
35 54310 : FILE *startlmhosts(const char *fname)
36 : {
37 54310 : FILE *fp = fopen(fname, "r");
38 54310 : if (!fp) {
39 54310 : DEBUG(4,("startlmhosts: Can't open lmhosts file %s. "
40 : "Error was %s\n",
41 : fname, strerror(errno)));
42 54310 : return NULL;
43 : }
44 0 : return fp;
45 : }
46 :
47 : /********************************************************
48 : Parse the next line in the lmhosts file.
49 : *********************************************************/
50 :
51 0 : bool getlmhostsent(TALLOC_CTX *ctx, FILE *fp, char **pp_name, int *name_type,
52 : struct sockaddr_storage *pss)
53 : {
54 0 : char line[1024];
55 :
56 0 : *pp_name = NULL;
57 :
58 0 : while(!feof(fp) && !ferror(fp)) {
59 0 : char *ip = NULL;
60 0 : char *flags = NULL;
61 0 : char *extra = NULL;
62 0 : char *name = NULL;
63 0 : const char *ptr;
64 0 : char *ptr1 = NULL;
65 0 : int count = 0;
66 :
67 0 : *name_type = -1;
68 :
69 0 : if (!fgets_slash(NULL,line,sizeof(line),fp)) {
70 0 : continue;
71 : }
72 :
73 0 : if (*line == '#') {
74 0 : continue;
75 : }
76 :
77 0 : ptr = line;
78 :
79 0 : if (next_token_talloc(ctx, &ptr, &ip, NULL))
80 0 : ++count;
81 0 : if (next_token_talloc(ctx, &ptr, &name, NULL))
82 0 : ++count;
83 0 : if (next_token_talloc(ctx, &ptr, &flags, NULL))
84 0 : ++count;
85 0 : if (next_token_talloc(ctx, &ptr, &extra, NULL))
86 0 : ++count;
87 :
88 0 : if (count <= 0)
89 0 : continue;
90 :
91 0 : if (count > 0 && count < 2) {
92 0 : DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",
93 : line));
94 0 : continue;
95 : }
96 :
97 0 : if (count >= 4) {
98 0 : DEBUG(0,("getlmhostsent: too many columns "
99 : "in lmhosts file (obsolete syntax)\n"));
100 0 : continue;
101 : }
102 :
103 0 : if (!flags) {
104 0 : flags = talloc_strdup(ctx, "");
105 0 : if (!flags) {
106 0 : continue;
107 : }
108 : }
109 :
110 0 : DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n",
111 : ip, name, flags));
112 :
113 0 : if (strchr_m(flags,'G') || strchr_m(flags,'S')) {
114 0 : DEBUG(0,("getlmhostsent: group flag "
115 : "in lmhosts ignored (obsolete)\n"));
116 0 : continue;
117 : }
118 :
119 0 : if (!interpret_string_addr(pss, ip, AI_NUMERICHOST)) {
120 0 : DEBUG(0,("getlmhostsent: invalid address "
121 : "%s.\n", ip));
122 : }
123 :
124 : /* Extra feature. If the name ends in '#XX',
125 : * where XX is a hex number, then only add that name type. */
126 0 : if((ptr1 = strchr_m(name, '#')) != NULL) {
127 0 : char *endptr;
128 0 : ptr1++;
129 :
130 0 : *name_type = (int)strtol(ptr1, &endptr, 16);
131 0 : if(!*ptr1 || (endptr == ptr1)) {
132 0 : DEBUG(0,("getlmhostsent: invalid name "
133 : "%s containing '#'.\n", name));
134 0 : continue;
135 : }
136 :
137 0 : *(--ptr1) = '\0'; /* Truncate at the '#' */
138 : }
139 :
140 0 : *pp_name = talloc_strdup(ctx, name);
141 0 : if (!*pp_name) {
142 0 : return false;
143 : }
144 0 : return true;
145 : }
146 :
147 0 : return false;
148 : }
149 :
150 : /********************************************************
151 : Finish parsing the lmhosts file.
152 : *********************************************************/
153 :
154 0 : void endlmhosts(FILE *fp)
155 : {
156 0 : fclose(fp);
157 0 : }
158 :
159 : /********************************************************
160 : Resolve via "lmhosts" method.
161 : *********************************************************/
162 :
163 54211 : NTSTATUS resolve_lmhosts_file_as_sockaddr(TALLOC_CTX *mem_ctx,
164 : const char *lmhosts_file,
165 : const char *name,
166 : int name_type,
167 : struct sockaddr_storage **return_iplist,
168 : size_t *return_count)
169 : {
170 : /*
171 : * "lmhosts" means parse the local lmhosts file.
172 : */
173 :
174 1242 : FILE *fp;
175 54211 : char *lmhost_name = NULL;
176 1242 : int name_type2;
177 1242 : struct sockaddr_storage return_ss;
178 54211 : NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
179 54211 : TALLOC_CTX *ctx = NULL;
180 54211 : size_t ret_count = 0;
181 54211 : struct sockaddr_storage *iplist = NULL;
182 :
183 54211 : DEBUG(3,("resolve_lmhosts: "
184 : "Attempting lmhosts lookup for name %s<0x%x>\n",
185 : name, name_type));
186 :
187 54211 : fp = startlmhosts(lmhosts_file);
188 :
189 54211 : if ( fp == NULL )
190 54211 : return NT_STATUS_NO_SUCH_FILE;
191 :
192 0 : ctx = talloc_new(mem_ctx);
193 0 : if (!ctx) {
194 0 : endlmhosts(fp);
195 0 : return NT_STATUS_NO_MEMORY;
196 : }
197 :
198 0 : while (getlmhostsent(ctx, fp, &lmhost_name, &name_type2, &return_ss)) {
199 :
200 0 : if (!strequal(name, lmhost_name)) {
201 0 : TALLOC_FREE(lmhost_name);
202 0 : continue;
203 : }
204 :
205 0 : if ((name_type2 != -1) && (name_type != name_type2)) {
206 0 : TALLOC_FREE(lmhost_name);
207 0 : continue;
208 : }
209 :
210 : /* wrap check. */
211 0 : if (ret_count + 1 < ret_count) {
212 0 : TALLOC_FREE(ctx);
213 0 : endlmhosts(fp);
214 0 : return NT_STATUS_INVALID_PARAMETER;
215 : }
216 0 : iplist = talloc_realloc(ctx, iplist,
217 : struct sockaddr_storage,
218 : ret_count+1);
219 :
220 0 : if (iplist == NULL) {
221 0 : TALLOC_FREE(ctx);
222 0 : endlmhosts(fp);
223 0 : DEBUG(3,("resolve_lmhosts: talloc_realloc fail !\n"));
224 0 : return NT_STATUS_NO_MEMORY;
225 : }
226 :
227 0 : iplist[ret_count] = return_ss;
228 0 : ret_count += 1;
229 :
230 : /* we found something */
231 0 : status = NT_STATUS_OK;
232 :
233 : /* Multiple names only for DC lookup */
234 0 : if (name_type != 0x1c)
235 0 : break;
236 : }
237 :
238 0 : *return_count = ret_count;
239 0 : *return_iplist = talloc_move(mem_ctx, &iplist);
240 0 : TALLOC_FREE(ctx);
241 0 : endlmhosts(fp);
242 0 : return status;
243 : }
244 :
|