From 4b1baa5a70964e94ecc4733a9f8cd3f318c758ea Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 Aug 2002 03:17:03 +0000 Subject: added a 'net ads lookup' command that does a CLDAP NetLogon query to a win2000 server. It does seem to work, and win200 sends us a valid reply, but we don't parse it yet. Maybe tomorrow :) (This used to be commit 6352508c54cee333ed7c0e3ebc372be7cd60ed62) --- source3/utils/net_ads.c | 26 ++++++++++++ source3/utils/net_ads_cldap.c | 95 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 source3/utils/net_ads_cldap.c (limited to 'source3/utils') diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index ad405fe68c..16450c5b29 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -56,6 +56,31 @@ int net_ads_usage(int argc, const char **argv) } +/* + this implements the CLDAP based netlogon lookup requests + for finding the domain controller of a ADS domain +*/ +static int net_ads_lookup(int argc, const char **argv) +{ + ADS_STRUCT *ads; + + ads = ads_init(NULL, NULL, opt_host); + if (ads) { + ads->auth.no_bind = 1; + } + + ads_connect(ads); + + if (!ads || !ads->config.realm) { + d_printf("Didn't find the cldap server!\n"); + return -1; + } + + return ads_cldap_netlogon(ads); +} + + + static int net_ads_info(int argc, const char **argv) { ADS_STRUCT *ads; @@ -1009,6 +1034,7 @@ int net_ads(int argc, const char **argv) {"PRINTER", net_ads_printer}, {"SEARCH", net_ads_search}, {"WORKGROUP", net_ads_workgroup}, + {"LOOKUP", net_ads_lookup}, {"HELP", net_ads_help}, {NULL, NULL} }; diff --git a/source3/utils/net_ads_cldap.c b/source3/utils/net_ads_cldap.c new file mode 100644 index 0000000000..f707f6beac --- /dev/null +++ b/source3/utils/net_ads_cldap.c @@ -0,0 +1,95 @@ +/* + Samba Unix/Linux SMB client library + net ads cldap functions + Copyright (C) 2001 Andrew Tridgell (tridge@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.h" + +#ifdef HAVE_ADS + +/* + do a cldap netlogon query +*/ +int ads_cldap_netlogon(ADS_STRUCT *ads) +{ + ASN1_DATA data; + char ntver[4]; + int sock; + + SIVAL(ntver, 0, 6); + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data,ASN1_SEQUENCE(0)); + asn1_write_Integer(&data, 4); + asn1_push_tag(&data, ASN1_APPLICATION(3)); + asn1_write_OctetString(&data, NULL, 0); + asn1_write_enumerated(&data, 0); + asn1_write_enumerated(&data, 0); + asn1_write_Integer(&data, 0); + asn1_write_Integer(&data, 0); + asn1_write_BOOLEAN2(&data, False); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + + asn1_push_tag(&data, ASN1_CONTEXT(3)); + asn1_write_OctetString(&data, "DnsDomain", 9); + asn1_write_OctetString(&data, ads->config.realm, strlen(ads->config.realm)); + asn1_pop_tag(&data); + + asn1_push_tag(&data, ASN1_CONTEXT(3)); + asn1_write_OctetString(&data, "Host", 4); + asn1_write_OctetString(&data, "blu", 3); + asn1_pop_tag(&data); + + + asn1_push_tag(&data, ASN1_CONTEXT(3)); + asn1_write_OctetString(&data, "NtVer", 5); + asn1_write_OctetString(&data, ntver, 4); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + + asn1_push_tag(&data,ASN1_SEQUENCE(0)); + asn1_write_OctetString(&data, "NetLogon", 8); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + if (data.has_error) { + d_printf("Failed to build cldap netlogon at offset %d\n", (int)data.ofs); + asn1_free(&data); + return -1; + } + + sock = open_udp_socket(inet_ntoa(ads->ldap_ip), ads->ldap_port); + if (sock == -1) { + d_printf("Failed to open udp socket to %s:%u\n", + inet_ntoa(ads->ldap_ip), + ads->ldap_port); + return -1; + } + + write(sock, data.data, data.length); + file_save("cldap_query.dat", data.data, data.length); + asn1_free(&data); + return 0; +} + + +#endif -- cgit From e38148f78ca631dcbc8a09616c2c91e5ec64c670 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 Aug 2002 15:30:26 +0000 Subject: we now receive and parse the main cldap netlogon reply. we still need to parse the core of the structure (This used to be commit 6780ae25bf7ca291f612682dec7ee7ff44c24bef) --- source3/utils/net_ads_cldap.c | 98 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 10 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/net_ads_cldap.c b/source3/utils/net_ads_cldap.c index f707f6beac..77a51d3b7c 100644 --- a/source3/utils/net_ads_cldap.c +++ b/source3/utils/net_ads_cldap.c @@ -23,16 +23,20 @@ #ifdef HAVE_ADS +struct cldap_netlogon_reply { + uint32 i1; +}; + /* do a cldap netlogon query */ -int ads_cldap_netlogon(ADS_STRUCT *ads) +static int send_cldap_netlogon(int sock, const char *domain, + const char *hostname, unsigned ntversion) { ASN1_DATA data; char ntver[4]; - int sock; - SIVAL(ntver, 0, 6); + SIVAL(ntver, 0, ntversion); memset(&data, 0, sizeof(data)); @@ -49,15 +53,14 @@ int ads_cldap_netlogon(ADS_STRUCT *ads) asn1_push_tag(&data, ASN1_CONTEXT(3)); asn1_write_OctetString(&data, "DnsDomain", 9); - asn1_write_OctetString(&data, ads->config.realm, strlen(ads->config.realm)); + asn1_write_OctetString(&data, domain, strlen(domain)); asn1_pop_tag(&data); asn1_push_tag(&data, ASN1_CONTEXT(3)); asn1_write_OctetString(&data, "Host", 4); - asn1_write_OctetString(&data, "blu", 3); + asn1_write_OctetString(&data, hostname, strlen(hostname)); asn1_pop_tag(&data); - asn1_push_tag(&data, ASN1_CONTEXT(3)); asn1_write_OctetString(&data, "NtVer", 5); asn1_write_OctetString(&data, ntver, 4); @@ -77,6 +80,75 @@ int ads_cldap_netlogon(ADS_STRUCT *ads) return -1; } + if (write(sock, data.data, data.length) != data.length) { + d_printf("failed to send cldap query (%s)\n", strerror(errno)); + } + + file_save("cldap_query.dat", data.data, data.length); + asn1_free(&data); + + return 0; +} + + +/* + receive a cldap netlogon reply +*/ +static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) +{ + int ret; + ASN1_DATA data; + DATA_BLOB blob; + DATA_BLOB os1, os2, os3; + + blob = data_blob(NULL, 8192); + + ret = read(sock, blob.data, blob.length); + if (ret <= 0) { + d_printf("no reply to cldap netlogon\n"); + return -1; + } + blob.length = ret; + + file_save("cldap_reply.dat", blob.data, blob.length); + + asn1_load(&data, blob); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_read_Integer(&data, &reply->i1); + asn1_start_tag(&data, ASN1_APPLICATION(4)); + asn1_read_OctetString(&data, &os1); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_read_OctetString(&data, &os2); + asn1_start_tag(&data, ASN1_SET); + asn1_read_OctetString(&data, &os3); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_end_tag(&data); + + file_save("cldap_reply_core.dat", os3.data, os3.length); + + data_blob_free(&os1); + data_blob_free(&os2); + data_blob_free(&os3); + data_blob_free(&blob); + + return 0; +} + + +/* + do a cldap netlogon query +*/ +int ads_cldap_netlogon(ADS_STRUCT *ads) +{ + int sock; + int ret; + extern pstring global_myname; + struct cldap_netlogon_reply reply; + sock = open_udp_socket(inet_ntoa(ads->ldap_ip), ads->ldap_port); if (sock == -1) { d_printf("Failed to open udp socket to %s:%u\n", @@ -85,10 +157,16 @@ int ads_cldap_netlogon(ADS_STRUCT *ads) return -1; } - write(sock, data.data, data.length); - file_save("cldap_query.dat", data.data, data.length); - asn1_free(&data); - return 0; + ret = send_cldap_netlogon(sock, ads->config.realm, global_myname, 6); + if (ret != 0) { + return ret; + } + + ret = recv_cldap_netlogon(sock, &reply); + + close(sock); + + return ret; } -- cgit From e6873a8f7f4a0bccb0bf9a9baf1a9933c7ee2eb3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 Aug 2002 15:59:14 +0000 Subject: we now parse the cldap reply and print its contents. There are a couple of unknown fields we still need to work out. (This used to be commit 67b4dbd5c9f2665d5e6157b8cd522ebff4b8a4ea) --- source3/utils/net_ads_cldap.c | 86 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 4 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/net_ads_cldap.c b/source3/utils/net_ads_cldap.c index 77a51d3b7c..b84ec0e6b4 100644 --- a/source3/utils/net_ads_cldap.c +++ b/source3/utils/net_ads_cldap.c @@ -24,9 +24,59 @@ #ifdef HAVE_ADS struct cldap_netlogon_reply { - uint32 i1; + uint32 version; + uint32 flags; + uint32 unknown[4]; + char *domain; + char *server_name; + char *flatname; + char *server_name2; + char *dns_name; + uint32 unknown2[2]; }; + +/* + pull a length prefixed string from a packet + return number of bytes consumed +*/ +static unsigned pull_len_string(char **ret, const char *p) +{ + unsigned len = *p; + (*ret) = NULL; + if (len == 0) return 1; + (*ret) = strndup(p+1, len); + return len+1; +} + +/* + pull a dotted string from a packet + return number of bytes consumed +*/ +static unsigned pull_dotted_string(char **ret, const char *p) +{ + char *s; + unsigned len, total_len=0; + + (*ret) = NULL; + + while ((len = pull_len_string(&s, p)) > 1) { + if (total_len) { + char *s2; + asprintf(&s2, "%s.%s", *ret, s); + SAFE_FREE(*ret); + (*ret) = s2; + } else { + (*ret) = s; + } + total_len += len; + p += len; + } + + return total_len + 1; +} + + /* do a cldap netlogon query */ @@ -100,6 +150,9 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) ASN1_DATA data; DATA_BLOB blob; DATA_BLOB os1, os2, os3; + uint32 i1; + char *p; + int i; blob = data_blob(NULL, 8192); @@ -114,7 +167,7 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) asn1_load(&data, blob); asn1_start_tag(&data, ASN1_SEQUENCE(0)); - asn1_read_Integer(&data, &reply->i1); + asn1_read_Integer(&data, &i1); asn1_start_tag(&data, ASN1_APPLICATION(4)); asn1_read_OctetString(&data, &os1); asn1_start_tag(&data, ASN1_SEQUENCE(0)); @@ -129,7 +182,25 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) asn1_end_tag(&data); file_save("cldap_reply_core.dat", os3.data, os3.length); - + + p = os3.data; + + reply->version = IVAL(p, 0); p += 4; + reply->flags = IVAL(p, 0); p += 4; + for (i=0;i<4;i++) { + reply->unknown[i] = IVAL(p, 0); + p += 4; + } + p += pull_dotted_string(&reply->domain, p); + p += 2; /* 0xc018 - whats this? */ + p += pull_len_string(&reply->server_name, p); + p += 2; /* 0xc018 - whats this? */ + p += pull_len_string(&reply->flatname, p); + p += 1; + p += pull_len_string(&reply->server_name2, p); + p += 2; + p += pull_len_string(&reply->dns_name, p); + data_blob_free(&os1); data_blob_free(&os2); data_blob_free(&os3); @@ -163,8 +234,15 @@ int ads_cldap_netlogon(ADS_STRUCT *ads) } ret = recv_cldap_netlogon(sock, &reply); - close(sock); + + d_printf("Version: 0x%x\n", reply.version); + d_printf("Flags: 0x%x\n", reply.flags); + d_printf("Domain: %s\n", reply.domain); + d_printf("Server Name: %s\n", reply.server_name); + d_printf("Flatname: %s\n", reply.flatname); + d_printf("Server Name2: %s\n", reply.server_name2); + d_printf("DNS Name: %s\n", reply.dns_name); return ret; } -- cgit From d44015ae91acceaab8e98cbfa9176f7ab445328a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 Aug 2002 16:56:09 +0000 Subject: print out the GUID in the CLDAP reply (This used to be commit 8aae10bcdc05fca4e0281ac91a7679c60b791534) --- source3/utils/net_ads_cldap.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/net_ads_cldap.c b/source3/utils/net_ads_cldap.c index b84ec0e6b4..1bf96fc5d5 100644 --- a/source3/utils/net_ads_cldap.c +++ b/source3/utils/net_ads_cldap.c @@ -26,11 +26,11 @@ struct cldap_netlogon_reply { uint32 version; uint32 flags; - uint32 unknown[4]; + GUID guid; char *domain; char *server_name; - char *flatname; - char *server_name2; + char *domain_flatname; + char *server_flatname; char *dns_name; uint32 unknown2[2]; }; @@ -152,7 +152,6 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) DATA_BLOB os1, os2, os3; uint32 i1; char *p; - int i; blob = data_blob(NULL, 8192); @@ -187,17 +186,15 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) reply->version = IVAL(p, 0); p += 4; reply->flags = IVAL(p, 0); p += 4; - for (i=0;i<4;i++) { - reply->unknown[i] = IVAL(p, 0); - p += 4; - } + memcpy(&reply->guid.info, p, GUID_SIZE); + p += GUID_SIZE; p += pull_dotted_string(&reply->domain, p); p += 2; /* 0xc018 - whats this? */ p += pull_len_string(&reply->server_name, p); p += 2; /* 0xc018 - whats this? */ - p += pull_len_string(&reply->flatname, p); + p += pull_len_string(&reply->domain_flatname, p); p += 1; - p += pull_len_string(&reply->server_name2, p); + p += pull_len_string(&reply->server_flatname, p); p += 2; p += pull_len_string(&reply->dns_name, p); @@ -237,11 +234,13 @@ int ads_cldap_netlogon(ADS_STRUCT *ads) close(sock); d_printf("Version: 0x%x\n", reply.version); + d_printf("GUID: "); + print_guid(&reply.guid); d_printf("Flags: 0x%x\n", reply.flags); d_printf("Domain: %s\n", reply.domain); d_printf("Server Name: %s\n", reply.server_name); - d_printf("Flatname: %s\n", reply.flatname); - d_printf("Server Name2: %s\n", reply.server_name2); + d_printf("Flatname: %s\n", reply.domain_flatname); + d_printf("Server Name2: %s\n", reply.server_flatname); d_printf("DNS Name: %s\n", reply.dns_name); return ret; -- cgit From 1ea5e17f950a8b7f50723649a48f67b4bca75160 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 21 Aug 2002 11:48:05 +0000 Subject: Fix debug level initialization for net.c Volker (This used to be commit 5af5326f1311a49d3c8316e1dcc27037b831065a) --- source3/utils/net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/utils') diff --git a/source3/utils/net.c b/source3/utils/net.c index fc7094bcf7..416a599be3 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -391,7 +391,7 @@ static struct functable net_func[] = { {"force", 'f', POPT_ARG_NONE, &opt_force}, {"timeout", 't', POPT_ARG_INT, &opt_timeout}, {"machine-pass",'P', POPT_ARG_NONE, &opt_machine_pass}, - { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug }, + {"debuglevel", 'D', POPT_ARG_STRING, &debuglevel}, { 0, 0, 0, 0} }; -- cgit From f3110c68847dc0f5b68fd64b0165d558cf0dac10 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 21 Aug 2002 17:07:10 +0000 Subject: just comment typos (This used to be commit 169e784f4829ef356ed6232ace950d43cac1d467) --- source3/utils/net_rpc.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 55e8a497cc..3f5c65ddf2 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -178,7 +178,7 @@ static int run_rpc_command(struct cli_state *cli_arg, const char *pipe_name, int /** * Force a change of the trust acccount password. * - * All paramaters are provided by the run_rpc_command funcion, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid aquired from the remote server @@ -224,7 +224,7 @@ static int rpc_changetrustpw(int argc, const char **argv) * * The password should be created with 'server manager' or eqiv first. * - * All paramaters are provided by the run_rpc_command funcion, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid aquired from the remote server @@ -319,7 +319,7 @@ int net_rpc_join(int argc, const char **argv) /** * display info about a rpc domain * - * All paramaters are provided by the run_rpc_command function, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -406,7 +406,7 @@ static int rpc_user_usage(int argc, const char **argv) /** * Add a new user to a remote RPC server * - * All paramaters are provided by the run_rpc_command funcion, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -494,7 +494,7 @@ static int rpc_user_add(int argc, const char **argv) /** * Delete a user from a remote RPC server * - * All paramaters are provided by the run_rpc_command funcion, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -595,7 +595,7 @@ static int rpc_user_delete(int argc, const char **argv) /** * List user's groups on a remote RPC server * - * All paramaters are provided by the run_rpc_command funcion, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -697,7 +697,7 @@ static int rpc_user_info(int argc, const char **argv) /** * List users on a remote RPC server * - * All paramaters are provided by the run_rpc_command function, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -811,7 +811,7 @@ static int rpc_group_usage(int argc, const char **argv) /** * List groups on a remote RPC server * - * All paramaters are provided by the run_rpc_command funcion, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -954,7 +954,7 @@ static int rpc_share_usage(int argc, const char **argv) /** * Add a share on a remote RPC server * - * All paramaters are provided by the run_rpc_command function, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -1002,7 +1002,7 @@ static int rpc_share_add(int argc, const char **argv) /** * Delete a share on a remote RPC server * - * All paramaters are provided by the run_rpc_command function, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -1070,7 +1070,7 @@ static void display_share_info_1(SRV_SHARE_INFO_1 *info1) /** * List shares on a remote RPC server * - * All paramaters are provided by the run_rpc_command function, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -1147,7 +1147,7 @@ static int rpc_file_usage(int argc, const char **argv) /** * Close a file on a remote RPC server * - * All paramaters are provided by the run_rpc_command function, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -1210,7 +1210,7 @@ static void display_file_info_3(FILE_INFO_3 *info3, FILE_INFO_3_STR *str3) /** * List open files on a remote RPC server * - * All paramaters are provided by the run_rpc_command funcion, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid acquired from the remote server @@ -1314,7 +1314,7 @@ int net_rpc_file(int argc, const char **argv) /** * ABORT the shutdown of a remote RPC Server * - * All paramaters are provided by the run_rpc_command function, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passed through. * * @param domain_sid The domain sid aquired from the remote server @@ -1362,7 +1362,7 @@ static int rpc_shutdown_abort(int argc, const char **argv) /** * Shut down a remote RPC Server * - * All paramaters are provided by the run_rpc_command funcion, except for + * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passes through. * * @param domain_sid The domain sid aquired from the remote server -- cgit From 90e65e7ac7b365a898a620d2dc4de1643e41cbf7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 21 Aug 2002 17:23:34 +0000 Subject: Add 'net rpc getsid' to fetch the PDC's SID into the local secrets.tdb Print domain SID on 'net rpc info' Volker (This used to be commit 12fd889a3f0e3eeeb27a51cdd7f648a59083f2ba) --- source3/utils/net_rpc.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) (limited to 'source3/utils') diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 3f5c65ddf2..df5b67372d 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -339,6 +339,9 @@ rpc_info_internals(const DOM_SID *domain_sid, struct cli_state *cli, POLICY_HND connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; SAM_UNK_CTR ctr; + fstring sid_str; + + sid_to_string(sid_str, domain_sid); /* Get sam policy handle */ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, @@ -361,6 +364,7 @@ rpc_info_internals(const DOM_SID *domain_sid, struct cli_state *cli, if (NT_STATUS_IS_OK(result)) { TALLOC_CTX *ctx = talloc_init(); d_printf("Domain Name: %s\n", unistr2_tdup(ctx, &ctr.info.inf2.uni_domain)); + d_printf("Domain SID: %s\n", sid_str); d_printf("Sequence number: %u\n", ctr.info.inf2.seq_num); d_printf("Num users: %u\n", ctr.info.inf2.num_domain_usrs); d_printf("Num domain groups: %u\n", ctr.info.inf2.num_domain_grps); @@ -387,6 +391,54 @@ int net_rpc_info(int argc, const char **argv) } +/** + * Fetch domain SID into the local secrets.tdb + * + * All parameters are provided by the run_rpc_command function, except for + * argc, argv which are passes through. + * + * @param domain_sid The domain sid acquired from the remote server + * @param cli A cli_state connected to the server. + * @param mem_ctx Talloc context, destoyed on completion of the function. + * @param argc Standard main() style argc + * @param argv Standard main() style argv. Initial components are already + * stripped + * + * @return Normal NTSTATUS return. + **/ + +static NTSTATUS +rpc_getsid_internals(const DOM_SID *domain_sid, struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, const char **argv) +{ + fstring sid_str; + + sid_to_string(sid_str, domain_sid); + d_printf("Storing SID %s for Domain %s in secrets.tdb\n", + sid_str, lp_workgroup()); + + if (!secrets_store_domain_sid(global_myname, domain_sid)) { + DEBUG(0,("pdb_generate_sam_sid: " + "Can't store domain SID as a pdc/bdc.\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + return NT_STATUS_OK; +} + + +/** + * 'net rpc getsid' entrypoint. + * @param argc Standard main() style argc + * @param argc Standard main() style argv. Initial components are already + * stripped + **/ +int net_rpc_getsid(int argc, const char **argv) +{ + return run_rpc_command(NULL, PIPE_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, + rpc_getsid_internals, + argc, argv); +} /****************************************************************************/ @@ -2120,12 +2172,13 @@ int net_rpc_usage(int argc, const char **argv) { d_printf(" net rpc info \t\t\tshow basic info about a domain \n"); d_printf(" net rpc join \t\t\tto join a domain \n"); - d_printf(" net rpc testjoin \t\t\ttests that a join is valid\n"); + d_printf(" net rpc testjoin \t\ttests that a join is valid\n"); d_printf(" net rpc user \t\t\tto add, delete and list users\n"); d_printf(" net rpc group \t\tto list groups\n"); d_printf(" net rpc share \t\tto add, delete, and list shares\n"); d_printf(" net rpc file \t\t\tto list open files\n"); d_printf(" net rpc changetrustpw \tto change the trust account password\n"); + d_printf(" net rpc getsid \t\tfetch the domain sid into the local secrets.tdb\n"); d_printf(" net rpc trustdom \t\tto create trusting domain's account\n" "\t\t\t\t\tor establish trust\n"); d_printf(" net rpc abortshutdown \tto abort the shutdown of a remote server\n"); @@ -2192,6 +2245,7 @@ int net_rpc(int argc, const char **argv) {"trustdom", rpc_trustdom}, {"abortshutdown", rpc_shutdown_abort}, {"shutdown", rpc_shutdown}, + {"getsid", net_rpc_getsid}, {"help", net_rpc_help}, {NULL, NULL} }; -- cgit From e573a2a32c1ff01bc09215efae6927f4795b4ef6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 21 Aug 2002 19:39:38 +0000 Subject: global_myname is a pstring, not an fstring (This used to be commit 2df34c9bfc76ee832e5005a2ad0ff0b6abb98034) --- source3/utils/net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/utils') diff --git a/source3/utils/net.c b/source3/utils/net.c index 416a599be3..a3aa7adcae 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -469,7 +469,7 @@ static struct functable net_func[] = { if (!*global_myname) { char *p2; - fstrcpy(global_myname, myhostname()); + pstrcpy(global_myname, myhostname()); p2 = strchr_m(global_myname, '.'); if (p2) *p2 = 0; -- cgit From 30e51241ecdda2724c441e372e6f99857719630f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 21 Aug 2002 19:48:56 +0000 Subject: pdbedit needs global_myname to be set in order to display the user SIDs correctly. Volker (This used to be commit 287b7bda11100c42f2cdea36a20a81f6ea397f43) --- source3/utils/pdbedit.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source3/utils') diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 51dbbb98c0..7c61e6d8be 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -508,6 +508,17 @@ int main (int argc, char **argv) exit(1); } + if (!*global_myname) { + char *p2; + + pstrcpy(global_myname, myhostname()); + p2 = strchr_m(global_myname, '.'); + if (p2) + *p2 = 0; + } + + strupper(global_myname); + setparms = (config_file ? BIT_CONFIGFILE : 0) + (new_debuglevel ? BIT_DEBUGLEVEL : 0) + (backend ? BIT_BACKEND : 0) + @@ -544,7 +555,7 @@ int main (int argc, char **argv) /* the lowest bit options are always accepted */ checkparms = setparms & ~MASK_ALWAYS_GOOD; - /* accoun tpolicy operations */ + /* account policy operations */ if ((checkparms & BIT_ACCPOLICY) && !(checkparms & ~(BIT_ACCPOLICY + BIT_ACCPOLVAL))) { uint32 value; int field = account_policy_name_to_fieldnum(account_policy); -- cgit From d3aa76cef528a15571cade12ebdd10973f4ca579 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 Aug 2002 19:59:23 +0000 Subject: Patch from Paul Green to be more POSIX-compatible (This used to be commit addf29e6765393b25c35bd833d29e29e4581c233) --- source3/utils/status.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/utils') diff --git a/source3/utils/status.c b/source3/utils/status.c index 0b0c591cb1..d87497f2fa 100644 --- a/source3/utils/status.c +++ b/source3/utils/status.c @@ -146,6 +146,7 @@ static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, int pid, ******************************************************************/ static int profile_dump(void) { +#ifdef WITH_PROFILE if (!profile_setup(True)) { fprintf(stderr,"Failed to initialise profile memory\n"); return -1; @@ -482,6 +483,9 @@ static int profile_dump(void) d_printf("run_elections_time: %u\n", profile_p->run_elections_time); d_printf("election_count: %u\n", profile_p->election_count); d_printf("election_time: %u\n", profile_p->election_time); +#else /* WITH_PROFILE */ + fprintf(stderr, "Profile data unavailable\n"); +#endif /* WITH_PROFILE */ return 0; } @@ -549,7 +553,9 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo {"conf", 's', POPT_ARG_STRING, 0, 's'}, {"user", 'u', POPT_ARG_STRING, 0, 'u'}, {"brief", 'b', POPT_ARG_NONE, &brief}, +#ifdef WITH_PROFILE {"profile", 'P', POPT_ARG_NONE, &profile_only}, +#endif /* WITH_PROFILE */ {"byterange", 'B', POPT_ARG_NONE, &show_brl}, { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug }, { 0, 0, 0, 0} -- cgit From 16caf06f6026f8104f4a6701993cbd560e2cd74d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 21 Aug 2002 20:29:11 +0000 Subject: This is like jht's (abortive) patch for showing only non-default testparm options. Andrew Bartlett (This used to be commit 4cd822d9e4e5f35a47b0837bfa73c8a457e6cc85) --- source3/utils/testparm.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c index 3086019467..852472073b 100644 --- a/source3/utils/testparm.c +++ b/source3/utils/testparm.c @@ -171,7 +171,7 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_ return ret; } -int main(int argc, char *argv[]) +int main(int argc, const char *argv[]) { extern char *optarg; extern int optind; @@ -185,17 +185,19 @@ int main(int argc, char *argv[]) static char *new_local_machine = NULL; const char *cname; const char *caddr; + static int show_defaults; struct poptOption long_options[] = { POPT_AUTOHELP {"suppress-prompt", 's', POPT_ARG_VAL, &silent_mode, 1, "Suppress prompt for enter"}, + {"verbose", 'v', POPT_ARG_NONE, &show_defaults, 1, "Show default options too"}, {"server", 'L',POPT_ARG_STRING, &new_local_machine, 0, "Set %%L macro to servername\n"}, {"encoding", 't', POPT_ARG_STRING, &term_code, 0, "Print parameters with encoding"}, {0,0,0,0} }; - pc = poptGetContext(NULL, argc, (const char **) argv, long_options, - POPT_CONTEXT_KEEP_FIRST); + pc = poptGetContext(NULL, argc, argv, long_options, + POPT_CONTEXT_KEEP_FIRST); while((opt = poptGetNextOpt(pc)) != -1); @@ -276,7 +278,7 @@ int main(int argc, char *argv[]) fflush(stdout); getc(stdin); } - lp_dump(stdout,True, lp_numservices()); + lp_dump(stdout, show_defaults, lp_numservices()); } if(cname && caddr){ -- cgit From 2a505d023f95457f63a3975e386b95e8658928f4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 22 Aug 2002 22:48:54 +0000 Subject: added a 'net rpc samdump' command for dumping the whole sam via samsync operations (as a BDC) (This used to be commit e4cb106d2e3e6a41529369545a7a6ce5fe6d8986) --- source3/utils/net_rpc.c | 1 + source3/utils/net_rpc_samsync.c | 162 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+) create mode 100644 source3/utils/net_rpc_samsync.c (limited to 'source3/utils') diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index df5b67372d..a7d2a08b38 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -2245,6 +2245,7 @@ int net_rpc(int argc, const char **argv) {"trustdom", rpc_trustdom}, {"abortshutdown", rpc_shutdown_abort}, {"shutdown", rpc_shutdown}, + {"samdump", rpc_samdump}, {"getsid", net_rpc_getsid}, {"help", net_rpc_help}, {NULL, NULL} diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c new file mode 100644 index 0000000000..44c3fdb26a --- /dev/null +++ b/source3/utils/net_rpc_samsync.c @@ -0,0 +1,162 @@ +/* + Unix SMB/CIFS implementation. + dump the remote SAM using rpc samsync operations + + Copyright (C) Andrew Tridgell 2002 + Copyright (C) Tim Potter 2001,2002 + + 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.h" + +static void display_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *g) +{ + int i; + d_printf("Group mem %u: ", rid); + for (i=0;inum_members;i++) { + d_printf("%u ", g->rids[i]); + } + d_printf("\n"); +} + +static void display_alias_info(uint32 rid, SAM_ALIAS_INFO *a) +{ + d_printf("Alias '%s' ", unistr2_static(&a->uni_als_name)); + d_printf("desc='%s' rid=%u\n", unistr2_static(&a->uni_als_desc), a->als_rid); +} + +static void display_alias_mem(uint32 rid, SAM_ALIAS_MEM_INFO *a) +{ + int i; + d_printf("Alias rid %u: ", rid); + for (i=0;inum_sids;i++) { + d_printf("%s ", sid_string_static(&a->sids[i].sid)); + } + d_printf("\n"); +} + +static void display_account_info(uint32 rid, SAM_ACCOUNT_INFO *a) +{ + fstring hex_nt_passwd, hex_lm_passwd; + uchar lm_passwd[16], nt_passwd[16]; + + /* Decode hashes from password hash */ + sam_pwd_hash(a->user_rid, a->pass.buf_lm_pwd, lm_passwd, 0); + sam_pwd_hash(a->user_rid, a->pass.buf_nt_pwd, nt_passwd, 0); + + /* Encode as strings */ + smbpasswd_sethexpwd(hex_lm_passwd, lm_passwd, a->acb_info); + smbpasswd_sethexpwd(hex_nt_passwd, nt_passwd, a->acb_info); + + printf("%s:%d:%s:%s:%s:LCT-0\n", unistr2_static(&a->uni_acct_name), + a->user_rid, hex_lm_passwd, hex_nt_passwd, + smbpasswd_encode_acb_info(a->acb_info)); +} + +static void display_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta) +{ + switch (hdr_delta->type) { + case SAM_DELTA_ACCOUNT_INFO: + display_account_info(hdr_delta->target_rid, &delta->account_info); + break; + case SAM_DELTA_GROUP_MEM: + display_group_mem_info(hdr_delta->target_rid, &delta->grp_mem_info); + break; + case SAM_DELTA_ALIAS_INFO: + display_alias_info(hdr_delta->target_rid, &delta->alias_info); + break; + case SAM_DELTA_ALIAS_MEM: + display_alias_mem(hdr_delta->target_rid, &delta->als_mem_info); + break; + default: + d_printf("Unknown delta record type %d\n", hdr_delta->type); + break; + } +} + +/* dump sam database via samsync rpc calls */ +int rpc_samdump(int argc, const char **argv) +{ + TALLOC_CTX *mem_ctx = NULL; + SAM_DELTA_HDR *hdr_deltas; + SAM_DELTA_CTR *deltas; + uint32 num_deltas; + NTSTATUS result; + int i; + unsigned last_rid=0; + DOM_CRED ret_creds; + struct cli_state *cli = NULL; + uchar trust_password[16]; + + /* Connect to remote machine */ + if (!(cli = net_make_ipc_connection(NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC))) { + return 1; + } + + if (!cli_nt_session_open(cli, PIPE_NETLOGON)) { + DEBUG(0,("Error connecting to NETLOGON pipe\n")); + goto fail; + } + + if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_password, NULL)) { + d_printf("Could not retrieve domain trust secret"); + goto fail; + } + + result = cli_nt_setup_creds(cli, SEC_CHAN_BDC, trust_password); + if (!NT_STATUS_IS_OK(result)) { + d_printf("Failed to setup BDC creds\n"); + goto fail; + } + + if (!(mem_ctx = talloc_init())) { + DEBUG(0,("talloc_init failed\n")); + goto fail; + } + + /* on first call the returnAuthenticator is empty */ + memset(&ret_creds, 0, sizeof(ret_creds)); + + /* Do sam synchronisation on the SAM database*/ + do { + result = cli_netlogon_sam_sync(cli, mem_ctx, &ret_creds, SAM_DATABASE_DOMAIN, last_rid+1, + &num_deltas, &hdr_deltas, &deltas); + clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds); + last_rid = 0; + for (i = 0; i < num_deltas; i++) { + display_sam_entry(&hdr_deltas[i], &deltas[i]); + last_rid = hdr_deltas[i].target_rid; + if (last_rid == 0) { + break; + } + } + } while (last_rid && NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); + + cli_nt_session_close(cli); + talloc_destroy(mem_ctx); + + return 0; + +fail: + if (cli) { + cli_nt_session_close(cli); + } + if (mem_ctx) { + talloc_destroy(mem_ctx); + } + return -1; +} -- cgit From 84b4e79227c4e5ad7f03c3fbc289465fa913cb39 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 22 Aug 2002 22:50:57 +0000 Subject: a few minor cleanups in the cldap request (This used to be commit 228fc518da0404fe770175d5277fe5f5b08f9c67) --- source3/utils/net_ads_cldap.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/net_ads_cldap.c b/source3/utils/net_ads_cldap.c index 1bf96fc5d5..6821a5902e 100644 --- a/source3/utils/net_ads_cldap.c +++ b/source3/utils/net_ads_cldap.c @@ -45,7 +45,7 @@ static unsigned pull_len_string(char **ret, const char *p) unsigned len = *p; (*ret) = NULL; if (len == 0) return 1; - (*ret) = strndup(p+1, len); + (*ret) = smb_xstrndup(p+1, len); return len+1; } @@ -156,8 +156,9 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) blob = data_blob(NULL, 8192); ret = read(sock, blob.data, blob.length); + if (ret <= 0) { - d_printf("no reply to cldap netlogon\n"); + d_printf("no reply received to cldap netlogon\n"); return -1; } blob.length = ret; @@ -180,6 +181,11 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) asn1_end_tag(&data); asn1_end_tag(&data); + if (data.has_error) { + d_printf("Failed to parse cldap reply\n"); + return -1; + } + file_save("cldap_reply_core.dat", os3.data, os3.length); p = os3.data; @@ -207,6 +213,18 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply) } +/* + free a cldap reply packet +*/ +static void cldap_reply_free(struct cldap_netlogon_reply *reply) +{ + SAFE_FREE(reply->domain); + SAFE_FREE(reply->server_name); + SAFE_FREE(reply->domain_flatname); + SAFE_FREE(reply->server_flatname); + SAFE_FREE(reply->dns_name); +} + /* do a cldap netlogon query */ @@ -233,6 +251,10 @@ int ads_cldap_netlogon(ADS_STRUCT *ads) ret = recv_cldap_netlogon(sock, &reply); close(sock); + if (ret == -1) { + return -1; + } + d_printf("Version: 0x%x\n", reply.version); d_printf("GUID: "); print_guid(&reply.guid); @@ -242,6 +264,8 @@ int ads_cldap_netlogon(ADS_STRUCT *ads) d_printf("Flatname: %s\n", reply.domain_flatname); d_printf("Server Name2: %s\n", reply.server_flatname); d_printf("DNS Name: %s\n", reply.dns_name); + + cldap_reply_free(&reply); return ret; } -- cgit From 907bec35135e803c04717482767a953b6c5fa2cb Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 27 Aug 2002 22:34:14 +0000 Subject: add hook for MSG_PRINTER_DRVUPGRADE that numps the change_id on all printers bound to a given driver (This used to be commit e913d508d4f894eb3f0e59b9c28b0fc5b56962ec) --- source3/utils/smbcontrol.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/utils') diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index 2d78b21dcc..5401755376 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -42,6 +42,7 @@ static struct { {"dmalloc-mark", MSG_REQ_DMALLOC_MARK }, {"dmalloc-log-changed", MSG_REQ_DMALLOC_LOG_CHANGED }, {"shutdown", MSG_SHUTDOWN }, + {"change_id", MSG_PRINTER_DRVUPGRADE}, {NULL, -1} }; @@ -553,6 +554,10 @@ static BOOL do_command(char *dest, char *msg_name, int iparams, char **params) if (!send_message(dest, MSG_SHUTDOWN, NULL, 0, False)) return False; break; + case MSG_PRINTER_DRVUPGRADE: + if (!send_message(dest, MSG_PRINTER_DRVUPGRADE, params[0], 0, False)) + return False; + break; } return (True); -- cgit From 2b2b0f7119fe043f61259579ce70e782f5f9ec5f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 28 Aug 2002 04:54:43 +0000 Subject: Put in intermediate version of new SAM system. It's not stable yet, code might be ugly, etc - please don't blame me for anything but instead try to fix the code :-). Compiling of the new sam system can be enabled with the configure option --with-sam Removing passdb/passgrp.c as it's unused fix typo in utils/testparm.c (This used to be commit 4b7de5ee236c043e6169f137992baf09a95c6f2c) --- source3/utils/testparm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/utils') diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c index 852472073b..d48cecba47 100644 --- a/source3/utils/testparm.c +++ b/source3/utils/testparm.c @@ -48,7 +48,7 @@ static int do_global_checks(void) SMB_STRUCT_STAT st; if (lp_security() >= SEC_DOMAIN && !lp_encrypted_passwords()) { - printf("ERROR: in 'security=domain' mode the 'encrypt passwords' parameter must also be set to 'true'.\n"); + printf("ERROR: in 'security=domain' mode the 'encrypt passwords' parameter must always be set to 'true'.\n"); ret = 1; } -- cgit From 32da080463d56d70622279e1f9224e95b37a4f01 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 28 Aug 2002 10:34:28 +0000 Subject: 'No news is good news' might sometimes be confusing, at least to me :-) Volker (This used to be commit f76a5431f0448efbc879aee965c643e2e362632a) --- source3/utils/net_rpc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/utils') diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index a7d2a08b38..cb5350b3ed 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -243,6 +243,7 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl extern pstring global_myname; fstring trust_passwd; unsigned char orig_trust_passwd_hash[16]; + NTSTATUS result; fstrcpy(trust_passwd, global_myname); strlower(trust_passwd); @@ -256,7 +257,12 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl E_md4hash(trust_passwd, orig_trust_passwd_hash); - return trust_pw_change_and_store_it(cli, mem_ctx, orig_trust_passwd_hash); + result = trust_pw_change_and_store_it(cli, mem_ctx, orig_trust_passwd_hash); + + if (NT_STATUS_IS_OK(result)) + printf("Joined domain %s.\n",lp_workgroup()); + + return result; } /** -- cgit From d5a4242d8880aca23210d7c2c019eda5b3e52eb3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 29 Aug 2002 08:00:15 +0000 Subject: show builtin groups in samdump (This used to be commit c1e00f5f160985323f5a9ade42f2ebb2a798b17c) --- source3/utils/net_rpc_samsync.c | 73 ++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 33 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index 44c3fdb26a..f9afb76875 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -43,7 +43,7 @@ static void display_alias_mem(uint32 rid, SAM_ALIAS_MEM_INFO *a) { int i; d_printf("Alias rid %u: ", rid); - for (i=0;inum_sids;i++) { + for (i=0;inum_members;i++) { d_printf("%s ", sid_string_static(&a->sids[i].sid)); } d_printf("\n"); @@ -88,19 +88,49 @@ static void display_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta) } } -/* dump sam database via samsync rpc calls */ -int rpc_samdump(int argc, const char **argv) + +static void dump_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds) { - TALLOC_CTX *mem_ctx = NULL; + unsigned last_rid = 0; + NTSTATUS result; + int i; + TALLOC_CTX *mem_ctx; SAM_DELTA_HDR *hdr_deltas; SAM_DELTA_CTR *deltas; uint32 num_deltas; + + if (!(mem_ctx = talloc_init())) { + return; + } + + d_printf("Dumping database %u\n", db_type); + + do { + result = cli_netlogon_sam_sync(cli, mem_ctx, ret_creds, db_type, last_rid+1, + &num_deltas, &hdr_deltas, &deltas); + clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), ret_creds); + last_rid = 0; + for (i = 0; i < num_deltas; i++) { + display_sam_entry(&hdr_deltas[i], &deltas[i]); + last_rid = hdr_deltas[i].target_rid; + if (last_rid == 0) { + break; + } + } + } while (last_rid && NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); + + talloc_destroy(mem_ctx); +} + +/* dump sam database via samsync rpc calls */ +int rpc_samdump(int argc, const char **argv) +{ NTSTATUS result; - int i; - unsigned last_rid=0; - DOM_CRED ret_creds; struct cli_state *cli = NULL; uchar trust_password[16]; + DOM_CRED ret_creds; + + ZERO_STRUCT(ret_creds); /* Connect to remote machine */ if (!(cli = net_make_ipc_connection(NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC))) { @@ -123,31 +153,11 @@ int rpc_samdump(int argc, const char **argv) goto fail; } - if (!(mem_ctx = talloc_init())) { - DEBUG(0,("talloc_init failed\n")); - goto fail; - } - - /* on first call the returnAuthenticator is empty */ - memset(&ret_creds, 0, sizeof(ret_creds)); - - /* Do sam synchronisation on the SAM database*/ - do { - result = cli_netlogon_sam_sync(cli, mem_ctx, &ret_creds, SAM_DATABASE_DOMAIN, last_rid+1, - &num_deltas, &hdr_deltas, &deltas); - clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds); - last_rid = 0; - for (i = 0; i < num_deltas; i++) { - display_sam_entry(&hdr_deltas[i], &deltas[i]); - last_rid = hdr_deltas[i].target_rid; - if (last_rid == 0) { - break; - } - } - } while (last_rid && NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); + dump_database(cli, SAM_DATABASE_DOMAIN, &ret_creds); + dump_database(cli, SAM_DATABASE_BUILTIN, &ret_creds); + dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); cli_nt_session_close(cli); - talloc_destroy(mem_ctx); return 0; @@ -155,8 +165,5 @@ fail: if (cli) { cli_nt_session_close(cli); } - if (mem_ctx) { - talloc_destroy(mem_ctx); - } return -1; } -- cgit From 957d9ab384696738fedf4bab9bd49978d3af75e7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 29 Aug 2002 10:36:05 +0000 Subject: There's more work to be done on samsync. Intermediate commit, now I get all the groups at least. Volker (This used to be commit 23a4f6991e93797afad0043689737a1b20c67f60) --- source3/utils/net_rpc_samsync.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index f9afb76875..a41eae40d1 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -67,6 +67,17 @@ static void display_account_info(uint32 rid, SAM_ACCOUNT_INFO *a) smbpasswd_encode_acb_info(a->acb_info)); } +static void display_domain_info(SAM_DOMAIN_INFO *a) +{ + d_printf("Domain name: %s\n", unistr2_static(&a->uni_dom_name)); +} + +static void display_group_info(uint32 rid, SAM_GROUP_INFO *a) +{ + d_printf("Group '%s' ", unistr2_static(&a->uni_grp_name)); + d_printf("desc='%s', rid=%u\n", unistr2_static(&a->uni_grp_desc), rid); +} + static void display_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta) { switch (hdr_delta->type) { @@ -82,6 +93,12 @@ static void display_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta) case SAM_DELTA_ALIAS_MEM: display_alias_mem(hdr_delta->target_rid, &delta->als_mem_info); break; + case SAM_DELTA_DOMAIN_INFO: + display_domain_info(&delta->domain_info); + break; + case SAM_DELTA_GROUP_INFO: + display_group_info(hdr_delta->target_rid, &delta->group_info); + break; default: d_printf("Unknown delta record type %d\n", hdr_delta->type); break; @@ -91,7 +108,7 @@ static void display_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta) static void dump_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds) { - unsigned last_rid = 0; + unsigned last_rid = -1; NTSTATUS result; int i; TALLOC_CTX *mem_ctx; @@ -113,9 +130,6 @@ static void dump_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret for (i = 0; i < num_deltas; i++) { display_sam_entry(&hdr_deltas[i], &deltas[i]); last_rid = hdr_deltas[i].target_rid; - if (last_rid == 0) { - break; - } } } while (last_rid && NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); @@ -155,7 +169,9 @@ int rpc_samdump(int argc, const char **argv) dump_database(cli, SAM_DATABASE_DOMAIN, &ret_creds); dump_database(cli, SAM_DATABASE_BUILTIN, &ret_creds); - dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); + + /* Currently we crash on PRIVS somewhere in unmarshalling */ + /* Dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); */ cli_nt_session_close(cli); -- cgit From dcd029169424d8846c1fbb0b1527516a4a026b27 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 30 Aug 2002 06:59:57 +0000 Subject: convert the LDAP/SASL code to use GSS-SPNEGO if possible we now do this: - look for suported SASL mechanisms on the LDAP server - choose GSS-SPNEGO if possible - within GSS-SPNEGO choose KRB5 if we can do a kinit - otherwise use NTLMSSP This change also means that we no longer rely on having a gssapi library to do ADS. todo: - add TLS/SSL support over LDAP - change to using LDAP/SSL for password change in ADS (This used to be commit b04e91f660d3b26d23044075d4a7e707eb41462d) --- source3/utils/net_ads.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/utils') diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 16450c5b29..eb1c3fe059 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -653,6 +653,10 @@ int net_ads_join(int argc, const char **argv) return -1; } + if (ads_kinit_password(ads)) { + return -1; + } + rc = ads_set_machine_password(ads, global_myname, password); if (!ADS_ERR_OK(rc)) { d_printf("ads_set_machine_password: %s\n", ads_errstr(rc)); -- cgit From cfb5e91178eb8befdb00780a819f9c5cd3eee8e4 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Fri, 30 Aug 2002 10:46:59 +0000 Subject: added cli_net_auth_3 client code. changed cli_nt_setup_creds() to call cli_net_auth_2 or cli_net_auth_3 based on a switch. pass also the negociation flags all the way. all the places calling cli_nt_setup_creds() are still using cli_net_aut2(), it's just for future use and for rpcclient. in the future we will be able to call auth_2 or auth_3 as we want. J.F. (This used to be commit 4d38caca40f98d0584fefb9d66424a3db5b5789e) --- source3/utils/net_rpc_join.c | 3 ++- source3/utils/net_rpc_samsync.c | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index c8be93c39c..b08095f1cc 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -49,6 +49,7 @@ int net_rpc_join_ok(const char *domain) int retval = 1; uint32 channel; NTSTATUS result; + uint32 neg_flags = 0x000001ff; /* Connect to remote machine */ if (!(cli = net_make_ipc_connection(NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC))) { @@ -75,7 +76,7 @@ int net_rpc_join_ok(const char *domain) CHECK_RPC_ERR(cli_nt_setup_creds(cli, channel, - stored_md4_trust_password), + stored_md4_trust_password, &neg_flags, 2), "error in domain join verification"); retval = 0; /* Success! */ diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index a41eae40d1..4ddb931adb 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -143,6 +143,8 @@ int rpc_samdump(int argc, const char **argv) struct cli_state *cli = NULL; uchar trust_password[16]; DOM_CRED ret_creds; + uint32 neg_flags = 0x000001ff; + ZERO_STRUCT(ret_creds); @@ -161,7 +163,7 @@ int rpc_samdump(int argc, const char **argv) goto fail; } - result = cli_nt_setup_creds(cli, SEC_CHAN_BDC, trust_password); + result = cli_nt_setup_creds(cli, SEC_CHAN_BDC, trust_password, &neg_flags, 2); if (!NT_STATUS_IS_OK(result)) { d_printf("Failed to setup BDC creds\n"); goto fail; -- cgit From 21a58f5a64e202c0daa99d6924b933f324350946 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 1 Sep 2002 07:52:54 +0000 Subject: Fix segfault in net command (This used to be commit 26bee60a419593a5afe4e48614f7f3fc414596a5) --- source3/utils/net_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/utils') diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index cb5350b3ed..25ed337c1f 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -2141,7 +2141,7 @@ BOOL net_rpc_check(unsigned flags) /* flags (i.e. server type) may depend on command */ if (!net_find_server(flags, &server_ip, &server_name)) - goto done; + return False; ZERO_STRUCT(cli); if (cli_initialise(&cli) == False) -- cgit From eec38ee3bb4bceeaa82abf8df1cce92b6a5781ce Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 6 Sep 2002 11:46:59 +0000 Subject: Patch from "Stefan (metze) Metzmacher" to extend the ADS_STATUS system to include NTSTATUS, and to provide a better general infrustructure for his sam_ads work. I've also added some extra failure mode DEBUG()s to parts of the code. NOTE: The ADS_ERR_OK() macro is rather sensitive to braketing issues - without the final set of brakets, the test is essentially inverted - causing some intersting 'error = success' messages... Andrew Bartlett (This used to be commit 5b9a7ab901bc311f3ad08462a8a68d133c34a8b4) --- source3/utils/net_ads.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/utils') diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index eb1c3fe059..8c85bd82f9 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -635,7 +635,7 @@ int net_ads_join(int argc, const char **argv) rc = ads_search_dn(ads, &res, dn, NULL); ads_msgfree(ads, res); - if (rc.error_type == ADS_ERROR_LDAP && rc.rc == LDAP_NO_SUCH_OBJECT) { + if (rc.error_type == ADS_ERROR_LDAP && rc.err.rc == LDAP_NO_SUCH_OBJECT) { d_printf("ads_join_realm: organizational unit %s does not exist (dn:%s)\n", org_unit, dn); return -1; -- cgit From 789d51b42ceb2d99658c72bf55904083d451fcab Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 6 Sep 2002 13:37:11 +0000 Subject: This is the 'easy' parts of the trusted domains patch n+3 patch from Rafal Szczesniak It includes a conversion of make_user_info*() to NTSTATUS and some minor changes to other files. It also picks up on a nasty segfault that can occour in some security=domain cases. Andrew Bartlett (This used to be commit d1e1fc3e4bf72717b3593685f0ea5750d676952a) --- source3/utils/net_rpc.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/utils') diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 25ed337c1f..4067ce344d 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1972,6 +1972,12 @@ static int rpc_trustdom_list(int argc, const char **argv) d_printf("%s%s%s\n", trusted_dom_names[i], padding, ascii_sid); }; + + /* + * in case of no trusted domains say something rather + * than just display blank line + */ + if (!num_domains) d_printf("none\n"); } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)); @@ -2076,6 +2082,8 @@ static int rpc_trustdom_list(int argc, const char **argv) }; }; + if (!num_domains) d_printf("none\n"); + } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)); /* close opened samr and domain policy handles */ -- cgit From 1bc851e3146627324734fc62e3ce13e680ae48ae Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 10 Sep 2002 21:48:07 +0000 Subject: removing compiler warnings about shadowed globals (This used to be commit 6f0561acadd139e37f86e30a2bbf10f428178eaf) --- source3/utils/smbpasswd.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index 98993676c9..75a4319cb9 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -217,23 +217,23 @@ static int process_options(int argc, char **argv, int local_flags) *************************************************************/ static char *stdin_new_passwd(void) { - static fstring new_passwd; + static fstring new_pw; size_t len; - ZERO_ARRAY(new_passwd); + ZERO_ARRAY(new_pw); /* * if no error is reported from fgets() and string at least contains * the newline that ends the password, then replace the newline with * a null terminator. */ - if ( fgets(new_passwd, sizeof(new_passwd), stdin) != NULL) { - if ((len = strlen(new_passwd)) > 0) { - if(new_passwd[len-1] == '\n') - new_passwd[len - 1] = 0; + if ( fgets(new_pw, sizeof(new_pw), stdin) != NULL) { + if ((len = strlen(new_pw)) > 0) { + if(new_pw[len-1] == '\n') + new_pw[len - 1] = 0; } } - return(new_passwd); + return(new_pw); } @@ -259,20 +259,20 @@ static char *get_pass( char *prompt, BOOL stdin_get) static char *prompt_for_new_password(BOOL stdin_get) { char *p; - fstring new_passwd; + fstring new_pw; - ZERO_ARRAY(new_passwd); + ZERO_ARRAY(new_pw); p = get_pass("New SMB password:", stdin_get); - fstrcpy(new_passwd, p); + fstrcpy(new_pw, p); SAFE_FREE(p); p = get_pass("Retype new SMB password:", stdin_get); - if (strcmp(p, new_passwd)) { + if (strcmp(p, new_pw)) { fprintf(stderr, "Mismatch - password unchanged.\n"); - ZERO_ARRAY(new_passwd); + ZERO_ARRAY(new_pw); SAFE_FREE(p); return NULL; } @@ -285,27 +285,27 @@ static char *prompt_for_new_password(BOOL stdin_get) Change a password either locally or remotely. *************************************************************/ -static BOOL password_change(const char *remote_machine, char *user_name, - char *old_passwd, char *new_passwd, int local_flags) +static BOOL password_change(const char *remote_mach, char *username, + char *old_passwd, char *new_pw, int local_flags) { BOOL ret; pstring err_str; pstring msg_str; - if (remote_machine != NULL) { + if (remote_mach != NULL) { if (local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER| LOCAL_TRUST_ACCOUNT|LOCAL_SET_NO_PASSWORD)) { /* these things can't be done remotely yet */ return False; } - ret = remote_password_change(remote_machine, user_name, - old_passwd, new_passwd, err_str, sizeof(err_str)); + ret = remote_password_change(remote_mach, username, + old_passwd, new_pw, err_str, sizeof(err_str)); if(*err_str) fprintf(stderr, err_str); return ret; } - ret = local_password_change(user_name, local_flags, new_passwd, + ret = local_password_change(username, local_flags, new_pw, err_str, sizeof(err_str), msg_str, sizeof(msg_str)); if(*msg_str) -- cgit From cdca2ad1c4ca396e130a1091063c3aeedbb06cd8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 11 Sep 2002 14:07:21 +0000 Subject: added gencache implementation from mimir - thanks! (This used to be commit 05a202c287f5daeb1ccbaf9479aa93e7928e93db) --- source3/utils/net.c | 1 + source3/utils/net_cache.c | 328 ++++++++++++++++++++++++++++++++++++++++++++++ source3/utils/net_help.c | 1 + 3 files changed, 330 insertions(+) create mode 100644 source3/utils/net_cache.c (limited to 'source3/utils') diff --git a/source3/utils/net.c b/source3/utils/net.c index a3aa7adcae..e3cfc24b69 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -352,6 +352,7 @@ static struct functable net_func[] = { {"TIME", net_time}, {"LOOKUP", net_lookup}, {"JOIN", net_join}, + {"CACHE", net_cache}, {"HELP", net_help}, {NULL, NULL} diff --git a/source3/utils/net_cache.c b/source3/utils/net_cache.c new file mode 100644 index 0000000000..359c06d1aa --- /dev/null +++ b/source3/utils/net_cache.c @@ -0,0 +1,328 @@ +/* + Samba Unix/Linux SMB client library + Distributed SMB/CIFS Server Management Utility + Copyright (C) Rafal Szczesniak 2002 + + 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 "net.h" + +/** + * @file net_cache.c + * @brief This is part of the net tool which is basically command + * line wrapper for gencache.c functions (mainly for testing) + * + **/ + + +/* + * These routines are used via gencache_iterate() to display the cache's contents + * (print_cache_entry) and to flush it (delete_cache_entry). + * Both of them are defined by first arg of gencache_iterate() routine. + */ +static void print_cache_entry(const char* keystr, const char* datastr, const time_t timeout) +{ + char* timeout_str = ctime(&timeout); + timeout_str[strlen(timeout_str) - 1] = '\0'; + d_printf("Key: %s\t\t Value: %s\t\t Timeout: %s %s\n", keystr, datastr, + timeout_str, timeout > time(NULL) ? "": "(expired)"); +} + +static void delete_cache_entry(const char* keystr, const char* datastr, const time_t timeout) +{ + if (!gencache_del(keystr)) + d_printf("Couldn't delete entry! key = %s", keystr); +} + + +/** + * Parse text representation of timeout value + * + * @param timeout_str string containing text representation of the timeout + * @return numeric timeout of time_t type + **/ +static time_t parse_timeout(const char* timeout_str) +{ + char sign = '\0', *number = NULL, unit = '\0'; + int len, number_begin, number_end; + time_t timeout; + + /* sign detection */ + if (timeout_str[0] == '!' || timeout_str[0] == '+') { + sign = timeout_str[0]; + number_begin = 1; + } else { + number_begin = 0; + } + + /* unit detection */ + len = strlen(timeout_str); + switch (timeout_str[len - 1]) { + case 's': + case 'm': + case 'h': + case 'd': + case 'w': unit = timeout_str[len - 1]; + } + + /* number detection */ + len = (sign) ? strlen(&timeout_str[number_begin]) : len; + number_end = (unit) ? len - 1 : len; + number = strndup(&timeout_str[number_begin], number_end); + + /* calculate actual timeout value */ + timeout = (time_t)atoi(number); + + switch (unit) { + case 'm': timeout *= 60; break; + case 'h': timeout *= 60*60; break; + case 'd': timeout *= 60*60*24; break; + case 'w': timeout *= 60*60*24*7; break; /* that's fair enough, I think :) */ + } + + switch (sign) { + case '!': timeout = time(NULL) - timeout; break; + case '+': + default: timeout += time(NULL); break; + } + + if (number) SAFE_FREE(number); + return timeout; +} + + +/** + * Add an entry to the cache + * + * @param argv key, value and timeout are passed in command line + * @return 0 on success, otherwise failure + **/ +static int net_cache_add(int argc, const char **argv) +{ + const char *keystr, *datastr, *timeout_str; + time_t timeout; + + if (argc < 3) { + d_printf("\nUsage: net cache add \n"); + return -1; + } + + keystr = argv[0]; + datastr = argv[1]; + timeout_str = argv[2]; + + /* parse timeout given in command line */ + timeout = parse_timeout(timeout_str); + if (!timeout) { + d_printf("Invalid timeout argument.\n"); + return -1; + } + + if (gencache_add(keystr, datastr, timeout)) { + d_printf("New cache entry stored successfully.\n"); + gencache_shutdown(); + return 0; + } + + d_printf("Entry couldn't be added. Perhaps there's already such a key.\n"); + gencache_shutdown(); + return -1; +} + + +/** + * Set new value of an existing entry in the cache + * + * @param argv key being searched and new value and timeout to set in the entry + * @return 0 on success, otherwise failure + **/ +static int net_cache_set(int argc, const char **argv) +{ + const char *keystr, *datastr, *timeout_str; + time_t timeout; + + if (argc < 3) { + d_printf("\nUsage: net cache set \n"); + return -1; + } + + keystr = argv[0]; + datastr = argv[1]; + timeout_str = argv[2]; + + /* parse timeout given in command line */ + timeout = parse_timeout(timeout_str); + if (!timeout) { + d_printf("Invalid timeout argument.\n"); + return -1; + } + + if (gencache_set(keystr, datastr, timeout)) { + d_printf("Cache entry set successfully.\n"); + gencache_shutdown(); + return 0; + } + + d_printf("Entry couldn't be set. Perhaps there's no such a key.\n"); + gencache_shutdown(); + return -1; +} + + +/** + * Delete an entry in the cache + * + * @param argv key to delete an entry of + * @return 0 on success, otherwise failure + **/ +static int net_cache_del(int argc, const char **argv) +{ + const char *keystr = argv[0]; + + if (argc < 1) { + d_printf("\nUsage: net cache add \n"); + return -1; + } + + if(gencache_del(keystr)) { + d_printf("Entry deleted.\n"); + return 0; + } + + d_printf("Couldn't delete specified entry\n"); + return -1; +} + + +/** + * Get and display an entry from the cache + * + * @param argv key to search an entry of + * @return 0 on success, otherwise failure + **/ +static int net_cache_get(int argc, const char **argv) +{ + const char* keystr = argv[0]; + char* valuestr; + time_t timeout; + + if (argc < 1) { + d_printf("\nUsage: net cache get \n"); + return -1; + } + + if (gencache_get(keystr, &valuestr, &timeout)) { + print_cache_entry(keystr, valuestr, timeout); + return 0; + } + + d_printf("Failed to find entry\n"); + return -1; +} + + +/** + * Search an entry/entries in the cache + * + * @param argv key pattern to match the entries to + * @return 0 on success, otherwise failure + **/ +static int net_cache_search(int argc, const char **argv) +{ + const char* pattern; + + if (argc < 1) { + d_printf("Usage: net cache search \n"); + return -1; + } + + pattern = argv[0]; + gencache_iterate(print_cache_entry, pattern); + return 0; +} + + +/** + * List the contents of the cache + * + * @param argv ignored in this functionailty + * @return always returns 0 + **/ +static int net_cache_list(int argc, const char **argv) +{ + const char* pattern = "*"; + gencache_iterate(print_cache_entry, pattern); + gencache_shutdown(); + return 0; +} + + +/** + * Flush the whole cache + * + * @param argv ignored in this functionality + * @return always returns 0 + **/ +static int net_cache_flush(int argc, const char **argv) +{ + const char* pattern = "*"; + gencache_iterate(delete_cache_entry, pattern); + gencache_shutdown(); + return 0; +} + + +/** + * Short help + * + * @param argv ignored in this functionality + * @return always returns -1 + **/ +static int net_cache_usage(int argc, const char **argv) +{ + d_printf(" net cache add \t add add new cache entry\n"); + d_printf(" net cache set \t set new value for existing cache entry\n"); + d_printf(" net cache del \t delete existing cache entry by key\n"); + d_printf(" net cache flush \t delete all entries existing in the cache\n"); + d_printf(" net cache get \t get cache entry by key\n"); + d_printf(" net cache search \t search for entries in the cache, by given pattern\n"); + d_printf(" net cache list \t list all cache entries (just like search for \"*\")\n"); + return -1; +} + + +/** + * Entry point to 'net cache' subfunctionality + * + * @param argv arguments passed to further called functions + * @return whatever further functions return + **/ +int net_cache(int argc, const char **argv) +{ + struct functable func[] = { + {"add", net_cache_add}, + {"set", net_cache_set}, + {"del", net_cache_del}, + {"get", net_cache_get}, + {"search", net_cache_search}, + {"list", net_cache_list}, + {"flush", net_cache_flush}, + {NULL, NULL} + }; + + return net_run_function(argc, argv, func, net_cache_usage); +} diff --git a/source3/utils/net_help.c b/source3/utils/net_help.c index ab3eac4b43..16309c5334 100644 --- a/source3/utils/net_help.c +++ b/source3/utils/net_help.c @@ -135,6 +135,7 @@ static int net_usage(int argc, const char **argv) " net user\t\tto manage users\n"\ " net group\t\tto manage groups\n"\ " net join\t\tto join a domain\n"\ + " net cache\t\tto operate on cache tdb file\n"\ "\n"\ " net ads \tto run ADS commands\n"\ " net rap \tto run RAP (pre-RPC) commands\n"\ -- cgit From b33681fc0b8ef7b9fa91c154f7c3117afafa349e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 17 Sep 2002 12:12:50 +0000 Subject: Add clock skew handling to our kerberos code. This allows us to cope with the DC being out of sync with the local machine. (This used to be commit 0d28d769472ea3b98ae4c8757093dfd4499f6dd1) --- source3/utils/net_ads.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 8c85bd82f9..af290ce83c 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -66,7 +66,7 @@ static int net_ads_lookup(int argc, const char **argv) ads = ads_init(NULL, NULL, opt_host); if (ads) { - ads->auth.no_bind = 1; + ads->auth.flags |= ADS_AUTH_NO_BIND; } ads_connect(ads); @@ -88,7 +88,7 @@ static int net_ads_info(int argc, const char **argv) ads = ads_init(NULL, NULL, opt_host); if (ads) { - ads->auth.no_bind = 1; + ads->auth.flags |= ADS_AUTH_NO_BIND; } ads_connect(ads); @@ -103,6 +103,7 @@ static int net_ads_info(int argc, const char **argv) d_printf("Realm: %s\n", ads->config.realm); d_printf("Bind Path: %s\n", ads->config.bind_path); d_printf("LDAP port: %d\n", ads->ldap_port); + d_printf("Server time: %s\n", http_timestring(ads->config.current_time)); return 0; } @@ -199,7 +200,7 @@ static int net_ads_workgroup(int argc, const char **argv) -static void usergrp_display(char *field, void **values, void *data_area) +static BOOL usergrp_display(char *field, void **values, void *data_area) { char **disp_fields = (char **) data_area; @@ -213,15 +214,16 @@ static void usergrp_display(char *field, void **values, void *data_area) } SAFE_FREE(disp_fields[0]); SAFE_FREE(disp_fields[1]); - return; + return True; } if (!values) /* must be new field, indicate string field */ - return; + return True; if (StrCaseCmp(field, "sAMAccountName") == 0) { disp_fields[0] = strdup((char *) values[0]); } if (StrCaseCmp(field, "description") == 0) disp_fields[1] = strdup((char *) values[0]); + return True; } static int net_ads_user_usage(int argc, const char **argv) @@ -270,7 +272,7 @@ static int ads_user_add(int argc, const char **argv) /* try setting the password */ asprintf(&upn, "%s@%s", argv[0], ads->config.realm); - status = krb5_set_password(ads->auth.kdc_server, upn, argv[1]); + status = krb5_set_password(ads->auth.kdc_server, upn, argv[1], ads->auth.time_offset); safe_free(upn); if (ADS_ERR_OK(status)) { d_printf("User %s added\n", argv[0]); @@ -653,7 +655,9 @@ int net_ads_join(int argc, const char **argv) return -1; } - if (ads_kinit_password(ads)) { + rc = ads_domain_sid(ads, &dom_sid); + if (!ADS_ERR_OK(rc)) { + d_printf("ads_domain_sid: %s\n", ads_errstr(rc)); return -1; } @@ -663,12 +667,6 @@ int net_ads_join(int argc, const char **argv) return -1; } - rc = ads_domain_sid(ads, &dom_sid); - if (!ADS_ERR_OK(rc)) { - d_printf("ads_domain_sid: %s\n", ads_errstr(rc)); - return -1; - } - if (!secrets_store_domain_sid(lp_workgroup(), &dom_sid)) { DEBUG(1,("Failed to save domain sid\n")); return -1; @@ -885,7 +883,7 @@ static int net_ads_password(int argc, const char **argv) new_password = getpass(prompt); ret = kerberos_set_password(ads->auth.kdc_server, auth_principal, - auth_password, argv[0], new_password); + auth_password, argv[0], new_password, ads->auth.time_offset); if (!ADS_ERR_OK(ret)) { d_printf("Password change failed :-( ...\n"); ads_destroy(&ads); -- cgit From c9ab9fe826a38e36a0f3c6b7924db8ce8fe70213 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Wed, 18 Sep 2002 06:11:13 +0000 Subject: Add a synonym for samdump ... (This used to be commit a8dc1464ea2d05eb2a26afdd433cdb6b69002259) --- source3/utils/net_rpc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/utils') diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 4067ce344d..50c14c6f5b 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -2260,6 +2260,7 @@ int net_rpc(int argc, const char **argv) {"abortshutdown", rpc_shutdown_abort}, {"shutdown", rpc_shutdown}, {"samdump", rpc_samdump}, + {"vampire", rpc_samdump}, {"getsid", net_rpc_getsid}, {"help", net_rpc_help}, {NULL, NULL} -- cgit From e59d5b50fe882cb1b65ca2f665b0c93c6273c436 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 18 Sep 2002 06:34:10 +0000 Subject: First code for 'net rpc vampire'. We should probably find a more positive name for this. It creates users and global groups. More to come. Volker (This used to be commit 0c1fadd9e024ef886542d362a7f119968552852d) --- source3/utils/net_rpc.c | 2 +- source3/utils/net_rpc_samsync.c | 278 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 279 insertions(+), 1 deletion(-) (limited to 'source3/utils') diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 50c14c6f5b..3192768931 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -2260,7 +2260,7 @@ int net_rpc(int argc, const char **argv) {"abortshutdown", rpc_shutdown_abort}, {"shutdown", rpc_shutdown}, {"samdump", rpc_samdump}, - {"vampire", rpc_samdump}, + {"vampire", rpc_vampire}, {"getsid", net_rpc_getsid}, {"help", net_rpc_help}, {NULL, NULL} diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index 4ddb931adb..6d8b7c672f 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -185,3 +185,281 @@ fail: } return -1; } + +/* Convert a SAM_ACCOUNT_DELTA to a SAM_ACCOUNT. */ + +static NTSTATUS +sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta) +{ + DOM_SID sid; + fstring s; + + /* Username, fullname, home dir, dir drive, logon script, acct + desc, workstations, profile. */ + + unistr2_to_ascii(s, &delta->uni_acct_name, sizeof(s) - 1); + pdb_set_nt_username(account, s); + + /* Unix username is the same - for sainity */ + pdb_set_username(account, s); + + unistr2_to_ascii(s, &delta->uni_full_name, sizeof(s) - 1); + pdb_set_fullname(account, s); + + unistr2_to_ascii(s, &delta->uni_home_dir, sizeof(s) - 1); + pdb_set_homedir(account, s, True); + + unistr2_to_ascii(s, &delta->uni_dir_drive, sizeof(s) - 1); + pdb_set_dir_drive(account, s, True); + + unistr2_to_ascii(s, &delta->uni_logon_script, sizeof(s) - 1); + pdb_set_logon_script(account, s, True); + + unistr2_to_ascii(s, &delta->uni_acct_desc, sizeof(s) - 1); + pdb_set_acct_desc(account, s); + + unistr2_to_ascii(s, &delta->uni_workstations, sizeof(s) - 1); + pdb_set_workstations(account, s); + + unistr2_to_ascii(s, &delta->uni_profile, sizeof(s) - 1); + pdb_set_profile_path(account, s, True); + + /* User and group sid */ + + sid_copy(&sid, get_global_sam_sid()); + sid_append_rid(&sid, delta->user_rid); + pdb_set_user_sid(account, &sid); + + sid_copy(&sid, get_global_sam_sid()); + sid_append_rid(&sid, delta->group_rid); + pdb_set_group_sid(account, &sid); + + /* Logon and password information */ + + pdb_set_logon_time(account, nt_time_to_unix(&delta->logon_time), True); + pdb_set_logoff_time(account, nt_time_to_unix(&delta->logoff_time), + True); + + pdb_set_logon_divs(account, delta->logon_divs); + + /* TODO: logon hours */ + /* TODO: bad password count */ + /* TODO: logon count */ + + pdb_set_pass_last_set_time( + account, nt_time_to_unix(&delta->pwd_last_set_time)); + + /* TODO: account expiry time */ + + pdb_set_acct_ctrl(account, delta->acb_info); + return NT_STATUS_OK; +} + +static NTSTATUS +fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) +{ + NTSTATUS nt_ret; + fstring account; + pstring add_script; + SAM_ACCOUNT *sam_account=NULL; + + fstrcpy(account, unistr2_static(&delta->uni_acct_name)); + d_printf("Creating account: %s\n", account); + + if (!NT_STATUS_IS_OK(nt_ret = pdb_init_sam(&sam_account))) + return nt_ret; + + if (!pdb_getsampwnam(sam_account, account)) { + struct passwd *pw; + + /* Create appropriate user */ + if (delta->acb_info & ACB_NORMAL) { + pstrcpy(add_script, lp_adduser_script()); + } else if ( (delta->acb_info & ACB_WSTRUST) || + (delta->acb_info & ACB_SVRTRUST) ) { + pstrcpy(add_script, lp_addmachine_script()); + } else { + DEBUG(1, ("Unknown user type: %s\n", + smbpasswd_encode_acb_info(delta->acb_info))); + pdb_free_sam(&sam_account); + return NT_STATUS_NO_SUCH_USER; + } + if (*add_script) { + int add_ret; + all_string_sub(add_script, "%u", account, + sizeof(account)); + add_ret = smbrun(add_script,NULL); + DEBUG(1,("fetch_account: Running the command `%s' " + "gave %d\n", add_script, add_ret)); + } + pw = getpwnam_alloc(account); + if (pw) { + nt_ret = pdb_init_sam_pw(&sam_account, pw); + + if (!NT_STATUS_IS_OK(nt_ret)) { + passwd_free(&pw); + pdb_free_sam(&sam_account); + return nt_ret; + } + passwd_free(&pw); + } else { + DEBUG(3, ("Could not create account %s\n", account)); + pdb_free_sam(&sam_account); + return NT_STATUS_NO_SUCH_USER; + } + } + + sam_account_from_delta(sam_account, delta); + pdb_add_sam_account(sam_account); + pdb_free_sam(&sam_account); + return NT_STATUS_OK; +} + +static NTSTATUS +fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta) +{ + fstring name; + fstring comment; + struct group *grp; + DOM_SID group_sid; + fstring sid_string; + GROUP_MAP map; + int flag = TDB_INSERT; + + unistr2_to_ascii(name, &delta->uni_grp_name, sizeof(name)-1); + unistr2_to_ascii(comment, &delta->uni_grp_desc, sizeof(comment)-1); + + if ((grp = getgrnam(name)) == NULL) + smb_create_group(name); + + if ((grp = getgrnam(name)) == NULL) + return NT_STATUS_ACCESS_DENIED; + + /* add the group to the mapping table */ + sid_copy(&group_sid, get_global_sam_sid()); + sid_append_rid(&group_sid, rid); + sid_to_string(sid_string, &group_sid); + + /* Add the group mapping */ + if (get_group_map_from_sid(group_sid, &map, False)) { + /* Don't TDB_INSERT, mapping exists */ + flag = 0; + } + + map.gid = grp->gr_gid; + map.sid = group_sid; + map.sid_name_use = SID_NAME_DOM_GRP; + fstrcpy(map.nt_name, name); + fstrcpy(map.comment, comment); + + map.priv_set.count = 0; + map.priv_set.set = NULL; + + add_mapping_entry(&map, flag); + + return NT_STATUS_OK; +} + +static void +fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta) +{ + switch(hdr_delta->type) { + case SAM_DELTA_ACCOUNT_INFO: + fetch_account_info(hdr_delta->target_rid, + &delta->account_info); + break; + case SAM_DELTA_GROUP_INFO: + fetch_group_info(hdr_delta->target_rid, + &delta->group_info); + break; + default: + d_printf("Unknown delta record type %d\n", hdr_delta->type); + break; + } +} + +static void +fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds) +{ + unsigned last_rid = -1; + NTSTATUS result; + int i; + TALLOC_CTX *mem_ctx; + SAM_DELTA_HDR *hdr_deltas; + SAM_DELTA_CTR *deltas; + uint32 num_deltas; + + if (!(mem_ctx = talloc_init())) { + return; + } + + d_printf("Fetching database %u\n", db_type); + + do { + result = cli_netlogon_sam_sync(cli, mem_ctx, ret_creds, + db_type, last_rid+1, + &num_deltas, + &hdr_deltas, &deltas); + clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), + ret_creds); + last_rid = 0; + for (i = 0; i < num_deltas; i++) { + fetch_sam_entry(&hdr_deltas[i], &deltas[i]); + last_rid = hdr_deltas[i].target_rid; + } + } while (last_rid && NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); + + talloc_destroy(mem_ctx); +} + +/* dump sam database via samsync rpc calls */ +int rpc_vampire(int argc, const char **argv) +{ + NTSTATUS result; + struct cli_state *cli = NULL; + uchar trust_password[16]; + DOM_CRED ret_creds; + uint32 neg_flags = 0x000001ff; + + ZERO_STRUCT(ret_creds); + + /* Connect to remote machine */ + if (!(cli = net_make_ipc_connection(NET_FLAGS_ANONYMOUS | + NET_FLAGS_PDC))) { + return 1; + } + + if (!cli_nt_session_open(cli, PIPE_NETLOGON)) { + DEBUG(0,("Error connecting to NETLOGON pipe\n")); + goto fail; + } + + if (!secrets_fetch_trust_account_password(lp_workgroup(), + trust_password, NULL)) { + d_printf("Could not retrieve domain trust secret"); + goto fail; + } + + result = cli_nt_setup_creds(cli, SEC_CHAN_BDC, trust_password, + &neg_flags, 2); + if (!NT_STATUS_IS_OK(result)) { + d_printf("Failed to setup BDC creds\n"); + goto fail; + } + + fetch_database(cli, SAM_DATABASE_DOMAIN, &ret_creds); + fetch_database(cli, SAM_DATABASE_BUILTIN, &ret_creds); + + /* Currently we crash on PRIVS somewhere in unmarshalling */ + /* Dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); */ + + cli_nt_session_close(cli); + + return 0; + +fail: + if (cli) { + cli_nt_session_close(cli); + } + return -1; +} -- cgit From d06d2c876e3f295715e818fa6869d968e32b3dc4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Sep 2002 10:30:00 +0000 Subject: Change parsing of policy and privs delta to what Ethereal says. Volker (This used to be commit 8c41b5cd1b8b0c2639def9552bd20b8aca39785c) --- source3/utils/net_rpc_samsync.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index 6d8b7c672f..9d54a771fc 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -171,9 +171,7 @@ int rpc_samdump(int argc, const char **argv) dump_database(cli, SAM_DATABASE_DOMAIN, &ret_creds); dump_database(cli, SAM_DATABASE_BUILTIN, &ret_creds); - - /* Currently we crash on PRIVS somewhere in unmarshalling */ - /* Dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); */ + dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); cli_nt_session_close(cli); -- cgit From cd2924f94efcb82683c702d4576aef85d33b8771 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Sep 2002 10:05:15 +0000 Subject: Add the ability to view/set the current local domain SIDs. Volker (This used to be commit f6ed429838cc0140c0d033875012c7a999891549) --- source3/utils/net.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'source3/utils') diff --git a/source3/utils/net.c b/source3/utils/net.c index e3cfc24b69..9363d1a6a0 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -329,6 +329,49 @@ static int net_file(int argc, const char **argv) return net_rap_file(argc, argv); } +static int net_setlocalsid(int argc, const char **argv) +{ + DOM_SID sid; + + if ( (argc != 1) + || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0) + || (!string_to_sid(&sid, argv[0])) + || (sid.num_auths != 4)) { + d_printf("usage: net setlocalsid S-1-5-21-x-y-z\n"); + return 1; + } + + if (!secrets_store_domain_sid(global_myname, &sid)) { + DEBUG(0,("Can't store domain SID as a pdc/bdc.\n")); + return 1; + } + + return 0; +} + +static int net_getdomainsid(int argc, const char **argv) +{ + DOM_SID domain_sid; + fstring sid_str; + + if (!secrets_fetch_domain_sid(global_myname, &domain_sid)) { + d_printf("Could not fetch local SID\n"); + return 1; + } + sid_to_string(sid_str, &domain_sid); + d_printf("SID for domain %s is: %s\n", global_myname, sid_str); + + if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { + d_printf("Could not fetch domain SID\n"); + return 1; + } + + sid_to_string(sid_str, &domain_sid); + d_printf("SID for domain %s is: %s\n", lp_workgroup(), sid_str); + + return 0; +} + /* main function table */ static struct functable net_func[] = { {"RPC", net_rpc}, @@ -353,6 +396,8 @@ static struct functable net_func[] = { {"LOOKUP", net_lookup}, {"JOIN", net_join}, {"CACHE", net_cache}, + {"SETLOCALSID", net_setlocalsid}, + {"GETDOMAINSID", net_getdomainsid}, {"HELP", net_help}, {NULL, NULL} -- cgit From 83ca90a67dd3db225706d32ffe58b114e1faf7d3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Sep 2002 15:36:02 +0000 Subject: Cosmetic fix for debug message. (This used to be commit 42774a7753eb8be1ec04bcb5dda089910a1b6d0b) --- source3/utils/net_rpc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 3192768931..8b8278b053 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -424,8 +424,7 @@ rpc_getsid_internals(const DOM_SID *domain_sid, struct cli_state *cli, sid_str, lp_workgroup()); if (!secrets_store_domain_sid(global_myname, domain_sid)) { - DEBUG(0,("pdb_generate_sam_sid: " - "Can't store domain SID as a pdc/bdc.\n")); + DEBUG(0,("Can't store domain SID\n")); return NT_STATUS_UNSUCCESSFUL; } -- cgit From 06ce201a29bb90a428a59a3d85752ccf2dca1bdd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Sep 2002 16:21:01 +0000 Subject: Ok, getting a bit more ambitious. Stop me, if this is wrong. ;-) When creating a group you have to take care of the fact that the underlying unix might not like the group name. This change gets around that problem by giving the add group script the chance to invent a group name. It then must only return the newly created numerical gid. Volker (This used to be commit b959419ed38e66a12b63cad3e5fbfa849f952acc) --- source3/utils/net_rpc_samsync.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index 9d54a771fc..95a813dcfd 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -323,14 +323,15 @@ fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta) fstring sid_string; GROUP_MAP map; int flag = TDB_INSERT; + gid_t gid; unistr2_to_ascii(name, &delta->uni_grp_name, sizeof(name)-1); unistr2_to_ascii(comment, &delta->uni_grp_desc, sizeof(comment)-1); if ((grp = getgrnam(name)) == NULL) - smb_create_group(name); + smb_create_group(name, &gid); - if ((grp = getgrnam(name)) == NULL) + if ((grp = getgrgid(gid)) == NULL) return NT_STATUS_ACCESS_DENIED; /* add the group to the mapping table */ -- cgit From 587c4c5aa67a4c589fb276fe2df355b443b1d086 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 23 Sep 2002 16:46:32 +0000 Subject: Add net getlocalsid [name] (This used to be commit 08c3e2b824cd2c93ca548fa18ea16a18f5b197e5) --- source3/utils/net.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'source3/utils') diff --git a/source3/utils/net.c b/source3/utils/net.c index 9363d1a6a0..800aeded0a 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -329,6 +329,31 @@ static int net_file(int argc, const char **argv) return net_rap_file(argc, argv); } +/* + Retrieve our local SID or the SID for the specified name + */ +static int net_getlocalsid(int argc, const char **argv) +{ + DOM_SID sid; + const char *name; + fstring sid_str; + + if (argc >= 1) { + name = argv[0]; + } + else { + name = global_myname; + } + + if (!secrets_fetch_domain_sid(name, &sid)) { + DEBUG(0, ("Can't fetch domain SID for name: %s\n", name)); + return 1; + } + sid_to_string(sid_str, &sid); + d_printf("SID for domain %s is: %s\n", name, sid_str); + return 0; +} + static int net_setlocalsid(int argc, const char **argv) { DOM_SID sid; @@ -396,6 +421,7 @@ static struct functable net_func[] = { {"LOOKUP", net_lookup}, {"JOIN", net_join}, {"CACHE", net_cache}, + {"GETLOCALSID", net_getlocalsid}, {"SETLOCALSID", net_setlocalsid}, {"GETDOMAINSID", net_getdomainsid}, -- cgit From 9264711576bff6b2c39be8a6aaad0024fbd4120f Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 23 Sep 2002 16:54:32 +0000 Subject: Update some help. People keep forgetting that! (This used to be commit b53547bf663ed1714326f9b0e74215e012e728af) --- source3/utils/net_help.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/utils') diff --git a/source3/utils/net_help.c b/source3/utils/net_help.c index 16309c5334..262670cb2a 100644 --- a/source3/utils/net_help.c +++ b/source3/utils/net_help.c @@ -58,7 +58,7 @@ static int help_usage(int argc, const char **argv) "\n"\ "Valid functions are:\n"\ " RPC RAP ADS FILE SHARE SESSION SERVER DOMAIN PRINTQ USER GROUP VALIDATE\n"\ -" GROUPMEMBER ADMIN SERVICE PASSWORD TIME LOOKUP\n"); +" GROUPMEMBER ADMIN SERVICE PASSWORD TIME LOOKUP GETLOCALSID SETLOCALSID\n"); return -1; } @@ -136,6 +136,8 @@ static int net_usage(int argc, const char **argv) " net group\t\tto manage groups\n"\ " net join\t\tto join a domain\n"\ " net cache\t\tto operate on cache tdb file\n"\ + " net getlocalsid [NAME]\tto get the SID for local name\n"\ + " net setlocalsid SID\tto set the local domain SID\n"\ "\n"\ " net ads \tto run ADS commands\n"\ " net rap \tto run RAP (pre-RPC) commands\n"\ -- cgit From 28947d6cd12040de37e3dfb29eeb1163cc429f32 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 24 Sep 2002 06:50:11 +0000 Subject: This is a first working version of net rpc vampire. First do a net rpc getsid, then join as a BDC, and then watch net rpc vampire suck out the good stuff out of a PDC :-). It's not perfect, but it does quite a bit for me. Watch out for more. Volker (This used to be commit f0d7ac9feb5844c93789344285b1d66f480209ba) --- source3/utils/net_rpc_samsync.c | 276 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 264 insertions(+), 12 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index 95a813dcfd..202d5b5c88 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -23,6 +23,8 @@ #include "includes.h" #include "../utils/net.h" +extern DOM_SID global_sid_Builtin; + static void display_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *g) { int i; @@ -191,6 +193,7 @@ sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta) { DOM_SID sid; fstring s; + uchar lm_passwd[16], nt_passwd[16]; /* Username, fullname, home dir, dir drive, logon script, acct desc, workstations, profile. */ @@ -235,9 +238,8 @@ sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta) /* Logon and password information */ pdb_set_logon_time(account, nt_time_to_unix(&delta->logon_time), True); - pdb_set_logoff_time(account, nt_time_to_unix(&delta->logoff_time), + pdb_set_logoff_time(account, nt_time_to_unix(&delta->logoff_time), True); - pdb_set_logon_divs(account, delta->logon_divs); /* TODO: logon hours */ @@ -247,6 +249,14 @@ sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta) pdb_set_pass_last_set_time( account, nt_time_to_unix(&delta->pwd_last_set_time)); + pdb_set_kickoff_time(account, get_time_t_max(), True); + + /* Decode hashes from password hash */ + sam_pwd_hash(delta->user_rid, delta->pass.buf_lm_pwd, lm_passwd, 0); + sam_pwd_hash(delta->user_rid, delta->pass.buf_nt_pwd, nt_passwd, 0); + pdb_set_nt_passwd(account, nt_passwd); + pdb_set_lanman_passwd(account, lm_passwd); + /* TODO: account expiry time */ pdb_set_acct_ctrl(account, delta->acb_info); @@ -260,6 +270,8 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) fstring account; pstring add_script; SAM_ACCOUNT *sam_account=NULL; + GROUP_MAP map; + struct group *grp; fstrcpy(account, unistr2_static(&delta->uni_acct_name)); d_printf("Creating account: %s\n", account); @@ -270,6 +282,8 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) if (!pdb_getsampwnam(sam_account, account)) { struct passwd *pw; + pdb_free_sam(&sam_account); + /* Create appropriate user */ if (delta->acb_info & ACB_NORMAL) { pstrcpy(add_script, lp_adduser_script()); @@ -308,7 +322,29 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) } sam_account_from_delta(sam_account, delta); - pdb_add_sam_account(sam_account); + + if (!pdb_add_sam_account(sam_account)) { + DEBUG(1, ("SAM Account for %s already existed, updating\n", + account)); + pdb_update_sam_account(sam_account); + } + + if (!get_group_map_from_sid(*pdb_get_group_sid(sam_account), + &map, False)) { + DEBUG(0, ("Primary group of %s has no mapping!\n", + pdb_get_username(sam_account))); + pdb_free_sam(&sam_account); + return NT_STATUS_NO_SUCH_GROUP; + } + + if (!(grp = getgrgid(map.gid))) { + DEBUG(0, ("Could not find unix group %d\n", map.gid)); + pdb_free_sam(&sam_account); + return NT_STATUS_NO_SUCH_GROUP; + } + + smb_set_primary_group(grp->gr_name, pdb_get_username(sam_account)); + pdb_free_sam(&sam_account); return NT_STATUS_OK; } @@ -318,7 +354,7 @@ fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta) { fstring name; fstring comment; - struct group *grp; + struct group *grp = NULL; DOM_SID group_sid; fstring sid_string; GROUP_MAP map; @@ -339,10 +375,24 @@ fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta) sid_append_rid(&group_sid, rid); sid_to_string(sid_string, &group_sid); - /* Add the group mapping */ if (get_group_map_from_sid(group_sid, &map, False)) { - /* Don't TDB_INSERT, mapping exists */ - flag = 0; + grp = getgrgid(map.gid); + flag = 0; /* Don't TDB_INSERT, mapping exists */ + } + + if (grp == NULL) + { + gid_t new_gid; + /* No group found from mapping, find it from its name. */ + if ((grp = getgrnam(name)) == NULL) { + /* No appropriate group found, create one */ + d_printf("Creating unix group: '%s'\n", name); + if (smb_create_group(name, &new_gid) != 0) + return NT_STATUS_ACCESS_DENIED; + } + + if ((grp = getgrgid(new_gid)) == NULL) + return NT_STATUS_ACCESS_DENIED; } map.gid = grp->gr_gid; @@ -359,8 +409,193 @@ fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta) return NT_STATUS_OK; } +static NTSTATUS +fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) +{ + int i; + TALLOC_CTX *t = NULL; + char **nt_members = NULL; + char **unix_members; + DOM_SID group_sid; + GROUP_MAP map; + struct group *grp; + + if (delta->num_members == 0) { + return NT_STATUS_OK; + } + + sid_copy(&group_sid, get_global_sam_sid()); + sid_append_rid(&group_sid, rid); + + if (!get_domain_group_from_sid(group_sid, &map, False)) { + DEBUG(0, ("Could not find global group %d\n", rid)); + return NT_STATUS_NO_SUCH_GROUP; + } + + if (!(grp = getgrgid(map.gid))) { + DEBUG(0, ("Could not find unix group %d\n", map.gid)); + return NT_STATUS_NO_SUCH_GROUP; + } + + d_printf("Group members of %s: ", grp->gr_name); + + if (!(t = talloc_init())) { + DEBUG(0, ("could not talloc_init\n")); + return NT_STATUS_NO_MEMORY; + } + + nt_members = talloc_zero(t, sizeof(char *) * delta->num_members); + + for (i=0; inum_members; i++) { + NTSTATUS nt_status; + SAM_ACCOUNT *member = NULL; + DOM_SID member_sid; + + if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(t, &member))) { + talloc_destroy(t); + return nt_status; + } + + sid_copy(&member_sid, get_global_sam_sid()); + sid_append_rid(&member_sid, delta->rids[i]); + + if (!pdb_getsampwsid(member, &member_sid)) { + DEBUG(1, ("Found bogus group member: %d\n", + delta->rids[i])); + pdb_free_sam(&member); + continue; + } + + if (pdb_get_group_rid(member) == rid) { + d_printf("%s(primary),", pdb_get_username(member)); + pdb_free_sam(&member); + continue; + } + + d_printf("%s,", pdb_get_username(member)); + nt_members[i] = talloc_strdup(t, pdb_get_username(member)); + pdb_free_sam(&member); + } + + d_printf("\n"); + + unix_members = grp->gr_mem; + + while (*unix_members) { + BOOL is_nt_member = False; + for (i=0; inum_members; i++) { + if (nt_members[i] == NULL) { + /* This was a primary group */ + continue; + } + + if (strcmp(*unix_members, nt_members[i]) == 0) { + is_nt_member = True; + break; + } + } + if (!is_nt_member) { + /* We look at a unix group member that is not + an nt group member. So, remove it. NT is + boss here. */ + smb_delete_user_group(grp->gr_name, *unix_members); + } + unix_members += 1; + } + + for (i=0; inum_members; i++) { + BOOL is_unix_member = False; + + if (nt_members[i] == NULL) { + /* This was the primary group */ + continue; + } + + unix_members = grp->gr_mem; + + while (*unix_members) { + if (strcmp(*unix_members, nt_members[i]) == 0) { + is_unix_member = True; + break; + } + unix_members += 1; + } + + if (!is_unix_member) { + /* We look at a nt group member that is not a + unix group member currently. So, add the nt + group member. */ + smb_add_user_group(grp->gr_name, nt_members[i]); + } + } + + talloc_destroy(t); + return NT_STATUS_OK; +} + +static NTSTATUS fetch_alias_info(uint32 rid, SAM_ALIAS_INFO *delta, + DOM_SID dom_sid) +{ + fstring name; + fstring comment; + struct group *grp = NULL; + DOM_SID alias_sid; + fstring sid_string; + GROUP_MAP map; + int insert_flag = TDB_INSERT; + + unistr2_to_ascii(name, &delta->uni_als_name, sizeof(name)-1); + unistr2_to_ascii(comment, &delta->uni_als_desc, sizeof(comment)-1); + + /* Find out whether the group is already mapped */ + sid_copy(&alias_sid, &dom_sid); + sid_append_rid(&alias_sid, rid); + sid_to_string(sid_string, &alias_sid); + + if (get_group_map_from_sid(alias_sid, &map, False)) { + grp = getgrgid(map.gid); + insert_flag = 0; /* Don't TDB_INSERT, mapping exists */ + } + + if (grp == NULL) { + gid_t new_gid; + /* No group found from mapping, find it from its name. */ + if ((grp = getgrnam(name)) == NULL) { + /* No appropriate group found, create one */ + d_printf("Creating unix group: '%s'\n", name); + if (smb_create_group(name, &new_gid) != 0) + return NT_STATUS_ACCESS_DENIED; + } + + if ((grp = getgrgid(new_gid)) == NULL) + return NT_STATUS_ACCESS_DENIED; + } + + map.gid = grp->gr_gid; + map.sid = alias_sid; + map.sid_name_use = SID_NAME_ALIAS; + + fstrcpy(map.nt_name, name); + fstrcpy(map.comment, comment); + + map.priv_set.count = 0; + map.priv_set.set = NULL; + + add_mapping_entry(&map, insert_flag); + + return NT_STATUS_OK; +} + +static NTSTATUS +fetch_alias_mem(uint32 rid, SAM_ALIAS_MEM_INFO *delta, DOM_SID dom_sid) +{ + + return NT_STATUS_OK; +} + static void -fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta) +fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta, + DOM_SID dom_sid) { switch(hdr_delta->type) { case SAM_DELTA_ACCOUNT_INFO: @@ -371,6 +606,18 @@ fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta) fetch_group_info(hdr_delta->target_rid, &delta->group_info); break; + case SAM_DELTA_GROUP_MEM: + fetch_group_mem_info(hdr_delta->target_rid, + &delta->grp_mem_info); + break; + case SAM_DELTA_ALIAS_INFO: + fetch_alias_info(hdr_delta->target_rid, + &delta->alias_info, dom_sid); + break; + case SAM_DELTA_ALIAS_MEM: + fetch_alias_mem(hdr_delta->target_rid, + &delta->als_mem_info, dom_sid); + break; default: d_printf("Unknown delta record type %d\n", hdr_delta->type); break; @@ -378,7 +625,8 @@ fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta) } static void -fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds) +fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds, + DOM_SID dom_sid) { unsigned last_rid = -1; NTSTATUS result; @@ -403,7 +651,7 @@ fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds) ret_creds); last_rid = 0; for (i = 0; i < num_deltas; i++) { - fetch_sam_entry(&hdr_deltas[i], &deltas[i]); + fetch_sam_entry(&hdr_deltas[i], &deltas[i], dom_sid); last_rid = hdr_deltas[i].target_rid; } } while (last_rid && NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); @@ -419,6 +667,7 @@ int rpc_vampire(int argc, const char **argv) uchar trust_password[16]; DOM_CRED ret_creds; uint32 neg_flags = 0x000001ff; + DOM_SID dom_sid; ZERO_STRUCT(ret_creds); @@ -446,8 +695,11 @@ int rpc_vampire(int argc, const char **argv) goto fail; } - fetch_database(cli, SAM_DATABASE_DOMAIN, &ret_creds); - fetch_database(cli, SAM_DATABASE_BUILTIN, &ret_creds); + dom_sid = *get_global_sam_sid(); + fetch_database(cli, SAM_DATABASE_DOMAIN, &ret_creds, dom_sid); + + sid_copy(&dom_sid, &global_sid_Builtin); + fetch_database(cli, SAM_DATABASE_BUILTIN, &ret_creds, dom_sid); /* Currently we crash on PRIVS somewhere in unmarshalling */ /* Dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); */ -- cgit