1 --- a/source3/Makefile.in
2 +++ b/source3/Makefile.in
3 @@ -1017,7 +1017,7 @@ TEST_LP_LOAD_OBJ = param/test_lp_load.o
5 PASSWD_UTIL_OBJ = utils/passwd_util.o
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 @@ -1789,7 +1789,7 @@ nmbd/nmbd_multicall.o: nmbd/nmbd.c nmbd/
13 echo "$(COMPILE_CC_PATH)" 1>&2;\
14 $(COMPILE_CC_PATH) >/dev/null 2>&1
16 -utils/smbpasswd_multicall.o: utils/smbpasswd.c utils/smbpasswd.o
17 +utils/smbpasswd_multicall.o: utils/owrt_smbpasswd.c utils/owrt_smbpasswd.o
19 @$(COMPILE_CC_PATH) -Dmain=smbpasswd_main && exit 0;\
20 echo "The following command failed:" 1>&2;\
21 @@ -1798,7 +1798,7 @@ utils/smbpasswd_multicall.o: utils/smbpa
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)))
29 MULTICALL_O = $(sort $(SMBD_MULTI_O) $(NMBD_MULTI_O) $(SMBPASSWD_MULTI_O) $(MULTI_O))
31 +++ b/source3/utils/owrt_smbpasswd.c
34 + * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
35 + * Copyright (C) 2008 John Crispin <blogic@openwrt.org>
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.
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
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. */
51 +#include "includes.h"
55 +static char buf[256];
57 +static void md4hash(const char *passwd, uchar p16[16])
60 + smb_ucs2_t wpwd[129];
63 + len = strlen(passwd);
64 + for (i = 0; i < len; i++) {
65 +#if __BYTE_ORDER == __LITTLE_ENDIAN
66 + wpwd[i] = (unsigned char)passwd[i];
68 + wpwd[i] = (unsigned char)passwd[i] << 8;
73 + len = len * sizeof(int16);
74 + mdfour(p16, (unsigned char *)wpwd, len);
79 +static bool find_passwd_line(FILE *fp, const char *user, char **next)
84 + if(!fgets(buf, sizeof(buf) - 1, fp))
87 + p1 = strchr(buf, ':');
89 + if (p1 - buf != strlen(user))
92 + if (strncmp(buf, user, p1 - buf) != 0)
102 +/* returns -1 if user is not present in /etc/passwd*/
103 +static int find_uid_for_user(const char *user)
106 + char *p1, *p2, *p3;
109 + fp = fopen("/etc/passwd", "r");
111 + printf("failed to open /etc/passwd");
115 + if (!find_passwd_line(fp, user, &p1)) {
116 + printf("User %s not found or invalid in /etc/passwd\n", user);
120 + p2 = strchr(p1 + 1, ':');
125 + p3 = strchr(p2, ':');
138 +static void smbpasswd_write_user(FILE *fp, const char *user, int uid, const char *password)
140 + static uchar nt_p16[NT_HASH_LEN];
144 + md4hash(strdup(password), nt_p16);
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]);
150 + snprintf(buf + len, sizeof(buf) - len, ":[U ]:LCT-00000001:\n");
154 +static void smbpasswd_delete_user(FILE *fp)
156 + fpos_t r_pos, w_pos;
157 + int len = strlen(buf);
159 + fgetpos(fp, &r_pos);
161 + w_pos.__pos -= len;
163 + while (fgets(buf, sizeof(buf) - 1, fp)) {
164 + int cur_len = strlen(buf);
166 + fsetpos(fp, &w_pos);
168 + r_pos.__pos += cur_len;
169 + w_pos.__pos += cur_len;
170 + fsetpos(fp, &r_pos);
173 + ftruncate(fileno(fp), w_pos.__pos);
176 +static int usage(const char *progname)
179 + "Usage: %s [options] <username>\n"
182 + " -s read password from stdin\n"
184 + " -x delete user\n",
189 +int main(int argc, char **argv)
191 + const char *prog = argv[0];
195 + bool add = false, delete = false, get_stdin = false, found;
199 + TALLOC_CTX *frame = talloc_stackframe();
201 + while ((ch = getopt(argc, argv, "asx")) != EOF) {
213 + return usage(prog);
218 + return usage(prog);
224 + return usage(prog);
228 + uid = find_uid_for_user(user);
230 + fprintf(stderr, "Could not find user '%s' in /etc/passwd\n", user);
235 + fp = fopen("/etc/samba/smbpasswd", "r+");
237 + fprintf(stderr, "Failed to open /etc/samba/smbpasswd");
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);
248 + smbpasswd_delete_user(fp);
252 + pw1 = get_pass("New SMB password:", get_stdin);
256 + pw2 = get_pass("Retype SMB password:", get_stdin);
260 + if (strcmp(pw1, pw2) != 0) {
261 + fprintf(stderr, "Mismatch - password unchanged.\n");
266 + fseek(fp, -strlen(buf), SEEK_CUR);
267 + smbpasswd_write_user(fp, user, uid, pw2);
274 + TALLOC_FREE(frame);