diff options
author | Andrew Bartlett <abartlet@samba.org> | 2005-05-02 14:17:19 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:16:27 -0500 |
commit | 8bf57cf8f57be28831023c2218d358b24b705256 (patch) | |
tree | e18e07afa72a46e9c6c94b8faf1ee21650b2cc20 /source4 | |
parent | 591ff7675dfe51f30029cb864df47bc8f6266494 (diff) | |
download | samba-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)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/include/structs.h | 3 | ||||
-rw-r--r-- | source4/lib/basic.mk | 9 | ||||
-rw-r--r-- | source4/lib/credentials.c | 3 | ||||
-rw-r--r-- | source4/lib/samba3/README | 5 | ||||
-rw-r--r-- | source4/lib/samba3/smbpasswd.c | 208 | ||||
-rw-r--r-- | source4/lib/util_str.c | 1 | ||||
-rw-r--r-- | source4/libnet/config.mk | 3 | ||||
-rw-r--r-- | source4/libnet/libnet.h | 1 | ||||
-rw-r--r-- | source4/libnet/libnet_vampire.c | 225 | ||||
-rw-r--r-- | source4/libnet/libnet_vampire.h | 40 | ||||
-rw-r--r-- | source4/passdb/secrets.c | 11 | ||||
-rw-r--r-- | source4/utils/net/config.mk | 1 | ||||
-rw-r--r-- | source4/utils/net/net.c | 1 | ||||
-rw-r--r-- | source4/utils/net/net_vampire.c | 68 |
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; +} |