dcesrv_lsa.c

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

C
2,518
字号
	}	ret = ldb_modify(state->sam_ldb, msg);	if (ret != 0) {		if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {			return NT_STATUS_OBJECT_NAME_NOT_FOUND;		}		DEBUG(3, ("Could not %s attributes from %s: %s", 			  ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",			  ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));		return NT_STATUS_UNEXPECTED_IO_ERROR;	}	return NT_STATUS_OK;}/*   lsa_AddPrivilegesToAccount*/static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,					   struct lsa_AddPrivilegesToAccount *r){	struct lsa_RightSet rights;	struct dcesrv_handle *h;	struct lsa_account_state *astate;	int i;	DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);	astate = h->data;	rights.count = r->in.privs->count;	rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);	if (rights.names == NULL) {		return NT_STATUS_NO_MEMORY;	}	for (i=0;i<rights.count;i++) {		int id = r->in.privs->set[i].luid.low;		if (r->in.privs->set[i].luid.high) {			return NT_STATUS_NO_SUCH_PRIVILEGE;		}		rights.names[i].string = sec_privilege_name(id);		if (rights.names[i].string == NULL) {			return NT_STATUS_NO_SUCH_PRIVILEGE;		}	}	return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 					  LDB_FLAG_MOD_ADD, astate->account_sid,					  &rights);}/*   lsa_RemovePrivilegesFromAccount*/static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,						struct lsa_RemovePrivilegesFromAccount *r){	struct lsa_RightSet *rights;	struct dcesrv_handle *h;	struct lsa_account_state *astate;	int i;	DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);	astate = h->data;	rights = talloc(mem_ctx, struct lsa_RightSet);	if (r->in.remove_all == 1 && 	    r->in.privs == NULL) {		struct lsa_EnumAccountRights r2;		NTSTATUS status;		r2.in.handle = &astate->policy->handle->wire_handle;		r2.in.sid = astate->account_sid;		r2.out.rights = rights;		status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);		if (!NT_STATUS_IS_OK(status)) {			return status;		}		return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 						  LDB_FLAG_MOD_DELETE, astate->account_sid,						  r2.out.rights);	}	if (r->in.remove_all != 0) {		return NT_STATUS_INVALID_PARAMETER;	}	rights->count = r->in.privs->count;	rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);	if (rights->names == NULL) {		return NT_STATUS_NO_MEMORY;	}	for (i=0;i<rights->count;i++) {		int id = r->in.privs->set[i].luid.low;		if (r->in.privs->set[i].luid.high) {			return NT_STATUS_NO_SUCH_PRIVILEGE;		}		rights->names[i].string = sec_privilege_name(id);		if (rights->names[i].string == NULL) {			return NT_STATUS_NO_SUCH_PRIVILEGE;		}	}	return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 					  LDB_FLAG_MOD_DELETE, astate->account_sid,					  rights);}/*   lsa_GetQuotasForAccount*/static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,		       struct lsa_GetQuotasForAccount *r){	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);}/*   lsa_SetQuotasForAccount*/static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,		       struct lsa_SetQuotasForAccount *r){	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);}/*   lsa_GetSystemAccessAccount*/static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,		       struct lsa_GetSystemAccessAccount *r){	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);}/*   lsa_SetSystemAccessAccount*/static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,		       struct lsa_SetSystemAccessAccount *r){	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);}/*   lsa_CreateSecret */static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,				 struct lsa_CreateSecret *r){	struct dcesrv_handle *policy_handle;	struct lsa_policy_state *policy_state;	struct lsa_secret_state *secret_state;	struct dcesrv_handle *handle;	struct ldb_message **msgs, *msg;	const char *errstr;	const char *attrs[] = {		NULL	};	const char *name;	int ret;	DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);	ZERO_STRUCTP(r->out.sec_handle);		switch (security_session_user_level(dce_call->conn->auth_state.session_info))	{	case SECURITY_SYSTEM:	case SECURITY_ADMINISTRATOR:		break;	default:		/* Users and annonymous are not allowed create secrets */		return NT_STATUS_ACCESS_DENIED;	}	policy_state = policy_handle->data;	if (!r->in.name.string) {		return NT_STATUS_INVALID_PARAMETER;	}		secret_state = talloc(mem_ctx, struct lsa_secret_state);	if (!secret_state) {		return NT_STATUS_NO_MEMORY;	}	secret_state->policy = policy_state;	msg = ldb_msg_new(mem_ctx);	if (msg == NULL) {		return NT_STATUS_NO_MEMORY;	}	if (strncmp("G$", r->in.name.string, 2) == 0) {		const char *name2;		name = &r->in.name.string[2];		secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);		secret_state->global = true;		if (strlen(name) < 1) {			return NT_STATUS_INVALID_PARAMETER;		}		name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));		/* search for the secret record */		ret = gendb_search(secret_state->sam_ldb,				   mem_ctx, policy_state->system_dn, &msgs, attrs,				   "(&(cn=%s)(objectclass=secret))", 				   name2);		if (ret > 0) {			return NT_STATUS_OBJECT_NAME_COLLISION;		}				if (ret == -1) {			DEBUG(0,("Failure searching for CN=%s: %s\n", 				 name2, ldb_errstring(secret_state->sam_ldb)));			return NT_STATUS_INTERNAL_DB_CORRUPTION;		}		msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);		if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {			return NT_STATUS_NO_MEMORY;		}				samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);		} else {		secret_state->global = false;		name = r->in.name.string;		if (strlen(name) < 1) {			return NT_STATUS_INVALID_PARAMETER;		}		secret_state->sam_ldb = talloc_reference(secret_state, 							 secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));		/* search for the secret record */		ret = gendb_search(secret_state->sam_ldb, mem_ctx,				   ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),				   &msgs, attrs,				   "(&(cn=%s)(objectclass=secret))", 				   ldb_binary_encode_string(mem_ctx, name));		if (ret > 0) {			return NT_STATUS_OBJECT_NAME_COLLISION;		}				if (ret == -1) {			DEBUG(0,("Failure searching for CN=%s: %s\n", 				 name, ldb_errstring(secret_state->sam_ldb)));			return NT_STATUS_INTERNAL_DB_CORRUPTION;		}		msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);		samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);	} 	/* pull in all the template attributes.  Note this is always from the global samdb */	ret = samdb_copy_template(secret_state->policy->sam_ldb, msg, 				  "secret", &errstr);	if (ret != 0) {		DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",			 errstr));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");		secret_state->secret_dn = talloc_reference(secret_state, msg->dn);	/* create the secret */	ret = ldb_add(secret_state->sam_ldb, msg);	if (ret != 0) {		DEBUG(0,("Failed to create secret record %s: %s\n",			 ldb_dn_get_linearized(msg->dn), 			 ldb_errstring(secret_state->sam_ldb)));		return NT_STATUS_ACCESS_DENIED;	}	handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);	if (!handle) {		return NT_STATUS_NO_MEMORY;	}		handle->data = talloc_steal(handle, secret_state);		secret_state->access_mask = r->in.access_mask;	secret_state->policy = talloc_reference(secret_state, policy_state);		*r->out.sec_handle = handle->wire_handle;		return NT_STATUS_OK;}/*   lsa_OpenSecret */static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,			       struct lsa_OpenSecret *r){	struct dcesrv_handle *policy_handle;		struct lsa_policy_state *policy_state;	struct lsa_secret_state *secret_state;	struct dcesrv_handle *handle;	struct ldb_message **msgs;	const char *attrs[] = {		NULL	};	const char *name;	int ret;	DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);	ZERO_STRUCTP(r->out.sec_handle);	policy_state = policy_handle->data;	if (!r->in.name.string) {		return NT_STATUS_INVALID_PARAMETER;	}		switch (security_session_user_level(dce_call->conn->auth_state.session_info))	{	case SECURITY_SYSTEM:	case SECURITY_ADMINISTRATOR:		break;	default:		/* Users and annonymous are not allowed to access secrets */		return NT_STATUS_ACCESS_DENIED;	}	secret_state = talloc(mem_ctx, struct lsa_secret_state);	if (!secret_state) {		return NT_STATUS_NO_MEMORY;	}	secret_state->policy = policy_state;	if (strncmp("G$", r->in.name.string, 2) == 0) {		name = &r->in.name.string[2];		secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);		secret_state->global = true;		if (strlen(name) < 1) {			return NT_STATUS_INVALID_PARAMETER;		}		/* search for the secret record */		ret = gendb_search(secret_state->sam_ldb,				   mem_ctx, policy_state->system_dn, &msgs, attrs,				   "(&(cn=%s Secret)(objectclass=secret))", 				   ldb_binary_encode_string(mem_ctx, name));		if (ret == 0) {			return NT_STATUS_OBJECT_NAME_NOT_FOUND;		}				if (ret != 1) {			DEBUG(0,("Found %d records matching DN %s\n", ret,				 ldb_dn_get_linearized(policy_state->system_dn)));			return NT_STATUS_INTERNAL_DB_CORRUPTION;		}		} else {		secret_state->global = false;		secret_state->sam_ldb = talloc_reference(secret_state, 				 secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));		name = r->in.name.string;		if (strlen(name) < 1) {			return NT_STATUS_INVALID_PARAMETER;		}		/* search for the secret record */		ret = gendb_search(secret_state->sam_ldb, mem_ctx,				   ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),				   &msgs, attrs,				   "(&(cn=%s)(objectclass=secret))", 				   ldb_binary_encode_string(mem_ctx, name));		if (ret == 0) {			return NT_STATUS_OBJECT_NAME_NOT_FOUND;		}				if (ret != 1) {			DEBUG(0,("Found %d records matching CN=%s\n", 				 ret, ldb_binary_encode_string(mem_ctx, name)));			return NT_STATUS_INTERNAL_DB_CORRUPTION;		}	} 	secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);		handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);	if (!handle) {		return NT_STATUS_NO_MEMORY;	}		handle->data = talloc_steal(handle, secret_state);		secret_state->access_mask = r->in.access_mask;	secret_state->policy = talloc_reference(secret_state, policy_state);		*r->out.sec_handle = handle->wire_handle;		return NT_STATUS_OK;}/*   lsa_SetSecret */static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,			      struct lsa_SetSecret *r){	struct dcesrv_handle *h;	struct lsa_secret_state *secret_state;	struct ldb_message *msg;	DATA_BLOB session_key;	DATA_BLOB crypt_secret, secret;	struct ldb_val val;	int ret;	NTSTATUS status = NT_STATUS_OK;	struct timeval now = timeval_current();	NTTIME nt_now = timeval_to_nttime(&now);	DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);	secret_state = h->data;	msg = ldb_msg_new(mem_ctx);	if (msg == NULL) {		return NT_STATUS_NO_MEMORY;	}	msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);	if (!msg->dn) {		return NT_STATUS_NO_MEMORY;	}	status = dcesrv_fetch_session_key(dce_call->conn, &session_key);	if (!NT_STATUS_IS_OK(status)) {		return status;	}	if (r->in.old_val) {		/* Decrypt */		crypt_secret.data = r->in.old_val->data;		crypt_secret.length = r->in.old_val->size;				status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);		if (!NT_STATUS_IS_OK(status)) {			return status;		}				val.data = secret.data;		val.length = secret.length;				/* set value */		if (samdb_msg_add_value(secret_state->sam_ldb, 					mem_ctx, msg, "priorValue", &val) != 0) {			return NT_STATUS_NO_MEMORY; 		}				/* set old value mtime */		if (samdb_msg_add_uint64(secret_state->sam_ldb, 					 mem_ctx, msg, "priorSetTime", nt_now) != 0) { 			return NT_STATUS_NO_MEMORY; 		}		if (!r->in.new_val) {			/* This behaviour varies depending of if this is a local, or a global secret... */			if (secret_state->global) {				/* set old value mtime */				if (samdb_msg_add_uint64(secret_state->sam_ldb, 							 mem_ctx, msg, "lastSetTime", nt_now) != 0) { 					return NT_STATUS_NO_MEMORY; 				}			} else {				if (samdb_msg_add_delete(secret_state->sam_ldb, 							 mem_ctx, msg, "currentValue")) {					return NT_STATUS_NO_MEMORY;				}				if (samdb_msg_add_delete(secret_state->sam_ldb, 							 mem_ctx, msg, "lastSetTime")) {					return NT_STATUS_NO_MEMORY;				}			}		}	}	if (r->in.new_val) {		/* Decrypt */

⌨️ 快捷键说明

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