cli_lsarpc.c

来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 1,375 行 · 第 1/2 页

C
1,375
字号
/*    Unix SMB/CIFS implementation.   RPC pipe client   Copyright (C) Tim Potter                        2000-2001,   Copyright (C) Andrew Tridgell              1992-1997,2000,   Copyright (C) Rafal Szczesniak                       2002   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   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 02139, USA.*/#include "includes.h"/** @defgroup lsa LSA - Local Security Architecture *  @ingroup rpc_client * * @{ **//** * @file cli_lsarpc.c * * RPC client routines for the LSA RPC pipe.  LSA means "local * security authority", which is half of a password database. **//** Open a LSA policy handle * * @param cli Handle on an initialised SMB connection */NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli,				TALLOC_CTX *mem_ctx,				BOOL sec_qos, uint32 des_access,				POLICY_HND *pol){	prs_struct qbuf, rbuf;	LSA_Q_OPEN_POL q;	LSA_R_OPEN_POL r;	LSA_SEC_QOS qos;	NTSTATUS result;	ZERO_STRUCT(q);	ZERO_STRUCT(r);	/* Initialise input parameters */	if (sec_qos) {		init_lsa_sec_qos(&qos, 2, 1, 0);		init_q_open_pol(&q, '\\', 0, des_access, &qos);	} else {		init_q_open_pol(&q, '\\', 0, des_access, NULL);	}	/* Marshall data and send request */	CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENPOLICY,			q, r,			qbuf, rbuf,			lsa_io_q_open_pol,			lsa_io_r_open_pol,			NT_STATUS_UNSUCCESSFUL );	/* Return output parameters */	result = r.status;	if (NT_STATUS_IS_OK(result)) {		*pol = r.pol;#ifdef __INSURE__		pol->marker = MALLOC(1);#endif	}	return result;}/** Open a LSA policy handle  *  * @param cli Handle on an initialised SMB connection   */NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli,				 TALLOC_CTX *mem_ctx, BOOL sec_qos,				 uint32 des_access, POLICY_HND *pol){	prs_struct qbuf, rbuf;	LSA_Q_OPEN_POL2 q;	LSA_R_OPEN_POL2 r;	LSA_SEC_QOS qos;	NTSTATUS result;	char *srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", cli->cli->desthost);	ZERO_STRUCT(q);	ZERO_STRUCT(r);	if (sec_qos) {		init_lsa_sec_qos(&qos, 2, 1, 0);		init_q_open_pol2(&q, srv_name_slash, 0, des_access, &qos);	} else {		init_q_open_pol2(&q, srv_name_slash, 0, des_access, NULL);	}	CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENPOLICY2,			q, r,			qbuf, rbuf,			lsa_io_q_open_pol2,			lsa_io_r_open_pol2,			NT_STATUS_UNSUCCESSFUL );	/* Return output parameters */	result = r.status;	if (NT_STATUS_IS_OK(result)) {		*pol = r.pol;#ifdef __INSURE__		pol->marker = (char *)malloc(1);#endif	}	return result;}/** Close a LSA policy handle */NTSTATUS rpccli_lsa_close(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, 			  POLICY_HND *pol){	prs_struct qbuf, rbuf;	LSA_Q_CLOSE q;	LSA_R_CLOSE r;	NTSTATUS result;	ZERO_STRUCT(q);	ZERO_STRUCT(r);	init_lsa_q_close(&q, pol);	CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_CLOSE,			q, r,			qbuf, rbuf,			lsa_io_q_close,			lsa_io_r_close,			NT_STATUS_UNSUCCESSFUL );	/* Return output parameters */	result = r.status;	if (NT_STATUS_IS_OK(result)) {#ifdef __INSURE__		SAFE_FREE(pol->marker);#endif		*pol = r.pol;	}	return result;}/** Lookup a list of sids */NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli,				TALLOC_CTX *mem_ctx,				POLICY_HND *pol, int num_sids,				const DOM_SID *sids, 				char ***domains, char ***names, uint32 **types){	prs_struct qbuf, rbuf;	LSA_Q_LOOKUP_SIDS q;	LSA_R_LOOKUP_SIDS r;	DOM_R_REF ref;	LSA_TRANS_NAME_ENUM t_names;	NTSTATUS result = NT_STATUS_OK;	int i;	ZERO_STRUCT(q);	ZERO_STRUCT(r);	init_q_lookup_sids(mem_ctx, &q, pol, num_sids, sids, 1);	ZERO_STRUCT(ref);	ZERO_STRUCT(t_names);	r.dom_ref = &ref;	r.names = &t_names;	CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPSIDS,			q, r,			qbuf, rbuf,			lsa_io_q_lookup_sids,			lsa_io_r_lookup_sids,			NT_STATUS_UNSUCCESSFUL );	if (!NT_STATUS_IS_OK(r.status) &&	    NT_STATUS_V(r.status) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) {	  		/* An actual error occured */		result = r.status;		goto done;	}	/* Return output parameters */	if (r.mapped_count == 0) {		result = NT_STATUS_NONE_MAPPED;		goto done;	}	if (!((*domains) = TALLOC_ARRAY(mem_ctx, char *, num_sids))) {		DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));		result = NT_STATUS_UNSUCCESSFUL;		goto done;	}	if (!((*names) = TALLOC_ARRAY(mem_ctx, char *, num_sids))) {		DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));		result = NT_STATUS_UNSUCCESSFUL;		goto done;	}	if (!((*types) = TALLOC_ARRAY(mem_ctx, uint32, num_sids))) {		DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));		result = NT_STATUS_UNSUCCESSFUL;		goto done;	}			for (i = 0; i < num_sids; i++) {		fstring name, dom_name;		uint32 dom_idx = t_names.name[i].domain_idx;		/* Translate optimised name through domain index array */		if (dom_idx != 0xffffffff) {			rpcstr_pull_unistr2_fstring(                                dom_name, &ref.ref_dom[dom_idx].uni_dom_name);			rpcstr_pull_unistr2_fstring(                                name, &t_names.uni_name[i]);			(*names)[i] = talloc_strdup(mem_ctx, name);			(*domains)[i] = talloc_strdup(mem_ctx, dom_name);			(*types)[i] = t_names.name[i].sid_name_use;						if (((*names)[i] == NULL) || ((*domains)[i] == NULL)) {				DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));				result = NT_STATUS_UNSUCCESSFUL;				goto done;			}		} else {			(*names)[i] = NULL;			(*domains)[i] = NULL;			(*types)[i] = SID_NAME_UNKNOWN;		}	} done:	return result;}/** Lookup a list of names */NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli,				 TALLOC_CTX *mem_ctx,				 POLICY_HND *pol, int num_names, 				 const char **names, DOM_SID **sids, 				 uint32 **types){	prs_struct qbuf, rbuf;	LSA_Q_LOOKUP_NAMES q;	LSA_R_LOOKUP_NAMES r;	DOM_R_REF ref;	NTSTATUS result;	int i;		ZERO_STRUCT(q);	ZERO_STRUCT(r);	ZERO_STRUCT(ref);	r.dom_ref = &ref;	init_q_lookup_names(mem_ctx, &q, pol, num_names, names);	CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPNAMES,			q, r,			qbuf, rbuf,			lsa_io_q_lookup_names,			lsa_io_r_lookup_names,			NT_STATUS_UNSUCCESSFUL);	result = r.status;	if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) !=	    NT_STATUS_V(STATUS_SOME_UNMAPPED)) {		/* An actual error occured */		goto done;	}	/* Return output parameters */	if (r.mapped_count == 0) {		result = NT_STATUS_NONE_MAPPED;		goto done;	}	if (!((*sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_names)))) {		DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));		result = NT_STATUS_UNSUCCESSFUL;		goto done;	}	if (!((*types = TALLOC_ARRAY(mem_ctx, uint32, num_names)))) {		DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));		result = NT_STATUS_UNSUCCESSFUL;		goto done;	}	for (i = 0; i < num_names; i++) {		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:	return result;}/** Query info policy * *  @param domain_sid - returned remote server's domain sid */NTSTATUS rpccli_lsa_query_info_policy(struct rpc_pipe_client *cli,				      TALLOC_CTX *mem_ctx,				      POLICY_HND *pol, uint16 info_class, 				      char **domain_name, DOM_SID **domain_sid){	prs_struct qbuf, rbuf;	LSA_Q_QUERY_INFO q;	LSA_R_QUERY_INFO r;	NTSTATUS result;	ZERO_STRUCT(q);	ZERO_STRUCT(r);	init_q_query(&q, pol, info_class);	CLI_DO_RPC(cli, mem_ctx, PI_LSARPC, LSA_QUERYINFOPOLICY,		q, r,		qbuf, rbuf,		lsa_io_q_query,		lsa_io_r_query,		NT_STATUS_UNSUCCESSFUL);	result = r.status;	if (!NT_STATUS_IS_OK(result)) {		goto done;	}	/* Return output parameters */	switch (info_class) {	case 3:		if (domain_name && (r.dom.id3.buffer_dom_name != 0)) {			*domain_name = unistr2_tdup(mem_ctx, 						   &r.dom.id3.						   uni_domain_name);		}		if (domain_sid && (r.dom.id3.buffer_dom_sid != 0)) {			*domain_sid = TALLOC_P(mem_ctx, DOM_SID);			if (*domain_sid) {				sid_copy(*domain_sid, &r.dom.id3.dom_sid.sid);			}		}		break;	case 5:				if (domain_name && (r.dom.id5.buffer_dom_name != 0)) {			*domain_name = unistr2_tdup(mem_ctx, 						   &r.dom.id5.						   uni_domain_name);		}					if (domain_sid && (r.dom.id5.buffer_dom_sid != 0)) {			*domain_sid = TALLOC_P(mem_ctx, DOM_SID);			if (*domain_sid) {				sid_copy(*domain_sid, &r.dom.id5.dom_sid.sid);			}		}		break;				default:		DEBUG(3, ("unknown info class %d\n", info_class));		break;		      	}	 done:	return result;}/** 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 rpccli_lsa_query_info_policy2(struct rpc_pipe_client *cli,				       TALLOC_CTX *mem_ctx,				       POLICY_HND *pol, uint16 info_class, 				       char **domain_name, char **dns_name,				       char **forest_name,				       struct uuid **domain_guid,				       DOM_SID **domain_sid){	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);	init_q_query2(&q, pol, info_class);	CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYINFO2,		q, r,		qbuf, rbuf,		lsa_io_q_query_info2,		lsa_io_r_query_info2,		NT_STATUS_UNSUCCESSFUL);	result = r.status;	if (!NT_STATUS_IS_OK(result)) {		goto done;	}	/* Return output parameters */	ZERO_STRUCTP(domain_guid);	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);	}	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);	}	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);	}		if (domain_guid) {		*domain_guid = TALLOC_P(mem_ctx, struct uuid);		memcpy(*domain_guid, 		       &r.info.dns_dom_info.dom_guid, 		       sizeof(struct uuid));	}	if (domain_sid && r.info.dns_dom_info.ptr_dom_sid != 0) {		*domain_sid = TALLOC_P(mem_ctx, DOM_SID);		if (*domain_sid) {			sid_copy(*domain_sid, 				 &r.info.dns_dom_info.dom_sid.sid);		}	}	 done:	return result;}/** * 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 **/NTSTATUS rpccli_lsa_enum_trust_dom(struct rpc_pipe_client *cli,				   TALLOC_CTX *mem_ctx,				   POLICY_HND *pol, uint32 *enum_ctx, 				   uint32 *num_domains,				   char ***domain_names, DOM_SID **domain_sids){	prs_struct qbuf, rbuf;	LSA_Q_ENUM_TRUST_DOM in;	LSA_R_ENUM_TRUST_DOM out;	int i;	fstring tmp;	ZERO_STRUCT(in);	ZERO_STRUCT(out);	/* 64k is enough for about 2000 trusted domains */	        init_q_enum_trust_dom(&in, pol, *enum_ctx, 0x10000);	CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMTRUSTDOM, 	            in, out, 	            qbuf, rbuf,	            lsa_io_q_enum_trust_dom,	            lsa_io_r_enum_trust_dom, 	            NT_STATUS_UNSUCCESSFUL );	/* check for an actual error */	if ( !NT_STATUS_IS_OK(out.status) 		&& !NT_STATUS_EQUAL(out.status, NT_STATUS_NO_MORE_ENTRIES) 		&& !NT_STATUS_EQUAL(out.status, STATUS_MORE_ENTRIES) )	{		return out.status;	}			/* Return output parameters */	*num_domains  = out.count;	*enum_ctx     = out.enum_context;		if ( out.count ) {		/* Allocate memory for trusted domain names and sids */		if ( !(*domain_names = TALLOC_ARRAY(mem_ctx, char *, out.count)) ) {			DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));			return NT_STATUS_NO_MEMORY;		}		if ( !(*domain_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, out.count)) ) {			DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));			return NT_STATUS_NO_MEMORY;		}		/* Copy across names and sids */		for (i = 0; i < out.count; i++) {			rpcstr_pull( tmp, out.domlist->domains[i].name.string->buffer, 				sizeof(tmp), out.domlist->domains[i].name.length, 0);			(*domain_names)[i] = talloc_strdup(mem_ctx, tmp);			sid_copy(&(*domain_sids)[i], &out.domlist->domains[i].sid->sid );		}	}	return out.status;}/** Enumerate privileges*/NTSTATUS rpccli_lsa_enum_privilege(struct rpc_pipe_client *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);	init_q_enum_privs(&q, pol, *enum_context, pref_max_length);	CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUM_PRIVS,		q, r,		qbuf, rbuf,		lsa_io_q_enum_privs,		lsa_io_r_enum_privs,		NT_STATUS_UNSUCCESSFUL);	result = r.status;	if (!NT_STATUS_IS_OK(result)) {		goto done;	}	/* Return output parameters */	*enum_context = r.enum_context;	*count = r.count;	if (!((*privs_name = TALLOC_ARRAY(mem_ctx, char *, r.count)))) {		DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));		result = NT_STATUS_UNSUCCESSFUL;		goto done;	}	if (!((*privs_high = TALLOC_ARRAY(mem_ctx, uint32, r.count)))) {		DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));		result = NT_STATUS_UNSUCCESSFUL;		goto done;	}	if (!((*privs_low = TALLOC_ARRAY(mem_ctx, uint32, r.count)))) {		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:	return result;}/** Get privilege name */NTSTATUS rpccli_lsa_get_dispname(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,			      POLICY_HND *pol, const char *name, 			      uint16 lang_id, uint16 lang_id_sys,			      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);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?