samba36: integrate a cleanup/rewrite of the smbpasswd utility from samba 3.0
git-svn-id: svn://svn.openwrt.org/openwrt/packages@30517 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
parent
ad0fe50267
commit
8fdba4d336
277
net/samba36/patches/111-owrt_smbpasswd.patch
Normal file
277
net/samba36/patches/111-owrt_smbpasswd.patch
Normal file
@ -0,0 +1,277 @@
|
||||
--- a/source3/Makefile.in
|
||||
+++ b/source3/Makefile.in
|
||||
@@ -1016,7 +1016,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) \
|
||||
@@ -1788,7 +1788,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;\
|
||||
@@ -1797,7 +1797,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,245 @@
|
||||
+/*
|
||||
+ * 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");
|
||||
+ 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);
|
||||
+ w_pos = r_pos;
|
||||
+ w_pos.__pos -= len;
|
||||
+
|
||||
+ while (fgets(buf, sizeof(buf) - 1, fp)) {
|
||||
+ int cur_len = strlen(buf);
|
||||
+
|
||||
+ fsetpos(fp, &w_pos);
|
||||
+ fputs(buf, fp);
|
||||
+ r_pos.__pos += cur_len;
|
||||
+ w_pos.__pos += cur_len;
|
||||
+ fsetpos(fp, &r_pos);
|
||||
+ }
|
||||
+
|
||||
+ ftruncate(fileno(fp), w_pos.__pos);
|
||||
+}
|
||||
+
|
||||
+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;
|
||||
+}
|
Loading…
x
Reference in New Issue
Block a user