dcesrv_srvsvc.c

来自「samba最新软件」· C语言 代码 · 共 2,328 行 · 第 1/4 页

C
2,328
字号
/*    Unix SMB/CIFS implementation.   endpoint server for the srvsvc pipe   Copyright (C) Stefan (metze) Metzmacher 2004-2006      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 3 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, see <http://www.gnu.org/licenses/>.*/#include "includes.h"#include "ntvfs/ntvfs.h"#include "rpc_server/dcerpc_server.h"#include "librpc/gen_ndr/ndr_srvsvc.h"#include "rpc_server/common/common.h"#include "rpc_server/common/proto.h"#include "auth/auth.h"#include "libcli/security/security.h"#include "system/time.h"#include "rpc_server/srvsvc/proto.h"#include "param/param.h"#define SRVSVC_CHECK_ADMIN_ACCESS do { \	struct security_token *t = dce_call->conn->auth_state.session_info->security_token; \	if (!security_token_has_builtin_administrators(t) && \	    !security_token_has_sid_string(t, SID_BUILTIN_SERVER_OPERATORS)) { \	    	return WERR_ACCESS_DENIED; \	} \} while (0)/*   srvsvc_NetCharDevEnum */static WERROR dcesrv_srvsvc_NetCharDevEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,				      struct srvsvc_NetCharDevEnum *r){	r->out.level = r->in.level;	r->out.totalentries = 0;	r->out.resume_handle = NULL;	switch (r->in.level) {	case 0:		r->out.ctr.ctr0 = talloc(mem_ctx, struct srvsvc_NetCharDevCtr0);		W_ERROR_HAVE_NO_MEMORY(r->out.ctr.ctr0);		r->out.ctr.ctr0->count = 0;		r->out.ctr.ctr0->array = NULL;		return WERR_NOT_SUPPORTED;	case 1:		r->out.ctr.ctr1 = talloc(mem_ctx, struct srvsvc_NetCharDevCtr1);		W_ERROR_HAVE_NO_MEMORY(r->out.ctr.ctr1);		r->out.ctr.ctr1->count = 0;		r->out.ctr.ctr1->array = NULL;		return WERR_NOT_SUPPORTED;	default:		return WERR_UNKNOWN_LEVEL;	}	return WERR_OK;}/*   srvsvc_NetCharDevGetInfo */static WERROR dcesrv_srvsvc_NetCharDevGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,		       struct srvsvc_NetCharDevGetInfo *r){	ZERO_STRUCT(r->out);	switch (r->in.level) {	case 0:	{		return WERR_NOT_SUPPORTED;	}	case 1:	{		return WERR_NOT_SUPPORTED;	}	default:		return WERR_UNKNOWN_LEVEL;	}	return WERR_UNKNOWN_LEVEL;}/*   srvsvc_NetCharDevControl */static WERROR dcesrv_srvsvc_NetCharDevControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,		       struct srvsvc_NetCharDevControl *r){	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);}/*   srvsvc_NetCharDevQEnum */static WERROR dcesrv_srvsvc_NetCharDevQEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,				     struct srvsvc_NetCharDevQEnum *r){	r->out.level = r->in.level;	r->out.totalentries = 0;	r->out.resume_handle = NULL;	switch (r->in.level) {	case 0:	{		r->out.ctr.ctr0 = talloc(mem_ctx, struct srvsvc_NetCharDevQCtr0);		W_ERROR_HAVE_NO_MEMORY(r->out.ctr.ctr0);		r->out.ctr.ctr0->count = 0;		r->out.ctr.ctr0->array = NULL;		return WERR_NOT_SUPPORTED;	}	case 1:	{		r->out.ctr.ctr1 = talloc(mem_ctx, struct srvsvc_NetCharDevQCtr1);		W_ERROR_HAVE_NO_MEMORY(r->out.ctr.ctr1);		r->out.ctr.ctr1->count = 0;		r->out.ctr.ctr1->array = NULL;		return WERR_NOT_SUPPORTED;	}	default:		return WERR_UNKNOWN_LEVEL;	}	return WERR_UNKNOWN_LEVEL;}/*   srvsvc_NetCharDevQGetInfo */static WERROR dcesrv_srvsvc_NetCharDevQGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,					struct srvsvc_NetCharDevQGetInfo *r){	ZERO_STRUCT(r->out);	switch (r->in.level) {	case 0:	{		return WERR_NOT_SUPPORTED;	}	case 1:	{		return WERR_NOT_SUPPORTED;	}	default:		return WERR_UNKNOWN_LEVEL;	}	return WERR_UNKNOWN_LEVEL;}/*   srvsvc_NetCharDevQSetInfo */static WERROR dcesrv_srvsvc_NetCharDevQSetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,		       struct srvsvc_NetCharDevQSetInfo *r){	switch (r->in.level) {	case 0:	{		if (r->in.parm_error) {			r->out.parm_error = r->in.parm_error;		}		return WERR_NOT_SUPPORTED;	}	case 1:	{		if (r->in.parm_error) {			r->out.parm_error = r->in.parm_error;		}		return WERR_NOT_SUPPORTED;	}	default:		return WERR_UNKNOWN_LEVEL;	}	return WERR_UNKNOWN_LEVEL;}/*   srvsvc_NetCharDevQPurge */static WERROR dcesrv_srvsvc_NetCharDevQPurge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,		       struct srvsvc_NetCharDevQPurge *r){	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);}/*   srvsvc_NetCharDevQPurgeSelf */static WERROR dcesrv_srvsvc_NetCharDevQPurgeSelf(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,					  struct srvsvc_NetCharDevQPurgeSelf *r){	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);	}/*   srvsvc_NetConnEnum */static WERROR dcesrv_srvsvc_NetConnEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,		       struct srvsvc_NetConnEnum *r){	r->out.level = r->in.level;	r->out.totalentries = 0;	r->out.resume_handle = NULL;	switch (r->in.level) {	case 0:	{		r->out.ctr.ctr0 = talloc(mem_ctx, struct srvsvc_NetConnCtr0);		W_ERROR_HAVE_NO_MEMORY(r->out.ctr.ctr0);		r->out.ctr.ctr0->count = 0;		r->out.ctr.ctr0->array = NULL;		return WERR_NOT_SUPPORTED;	}	case 1:	{		r->out.ctr.ctr1 = talloc(mem_ctx, struct srvsvc_NetConnCtr1);		W_ERROR_HAVE_NO_MEMORY(r->out.ctr.ctr1);		r->out.ctr.ctr1->count = 0;		r->out.ctr.ctr1->array = NULL;		return WERR_NOT_SUPPORTED;	}	default:		return WERR_UNKNOWN_LEVEL;	}	return WERR_UNKNOWN_LEVEL;}/*   srvsvc_NetFileEnum */static WERROR dcesrv_srvsvc_NetFileEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,				 struct srvsvc_NetFileEnum *r){	r->out.level = r->in.level;	r->out.totalentries = 0;	r->out.resume_handle = NULL;	switch (r->in.level) {	case 2:	{		r->out.ctr.ctr2 = talloc(mem_ctx, struct srvsvc_NetFileCtr2);		W_ERROR_HAVE_NO_MEMORY(r->out.ctr.ctr2);		r->out.ctr.ctr2->count = 0;		r->out.ctr.ctr2->array = NULL;		return WERR_NOT_SUPPORTED;	}	case 3:	{		r->out.ctr.ctr3 = talloc(mem_ctx, struct srvsvc_NetFileCtr3);		W_ERROR_HAVE_NO_MEMORY(r->out.ctr.ctr3);		r->out.ctr.ctr3->count = 0;		r->out.ctr.ctr3->array = NULL;		return WERR_NOT_SUPPORTED;	}	default:		return WERR_UNKNOWN_LEVEL;	}	return WERR_UNKNOWN_LEVEL;}/*   srvsvc_NetFileGetInfo */static WERROR dcesrv_srvsvc_NetFileGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,				    struct srvsvc_NetFileGetInfo *r){	ZERO_STRUCT(r->out);	switch (r->in.level) {	case 2:	{		return WERR_NOT_SUPPORTED;	}	case 3:	{		return WERR_NOT_SUPPORTED;	}	default:		return WERR_UNKNOWN_LEVEL;	}	return WERR_UNKNOWN_LEVEL;}/*   srvsvc_NetFileClose */static WERROR dcesrv_srvsvc_NetFileClose(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,		       struct srvsvc_NetFileClose *r){	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);}/*   srvsvc_NetSessEnum */static WERROR dcesrv_srvsvc_NetSessEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,		       struct srvsvc_NetSessEnum *r){	r->out.level = r->in.level;	r->out.totalentries = 0;	r->out.resume_handle = NULL;	switch (r->in.level) {	case 0:	{		r->out.ctr.ctr0 = talloc(mem_ctx, struct srvsvc_NetSessCtr0);		W_ERROR_HAVE_NO_MEMORY(r->out.ctr.ctr0);		r->out.ctr.ctr0->count = 0;		r->out.ctr.ctr0->array = NULL;		return WERR_NOT_SUPPORTED;	}	case 1:	{		r->out.ctr.ctr1 = talloc(mem_ctx, struct srvsvc_NetSessCtr1);		W_ERROR_HAVE_NO_MEMORY(r->out.ctr.ctr1);		r->out.ctr.ctr1->count = 0;		r->out.ctr.ctr1->array = NULL;		return WERR_NOT_SUPPORTED;	}	case 2:	{		r->out.ctr.ctr2 = talloc(mem_ctx, struct srvsvc_NetSessCtr2);		W_ERROR_HAVE_NO_MEMORY(r->out.ctr.ctr2);		r->out.ctr.ctr2->count = 0;		r->out.ctr.ctr2->array = NULL;		return WERR_NOT_SUPPORTED;	}	case 10:	{		r->out.ctr.ctr10 = talloc(mem_ctx, struct srvsvc_NetSessCtr10);		W_ERROR_HAVE_NO_MEMORY(r->out.ctr.ctr10);		r->out.ctr.ctr2->count = 0;		r->out.ctr.ctr2->array = NULL;		return WERR_NOT_SUPPORTED;	}	case 502:	{		r->out.ctr.ctr502 = talloc(mem_ctx, struct srvsvc_NetSessCtr502);		W_ERROR_HAVE_NO_MEMORY(r->out.ctr.ctr502);		r->out.ctr.ctr2->count = 0;		r->out.ctr.ctr2->array = NULL;		return WERR_NOT_SUPPORTED;	}	default:		return WERR_UNKNOWN_LEVEL;	}	return WERR_UNKNOWN_LEVEL;}/*   srvsvc_NetSessDel */static WERROR dcesrv_srvsvc_NetSessDel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,		       struct srvsvc_NetSessDel *r){	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);}/*   srvsvc_NetShareAdd */static WERROR dcesrv_srvsvc_NetShareAdd(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,		       struct srvsvc_NetShareAdd *r){	switch (r->in.level) {	case 0:	{		if (r->in.parm_error) {			r->out.parm_error = r->in.parm_error;		}		return WERR_NOT_SUPPORTED;	}	case 1:	{		if (r->in.parm_error) {			r->out.parm_error = r->in.parm_error;		}		return WERR_NOT_SUPPORTED;	}	case 2:	{		NTSTATUS nterr;		struct share_info *info;		struct share_context *sctx;		int count = 8;		int i;		nterr = share_get_context_by_name(mem_ctx, lp_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);		if (!NT_STATUS_IS_OK(nterr)) {			return ntstatus_to_werror(nterr);		}		/* there are no more than 8 options in struct srvsvc_NetShareInfo2 */		info = talloc_array(mem_ctx, struct share_info, count);		W_ERROR_HAVE_NO_MEMORY(info);		i = 0;		info[i].name = SHARE_TYPE;		info[i].type = SHARE_INFO_STRING;		switch (r->in.info.info2->type) {		case 0x00:			info[i].value = talloc_strdup(info, "DISK");			break;		case 0x01:			info[i].value = talloc_strdup(info, "PRINTER");			break;		case 0x03:			info[i].value = talloc_strdup(info, "IPC");			break;		default:			return WERR_INVALID_PARAM;		}		W_ERROR_HAVE_NO_MEMORY(info[i].value);		i++;		if (r->in.info.info2->path && r->in.info.info2->path[0]) {			info[i].name = SHARE_PATH;			info[i].type = SHARE_INFO_STRING;			/* Windows will send a path in a form of C:\example\path */			if (r->in.info.info2->path[1] == ':') {				info[i].value = talloc_strdup(info, &r->in.info.info2->path[2]);			} else {				/* very strange let's try to set as is */				info[i].value = talloc_strdup(info, r->in.info.info2->path);			}			W_ERROR_HAVE_NO_MEMORY(info[i].value);			all_string_sub((char *)info[i].value, "\\", "/", 0);			i++;		}		if (r->in.info.info2->comment && r->in.info.info2->comment[0]) {			info[i].name = SHARE_COMMENT;			info[i].type = SHARE_INFO_STRING;			info[i].value = talloc_strdup(info, r->in.info.info2->comment);			W_ERROR_HAVE_NO_MEMORY(info[i].value);			i++;		}		if (r->in.info.info2->password && r->in.info.info2->password[0]) {			info[i].name = SHARE_PASSWORD;			info[i].type = SHARE_INFO_STRING;			info[i].value = talloc_strdup(info, r->in.info.info502->password);			W_ERROR_HAVE_NO_MEMORY(info[i].value);			i++;		}		info[i].name = SHARE_MAX_CONNECTIONS;		info[i].type = SHARE_INFO_INT;		info[i].value = talloc(info, int);		*((int *)info[i].value) = r->in.info.info2->max_users;		i++;		/* TODO: security descriptor */		nterr = share_create(sctx, r->in.info.info2->name, info, i);		if (!NT_STATUS_IS_OK(nterr)) {			return ntstatus_to_werror(nterr);		}		if (r->in.parm_error) {			r->out.parm_error = r->in.parm_error;		}				return WERR_OK;	}	case 501:	{			if (r->in.parm_error) {			r->out.parm_error = r->in.parm_error;		}		return WERR_NOT_SUPPORTED;	}	case 502:	{		NTSTATUS nterr;		struct share_info *info;		struct share_context *sctx;		int count = 10;		int i;		nterr = share_get_context_by_name(mem_ctx, lp_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);		if (!NT_STATUS_IS_OK(nterr)) {			return ntstatus_to_werror(nterr);		}		/* there are no more than 10 options in struct srvsvc_NetShareInfo502 */		info = talloc_array(mem_ctx, struct share_info, count);		W_ERROR_HAVE_NO_MEMORY(info);		i = 0;		info[i].name = SHARE_TYPE;		info[i].type = SHARE_INFO_STRING;		switch (r->in.info.info502->type) {		case 0x00:			info[i].value = talloc_strdup(info, "DISK");			break;		case 0x01:			info[i].value = talloc_strdup(info, "PRINTER");			break;		case 0x03:			info[i].value = talloc_strdup(info, "IPC");			break;		default:			return WERR_INVALID_PARAM;		}		W_ERROR_HAVE_NO_MEMORY(info[i].value);		i++;		if (r->in.info.info502->path && r->in.info.info502->path[0]) {			info[i].name = SHARE_PATH;			info[i].type = SHARE_INFO_STRING;			/* Windows will send a path in a form of C:\example\path */			if (r->in.info.info2->path[1] == ':') {				info[i].value = talloc_strdup(info, &r->in.info.info502->path[2]);			} else {

⌨️ 快捷键说明

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