From 8ba00d147bbdb705b411e182433632c81a036188 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 5 Dec 2001 11:00:26 +0000 Subject: OK. Smbpasswd -j is DEAD. This moves the rest of the functionality into the 'net rpc join' code. Futhermore, this moves that entire area over to the libsmb codebase, rather than the crufty old rpc_client stuff. I have also fixed up the smbpasswd -a -m bug in the process. We also have a new 'net rpc changetrustpw' that can be called from a cron-job to regularly change the trust account password, for sites that run winbind but not smbd. With a little more work, we can kill rpc_client from smbd entirly! (It is mostly the domain auth stuff - which I can rework - and the spoolss stuff that sombody else will need to look over). Andrew Bartlett (This used to be commit 575897e879fc175ba702adf245384033342c903d) --- source3/utils/net.c | 4 +- source3/utils/net.h | 6 +- source3/utils/net_ads.c | 2 +- source3/utils/net_rpc.c | 68 ++++++++++++++-- source3/utils/net_rpc_join.c | 6 +- source3/utils/smbpasswd.c | 179 ++++++++++--------------------------------- 6 files changed, 112 insertions(+), 153 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/net.c b/source3/utils/net.c index e20833bc0b..5efd79fa5b 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -163,7 +163,7 @@ static BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **se if (!*server_name) { *server_name = strdup(inet_ntoa(dest_ip)); } - } else if (server_name) { + } else if (*server_name) { /* resolve the IP address */ if (!resolve_name(*server_name, server_ip, 0x20)) { DEBUG(1,("Unable to resolve server name\n")); @@ -404,6 +404,8 @@ static struct functable net_func[] = { *p2 = 0; } + strupper(global_myname); + load_interfaces(); rc = net_run_function(argc_new-1, argv_new+1, net_func, net_usage); diff --git a/source3/utils/net.h b/source3/utils/net.h index bdc4a08868..e912efe09e 100644 --- a/source3/utils/net.h +++ b/source3/utils/net.h @@ -26,13 +26,13 @@ For example, localhost is insane for a 'join' operation. */ -#define NET_FLAGS_LOCALHOST_DEFAULT_INSANE 3 +#define NET_FLAGS_LOCALHOST_DEFAULT_INSANE 4 /* We want to find the PDC only */ -#define NET_FLAGS_PDC 4 +#define NET_FLAGS_PDC 8 /* We want an anonymous connection */ -#define NET_FLAGS_ANONYMOUS 5 +#define NET_FLAGS_ANONYMOUS 16 extern int opt_maxusers; diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index c956d9bb65..cecfb6a4d0 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -166,7 +166,7 @@ static int net_ads_join(int argc, const char **argv) } - tmp_password = generate_random_str(15); + tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); password = strdup(tmp_password); if (!(ads = ads_startup())) return -1; diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index b1a9ad4aa9..97a1a1d342 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -81,11 +81,11 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli) } -static int run_rpc_command(const char *pipe_name, +static int run_rpc_command(const char *pipe_name, int conn_flags, rpc_command_fn fn, int argc, const char **argv) { - struct cli_state *cli = net_make_ipc_connection(0); + struct cli_state *cli = net_make_ipc_connection(conn_flags); TALLOC_CTX *mem_ctx; NTSTATUS nt_status; DOM_SID *domain_sid = net_get_remote_domain_sid(cli); @@ -103,6 +103,8 @@ static int run_rpc_command(const char *pipe_name, nt_status = fn(domain_sid, cli, mem_ctx, argc, argv); + DEBUG(5, ("rpc command function returned %s\n", get_nt_error_msg(nt_status))); + if (cli->nt_pipe_fnum) cli_nt_session_close(cli); @@ -160,9 +162,62 @@ static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, struct cli_sta return result; } +static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, + int argc, const char **argv) { + + return trust_pw_find_change_and_store_it(cli, mem_ctx, opt_target_workgroup); +} + +static int rpc_changetrustpw(int argc, const char **argv) +{ + return run_rpc_command(PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_changetrustpw_internals, + argc, argv); +} + +static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, + int argc, const char **argv) { + + extern pstring global_myname; + fstring trust_passwd; + unsigned char orig_trust_passwd_hash[16]; + + fstrcpy(trust_passwd, global_myname); + strlower(trust_passwd); + E_md4hash( (uchar *)trust_passwd, orig_trust_passwd_hash); + + return trust_pw_change_and_store_it(cli, mem_ctx, orig_trust_passwd_hash); +} + +static int rpc_join_oldstyle(int argc, const char **argv) +{ + return run_rpc_command(PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_join_oldstyle_internals, + argc, argv); +} + +static int rpc_join_usage(int argc, const char **argv) +{ + d_printf(" net rpc join \t to join a domain with admin username & password\n"); + d_printf(" net rpc join oldstyle \t to join a domain created in server manager\n"); + return -1; +} + +static int rpc_join(int argc, const char **argv) +{ + struct functable func[] = { + {"oldstyle", rpc_join_oldstyle}, + {NULL, NULL} + }; + + if (argc == 0) { + return net_rpc_join(argc, argv); + } + + return net_run_function(argc, argv, func, rpc_join_usage); +} + static int rpc_user_add(int argc, const char **argv) { - return run_rpc_command(PIPE_SAMR, rpc_user_add_internals, + return run_rpc_command(PIPE_SAMR, 0, rpc_user_add_internals, argc, argv); } @@ -188,15 +243,18 @@ static int rpc_user(int argc, const char **argv) int net_rpc_usage(int argc, const char **argv) { - d_printf(" net rpc join \tto join a domin \n"); + d_printf(" net rpc join \tto join a domain \n"); + d_printf(" net rpc user \tto add, delete and list users\n"); + d_printf(" net rpc changetrustpw \tto change the trust account password\n"); return -1; } int net_rpc(int argc, const char **argv) { struct functable func[] = { - {"join", net_rpc_join}, + {"join", rpc_join}, {"user", rpc_user}, + {"changetrustpw", rpc_changetrustpw}, {NULL, NULL} }; return net_run_function(argc, argv, func, net_rpc_usage); diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index 463de61b05..2b73117c38 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -191,7 +191,7 @@ int net_rpc_join(int argc, const char **argv) { char *str; - str = generate_random_str(15); + str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); clear_trust_password = strdup(str); } @@ -256,8 +256,6 @@ int net_rpc_join(int argc, const char **argv) strupper(domain); - secrets_init(); - if (!secrets_store_domain_sid(domain, &domain_sid)) { DEBUG(0, ("error storing domain sid for %s\n", domain)); goto done; @@ -284,7 +282,7 @@ int net_rpc_join(int argc, const char **argv) goto done; } - CHECK_RPC_ERR(cli_nt_setup_creds(cli, stored_md4_trust_password), + CHECK_RPC_ERR(new_cli_nt_setup_creds(cli, stored_md4_trust_password), "error in domain join verification"); retval = 0; /* Success! */ diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index 92136bea7a..e076687c4f 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -50,7 +50,6 @@ static void usage(void) printf("extra options when run by root or in local mode:\n"); printf(" -L local mode (must be first option)\n"); printf(" -R ORDER name resolve order\n"); - printf(" -j DOMAIN join domain name\n"); printf(" -a add user\n"); printf(" -x delete user\n"); printf(" -d disable user\n"); @@ -61,67 +60,6 @@ static void usage(void) exit(1); } -/********************************************************* -Join a domain. -**********************************************************/ -static int join_domain(char *domain, char *remote) -{ - pstring remote_machine; - fstring trust_passwd; - unsigned char orig_trust_passwd_hash[16]; - BOOL ret; - - pstrcpy(remote_machine, remote ? remote : ""); - fstrcpy(trust_passwd, global_myname); - strlower(trust_passwd); - E_md4hash( (uchar *)trust_passwd, orig_trust_passwd_hash); - - /* Ensure that we are not trying to join a - domain if we are locally set up as a domain - controller. */ - - if(strequal(remote, global_myname)) { - fprintf(stderr, "Cannot join domain %s as the domain controller name is our own. We cannot be a domain controller for a domain and also be a domain member.\n", domain); - return 1; - } - - /* - * Write the old machine account password. - */ - - if(!secrets_store_trust_account_password(domain, orig_trust_passwd_hash)) { - fprintf(stderr, "Unable to write the machine account password for \ -machine %s in domain %s.\n", global_myname, domain); - return 1; - } - - /* - * If we are given a remote machine assume this is the PDC. - */ - - if(remote == NULL) { - pstrcpy(remote_machine, lp_passwordserver()); - } - - if(!*remote_machine) { - fprintf(stderr, "No password server list given in smb.conf - \ -unable to join domain.\n"); - return 1; - } - - ret = change_trust_account_password( domain, remote_machine); - - if(!ret) { - trust_password_delete(domain); - fprintf(stderr,"Unable to join domain %s.\n",domain); - } else { - printf("Joined domain %s.\n",domain); - } - - return (int)ret; -} - - static void set_line_buffering(FILE *f) { setvbuf(f, NULL, _IOLBF, 0); @@ -241,11 +179,10 @@ static int process_root(int argc, char *argv[]) { struct passwd *pwd; int result = 0, ch; - BOOL joining_domain = False, got_pass = False, got_username = False; + BOOL got_pass = False, got_username = False; int local_flags = LOCAL_SET_PASSWORD; BOOL stdin_passwd_get = False; fstring user_name, user_password; - char *new_domain = NULL; char *new_passwd = NULL; char *old_passwd = NULL; char *remote_machine = NULL; @@ -255,7 +192,7 @@ static int process_root(int argc, char *argv[]) user_name[0] = '\0'; - while ((ch = getopt(argc, argv, "axdehmnj:r:sR:D:U:L")) != EOF) { + while ((ch = getopt(argc, argv, "axdehmnjr:sR:D:U:L")) != EOF) { switch(ch) { case 'L': local_mode = True; @@ -278,14 +215,9 @@ static int process_root(int argc, char *argv[]) case 'm': local_flags |= LOCAL_TRUST_ACCOUNT; break; - case 'n': - local_flags |= LOCAL_SET_NO_PASSWORD; - local_flags &= ~LOCAL_SET_PASSWORD; - break; case 'j': - new_domain = optarg; - strupper(new_domain); - joining_domain = True; + d_printf("See 'net rpc join' for this functionality\n"); + exit(1); break; case 'r': remote_machine = optarg; @@ -334,48 +266,16 @@ static int process_root(int argc, char *argv[]) */ if(((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) == (LOCAL_ADD_USER|LOCAL_DELETE_USER)) || ((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) && - ((remote_machine != NULL) || joining_domain))) { + (remote_machine != NULL))) { usage(); } /* Only load interfaces if we are doing network operations. */ - if (joining_domain || remote_machine) { + if (remote_machine) { load_interfaces(); } - /* Join a domain */ - - if (joining_domain) { - - if (argc != 0) - usage(); - - /* Are we joining by specifing an admin username and - password? */ - - if (user_name[0]) { - - /* Get administrator password if not specified */ - - if (!got_pass) { - char *pass = getpass("Password: "); - - if (pass) - pstrcpy(user_password, pass); - } - - d_printf("use net rpc join to do this now.\n"); - return 1; - - } else { - - /* Or just with the server manager? */ - - return join_domain(new_domain, remote_machine); - } - } - /* * Deal with root - can add a user, but only locally. */ @@ -435,45 +335,46 @@ static int process_root(int argc, char *argv[]) slprintf(buf, sizeof(buf)-1, "%s$", user_name); fstrcpy(user_name, buf); - } - - if (remote_machine != NULL) { - old_passwd = get_pass("Old SMB password:",stdin_passwd_get); - } - - if (!(local_flags & LOCAL_SET_PASSWORD)) { - - /* - * If we are trying to enable a user, first we need to find out - * if they are using a modern version of the smbpasswd file that - * disables a user by just writing a flag into the file. If so - * then we can re-enable a user without prompting for a new - * password. If not (ie. they have a no stored password in the - * smbpasswd file) then we need to prompt for a new password. - */ - - if(local_flags & LOCAL_ENABLE_USER) { - SAM_ACCOUNT *sampass = NULL; - BOOL ret; + } else { + + if (remote_machine != NULL) { + old_passwd = get_pass("Old SMB password:",stdin_passwd_get); + } + + if (!(local_flags & LOCAL_SET_PASSWORD)) { + + /* + * If we are trying to enable a user, first we need to find out + * if they are using a modern version of the smbpasswd file that + * disables a user by just writing a flag into the file. If so + * then we can re-enable a user without prompting for a new + * password. If not (ie. they have a no stored password in the + * smbpasswd file) then we need to prompt for a new password. + */ - pdb_init_sam(&sampass); - ret = pdb_getsampwnam(sampass, user_name); - if((sampass != False) && (pdb_get_lanman_passwd(sampass) == NULL)) { - local_flags |= LOCAL_SET_PASSWORD; + if(local_flags & LOCAL_ENABLE_USER) { + SAM_ACCOUNT *sampass = NULL; + BOOL ret; + + pdb_init_sam(&sampass); + ret = pdb_getsampwnam(sampass, user_name); + if((sampass != False) && (pdb_get_lanman_passwd(sampass) == NULL)) { + local_flags |= LOCAL_SET_PASSWORD; + } + pdb_free_sam(&sampass); } - pdb_free_sam(&sampass); } - } - - if(local_flags & LOCAL_SET_PASSWORD) { - new_passwd = prompt_for_new_password(stdin_passwd_get); - if(!new_passwd) { - fprintf(stderr, "Unable to get new password.\n"); - exit(1); + if(local_flags & LOCAL_SET_PASSWORD) { + new_passwd = prompt_for_new_password(stdin_passwd_get); + + if(!new_passwd) { + fprintf(stderr, "Unable to get new password.\n"); + exit(1); + } } } - + if (!password_change(remote_machine, user_name, old_passwd, new_passwd, local_flags)) { fprintf(stderr,"Failed to modify password entry for user %s\n", user_name); result = 1; -- cgit