diff options
Diffstat (limited to 'source3/utils')
-rw-r--r-- | source3/utils/net_ads.c | 651 | ||||
-rw-r--r-- | source3/utils/net_dom.c | 4 | ||||
-rw-r--r-- | source3/utils/net_domain.c | 344 | ||||
-rw-r--r-- | source3/utils/net_lookup.c | 9 | ||||
-rw-r--r-- | source3/utils/net_rpc.c | 1670 | ||||
-rw-r--r-- | source3/utils/net_rpc_audit.c | 34 | ||||
-rw-r--r-- | source3/utils/net_rpc_join.c | 125 | ||||
-rw-r--r-- | source3/utils/net_rpc_rights.c | 193 | ||||
-rw-r--r-- | source3/utils/net_rpc_samsync.c | 959 | ||||
-rw-r--r-- | source3/utils/net_rpc_service.c | 369 | ||||
-rw-r--r-- | source3/utils/net_rpc_sh_acct.c | 167 | ||||
-rw-r--r-- | source3/utils/ntlm_auth.c | 424 | ||||
-rw-r--r-- | source3/utils/smbcontrol.c | 57 | ||||
-rw-r--r-- | source3/utils/smbfilter.c | 8 |
14 files changed, 2512 insertions, 2502 deletions
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 732ba8d8b6..9358a4f184 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -23,6 +23,8 @@ #include "includes.h" #include "utils/net.h" +#include "libnet/libnet.h" + #ifdef HAVE_ADS int net_ads_usage(int argc, const char **argv) @@ -810,76 +812,65 @@ static int net_ads_status(int argc, const char **argv) static int net_ads_leave(int argc, const char **argv) { - ADS_STRUCT *ads = NULL; - ADS_STATUS adsret; - NTSTATUS status; - int ret = -1; - struct cli_state *cli = NULL; TALLOC_CTX *ctx; - DOM_SID *dom_sid = NULL; - const char *short_domain_name = NULL; - - if (!secrets_init()) { - DEBUG(1,("Failed to initialise secrets database\n")); - return -1; - } + struct libnet_UnjoinCtx *r = NULL; + WERROR werr; if (!(ctx = talloc_init("net_ads_leave"))) { d_fprintf(stderr, "Could not initialise talloc context.\n"); return -1; } - /* The finds a DC and takes care of getting the - user creds if necessary */ + use_in_memory_ccache(); - if (!ADS_ERR_OK(ads_startup(True, &ads))) { + werr = libnet_init_UnjoinCtx(ctx, &r); + if (!W_ERROR_IS_OK(werr)) { + d_fprintf(stderr, "Could not initialise unjoin context.\n"); return -1; } - /* make RPC calls here */ + r->in.debug = opt_verbose; + r->in.dc_name = opt_host; + r->in.domain_name = lp_realm(); + r->in.admin_account = opt_user_name; + r->in.admin_password = net_prompt_pass(opt_user_name); + r->in.unjoin_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | + WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE; - if ( !NT_STATUS_IS_OK(connect_to_ipc_krb5(&cli, &ads->ldap.ss, - ads->config.ldap_server_name)) ) - { + werr = libnet_Unjoin(ctx, r); + if (!W_ERROR_IS_OK(werr)) { + d_printf("Failed to leave domain: %s\n", + r->out.error_string ? r->out.error_string : + get_friendly_werror_msg(werr)); goto done; } - if ( !NT_STATUS_IS_OK(netdom_get_domain_sid( ctx, cli, &short_domain_name, &dom_sid )) ) { + if (W_ERROR_IS_OK(werr)) { + d_printf("Deleted account for '%s' in realm '%s'\n", + r->in.machine_name, r->out.dns_domain_name); goto done; } - saf_delete( short_domain_name ); - - status = netdom_leave_domain(ctx, cli, dom_sid); - - /* Try and delete it via LDAP - the old way we used to. */ - - adsret = ads_leave_realm(ads, global_myname()); - if (ADS_ERR_OK(adsret)) { - d_printf("Deleted account for '%s' in realm '%s'\n", - global_myname(), ads->config.realm); - ret = 0; - } else { - /* We couldn't delete it - see if the disable succeeded. */ - if (NT_STATUS_IS_OK(status)) { - d_printf("Disabled account for '%s' in realm '%s'\n", - global_myname(), ads->config.realm); - ret = 0; - } else { - d_fprintf(stderr, "Failed to disable machine account for '%s' in realm '%s'\n", - global_myname(), ads->config.realm); - } + /* We couldn't delete it - see if the disable succeeded. */ + if (r->out.disabled_machine_account) { + d_printf("Disabled account for '%s' in realm '%s'\n", + r->in.machine_name, r->out.dns_domain_name); + werr = WERR_OK; + goto done; } -done: + d_fprintf(stderr, "Failed to disable machine account for '%s' in realm '%s'\n", + r->in.machine_name, r->out.dns_domain_name); - if ( cli ) - cli_shutdown(cli); + done: + TALLOC_FREE(r); + TALLOC_FREE(ctx); - ads_destroy(&ads); - TALLOC_FREE( ctx ); + if (W_ERROR_IS_OK(werr)) { + return 0; + } - return ret; + return -1; } static NTSTATUS net_ads_join_ok(void) @@ -957,338 +948,6 @@ static NTSTATUS check_ads_config( void ) } /******************************************************************* - Do the domain join - ********************************************************************/ - -static NTSTATUS net_join_domain(TALLOC_CTX *ctx, const char *servername, - struct sockaddr_storage *pss, - const char **domain, - DOM_SID **dom_sid, - const char *password) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct cli_state *cli = NULL; - - ret = connect_to_ipc_krb5(&cli, pss, servername); - if ( !NT_STATUS_IS_OK(ret) ) { - goto done; - } - - ret = netdom_get_domain_sid( ctx, cli, domain, dom_sid ); - if ( !NT_STATUS_IS_OK(ret) ) { - goto done; - } - - /* cli->server_domain is not filled in when using krb5 - session setups */ - - saf_store( *domain, cli->desthost ); - - ret = netdom_join_domain( ctx, cli, *dom_sid, password, ND_TYPE_AD ); - -done: - if ( cli ) - cli_shutdown(cli); - - return ret; -} - -/******************************************************************* - Set a machines dNSHostName and servicePrincipalName attributes - ********************************************************************/ - -static ADS_STATUS net_set_machine_spn(TALLOC_CTX *ctx, ADS_STRUCT *ads_s ) -{ - ADS_STATUS status = ADS_ERROR(LDAP_SERVER_DOWN); - char *new_dn; - ADS_MODLIST mods; - const char *servicePrincipalName[3] = {NULL, NULL, NULL}; - char *psp; - fstring my_fqdn; - LDAPMessage *res = NULL; - char *dn_string = NULL; - const char *machine_name = global_myname(); - int count; - - if ( !machine_name ) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - /* Find our DN */ - - status = ads_find_machine_acct(ads_s, &res, machine_name); - if (!ADS_ERR_OK(status)) - return status; - - if ( (count = ads_count_replies(ads_s, res)) != 1 ) { - DEBUG(1,("net_set_machine_spn: %d entries returned!\n", count)); - return ADS_ERROR(LDAP_NO_MEMORY); - } - - if ( (dn_string = ads_get_dn(ads_s, res)) == NULL ) { - DEBUG(1, ("ads_add_machine_acct: ads_get_dn returned NULL (malloc failure?)\n")); - goto done; - } - - new_dn = talloc_strdup(ctx, dn_string); - ads_memfree(ads_s, dn_string); - if (!new_dn) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - /* Windows only creates HOST/shortname & HOST/fqdn. */ - - if ( !(psp = talloc_asprintf(ctx, "HOST/%s", machine_name)) ) - goto done; - strupper_m(psp); - servicePrincipalName[0] = psp; - - name_to_fqdn(my_fqdn, machine_name); - strlower_m(my_fqdn); - if ( !(psp = talloc_asprintf(ctx, "HOST/%s", my_fqdn)) ) - goto done; - servicePrincipalName[1] = psp; - - if (!(mods = ads_init_mods(ctx))) { - goto done; - } - - /* fields of primary importance */ - - ads_mod_str(ctx, &mods, "dNSHostName", my_fqdn); - ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); - - status = ads_gen_mod(ads_s, new_dn, mods); - -done: - ads_msgfree(ads_s, res); - - return status; -} - -/******************************************************************* - Set a machines dNSHostName and servicePrincipalName attributes - ********************************************************************/ - -static ADS_STATUS net_set_machine_upn(TALLOC_CTX *ctx, ADS_STRUCT *ads_s, const char *upn ) -{ - ADS_STATUS status = ADS_ERROR(LDAP_SERVER_DOWN); - char *new_dn; - ADS_MODLIST mods; - LDAPMessage *res = NULL; - char *dn_string = NULL; - const char *machine_name = global_myname(); - int count; - - if ( !machine_name ) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - /* Find our DN */ - - status = ads_find_machine_acct(ads_s, &res, machine_name); - if (!ADS_ERR_OK(status)) - return status; - - if ( (count = ads_count_replies(ads_s, res)) != 1 ) { - DEBUG(1,("net_set_machine_spn: %d entries returned!\n", count)); - return ADS_ERROR(LDAP_NO_MEMORY); - } - - if ( (dn_string = ads_get_dn(ads_s, res)) == NULL ) { - DEBUG(1, ("ads_add_machine_acct: ads_get_dn returned NULL (malloc failure?)\n")); - goto done; - } - - new_dn = talloc_strdup(ctx, dn_string); - ads_memfree(ads_s, dn_string); - if (!new_dn) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - /* now do the mods */ - - if (!(mods = ads_init_mods(ctx))) { - goto done; - } - - /* fields of primary importance */ - - ads_mod_str(ctx, &mods, "userPrincipalName", upn); - - status = ads_gen_mod(ads_s, new_dn, mods); - -done: - ads_msgfree(ads_s, res); - - return status; -} - -/******************************************************************* - Set a machines dNSHostName and servicePrincipalName attributes - ********************************************************************/ - -static ADS_STATUS net_set_os_attributes(TALLOC_CTX *ctx, ADS_STRUCT *ads_s, - const char *os_name, const char *os_version ) -{ - ADS_STATUS status = ADS_ERROR(LDAP_SERVER_DOWN); - char *new_dn; - ADS_MODLIST mods; - LDAPMessage *res = NULL; - char *dn_string = NULL; - const char *machine_name = global_myname(); - int count; - char *os_sp = NULL; - - if ( !os_name || !os_version ) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - /* Find our DN */ - - status = ads_find_machine_acct(ads_s, &res, machine_name); - if (!ADS_ERR_OK(status)) - return status; - - if ( (count = ads_count_replies(ads_s, res)) != 1 ) { - DEBUG(1,("net_set_machine_spn: %d entries returned!\n", count)); - return ADS_ERROR(LDAP_NO_MEMORY); - } - - if ( (dn_string = ads_get_dn(ads_s, res)) == NULL ) { - DEBUG(1, ("ads_add_machine_acct: ads_get_dn returned NULL (malloc failure?)\n")); - goto done; - } - - new_dn = talloc_strdup(ctx, dn_string); - ads_memfree(ads_s, dn_string); - if (!new_dn) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - /* now do the mods */ - - if (!(mods = ads_init_mods(ctx))) { - goto done; - } - - os_sp = talloc_asprintf( ctx, "Samba %s", SAMBA_VERSION_STRING ); - - /* fields of primary importance */ - - ads_mod_str(ctx, &mods, "operatingSystem", os_name); - ads_mod_str(ctx, &mods, "operatingSystemVersion", os_version); - if ( os_sp ) - ads_mod_str(ctx, &mods, "operatingSystemServicePack", os_sp); - - status = ads_gen_mod(ads_s, new_dn, mods); - -done: - ads_msgfree(ads_s, res); - TALLOC_FREE( os_sp ); - - return status; -} - -/******************************************************************* - join a domain using ADS (LDAP mods) - ********************************************************************/ - -static ADS_STATUS net_precreate_machine_acct( ADS_STRUCT *ads, const char *ou ) -{ - ADS_STATUS rc = ADS_ERROR(LDAP_SERVER_DOWN); - char *ou_str = NULL; - char *dn = NULL; - LDAPMessage *res = NULL; - bool moved; - - ou_str = ads_ou_string(ads, ou); - if (asprintf(&dn, "%s,%s", ou_str, ads->config.bind_path) == -1) { - rc = ADS_ERROR(LDAP_NO_MEMORY); - goto done; - } - - rc = ads_search_dn(ads, &res, dn, NULL); - if (!ADS_ERR_OK(rc)) { - d_fprintf(stderr, "The specified OU does not exist.\n"); - goto done; - } - - /* Attempt to create the machine account and bail if this fails. - Assume that the admin wants exactly what they requested */ - - rc = ads_create_machine_acct( ads, global_myname(), dn ); - if (ADS_ERR_OK(rc)) { - DEBUG(1, ("machine account created\n")); - goto done; - } - if ( !(rc.error_type == ENUM_ADS_ERROR_LDAP && rc.err.rc == LDAP_ALREADY_EXISTS) ) { - DEBUG(1, ("machine account creation failed\n")); - goto done; - } - - rc = ads_move_machine_acct(ads, global_myname(), dn, &moved); - if (!ADS_ERR_OK(rc)) { - DEBUG(1, ("failure to locate/move pre-existing machine account\n")); - goto done; - } - - if (moved) { - d_printf("The machine account was moved into the specified OU.\n"); - } else { - d_printf("The machine account already exists in the specified OU.\n"); - } - -done: - ads_msgfree(ads, res); - SAFE_FREE( ou_str ); - SAFE_FREE( dn ); - - return rc; -} - -/************************************************************************ - ************************************************************************/ - -static bool net_derive_salting_principal( TALLOC_CTX *ctx, ADS_STRUCT *ads ) -{ - uint32 domain_func; - ADS_STATUS status; - fstring salt; - char *std_salt; - const char *machine_name = global_myname(); - - status = ads_domain_func_level( ads, &domain_func ); - if ( !ADS_ERR_OK(status) ) { - DEBUG(2,("Failed to determine domain functional level!\n")); - return False; - } - - /* go ahead and setup the default salt */ - - if ( (std_salt = kerberos_standard_des_salt()) == NULL ) { - d_fprintf(stderr, "net_derive_salting_principal: failed to obtain stanard DES salt\n"); - return False; - } - - fstrcpy( salt, std_salt ); - SAFE_FREE( std_salt ); - - /* if it's a Windows functional domain, we have to look for the UPN */ - - if ( domain_func == DS_DOMAIN_FUNCTION_2000 ) { - char *upn; - - upn = ads_get_upn(ads, ctx, machine_name); - if ( upn ) { - fstrcpy( salt, upn ); - } - } - - return kerberos_secrets_store_des_salt( salt ); -} - -/******************************************************************* Send a DNS update request *******************************************************************/ @@ -1443,50 +1102,35 @@ static int net_ads_join_usage(int argc, const char **argv) int net_ads_join(int argc, const char **argv) { - ADS_STRUCT *ads = NULL; - ADS_STATUS status; NTSTATUS nt_status; - const char *short_domain_name = NULL; - char *tmp_password, *password; TALLOC_CTX *ctx = NULL; - DOM_SID *domain_sid = NULL; + struct libnet_JoinCtx *r = NULL; + const char *domain = lp_realm(); + WERROR werr = WERR_SETUP_NOT_JOINED; bool createupn = False; const char *machineupn = NULL; const char *create_in_ou = NULL; int i; - fstring dc_name; - struct sockaddr_storage dcss; const char *os_name = NULL; const char *os_version = NULL; nt_status = check_ads_config(); if (!NT_STATUS_IS_OK(nt_status)) { d_fprintf(stderr, "Invalid configuration. Exiting....\n"); + werr = ntstatus_to_werror(nt_status); goto fail; } - /* find a DC to initialize the server affinity cache */ - - get_dc_name( lp_workgroup(), lp_realm(), dc_name, &dcss ); - - status = ads_startup(True, &ads); - if (!ADS_ERR_OK(status)) { - DEBUG(1, ("error on ads_startup: %s\n", ads_errstr(status))); - nt_status = ads_ntstatus(status); - goto fail; - } + use_in_memory_ccache(); - if (strcmp(ads->config.realm, lp_realm()) != 0) { - d_fprintf(stderr, "realm of remote server (%s) and realm in %s " - "(%s) DO NOT match. Aborting join\n", - ads->config.realm, get_dyn_CONFIGFILE(), lp_realm()); - nt_status = NT_STATUS_INVALID_PARAMETER; + werr = libnet_init_JoinCtx(ctx, &r); + if (!W_ERROR_IS_OK(werr)) { goto fail; } if (!(ctx = talloc_init("net_ads_join"))) { d_fprintf(stderr, "Could not initialise talloc context.\n"); - nt_status = NT_STATUS_NO_MEMORY; + werr = WERR_NOMEM; goto fail; } @@ -1500,203 +1144,102 @@ int net_ads_join(int argc, const char **argv) else if ( !StrnCaseCmp(argv[i], "createcomputer", strlen("createcomputer")) ) { if ( (create_in_ou = get_string_param(argv[i])) == NULL ) { d_fprintf(stderr, "Please supply a valid OU path.\n"); - nt_status = NT_STATUS_INVALID_PARAMETER; + werr = WERR_INVALID_PARAM; goto fail; } } else if ( !StrnCaseCmp(argv[i], "osName", strlen("osName")) ) { if ( (os_name = get_string_param(argv[i])) == NULL ) { d_fprintf(stderr, "Please supply a operating system name.\n"); - nt_status = NT_STATUS_INVALID_PARAMETER; + werr = WERR_INVALID_PARAM; goto fail; } } else if ( !StrnCaseCmp(argv[i], "osVer", strlen("osVer")) ) { if ( (os_version = get_string_param(argv[i])) == NULL ) { d_fprintf(stderr, "Please supply a valid operating system version.\n"); - nt_status = NT_STATUS_INVALID_PARAMETER; + werr = WERR_INVALID_PARAM; goto fail; } } else { - d_fprintf(stderr, "Bad option: %s\n", argv[i]); - nt_status = NT_STATUS_INVALID_PARAMETER; - goto fail; - } - } - - /* If we were given an OU, try to create the machine in - the OU account first and then do the normal RPC join */ - - if ( create_in_ou ) { - status = net_precreate_machine_acct( ads, create_in_ou ); - if ( !ADS_ERR_OK(status) ) { - d_fprintf( stderr, "Failed to pre-create the machine object " - "in OU %s.\n", create_in_ou); - DEBUG(1, ("error calling net_precreate_machine_acct: %s\n", - ads_errstr(status))); - nt_status = ads_ntstatus(status); - goto fail; + domain = argv[i]; } } /* Do the domain join here */ - tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); - password = talloc_strdup(ctx, tmp_password); - - nt_status = net_join_domain(ctx, ads->config.ldap_server_name, - &ads->ldap.ss, &short_domain_name, &domain_sid, password); - if ( !NT_STATUS_IS_OK(nt_status) ) { - DEBUG(1, ("call of net_join_domain failed: %s\n", - get_friendly_nt_error_msg(nt_status))); + r->in.domain_name = domain; + r->in.create_upn = createupn; + r->in.upn = machineupn; + r->in.account_ou = create_in_ou; + r->in.os_name = os_name; + r->in.os_version = os_version; + r->in.dc_name = opt_host; + r->in.admin_account = opt_user_name; + r->in.admin_password = net_prompt_pass(opt_user_name); + r->in.debug = opt_verbose; + r->in.join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | + WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE | + WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED; + + werr = libnet_Join(ctx, r); + if (!W_ERROR_IS_OK(werr)) { goto fail; } /* Check the short name of the domain */ - if ( !strequal(lp_workgroup(), short_domain_name) ) { + if (!strequal(lp_workgroup(), r->out.netbios_domain_name)) { d_printf("The workgroup in %s does not match the short\n", get_dyn_CONFIGFILE()); d_printf("domain name obtained from the server.\n"); - d_printf("Using the name [%s] from the server.\n", short_domain_name); + d_printf("Using the name [%s] from the server.\n", r->out.netbios_domain_name); d_printf("You should set \"workgroup = %s\" in %s.\n", - short_domain_name, get_dyn_CONFIGFILE()); + r->out.netbios_domain_name, get_dyn_CONFIGFILE()); } - d_printf("Using short domain name -- %s\n", short_domain_name); + d_printf("Using short domain name -- %s\n", r->out.netbios_domain_name); - /* HACK ALERT! Store the sid and password under both the lp_workgroup() - value from smb.conf and the string returned from the server. The former is - neede to bootstrap winbindd's first connection to the DC to get the real - short domain name --jerry */ + d_printf("Joined '%s' to realm '%s'\n", r->in.machine_name, + r->out.dns_domain_name); - if ( (netdom_store_machine_account( lp_workgroup(), domain_sid, password ) == -1) - || (netdom_store_machine_account( short_domain_name, domain_sid, password ) == -1) ) +#if defined(WITH_DNS_UPDATES) { - /* issue an internal error here for now. - * everything else would mean changing tdb routines. */ - nt_status = NT_STATUS_INTERNAL_ERROR; - goto fail; - } - - /* Verify that everything is ok */ - - nt_status = net_rpc_join_ok(short_domain_name, - ads->config.ldap_server_name, &ads->ldap.ss); - if (!NT_STATUS_IS_OK(nt_status)) { - d_fprintf(stderr, - "Failed to verify membership in domain: %s!\n", - nt_errstr(nt_status)); - goto fail; - } - - /* create the dNSHostName & servicePrincipalName values */ - - status = net_set_machine_spn( ctx, ads ); - if ( !ADS_ERR_OK(status) ) { - - d_fprintf(stderr, "Failed to set servicePrincipalNames. Please ensure that\n"); - d_fprintf(stderr, "the DNS domain of this server matches the AD domain,\n"); - d_fprintf(stderr, "Or rejoin with using Domain Admin credentials.\n"); - - /* Disable the machine account in AD. Better to fail than to leave - a confused admin. */ - - if ( net_ads_leave( 0, NULL ) != 0 ) { - d_fprintf( stderr, "Failed to disable machine account in AD. Please do so manually.\n"); + /* We enter this block with user creds */ + ADS_STRUCT *ads_dns = NULL; + + if ( (ads_dns = ads_init( lp_realm(), NULL, NULL )) != NULL ) { + /* kinit with the machine password */ + + use_in_memory_ccache(); + asprintf( &ads_dns->auth.user_name, "%s$", global_myname() ); + ads_dns->auth.password = secrets_fetch_machine_password( + lp_workgroup(), NULL, NULL ); + ads_dns->auth.realm = SMB_STRDUP( lp_realm() ); + ads_kinit_password( ads_dns ); } - /* clear out the machine password */ - - netdom_store_machine_account( lp_workgroup(), domain_sid, "" ); - netdom_store_machine_account( short_domain_name, domain_sid, "" ); - - nt_status = ads_ntstatus(status); - goto fail; - } - - if ( !net_derive_salting_principal( ctx, ads ) ) { - DEBUG(1,("Failed to determine salting principal\n")); - goto fail; - } - - if ( createupn ) { - char *upn; - - /* default to using the short UPN name */ - if (!machineupn ) { - upn = talloc_asprintf(ctx, - "host/%s@%s", global_myname(), - ads->config.realm ); - if (!upn) { - nt_status = NT_STATUS_NO_MEMORY; - goto fail; - } - machineupn = upn; - } - - status = net_set_machine_upn( ctx, ads, machineupn ); - if ( !ADS_ERR_OK(status) ) { - d_fprintf(stderr, "Failed to set userPrincipalName. Are you a Domain Admin?\n"); - } - } - - /* Try to set the operatingSystem attributes if asked */ - - if ( os_name && os_version ) { - status = net_set_os_attributes( ctx, ads, os_name, os_version ); - if ( !ADS_ERR_OK(status) ) { - d_fprintf(stderr, "Failed to set operatingSystem attributes. " - "Are you a Domain Admin?\n"); + if ( !ads_dns || !NT_STATUS_IS_OK(net_update_dns( ctx, ads_dns )) ) { + d_fprintf( stderr, "DNS update failed!\n" ); } - } - /* Now build the keytab, using the same ADS connection */ - - if (lp_use_kerberos_keytab() && ads_keytab_create_default(ads)) { - DEBUG(1,("Error creating host keytab!\n")); + /* exit from this block using machine creds */ + ads_destroy(&ads_dns); } - -#if defined(WITH_DNS_UPDATES) - /* We enter this block with user creds */ - ads_kdestroy( NULL ); - ads_destroy(&ads); - ads = NULL; - - if ( (ads = ads_init( lp_realm(), NULL, NULL )) != NULL ) { - /* kinit with the machine password */ - - use_in_memory_ccache(); - asprintf( &ads->auth.user_name, "%s$", global_myname() ); - ads->auth.password = secrets_fetch_machine_password( - lp_workgroup(), NULL, NULL ); - ads->auth.realm = SMB_STRDUP( lp_realm() ); - ads_kinit_password( ads ); - } - - if ( !ads || !NT_STATUS_IS_OK(net_update_dns( ctx, ads )) ) { - d_fprintf( stderr, "DNS update failed!\n" ); - } - - /* exit from this block using machine creds */ #endif - - d_printf("Joined '%s' to realm '%s'\n", global_myname(), ads->server.realm); - + TALLOC_FREE(r); TALLOC_FREE( ctx ); - ads_destroy(&ads); return 0; fail: /* issue an overall failure message at the end. */ - d_printf("Failed to join domain: %s\n", get_friendly_nt_error_msg(nt_status)); - + d_printf("Failed to join domain: %s\n", + r && r->out.error_string ? r->out.error_string : + get_friendly_werror_msg(werr)); TALLOC_FREE( ctx ); - ads_destroy(&ads); return -1; - } /******************************************************************* @@ -2519,8 +2062,8 @@ static int net_ads_kerberos_renew(int argc, const char **argv) static int net_ads_kerberos_pac(int argc, const char **argv) { - PAC_DATA *pac = NULL; - PAC_LOGON_INFO *info = NULL; + struct PAC_DATA *pac = NULL; + struct PAC_LOGON_INFO *info = NULL; TALLOC_CTX *mem_ctx = NULL; NTSTATUS status; int ret = -1; @@ -2551,7 +2094,9 @@ static int net_ads_kerberos_pac(int argc, const char **argv) info = get_logon_info_from_pac(pac); if (info) { - dump_pac_logon_info(0, info); + const char *s; + s = NDR_PRINT_STRUCT_STRING(mem_ctx, PAC_LOGON_INFO, info); + d_printf("The Pac: %s\n", s); } ret = 0; diff --git a/source3/utils/net_dom.c b/source3/utils/net_dom.c index 30993ae2fa..e88bbdb276 100644 --- a/source3/utils/net_dom.c +++ b/source3/utils/net_dom.c @@ -101,7 +101,7 @@ static int net_dom_unjoin(int argc, const char **argv) status = NetUnjoinDomain(server_name, account, password, unjoin_flags); if (status != 0) { printf("Failed to unjoin domain: %s\n", - libnetapi_errstr(status)); + libnetapi_get_error_string(ctx, status)); goto done; } @@ -215,7 +215,7 @@ static int net_dom_join(int argc, const char **argv) Account, password, join_flags); if (status != 0) { printf("Failed to join domain: %s\n", - libnetapi_errstr(status)); + libnetapi_get_error_string(ctx, status)); goto done; } diff --git a/source3/utils/net_domain.c b/source3/utils/net_domain.c deleted file mode 100644 index da5e61caf0..0000000000 --- a/source3/utils/net_domain.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - Samba Unix/Linux SMB client library - net ads commands - Copyright (C) 2001 Andrew Tridgell (tridge@samba.org) - Copyright (C) 2001 Remus Koos (remuskoos@yahoo.com) - Copyright (C) 2002 Jim McDonough (jmcd@us.ibm.com) - Copyright (C) 2006 Gerald (Jerry) Carter (jerry@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 3 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, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "utils/net.h" - -/* Macro for checking RPC error codes to make things more readable */ - -#define CHECK_RPC_ERR(rpc, msg) \ - if (!NT_STATUS_IS_OK(result = rpc)) { \ - DEBUG(0, (msg ": %s\n", nt_errstr(result))); \ - goto done; \ - } - -#define CHECK_RPC_ERR_DEBUG(rpc, debug_args) \ - if (!NT_STATUS_IS_OK(result = rpc)) { \ - DEBUG(0, debug_args); \ - goto done; \ - } - -/******************************************************************* - Leave an AD domain. Windows XP disables the machine account. - We'll try the same. The old code would do an LDAP delete. - That only worked using the machine creds because added the machine - with full control to the computer object's ACL. -*******************************************************************/ - -NTSTATUS netdom_leave_domain( TALLOC_CTX *mem_ctx, struct cli_state *cli, - DOM_SID *dom_sid ) -{ - struct rpc_pipe_client *pipe_hnd = NULL; - POLICY_HND sam_pol, domain_pol, user_pol; - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - char *acct_name; - uint32 flags = 0x3e8; - const char *const_acct_name; - uint32 user_rid; - uint32 num_rids, *name_types, *user_rids; - SAM_USERINFO_CTR ctr, *qctr = NULL; - SAM_USER_INFO_16 p16; - - /* Open the domain */ - - if ( (pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &status)) == NULL ) { - DEBUG(0, ("Error connecting to SAM pipe. Error was %s\n", - nt_errstr(status) )); - return status; - } - - status = rpccli_samr_connect(pipe_hnd, mem_ctx, - SEC_RIGHTS_MAXIMUM_ALLOWED, &sam_pol); - if ( !NT_STATUS_IS_OK(status) ) - return status; - - - status = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &sam_pol, - SEC_RIGHTS_MAXIMUM_ALLOWED, dom_sid, &domain_pol); - if ( !NT_STATUS_IS_OK(status) ) - return status; - - /* Create domain user */ - - acct_name = talloc_asprintf(mem_ctx, "%s$", global_myname()); - strlower_m(acct_name); - const_acct_name = acct_name; - - status = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, - &domain_pol, flags, 1, &const_acct_name, - &num_rids, &user_rids, &name_types); - if ( !NT_STATUS_IS_OK(status) ) - return status; - - if ( name_types[0] != SID_NAME_USER) { - DEBUG(0, ("%s is not a user account (type=%d)\n", acct_name, name_types[0])); - return NT_STATUS_INVALID_WORKSTATION; - } - - user_rid = user_rids[0]; - - /* Open handle on user */ - - status = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol, - SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid, &user_pol); - if ( !NT_STATUS_IS_OK(status) ) { - goto done; - } - - /* Get user info */ - - status = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, &user_pol, 16, &qctr); - if ( !NT_STATUS_IS_OK(status) ) { - rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol); - goto done; - } - - /* now disable and setuser info */ - - ZERO_STRUCT(ctr); - ctr.switch_value = 16; - ctr.info.id16 = &p16; - - p16.acb_info = qctr->info.id16->acb_info | ACB_DISABLED; - - status = rpccli_samr_set_userinfo2(pipe_hnd, mem_ctx, &user_pol, 16, - &cli->user_session_key, &ctr); - - rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol); - -done: - rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol); - rpccli_samr_close(pipe_hnd, mem_ctx, &sam_pol); - - cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */ - - return status; -} - -/******************************************************************* - Store the machine password and domain SID - ********************************************************************/ - -int netdom_store_machine_account( const char *domain, DOM_SID *sid, const char *pw ) -{ - if (!secrets_store_domain_sid(domain, sid)) { - DEBUG(1,("Failed to save domain sid\n")); - return -1; - } - - if (!secrets_store_machine_password(pw, domain, SEC_CHAN_WKSTA)) { - DEBUG(1,("Failed to save machine password\n")); - return -1; - } - - return 0; -} - -/******************************************************************* - ********************************************************************/ - -NTSTATUS netdom_get_domain_sid( TALLOC_CTX *mem_ctx, struct cli_state *cli, - const char **domain, DOM_SID **sid ) -{ - struct rpc_pipe_client *pipe_hnd = NULL; - POLICY_HND lsa_pol; - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - - if ( (pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &status)) == NULL ) { - DEBUG(0, ("Error connecting to LSA pipe. Error was %s\n", - nt_errstr(status) )); - return status; - } - - status = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True, - SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol); - if ( !NT_STATUS_IS_OK(status) ) - return status; - - status = rpccli_lsa_query_info_policy(pipe_hnd, mem_ctx, - &lsa_pol, 5, domain, sid); - if ( !NT_STATUS_IS_OK(status) ) - return status; - - rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol); - cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */ - - /* Bail out if domain didn't get set. */ - if (!domain) { - DEBUG(0, ("Could not get domain name.\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - return NT_STATUS_OK; -} - -/******************************************************************* - Do the domain join - ********************************************************************/ - -NTSTATUS netdom_join_domain( TALLOC_CTX *mem_ctx, struct cli_state *cli, - DOM_SID *dom_sid, const char *clear_pw, - enum netdom_domain_t dom_type ) -{ - struct rpc_pipe_client *pipe_hnd = NULL; - POLICY_HND sam_pol, domain_pol, user_pol; - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - char *acct_name; - const char *const_acct_name; - uint32 user_rid; - uint32 num_rids, *name_types, *user_rids; - uint32 flags = 0x3e8; - uint32 acb_info = ACB_WSTRUST; - uint32 fields_present; - uchar pwbuf[532]; - SAM_USERINFO_CTR ctr; - SAM_USER_INFO_25 p25; - const int infolevel = 25; - struct MD5Context md5ctx; - uchar md5buffer[16]; - DATA_BLOB digested_session_key; - uchar md4_trust_password[16]; - - /* Open the domain */ - - if ( (pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &status)) == NULL ) { - DEBUG(0, ("Error connecting to SAM pipe. Error was %s\n", - nt_errstr(status) )); - return status; - } - - status = rpccli_samr_connect(pipe_hnd, mem_ctx, - SEC_RIGHTS_MAXIMUM_ALLOWED, &sam_pol); - if ( !NT_STATUS_IS_OK(status) ) - return status; - - - status = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &sam_pol, - SEC_RIGHTS_MAXIMUM_ALLOWED, dom_sid, &domain_pol); - if ( !NT_STATUS_IS_OK(status) ) - return status; - - /* Create domain user */ - - acct_name = talloc_asprintf(mem_ctx, "%s$", global_myname()); - strlower_m(acct_name); - const_acct_name = acct_name; - - /* Don't try to set any acb_info flags other than ACB_WSTRUST */ - - status = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol, - acct_name, acb_info, 0xe005000b, &user_pol, &user_rid); - - if ( !NT_STATUS_IS_OK(status) - && !NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) - { - d_fprintf(stderr, "Creation of workstation account failed\n"); - - /* If NT_STATUS_ACCESS_DENIED then we have a valid - username/password combo but the user does not have - administrator access. */ - - if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) - d_fprintf(stderr, "User specified does not have administrator privileges\n"); - - return status; - } - - /* We *must* do this.... don't ask... */ - - if (NT_STATUS_IS_OK(status)) { - rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol); - } - - status = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, - &domain_pol, flags, 1, &const_acct_name, - &num_rids, &user_rids, &name_types); - if ( !NT_STATUS_IS_OK(status) ) - return status; - - if ( name_types[0] != SID_NAME_USER) { - DEBUG(0, ("%s is not a user account (type=%d)\n", acct_name, name_types[0])); - return NT_STATUS_INVALID_WORKSTATION; - } - - user_rid = user_rids[0]; - - /* Open handle on user */ - - status = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol, - SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid, &user_pol); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - /* Create a random machine account password and generate the hash */ - - E_md4hash(clear_pw, md4_trust_password); - encode_pw_buffer(pwbuf, clear_pw, STR_UNICODE); - - generate_random_buffer((uint8*)md5buffer, sizeof(md5buffer)); - digested_session_key = data_blob_talloc(mem_ctx, 0, 16); - - MD5Init(&md5ctx); - MD5Update(&md5ctx, md5buffer, sizeof(md5buffer)); - MD5Update(&md5ctx, cli->user_session_key.data, cli->user_session_key.length); - MD5Final(digested_session_key.data, &md5ctx); - - SamOEMhashBlob(pwbuf, sizeof(pwbuf), &digested_session_key); - memcpy(&pwbuf[516], md5buffer, sizeof(md5buffer)); - - /* Fill in the additional account flags now */ - - acb_info |= ACB_PWNOEXP; - if ( dom_type == ND_TYPE_AD ) { -#if !defined(ENCTYPE_ARCFOUR_HMAC) - acb_info |= ACB_USE_DES_KEY_ONLY; -#endif - ;; - } - - /* Set password and account flags on machine account */ - - ZERO_STRUCT(ctr); - ZERO_STRUCT(p25); - - fields_present = ACCT_NT_PWD_SET | ACCT_LM_PWD_SET | ACCT_FLAGS; - init_sam_user_info25P(&p25, fields_present, acb_info, (char *)pwbuf); - - ctr.switch_value = infolevel; - ctr.info.id25 = &p25; - - status = rpccli_samr_set_userinfo2(pipe_hnd, mem_ctx, &user_pol, - infolevel, &cli->user_session_key, &ctr); - - if ( !NT_STATUS_IS_OK(status) ) { - d_fprintf( stderr, "Failed to set password for machine account (%s)\n", - nt_errstr(status)); - return status; - } - - rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol); - cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */ - - return status; -} - diff --git a/source3/utils/net_lookup.c b/source3/utils/net_lookup.c index 765971fba3..e5d83bc891 100644 --- a/source3/utils/net_lookup.c +++ b/source3/utils/net_lookup.c @@ -366,8 +366,9 @@ static int net_lookup_dsgetdcname(int argc, const char **argv) const char *domain_name = NULL; char *site_name = NULL; uint32_t flags = 0; - struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + struct netr_DsRGetDCNameInfo *info = NULL; TALLOC_CTX *mem_ctx; + char *s = NULL; if (argc < 1 || argc > 3) { d_printf("usage: net lookup dsgetdcname " @@ -401,7 +402,7 @@ static int net_lookup_dsgetdcname(int argc, const char **argv) site_name = sitename_fetch(domain_name); } - status = dsgetdcname(mem_ctx, NULL, domain_name, NULL, site_name, + status = dsgetdcname(mem_ctx, domain_name, NULL, site_name, flags, &info); if (!NT_STATUS_IS_OK(status)) { d_printf("failed with: %s\n", nt_errstr(status)); @@ -410,7 +411,9 @@ static int net_lookup_dsgetdcname(int argc, const char **argv) return -1; } - display_ds_domain_controller_info(mem_ctx, info); + s = NDR_PRINT_STRUCT_STRING(mem_ctx, netr_DsRGetDCNameInfo, info); + printf("%s\n", s); + TALLOC_FREE(s); SAFE_FREE(site_name); TALLOC_FREE(mem_ctx); diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 677924649c..f7fadb9520 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -3,7 +3,7 @@ Distributed SMB/CIFS Server Management Utility Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org) Copyright (C) 2002 Jim McDonough (jmcd@us.ibm.com) - Copyright (C) 2004 Guenther Deschner (gd@samba.org) + Copyright (C) 2004,2008 Guenther Deschner (gd@samba.org) Copyright (C) 2005 Jeremy Allison (jra@samba.org) Copyright (C) 2006 Jelmer Vernooij (jelmer@samba.org) @@ -57,8 +57,8 @@ NTSTATUS net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx, struct rpc_pipe_client *lsa_pipe; POLICY_HND pol; NTSTATUS result = NT_STATUS_OK; - uint32 info_class = 5; - + union lsa_PolicyInformation *info = NULL; + lsa_pipe = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &result); if (!lsa_pipe) { d_fprintf(stderr, "Could not initialise lsa pipe\n"); @@ -74,15 +74,19 @@ NTSTATUS net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } - result = rpccli_lsa_query_info_policy(lsa_pipe, mem_ctx, &pol, - info_class, domain_name, - domain_sid); + result = rpccli_lsa_QueryInfoPolicy(lsa_pipe, mem_ctx, + &pol, + LSA_POLICY_INFO_ACCOUNT_DOMAIN, + &info); if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "lsaquery failed: %s\n", nt_errstr(result)); return result; } + *domain_name = info->account_domain.name.string; + *domain_sid = info->account_domain.sid; + rpccli_lsa_Close(lsa_pipe, mem_ctx, &pol); cli_rpc_pipe_close(lsa_pipe); @@ -388,7 +392,7 @@ static int rpc_join_usage(int argc, const char **argv) * @param argc Standard main() style argv. Initial components are already * stripped * - * Main 'net_rpc_join()' (where the admain username/password is used) is + * Main 'net_rpc_join()' (where the admin username/password is used) is * in net_rpc_join.c * Try to just change the password, but if that doesn't work, use/prompt * for a username/password. @@ -440,40 +444,44 @@ NTSTATUS rpc_info_internals(const DOM_SID *domain_sid, { POLICY_HND connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - SAM_UNK_CTR ctr; + union samr_DomainInfo *info = NULL; fstring sid_str; sid_to_fstring(sid_str, domain_sid); - /* Get sam policy handle */ - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + /* Get sam policy handle */ + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "Could not connect to SAM: %s\n", nt_errstr(result)); goto done; } - + /* Get domain policy handle */ - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - domain_sid, &domain_pol); + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + CONST_DISCARD(struct dom_sid2 *, domain_sid), + &domain_pol); if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "Could not open domain: %s\n", nt_errstr(result)); goto done; } - ZERO_STRUCT(ctr); - result = rpccli_samr_query_dom_info(pipe_hnd, mem_ctx, &domain_pol, - 2, &ctr); + result = rpccli_samr_QueryDomainInfo(pipe_hnd, mem_ctx, + &domain_pol, + 2, + &info); if (NT_STATUS_IS_OK(result)) { - TALLOC_CTX *ctx = talloc_init("rpc_info_internals"); - d_printf("Domain Name: %s\n", unistr2_to_ascii_talloc(ctx, &ctr.info.inf2.uni_domain)); + d_printf("Domain Name: %s\n", info->info2.domain_name.string); d_printf("Domain SID: %s\n", sid_str); - d_printf("Sequence number: %llu\n", (unsigned long long)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); - d_printf("Num local groups: %u\n", ctr.info.inf2.num_local_grps); - talloc_destroy(ctx); + d_printf("Sequence number: %llu\n", + (unsigned long long)info->info2.sequence_num); + d_printf("Num users: %u\n", info->info2.num_users); + d_printf("Num domain groups: %u\n", info->info2.num_groups); + d_printf("Num local groups: %u\n", info->info2.num_aliases); } done: @@ -587,8 +595,11 @@ static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, POLICY_HND connect_pol, domain_pol, user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; const char *acct_name; + struct lsa_String lsa_acct_name; uint32 acb_info; - uint32 access_mask, user_rid; + uint32 acct_flags, user_rid; + uint32_t access_granted = 0; + struct samr_Ids user_rids, name_types; if (argc < 1) { d_printf("User must be specified\n"); @@ -597,20 +608,25 @@ static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, } acct_name = argv[0]; + init_lsa_String(&lsa_acct_name, acct_name); /* Get sam policy handle */ - - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } /* Get domain policy handle */ - - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - domain_sid, &domain_pol); + + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + CONST_DISCARD(struct dom_sid2 *, domain_sid), + &domain_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } @@ -618,35 +634,46 @@ static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, /* Create domain user */ acb_info = ACB_NORMAL; - access_mask = 0xe005000b; + acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE | + SEC_STD_WRITE_DAC | SEC_STD_DELETE | + SAMR_USER_ACCESS_SET_PASSWORD | + SAMR_USER_ACCESS_GET_ATTRIBUTES | + SAMR_USER_ACCESS_SET_ATTRIBUTES; + + result = rpccli_samr_CreateUser2(pipe_hnd, mem_ctx, + &domain_pol, + &lsa_acct_name, + acb_info, + acct_flags, + &user_pol, + &access_granted, + &user_rid); - result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol, - acct_name, acb_info, access_mask, - &user_pol, &user_rid); if (!NT_STATUS_IS_OK(result)) { goto done; } if (argc == 2) { - uint32 *user_rids, num_rids, *name_types; - uint32 flags = 0x000003e8; /* Unknown */ - SAM_USERINFO_CTR ctr; - SAM_USER_INFO_24 p24; + union samr_UserInfo info; uchar pwbuf[516]; - result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, - flags, 1, &acct_name, - &num_rids, &user_rids, - &name_types); + result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx, + &domain_pol, + 1, + &lsa_acct_name, + &user_rids, + &name_types); if (!NT_STATUS_IS_OK(result)) { goto done; } - result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol, - MAXIMUM_ALLOWED_ACCESS, - user_rids[0], &user_pol); + result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx, + &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + user_rids.ids[0], + &user_pol); if (!NT_STATUS_IS_OK(result)) { goto done; @@ -654,24 +681,24 @@ static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, /* Set password on account */ - ZERO_STRUCT(ctr); - ZERO_STRUCT(p24); - encode_pw_buffer(pwbuf, argv[1], STR_UNICODE); - init_sam_user_info24(&p24, (char *)pwbuf,24); + init_samr_user_info24(&info.info24, pwbuf, 24); - ctr.switch_value = 24; - ctr.info.id24 = &p24; + SamOEMhashBlob(info.info24.password.data, 516, + &cli->user_session_key); - result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24, - &cli->user_session_key, &ctr); + result = rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx, + &user_pol, + 24, + &info); if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "Failed to set password for user %s - %s\n", acct_name, nt_errstr(result)); - result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol); + result = rpccli_samr_DeleteUser(pipe_hnd, mem_ctx, + &user_pol); if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "Failed to delete user %s - %s\n", @@ -745,16 +772,20 @@ static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid, /* Get sam policy and domain handles */ - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - domain_sid, &domain_pol); + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + CONST_DISCARD(struct dom_sid2 *, domain_sid), + &domain_pol); if (!NT_STATUS_IS_OK(result)) { goto done; @@ -763,21 +794,27 @@ static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid, /* Get handle on user */ { - uint32 *user_rids, num_rids, *name_types; - uint32 flags = 0x000003e8; /* Unknown */ + struct samr_Ids user_rids, name_types; + struct lsa_String lsa_acct_name; - result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, - flags, 1, &acct_name, - &num_rids, &user_rids, - &name_types); + init_lsa_String(&lsa_acct_name, acct_name); + + result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx, + &domain_pol, + 1, + &lsa_acct_name, + &user_rids, + &name_types); if (!NT_STATUS_IS_OK(result)) { goto done; } - result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol, - MAXIMUM_ALLOWED_ACCESS, - user_rids[0], &user_pol); + result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx, + &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + user_rids.ids[0], + &user_pol); if (!NT_STATUS_IS_OK(result)) { goto done; @@ -786,7 +823,8 @@ static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid, /* Delete user */ - result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol); + result = rpccli_samr_DeleteUser(pipe_hnd, mem_ctx, + &user_pol); if (!NT_STATUS_IS_OK(result)) { goto done; @@ -831,14 +869,9 @@ static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid, NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 info_level = 7; const char *old_name, *new_name; - uint32 *user_rid; - uint32 flags = 0x000003e8; /* Unknown */ - uint32 num_rids, *name_types; - uint32 num_names = 1; - const char **names; - SAM_USERINFO_CTR *user_ctr; - SAM_USERINFO_CTR ctr; - SAM_USER_INFO_7 info7; + struct samr_Ids user_rids, name_types; + struct lsa_String lsa_acct_name; + union samr_UserInfo *info = NULL; if (argc != 2) { d_printf("Old and new username must be specified\n"); @@ -849,62 +882,68 @@ static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid, old_name = argv[0]; new_name = argv[1]; - ZERO_STRUCT(ctr); - ZERO_STRUCT(user_ctr); - /* Get sam policy handle */ - - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); + if (!NT_STATUS_IS_OK(result)) { goto done; } /* Get domain policy handle */ - - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - domain_sid, &domain_pol); + + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + CONST_DISCARD(struct dom_sid2 *, domain_sid), + &domain_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } - if ((names = TALLOC_ARRAY(mem_ctx, const char *, num_names)) == NULL) { - result = NT_STATUS_NO_MEMORY; - goto done; - } - names[0] = old_name; - result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, - flags, num_names, names, - &num_rids, &user_rid, &name_types); + init_lsa_String(&lsa_acct_name, old_name); + + result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx, + &domain_pol, + 1, + &lsa_acct_name, + &user_rids, + &name_types); if (!NT_STATUS_IS_OK(result)) { goto done; } /* Open domain user */ - result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol, - MAXIMUM_ALLOWED_ACCESS, user_rid[0], &user_pol); + result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx, + &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + user_rids.ids[0], + &user_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } /* Query user info */ - result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, &user_pol, - info_level, &user_ctr); + result = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx, + &user_pol, + info_level, + &info); if (!NT_STATUS_IS_OK(result)) { goto done; } - ctr.switch_value = info_level; - ctr.info.id7 = &info7; - - init_sam_user_info7(&info7, new_name); + init_samr_user_info7(&info->info7, new_name); /* Set new name */ - result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, - info_level, &cli->user_session_key, &ctr); + result = rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx, + &user_pol, + info_level, + info); if (!NT_STATUS_IS_OK(result)) { goto done; @@ -978,12 +1017,11 @@ static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid, { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; POLICY_HND connect_pol, domain_pol, user_pol; - SAM_USERINFO_CTR ctr; - SAM_USER_INFO_24 p24; uchar pwbuf[516]; const char *user; const char *new_password; char *prompt = NULL; + union samr_UserInfo info; if (argc < 1) { d_printf("User must be specified\n"); @@ -1003,16 +1041,20 @@ static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid, /* Get sam policy and domain handles */ - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - domain_sid, &domain_pol); + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + CONST_DISCARD(struct dom_sid2 *, domain_sid), + &domain_pol); if (!NT_STATUS_IS_OK(result)) { goto done; @@ -1021,21 +1063,26 @@ static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid, /* Get handle on user */ { - uint32 *user_rids, num_rids, *name_types; - uint32 flags = 0x000003e8; /* Unknown */ + struct samr_Ids user_rids, name_types; + struct lsa_String lsa_acct_name; - result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, - flags, 1, &user, - &num_rids, &user_rids, - &name_types); + init_lsa_String(&lsa_acct_name, user); + result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx, + &domain_pol, + 1, + &lsa_acct_name, + &user_rids, + &name_types); if (!NT_STATUS_IS_OK(result)) { goto done; } - result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol, - MAXIMUM_ALLOWED_ACCESS, - user_rids[0], &user_pol); + result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx, + &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + user_rids.ids[0], + &user_pol); if (!NT_STATUS_IS_OK(result)) { goto done; @@ -1044,18 +1091,17 @@ static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid, /* Set password on account */ - ZERO_STRUCT(ctr); - ZERO_STRUCT(p24); - encode_pw_buffer(pwbuf, new_password, STR_UNICODE); - init_sam_user_info24(&p24, (char *)pwbuf,24); + init_samr_user_info24(&info.info24, pwbuf, 24); - ctr.switch_value = 24; - ctr.info.id24 = &p24; + SamOEMhashBlob(info.info24.password.data, 516, + &cli->user_session_key); - result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24, - &cli->user_session_key, &ctr); + result = rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx, + &user_pol, + 24, + &info); if (!NT_STATUS_IS_OK(result)) { goto done; @@ -1110,11 +1156,14 @@ static NTSTATUS rpc_user_info_internals(const DOM_SID *domain_sid, { POLICY_HND connect_pol, domain_pol, user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 *rids, num_rids, *name_types, num_names; - uint32 flags = 0x000003e8; /* Unknown */ int i; - char **names; - DOM_GID *user_gids; + struct samr_RidWithAttributeArray *rid_array = NULL; + struct lsa_Strings names; + struct samr_Ids types; + uint32_t *lrids = NULL; + struct samr_Ids rids, name_types; + struct lsa_String lsa_acct_name; + if (argc < 1) { d_printf("User must be specified\n"); @@ -1122,50 +1171,65 @@ static NTSTATUS rpc_user_info_internals(const DOM_SID *domain_sid, return NT_STATUS_OK; } /* Get sam policy handle */ - - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; /* Get domain policy handle */ - - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - domain_sid, &domain_pol); + + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + CONST_DISCARD(struct dom_sid2 *, domain_sid), + &domain_pol); if (!NT_STATUS_IS_OK(result)) goto done; /* Get handle on user */ - result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, - flags, 1, &argv[0], - &num_rids, &rids, &name_types); + init_lsa_String(&lsa_acct_name, argv[0]); + + result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx, + &domain_pol, + 1, + &lsa_acct_name, + &rids, + &name_types); if (!NT_STATUS_IS_OK(result)) goto done; - result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol, - MAXIMUM_ALLOWED_ACCESS, - rids[0], &user_pol); + result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx, + &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + rids.ids[0], + &user_pol); if (!NT_STATUS_IS_OK(result)) goto done; - result = rpccli_samr_query_usergroups(pipe_hnd, mem_ctx, &user_pol, - &num_rids, &user_gids); + result = rpccli_samr_GetGroupsForUser(pipe_hnd, mem_ctx, + &user_pol, + &rid_array); if (!NT_STATUS_IS_OK(result)) goto done; /* Look up rids */ - if (num_rids) { - if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) { + if (rid_array->count) { + if ((lrids = TALLOC_ARRAY(mem_ctx, uint32, rid_array->count)) == NULL) { result = NT_STATUS_NO_MEMORY; goto done; } - for (i = 0; i < num_rids; i++) - rids[i] = user_gids[i].g_rid; + for (i = 0; i < rid_array->count; i++) + lrids[i] = rid_array->rids[i].rid; - result = rpccli_samr_lookup_rids(pipe_hnd, mem_ctx, &domain_pol, - num_rids, rids, - &num_names, &names, &name_types); + result = rpccli_samr_LookupRids(pipe_hnd, mem_ctx, + &domain_pol, + rid_array->count, + lrids, + &names, + &types); if (!NT_STATUS_IS_OK(result)) { goto done; @@ -1173,8 +1237,8 @@ static NTSTATUS rpc_user_info_internals(const DOM_SID *domain_sid, /* Display results */ - for (i = 0; i < num_names; i++) - printf("%s\n", names[i]); + for (i = 0; i < names.count; i++) + printf("%s\n", names.names[i].string); } done: return result; @@ -1223,50 +1287,59 @@ static NTSTATUS rpc_user_list_internals(const DOM_SID *domain_sid, POLICY_HND connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 start_idx=0, num_entries, i, loop_count = 0; - SAM_DISPINFO_CTR ctr; - SAM_DISPINFO_1 info1; /* Get sam policy handle */ - - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } /* Get domain policy handle */ - - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - domain_sid, &domain_pol); + + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + CONST_DISCARD(struct dom_sid2 *, domain_sid), + &domain_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } /* Query domain users */ - ZERO_STRUCT(ctr); - ZERO_STRUCT(info1); - ctr.sam.info1 = &info1; if (opt_long_list_entries) d_printf("\nUser name Comment"\ "\n-----------------------------\n"); do { - fstring user, desc; + const char *user = NULL; + const char *desc = NULL; uint32 max_entries, max_size; + uint32_t total_size, returned_size; + union samr_DispInfo info; get_query_dispinfo_params( loop_count, &max_entries, &max_size); - result = rpccli_samr_query_dispinfo(pipe_hnd, mem_ctx, &domain_pol, - &start_idx, 1, &num_entries, - max_entries, max_size, &ctr); + result = rpccli_samr_QueryDisplayInfo(pipe_hnd, mem_ctx, + &domain_pol, + 1, + start_idx, + max_entries, + max_size, + &total_size, + &returned_size, + &info); loop_count++; + start_idx += info.info1.count; + num_entries = info.info1.count; for (i = 0; i < num_entries; i++) { - unistr2_to_ascii(user, &(&ctr.sam.info1->str[i])->uni_acct_name, sizeof(user)); - if (opt_long_list_entries) - unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc)); - + user = info.info1.entries[i].account_name.string; + if (opt_long_list_entries) + desc = info.info1.entries[i].description.string; if (opt_long_list_entries) printf("%-21.21s %s\n", user, desc); else @@ -1333,9 +1406,8 @@ static NTSTATUS rpc_sh_handle_user(TALLOC_CTX *mem_ctx, TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, struct rpc_pipe_client *pipe_hnd, - const POLICY_HND *user_hnd, + POLICY_HND *user_hnd, int argc, const char **argv)) - { POLICY_HND connect_pol, domain_pol, user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; @@ -1373,22 +1445,28 @@ static NTSTATUS rpc_sh_handle_user(TALLOC_CTX *mem_ctx, goto done; } - result = rpccli_samr_connect(pipe_hnd, mem_ctx, - MAXIMUM_ALLOWED_ACCESS, &connect_pol); + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - ctx->domain_sid, &domain_pol); + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + ctx->domain_sid, + &domain_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } - result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol, - MAXIMUM_ALLOWED_ACCESS, - rid, &user_pol); + result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx, + &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + rid, + &user_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } @@ -1397,13 +1475,13 @@ static NTSTATUS rpc_sh_handle_user(TALLOC_CTX *mem_ctx, done: if (is_valid_policy_hnd(&user_pol)) { - rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol); + rpccli_samr_Close(pipe_hnd, mem_ctx, &user_pol); } if (is_valid_policy_hnd(&domain_pol)) { - rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol); + rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol); } if (is_valid_policy_hnd(&connect_pol)) { - rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol); + rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol); } return result; } @@ -1411,28 +1489,28 @@ static NTSTATUS rpc_sh_handle_user(TALLOC_CTX *mem_ctx, static NTSTATUS rpc_sh_user_show_internals(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, struct rpc_pipe_client *pipe_hnd, - const POLICY_HND *user_hnd, + POLICY_HND *user_hnd, int argc, const char **argv) { NTSTATUS result; - SAM_USERINFO_CTR *ctr; - SAM_USER_INFO_21 *info; + union samr_UserInfo *info = NULL; if (argc != 0) { d_fprintf(stderr, "usage: %s show <username>\n", ctx->whoami); return NT_STATUS_INVALID_PARAMETER; } - result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd, - 21, &ctr); + result = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx, + user_hnd, + 21, + &info); if (!NT_STATUS_IS_OK(result)) { return result; } - info = ctr->info.id21; - - d_printf("user rid: %d, group rid: %d\n", info->user_rid, - info->group_rid); + d_printf("user rid: %d, group rid: %d\n", + info->info21.rid, + info->info21.primary_gid); return result; } @@ -1448,27 +1526,25 @@ static NTSTATUS rpc_sh_user_show(TALLOC_CTX *mem_ctx, #define FETCHSTR(name, rec) \ do { if (strequal(ctx->thiscmd, name)) { \ - oldval = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_##rec); } \ + oldval = talloc_strdup(mem_ctx, info->info21.rec.string); } \ } while (0); #define SETSTR(name, rec, flag) \ do { if (strequal(ctx->thiscmd, name)) { \ - init_unistr2(&usr->uni_##rec, argv[0], UNI_STR_TERMINATE); \ - init_uni_hdr(&usr->hdr_##rec, &usr->uni_##rec); \ - usr->fields_present |= ACCT_##flag; } \ + init_lsa_String(&(info->info21.rec), argv[0]); \ + info->info21.fields_present |= SAMR_FIELD_##flag; } \ } while (0); static NTSTATUS rpc_sh_user_str_edit_internals(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, struct rpc_pipe_client *pipe_hnd, - const POLICY_HND *user_hnd, + POLICY_HND *user_hnd, int argc, const char **argv) { NTSTATUS result; - SAM_USERINFO_CTR *ctr; - SAM_USER_INFO_21 *usr; const char *username; const char *oldval = ""; + union samr_UserInfo *info = NULL; if (argc > 1) { d_fprintf(stderr, "usage: %s <username> [new value|NULL]\n", @@ -1476,44 +1552,45 @@ static NTSTATUS rpc_sh_user_str_edit_internals(TALLOC_CTX *mem_ctx, return NT_STATUS_INVALID_PARAMETER; } - result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd, - 21, &ctr); + result = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx, + user_hnd, + 21, + &info); if (!NT_STATUS_IS_OK(result)) { return result; } - usr = ctr->info.id21; - - username = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_user_name); + username = talloc_strdup(mem_ctx, info->info21.account_name.string); FETCHSTR("fullname", full_name); - FETCHSTR("homedir", home_dir); - FETCHSTR("homedrive", dir_drive); + FETCHSTR("homedir", home_directory); + FETCHSTR("homedrive", home_drive); FETCHSTR("logonscript", logon_script); FETCHSTR("profilepath", profile_path); - FETCHSTR("description", acct_desc); + FETCHSTR("description", description); if (argc == 0) { d_printf("%s's %s: [%s]\n", username, ctx->thiscmd, oldval); goto done; } - ZERO_STRUCTP(usr); - if (strcmp(argv[0], "NULL") == 0) { argv[0] = ""; } + ZERO_STRUCT(info->info21); + SETSTR("fullname", full_name, FULL_NAME); - SETSTR("homedir", home_dir, HOME_DIR); - SETSTR("homedrive", dir_drive, HOME_DRIVE); + SETSTR("homedir", home_directory, HOME_DIRECTORY); + SETSTR("homedrive", home_drive, HOME_DRIVE); SETSTR("logonscript", logon_script, LOGON_SCRIPT); - SETSTR("profilepath", profile_path, PROFILE); - SETSTR("description", acct_desc, DESCRIPTION); + SETSTR("profilepath", profile_path, PROFILE_PATH); + SETSTR("description", description, DESCRIPTION); - result = rpccli_samr_set_userinfo2( - pipe_hnd, mem_ctx, user_hnd, 21, - &pipe_hnd->cli->user_session_key, ctr); + result = rpccli_samr_SetUserInfo(pipe_hnd, mem_ctx, + user_hnd, + 21, + info); d_printf("Set %s's %s from [%s] to [%s]\n", username, ctx->thiscmd, oldval, argv[0]); @@ -1544,16 +1621,15 @@ static NTSTATUS rpc_sh_user_str_edit(TALLOC_CTX *mem_ctx, static NTSTATUS rpc_sh_user_flag_edit_internals(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, struct rpc_pipe_client *pipe_hnd, - const POLICY_HND *user_hnd, + POLICY_HND *user_hnd, int argc, const char **argv) { NTSTATUS result; - SAM_USERINFO_CTR *ctr; - SAM_USER_INFO_21 *usr; const char *username; const char *oldval = "unknown"; uint32 oldflags, newflags; bool newval; + union samr_UserInfo *info = NULL; if ((argc > 1) || ((argc == 1) && !strequal(argv[0], "yes") && @@ -1565,17 +1641,17 @@ static NTSTATUS rpc_sh_user_flag_edit_internals(TALLOC_CTX *mem_ctx, newval = strequal(argv[0], "yes"); - result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd, - 21, &ctr); + result = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx, + user_hnd, + 21, + &info); if (!NT_STATUS_IS_OK(result)) { return result; } - usr = ctr->info.id21; - - username = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_user_name); - oldflags = usr->acb_info; - newflags = usr->acb_info; + username = talloc_strdup(mem_ctx, info->info21.account_name.string); + oldflags = info->info21.acct_flags; + newflags = info->info21.acct_flags; HANDLEFLG("disabled", DISABLED); HANDLEFLG("pwnotreq", PWNOTREQ); @@ -1587,14 +1663,15 @@ static NTSTATUS rpc_sh_user_flag_edit_internals(TALLOC_CTX *mem_ctx, goto done; } - ZERO_STRUCTP(usr); + ZERO_STRUCT(info->info21); - usr->acb_info = newflags; - usr->fields_present = ACCT_FLAGS; + info->info21.acct_flags = newflags; + info->info21.fields_present = SAMR_FIELD_ACCT_FLAGS; - result = rpccli_samr_set_userinfo2( - pipe_hnd, mem_ctx, user_hnd, 21, - &pipe_hnd->cli->user_session_key, ctr); + result = rpccli_samr_SetUserInfo(pipe_hnd, mem_ctx, + user_hnd, + 21, + info); if (NT_STATUS_IS_OK(result)) { d_printf("Set %s's %s flag from [%s] to [%s]\n", username, @@ -1720,15 +1797,15 @@ static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid, POLICY_HND connect_pol, domain_pol, group_pol, user_pol; bool group_is_primary = False; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - uint32 *group_rids, num_rids, *name_types, num_members, - *group_attrs, group_rid; - uint32 flags = 0x000003e8; /* Unknown */ + uint32_t group_rid; + struct samr_RidTypeArray *rids = NULL; /* char **names; */ int i; /* DOM_GID *user_gids; */ - SAM_USERINFO_CTR *user_ctr; - fstring temp; + + struct samr_Ids group_rids, name_types; + struct lsa_String lsa_acct_name; + union samr_UserInfo *info = NULL; if (argc < 1) { d_printf("specify group\n"); @@ -1736,50 +1813,59 @@ static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid, return NT_STATUS_OK; /* ok? */ } - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) { - d_fprintf(stderr, "Request samr_connect failed\n"); + d_fprintf(stderr, "Request samr_Connect2 failed\n"); goto done; } - - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - domain_sid, &domain_pol); - + + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + CONST_DISCARD(struct dom_sid2 *, domain_sid), + &domain_pol); + if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "Request open_domain failed\n"); goto done; } - - result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, - flags, 1, &argv[0], - &num_rids, &group_rids, - &name_types); + init_lsa_String(&lsa_acct_name, argv[0]); + + result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx, + &domain_pol, + 1, + &lsa_acct_name, + &group_rids, + &name_types); if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "Lookup of '%s' failed\n",argv[0]); goto done; } - switch (name_types[0]) + switch (name_types.ids[0]) { case SID_NAME_DOM_GRP: - result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol, - MAXIMUM_ALLOWED_ACCESS, - group_rids[0], &group_pol); + result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx, + &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + group_rids.ids[0], + &group_pol); if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "Request open_group failed"); goto done; } - - group_rid = group_rids[0]; - - result = rpccli_samr_query_groupmem(pipe_hnd, mem_ctx, &group_pol, - &num_members, &group_rids, - &group_attrs); - + + group_rid = group_rids.ids[0]; + + result = rpccli_samr_QueryGroupMember(pipe_hnd, mem_ctx, + &group_pol, + &rids); + if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "Unable to query group members of %s",argv[0]); goto done; @@ -1787,40 +1873,44 @@ static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid, if (opt_verbose) { d_printf("Domain Group %s (rid: %d) has %d members\n", - argv[0],group_rid,num_members); + argv[0],group_rid, rids->count); } /* Check if group is anyone's primary group */ - for (i = 0; i < num_members; i++) + for (i = 0; i < rids->count; i++) { - result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol, - MAXIMUM_ALLOWED_ACCESS, - group_rids[i], &user_pol); + result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx, + &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + rids->rids[i], + &user_pol); if (!NT_STATUS_IS_OK(result)) { - d_fprintf(stderr, "Unable to open group member %d\n",group_rids[i]); + d_fprintf(stderr, "Unable to open group member %d\n", + rids->rids[i]); goto done; } - - ZERO_STRUCT(user_ctr); - result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, &user_pol, - 21, &user_ctr); - + result = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx, + &user_pol, + 21, + &info); + if (!NT_STATUS_IS_OK(result)) { - d_fprintf(stderr, "Unable to lookup userinfo for group member %d\n",group_rids[i]); + d_fprintf(stderr, "Unable to lookup userinfo for group member %d\n", + rids->rids[i]); goto done; } - - if (user_ctr->info.id21->group_rid == group_rid) { - unistr2_to_ascii(temp, &(user_ctr->info.id21)->uni_user_name, - sizeof(temp)); - if (opt_verbose) - d_printf("Group is primary group of %s\n",temp); + + if (info->info21.primary_gid == group_rid) { + if (opt_verbose) { + d_printf("Group is primary group of %s\n", + info->info21.account_name.string); + } group_is_primary = True; } - rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol); + rpccli_samr_Close(pipe_hnd, mem_ctx, &user_pol); } if (group_is_primary) { @@ -1831,11 +1921,14 @@ static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid, } /* remove all group members */ - for (i = 0; i < num_members; i++) + for (i = 0; i < rids->count; i++) { if (opt_verbose) - d_printf("Remove group member %d...",group_rids[i]); - result = rpccli_samr_del_groupmem(pipe_hnd, mem_ctx, &group_pol, group_rids[i]); + d_printf("Remove group member %d...", + rids->rids[i]); + result = rpccli_samr_DeleteGroupMember(pipe_hnd, mem_ctx, + &group_pol, + rids->rids[i]); if (NT_STATUS_IS_OK(result)) { if (opt_verbose) @@ -1847,25 +1940,29 @@ static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid, } } - result = rpccli_samr_delete_dom_group(pipe_hnd, mem_ctx, &group_pol); + result = rpccli_samr_DeleteDomainGroup(pipe_hnd, mem_ctx, + &group_pol); break; /* removing a local group is easier... */ case SID_NAME_ALIAS: - result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol, - MAXIMUM_ALLOWED_ACCESS, - group_rids[0], &group_pol); + result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx, + &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + group_rids.ids[0], + &group_pol); if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "Request open_alias failed\n"); goto done; } - - result = rpccli_samr_delete_dom_alias(pipe_hnd, mem_ctx, &group_pol); + + result = rpccli_samr_DeleteDomAlias(pipe_hnd, mem_ctx, + &group_pol); break; default: d_fprintf(stderr, "%s is of type %s. This command is only for deleting local or global groups\n", - argv[0],sid_type_lookup(name_types[0])); + argv[0],sid_type_lookup(name_types.ids[0])); result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -1873,7 +1970,7 @@ static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid, if (NT_STATUS_IS_OK(result)) { if (opt_verbose) - d_printf("Deleted %s '%s'\n",sid_type_lookup(name_types[0]),argv[0]); + d_printf("Deleted %s '%s'\n",sid_type_lookup(name_types.ids[0]),argv[0]); } else { d_fprintf(stderr, "Deleting of %s failed: %s\n",argv[0], get_friendly_nt_error_msg(result)); @@ -1900,7 +1997,9 @@ static NTSTATUS rpc_group_add_internals(const DOM_SID *domain_sid, { POLICY_HND connect_pol, domain_pol, group_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - GROUP_INFO_CTR group_info; + union samr_GroupInfo group_info; + struct lsa_String grp_name; + uint32_t rid = 0; if (argc != 1) { d_printf("Group name must be specified\n"); @@ -1908,34 +2007,45 @@ static NTSTATUS rpc_group_add_internals(const DOM_SID *domain_sid, return NT_STATUS_OK; } + init_lsa_String(&grp_name, argv[0]); + /* Get sam policy handle */ - - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; /* Get domain policy handle */ - - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - domain_sid, &domain_pol); + + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + CONST_DISCARD(struct dom_sid2 *, domain_sid), + &domain_pol); if (!NT_STATUS_IS_OK(result)) goto done; /* Create the group */ - result = rpccli_samr_create_dom_group(pipe_hnd, mem_ctx, &domain_pol, - argv[0], MAXIMUM_ALLOWED_ACCESS, - &group_pol); + result = rpccli_samr_CreateDomainGroup(pipe_hnd, mem_ctx, + &domain_pol, + &grp_name, + MAXIMUM_ALLOWED_ACCESS, + &group_pol, + &rid); if (!NT_STATUS_IS_OK(result)) goto done; if (strlen(opt_comment) == 0) goto done; /* We've got a comment to set */ - group_info.switch_value1 = 4; - init_samr_group_info4(&group_info.group.info4, opt_comment); + init_lsa_String(&group_info.description, opt_comment); - result = rpccli_samr_set_groupinfo(pipe_hnd, mem_ctx, &group_pol, &group_info); + result = rpccli_samr_SetGroupInfo(pipe_hnd, mem_ctx, + &group_pol, + 4, + &group_info); if (!NT_STATUS_IS_OK(result)) goto done; done: @@ -1957,7 +2067,9 @@ static NTSTATUS rpc_alias_add_internals(const DOM_SID *domain_sid, { POLICY_HND connect_pol, domain_pol, alias_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - ALIAS_INFO_CTR alias_info; + union samr_AliasInfo alias_info; + struct lsa_String alias_name; + uint32_t rid = 0; if (argc != 1) { d_printf("Alias name must be specified\n"); @@ -1965,33 +2077,46 @@ static NTSTATUS rpc_alias_add_internals(const DOM_SID *domain_sid, return NT_STATUS_OK; } + init_lsa_String(&alias_name, argv[0]); + /* Get sam policy handle */ - - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; /* Get domain policy handle */ - - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - domain_sid, &domain_pol); + + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + CONST_DISCARD(struct dom_sid2 *, domain_sid), + &domain_pol); if (!NT_STATUS_IS_OK(result)) goto done; /* Create the group */ - result = rpccli_samr_create_dom_alias(pipe_hnd, mem_ctx, &domain_pol, - argv[0], &alias_pol); + result = rpccli_samr_CreateDomAlias(pipe_hnd, mem_ctx, + &domain_pol, + &alias_name, + MAXIMUM_ALLOWED_ACCESS, + &alias_pol, + &rid); if (!NT_STATUS_IS_OK(result)) goto done; if (strlen(opt_comment) == 0) goto done; /* We've got a comment to set */ - alias_info.level = 3; - init_samr_alias_info3(&alias_info.alias.info3, opt_comment); + init_lsa_String(&alias_info.description, opt_comment); + + result = rpccli_samr_SetAliasInfo(pipe_hnd, mem_ctx, + &alias_pol, + 3, + &alias_info); - result = rpccli_samr_set_aliasinfo(pipe_hnd, mem_ctx, &alias_pol, &alias_info); if (!NT_STATUS_IS_OK(result)) goto done; done: @@ -2080,9 +2205,8 @@ static NTSTATUS rpc_add_groupmem(struct rpc_pipe_client *pipe_hnd, uint32 group_rid; POLICY_HND group_pol; - uint32 num_rids; - uint32 *rids = NULL; - uint32 *rid_types = NULL; + struct samr_Ids rids, rid_types; + struct lsa_String lsa_acct_name; DOM_SID sid; @@ -2092,42 +2216,56 @@ static NTSTATUS rpc_add_groupmem(struct rpc_pipe_client *pipe_hnd, return NT_STATUS_UNSUCCESSFUL; } - /* Get sam policy handle */ - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + /* Get sam policy handle */ + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) { return result; } - + /* Get domain policy handle */ - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - &sid, &domain_pol); + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &sid, + &domain_pol); if (!NT_STATUS_IS_OK(result)) { return result; } - result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000, - 1, &member, - &num_rids, &rids, &rid_types); + init_lsa_String(&lsa_acct_name, member); + + result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx, + &domain_pol, + 1, + &lsa_acct_name, + &rids, + &rid_types); if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "Could not lookup up group member %s\n", member); goto done; } - result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol, - MAXIMUM_ALLOWED_ACCESS, - group_rid, &group_pol); + result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx, + &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + group_rid, + &group_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } - result = rpccli_samr_add_groupmem(pipe_hnd, mem_ctx, &group_pol, rids[0]); + result = rpccli_samr_AddGroupMember(pipe_hnd, mem_ctx, + &group_pol, + rids.ids[0], + 0x0005); /* unknown flags */ done: - rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol); + rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol); return result; } @@ -2160,37 +2298,45 @@ static NTSTATUS rpc_add_aliasmem(struct rpc_pipe_client *pipe_hnd, return result; } - /* Get sam policy handle */ - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + /* Get sam policy handle */ + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } - + /* Get domain policy handle */ - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - &sid, &domain_pol); + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &sid, + &domain_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } - result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol, - MAXIMUM_ALLOWED_ACCESS, - alias_rid, &alias_pol); + result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx, + &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + alias_rid, + &alias_pol); if (!NT_STATUS_IS_OK(result)) { return result; } - result = rpccli_samr_add_aliasmem(pipe_hnd, mem_ctx, &alias_pol, &member_sid); + result = rpccli_samr_AddAliasMember(pipe_hnd, mem_ctx, + &alias_pol, + &member_sid); if (!NT_STATUS_IS_OK(result)) { return result; } done: - rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol); + rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol); return result; } @@ -2261,9 +2407,8 @@ static NTSTATUS rpc_del_groupmem(struct rpc_pipe_client *pipe_hnd, uint32 group_rid; POLICY_HND group_pol; - uint32 num_rids; - uint32 *rids = NULL; - uint32 *rid_types = NULL; + struct samr_Ids rids, rid_types; + struct lsa_String lsa_acct_name; DOM_SID sid; @@ -2272,39 +2417,51 @@ static NTSTATUS rpc_del_groupmem(struct rpc_pipe_client *pipe_hnd, if (!sid_split_rid(&sid, &group_rid)) return NT_STATUS_UNSUCCESSFUL; - /* Get sam policy handle */ - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + /* Get sam policy handle */ + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) return result; - + /* Get domain policy handle */ - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - &sid, &domain_pol); + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &sid, + &domain_pol); if (!NT_STATUS_IS_OK(result)) return result; - result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000, - 1, &member, - &num_rids, &rids, &rid_types); + init_lsa_String(&lsa_acct_name, member); + result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx, + &domain_pol, + 1, + &lsa_acct_name, + &rids, + &rid_types); if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "Could not lookup up group member %s\n", member); goto done; } - result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol, - MAXIMUM_ALLOWED_ACCESS, - group_rid, &group_pol); + result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx, + &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + group_rid, + &group_pol); if (!NT_STATUS_IS_OK(result)) goto done; - result = rpccli_samr_del_groupmem(pipe_hnd, mem_ctx, &group_pol, rids[0]); + result = rpccli_samr_DeleteGroupMember(pipe_hnd, mem_ctx, + &group_pol, + rids.ids[0]); done: - rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol); + rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol); return result; } @@ -2336,35 +2493,43 @@ static NTSTATUS rpc_del_aliasmem(struct rpc_pipe_client *pipe_hnd, return result; } - /* Get sam policy handle */ - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + /* Get sam policy handle */ + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } - + /* Get domain policy handle */ - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - &sid, &domain_pol); + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &sid, + &domain_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } - result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol, - MAXIMUM_ALLOWED_ACCESS, - alias_rid, &alias_pol); + result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx, + &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + alias_rid, + &alias_pol); if (!NT_STATUS_IS_OK(result)) return result; - result = rpccli_samr_del_aliasmem(pipe_hnd, mem_ctx, &alias_pol, &member_sid); + result = rpccli_samr_DeleteAliasMember(pipe_hnd, mem_ctx, + &alias_pol, + &member_sid); if (!NT_STATUS_IS_OK(result)) return result; done: - rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol); + rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol); return result; } @@ -2452,7 +2617,7 @@ static NTSTATUS rpc_group_list_internals(const DOM_SID *domain_sid, POLICY_HND connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0; - struct acct_info *groups; + struct samr_SamArray *groups = NULL; bool global = False; bool local = False; bool builtin = False; @@ -2475,18 +2640,22 @@ static NTSTATUS rpc_group_list_internals(const DOM_SID *domain_sid, } /* Get sam policy handle */ - - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } /* Get domain policy handle */ - - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - domain_sid, &domain_pol); + + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + CONST_DISCARD(struct dom_sid2 *, domain_sid), + &domain_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } @@ -2496,34 +2665,38 @@ static NTSTATUS rpc_group_list_internals(const DOM_SID *domain_sid, d_printf("\nGroup name Comment"\ "\n-----------------------------\n"); do { - SAM_DISPINFO_CTR ctr; - SAM_DISPINFO_3 info3; - uint32 max_size; - - ZERO_STRUCT(ctr); - ZERO_STRUCT(info3); - ctr.sam.info3 = &info3; + uint32_t max_size, total_size, returned_size; + union samr_DispInfo info; if (!global) break; get_query_dispinfo_params( loop_count, &max_entries, &max_size); - result = rpccli_samr_query_dispinfo(pipe_hnd, mem_ctx, &domain_pol, - &start_idx, 3, &num_entries, - max_entries, max_size, &ctr); + result = rpccli_samr_QueryDisplayInfo(pipe_hnd, mem_ctx, + &domain_pol, + 3, + start_idx, + max_entries, + max_size, + &total_size, + &returned_size, + &info); + num_entries = info.info3.count; + start_idx += info.info3.count; if (!NT_STATUS_IS_OK(result) && !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) break; - + for (i = 0; i < num_entries; i++) { - fstring group, desc; + const char *group = NULL; + const char *desc = NULL; + + group = info.info3.entries[i].account_name.string; + desc = info.info3.entries[i].description.string; - unistr2_to_ascii(group, &(&ctr.sam.info3->str[i])->uni_grp_name, sizeof(group)); - unistr2_to_ascii(desc, &(&ctr.sam.info3->str[i])->uni_grp_desc, sizeof(desc)); - if (opt_long_list_entries) printf("%-21.21s %-50.50s\n", group, desc); @@ -2536,59 +2709,57 @@ static NTSTATUS rpc_group_list_internals(const DOM_SID *domain_sid, do { if (!local) break; - /* The max_size field in cli_samr_enum_als_groups is more like - * an account_control field with indiviual bits what to - * retrieve. Set this to 0xffff as NT4 usrmgr.exe does to get - * everything. I'm too lazy (sorry) to get this through to - * rpc_parse/ etc. Volker */ - - result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol, - &start_idx, 0xffff, - &groups, &num_entries); - + result = rpccli_samr_EnumDomainAliases(pipe_hnd, mem_ctx, + &domain_pol, + &start_idx, + &groups, + 0xffff, + &num_entries); if (!NT_STATUS_IS_OK(result) && !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) break; - + for (i = 0; i < num_entries; i++) { - char *description = NULL; + const char *description = NULL; if (opt_long_list_entries) { POLICY_HND alias_pol; - ALIAS_INFO_CTR ctr; - - if ((NT_STATUS_IS_OK(rpccli_samr_open_alias(pipe_hnd, mem_ctx, - &domain_pol, - 0x8, - groups[i].rid, - &alias_pol))) && - (NT_STATUS_IS_OK(rpccli_samr_query_alias_info(pipe_hnd, mem_ctx, - &alias_pol, 3, - &ctr))) && - (NT_STATUS_IS_OK(rpccli_samr_close(pipe_hnd, mem_ctx, + union samr_AliasInfo *info = NULL; + + if ((NT_STATUS_IS_OK(rpccli_samr_OpenAlias(pipe_hnd, mem_ctx, + &domain_pol, + 0x8, + groups->entries[i].idx, + &alias_pol))) && + (NT_STATUS_IS_OK(rpccli_samr_QueryAliasInfo(pipe_hnd, mem_ctx, + &alias_pol, + 3, + &info))) && + (NT_STATUS_IS_OK(rpccli_samr_Close(pipe_hnd, mem_ctx, &alias_pol)))) { - description = unistr2_to_ascii_talloc(mem_ctx, - ctr.alias.info3.description.string); + description = info->description.string; } } - + if (description != NULL) { - printf("%-21.21s %-50.50s\n", - groups[i].acct_name, + printf("%-21.21s %-50.50s\n", + groups->entries[i].name.string, description); } else { - printf("%s\n", groups[i].acct_name); + printf("%s\n", groups->entries[i].name.string); } } } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); - rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol); + rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol); /* Get builtin policy handle */ - - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - &global_sid_Builtin, &domain_pol); + + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin), + &domain_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } @@ -2597,44 +2768,46 @@ static NTSTATUS rpc_group_list_internals(const DOM_SID *domain_sid, do { if (!builtin) break; - result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol, - &start_idx, max_entries, - &groups, &num_entries); - + result = rpccli_samr_EnumDomainAliases(pipe_hnd, mem_ctx, + &domain_pol, + &start_idx, + &groups, + max_entries, + &num_entries); if (!NT_STATUS_IS_OK(result) && !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) break; - + for (i = 0; i < num_entries; i++) { - char *description = NULL; + const char *description = NULL; if (opt_long_list_entries) { POLICY_HND alias_pol; - ALIAS_INFO_CTR ctr; - - if ((NT_STATUS_IS_OK(rpccli_samr_open_alias(pipe_hnd, mem_ctx, - &domain_pol, - 0x8, - groups[i].rid, - &alias_pol))) && - (NT_STATUS_IS_OK(rpccli_samr_query_alias_info(pipe_hnd, mem_ctx, - &alias_pol, 3, - &ctr))) && - (NT_STATUS_IS_OK(rpccli_samr_close(pipe_hnd, mem_ctx, + union samr_AliasInfo *info = NULL; + + if ((NT_STATUS_IS_OK(rpccli_samr_OpenAlias(pipe_hnd, mem_ctx, + &domain_pol, + 0x8, + groups->entries[i].idx, + &alias_pol))) && + (NT_STATUS_IS_OK(rpccli_samr_QueryAliasInfo(pipe_hnd, mem_ctx, + &alias_pol, + 3, + &info))) && + (NT_STATUS_IS_OK(rpccli_samr_Close(pipe_hnd, mem_ctx, &alias_pol)))) { - description = unistr2_to_ascii_talloc(mem_ctx, - ctr.alias.info3.description.string); + description = info->description.string; } } - + if (description != NULL) { - printf("%-21.21s %-50.50s\n", - groups[i].acct_name, + printf("%-21.21s %-50.50s\n", + groups->entries[i].name.string, description); } else { - printf("%s\n", groups[i].acct_name); + printf("%s\n", groups->entries[i].name.string); } } } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); @@ -2659,38 +2832,46 @@ static NTSTATUS rpc_list_group_members(struct rpc_pipe_client *pipe_hnd, { NTSTATUS result; POLICY_HND group_pol; - uint32 num_members, *group_rids, *group_attrs; - uint32 num_names; - char **names; - uint32 *name_types; + uint32 num_members, *group_rids; int i; + struct samr_RidTypeArray *rids = NULL; + struct lsa_Strings names; + struct samr_Ids types; fstring sid_str; sid_to_fstring(sid_str, domain_sid); - result = rpccli_samr_open_group(pipe_hnd, mem_ctx, domain_pol, - MAXIMUM_ALLOWED_ACCESS, - rid, &group_pol); + result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx, + domain_pol, + MAXIMUM_ALLOWED_ACCESS, + rid, + &group_pol); if (!NT_STATUS_IS_OK(result)) return result; - result = rpccli_samr_query_groupmem(pipe_hnd, mem_ctx, &group_pol, - &num_members, &group_rids, - &group_attrs); + result = rpccli_samr_QueryGroupMember(pipe_hnd, mem_ctx, + &group_pol, + &rids); if (!NT_STATUS_IS_OK(result)) return result; + num_members = rids->count; + group_rids = rids->rids; + while (num_members > 0) { int this_time = 512; if (num_members < this_time) this_time = num_members; - result = rpccli_samr_lookup_rids(pipe_hnd, mem_ctx, domain_pol, - this_time, group_rids, - &num_names, &names, &name_types); + result = rpccli_samr_LookupRids(pipe_hnd, mem_ctx, + domain_pol, + this_time, + group_rids, + &names, + &types); if (!NT_STATUS_IS_OK(result)) return result; @@ -2702,10 +2883,12 @@ static NTSTATUS rpc_list_group_members(struct rpc_pipe_client *pipe_hnd, if (opt_long_list_entries) { printf("%s-%d %s\\%s %d\n", sid_str, - group_rids[i], domain_name, names[i], + group_rids[i], domain_name, + names.names[i].string, SID_NAME_USER); } else { - printf("%s\\%s\n", domain_name, names[i]); + printf("%s\\%s\n", domain_name, + names.names[i].string); } } @@ -2730,21 +2913,28 @@ static NTSTATUS rpc_list_alias_members(struct rpc_pipe_client *pipe_hnd, char **names; enum lsa_SidType *types; int i; + struct lsa_SidArray sid_array; - result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, domain_pol, - MAXIMUM_ALLOWED_ACCESS, rid, &alias_pol); + result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx, + domain_pol, + MAXIMUM_ALLOWED_ACCESS, + rid, + &alias_pol); if (!NT_STATUS_IS_OK(result)) return result; - result = rpccli_samr_query_aliasmem(pipe_hnd, mem_ctx, &alias_pol, - &num_members, &alias_sids); + result = rpccli_samr_GetMembersInAlias(pipe_hnd, mem_ctx, + &alias_pol, + &sid_array); if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "Couldn't list alias members\n"); return result; } + num_members = sid_array.num_sids; + if (num_members == 0) { return NT_STATUS_OK; } @@ -2765,6 +2955,17 @@ static NTSTATUS rpc_list_alias_members(struct rpc_pipe_client *pipe_hnd, return result; } + alias_sids = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_members); + if (!alias_sids) { + d_fprintf(stderr, "Out of memory\n"); + cli_rpc_pipe_close(lsa_pipe); + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i<num_members; i++) { + sid_copy(&alias_sids[i], sid_array.sids[i].sid); + } + result = rpccli_lsa_lookup_sids(lsa_pipe, mem_ctx, &lsa_pol, num_members, alias_sids, &domains, &names, &types); @@ -2806,27 +3007,38 @@ static NTSTATUS rpc_group_members_internals(const DOM_SID *domain_sid, { NTSTATUS result; POLICY_HND connect_pol, domain_pol; - uint32 num_rids, *rids, *rid_types; + struct samr_Ids rids, rid_types; + struct lsa_String lsa_acct_name; /* Get sam policy handle */ - - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) return result; /* Get domain policy handle */ - - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - domain_sid, &domain_pol); + + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + CONST_DISCARD(struct dom_sid2 *, domain_sid), + &domain_pol); if (!NT_STATUS_IS_OK(result)) return result; - result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000, - 1, argv, &num_rids, &rids, &rid_types); + init_lsa_String(&lsa_acct_name, argv[0]); /* sure? */ + + result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx, + &domain_pol, + 1, + &lsa_acct_name, + &rids, + &rid_types); if (!NT_STATUS_IS_OK(result)) { @@ -2834,22 +3046,27 @@ static NTSTATUS rpc_group_members_internals(const DOM_SID *domain_sid, DOM_SID sid_Builtin; - rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol); + rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol); string_to_sid(&sid_Builtin, "S-1-5-32"); - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - &sid_Builtin, &domain_pol); + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + &sid_Builtin, + &domain_pol); if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "Couldn't find group %s\n", argv[0]); return result; } - result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000, - 1, argv, &num_rids, - &rids, &rid_types); + result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx, + &domain_pol, + 1, + &lsa_acct_name, + &rids, + &rid_types); if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "Couldn't find group %s\n", argv[0]); @@ -2857,20 +3074,20 @@ static NTSTATUS rpc_group_members_internals(const DOM_SID *domain_sid, } } - if (num_rids != 1) { + if (rids.count != 1) { d_fprintf(stderr, "Couldn't find group %s\n", argv[0]); return result; } - if (rid_types[0] == SID_NAME_DOM_GRP) { + if (rid_types.ids[0] == SID_NAME_DOM_GRP) { return rpc_list_group_members(pipe_hnd, mem_ctx, domain_name, domain_sid, &domain_pol, - rids[0]); + rids.ids[0]); } - if (rid_types[0] == SID_NAME_ALIAS) { + if (rid_types.ids[0] == SID_NAME_ALIAS) { return rpc_list_alias_members(pipe_hnd, mem_ctx, &domain_pol, - rids[0]); + rids.ids[0]); } return NT_STATUS_NO_SUCH_GROUP; @@ -2897,8 +3114,9 @@ static NTSTATUS rpc_group_rename_internals(const DOM_SID *domain_sid, { NTSTATUS result; POLICY_HND connect_pol, domain_pol, group_pol; - uint32 num_rids, *rids, *rid_types; - GROUP_INFO_CTR ctr; + union samr_GroupInfo group_info; + struct samr_Ids rids, rid_types; + struct lsa_String lsa_acct_name; if (argc != 2) { d_printf("Usage: 'net rpc group rename group newname'\n"); @@ -2906,48 +3124,60 @@ static NTSTATUS rpc_group_rename_internals(const DOM_SID *domain_sid, } /* Get sam policy handle */ - - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) return result; /* Get domain policy handle */ - - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - domain_sid, &domain_pol); + + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + CONST_DISCARD(struct dom_sid2 *, domain_sid), + &domain_pol); if (!NT_STATUS_IS_OK(result)) return result; - result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000, - 1, argv, &num_rids, &rids, &rid_types); + init_lsa_String(&lsa_acct_name, argv[0]); - if (num_rids != 1) { + result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx, + &domain_pol, + 1, + &lsa_acct_name, + &rids, + &rid_types); + + if (rids.count != 1) { d_fprintf(stderr, "Couldn't find group %s\n", argv[0]); return result; } - if (rid_types[0] != SID_NAME_DOM_GRP) { + if (rid_types.ids[0] != SID_NAME_DOM_GRP) { d_fprintf(stderr, "Can only rename domain groups\n"); return NT_STATUS_UNSUCCESSFUL; } - result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol, - MAXIMUM_ALLOWED_ACCESS, - rids[0], &group_pol); + result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx, + &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + rids.ids[0], + &group_pol); if (!NT_STATUS_IS_OK(result)) return result; - ZERO_STRUCT(ctr); + init_lsa_String(&group_info.name, argv[1]); - ctr.switch_value1 = 2; - init_samr_group_info2(&ctr.group.info2, argv[1]); - - result = rpccli_samr_set_groupinfo(pipe_hnd, mem_ctx, &group_pol, &ctr); + result = rpccli_samr_SetGroupInfo(pipe_hnd, mem_ctx, + &group_pol, + 2, + &group_info); if (!NT_STATUS_IS_OK(result)) return result; @@ -3370,14 +3600,14 @@ static bool check_share_sanity(struct cli_state *cli, fstring netname, uint32 ty } /** - * Migrate shares from a remote RPC server to the local RPC srever + * Migrate shares from a remote RPC server to the local RPC server * * All parameters are provided by the run_rpc_command function, except for - * argc, argv which are passes through. + * argc, argv which are passed 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 mem_ctx Talloc context, destroyed on completion of the function. * @param argc Standard main() style argc * @param argv Standard main() style argv. Initial components are already * stripped @@ -4000,15 +4230,17 @@ static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd, const DOM_SID *domain_sid) { uint32 start_idx, max_entries, num_entries, i; - struct acct_info *groups; + struct samr_SamArray *groups = NULL; NTSTATUS result; POLICY_HND domain_pol; /* Get domain policy handle */ - - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, connect_pol, - MAXIMUM_ALLOWED_ACCESS, - domain_sid, &domain_pol); + + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + connect_pol, + MAXIMUM_ALLOWED_ACCESS, + CONST_DISCARD(struct dom_sid2 *, domain_sid), + &domain_pol); if (!NT_STATUS_IS_OK(result)) return result; @@ -4016,32 +4248,36 @@ static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd, max_entries = 250; do { - result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol, - &start_idx, max_entries, - &groups, &num_entries); - + result = rpccli_samr_EnumDomainAliases(pipe_hnd, mem_ctx, + &domain_pol, + &start_idx, + &groups, + max_entries, + &num_entries); for (i = 0; i < num_entries; i++) { POLICY_HND alias_pol; struct full_alias alias; - DOM_SID *members; + struct lsa_SidArray sid_array; int j; - result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol, - MAXIMUM_ALLOWED_ACCESS, - groups[i].rid, - &alias_pol); + result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx, + &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + groups->entries[i].idx, + &alias_pol); if (!NT_STATUS_IS_OK(result)) goto done; - result = rpccli_samr_query_aliasmem(pipe_hnd, mem_ctx, - &alias_pol, - &alias.num_members, - &members); + result = rpccli_samr_GetMembersInAlias(pipe_hnd, mem_ctx, + &alias_pol, + &sid_array); if (!NT_STATUS_IS_OK(result)) goto done; - result = rpccli_samr_close(pipe_hnd, mem_ctx, &alias_pol); + alias.num_members = sid_array.num_sids; + + result = rpccli_samr_Close(pipe_hnd, mem_ctx, &alias_pol); if (!NT_STATUS_IS_OK(result)) goto done; @@ -4052,11 +4288,11 @@ static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd, for (j = 0; j < alias.num_members; j++) sid_copy(&alias.members[j], - &members[j]); + sid_array.sids[j].sid); } sid_copy(&alias.sid, domain_sid); - sid_append_rid(&alias.sid, groups[i].rid); + sid_append_rid(&alias.sid, groups->entries[i].idx); push_alias(mem_ctx, &alias); } @@ -4065,7 +4301,7 @@ static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd, result = NT_STATUS_OK; done: - rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol); + rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol); return result; } @@ -4150,8 +4386,10 @@ static NTSTATUS rpc_aliaslist_internals(const DOM_SID *domain_sid, NTSTATUS result; POLICY_HND connect_pol; - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) goto done; @@ -4165,7 +4403,7 @@ static NTSTATUS rpc_aliaslist_internals(const DOM_SID *domain_sid, result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol, domain_sid); - rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol); + rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol); done: return result; } @@ -5340,8 +5578,12 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, POLICY_HND connect_pol, domain_pol, user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; char *acct_name; + struct lsa_String lsa_acct_name; uint32 acb_info; - uint32 unknown, user_rid; + uint32 acct_flags=0; + uint32 user_rid; + uint32_t access_granted = 0; + union samr_UserInfo info; if (argc != 2) { d_printf("Usage: net rpc trustdom add <domain_name> <pw>\n"); @@ -5351,71 +5593,90 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, /* * Make valid trusting domain account (ie. uppercased and with '$' appended) */ - + if (asprintf(&acct_name, "%s$", argv[0]) < 0) { return NT_STATUS_NO_MEMORY; } strupper_m(acct_name); + init_lsa_String(&lsa_acct_name, acct_name); + /* Get samr policy handle */ - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } - + /* Get domain policy handle */ - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - domain_sid, &domain_pol); + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + CONST_DISCARD(struct dom_sid2 *, domain_sid), + &domain_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } /* Create trusting domain's account */ - acb_info = ACB_NORMAL; - unknown = 0xe00500b0; /* No idea what this is - a permission mask? - mimir: yes, most probably it is */ - - result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol, - acct_name, acb_info, unknown, - &user_pol, &user_rid); + acb_info = ACB_NORMAL; + acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE | + SEC_STD_WRITE_DAC | SEC_STD_DELETE | + SAMR_USER_ACCESS_SET_PASSWORD | + SAMR_USER_ACCESS_GET_ATTRIBUTES | + SAMR_USER_ACCESS_SET_ATTRIBUTES; + + result = rpccli_samr_CreateUser2(pipe_hnd, mem_ctx, + &domain_pol, + &lsa_acct_name, + acb_info, + acct_flags, + &user_pol, + &access_granted, + &user_rid); if (!NT_STATUS_IS_OK(result)) { goto done; } { - SAM_USERINFO_CTR ctr; - SAM_USER_INFO_23 p23; NTTIME notime; - char nostr[] = ""; - LOGON_HRS hrs; + struct samr_LogonHours hours; + const int units_per_week = 168; uchar pwbuf[516]; encode_pw_buffer(pwbuf, argv[1], STR_UNICODE); - ZERO_STRUCT(ctr); - ZERO_STRUCT(p23); ZERO_STRUCT(notime); - hrs.max_len = 1260; - hrs.offset = 0; - hrs.len = 21; - memset(hrs.hours, 0xFF, sizeof(hrs.hours)); - acb_info = ACB_DOMTRUST; - - init_sam_user_info23A(&p23, ¬ime, ¬ime, ¬ime, - ¬ime, ¬ime, ¬ime, - nostr, nostr, nostr, nostr, nostr, - nostr, nostr, nostr, nostr, nostr, - 0, 0, acb_info, ACCT_FLAGS, 168, &hrs, - 0, 0, (char *)pwbuf); - ctr.switch_value = 23; - ctr.info.id23 = &p23; - p23.passmustchange = 0; - - result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 23, - &cli->user_session_key, &ctr); + + ZERO_STRUCT(hours); + hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week); + if (!hours.bits) { + result = NT_STATUS_NO_MEMORY; + goto done; + } + hours.units_per_week = units_per_week; + memset(hours.bits, 0xFF, units_per_week); + + init_samr_user_info23(&info.info23, + notime, notime, notime, + notime, notime, notime, + NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, + 0, 0, ACB_DOMTRUST, SAMR_FIELD_ACCT_FLAGS, + hours, + 0, 0, 0, 0, 0, 0, 0, + pwbuf, 24); + + SamOEMhashBlob(info.info23.password.data, 516, + &cli->user_session_key); + + result = rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx, + &user_pol, + 23, + &info); if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("Could not set trust account password: %s\n", @@ -5476,10 +5737,9 @@ static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid, POLICY_HND connect_pol, domain_pol, user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; char *acct_name; - const char **names; DOM_SID trust_acct_sid; - uint32 *user_rids, num_rids, *name_types; - uint32 flags = 0x000003e8; /* Unknown */ + struct samr_Ids user_rids, name_types; + struct lsa_String lsa_acct_name; if (argc != 1) { d_printf("Usage: net rpc trustdom del <domain_name>\n"); @@ -5496,38 +5756,43 @@ static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid, strupper_m(acct_name); - if ((names = TALLOC_ARRAY(mem_ctx, const char *, 1)) == NULL) { - return NT_STATUS_NO_MEMORY; - } - names[0] = acct_name; - - /* Get samr policy handle */ - result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } - + /* Get domain policy handle */ - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - domain_sid, &domain_pol); + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + CONST_DISCARD(struct dom_sid2 *, domain_sid), + &domain_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } - result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, flags, 1, - names, &num_rids, - &user_rids, &name_types); - + init_lsa_String(&lsa_acct_name, acct_name); + + result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx, + &domain_pol, + 1, + &lsa_acct_name, + &user_rids, + &name_types); + if (!NT_STATUS_IS_OK(result)) { goto done; } - result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol, - MAXIMUM_ALLOWED_ACCESS, - user_rids[0], &user_pol); + result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx, + &domain_pol, + MAXIMUM_ALLOWED_ACCESS, + user_rids.ids[0], + &user_pol); if (!NT_STATUS_IS_OK(result)) { goto done; @@ -5535,22 +5800,23 @@ static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid, /* append the rid to the domain sid */ sid_copy(&trust_acct_sid, domain_sid); - if (!sid_append_rid(&trust_acct_sid, user_rids[0])) { + if (!sid_append_rid(&trust_acct_sid, user_rids.ids[0])) { goto done; } /* remove the sid */ - result = rpccli_samr_remove_sid_foreign_domain(pipe_hnd, mem_ctx, &user_pol, - &trust_acct_sid); - + result = rpccli_samr_RemoveMemberFromForeignDomain(pipe_hnd, mem_ctx, + &user_pol, + &trust_acct_sid); if (!NT_STATUS_IS_OK(result)) { goto done; } /* Delete user */ - result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol); + result = rpccli_samr_DeleteUser(pipe_hnd, mem_ctx, + &user_pol); if (!NT_STATUS_IS_OK(result)) { goto done; @@ -5608,10 +5874,10 @@ static int rpc_trustdom_establish(int argc, const char **argv) DOM_SID *domain_sid; char* domain_name; - const char* domain_name_pol; char* acct_name; fstring pdc_name; char *dc_name; + union lsa_PolicyInformation *info = NULL; /* * Connect to \\server\ipc$ as 'our domain' account with password @@ -5713,10 +5979,11 @@ static int rpc_trustdom_establish(int argc, const char **argv) } /* Querying info level 5 */ - - nt_status = rpccli_lsa_query_info_policy(pipe_hnd, mem_ctx, &connect_hnd, - 5 /* info level */, - &domain_name_pol, &domain_sid); + + nt_status = rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx, + &connect_hnd, + LSA_POLICY_INFO_ACCOUNT_DOMAIN, + &info); if (NT_STATUS_IS_ERR(nt_status)) { DEBUG(0, ("LSA Query Info failed. Returned error was %s\n", nt_errstr(nt_status))); @@ -5725,6 +5992,8 @@ static int rpc_trustdom_establish(int argc, const char **argv) return -1; } + domain_sid = info->account_domain.sid; + /* There should be actually query info level 3 (following nt serv behaviour), but I still don't know if it's _really_ necessary */ @@ -5911,14 +6180,13 @@ static int rpc_trustdom_vampire(int argc, const char **argv) const char *domain_name = NULL; DOM_SID *queried_dom_sid; POLICY_HND connect_hnd; + union lsa_PolicyInformation *info = NULL; /* trusted domains listing variables */ - unsigned int num_domains, enum_ctx = 0; + unsigned int enum_ctx = 0; int i; - DOM_SID *domain_sids; - char **trusted_dom_names; + struct lsa_DomainList dom_list; fstring pdc_name; - const char *dummy; /* * Listing trusted domains (stored in secrets.tdb, if local) @@ -5969,9 +6237,10 @@ static int rpc_trustdom_vampire(int argc, const char **argv) }; /* query info level 5 to obtain sid of a domain being queried */ - nt_status = rpccli_lsa_query_info_policy( - pipe_hnd, mem_ctx, &connect_hnd, 5 /* info level */, - &dummy, &queried_dom_sid); + nt_status = rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx, + &connect_hnd, + LSA_POLICY_INFO_ACCOUNT_DOMAIN, + &info); if (NT_STATUS_IS_ERR(nt_status)) { DEBUG(0, ("LSA Query Info failed. Returned error was %s\n", @@ -5981,6 +6250,8 @@ static int rpc_trustdom_vampire(int argc, const char **argv) return -1; } + queried_dom_sid = info->account_domain.sid; + /* * Keep calling LsaEnumTrustdom over opened pipe until * the end of enumeration is reached @@ -5989,10 +6260,11 @@ static int rpc_trustdom_vampire(int argc, const char **argv) d_printf("Vampire trusted domains:\n\n"); do { - nt_status = rpccli_lsa_enum_trust_dom(pipe_hnd, mem_ctx, &connect_hnd, &enum_ctx, - &num_domains, - &trusted_dom_names, &domain_sids); - + nt_status = rpccli_lsa_EnumTrustDom(pipe_hnd, mem_ctx, + &connect_hnd, + &enum_ctx, + &dom_list, + (uint32_t)-1); if (NT_STATUS_IS_ERR(nt_status)) { DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n", nt_errstr(nt_status))); @@ -6000,13 +6272,15 @@ static int rpc_trustdom_vampire(int argc, const char **argv) talloc_destroy(mem_ctx); return -1; }; - - for (i = 0; i < num_domains; i++) { - print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]); + for (i = 0; i < dom_list.count; i++) { + + print_trusted_domain(dom_list.domains[i].sid, + dom_list.domains[i].name.string); nt_status = vampire_trusted_domain(pipe_hnd, mem_ctx, &connect_hnd, - domain_sids[i], trusted_dom_names[i]); + *dom_list.domains[i].sid, + dom_list.domains[i].name.string); if (!NT_STATUS_IS_OK(nt_status)) { cli_shutdown(cli); talloc_destroy(mem_ctx); @@ -6018,7 +6292,7 @@ static int rpc_trustdom_vampire(int argc, const char **argv) * in case of no trusted domains say something rather * than just display blank line */ - if (!num_domains) d_printf("none\n"); + if (!dom_list.count) d_printf("none\n"); } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)); @@ -6051,20 +6325,18 @@ static int rpc_trustdom_list(int argc, const char **argv) fstring padding; int ascii_dom_name_len; POLICY_HND connect_hnd; - + union lsa_PolicyInformation *info = NULL; + /* trusted domains listing variables */ unsigned int num_domains, enum_ctx = 0; int i, pad_len, col_len = 20; - DOM_SID *domain_sids; - char **trusted_dom_names; + struct lsa_DomainList dom_list; fstring pdc_name; - const char *dummy; - + /* trusting domains listing variables */ POLICY_HND domain_hnd; - char **trusting_dom_names; - uint32 *trusting_dom_rids; - + struct samr_SamArray *trusts = NULL; + /* * Listing trusted domains (stored in secrets.tdb, if local) */ @@ -6114,9 +6386,10 @@ static int rpc_trustdom_list(int argc, const char **argv) }; /* query info level 5 to obtain sid of a domain being queried */ - nt_status = rpccli_lsa_query_info_policy( - pipe_hnd, mem_ctx, &connect_hnd, 5 /* info level */, - &dummy, &queried_dom_sid); + nt_status = rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx, + &connect_hnd, + LSA_POLICY_INFO_ACCOUNT_DOMAIN, + &info); if (NT_STATUS_IS_ERR(nt_status)) { DEBUG(0, ("LSA Query Info failed. Returned error was %s\n", @@ -6125,7 +6398,9 @@ static int rpc_trustdom_list(int argc, const char **argv) talloc_destroy(mem_ctx); return -1; } - + + queried_dom_sid = info->account_domain.sid; + /* * Keep calling LsaEnumTrustdom over opened pipe until * the end of enumeration is reached @@ -6134,10 +6409,11 @@ static int rpc_trustdom_list(int argc, const char **argv) d_printf("Trusted domains list:\n\n"); do { - nt_status = rpccli_lsa_enum_trust_dom(pipe_hnd, mem_ctx, &connect_hnd, &enum_ctx, - &num_domains, - &trusted_dom_names, &domain_sids); - + nt_status = rpccli_lsa_EnumTrustDom(pipe_hnd, mem_ctx, + &connect_hnd, + &enum_ctx, + &dom_list, + (uint32_t)-1); if (NT_STATUS_IS_ERR(nt_status)) { DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n", nt_errstr(nt_status))); @@ -6145,16 +6421,17 @@ static int rpc_trustdom_list(int argc, const char **argv) talloc_destroy(mem_ctx); return -1; }; - - for (i = 0; i < num_domains; i++) { - print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]); + + for (i = 0; i < dom_list.count; i++) { + print_trusted_domain(dom_list.domains[i].sid, + dom_list.domains[i].name.string); }; - + /* * in case of no trusted domains say something rather * than just display blank line */ - if (!num_domains) d_printf("none\n"); + if (!dom_list.count) d_printf("none\n"); } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)); @@ -6186,10 +6463,12 @@ static int rpc_trustdom_list(int argc, const char **argv) talloc_destroy(mem_ctx); return -1; }; - - /* SamrConnect */ - nt_status = rpccli_samr_connect(pipe_hnd, mem_ctx, SA_RIGHT_SAM_OPEN_DOMAIN, - &connect_hnd); + + /* SamrConnect2 */ + nt_status = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + SA_RIGHT_SAM_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))); @@ -6197,12 +6476,14 @@ static int rpc_trustdom_list(int argc, const char **argv) talloc_destroy(mem_ctx); return -1; }; - + /* SamrOpenDomain - we have to open domain policy handle in order to be able to enumerate accounts*/ - nt_status = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_hnd, - SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, - queried_dom_sid, &domain_hnd); + nt_status = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_hnd, + SA_RIGHT_DOMAIN_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))); @@ -6217,11 +6498,14 @@ static int rpc_trustdom_list(int argc, const char **argv) enum_ctx = 0; /* reset enumeration context from last enumeration */ do { - - nt_status = rpccli_samr_enum_dom_users(pipe_hnd, mem_ctx, &domain_hnd, - &enum_ctx, ACB_DOMTRUST, 0xffff, - &trusting_dom_names, &trusting_dom_rids, - &num_domains); + + nt_status = rpccli_samr_EnumDomainUsers(pipe_hnd, mem_ctx, + &domain_hnd, + &enum_ctx, + ACB_DOMTRUST, + &trusts, + 0xffff, + &num_domains); if (NT_STATUS_IS_ERR(nt_status)) { DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n", nt_errstr(nt_status))); @@ -6229,9 +6513,11 @@ static int rpc_trustdom_list(int argc, const char **argv) talloc_destroy(mem_ctx); return -1; }; - + for (i = 0; i < num_domains; i++) { + char *str = CONST_DISCARD(char *, trusts->entries[i].name.string); + /* * get each single domain's sid (do we _really_ need this ?): * 1) connect to domain's pdc @@ -6239,22 +6525,22 @@ static int rpc_trustdom_list(int argc, const char **argv) */ /* get rid of '$' tail */ - ascii_dom_name_len = strlen(trusting_dom_names[i]); + ascii_dom_name_len = strlen(str); if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN) - trusting_dom_names[i][ascii_dom_name_len - 1] = '\0'; - + str[ascii_dom_name_len - 1] = '\0'; + /* calculate padding space for d_printf to look nicer */ - pad_len = col_len - strlen(trusting_dom_names[i]); + pad_len = col_len - strlen(str); padding[pad_len] = 0; do padding[--pad_len] = ' '; while (pad_len); /* set opt_* variables to remote domain */ - strupper_m(trusting_dom_names[i]); - opt_workgroup = talloc_strdup(mem_ctx, trusting_dom_names[i]); + strupper_m(str); + opt_workgroup = talloc_strdup(mem_ctx, str); opt_target_workgroup = opt_workgroup; - - d_printf("%s%s", trusting_dom_names[i], padding); - + + d_printf("%s%s", str, padding); + /* connect to remote domain controller */ nt_status = net_make_ipc_connection( NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS, @@ -6278,12 +6564,12 @@ static int rpc_trustdom_list(int argc, const char **argv) } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)); /* close opened samr and domain policy handles */ - nt_status = rpccli_samr_close(pipe_hnd, mem_ctx, &domain_hnd); + nt_status = rpccli_samr_Close(pipe_hnd, 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 = rpccli_samr_close(pipe_hnd, mem_ctx, &connect_hnd); + nt_status = rpccli_samr_Close(pipe_hnd, 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)); }; diff --git a/source3/utils/net_rpc_audit.c b/source3/utils/net_rpc_audit.c index 50bd555f16..a846395bb8 100644 --- a/source3/utils/net_rpc_audit.c +++ b/source3/utils/net_rpc_audit.c @@ -1,7 +1,7 @@ /* Samba Unix/Linux SMB client library Distributed SMB/CIFS Server Management Utility - Copyright (C) 2006 Guenther Deschner + Copyright (C) 2006,2008 Guenther Deschner 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 @@ -71,7 +71,7 @@ static NTSTATUS rpc_audit_get_internal(const DOM_SID *domain_sid, { POLICY_HND pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - union lsa_PolicyInformation info; + union lsa_PolicyInformation *info = NULL; int i; uint32_t audit_category; @@ -103,7 +103,7 @@ static NTSTATUS rpc_audit_get_internal(const DOM_SID *domain_sid, goto done; } - for (i=0; i < info.audit_events.count; i++) { + for (i=0; i < info->audit_events.count; i++) { const char *val = NULL, *policy = NULL; @@ -111,7 +111,7 @@ static NTSTATUS rpc_audit_get_internal(const DOM_SID *domain_sid, continue; } - val = audit_policy_str(mem_ctx, info.audit_events.settings[i]); + val = audit_policy_str(mem_ctx, info->audit_events.settings[i]); policy = audit_description_str(i); print_auditing_category(policy, val); } @@ -138,7 +138,7 @@ static NTSTATUS rpc_audit_set_internal(const DOM_SID *domain_sid, { POLICY_HND pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - union lsa_PolicyInformation info; + union lsa_PolicyInformation *info = NULL; uint32_t audit_policy, audit_category; if (argc < 2 || argc > 3) { @@ -184,12 +184,12 @@ static NTSTATUS rpc_audit_set_internal(const DOM_SID *domain_sid, goto done; } - info.audit_events.settings[audit_category] = audit_policy; + info->audit_events.settings[audit_category] = audit_policy; result = rpccli_lsa_SetInfoPolicy(pipe_hnd, mem_ctx, &pol, LSA_POLICY_INFO_AUDIT_EVENTS, - &info); + info); if (!NT_STATUS_IS_OK(result)) { goto done; @@ -200,7 +200,7 @@ static NTSTATUS rpc_audit_set_internal(const DOM_SID *domain_sid, LSA_POLICY_INFO_AUDIT_EVENTS, &info); { - const char *val = audit_policy_str(mem_ctx, info.audit_events.settings[audit_category]); + const char *val = audit_policy_str(mem_ctx, info->audit_events.settings[audit_category]); const char *policy = audit_description_str(audit_category); print_auditing_category(policy, val); } @@ -224,7 +224,7 @@ static NTSTATUS rpc_audit_enable_internal_ext(struct rpc_pipe_client *pipe_hnd, { POLICY_HND pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - union lsa_PolicyInformation info; + union lsa_PolicyInformation *info = NULL; result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true, SEC_RIGHTS_MAXIMUM_ALLOWED, @@ -242,12 +242,12 @@ static NTSTATUS rpc_audit_enable_internal_ext(struct rpc_pipe_client *pipe_hnd, goto done; } - info.audit_events.auditing_mode = enable; + info->audit_events.auditing_mode = enable; result = rpccli_lsa_SetInfoPolicy(pipe_hnd, mem_ctx, &pol, LSA_POLICY_INFO_AUDIT_EVENTS, - &info); + info); if (!NT_STATUS_IS_OK(result)) { goto done; @@ -305,7 +305,7 @@ static NTSTATUS rpc_audit_list_internal(const DOM_SID *domain_sid, { POLICY_HND pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - union lsa_PolicyInformation info; + union lsa_PolicyInformation *info = NULL; int i; result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true, @@ -325,7 +325,7 @@ static NTSTATUS rpc_audit_list_internal(const DOM_SID *domain_sid, } printf("Auditing:\t\t"); - switch (info.audit_events.auditing_mode) { + switch (info->audit_events.auditing_mode) { case true: printf("Enabled"); break; @@ -333,16 +333,16 @@ static NTSTATUS rpc_audit_list_internal(const DOM_SID *domain_sid, printf("Disabled"); break; default: - printf("unknown (%d)", info.audit_events.auditing_mode); + printf("unknown (%d)", info->audit_events.auditing_mode); break; } printf("\n"); - printf("Auditing categories:\t%d\n", info.audit_events.count); + printf("Auditing categories:\t%d\n", info->audit_events.count); printf("Auditing settings:\n"); - for (i=0; i < info.audit_events.count; i++) { - const char *val = audit_policy_str(mem_ctx, info.audit_events.settings[i]); + for (i=0; i < info->audit_events.count; i++) { + const char *val = audit_policy_str(mem_ctx, info->audit_events.settings[i]); const char *policy = audit_description_str(i); print_auditing_category(policy, val); } diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index 6e37f3c84c..8259ec46e6 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -3,6 +3,7 @@ Distributed SMB/CIFS Server Management Utility Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org) Copyright (C) Tim Potter 2001 + Copyright (C) 2008 Guenther Deschner 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 @@ -45,7 +46,7 @@ NTSTATUS net_rpc_join_ok(const char *domain, const char *server, { enum security_types sec; unsigned int conn_flags = NET_FLAGS_PDC; - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; + uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct cli_state *cli = NULL; struct rpc_pipe_client *pipe_hnd = NULL; struct rpc_pipe_client *netlogon_pipe = NULL; @@ -132,7 +133,7 @@ int net_rpc_join_newstyle(int argc, const char **argv) struct cli_state *cli; TALLOC_CTX *mem_ctx; uint32 acb_info = ACB_WSTRUST; - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|(lp_client_schannel() ? NETLOGON_NEG_SCHANNEL : 0); + uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|(lp_client_schannel() ? NETLOGON_NEG_SCHANNEL : 0); uint32 sec_channel_type; struct rpc_pipe_client *pipe_hnd = NULL; @@ -146,20 +147,21 @@ int net_rpc_join_newstyle(int argc, const char **argv) char *clear_trust_password = NULL; uchar pwbuf[516]; - SAM_USERINFO_CTR ctr; - SAM_USER_INFO_24 p24; - SAM_USER_INFO_16 p16; uchar md4_trust_password[16]; + union samr_UserInfo set_info; /* Misc */ NTSTATUS result; int retval = 1; const char *domain = NULL; - uint32 num_rids, *name_types, *user_rids; - uint32 flags = 0x3e8; char *acct_name; - const char *const_acct_name; + struct lsa_String lsa_acct_name; + uint32 acct_flags=0; + uint32_t access_granted = 0; + union lsa_PolicyInformation *info = NULL; + struct samr_Ids user_rids; + struct samr_Ids name_types; /* check what type of join */ if (argc >= 0) { @@ -209,10 +211,15 @@ int net_rpc_join_newstyle(int argc, const char **argv) &lsa_pol), "error opening lsa policy handle"); - CHECK_RPC_ERR(rpccli_lsa_query_info_policy(pipe_hnd, mem_ctx, &lsa_pol, - 5, &domain, &domain_sid), + CHECK_RPC_ERR(rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx, + &lsa_pol, + LSA_POLICY_INFO_ACCOUNT_DOMAIN, + &info), "error querying info policy"); + domain = info->account_domain.name.string; + domain_sid = info->account_domain.sid; + rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol); cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */ @@ -230,15 +237,18 @@ int net_rpc_join_newstyle(int argc, const char **argv) goto done; } - CHECK_RPC_ERR(rpccli_samr_connect(pipe_hnd, mem_ctx, - SEC_RIGHTS_MAXIMUM_ALLOWED, - &sam_pol), + CHECK_RPC_ERR(rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &sam_pol), "could not connect to SAM database"); - - CHECK_RPC_ERR(rpccli_samr_open_domain(pipe_hnd, mem_ctx, &sam_pol, - SEC_RIGHTS_MAXIMUM_ALLOWED, - domain_sid, &domain_pol), + + CHECK_RPC_ERR(rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &sam_pol, + SEC_RIGHTS_MAXIMUM_ALLOWED, + domain_sid, + &domain_pol), "could not open domain"); /* Create domain user */ @@ -247,12 +257,25 @@ int net_rpc_join_newstyle(int argc, const char **argv) goto done; } strlower_m(acct_name); - const_acct_name = acct_name; - result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol, - acct_name, acb_info, - 0xe005000b, &user_pol, - &user_rid); + init_lsa_String(&lsa_acct_name, acct_name); + + acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE | + SEC_STD_WRITE_DAC | SEC_STD_DELETE | + SAMR_USER_ACCESS_SET_PASSWORD | + SAMR_USER_ACCESS_GET_ATTRIBUTES | + SAMR_USER_ACCESS_SET_ATTRIBUTES; + + DEBUG(10, ("Creating account with flags: %d\n",acct_flags)); + + result = rpccli_samr_CreateUser2(pipe_hnd, mem_ctx, + &domain_pol, + &lsa_acct_name, + acb_info, + acct_flags, + &user_pol, + &access_granted, + &user_rid); if (!NT_STATUS_IS_OK(result) && !NT_STATUS_EQUAL(result, NT_STATUS_USER_EXISTS)) { @@ -271,30 +294,33 @@ int net_rpc_join_newstyle(int argc, const char **argv) /* We *must* do this.... don't ask... */ if (NT_STATUS_IS_OK(result)) { - rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol); + rpccli_samr_Close(pipe_hnd, mem_ctx, &user_pol); } - CHECK_RPC_ERR_DEBUG(rpccli_samr_lookup_names(pipe_hnd, mem_ctx, - &domain_pol, flags, - 1, &const_acct_name, - &num_rids, - &user_rids, &name_types), + CHECK_RPC_ERR_DEBUG(rpccli_samr_LookupNames(pipe_hnd, mem_ctx, + &domain_pol, + 1, + &lsa_acct_name, + &user_rids, + &name_types), ("error looking up rid for user %s: %s\n", acct_name, nt_errstr(result))); - if (name_types[0] != SID_NAME_USER) { - DEBUG(0, ("%s is not a user account (type=%d)\n", acct_name, name_types[0])); + if (name_types.ids[0] != SID_NAME_USER) { + DEBUG(0, ("%s is not a user account (type=%d)\n", acct_name, name_types.ids[0])); goto done; } - user_rid = user_rids[0]; - + user_rid = user_rids.ids[0]; + /* Open handle on user */ CHECK_RPC_ERR_DEBUG( - rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol, - SEC_RIGHTS_MAXIMUM_ALLOWED, - user_rid, &user_pol), + rpccli_samr_OpenUser(pipe_hnd, mem_ctx, + &domain_pol, + SEC_RIGHTS_MAXIMUM_ALLOWED, + user_rid, + &user_pol), ("could not re-open existing user %s: %s\n", acct_name, nt_errstr(result))); @@ -311,16 +337,15 @@ int net_rpc_join_newstyle(int argc, const char **argv) /* Set password on machine account */ - ZERO_STRUCT(ctr); - ZERO_STRUCT(p24); + init_samr_user_info24(&set_info.info24, pwbuf, 24); - init_sam_user_info24(&p24, (char *)pwbuf,24); + SamOEMhashBlob(set_info.info24.password.data, 516, + &cli->user_session_key); - ctr.switch_value = 24; - ctr.info.id24 = &p24; - - CHECK_RPC_ERR(rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24, - &cli->user_session_key, &ctr), + CHECK_RPC_ERR(rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx, + &user_pol, + 24, + &set_info), "error setting trust account password"); /* Why do we have to try to (re-)set the ACB to be the same as what @@ -332,19 +357,17 @@ int net_rpc_join_newstyle(int argc, const char **argv) seems to cope with either value so don't bomb out if the set userinfo2 level 0x10 fails. -tpot */ - ZERO_STRUCT(ctr); - ctr.switch_value = 16; - ctr.info.id16 = &p16; - - init_sam_user_info16(&p16, acb_info); + set_info.info16.acct_flags = acb_info; /* Ignoring the return value is necessary for joining a domain as a normal user with "Add workstation to domain" privilege. */ - result = rpccli_samr_set_userinfo2(pipe_hnd, mem_ctx, &user_pol, 16, - &cli->user_session_key, &ctr); + result = rpccli_samr_SetUserInfo(pipe_hnd, mem_ctx, + &user_pol, + 16, + &set_info); - rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol); + rpccli_samr_Close(pipe_hnd, mem_ctx, &user_pol); cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */ /* Now check the whole process from top-to-bottom */ diff --git a/source3/utils/net_rpc_rights.c b/source3/utils/net_rpc_rights.c index 5f222b8c7e..7857dbcbaf 100644 --- a/source3/utils/net_rpc_rights.c +++ b/source3/utils/net_rpc_rights.c @@ -2,6 +2,7 @@ Samba Unix/Linux SMB client library Distributed SMB/CIFS Server Management Utility Copyright (C) Gerald (Jerry) Carter 2004 + Copyright (C) Guenther Deschner 2008 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 @@ -94,37 +95,49 @@ static NTSTATUS enum_privileges(struct rpc_pipe_client *pipe_hnd, NTSTATUS result; uint32 enum_context = 0; uint32 pref_max_length=0x1000; - uint32 count=0; - char **privs_name; - uint32 *privs_high; - uint32 *privs_low; int i; uint16 lang_id=0; uint16 lang_id_sys=0; uint16 lang_id_desc; - fstring description; + struct lsa_StringLarge *description = NULL; + struct lsa_PrivArray priv_array; - result = rpccli_lsa_enum_privilege(pipe_hnd, ctx, pol, &enum_context, - pref_max_length, &count, &privs_name, &privs_high, &privs_low); + result = rpccli_lsa_EnumPrivs(pipe_hnd, ctx, + pol, + &enum_context, + &priv_array, + pref_max_length); if ( !NT_STATUS_IS_OK(result) ) return result; /* Print results */ - - for (i = 0; i < count; i++) { - d_printf("%30s ", privs_name[i] ? privs_name[i] : "*unknown*" ); - + + for (i = 0; i < priv_array.count; i++) { + + struct lsa_String lsa_name; + + d_printf("%30s ", + priv_array.privs[i].name.string ? priv_array.privs[i].name.string : "*unknown*" ); + /* try to get the description */ - - if ( !NT_STATUS_IS_OK(rpccli_lsa_get_dispname(pipe_hnd, ctx, pol, - privs_name[i], lang_id, lang_id_sys, description, &lang_id_desc)) ) - { + + init_lsa_String(&lsa_name, priv_array.privs[i].name.string); + + result = rpccli_lsa_LookupPrivDisplayName(pipe_hnd, ctx, + pol, + &lsa_name, + lang_id, + lang_id_sys, + &description, + &lang_id_desc); + + if (!NT_STATUS_IS_OK(result)) { d_printf("??????\n"); continue; } - - d_printf("%s\n", description ); + + d_printf("%s\n", description->string); } return NT_STATUS_OK; @@ -140,22 +153,24 @@ static NTSTATUS check_privilege_for_user(struct rpc_pipe_client *pipe_hnd, const char *right) { NTSTATUS result; - uint32 count; - char **rights; + struct lsa_RightSet rights; int i; - result = rpccli_lsa_enum_account_rights(pipe_hnd, ctx, pol, sid, &count, &rights); + result = rpccli_lsa_EnumAccountRights(pipe_hnd, ctx, + pol, + sid, + &rights); if (!NT_STATUS_IS_OK(result)) { return result; } - if (count == 0) { + if (rights.count == 0) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - - for (i = 0; i < count; i++) { - if (StrCaseCmp(rights[i], right) == 0) { + + for (i = 0; i < rights.count; i++) { + if (StrCaseCmp(rights.names[i].string, right) == 0) { return NT_STATUS_OK; } } @@ -172,20 +187,23 @@ static NTSTATUS enum_privileges_for_user(struct rpc_pipe_client *pipe_hnd, DOM_SID *sid ) { NTSTATUS result; - uint32 count; - char **rights; + struct lsa_RightSet rights; int i; - result = rpccli_lsa_enum_account_rights(pipe_hnd, ctx, pol, sid, &count, &rights); + result = rpccli_lsa_EnumAccountRights(pipe_hnd, ctx, + pol, + sid, + &rights); if (!NT_STATUS_IS_OK(result)) return result; - if ( count == 0 ) + if (rights.count == 0) { d_printf("No privileges assigned\n"); - - for (i = 0; i < count; i++) { - printf("%s\n", rights[i]); + } + + for (i = 0; i < rights.count; i++) { + printf("%s\n", rights.names[i].string); } return NT_STATUS_OK; @@ -202,24 +220,27 @@ static NTSTATUS enum_accounts_for_privilege(struct rpc_pipe_client *pipe_hnd, NTSTATUS result; uint32 enum_context=0; uint32 pref_max_length=0x1000; - DOM_SID *sids = NULL; - uint32 count=0; + struct lsa_SidArray sid_array; int i; fstring name; - result = rpccli_lsa_enum_sids(pipe_hnd, ctx, pol, &enum_context, - pref_max_length, &count, &sids); + result = rpccli_lsa_EnumAccounts(pipe_hnd, ctx, + pol, + &enum_context, + &sid_array, + pref_max_length); if (!NT_STATUS_IS_OK(result)) return result; d_printf("%s:\n", privilege); - for ( i=0; i<count; i++ ) { - - - result = check_privilege_for_user( pipe_hnd, ctx, pol, &sids[i], privilege); - + for ( i=0; i<sid_array.num_sids; i++ ) { + + result = check_privilege_for_user(pipe_hnd, ctx, pol, + sid_array.sids[i].sid, + privilege); + if ( ! NT_STATUS_IS_OK(result)) { if ( ! NT_STATUS_EQUAL(result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { return result; @@ -229,9 +250,9 @@ static NTSTATUS enum_accounts_for_privilege(struct rpc_pipe_client *pipe_hnd, /* try to convert the SID to a name. Fall back to printing the raw SID if necessary */ - result = sid_to_name( pipe_hnd, ctx, &sids[i], name ); + result = sid_to_name( pipe_hnd, ctx, sid_array.sids[i].sid, name ); if ( !NT_STATUS_IS_OK (result) ) - sid_to_fstring(name, &sids[i]); + sid_to_fstring(name, sid_array.sids[i].sid); d_printf(" %s\n", name); } @@ -249,30 +270,32 @@ static NTSTATUS enum_privileges_for_accounts(struct rpc_pipe_client *pipe_hnd, NTSTATUS result; uint32 enum_context=0; uint32 pref_max_length=0x1000; - DOM_SID *sids; - uint32 count=0; + struct lsa_SidArray sid_array; int i; fstring name; - result = rpccli_lsa_enum_sids(pipe_hnd, ctx, pol, &enum_context, - pref_max_length, &count, &sids); + result = rpccli_lsa_EnumAccounts(pipe_hnd, ctx, + pol, + &enum_context, + &sid_array, + pref_max_length); if (!NT_STATUS_IS_OK(result)) return result; - - for ( i=0; i<count; i++ ) { - + + for ( i=0; i<sid_array.num_sids; i++ ) { + /* try to convert the SID to a name. Fall back to printing the raw SID if necessary */ - - result = sid_to_name(pipe_hnd, ctx, &sids[i], name ); + + result = sid_to_name(pipe_hnd, ctx, sid_array.sids[i].sid, name); if ( !NT_STATUS_IS_OK (result) ) - sid_to_fstring(name, &sids[i]); - + sid_to_fstring(name, sid_array.sids[i].sid); + d_printf("%s\n", name); - - result = enum_privileges_for_user(pipe_hnd, ctx, pol, &sids[i] ); - + + result = enum_privileges_for_user(pipe_hnd, ctx, pol, + sid_array.sids[i].sid); if ( !NT_STATUS_IS_OK(result) ) return result; @@ -297,7 +320,8 @@ static NTSTATUS rpc_rights_list_internal(const DOM_SID *domain_sid, NTSTATUS result; DOM_SID sid; fstring privname; - fstring description; + struct lsa_String lsa_name; + struct lsa_StringLarge *description = NULL; uint16 lang_id = 0; uint16 lang_id_sys = 0; uint16 lang_id_desc; @@ -325,14 +349,19 @@ static NTSTATUS rpc_rights_list_internal(const DOM_SID *domain_sid, } while ( argv[i] != NULL ) { - fstrcpy( privname, argv[i] ); + fstrcpy(privname, argv[i]); + init_lsa_String(&lsa_name, argv[i]); i++; /* verify that this is a valid privilege for error reporting */ - - result = rpccli_lsa_get_dispname(pipe_hnd, mem_ctx, &pol, privname, lang_id, - lang_id_sys, description, &lang_id_desc); - + result = rpccli_lsa_LookupPrivDisplayName(pipe_hnd, mem_ctx, + &pol, + &lsa_name, + lang_id, + lang_id_sys, + &description, + &lang_id_desc); + if ( !NT_STATUS_IS_OK(result) ) { if ( NT_STATUS_EQUAL( result, NT_STATUS_NO_SUCH_PRIVILEGE ) ) d_fprintf(stderr, "No such privilege exists: %s.\n", privname); @@ -408,6 +437,8 @@ static NTSTATUS rpc_rights_grant_internal(const DOM_SID *domain_sid, { POLICY_HND dom_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + struct lsa_RightSet rights; + int i; DOM_SID sid; @@ -427,8 +458,21 @@ static NTSTATUS rpc_rights_grant_internal(const DOM_SID *domain_sid, if (!NT_STATUS_IS_OK(result)) return result; - result = rpccli_lsa_add_account_rights(pipe_hnd, mem_ctx, &dom_pol, sid, - argc-1, argv+1); + rights.count = argc-1; + rights.names = TALLOC_ARRAY(mem_ctx, struct lsa_StringLarge, + rights.count); + if (!rights.names) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i<argc-1; i++) { + init_lsa_StringLarge(&rights.names[i], argv[i+1]); + } + + result = rpccli_lsa_AddAccountRights(pipe_hnd, mem_ctx, + &dom_pol, + &sid, + &rights); if (!NT_STATUS_IS_OK(result)) goto done; @@ -459,8 +503,9 @@ static NTSTATUS rpc_rights_revoke_internal(const DOM_SID *domain_sid, { POLICY_HND dom_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - + struct lsa_RightSet rights; DOM_SID sid; + int i; if (argc < 2 ) { d_printf("Usage: net rpc rights revoke <name|SID> <rights...>\n"); @@ -478,8 +523,22 @@ static NTSTATUS rpc_rights_revoke_internal(const DOM_SID *domain_sid, if (!NT_STATUS_IS_OK(result)) return result; - result = rpccli_lsa_remove_account_rights(pipe_hnd, mem_ctx, &dom_pol, sid, - False, argc-1, argv+1); + rights.count = argc-1; + rights.names = TALLOC_ARRAY(mem_ctx, struct lsa_StringLarge, + rights.count); + if (!rights.names) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i<argc-1; i++) { + init_lsa_StringLarge(&rights.names[i], argv[i+1]); + } + + result = rpccli_lsa_RemoveAccountRights(pipe_hnd, mem_ctx, + &dom_pol, + &sid, + false, + &rights); if (!NT_STATUS_IS_OK(result)) goto done; diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index 779006884d..775270a69b 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. dump the remote SAM using rpc samsync operations @@ -7,17 +7,18 @@ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005 Modified by Volker Lendecke 2002 Copyright (C) Jeremy Allison 2005. + Copyright (C) Guenther Deschner 2008. 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 3 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, see <http://www.gnu.org/licenses/>. */ @@ -31,57 +32,62 @@ static uint32 ldif_uid = 999; /* Keep track of ldap initialization */ static int init_ldap = 1; -static void display_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *g) +static void display_group_mem_info(uint32_t rid, + struct netr_DELTA_GROUP_MEMBER *r) { int i; d_printf("Group mem %u: ", rid); - for (i=0;i<g->num_members;i++) { - d_printf("%u ", g->rids[i]); + for (i=0; i< r->num_rids; i++) { + d_printf("%u ", r->rids[i]); } d_printf("\n"); } -static void display_alias_info(uint32 rid, SAM_ALIAS_INFO *a) +static void display_alias_info(uint32_t rid, + struct netr_DELTA_ALIAS *r) { - 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); + d_printf("Alias '%s' ", r->alias_name.string); + d_printf("desc='%s' rid=%u\n", r->description.string, r->rid); } -static void display_alias_mem(uint32 rid, SAM_ALIAS_MEM_INFO *a) +static void display_alias_mem(uint32_t rid, + struct netr_DELTA_ALIAS_MEMBER *r) { int i; d_printf("Alias rid %u: ", rid); - for (i=0;i<a->num_members;i++) { - d_printf("%s ", sid_string_tos(&a->sids[i].sid)); + for (i=0; i< r->sids.num_sids; i++) { + d_printf("%s ", sid_string_tos(r->sids.sids[i].sid)); } d_printf("\n"); } -static void display_account_info(uint32 rid, SAM_ACCOUNT_INFO *a) +static void display_account_info(uint32_t rid, + struct netr_DELTA_USER *r) { fstring hex_nt_passwd, hex_lm_passwd; uchar lm_passwd[16], nt_passwd[16]; static uchar zero_buf[16]; /* Decode hashes from password hash (if they are not NULL) */ - - if (memcmp(a->pass.buf_lm_pwd, zero_buf, 16) != 0) { - sam_pwd_hash(a->user_rid, a->pass.buf_lm_pwd, lm_passwd, 0); - pdb_sethexpwd(hex_lm_passwd, lm_passwd, a->acb_info); + + if (memcmp(r->lmpassword.hash, zero_buf, 16) != 0) { + sam_pwd_hash(r->rid, r->lmpassword.hash, lm_passwd, 0); + pdb_sethexpwd(hex_lm_passwd, lm_passwd, r->acct_flags); } else { pdb_sethexpwd(hex_lm_passwd, NULL, 0); } - if (memcmp(a->pass.buf_nt_pwd, zero_buf, 16) != 0) { - sam_pwd_hash(a->user_rid, a->pass.buf_nt_pwd, nt_passwd, 0); - pdb_sethexpwd(hex_nt_passwd, nt_passwd, a->acb_info); + if (memcmp(r->ntpassword.hash, zero_buf, 16) != 0) { + sam_pwd_hash(r->rid, r->ntpassword.hash, nt_passwd, 0); + pdb_sethexpwd(hex_nt_passwd, nt_passwd, r->acct_flags); } else { pdb_sethexpwd(hex_nt_passwd, NULL, 0); } - - printf("%s:%d:%s:%s:%s:LCT-0\n", unistr2_static(&a->uni_acct_name), - a->user_rid, hex_lm_passwd, hex_nt_passwd, - pdb_encode_acct_ctrl(a->acb_info, NEW_PW_FORMAT_SPACE_PADDED_LEN)); + + printf("%s:%d:%s:%s:%s:LCT-0\n", + r->account_name.string, + r->rid, hex_lm_passwd, hex_nt_passwd, + pdb_encode_acct_ctrl(r->acct_flags, NEW_PW_FORMAT_SPACE_PADDED_LEN)); } static time_t uint64s_nt_time_to_unix_abs(const uint64 *src) @@ -91,102 +97,201 @@ static time_t uint64s_nt_time_to_unix_abs(const uint64 *src) return nt_time_to_unix_abs(&nttime); } -static void display_domain_info(SAM_DOMAIN_INFO *a) +static void display_domain_info(struct netr_DELTA_DOMAIN *r) { time_t u_logout; - u_logout = uint64s_nt_time_to_unix_abs(&a->force_logoff); + u_logout = uint64s_nt_time_to_unix_abs((const uint64 *)&r->force_logoff_time); - d_printf("Domain name: %s\n", unistr2_static(&a->uni_dom_name)); + d_printf("Domain name: %s\n", r->domain_name.string); - d_printf("Minimal Password Length: %d\n", a->min_pwd_len); - d_printf("Password History Length: %d\n", a->pwd_history_len); + d_printf("Minimal Password Length: %d\n", r->min_password_length); + d_printf("Password History Length: %d\n", r->password_history_length); d_printf("Force Logoff: %d\n", (int)u_logout); - d_printf("Max Password Age: %s\n", display_time(a->max_pwd_age)); - d_printf("Min Password Age: %s\n", display_time(a->min_pwd_age)); + d_printf("Max Password Age: %s\n", display_time(r->max_password_age)); + d_printf("Min Password Age: %s\n", display_time(r->min_password_age)); +#if 0 + /* FIXME - gd */ d_printf("Lockout Time: %s\n", display_time(a->account_lockout.lockout_duration)); d_printf("Lockout Reset Time: %s\n", display_time(a->account_lockout.reset_count)); - d_printf("Bad Attempt Lockout: %d\n", a->account_lockout.bad_attempt_lockout); - d_printf("User must logon to change password: %d\n", a->logon_chgpass); +#endif + d_printf("User must logon to change password: %d\n", r->logon_to_chgpass); } -static void display_group_info(uint32 rid, SAM_GROUP_INFO *a) +static void display_group_info(uint32_t rid, struct netr_DELTA_GROUP *r) { - d_printf("Group '%s' ", unistr2_static(&a->uni_grp_name)); - d_printf("desc='%s', rid=%u\n", unistr2_static(&a->uni_grp_desc), rid); + d_printf("Group '%s' ", r->group_name.string); + d_printf("desc='%s', rid=%u\n", r->description.string, rid); } -static void display_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta) +static void display_sam_entry(struct netr_DELTA_ENUM *r) { - switch (hdr_delta->type) { - case SAM_DELTA_ACCOUNT_INFO: - display_account_info(hdr_delta->target_rid, &delta->account_info); + union netr_DELTA_UNION u = r->delta_union; + union netr_DELTA_ID_UNION id = r->delta_id_union; + + switch (r->delta_type) { + case NETR_DELTA_DOMAIN: + display_domain_info(u.domain); + break; + case NETR_DELTA_GROUP: + display_group_info(id.rid, u.group); + break; +#if 0 + case NETR_DELTA_DELETE_GROUP: + printf("Delete Group: %d\n", + u.delete_account.unknown); + break; + case NETR_DELTA_RENAME_GROUP: + printf("Rename Group: %s -> %s\n", + u.rename_group->OldName.string, + u.rename_group->NewName.string); break; - case SAM_DELTA_GROUP_MEM: - display_group_mem_info(hdr_delta->target_rid, &delta->grp_mem_info); +#endif + case NETR_DELTA_USER: + display_account_info(id.rid, u.user); break; - case SAM_DELTA_ALIAS_INFO: - display_alias_info(hdr_delta->target_rid, &delta->alias_info); +#if 0 + case NETR_DELTA_DELETE_USER: + printf("Delete User: %d\n", + id.rid); break; - case SAM_DELTA_ALIAS_MEM: - display_alias_mem(hdr_delta->target_rid, &delta->als_mem_info); + case NETR_DELTA_RENAME_USER: + printf("Rename user: %s -> %s\n", + u.rename_user->OldName.string, + u.rename_user->NewName.string); break; - case SAM_DELTA_DOMAIN_INFO: - display_domain_info(&delta->domain_info); +#endif + case NETR_DELTA_GROUP_MEMBER: + display_group_mem_info(id.rid, u.group_member); break; - case SAM_DELTA_GROUP_INFO: - display_group_info(hdr_delta->target_rid, &delta->group_info); + case NETR_DELTA_ALIAS: + display_alias_info(id.rid, u.alias); break; - /* The following types are recognised but not handled */ - case SAM_DELTA_RENAME_GROUP: - d_printf("SAM_DELTA_RENAME_GROUP not handled\n"); +#if 0 + case NETR_DELTA_DELETE_ALIAS: + printf("Delete Alias: %d\n", + id.rid); break; - case SAM_DELTA_RENAME_USER: - d_printf("SAM_DELTA_RENAME_USER not handled\n"); + case NETR_DELTA_RENAME_ALIAS: + printf("Rename alias: %s -> %s\n", + u.rename_alias->OldName.string, + u.rename_alias->NewName.string); break; - case SAM_DELTA_RENAME_ALIAS: - d_printf("SAM_DELTA_RENAME_ALIAS not handled\n"); +#endif + case NETR_DELTA_ALIAS_MEMBER: + display_alias_mem(id.rid, u.alias_member); + break; +#if 0 + case NETR_DELTA_POLICY: + printf("Policy\n"); break; - case SAM_DELTA_POLICY_INFO: - d_printf("SAM_DELTA_POLICY_INFO not handled\n"); + case NETR_DELTA_TRUSTED_DOMAIN: + printf("Trusted Domain: %s\n", + u.trusted_domain->domain_name.string); break; - case SAM_DELTA_TRUST_DOMS: - d_printf("SAM_DELTA_TRUST_DOMS not handled\n"); + case NETR_DELTA_DELETE_TRUST: + printf("Delete Trust: %d\n", + u.delete_trust.unknown); break; - case SAM_DELTA_PRIVS_INFO: - d_printf("SAM_DELTA_PRIVS_INFO not handled\n"); + case NETR_DELTA_ACCOUNT: + printf("Account\n"); break; - case SAM_DELTA_SECRET_INFO: - d_printf("SAM_DELTA_SECRET_INFO not handled\n"); + case NETR_DELTA_DELETE_ACCOUNT: + printf("Delete Account: %d\n", + u.delete_account.unknown); break; - case SAM_DELTA_DELETE_GROUP: - d_printf("SAM_DELTA_DELETE_GROUP not handled\n"); + case NETR_DELTA_SECRET: + printf("Secret\n"); break; - case SAM_DELTA_DELETE_USER: - d_printf("SAM_DELTA_DELETE_USER not handled\n"); + case NETR_DELTA_DELETE_SECRET: + printf("Delete Secret: %d\n", + u.delete_secret.unknown); + break; + case NETR_DELTA_DELETE_GROUP2: + printf("Delete Group2: %s\n", + u.delete_group->account_name); + break; + case NETR_DELTA_DELETE_USER2: + printf("Delete User2: %s\n", + u.delete_user->account_name); + break; + case NETR_DELTA_MODIFY_COUNT: + printf("sam sequence update: 0x%016llx\n", + (unsigned long long) *u.modified_count); + break; +#endif + /* The following types are recognised but not handled */ + case NETR_DELTA_RENAME_GROUP: + d_printf("NETR_DELTA_RENAME_GROUP not handled\n"); break; - case SAM_DELTA_MODIFIED_COUNT: - d_printf("SAM_DELTA_MODIFIED_COUNT not handled\n"); + case NETR_DELTA_RENAME_USER: + d_printf("NETR_DELTA_RENAME_USER not handled\n"); + break; + case NETR_DELTA_RENAME_ALIAS: + d_printf("NETR_DELTA_RENAME_ALIAS not handled\n"); + break; + case NETR_DELTA_POLICY: + d_printf("NETR_DELTA_POLICY not handled\n"); + break; + case NETR_DELTA_TRUSTED_DOMAIN: + d_printf("NETR_DELTA_TRUSTED_DOMAIN not handled\n"); + break; + case NETR_DELTA_ACCOUNT: + d_printf("NETR_DELTA_ACCOUNT not handled\n"); + break; + case NETR_DELTA_SECRET: + d_printf("NETR_DELTA_SECRET not handled\n"); + break; + case NETR_DELTA_DELETE_GROUP: + d_printf("NETR_DELTA_DELETE_GROUP not handled\n"); + break; + case NETR_DELTA_DELETE_USER: + d_printf("NETR_DELTA_DELETE_USER not handled\n"); + break; + case NETR_DELTA_MODIFY_COUNT: + d_printf("NETR_DELTA_MODIFY_COUNT not handled\n"); + break; + case NETR_DELTA_DELETE_ALIAS: + d_printf("NETR_DELTA_DELETE_ALIAS not handled\n"); + break; + case NETR_DELTA_DELETE_TRUST: + d_printf("NETR_DELTA_DELETE_TRUST not handled\n"); + break; + case NETR_DELTA_DELETE_ACCOUNT: + d_printf("NETR_DELTA_DELETE_ACCOUNT not handled\n"); + break; + case NETR_DELTA_DELETE_SECRET: + d_printf("NETR_DELTA_DELETE_SECRET not handled\n"); + break; + case NETR_DELTA_DELETE_GROUP2: + d_printf("NETR_DELTA_DELETE_GROUP2 not handled\n"); + break; + case NETR_DELTA_DELETE_USER2: + d_printf("NETR_DELTA_DELETE_USER2 not handled\n"); break; default: - d_printf("Unknown delta record type %d\n", hdr_delta->type); + printf("unknown delta type 0x%02x\n", + r->delta_type); break; } } static void dump_database(struct rpc_pipe_client *pipe_hnd, uint32 db_type) { - uint32 sync_context = 0; NTSTATUS result; int i; TALLOC_CTX *mem_ctx; - SAM_DELTA_HDR *hdr_deltas; - SAM_DELTA_CTR *deltas; - uint32 num_deltas; + const char *logon_server = pipe_hnd->cli->desthost; + const char *computername = global_myname(); + struct netr_Authenticator credential; + struct netr_Authenticator return_authenticator; + enum netr_SamDatabaseID database_id = db_type; + uint16_t restart_state = 0; + uint32_t sync_context = 0; if (!(mem_ctx = talloc_init("dump_database"))) { return; @@ -208,36 +313,59 @@ static void dump_database(struct rpc_pipe_client *pipe_hnd, uint32 db_type) } do { - result = rpccli_netlogon_sam_sync(pipe_hnd, mem_ctx, db_type, - sync_context, - &num_deltas, &hdr_deltas, &deltas); - if (!NT_STATUS_IS_OK(result)) + struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL; + + netlogon_creds_client_step(pipe_hnd->dc, &credential); + + result = rpccli_netr_DatabaseSync2(pipe_hnd, mem_ctx, + logon_server, + computername, + &credential, + &return_authenticator, + database_id, + restart_state, + &sync_context, + &delta_enum_array, + 0xffff); + + /* Check returned credentials. */ + if (!netlogon_creds_client_check(pipe_hnd->dc, + &return_authenticator.cred)) { + DEBUG(0,("credentials chain check failed\n")); + return; + } + + if (NT_STATUS_IS_ERR(result)) { break; + } - for (i = 0; i < num_deltas; i++) { - display_sam_entry(&hdr_deltas[i], &deltas[i]); + /* Display results */ + for (i = 0; i < delta_enum_array->num_deltas; i++) { + display_sam_entry(&delta_enum_array->delta_enum[i]); } - sync_context += 1; + + TALLOC_FREE(delta_enum_array); + } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); talloc_destroy(mem_ctx); } /* dump sam database via samsync rpc calls */ -NTSTATUS rpc_samdump_internals(const DOM_SID *domain_sid, - const char *domain_name, +NTSTATUS rpc_samdump_internals(const DOM_SID *domain_sid, + const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, int argc, - const char **argv) + const char **argv) { #if 0 /* net_rpc.c now always tries to create an schannel pipe.. */ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; uchar trust_password[16]; - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS; + uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS; uint32 sec_channel_type = 0; if (!secrets_fetch_trust_account_password(domain_name, @@ -277,7 +405,8 @@ NTSTATUS rpc_samdump_internals(const DOM_SID *domain_sid, (!(s1) && (s2)) ||\ ((s1) && (s2) && (strcmp((s1), (s2)) != 0)) -static NTSTATUS sam_account_from_delta(struct samu *account, SAM_ACCOUNT_INFO *delta) +static NTSTATUS sam_account_from_delta(struct samu *account, + struct netr_DELTA_USER *r) { const char *old_string, *new_string; time_t unix_time, stored_time; @@ -287,15 +416,14 @@ static NTSTATUS sam_account_from_delta(struct samu *account, SAM_ACCOUNT_INFO *d /* Username, fullname, home dir, dir drive, logon script, acct desc, workstations, profile. */ - if (delta->hdr_acct_name.buffer) { + if (r->account_name.string) { old_string = pdb_get_nt_username(account); - new_string = unistr2_static(&delta->uni_acct_name); + new_string = r->account_name.string; if (STRING_CHANGED) { pdb_set_nt_username(account, new_string, PDB_CHANGED); - } - + /* Unix username is the same - for sanity */ old_string = pdb_get_username( account ); if (STRING_CHANGED) { @@ -303,69 +431,70 @@ static NTSTATUS sam_account_from_delta(struct samu *account, SAM_ACCOUNT_INFO *d } } - if (delta->hdr_full_name.buffer) { + if (r->full_name.string) { old_string = pdb_get_fullname(account); - new_string = unistr2_static(&delta->uni_full_name); + new_string = r->full_name.string; if (STRING_CHANGED) pdb_set_fullname(account, new_string, PDB_CHANGED); } - if (delta->hdr_home_dir.buffer) { + if (r->home_directory.string) { old_string = pdb_get_homedir(account); - new_string = unistr2_static(&delta->uni_home_dir); + new_string = r->home_directory.string; if (STRING_CHANGED) pdb_set_homedir(account, new_string, PDB_CHANGED); } - if (delta->hdr_dir_drive.buffer) { + if (r->home_drive.string) { old_string = pdb_get_dir_drive(account); - new_string = unistr2_static(&delta->uni_dir_drive); + new_string = r->home_drive.string; if (STRING_CHANGED) pdb_set_dir_drive(account, new_string, PDB_CHANGED); } - if (delta->hdr_logon_script.buffer) { + if (r->logon_script.string) { old_string = pdb_get_logon_script(account); - new_string = unistr2_static(&delta->uni_logon_script); + new_string = r->logon_script.string; if (STRING_CHANGED) pdb_set_logon_script(account, new_string, PDB_CHANGED); } - if (delta->hdr_acct_desc.buffer) { + if (r->description.string) { old_string = pdb_get_acct_desc(account); - new_string = unistr2_static(&delta->uni_acct_desc); + new_string = r->description.string; if (STRING_CHANGED) pdb_set_acct_desc(account, new_string, PDB_CHANGED); } - if (delta->hdr_workstations.buffer) { + if (r->workstations.string) { old_string = pdb_get_workstations(account); - new_string = unistr2_static(&delta->uni_workstations); + new_string = r->workstations.string; if (STRING_CHANGED) pdb_set_workstations(account, new_string, PDB_CHANGED); } - if (delta->hdr_profile.buffer) { + if (r->profile_path.string) { old_string = pdb_get_profile_path(account); - new_string = unistr2_static(&delta->uni_profile); + new_string = r->profile_path.string; if (STRING_CHANGED) pdb_set_profile_path(account, new_string, PDB_CHANGED); } - if (delta->hdr_parameters.buffer) { + if (r->parameters.string) { DATA_BLOB mung; char *newstr; old_string = pdb_get_munged_dial(account); - mung.length = delta->hdr_parameters.uni_str_len; - mung.data = (uint8 *) delta->uni_parameters.buffer; - newstr = (mung.length == 0) ? NULL : base64_encode_data_blob(mung); + mung.length = r->parameters.length; + mung.data = (uint8 *) r->parameters.string; + newstr = (mung.length == 0) ? NULL : + base64_encode_data_blob(talloc_tos(), mung); if (STRING_CHANGED_NC(old_string, newstr)) pdb_set_munged_dial(account, newstr, PDB_CHANGED); @@ -373,57 +502,59 @@ static NTSTATUS sam_account_from_delta(struct samu *account, SAM_ACCOUNT_INFO *d } /* User and group sid */ - if (pdb_get_user_rid(account) != delta->user_rid) - pdb_set_user_sid_from_rid(account, delta->user_rid, PDB_CHANGED); - if (pdb_get_group_rid(account) != delta->group_rid) - pdb_set_group_sid_from_rid(account, delta->group_rid, PDB_CHANGED); + if (pdb_get_user_rid(account) != r->rid) + pdb_set_user_sid_from_rid(account, r->rid, PDB_CHANGED); + if (pdb_get_group_rid(account) != r->primary_gid) + pdb_set_group_sid_from_rid(account, r->primary_gid, PDB_CHANGED); /* Logon and password information */ - if (!nt_time_is_zero(&delta->logon_time)) { - unix_time = nt_time_to_unix(delta->logon_time); + if (!nt_time_is_zero(&r->last_logon)) { + unix_time = nt_time_to_unix(r->last_logon); stored_time = pdb_get_logon_time(account); if (stored_time != unix_time) pdb_set_logon_time(account, unix_time, PDB_CHANGED); } - if (!nt_time_is_zero(&delta->logoff_time)) { - unix_time = nt_time_to_unix(delta->logoff_time); + if (!nt_time_is_zero(&r->last_logoff)) { + unix_time = nt_time_to_unix(r->last_logoff); stored_time = pdb_get_logoff_time(account); if (stored_time != unix_time) pdb_set_logoff_time(account, unix_time,PDB_CHANGED); } /* Logon Divs */ - if (pdb_get_logon_divs(account) != delta->logon_divs) - pdb_set_logon_divs(account, delta->logon_divs, PDB_CHANGED); + if (pdb_get_logon_divs(account) != r->logon_hours.units_per_week) + pdb_set_logon_divs(account, r->logon_hours.units_per_week, PDB_CHANGED); +#if 0 + /* no idea what to do with this one - gd */ /* Max Logon Hours */ if (delta->unknown1 != pdb_get_unknown_6(account)) { pdb_set_unknown_6(account, delta->unknown1, PDB_CHANGED); } - +#endif /* Logon Hours Len */ - if (delta->buf_logon_hrs.buf_len != pdb_get_hours_len(account)) { - pdb_set_hours_len(account, delta->buf_logon_hrs.buf_len, PDB_CHANGED); + if (r->logon_hours.units_per_week/8 != pdb_get_hours_len(account)) { + pdb_set_hours_len(account, r->logon_hours.units_per_week/8, PDB_CHANGED); } /* Logon Hours */ - if (delta->buf_logon_hrs.buffer) { + if (r->logon_hours.bits) { char oldstr[44], newstr[44]; pdb_sethexhours(oldstr, pdb_get_hours(account)); - pdb_sethexhours(newstr, delta->buf_logon_hrs.buffer); + pdb_sethexhours(newstr, r->logon_hours.bits); if (!strequal(oldstr, newstr)) - pdb_set_hours(account, (const uint8 *)delta->buf_logon_hrs.buffer, PDB_CHANGED); + pdb_set_hours(account, r->logon_hours.bits, PDB_CHANGED); } - if (pdb_get_bad_password_count(account) != delta->bad_pwd_count) - pdb_set_bad_password_count(account, delta->bad_pwd_count, PDB_CHANGED); + if (pdb_get_bad_password_count(account) != r->bad_password_count) + pdb_set_bad_password_count(account, r->bad_password_count, PDB_CHANGED); - if (pdb_get_logon_count(account) != delta->logon_count) - pdb_set_logon_count(account, delta->logon_count, PDB_CHANGED); + if (pdb_get_logon_count(account) != r->logon_count) + pdb_set_logon_count(account, r->logon_count, PDB_CHANGED); - if (!nt_time_is_zero(&delta->pwd_last_set_time)) { - unix_time = nt_time_to_unix(delta->pwd_last_set_time); + if (!nt_time_is_zero(&r->last_password_change)) { + unix_time = nt_time_to_unix(r->last_password_change); stored_time = pdb_get_pass_last_set_time(account); if (stored_time != unix_time) pdb_set_pass_last_set_time(account, unix_time, PDB_CHANGED); @@ -432,42 +563,41 @@ static NTSTATUS sam_account_from_delta(struct samu *account, SAM_ACCOUNT_INFO *d pdb_set_pass_last_set_time(account, time(NULL), PDB_CHANGED); } -#if 0 -/* No kickoff time in the delta? */ - if (!nt_time_is_zero(&delta->kickoff_time)) { - unix_time = nt_time_to_unix(&delta->kickoff_time); + if (!nt_time_is_zero(&r->acct_expiry)) { + unix_time = nt_time_to_unix(r->acct_expiry); stored_time = pdb_get_kickoff_time(account); if (stored_time != unix_time) pdb_set_kickoff_time(account, unix_time, PDB_CHANGED); } -#endif - /* Decode hashes from password hash - Note that win2000 may send us all zeros for the hashes if it doesn't + /* Decode hashes from password hash + Note that win2000 may send us all zeros for the hashes if it doesn't think this channel is secure enough - don't set the passwords at all in that case */ - if (memcmp(delta->pass.buf_lm_pwd, zero_buf, 16) != 0) { - sam_pwd_hash(delta->user_rid, delta->pass.buf_lm_pwd, lm_passwd, 0); + if (memcmp(r->ntpassword.hash, zero_buf, 16) != 0) { + sam_pwd_hash(r->rid, r->ntpassword.hash, lm_passwd, 0); pdb_set_lanman_passwd(account, lm_passwd, PDB_CHANGED); } - if (memcmp(delta->pass.buf_nt_pwd, zero_buf, 16) != 0) { - sam_pwd_hash(delta->user_rid, delta->pass.buf_nt_pwd, nt_passwd, 0); + if (memcmp(r->lmpassword.hash, zero_buf, 16) != 0) { + sam_pwd_hash(r->rid, r->lmpassword.hash, nt_passwd, 0); pdb_set_nt_passwd(account, nt_passwd, PDB_CHANGED); } /* TODO: account expiry time */ - pdb_set_acct_ctrl(account, delta->acb_info, PDB_CHANGED); + pdb_set_acct_ctrl(account, r->acct_flags, PDB_CHANGED); pdb_set_domain(account, lp_workgroup(), PDB_CHANGED); return NT_STATUS_OK; } -static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) +static NTSTATUS fetch_account_info(uint32_t rid, + struct netr_DELTA_USER *r) { + NTSTATUS nt_ret = NT_STATUS_UNSUCCESSFUL; fstring account; char *add_script = NULL; @@ -479,7 +609,7 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) struct passwd *passwd; fstring sid_string; - fstrcpy(account, unistr2_static(&delta->uni_acct_name)); + fstrcpy(account, r->account_name.string); d_printf("Creating account: %s\n", account); if ( !(sam_account = samu_new( NULL )) ) { @@ -488,17 +618,17 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) if (!(passwd = Get_Pwnam_alloc(sam_account, account))) { /* Create appropriate user */ - if (delta->acb_info & ACB_NORMAL) { + if (r->acct_flags & ACB_NORMAL) { add_script = talloc_strdup(sam_account, lp_adduser_script()); - } else if ( (delta->acb_info & ACB_WSTRUST) || - (delta->acb_info & ACB_SVRTRUST) || - (delta->acb_info & ACB_DOMTRUST) ) { + } else if ( (r->acct_flags & ACB_WSTRUST) || + (r->acct_flags & ACB_SVRTRUST) || + (r->acct_flags & ACB_DOMTRUST) ) { add_script = talloc_strdup(sam_account, lp_addmachine_script()); } else { DEBUG(1, ("Unknown user type: %s\n", - pdb_encode_acct_ctrl(delta->acb_info, NEW_PW_FORMAT_SPACE_PADDED_LEN))); + pdb_encode_acct_ctrl(r->acct_flags, NEW_PW_FORMAT_SPACE_PADDED_LEN))); nt_ret = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -533,30 +663,30 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) } sid_copy(&user_sid, get_global_sam_sid()); - sid_append_rid(&user_sid, delta->user_rid); + sid_append_rid(&user_sid, r->rid); DEBUG(3, ("Attempting to find SID %s for user %s in the passdb\n", sid_to_fstring(sid_string, &user_sid), account)); if (!pdb_getsampwsid(sam_account, &user_sid)) { - sam_account_from_delta(sam_account, delta); - DEBUG(3, ("Attempting to add user SID %s for user %s in the passdb\n", + sam_account_from_delta(sam_account, r); + DEBUG(3, ("Attempting to add user SID %s for user %s in the passdb\n", sid_to_fstring(sid_string, &user_sid), pdb_get_username(sam_account))); if (!NT_STATUS_IS_OK(pdb_add_sam_account(sam_account))) { DEBUG(1, ("SAM Account for %s failed to be added to the passdb!\n", account)); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_ACCESS_DENIED; } } else { - sam_account_from_delta(sam_account, delta); - DEBUG(3, ("Attempting to update user SID %s for user %s in the passdb\n", + sam_account_from_delta(sam_account, r); + DEBUG(3, ("Attempting to update user SID %s for user %s in the passdb\n", sid_to_fstring(sid_string, &user_sid), pdb_get_username(sam_account))); if (!NT_STATUS_IS_OK(pdb_update_sam_account(sam_account))) { DEBUG(1, ("SAM Account for %s failed to be updated in the passdb!\n", account)); TALLOC_FREE(sam_account); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_ACCESS_DENIED; } } @@ -572,7 +702,7 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) } else { if (map.gid != passwd->pw_gid) { if (!(grp = getgrgid(map.gid))) { - DEBUG(0, ("Could not find unix group %lu for user %s (group SID=%s)\n", + DEBUG(0, ("Could not find unix group %lu for user %s (group SID=%s)\n", (unsigned long)map.gid, pdb_get_username(sam_account), sid_string_tos(&group_sid))); } else { smb_set_primary_group(grp->gr_name, pdb_get_username(sam_account)); @@ -581,7 +711,7 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) } if ( !passwd ) { - DEBUG(1, ("No unix user for this account (%s), cannot adjust mappings\n", + DEBUG(1, ("No unix user for this account (%s), cannot adjust mappings\n", pdb_get_username(sam_account))); } @@ -590,7 +720,8 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) return nt_ret; } -static NTSTATUS fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta) +static NTSTATUS fetch_group_info(uint32_t rid, + struct netr_DELTA_GROUP *r) { fstring name; fstring comment; @@ -600,8 +731,8 @@ static NTSTATUS fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta) GROUP_MAP map; bool insert = True; - unistr2_to_ascii(name, &delta->uni_grp_name, sizeof(name)); - unistr2_to_ascii(comment, &delta->uni_grp_desc, sizeof(comment)); + fstrcpy(name, r->group_name.string); + fstrcpy(comment, r->description.string); /* add the group to the mapping table */ sid_copy(&group_sid, get_global_sam_sid()); @@ -619,14 +750,14 @@ static NTSTATUS fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta) /* 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, &gid) != 0) return NT_STATUS_ACCESS_DENIED; - + if ((grp = getgrnam(name)) == NULL) return NT_STATUS_ACCESS_DENIED; } @@ -636,7 +767,7 @@ static NTSTATUS fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta) map.sid = group_sid; map.sid_name_use = SID_NAME_DOM_GRP; fstrcpy(map.nt_name, name); - if (delta->hdr_grp_desc.buffer) { + if (r->description.string) { fstrcpy(map.comment, comment); } else { fstrcpy(map.comment, ""); @@ -650,7 +781,8 @@ static NTSTATUS 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) +static NTSTATUS fetch_group_mem_info(uint32_t rid, + struct netr_DELTA_GROUP_MEMBER *r) { int i; TALLOC_CTX *t = NULL; @@ -660,7 +792,7 @@ static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) GROUP_MAP map; struct group *grp; - if (delta->num_members == 0) { + if (r->num_rids == 0) { return NT_STATUS_OK; } @@ -684,8 +816,8 @@ static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) return NT_STATUS_NO_MEMORY; } - if (delta->num_members) { - if ((nt_members = TALLOC_ZERO_ARRAY(t, char *, delta->num_members)) == NULL) { + if (r->num_rids) { + if ((nt_members = TALLOC_ZERO_ARRAY(t, char *, r->num_rids)) == NULL) { DEBUG(0, ("talloc failed\n")); talloc_free(t); return NT_STATUS_NO_MEMORY; @@ -694,7 +826,7 @@ static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) nt_members = NULL; } - for (i=0; i<delta->num_members; i++) { + for (i=0; i < r->num_rids; i++) { struct samu *member = NULL; DOM_SID member_sid; @@ -704,11 +836,11 @@ static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) } sid_copy(&member_sid, get_global_sam_sid()); - sid_append_rid(&member_sid, delta->rids[i]); + sid_append_rid(&member_sid, r->rids[i]); if (!pdb_getsampwsid(member, &member_sid)) { DEBUG(1, ("Found bogus group member: %d (member_sid=%s group=%s)\n", - delta->rids[i], sid_string_tos(&member_sid), grp->gr_name)); + r->rids[i], sid_string_tos(&member_sid), grp->gr_name)); TALLOC_FREE(member); continue; } @@ -718,7 +850,7 @@ static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) TALLOC_FREE(member); continue; } - + d_printf("%s,", pdb_get_username(member)); nt_members[i] = talloc_strdup(t, pdb_get_username(member)); TALLOC_FREE(member); @@ -730,7 +862,7 @@ static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) while (*unix_members) { bool is_nt_member = False; - for (i=0; i<delta->num_members; i++) { + for (i=0; i < r->num_rids; i++) { if (nt_members[i] == NULL) { /* This was a primary group */ continue; @@ -750,7 +882,7 @@ static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) unix_members += 1; } - for (i=0; i<delta->num_members; i++) { + for (i=0; i < r->num_rids; i++) { bool is_unix_member = False; if (nt_members[i] == NULL) { @@ -775,12 +907,13 @@ static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) 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, +static NTSTATUS fetch_alias_info(uint32_t rid, + struct netr_DELTA_ALIAS *r, DOM_SID dom_sid) { fstring name; @@ -791,8 +924,8 @@ static NTSTATUS fetch_alias_info(uint32 rid, SAM_ALIAS_INFO *delta, GROUP_MAP map; bool insert = True; - unistr2_to_ascii(name, &delta->uni_als_name, sizeof(name)); - unistr2_to_ascii(comment, &delta->uni_als_desc, sizeof(comment)); + fstrcpy(name, r->alias_name.string); + fstrcpy(comment, r->description.string); /* Find out whether the group is already mapped */ sid_copy(&alias_sid, &dom_sid); @@ -837,24 +970,33 @@ static NTSTATUS fetch_alias_info(uint32 rid, SAM_ALIAS_INFO *delta, return NT_STATUS_OK; } -static NTSTATUS fetch_alias_mem(uint32 rid, SAM_ALIAS_MEM_INFO *delta, DOM_SID dom_sid) +static NTSTATUS fetch_alias_mem(uint32_t rid, + struct netr_DELTA_ALIAS_MEMBER *r, + DOM_SID dom_sid) { return NT_STATUS_OK; } -static NTSTATUS fetch_domain_info(uint32 rid, SAM_DOMAIN_INFO *delta) +static NTSTATUS fetch_domain_info(uint32_t rid, + struct netr_DELTA_DOMAIN *r) { - time_t u_max_age, u_min_age, u_logout, u_lockoutreset, u_lockouttime; + time_t u_max_age, u_min_age, u_logout; +#if 0 + /* FIXME: gd */ + time_t u_lockoutreset, u_lockouttime; +#endif NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - char *domname; + const char *domname; - u_max_age = uint64s_nt_time_to_unix_abs(&delta->max_pwd_age); - u_min_age = uint64s_nt_time_to_unix_abs(&delta->min_pwd_age); - u_logout = uint64s_nt_time_to_unix_abs(&delta->force_logoff); + u_max_age = uint64s_nt_time_to_unix_abs((uint64 *)&r->max_password_age); + u_min_age = uint64s_nt_time_to_unix_abs((uint64 *)&r->min_password_age); + u_logout = uint64s_nt_time_to_unix_abs((uint64 *)&r->force_logoff_time); +#if 0 + /* FIXME: gd */ u_lockoutreset = uint64s_nt_time_to_unix_abs(&delta->account_lockout.reset_count); u_lockouttime = uint64s_nt_time_to_unix_abs(&delta->account_lockout.lockout_duration); - - domname = unistr2_to_ascii_talloc(talloc_tos(), &delta->uni_dom_name); +#endif + domname = r->domain_name.string; if (!domname) { return NT_STATUS_NO_MEMORY; } @@ -866,10 +1008,12 @@ static NTSTATUS fetch_domain_info(uint32 rid, SAM_DOMAIN_INFO *delta) } - if (!pdb_set_account_policy(AP_PASSWORD_HISTORY, delta->pwd_history_len)) + if (!pdb_set_account_policy(AP_PASSWORD_HISTORY, + r->password_history_length)) return nt_status; - if (!pdb_set_account_policy(AP_MIN_PASSWORD_LEN, delta->min_pwd_len)) + if (!pdb_set_account_policy(AP_MIN_PASSWORD_LEN, + r->min_password_length)) return nt_status; if (!pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (uint32)u_max_age)) @@ -880,7 +1024,8 @@ static NTSTATUS fetch_domain_info(uint32 rid, SAM_DOMAIN_INFO *delta) if (!pdb_set_account_policy(AP_TIME_TO_LOGOUT, (uint32)u_logout)) return nt_status; - +#if 0 +/* FIXME: gd */ if (!pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, delta->account_lockout.bad_attempt_lockout)) return nt_status; @@ -892,88 +1037,111 @@ static NTSTATUS fetch_domain_info(uint32 rid, SAM_DOMAIN_INFO *delta) if (!pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (uint32)u_lockouttime)) return nt_status; +#endif - if (!pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, delta->logon_chgpass)) + if (!pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, + r->logon_to_chgpass)) return nt_status; return NT_STATUS_OK; } - -static void fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta, - DOM_SID dom_sid) +static void fetch_sam_entry(struct netr_DELTA_ENUM *r, DOM_SID dom_sid) { - switch(hdr_delta->type) { - case SAM_DELTA_ACCOUNT_INFO: - fetch_account_info(hdr_delta->target_rid, - &delta->account_info); + switch(r->delta_type) { + case NETR_DELTA_USER: + fetch_account_info(r->delta_id_union.rid, + r->delta_union.user); break; - case SAM_DELTA_GROUP_INFO: - fetch_group_info(hdr_delta->target_rid, - &delta->group_info); + case NETR_DELTA_GROUP: + fetch_group_info(r->delta_id_union.rid, + r->delta_union.group); break; - case SAM_DELTA_GROUP_MEM: - fetch_group_mem_info(hdr_delta->target_rid, - &delta->grp_mem_info); + case NETR_DELTA_GROUP_MEMBER: + fetch_group_mem_info(r->delta_id_union.rid, + r->delta_union.group_member); break; - case SAM_DELTA_ALIAS_INFO: - fetch_alias_info(hdr_delta->target_rid, - &delta->alias_info, dom_sid); + case NETR_DELTA_ALIAS: + fetch_alias_info(r->delta_id_union.rid, + r->delta_union.alias, + dom_sid); break; - case SAM_DELTA_ALIAS_MEM: - fetch_alias_mem(hdr_delta->target_rid, - &delta->als_mem_info, dom_sid); + case NETR_DELTA_ALIAS_MEMBER: + fetch_alias_mem(r->delta_id_union.rid, + r->delta_union.alias_member, + dom_sid); break; - case SAM_DELTA_DOMAIN_INFO: - fetch_domain_info(hdr_delta->target_rid, - &delta->domain_info); + case NETR_DELTA_DOMAIN: + fetch_domain_info(r->delta_id_union.rid, + r->delta_union.domain); break; /* The following types are recognised but not handled */ - case SAM_DELTA_RENAME_GROUP: - d_printf("SAM_DELTA_RENAME_GROUP not handled\n"); + case NETR_DELTA_RENAME_GROUP: + d_printf("NETR_DELTA_RENAME_GROUP not handled\n"); + break; + case NETR_DELTA_RENAME_USER: + d_printf("NETR_DELTA_RENAME_USER not handled\n"); + break; + case NETR_DELTA_RENAME_ALIAS: + d_printf("NETR_DELTA_RENAME_ALIAS not handled\n"); + break; + case NETR_DELTA_POLICY: + d_printf("NETR_DELTA_POLICY not handled\n"); break; - case SAM_DELTA_RENAME_USER: - d_printf("SAM_DELTA_RENAME_USER not handled\n"); + case NETR_DELTA_TRUSTED_DOMAIN: + d_printf("NETR_DELTA_TRUSTED_DOMAIN not handled\n"); break; - case SAM_DELTA_RENAME_ALIAS: - d_printf("SAM_DELTA_RENAME_ALIAS not handled\n"); + case NETR_DELTA_ACCOUNT: + d_printf("NETR_DELTA_ACCOUNT not handled\n"); break; - case SAM_DELTA_POLICY_INFO: - d_printf("SAM_DELTA_POLICY_INFO not handled\n"); + case NETR_DELTA_SECRET: + d_printf("NETR_DELTA_SECRET not handled\n"); break; - case SAM_DELTA_TRUST_DOMS: - d_printf("SAM_DELTA_TRUST_DOMS not handled\n"); + case NETR_DELTA_DELETE_GROUP: + d_printf("NETR_DELTA_DELETE_GROUP not handled\n"); break; - case SAM_DELTA_PRIVS_INFO: - d_printf("SAM_DELTA_PRIVS_INFO not handled\n"); + case NETR_DELTA_DELETE_USER: + d_printf("NETR_DELTA_DELETE_USER not handled\n"); break; - case SAM_DELTA_SECRET_INFO: - d_printf("SAM_DELTA_SECRET_INFO not handled\n"); + case NETR_DELTA_MODIFY_COUNT: + d_printf("NETR_DELTA_MODIFY_COUNT not handled\n"); break; - case SAM_DELTA_DELETE_GROUP: - d_printf("SAM_DELTA_DELETE_GROUP not handled\n"); + case NETR_DELTA_DELETE_ALIAS: + d_printf("NETR_DELTA_DELETE_ALIAS not handled\n"); break; - case SAM_DELTA_DELETE_USER: - d_printf("SAM_DELTA_DELETE_USER not handled\n"); + case NETR_DELTA_DELETE_TRUST: + d_printf("NETR_DELTA_DELETE_TRUST not handled\n"); break; - case SAM_DELTA_MODIFIED_COUNT: - d_printf("SAM_DELTA_MODIFIED_COUNT not handled\n"); + case NETR_DELTA_DELETE_ACCOUNT: + d_printf("NETR_DELTA_DELETE_ACCOUNT not handled\n"); + break; + case NETR_DELTA_DELETE_SECRET: + d_printf("NETR_DELTA_DELETE_SECRET not handled\n"); + break; + case NETR_DELTA_DELETE_GROUP2: + d_printf("NETR_DELTA_DELETE_GROUP2 not handled\n"); + break; + case NETR_DELTA_DELETE_USER2: + d_printf("NETR_DELTA_DELETE_USER2 not handled\n"); break; default: - d_printf("Unknown delta record type %d\n", hdr_delta->type); + d_printf("Unknown delta record type %d\n", r->delta_type); break; } } static NTSTATUS fetch_database(struct rpc_pipe_client *pipe_hnd, uint32 db_type, DOM_SID dom_sid) { - uint32 sync_context = 0; NTSTATUS result; int i; TALLOC_CTX *mem_ctx; - SAM_DELTA_HDR *hdr_deltas; - SAM_DELTA_CTR *deltas; - uint32 num_deltas; + const char *logon_server = pipe_hnd->cli->desthost; + const char *computername = global_myname(); + struct netr_Authenticator credential; + struct netr_Authenticator return_authenticator; + enum netr_SamDatabaseID database_id = db_type; + uint16_t restart_state = 0; + uint32_t sync_context = 0; if (!(mem_ctx = talloc_init("fetch_database"))) return NT_STATUS_NO_MEMORY; @@ -994,20 +1162,36 @@ static NTSTATUS fetch_database(struct rpc_pipe_client *pipe_hnd, uint32 db_type, } do { - result = rpccli_netlogon_sam_sync(pipe_hnd, mem_ctx, - db_type, sync_context, - &num_deltas, - &hdr_deltas, &deltas); - - if (NT_STATUS_IS_OK(result) || - NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { - for (i = 0; i < num_deltas; i++) { - fetch_sam_entry(&hdr_deltas[i], &deltas[i], dom_sid); - } - } else - return result; + struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL; + + netlogon_creds_client_step(pipe_hnd->dc, &credential); + + result = rpccli_netr_DatabaseSync2(pipe_hnd, mem_ctx, + logon_server, + computername, + &credential, + &return_authenticator, + database_id, + restart_state, + &sync_context, + &delta_enum_array, + 0xffff); + + /* Check returned credentials. */ + if (!netlogon_creds_client_check(pipe_hnd->dc, + &return_authenticator.cred)) { + DEBUG(0,("credentials chain check failed\n")); + return NT_STATUS_ACCESS_DENIED; + } + + if (NT_STATUS_IS_ERR(result)) { + break; + } + + for (i = 0; i < delta_enum_array->num_deltas; i++) { + fetch_sam_entry(&delta_enum_array->delta_enum[i], dom_sid); + } - sync_context += 1; } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); talloc_destroy(mem_ctx); @@ -1015,7 +1199,7 @@ static NTSTATUS fetch_database(struct rpc_pipe_client *pipe_hnd, uint32 db_type, return result; } -static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const char +static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const char *builtin_sid, FILE *add_fd) { const char *user_suffix, *group_suffix, *machine_suffix, *idmap_suffix; @@ -1047,7 +1231,7 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch SAFE_FREE(suffix_attr); return NT_STATUS_NO_MEMORY; } - /* If it exists and is distinct from other containers, + /* If it exists and is distinct from other containers, Write the Users entity */ if (*user_suffix && strcmp(user_suffix, suffix)) { user_attr = sstring_sub(lp_ldap_user_suffix(), '=', ','); @@ -1066,7 +1250,7 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch SAFE_FREE(user_attr); return NT_STATUS_NO_MEMORY; } - /* If it exists and is distinct from other containers, + /* If it exists and is distinct from other containers, Write the Groups entity */ if (*group_suffix && strcmp(group_suffix, suffix)) { group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ','); @@ -1078,7 +1262,7 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch fflush(add_fd); } - /* If it exists and is distinct from other containers, + /* If it exists and is distinct from other containers, Write the Computers entity */ machine_suffix = lp_ldap_machine_suffix(); if (machine_suffix == NULL) { @@ -1102,7 +1286,7 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch fflush(add_fd); } - /* If it exists and is distinct from other containers, + /* If it exists and is distinct from other containers, Write the IdMap entity */ idmap_suffix = lp_ldap_idmap_suffix(); if (idmap_suffix == NULL) { @@ -1138,7 +1322,7 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch fprintf(add_fd, "\n"); fflush(add_fd); - /* Write the Domain Admins entity */ + /* Write the Domain Admins entity */ fprintf(add_fd, "# Domain Admins, %s, %s\n", group_attr, suffix); fprintf(add_fd, "dn: cn=Domain Admins,ou=%s,%s\n", group_attr, @@ -1155,7 +1339,7 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch fprintf(add_fd, "\n"); fflush(add_fd); - /* Write the Domain Users entity */ + /* Write the Domain Users entity */ fprintf(add_fd, "# Domain Users, %s, %s\n", group_attr, suffix); fprintf(add_fd, "dn: cn=Domain Users,ou=%s,%s\n", group_attr, @@ -1171,7 +1355,7 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch fprintf(add_fd, "\n"); fflush(add_fd); - /* Write the Domain Guests entity */ + /* Write the Domain Guests entity */ fprintf(add_fd, "# Domain Guests, %s, %s\n", group_attr, suffix); fprintf(add_fd, "dn: cn=Domain Guests,ou=%s,%s\n", group_attr, @@ -1272,7 +1456,7 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch return NT_STATUS_OK; } -static NTSTATUS map_populate_groups(GROUPMAP *groupmap, ACCOUNTMAP *accountmap, fstring sid, +static NTSTATUS map_populate_groups(GROUPMAP *groupmap, ACCOUNTMAP *accountmap, fstring sid, const char *suffix, const char *builtin_sid) { char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ','); @@ -1422,16 +1606,15 @@ static int fprintf_attr(FILE *add_fd, const char *attr_name, base64_blob.data = (unsigned char *)value; base64_blob.length = strlen(value); - base64 = base64_encode_data_blob(base64_blob); + base64 = base64_encode_data_blob(value, base64_blob); SMB_ASSERT(base64 != NULL); res = fprintf(add_fd, "%s:: %s\n", attr_name, base64); TALLOC_FREE(value); - TALLOC_FREE(base64); return res; } -static NTSTATUS fetch_group_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupmap, +static NTSTATUS fetch_group_info_to_ldif(struct netr_DELTA_GROUP *r, GROUPMAP *groupmap, FILE *add_fd, fstring sid, char *suffix) { fstring groupname; @@ -1439,9 +1622,7 @@ static NTSTATUS fetch_group_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupma char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ','); /* Get the group name */ - unistr2_to_ascii(groupname, - &delta->group_info.uni_grp_name, - sizeof(groupname)); + fstrcpy(groupname, r->group_name.string); /* Set up the group type (always 2 for group info) */ grouptype = 2; @@ -1463,7 +1644,7 @@ static NTSTATUS fetch_group_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupma } /* Map the group rid, gid, and dn */ - g_rid = delta->group_info.gid.g_rid; + g_rid = r->rid; groupmap->rid = g_rid; groupmap->gidNumber = ldif_gid; snprintf(groupmap->sambaSID, sizeof(groupmap->sambaSID), @@ -1491,7 +1672,7 @@ static NTSTATUS fetch_group_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupma return NT_STATUS_OK; } -static NTSTATUS fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, +static NTSTATUS fetch_account_info_to_ldif(struct netr_DELTA_USER *r, GROUPMAP *groupmap, ACCOUNTMAP *accountmap, FILE *add_fd, @@ -1511,21 +1692,18 @@ static NTSTATUS fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, int i; /* Get the username */ - unistr2_to_ascii(username, - &(delta->account_info.uni_acct_name), - sizeof(username)); + fstrcpy(username, r->account_name.string); /* Get the rid */ - rid = delta->account_info.user_rid; + rid = r->rid; /* Map the rid and username for group member info later */ accountmap->rid = rid; snprintf(accountmap->cn, sizeof(accountmap->cn), "%s", username); /* Get the home directory */ - if (delta->account_info.acb_info & ACB_NORMAL) { - unistr2_to_ascii(homedir, &(delta->account_info.uni_home_dir), - sizeof(homedir)); + if (r->acct_flags & ACB_NORMAL) { + fstrcpy(homedir, r->home_directory.string); if (!*homedir) { snprintf(homedir, sizeof(homedir), "/home/%s", username); } else { @@ -1538,60 +1716,48 @@ static NTSTATUS fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, } /* Get the logon script */ - unistr2_to_ascii(logonscript, &(delta->account_info.uni_logon_script), - sizeof(logonscript)); + fstrcpy(logonscript, r->logon_script.string); /* Get the home drive */ - unistr2_to_ascii(homedrive, &(delta->account_info.uni_dir_drive), - sizeof(homedrive)); + fstrcpy(homedrive, r->home_drive.string); /* Get the home path */ - unistr2_to_ascii(homepath, &(delta->account_info.uni_home_dir), - sizeof(homepath)); + fstrcpy(homepath, r->home_directory.string); /* Get the description */ - unistr2_to_ascii(description, &(delta->account_info.uni_acct_desc), - sizeof(description)); + fstrcpy(description, r->description.string); /* Get the display name */ - unistr2_to_ascii(fullname, &(delta->account_info.uni_full_name), - sizeof(fullname)); + fstrcpy(fullname, r->full_name.string); /* Get the profile path */ - unistr2_to_ascii(profilepath, &(delta->account_info.uni_profile), - sizeof(profilepath)); + fstrcpy(profilepath, r->profile_path.string); /* Get lm and nt password data */ - if (memcmp(delta->account_info.pass.buf_lm_pwd, zero_buf, 16) != 0) { - sam_pwd_hash(delta->account_info.user_rid, - delta->account_info.pass.buf_lm_pwd, - lm_passwd, 0); - pdb_sethexpwd(hex_lm_passwd, lm_passwd, - delta->account_info.acb_info); + if (memcmp(r->lmpassword.hash, zero_buf, 16) != 0) { + sam_pwd_hash(r->rid, r->lmpassword.hash, lm_passwd, 0); + pdb_sethexpwd(hex_lm_passwd, lm_passwd, r->acct_flags); } else { pdb_sethexpwd(hex_lm_passwd, NULL, 0); } - if (memcmp(delta->account_info.pass.buf_nt_pwd, zero_buf, 16) != 0) { - sam_pwd_hash(delta->account_info.user_rid, - delta->account_info.pass.buf_nt_pwd, - nt_passwd, 0); - pdb_sethexpwd(hex_nt_passwd, nt_passwd, - delta->account_info.acb_info); + if (memcmp(r->ntpassword.hash, zero_buf, 16) != 0) { + sam_pwd_hash(r->rid, r->ntpassword.hash, nt_passwd, 0); + pdb_sethexpwd(hex_nt_passwd, nt_passwd, r->acct_flags); } else { pdb_sethexpwd(hex_nt_passwd, NULL, 0); } - unix_time = nt_time_to_unix(delta->account_info.pwd_last_set_time); + unix_time = nt_time_to_unix(r->last_password_change); /* Increment the uid for the new user */ ldif_uid++; /* Set up group id and sambaSID for the user */ - group_rid = delta->account_info.group_rid; + group_rid = r->primary_gid; for (i=0; i<alloced; i++) { if (groupmap[i].rid == group_rid) break; } if (i == alloced){ - DEBUG(1, ("Could not find rid %d in groupmap array\n", + DEBUG(1, ("Could not find rid %d in groupmap array\n", group_rid)); return NT_STATUS_UNSUCCESSFUL; } @@ -1599,7 +1765,7 @@ static NTSTATUS fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, snprintf(sambaSID, sizeof(sambaSID), groupmap[i].sambaSID); /* Set up sambaAcctFlags */ - flags = pdb_encode_acct_ctrl(delta->account_info.acb_info, + flags = pdb_encode_acct_ctrl(r->acct_flags, NEW_PW_FORMAT_SPACE_PADDED_LEN); /* Add the user to the temporary add ldif file */ @@ -1626,8 +1792,8 @@ static NTSTATUS fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, fprintf_attr(add_fd, "sambaHomeDrive", "%s", homedrive); if (*logonscript) fprintf_attr(add_fd, "sambaLogonScript", "%s", logonscript); - fprintf(add_fd, "loginShell: %s\n", - ((delta->account_info.acb_info & ACB_NORMAL) ? + fprintf(add_fd, "loginShell: %s\n", + ((r->acct_flags & ACB_NORMAL) ? "/bin/bash" : "/bin/false")); fprintf(add_fd, "gecos: System User\n"); if (*description) @@ -1651,10 +1817,10 @@ static NTSTATUS fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, return NT_STATUS_OK; } -static NTSTATUS fetch_alias_info_to_ldif(SAM_DELTA_CTR *delta, +static NTSTATUS fetch_alias_info_to_ldif(struct netr_DELTA_ALIAS *r, GROUPMAP *groupmap, FILE *add_fd, fstring sid, - char *suffix, + char *suffix, unsigned db_type) { fstring aliasname, description; @@ -1662,12 +1828,10 @@ static NTSTATUS fetch_alias_info_to_ldif(SAM_DELTA_CTR *delta, char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ','); /* Get the alias name */ - unistr2_to_ascii(aliasname, &(delta->alias_info.uni_als_name), - sizeof(aliasname)); + fstrcpy(aliasname, r->alias_name.string); /* Get the alias description */ - unistr2_to_ascii(description, &(delta->alias_info.uni_als_desc), - sizeof(description)); + fstrcpy(description, r->description.string); /* Set up the group type */ switch (db_type) { @@ -1684,7 +1848,7 @@ static NTSTATUS fetch_alias_info_to_ldif(SAM_DELTA_CTR *delta, /* These groups are entered by populate_ldap_for_ldif - Note that populate creates a group called Relicators, + Note that populate creates a group called Relicators, but NT returns a group called Replicator */ if (strcmp(aliasname, "Domain Admins") == 0 || @@ -1703,7 +1867,7 @@ static NTSTATUS fetch_alias_info_to_ldif(SAM_DELTA_CTR *delta, } /* Map the group rid and gid */ - g_rid = delta->group_info.gid.g_rid; + g_rid = r->rid; groupmap->gidNumber = ldif_gid; snprintf(groupmap->sambaSID, sizeof(groupmap->sambaSID), "%s-%d", sid, g_rid); @@ -1730,8 +1894,8 @@ static NTSTATUS fetch_alias_info_to_ldif(SAM_DELTA_CTR *delta, return NT_STATUS_OK; } -static NTSTATUS fetch_groupmem_info_to_ldif(SAM_DELTA_CTR *delta, - SAM_DELTA_HDR *hdr_delta, +static NTSTATUS fetch_groupmem_info_to_ldif(struct netr_DELTA_GROUP_MEMBER *r, + uint32_t id_rid, GROUPMAP *groupmap, ACCOUNTMAP *accountmap, FILE *mod_fd, int alloced) @@ -1741,8 +1905,8 @@ static NTSTATUS fetch_groupmem_info_to_ldif(SAM_DELTA_CTR *delta, int i, j, k; /* Get the dn for the group */ - if (delta->grp_mem_info.num_members > 0) { - group_rid = hdr_delta->target_rid; + if (r->num_rids > 0) { + group_rid = id_rid; for (j=0; j<alloced; j++) { if (groupmap[j].rid == group_rid) break; } @@ -1755,8 +1919,8 @@ static NTSTATUS fetch_groupmem_info_to_ldif(SAM_DELTA_CTR *delta, fprintf(mod_fd, "dn: %s\n", group_dn); /* Get the cn for each member */ - for (i=0; i<delta->grp_mem_info.num_members; i++) { - rid = delta->grp_mem_info.rids[i]; + for (i=0; i < r->num_rids; i++) { + rid = r->rids[i]; for (k=0; k<alloced; k++) { if (accountmap[k].rid == rid) break; } @@ -1786,15 +1950,19 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd, const char *add_template = "/tmp/add.ldif.XXXXXX"; const char *mod_template = "/tmp/mod.ldif.XXXXXX"; fstring sid, domainname; - uint32 sync_context = 0; NTSTATUS ret = NT_STATUS_OK, result; int k; TALLOC_CTX *mem_ctx; - SAM_DELTA_HDR *hdr_deltas; - SAM_DELTA_CTR *deltas; uint32 num_deltas; FILE *add_file = NULL, *mod_file = NULL, *ldif_file = NULL; int num_alloced = 0, g_index = 0, a_index = 0; + const char *logon_server = pipe_hnd->cli->desthost; + const char *computername = global_myname(); + struct netr_Authenticator credential; + struct netr_Authenticator return_authenticator; + enum netr_SamDatabaseID database_id = db_type; + uint16_t restart_state = 0; + uint32_t sync_context = 0; /* Set up array for mapping accounts to groups */ /* Array element is the group rid */ @@ -1802,7 +1970,7 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd, /* Set up array for mapping account rid's to cn's */ /* Array element is the account rid */ - ACCOUNTMAP *accountmap = NULL; + ACCOUNTMAP *accountmap = NULL; if (!(mem_ctx = talloc_init("fetch_database"))) { return NT_STATUS_NO_MEMORY; @@ -1838,7 +2006,7 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd, DEBUG(1, ("Could not open %s\n", mod_name)); ret = NT_STATUS_UNSUCCESSFUL; goto done; - } + } /* Get the sid */ sid_to_fstring(sid, &dom_sid); @@ -1894,23 +2062,41 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd, d_fprintf(stderr, "Fetching PRIVS databases\n"); break; default: - d_fprintf(stderr, - "Fetching unknown database type %u\n", + d_fprintf(stderr, + "Fetching unknown database type %u\n", db_type ); break; } do { - result = rpccli_netlogon_sam_sync(pipe_hnd, mem_ctx, - db_type, sync_context, - &num_deltas, &hdr_deltas, - &deltas); - if (!NT_STATUS_IS_OK(result) && - !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { - ret = NT_STATUS_OK; - goto done; /* is this correct? jmcd */ + struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL; + + netlogon_creds_client_step(pipe_hnd->dc, &credential); + + result = rpccli_netr_DatabaseSync2(pipe_hnd, mem_ctx, + logon_server, + computername, + &credential, + &return_authenticator, + database_id, + restart_state, + &sync_context, + &delta_enum_array, + 0xffff); + + /* Check returned credentials. */ + if (!netlogon_creds_client_check(pipe_hnd->dc, + &return_authenticator.cred)) { + DEBUG(0,("credentials chain check failed\n")); + return NT_STATUS_ACCESS_DENIED; } + if (NT_STATUS_IS_ERR(result)) { + break; + } + + num_deltas = delta_enum_array->num_deltas; + /* Re-allocate memory for groupmap and accountmap arrays */ groupmap = SMB_REALLOC_ARRAY(groupmap, GROUPMAP, num_deltas+num_alloced); @@ -1923,7 +2109,7 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd, } /* Initialize the new records */ - memset(&groupmap[num_alloced], 0, + memset(&groupmap[num_alloced], 0, sizeof(GROUPMAP)*num_deltas); memset(&accountmap[num_alloced], 0, sizeof(ACCOUNTMAP)*num_deltas); @@ -1933,73 +2119,60 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd, /* Loop through the deltas */ for (k=0; k<num_deltas; k++) { - switch(hdr_deltas[k].type) { - case SAM_DELTA_DOMAIN_INFO: + + union netr_DELTA_UNION u = + delta_enum_array->delta_enum[k].delta_union; + union netr_DELTA_ID_UNION id = + delta_enum_array->delta_enum[k].delta_id_union; + + switch(delta_enum_array->delta_enum[k].delta_type) { + case NETR_DELTA_DOMAIN: /* Is this case needed? */ - unistr2_to_ascii( - domainname, - &deltas[k].domain_info.uni_dom_name, - sizeof(domainname)); + fstrcpy(domainname, + u.domain->domain_name.string); break; - case SAM_DELTA_GROUP_INFO: + case NETR_DELTA_GROUP: fetch_group_info_to_ldif( - &deltas[k], &groupmap[g_index], + u.group, + &groupmap[g_index], add_file, sid, suffix); g_index++; break; - case SAM_DELTA_ACCOUNT_INFO: + case NETR_DELTA_USER: fetch_account_info_to_ldif( - &deltas[k], groupmap, + u.user, groupmap, &accountmap[a_index], add_file, sid, suffix, num_alloced); a_index++; break; - case SAM_DELTA_ALIAS_INFO: + case NETR_DELTA_ALIAS: fetch_alias_info_to_ldif( - &deltas[k], &groupmap[g_index], + u.alias, &groupmap[g_index], add_file, sid, suffix, db_type); g_index++; break; - case SAM_DELTA_GROUP_MEM: + case NETR_DELTA_GROUP_MEMBER: fetch_groupmem_info_to_ldif( - &deltas[k], &hdr_deltas[k], - groupmap, accountmap, + u.group_member, id.rid, + groupmap, accountmap, mod_file, num_alloced); break; - case SAM_DELTA_ALIAS_MEM: - break; - case SAM_DELTA_POLICY_INFO: - break; - case SAM_DELTA_PRIVS_INFO: - break; - case SAM_DELTA_TRUST_DOMS: - /* Implemented but broken */ - break; - case SAM_DELTA_SECRET_INFO: - /* Implemented but broken */ - break; - case SAM_DELTA_RENAME_GROUP: - /* Not yet implemented */ - break; - case SAM_DELTA_RENAME_USER: - /* Not yet implemented */ - break; - case SAM_DELTA_RENAME_ALIAS: - /* Not yet implemented */ - break; - case SAM_DELTA_DELETE_GROUP: - /* Not yet implemented */ - break; - case SAM_DELTA_DELETE_USER: - /* Not yet implemented */ - break; - case SAM_DELTA_MODIFIED_COUNT: - break; + case NETR_DELTA_ALIAS_MEMBER: + case NETR_DELTA_POLICY: + case NETR_DELTA_ACCOUNT: + case NETR_DELTA_TRUSTED_DOMAIN: + case NETR_DELTA_SECRET: + case NETR_DELTA_RENAME_GROUP: + case NETR_DELTA_RENAME_USER: + case NETR_DELTA_RENAME_ALIAS: + case NETR_DELTA_DELETE_GROUP: + case NETR_DELTA_DELETE_USER: + case NETR_DELTA_MODIFY_COUNT: default: break; } /* end of switch */ @@ -2065,7 +2238,7 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd, DEBUG(1,("unlink(%s) failed, error was (%s)\n", mod_name, strerror(errno))); } - + if (ldif_file && (ldif_file != stdout)) { fclose(ldif_file); } @@ -2079,15 +2252,15 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd, return ret; } -/** +/** * Basic usage function for 'net rpc vampire' * @param argc Standard main() style argc * @param argc Standard main() style argv. Initial components are already * stripped **/ -int rpc_vampire_usage(int argc, const char **argv) -{ +int rpc_vampire_usage(int argc, const char **argv) +{ d_printf("net rpc vampire [ldif [<ldif-filename>] [options]\n" "\t to pull accounts from a remote PDC where we are a BDC\n" "\t\t no args puts accounts in local passdb from smb.conf\n" @@ -2100,13 +2273,13 @@ int rpc_vampire_usage(int argc, const char **argv) /* dump sam database via samsync rpc calls */ -NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid, - const char *domain_name, +NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid, + const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, int argc, - const char **argv) + const char **argv) { NTSTATUS result; fstring my_dom_sid_str; @@ -2120,7 +2293,7 @@ NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid, "workgroup=%s\n\n in your smb.conf?\n", domain_name, get_global_sam_name(), - sid_to_fstring(my_dom_sid_str, + sid_to_fstring(my_dom_sid_str, get_global_sam_sid()), domain_name, sid_to_fstring(rem_dom_sid_str, domain_sid), diff --git a/source3/utils/net_rpc_service.c b/source3/utils/net_rpc_service.c index a70ecf3c72..242d653017 100644 --- a/source3/utils/net_rpc_service.c +++ b/source3/utils/net_rpc_service.c @@ -1,30 +1,33 @@ -/* - Samba Unix/Linux SMB client library - Distributed SMB/CIFS Server Management Utility +/* + Samba Unix/Linux SMB client library + Distributed SMB/CIFS Server Management Utility Copyright (C) Gerald (Jerry) Carter 2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>. */ - + #include "includes.h" #include "utils/net.h" +#define CLI_SERVER_NAME_SLASH(_ctx, _p, _cli) \ + _p = talloc_asprintf(_ctx, "\\\\%s", _cli->cli->desthost); + /******************************************************************** ********************************************************************/ static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, POLICY_HND *hSCM, const char *service, uint32 *state ) @@ -32,24 +35,32 @@ static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd, POLICY_HND hService; SERVICE_STATUS service_status; WERROR result = WERR_GENERAL_FAILURE; - + NTSTATUS status; + /* now cycle until the status is actually 'watch_state' */ - - result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, hSCM, &hService, - service, SC_RIGHT_SVC_QUERY_STATUS ); - if ( !W_ERROR_IS_OK(result) ) { + status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx, + hSCM, + service, + SC_RIGHT_SVC_QUERY_STATUS, + &hService, + &result); + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result)); return result; } - result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status ); - if ( W_ERROR_IS_OK(result) ) { + status = rpccli_svcctl_QueryServiceStatus(pipe_hnd, mem_ctx, + &hService, + &service_status, + &result); + + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { *state = service_status.state; } - + rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL); - + return result; } @@ -57,17 +68,17 @@ static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd, ********************************************************************/ static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, POLICY_HND *hSCM, - const char *service, + const char *service, uint32 watch_state, uint32 *final_state ) { uint32 i; uint32 state = 0; WERROR result = WERR_GENERAL_FAILURE; - - + + i = 0; while ( (state != watch_state ) && i<30 ) { /* get the status */ @@ -76,15 +87,15 @@ static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd, if ( !W_ERROR_IS_OK(result) ) { break; } - + d_printf("."); i++; sys_usleep( 100 ); } d_printf("\n"); - + *final_state = state; - + return result; } @@ -92,155 +103,187 @@ static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd, ********************************************************************/ static WERROR control_service(struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, POLICY_HND *hSCM, - const char *service, + const char *service, uint32 control, uint32 watch_state ) { POLICY_HND hService; WERROR result = WERR_GENERAL_FAILURE; + NTSTATUS status; SERVICE_STATUS service_status; uint32 state = 0; - + /* Open the Service */ - - result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, hSCM, &hService, - service, (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE) ); - if ( !W_ERROR_IS_OK(result) ) { + status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx, + hSCM, + service, + (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE), + &hService, + &result); + + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result)); goto done; } - + /* get the status */ - result = rpccli_svcctl_control_service(pipe_hnd, mem_ctx, &hService, - control, &service_status ); - - if ( !W_ERROR_IS_OK(result) ) { + status = rpccli_svcctl_ControlService(pipe_hnd, mem_ctx, + &hService, + control, + &service_status, + &result); + + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { d_fprintf(stderr, "Control service request failed. [%s]\n", dos_errstr(result)); goto done; } - + /* loop -- checking the state until we are where we want to be */ - + result = watch_service_state(pipe_hnd, mem_ctx, hSCM, service, watch_state, &state ); - + d_printf("%s service is %s.\n", service, svc_status_string(state)); -done: +done: rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL); - + return result; -} +} /******************************************************************** ********************************************************************/ static NTSTATUS rpc_service_list_internal(const DOM_SID *domain_sid, - const char *domain_name, + const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, int argc, const char **argv ) { POLICY_HND hSCM; ENUM_SERVICES_STATUS *services; WERROR result = WERR_GENERAL_FAILURE; + NTSTATUS status; fstring servicename; fstring displayname; uint32 num_services = 0; + const char *server_name; int i; - + if (argc != 0 ) { d_printf("Usage: net rpc service list\n"); return NT_STATUS_OK; } - result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE ); - if ( !W_ERROR_IS_OK(result) ) { + CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd); + NT_STATUS_HAVE_NO_MEMORY(server_name); + + status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx, + server_name, + NULL, + SC_RIGHT_MGR_ENUMERATE_SERVICE, + &hSCM, + &result); + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); return werror_to_ntstatus(result); } - + result = rpccli_svcctl_enumerate_services(pipe_hnd, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32, SVCCTL_STATE_ALL, &num_services, &services ); - + if ( !W_ERROR_IS_OK(result) ) { d_fprintf(stderr, "Failed to enumerate services. [%s]\n", dos_errstr(result)); goto done; } - + if ( num_services == 0 ) d_printf("No services returned\n"); - + for ( i=0; i<num_services; i++ ) { rpcstr_pull( servicename, services[i].servicename.buffer, sizeof(servicename), -1, STR_TERMINATE ); rpcstr_pull( displayname, services[i].displayname.buffer, sizeof(displayname), -1, STR_TERMINATE ); - + d_printf("%-20s \"%s\"\n", servicename, displayname); } -done: +done: rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL); - + return werror_to_ntstatus(result); -} +} /******************************************************************** ********************************************************************/ static NTSTATUS rpc_service_status_internal(const DOM_SID *domain_sid, - const char *domain_name, + const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, int argc, const char **argv ) { POLICY_HND hSCM, hService; WERROR result = WERR_GENERAL_FAILURE; - fstring servicename; + NTSTATUS status; SERVICE_STATUS service_status; SERVICE_CONFIG config; fstring ascii_string; - + const char *server_name; + if (argc != 1 ) { d_printf("Usage: net rpc service status <service>\n"); return NT_STATUS_OK; } - fstrcpy( servicename, argv[0] ); - /* Open the Service Control Manager */ - - result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE ); - if ( !W_ERROR_IS_OK(result) ) { + CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd); + NT_STATUS_HAVE_NO_MEMORY(server_name); + + status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx, + server_name, + NULL, + SC_RIGHT_MGR_ENUMERATE_SERVICE, + &hSCM, + &result); + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); return werror_to_ntstatus(result); } - + /* Open the Service */ - - result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, &hSCM, &hService, servicename, - (SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG) ); - if ( !W_ERROR_IS_OK(result) ) { + status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx, + &hSCM, + argv[0], + (SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG), + &hService, + &result); + + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result)); goto done; } - + /* get the status */ - result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status ); - if ( !W_ERROR_IS_OK(result) ) { + status = rpccli_svcctl_QueryServiceStatus(pipe_hnd, mem_ctx, + &hService, + &service_status, + &result); + + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { d_fprintf(stderr, "Query status request failed. [%s]\n", dos_errstr(result)); goto done; } - - d_printf("%s service is %s.\n", servicename, svc_status_string(service_status.state)); + + d_printf("%s service is %s.\n", argv[0], svc_status_string(service_status.state)); /* get the config */ @@ -284,28 +327,30 @@ static NTSTATUS rpc_service_status_internal(const DOM_SID *domain_sid, d_printf("\tDisplay Name = %s\n", ascii_string); } -done: +done: rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL); rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL); return werror_to_ntstatus(result); -} +} /******************************************************************** ********************************************************************/ static NTSTATUS rpc_service_stop_internal(const DOM_SID *domain_sid, - const char *domain_name, + const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, int argc, const char **argv ) { POLICY_HND hSCM; WERROR result = WERR_GENERAL_FAILURE; + NTSTATUS status; fstring servicename; - + const char *server_name; + if (argc != 1 ) { d_printf("Usage: net rpc service status <service>\n"); return NT_STATUS_OK; @@ -314,36 +359,45 @@ static NTSTATUS rpc_service_stop_internal(const DOM_SID *domain_sid, fstrcpy( servicename, argv[0] ); /* Open the Service Control Manager */ - - result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE ); - if ( !W_ERROR_IS_OK(result) ) { + CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd); + NT_STATUS_HAVE_NO_MEMORY(server_name); + + status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx, + server_name, + NULL, + SC_RIGHT_MGR_ENUMERATE_SERVICE, + &hSCM, + &result); + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); return werror_to_ntstatus(result); } - - result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename, + + result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename, SVCCTL_CONTROL_STOP, SVCCTL_STOPPED ); - + rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL); - + return werror_to_ntstatus(result); -} +} /******************************************************************** ********************************************************************/ static NTSTATUS rpc_service_pause_internal(const DOM_SID *domain_sid, - const char *domain_name, + const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, int argc, const char **argv ) { POLICY_HND hSCM; WERROR result = WERR_GENERAL_FAILURE; + NTSTATUS status; fstring servicename; - + const char *server_name; + if (argc != 1 ) { d_printf("Usage: net rpc service status <service>\n"); return NT_STATUS_OK; @@ -352,36 +406,45 @@ static NTSTATUS rpc_service_pause_internal(const DOM_SID *domain_sid, fstrcpy( servicename, argv[0] ); /* Open the Service Control Manager */ - - result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE ); - if ( !W_ERROR_IS_OK(result) ) { + CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd); + NT_STATUS_HAVE_NO_MEMORY(server_name); + + status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx, + server_name, + NULL, + SC_RIGHT_MGR_ENUMERATE_SERVICE, + &hSCM, + &result); + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); return werror_to_ntstatus(result); } - - result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename, + + result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename, SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED ); - + rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL); - + return werror_to_ntstatus(result); -} +} /******************************************************************** ********************************************************************/ static NTSTATUS rpc_service_resume_internal(const DOM_SID *domain_sid, - const char *domain_name, + const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, int argc, const char **argv ) { POLICY_HND hSCM; WERROR result = WERR_GENERAL_FAILURE; + NTSTATUS status; fstring servicename; - + const char *server_name; + if (argc != 1 ) { d_printf("Usage: net rpc service status <service>\n"); return NT_STATUS_OK; @@ -390,78 +453,100 @@ static NTSTATUS rpc_service_resume_internal(const DOM_SID *domain_sid, fstrcpy( servicename, argv[0] ); /* Open the Service Control Manager */ - - result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE ); - if ( !W_ERROR_IS_OK(result) ) { + CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd); + NT_STATUS_HAVE_NO_MEMORY(server_name); + + status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx, + server_name, + NULL, + SC_RIGHT_MGR_ENUMERATE_SERVICE, + &hSCM, + &result); + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); return werror_to_ntstatus(result); } - - result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename, + + result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename, SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING ); - + rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL); - + return werror_to_ntstatus(result); -} +} /******************************************************************** ********************************************************************/ static NTSTATUS rpc_service_start_internal(const DOM_SID *domain_sid, - const char *domain_name, + const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, int argc, const char **argv ) { POLICY_HND hSCM, hService; WERROR result = WERR_GENERAL_FAILURE; - fstring servicename; + NTSTATUS status; uint32 state = 0; - + const char *server_name; + if (argc != 1 ) { d_printf("Usage: net rpc service status <service>\n"); return NT_STATUS_OK; } - fstrcpy( servicename, argv[0] ); - /* Open the Service Control Manager */ - - result = rpccli_svcctl_open_scm( pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE ); - if ( !W_ERROR_IS_OK(result) ) { + CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd); + NT_STATUS_HAVE_NO_MEMORY(server_name); + + status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx, + server_name, + NULL, + SC_RIGHT_MGR_ENUMERATE_SERVICE, + &hSCM, + &result); + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); return werror_to_ntstatus(result); } - + /* Open the Service */ - - result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, &hSCM, &hService, - servicename, SC_RIGHT_SVC_START ); - if ( !W_ERROR_IS_OK(result) ) { + status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx, + &hSCM, + argv[0], + SC_RIGHT_SVC_START, + &hService, + &result); + + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result)); goto done; } - + /* get the status */ - result = rpccli_svcctl_start_service(pipe_hnd, mem_ctx, &hService, NULL, 0 ); - if ( !W_ERROR_IS_OK(result) ) { + status = rpccli_svcctl_StartServiceW(pipe_hnd, mem_ctx, + &hService, + 0, + NULL, + &result); + + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { d_fprintf(stderr, "Query status request failed. [%s]\n", dos_errstr(result)); goto done; } - - result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, servicename, SVCCTL_RUNNING, &state ); - + + result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, argv[0], SVCCTL_RUNNING, &state ); + if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) ) - d_printf("Successfully started service: %s\n", servicename ); + d_printf("Successfully started service: %s\n", argv[0] ); else - d_fprintf(stderr, "Failed to start service: %s [%s]\n", servicename, dos_errstr(result) ); - -done: + d_fprintf(stderr, "Failed to start service: %s [%s]\n", argv[0], dos_errstr(result) ); + +done: rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL); rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL); @@ -473,7 +558,7 @@ done: static int rpc_service_list( int argc, const char **argv ) { - return run_rpc_command( NULL, PI_SVCCTL, 0, + return run_rpc_command( NULL, PI_SVCCTL, 0, rpc_service_list_internal, argc, argv ); } @@ -482,7 +567,7 @@ static int rpc_service_list( int argc, const char **argv ) static int rpc_service_start( int argc, const char **argv ) { - return run_rpc_command( NULL, PI_SVCCTL, 0, + return run_rpc_command( NULL, PI_SVCCTL, 0, rpc_service_start_internal, argc, argv ); } @@ -491,7 +576,7 @@ static int rpc_service_start( int argc, const char **argv ) static int rpc_service_stop( int argc, const char **argv ) { - return run_rpc_command( NULL, PI_SVCCTL, 0, + return run_rpc_command( NULL, PI_SVCCTL, 0, rpc_service_stop_internal, argc, argv ); } @@ -500,7 +585,7 @@ static int rpc_service_stop( int argc, const char **argv ) static int rpc_service_resume( int argc, const char **argv ) { - return run_rpc_command( NULL, PI_SVCCTL, 0, + return run_rpc_command( NULL, PI_SVCCTL, 0, rpc_service_resume_internal, argc, argv ); } @@ -509,7 +594,7 @@ static int rpc_service_resume( int argc, const char **argv ) static int rpc_service_pause( int argc, const char **argv ) { - return run_rpc_command( NULL, PI_SVCCTL, 0, + return run_rpc_command( NULL, PI_SVCCTL, 0, rpc_service_pause_internal, argc, argv ); } @@ -518,7 +603,7 @@ static int rpc_service_pause( int argc, const char **argv ) static int rpc_service_status( int argc, const char **argv ) { - return run_rpc_command( NULL, PI_SVCCTL, 0, + return run_rpc_command( NULL, PI_SVCCTL, 0, rpc_service_status_internal, argc, argv ); } @@ -533,14 +618,14 @@ static int net_help_service( int argc, const char **argv ) d_printf("net rpc service pause <service> Pause a service\n"); d_printf("net rpc service resume <service> Resume a paused service\n"); d_printf("net rpc service status <service> View the current status of a service\n"); - + return -1; } /******************************************************************** ********************************************************************/ -int net_rpc_service(int argc, const char **argv) +int net_rpc_service(int argc, const char **argv) { struct functable func[] = { {"list", rpc_service_list}, @@ -551,9 +636,9 @@ int net_rpc_service(int argc, const char **argv) {"status", rpc_service_status}, {NULL, NULL} }; - + if ( argc ) return net_run_function( argc, argv, func, net_help_service ); - + return net_help_service( argc, argv ); } diff --git a/source3/utils/net_rpc_sh_acct.c b/source3/utils/net_rpc_sh_acct.c index ac0ffca1f3..57640ca3a8 100644 --- a/source3/utils/net_rpc_sh_acct.c +++ b/source3/utils/net_rpc_sh_acct.c @@ -31,39 +31,46 @@ static NTSTATUS rpc_sh_acct_do(TALLOC_CTX *mem_ctx, int argc, const char **argv, int (*fn)(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, - SAM_UNK_INFO_1 *i1, - SAM_UNK_INFO_3 *i3, - SAM_UNK_INFO_12 *i12, + struct samr_DomInfo1 *i1, + struct samr_DomInfo3 *i3, + struct samr_DomInfo12 *i12, int argc, const char **argv)) { POLICY_HND connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - SAM_UNK_CTR ctr1, ctr3, ctr12; + union samr_DomainInfo *info1 = NULL; + union samr_DomainInfo *info3 = NULL; + union samr_DomainInfo *info12 = NULL; int store; ZERO_STRUCT(connect_pol); ZERO_STRUCT(domain_pol); /* Get sam policy handle */ - - result = rpccli_samr_connect(pipe_hnd, mem_ctx, - MAXIMUM_ALLOWED_ACCESS, - &connect_pol); + + result = rpccli_samr_Connect2(pipe_hnd, mem_ctx, + pipe_hnd->cli->desthost, + MAXIMUM_ALLOWED_ACCESS, + &connect_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } /* Get domain policy handle */ - - result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol, - MAXIMUM_ALLOWED_ACCESS, - ctx->domain_sid, &domain_pol); + + result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, + &connect_pol, + MAXIMUM_ALLOWED_ACCESS, + ctx->domain_sid, + &domain_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } - result = rpccli_samr_query_dom_info(pipe_hnd, mem_ctx, &domain_pol, - 1, &ctr1); + result = rpccli_samr_QueryDomainInfo(pipe_hnd, mem_ctx, + &domain_pol, + 1, + &info1); if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "query_domain_info level 1 failed: %s\n", @@ -71,8 +78,10 @@ static NTSTATUS rpc_sh_acct_do(TALLOC_CTX *mem_ctx, goto done; } - result = rpccli_samr_query_dom_info(pipe_hnd, mem_ctx, &domain_pol, - 3, &ctr3); + result = rpccli_samr_QueryDomainInfo(pipe_hnd, mem_ctx, + &domain_pol, + 3, + &info3); if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "query_domain_info level 3 failed: %s\n", @@ -80,8 +89,10 @@ static NTSTATUS rpc_sh_acct_do(TALLOC_CTX *mem_ctx, goto done; } - result = rpccli_samr_query_dom_info(pipe_hnd, mem_ctx, &domain_pol, - 12, &ctr12); + result = rpccli_samr_QueryDomainInfo(pipe_hnd, mem_ctx, + &domain_pol, + 12, + &info12); if (!NT_STATUS_IS_OK(result)) { d_fprintf(stderr, "query_domain_info level 12 failed: %s\n", @@ -89,8 +100,8 @@ static NTSTATUS rpc_sh_acct_do(TALLOC_CTX *mem_ctx, goto done; } - store = fn(mem_ctx, ctx, &ctr1.info.inf1, &ctr3.info.inf3, - &ctr12.info.inf12, argc, argv); + store = fn(mem_ctx, ctx, &info1->info1, &info3->info3, + &info12->info12, argc, argv); if (store <= 0) { /* Don't save anything */ @@ -99,16 +110,22 @@ static NTSTATUS rpc_sh_acct_do(TALLOC_CTX *mem_ctx, switch (store) { case 1: - result = rpccli_samr_set_domain_info(pipe_hnd, mem_ctx, - &domain_pol, 1, &ctr1); + result = rpccli_samr_SetDomainInfo(pipe_hnd, mem_ctx, + &domain_pol, + 1, + info1); break; case 3: - result = rpccli_samr_set_domain_info(pipe_hnd, mem_ctx, - &domain_pol, 3, &ctr3); + result = rpccli_samr_SetDomainInfo(pipe_hnd, mem_ctx, + &domain_pol, + 3, + info3); break; case 12: - result = rpccli_samr_set_domain_info(pipe_hnd, mem_ctx, - &domain_pol, 12, &ctr12); + result = rpccli_samr_SetDomainInfo(pipe_hnd, mem_ctx, + &domain_pol, + 12, + info12); break; default: d_fprintf(stderr, "Got unexpected info level %d\n", store); @@ -118,18 +135,19 @@ static NTSTATUS rpc_sh_acct_do(TALLOC_CTX *mem_ctx, done: if (is_valid_policy_hnd(&domain_pol)) { - rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol); + rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol); } if (is_valid_policy_hnd(&connect_pol)) { - rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol); + rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol); } return result; } static int account_show(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, - SAM_UNK_INFO_1 *i1, SAM_UNK_INFO_3 *i3, - SAM_UNK_INFO_12 *i12, + struct samr_DomInfo1 *i1, + struct samr_DomInfo3 *i3, + struct samr_DomInfo12 *i12, int argc, const char **argv) { if (argc != 0) { @@ -137,40 +155,40 @@ static int account_show(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, return -1; } - d_printf("Minimum password length: %d\n", i1->min_length_password); - d_printf("Password history length: %d\n", i1->password_history); + d_printf("Minimum password length: %d\n", i1->min_password_length); + d_printf("Password history length: %d\n", i1->password_history_length); d_printf("Minimum password age: "); - if (!nt_time_is_zero(&i1->min_passwordage)) { - time_t t = nt_time_to_unix_abs(&i1->min_passwordage); + if (!nt_time_is_zero((NTTIME *)&i1->min_password_age)) { + time_t t = nt_time_to_unix_abs((NTTIME *)&i1->min_password_age); d_printf("%d seconds\n", (int)t); } else { d_printf("not set\n"); } d_printf("Maximum password age: "); - if (nt_time_is_set(&i1->expire)) { - time_t t = nt_time_to_unix_abs(&i1->expire); + if (nt_time_is_set((NTTIME *)&i1->max_password_age)) { + time_t t = nt_time_to_unix_abs((NTTIME *)&i1->max_password_age); d_printf("%d seconds\n", (int)t); } else { d_printf("not set\n"); } - d_printf("Bad logon attempts: %d\n", i12->bad_attempt_lockout); + d_printf("Bad logon attempts: %d\n", i12->lockout_threshold); - if (i12->bad_attempt_lockout != 0) { + if (i12->lockout_threshold != 0) { d_printf("Account lockout duration: "); - if (nt_time_is_set(&i12->duration)) { - time_t t = nt_time_to_unix_abs(&i12->duration); + if (nt_time_is_set(&i12->lockout_duration)) { + time_t t = nt_time_to_unix_abs(&i12->lockout_duration); d_printf("%d seconds\n", (int)t); } else { d_printf("not set\n"); } d_printf("Bad password count reset after: "); - if (nt_time_is_set(&i12->reset_count)) { - time_t t = nt_time_to_unix_abs(&i12->reset_count); + if (nt_time_is_set(&i12->lockout_window)) { + time_t t = nt_time_to_unix_abs(&i12->lockout_window); d_printf("%d seconds\n", (int)t); } else { d_printf("not set\n"); @@ -178,7 +196,7 @@ static int account_show(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, } d_printf("Disconnect users when logon hours expire: %s\n", - nt_time_is_zero(&i3->logout) ? "yes" : "no"); + nt_time_is_zero(&i3->force_logoff_time) ? "yes" : "no"); d_printf("User must logon to change password: %s\n", (i1->password_properties & 0x2) ? "yes" : "no"); @@ -195,8 +213,9 @@ static NTSTATUS rpc_sh_acct_pol_show(TALLOC_CTX *mem_ctx, } static int account_set_badpw(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, - SAM_UNK_INFO_1 *i1, SAM_UNK_INFO_3 *i3, - SAM_UNK_INFO_12 *i12, + struct samr_DomInfo1 *i1, + struct samr_DomInfo3 *i3, + struct samr_DomInfo12 *i12, int argc, const char **argv) { if (argc != 1) { @@ -204,9 +223,9 @@ static int account_set_badpw(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, return -1; } - i12->bad_attempt_lockout = atoi(argv[0]); + i12->lockout_threshold = atoi(argv[0]); d_printf("Setting bad password count to %d\n", - i12->bad_attempt_lockout); + i12->lockout_threshold); return 12; } @@ -222,8 +241,9 @@ static NTSTATUS rpc_sh_acct_set_badpw(TALLOC_CTX *mem_ctx, static int account_set_lockduration(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, - SAM_UNK_INFO_1 *i1, SAM_UNK_INFO_3 *i3, - SAM_UNK_INFO_12 *i12, + struct samr_DomInfo1 *i1, + struct samr_DomInfo3 *i3, + struct samr_DomInfo12 *i12, int argc, const char **argv) { if (argc != 1) { @@ -231,9 +251,9 @@ static int account_set_lockduration(TALLOC_CTX *mem_ctx, return -1; } - unix_to_nt_time_abs(&i12->duration, atoi(argv[0])); + unix_to_nt_time_abs(&i12->lockout_duration, atoi(argv[0])); d_printf("Setting lockout duration to %d seconds\n", - (int)nt_time_to_unix_abs(&i12->duration)); + (int)nt_time_to_unix_abs(&i12->lockout_duration)); return 12; } @@ -249,8 +269,9 @@ static NTSTATUS rpc_sh_acct_set_lockduration(TALLOC_CTX *mem_ctx, static int account_set_resetduration(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, - SAM_UNK_INFO_1 *i1, SAM_UNK_INFO_3 *i3, - SAM_UNK_INFO_12 *i12, + struct samr_DomInfo1 *i1, + struct samr_DomInfo3 *i3, + struct samr_DomInfo12 *i12, int argc, const char **argv) { if (argc != 1) { @@ -258,9 +279,9 @@ static int account_set_resetduration(TALLOC_CTX *mem_ctx, return -1; } - unix_to_nt_time_abs(&i12->reset_count, atoi(argv[0])); + unix_to_nt_time_abs(&i12->lockout_window, atoi(argv[0])); d_printf("Setting bad password reset duration to %d seconds\n", - (int)nt_time_to_unix_abs(&i12->reset_count)); + (int)nt_time_to_unix_abs(&i12->lockout_window)); return 12; } @@ -276,8 +297,9 @@ static NTSTATUS rpc_sh_acct_set_resetduration(TALLOC_CTX *mem_ctx, static int account_set_minpwage(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, - SAM_UNK_INFO_1 *i1, SAM_UNK_INFO_3 *i3, - SAM_UNK_INFO_12 *i12, + struct samr_DomInfo1 *i1, + struct samr_DomInfo3 *i3, + struct samr_DomInfo12 *i12, int argc, const char **argv) { if (argc != 1) { @@ -285,9 +307,9 @@ static int account_set_minpwage(TALLOC_CTX *mem_ctx, return -1; } - unix_to_nt_time_abs(&i1->min_passwordage, atoi(argv[0])); + unix_to_nt_time_abs((NTTIME *)&i1->min_password_age, atoi(argv[0])); d_printf("Setting minimum password age to %d seconds\n", - (int)nt_time_to_unix_abs(&i1->min_passwordage)); + (int)nt_time_to_unix_abs((NTTIME *)&i1->min_password_age)); return 1; } @@ -303,8 +325,9 @@ static NTSTATUS rpc_sh_acct_set_minpwage(TALLOC_CTX *mem_ctx, static int account_set_maxpwage(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, - SAM_UNK_INFO_1 *i1, SAM_UNK_INFO_3 *i3, - SAM_UNK_INFO_12 *i12, + struct samr_DomInfo1 *i1, + struct samr_DomInfo3 *i3, + struct samr_DomInfo12 *i12, int argc, const char **argv) { if (argc != 1) { @@ -312,9 +335,9 @@ static int account_set_maxpwage(TALLOC_CTX *mem_ctx, return -1; } - unix_to_nt_time_abs(&i1->expire, atoi(argv[0])); + unix_to_nt_time_abs((NTTIME *)&i1->max_password_age, atoi(argv[0])); d_printf("Setting maximum password age to %d seconds\n", - (int)nt_time_to_unix_abs(&i1->expire)); + (int)nt_time_to_unix_abs((NTTIME *)&i1->max_password_age)); return 1; } @@ -330,8 +353,9 @@ static NTSTATUS rpc_sh_acct_set_maxpwage(TALLOC_CTX *mem_ctx, static int account_set_minpwlen(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, - SAM_UNK_INFO_1 *i1, SAM_UNK_INFO_3 *i3, - SAM_UNK_INFO_12 *i12, + struct samr_DomInfo1 *i1, + struct samr_DomInfo3 *i3, + struct samr_DomInfo12 *i12, int argc, const char **argv) { if (argc != 1) { @@ -339,9 +363,9 @@ static int account_set_minpwlen(TALLOC_CTX *mem_ctx, return -1; } - i1->min_length_password = atoi(argv[0]); + i1->min_password_length = atoi(argv[0]); d_printf("Setting minimum password length to %d\n", - i1->min_length_password); + i1->min_password_length); return 1; } @@ -357,8 +381,9 @@ static NTSTATUS rpc_sh_acct_set_minpwlen(TALLOC_CTX *mem_ctx, static int account_set_pwhistlen(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, - SAM_UNK_INFO_1 *i1, SAM_UNK_INFO_3 *i3, - SAM_UNK_INFO_12 *i12, + struct samr_DomInfo1 *i1, + struct samr_DomInfo3 *i3, + struct samr_DomInfo12 *i12, int argc, const char **argv) { if (argc != 1) { @@ -366,9 +391,9 @@ static int account_set_pwhistlen(TALLOC_CTX *mem_ctx, return -1; } - i1->password_history = atoi(argv[0]); + i1->password_history_length = atoi(argv[0]); d_printf("Setting password history length to %d\n", - i1->password_history); + i1->password_history_length); return 1; } diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 6a702fc0cf..df2bf9753b 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -1,23 +1,24 @@ -/* +/* Unix SMB/CIFS implementation. Winbind status program. Copyright (C) Tim Potter 2000-2003 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004 - Copyright (C) Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it> 2000 + Copyright (C) Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it> 2000 Copyright (C) Robert O'Callahan 2006 (added cached credential code). + Copyright (C) Kai Blin <kai@samba.org> 2008 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 3 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, see <http://www.gnu.org/licenses/>. */ @@ -28,7 +29,8 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND -#define SQUID_BUFFER_SIZE 2010 +#define INITIAL_BUFFER_SIZE 300 +#define MAX_BUFFER_SIZE 630000 enum stdio_helper_mode { SQUID_2_4_BASIC, @@ -42,28 +44,56 @@ enum stdio_helper_mode { NUM_HELPER_MODES }; -typedef void (*stdio_helper_function)(enum stdio_helper_mode stdio_helper_mode, - char *buf, int length); +enum ntlm_auth_cli_state { + CLIENT_INITIAL = 0, + CLIENT_RESPONSE, + CLIENT_FINISHED, + CLIENT_ERROR +}; + +enum ntlm_auth_svr_state { + SERVER_INITIAL = 0, + SERVER_CHALLENGE, + SERVER_FINISHED, + SERVER_ERROR +}; + +struct ntlm_auth_state { + TALLOC_CTX *mem_ctx; + enum stdio_helper_mode helper_mode; + enum ntlm_auth_cli_state cli_state; + enum ntlm_auth_svr_state svr_state; + struct ntlmssp_state *ntlmssp_state; + uint32_t neg_flags; + char *want_feature_list; + bool have_session_key; + DATA_BLOB session_key; + DATA_BLOB initial_message; +}; + +typedef void (*stdio_helper_function)(struct ntlm_auth_state *state, char *buf, + int length); -static void manage_squid_basic_request (enum stdio_helper_mode stdio_helper_mode, +static void manage_squid_basic_request (struct ntlm_auth_state *state, char *buf, int length); -static void manage_squid_ntlmssp_request (enum stdio_helper_mode stdio_helper_mode, - char *buf, int length); +static void manage_squid_ntlmssp_request (struct ntlm_auth_state *state, + char *buf, int length); -static void manage_client_ntlmssp_request (enum stdio_helper_mode stdio_helper_mode, - char *buf, int length); +static void manage_client_ntlmssp_request (struct ntlm_auth_state *state, + char *buf, int length); -static void manage_gss_spnego_request (enum stdio_helper_mode stdio_helper_mode, - char *buf, int length); +static void manage_gss_spnego_request (struct ntlm_auth_state *state, + char *buf, int length); -static void manage_gss_spnego_client_request (enum stdio_helper_mode stdio_helper_mode, - char *buf, int length); +static void manage_gss_spnego_client_request (struct ntlm_auth_state *state, + char *buf, int length); -static void manage_ntlm_server_1_request (enum stdio_helper_mode stdio_helper_mode, - char *buf, int length); +static void manage_ntlm_server_1_request (struct ntlm_auth_state *state, + char *buf, int length); -static void manage_ntlm_change_password_1_request(enum stdio_helper_mode helper_mode, char *buf, int length); +static void manage_ntlm_change_password_1_request(struct ntlm_auth_state *state, + char *buf, int length); static const struct { enum stdio_helper_mode mode; @@ -123,7 +153,7 @@ static char winbind_separator(void) d_printf("winbind separator was NULL!\n"); return *lp_winbind_separator(); } - + return sep; } @@ -388,7 +418,7 @@ NTSTATUS contact_winbind_auth_crap(const char *username, } if (flags & WBFLAG_PAM_UNIX_NAME) { - *unix_name = SMB_STRDUP((char *)response.extra_data.data); + *unix_name = SMB_STRDUP(response.data.auth.unix_username); if (!*unix_name) { winbindd_free_response(&response); return NT_STATUS_NO_MEMORY; @@ -679,14 +709,9 @@ static NTSTATUS do_ccache_ntlm_auth(DATA_BLOB initial_msg, DATA_BLOB challenge_m return NT_STATUS_MORE_PROCESSING_REQUIRED; } -static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode, - char *buf, int length) +static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, + char *buf, int length) { - static NTLMSSP_STATE *ntlmssp_state = NULL; - static char* want_feature_list = NULL; - static uint32 neg_flags = 0; - static bool have_session_key = False; - static DATA_BLOB session_key; DATA_BLOB request, reply; NTSTATUS nt_status; @@ -699,8 +724,9 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod if (strlen(buf) > 3) { if(strncmp(buf, "SF ", 3) == 0){ DEBUG(10, ("Setting flags to negotioate\n")); - SAFE_FREE(want_feature_list); - want_feature_list = SMB_STRNDUP(buf+3, strlen(buf)-3); + TALLOC_FREE(state->want_feature_list); + state->want_feature_list = talloc_strdup(state->mem_ctx, + buf+3); x_fprintf(x_stdout, "OK\n"); return; } @@ -710,9 +736,11 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod } if ((strncmp(buf, "PW ", 3) == 0)) { - /* The calling application wants us to use a local password (rather than winbindd) */ + /* The calling application wants us to use a local password + * (rather than winbindd) */ - opt_password = SMB_STRNDUP((const char *)request.data, request.length); + opt_password = SMB_STRNDUP((const char *)request.data, + request.length); if (opt_password == NULL) { DEBUG(1, ("Out of memory\n")); @@ -727,25 +755,33 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod } if (strncmp(buf, "YR", 2) == 0) { - if (ntlmssp_state) - ntlmssp_end(&ntlmssp_state); + if (state->ntlmssp_state) + ntlmssp_end(&state->ntlmssp_state); + state->svr_state = SERVER_INITIAL; } else if (strncmp(buf, "KK", 2) == 0) { - + /* No special preprocessing required */ } else if (strncmp(buf, "GF", 2) == 0) { DEBUG(10, ("Requested negotiated NTLMSSP flags\n")); - x_fprintf(x_stdout, "GF 0x%08lx\n", have_session_key?neg_flags:0l); + + if (state->svr_state == SERVER_FINISHED) { + x_fprintf(x_stdout, "GF 0x%08x\n", state->neg_flags); + } + else { + x_fprintf(x_stdout, "BH\n"); + } data_blob_free(&request); return; } else if (strncmp(buf, "GK", 2) == 0) { DEBUG(10, ("Requested NTLMSSP session key\n")); - if(have_session_key) { - char *key64 = base64_encode_data_blob(session_key); + if(state->have_session_key) { + char *key64 = base64_encode_data_blob(state->mem_ctx, + state->session_key); x_fprintf(x_stdout, "GK %s\n", key64?key64:"<NULL>"); TALLOC_FREE(key64); } else { x_fprintf(x_stdout, "BH\n"); } - + data_blob_free(&request); return; } else { @@ -754,65 +790,62 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod return; } - if (!ntlmssp_state) { - if (!NT_STATUS_IS_OK(nt_status = ntlm_auth_start_ntlmssp_server(&ntlmssp_state))) { + if (!state->ntlmssp_state) { + nt_status = ntlm_auth_start_ntlmssp_server( + &state->ntlmssp_state); + if (!NT_STATUS_IS_OK(nt_status)) { x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); return; } - ntlmssp_want_feature_list(ntlmssp_state, want_feature_list); + ntlmssp_want_feature_list(state->ntlmssp_state, + state->want_feature_list); } DEBUG(10, ("got NTLMSSP packet:\n")); dump_data(10, request.data, request.length); - nt_status = ntlmssp_update(ntlmssp_state, request, &reply); - + nt_status = ntlmssp_update(state->ntlmssp_state, request, &reply); + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - char *reply_base64 = base64_encode_data_blob(reply); + char *reply_base64 = base64_encode_data_blob(state->mem_ctx, + reply); x_fprintf(x_stdout, "TT %s\n", reply_base64); TALLOC_FREE(reply_base64); data_blob_free(&reply); + state->svr_state = SERVER_CHALLENGE; DEBUG(10, ("NTLMSSP challenge\n")); } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) { x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status))); - ntlmssp_end(&ntlmssp_state); + ntlmssp_end(&state->ntlmssp_state); } else if (!NT_STATUS_IS_OK(nt_status)) { x_fprintf(x_stdout, "NA %s\n", nt_errstr(nt_status)); DEBUG(10, ("NTLMSSP %s\n", nt_errstr(nt_status))); } else { - x_fprintf(x_stdout, "AF %s\n", (char *)ntlmssp_state->auth_context); + x_fprintf(x_stdout, "AF %s\n", + (char *)state->ntlmssp_state->auth_context); DEBUG(10, ("NTLMSSP OK!\n")); - - if(have_session_key) - data_blob_free(&session_key); - session_key = data_blob(ntlmssp_state->session_key.data, - ntlmssp_state->session_key.length); - neg_flags = ntlmssp_state->neg_flags; - have_session_key = True; + + if(state->have_session_key) + data_blob_free(&state->session_key); + state->session_key = data_blob( + state->ntlmssp_state->session_key.data, + state->ntlmssp_state->session_key.length); + state->neg_flags = state->ntlmssp_state->neg_flags; + state->have_session_key = true; + state->svr_state = SERVER_FINISHED; } data_blob_free(&request); } -static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode, - char *buf, int length) +static void manage_client_ntlmssp_request(struct ntlm_auth_state *state, + char *buf, int length) { - /* The statics here are *HORRIBLE* and this entire concept - needs to be rewritten. Essentially it's using these statics - as the state in a state machine. BLEEEGH ! JRA. */ - - static NTLMSSP_STATE *ntlmssp_state = NULL; - static DATA_BLOB initial_message; - static char* want_feature_list = NULL; - static uint32 neg_flags = 0; - static bool have_session_key = False; - static DATA_BLOB session_key; DATA_BLOB request, reply; NTSTATUS nt_status; - bool first = False; - + if (!opt_username || !*opt_username) { x_fprintf(x_stderr, "username must be specified!\n\n"); exit(1); @@ -827,8 +860,9 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo if (strlen(buf) > 3) { if(strncmp(buf, "SF ", 3) == 0) { DEBUG(10, ("Looking for flags to negotiate\n")); - SAFE_FREE(want_feature_list); - want_feature_list = SMB_STRNDUP(buf+3, strlen(buf)-3); + talloc_free(state->want_feature_list); + state->want_feature_list = talloc_strdup(state->mem_ctx, + buf+3); x_fprintf(x_stdout, "OK\n"); return; } @@ -840,7 +874,8 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo if (strncmp(buf, "PW ", 3) == 0) { /* We asked for a password and obviously got it :-) */ - opt_password = SMB_STRNDUP((const char *)request.data, request.length); + opt_password = SMB_STRNDUP((const char *)request.data, + request.length); if (opt_password == NULL) { DEBUG(1, ("Out of memory\n")); @@ -854,8 +889,8 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo return; } - if (!ntlmssp_state && use_cached_creds) { - /* check whether credentials are usable. */ + if (!state->ntlmssp_state && use_cached_creds) { + /* check whether cached credentials are usable. */ DATA_BLOB empty_blob = data_blob_null; nt_status = do_ccache_ntlm_auth(empty_blob, empty_blob, NULL); @@ -866,30 +901,39 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo } if (opt_password == NULL && !use_cached_creds) { - /* Request a password from the calling process. After - sending it, the calling process should retry asking for the negotiate. */ - + sending it, the calling process should retry asking for the + negotiate. */ + DEBUG(10, ("Requesting password\n")); x_fprintf(x_stdout, "PW\n"); return; } if (strncmp(buf, "YR", 2) == 0) { - if (ntlmssp_state) - ntlmssp_end(&ntlmssp_state); + if (state->ntlmssp_state) + ntlmssp_end(&state->ntlmssp_state); + state->cli_state = CLIENT_INITIAL; } else if (strncmp(buf, "TT", 2) == 0) { - + /* No special preprocessing required */ } else if (strncmp(buf, "GF", 2) == 0) { DEBUG(10, ("Requested negotiated NTLMSSP flags\n")); - x_fprintf(x_stdout, "GF 0x%08lx\n", have_session_key?neg_flags:0l); + + if(state->cli_state == CLIENT_FINISHED) { + x_fprintf(x_stdout, "GF 0x%08x\n", state->neg_flags); + } + else { + x_fprintf(x_stdout, "BH\n"); + } + data_blob_free(&request); return; } else if (strncmp(buf, "GK", 2) == 0 ) { DEBUG(10, ("Requested session key\n")); - if(have_session_key) { - char *key64 = base64_encode_data_blob(session_key); + if(state->cli_state == CLIENT_FINISHED) { + char *key64 = base64_encode_data_blob(state->mem_ctx, + state->session_key); x_fprintf(x_stdout, "GK %s\n", key64?key64:"<NULL>"); TALLOC_FREE(key64); } @@ -905,67 +949,75 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo return; } - if (!ntlmssp_state) { - if (!NT_STATUS_IS_OK(nt_status = ntlm_auth_start_ntlmssp_client(&ntlmssp_state))) { + if (!state->ntlmssp_state) { + nt_status = ntlm_auth_start_ntlmssp_client( + &state->ntlmssp_state); + if (!NT_STATUS_IS_OK(nt_status)) { x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); return; } - ntlmssp_want_feature_list(ntlmssp_state, want_feature_list); - first = True; - initial_message = data_blob_null; + ntlmssp_want_feature_list(state->ntlmssp_state, + state->want_feature_list); + state->initial_message = data_blob_null; } DEBUG(10, ("got NTLMSSP packet:\n")); dump_data(10, request.data, request.length); - if (use_cached_creds && !opt_password && !first) { - nt_status = do_ccache_ntlm_auth(initial_message, request, &reply); + if (use_cached_creds && !opt_password && + (state->cli_state == CLIENT_RESPONSE)) { + nt_status = do_ccache_ntlm_auth(state->initial_message, request, + &reply); } else { - nt_status = ntlmssp_update(ntlmssp_state, request, &reply); + nt_status = ntlmssp_update(state->ntlmssp_state, request, + &reply); } - + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - char *reply_base64 = base64_encode_data_blob(reply); - if (first) { + char *reply_base64 = base64_encode_data_blob(state->mem_ctx, + reply); + if (state->cli_state == CLIENT_INITIAL) { x_fprintf(x_stdout, "YR %s\n", reply_base64); - } else { - x_fprintf(x_stdout, "KK %s\n", reply_base64); - } - TALLOC_FREE(reply_base64); - if (first) { - initial_message = reply; + state->initial_message = reply; + state->cli_state = CLIENT_RESPONSE; } else { + x_fprintf(x_stdout, "KK %s\n", reply_base64); data_blob_free(&reply); } + TALLOC_FREE(reply_base64); DEBUG(10, ("NTLMSSP challenge\n")); } else if (NT_STATUS_IS_OK(nt_status)) { - char *reply_base64 = base64_encode_data_blob(reply); + char *reply_base64 = base64_encode_data_blob(talloc_tos(), + reply); x_fprintf(x_stdout, "AF %s\n", reply_base64); TALLOC_FREE(reply_base64); - if(have_session_key) - data_blob_free(&session_key); + if(state->have_session_key) + data_blob_free(&state->session_key); - session_key = data_blob(ntlmssp_state->session_key.data, - ntlmssp_state->session_key.length); - neg_flags = ntlmssp_state->neg_flags; - have_session_key = True; + state->session_key = data_blob( + state->ntlmssp_state->session_key.data, + state->ntlmssp_state->session_key.length); + state->neg_flags = state->ntlmssp_state->neg_flags; + state->have_session_key = true; DEBUG(10, ("NTLMSSP OK!\n")); - if (ntlmssp_state) - ntlmssp_end(&ntlmssp_state); + state->cli_state = CLIENT_FINISHED; + if (state->ntlmssp_state) + ntlmssp_end(&state->ntlmssp_state); } else { x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status))); - if (ntlmssp_state) - ntlmssp_end(&ntlmssp_state); + state->cli_state = CLIENT_ERROR; + if (state->ntlmssp_state) + ntlmssp_end(&state->ntlmssp_state); } data_blob_free(&request); } -static void manage_squid_basic_request(enum stdio_helper_mode stdio_helper_mode, - char *buf, int length) +static void manage_squid_basic_request(struct ntlm_auth_state *state, + char *buf, int length) { char *user, *pass; user=buf; @@ -979,7 +1031,7 @@ static void manage_squid_basic_request(enum stdio_helper_mode stdio_helper_mode, *pass='\0'; pass++; - if (stdio_helper_mode == SQUID_2_5_BASIC) { + if (state->helper_mode == SQUID_2_5_BASIC) { rfc1738_unescape(user); rfc1738_unescape(pass); } @@ -1039,7 +1091,7 @@ static void offer_gss_spnego_mechs(void) { return; } - reply_base64 = base64_encode_data_blob(token); + reply_base64 = base64_encode_data_blob(talloc_tos(), token); x_fprintf(x_stdout, "TT %s *\n", reply_base64); TALLOC_FREE(reply_base64); @@ -1048,8 +1100,8 @@ static void offer_gss_spnego_mechs(void) { return; } -static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode, - char *buf, int length) +static void manage_gss_spnego_request(struct ntlm_auth_state *state, + char *buf, int length) { static NTLMSSP_STATE *ntlmssp_state = NULL; SPNEGO_DATA request, response; @@ -1163,7 +1215,7 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode, char *principal; DATA_BLOB ap_rep; DATA_BLOB session_key; - PAC_DATA *pac_data = NULL; + struct PAC_DATA *pac_data = NULL; if ( request.negTokenInit.mechToken.data == NULL ) { DEBUG(1, ("Client did not provide Kerberos data\n")); @@ -1276,7 +1328,7 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode, return; } - reply_base64 = base64_encode_data_blob(token); + reply_base64 = base64_encode_data_blob(talloc_tos(), token); x_fprintf(x_stdout, "%s %s %s\n", reply_code, reply_base64, reply_argument); @@ -1343,7 +1395,7 @@ static bool manage_client_ntlmssp_init(SPNEGO_DATA spnego) write_spnego_data(&to_server, &spnego); data_blob_free(&spnego.negTokenInit.mechToken); - to_server_base64 = base64_encode_data_blob(to_server); + to_server_base64 = base64_encode_data_blob(talloc_tos(), to_server); data_blob_free(&to_server); x_fprintf(x_stdout, "KK %s\n", to_server_base64); TALLOC_FREE(to_server_base64); @@ -1401,7 +1453,7 @@ static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego) write_spnego_data(&to_server, &spnego); data_blob_free(&request); - to_server_base64 = base64_encode_data_blob(to_server); + to_server_base64 = base64_encode_data_blob(talloc_tos(), to_server); data_blob_free(&to_server); x_fprintf(x_stdout, "KK %s\n", to_server_base64); TALLOC_FREE(to_server_base64); @@ -1490,7 +1542,7 @@ static bool manage_client_krb5_init(SPNEGO_DATA spnego) return False; } - reply_base64 = base64_encode_data_blob(to_server); + reply_base64 = base64_encode_data_blob(talloc_tos(), to_server); x_fprintf(x_stdout, "KK %s *\n", reply_base64); TALLOC_FREE(reply_base64); @@ -1522,8 +1574,8 @@ static void manage_client_krb5_targ(SPNEGO_DATA spnego) #endif -static void manage_gss_spnego_client_request(enum stdio_helper_mode stdio_helper_mode, - char *buf, int length) +static void manage_gss_spnego_client_request(struct ntlm_auth_state *state, + char *buf, int length) { DATA_BLOB request; SPNEGO_DATA spnego; @@ -1660,8 +1712,8 @@ static void manage_gss_spnego_client_request(enum stdio_helper_mode stdio_helper return; } -static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mode, - char *buf, int length) +static void manage_ntlm_server_1_request(struct ntlm_auth_state *state, + char *buf, int length) { char *request, *parameter; static DATA_BLOB challenge; @@ -1853,7 +1905,8 @@ static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mod } } -static void manage_ntlm_change_password_1_request(enum stdio_helper_mode helper_mode, char *buf, int length) +static void manage_ntlm_change_password_1_request(struct ntlm_auth_state *state, + char *buf, int length) { char *request, *parameter; static DATA_BLOB new_nt_pswd; @@ -2063,57 +2116,93 @@ static void manage_ntlm_change_password_1_request(enum stdio_helper_mode helper_ } } -static void manage_squid_request(enum stdio_helper_mode helper_mode, stdio_helper_function fn) +static void manage_squid_request(struct ntlm_auth_state *state, + stdio_helper_function fn) { - char buf[SQUID_BUFFER_SIZE+1]; - int length; + char *buf; + char tmp[INITIAL_BUFFER_SIZE+1]; + int length, buf_size = 0; char *c; - static bool err; - /* this is not a typo - x_fgets doesn't work too well under squid */ - if (fgets(buf, sizeof(buf)-1, stdin) == NULL) { - if (ferror(stdin)) { - DEBUG(1, ("fgets() failed! dying..... errno=%d (%s)\n", ferror(stdin), - strerror(ferror(stdin)))); - - exit(1); /* BIIG buffer */ - } - exit(0); - } - - c=(char *)memchr(buf,'\n',sizeof(buf)-1); - if (c) { - *c = '\0'; - length = c-buf; - } else { - err = 1; - return; - } - if (err) { - DEBUG(2, ("Oversized message\n")); + buf = talloc_strdup(state->mem_ctx, ""); + if (!buf) { + DEBUG(0, ("Failed to allocate input buffer.\n")); x_fprintf(x_stderr, "ERR\n"); - err = 0; - return; + exit(1); } + do { + + /* this is not a typo - x_fgets doesn't work too well under + * squid */ + if (fgets(tmp, sizeof(tmp)-1, stdin) == NULL) { + if (ferror(stdin)) { + DEBUG(1, ("fgets() failed! dying..... errno=%d " + "(%s)\n", ferror(stdin), + strerror(ferror(stdin)))); + + exit(1); + } + exit(0); + } + + buf = talloc_strdup_append_buffer(buf, tmp); + buf_size += INITIAL_BUFFER_SIZE; + + if (buf_size > MAX_BUFFER_SIZE) { + DEBUG(2, ("Oversized message\n")); + x_fprintf(x_stderr, "ERR\n"); + talloc_free(buf); + return; + } + + c = strchr(buf, '\n'); + } while (c == NULL); + + *c = '\0'; + length = c-buf; + DEBUG(10, ("Got '%s' from squid (length: %d).\n",buf,length)); if (buf[0] == '\0') { DEBUG(2, ("Invalid Request\n")); x_fprintf(x_stderr, "ERR\n"); + talloc_free(buf); return; } - - fn(helper_mode, buf, length); + + fn(state, buf, length); + talloc_free(buf); } static void squid_stream(enum stdio_helper_mode stdio_mode, stdio_helper_function fn) { + TALLOC_CTX *mem_ctx; + struct ntlm_auth_state *state; + /* initialize FDescs */ x_setbuf(x_stdout, NULL); x_setbuf(x_stderr, NULL); + + mem_ctx = talloc_init("ntlm_auth"); + if (!mem_ctx) { + DEBUG(0, ("squid_stream: Failed to create talloc context\n")); + x_fprintf(x_stderr, "ERR\n"); + exit(1); + } + + state = talloc_zero(mem_ctx, struct ntlm_auth_state); + if (!state) { + DEBUG(0, ("squid_stream: Failed to talloc ntlm_auth_state\n")); + x_fprintf(x_stderr, "ERR\n"); + exit(1); + } + + state->mem_ctx = mem_ctx; + state->helper_mode = stdio_mode; + while(1) { - manage_squid_request(stdio_mode, fn); + manage_squid_request(state, fn); } } @@ -2233,7 +2322,8 @@ enum { { "use-cached-creds", 0, POPT_ARG_NONE, &use_cached_creds, OPT_USE_CACHED_CREDS, "Use cached credentials if no password is given"}, { "diagnostics", 0, POPT_ARG_NONE, &diagnostics, OPT_DIAGNOSTICS, "Perform diagnostics on the authentictaion chain"}, { "require-membership-of", 0, POPT_ARG_STRING, &require_membership_of, OPT_REQUIRE_MEMBERSHIP, "Require that a user be a member of this group (either name or SID) for authentication to succeed" }, - POPT_COMMON_SAMBA + POPT_COMMON_CONFIGFILE + POPT_COMMON_VERSION POPT_TABLEEND }; @@ -2241,14 +2331,6 @@ enum { load_case_tables(); dbf = x_stderr; - - /* Samba client initialisation */ - - if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, True)) { - d_fprintf(stderr, "ntlm_auth: error opening config file %s. Error was %s\n", - get_dyn_CONFIGFILE(), strerror(errno)); - exit(1); - } /* Parse options */ @@ -2261,6 +2343,18 @@ enum { return 1; } + while((opt = poptGetNextOpt(pc)) != -1) { + /* Get generic config options like --configfile */ + } + + poptFreeContext(pc); + + if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, True)) { + d_fprintf(stderr, "ntlm_auth: error opening config file %s. Error was %s\n", + get_dyn_CONFIGFILE(), strerror(errno)); + exit(1); + } + pc = poptGetContext(NULL, argc, (const char **)argv, long_options, POPT_CONTEXT_KEEP_FIRST); diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index fe0c22911e..db2eefe1e2 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -1008,6 +1008,62 @@ static bool do_dump_event_list(struct messaging_context *msg_ctx, return send_message(msg_ctx, pid, MSG_DUMP_EVENT_LIST, NULL, 0); } +static bool do_winbind_dump_domain_list(struct messaging_context *msg_ctx, + const struct server_id pid, + const int argc, const char **argv) +{ + const char *domain = NULL; + int domain_len = 0; + struct server_id myid; + uint8_t *buf = NULL; + int buf_len = 0; + + myid = pid_to_procid(sys_getpid()); + + if (argc < 1 || argc > 2) { + fprintf(stderr, "Usage: smbcontrol <dest> dump_domain_list " + "<domain>\n"); + return false; + } + + if (argc == 2) { + domain = argv[1]; + domain_len = strlen(argv[1]) + 1; + } + + messaging_register(msg_ctx, NULL, MSG_WINBIND_DUMP_DOMAIN_LIST, + print_pid_string_cb); + + buf_len = sizeof(myid)+domain_len; + buf = SMB_MALLOC_ARRAY(uint8_t, buf_len); + if (!buf) { + return false; + } + + memcpy(buf, &myid, sizeof(myid)); + memcpy(&buf[sizeof(myid)], domain, domain_len); + + if (!send_message(msg_ctx, pid, MSG_WINBIND_DUMP_DOMAIN_LIST, + buf, buf_len)) + { + SAFE_FREE(buf); + return false; + } + + wait_replies(msg_ctx, procid_to_pid(&pid) == 0); + + /* No replies were received within the timeout period */ + + SAFE_FREE(buf); + if (num_replies == 0) { + printf("No replies received\n"); + } + + messaging_deregister(msg_ctx, MSG_WINBIND_DUMP_DOMAIN_LIST, NULL); + + return num_replies; +} + static void winbind_validate_cache_cb(struct messaging_context *msg, void *private_data, uint32_t msg_type, @@ -1150,6 +1206,7 @@ static const struct { { "dump-event-list", do_dump_event_list, "Dump event list"}, { "validate-cache" , do_winbind_validate_cache, "Validate winbind's credential cache" }, + { "dump-domain-list", do_winbind_dump_domain_list, "Dump winbind domain list"}, { "noop", do_noop, "Do nothing" }, { NULL } }; diff --git a/source3/utils/smbfilter.c b/source3/utils/smbfilter.c index 8db969722a..e128e1ce34 100644 --- a/source3/utils/smbfilter.c +++ b/source3/utils/smbfilter.c @@ -169,7 +169,9 @@ static void filter_child(int c, struct sockaddr_storage *dest_ss) if (num <= 0) continue; if (c != -1 && FD_ISSET(c, &fds)) { - if (!receive_smb_raw(c, packet, 0, 0, NULL)) { + size_t len; + if (!NT_STATUS_IS_OK(receive_smb_raw( + c, packet, 0, 0, &len))) { d_printf("client closed connection\n"); exit(0); } @@ -180,7 +182,9 @@ static void filter_child(int c, struct sockaddr_storage *dest_ss) } } if (s != -1 && FD_ISSET(s, &fds)) { - if (!receive_smb_raw(s, packet, 0, 0, NULL)) { + size_t len; + if (!NT_STATUS_IS_OK(receive_smb_raw( + s, packet, 0, 0, &len))) { d_printf("server closed connection\n"); exit(0); } |