mirror of
https://github.com/samba-team/samba.git
synced 2025-02-02 09:47:23 +03:00
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)
This commit is contained in:
parent
591ff7675d
commit
8bf57cf8f5
@ -201,3 +201,6 @@ struct wrepl_pull_table;
|
|||||||
struct wrepl_pull_names;
|
struct wrepl_pull_names;
|
||||||
|
|
||||||
struct arcfour_state;
|
struct arcfour_state;
|
||||||
|
|
||||||
|
union libnet_SamDump;
|
||||||
|
|
||||||
|
@ -40,6 +40,15 @@ INIT_OBJ_FILES = \
|
|||||||
# End SUBSYSTEM LIBCOMPRESION
|
# End SUBSYSTEM LIBCOMPRESION
|
||||||
################################################
|
################################################
|
||||||
|
|
||||||
|
|
||||||
|
################################################
|
||||||
|
# Start SUBSYSTEM LIBSAMBA3
|
||||||
|
[SUBSYSTEM::LIBSAMBA3]
|
||||||
|
INIT_OBJ_FILES = \
|
||||||
|
lib/samba3/smbpasswd.o
|
||||||
|
# End SUBSYSTEM LIBSAMBA3
|
||||||
|
################################################
|
||||||
|
|
||||||
##############################
|
##############################
|
||||||
# Start SUBSYSTEM LIBBASIC
|
# Start SUBSYSTEM LIBBASIC
|
||||||
[SUBSYSTEM::LIBBASIC]
|
[SUBSYSTEM::LIBBASIC]
|
||||||
|
@ -458,6 +458,7 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
|
|||||||
"samAccountName",
|
"samAccountName",
|
||||||
"flatname",
|
"flatname",
|
||||||
"realm",
|
"realm",
|
||||||
|
"secureChannelType",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -512,7 +513,7 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sct = ldb_msg_find_int(msgs[0], "secureChannelType", 0);
|
sct = ldb_msg_find_int(msgs[0], "secureChannelType", 0);
|
||||||
if (!sct) {
|
if (sct) {
|
||||||
cli_credentials_set_secure_channel_type(cred, sct);
|
cli_credentials_set_secure_channel_type(cred, sct);
|
||||||
} else {
|
} else {
|
||||||
DEBUG(1, ("Domain join for acocunt %s did not have a secureChannelType set!\n",
|
DEBUG(1, ("Domain join for acocunt %s did not have a secureChannelType set!\n",
|
||||||
|
5
source4/lib/samba3/README
Normal file
5
source4/lib/samba3/README
Normal file
@ -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.
|
208
source4/lib/samba3/smbpasswd.c
Normal file
208
source4/lib/samba3/smbpasswd.c
Normal file
@ -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;
|
||||||
|
}
|
@ -395,6 +395,7 @@ char *StrnCpy(char *dest,const char *src,size_t n)
|
|||||||
|
|
||||||
valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
|
valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
|
||||||
|
|
||||||
|
|
||||||
**/
|
**/
|
||||||
size_t strhex_to_str(char *p, size_t len, const char *strhex)
|
size_t strhex_to_str(char *p, size_t len, const char *strhex)
|
||||||
{
|
{
|
||||||
|
@ -8,9 +8,10 @@ ADD_OBJ_FILES = \
|
|||||||
libnet/libnet_time.o \
|
libnet/libnet_time.o \
|
||||||
libnet/libnet_rpc.o \
|
libnet/libnet_rpc.o \
|
||||||
libnet/libnet_join.o \
|
libnet/libnet_join.o \
|
||||||
|
libnet/libnet_vampire.o \
|
||||||
libnet/libnet_user.o \
|
libnet/libnet_user.o \
|
||||||
libnet/userinfo.o \
|
libnet/userinfo.o \
|
||||||
libnet/userman.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
|
# End SUBSYSTEM LIBNET
|
||||||
#################################
|
#################################
|
||||||
|
@ -32,4 +32,5 @@ struct libnet_context {
|
|||||||
#include "libnet/libnet_time.h"
|
#include "libnet/libnet_time.h"
|
||||||
#include "libnet/libnet_rpc.h"
|
#include "libnet/libnet_rpc.h"
|
||||||
#include "libnet/libnet_join.h"
|
#include "libnet/libnet_join.h"
|
||||||
|
#include "libnet/libnet_vampire.h"
|
||||||
#include "libnet/libnet_user.h"
|
#include "libnet/libnet_user.h"
|
||||||
|
225
source4/libnet/libnet_vampire.c
Normal file
225
source4/libnet/libnet_vampire.c
Normal file
@ -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;
|
||||||
|
}
|
40
source4/libnet/libnet_vampire.h
Normal file
40
source4/libnet/libnet_vampire.h
Normal file
@ -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;
|
||||||
|
};
|
||||||
|
|
@ -181,17 +181,28 @@ struct ldb_context *secrets_db_connect(TALLOC_CTX *mem_ctx)
|
|||||||
{
|
{
|
||||||
char *path;
|
char *path;
|
||||||
struct ldb_context *ldb;
|
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");
|
path = private_path(mem_ctx, "secrets.ldb");
|
||||||
if (!path) {
|
if (!path) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
existed = file_exists(path);
|
||||||
|
|
||||||
ldb = ldb_wrap_connect(mem_ctx, path, 0, NULL);
|
ldb = ldb_wrap_connect(mem_ctx, path, 0, NULL);
|
||||||
talloc_free(path);
|
talloc_free(path);
|
||||||
if (!ldb) {
|
if (!ldb) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!existed) {
|
||||||
|
gendb_add_ldif(ldb, init_ldif);
|
||||||
|
}
|
||||||
|
|
||||||
return ldb;
|
return ldb;
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ OBJ_FILES = \
|
|||||||
utils/net/net_password.o \
|
utils/net/net_password.o \
|
||||||
utils/net/net_time.o \
|
utils/net/net_time.o \
|
||||||
utils/net/net_join.o \
|
utils/net/net_join.o \
|
||||||
|
utils/net/net_vampire.o \
|
||||||
utils/net/net_user.o
|
utils/net/net_user.o
|
||||||
REQUIRED_SUBSYSTEMS = \
|
REQUIRED_SUBSYSTEMS = \
|
||||||
CONFIG \
|
CONFIG \
|
||||||
|
@ -105,6 +105,7 @@ static const struct net_functable net_functable[] = {
|
|||||||
{"password", "change password\n", net_password, net_password_usage},
|
{"password", "change password\n", net_password, net_password_usage},
|
||||||
{"time", "get remote server's time\n", net_time, net_time_usage},
|
{"time", "get remote server's time\n", net_time, net_time_usage},
|
||||||
{"join", "join a domain\n", net_join, net_join_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},
|
{"user", "manage user accounts\n", net_user, net_user_usage},
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
68
source4/utils/net/net_vampire.c
Normal file
68
source4/utils/net/net_vampire.c
Normal file
@ -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;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user