1/* 2 Unix SMB/CIFS implementation. 3 4 Name lookup. 5 6 Copyright (C) Jeremy Allison 2005 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20*/ 21 22#include "includes.h" 23#include "utils/net.h" 24 25/******************************************************** 26 Connection cachine struct. Goes away when ctx destroyed. 27********************************************************/ 28 29struct con_struct { 30 bool failed_connect; 31 NTSTATUS err; 32 struct cli_state *cli; 33 struct rpc_pipe_client *lsapipe; 34 struct policy_handle pol; 35}; 36 37static struct con_struct *cs; 38 39/******************************************************** 40 Close connection on context destruction. 41********************************************************/ 42 43static int cs_destructor(struct con_struct *p) 44{ 45 if (cs->cli) { 46 cli_shutdown(cs->cli); 47 } 48 cs = NULL; 49 return 0; 50} 51 52/******************************************************** 53 Create the connection to localhost. 54********************************************************/ 55 56static struct con_struct *create_cs(struct net_context *c, 57 TALLOC_CTX *ctx, NTSTATUS *perr) 58{ 59 NTSTATUS nt_status; 60 struct sockaddr_storage loopback_ss; 61 62 *perr = NT_STATUS_OK; 63 64 if (!interpret_string_addr(&loopback_ss, "127.0.0.1", AI_NUMERICHOST)) { 65 *perr = NT_STATUS_INVALID_PARAMETER; 66 return NULL; 67 } 68 69 if (cs) { 70 if (cs->failed_connect) { 71 *perr = cs->err; 72 return NULL; 73 } 74 return cs; 75 } 76 77 cs = TALLOC_P(ctx, struct con_struct); 78 if (!cs) { 79 *perr = NT_STATUS_NO_MEMORY; 80 return NULL; 81 } 82 83 ZERO_STRUCTP(cs); 84 talloc_set_destructor(cs, cs_destructor); 85 86 /* Connect to localhost with given username/password. */ 87 /* JRA. Pretty sure we can just do this anonymously.... */ 88#if 0 89 if (!opt_password && !opt_machine_pass) { 90 char *pass = getpass("Password:"); 91 if (pass) { 92 opt_password = SMB_STRDUP(pass); 93 } 94 } 95#endif 96 97 nt_status = cli_full_connection(&cs->cli, global_myname(), global_myname(), 98 &loopback_ss, 0, 99 "IPC$", "IPC", 100#if 0 101 c->opt_user_name, 102 c->opt_workgroup, 103 c->opt_password, 104#else 105 "", 106 c->opt_workgroup, 107 "", 108#endif 109 0, 110 Undefined, 111 NULL); 112 113 if (!NT_STATUS_IS_OK(nt_status)) { 114 DEBUG(2,("create_cs: Connect failed. Error was %s\n", nt_errstr(nt_status))); 115 cs->failed_connect = true; 116 cs->err = nt_status; 117 *perr = nt_status; 118 return NULL; 119 } 120 121 nt_status = cli_rpc_pipe_open_noauth(cs->cli, 122 &ndr_table_lsarpc.syntax_id, 123 &cs->lsapipe); 124 125 if (!NT_STATUS_IS_OK(nt_status)) { 126 DEBUG(2,("create_cs: open LSA pipe failed. Error was %s\n", nt_errstr(nt_status))); 127 cs->failed_connect = true; 128 cs->err = nt_status; 129 *perr = nt_status; 130 return NULL; 131 } 132 133 nt_status = rpccli_lsa_open_policy(cs->lsapipe, ctx, true, 134 SEC_FLAG_MAXIMUM_ALLOWED, 135 &cs->pol); 136 137 if (!NT_STATUS_IS_OK(nt_status)) { 138 DEBUG(2,("create_cs: rpccli_lsa_open_policy failed. Error was %s\n", nt_errstr(nt_status))); 139 cs->failed_connect = true; 140 cs->err = nt_status; 141 *perr = nt_status; 142 return NULL; 143 } 144 145 return cs; 146} 147 148/******************************************************** 149 Do a lookup_sids call to localhost. 150 Check if the local machine is authoritative for this sid. We can't 151 check if this is our SID as that's stored in the root-read-only 152 secrets.tdb. 153 The local smbd will also ask winbindd for us, so we don't have to. 154********************************************************/ 155 156NTSTATUS net_lookup_name_from_sid(struct net_context *c, 157 TALLOC_CTX *ctx, 158 DOM_SID *psid, 159 const char **ppdomain, 160 const char **ppname) 161{ 162 NTSTATUS nt_status; 163 struct con_struct *csp = NULL; 164 char **domains; 165 char **names; 166 enum lsa_SidType *types; 167 168 *ppdomain = NULL; 169 *ppname = NULL; 170 171 csp = create_cs(c, ctx, &nt_status); 172 if (csp == NULL) { 173 return nt_status; 174 } 175 176 nt_status = rpccli_lsa_lookup_sids(csp->lsapipe, ctx, 177 &csp->pol, 178 1, psid, 179 &domains, 180 &names, 181 &types); 182 183 if (!NT_STATUS_IS_OK(nt_status)) { 184 return nt_status; 185 } 186 187 *ppdomain = domains[0]; 188 *ppname = names[0]; 189 /* Don't care about type here. */ 190 191 /* Converted OK */ 192 return NT_STATUS_OK; 193} 194 195/******************************************************** 196 Do a lookup_names call to localhost. 197********************************************************/ 198 199NTSTATUS net_lookup_sid_from_name(struct net_context *c, TALLOC_CTX *ctx, 200 const char *full_name, DOM_SID *pret_sid) 201{ 202 NTSTATUS nt_status; 203 struct con_struct *csp = NULL; 204 DOM_SID *sids = NULL; 205 enum lsa_SidType *types = NULL; 206 207 csp = create_cs(c, ctx, &nt_status); 208 if (csp == NULL) { 209 return nt_status; 210 } 211 212 nt_status = rpccli_lsa_lookup_names(csp->lsapipe, ctx, 213 &csp->pol, 214 1, 215 &full_name, 216 NULL, 1, 217 &sids, &types); 218 219 if (!NT_STATUS_IS_OK(nt_status)) { 220 return nt_status; 221 } 222 223 *pret_sid = sids[0]; 224 225 /* Converted OK */ 226 return NT_STATUS_OK; 227} 228