2006-02-04 01:19:41 +03:00
/*
Unix SMB / CIFS implementation .
Name lookup .
Copyright ( C ) Jeremy Allison 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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2006-02-04 01:19:41 +03:00
( 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
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2006-02-04 01:19:41 +03:00
*/
# include "includes.h"
# include "utils/net.h"
2010-05-05 03:39:16 +04:00
# include "../librpc/gen_ndr/ndr_lsa.h"
2010-05-18 20:26:16 +04:00
# include "rpc_client/cli_lsarpc.h"
2006-02-04 01:19:41 +03:00
/********************************************************
Connection cachine struct . Goes away when ctx destroyed .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct con_struct {
2007-10-19 04:40:25 +04:00
bool failed_connect ;
2006-02-15 05:07:14 +03:00
NTSTATUS err ;
2006-02-04 01:19:41 +03:00
struct cli_state * cli ;
struct rpc_pipe_client * lsapipe ;
2009-03-19 00:49:41 +03:00
struct policy_handle pol ;
2006-02-04 01:19:41 +03:00
} ;
static struct con_struct * cs ;
/********************************************************
Close connection on context destruction .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-08-29 23:14:25 +04:00
static int cs_destructor ( struct con_struct * p )
2006-02-04 01:19:41 +03:00
{
if ( cs - > cli ) {
cli_shutdown ( cs - > cli ) ;
}
cs = NULL ;
return 0 ;
}
/********************************************************
Create the connection to localhost .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-10 01:22:12 +04:00
static struct con_struct * create_cs ( struct net_context * c ,
TALLOC_CTX * ctx , NTSTATUS * perr )
2006-02-04 01:19:41 +03:00
{
NTSTATUS nt_status ;
2007-10-25 01:16:54 +04:00
struct sockaddr_storage loopback_ss ;
2006-02-04 01:19:41 +03:00
2006-02-15 05:07:14 +03:00
* perr = NT_STATUS_OK ;
2007-10-25 01:16:54 +04:00
if ( ! interpret_string_addr ( & loopback_ss , " 127.0.0.1 " , AI_NUMERICHOST ) ) {
* perr = NT_STATUS_INVALID_PARAMETER ;
return NULL ;
}
2006-02-04 01:19:41 +03:00
if ( cs ) {
if ( cs - > failed_connect ) {
2006-02-15 05:07:14 +03:00
* perr = cs - > err ;
2006-02-04 01:19:41 +03:00
return NULL ;
}
return cs ;
}
cs = TALLOC_P ( ctx , struct con_struct ) ;
if ( ! cs ) {
2006-02-15 05:07:14 +03:00
* perr = NT_STATUS_NO_MEMORY ;
2006-02-04 01:19:41 +03:00
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: " ) ;
if ( pass ) {
opt_password = SMB_STRDUP ( pass ) ;
}
}
# endif
nt_status = cli_full_connection ( & cs - > cli , global_myname ( ) , global_myname ( ) ,
2007-10-25 01:16:54 +04:00
& loopback_ss , 0 ,
2006-02-04 01:19:41 +03:00
" IPC$ " , " IPC " ,
#if 0
2008-05-10 01:22:12 +04:00
c - > opt_user_name ,
c - > opt_workgroup ,
c - > opt_password ,
2006-02-04 01:19:41 +03:00
# else
" " ,
2008-05-10 01:22:12 +04:00
c - > opt_workgroup ,
2006-02-04 01:19:41 +03:00
" " ,
# endif
0 ,
2010-12-20 18:37:23 +03:00
Undefined ) ;
2006-02-04 01:19:41 +03:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
DEBUG ( 2 , ( " create_cs: Connect failed. Error was %s \n " , nt_errstr ( nt_status ) ) ) ;
2008-05-12 13:53:23 +04:00
cs - > failed_connect = true ;
2006-02-15 05:07:14 +03:00
cs - > err = nt_status ;
* perr = nt_status ;
2006-02-04 01:19:41 +03:00
return NULL ;
}
2008-07-20 13:04:31 +04:00
nt_status = cli_rpc_pipe_open_noauth ( cs - > cli ,
& ndr_table_lsarpc . syntax_id ,
& cs - > lsapipe ) ;
2006-02-04 01:19:41 +03:00
2008-07-20 13:04:31 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2006-02-04 01:19:41 +03:00
DEBUG ( 2 , ( " create_cs: open LSA pipe failed. Error was %s \n " , nt_errstr ( nt_status ) ) ) ;
2008-05-12 13:53:23 +04:00
cs - > failed_connect = true ;
2006-02-15 05:07:14 +03:00
cs - > err = nt_status ;
* perr = nt_status ;
2006-02-04 01:19:41 +03:00
return NULL ;
}
2008-05-12 13:53:23 +04:00
nt_status = rpccli_lsa_open_policy ( cs - > lsapipe , ctx , true ,
2009-04-15 03:12:13 +04:00
SEC_FLAG_MAXIMUM_ALLOWED ,
2006-02-04 01:19:41 +03:00
& 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 ) ) ) ;
2008-05-12 13:53:23 +04:00
cs - > failed_connect = true ;
2006-02-15 05:07:14 +03:00
cs - > err = nt_status ;
* perr = nt_status ;
2006-02-04 01:19:41 +03:00
return NULL ;
}
2006-02-15 05:07:14 +03:00
2006-02-04 01:19:41 +03:00
return cs ;
}
/********************************************************
Do a lookup_sids call to localhost .
Check if the local machine is authoritative for this sid . We can ' t
check if this is our SID as that ' s stored in the root - read - only
secrets . tdb .
The local smbd will also ask winbindd for us , so we don ' t have to .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-10 01:22:12 +04:00
NTSTATUS net_lookup_name_from_sid ( struct net_context * c ,
TALLOC_CTX * ctx ,
2010-05-21 05:25:01 +04:00
struct dom_sid * psid ,
2006-02-04 01:19:41 +03:00
const char * * ppdomain ,
const char * * ppname )
{
NTSTATUS nt_status ;
struct con_struct * csp = NULL ;
char * * domains ;
char * * names ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType * types ;
2006-02-04 01:19:41 +03:00
* ppdomain = NULL ;
* ppname = NULL ;
2008-05-10 01:22:12 +04:00
csp = create_cs ( c , ctx , & nt_status ) ;
2006-02-04 01:19:41 +03:00
if ( csp = = NULL ) {
2006-02-15 05:07:14 +03:00
return nt_status ;
2006-02-04 01:19:41 +03:00
}
nt_status = rpccli_lsa_lookup_sids ( csp - > lsapipe , ctx ,
& csp - > pol ,
1 , psid ,
& domains ,
& names ,
& types ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2006-02-15 05:07:14 +03:00
return nt_status ;
2006-02-04 01:19:41 +03:00
}
* ppdomain = domains [ 0 ] ;
* ppname = names [ 0 ] ;
/* Don't care about type here. */
/* Converted OK */
2006-02-15 05:07:14 +03:00
return NT_STATUS_OK ;
2006-02-04 01:19:41 +03:00
}
/********************************************************
Do a lookup_names call to localhost .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-10 01:22:12 +04:00
NTSTATUS net_lookup_sid_from_name ( struct net_context * c , TALLOC_CTX * ctx ,
2010-05-21 05:25:01 +04:00
const char * full_name , struct dom_sid * pret_sid )
2006-02-04 01:19:41 +03:00
{
NTSTATUS nt_status ;
struct con_struct * csp = NULL ;
2010-05-21 05:25:01 +04:00
struct dom_sid * sids = NULL ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType * types = NULL ;
2006-02-04 01:19:41 +03:00
2008-05-10 01:22:12 +04:00
csp = create_cs ( c , ctx , & nt_status ) ;
2006-02-04 01:19:41 +03:00
if ( csp = = NULL ) {
2006-02-15 05:07:14 +03:00
return nt_status ;
2006-02-04 01:19:41 +03:00
}
nt_status = rpccli_lsa_lookup_names ( csp - > lsapipe , ctx ,
& csp - > pol ,
1 ,
& full_name ,
2007-06-27 15:42:17 +04:00
NULL , 1 ,
& sids , & types ) ;
2006-02-04 01:19:41 +03:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2006-02-15 05:07:14 +03:00
return nt_status ;
2006-02-04 01:19:41 +03:00
}
* pret_sid = sids [ 0 ] ;
/* Converted OK */
2006-02-15 05:07:14 +03:00
return NT_STATUS_OK ;
2006-02-04 01:19:41 +03:00
}