summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-05-02 14:17:19 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:16:27 -0500
commit8bf57cf8f57be28831023c2218d358b24b705256 (patch)
treee18e07afa72a46e9c6c94b8faf1ee21650b2cc20
parent591ff7675dfe51f30029cb864df47bc8f6266494 (diff)
downloadsamba-8bf57cf8f57be28831023c2218d358b24b705256.tar.gz
samba-8bf57cf8f57be28831023c2218d358b24b705256.tar.bz2
samba-8bf57cf8f57be28831023c2218d358b24b705256.zip
r6573: Start on my project to implement an NT4 compatible BDC in Samba4.
This brings in a compatability layer for Samba3 in Samba4 - where we will start to define file formats and similar details. The 'net samdump' command uses 'password server = ' for now, and performs a similar task to Samba3's 'net rpc samsync'. Andrew Bartlett (This used to be commit 550f17f9924fe783917318753de7d1a388423908)
-rw-r--r--source4/include/structs.h3
-rw-r--r--source4/lib/basic.mk9
-rw-r--r--source4/lib/credentials.c3
-rw-r--r--source4/lib/samba3/README5
-rw-r--r--source4/lib/samba3/smbpasswd.c208
-rw-r--r--source4/lib/util_str.c1
-rw-r--r--source4/libnet/config.mk3
-rw-r--r--source4/libnet/libnet.h1
-rw-r--r--source4/libnet/libnet_vampire.c225
-rw-r--r--source4/libnet/libnet_vampire.h40
-rw-r--r--source4/passdb/secrets.c11
-rw-r--r--source4/utils/net/config.mk1
-rw-r--r--source4/utils/net/net.c1
-rw-r--r--source4/utils/net/net_vampire.c68
14 files changed, 577 insertions, 2 deletions
diff --git a/source4/include/structs.h b/source4/include/structs.h
index 4e29ef8d50..c1998ee991 100644
--- a/source4/include/structs.h
+++ b/source4/include/structs.h
@@ -201,3 +201,6 @@ struct wrepl_pull_table;
struct wrepl_pull_names;
struct arcfour_state;
+
+union libnet_SamDump;
+
diff --git a/source4/lib/basic.mk b/source4/lib/basic.mk
index f0b2b05b6a..c1a34d39bb 100644
--- a/source4/lib/basic.mk
+++ b/source4/lib/basic.mk
@@ -40,6 +40,15 @@ INIT_OBJ_FILES = \
# End SUBSYSTEM LIBCOMPRESION
################################################
+
+################################################
+# Start SUBSYSTEM LIBSAMBA3
+[SUBSYSTEM::LIBSAMBA3]
+INIT_OBJ_FILES = \
+ lib/samba3/smbpasswd.o
+# End SUBSYSTEM LIBSAMBA3
+################################################
+
##############################
# Start SUBSYSTEM LIBBASIC
[SUBSYSTEM::LIBBASIC]
diff --git a/source4/lib/credentials.c b/source4/lib/credentials.c
index 64e3b9958d..7e25fc780b 100644
--- a/source4/lib/credentials.c
+++ b/source4/lib/credentials.c
@@ -458,6 +458,7 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
"samAccountName",
"flatname",
"realm",
+ "secureChannelType",
NULL
};
@@ -512,7 +513,7 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
}
sct = ldb_msg_find_int(msgs[0], "secureChannelType", 0);
- if (!sct) {
+ if (sct) {
cli_credentials_set_secure_channel_type(cred, sct);
} else {
DEBUG(1, ("Domain join for acocunt %s did not have a secureChannelType set!\n",
diff --git a/source4/lib/samba3/README b/source4/lib/samba3/README
new file mode 100644
index 0000000000..cf55be047a
--- /dev/null
+++ b/source4/lib/samba3/README
@@ -0,0 +1,5 @@
+This directory contains various files and functions for the purpose of
+Samba3 import, migration and compatability.
+
+For example, the first file in this directory (smbpasswd.c) handles
+portions of the smbpasswd file format.
diff --git a/source4/lib/samba3/smbpasswd.c b/source4/lib/samba3/smbpasswd.c
new file mode 100644
index 0000000000..587d038a3d
--- /dev/null
+++ b/source4/lib/samba3/smbpasswd.c
@@ -0,0 +1,208 @@
+/*
+ Unix SMB/CIFS implementation.
+ smbpasswd file format routines
+
+ Copyright (C) Andrew Tridgell 1992-1998
+ Modified by Jeremy Allison 1995.
+ Modified by Gerald (Jerry) Carter 2000-2001
+ Copyright (C) Tim Potter 2001
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
+
+ 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.
+*/
+
+/*! \file lib/smbpasswd.c
+
+ The smbpasswd file is used to store encrypted passwords in a similar
+ fashion to the /etc/passwd file. The format is colon separated fields
+ with one user per line like so:
+
+ <username>:<uid>:<lanman hash>:<nt hash>:<acb info>:<last change time>
+
+ The username and uid must correspond to an entry in the /etc/passwd
+ file. The lanman and nt password hashes are 32 hex digits corresponding
+ to the 16-byte lanman and nt hashes respectively.
+
+ The password last change time is stored as a string of the format
+ LCD-<change time> where the change time is expressed as an
+
+ 'N' No password
+ 'D' Disabled
+ 'H' Homedir required
+ 'T' Temp account.
+ 'U' User account (normal)
+ 'M' MNS logon user account - what is this ?
+ 'W' Workstation account
+ 'S' Server account
+ 'L' Locked account
+ 'X' No Xpiry on password
+ 'I' Interdomain trust account
+
+*/
+
+#include "includes.h"
+#include "librpc/gen_ndr/ndr_samr.h"
+#include "system/iconv.h"
+
+/*! Convert 32 hex characters into a 16 byte array. */
+
+struct samr_Password *smbpasswd_gethexpwd(TALLOC_CTX *mem_ctx, char *p)
+{
+ int i;
+ unsigned char lonybble, hinybble;
+ const char *hexchars = "0123456789ABCDEF";
+ char *p1, *p2;
+ struct samr_Password *pwd = talloc(mem_ctx, struct samr_Password);
+
+ if (!p) return NULL;
+
+ for (i = 0; i < (sizeof(pwd->hash) * 2); i += 2)
+ {
+ hinybble = toupper(p[i]);
+ lonybble = toupper(p[i + 1]);
+
+ p1 = strchr_m(hexchars, hinybble);
+ p2 = strchr_m(hexchars, lonybble);
+
+ if (!p1 || !p2)
+ {
+ return (False);
+ }
+
+ hinybble = PTR_DIFF(p1, hexchars);
+ lonybble = PTR_DIFF(p2, hexchars);
+
+ pwd->hash[i / 2] = (hinybble << 4) | lonybble;
+ }
+ return pwd;
+}
+
+/*! Convert a 16-byte array into 32 hex characters. */
+ struct samr_Password *lm_hash_p = NULL;
+ struct samr_Password *nt_hash_p = NULL;
+
+char *smbpasswd_sethexpwd(TALLOC_CTX *mem_ctx, struct samr_Password *pwd, uint16_t acb_info)
+{
+ char *p;
+ if (pwd != NULL) {
+ int i;
+ p = talloc_array(mem_ctx, char, 33);
+ if (!p) {
+ return NULL;
+ }
+
+ for (i = 0; i < sizeof(pwd->hash); i++)
+ slprintf(&p[i*2], 3, "%02X", pwd->hash[i]);
+ } else {
+ if (acb_info & ACB_PWNOTREQ)
+ p = talloc_strdup(mem_ctx, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
+ else
+ p = talloc_strdup(mem_ctx, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+ }
+ return p;
+}
+
+/*! Decode the account control bits (ACB) info from a string. */
+
+uint16_t smbpasswd_decode_acb_info(const char *p)
+{
+ uint16_t acb_info = 0;
+ BOOL finished = False;
+
+ /*
+ * Check if the account type bits have been encoded after the
+ * NT password (in the form [NDHTUWSLXI]).
+ */
+
+ if (*p != '[') return 0;
+
+ for (p++; *p && !finished; p++)
+ {
+ switch (*p) {
+ case 'N': /* 'N'o password. */
+ acb_info |= ACB_PWNOTREQ;
+ break;
+ case 'D': /* 'D'isabled. */
+ acb_info |= ACB_DISABLED;
+ break;
+ case 'H': /* 'H'omedir required. */
+ acb_info |= ACB_HOMDIRREQ;
+ break;
+ case 'T': /* 'T'emp account. */
+ acb_info |= ACB_TEMPDUP;
+ break;
+ case 'U': /* 'U'ser account (normal). */
+ acb_info |= ACB_NORMAL;
+ break;
+ case 'M': /* 'M'NS logon user account. What is this ? */
+ acb_info |= ACB_MNS;
+ break;
+ case 'W': /* 'W'orkstation account. */
+ acb_info |= ACB_WSTRUST;
+ break;
+ case 'S': /* 'S'erver account. */
+ acb_info |= ACB_SVRTRUST;
+ break;
+ case 'L': /* 'L'ocked account. */
+ acb_info |= ACB_AUTOLOCK;
+ break;
+ case 'X': /* No 'X'piry on password */
+ acb_info |= ACB_PWNOEXP;
+ break;
+ case 'I': /* 'I'nterdomain trust account. */
+ acb_info |= ACB_DOMTRUST;
+ break;
+
+ case ' ':
+ break;
+ case ':':
+ case '\n':
+ case '\0':
+ case ']':
+ default:
+ finished = True;
+ break;
+ }
+ }
+
+ return acb_info;
+}
+
+/*! Encode account control bits (ACBs) into a string. */
+
+char *smbpasswd_encode_acb_info(TALLOC_CTX *mem_ctx, uint16_t acb_info)
+{
+ char *acct_str = talloc_array(mem_ctx, char, 35);
+ size_t i = 0;
+
+ acct_str[i++] = '[';
+
+ if (acb_info & ACB_PWNOTREQ ) acct_str[i++] = 'N';
+ if (acb_info & ACB_DISABLED ) acct_str[i++] = 'D';
+ if (acb_info & ACB_HOMDIRREQ) acct_str[i++] = 'H';
+ if (acb_info & ACB_TEMPDUP ) acct_str[i++] = 'T';
+ if (acb_info & ACB_NORMAL ) acct_str[i++] = 'U';
+ if (acb_info & ACB_MNS ) acct_str[i++] = 'M';
+ if (acb_info & ACB_WSTRUST ) acct_str[i++] = 'W';
+ if (acb_info & ACB_SVRTRUST ) acct_str[i++] = 'S';
+ if (acb_info & ACB_AUTOLOCK ) acct_str[i++] = 'L';
+ if (acb_info & ACB_PWNOEXP ) acct_str[i++] = 'X';
+ if (acb_info & ACB_DOMTRUST ) acct_str[i++] = 'I';
+
+ acct_str[i++] = ']';
+ acct_str[i++] = '\0';
+
+ return acct_str;
+}
diff --git a/source4/lib/util_str.c b/source4/lib/util_str.c
index dc39da50c7..5d12a01f6e 100644
--- a/source4/lib/util_str.c
+++ b/source4/lib/util_str.c
@@ -395,6 +395,7 @@ char *StrnCpy(char *dest,const char *src,size_t n)
valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
+
**/
size_t strhex_to_str(char *p, size_t len, const char *strhex)
{
diff --git a/source4/libnet/config.mk b/source4/libnet/config.mk
index 008dc7ea8b..3d3c4430cf 100644
--- a/source4/libnet/config.mk
+++ b/source4/libnet/config.mk
@@ -8,9 +8,10 @@ ADD_OBJ_FILES = \
libnet/libnet_time.o \
libnet/libnet_rpc.o \
libnet/libnet_join.o \
+ libnet/libnet_vampire.o \
libnet/libnet_user.o \
libnet/userinfo.o \
libnet/userman.o
-REQUIRED_SUBSYSTEMS = RPC_NDR_SAMR RPC_NDR_SRVSVC LIBCLI_COMPOSITE
+REQUIRED_SUBSYSTEMS = RPC_NDR_SAMR RPC_NDR_SRVSVC LIBCLI_COMPOSITE LIBSAMBA3
# End SUBSYSTEM LIBNET
#################################
diff --git a/source4/libnet/libnet.h b/source4/libnet/libnet.h
index 5fb825df4d..bfe843952c 100644
--- a/source4/libnet/libnet.h
+++ b/source4/libnet/libnet.h
@@ -32,4 +32,5 @@ struct libnet_context {
#include "libnet/libnet_time.h"
#include "libnet/libnet_rpc.h"
#include "libnet/libnet_join.h"
+#include "libnet/libnet_vampire.h"
#include "libnet/libnet_user.h"
diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c
new file mode 100644
index 0000000000..daf7bdfaed
--- /dev/null
+++ b/source4/libnet/libnet_vampire.c
@@ -0,0 +1,225 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
+
+ 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 "libnet/libnet.h"
+#include "librpc/gen_ndr/ndr_netlogon.h"
+#include "librpc/gen_ndr/ndr_samr.h"
+
+static BOOL vampire_samdump_handle_user(TALLOC_CTX *mem_ctx,
+ struct creds_CredentialState *creds,
+ struct netr_DELTA_ENUM *delta)
+{
+ uint32_t rid = delta->delta_id_union.rid;
+ struct netr_DELTA_USER *user = delta->delta_union.user;
+ struct samr_Password lm_hash;
+ struct samr_Password nt_hash;
+ struct samr_Password *lm_hash_p = NULL;
+ struct samr_Password *nt_hash_p = NULL;
+ const char *username = user->account_name.string;
+ char *hex_lm_password;
+ char *hex_nt_password;
+
+ NTSTATUS nt_status;
+
+ if (user->lm_password_present) {
+ sam_rid_crypt(rid, user->lmpassword.hash, lm_hash.hash, 0);
+ lm_hash_p = &lm_hash;
+ }
+ if (user->nt_password_present) {
+ sam_rid_crypt(rid, user->ntpassword.hash, nt_hash.hash, 0);
+ nt_hash_p = &nt_hash;
+ }
+
+ if (user->user_private_info.SensitiveData) {
+ DATA_BLOB data;
+ struct netr_USER_KEYS keys;
+ data.data = user->user_private_info.SensitiveData;
+ data.length = user->user_private_info.DataLength;
+ creds_arcfour_crypt(creds, data.data, data.length);
+ nt_status = ndr_pull_struct_blob(&data, mem_ctx, &keys, (ndr_pull_flags_fn_t)ndr_pull_netr_USER_KEYS);
+ if (NT_STATUS_IS_OK(nt_status)) {
+ if (keys.keys.keys2.lmpassword.length == 16) {
+ sam_rid_crypt(rid, keys.keys.keys2.lmpassword.pwd.hash, lm_hash.hash, 0);
+ lm_hash_p = &lm_hash;
+ }
+ if (keys.keys.keys2.ntpassword.length == 16) {
+ sam_rid_crypt(rid, keys.keys.keys2.ntpassword.pwd.hash, nt_hash.hash, 0);
+ nt_hash_p = &nt_hash;
+ }
+ } else {
+ printf("Failed to parse Sensitive Data for %s:\n", username);
+ dump_data(10, data.data, data.length);
+ return False;
+ }
+ }
+
+ hex_lm_password = smbpasswd_sethexpwd(mem_ctx, lm_hash_p, user->acct_flags);
+ hex_nt_password = smbpasswd_sethexpwd(mem_ctx, nt_hash_p, user->acct_flags);
+
+ printf("%s:%d:%s:%s:%s:LCT-%08X\n", username,
+ rid, hex_lm_password, hex_nt_password,
+ smbpasswd_encode_acb_info(mem_ctx, user->acct_flags),
+ (unsigned int)nt_time_to_unix(user->last_password_change));
+
+ return True;
+}
+
+
+
+static NTSTATUS libnet_SamDump_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SamDump *r)
+{
+ NTSTATUS nt_status;
+ TALLOC_CTX *loop_ctx, *delta_ctx;
+ struct creds_CredentialState *creds;
+ struct netr_DatabaseSync dbsync;
+ struct cli_credentials *machine_account;
+ struct dcerpc_binding *b;
+ struct dcerpc_pipe *p;
+
+ /* TODO: This is bogus */
+ const char **bindings = lp_passwordserver();
+ const char *binding;
+
+ if (bindings && bindings[0]) {
+ binding = bindings[0];
+ }
+
+ machine_account = cli_credentials_init(mem_ctx);
+ if (!machine_account) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ cli_credentials_set_conf(machine_account);
+ nt_status = cli_credentials_set_machine_account(machine_account);
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ r->netlogon.error_string = talloc_strdup(mem_ctx, "Could not obtain machine account password - are we joined to the domain?");
+ return nt_status;
+ }
+
+ if (cli_credentials_get_secure_channel_type(machine_account) != SEC_CHAN_BDC) {
+ r->netlogon.error_string
+ = talloc_asprintf(mem_ctx,
+ "Our join to domain %s is not as a BDC (%d), please rejoin as a BDC",
+ cli_credentials_get_secure_channel_type(machine_account),
+ cli_credentials_get_domain(machine_account));
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+
+ /* Connect to DC (take a binding string for now) */
+
+ nt_status = dcerpc_parse_binding(mem_ctx, binding, &b);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ r->netlogon.error_string = talloc_asprintf(mem_ctx, "Bad binding string %s\n", binding);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* We like schannel */
+ b->flags &= ~DCERPC_AUTH_OPTIONS;
+ b->flags |= DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_128;
+
+ /* Setup schannel */
+ nt_status = dcerpc_pipe_connect_b(mem_ctx, &p, b,
+ DCERPC_NETLOGON_UUID,
+ DCERPC_NETLOGON_VERSION,
+ machine_account);
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ return nt_status;
+ }
+
+ /* call domain logon */
+
+ nt_status = dcerpc_schannel_creds(p->conn->security_state.generic_state, mem_ctx, &creds);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ return nt_status;
+ }
+
+ dbsync.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
+ dbsync.in.computername = cli_credentials_get_workstation(machine_account);
+ dbsync.in.preferredmaximumlength = (uint32_t)-1;
+ ZERO_STRUCT(dbsync.in.return_authenticator);
+
+ dbsync.in.sync_context = 0;
+ dbsync.in.database_id = SAM_DATABASE_DOMAIN;
+
+ do {
+ int d;
+ loop_ctx = talloc_named(mem_ctx, 0, "DatabaseSync loop context");
+ creds_client_authenticator(creds, &dbsync.in.credential);
+
+ nt_status = dcerpc_netr_DatabaseSync(p, loop_ctx, &dbsync);
+ if (!NT_STATUS_IS_OK(nt_status) &&
+ !NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)) {
+ printf("DatabaseSync - %s\n", nt_errstr(nt_status));
+ return nt_status;
+ }
+
+ if (!creds_client_check(creds, &dbsync.out.return_authenticator.cred)) {
+ printf("Credential chaining failed\n");
+ }
+
+ dbsync.in.sync_context = dbsync.out.sync_context;
+
+ for (d=0; d < dbsync.out.delta_enum_array->num_deltas; d++) {
+ delta_ctx = talloc_named(loop_ctx, 0, "DatabaseSync delta context");
+ switch (dbsync.out.delta_enum_array->delta_enum[d].delta_type) {
+ case NETR_DELTA_USER:
+ if (!vampire_samdump_handle_user(delta_ctx,
+ creds,
+ &dbsync.out.delta_enum_array->delta_enum[d])) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ break;
+ }
+ talloc_free(delta_ctx);
+ }
+ talloc_free(loop_ctx);
+ } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
+ return NT_STATUS_OK;
+}
+
+NTSTATUS libnet_SamDump_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SamDump *r)
+{
+ NTSTATUS nt_status;
+ union libnet_SamDump r2;
+
+ r2.generic.level = LIBNET_SAMDUMP_NETLOGON;
+ r2.generic.error_string = NULL;
+ nt_status = libnet_SamDump(ctx, mem_ctx, &r2);
+ r->generic.error_string = r2.netlogon.error_string;
+
+
+ return nt_status;
+}
+
+NTSTATUS libnet_SamDump(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SamDump *r)
+{
+ switch (r->generic.level) {
+ case LIBNET_SAMDUMP_GENERIC:
+ return libnet_SamDump_generic(ctx, mem_ctx, r);
+ case LIBNET_SAMDUMP_NETLOGON:
+ return libnet_SamDump_netlogon(ctx, mem_ctx, r);
+ }
+
+ return NT_STATUS_INVALID_LEVEL;
+}
diff --git a/source4/libnet/libnet_vampire.h b/source4/libnet/libnet_vampire.h
new file mode 100644
index 0000000000..22ac1606bd
--- /dev/null
+++ b/source4/libnet/libnet_vampire.h
@@ -0,0 +1,40 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
+
+ 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 "librpc/gen_ndr/ndr_netlogon.h"
+
+/* struct and enum for doing a remote domain join */
+enum libnet_SamDump_level {
+ LIBNET_SAMDUMP_GENERIC,
+ LIBNET_SAMDUMP_NETLOGON,
+};
+
+union libnet_SamDump {
+ struct {
+ enum libnet_SamDump_level level;
+ char *error_string;
+ } generic;
+
+ struct {
+ enum libnet_SamDump_level level;
+ char *error_string;
+ } netlogon;
+};
+
diff --git a/source4/passdb/secrets.c b/source4/passdb/secrets.c
index d9501b866c..7bc7183b98 100644
--- a/source4/passdb/secrets.c
+++ b/source4/passdb/secrets.c
@@ -181,17 +181,28 @@ struct ldb_context *secrets_db_connect(TALLOC_CTX *mem_ctx)
{
char *path;
struct ldb_context *ldb;
+ BOOL existed;
+ const char *init_ldif =
+ "dn: @ATTRIBUTES\n" \
+ "computerName: CASE_INSENSITIVE\n" \
+ "flatname: CASE_INSENSITIVE\n";
path = private_path(mem_ctx, "secrets.ldb");
if (!path) {
return NULL;
}
+ existed = file_exists(path);
+
ldb = ldb_wrap_connect(mem_ctx, path, 0, NULL);
talloc_free(path);
if (!ldb) {
return NULL;
}
+
+ if (!existed) {
+ gendb_add_ldif(ldb, init_ldif);
+ }
return ldb;
}
diff --git a/source4/utils/net/config.mk b/source4/utils/net/config.mk
index 14b4683b9f..f68cf68c8c 100644
--- a/source4/utils/net/config.mk
+++ b/source4/utils/net/config.mk
@@ -8,6 +8,7 @@ OBJ_FILES = \
utils/net/net_password.o \
utils/net/net_time.o \
utils/net/net_join.o \
+ utils/net/net_vampire.o \
utils/net/net_user.o
REQUIRED_SUBSYSTEMS = \
CONFIG \
diff --git a/source4/utils/net/net.c b/source4/utils/net/net.c
index 96ae23c7e4..c7c6f7dec9 100644
--- a/source4/utils/net/net.c
+++ b/source4/utils/net/net.c
@@ -105,6 +105,7 @@ static const struct net_functable net_functable[] = {
{"password", "change password\n", net_password, net_password_usage},
{"time", "get remote server's time\n", net_time, net_time_usage},
{"join", "join a domain\n", net_join, net_join_usage},
+ {"samdump", "dump the sam of a domain\n", net_samdump, net_samdump_usage},
{"user", "manage user accounts\n", net_user, net_user_usage},
{NULL, NULL, NULL, NULL}
};
diff --git a/source4/utils/net/net_vampire.c b/source4/utils/net/net_vampire.c
new file mode 100644
index 0000000000..df2d84746b
--- /dev/null
+++ b/source4/utils/net/net_vampire.c
@@ -0,0 +1,68 @@
+/*
+ Samba Unix/Linux SMB client library
+ Distributed SMB/CIFS Server Management Utility
+
+ Copyright (C) 2004 Stefan Metzmacher <metze@samba.org>
+ Copyright (C) 2005 Andrew Bartlett <abartlet@samba.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 "utils/net/net.h"
+#include "libnet/libnet.h"
+#include "librpc/gen_ndr/ndr_samr.h"
+
+int net_samdump(struct net_context *ctx, int argc, const char **argv)
+{
+ NTSTATUS status;
+ struct libnet_context *libnetctx;
+ union libnet_SamDump r;
+
+ libnetctx = libnet_context_init();
+ if (!libnetctx) {
+ return -1;
+ }
+ libnetctx->credentials = ctx->credentials;
+
+ /* prepare password change */
+ r.generic.level = LIBNET_SAMDUMP_GENERIC;
+ r.generic.error_string = NULL;
+
+ /* do the domain join */
+ status = libnet_SamDump(libnetctx, ctx->mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("libnet_SamDump returned %s: %s\n",
+ nt_errstr(status),
+ r.generic.error_string));
+ return -1;
+ }
+
+ libnet_context_destroy(&libnetctx);
+
+ return 0;
+}
+
+int net_samdump_usage(struct net_context *ctx, int argc, const char **argv)
+{
+ d_printf("net samdump\n");
+ return 0;
+}
+
+int net_samdump_help(struct net_context *ctx, int argc, const char **argv)
+{
+ d_printf("Dumps the sam of the domain we are joined to.\n");
+ return 0;
+}