2000-12-13 15:52:21 +03:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2000-12-13 15:52:21 +03:00
RPC pipe client
2001-05-07 05:55:08 +04:00
Copyright ( C ) Tim Potter 2000 - 2001 ,
2000-12-13 15:52:21 +03:00
Copyright ( C ) Andrew Tridgell 1992 - 1997 , 2000 ,
Copyright ( C ) Luke Kenneth Casson Leighton 1996 - 1997 , 2000 ,
Copyright ( C ) Paul Ashton 1997 , 2000 ,
2002-05-17 17:49:01 +04:00
Copyright ( C ) Elrond 2000 ,
Copyright ( C ) Rafal Szczesniak 2002
2000-12-13 15:52:21 +03:00
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 2 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 , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2002-01-06 06:48:41 +03:00
/** @defgroup lsa LSA - Local Security Architecture
2001-11-23 08:50:05 +03:00
* @ ingroup rpc_client
2001-11-15 09:03:22 +03:00
*
* @ {
* */
/**
* @ file cli_lsarpc . c
*
* RPC client routines for the LSA RPC pipe . LSA means " local
* security authority " , which is half of a password database.
* */
2001-11-23 08:50:05 +03:00
/** Open a LSA policy handle
*
* @ param cli Handle on an initialised SMB connection */
2000-12-13 15:52:21 +03:00
2001-08-28 01:32:54 +04:00
NTSTATUS cli_lsa_open_policy ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
BOOL sec_qos , uint32 des_access , POLICY_HND * pol )
2000-12-13 15:52:21 +03:00
{
prs_struct qbuf , rbuf ;
LSA_Q_OPEN_POL q ;
LSA_R_OPEN_POL r ;
LSA_SEC_QOS qos ;
2001-08-28 01:32:54 +04:00
NTSTATUS result ;
2000-12-13 15:52:21 +03:00
ZERO_STRUCT ( q ) ;
ZERO_STRUCT ( r ) ;
/* Initialise parse structures */
2001-04-28 04:32:56 +04:00
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
2000-12-13 15:52:21 +03:00
/* Initialise input parameters */
if ( sec_qos ) {
2001-12-18 02:03:23 +03:00
init_lsa_sec_qos ( & qos , 2 , 1 , 0 ) ;
2000-12-13 15:52:21 +03:00
init_q_open_pol ( & q , ' \\ ' , 0 , des_access , & qos ) ;
} else {
init_q_open_pol ( & q , ' \\ ' , 0 , des_access , NULL ) ;
}
/* Marshall data and send request */
if ( ! lsa_io_q_open_pol ( " " , & q , & qbuf , 0 ) | |
2005-01-06 14:42:40 +03:00
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_OPENPOLICY , & qbuf , & rbuf ) ) {
2000-12-18 08:27:44 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
2000-12-13 15:52:21 +03:00
}
/* Unmarshall response */
if ( ! lsa_io_r_open_pol ( " " , & r , & rbuf , 0 ) ) {
2000-12-18 08:27:44 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
2000-12-13 15:52:21 +03:00
}
/* Return output parameters */
2001-09-04 11:13:01 +04:00
if ( NT_STATUS_IS_OK ( result = r . status ) ) {
2001-01-10 21:44:39 +03:00
* pol = r . pol ;
2002-04-04 10:55:32 +04:00
# ifdef __INSURE__
2004-12-07 21:25:53 +03:00
pol - > marker = MALLOC ( 1 ) ;
2002-04-04 10:55:32 +04:00
# endif
2000-12-13 15:52:21 +03:00
}
2000-12-18 08:27:44 +03:00
done :
2000-12-15 04:02:11 +03:00
prs_mem_free ( & qbuf ) ;
prs_mem_free ( & rbuf ) ;
2000-12-18 08:27:44 +03:00
2000-12-13 15:52:21 +03:00
return result ;
}
2002-02-21 01:34:35 +03:00
/** Open a LSA policy handle
*
* @ param cli Handle on an initialised SMB connection
*/
2001-08-21 07:05:27 +04:00
2001-08-28 01:32:54 +04:00
NTSTATUS cli_lsa_open_policy2 ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
BOOL sec_qos , uint32 des_access , POLICY_HND * pol )
2001-08-21 07:05:27 +04:00
{
prs_struct qbuf , rbuf ;
LSA_Q_OPEN_POL2 q ;
LSA_R_OPEN_POL2 r ;
LSA_SEC_QOS qos ;
2001-08-28 01:32:54 +04:00
NTSTATUS result ;
2001-08-21 07:05:27 +04:00
ZERO_STRUCT ( q ) ;
ZERO_STRUCT ( r ) ;
/* Initialise parse structures */
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
/* Initialise input parameters */
if ( sec_qos ) {
2001-12-18 02:03:23 +03:00
init_lsa_sec_qos ( & qos , 2 , 1 , 0 ) ;
2002-02-21 01:34:35 +03:00
init_q_open_pol2 ( & q , cli - > srv_name_slash , 0 , des_access ,
2001-08-21 07:05:27 +04:00
& qos ) ;
} else {
2002-02-21 01:34:35 +03:00
init_q_open_pol2 ( & q , cli - > srv_name_slash , 0 , des_access ,
2001-08-21 07:05:27 +04:00
NULL ) ;
}
/* Marshall data and send request */
if ( ! lsa_io_q_open_pol2 ( " " , & q , & qbuf , 0 ) | |
2005-01-06 14:42:40 +03:00
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_OPENPOLICY2 , & qbuf , & rbuf ) ) {
2001-08-21 07:05:27 +04:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Unmarshall response */
if ( ! lsa_io_r_open_pol2 ( " " , & r , & rbuf , 0 ) ) {
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Return output parameters */
2001-09-04 11:13:01 +04:00
if ( NT_STATUS_IS_OK ( result = r . status ) ) {
2001-08-21 07:05:27 +04:00
* pol = r . pol ;
2002-04-04 10:55:32 +04:00
# ifdef __INSURE__
pol - > marker = ( char * ) malloc ( 1 ) ;
# endif
2001-08-21 07:05:27 +04:00
}
done :
prs_mem_free ( & qbuf ) ;
prs_mem_free ( & rbuf ) ;
return result ;
}
2001-11-15 09:03:22 +03:00
/** Close a LSA policy handle */
2000-12-13 15:52:21 +03:00
2001-08-28 01:32:54 +04:00
NTSTATUS cli_lsa_close ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
POLICY_HND * pol )
2000-12-13 15:52:21 +03:00
{
prs_struct qbuf , rbuf ;
LSA_Q_CLOSE q ;
LSA_R_CLOSE r ;
2001-08-28 01:32:54 +04:00
NTSTATUS result ;
2000-12-13 15:52:21 +03:00
ZERO_STRUCT ( q ) ;
ZERO_STRUCT ( r ) ;
/* Initialise parse structures */
2001-04-28 04:32:56 +04:00
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
2000-12-13 15:52:21 +03:00
/* Marshall data and send request */
2001-01-10 21:44:39 +03:00
init_lsa_q_close ( & q , pol ) ;
2000-12-13 15:52:21 +03:00
if ( ! lsa_io_q_close ( " " , & q , & qbuf , 0 ) | |
2005-01-06 14:42:40 +03:00
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_CLOSE , & qbuf , & rbuf ) ) {
2000-12-18 08:27:44 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
2000-12-13 15:52:21 +03:00
}
/* Unmarshall response */
if ( ! lsa_io_r_close ( " " , & r , & rbuf , 0 ) ) {
2000-12-18 08:27:44 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
2000-12-13 15:52:21 +03:00
}
/* Return output parameters */
2001-09-04 11:13:01 +04:00
if ( NT_STATUS_IS_OK ( result = r . status ) ) {
2002-04-04 10:55:32 +04:00
# ifdef __INSURE__
SAFE_FREE ( pol - > marker ) ;
# endif
2001-01-10 21:44:39 +03:00
* pol = r . pol ;
2000-12-13 15:52:21 +03:00
}
2000-12-18 08:27:44 +03:00
done :
2000-12-15 04:02:11 +03:00
prs_mem_free ( & qbuf ) ;
prs_mem_free ( & rbuf ) ;
2000-12-18 08:27:44 +03:00
2000-12-13 15:52:21 +03:00
return result ;
}
2001-11-15 09:03:22 +03:00
/** Lookup a list of sids */
2000-12-13 15:52:21 +03:00
2001-08-28 01:32:54 +04:00
NTSTATUS cli_lsa_lookup_sids ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
2004-01-05 05:04:37 +03:00
POLICY_HND * pol , int num_sids , const DOM_SID * sids ,
2002-04-14 15:21:25 +04:00
char * * * domains , char * * * names , uint32 * * types )
2000-12-13 15:52:21 +03:00
{
prs_struct qbuf , rbuf ;
LSA_Q_LOOKUP_SIDS q ;
LSA_R_LOOKUP_SIDS r ;
DOM_R_REF ref ;
LSA_TRANS_NAME_ENUM t_names ;
2001-08-28 01:32:54 +04:00
NTSTATUS result ;
2000-12-13 15:52:21 +03:00
int i ;
ZERO_STRUCT ( q ) ;
ZERO_STRUCT ( r ) ;
/* Initialise parse structures */
2001-04-28 04:32:56 +04:00
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
2000-12-13 15:52:21 +03:00
/* Marshall data and send request */
2001-04-28 04:32:56 +04:00
init_q_lookup_sids ( mem_ctx , & q , pol , num_sids , sids , 1 ) ;
2000-12-13 15:52:21 +03:00
if ( ! lsa_io_q_lookup_sids ( " " , & q , & qbuf , 0 ) | |
2005-01-06 14:42:40 +03:00
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_LOOKUPSIDS , & qbuf , & rbuf ) ) {
2000-12-18 08:27:44 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
2000-12-13 15:52:21 +03:00
}
/* Unmarshall response */
ZERO_STRUCT ( ref ) ;
ZERO_STRUCT ( t_names ) ;
r . dom_ref = & ref ;
r . names = & t_names ;
if ( ! lsa_io_r_lookup_sids ( " " , & r , & rbuf , 0 ) ) {
2000-12-18 08:27:44 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
2000-12-13 15:52:21 +03:00
}
result = r . status ;
2001-11-22 11:31:50 +03:00
if ( ! NT_STATUS_IS_OK ( result ) & &
2002-04-14 15:21:25 +04:00
NT_STATUS_V ( result ) ! = NT_STATUS_V ( STATUS_SOME_UNMAPPED ) ) {
2000-12-13 15:52:21 +03:00
/* An actual error occured */
goto done ;
}
/* Return output parameters */
2001-11-22 11:31:50 +03:00
if ( r . mapped_count = = 0 ) {
result = NT_STATUS_NONE_MAPPED ;
goto done ;
}
2004-12-07 21:25:53 +03:00
if ( ! ( ( * domains ) = TALLOC_ARRAY ( mem_ctx , char * , num_sids ) ) ) {
2002-01-20 04:24:59 +03:00
DEBUG ( 0 , ( " cli_lsa_lookup_sids(): out of memory \n " ) ) ;
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2004-12-07 21:25:53 +03:00
if ( ! ( ( * names ) = TALLOC_ARRAY ( mem_ctx , char * , num_sids ) ) ) {
2000-12-13 15:52:21 +03:00
DEBUG ( 0 , ( " cli_lsa_lookup_sids(): out of memory \n " ) ) ;
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2004-12-07 21:25:53 +03:00
if ( ! ( ( * types ) = TALLOC_ARRAY ( mem_ctx , uint32 , num_sids ) ) ) {
2000-12-13 15:52:21 +03:00
DEBUG ( 0 , ( " cli_lsa_lookup_sids(): out of memory \n " ) ) ;
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2002-04-14 15:21:25 +04:00
for ( i = 0 ; i < num_sids ; i + + ) {
2002-01-20 04:24:59 +03:00
fstring name , dom_name ;
2000-12-13 15:52:21 +03:00
uint32 dom_idx = t_names . name [ i ] . domain_idx ;
/* Translate optimised name through domain index array */
if ( dom_idx ! = 0xffffffff ) {
2001-07-20 05:35:00 +04:00
rpcstr_pull_unistr2_fstring (
dom_name , & ref . ref_dom [ dom_idx ] . uni_dom_name ) ;
rpcstr_pull_unistr2_fstring (
name , & t_names . uni_name [ i ] ) ;
2000-12-13 15:52:21 +03:00
2002-01-20 04:24:59 +03:00
( * names ) [ i ] = talloc_strdup ( mem_ctx , name ) ;
( * domains ) [ i ] = talloc_strdup ( mem_ctx , dom_name ) ;
2000-12-13 15:52:21 +03:00
( * types ) [ i ] = t_names . name [ i ] . sid_name_use ;
2002-01-20 04:24:59 +03:00
if ( ( ( * names ) [ i ] = = NULL ) | | ( ( * domains ) [ i ] = = NULL ) ) {
DEBUG ( 0 , ( " cli_lsa_lookup_sids(): out of memory \n " ) ) ;
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2001-07-20 05:35:00 +04:00
2000-12-13 15:52:21 +03:00
} else {
( * names ) [ i ] = NULL ;
2003-10-22 11:29:18 +04:00
( * domains ) [ i ] = NULL ;
2000-12-13 15:52:21 +03:00
( * types ) [ i ] = SID_NAME_UNKNOWN ;
}
}
done :
2000-12-15 04:02:11 +03:00
prs_mem_free ( & qbuf ) ;
prs_mem_free ( & rbuf ) ;
2000-12-13 15:52:21 +03:00
return result ;
}
2001-11-15 09:03:22 +03:00
/** Lookup a list of names */
2000-12-13 15:52:21 +03:00
2001-08-28 01:32:54 +04:00
NTSTATUS cli_lsa_lookup_names ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
2002-04-14 15:21:25 +04:00
POLICY_HND * pol , int num_names ,
const char * * names , DOM_SID * * sids ,
uint32 * * types )
2000-12-13 15:52:21 +03:00
{
prs_struct qbuf , rbuf ;
LSA_Q_LOOKUP_NAMES q ;
LSA_R_LOOKUP_NAMES r ;
DOM_R_REF ref ;
2001-08-28 01:32:54 +04:00
NTSTATUS result ;
2000-12-13 15:52:21 +03:00
int i ;
ZERO_STRUCT ( q ) ;
ZERO_STRUCT ( r ) ;
/* Initialise parse structures */
2001-04-28 04:32:56 +04:00
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
2000-12-13 15:52:21 +03:00
/* Marshall data and send request */
2002-01-26 14:48:42 +03:00
init_q_lookup_names ( mem_ctx , & q , pol , num_names , names ) ;
2000-12-13 15:52:21 +03:00
if ( ! lsa_io_q_lookup_names ( " " , & q , & qbuf , 0 ) | |
2005-01-06 14:42:40 +03:00
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_LOOKUPNAMES , & qbuf , & rbuf ) ) {
2000-12-18 08:27:44 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
2000-12-13 15:52:21 +03:00
}
/* Unmarshall response */
ZERO_STRUCT ( ref ) ;
r . dom_ref = & ref ;
2000-12-15 04:02:11 +03:00
if ( ! lsa_io_r_lookup_names ( " " , & r , & rbuf , 0 ) ) {
2000-12-18 08:27:44 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
2000-12-13 15:52:21 +03:00
}
result = r . status ;
2002-04-14 15:21:25 +04:00
if ( ! NT_STATUS_IS_OK ( result ) & & NT_STATUS_V ( result ) ! =
NT_STATUS_V ( STATUS_SOME_UNMAPPED ) ) {
2000-12-13 15:52:21 +03:00
/* An actual error occured */
goto done ;
}
/* Return output parameters */
2001-11-22 11:31:50 +03:00
if ( r . mapped_count = = 0 ) {
result = NT_STATUS_NONE_MAPPED ;
goto done ;
}
2004-12-07 21:25:53 +03:00
if ( ! ( ( * sids = TALLOC_ARRAY ( mem_ctx , DOM_SID , num_names ) ) ) ) {
2000-12-13 15:52:21 +03:00
DEBUG ( 0 , ( " cli_lsa_lookup_sids(): out of memory \n " ) ) ;
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2004-12-07 21:25:53 +03:00
if ( ! ( ( * types = TALLOC_ARRAY ( mem_ctx , uint32 , num_names ) ) ) ) {
2000-12-13 15:52:21 +03:00
DEBUG ( 0 , ( " cli_lsa_lookup_sids(): out of memory \n " ) ) ;
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2002-04-14 15:21:25 +04:00
for ( i = 0 ; i < num_names ; i + + ) {
2000-12-13 15:52:21 +03:00
DOM_RID2 * t_rids = r . dom_rid ;
uint32 dom_idx = t_rids [ i ] . rid_idx ;
uint32 dom_rid = t_rids [ i ] . rid ;
DOM_SID * sid = & ( * sids ) [ i ] ;
/* Translate optimised sid through domain index array */
if ( dom_idx ! = 0xffffffff ) {
sid_copy ( sid , & ref . ref_dom [ dom_idx ] . ref_dom . sid ) ;
if ( dom_rid ! = 0xffffffff ) {
sid_append_rid ( sid , dom_rid ) ;
}
( * types ) [ i ] = t_rids [ i ] . type ;
} else {
ZERO_STRUCTP ( sid ) ;
( * types ) [ i ] = SID_NAME_UNKNOWN ;
}
}
done :
2000-12-15 04:02:11 +03:00
prs_mem_free ( & qbuf ) ;
prs_mem_free ( & rbuf ) ;
2000-12-13 15:52:21 +03:00
return result ;
}
2000-12-18 09:09:40 +03:00
2002-02-21 01:34:35 +03:00
/** Query info policy
*
* @ param domain_sid - returned remote server ' s domain sid */
2000-12-18 09:09:40 +03:00
2001-08-28 01:32:54 +04:00
NTSTATUS cli_lsa_query_info_policy ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
POLICY_HND * pol , uint16 info_class ,
2004-01-08 11:19:18 +03:00
char * * domain_name , DOM_SID * * domain_sid )
2000-12-18 09:09:40 +03:00
{
prs_struct qbuf , rbuf ;
LSA_Q_QUERY_INFO q ;
LSA_R_QUERY_INFO r ;
2001-08-28 01:32:54 +04:00
NTSTATUS result ;
2000-12-18 09:09:40 +03:00
ZERO_STRUCT ( q ) ;
ZERO_STRUCT ( r ) ;
/* Initialise parse structures */
2001-04-28 04:32:56 +04:00
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
2000-12-18 09:09:40 +03:00
/* Marshall data and send request */
2001-01-10 21:44:39 +03:00
init_q_query ( & q , pol , info_class ) ;
2000-12-18 09:09:40 +03:00
if ( ! lsa_io_q_query ( " " , & q , & qbuf , 0 ) | |
2005-01-06 14:42:40 +03:00
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_QUERYINFOPOLICY , & qbuf , & rbuf ) ) {
2000-12-18 09:09:40 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Unmarshall response */
if ( ! lsa_io_r_query ( " " , & r , & rbuf , 0 ) ) {
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2001-09-04 11:13:01 +04:00
if ( ! NT_STATUS_IS_OK ( result = r . status ) ) {
2000-12-18 09:09:40 +03:00
goto done ;
}
/* Return output parameters */
switch ( info_class ) {
case 3 :
2004-01-08 11:19:18 +03:00
if ( domain_name & & ( r . dom . id3 . buffer_dom_name ! = 0 ) ) {
* domain_name = unistr2_tdup ( mem_ctx ,
& r . dom . id3 .
uni_domain_name ) ;
2000-12-18 09:09:40 +03:00
}
2004-01-08 11:19:18 +03:00
if ( domain_sid & & ( r . dom . id3 . buffer_dom_sid ! = 0 ) ) {
2004-12-07 21:25:53 +03:00
* domain_sid = TALLOC_P ( mem_ctx , DOM_SID ) ;
2004-01-08 11:19:18 +03:00
if ( * domain_sid ) {
sid_copy ( * domain_sid , & r . dom . id3 . dom_sid . sid ) ;
}
2000-12-18 09:09:40 +03:00
}
break ;
case 5 :
2004-01-08 11:19:18 +03:00
if ( domain_name & & ( r . dom . id5 . buffer_dom_name ! = 0 ) ) {
* domain_name = unistr2_tdup ( mem_ctx ,
& r . dom . id5 .
uni_domain_name ) ;
2000-12-18 09:09:40 +03:00
}
2004-01-08 11:19:18 +03:00
if ( domain_sid & & ( r . dom . id5 . buffer_dom_sid ! = 0 ) ) {
2004-12-07 21:25:53 +03:00
* domain_sid = TALLOC_P ( mem_ctx , DOM_SID ) ;
2004-01-08 11:19:18 +03:00
if ( * domain_sid ) {
sid_copy ( * domain_sid , & r . dom . id5 . dom_sid . sid ) ;
}
2000-12-18 09:09:40 +03:00
}
break ;
2004-01-08 11:19:18 +03:00
2000-12-18 09:09:40 +03:00
default :
DEBUG ( 3 , ( " unknown info class %d \n " , info_class ) ) ;
break ;
}
done :
prs_mem_free ( & qbuf ) ;
prs_mem_free ( & rbuf ) ;
return result ;
}
2001-01-10 21:44:39 +03:00
2002-08-12 17:40:59 +04:00
/** Query info policy2
*
* @ param domain_name - returned remote server ' s domain name
* @ param dns_name - returned remote server ' s dns domain name
* @ param forest_name - returned remote server ' s forest name
* @ param domain_guid - returned remote server ' s domain guid
* @ param domain_sid - returned remote server ' s domain sid */
NTSTATUS cli_lsa_query_info_policy2 ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
POLICY_HND * pol , uint16 info_class ,
2004-01-08 11:19:18 +03:00
char * * domain_name , char * * dns_name ,
2004-04-13 18:39:48 +04:00
char * * forest_name , struct uuid * * domain_guid ,
2004-01-08 11:19:18 +03:00
DOM_SID * * domain_sid )
2002-08-12 17:40:59 +04:00
{
prs_struct qbuf , rbuf ;
LSA_Q_QUERY_INFO2 q ;
LSA_R_QUERY_INFO2 r ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
if ( info_class ! = 12 )
goto done ;
ZERO_STRUCT ( q ) ;
ZERO_STRUCT ( r ) ;
/* Initialise parse structures */
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
/* Marshall data and send request */
init_q_query2 ( & q , pol , info_class ) ;
if ( ! lsa_io_q_query_info2 ( " " , & q , & qbuf , 0 ) | |
2005-01-06 14:42:40 +03:00
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_QUERYINFO2 , & qbuf , & rbuf ) ) {
2002-08-12 17:40:59 +04:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Unmarshall response */
if ( ! lsa_io_r_query_info2 ( " " , & r , & rbuf , 0 ) ) {
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( ! NT_STATUS_IS_OK ( result = r . status ) ) {
goto done ;
}
/* Return output parameters */
ZERO_STRUCTP ( domain_guid ) ;
2004-01-08 11:19:18 +03:00
if ( domain_name & & r . info . dns_dom_info . hdr_nb_dom_name . buffer ) {
* domain_name = unistr2_tdup ( mem_ctx ,
& r . info . dns_dom_info
. uni_nb_dom_name ) ;
2002-08-12 17:40:59 +04:00
}
2004-01-08 11:19:18 +03:00
if ( dns_name & & r . info . dns_dom_info . hdr_dns_dom_name . buffer ) {
* dns_name = unistr2_tdup ( mem_ctx ,
& r . info . dns_dom_info
. uni_dns_dom_name ) ;
2002-08-12 17:40:59 +04:00
}
2004-01-08 11:19:18 +03:00
if ( forest_name & & r . info . dns_dom_info . hdr_forest_name . buffer ) {
* forest_name = unistr2_tdup ( mem_ctx ,
& r . info . dns_dom_info
. uni_forest_name ) ;
2002-08-12 17:40:59 +04:00
}
2004-01-08 11:19:18 +03:00
if ( domain_guid ) {
2004-12-07 21:25:53 +03:00
* domain_guid = TALLOC_P ( mem_ctx , struct uuid ) ;
2004-01-08 11:19:18 +03:00
memcpy ( * domain_guid ,
& r . info . dns_dom_info . dom_guid ,
2004-04-13 18:39:48 +04:00
sizeof ( struct uuid ) ) ;
2004-01-08 11:19:18 +03:00
}
if ( domain_sid & & r . info . dns_dom_info . ptr_dom_sid ! = 0 ) {
2004-12-07 21:25:53 +03:00
* domain_sid = TALLOC_P ( mem_ctx , DOM_SID ) ;
2004-01-08 11:19:18 +03:00
if ( * domain_sid ) {
sid_copy ( * domain_sid ,
& r . info . dns_dom_info . dom_sid . sid ) ;
}
2002-08-12 17:40:59 +04:00
}
done :
prs_mem_free ( & qbuf ) ;
prs_mem_free ( & rbuf ) ;
return result ;
}
2002-05-17 17:49:01 +04:00
/**
* Enumerate list of trusted domains
*
* @ param cli client state ( cli_state ) structure of the connection
* @ param mem_ctx memory context
* @ param pol opened lsa policy handle
* @ param enum_ctx enumeration context ie . index of first returned domain entry
* @ param pref_num_domains preferred max number of entries returned in one response
* @ param num_domains total number of trusted domains returned by response
* @ param domain_names returned trusted domain names
* @ param domain_sids returned trusted domain sids
*
* @ return nt status code of response
* */
2001-01-10 21:44:39 +03:00
2001-08-28 01:32:54 +04:00
NTSTATUS cli_lsa_enum_trust_dom ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
POLICY_HND * pol , uint32 * enum_ctx ,
2002-08-05 06:47:46 +04:00
uint32 * num_domains ,
2002-07-27 04:15:02 +04:00
char * * * domain_names , DOM_SID * * domain_sids )
2001-01-10 21:44:39 +03:00
{
prs_struct qbuf , rbuf ;
LSA_Q_ENUM_TRUST_DOM q ;
LSA_R_ENUM_TRUST_DOM r ;
2001-08-28 01:32:54 +04:00
NTSTATUS result ;
2001-01-10 21:44:39 +03:00
int i ;
ZERO_STRUCT ( q ) ;
ZERO_STRUCT ( r ) ;
/* Initialise parse structures */
2001-04-28 04:32:56 +04:00
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
2001-01-10 21:44:39 +03:00
/* Marshall data and send request */
2002-08-05 06:47:46 +04:00
/* 64k is enough for about 2000 trusted domains */
init_q_enum_trust_dom ( & q , pol , * enum_ctx , 0x10000 ) ;
2001-01-10 21:44:39 +03:00
if ( ! lsa_io_q_enum_trust_dom ( " " , & q , & qbuf , 0 ) | |
2005-01-06 14:42:40 +03:00
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_ENUMTRUSTDOM , & qbuf , & rbuf ) ) {
2001-01-10 21:44:39 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Unmarshall response */
if ( ! lsa_io_r_enum_trust_dom ( " " , & r , & rbuf , 0 ) ) {
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
result = r . status ;
2002-05-17 17:49:01 +04:00
if ( ! NT_STATUS_IS_OK ( result ) & &
! NT_STATUS_EQUAL ( result , NT_STATUS_NO_MORE_ENTRIES ) & &
! NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) ) {
2001-01-10 21:44:39 +03:00
/* An actual error ocured */
goto done ;
}
/* Return output parameters */
2001-06-22 06:15:02 +04:00
if ( r . num_domains ) {
2001-01-10 21:44:39 +03:00
2001-06-22 06:15:02 +04:00
/* Allocate memory for trusted domain names and sids */
2001-01-10 21:44:39 +03:00
2004-12-07 21:25:53 +03:00
* domain_names = TALLOC_ARRAY ( mem_ctx , char * , r . num_domains ) ;
2001-01-10 21:44:39 +03:00
2001-06-22 06:15:02 +04:00
if ( ! * domain_names ) {
DEBUG ( 0 , ( " cli_lsa_enum_trust_dom(): out of memory \n " ) ) ;
2002-07-27 04:15:02 +04:00
result = NT_STATUS_NO_MEMORY ;
2001-06-22 06:15:02 +04:00
goto done ;
}
2004-12-07 21:25:53 +03:00
* domain_sids = TALLOC_ARRAY ( mem_ctx , DOM_SID , r . num_domains ) ;
2001-06-22 06:15:02 +04:00
if ( ! domain_sids ) {
DEBUG ( 0 , ( " cli_lsa_enum_trust_dom(): out of memory \n " ) ) ;
2002-07-27 04:15:02 +04:00
result = NT_STATUS_NO_MEMORY ;
2001-06-22 06:15:02 +04:00
goto done ;
}
/* Copy across names and sids */
for ( i = 0 ; i < r . num_domains ; i + + ) {
fstring tmp ;
unistr2_to_ascii ( tmp , & r . uni_domain_name [ i ] ,
sizeof ( tmp ) - 1 ) ;
2002-04-04 10:11:22 +04:00
( * domain_names ) [ i ] = talloc_strdup ( mem_ctx , tmp ) ;
2001-06-22 06:15:02 +04:00
sid_copy ( & ( * domain_sids ) [ i ] , & r . domain_sid [ i ] . sid ) ;
}
2001-01-10 21:44:39 +03:00
}
* num_domains = r . num_domains ;
* enum_ctx = r . enum_context ;
done :
prs_mem_free ( & qbuf ) ;
prs_mem_free ( & rbuf ) ;
return result ;
}
2001-11-15 09:03:22 +03:00
2002-07-27 04:15:02 +04:00
2001-11-22 19:12:43 +03:00
/** Enumerate privileges*/
NTSTATUS cli_lsa_enum_privilege ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
POLICY_HND * pol , uint32 * enum_context , uint32 pref_max_length ,
uint32 * count , char * * * privs_name , uint32 * * privs_high , uint32 * * privs_low )
{
prs_struct qbuf , rbuf ;
LSA_Q_ENUM_PRIVS q ;
LSA_R_ENUM_PRIVS r ;
NTSTATUS result ;
int i ;
ZERO_STRUCT ( q ) ;
ZERO_STRUCT ( r ) ;
/* Initialise parse structures */
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
/* Marshall data and send request */
init_q_enum_privs ( & q , pol , * enum_context , pref_max_length ) ;
if ( ! lsa_io_q_enum_privs ( " " , & q , & qbuf , 0 ) | |
2005-01-06 14:42:40 +03:00
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_ENUM_PRIVS , & qbuf , & rbuf ) ) {
2001-11-22 19:12:43 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Unmarshall response */
if ( ! lsa_io_r_enum_privs ( " " , & r , & rbuf , 0 ) ) {
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( ! NT_STATUS_IS_OK ( result = r . status ) ) {
goto done ;
}
/* Return output parameters */
* enum_context = r . enum_context ;
* count = r . count ;
2004-12-07 21:25:53 +03:00
if ( ! ( ( * privs_name = TALLOC_ARRAY ( mem_ctx , char * , r . count ) ) ) ) {
2001-11-22 19:12:43 +03:00
DEBUG ( 0 , ( " (cli_lsa_enum_privilege): out of memory \n " ) ) ;
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2004-12-07 21:25:53 +03:00
if ( ! ( ( * privs_high = TALLOC_ARRAY ( mem_ctx , uint32 , r . count ) ) ) ) {
2001-11-22 19:12:43 +03:00
DEBUG ( 0 , ( " (cli_lsa_enum_privilege): out of memory \n " ) ) ;
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2004-12-07 21:25:53 +03:00
if ( ! ( ( * privs_low = TALLOC_ARRAY ( mem_ctx , uint32 , r . count ) ) ) ) {
2001-11-22 19:12:43 +03:00
DEBUG ( 0 , ( " (cli_lsa_enum_privilege): out of memory \n " ) ) ;
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
for ( i = 0 ; i < r . count ; i + + ) {
fstring name ;
rpcstr_pull_unistr2_fstring ( name , & r . privs [ i ] . name ) ;
( * privs_name ) [ i ] = talloc_strdup ( mem_ctx , name ) ;
( * privs_high ) [ i ] = r . privs [ i ] . luid_high ;
( * privs_low ) [ i ] = r . privs [ i ] . luid_low ;
}
done :
prs_mem_free ( & qbuf ) ;
prs_mem_free ( & rbuf ) ;
return result ;
}
2001-11-22 19:54:48 +03:00
/** Get privilege name */
NTSTATUS cli_lsa_get_dispname ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
2003-02-26 02:51:56 +03:00
POLICY_HND * pol , const char * name ,
uint16 lang_id , uint16 lang_id_sys ,
2001-11-22 19:54:48 +03:00
fstring description , uint16 * lang_id_desc )
{
prs_struct qbuf , rbuf ;
LSA_Q_PRIV_GET_DISPNAME q ;
LSA_R_PRIV_GET_DISPNAME r ;
NTSTATUS result ;
ZERO_STRUCT ( q ) ;
ZERO_STRUCT ( r ) ;
/* Initialise parse structures */
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
/* Marshall data and send request */
init_lsa_priv_get_dispname ( & q , pol , name , lang_id , lang_id_sys ) ;
if ( ! lsa_io_q_priv_get_dispname ( " " , & q , & qbuf , 0 ) | |
2005-01-06 14:42:40 +03:00
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_PRIV_GET_DISPNAME , & qbuf , & rbuf ) ) {
2001-11-22 19:54:48 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Unmarshall response */
if ( ! lsa_io_r_priv_get_dispname ( " " , & r , & rbuf , 0 ) ) {
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( ! NT_STATUS_IS_OK ( result = r . status ) ) {
goto done ;
}
/* Return output parameters */
rpcstr_pull_unistr2_fstring ( description , & r . desc ) ;
* lang_id_desc = r . lang_id ;
done :
prs_mem_free ( & qbuf ) ;
prs_mem_free ( & rbuf ) ;
return result ;
}
2001-11-23 02:50:16 +03:00
/** Enumerate list of SIDs */
NTSTATUS cli_lsa_enum_sids ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
POLICY_HND * pol , uint32 * enum_ctx , uint32 pref_max_length ,
uint32 * num_sids , DOM_SID * * sids )
{
prs_struct qbuf , rbuf ;
LSA_Q_ENUM_ACCOUNTS q ;
LSA_R_ENUM_ACCOUNTS r ;
NTSTATUS result ;
int i ;
ZERO_STRUCT ( q ) ;
ZERO_STRUCT ( r ) ;
/* Initialise parse structures */
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
/* Marshall data and send request */
init_lsa_q_enum_accounts ( & q , pol , * enum_ctx , pref_max_length ) ;
if ( ! lsa_io_q_enum_accounts ( " " , & q , & qbuf , 0 ) | |
2005-01-06 14:42:40 +03:00
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_ENUM_ACCOUNTS , & qbuf , & rbuf ) ) {
2001-11-23 02:50:16 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Unmarshall response */
if ( ! lsa_io_r_enum_accounts ( " " , & r , & rbuf , 0 ) ) {
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
result = r . status ;
if ( ! NT_STATUS_IS_OK ( result = r . status ) ) {
goto done ;
}
2001-11-23 18:11:22 +03:00
if ( r . sids . num_entries = = 0 )
goto done ;
2001-11-23 02:50:16 +03:00
/* Return output parameters */
2004-12-07 21:25:53 +03:00
* sids = TALLOC_ARRAY ( mem_ctx , DOM_SID , r . sids . num_entries ) ;
2001-11-23 02:50:16 +03:00
if ( ! * sids ) {
DEBUG ( 0 , ( " (cli_lsa_enum_sids): out of memory \n " ) ) ;
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Copy across names and sids */
for ( i = 0 ; i < r . sids . num_entries ; i + + ) {
sid_copy ( & ( * sids ) [ i ] , & r . sids . sid [ i ] . sid ) ;
}
* num_sids = r . sids . num_entries ;
* enum_ctx = r . enum_context ;
done :
prs_mem_free ( & qbuf ) ;
prs_mem_free ( & rbuf ) ;
return result ;
}
2005-01-14 22:26:13 +03:00
/** Create a LSA user handle
*
* @ param cli Handle on an initialised SMB connection
*
* FIXME : The code is actually identical to open account
* TODO : Check and code what the function should exactly do
*
* */
NTSTATUS cli_lsa_create_account ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
POLICY_HND * dom_pol , DOM_SID * sid , uint32 desired_access ,
POLICY_HND * user_pol )
{
prs_struct qbuf , rbuf ;
LSA_Q_CREATEACCOUNT q ;
LSA_R_CREATEACCOUNT r ;
NTSTATUS result ;
ZERO_STRUCT ( q ) ;
ZERO_STRUCT ( r ) ;
/* Initialise parse structures */
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
/* Initialise input parameters */
init_lsa_q_create_account ( & q , dom_pol , sid , desired_access ) ;
/* Marshall data and send request */
if ( ! lsa_io_q_create_account ( " " , & q , & qbuf , 0 ) | |
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_CREATEACCOUNT , & qbuf , & rbuf ) ) {
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Unmarshall response */
if ( ! lsa_io_r_create_account ( " " , & r , & rbuf , 0 ) ) {
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Return output parameters */
if ( NT_STATUS_IS_OK ( result = r . status ) ) {
* user_pol = r . pol ;
}
done :
prs_mem_free ( & qbuf ) ;
prs_mem_free ( & rbuf ) ;
return result ;
}
2001-11-24 03:13:41 +03:00
/** Open a LSA user handle
*
* @ param cli Handle on an initialised SMB connection */
NTSTATUS cli_lsa_open_account ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
POLICY_HND * dom_pol , DOM_SID * sid , uint32 des_access ,
POLICY_HND * user_pol )
{
prs_struct qbuf , rbuf ;
LSA_Q_OPENACCOUNT q ;
LSA_R_OPENACCOUNT r ;
NTSTATUS result ;
ZERO_STRUCT ( q ) ;
ZERO_STRUCT ( r ) ;
/* Initialise parse structures */
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
/* Initialise input parameters */
init_lsa_q_open_account ( & q , dom_pol , sid , des_access ) ;
/* Marshall data and send request */
if ( ! lsa_io_q_open_account ( " " , & q , & qbuf , 0 ) | |
2005-01-06 14:42:40 +03:00
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_OPENACCOUNT , & qbuf , & rbuf ) ) {
2001-11-24 03:13:41 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Unmarshall response */
if ( ! lsa_io_r_open_account ( " " , & r , & rbuf , 0 ) ) {
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Return output parameters */
if ( NT_STATUS_IS_OK ( result = r . status ) ) {
* user_pol = r . pol ;
}
done :
prs_mem_free ( & qbuf ) ;
prs_mem_free ( & rbuf ) ;
return result ;
}
/** Enumerate user privileges
*
* @ param cli Handle on an initialised SMB connection */
NTSTATUS cli_lsa_enum_privsaccount ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
POLICY_HND * pol , uint32 * count , LUID_ATTR * * set )
{
prs_struct qbuf , rbuf ;
LSA_Q_ENUMPRIVSACCOUNT q ;
LSA_R_ENUMPRIVSACCOUNT r ;
NTSTATUS result ;
int i ;
ZERO_STRUCT ( q ) ;
ZERO_STRUCT ( r ) ;
/* Initialise parse structures */
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
/* Initialise input parameters */
init_lsa_q_enum_privsaccount ( & q , pol ) ;
/* Marshall data and send request */
if ( ! lsa_io_q_enum_privsaccount ( " " , & q , & qbuf , 0 ) | |
2005-01-06 14:42:40 +03:00
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_ENUMPRIVSACCOUNT , & qbuf , & rbuf ) ) {
2001-11-24 03:13:41 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Unmarshall response */
if ( ! lsa_io_r_enum_privsaccount ( " " , & r , & rbuf , 0 ) ) {
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Return output parameters */
if ( ! NT_STATUS_IS_OK ( result = r . status ) ) {
goto done ;
}
if ( r . count = = 0 )
goto done ;
2004-12-07 21:25:53 +03:00
if ( ! ( ( * set = TALLOC_ARRAY ( mem_ctx , LUID_ATTR , r . count ) ) ) ) {
2001-11-24 03:13:41 +03:00
DEBUG ( 0 , ( " (cli_lsa_enum_privsaccount): out of memory \n " ) ) ;
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
for ( i = 0 ; i < r . count ; i + + ) {
2005-01-13 21:20:37 +03:00
( * set ) [ i ] . luid . low = r . set . set [ i ] . luid . low ;
( * set ) [ i ] . luid . high = r . set . set [ i ] . luid . high ;
( * set ) [ i ] . attr = r . set . set [ i ] . attr ;
2001-11-24 03:13:41 +03:00
}
* count = r . count ;
done :
prs_mem_free ( & qbuf ) ;
prs_mem_free ( & rbuf ) ;
return result ;
}
/** Get a privilege value given its name */
2005-03-10 21:50:47 +03:00
NTSTATUS cli_lsa_lookup_priv_value ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
2003-02-26 02:51:56 +03:00
POLICY_HND * pol , const char * name , LUID * luid )
2001-11-24 03:13:41 +03:00
{
prs_struct qbuf , rbuf ;
2005-03-10 21:50:47 +03:00
LSA_Q_LOOKUP_PRIV_VALUE q ;
LSA_R_LOOKUP_PRIV_VALUE r ;
2001-11-24 03:13:41 +03:00
NTSTATUS result ;
ZERO_STRUCT ( q ) ;
ZERO_STRUCT ( r ) ;
/* Initialise parse structures */
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
/* Marshall data and send request */
2005-03-10 21:50:47 +03:00
init_lsa_q_lookup_priv_value ( & q , pol , name ) ;
2001-11-24 03:13:41 +03:00
2005-03-10 21:50:47 +03:00
if ( ! lsa_io_q_lookup_priv_value ( " " , & q , & qbuf , 0 ) | |
2005-01-06 14:42:40 +03:00
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_LOOKUPPRIVVALUE , & qbuf , & rbuf ) ) {
2001-11-24 03:13:41 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Unmarshall response */
2005-03-10 21:50:47 +03:00
if ( ! lsa_io_r_lookup_priv_value ( " " , & r , & rbuf , 0 ) ) {
2001-11-24 03:13:41 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( ! NT_STATUS_IS_OK ( result = r . status ) ) {
goto done ;
}
/* Return output parameters */
( * luid ) . low = r . luid . low ;
( * luid ) . high = r . luid . high ;
done :
prs_mem_free ( & qbuf ) ;
prs_mem_free ( & rbuf ) ;
return result ;
}
2001-12-11 05:17:26 +03:00
/** Query LSA security object */
NTSTATUS cli_lsa_query_secobj ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
POLICY_HND * pol , uint32 sec_info ,
SEC_DESC_BUF * * psdb )
{
prs_struct qbuf , rbuf ;
LSA_Q_QUERY_SEC_OBJ q ;
LSA_R_QUERY_SEC_OBJ r ;
NTSTATUS result ;
ZERO_STRUCT ( q ) ;
ZERO_STRUCT ( r ) ;
/* Initialise parse structures */
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
/* Marshall data and send request */
init_q_query_sec_obj ( & q , pol , sec_info ) ;
if ( ! lsa_io_q_query_sec_obj ( " " , & q , & qbuf , 0 ) | |
2005-01-06 14:42:40 +03:00
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_QUERYSECOBJ , & qbuf , & rbuf ) ) {
2001-12-11 05:17:26 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Unmarshall response */
if ( ! lsa_io_r_query_sec_obj ( " " , & r , & rbuf , 0 ) ) {
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( ! NT_STATUS_IS_OK ( result = r . status ) ) {
goto done ;
}
/* Return output parameters */
if ( psdb )
* psdb = r . buf ;
done :
prs_mem_free ( & qbuf ) ;
prs_mem_free ( & rbuf ) ;
return result ;
}
2003-01-15 20:22:48 +03:00
/* Enumerate account rights This is similar to enum_privileges but
takes a SID directly , avoiding the open_account call .
*/
NTSTATUS cli_lsa_enum_account_rights ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
2005-01-18 21:28:34 +03:00
POLICY_HND * pol , DOM_SID * sid ,
2005-01-19 19:52:19 +03:00
uint32 * count , char * * * priv_names )
2003-01-15 20:22:48 +03:00
{
prs_struct qbuf , rbuf ;
LSA_Q_ENUM_ACCT_RIGHTS q ;
LSA_R_ENUM_ACCT_RIGHTS r ;
NTSTATUS result ;
int i ;
2005-01-18 21:28:34 +03:00
fstring * privileges ;
2005-01-19 19:52:19 +03:00
char * * names ;
2003-01-15 20:22:48 +03:00
ZERO_STRUCT ( q ) ;
ZERO_STRUCT ( r ) ;
/* Initialise parse structures */
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
/* Marshall data and send request */
2005-01-18 21:28:34 +03:00
init_q_enum_acct_rights ( & q , pol , 2 , sid ) ;
2003-01-15 20:22:48 +03:00
if ( ! lsa_io_q_enum_acct_rights ( " " , & q , & qbuf , 0 ) | |
2005-01-06 14:42:40 +03:00
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_ENUMACCTRIGHTS , & qbuf , & rbuf ) ) {
2003-01-15 20:22:48 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( ! lsa_io_r_enum_acct_rights ( " " , & r , & rbuf , 0 ) ) {
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( ! NT_STATUS_IS_OK ( result = r . status ) ) {
goto done ;
}
* count = r . count ;
if ( ! * count ) {
goto done ;
}
2005-01-18 21:28:34 +03:00
privileges = TALLOC_ARRAY ( mem_ctx , fstring , * count ) ;
2005-01-19 19:52:19 +03:00
names = TALLOC_ARRAY ( mem_ctx , char * , * count ) ;
2005-01-18 21:28:34 +03:00
for ( i = 0 ; i < * count ; i + + ) {
/* ensure NULL termination ... what a hack */
pull_ucs2 ( NULL , privileges [ i ] , r . rights . strings [ i ] . string . buffer ,
sizeof ( fstring ) , r . rights . strings [ i ] . string . uni_str_len * 2 , 0 ) ;
/* now copy to the return array */
2005-01-19 19:52:19 +03:00
names [ i ] = talloc_strdup ( mem_ctx , privileges [ i ] ) ;
2003-01-15 20:22:48 +03:00
}
2005-01-19 19:52:19 +03:00
* priv_names = names ;
2003-01-15 20:22:48 +03:00
done :
return result ;
}
2003-01-29 05:24:12 +03:00
2003-01-29 00:09:56 +03:00
/* add account rights to an account. */
NTSTATUS cli_lsa_add_account_rights ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
2003-01-29 05:24:12 +03:00
POLICY_HND * pol , DOM_SID sid ,
uint32 count , const char * * privs_name )
2003-01-29 00:09:56 +03:00
{
prs_struct qbuf , rbuf ;
LSA_Q_ADD_ACCT_RIGHTS q ;
LSA_R_ADD_ACCT_RIGHTS r ;
NTSTATUS result ;
ZERO_STRUCT ( q ) ;
/* Initialise parse structures */
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
/* Marshall data and send request */
init_q_add_acct_rights ( & q , pol , & sid , count , privs_name ) ;
if ( ! lsa_io_q_add_acct_rights ( " " , & q , & qbuf , 0 ) | |
2005-01-06 14:42:40 +03:00
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_ADDACCTRIGHTS , & qbuf , & rbuf ) ) {
2003-01-29 00:09:56 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Unmarshall response */
if ( ! lsa_io_r_add_acct_rights ( " " , & r , & rbuf , 0 ) ) {
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2003-01-29 05:24:12 +03:00
if ( ! NT_STATUS_IS_OK ( result = r . status ) ) {
goto done ;
}
done :
return result ;
}
/* remove account rights for an account. */
NTSTATUS cli_lsa_remove_account_rights ( struct cli_state * cli , TALLOC_CTX * mem_ctx ,
POLICY_HND * pol , DOM_SID sid , BOOL removeall ,
uint32 count , const char * * privs_name )
{
prs_struct qbuf , rbuf ;
LSA_Q_REMOVE_ACCT_RIGHTS q ;
LSA_R_REMOVE_ACCT_RIGHTS r ;
NTSTATUS result ;
ZERO_STRUCT ( q ) ;
/* Initialise parse structures */
prs_init ( & qbuf , MAX_PDU_FRAG_LEN , mem_ctx , MARSHALL ) ;
prs_init ( & rbuf , 0 , mem_ctx , UNMARSHALL ) ;
/* Marshall data and send request */
init_q_remove_acct_rights ( & q , pol , & sid , removeall ? 1 : 0 , count , privs_name ) ;
if ( ! lsa_io_q_remove_acct_rights ( " " , & q , & qbuf , 0 ) | |
2005-01-06 14:42:40 +03:00
! rpc_api_pipe_req ( cli , PI_LSARPC , LSA_REMOVEACCTRIGHTS , & qbuf , & rbuf ) ) {
2003-01-29 05:24:12 +03:00
result = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* Unmarshall response */
if ( ! lsa_io_r_remove_acct_rights ( " " , & r , & rbuf , 0 ) ) {
result = NT_STATUS_UNSUCCESSFUL ;
2003-01-29 00:09:56 +03:00
goto done ;
2003-01-29 05:24:12 +03:00
}
2003-01-29 00:09:56 +03:00
2003-01-29 05:24:12 +03:00
if ( ! NT_STATUS_IS_OK ( result = r . status ) ) {
goto done ;
}
2003-01-29 00:09:56 +03:00
done :
return result ;
}
2003-01-15 20:22:48 +03:00
2003-01-29 05:24:12 +03:00
2002-04-04 10:55:32 +04:00
#if 0
/** An example of how to use the routines in this file. Fetch a DOMAIN
sid . Does complete cli setup / teardown anonymously . */
2001-11-24 03:13:41 +03:00
2001-12-05 22:33:35 +03:00
BOOL fetch_domain_sid ( char * domain , char * remote_machine , DOM_SID * psid )
{
extern pstring global_myname ;
struct cli_state cli ;
NTSTATUS result ;
POLICY_HND lsa_pol ;
BOOL ret = False ;
ZERO_STRUCT ( cli ) ;
if ( cli_initialise ( & cli ) = = False ) {
DEBUG ( 0 , ( " fetch_domain_sid: unable to initialize client connection. \n " ) ) ;
return False ;
}
if ( ! resolve_name ( remote_machine , & cli . dest_ip , 0x20 ) ) {
DEBUG ( 0 , ( " fetch_domain_sid: Can't resolve address for %s \n " , remote_machine ) ) ;
goto done ;
}
if ( ! cli_connect ( & cli , remote_machine , & cli . dest_ip ) ) {
DEBUG ( 0 , ( " fetch_domain_sid: unable to connect to SMB server on \
machine % s . Error was : % s . \ n " , remote_machine, cli_errstr(&cli) ));
goto done ;
}
if ( ! attempt_netbios_session_request ( & cli , global_myname , remote_machine , & cli . dest_ip ) ) {
2002-02-13 19:44:49 +03:00
DEBUG ( 0 , ( " fetch_domain_sid: machine %s rejected the NetBIOS session request. \n " ,
remote_machine ) ) ;
2001-12-05 22:33:35 +03:00
goto done ;
}
cli . protocol = PROTOCOL_NT1 ;
if ( ! cli_negprot ( & cli ) ) {
DEBUG ( 0 , ( " fetch_domain_sid: machine %s rejected the negotiate protocol. \
Error was : % s . \ n " , remote_machine, cli_errstr(&cli) ));
goto done ;
}
if ( cli . protocol ! = PROTOCOL_NT1 ) {
DEBUG ( 0 , ( " fetch_domain_sid: machine %s didn't negotiate NT protocol. \n " ,
remote_machine ) ) ;
goto done ;
}
/*
* Do an anonymous session setup .
*/
if ( ! cli_session_setup ( & cli , " " , " " , 0 , " " , 0 , " " ) ) {
DEBUG ( 0 , ( " fetch_domain_sid: machine %s rejected the session setup. \
Error was : % s . \ n " , remote_machine, cli_errstr(&cli) ));
goto done ;
}
2002-06-01 04:10:08 +04:00
if ( ! ( cli . sec_mode & NEGOTIATE_SECURITY_USER_LEVEL ) ) {
2001-12-05 22:33:35 +03:00
DEBUG ( 0 , ( " fetch_domain_sid: machine %s isn't in user level security mode \n " ,
remote_machine ) ) ;
goto done ;
}
if ( ! cli_send_tconX ( & cli , " IPC$ " , " IPC " , " " , 1 ) ) {
DEBUG ( 0 , ( " fetch_domain_sid: machine %s rejected the tconX on the IPC$ share. \
Error was : % s . \ n " , remote_machine, cli_errstr(&cli) ));
goto done ;
}
/* Fetch domain sid */
2002-10-04 08:10:23 +04:00
if ( ! cli_nt_session_open ( & cli , PI_LSARPC ) ) {
2001-12-05 22:33:35 +03:00
DEBUG ( 0 , ( " fetch_domain_sid: Error connecting to SAM pipe \n " ) ) ;
goto done ;
}
result = cli_lsa_open_policy ( & cli , cli . mem_ctx , True , SEC_RIGHTS_QUERY_VALUE , & lsa_pol ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
DEBUG ( 0 , ( " fetch_domain_sid: Error opening lsa policy handle. %s \n " ,
2002-03-17 07:36:35 +03:00
nt_errstr ( result ) ) ) ;
2001-12-05 22:33:35 +03:00
goto done ;
}
result = cli_lsa_query_info_policy ( & cli , cli . mem_ctx , & lsa_pol , 5 , domain , psid ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
DEBUG ( 0 , ( " fetch_domain_sid: Error querying lsa policy handle. %s \n " ,
2002-03-17 07:36:35 +03:00
nt_errstr ( result ) ) ) ;
2001-12-05 22:33:35 +03:00
goto done ;
}
ret = True ;
done :
cli_shutdown ( & cli ) ;
return ret ;
}
2002-01-06 06:48:41 +03:00
2002-04-04 10:55:32 +04:00
# endif
2001-11-15 09:03:22 +03:00
/** @} **/