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