OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | --- a/source3/Makefile.in |
2 | +++ b/source3/Makefile.in |
||
3 | @@ -1025,7 +1025,7 @@ TEST_LP_LOAD_OBJ = param/test_lp_load.o |
||
4 | |||
5 | PASSWD_UTIL_OBJ = utils/passwd_util.o |
||
6 | |||
7 | -SMBPASSWD_OBJ = utils/smbpasswd.o $(PASSWD_UTIL_OBJ) $(PASSCHANGE_OBJ) \ |
||
8 | +SMBPASSWD_OBJ = utils/owrt_smbpasswd.o $(PASSWD_UTIL_OBJ) $(PASSCHANGE_OBJ) \ |
||
9 | $(PARAM_OBJ) $(LIBSMB_OBJ) $(PASSDB_OBJ) \ |
||
10 | $(GROUPDB_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \ |
||
11 | $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) \ |
||
12 | @@ -1813,7 +1813,7 @@ nmbd/nmbd_multicall.o: nmbd/nmbd.c nmbd/ |
||
13 | echo "$(COMPILE_CC_PATH)" 1>&2;\ |
||
14 | $(COMPILE_CC_PATH) >/dev/null 2>&1 |
||
15 | |||
16 | -utils/smbpasswd_multicall.o: utils/smbpasswd.c utils/smbpasswd.o |
||
17 | +utils/smbpasswd_multicall.o: utils/owrt_smbpasswd.c utils/owrt_smbpasswd.o |
||
18 | @echo Compiling $<.c |
||
19 | @$(COMPILE_CC_PATH) -Dmain=smbpasswd_main && exit 0;\ |
||
20 | echo "The following command failed:" 1>&2;\ |
||
21 | @@ -1822,7 +1822,7 @@ utils/smbpasswd_multicall.o: utils/smbpa |
||
22 | |||
23 | SMBD_MULTI_O = $(patsubst smbd/server.o,smbd/server_multicall.o,$(SMBD_OBJ)) |
||
24 | NMBD_MULTI_O = $(patsubst nmbd/nmbd.o,nmbd/nmbd_multicall.o,$(filter-out $(LIB_DUMMY_OBJ),$(NMBD_OBJ))) |
||
25 | -SMBPASSWD_MULTI_O = $(patsubst utils/smbpasswd.o,utils/smbpasswd_multicall.o,$(filter-out $(LIB_DUMMY_OBJ),$(SMBPASSWD_OBJ))) |
||
26 | +SMBPASSWD_MULTI_O = $(patsubst utils/owrt_smbpasswd.o,utils/smbpasswd_multicall.o,$(filter-out $(LIB_DUMMY_OBJ),$(SMBPASSWD_OBJ))) |
||
27 | MULTI_O = multi.o |
||
28 | |||
29 | MULTICALL_O = $(sort $(SMBD_MULTI_O) $(NMBD_MULTI_O) $(SMBPASSWD_MULTI_O) $(MULTI_O)) |
||
30 | --- /dev/null |
||
31 | +++ b/source3/utils/owrt_smbpasswd.c |
||
32 | @@ -0,0 +1,249 @@ |
||
33 | +/* |
||
34 | + * Copyright (C) 2012 Felix Fietkau <nbd@nbd.name> |
||
35 | + * Copyright (C) 2008 John Crispin <blogic@openwrt.org> |
||
36 | + * |
||
37 | + * This program is free software; you can redistribute it and/or modify it |
||
38 | + * under the terms of the GNU General Public License as published by the |
||
39 | + * Free Software Foundation; either version 2 of the License, or (at your |
||
40 | + * option) any later version. |
||
41 | + * |
||
42 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
||
43 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
||
44 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
||
45 | + * more details. |
||
46 | + * |
||
47 | + * You should have received a copy of the GNU General Public License along with |
||
48 | + * this program; if not, write to the Free Software Foundation, Inc., 675 |
||
49 | + * Mass Ave, Cambridge, MA 02139, USA. */ |
||
50 | + |
||
51 | +#include "includes.h" |
||
52 | +#include <endian.h> |
||
53 | +#include <stdio.h> |
||
54 | + |
||
55 | +static char buf[256]; |
||
56 | + |
||
57 | +static void md4hash(const char *passwd, uchar p16[16]) |
||
58 | +{ |
||
59 | + int len; |
||
60 | + smb_ucs2_t wpwd[129]; |
||
61 | + int i; |
||
62 | + |
||
63 | + len = strlen(passwd); |
||
64 | + for (i = 0; i < len; i++) { |
||
65 | +#if __BYTE_ORDER == __LITTLE_ENDIAN |
||
66 | + wpwd[i] = (unsigned char)passwd[i]; |
||
67 | +#else |
||
68 | + wpwd[i] = (unsigned char)passwd[i] << 8; |
||
69 | +#endif |
||
70 | + } |
||
71 | + wpwd[i] = 0; |
||
72 | + |
||
73 | + len = len * sizeof(int16); |
||
74 | + mdfour(p16, (unsigned char *)wpwd, len); |
||
75 | + ZERO_STRUCT(wpwd); |
||
76 | +} |
||
77 | + |
||
78 | + |
||
79 | +static bool find_passwd_line(FILE *fp, const char *user, char **next) |
||
80 | +{ |
||
81 | + char *p1; |
||
82 | + |
||
83 | + while (!feof(fp)) { |
||
84 | + if(!fgets(buf, sizeof(buf) - 1, fp)) |
||
85 | + continue; |
||
86 | + |
||
87 | + p1 = strchr(buf, ':'); |
||
88 | + |
||
89 | + if (p1 - buf != strlen(user)) |
||
90 | + continue; |
||
91 | + |
||
92 | + if (strncmp(buf, user, p1 - buf) != 0) |
||
93 | + continue; |
||
94 | + |
||
95 | + if (next) |
||
96 | + *next = p1; |
||
97 | + return true; |
||
98 | + } |
||
99 | + return false; |
||
100 | +} |
||
101 | + |
||
102 | +/* returns -1 if user is not present in /etc/passwd*/ |
||
103 | +static int find_uid_for_user(const char *user) |
||
104 | +{ |
||
105 | + FILE *fp; |
||
106 | + char *p1, *p2, *p3; |
||
107 | + int ret = -1; |
||
108 | + |
||
109 | + fp = fopen("/etc/passwd", "r"); |
||
110 | + if (!fp) { |
||
111 | + printf("failed to open /etc/passwd"); |
||
112 | + goto out; |
||
113 | + } |
||
114 | + |
||
115 | + if (!find_passwd_line(fp, user, &p1)) { |
||
116 | + printf("User %s not found or invalid in /etc/passwd\n", user); |
||
117 | + goto out; |
||
118 | + } |
||
119 | + |
||
120 | + p2 = strchr(p1 + 1, ':'); |
||
121 | + if (!p2) |
||
122 | + goto out; |
||
123 | + |
||
124 | + p2++; |
||
125 | + p3 = strchr(p2, ':'); |
||
126 | + if (!p1) |
||
127 | + goto out; |
||
128 | + |
||
129 | + *p3 = '\0'; |
||
130 | + ret = atoi(p2); |
||
131 | + |
||
132 | +out: |
||
133 | + if(fp) |
||
134 | + fclose(fp); |
||
135 | + return ret; |
||
136 | +} |
||
137 | + |
||
138 | +static void smbpasswd_write_user(FILE *fp, const char *user, int uid, const char *password) |
||
139 | +{ |
||
140 | + static uchar nt_p16[NT_HASH_LEN]; |
||
141 | + int len = 0; |
||
142 | + int i; |
||
143 | + |
||
144 | + md4hash(strdup(password), nt_p16); |
||
145 | + |
||
146 | + len += snprintf(buf + len, sizeof(buf) - len, "%s:%u:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:", user, uid); |
||
147 | + for(i = 0; i < NT_HASH_LEN; i++) |
||
148 | + len += snprintf(buf + len, sizeof(buf) - len, "%02X", nt_p16[i]); |
||
149 | + |
||
150 | + snprintf(buf + len, sizeof(buf) - len, ":[U ]:LCT-00000001:\n"); |
||
151 | + fputs(buf, fp); |
||
152 | +} |
||
153 | + |
||
154 | +static void smbpasswd_delete_user(FILE *fp) |
||
155 | +{ |
||
156 | + fpos_t r_pos, w_pos; |
||
157 | + int len = strlen(buf); |
||
158 | + |
||
159 | + fgetpos(fp, &r_pos); |
||
160 | + fseek(fp, -len, SEEK_CUR); |
||
161 | + fgetpos(fp, &w_pos); |
||
162 | + fsetpos(fp, &r_pos); |
||
163 | + |
||
164 | + while (fgets(buf, sizeof(buf) - 1, fp)) { |
||
165 | + int cur_len = strlen(buf); |
||
166 | + |
||
167 | + fsetpos(fp, &w_pos); |
||
168 | + fputs(buf, fp); |
||
169 | + fgetpos(fp, &w_pos); |
||
170 | + |
||
171 | + fsetpos(fp, &r_pos); |
||
172 | + fseek(fp, cur_len, SEEK_CUR); |
||
173 | + fgetpos(fp, &r_pos); |
||
174 | + } |
||
175 | + |
||
176 | + fsetpos(fp, &w_pos); |
||
177 | + ftruncate(fileno(fp), ftello(fp)); |
||
178 | +} |
||
179 | + |
||
180 | +static int usage(const char *progname) |
||
181 | +{ |
||
182 | + fprintf(stderr, |
||
183 | + "Usage: %s [options] <username>\n" |
||
184 | + "\n" |
||
185 | + "Options:\n" |
||
186 | + " -s read password from stdin\n" |
||
187 | + " -a add user\n" |
||
188 | + " -x delete user\n", |
||
189 | + progname); |
||
190 | + return 1; |
||
191 | +} |
||
192 | + |
||
193 | +int main(int argc, char **argv) |
||
194 | +{ |
||
195 | + const char *prog = argv[0]; |
||
196 | + const char *user; |
||
197 | + char *pw1, *pw2; |
||
198 | + FILE *fp; |
||
199 | + bool add = false, delete = false, get_stdin = false, found; |
||
200 | + int ch; |
||
201 | + int uid; |
||
202 | + |
||
203 | + TALLOC_CTX *frame = talloc_stackframe(); |
||
204 | + |
||
205 | + while ((ch = getopt(argc, argv, "asx")) != EOF) { |
||
206 | + switch (ch) { |
||
207 | + case 's': |
||
208 | + get_stdin = true; |
||
209 | + break; |
||
210 | + case 'a': |
||
211 | + add = true; |
||
212 | + break; |
||
213 | + case 'x': |
||
214 | + delete = true; |
||
215 | + break; |
||
216 | + default: |
||
217 | + return usage(prog); |
||
218 | + } |
||
219 | + } |
||
220 | + |
||
221 | + if (add && delete) |
||
222 | + return usage(prog); |
||
223 | + |
||
224 | + argc -= optind; |
||
225 | + argv += optind; |
||
226 | + |
||
227 | + if (!argc) |
||
228 | + return usage(prog); |
||
229 | + |
||
230 | + user = argv[0]; |
||
231 | + if (!delete) { |
||
232 | + uid = find_uid_for_user(user); |
||
233 | + if (uid < 0) { |
||
234 | + fprintf(stderr, "Could not find user '%s' in /etc/passwd\n", user); |
||
235 | + return 2; |
||
236 | + } |
||
237 | + } |
||
238 | + |
||
239 | + fp = fopen("/etc/samba/smbpasswd", "r+"); |
||
240 | + if(!fp) { |
||
241 | + fprintf(stderr, "Failed to open /etc/samba/smbpasswd"); |
||
242 | + return 3; |
||
243 | + } |
||
244 | + |
||
245 | + found = find_passwd_line(fp, user, NULL); |
||
246 | + if (!add && !found) { |
||
247 | + fprintf(stderr, "Could not find user '%s' in /etc/samba/smbpasswd\n", user); |
||
248 | + return 3; |
||
249 | + } |
||
250 | + |
||
251 | + if (delete) { |
||
252 | + smbpasswd_delete_user(fp); |
||
253 | + goto out; |
||
254 | + } |
||
255 | + |
||
256 | + pw1 = get_pass("New SMB password:", get_stdin); |
||
257 | + if (!pw1) |
||
258 | + pw1 = strdup(""); |
||
259 | + |
||
260 | + pw2 = get_pass("Retype SMB password:", get_stdin); |
||
261 | + if (!pw2) |
||
262 | + pw2 = strdup(""); |
||
263 | + |
||
264 | + if (strcmp(pw1, pw2) != 0) { |
||
265 | + fprintf(stderr, "Mismatch - password unchanged.\n"); |
||
266 | + goto out_free; |
||
267 | + } |
||
268 | + |
||
269 | + if (found) |
||
270 | + fseek(fp, -strlen(buf), SEEK_CUR); |
||
271 | + smbpasswd_write_user(fp, user, uid, pw2); |
||
272 | + |
||
273 | +out_free: |
||
274 | + free(pw1); |
||
275 | + free(pw2); |
||
276 | +out: |
||
277 | + fclose(fp); |
||
278 | + TALLOC_FREE(frame); |
||
279 | + |
||
280 | + return 0; |
||
281 | +} |