struct cli_state *get_ipc_connect_master_ip(pstring workgroup, struct user_auth_info *user_info, struct in_addr *mb_ip) { fstring name; struct cli_state *cli; struct in_addr server_ss; /* * Do a name status query to find out the name of the master browser. * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain * master browser will not respond to a wildcard query (or, at least, * an NT4 server acting as the domain master browser will not). * * We might be able to use ONLY the query on MSBROWSE, but that's not * yet been tested with all Windows versions, so until it is, leave * the original wildcard query as the first choice and fall back to * MSBROWSE if the wildcard query fails. */ if (!name_status_find("*", 0, 0x1d, *mb_ip, name) && !name_status_find(MSBROWSE, 1, 0x1d, *mb_ip, name)) return NULL; if (!find_master_ip(name, &server_ss)) return NULL; pstrcpy(workgroup, name); DEBUG(4, ("found master browser %s, %s\n", name, inet_ntoa(*mb_ip))); cli = get_ipc_connect(inet_ntoa(server_ss), &server_ss, user_info); return cli; }
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 BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) { struct ip_service *ip_list = NULL; struct in_addr dc_ip, exclude_ip; int count, i; NTSTATUS result; zero_ip(&exclude_ip); /* get a list of all domain controllers */ if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, NULL, &ip_list, &count, False))) { DEBUG(3, ("Could not look up dc's for domain %s\n", domain)); return False; } /* Remove the entry we've already failed with (should be the PDC). */ for (i = 0; i < count; i++) { if (is_zero_ip(ip_list[i].ip)) continue; if (name_status_find(domain, 0x1c, 0x20, ip_list[i].ip, srv_name)) { result = check_negative_conn_cache( domain, srv_name ); if ( NT_STATUS_IS_OK(result) ) { dc_ip = ip_list[i].ip; goto done; } } } SAFE_FREE(ip_list); /* No-one to talk to )-: */ return False; /* Boo-hoo */ done: /* We have the netbios name and IP address of a domain controller. Ideally we should sent a SAMLOGON request to determine whether the DC is alive and kicking. If we can catch a dead DC before performing a cli_connect() we can avoid a 30-second timeout. */ DEBUG(3, ("rpc_dc_name: Returning DC %s (%s) for domain %s\n", srv_name, inet_ntoa(dc_ip), domain)); *ip_out = dc_ip; SAFE_FREE(ip_list); return True; }
static bool rpc_dc_name(const char *domain, fstring srv_name, struct sockaddr_storage *ss_out) { struct ip_service *ip_list = NULL; struct sockaddr_storage dc_ss; int count, i; NTSTATUS result; char addr[INET6_ADDRSTRLEN]; /* get a list of all domain controllers */ if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, NULL, &ip_list, &count, False))) { DEBUG(3, ("Could not look up dc's for domain %s\n", domain)); return False; } /* Remove the entry we've already failed with (should be the PDC). */ for (i = 0; i < count; i++) { if (is_zero_addr((struct sockaddr *)&ip_list[i].ss)) continue; if (name_status_find(domain, 0x1c, 0x20, &ip_list[i].ss, srv_name)) { result = check_negative_conn_cache( domain, srv_name ); if ( NT_STATUS_IS_OK(result) ) { dc_ss = ip_list[i].ss; goto done; } } } SAFE_FREE(ip_list); /* No-one to talk to )-: */ return False; /* Boo-hoo */ done: /* We have the netbios name and IP address of a domain controller. Ideally we should sent a SAMLOGON request to determine whether the DC is alive and kicking. If we can catch a dead DC before performing a cli_connect() we can avoid a 30-second timeout. */ print_sockaddr(addr, sizeof(addr), &dc_ss); DEBUG(3, ("rpc_dc_name: Returning DC %s (%s) for domain %s\n", srv_name, addr, domain)); *ss_out = dc_ss; SAFE_FREE(ip_list); return True; }
BOOL net_find_pdc(struct in_addr *server_ip, fstring server_name, const char *domain_name) { if (get_pdc_ip(domain_name, server_ip)) { if (is_zero_ip(*server_ip)) return False; if (!name_status_find(domain_name, 0x1b, 0x20, *server_ip, server_name)) return False; return True; } else return False; }
bool net_find_pdc(struct sockaddr_storage *server_ss, fstring server_name, const char *domain_name) { if (!get_pdc_ip(domain_name, server_ss)) { return false; } if (is_zero_addr(server_ss)) { return false; } if (!name_status_find(domain_name, 0x1b, 0x20, server_ss, server_name)) { return false; } return true; }
/***************************************************** find a workgroup (any workgroup!) that has a master browser on the local network *******************************************************/ static char *smbw_find_workgroup(void) { fstring server; char *p; struct in_addr *ip_list = NULL; int count = 0; int i; /* first off see if an existing workgroup name exists */ p = smbw_getshared("WORKGROUP"); if (!p) p = lp_workgroup(); slprintf(server, sizeof(server), "%s#1D", p); if (smbw_server(server, "IPC$")) return p; /* go looking for workgroups */ if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) { DEBUG(1,("No workgroups found!")); return p; } for (i=0;i<count;i++) { static fstring name; if (name_status_find("*", 0, 0x1d, ip_list[i], name)) { slprintf(server, sizeof(server), "%s#1D", name); if (smbw_server(server, "IPC$")) { smbw_setshared("WORKGROUP", name); SAFE_FREE(ip_list); return name; } } } SAFE_FREE(ip_list); return p; }
bool net_find_server(struct net_context *c, const char *domain, unsigned flags, struct sockaddr_storage *server_ss, char **server_name) { const char *d = domain ? domain : c->opt_target_workgroup; if (c->opt_host) { *server_name = SMB_STRDUP(c->opt_host); } if (c->opt_have_ip) { *server_ss = c->opt_dest_ip; if (!*server_name) { char addr[INET6_ADDRSTRLEN]; print_sockaddr(addr, sizeof(addr), &c->opt_dest_ip); *server_name = SMB_STRDUP(addr); } } else if (*server_name) { /* resolve the IP address */ if (!resolve_name(*server_name, server_ss, 0x20, false)) { DEBUG(1,("Unable to resolve server name\n")); return false; } } else if (flags & NET_FLAGS_PDC) { fstring dc_name; struct sockaddr_storage pdc_ss; if (!get_pdc_ip(d, &pdc_ss)) { DEBUG(1,("Unable to resolve PDC server address\n")); return false; } if (is_zero_addr(&pdc_ss)) { return false; } if (!name_status_find(d, 0x1b, 0x20, &pdc_ss, dc_name)) { return false; } *server_name = SMB_STRDUP(dc_name); *server_ss = pdc_ss; } else if (flags & NET_FLAGS_DMB) { struct sockaddr_storage msbrow_ss; char addr[INET6_ADDRSTRLEN]; /* if (!resolve_name(MSBROWSE, &msbrow_ip, 1, false)) */ if (!resolve_name(d, &msbrow_ss, 0x1B, false)) { DEBUG(1,("Unable to resolve domain browser via name lookup\n")); return false; } *server_ss = msbrow_ss; print_sockaddr(addr, sizeof(addr), server_ss); *server_name = SMB_STRDUP(addr); } else if (flags & NET_FLAGS_MASTER) { struct sockaddr_storage brow_ss; char addr[INET6_ADDRSTRLEN]; if (!resolve_name(d, &brow_ss, 0x1D, false)) { /* go looking for workgroups */ DEBUG(1,("Unable to resolve master browser via name lookup\n")); return false; } *server_ss = brow_ss; print_sockaddr(addr, sizeof(addr), server_ss); *server_name = SMB_STRDUP(addr); } else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) { if (!interpret_string_addr(server_ss, "127.0.0.1", AI_NUMERICHOST)) { DEBUG(1,("Unable to resolve 127.0.0.1\n")); return false; } *server_name = SMB_STRDUP("127.0.0.1"); } if (!*server_name) { DEBUG(1,("no server to connect to\n")); return false; } return true; }
static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, struct messaging_context *msg_ctx, const char *domain_name, uint32_t flags, struct ip_service_name *dclist, int num_dcs, struct netr_DsRGetDCNameInfo **info) { struct sockaddr_storage ss; struct ip_service ip_list; enum nbt_name_type name_type = NBT_NAME_LOGON; NTSTATUS status; int i; const char *dc_name = NULL; fstring tmp_dc_name; struct netlogon_samlogon_response *r = NULL; bool store_cache = false; uint32_t nt_version = NETLOGON_NT_VERSION_1 | NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX_WITH_IP; if (!msg_ctx) { msg_ctx = msg_context(mem_ctx); } if (flags & DS_PDC_REQUIRED) { name_type = NBT_NAME_PDC; } nt_version |= map_ds_flags_to_nt_version(flags); DEBUG(10,("process_dc_netbios\n")); for (i=0; i<num_dcs; i++) { ip_list.ss = dclist[i].ss; ip_list.port = 0; if (!interpret_string_addr(&ss, dclist[i].hostname, AI_NUMERICHOST)) { return NT_STATUS_UNSUCCESSFUL; } if (send_getdc_request(mem_ctx, msg_ctx, &dclist[i].ss, domain_name, NULL, nt_version)) { int k; smb_msleep(300); for (k=0; k<5; k++) { if (receive_getdc_response(mem_ctx, &dclist[i].ss, domain_name, &nt_version, &dc_name, &r)) { store_cache = true; namecache_store(dc_name, NBT_NAME_SERVER, 1, &ip_list); goto make_reply; } smb_msleep(1500); } } if (name_status_find(domain_name, name_type, NBT_NAME_SERVER, &dclist[i].ss, tmp_dc_name)) { struct NETLOGON_SAM_LOGON_RESPONSE_NT40 logon1; r = TALLOC_ZERO_P(mem_ctx, struct netlogon_samlogon_response); NT_STATUS_HAVE_NO_MEMORY(r); ZERO_STRUCT(logon1); nt_version = NETLOGON_NT_VERSION_1; logon1.nt_version = nt_version; logon1.server = tmp_dc_name; logon1.domain = talloc_strdup_upper(mem_ctx, domain_name); NT_STATUS_HAVE_NO_MEMORY(logon1.domain); r->data.nt4 = logon1; r->ntver = nt_version; map_netlogon_samlogon_response(r); namecache_store(tmp_dc_name, NBT_NAME_SERVER, 1, &ip_list); goto make_reply; } } return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; make_reply: status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss, &r->data.nt5_ex, info); if (NT_STATUS_IS_OK(status) && store_cache) { return store_cldap_reply(mem_ctx, flags, &dclist[i].ss, nt_version, &r->data.nt5_ex); } return status; }
BOOL net_find_server(const char *domain, unsigned flags, struct in_addr *server_ip, char **server_name) { const char *d = domain ? domain : opt_target_workgroup; if (opt_host) { *server_name = SMB_STRDUP(opt_host); } if (opt_have_ip) { *server_ip = opt_dest_ip; if (!*server_name) { *server_name = SMB_STRDUP(inet_ntoa(opt_dest_ip)); } } else if (*server_name) { /* resolve the IP address */ if (!resolve_name(*server_name, server_ip, 0x20)) { DEBUG(1,("Unable to resolve server name\n")); return False; } } else if (flags & NET_FLAGS_PDC) { struct in_addr pdc_ip; if (get_pdc_ip(d, &pdc_ip)) { fstring dc_name; if (is_zero_ip(pdc_ip)) return False; if ( !name_status_find(d, 0x1b, 0x20, pdc_ip, dc_name) ) return False; *server_name = SMB_STRDUP(dc_name); *server_ip = pdc_ip; } } else if (flags & NET_FLAGS_DMB) { struct in_addr msbrow_ip; /* if (!resolve_name(MSBROWSE, &msbrow_ip, 1)) */ if (!resolve_name(d, &msbrow_ip, 0x1B)) { DEBUG(1,("Unable to resolve domain browser via name lookup\n")); return False; } else { *server_ip = msbrow_ip; } *server_name = SMB_STRDUP(inet_ntoa(opt_dest_ip)); } else if (flags & NET_FLAGS_MASTER) { struct in_addr brow_ips; if (!resolve_name(d, &brow_ips, 0x1D)) { /* go looking for workgroups */ DEBUG(1,("Unable to resolve master browser via name lookup\n")); return False; } else { *server_ip = brow_ips; } *server_name = SMB_STRDUP(inet_ntoa(opt_dest_ip)); } else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) { *server_ip = loopback_ip; *server_name = SMB_STRDUP("127.0.0.1"); } if (!server_name || !*server_name) { DEBUG(1,("no server to connect to\n")); return False; } return True; }
static SMBCSRV * SMBC_server_internal(TALLOC_CTX *ctx, SMBCCTX *context, bool connect_if_not_found, const char *server, const char *share, char **pp_workgroup, char **pp_username, char **pp_password, bool *in_cache) { SMBCSRV *srv=NULL; char *workgroup = NULL; struct cli_state *c; struct nmb_name called, calling; const char *server_n = server; struct sockaddr_storage ss; int tried_reverse = 0; int port_try_first; int port_try_next; int is_ipc = (share != NULL && strcmp(share, "IPC$") == 0); uint32 fs_attrs = 0; const char *username_used; NTSTATUS status; char *newserver, *newshare; zero_sockaddr(&ss); ZERO_STRUCT(c); *in_cache = false; if (server[0] == 0) { errno = EPERM; return NULL; } /* Look for a cached connection */ srv = SMBC_find_server(ctx, context, server, share, pp_workgroup, pp_username, pp_password); /* * If we found a connection and we're only allowed one share per * server... */ if (srv && *share != '\0' && smbc_getOptionOneSharePerServer(context)) { /* * ... then if there's no current connection to the share, * connect to it. SMBC_find_server(), or rather the function * pointed to by context->get_cached_srv_fn which * was called by SMBC_find_server(), will have issued a tree * disconnect if the requested share is not the same as the * one that was already connected. */ /* * 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. */ if (srv->cli->cnum == (uint16) -1) { /* Ensure we have accurate auth info */ SMBC_call_auth_fn(ctx, context, srv->cli->desthost, srv->cli->share, pp_workgroup, pp_username, pp_password); if (!*pp_workgroup || !*pp_username || !*pp_password) { errno = ENOMEM; cli_shutdown(srv->cli); srv->cli = NULL; smbc_getFunctionRemoveCachedServer(context)(context, srv); return NULL; } /* * We don't need to renegotiate encryption * here as the encryption context is not per * tid. */ status = cli_tcon_andx(srv->cli, srv->cli->share, "?????", *pp_password, strlen(*pp_password)+1); if (!NT_STATUS_IS_OK(status)) { errno = map_errno_from_nt_status(status); cli_shutdown(srv->cli); srv->cli = NULL; smbc_getFunctionRemoveCachedServer(context)(context, srv); srv = NULL; } /* Determine if this share supports case sensitivity */ if (is_ipc) { DEBUG(4, ("IPC$ so ignore case sensitivity\n")); } else if (!cli_get_fs_attr_info(c, &fs_attrs)) { DEBUG(4, ("Could not retrieve " "case sensitivity flag: %s.\n", cli_errstr(c))); /* * We can't determine the case sensitivity of * the share. We have no choice but to use the * user-specified case sensitivity setting. */ if (smbc_getOptionCaseSensitive(context)) { cli_set_case_sensitive(c, True); } else { cli_set_case_sensitive(c, False); } } else { DEBUG(4, ("Case sensitive: %s\n", (fs_attrs & FILE_CASE_SENSITIVE_SEARCH ? "True" : "False"))); cli_set_case_sensitive( c, (fs_attrs & FILE_CASE_SENSITIVE_SEARCH ? True : False)); } /* * Regenerate the dev value since it's based on both * server and share */ if (srv) { srv->dev = (dev_t)(str_checksum(srv->cli->desthost) ^ str_checksum(srv->cli->share)); } } } /* If we have a connection... */ if (srv) { /* ... then we're done here. Give 'em what they came for. */ *in_cache = true; goto done; } /* If we're not asked to connect when a connection doesn't exist... */ if (! connect_if_not_found) { /* ... then we're done here. */ return NULL; } if (!*pp_workgroup || !*pp_username || !*pp_password) { errno = ENOMEM; return NULL; } make_nmb_name(&calling, smbc_getNetbiosName(context), 0x0); make_nmb_name(&called , server, 0x20); DEBUG(4,("SMBC_server: server_n=[%s] server=[%s]\n", server_n, server)); DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); again: zero_sockaddr(&ss); /* have to open a new connection */ if ((c = cli_initialise()) == NULL) { errno = ENOMEM; return NULL; } if (smbc_getOptionUseKerberos(context)) { c->use_kerberos = True; } if (smbc_getOptionFallbackAfterKerberos(context)) { c->fallback_after_kerberos = True; } if (smbc_getOptionUseCCache(context)) { c->use_ccache = True; } c->timeout = smbc_getTimeout(context); /* * Force use of port 139 for first try if share is $IPC, empty, or * null, so browse lists can work */ if (share == NULL || *share == '\0' || is_ipc) { port_try_first = 139; port_try_next = 445; } else { port_try_first = 445; port_try_next = 139; } c->port = port_try_first; status = cli_connect(c, server_n, &ss); if (!NT_STATUS_IS_OK(status)) { /* First connection attempt failed. Try alternate port. */ c->port = port_try_next; status = cli_connect(c, server_n, &ss); if (!NT_STATUS_IS_OK(status)) { cli_shutdown(c); errno = ETIMEDOUT; return NULL; } } if (!cli_session_request(c, &calling, &called)) { cli_shutdown(c); if (strcmp(called.name, "*SMBSERVER")) { make_nmb_name(&called , "*SMBSERVER", 0x20); goto again; } else { /* Try one more time, but ensure we don't loop */ /* Only try this if server is an IP address ... */ if (is_ipaddress(server) && !tried_reverse) { fstring remote_name; struct sockaddr_storage rem_ss; if (!interpret_string_addr(&rem_ss, server, NI_NUMERICHOST)) { DEBUG(4, ("Could not convert IP address " "%s to struct sockaddr_storage\n", server)); errno = ETIMEDOUT; return NULL; } tried_reverse++; /* Yuck */ if (name_status_find("*", 0, 0, &rem_ss, remote_name)) { make_nmb_name(&called, remote_name, 0x20); goto again; } } } errno = ETIMEDOUT; return NULL; } DEBUG(4,(" session request ok\n")); status = cli_negprot(c); if (!NT_STATUS_IS_OK(status)) { cli_shutdown(c); errno = ETIMEDOUT; return NULL; } username_used = *pp_username; if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used, *pp_password, strlen(*pp_password), *pp_password, strlen(*pp_password), *pp_workgroup))) { fprintf(stderr, "JerryLin: Libsmb_server.c->SMBC_server_internal: cli_session_setup fail with username=[%s], password=[%s]\n", username_used, *pp_password); /* Failed. Try an anonymous login, if allowed by flags. */ username_used = ""; if (smbc_getOptionNoAutoAnonymousLogin(context) || !NT_STATUS_IS_OK(cli_session_setup(c, username_used, *pp_password, 1, *pp_password, 0, *pp_workgroup))) { cli_shutdown(c); errno = EPERM; return NULL; } } status = cli_init_creds(c, username_used, *pp_workgroup, *pp_password); if (!NT_STATUS_IS_OK(status)) { errno = map_errno_from_nt_status(status); cli_shutdown(c); return NULL; } DEBUG(4,(" session setup ok\n")); /* here's the fun part....to support 'msdfs proxy' shares (on Samba or windows) we have to issues a TRANS_GET_DFS_REFERRAL here before trying to connect to the original share. cli_check_msdfs_proxy() will fail if it is a normal share. */ if ((c->capabilities & CAP_DFS) && cli_check_msdfs_proxy(ctx, c, share, &newserver, &newshare, /* FIXME: cli_check_msdfs_proxy() does not support smbc_smb_encrypt_level type */ context->internal->smb_encryption_level ? true : false, *pp_username, *pp_password, *pp_workgroup)) { cli_shutdown(c); srv = SMBC_server_internal(ctx, context, connect_if_not_found, newserver, newshare, pp_workgroup, pp_username, pp_password, in_cache); TALLOC_FREE(newserver); TALLOC_FREE(newshare); return srv; } /* must be a normal share */ status = cli_tcon_andx(c, share, "?????", *pp_password, strlen(*pp_password)+1); if (!NT_STATUS_IS_OK(status)) { errno = map_errno_from_nt_status(status); fprintf(stderr, "JerryLin: Libsmb_server.c->SMBC_server_internal: cli_tcon_andx return %08X, errno=[%d]\n", NT_STATUS_V(status), errno); cli_shutdown(c); return NULL; } DEBUG(4,(" tconx ok\n")); /* Determine if this share supports case sensitivity */ if (is_ipc) { DEBUG(4, ("IPC$ so ignore case sensitivity\n")); } else if (!cli_get_fs_attr_info(c, &fs_attrs)) { DEBUG(4, ("Could not retrieve case sensitivity flag: %s.\n", cli_errstr(c))); /* * We can't determine the case sensitivity of the share. We * have no choice but to use the user-specified case * sensitivity setting. */ if (smbc_getOptionCaseSensitive(context)) { cli_set_case_sensitive(c, True); } else { cli_set_case_sensitive(c, False); } } else { DEBUG(4, ("Case sensitive: %s\n", (fs_attrs & FILE_CASE_SENSITIVE_SEARCH ? "True" : "False"))); cli_set_case_sensitive(c, (fs_attrs & FILE_CASE_SENSITIVE_SEARCH ? True : False)); } if (context->internal->smb_encryption_level) { /* Attempt UNIX smb encryption. */ if (!NT_STATUS_IS_OK(cli_force_encryption(c, username_used, *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\n")); if (context->internal->smb_encryption_level == 2) { cli_shutdown(c); errno = EPERM; return NULL; } } DEBUG(4,(" SMB encrypt ok\n")); } /* * Ok, we have got a nice connection * Let's allocate a server structure. */ srv = SMB_MALLOC_P(SMBCSRV); if (!srv) { cli_shutdown(c); errno = ENOMEM; return NULL; } ZERO_STRUCTP(srv); srv->cli = c; srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); srv->no_pathinfo = False; srv->no_pathinfo2 = False; srv->no_nt_session = False; done: if (!pp_workgroup || !*pp_workgroup || !**pp_workgroup) { workgroup = talloc_strdup(ctx, smbc_getWorkgroup(context)); } else { workgroup = *pp_workgroup; } if(!workgroup) { return NULL; } /* set the credentials to make DFS work */ smbc_set_credentials_with_fallback(context, workgroup, *pp_username, *pp_password); return srv; }
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 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; }