samba36: update to 3.6.11 and refresh patches (based on patch from #12914)
[openwrt.org/openwrt.git] / package / network / services / samba36 / patches / 111-owrt_smbpasswd.patch
blob:a/package/network/services/samba36/patches/111-owrt_smbpasswd.patch -> blob:b/package/network/services/samba36/patches/111-owrt_smbpasswd.patch
--- a/source3/Makefile.in --- a/source3/Makefile.in
+++ b/source3/Makefile.in +++ b/source3/Makefile.in
@@ -1017,7 +1017,7 @@ TEST_LP_LOAD_OBJ = param/test_lp_load.o @@ -1025,7 +1025,7 @@ TEST_LP_LOAD_OBJ = param/test_lp_load.o
PASSWD_UTIL_OBJ = utils/passwd_util.o PASSWD_UTIL_OBJ = utils/passwd_util.o
-SMBPASSWD_OBJ = utils/smbpasswd.o $(PASSWD_UTIL_OBJ) $(PASSCHANGE_OBJ) \ -SMBPASSWD_OBJ = utils/smbpasswd.o $(PASSWD_UTIL_OBJ) $(PASSCHANGE_OBJ) \
+SMBPASSWD_OBJ = utils/owrt_smbpasswd.o $(PASSWD_UTIL_OBJ) $(PASSCHANGE_OBJ) \ +SMBPASSWD_OBJ = utils/owrt_smbpasswd.o $(PASSWD_UTIL_OBJ) $(PASSCHANGE_OBJ) \
$(PARAM_OBJ) $(LIBSMB_OBJ) $(PASSDB_OBJ) \ $(PARAM_OBJ) $(LIBSMB_OBJ) $(PASSDB_OBJ) \
$(GROUPDB_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \ $(GROUPDB_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \
$(POPT_LIB_OBJ) $(SMBLDAP_OBJ) \ $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) \
@@ -1789,7 +1789,7 @@ nmbd/nmbd_multicall.o: nmbd/nmbd.c nmbd/ @@ -1813,7 +1813,7 @@ nmbd/nmbd_multicall.o: nmbd/nmbd.c nmbd/
echo "$(COMPILE_CC_PATH)" 1>&2;\ echo "$(COMPILE_CC_PATH)" 1>&2;\
$(COMPILE_CC_PATH) >/dev/null 2>&1 $(COMPILE_CC_PATH) >/dev/null 2>&1
-utils/smbpasswd_multicall.o: utils/smbpasswd.c utils/smbpasswd.o -utils/smbpasswd_multicall.o: utils/smbpasswd.c utils/smbpasswd.o
+utils/smbpasswd_multicall.o: utils/owrt_smbpasswd.c utils/owrt_smbpasswd.o +utils/smbpasswd_multicall.o: utils/owrt_smbpasswd.c utils/owrt_smbpasswd.o
@echo Compiling $<.c @echo Compiling $<.c
@$(COMPILE_CC_PATH) -Dmain=smbpasswd_main && exit 0;\ @$(COMPILE_CC_PATH) -Dmain=smbpasswd_main && exit 0;\
echo "The following command failed:" 1>&2;\ echo "The following command failed:" 1>&2;\
@@ -1798,7 +1798,7 @@ utils/smbpasswd_multicall.o: utils/smbpa @@ -1822,7 +1822,7 @@ utils/smbpasswd_multicall.o: utils/smbpa
SMBD_MULTI_O = $(patsubst smbd/server.o,smbd/server_multicall.o,$(SMBD_OBJ)) SMBD_MULTI_O = $(patsubst smbd/server.o,smbd/server_multicall.o,$(SMBD_OBJ))
NMBD_MULTI_O = $(patsubst nmbd/nmbd.o,nmbd/nmbd_multicall.o,$(filter-out $(LIB_DUMMY_OBJ),$(NMBD_OBJ))) NMBD_MULTI_O = $(patsubst nmbd/nmbd.o,nmbd/nmbd_multicall.o,$(filter-out $(LIB_DUMMY_OBJ),$(NMBD_OBJ)))
-SMBPASSWD_MULTI_O = $(patsubst utils/smbpasswd.o,utils/smbpasswd_multicall.o,$(filter-out $(LIB_DUMMY_OBJ),$(SMBPASSWD_OBJ))) -SMBPASSWD_MULTI_O = $(patsubst utils/smbpasswd.o,utils/smbpasswd_multicall.o,$(filter-out $(LIB_DUMMY_OBJ),$(SMBPASSWD_OBJ)))
+SMBPASSWD_MULTI_O = $(patsubst utils/owrt_smbpasswd.o,utils/smbpasswd_multicall.o,$(filter-out $(LIB_DUMMY_OBJ),$(SMBPASSWD_OBJ))) +SMBPASSWD_MULTI_O = $(patsubst utils/owrt_smbpasswd.o,utils/smbpasswd_multicall.o,$(filter-out $(LIB_DUMMY_OBJ),$(SMBPASSWD_OBJ)))
MULTI_O = multi.o MULTI_O = multi.o
MULTICALL_O = $(sort $(SMBD_MULTI_O) $(NMBD_MULTI_O) $(SMBPASSWD_MULTI_O) $(MULTI_O)) MULTICALL_O = $(sort $(SMBD_MULTI_O) $(NMBD_MULTI_O) $(SMBPASSWD_MULTI_O) $(MULTI_O))
--- /dev/null --- /dev/null
+++ b/source3/utils/owrt_smbpasswd.c +++ b/source3/utils/owrt_smbpasswd.c
@@ -0,0 +1,245 @@ @@ -0,0 +1,249 @@
+/* +/*
+ * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org> + * Copyright (C) 2012 Felix Fietkau <nbd@nbd.name>
+ * Copyright (C) 2008 John Crispin <blogic@openwrt.org> + * Copyright (C) 2008 John Crispin <blogic@openwrt.org>
+ * + *
+ * This program is free software; you can redistribute it and/or modify it + * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the + * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your + * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. + * option) any later version.
+ * + *
+ * This program is distributed in the hope that it will be useful, but WITHOUT + * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details. + * more details.
+ * + *
+ * You should have received a copy of the GNU General Public License along with + * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675 + * this program; if not, write to the Free Software Foundation, Inc., 675
+ * Mass Ave, Cambridge, MA 02139, USA. */ + * Mass Ave, Cambridge, MA 02139, USA. */
+ +
+#include "includes.h" +#include "includes.h"
+#include <endian.h> +#include <endian.h>
+#include <stdio.h> +#include <stdio.h>
+ +
+static char buf[256]; +static char buf[256];
+ +
+static void md4hash(const char *passwd, uchar p16[16]) +static void md4hash(const char *passwd, uchar p16[16])
+{ +{
+ int len; + int len;
+ smb_ucs2_t wpwd[129]; + smb_ucs2_t wpwd[129];
+ int i; + int i;
+ +
+ len = strlen(passwd); + len = strlen(passwd);
+ for (i = 0; i < len; i++) { + for (i = 0; i < len; i++) {
+#if __BYTE_ORDER == __LITTLE_ENDIAN +#if __BYTE_ORDER == __LITTLE_ENDIAN
+ wpwd[i] = (unsigned char)passwd[i]; + wpwd[i] = (unsigned char)passwd[i];
+#else +#else
+ wpwd[i] = (unsigned char)passwd[i] << 8; + wpwd[i] = (unsigned char)passwd[i] << 8;
+#endif +#endif
+ } + }
+ wpwd[i] = 0; + wpwd[i] = 0;
+ +
+ len = len * sizeof(int16); + len = len * sizeof(int16);
+ mdfour(p16, (unsigned char *)wpwd, len); + mdfour(p16, (unsigned char *)wpwd, len);
+ ZERO_STRUCT(wpwd); + ZERO_STRUCT(wpwd);
+} +}
+ +
+ +
+static bool find_passwd_line(FILE *fp, const char *user, char **next) +static bool find_passwd_line(FILE *fp, const char *user, char **next)
+{ +{
+ char *p1; + char *p1;
+ +
+ while (!feof(fp)) { + while (!feof(fp)) {
+ if(!fgets(buf, sizeof(buf) - 1, fp)) + if(!fgets(buf, sizeof(buf) - 1, fp))
+ continue; + continue;
+ +
+ p1 = strchr(buf, ':'); + p1 = strchr(buf, ':');
+ +
+ if (p1 - buf != strlen(user)) + if (p1 - buf != strlen(user))
+ continue; + continue;
+ +
+ if (strncmp(buf, user, p1 - buf) != 0) + if (strncmp(buf, user, p1 - buf) != 0)
+ continue; + continue;
+ +
+ if (next) + if (next)
+ *next = p1; + *next = p1;
+ return true; + return true;
+ } + }
+ return false; + return false;
+} +}
+ +
+/* returns -1 if user is not present in /etc/passwd*/ +/* returns -1 if user is not present in /etc/passwd*/
+static int find_uid_for_user(const char *user) +static int find_uid_for_user(const char *user)
+{ +{
+ FILE *fp; + FILE *fp;
+ char *p1, *p2, *p3; + char *p1, *p2, *p3;
+ int ret = -1; + int ret = -1;
+ +
+ fp = fopen("/etc/passwd", "r"); + fp = fopen("/etc/passwd", "r");
+ if (!fp) { + if (!fp) {
+ printf("failed to open /etc/passwd"); + printf("failed to open /etc/passwd");
+ goto out; + goto out;
+ } + }
+ +
+ if (!find_passwd_line(fp, user, &p1)) { + if (!find_passwd_line(fp, user, &p1)) {
+ printf("User %s not found or invalid in /etc/passwd\n"); + printf("User %s not found or invalid in /etc/passwd\n", user);
+ goto out; + goto out;
+ } + }
+ +
+ p2 = strchr(p1 + 1, ':'); + p2 = strchr(p1 + 1, ':');
+ if (!p2) + if (!p2)
+ goto out; + goto out;
+ +
+ p2++; + p2++;
+ p3 = strchr(p2, ':'); + p3 = strchr(p2, ':');
+ if (!p1) + if (!p1)
+ goto out; + goto out;
+ +
+ *p3 = '\0'; + *p3 = '\0';
+ ret = atoi(p2); + ret = atoi(p2);
+ +
+out: +out:
+ if(fp) + if(fp)
+ fclose(fp); + fclose(fp);
+ return ret; + return ret;
+} +}
+ +
+static void smbpasswd_write_user(FILE *fp, const char *user, int uid, const char *password) +static void smbpasswd_write_user(FILE *fp, const char *user, int uid, const char *password)
+{ +{
+ static uchar nt_p16[NT_HASH_LEN]; + static uchar nt_p16[NT_HASH_LEN];
+ int len = 0; + int len = 0;
+ int i; + int i;
+ +
+ md4hash(strdup(password), nt_p16); + md4hash(strdup(password), nt_p16);
+ +
+ len += snprintf(buf + len, sizeof(buf) - len, "%s:%u:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:", user, uid); + len += snprintf(buf + len, sizeof(buf) - len, "%s:%u:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:", user, uid);
+ for(i = 0; i < NT_HASH_LEN; i++) + for(i = 0; i < NT_HASH_LEN; i++)
+ len += snprintf(buf + len, sizeof(buf) - len, "%02X", nt_p16[i]); + len += snprintf(buf + len, sizeof(buf) - len, "%02X", nt_p16[i]);
+ +
+ snprintf(buf + len, sizeof(buf) - len, ":[U ]:LCT-00000001:\n"); + snprintf(buf + len, sizeof(buf) - len, ":[U ]:LCT-00000001:\n");
+ fputs(buf, fp); + fputs(buf, fp);
+} +}
+ +
+static void smbpasswd_delete_user(FILE *fp) +static void smbpasswd_delete_user(FILE *fp)
+{ +{
+ fpos_t r_pos, w_pos; + fpos_t r_pos, w_pos;
+ int len = strlen(buf); + int len = strlen(buf);
+ +
+ fgetpos(fp, &r_pos); + fgetpos(fp, &r_pos);
+ w_pos = r_pos; + fseek(fp, -len, SEEK_CUR);
+ w_pos.__pos -= len; + fgetpos(fp, &w_pos);
  + fsetpos(fp, &r_pos);
+ +
+ while (fgets(buf, sizeof(buf) - 1, fp)) { + while (fgets(buf, sizeof(buf) - 1, fp)) {
+ int cur_len = strlen(buf); + int cur_len = strlen(buf);
+ +
+ fsetpos(fp, &w_pos); + fsetpos(fp, &w_pos);
+ fputs(buf, fp); + fputs(buf, fp);
+ r_pos.__pos += cur_len; + fgetpos(fp, &w_pos);
+ w_pos.__pos += cur_len; +
+ fsetpos(fp, &r_pos); + fsetpos(fp, &r_pos);
+ } + fseek(fp, cur_len, SEEK_CUR);
+ + fgetpos(fp, &r_pos);
+ ftruncate(fileno(fp), w_pos.__pos); + }
  +
  + fsetpos(fp, &w_pos);
  + ftruncate(fileno(fp), ftello(fp));
+} +}
+ +
+static int usage(const char *progname) +static int usage(const char *progname)
+{ +{
+ fprintf(stderr, + fprintf(stderr,
+ "Usage: %s [options] <username>\n" + "Usage: %s [options] <username>\n"
+ "\n" + "\n"
+ "Options:\n" + "Options:\n"
+ " -s read password from stdin\n" + " -s read password from stdin\n"
+ " -a add user\n" + " -a add user\n"
+ " -x delete user\n", + " -x delete user\n",
+ progname); + progname);
+ return 1; + return 1;
+} +}
+ +
+int main(int argc, char **argv) +int main(int argc, char **argv)
+{ +{
+ const char *prog = argv[0]; + const char *prog = argv[0];
+ const char *user; + const char *user;
+ char *pw1, *pw2; + char *pw1, *pw2;
+ FILE *fp; + FILE *fp;
+ bool add = false, delete = false, get_stdin = false, found; + bool add = false, delete = false, get_stdin = false, found;
+ int ch; + int ch;
+ int uid; + int uid;
+ +
+ TALLOC_CTX *frame = talloc_stackframe(); + TALLOC_CTX *frame = talloc_stackframe();
+ +
+ while ((ch = getopt(argc, argv, "asx")) != EOF) { + while ((ch = getopt(argc, argv, "asx")) != EOF) {
+ switch (ch) { + switch (ch) {
+ case 's': + case 's':
+ get_stdin = true; + get_stdin = true;
+ break; + break;
+ case 'a': + case 'a':
+ add = true; + add = true;
+ break; + break;
+ case 'x': + case 'x':
+ delete = true; + delete = true;
+ break; + break;
+ default: + default:
+ return usage(prog); + return usage(prog);
+ } + }
+ } + }
+ +
+ if (add && delete) + if (add && delete)
+ return usage(prog); + return usage(prog);
+ +
+ argc -= optind; + argc -= optind;
+ argv += optind; + argv += optind;
+ +
+ if (!argc) + if (!argc)
+ return usage(prog); + return usage(prog);
+ +
+ user = argv[0]; + user = argv[0];
+ if (!delete) { + if (!delete) {
+ uid = find_uid_for_user(user); + uid = find_uid_for_user(user);
+ if (uid < 0) { + if (uid < 0) {
+ fprintf(stderr, "Could not find user '%s' in /etc/passwd\n", user); + fprintf(stderr, "Could not find user '%s' in /etc/passwd\n", user);
+ return 2; + return 2;
+ } + }
+ } + }
+ +
+ fp = fopen("/etc/samba/smbpasswd", "r+"); + fp = fopen("/etc/samba/smbpasswd", "r+");
+ if(!fp) { + if(!fp) {
+ fprintf(stderr, "Failed to open /etc/samba/smbpasswd"); + fprintf(stderr, "Failed to open /etc/samba/smbpasswd");
+ return 3; + return 3;
+ } + }
+ +
+ found = find_passwd_line(fp, user, NULL); + found = find_passwd_line(fp, user, NULL);
+ if (!add && !found) { + if (!add && !found) {
+ fprintf(stderr, "Could not find user '%s' in /etc/samba/smbpasswd\n", user); + fprintf(stderr, "Could not find user '%s' in /etc/samba/smbpasswd\n", user);
+ return 3; + return 3;
+ } + }
+ +
+ if (delete) { + if (delete) {
+ smbpasswd_delete_user(fp); + smbpasswd_delete_user(fp);
+ goto out; + goto out;
+ } + }
+ +
+ pw1 = get_pass("New SMB password:", get_stdin); + pw1 = get_pass("New SMB password:", get_stdin);
+ if (!pw1) + if (!pw1)
+ pw1 = strdup(""); + pw1 = strdup("");
+ +
+ pw2 = get_pass("Retype SMB password:", get_stdin); + pw2 = get_pass("Retype SMB password:", get_stdin);
+ if (!pw2) + if (!pw2)
+ pw2 = strdup(""); + pw2 = strdup("");
+ +
+ if (strcmp(pw1, pw2) != 0) { + if (strcmp(pw1, pw2) != 0) {
+ fprintf(stderr, "Mismatch - password unchanged.\n"); + fprintf(stderr, "Mismatch - password unchanged.\n");
+ goto out_free; + goto out_free;
+ } + }
+ +
+ if (found) + if (found)
+ fseek(fp, -strlen(buf), SEEK_CUR); + fseek(fp, -strlen(buf), SEEK_CUR);
+ smbpasswd_write_user(fp, user, uid, pw2); + smbpasswd_write_user(fp, user, uid, pw2);
+ +
+out_free: +out_free:
+ free(pw1); + free(pw1);
+ free(pw2); + free(pw2);
+out: +out:
+ fclose(fp); + fclose(fp);
+ TALLOC_FREE(frame); + TALLOC_FREE(frame);
+ +
+ return 0; + return 0;
+} +}
   
comments