/***************************************************** return a connection to a server *******************************************************/ static struct cli_state *connect_one(const char *share) { struct cli_state *c; struct in_addr ip; NTSTATUS nt_status; zero_ip(&ip); if (!cmdline_auth_info.got_pass) { char *pass = getpass("Password: "******"?????", cmdline_auth_info.username, lp_workgroup(), cmdline_auth_info.password, 0, cmdline_auth_info.signing_state, NULL))) { return c; } else { DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status))); return NULL; } }
static struct cli_state * /* O - SMB connection */ smb_connect(const char *workgroup, /* I - Workgroup */ const char *server, /* I - Server */ const char *share, /* I - Printer */ const char *username, /* I - Username */ const char *password) /* I - Password */ { struct cli_state *c; /* New connection */ pstring myname; /* Client name */ NTSTATUS nt_status; /* * Get the names and addresses of the client and server... */ get_myname(myname); nt_status = cli_full_connection(&c, myname, server, NULL, 0, share, "?????", username, workgroup, password, 0, Undefined, NULL); if (!NT_STATUS_IS_OK(nt_status)) { fprintf(stderr, "ERROR: Connection failed with error %s\n", nt_errstr(nt_status)); return NULL; } /* * Return the new connection... */ return (c); }
NTSTATUS connect_to_ipc_krb5(struct cli_state **c, struct in_addr *server_ip, const char *server_name) { NTSTATUS nt_status; char *user_and_realm = NULL; if (!opt_password && !opt_machine_pass) { char *pass = getpass("Password:"******"IPC$", "IPC", user_and_realm, opt_workgroup, opt_password, CLI_FULL_CONNECTION_USE_KERBEROS, Undefined, NULL); SAFE_FREE(user_and_realm); if (NT_STATUS_IS_OK(nt_status)) { return nt_status; } else { DEBUG(1,("Cannot connect to server using kerberos. Error was %s\n", nt_errstr(nt_status))); return nt_status; } }
struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip, struct user_auth_info *user_info) { struct cli_state *cli; pstring myname; NTSTATUS nt_status; get_myname(myname); nt_status = cli_full_connection(&cli, myname, server, server_ip, 0, "IPC$", "IPC", user_info->username, lp_workgroup(), user_info->password, strlen(user_info->password)); if (NT_STATUS_IS_OK(nt_status)) { return cli; } else if (is_ipaddress(server)) { /* windows 9* needs a correct NMB name for connections */ fstring remote_name; if (name_status_find("*", 0, 0, *server_ip, remote_name)) { cli = get_ipc_connect(remote_name, server_ip, user_info); if (cli) return cli; } } return NULL; }
static NTSTATUS gpo_connect_server(ADS_STRUCT *ads, const char *server, const char *service, void *ret_cli) { NTSTATUS result; struct cli_state *cli; result = cli_full_connection(&cli, lp_netbios_name(), server, NULL, 0, service, "A:", ads->auth.user_name, NULL, ads->auth.password, CLI_FULL_CONNECTION_USE_KERBEROS | CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS, Undefined); if (!NT_STATUS_IS_OK(result)) { DEBUG(10,("check_refresh_gpo: " "failed to connect: %s\n", nt_errstr(result))); return result; } *(struct cli_state **) ret_cli = cli; return NT_STATUS_OK; }
static struct cli_state *connect_one(const char *share) { struct cli_state *c; struct sockaddr_storage ss; NTSTATUS nt_status; uint32_t flags = 0; zero_sockaddr(&ss); if (get_cmdline_auth_info_use_machine_account() && !set_cmdline_auth_info_machine_account_creds()) { return NULL; } if (get_cmdline_auth_info_use_kerberos()) { flags |= CLI_FULL_CONNECTION_USE_KERBEROS | CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS; } if (!get_cmdline_auth_info_got_pass()) { char *pass = getpass("Password: "******"?????", get_cmdline_auth_info_username(), lp_workgroup(), get_cmdline_auth_info_password(), flags, get_cmdline_auth_info_signing_state(), NULL); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status))); return NULL; } if (get_cmdline_auth_info_smb_encrypt()) { nt_status = cli_cm_force_encryption(c, get_cmdline_auth_info_username(), get_cmdline_auth_info_password(), lp_workgroup(), share); if (!NT_STATUS_IS_OK(nt_status)) { cli_shutdown(c); return NULL; } } return c; }
NTSTATUS connect_to_ipc_krb5(struct net_context *c, struct cli_state **cli_ctx, struct sockaddr_storage *server_ss, const char *server_name) { NTSTATUS nt_status; char *user_and_realm = NULL; /* FIXME: Should get existing kerberos ticket if possible. */ c->opt_password = net_prompt_pass(c, c->opt_user_name); if (!c->opt_password) { return NT_STATUS_NO_MEMORY; } user_and_realm = get_user_and_realm(c->opt_user_name); if (!user_and_realm) { return NT_STATUS_NO_MEMORY; } nt_status = cli_full_connection(cli_ctx, NULL, server_name, server_ss, c->opt_port, "IPC$", "IPC", user_and_realm, c->opt_workgroup, c->opt_password, CLI_FULL_CONNECTION_USE_KERBEROS, Undefined); SAFE_FREE(user_and_realm); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(1,("Cannot connect to server using kerberos. Error was %s\n", nt_errstr(nt_status))); return nt_status; } if (c->smb_encrypt) { nt_status = cli_cm_force_encryption(*cli_ctx, user_and_realm, c->opt_password, c->opt_workgroup, "IPC$"); if (!NT_STATUS_IS_OK(nt_status)) { cli_shutdown(*cli_ctx); *cli_ctx = NULL; } } return nt_status; }
static struct cli_state *connect_one(const char *share) { struct cli_state *c; NTSTATUS nt_status; uint32_t flags = 0; if (get_cmdline_auth_info_use_machine_account(smbcquotas_auth_info) && !set_cmdline_auth_info_machine_account_creds(smbcquotas_auth_info)) { return NULL; } if (get_cmdline_auth_info_use_kerberos(smbcquotas_auth_info)) { flags |= CLI_FULL_CONNECTION_USE_KERBEROS | CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS; } set_cmdline_auth_info_getpass(smbcquotas_auth_info); nt_status = cli_full_connection(&c, lp_netbios_name(), server, NULL, 0, share, "?????", get_cmdline_auth_info_username(smbcquotas_auth_info), lp_workgroup(), get_cmdline_auth_info_password(smbcquotas_auth_info), flags, get_cmdline_auth_info_signing_state(smbcquotas_auth_info)); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status))); return NULL; } if (get_cmdline_auth_info_smb_encrypt(smbcquotas_auth_info)) { nt_status = cli_cm_force_encryption(c, get_cmdline_auth_info_username(smbcquotas_auth_info), get_cmdline_auth_info_password(smbcquotas_auth_info), lp_workgroup(), share); if (!NT_STATUS_IS_OK(nt_status)) { cli_shutdown(c); return NULL; } } return c; }
NTSTATUS connect_to_ipc_krb5(struct cli_state **c, struct sockaddr_storage *server_ss, const char *server_name) { NTSTATUS nt_status; char *user_and_realm = NULL; opt_password = net_prompt_pass(opt_user_name); if (!opt_password) { return NT_STATUS_NO_MEMORY; } user_and_realm = get_user_and_realm(opt_user_name); if (!user_and_realm) { return NT_STATUS_NO_MEMORY; } nt_status = cli_full_connection(c, NULL, server_name, server_ss, opt_port, "IPC$", "IPC", user_and_realm, opt_workgroup, opt_password, CLI_FULL_CONNECTION_USE_KERBEROS, Undefined, NULL); SAFE_FREE(user_and_realm); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(1,("Cannot connect to server using kerberos. Error was %s\n", nt_errstr(nt_status))); return nt_status; } if (smb_encrypt) { nt_status = cli_cm_force_encryption(*c, user_and_realm, opt_password, opt_workgroup, "IPC$"); if (!NT_STATUS_IS_OK(nt_status)) { cli_shutdown(*c); *c = NULL; } } return nt_status; }
NTSTATUS connect_to_service(struct cli_state **c, struct in_addr *server_ip, const char *server_name, const char *service_name, const char *service_type) { NTSTATUS nt_status; if (!opt_password && !opt_machine_pass) { char *pass = getpass("Password:"******"Could not connect to server %s\n", server_name); /* Display a nicer message depending on the result */ if (NT_STATUS_V(nt_status) == NT_STATUS_V(NT_STATUS_LOGON_FAILURE)) d_fprintf(stderr, "The username or password was not correct.\n"); if (NT_STATUS_V(nt_status) == NT_STATUS_V(NT_STATUS_ACCOUNT_LOCKED_OUT)) d_fprintf(stderr, "The account was locked out.\n"); if (NT_STATUS_V(nt_status) == NT_STATUS_V(NT_STATUS_ACCOUNT_DISABLED)) d_fprintf(stderr, "The account was disabled.\n"); return nt_status; }
/**************************************************************************** connect to \\server\ipc$ anonymously ****************************************************************************/ NTSTATUS connect_to_ipc_anonymous(struct cli_state **c, struct in_addr *server_ip, const char *server_name) { NTSTATUS nt_status; nt_status = cli_full_connection(c, opt_requester_name, server_name, server_ip, opt_port, "IPC$", "IPC", "", "", "", 0, Undefined, NULL); if (NT_STATUS_IS_OK(nt_status)) { return nt_status; } else { DEBUG(1,("Cannot connect to server (anonymously). Error was %s\n", nt_errstr(nt_status))); return nt_status; } }
/**************************************************************************** connect to \\server\ipc$ using KRB5 ****************************************************************************/ NTSTATUS connect_to_ipc_krb5(struct cli_state **c, struct in_addr *server_ip, const char *server_name) { NTSTATUS nt_status; nt_status = cli_full_connection(c, NULL, server_name, server_ip, opt_port, "IPC$", "IPC", opt_user_name, opt_workgroup, opt_password, CLI_FULL_CONNECTION_USE_KERBEROS, Undefined, NULL); if (NT_STATUS_IS_OK(nt_status)) { return nt_status; } else { DEBUG(1,("Cannot connect to server using kerberos. Error was %s\n", nt_errstr(nt_status))); return nt_status; } }
NTSTATUS connect_to_ipc_anonymous(struct net_context *c, struct cli_state **cli_ctx, struct sockaddr_storage *server_ss, const char *server_name) { NTSTATUS nt_status; nt_status = cli_full_connection(cli_ctx, c->opt_requester_name, server_name, server_ss, c->opt_port, "IPC$", "IPC", "", "", "", 0, Undefined); if (NT_STATUS_IS_OK(nt_status)) { return nt_status; } else { DEBUG(1,("Cannot connect to server (anonymously). Error was %s\n", nt_errstr(nt_status))); return nt_status; } }
static int net_ads_printer_publish(int argc, const char **argv) { ADS_STRUCT *ads; ADS_STATUS rc; const char *servername, *printername; struct cli_state *cli; struct in_addr server_ip; NTSTATUS nt_status; TALLOC_CTX *mem_ctx = talloc_init("net_ads_printer_publish"); ADS_MODLIST mods = ads_init_mods(mem_ctx); char *prt_dn, *srv_dn, **srv_cn; void *res = NULL; if (!(ads = ads_startup())) { return -1; } if (argc < 1) { return net_ads_printer_usage(argc, argv); } printername = argv[0]; if (argc == 2) { servername = argv[1]; } else { servername = global_myname(); } /* Get printer data from SPOOLSS */ resolve_name(servername, &server_ip, 0x20); nt_status = cli_full_connection(&cli, global_myname(), servername, &server_ip, 0, "IPC$", "IPC", opt_user_name, opt_workgroup, opt_password ? opt_password : "", CLI_FULL_CONNECTION_USE_KERBEROS, Undefined, NULL); if (NT_STATUS_IS_ERR(nt_status)) { d_printf("Unable to open a connnection to %s to obtain data " "for %s\n", servername, printername); ads_destroy(&ads); return -1; } /* Publish on AD server */ ads_find_machine_acct(ads, &res, servername); if (ads_count_replies(ads, res) == 0) { d_printf("Could not find machine account for server %s\n", servername); ads_destroy(&ads); return -1; } srv_dn = ldap_get_dn(ads->ld, res); srv_cn = ldap_explode_dn(srv_dn, 1); asprintf(&prt_dn, "cn=%s-%s,%s", srv_cn[0], printername, srv_dn); cli_nt_session_open(cli, PI_SPOOLSS); get_remote_printer_publishing_data(cli, mem_ctx, &mods, printername); rc = ads_add_printer_entry(ads, prt_dn, mem_ctx, &mods); if (!ADS_ERR_OK(rc)) { d_printf("ads_publish_printer: %s\n", ads_errstr(rc)); ads_destroy(&ads); return -1; } d_printf("published printer\n"); ads_destroy(&ads); return 0; }
/* * Connect to a server for getting/setting attributes, possibly on an existing * connection. This works similarly to SMBC_server(). */ SMBCSRV * SMBC_attr_server(TALLOC_CTX *ctx, SMBCCTX *context, const char *server, uint16_t port, const char *share, char **pp_workgroup, char **pp_username, char **pp_password) { int flags; struct cli_state *ipc_cli = NULL; struct rpc_pipe_client *pipe_hnd = NULL; NTSTATUS nt_status; SMBCSRV *srv=NULL; SMBCSRV *ipc_srv=NULL; /* * Use srv->cli->desthost and srv->cli->share instead of * server and share below to connect to the actual share, * i.e., a normal share or a referred share from * 'msdfs proxy' share. */ srv = SMBC_server(ctx, context, true, server, port, share, pp_workgroup, pp_username, pp_password); if (!srv) { return NULL; } server = smbXcli_conn_remote_name(srv->cli->conn); share = srv->cli->share; /* * See if we've already created this special connection. Reference * our "special" share name '*IPC$', which is an impossible real share * name due to the leading asterisk. */ ipc_srv = SMBC_find_server(ctx, context, server, "*IPC$", pp_workgroup, pp_username, pp_password); if (!ipc_srv) { int signing_state = SMB_SIGNING_DEFAULT; /* We didn't find a cached connection. Get the password */ if (!*pp_password || (*pp_password)[0] == '\0') { /* ... then retrieve it now. */ SMBC_call_auth_fn(ctx, context, server, share, pp_workgroup, pp_username, pp_password); if (!*pp_workgroup || !*pp_username || !*pp_password) { errno = ENOMEM; return NULL; } } flags = 0; if (smbc_getOptionUseKerberos(context)) { flags |= CLI_FULL_CONNECTION_USE_KERBEROS; } if (smbc_getOptionUseCCache(context)) { flags |= CLI_FULL_CONNECTION_USE_CCACHE; } if (context->internal->smb_encryption_level != SMBC_ENCRYPTLEVEL_NONE) { signing_state = SMB_SIGNING_REQUIRED; } nt_status = cli_full_connection(&ipc_cli, lp_netbios_name(), server, NULL, 0, "IPC$", "?????", *pp_username, *pp_workgroup, *pp_password, flags, signing_state); if (! NT_STATUS_IS_OK(nt_status)) { DEBUG(1,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status))); errno = ENOTSUP; return NULL; } if (context->internal->smb_encryption_level) { /* Attempt UNIX smb encryption. */ if (!NT_STATUS_IS_OK(cli_force_encryption(ipc_cli, *pp_username, *pp_password, *pp_workgroup))) { /* * context->smb_encryption_level == * 1 means don't fail if encryption can't be * negotiated, == 2 means fail if encryption * can't be negotiated. */ DEBUG(4,(" SMB encrypt failed on IPC$\n")); if (context->internal->smb_encryption_level == 2) { cli_shutdown(ipc_cli); errno = EPERM; return NULL; } } DEBUG(4,(" SMB encrypt ok on IPC$\n")); } ipc_srv = SMB_MALLOC_P(SMBCSRV); if (!ipc_srv) { errno = ENOMEM; cli_shutdown(ipc_cli); return NULL; } ZERO_STRUCTP(ipc_srv); DLIST_ADD(ipc_srv->cli, ipc_cli); nt_status = cli_rpc_pipe_open_noauth( ipc_srv->cli, &ndr_table_lsarpc, &pipe_hnd); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(1, ("cli_nt_session_open fail!\n")); errno = ENOTSUP; cli_shutdown(ipc_srv->cli); free(ipc_srv); return NULL; } /* * Some systems don't support * SEC_FLAG_MAXIMUM_ALLOWED, but NT sends 0x2000000 * so we might as well do it too. */ nt_status = rpccli_lsa_open_policy( pipe_hnd, talloc_tos(), True, GENERIC_EXECUTE_ACCESS, &ipc_srv->pol); if (!NT_STATUS_IS_OK(nt_status)) { errno = SMBC_errno(context, ipc_srv->cli); cli_shutdown(ipc_srv->cli); free(ipc_srv); return NULL; } /* now add it to the cache (internal or external) */ errno = 0; /* let cache function set errno if it likes */ if (smbc_getFunctionAddCachedServer(context)(context, ipc_srv, server, "*IPC$", *pp_workgroup, *pp_username)) { DEBUG(3, (" Failed to add server to cache\n")); if (errno == 0) { errno = ENOMEM; } cli_shutdown(ipc_srv->cli); free(ipc_srv); return NULL; } DLIST_ADD(context->internal->servers, ipc_srv); } return ipc_srv; }
bool enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, char ***domain_names, uint32 *num_domains, DOM_SID **sids ) { struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; fstring dc_name; struct sockaddr_storage dc_ss; uint32 enum_ctx = 0; struct cli_state *cli = NULL; struct rpc_pipe_client *lsa_pipe; bool retry; struct lsa_DomainList dom_list; int i; *domain_names = NULL; *num_domains = 0; *sids = NULL; /* lookup a DC first */ if ( !get_dc_name(domain, NULL, dc_name, &dc_ss) ) { DEBUG(3,("enumerate_domain_trusts: can't locate a DC for domain %s\n", domain)); return False; } /* setup the anonymous connection */ result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ss, 0, "IPC$", "IPC", "", "", "", 0, Undefined, &retry); if ( !NT_STATUS_IS_OK(result) ) goto done; /* open the LSARPC_PIPE */ result = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id, &lsa_pipe); if (!NT_STATUS_IS_OK(result)) { goto done; } /* get a handle */ result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True, LSA_POLICY_VIEW_LOCAL_INFORMATION, &pol); if ( !NT_STATUS_IS_OK(result) ) goto done; /* Lookup list of trusted domains */ result = rpccli_lsa_EnumTrustDom(lsa_pipe, mem_ctx, &pol, &enum_ctx, &dom_list, (uint32_t)-1); if ( !NT_STATUS_IS_OK(result) ) goto done; *num_domains = dom_list.count; *domain_names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_domains); if (!*domain_names) { result = NT_STATUS_NO_MEMORY; goto done; } *sids = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_domains); if (!*sids) { result = NT_STATUS_NO_MEMORY; goto done; } for (i=0; i< *num_domains; i++) { (*domain_names)[i] = CONST_DISCARD(char *, dom_list.domains[i].name.string); (*sids)[i] = *dom_list.domains[i].sid; } done: /* cleanup */ if (cli) { DEBUG(10,("enumerate_domain_trusts: shutting down connection...\n")); cli_shutdown( cli ); } return NT_STATUS_IS_OK(result); }
static bool enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, char ***domain_names, uint32 *num_domains, struct dom_sid **sids ) { struct policy_handle pol; NTSTATUS status, result; fstring dc_name; struct sockaddr_storage dc_ss; uint32 enum_ctx = 0; struct cli_state *cli = NULL; struct rpc_pipe_client *lsa_pipe = NULL; struct lsa_DomainList dom_list; int i; struct dcerpc_binding_handle *b = NULL; *domain_names = NULL; *num_domains = 0; *sids = NULL; /* lookup a DC first */ if ( !get_dc_name(domain, NULL, dc_name, &dc_ss) ) { DEBUG(3,("enumerate_domain_trusts: can't locate a DC for domain %s\n", domain)); return False; } /* setup the anonymous connection */ status = cli_full_connection( &cli, lp_netbios_name(), dc_name, &dc_ss, 0, "IPC$", "IPC", "", "", "", 0, Undefined); if ( !NT_STATUS_IS_OK(status) ) goto done; /* open the LSARPC_PIPE */ status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id, &lsa_pipe); if (!NT_STATUS_IS_OK(status)) { goto done; } b = lsa_pipe->binding_handle; /* get a handle */ status = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True, LSA_POLICY_VIEW_LOCAL_INFORMATION, &pol); if ( !NT_STATUS_IS_OK(status) ) goto done; /* Lookup list of trusted domains */ status = dcerpc_lsa_EnumTrustDom(b, mem_ctx, &pol, &enum_ctx, &dom_list, (uint32_t)-1, &result); if ( !NT_STATUS_IS_OK(status) ) goto done; if (!NT_STATUS_IS_OK(result)) { status = result; goto done; } *num_domains = dom_list.count; *domain_names = talloc_zero_array(mem_ctx, char *, *num_domains); if (!*domain_names) { status = NT_STATUS_NO_MEMORY; goto done; } *sids = talloc_zero_array(mem_ctx, struct dom_sid, *num_domains); if (!*sids) { status = NT_STATUS_NO_MEMORY; goto done; } for (i=0; i< *num_domains; i++) { (*domain_names)[i] = discard_const_p(char, dom_list.domains[i].name.string); (*sids)[i] = *dom_list.domains[i].sid; } done: /* cleanup */ if (cli) { DEBUG(10,("enumerate_domain_trusts: shutting down connection...\n")); cli_shutdown( cli ); } return NT_STATUS_IS_OK(status); }
static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, const char *domain, const char *dc_name, struct in_addr dc_ip, const char *setup_creds_as, uint16 sec_chan, const unsigned char *trust_passwd, BOOL *retry) { NTSTATUS result; /* TODO: Send a SAMLOGON request to determine whether this is a valid logonserver. We can avoid a 30-second timeout if the DC is down if the SAMLOGON request fails as it is only over UDP. */ /* we use a mutex to prevent two connections at once - when a Win2k PDC get two connections where one hasn't completed a session setup yet it will send a TCP reset to the first connection (tridge) */ /* * With NT4.x DC's *all* authentication must be serialized to avoid * ACCESS_DENIED errors if 2 auths are done from the same machine. JRA. */ if (!grab_server_mutex(dc_name)) return NT_STATUS_NO_LOGON_SERVERS; /* Attempt connection */ *retry = True; result = cli_full_connection(cli, global_myname(), dc_name, &dc_ip, 0, "IPC$", "IPC", "", "", "", 0, Undefined, retry); if (!NT_STATUS_IS_OK(result)) { /* map to something more useful */ if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) { result = NT_STATUS_NO_LOGON_SERVERS; } release_server_mutex(); return result; } /* * We now have an anonymous connection to IPC$ on the domain password server. */ /* * Even if the connect succeeds we need to setup the netlogon * pipe here. We do this as we may just have changed the domain * account password on the PDC and yet we may be talking to * a BDC that doesn't have this replicated yet. In this case * a successful connect to a DC needs to take the netlogon connect * into account also. This patch from "Bjart Kvarme" <*****@*****.**>. */ if(cli_nt_session_open(*cli, PI_NETLOGON) == False) { DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \ machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli))); cli_nt_session_close(*cli); cli_ulogoff(*cli); cli_shutdown(*cli); release_server_mutex(); return NT_STATUS_NO_LOGON_SERVERS; }
NTSTATUS change_trust_account_password( const char *domain, const char *remote_machine) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; struct in_addr pdc_ip; fstring dc_name; struct cli_state *cli; DEBUG(5,("change_trust_account_password: Attempting to change trust account password in domain %s....\n", domain)); if (remote_machine == NULL || !strcmp(remote_machine, "*")) { /* Use the PDC *only* for this */ if ( !get_pdc_ip(domain, &pdc_ip) ) { DEBUG(0,("Can't get IP for PDC for domain %s\n", domain)); goto failed; } if ( !name_status_find( domain, 0x1b, 0x20, pdc_ip, dc_name) ) goto failed; } else { /* supoport old deprecated "smbpasswd -j DOMAIN -r MACHINE" behavior */ fstrcpy( dc_name, remote_machine ); } /* if this next call fails, then give up. We can't do password changes on BDC's --jerry */ if (!NT_STATUS_IS_OK(cli_full_connection(&cli, global_myname(), dc_name, NULL, 0, "IPC$", "IPC", "", "", "", 0, Undefined, NULL))) { DEBUG(0,("modify_trust_password: Connection to %s failed!\n", dc_name)); nt_status = NT_STATUS_UNSUCCESSFUL; goto failed; } /* * Ok - we have an anonymous connection to the IPC$ share. * Now start the NT Domain stuff :-). */ if(cli_nt_session_open(cli, PI_NETLOGON) == False) { DEBUG(0,("modify_trust_password: unable to open the domain client session to machine %s. Error was : %s.\n", dc_name, cli_errstr(cli))); cli_nt_session_close(cli); cli_ulogoff(cli); cli_shutdown(cli); nt_status = NT_STATUS_UNSUCCESSFUL; goto failed; } nt_status = trust_pw_find_change_and_store_it(cli, cli->mem_ctx, domain); cli_nt_session_close(cli); cli_ulogoff(cli); cli_shutdown(cli); failed: if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("%s : change_trust_account_password: Failed to change password for domain %s.\n", timestring(False), domain)); } else DEBUG(5,("change_trust_account_password: sucess!\n")); return nt_status; }
NTSTATUS connect_to_service(struct cli_state **c, struct sockaddr_storage *server_ss, const char *server_name, const char *service_name, const char *service_type) { NTSTATUS nt_status; opt_password = net_prompt_pass(opt_user_name); if (!opt_password) { return NT_STATUS_NO_MEMORY; } nt_status = cli_full_connection(c, NULL, server_name, server_ss, opt_port, service_name, service_type, opt_user_name, opt_workgroup, opt_password, 0, Undefined, NULL); if (!NT_STATUS_IS_OK(nt_status)) { d_fprintf(stderr, "Could not connect to server %s\n", server_name); /* Display a nicer message depending on the result */ if (NT_STATUS_V(nt_status) == NT_STATUS_V(NT_STATUS_LOGON_FAILURE)) d_fprintf(stderr, "The username or password was not correct.\n"); if (NT_STATUS_V(nt_status) == NT_STATUS_V(NT_STATUS_ACCOUNT_LOCKED_OUT)) d_fprintf(stderr, "The account was locked out.\n"); if (NT_STATUS_V(nt_status) == NT_STATUS_V(NT_STATUS_ACCOUNT_DISABLED)) d_fprintf(stderr, "The account was disabled.\n"); return nt_status; } if (smb_encrypt) { nt_status = cli_force_encryption(*c, opt_user_name, opt_password, opt_workgroup); if (NT_STATUS_EQUAL(nt_status,NT_STATUS_NOT_SUPPORTED)) { d_printf("Encryption required and " "server that doesn't support " "UNIX extensions - failing connect\n"); } else if (NT_STATUS_EQUAL(nt_status,NT_STATUS_UNKNOWN_REVISION)) { d_printf("Encryption required and " "can't get UNIX CIFS extensions " "version from server.\n"); } else if (NT_STATUS_EQUAL(nt_status,NT_STATUS_UNSUPPORTED_COMPRESSION)) { d_printf("Encryption required and " "share %s doesn't support " "encryption.\n", service_name); } else if (!NT_STATUS_IS_OK(nt_status)) { d_printf("Encryption required and " "setup failed with error %s.\n", nt_errstr(nt_status)); } if (!NT_STATUS_IS_OK(nt_status)) { cli_shutdown(*c); *c = NULL; } } return nt_status; }
static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, const char *domain, const char *dc_name, const struct sockaddr_storage *dc_ss, struct rpc_pipe_client **pipe_ret) { NTSTATUS result; struct rpc_pipe_client *netlogon_pipe = NULL; *cli = NULL; *pipe_ret = NULL; /* TODO: Send a SAMLOGON request to determine whether this is a valid logonserver. We can avoid a 30-second timeout if the DC is down if the SAMLOGON request fails as it is only over UDP. */ /* we use a mutex to prevent two connections at once - when a Win2k PDC get two connections where one hasn't completed a session setup yet it will send a TCP reset to the first connection (tridge) */ /* * With NT4.x DC's *all* authentication must be serialized to avoid * ACCESS_DENIED errors if 2 auths are done from the same machine. JRA. */ mutex = grab_named_mutex(NULL, dc_name, 10); if (mutex == NULL) { return NT_STATUS_NO_LOGON_SERVERS; } /* Attempt connection */ result = cli_full_connection(cli, lp_netbios_name(), dc_name, dc_ss, 0, "IPC$", "IPC", "", "", "", 0, SMB_SIGNING_DEFAULT); if (!NT_STATUS_IS_OK(result)) { /* map to something more useful */ if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) { result = NT_STATUS_NO_LOGON_SERVERS; } if (*cli) { cli_shutdown(*cli); *cli = NULL; } TALLOC_FREE(mutex); return result; } /* * We now have an anonymous connection to IPC$ on the domain password server. */ /* * Even if the connect succeeds we need to setup the netlogon * pipe here. We do this as we may just have changed the domain * account password on the PDC and yet we may be talking to * a BDC that doesn't have this replicated yet. In this case * a successful connect to a DC needs to take the netlogon connect * into account also. This patch from "Bjart Kvarme" <*****@*****.**>. */ /* open the netlogon pipe. */ if (lp_client_schannel()) { /* We also setup the creds chain in the open_schannel call. */ result = cli_rpc_pipe_open_schannel( *cli, &ndr_table_netlogon, NCACN_NP, DCERPC_AUTH_LEVEL_PRIVACY, domain, &netlogon_pipe); } else { result = cli_rpc_pipe_open_noauth( *cli, &ndr_table_netlogon, &netlogon_pipe); } if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \ machine %s. Error was : %s.\n", dc_name, nt_errstr(result))); cli_shutdown(*cli); *cli = NULL; TALLOC_FREE(mutex); return result; }
/* * Connect to a server for getting/setting attributes, possibly on an existing * connection. This works similarly to SMBC_server(). */ SMBCSRV * SMBC_attr_server(TALLOC_CTX *ctx, SMBCCTX *context, const char *server, const char *share, char **pp_workgroup, char **pp_username, char **pp_password) { int flags; struct sockaddr_storage ss; struct cli_state *ipc_cli; struct rpc_pipe_client *pipe_hnd; NTSTATUS nt_status; SMBCSRV *ipc_srv=NULL; /* * See if we've already created this special connection. Reference * our "special" share name '*IPC$', which is an impossible real share * name due to the leading asterisk. */ ipc_srv = SMBC_find_server(ctx, context, server, "*IPC$", pp_workgroup, pp_username, pp_password); if (!ipc_srv) { /* We didn't find a cached connection. Get the password */ if (!*pp_password || (*pp_password)[0] == '\0') { /* ... then retrieve it now. */ SMBC_call_auth_fn(ctx, context, server, share, pp_workgroup, pp_username, pp_password); if (!*pp_workgroup || !*pp_username || !*pp_password) { errno = ENOMEM; return NULL; } } flags = 0; if (smbc_getOptionUseKerberos(context)) { flags |= CLI_FULL_CONNECTION_USE_KERBEROS; } zero_sockaddr(&ss); nt_status = cli_full_connection(&ipc_cli, global_myname(), server, &ss, 0, "IPC$", "?????", *pp_username, *pp_workgroup, *pp_password, flags, Undefined, NULL); if (! NT_STATUS_IS_OK(nt_status)) { DEBUG(1,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status))); errno = ENOTSUP; return NULL; } if (context->internal->smb_encryption_level) { /* Attempt UNIX smb encryption. */ if (!NT_STATUS_IS_OK(cli_force_encryption(ipc_cli, *pp_username, *pp_password, *pp_workgroup))) { /* * context->smb_encryption_level == * 1 means don't fail if encryption can't be * negotiated, == 2 means fail if encryption * can't be negotiated. */ DEBUG(4,(" SMB encrypt failed on IPC$\n")); if (context->internal->smb_encryption_level == 2) { cli_shutdown(ipc_cli); errno = EPERM; return NULL; } } DEBUG(4,(" SMB encrypt ok on IPC$\n")); } ipc_srv = SMB_MALLOC_P(SMBCSRV); if (!ipc_srv) { errno = ENOMEM; cli_shutdown(ipc_cli); return NULL; } ZERO_STRUCTP(ipc_srv); ipc_srv->cli = ipc_cli; nt_status = cli_rpc_pipe_open_noauth( ipc_srv->cli, &ndr_table_lsarpc.syntax_id, &pipe_hnd); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(1, ("cli_nt_session_open fail!\n")); errno = ENOTSUP; cli_shutdown(ipc_srv->cli); free(ipc_srv); return NULL; } /* * Some systems don't support * SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000 * so we might as well do it too. */ nt_status = rpccli_lsa_open_policy( pipe_hnd, talloc_tos(), True, GENERIC_EXECUTE_ACCESS, &ipc_srv->pol); if (!NT_STATUS_IS_OK(nt_status)) { errno = SMBC_errno(context, ipc_srv->cli); cli_shutdown(ipc_srv->cli); return NULL; } /* now add it to the cache (internal or external) */ errno = 0; /* let cache function set errno if it likes */ if (smbc_getFunctionAddCachedServer(context)(context, ipc_srv, server, "*IPC$", *pp_workgroup, *pp_username)) { DEBUG(3, (" Failed to add server to cache\n")); if (errno == 0) { errno = ENOMEM; } cli_shutdown(ipc_srv->cli); free(ipc_srv); return NULL; } DLIST_ADD(context->internal->servers, ipc_srv); } return ipc_srv; }
static NTSTATUS connect_to_domain_password_server(struct cli_state **cli_ret, const char *domain, const char *dc_name, const struct sockaddr_storage *dc_ss, struct rpc_pipe_client **pipe_ret, TALLOC_CTX *mem_ctx, struct netlogon_creds_cli_context **creds_ret) { TALLOC_CTX *frame = talloc_stackframe(); struct messaging_context *msg_ctx = server_messaging_context(); NTSTATUS result; struct cli_state *cli = NULL; struct rpc_pipe_client *netlogon_pipe = NULL; struct netlogon_creds_cli_context *netlogon_creds = NULL; struct netlogon_creds_CredentialState *creds = NULL; uint32_t netlogon_flags = 0; enum netr_SchannelType sec_chan_type = 0; const char *_account_name = NULL; const char *account_name = NULL; struct samr_Password current_nt_hash; struct samr_Password *previous_nt_hash = NULL; bool ok; *cli_ret = NULL; *pipe_ret = NULL; *creds_ret = NULL; /* TODO: Send a SAMLOGON request to determine whether this is a valid logonserver. We can avoid a 30-second timeout if the DC is down if the SAMLOGON request fails as it is only over UDP. */ /* we use a mutex to prevent two connections at once - when a Win2k PDC get two connections where one hasn't completed a session setup yet it will send a TCP reset to the first connection (tridge) */ /* * With NT4.x DC's *all* authentication must be serialized to avoid * ACCESS_DENIED errors if 2 auths are done from the same machine. JRA. */ mutex = grab_named_mutex(NULL, dc_name, 10); if (mutex == NULL) { TALLOC_FREE(frame); return NT_STATUS_NO_LOGON_SERVERS; } /* Attempt connection */ result = cli_full_connection(&cli, lp_netbios_name(), dc_name, dc_ss, 0, "IPC$", "IPC", "", "", "", 0, SMB_SIGNING_DEFAULT); if (!NT_STATUS_IS_OK(result)) { /* map to something more useful */ if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) { result = NT_STATUS_NO_LOGON_SERVERS; } TALLOC_FREE(mutex); TALLOC_FREE(frame); return result; } /* * We now have an anonymous connection to IPC$ on the domain password server. */ ok = get_trust_pw_hash(domain, current_nt_hash.hash, &_account_name, &sec_chan_type); if (!ok) { cli_shutdown(cli); TALLOC_FREE(mutex); TALLOC_FREE(frame); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } account_name = talloc_asprintf(talloc_tos(), "%s$", _account_name); if (account_name == NULL) { cli_shutdown(cli); TALLOC_FREE(mutex); TALLOC_FREE(frame); return NT_STATUS_NO_MEMORY; } result = rpccli_create_netlogon_creds(dc_name, domain, account_name, sec_chan_type, msg_ctx, talloc_tos(), &netlogon_creds); if (!NT_STATUS_IS_OK(result)) { cli_shutdown(cli); TALLOC_FREE(mutex); TALLOC_FREE(frame); SAFE_FREE(previous_nt_hash); return result; } result = rpccli_setup_netlogon_creds(cli, netlogon_creds, false, /* force_reauth */ current_nt_hash, previous_nt_hash); SAFE_FREE(previous_nt_hash); if (!NT_STATUS_IS_OK(result)) { cli_shutdown(cli); TALLOC_FREE(mutex); TALLOC_FREE(frame); return result; } result = netlogon_creds_cli_get(netlogon_creds, talloc_tos(), &creds); if (!NT_STATUS_IS_OK(result)) { cli_shutdown(cli); TALLOC_FREE(mutex); TALLOC_FREE(frame); return result; } netlogon_flags = creds->negotiate_flags; TALLOC_FREE(creds); if (netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC) { result = cli_rpc_pipe_open_schannel_with_key( cli, &ndr_table_netlogon, NCACN_NP, domain, netlogon_creds, &netlogon_pipe); } else { result = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon, &netlogon_pipe); } if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("connect_to_domain_password_server: " "unable to open the domain client session to " "machine %s. Flags[0x%08X] Error was : %s.\n", dc_name, (unsigned)netlogon_flags, nt_errstr(result))); cli_shutdown(cli); TALLOC_FREE(mutex); TALLOC_FREE(frame); return result; } if(!netlogon_pipe) { DEBUG(0, ("connect_to_domain_password_server: unable to open " "the domain client session to machine %s. Error " "was : %s.\n", dc_name, nt_errstr(result))); cli_shutdown(cli); TALLOC_FREE(mutex); TALLOC_FREE(frame); return NT_STATUS_NO_LOGON_SERVERS; } /* We exit here with the mutex *locked*. JRA */ *cli_ret = cli; *pipe_ret = netlogon_pipe; *creds_ret = talloc_move(mem_ctx, &netlogon_creds); TALLOC_FREE(frame); return NT_STATUS_OK; }
NTSTATUS connect_to_service(struct net_context *c, struct cli_state **cli_ctx, struct sockaddr_storage *server_ss, const char *server_name, const char *service_name, const char *service_type) { NTSTATUS nt_status; int flags = 0; c->opt_password = net_prompt_pass(c, c->opt_user_name); if (c->opt_kerberos) { flags |= CLI_FULL_CONNECTION_USE_KERBEROS; } if (c->opt_kerberos && c->opt_password) { flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS; } if (c->opt_ccache) { flags |= CLI_FULL_CONNECTION_USE_CCACHE; } nt_status = cli_full_connection(cli_ctx, NULL, server_name, server_ss, c->opt_port, service_name, service_type, c->opt_user_name, c->opt_workgroup, c->opt_password, flags, Undefined); if (!NT_STATUS_IS_OK(nt_status)) { d_fprintf(stderr, _("Could not connect to server %s\n"), server_name); /* Display a nicer message depending on the result */ if (NT_STATUS_V(nt_status) == NT_STATUS_V(NT_STATUS_LOGON_FAILURE)) d_fprintf(stderr, _("The username or password was not " "correct.\n")); if (NT_STATUS_V(nt_status) == NT_STATUS_V(NT_STATUS_ACCOUNT_LOCKED_OUT)) d_fprintf(stderr, _("The account was locked out.\n")); if (NT_STATUS_V(nt_status) == NT_STATUS_V(NT_STATUS_ACCOUNT_DISABLED)) d_fprintf(stderr, _("The account was disabled.\n")); return nt_status; } if (c->smb_encrypt) { nt_status = cli_force_encryption(*cli_ctx, c->opt_user_name, c->opt_password, c->opt_workgroup); if (NT_STATUS_EQUAL(nt_status,NT_STATUS_NOT_SUPPORTED)) { d_printf(_("Encryption required and " "server that doesn't support " "UNIX extensions - failing connect\n")); } else if (NT_STATUS_EQUAL(nt_status,NT_STATUS_UNKNOWN_REVISION)) { d_printf(_("Encryption required and " "can't get UNIX CIFS extensions " "version from server.\n")); } else if (NT_STATUS_EQUAL(nt_status,NT_STATUS_UNSUPPORTED_COMPRESSION)) { d_printf(_("Encryption required and " "share %s doesn't support " "encryption.\n"), service_name); } else if (!NT_STATUS_IS_OK(nt_status)) { d_printf(_("Encryption required and " "setup failed with error %s.\n"), nt_errstr(nt_status)); } if (!NT_STATUS_IS_OK(nt_status)) { cli_shutdown(*cli_ctx); *cli_ctx = NULL; } } return nt_status; }
NTSTATUS change_trust_account_password( const char *domain, const char *remote_machine) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; struct sockaddr_storage pdc_ss; fstring dc_name; struct cli_state *cli = NULL; struct rpc_pipe_client *netlogon_pipe = NULL; DEBUG(5,("change_trust_account_password: Attempting to change trust account password in domain %s....\n", domain)); if (remote_machine == NULL || !strcmp(remote_machine, "*")) { /* Use the PDC *only* for this */ if ( !get_pdc_ip(domain, &pdc_ss) ) { DEBUG(0,("Can't get IP for PDC for domain %s\n", domain)); goto failed; } if ( !name_status_find( domain, 0x1b, 0x20, &pdc_ss, dc_name) ) goto failed; } else { /* supoport old deprecated "smbpasswd -j DOMAIN -r MACHINE" behavior */ fstrcpy( dc_name, remote_machine ); } /* if this next call fails, then give up. We can't do password changes on BDC's --jerry */ if (!NT_STATUS_IS_OK(cli_full_connection(&cli, global_myname(), dc_name, NULL, 0, "IPC$", "IPC", "", "", "", 0, Undefined, NULL))) { DEBUG(0,("modify_trust_password: Connection to %s failed!\n", dc_name)); nt_status = NT_STATUS_UNSUCCESSFUL; goto failed; } /* * Ok - we have an anonymous connection to the IPC$ share. * Now start the NT Domain stuff :-). */ /* Shouldn't we open this with schannel ? JRA. */ nt_status = cli_rpc_pipe_open_noauth( cli, &ndr_table_netlogon.syntax_id, &netlogon_pipe); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("modify_trust_password: unable to open the domain client session to machine %s. Error was : %s.\n", dc_name, nt_errstr(nt_status))); cli_shutdown(cli); cli = NULL; goto failed; } nt_status = trust_pw_find_change_and_store_it( netlogon_pipe, netlogon_pipe, domain); cli_shutdown(cli); cli = NULL; failed: if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("%s : change_trust_account_password: Failed to change password for domain %s.\n", current_timestring(talloc_tos(), False), domain)); } else DEBUG(5,("change_trust_account_password: sucess!\n")); return nt_status; }
static struct con_struct *create_cs(struct net_context *c, TALLOC_CTX *ctx, NTSTATUS *perr) { NTSTATUS nt_status; struct sockaddr_storage loopback_ss; *perr = NT_STATUS_OK; if (!interpret_string_addr(&loopback_ss, "127.0.0.1", AI_NUMERICHOST)) { *perr = NT_STATUS_INVALID_PARAMETER; return NULL; } if (cs) { if (cs->failed_connect) { *perr = cs->err; return NULL; } return cs; } cs = talloc(ctx, struct con_struct); if (!cs) { *perr = NT_STATUS_NO_MEMORY; return NULL; } ZERO_STRUCTP(cs); talloc_set_destructor(cs, cs_destructor); /* Connect to localhost with given username/password. */ /* JRA. Pretty sure we can just do this anonymously.... */ #if 0 if (!opt_password && !opt_machine_pass) { char *pass = getpass("Password:"******"IPC$", "IPC", #if 0 c->opt_user_name, c->opt_workgroup, c->opt_password, #else "", c->opt_workgroup, "", #endif 0, SMB_SIGNING_DEFAULT); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(2,("create_cs: Connect failed. Error was %s\n", nt_errstr(nt_status))); cs->failed_connect = true; cs->err = nt_status; *perr = nt_status; return NULL; } nt_status = cli_rpc_pipe_open_noauth(cs->cli, &ndr_table_lsarpc.syntax_id, &cs->lsapipe); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(2,("create_cs: open LSA pipe failed. Error was %s\n", nt_errstr(nt_status))); cs->failed_connect = true; cs->err = nt_status; *perr = nt_status; return NULL; } nt_status = rpccli_lsa_open_policy(cs->lsapipe, ctx, true, SEC_FLAG_MAXIMUM_ALLOWED, &cs->pol); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(2,("create_cs: rpccli_lsa_open_policy failed. Error was %s\n", nt_errstr(nt_status))); cs->failed_connect = true; cs->err = nt_status; *perr = nt_status; return NULL; } return cs; }
BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, char ***domain_names, uint32 *num_domains, DOM_SID **sids ) { POLICY_HND pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; fstring dc_name; struct in_addr dc_ip; uint32 enum_ctx = 0; struct cli_state *cli = NULL; struct rpc_pipe_client *lsa_pipe; BOOL retry; *domain_names = NULL; *num_domains = 0; *sids = NULL; /* lookup a DC first */ if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) { DEBUG(3,("enumerate_domain_trusts: can't locate a DC for domain %s\n", domain)); return False; } /* setup the anonymous connection */ result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ip, 0, "IPC$", "IPC", "", "", "", 0, Undefined, &retry); if ( !NT_STATUS_IS_OK(result) ) goto done; /* open the LSARPC_PIPE */ lsa_pipe = cli_rpc_pipe_open_noauth( cli, PI_LSARPC, &result ); if ( !lsa_pipe) { goto done; } /* get a handle */ result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True, POLICY_VIEW_LOCAL_INFORMATION, &pol); if ( !NT_STATUS_IS_OK(result) ) goto done; /* Lookup list of trusted domains */ result = rpccli_lsa_enum_trust_dom(lsa_pipe, mem_ctx, &pol, &enum_ctx, num_domains, domain_names, sids); if ( !NT_STATUS_IS_OK(result) ) goto done; done: /* cleanup */ if (cli) { DEBUG(10,("enumerate_domain_trusts: shutting down connection...\n")); cli_shutdown( cli ); } return NT_STATUS_IS_OK(result); }