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_net.h"
26 : #include "system/filesys.h"
27 : #include "system/network.h"
28 : #include "../libcli/nbt/libnbt.h"
29 :
30 : /********************************************************
31 : Start parsing the lmhosts file.
32 : *********************************************************/
33 :
34 40633 : FILE *startlmhosts(const char *fname)
35 : {
36 40633 : FILE *fp = fopen(fname, "r");
37 40633 : if (!fp) {
38 40633 : DEBUG(4,("startlmhosts: Can't open lmhosts file %s. "
39 : "Error was %s\n",
40 : fname, strerror(errno)));
41 40633 : return NULL;
42 : }
43 0 : return fp;
44 : }
45 :
46 : /********************************************************
47 : Parse the next line in the lmhosts file.
48 : *********************************************************/
49 :
50 0 : bool getlmhostsent(TALLOC_CTX *ctx, FILE *fp, char **pp_name, int *name_type,
51 : struct sockaddr_storage *pss)
52 : {
53 : char line[1024];
54 :
55 0 : *pp_name = NULL;
56 :
57 0 : while(!feof(fp) && !ferror(fp)) {
58 0 : char *ip = NULL;
59 0 : char *flags = NULL;
60 0 : char *extra = NULL;
61 0 : char *name = NULL;
62 : const char *ptr;
63 0 : char *ptr1 = NULL;
64 0 : int count = 0;
65 :
66 0 : *name_type = -1;
67 :
68 0 : if (!fgets_slash(NULL,line,sizeof(line),fp)) {
69 0 : continue;
70 : }
71 :
72 0 : if (*line == '#') {
73 0 : continue;
74 : }
75 :
76 0 : ptr = line;
77 :
78 0 : if (next_token_talloc(ctx, &ptr, &ip, NULL))
79 0 : ++count;
80 0 : if (next_token_talloc(ctx, &ptr, &name, NULL))
81 0 : ++count;
82 0 : if (next_token_talloc(ctx, &ptr, &flags, NULL))
83 0 : ++count;
84 0 : if (next_token_talloc(ctx, &ptr, &extra, NULL))
85 0 : ++count;
86 :
87 0 : if (count <= 0)
88 0 : continue;
89 :
90 0 : if (count > 0 && count < 2) {
91 0 : DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",
92 : line));
93 0 : continue;
94 : }
95 :
96 0 : if (count >= 4) {
97 0 : DEBUG(0,("getlmhostsent: too many columns "
98 : "in lmhosts file (obsolete syntax)\n"));
99 0 : continue;
100 : }
101 :
102 0 : if (!flags) {
103 0 : flags = talloc_strdup(ctx, "");
104 0 : if (!flags) {
105 0 : continue;
106 : }
107 : }
108 :
109 0 : DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n",
110 : ip, name, flags));
111 :
112 0 : if (strchr_m(flags,'G') || strchr_m(flags,'S')) {
113 0 : DEBUG(0,("getlmhostsent: group flag "
114 : "in lmhosts ignored (obsolete)\n"));
115 0 : continue;
116 : }
117 :
118 0 : if (!interpret_string_addr(pss, ip, AI_NUMERICHOST)) {
119 0 : DEBUG(0,("getlmhostsent: invalid address "
120 : "%s.\n", ip));
121 : }
122 :
123 : /* Extra feature. If the name ends in '#XX',
124 : * where XX is a hex number, then only add that name type. */
125 0 : if((ptr1 = strchr_m(name, '#')) != NULL) {
126 : char *endptr;
127 0 : ptr1++;
128 :
129 0 : *name_type = (int)strtol(ptr1, &endptr, 16);
130 0 : if(!*ptr1 || (endptr == ptr1)) {
131 0 : DEBUG(0,("getlmhostsent: invalid name "
132 : "%s containing '#'.\n", name));
133 0 : continue;
134 : }
135 :
136 0 : *(--ptr1) = '\0'; /* Truncate at the '#' */
137 : }
138 :
139 0 : *pp_name = talloc_strdup(ctx, name);
140 0 : if (!*pp_name) {
141 0 : return false;
142 : }
143 0 : return true;
144 : }
145 :
146 0 : return false;
147 : }
148 :
149 : /********************************************************
150 : Finish parsing the lmhosts file.
151 : *********************************************************/
152 :
153 0 : void endlmhosts(FILE *fp)
154 : {
155 0 : fclose(fp);
156 0 : }
157 :
158 : /********************************************************
159 : Resolve via "lmhosts" method.
160 : *********************************************************/
161 :
162 40607 : NTSTATUS resolve_lmhosts_file_as_sockaddr(TALLOC_CTX *mem_ctx,
163 : const char *lmhosts_file,
164 : const char *name,
165 : int name_type,
166 : struct sockaddr_storage **return_iplist,
167 : size_t *return_count)
168 : {
169 : /*
170 : * "lmhosts" means parse the local lmhosts file.
171 : */
172 :
173 : FILE *fp;
174 40607 : char *lmhost_name = NULL;
175 : int name_type2;
176 : struct sockaddr_storage return_ss;
177 40607 : NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
178 40607 : TALLOC_CTX *ctx = NULL;
179 40607 : size_t ret_count = 0;
180 40607 : struct sockaddr_storage *iplist = NULL;
181 :
182 40607 : DEBUG(3,("resolve_lmhosts: "
183 : "Attempting lmhosts lookup for name %s<0x%x>\n",
184 : name, name_type));
185 :
186 40607 : fp = startlmhosts(lmhosts_file);
187 :
188 40607 : if ( fp == NULL )
189 40607 : return NT_STATUS_NO_SUCH_FILE;
190 :
191 0 : ctx = talloc_new(mem_ctx);
192 0 : if (!ctx) {
193 0 : endlmhosts(fp);
194 0 : return NT_STATUS_NO_MEMORY;
195 : }
196 :
197 0 : while (getlmhostsent(ctx, fp, &lmhost_name, &name_type2, &return_ss)) {
198 :
199 0 : if (!strequal(name, lmhost_name)) {
200 0 : TALLOC_FREE(lmhost_name);
201 0 : continue;
202 : }
203 :
204 0 : if ((name_type2 != -1) && (name_type != name_type2)) {
205 0 : TALLOC_FREE(lmhost_name);
206 0 : continue;
207 : }
208 :
209 : /* wrap check. */
210 0 : if (ret_count + 1 < ret_count) {
211 0 : TALLOC_FREE(ctx);
212 0 : endlmhosts(fp);
213 0 : return NT_STATUS_INVALID_PARAMETER;
214 : }
215 0 : iplist = talloc_realloc(ctx, iplist,
216 : struct sockaddr_storage,
217 : ret_count+1);
218 :
219 0 : if (iplist == NULL) {
220 0 : TALLOC_FREE(ctx);
221 0 : endlmhosts(fp);
222 0 : DEBUG(3,("resolve_lmhosts: talloc_realloc fail !\n"));
223 0 : return NT_STATUS_NO_MEMORY;
224 : }
225 :
226 0 : iplist[ret_count] = return_ss;
227 0 : ret_count += 1;
228 :
229 : /* we found something */
230 0 : status = NT_STATUS_OK;
231 :
232 : /* Multiple names only for DC lookup */
233 0 : if (name_type != 0x1c)
234 0 : break;
235 : }
236 :
237 0 : *return_count = ret_count;
238 0 : *return_iplist = talloc_move(mem_ctx, &iplist);
239 0 : TALLOC_FREE(ctx);
240 0 : endlmhosts(fp);
241 0 : return status;
242 : }
243 :
|