Root/package/network/services/samba36/patches/111-owrt_smbpasswd.patch

1--- a/source3/Makefile.in
2+++ b/source3/Makefile.in
3@@ -1016,7 +1016,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@@ -1788,7 +1788,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@@ -1797,7 +1797,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,245 @@
33+/*
34+ * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
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");
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+ w_pos = r_pos;
161+ w_pos.__pos -= len;
162+
163+ while (fgets(buf, sizeof(buf) - 1, fp)) {
164+ int cur_len = strlen(buf);
165+
166+ fsetpos(fp, &w_pos);
167+ fputs(buf, fp);
168+ r_pos.__pos += cur_len;
169+ w_pos.__pos += cur_len;
170+ fsetpos(fp, &r_pos);
171+ }
172+
173+ ftruncate(fileno(fp), w_pos.__pos);
174+}
175+
176+static int usage(const char *progname)
177+{
178+ fprintf(stderr,
179+ "Usage: %s [options] <username>\n"
180+ "\n"
181+ "Options:\n"
182+ " -s read password from stdin\n"
183+ " -a add user\n"
184+ " -x delete user\n",
185+ progname);
186+ return 1;
187+}
188+
189+int main(int argc, char **argv)
190+{
191+ const char *prog = argv[0];
192+ const char *user;
193+ char *pw1, *pw2;
194+ FILE *fp;
195+ bool add = false, delete = false, get_stdin = false, found;
196+ int ch;
197+ int uid;
198+
199+ TALLOC_CTX *frame = talloc_stackframe();
200+
201+ while ((ch = getopt(argc, argv, "asx")) != EOF) {
202+ switch (ch) {
203+ case 's':
204+ get_stdin = true;
205+ break;
206+ case 'a':
207+ add = true;
208+ break;
209+ case 'x':
210+ delete = true;
211+ break;
212+ default:
213+ return usage(prog);
214+ }
215+ }
216+
217+ if (add && delete)
218+ return usage(prog);
219+
220+ argc -= optind;
221+ argv += optind;
222+
223+ if (!argc)
224+ return usage(prog);
225+
226+ user = argv[0];
227+ if (!delete) {
228+ uid = find_uid_for_user(user);
229+ if (uid < 0) {
230+ fprintf(stderr, "Could not find user '%s' in /etc/passwd\n", user);
231+ return 2;
232+ }
233+ }
234+
235+ fp = fopen("/etc/samba/smbpasswd", "r+");
236+ if(!fp) {
237+ fprintf(stderr, "Failed to open /etc/samba/smbpasswd");
238+ return 3;
239+ }
240+
241+ found = find_passwd_line(fp, user, NULL);
242+ if (!add && !found) {
243+ fprintf(stderr, "Could not find user '%s' in /etc/samba/smbpasswd\n", user);
244+ return 3;
245+ }
246+
247+ if (delete) {
248+ smbpasswd_delete_user(fp);
249+ goto out;
250+ }
251+
252+ pw1 = get_pass("New SMB password:", get_stdin);
253+ if (!pw1)
254+ pw1 = strdup("");
255+
256+ pw2 = get_pass("Retype SMB password:", get_stdin);
257+ if (!pw2)
258+ pw2 = strdup("");
259+
260+ if (strcmp(pw1, pw2) != 0) {
261+ fprintf(stderr, "Mismatch - password unchanged.\n");
262+ goto out_free;
263+ }
264+
265+ if (found)
266+ fseek(fp, -strlen(buf), SEEK_CUR);
267+ smbpasswd_write_user(fp, user, uid, pw2);
268+
269+out_free:
270+ free(pw1);
271+ free(pw2);
272+out:
273+ fclose(fp);
274+ TALLOC_FREE(frame);
275+
276+ return 0;
277+}
278

Archive Download this file



interactive