Esempio n. 1
0
/* 
  spoolss_EnumForms 
*/
static WERROR dcesrv_spoolss_EnumForms(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
		       struct spoolss_EnumForms *r)
{
	struct ntptr_GenericHandle *handle;
	struct dcesrv_handle *h;
	WERROR status;
	struct smb_iconv_convenience *ic = lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx);

	DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
	handle = talloc_get_type(h->data, struct ntptr_GenericHandle);
	if (!handle)
		return WERR_BADFID;

	switch (handle->type) {
		case NTPTR_HANDLE_SERVER:
			status = ntptr_EnumPrintServerForms(handle, mem_ctx, r);
			W_ERROR_NOT_OK_RETURN(status);
			break;
		case NTPTR_HANDLE_PRINTER:
			status = ntptr_EnumPrinterForms(handle, mem_ctx, r);
			W_ERROR_NOT_OK_RETURN(status);
			break;
		default:
			return WERR_FOOBAR;
	}

	*r->out.needed	= SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumForms, ic, *r->out.info, r->in.level, *r->out.count);
	*r->out.info	= SPOOLSS_BUFFER_OK(*r->out.info, NULL);
	*r->out.count	= SPOOLSS_BUFFER_OK(*r->out.count, 0);
	return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
Esempio n. 2
0
/* 
  spoolss_GetForm 
*/
static WERROR dcesrv_spoolss_GetForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
		       struct spoolss_GetForm *r)
{
	struct ntptr_GenericHandle *handle;
	struct dcesrv_handle *h;
	WERROR status;
	struct smb_iconv_convenience *ic = lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx);

	DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
	handle = talloc_get_type(h->data, struct ntptr_GenericHandle);
	if (!handle)
		return WERR_BADFID;

	switch (handle->type) {
		case NTPTR_HANDLE_SERVER:
			/*
			 * stupid, but w2k3 returns WERR_BADFID here?
			 */
			return WERR_BADFID;
		case NTPTR_HANDLE_PRINTER:
			status = ntptr_GetPrinterForm(handle, mem_ctx, r);
			W_ERROR_NOT_OK_RETURN(status);
			break;
		default:
			return WERR_FOOBAR;
	}

	*r->out.needed	= SPOOLSS_BUFFER_UNION(spoolss_FormInfo, ic, r->out.info, r->in.level);
	r->out.info	= SPOOLSS_BUFFER_OK(r->out.info, NULL);
	return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
}
Esempio n. 3
0
/* 
  spoolss_SetForm 
*/
static WERROR dcesrv_spoolss_SetForm(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
		       struct spoolss_SetForm *r)
{
	struct ntptr_GenericHandle *handle;
	struct dcesrv_handle *h;
	WERROR status;

	DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
	handle = talloc_get_type(h->data, struct ntptr_GenericHandle);
	if (!handle)
		return WERR_BADFID;

	switch (handle->type) {
		case NTPTR_HANDLE_SERVER:
			status = ntptr_SetPrintServerForm(handle, mem_ctx, r);
			W_ERROR_NOT_OK_RETURN(status);
			break;
		case NTPTR_HANDLE_PRINTER:
			status = ntptr_SetPrinterForm(handle, mem_ctx, r);
			W_ERROR_NOT_OK_RETURN(status);
			break;
		default:
			return WERR_FOOBAR;
	}

	return WERR_OK;
}
Esempio n. 4
0
/* 
  spoolss_XcvData
*/
static WERROR dcesrv_spoolss_XcvData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
		       struct spoolss_XcvData *r)
{
	struct ntptr_GenericHandle *handle;
	struct dcesrv_handle *h;
	WERROR status;

	DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
	handle = talloc_get_type(h->data, struct ntptr_GenericHandle);

	switch (handle->type) {
		case NTPTR_HANDLE_SERVER:
			status = ntptr_XcvDataPrintServer(handle, mem_ctx, r);
			W_ERROR_NOT_OK_RETURN(status);
			break;
		case NTPTR_HANDLE_PRINTER:
			status = ntptr_XcvDataPrinter(handle, mem_ctx, r);
			W_ERROR_NOT_OK_RETURN(status);
			break;
		case NTPTR_HANDLE_PORT:
			status = ntptr_XcvDataPort(handle, mem_ctx, r);
			W_ERROR_NOT_OK_RETURN(status);
			break;
		case NTPTR_HANDLE_MONITOR:
			status = ntptr_XcvDataMonitor(handle, mem_ctx, r);
			W_ERROR_NOT_OK_RETURN(status);
			break;
		default:
			return WERR_FOOBAR;
	}

	/* TODO: handle the buffer sizes here! */
	return WERR_OK;
}
Esempio n. 5
0
/* 
  drsuapi_DsRemoveDSServer
*/
static WERROR dcesrv_drsuapi_DsRemoveDSServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
				       struct drsuapi_DsRemoveDSServer *r)
{
	struct drsuapi_bind_state *b_state;
	struct dcesrv_handle *h;
	struct ldb_dn *ntds_dn;
	int ret;
	bool ok;
	WERROR status;

	ZERO_STRUCT(r->out.res);
	*r->out.level_out = 1;

	status = drs_security_level_check(dce_call, "DsRemoveDSServer");
	if (!W_ERROR_IS_OK(status)) {
		return status;
	}

	DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
	b_state = h->data;

	switch (r->in.level) {
	case 1:
		ntds_dn = ldb_dn_new(mem_ctx, b_state->sam_ctx, r->in.req->req1.server_dn);
		W_ERROR_HAVE_NO_MEMORY(ntds_dn);

		ok = ldb_dn_validate(ntds_dn);
		if (!ok) {
			return WERR_FOOBAR;
		}

		/* TODO: it's likely that we need more checks here */

		ok = ldb_dn_add_child_fmt(ntds_dn, "CN=NTDS Settings");
		if (!ok) {
			return WERR_FOOBAR;
		}

		if (r->in.req->req1.commit) {
			ret = ldb_delete(b_state->sam_ctx, ntds_dn);
			if (ret != LDB_SUCCESS) {
				return WERR_FOOBAR;
			}
		}

		return WERR_OK;
	default:
		break;
	}

	return WERR_FOOBAR;
}
Esempio n. 6
0
/* 
  spoolss_ReplyClosePrinter 
*/
static WERROR dcesrv_spoolss_ReplyClosePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
		       struct spoolss_ReplyClosePrinter *r)
{
	struct dcesrv_handle *handle;
	
	DCESRV_PULL_HANDLE_WERR(handle, r->in.handle, SPOOLSS_NOTIFY);

	talloc_free(handle);

	ZERO_STRUCTP(r->out.handle);

	return WERR_OK;
}
Esempio n. 7
0
/* 
  drsuapi_DsCrackNames 
*/
static WERROR dcesrv_drsuapi_DsCrackNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
			    struct drsuapi_DsCrackNames *r)
{
	WERROR status;
	struct drsuapi_bind_state *b_state;
	struct dcesrv_handle *h;

	*r->out.level_out = r->in.level;

	DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
	b_state = h->data;

	r->out.ctr = talloc_zero(mem_ctx, union drsuapi_DsNameCtr);
	W_ERROR_HAVE_NO_MEMORY(r->out.ctr);

	switch (r->in.level) {
		case 1: {
			struct drsuapi_DsNameCtr1 *ctr1;
			struct drsuapi_DsNameInfo1 *names;
			int count;
			int i;

			ctr1 = talloc(mem_ctx, struct drsuapi_DsNameCtr1);
			W_ERROR_HAVE_NO_MEMORY(ctr1);

			count = r->in.req->req1.count;
			names = talloc_array(mem_ctx, struct drsuapi_DsNameInfo1, count);
			W_ERROR_HAVE_NO_MEMORY(names);

			for (i=0; i < count; i++) {
				status = DsCrackNameOneName(b_state->sam_ctx, mem_ctx,
							    r->in.req->req1.format_flags,
							    r->in.req->req1.format_offered,
							    r->in.req->req1.format_desired,
							    r->in.req->req1.names[i].str,
							    &names[i]);
				if (!W_ERROR_IS_OK(status)) {
					return status;
				}
			}

			ctr1->count = count;
			ctr1->array = names;
			r->out.ctr->ctr1 = ctr1;

			return WERR_OK;
		}
	}
	
	return WERR_UNKNOWN_LEVEL;
}
Esempio n. 8
0
/* 
  drsuapi_DsGetDomainControllerInfo 
*/
static WERROR dcesrv_drsuapi_DsGetDomainControllerInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
						struct drsuapi_DsGetDomainControllerInfo *r)
{
	struct dcesrv_handle *h;
	struct drsuapi_bind_state *b_state;	
	DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
	b_state = h->data;

	switch (r->in.level) {
	case 1:
		return dcesrv_drsuapi_DsGetDomainControllerInfo_1(b_state, mem_ctx, r);
	}

	return WERR_UNKNOWN_LEVEL;
}
Esempio n. 9
0
/* 
  drsuapi_DsUnbind 
*/
static WERROR dcesrv_drsuapi_DsUnbind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
			       struct drsuapi_DsUnbind *r)
{
	struct dcesrv_handle *h;

	*r->out.bind_handle = *r->in.bind_handle;

	DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);

	talloc_free(h);

	ZERO_STRUCTP(r->out.bind_handle);

	return WERR_OK;
}
Esempio n. 10
0
/* 
  spoolss_ClosePrinter 
*/
static WERROR dcesrv_spoolss_ClosePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
		       struct spoolss_ClosePrinter *r)
{
	struct dcesrv_handle *h;

	*r->out.handle = *r->in.handle;

	DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);

	talloc_free(h);

	ZERO_STRUCTP(r->out.handle);

	return WERR_OK;
}
Esempio n. 11
0
/* 
  drsuapi_DsCrackNames 
*/
static WERROR dcesrv_drsuapi_DsCrackNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
			    struct drsuapi_DsCrackNames *r)
{
	struct drsuapi_bind_state *b_state;
	struct dcesrv_handle *h;

	*r->out.level_out = r->in.level;

	DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
	b_state = h->data;

	r->out.ctr = talloc_zero(mem_ctx, union drsuapi_DsNameCtr);
	W_ERROR_HAVE_NO_MEMORY(r->out.ctr);

	switch (r->in.level) {
		case 1: {
			switch(r->in.req->req1.format_offered){
			case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT_NAME_SANS_DOMAIN_EX:
			case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT_NAME_SANS_DOMAIN:
			case DRSUAPI_DS_NAME_FORMAT_STRING_SID_NAME:
			case DRSUAPI_DS_NAME_FORMAT_ALT_SECURITY_IDENTITIES_NAME:
			case DRSUAPI_DS_NAME_FORMAT_MAP_SCHEMA_GUID:
			case DRSUAPI_DS_NAME_FORMAT_LIST_NCS:
			case DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS:
			case DRSUAPI_DS_NAME_FORMAT_LIST_GLOBAL_CATALOG_SERVERS:
			case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_WITH_DCS_IN_SITE:
			case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_FOR_DOMAIN_IN_SITE:
			case DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS_IN_SITE:
			case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_IN_SITE:
			case DRSUAPI_DS_NAME_FORMAT_LIST_SITES:
			case DRSUAPI_DS_NAME_FORMAT_UPN_AND_ALTSECID:
			case DRSUAPI_DS_NAME_FORMAT_UPN_FOR_LOGON:
				DEBUG(0, ("DsCrackNames: Unsupported operation requested: %X",
					  r->in.req->req1.format_offered));
				return WERR_OK;
			case DRSUAPI_DS_NAME_FORMAT_LIST_INFO_FOR_SERVER:
				return dcesrv_drsuapi_ListInfoServer(b_state->sam_ctx, mem_ctx, &r->in.req->req1, &r->out.ctr->ctr1);
			case DRSUAPI_DS_NAME_FORMAT_LIST_ROLES:
				return dcesrv_drsuapi_ListRoles(b_state->sam_ctx, mem_ctx,
								&r->in.req->req1, &r->out.ctr->ctr1);
			default:/* format_offered is in the enum drsuapi_DsNameFormat*/
				return dcesrv_drsuapi_CrackNamesByNameFormat(b_state->sam_ctx, mem_ctx,
									     &r->in.req->req1, &r->out.ctr->ctr1);
			}
		}
	}
	return WERR_UNKNOWN_LEVEL;
}
Esempio n. 12
0
/* 
  spoolss_GetPrinterData 
*/
static WERROR dcesrv_spoolss_GetPrinterData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
		       struct spoolss_GetPrinterData *r)
{
	struct ntptr_GenericHandle *handle;
	struct dcesrv_handle *h;
	WERROR status;
	struct smb_iconv_convenience *ic = lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx);

	DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
	handle = talloc_get_type(h->data, struct ntptr_GenericHandle);
	if (!handle)
		return WERR_BADFID;

	r->out.type = talloc_zero(mem_ctx, enum winreg_Type);
	W_ERROR_HAVE_NO_MEMORY(r->out.type);

	r->out.needed = talloc_zero(mem_ctx, uint32_t);
	W_ERROR_HAVE_NO_MEMORY(r->out.needed);

	r->out.data = talloc_zero(mem_ctx, union spoolss_PrinterData);
	W_ERROR_HAVE_NO_MEMORY(r->out.data);

	switch (handle->type) {
		case NTPTR_HANDLE_SERVER:
			status = ntptr_GetPrintServerData(handle, mem_ctx, r);
			break;
		default:
			status = WERR_FOOBAR;
			break;
	}

	W_ERROR_NOT_OK_RETURN(status);

	*r->out.needed	= ndr_size_spoolss_PrinterData(r->out.data, *r->out.type, ic, 0);
	*r->out.type	= SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
	r->out.data	= SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
	return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
}
Esempio n. 13
0
/*
  drsuapi_DsWriteAccountSpn
*/
WERROR dcesrv_drsuapi_DsWriteAccountSpn(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
					struct drsuapi_DsWriteAccountSpn *r)
{
	struct drsuapi_bind_state *b_state;
	struct dcesrv_handle *h;

	*r->out.level_out = r->in.level;

	DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
	b_state = h->data;

	r->out.res = talloc(mem_ctx, union drsuapi_DsWriteAccountSpnResult);
	W_ERROR_HAVE_NO_MEMORY(r->out.res);

	switch (r->in.level) {
		case 1: {
			struct drsuapi_DsWriteAccountSpnRequest1 *req;
			struct ldb_message *msg;
			int count, i, ret;
			struct ldb_result *res;
			const char *attrs[] = { "servicePrincipalName", NULL };
			struct ldb_message_element *el;
			unsigned spn_count=0;

			req = &r->in.req->req1;
			count = req->count;

			msg = ldb_msg_new(mem_ctx);
			if (msg == NULL) {
				return WERR_NOMEM;
			}

			msg->dn = ldb_dn_new(msg, b_state->sam_ctx, req->object_dn);
			if ( ! ldb_dn_validate(msg->dn)) {
				r->out.res->res1.status = WERR_OK;
				return WERR_OK;
			}

			/* load the existing SPNs, as these are
			 * ignored for adds and deletes (see MS-DRSR
			 * section 4.1.28.3)
			 */
			ret = ldb_search(b_state->sam_ctx, msg, &res, msg->dn, LDB_SCOPE_BASE,
					 attrs, NULL);
			if (ret != LDB_SUCCESS) {
				DEBUG(0,("Failed to load existing SPNs on %s: %s\n",
					 ldb_dn_get_linearized(msg->dn),
					 ldb_errstring(b_state->sam_ctx)));
				r->out.res->res1.status = WERR_DS_OBJ_NOT_FOUND;
				return WERR_OK;
			}
			el = ldb_msg_find_element(res->msgs[0], "servicePrincipalName");

			/* construct mods */
			for (i = 0; i < count; i++) {
				bool found = false;
				int j;
				for (j=0; el && j<el->num_values; j++) {
					if (samdb_ldb_val_case_cmp(req->spn_names[i].str, &el->values[j]) == 0) {
						found = true;
						break;
					}
				}
				if ((req->operation == DRSUAPI_DS_SPN_OPERATION_ADD && found) ||
				    (req->operation == DRSUAPI_DS_SPN_OPERATION_DELETE && !found)) {
					continue;
				}
				ret = samdb_msg_add_string(b_state->sam_ctx,
							   msg, msg, "servicePrincipalName",
							   req->spn_names[i].str);
				if (ret != LDB_SUCCESS) {
					return WERR_NOMEM;
				}
				spn_count++;
			}

			if (msg->num_elements == 0) {
				DEBUG(2,("No SPNs need changing on %s\n", ldb_dn_get_linearized(msg->dn)));
				r->out.res->res1.status = WERR_OK;
				return WERR_OK;
			}

			for (i=0;i<msg->num_elements;i++) {
				switch (req->operation) {
				case DRSUAPI_DS_SPN_OPERATION_ADD:
					msg->elements[i].flags = LDB_FLAG_MOD_ADD;
					break;
				case DRSUAPI_DS_SPN_OPERATION_REPLACE:
					msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
					break;
				case DRSUAPI_DS_SPN_OPERATION_DELETE:
					msg->elements[i].flags = LDB_FLAG_MOD_DELETE;
					break;
				}
			}

			/* Apply to database */

			ret = ldb_modify(b_state->sam_ctx, msg);
			if (ret != 0) {
				DEBUG(0,("Failed to modify SPNs on %s: %s\n",
					 ldb_dn_get_linearized(msg->dn),
					 ldb_errstring(b_state->sam_ctx)));
				r->out.res->res1.status = WERR_ACCESS_DENIED;
			} else {
				DEBUG(2,("Modified %u SPNs on %s\n", spn_count, ldb_dn_get_linearized(msg->dn)));
				r->out.res->res1.status = WERR_OK;
			}

			return WERR_OK;
		}
	}

	return WERR_UNKNOWN_LEVEL;
}
Esempio n. 14
0
/*
  drsuapi_DsWriteAccountSpn
*/
WERROR dcesrv_drsuapi_DsWriteAccountSpn(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
					struct drsuapi_DsWriteAccountSpn *r)
{
	struct drsuapi_bind_state *b_state;
	struct dcesrv_handle *h;

	*r->out.level_out = r->in.level;

	DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
	b_state = h->data;

	r->out.res = talloc(mem_ctx, union drsuapi_DsWriteAccountSpnResult);
	W_ERROR_HAVE_NO_MEMORY(r->out.res);

	switch (r->in.level) {
		case 1: {
			struct drsuapi_DsWriteAccountSpnRequest1 *req;
			struct ldb_message *msg;
			uint32_t count;
			unsigned int i;
			int ret;
			unsigned spn_count=0;
			bool passed_checks = true;
			struct ldb_context *sam_ctx;

			req = &r->in.req->req1;
			count = req->count;

			msg = ldb_msg_new(mem_ctx);
			if (msg == NULL) {
				return WERR_NOMEM;
			}

			msg->dn = ldb_dn_new(msg, b_state->sam_ctx,
					     req->object_dn);
			if ( ! ldb_dn_validate(msg->dn)) {
				r->out.res->res1.status = WERR_OK;
				return WERR_OK;
			}

			/* construct mods */
			for (i = 0; i < count; i++) {
				if (!writespn_check_spn(b_state,
						       dce_call,
						       msg->dn,
						       req->spn_names[i].str)) {
					passed_checks = false;
				}
				ret = ldb_msg_add_string(msg,
							 "servicePrincipalName",
							 req->spn_names[i].str);
				if (ret != LDB_SUCCESS) {
					return WERR_NOMEM;
				}
				spn_count++;
			}

			if (msg->num_elements == 0) {
				DEBUG(2,("No SPNs need changing on %s\n",
					 ldb_dn_get_linearized(msg->dn)));
				r->out.res->res1.status = WERR_OK;
				return WERR_OK;
			}

			for (i=0;i<msg->num_elements;i++) {
				switch (req->operation) {
				case DRSUAPI_DS_SPN_OPERATION_ADD:
					msg->elements[i].flags = LDB_FLAG_MOD_ADD;
					break;
				case DRSUAPI_DS_SPN_OPERATION_REPLACE:
					msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
					break;
				case DRSUAPI_DS_SPN_OPERATION_DELETE:
					msg->elements[i].flags = LDB_FLAG_MOD_DELETE;
					break;
				}
			}

			if (passed_checks && b_state->sam_ctx_system) {
				sam_ctx = b_state->sam_ctx_system;
			} else {
				sam_ctx = b_state->sam_ctx;
			}

			/* Apply to database */
			ret = dsdb_modify(sam_ctx, msg, DSDB_MODIFY_PERMISSIVE);
			if (ret != LDB_SUCCESS) {
				DEBUG(0,("Failed to modify SPNs on %s: %s\n",
					 ldb_dn_get_linearized(msg->dn),
					 ldb_errstring(b_state->sam_ctx)));
				NDR_PRINT_IN_DEBUG(
					drsuapi_DsWriteAccountSpn, r);
				r->out.res->res1.status = WERR_ACCESS_DENIED;
			} else {
				DEBUG(2,("Modified %u SPNs on %s\n", spn_count,
					 ldb_dn_get_linearized(msg->dn)));
				r->out.res->res1.status = WERR_OK;
			}

			return WERR_OK;
		}
	}

	return WERR_UNKNOWN_LEVEL;
}
Esempio n. 15
0
/* 
  drsuapi_DsWriteAccountSpn 
*/
static WERROR dcesrv_drsuapi_DsWriteAccountSpn(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
		       struct drsuapi_DsWriteAccountSpn *r)
{
	struct drsuapi_bind_state *b_state;
	struct dcesrv_handle *h;

	*r->out.level_out = r->in.level;

	DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
	b_state = h->data;

	r->out.res = talloc(mem_ctx, union drsuapi_DsWriteAccountSpnResult);
	W_ERROR_HAVE_NO_MEMORY(r->out.res);

	switch (r->in.level) {
		case 1: {
			struct drsuapi_DsWriteAccountSpnRequest1 *req;
			struct ldb_message *msg;
			int count, i, ret;
			req = &r->in.req->req1;
			count = req->count;

			msg = ldb_msg_new(mem_ctx);
			if (msg == NULL) {
				return WERR_NOMEM;
			}

			msg->dn = ldb_dn_new(msg, b_state->sam_ctx, req->object_dn);
			if ( ! ldb_dn_validate(msg->dn)) {
				r->out.res->res1.status = WERR_OK;
				return WERR_OK;
			}
			
			/* construct mods */
			for (i = 0; i < count; i++) {
				samdb_msg_add_string(b_state->sam_ctx, 
						     msg, msg, "servicePrincipalName",
						     req->spn_names[i].str);
			}
			for (i=0;i<msg->num_elements;i++) {
				switch (req->operation) {
				case DRSUAPI_DS_SPN_OPERATION_ADD:
 					msg->elements[i].flags = LDB_FLAG_MOD_ADD;
					break;
				case DRSUAPI_DS_SPN_OPERATION_REPLACE:
					msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
					break;
				case DRSUAPI_DS_SPN_OPERATION_DELETE:
					msg->elements[i].flags = LDB_FLAG_MOD_DELETE;
					break;
				}
			}
   
			/* Apply to database */

			ret = ldb_modify(b_state->sam_ctx, msg);
			if (ret != 0) {
				DEBUG(0,("Failed to modify SPNs on %s: %s\n",
					 ldb_dn_get_linearized(msg->dn), 
					 ldb_errstring(b_state->sam_ctx)));
				r->out.res->res1.status = WERR_ACCESS_DENIED;
			} else {
				r->out.res->res1.status = WERR_OK;
			}

			return WERR_OK;
		}
	}
	
	return WERR_UNKNOWN_LEVEL;
}
Esempio n. 16
0
/* 
  drsuapi_DsAddEntry
*/
WERROR dcesrv_drsuapi_DsAddEntry(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
				 struct drsuapi_DsAddEntry *r)
{
	WERROR status;
	struct drsuapi_bind_state *b_state;
	struct dcesrv_handle *h;
	uint32_t num = 0;
	struct drsuapi_DsReplicaObjectIdentifier2 *ids = NULL;
	int ret;
	const struct drsuapi_DsReplicaObjectListItem *first_object;

	if (DEBUGLVL(4)) {
		NDR_PRINT_FUNCTION_DEBUG(drsuapi_DsAddEntry, NDR_IN, r);
	}

	/* TODO: check which out level the client supports */

	ZERO_STRUCTP(r->out.ctr);
	*r->out.level_out = 3;
	r->out.ctr->ctr3.err_ver = 1;
	r->out.ctr->ctr3.err_data = talloc_zero(mem_ctx, union drsuapi_DsAddEntry_ErrData);

	DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
	b_state = h->data;

	status = drs_security_level_check(dce_call, "DsAddEntry", SECURITY_DOMAIN_CONTROLLER, NULL);
	if (!W_ERROR_IS_OK(status)) {
		return status;
	}

	switch (r->in.level) {
	case 2:
		ret = ldb_transaction_start(b_state->sam_ctx);
		if (ret != LDB_SUCCESS) {
			return WERR_DS_DRA_INTERNAL_ERROR;
		}


		first_object = &r->in.req->req2.first_object;

		status = dsdb_origin_objects_commit(b_state->sam_ctx,
						    mem_ctx,
						    first_object,
						    &num,
						    DSDB_REPL_FLAG_ADD_NCNAME,
						    &ids);
		if (!W_ERROR_IS_OK(status)) {
			r->out.ctr->ctr3.err_data->v1.status = status;
			ldb_transaction_cancel(b_state->sam_ctx);
			DEBUG(0,(__location__ ": DsAddEntry failed - %s\n", win_errstr(status)));
			return status;
		}

		r->out.ctr->ctr3.count = num;
		r->out.ctr->ctr3.objects = ids;

		break;
	default:
		return WERR_FOOBAR;
	}

	/* if any of the added entries are nTDSDSA objects then we
	 * need to add the SPNs to the machine account
	 */
	status = drsuapi_add_SPNs(b_state, dce_call, mem_ctx, first_object);
	if (!W_ERROR_IS_OK(status)) {
		r->out.ctr->ctr3.err_data->v1.status = status;
		ldb_transaction_cancel(b_state->sam_ctx);
		DEBUG(0,(__location__ ": DsAddEntry add SPNs failed - %s\n", win_errstr(status)));
		return status;
	}

	ret = ldb_transaction_commit(b_state->sam_ctx);
	if (ret != LDB_SUCCESS) {
		DEBUG(0,(__location__ ": DsAddEntry commit failed: %s\n",
			 ldb_errstring(b_state->sam_ctx)));
		return WERR_DS_DRA_INTERNAL_ERROR;
	}

	return WERR_OK;
}