From f0255b38bc17f4da9a63b2be4c3ce505688e933e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 17 Aug 2002 14:45:04 +0000 Subject: sync 3.0 branch with HEAD (This used to be commit 1b83b78e332b9d28914eff155530e81cf2073a58) --- source3/utils/net.c | 5 +- source3/utils/net_ads.c | 141 +++++++++++++---- source3/utils/net_lookup.c | 9 +- source3/utils/net_rpc.c | 368 ++++++++++++++++++++++++++++++++++++------- source3/utils/net_rpc_join.c | 110 ++++++++++--- source3/utils/pdbedit.c | 316 ++++++++++++++++++++++++++----------- source3/utils/smbcacls.c | 2 +- source3/utils/smbcontrol.c | 20 +++ source3/utils/smbgroupedit.c | 4 +- source3/utils/smbpasswd.c | 6 +- source3/utils/smbtree.c | 2 +- source3/utils/status.c | 10 +- source3/utils/testparm.c | 9 +- 13 files changed, 784 insertions(+), 218 deletions(-) (limited to 'source3') diff --git a/source3/utils/net.c b/source3/utils/net.c index d34ac21f39..fc7094bcf7 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -234,7 +234,7 @@ BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_na } -BOOL net_find_dc(struct in_addr *server_ip, fstring server_name, char *domain_name) +BOOL net_find_dc(struct in_addr *server_ip, fstring server_name, const char *domain_name) { struct in_addr *ip_list; int addr_count; @@ -381,8 +381,6 @@ static struct functable net_func[] = { {"port", 'p', POPT_ARG_INT, &opt_port}, {"myname", 'n', POPT_ARG_STRING, &opt_requester_name}, {"conf", 's', POPT_ARG_STRING, &servicesf}, - {"debug", 'd', POPT_ARG_STRING, &debuglevel}, - {"debuglevel", 'd', POPT_ARG_STRING, &debuglevel}, {"server", 'S', POPT_ARG_STRING, &opt_host}, {"comment", 'C', POPT_ARG_STRING, &opt_comment}, {"maxusers", 'M', POPT_ARG_INT, &opt_maxusers}, @@ -393,6 +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 }, { 0, 0, 0, 0} }; diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index fa3eac6bd3..ad405fe68c 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -32,6 +32,8 @@ int net_ads_usage(int argc, const char **argv) "\n\tjoins the local machine to a ADS realm\n"\ "\nnet ads leave"\ "\n\tremoves the local machine from a ADS realm\n"\ +"\nnet ads testjoin"\ +"\n\ttests that an exiting join is OK\n"\ "\nnet ads user"\ "\n\tlist, add, or delete users in the realm\n"\ "\nnet ads group"\ @@ -58,18 +60,23 @@ static int net_ads_info(int argc, const char **argv) { ADS_STRUCT *ads; - ads = ads_init(NULL, NULL, opt_host, NULL, NULL); + ads = ads_init(NULL, NULL, opt_host); + + if (ads) { + ads->auth.no_bind = 1; + } + ads_connect(ads); - if (!ads) { + if (!ads || !ads->config.realm) { d_printf("Didn't find the ldap server!\n"); return -1; } - d_printf("LDAP server: %s\n", ads->ldap_server); - d_printf("LDAP server name: %s\n", ads->ldap_server_name); - d_printf("Realm: %s\n", ads->realm); - d_printf("Bind Path: %s\n", ads->bind_path); + d_printf("LDAP server: %s\n", inet_ntoa(ads->ldap_ip)); + d_printf("LDAP server name: %s\n", ads->config.ldap_server_name); + 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); return 0; @@ -83,7 +90,7 @@ static ADS_STRUCT *ads_startup(void) BOOL need_password = False; BOOL second_time = False; - ads = ads_init(NULL, NULL, opt_host, NULL, NULL); + ads = ads_init(NULL, NULL, opt_host); if (!opt_user_name) { opt_user_name = "administrator"; @@ -101,9 +108,9 @@ retry: } if (opt_password) - ads->password = strdup(opt_password); + ads->auth.password = strdup(opt_password); - ads->user_name = strdup(opt_user_name); + ads->auth.user_name = strdup(opt_user_name); status = ads_connect(ads); if (!ADS_ERR_OK(status)) { @@ -136,8 +143,38 @@ int net_ads_check(void) return 0; } +/* + determine the netbios workgroup name for a domain + */ +static int net_ads_workgroup(int argc, const char **argv) +{ + ADS_STRUCT *ads; + TALLOC_CTX *ctx; + char *workgroup; + + if (!(ads = ads_startup())) return -1; + + if (!(ctx = talloc_init_named("net_ads_workgroup"))) { + return -1; + } + + if (!ADS_ERR_OK(ads_workgroup_name(ads, ctx, &workgroup))) { + d_printf("Failed to find workgroup for realm '%s'\n", + ads->config.realm); + talloc_destroy(ctx); + return -1; + } -static BOOL usergrp_display(char *field, void **values, void *data_area) + d_printf("Workgroup: %s\n", workgroup); + + talloc_destroy(ctx); + + return 0; +} + + + +static void usergrp_display(char *field, void **values, void *data_area) { char **disp_fields = (char **) data_area; @@ -151,16 +188,15 @@ static BOOL usergrp_display(char *field, void **values, void *data_area) } SAFE_FREE(disp_fields[0]); SAFE_FREE(disp_fields[1]); - return True; + return; } if (!values) /* must be new field, indicate string field */ - return True; + return; 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; /* always strings here */ } static int net_ads_user_usage(int argc, const char **argv) @@ -208,8 +244,8 @@ static int ads_user_add(int argc, const char **argv) } /* try setting the password */ - asprintf(&upn, "%s@%s", argv[0], ads->realm); - status = krb5_set_password(ads->kdc_server, upn, argv[1]); + asprintf(&upn, "%s@%s", argv[0], ads->config.realm); + status = krb5_set_password(ads->auth.kdc_server, upn, argv[1]); safe_free(upn); if (ADS_ERR_OK(status)) { d_printf("User %s added\n", argv[0]); @@ -326,7 +362,7 @@ int net_ads_user(int argc, const char **argv) d_printf("\nUser name Comment"\ "\n-----------------------------\n"); - rc = ads_do_search_all_fn(ads, ads->bind_path, + rc = ads_do_search_all_fn(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, "(objectclass=user)", opt_long_list_entries ? longattrs : @@ -433,7 +469,7 @@ int net_ads_group(int argc, const char **argv) if (opt_long_list_entries) d_printf("\nGroup name Comment"\ "\n-----------------------------\n"); - rc = ads_do_search_all_fn(ads, ads->bind_path, + rc = ads_do_search_all_fn(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, "(objectclass=group)", opt_long_list_entries ? longattrs : @@ -494,15 +530,54 @@ static int net_ads_leave(int argc, const char **argv) rc = ads_leave_realm(ads, global_myname); if (!ADS_ERR_OK(rc)) { d_printf("Failed to delete host '%s' from the '%s' realm.\n", - global_myname, ads->realm); + global_myname, ads->config.realm); return -1; } - d_printf("Removed '%s' from realm '%s'\n", global_myname, ads->realm); + d_printf("Removed '%s' from realm '%s'\n", global_myname, ads->config.realm); + + return 0; +} + +static int net_ads_join_ok(void) +{ + ADS_STRUCT *ads = NULL; + extern pstring global_myname; + + if (!secrets_init()) { + DEBUG(1,("Failed to initialise secrets database\n")); + return -1; + } + + asprintf(&opt_user_name, "%s$", global_myname); + opt_password = secrets_fetch_machine_password(); + if (!(ads = ads_startup())) { + return -1; + } + + ads_destroy(&ads); return 0; } +/* + check that an existing join is OK + */ +int net_ads_testjoin(int argc, const char **argv) +{ + /* Display success or failure */ + if (net_ads_join_ok() != 0) { + fprintf(stderr,"Join to domain is not valid\n"); + return -1; + } + + printf("Join is OK\n"); + return 0; +} + +/* + join a domain using ADS + */ int net_ads_join(int argc, const char **argv) { ADS_STRUCT *ads; @@ -529,7 +604,7 @@ int net_ads_join(int argc, const char **argv) if (!(ads = ads_startup())) return -1; ou_str = ads_ou_string(org_unit); - asprintf(&dn, "%s,%s", ou_str, ads->bind_path); + asprintf(&dn, "%s,%s", ou_str, ads->config.bind_path); free(ou_str); rc = ads_search_dn(ads, &res, dn, NULL); @@ -575,7 +650,7 @@ int net_ads_join(int argc, const char **argv) return -1; } - d_printf("Joined '%s' to realm '%s'\n", global_myname, ads->realm); + d_printf("Joined '%s' to realm '%s'\n", global_myname, ads->config.realm); free(password); @@ -670,7 +745,7 @@ static int net_ads_printer_publish(int argc, const char **argv) get_a_printer, because the server name might be localhost or an ip address */ prt.printerName = argv[0]; - asprintf(&servername, "%s.%s", global_myname, ads->realm); + asprintf(&servername, "%s.%s", global_myname, ads->config.realm); prt.serverName = servername; prt.shortServerName = global_myname; prt.versionNumber = "4"; @@ -774,13 +849,13 @@ static int net_ads_password(int argc, const char **argv) /* use the realm so we can eventually change passwords for users in realms other than default */ - if (!(ads = ads_init(realm, NULL, NULL, NULL, NULL))) return -1; + if (!(ads = ads_init(realm, NULL, NULL))) return -1; asprintf(&prompt, "Enter new password for %s:", argv[0]); new_password = getpass(prompt); - ret = kerberos_set_password(ads->kdc_server, auth_principal, + ret = kerberos_set_password(ads->auth.kdc_server, auth_principal, auth_password, argv[0], new_password); if (!ADS_ERR_OK(ret)) { d_printf("Password change failed :-( ...\n"); @@ -805,11 +880,21 @@ static int net_ads_change_localhost_pass(int argc, const char **argv) char *hostname; ADS_STATUS ret; - if (!(ads = ads_init_simple())) return -1; + if (!secrets_init()) { + DEBUG(1,("Failed to initialise secrets database\n")); + return -1; + } + + asprintf(&opt_user_name, "%s$", global_myname); + opt_password = secrets_fetch_machine_password(); + + if (!(ads = ads_startup())) { + return -1; + } hostname = strdup(global_myname); strlower(hostname); - asprintf(&host_principal, "%s@%s", hostname, ads->realm); + asprintf(&host_principal, "%s@%s", hostname, ads->config.realm); SAFE_FREE(hostname); d_printf("Changing password for principal: HOST/%s\n", host_principal); @@ -868,7 +953,7 @@ static int net_ads_search(int argc, const char **argv) exp = argv[0]; attrs = (argv + 1); - rc = ads_do_search_all(ads, ads->bind_path, + rc = ads_do_search_all(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, exp, attrs, &res); if (!ADS_ERR_OK(rc)) { @@ -914,6 +999,7 @@ int net_ads(int argc, const char **argv) struct functable func[] = { {"INFO", net_ads_info}, {"JOIN", net_ads_join}, + {"TESTJOIN", net_ads_testjoin}, {"LEAVE", net_ads_leave}, {"STATUS", net_ads_status}, {"USER", net_ads_user}, @@ -922,6 +1008,7 @@ int net_ads(int argc, const char **argv) {"CHOSTPASS", net_ads_change_localhost_pass}, {"PRINTER", net_ads_printer}, {"SEARCH", net_ads_search}, + {"WORKGROUP", net_ads_workgroup}, {"HELP", net_ads_help}, {NULL, NULL} }; diff --git a/source3/utils/net_lookup.c b/source3/utils/net_lookup.c index a324f594a1..f76b186251 100644 --- a/source3/utils/net_lookup.c +++ b/source3/utils/net_lookup.c @@ -77,7 +77,8 @@ static void print_ldap_srvlist(char *srvlist) static int net_lookup_ldap(int argc, const char **argv) { #ifdef HAVE_LDAP - char *srvlist, *domain; + char *srvlist; + const char *domain; int rc, count; struct in_addr *addr; struct hostent *hostent; @@ -125,7 +126,7 @@ static int net_lookup_dc(int argc, const char **argv) { struct in_addr *ip_list; char *pdc_str = NULL; - char *domain=opt_target_workgroup; + const char *domain=opt_target_workgroup; int count, i; if (argc > 0) @@ -154,7 +155,7 @@ static int net_lookup_dc(int argc, const char **argv) static int net_lookup_master(int argc, const char **argv) { struct in_addr master_ip; - char *domain=opt_target_workgroup; + const char *domain=opt_target_workgroup; if (argc > 0) domain=argv[0]; @@ -214,6 +215,8 @@ static int net_lookup_kdc(int argc, const char **argv) DEBUG(1, ("No kerberos support\n")); return -1; } + + /* lookup hosts or IP addresses using internal samba lookup fns */ int net_lookup(int argc, const char **argv) { diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index dc50c438d4..55e8a497cc 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -117,15 +117,21 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli) * @return A shell status integer (0 for success) */ -static int run_rpc_command(const char *pipe_name, int conn_flags, - rpc_command_fn fn, - int argc, const char **argv) +static int run_rpc_command(struct cli_state *cli_arg, const char *pipe_name, int conn_flags, + rpc_command_fn fn, + int argc, const char **argv) { - struct cli_state *cli = net_make_ipc_connection(conn_flags); + struct cli_state *cli = NULL; TALLOC_CTX *mem_ctx; NTSTATUS nt_status; DOM_SID *domain_sid; + /* make use of cli_state handed over as an argument, if possible */ + if (!cli_arg) + cli = net_make_ipc_connection(conn_flags); + else + cli = cli_arg; + if (!cli) { return -1; } @@ -141,7 +147,7 @@ static int run_rpc_command(const char *pipe_name, int conn_flags, } if (!cli_nt_session_open(cli, pipe_name)) { - DEBUG(0, ("Could not initialise samr pipe\n")); + DEBUG(0, ("Could not initialise %s pipe\n", pipe_name)); } nt_status = fn(domain_sid, cli, mem_ctx, argc, argv); @@ -156,6 +162,10 @@ static int run_rpc_command(const char *pipe_name, int conn_flags, if (cli->nt_pipe_fnum) cli_nt_session_close(cli); + /* close the connection only if it was opened here */ + if (!cli_arg) + cli_shutdown(cli); + talloc_destroy(mem_ctx); return (!NT_STATUS_IS_OK(nt_status)); @@ -199,7 +209,7 @@ static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, struct cl static int rpc_changetrustpw(int argc, const char **argv) { - return run_rpc_command(PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_changetrustpw_internals, + return run_rpc_command(NULL, PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_changetrustpw_internals, argc, argv); } @@ -244,7 +254,7 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl trust_passwd[14] = '\0'; - E_md4hash( (uchar *)trust_passwd, orig_trust_passwd_hash); + E_md4hash(trust_passwd, orig_trust_passwd_hash); return trust_pw_change_and_store_it(cli, mem_ctx, orig_trust_passwd_hash); } @@ -261,7 +271,7 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl static int net_rpc_join_oldstyle(int argc, const char **argv) { - return run_rpc_command(PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_join_oldstyle_internals, + return run_rpc_command(NULL, PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_join_oldstyle_internals, argc, argv); } @@ -371,7 +381,7 @@ rpc_info_internals(const DOM_SID *domain_sid, struct cli_state *cli, **/ int net_rpc_info(int argc, const char **argv) { - return run_rpc_command(PIPE_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, + return run_rpc_command(NULL, PIPE_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_info_internals, argc, argv); } @@ -477,7 +487,7 @@ static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, struct cli_sta static int rpc_user_add(int argc, const char **argv) { - return run_rpc_command(PIPE_SAMR, 0, rpc_user_add_internals, + return run_rpc_command(NULL, PIPE_SAMR, 0, rpc_user_add_internals, argc, argv); } @@ -578,7 +588,7 @@ static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid, static int rpc_user_delete(int argc, const char **argv) { - return run_rpc_command(PIPE_SAMR, 0, rpc_user_del_internals, + return run_rpc_command(NULL, PIPE_SAMR, 0, rpc_user_del_internals, argc, argv); } @@ -680,7 +690,7 @@ rpc_user_info_internals(const DOM_SID *domain_sid, struct cli_state *cli, static int rpc_user_info(int argc, const char **argv) { - return run_rpc_command(PIPE_SAMR, 0, rpc_user_info_internals, + return run_rpc_command(NULL, PIPE_SAMR, 0, rpc_user_info_internals, argc, argv); } @@ -775,7 +785,7 @@ int net_rpc_user(int argc, const char **argv) if (opt_long_list_entries) { } else { } - return run_rpc_command(PIPE_SAMR, 0, + return run_rpc_command(NULL,PIPE_SAMR, 0, rpc_user_list_internals, argc, argv); } @@ -926,7 +936,7 @@ int net_rpc_group(int argc, const char **argv) if (opt_long_list_entries) { } else { } - return run_rpc_command(PIPE_SAMR, 0, + return run_rpc_command(NULL, PIPE_SAMR, 0, rpc_group_list_internals, argc, argv); } @@ -984,7 +994,7 @@ static int rpc_share_add(int argc, const char **argv) DEBUG(1,("Sharename or path not specified on add\n")); return rpc_share_usage(argc, argv); } - return run_rpc_command(PIPE_SRVSVC, 0, + return run_rpc_command(NULL, PIPE_SRVSVC, 0, rpc_share_add_internals, argc, argv); } @@ -1030,7 +1040,7 @@ static int rpc_share_delete(int argc, const char **argv) DEBUG(1,("Sharename not specified on delete\n")); return rpc_share_usage(argc, argv); } - return run_rpc_command(PIPE_SRVSVC, 0, + return run_rpc_command(NULL, PIPE_SRVSVC, 0, rpc_share_del_internals, argc, argv); } @@ -1120,7 +1130,7 @@ int net_rpc_share(int argc, const char **argv) }; if (argc == 0) - return run_rpc_command(PIPE_SRVSVC, 0, + return run_rpc_command(NULL, PIPE_SRVSVC, 0, rpc_share_list_internals, argc, argv); @@ -1174,7 +1184,7 @@ static int rpc_file_close(int argc, const char **argv) return(rpc_file_usage(argc, argv)); } - return run_rpc_command(PIPE_SRVSVC, 0, + return run_rpc_command(NULL, PIPE_SRVSVC, 0, rpc_file_close_internals, argc, argv); } @@ -1221,13 +1231,13 @@ rpc_file_list_internals(const DOM_SID *domain_sid, struct cli_state *cli, WERROR result; ENUM_HND hnd; uint32 preferred_len = 0xffffffff, i; - char *username=NULL; + const char *username=NULL; init_enum_hnd(&hnd, 0); /* if argc > 0, must be user command */ if (argc > 0) - username = argv[0]; + username = smb_xstrdup(argv[0]); result = cli_srvsvc_net_file_enum( cli, mem_ctx, 3, username, &ctr, preferred_len, &hnd); @@ -1265,7 +1275,7 @@ static int rpc_file_user(int argc, const char **argv) return(rpc_file_usage(argc, argv)); } - return run_rpc_command(PIPE_SRVSVC, 0, + return run_rpc_command(NULL, PIPE_SRVSVC, 0, rpc_file_list_internals, argc, argv); } @@ -1290,7 +1300,7 @@ int net_rpc_file(int argc, const char **argv) }; if (argc == 0) - return run_rpc_command(PIPE_SRVSVC, 0, + return run_rpc_command(NULL, PIPE_SRVSVC, 0, rpc_file_list_internals, argc, argv); @@ -1345,7 +1355,7 @@ static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, struct c static int rpc_shutdown_abort(int argc, const char **argv) { - return run_rpc_command(PIPE_WINREG, 0, rpc_shutdown_abort_internals, + return run_rpc_command(NULL, PIPE_WINREG, 0, rpc_shutdown_abort_internals, argc, argv); } @@ -1435,7 +1445,7 @@ static NTSTATUS rpc_shutdown_internals(const DOM_SID *domain_sid, struct cli_sta static int rpc_shutdown(int argc, const char **argv) { - return run_rpc_command(PIPE_WINREG, 0, rpc_shutdown_internals, + return run_rpc_command(NULL, PIPE_WINREG, 0, rpc_shutdown_internals, argc, argv); } @@ -1460,7 +1470,7 @@ static int rpc_shutdown(int argc, const char **argv) */ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, - int argc, const char **argv) { + int argc, const char **argv) { POLICY_HND connect_pol, domain_pol, user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; @@ -1483,16 +1493,14 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli strupper(acct_name); - /* Get sam policy handle */ - - result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, + /* Get samr policy handle */ + result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, &connect_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } /* Get domain policy handle */ - result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, MAXIMUM_ALLOWED_ACCESS, domain_sid, &domain_pol); @@ -1501,10 +1509,9 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli } /* Create trusting domain's account */ - acb_info = ACB_DOMTRUST; - unknown = 0xe005000b; /* No idea what this is - a permission mask? - Is it needed for interdomain account also ? */ + unknown = 0xe005000b; /* No idea what this is - a permission mask? + mimir: yes, most probably it is */ result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol, acct_name, acb_info, unknown, @@ -1529,7 +1536,7 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli static int rpc_trustdom_add(int argc, const char **argv) { - return run_rpc_command(PIPE_SAMR, 0, rpc_trustdom_add_internals, + return run_rpc_command(NULL, PIPE_SAMR, 0, rpc_trustdom_add_internals, argc, argv); } @@ -1562,9 +1569,10 @@ static int rpc_trustdom_del(int argc, const char **argv) extern char *opt_user_name; extern char *opt_password; +extern char *opt_workgroup; -static int rpc_trustdom_establish(int argc, const char **argv) { - +static int rpc_trustdom_establish(int argc, const char **argv) +{ struct cli_state *cli; struct in_addr server_ip; POLICY_HND connect_hnd; @@ -1582,19 +1590,26 @@ static int rpc_trustdom_establish(int argc, const char **argv) { */ if (argc != 1) { - d_printf("Usage: net rpc trustdom add \n"); + d_printf("Usage: net rpc trustdom establish \n"); return -1; } - domain_name = smb_xstrdup(argv[0]); strupper(domain_name); + /* + * opt_workgroup will be used by connection functions further, + * hence it should be set to remote domain name instead of ours + */ + if (opt_workgroup) { + SAFE_FREE(opt_workgroup); + opt_workgroup = smb_xstrdup(domain_name); + }; + asprintf(&acct_name, "%s$", lp_workgroup()); strupper(acct_name); - opt_user_name = (char*)malloc(strlen(acct_name) + 1); - safe_strcpy(opt_user_name, acct_name, strlen(acct_name) + 1); + opt_user_name = acct_name; /* find the domain controller */ if (!net_find_dc(&server_ip, pdc_name, domain_name)) { @@ -1634,10 +1649,7 @@ static int rpc_trustdom_establish(int argc, const char **argv) { /* * Call WksQueryInfo to check remote server's capabilities - * FIXME:Is really necessary ? nt serv does this, but from samba's - * point of view it doesn't seem to make the difference - * IDEA: It may be used to get info about type of pdc we're talking to - * (e.g. WinNT or Win2k) + * note: It is now used only to get unicode domain name */ if (!cli_nt_session_open(cli, PIPE_WKSSVC)) { @@ -1645,12 +1657,8 @@ static int rpc_trustdom_establish(int argc, const char **argv) { return -1; } - /* TODO: convert this call from rpc_client/cli_wkssvc.c - to cli_wks_query_info() in libsmb/cli_wkssvc.c - UPDATE: already done :) - */ - - if (!(mem_ctx = talloc_init())) { + if (!(mem_ctx = talloc_init_named("establishing trust relationship to domain %s", + domain_name))) { DEBUG(0, ("talloc_init() failed\n")); cli_shutdown(cli); return -1; @@ -1679,10 +1687,12 @@ static int rpc_trustdom_establish(int argc, const char **argv) { if (!cli_nt_session_open(cli, PIPE_LSARPC)) { DEBUG(0, ("Could not initialise lsa pipe\n")); + cli_shutdown(cli); + return -1; } nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE, - &connect_hnd); + &connect_hnd); if (NT_STATUS_IS_ERR(nt_status)) { DEBUG(0, ("Couldn't open policy handle. Error was %s\n", nt_errstr(nt_status))); @@ -1692,7 +1702,8 @@ static int rpc_trustdom_establish(int argc, const char **argv) { /* Querying info level 5 */ nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd, - 5 /* info level */, domain_name, &domain_sid); + 5 /* info level */, domain_name, + &domain_sid); if (NT_STATUS_IS_ERR(nt_status)) { DEBUG(0, ("LSA Query Info failed. Returned error was %s\n", nt_errstr(nt_status))); @@ -1700,6 +1711,8 @@ static int rpc_trustdom_establish(int argc, const char **argv) { } + + /* There should be actually query info level 3 (following nt serv behaviour), but I still don't know if it's _really_ necessary */ @@ -1743,8 +1756,8 @@ static int rpc_trustdom_establish(int argc, const char **argv) { * @return Integer status (0 means success) **/ -static int rpc_trustdom_revoke(int argc, const char **argv) { - +static int rpc_trustdom_revoke(int argc, const char **argv) +{ char* domain_name; if (argc < 1) return -1; @@ -1772,7 +1785,8 @@ static int rpc_trustdom_revoke(int argc, const char **argv) { * @return Integer status returned to shell **/ -static int rpc_trustdom_usage(int argc, const char **argv) { +static int rpc_trustdom_usage(int argc, const char **argv) +{ d_printf(" net rpc trustdom add \t\t add trusting domain's account\n"); d_printf(" net rpc trustdom del \t\t delete trusting domain's account\n"); d_printf(" net rpc trustdom establish \t establish relationship to trusted domain\n"); @@ -1782,6 +1796,249 @@ static int rpc_trustdom_usage(int argc, const char **argv) { } +static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + fstring str_sid; + sid_to_string(str_sid, domain_sid); + d_printf("%s\n", str_sid); + return NT_STATUS_OK; +}; + + +extern char* opt_workgroup; +extern char* opt_target_worgroup; +extern char* opt_host; +extern char* opt_password; + +static int rpc_trustdom_list(int argc, const char **argv) +{ + /* common variables */ + TALLOC_CTX* mem_ctx; + struct cli_state *cli, *remote_cli; + NTSTATUS nt_status; + char *domain_name = NULL; + DOM_SID queried_dom_sid; + fstring ascii_sid, padding; + int ascii_dom_name_len; + POLICY_HND connect_hnd; + + /* trusted domains listing variables */ + int enum_ctx = 0; + int num_domains, i, pad_len, col_len = 20; + DOM_SID *domain_sids; + char **trusted_dom_names; + fstring pdc_name; + + /* trusting domains listing variables */ + POLICY_HND domain_hnd; + char **trusting_dom_names; + uint32 *trusting_dom_rids; + + /* + * Listing trusted domains (stored in secrets.tdb, if local) + */ + + mem_ctx = talloc_init_named("trust relationships listing"); + + /* + * set domain and pdc name to local samba server (default) + * or to remote one given in command line + */ + strupper(opt_workgroup); + if (strcmp(opt_workgroup, lp_workgroup())) { + domain_name = opt_workgroup; + if (opt_target_workgroup) SAFE_FREE(opt_target_workgroup); + opt_target_workgroup = opt_workgroup; + } else { + safe_strcpy(pdc_name, global_myname, FSTRING_LEN); + domain_name = talloc_strdup(mem_ctx, lp_workgroup()); + if (opt_target_workgroup) SAFE_FREE(opt_target_workgroup); + opt_target_workgroup = domain_name; + }; + + /* open \PIPE\lsarpc and open policy handle */ + if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC))) { + DEBUG(0, ("Couldn't connect to domain controller\n")); + return -1; + }; + + if (!cli_nt_session_open(cli, PIPE_LSARPC)) { + DEBUG(0, ("Could not initialise lsa pipe\n")); + return -1; + }; + + nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE, + &connect_hnd); + if (NT_STATUS_IS_ERR(nt_status)) { + DEBUG(0, ("Couldn't open policy handle. Error was %s\n", + nt_errstr(nt_status))); + return -1; + }; + + /* query info level 5 to obtain sid of a domain being queried */ + nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd, + 5 /* info level */, domain_name, &queried_dom_sid); + if (NT_STATUS_IS_ERR(nt_status)) { + DEBUG(0, ("LSA Query Info failed. Returned error was %s\n", + nt_errstr(nt_status))); + return -1; + } + + /* + * Keep calling LsaEnumTrustdom over opened pipe until + * the end of enumeration is reached + */ + + d_printf("Trusted domains list:\n\n"); + + do { + nt_status = cli_lsa_enum_trust_dom(cli, mem_ctx, &connect_hnd, &enum_ctx, + &num_domains, + &trusted_dom_names, &domain_sids); + + if (NT_STATUS_IS_ERR(nt_status)) { + DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n", + nt_errstr(nt_status))); + return -1; + }; + + for (i = 0; i < num_domains; i++) { + /* convert sid into ascii string */ + sid_to_string(ascii_sid, &(domain_sids[i])); + + /* calculate padding space for d_printf to look nicer */ + pad_len = col_len - strlen(trusted_dom_names[i]); + padding[pad_len] = 0; + do padding[--pad_len] = ' '; while (pad_len); + + d_printf("%s%s%s\n", trusted_dom_names[i], padding, ascii_sid); + }; + + } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)); + + /* close this connection before doing next one */ + nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd); + if (NT_STATUS_IS_ERR(nt_status)) { + DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n", + nt_errstr(nt_status))); + return -1; + }; + + cli_nt_session_close(cli); + + /* + * Listing trusting domains (stored in passdb backend, if local) + */ + + d_printf("\nTrusting domains list:\n\n"); + + /* + * Open \PIPE\samr and get needed policy handles + */ + if (!cli_nt_session_open(cli, PIPE_SAMR)) { + DEBUG(0, ("Could not initialise samr pipe\n")); + return -1; + }; + + /* SamrConnect */ + nt_status = cli_samr_connect(cli, mem_ctx, SAMR_ACCESS_OPEN_DOMAIN, + &connect_hnd); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n", + nt_errstr(nt_status))); + return -1; + }; + + /* SamrOpenDomain - we have to open domain policy handle in order to be + able to enumerate accounts*/ + nt_status = cli_samr_open_domain(cli, mem_ctx, &connect_hnd, + DOMAIN_ACCESS_ENUM_ACCOUNTS, + &queried_dom_sid, &domain_hnd); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0, ("Couldn't open domain object. Error was %s\n", + nt_errstr(nt_status))); + return -1; + }; + + /* + * perform actual enumeration + */ + + enum_ctx = 0; /* reset enumeration context from last enumeration */ + do { + + nt_status = cli_samr_enum_dom_users(cli, mem_ctx, &domain_hnd, + &enum_ctx, ACB_DOMTRUST, 0xffff, + &trusting_dom_names, &trusting_dom_rids, + &num_domains); + if (NT_STATUS_IS_ERR(nt_status)) { + DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n", + nt_errstr(nt_status))); + return -1; + }; + + for (i = 0; i < num_domains; i++) { + + /* + * get each single domain's sid (do we _really_ need this ?): + * 1) connect to domain's pdc + * 2) query the pdc for domain's sid + */ + + /* get rid of '$' tail */ + ascii_dom_name_len = strlen(trusting_dom_names[i]); + if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN) + trusting_dom_names[i][ascii_dom_name_len - 1] = '\0'; + + /* calculate padding space for d_printf to look nicer */ + pad_len = col_len - strlen(trusting_dom_names[i]); + padding[pad_len] = 0; + do padding[--pad_len] = ' '; while (pad_len); + + /* set opt_* variables to remote domain */ + strupper(trusting_dom_names[i]); + opt_workgroup = talloc_strdup(mem_ctx, trusting_dom_names[i]); + if (opt_target_workgroup) SAFE_FREE(opt_target_workgroup); + opt_target_workgroup = opt_workgroup; + + d_printf("%s%s", trusting_dom_names[i], padding); + + /* connect to remote domain controller */ + remote_cli = net_make_ipc_connection(NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS); + if (remote_cli) { + /* query for domain's sid */ + if (run_rpc_command(remote_cli, PIPE_LSARPC, 0, rpc_query_domain_sid, argc, argv)) + d_printf("couldn't get domain's sid\n"); + + cli_shutdown(remote_cli); + + } else { + d_printf("domain controller is not responding\n"); + }; + }; + + } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)); + + /* close opened samr and domain policy handles */ + nt_status = cli_samr_close(cli, mem_ctx, &domain_hnd); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name)); + }; + + nt_status = cli_samr_close(cli, mem_ctx, &connect_hnd); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name)); + }; + + /* close samr pipe and connection to IPC$ */ + cli_nt_session_close(cli); + cli_shutdown(cli); + + talloc_destroy(mem_ctx); + return 0; +} + /** * Entrypoint for 'net rpc trustdom' code * @@ -1799,6 +2056,7 @@ static int rpc_trustdom(int argc, const char **argv) {"establish", rpc_trustdom_establish}, {"revoke", rpc_trustdom_revoke}, {"help", rpc_trustdom_usage}, + {"list", rpc_trustdom_list}, {NULL, NULL} }; @@ -1862,6 +2120,7 @@ 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 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"); @@ -1924,6 +2183,7 @@ int net_rpc(int argc, const char **argv) struct functable func[] = { {"info", net_rpc_info}, {"join", net_rpc_join}, + {"testjoin", net_rpc_testjoin}, {"user", net_rpc_user}, {"group", net_rpc_group}, {"share", net_rpc_share}, diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index cc1a203ca1..c8be93c39c 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -35,6 +35,61 @@ goto done; \ } + +/** + * confirm that a domain join is still valid + * + * @return A shell status integer (0 for success) + * + **/ +int net_rpc_join_ok(const char *domain) +{ + struct cli_state *cli; + uchar stored_md4_trust_password[16]; + int retval = 1; + uint32 channel; + NTSTATUS result; + + /* 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 done; + } + + if (!secrets_fetch_trust_account_password(domain, + stored_md4_trust_password, NULL)) { + DEBUG(0,("Could not reterive domain trust secret")); + goto done; + } + + if (lp_server_role() == ROLE_DOMAIN_BDC || + lp_server_role() == ROLE_DOMAIN_PDC) { + channel = SEC_CHAN_BDC; + } else { + channel = SEC_CHAN_WKSTA; + } + + CHECK_RPC_ERR(cli_nt_setup_creds(cli, + channel, + stored_md4_trust_password), + "error in domain join verification"); + + retval = 0; /* Success! */ + +done: + /* Close down pipe - this will clean up open policy handles */ + if (cli->nt_pipe_fnum) + cli_nt_session_close(cli); + + cli_shutdown(cli); + + return retval; +} + /** * Join a domain using the administrator username and password * @@ -67,7 +122,6 @@ int net_rpc_join_newstyle(int argc, const char **argv) char *clear_trust_password = NULL; fstring ucs2_trust_password; int ucs2_pw_len; - uchar stored_md4_trust_password[16]; uchar pwbuf[516], sess_key[16]; SAM_USERINFO_CTR ctr; SAM_USER_INFO_24 p24; @@ -80,8 +134,9 @@ int net_rpc_join_newstyle(int argc, const char **argv) fstring domain; uint32 num_rids, *name_types, *user_rids; uint32 flags = 0x3e8; - const char *acct_name; - + char *acct_name; + const char *const_acct_name; + /* Connect to remote machine */ if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC))) @@ -133,6 +188,7 @@ int net_rpc_join_newstyle(int argc, const char **argv) /* Create domain user */ acct_name = talloc_asprintf(mem_ctx, "%s$", global_myname); strlower(acct_name); + const_acct_name = acct_name; acb_info = ((lp_server_role() == ROLE_DOMAIN_BDC) || lp_server_role() == ROLE_DOMAIN_PDC) ? ACB_SVRTRUST : ACB_WSTRUST; @@ -162,7 +218,8 @@ int net_rpc_join_newstyle(int argc, const char **argv) CHECK_RPC_ERR_DEBUG(cli_samr_lookup_names(cli, mem_ctx, &domain_pol, flags, - 1, &acct_name, &num_rids, + 1, &const_acct_name, + &num_rids, &user_rids, &name_types), ("error looking up rid for user %s: %s\n", acct_name, nt_errstr(result))); @@ -253,28 +310,10 @@ int net_rpc_join_newstyle(int argc, const char **argv) } /* Now check the whole process from top-to-bottom */ - cli_samr_close(cli, mem_ctx, &user_pol); - cli_nt_session_close(cli); /* Done with this pipe */ - if (!cli_nt_session_open(cli, PIPE_NETLOGON)) { - DEBUG(0, ("Error connecting to NETLOGON pipe\n")); - goto done; - } - - if (!secrets_fetch_trust_account_password(domain, - stored_md4_trust_password, NULL)) { - DEBUG(0, ("Could not reterive secrets we just stored!")); - goto done; - } - - CHECK_RPC_ERR(new_cli_nt_setup_creds(cli, - (acb_info & ACB_SVRTRUST) ? SEC_CHAN_BDC : SEC_CHAN_WKSTA, - stored_md4_trust_password), - "error in domain join verification"); - - retval = 0; /* Success! */ + retval = net_rpc_join_ok(domain); done: /* Close down pipe - this will clean up open policy handles */ @@ -297,3 +336,28 @@ done: return retval; } + + +/** + * check that a join is OK + * + * @return A shell status integer (0 for success) + * + **/ +int net_rpc_testjoin(int argc, const char **argv) +{ + char *domain = lp_workgroup(); + + domain = smb_xstrdup(domain); + + /* Display success or failure */ + if (net_rpc_join_ok(domain) != 0) { + fprintf(stderr,"Join to domain '%s' is not valid\n",domain); + free(domain); + return -1; + } + + printf("Join to '%s' is OK\n",domain); + free(domain); + return 0; +} diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index b30ab6f38e..51dbbb98c0 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -23,6 +23,35 @@ #include "includes.h" +#define BIT_CONFIGFILE 0x00000001 +#define BIT_DEBUGLEVEL 0x00000002 +#define BIT_BACKEND 0x00000004 +#define BIT_VERBOSE 0x00000008 +#define BIT_SPSTYLE 0x00000010 +#define BIT_RESERV_1 0x00000020 +#define BIT_RESERV_2 0x00000040 +#define BIT_RESERV_3 0x00000080 +#define BIT_FULLNAME 0x00000100 +#define BIT_HOMEDIR 0x00000200 +#define BIT_HDIRDRIVE 0x00000400 +#define BIT_LOGSCRIPT 0x00000800 +#define BIT_PROFILE 0x00001000 +#define BIT_MACHINE 0x00002000 +#define BIT_RESERV_4 0x00004000 +#define BIT_USER 0x00008000 +#define BIT_LIST 0x00010000 +#define BIT_MODIFY 0x00020000 +#define BIT_CREATE 0x00040000 +#define BIT_DELETE 0x00080000 +#define BIT_ACCPOLICY 0x00100000 +#define BIT_ACCPOLVAL 0x00200000 +#define BIT_RESERV_6 0x00400000 +#define BIT_RESERV_7 0x00800000 +#define BIT_IMPORT 0x01000000 +#define BIT_EXPORT 0x02000000 + +#define MASK_ALWAYS_GOOD 0x0000001F +#define MASK_USER_GOOD 0x00001F00 extern pstring global_myname; extern BOOL AllowDebugChange; @@ -30,27 +59,21 @@ extern BOOL AllowDebugChange; Add all currently available users to another db ********************************************************/ -int export_database (struct pdb_context *in, char *db){ - struct pdb_context *context; +static int export_database (struct pdb_context *in, struct pdb_context *out) { SAM_ACCOUNT *user = NULL; - if (!NT_STATUS_IS_OK(make_pdb_context_string(&context, db))){ - fprintf(stderr, "Can't initialize %s.\n", db); - return 1; - } - - if (!in->pdb_setsampwent(in, 0)){ + if (!in->pdb_setsampwent(in, 0)) { fprintf(stderr, "Can't sampwent!\n"); return 1; } - if (!NT_STATUS_IS_OK(pdb_init_sam(&user))){ + if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) { fprintf(stderr, "Can't initialize new SAM_ACCOUNT!\n"); return 1; } - while (in->pdb_getsampwent(in,user)){ - context->pdb_add_sam_account(context,user); + while (in->pdb_getsampwent(in, user)) { + out->pdb_add_sam_account(out, user); if (!NT_STATUS_IS_OK(pdb_reset_sam(user))){ fprintf(stderr, "Can't reset SAM_ACCOUNT!\n"); return 1; @@ -91,7 +114,7 @@ static int print_sam_info (SAM_ACCOUNT *sam_pwent, BOOL verbosity, BOOL smbpwdst sid_string_static(pdb_get_group_sid(sam_pwent))); printf ("Full Name: %s\n", pdb_get_fullname(sam_pwent)); printf ("Home Directory: %s\n", pdb_get_homedir(sam_pwent)); - printf ("HomeDir Drive: %s\n", pdb_get_dirdrive(sam_pwent)); + printf ("HomeDir Drive: %s\n", pdb_get_dir_drive(sam_pwent)); printf ("Logon Script: %s\n", pdb_get_logon_script(sam_pwent)); printf ("Profile Path: %s\n", pdb_get_profile_path(sam_pwent)); printf ("Domain: %s\n", pdb_get_domain(sam_pwent)); @@ -255,7 +278,7 @@ static int new_user (struct pdb_context *in, char *username, char *fullname, cha { SAM_ACCOUNT *sam_pwent=NULL; struct passwd *pwd = NULL; - char *password1, *password2; + char *password1, *password2, *staticpass; ZERO_STRUCT(sam_pwent); @@ -270,15 +293,27 @@ static int new_user (struct pdb_context *in, char *username, char *fullname, cha } } - password1 = getpass("new password:"); - password2 = getpass("retype new password:"); + staticpass = getpass("new password:"); + password1 = strdup(staticpass); + memset(staticpass, 0, strlen(staticpass)); + staticpass = getpass("retype new password:"); + password2 = strdup(staticpass); + memset(staticpass, 0, strlen(staticpass)); if (strcmp (password1, password2)) { - fprintf (stderr, "Passwords does not match!\n"); - pdb_free_sam (&sam_pwent); - return -1; + fprintf (stderr, "Passwords does not match!\n"); + memset(password1, 0, strlen(password1)); + SAFE_FREE(password1); + memset(password2, 0, strlen(password2)); + SAFE_FREE(password2); + pdb_free_sam (&sam_pwent); + return -1; } pdb_set_plaintext_passwd(sam_pwent, password1); + memset(password1, 0, strlen(password1)); + SAFE_FREE(password1); + memset(password2, 0, strlen(password2)); + SAFE_FREE(password2); if (fullname) pdb_set_fullname(sam_pwent, fullname); @@ -384,7 +419,7 @@ static int delete_machine_entry (struct pdb_context *in, char *machinename) } if (!in->pdb_getsampwnam(in, samaccount, name)) { - fprintf (stderr, "user %s does not exist in the passdb\n", name); + fprintf (stderr, "machine %s does not exist in the passdb\n", name); return -1; } @@ -400,129 +435,230 @@ int main (int argc, char **argv) static BOOL list_users = False; static BOOL verbose = False; static BOOL spstyle = False; - static BOOL setparms = False; static BOOL machine = False; static BOOL add_user = False; static BOOL delete_user = False; - static BOOL import = False; + static BOOL modify_user = False; + uint32 setparms, checkparms; int opt; static char *full_name = NULL; static char *user_name = NULL; static char *home_dir = NULL; static char *home_drive = NULL; + static char *backend = NULL; static char *backend_in = NULL; static char *backend_out = NULL; static char *logon_script = NULL; static char *profile_path = NULL; static char *config_file = dyn_CONFIGFILE; static char *new_debuglevel = NULL; + static char *account_policy = NULL; + static long int account_policy_value = 0; + BOOL account_policy_value_set = False; - struct pdb_context *in; + struct pdb_context *bin; + struct pdb_context *bout; + struct pdb_context *bdef; poptContext pc; struct poptOption long_options[] = { POPT_AUTOHELP - {"list", 'l',POPT_ARG_VAL, &list_users, 1, "list all users", NULL}, - {"verbose", 'v',POPT_ARG_VAL, &verbose, 1, "be verbose", NULL }, - {"smbpasswd-style", 'w',POPT_ARG_VAL, &spstyle, 1, "give output in smbpasswd style", NULL}, - {"user", 'u',POPT_ARG_STRING,&user_name, 0, "use username", "USER" }, - {"fullname", 'f',POPT_ARG_STRING,&full_name, 0, "set full name", NULL}, - {"homedir", 'h',POPT_ARG_STRING,&home_dir, 0, "set home directory", NULL}, - {"drive", 'd',POPT_ARG_STRING,&home_drive, 0, "set home drive", NULL}, - {"script", 's',POPT_ARG_STRING,&logon_script, 0, "set logon script", NULL}, - {"profile", 'p',POPT_ARG_STRING,&profile_path, 0, "set profile path", NULL}, - {"create", 'a',POPT_ARG_VAL,&add_user, 1, "create user", NULL}, - {"machine", 'm',POPT_ARG_VAL,&machine, 1,"account is a machine account",NULL}, - {"delete", 'x',POPT_ARG_VAL,&delete_user,1,"delete user",NULL}, - {"import", 'i',POPT_ARG_STRING,&backend_in,0,"use different passdb backend",NULL}, - {"export", 'e',POPT_ARG_STRING,&backend_out,0,"export user accounts to backend", NULL}, - {"debuglevel",'D', POPT_ARG_STRING, &new_debuglevel,0,"set debuglevel",NULL}, - {"configfile",'c',POPT_ARG_STRING, &config_file,0,"use different configuration file",NULL}, + {"list", 'l', POPT_ARG_NONE, &list_users, 0, "list all users", NULL}, + {"verbose", 'v', POPT_ARG_NONE, &verbose, 0, "be verbose", NULL }, + {"smbpasswd-style", 'w',POPT_ARG_NONE, &spstyle, 0, "give output in smbpasswd style", NULL}, + {"user", 'u', POPT_ARG_STRING, &user_name, 0, "use username", "USER" }, + {"fullname", 'f', POPT_ARG_STRING, &full_name, 0, "set full name", NULL}, + {"homedir", 'h', POPT_ARG_STRING, &home_dir, 0, "set home directory", NULL}, + {"drive", 'd', POPT_ARG_STRING, &home_drive, 0, "set home drive", NULL}, + {"script", 's', POPT_ARG_STRING, &logon_script, 0, "set logon script", NULL}, + {"profile", 'p', POPT_ARG_STRING, &profile_path, 0, "set profile path", NULL}, + {"create", 'a', POPT_ARG_NONE, &add_user, 0, "create user", NULL}, + {"modify", 'r', POPT_ARG_NONE, &modify_user, 0, "modify user", NULL}, + {"machine", 'm', POPT_ARG_NONE, &machine, 0, "account is a machine account", NULL}, + {"delete", 'x', POPT_ARG_NONE, &delete_user, 0, "delete user", NULL}, + {"backend", 'b', POPT_ARG_STRING, &backend, 0, "use different passdb backend as default backend", NULL}, + {"import", 'i', POPT_ARG_STRING, &backend_in, 0, "import user accounts from this backend", NULL}, + {"export", 'e', POPT_ARG_STRING, &backend_out, 0, "export user accounts to this backend", NULL}, + {"debuglevel", 'D', POPT_ARG_STRING, &new_debuglevel, 0,"set debuglevel",NULL}, + {"configfile", 'c', POPT_ARG_STRING, &config_file, 0,"use different configuration file",NULL}, + {"account-policy", 'P', POPT_ARG_STRING, &account_policy, 0,"value of an account policy (like maximum password age)",NULL}, + {"value", 'V', POPT_ARG_LONG, &account_policy_value, 'V',"set the account policy to this value", NULL}, {0,0,0,0} }; - + setup_logging("pdbedit", True); - + pc = poptGetContext(NULL, argc, (const char **) argv, long_options, - POPT_CONTEXT_KEEP_FIRST); - - while((opt = poptGetNextOpt(pc)) != -1); - - if (new_debuglevel){ + POPT_CONTEXT_KEEP_FIRST); + + while((opt = poptGetNextOpt(pc)) != -1) { + switch (opt) { + case 'V': + account_policy_value_set = True; + break; + } + } + + if (new_debuglevel) { debug_parse_levels(new_debuglevel); AllowDebugChange = False; } - + if (!lp_load(config_file,True,False,False)) { - fprintf(stderr, "Can't load %s - run testparm to debug it\n", - config_file); + fprintf(stderr, "Can't load %s - run testparm to debug it\n", config_file); exit(1); } - - setparms = (full_name || home_dir || home_drive || logon_script || profile_path); - - if (((add_user?1:0) + (delete_user?1:0) + (list_users?1:0) + (import?1:0) + (setparms?1:0)) + (backend_out?1:0) > 1) { - fprintf (stderr, "Incompatible options on command line!\n"); - exit(1); - } - - if (!backend_in) { - if (!NT_STATUS_IS_OK(make_pdb_context_list(&in, lp_passdb_backend()))){ + setparms = (config_file ? BIT_CONFIGFILE : 0) + + (new_debuglevel ? BIT_DEBUGLEVEL : 0) + + (backend ? BIT_BACKEND : 0) + + (verbose ? BIT_VERBOSE : 0) + + (spstyle ? BIT_SPSTYLE : 0) + + (full_name ? BIT_FULLNAME : 0) + + (home_dir ? BIT_HOMEDIR : 0) + + (home_drive ? BIT_HDIRDRIVE : 0) + + (logon_script ? BIT_LOGSCRIPT : 0) + + (profile_path ? BIT_PROFILE : 0) + + (machine ? BIT_MACHINE : 0) + + (user_name ? BIT_USER : 0) + + (list_users ? BIT_LIST : 0) + + (modify_user ? BIT_MODIFY : 0) + + (add_user ? BIT_CREATE : 0) + + (delete_user ? BIT_DELETE : 0) + + (account_policy ? BIT_ACCPOLICY : 0) + + (account_policy_value_set ? BIT_ACCPOLVAL : 0) + + (backend_in ? BIT_IMPORT : 0) + + (backend_out ? BIT_EXPORT : 0); + + if (setparms & BIT_BACKEND) { + if (!NT_STATUS_IS_OK(make_pdb_context_string(&bdef, backend))) { fprintf(stderr, "Can't initialize passdb backend.\n"); return 1; } } else { - if (!NT_STATUS_IS_OK(make_pdb_context_string(&in, backend_in))){ + if (!NT_STATUS_IS_OK(make_pdb_context_list(&bdef, lp_passdb_backend()))) { fprintf(stderr, "Can't initialize passdb backend.\n"); return 1; } } + + /* the lowest bit options are always accepted */ + checkparms = setparms & ~MASK_ALWAYS_GOOD; + + /* accoun tpolicy operations */ + if ((checkparms & BIT_ACCPOLICY) && !(checkparms & ~(BIT_ACCPOLICY + BIT_ACCPOLVAL))) { + uint32 value; + int field = account_policy_name_to_fieldnum(account_policy); + if (field == 0) { + fprintf(stderr, "No account policy by that name\n"); + exit(1); + } + if (!account_policy_get(field, &value)) { + fprintf(stderr, "valid account policy, but unable to fetch value!\n"); + exit(1); + } + if (account_policy_value_set) { + printf("account policy value for %s was %u\n", account_policy, value); + if (!account_policy_set(field, account_policy_value)) { + fprintf(stderr, "valid account policy, but unable to set value!\n"); + exit(1); + } + printf("account policy value for %s is now %lu\n", account_policy, account_policy_value); + exit(0); + } else { + printf("account policy value for %s is %u\n", account_policy, value); + exit(0); + } + } - if (add_user) { - if (!user_name) { - fprintf (stderr, "Username not specified! (use -u option)\n"); - return -1; + /* import and export operations */ + if (((checkparms & BIT_IMPORT) || (checkparms & BIT_EXPORT)) + && !(checkparms & ~(BIT_IMPORT +BIT_EXPORT))) { + if (backend_in) { + if (!NT_STATUS_IS_OK(make_pdb_context_string(&bin, backend_in))) { + fprintf(stderr, "Can't initialize passdb backend.\n"); + return 1; + } + } else { + bin = bdef; } - if (machine) - return new_machine (in, user_name); - else - return new_user (in, user_name, full_name, home_dir, - home_drive, logon_script, - profile_path); + if (backend_out) { + if (!NT_STATUS_IS_OK(make_pdb_context_string(&bout, backend_out))) { + fprintf(stderr, "Can't initialize %s.\n", backend_out); + return 1; + } + } else { + bout = bdef; + } + return export_database(bin, bout); } - if (delete_user) { - if (!user_name) { + /* if BIT_USER is defined but nothing else then threat it as -l -u for compatibility */ + /* fake up BIT_LIST if only BIT_USER is defined */ + if ((checkparms & BIT_USER) && !(checkparms & ~BIT_USER)) { + checkparms += BIT_LIST; + } + + /* modify flag is optional to maintain backwards compatibility */ + /* fake up BIT_MODIFY if BIT_USER and at least one of MASK_USER_GOOD is defined */ + if (!((checkparms & ~MASK_USER_GOOD) & ~BIT_USER) && (checkparms & MASK_USER_GOOD)) { + checkparms += BIT_MODIFY; + } + + /* list users operations */ + if (checkparms & BIT_LIST) { + if (!(checkparms & ~BIT_LIST)) { + return print_users_list (bdef, verbose, spstyle); + } + if (!(checkparms & ~(BIT_USER + BIT_LIST))) { + return print_user_info (bdef, user_name, verbose, spstyle); + } + } + + /* mask out users options */ + checkparms &= ~MASK_USER_GOOD; + + /* account operation */ + if ((checkparms & BIT_CREATE) || (checkparms & BIT_MODIFY) || (checkparms & BIT_DELETE)) { + /* check use of -u option */ + if (!(checkparms & BIT_USER)) { fprintf (stderr, "Username not specified! (use -u option)\n"); return -1; } - if (machine) - return delete_machine_entry (in, user_name); - else - return delete_user_entry (in, user_name); - } - if (user_name) { - if (setparms) - return set_user_info (in, user_name, full_name, + /* account creation operations */ + if (!(checkparms & ~(BIT_CREATE + BIT_USER + BIT_MACHINE))) { + if (checkparms & BIT_MACHINE) { + return new_machine (bdef, user_name); + } else { + return new_user (bdef, user_name, full_name, home_dir, + home_drive, logon_script, + profile_path); + } + } + + /* account deletion operations */ + if (!(checkparms & ~(BIT_DELETE + BIT_USER + BIT_MACHINE))) { + if (checkparms & BIT_MACHINE) { + return delete_machine_entry (bdef, user_name); + } else { + return delete_user_entry (bdef, user_name); + } + } + + /* account modification operations */ + if (!(checkparms & ~(BIT_MODIFY + BIT_USER))) { + return set_user_info (bdef, user_name, full_name, home_dir, home_drive, logon_script, profile_path); - else - return print_user_info (in, user_name, verbose, - spstyle); + } } - if (list_users) - return print_users_list (in, verbose, spstyle); - - if (backend_out) - return export_database(in, backend_out); - + if (setparms >= 0x20) { + fprintf (stderr, "Incompatible or insufficient options on command line!\n"); + } poptPrintHelp(pc, stderr, 0); return 1; } - - diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c index b6a13180a3..4f9df90fa2 100644 --- a/source3/utils/smbcacls.c +++ b/source3/utils/smbcacls.c @@ -29,7 +29,7 @@ static pstring owner_username; static fstring server; static int got_pass; static int test_args; -TALLOC_CTX *ctx; +static TALLOC_CTX *ctx; #define CREATE_ACCESS_READ READ_CONTROL_ACCESS #define CREATE_ACCESS_WRITE (WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS) diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index 65519e8888..2d78b21dcc 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -223,6 +223,23 @@ static void register_all(void) message_register(MSG_POOL_USAGE, pool_usage_cb); } +/* This guy is here so we can link printing/notify.c to the smbcontrol + binary without having to pull in tons of other crap. */ + +TDB_CONTEXT *conn_tdb_ctx(void) +{ + static TDB_CONTEXT *tdb; + + if (tdb) + return tdb; + + tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0); + + if (!tdb) + DEBUG(3, ("Failed to open connections database in send_spoolss_notify2_msg\n")); + + return tdb; +} /**************************************************************************** do command @@ -352,6 +369,9 @@ static BOOL do_command(char *dest, char *msg_name, int iparams, char **params) fprintf(stderr, "Must specify subcommand:\n"); fprintf(stderr, "\tqueuepause \n"); fprintf(stderr, "\tqueueresume \n"); + fprintf(stderr, "\tjobpause \n"); + fprintf(stderr, "\tjobresume \n"); + fprintf(stderr, "\tjobdelete \n"); return False; } diff --git a/source3/utils/smbgroupedit.c b/source3/utils/smbgroupedit.c index 3fdc07c2d5..4358e6f08c 100644 --- a/source3/utils/smbgroupedit.c +++ b/source3/utils/smbgroupedit.c @@ -22,7 +22,7 @@ #include "includes.h" extern pstring global_myname; -extern pstring global_myworkgroup; +extern fstring global_myworkgroup; /* * Next two lines needed for SunOS and don't @@ -45,11 +45,13 @@ static void usage(void) printf(" -a group create new group\n"); printf(" -n group NT group name\n"); printf(" -p privilege only local\n"); + printf(" -d description group description\n"); printf(" -v list groups\n"); printf(" -l long list (include details)\n"); printf(" -s short list (default)\n"); printf(" -c SID change group\n"); printf(" -u unix group\n"); + printf(" -d description group description\n"); printf(" -x group delete this group\n"); printf("\n"); printf(" -t[b|d|l] type: builtin, domain, local \n"); diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index 70bf551edb..98993676c9 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -92,7 +92,7 @@ static int process_options(int argc, char **argv, int local_flags) user_name[0] = '\0'; - while ((ch = getopt(argc, argv, "c:axdehmnjr:sw:R:D:U:L")) != EOF) { + while ((ch = getopt(argc, argv, "c:axdehminjr:sw:R:D:U:L")) != EOF) { switch(ch) { case 'L': local_flags |= LOCAL_AM_ROOT; @@ -416,9 +416,11 @@ static int process_root(int local_flags) exit(1); } } + + /* prepare uppercased and '$' terminated username */ slprintf(buf, sizeof(buf) - 1, "%s$", user_name); fstrcpy(user_name, buf); - + } else { if (remote_machine != NULL) { diff --git a/source3/utils/smbtree.c b/source3/utils/smbtree.c index bcb460ee0b..b733f8112f 100644 --- a/source3/utils/smbtree.c +++ b/source3/utils/smbtree.c @@ -32,7 +32,7 @@ struct user_auth_info { /* How low can we go? */ enum tree_level {LEV_WORKGROUP, LEV_SERVER, LEV_SHARE}; -enum tree_level level = LEV_SHARE; +static enum tree_level level = LEV_SHARE; static void usage(void) { diff --git a/source3/utils/status.c b/source3/utils/status.c index b1e8bb9d8e..0b0c591cb1 100644 --- a/source3/utils/status.c +++ b/source3/utils/status.c @@ -37,14 +37,6 @@ extern BOOL AllowDebugChange; -struct session_record{ - pid_t pid; - uid_t uid; - char machine[31]; - time_t start; - struct session_record *next; -} *srecs; - static pstring Ucrit_username = ""; /* added by OH */ static pid_t Ucrit_pid[100]; /* Ugly !!! */ /* added by OH */ static int Ucrit_MaxPid=0; /* added by OH */ @@ -559,7 +551,7 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo {"brief", 'b', POPT_ARG_NONE, &brief}, {"profile", 'P', POPT_ARG_NONE, &profile_only}, {"byterange", 'B', POPT_ARG_NONE, &show_brl}, - {"debug", 'd', POPT_ARG_STRING, &new_debuglevel}, + { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug }, { 0, 0, 0, 0} }; diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c index 1d48249a75..3086019467 100644 --- a/source3/utils/testparm.c +++ b/source3/utils/testparm.c @@ -175,7 +175,6 @@ int main(int argc, char *argv[]) { extern char *optarg; extern int optind; - extern fstring local_machine; const char *config_file = dyn_CONFIGFILE; int s; static BOOL silent_mode = False; @@ -183,7 +182,7 @@ int main(int argc, char *argv[]) int opt; poptContext pc; static char *term_code = ""; - static char *new_local_machine = local_machine; + static char *new_local_machine = NULL; const char *cname; const char *caddr; @@ -207,8 +206,10 @@ int main(int argc, char *argv[]) cname = poptGetArg(pc); caddr = poptGetArg(pc); - - fstrcpy(local_machine,new_local_machine); + + if (new_local_machine) { + set_local_machine_name(new_local_machine); + } dbf = x_stdout; DEBUGLEVEL = 2; -- cgit