Example #1
0
/**
   \details Test the NspiGetNamesFromIDs RPC operation (0x11)

   \param mt pointer on the top-level mapitest structure

   \return true on success, otherwise false
 */
_PUBLIC_ bool mapitest_nspi_GetNamesFromIDs(struct mapitest *mt)
{
	TALLOC_CTX			*mem_ctx;
	enum MAPISTATUS			retval;
	struct nspi_context		*nspi_ctx;
	struct SPropTagArray		*ppReturnedPropTags;
	struct PropertyNameSet_r	*ppNames;

	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_GetNamesFromIDs");
	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;


	ppReturnedPropTags = talloc_zero(mem_ctx, struct SPropTagArray);
	ppNames = talloc_zero(mem_ctx, struct PropertyNameSet_r);
	retval = nspi_GetNamesFromIDs(nspi_ctx, mem_ctx, NULL, NULL, &ppReturnedPropTags, &ppNames);
	mapitest_print_retval_clean(mt, "NspiGetNamesFromIDs", retval);
	MAPIFreeBuffer(ppReturnedPropTags);
	MAPIFreeBuffer(ppNames);
	talloc_free(mem_ctx);

	if (retval == MAPI_E_SUCCESS) {
	      return true;
	} else {
	      return false;
	}
}
Example #2
0
/**
   \details Test the NspiGetSpecialTable RPC operation (0x0c)

   \param mt pointer on the top-level mapitest structure

   \return true on success, otherwise false
 */
_PUBLIC_ bool mapitest_nspi_GetSpecialTable(struct mapitest *mt)
{
	TALLOC_CTX		*mem_ctx;
	enum MAPISTATUS		retval;
	struct nspi_context	*nspi_ctx;
	struct PropertyRowSet_r		*RowSet;

	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_GetSpecialTable");
	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;

	RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r);
	retval = nspi_GetSpecialTable(nspi_ctx, mem_ctx, 0x0, &RowSet);
	MAPIFreeBuffer(RowSet);
	mapitest_print_retval_clean(mt, "NspiGetSpecialTable (Hierarchy Table)", retval);

	if (retval != MAPI_E_SUCCESS) {
		talloc_free(mem_ctx);
		return false;
	}

	RowSet = talloc_zero(mt->mem_ctx, struct PropertyRowSet_r);
	retval = nspi_GetSpecialTable(nspi_ctx, mem_ctx, 0x2, &RowSet);
	MAPIFreeBuffer(RowSet);
	mapitest_print_retval_clean(mt, "NspiGetSpecialTable (Address Creation Template)", retval);
	talloc_free(mem_ctx);

	if (retval == MAPI_E_SUCCESS) {
	      return true;
	} else {
	      return false;
	}
}
Example #3
0
/**
   \details Test the NspiQueryColumns RPC operation (0x10)

   \param mt pointer on the top-level mapitest structure

   \return true on success, otherwise false
 */
_PUBLIC_ bool mapitest_nspi_QueryColumns(struct mapitest *mt)
{
	TALLOC_CTX		*mem_ctx;
	enum MAPISTATUS		retval;
	struct nspi_context	*nspi_ctx;
	struct SPropTagArray	*SPropTagArray = NULL;
	
	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_QueryColumns");
	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
	
	SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray);

	retval = nspi_QueryColumns(nspi_ctx, mem_ctx, true, &SPropTagArray);
	if (retval != MAPI_E_SUCCESS) {
		mapitest_print_retval_clean(mt, "NspiQueryColumns", retval);
		MAPIFreeBuffer(SPropTagArray);
		talloc_free(mem_ctx);
		return false;
	}

	if (SPropTagArray) {
		mapitest_print(mt, "* %d columns returned\n", SPropTagArray->cValues);
		mapitest_print_retval_clean(mt, "NspiQueryColumns", retval);
		MAPIFreeBuffer(SPropTagArray);
	}
	talloc_free(mem_ctx);

	return true;
}
Example #4
0
/**
   \details Test the NspiUpdateStat RPC operation (0x02)

   \param mt pointer on the top-level mapitest structure

   \return true on success, otherwise false
 */
_PUBLIC_ bool mapitest_nspi_UpdateStat(struct mapitest *mt)
{
	TALLOC_CTX		*mem_ctx;
	enum MAPISTATUS		retval;
	struct nspi_context	*nspi_ctx;
	int32_t       		plDelta = 1;
	struct PropertyRowSet_r	*RowSet;

	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_UpdateStat");
	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;

	RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r);
	retval = nspi_GetSpecialTable(nspi_ctx, mem_ctx, 0x2, &RowSet);
	MAPIFreeBuffer(RowSet);
	if (retval != MAPI_E_SUCCESS) {
		talloc_free(mem_ctx);
		return false;
	}

	retval = nspi_UpdateStat(nspi_ctx, mem_ctx, &plDelta);
	mapitest_print_retval(mt, "NspiUpdateStat");
	if (retval != MAPI_E_SUCCESS) {
		talloc_free(mem_ctx);
		return false;
	}
	mapitest_print(mt, "* %-35s: %d\n", "plDelta", plDelta);
	talloc_free(mem_ctx);

	return true;
}
Example #5
0
/**
   \details Test the NspiGetPropList RPC operation (0x08)

   \param mt pointer on the top-level mapitest structure

   \return true on success, otherwise false
 */
_PUBLIC_ bool mapitest_nspi_GetPropList(struct mapitest *mt)
{
	TALLOC_CTX			*mem_ctx;
	enum MAPISTATUS			retval;
	struct nspi_context		*nspi_ctx;
	struct SPropTagArray		*pPropTags = 0;
	struct PropertyTagArray_r	*MIds;
	struct PropertyValue_r		*lpProp;
	struct Restriction_r		Filter;
	struct SPropTagArray		*SPropTagArray;
	struct PropertyRowSet_r		*RowSet;

	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_GetPropList");
	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;

	/* Step 1. Query for current profile username */
	SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_DISPLAY_NAME);
	lpProp = talloc_zero(mem_ctx, struct PropertyValue_r);
	lpProp->ulPropTag = PR_ANR_UNICODE;
	lpProp->dwAlignPad = 0;
	lpProp->value.lpszW = mt->mapi_ctx->session->profile->username;

	Filter.rt = RES_PROPERTY;
	Filter.res.resProperty.relop = RES_PROPERTY;
	Filter.res.resProperty.ulPropTag = PR_ANR_UNICODE;
	Filter.res.resProperty.lpProp = lpProp;

	RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r);
	MIds = talloc_zero(mem_ctx, struct PropertyTagArray_r);
	retval = nspi_GetMatches(nspi_ctx, mem_ctx, SPropTagArray, &Filter, 5000, &RowSet, &MIds);
	MAPIFreeBuffer(SPropTagArray);
	MAPIFreeBuffer(lpProp);
	MAPIFreeBuffer(RowSet);
	if (retval != MAPI_E_SUCCESS) {
		MAPIFreeBuffer(MIds);
		talloc_free(mem_ctx);
		return retval;
	}


	/* Step 2. Call NspiGetPropList using the MId returned by NspiGetMatches */
	pPropTags = talloc_zero(mt->mem_ctx, struct SPropTagArray);
	retval = nspi_GetPropList(nspi_ctx, mem_ctx, 0, MIds->aulPropTag[0], &pPropTags);
	MAPIFreeBuffer(MIds);
	mapitest_print_retval(mt, "NspiGetPropList");

	if (retval != MAPI_E_SUCCESS) {
		MAPIFreeBuffer(pPropTags);
		talloc_free(mem_ctx);
		return false;
	}

	if (pPropTags) {
		mapitest_print(mt, "* %-35s: %d\n", "Properties number", pPropTags->cValues);
		MAPIFreeBuffer(pPropTags);
	}
	talloc_free(mem_ctx);

	return true;
}
Example #6
0
/**
   \details Test the NspiDNToMId RPC operation (0x7)

   \param mt pointer on the top-level mapitest structure

   \return true on success, otherwise false
 */
_PUBLIC_ bool mapitest_nspi_DNToMId(struct mapitest *mt)
{
	TALLOC_CTX			*mem_ctx;
	enum MAPISTATUS			retval;
	struct nspi_context		*nspi_ctx;
	struct StringsArray_r		pNames;
	struct PropertyTagArray_r	*MId;

	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_DNToMId");
	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;

	pNames.Count = 0x1;
	pNames.Strings = (const char **) talloc_array(mem_ctx, char *, 1);
	pNames.Strings[0] = mt->mapi_ctx->session->profile->homemdb;

	MId = talloc_zero(mem_ctx, struct PropertyTagArray_r);

	retval = nspi_DNToMId(nspi_ctx, mem_ctx, &pNames, &MId);
	MAPIFreeBuffer((char **)pNames.Strings);
	MAPIFreeBuffer(MId);
	talloc_free(mem_ctx);

	mapitest_print_retval_clean(mt, "NspiDNToMId", retval);

	if (retval == MAPI_E_SUCCESS) {
	      return true;
	} else {
	      return false;
	}
}
Example #7
0
TallocContext::TallocContext(const char *name)
{
    m_ctx = talloc_named(NULL, 0, "%s", name);
    if (!m_ctx) {
        qCritical() << name << "talloc_named failed";
    }
}
Example #8
0
/* Given the right private pointer from hdb_samba4, get a PAC from the attached ldb messages */
static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context,
					 struct hdb_entry_ex *client,
					 krb5_pac *pac)
{
	TALLOC_CTX *mem_ctx;
	DATA_BLOB *pac_blob;
	krb5_error_code ret;
	NTSTATUS nt_status;

	mem_ctx = talloc_named(client->ctx, 0, "samba_get_pac context");
	if (!mem_ctx) {
		return ENOMEM;
	}

	nt_status = samba_kdc_get_pac_blob(mem_ctx, client, &pac_blob);
	if (!NT_STATUS_IS_OK(nt_status)) {
		talloc_free(mem_ctx);
		return EINVAL;
	}

	ret = samba_make_krb5_pac(context, pac_blob, NULL, pac);

	talloc_free(mem_ctx);
	return ret;
}
Example #9
0
static NTSTATUS w32time__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull, void **r)
{
	enum ndr_err_code ndr_err;
	uint16_t opnum = dce_call->pkt.u.request.opnum;

	dce_call->fault_code = 0;

	if (opnum >= ndr_table_w32time.num_calls) {
		dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
		return NT_STATUS_NET_WRITE_FAULT;
	}

	*r = talloc_named(mem_ctx,
			  ndr_table_w32time.calls[opnum].struct_size,
			  "struct %s",
			  ndr_table_w32time.calls[opnum].name);
	NT_STATUS_HAVE_NO_MEMORY(*r);

        /* unravel the NDR for the packet */
	ndr_err = ndr_table_w32time.calls[opnum].ndr_pull(pull, NDR_IN, *r);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		dcerpc_log_packet(dce_call->conn->packet_log_dir, 
				  &ndr_table_w32time, opnum, NDR_IN,
				  &dce_call->pkt.u.request.stub_and_verifier);
		dce_call->fault_code = DCERPC_FAULT_NDR;
		return NT_STATUS_NET_WRITE_FAULT;
	}

	return NT_STATUS_OK;
}
Example #10
0
/**
   \details Initialize the EMSABP context and open connections to
   Samba databases.

   \param lp_ctx pointer to the loadparm context
   \param tdb_ctx pointer to the EMSABP TDB context

   \return Allocated emsabp_context on success, otherwise NULL
 */
_PUBLIC_ struct emsabp_context *emsabp_init(struct loadparm_context *lp_ctx,
					    TDB_CONTEXT *tdb_ctx)
{
	TALLOC_CTX		*mem_ctx;
	struct emsabp_context	*emsabp_ctx;
	struct tevent_context	*ev;
	const char		*samdb_url;

	/* Sanity checks */
	if (!lp_ctx) return NULL;

	mem_ctx = talloc_named(NULL, 0, "emsabp_init");
	
	emsabp_ctx = talloc_zero(mem_ctx, struct emsabp_context);
	if (!emsabp_ctx) {
		talloc_free(mem_ctx);
		return NULL;
	}

	emsabp_ctx->mem_ctx = mem_ctx;

	ev = tevent_context_init(mem_ctx);
	if (!ev) {
		talloc_free(mem_ctx);
		return NULL;
	}
	tevent_loop_allow_nesting(ev);

	/* Save a pointer to the loadparm context */
	emsabp_ctx->lp_ctx = lp_ctx;


	/* Retrieve samdb url (local or external) */
	samdb_url = lpcfg_parm_string(lp_ctx, NULL, "dcerpc_mapiproxy", "samdb_url");

	/* return an opaque context pointer on samDB database */
	if (!samdb_url) {
		emsabp_ctx->samdb_ctx = samdb_connect(mem_ctx, ev, lp_ctx, system_session(lp_ctx), 0);
	} else {
		emsabp_ctx->samdb_ctx = samdb_connect_url(mem_ctx, ev, lp_ctx, system_session(lp_ctx), 0, samdb_url);
	}

	if (!emsabp_ctx->samdb_ctx) {
		talloc_free(mem_ctx);
		DEBUG(0, ("[%s:%d]: Connection to \"sam.ldb\" failed\n", __FUNCTION__, __LINE__));
		return NULL;
	}

	/* Reference the global TDB context to the current emsabp context */
	emsabp_ctx->tdb_ctx = tdb_ctx;

	/* Initialize a temporary (on-memory) TDB database to store
	 * temporary MId used within EMSABP */
	emsabp_ctx->ttdb_ctx = emsabp_tdb_init_tmp(emsabp_ctx->mem_ctx);
	if (!emsabp_ctx->ttdb_ctx) {
		smb_panic("unable to create on-memory TDB database");
	}

	return emsabp_ctx;
}
Example #11
0
NTSTATUS schannel_get_creds_state(TALLOC_CTX *mem_ctx,
				  struct loadparm_context *lp_ctx,
				  const char *computer_name,
				  struct netlogon_creds_CredentialState **_creds)
{
	TALLOC_CTX *tmpctx;
	struct tdb_wrap *tdb_sc;
	struct netlogon_creds_CredentialState *creds;
	NTSTATUS status;

	tmpctx = talloc_named(mem_ctx, 0, "schannel_get_creds_state");
	if (!tmpctx) {
		return NT_STATUS_NO_MEMORY;
	}

	tdb_sc = open_schannel_session_store(tmpctx, lp_ctx);
	if (!tdb_sc) {
		return NT_STATUS_ACCESS_DENIED;
	}

	status = schannel_fetch_session_key_tdb(tdb_sc, tmpctx, 
						computer_name, &creds);
	if (NT_STATUS_IS_OK(status)) {
		*_creds = talloc_steal(mem_ctx, creds);
		if (!*_creds) {
			status = NT_STATUS_NO_MEMORY;
		}
	}

	talloc_free(tmpctx);
	return status;
}
Example #12
0
/* Given a kdc entry, consult the account_ok routine in auth/auth_sam.c
 * for consistency */
NTSTATUS samba_kdc_check_client_access(struct samba_kdc_entry *kdc_entry,
				       const char *client_name,
				       const char *workstation,
				       bool password_change)
{
	TALLOC_CTX *tmp_ctx;
	NTSTATUS nt_status;

	tmp_ctx = talloc_named(NULL, 0, "samba_kdc_check_client_access");
	if (!tmp_ctx) {
		return NT_STATUS_NO_MEMORY;
	}

	/* we allow all kinds of trusts here */
	nt_status = authsam_account_ok(tmp_ctx,
				       kdc_entry->kdc_db_ctx->samdb,
				       MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
				       MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT,
				       kdc_entry->realm_dn, kdc_entry->msg,
				       workstation, client_name,
				       true, password_change);

	talloc_free(tmp_ctx);
	return nt_status;
}
Example #13
0
static DATA_BLOB NTLMv2_generate_response(TALLOC_CTX *out_mem_ctx,
					  const uint8_t ntlm_v2_hash[16],
					  const DATA_BLOB *server_chal,
					  const DATA_BLOB *names_blob)
{
	uint8_t ntlmv2_response[16];
	DATA_BLOB ntlmv2_client_data;
	DATA_BLOB final_response;

	TALLOC_CTX *mem_ctx = talloc_named(out_mem_ctx, 0,
					   "NTLMv2_generate_response internal context");

	if (!mem_ctx) {
		return data_blob(NULL, 0);
	}

	/* NTLMv2 */
	/* generate some data to pass into the response function - including
	   the hostname and domain name of the server */
	ntlmv2_client_data = NTLMv2_generate_client_data(mem_ctx, names_blob);

	/* Given that data, and the challenge from the server, generate a response */
	SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response);

	final_response = data_blob_talloc(out_mem_ctx, NULL, sizeof(ntlmv2_response) + ntlmv2_client_data.length);

	memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response));

	memcpy(final_response.data+sizeof(ntlmv2_response),
	       ntlmv2_client_data.data, ntlmv2_client_data.length);

	talloc_free(mem_ctx);

	return final_response;
}
/**
   \details return the next unmapped property ID

   \param ldb_ctx pointer to the namedprops ldb context

   \return 0 on error, the next mapped id otherwise
 */
_PUBLIC_ uint16_t mapistore_namedprops_next_unused_id(struct ldb_context *ldb_ctx)
{
	uint16_t		highest_id = 0, current_id;
	TALLOC_CTX		*mem_ctx;
	struct ldb_result	*res = NULL;
	const char * const	attrs[] = { "mappedId", NULL };
	int			ret;
	unsigned int		i;

	mem_ctx = talloc_named(NULL, 0, "mapistore_namedprops_get_mapped_propID");

	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
			 LDB_SCOPE_SUBTREE, attrs, "(cn=*)");
	MAPISTORE_RETVAL_IF(ret != LDB_SUCCESS, 0, mem_ctx);

	for (i = 0; i < res->count; i++) {
		current_id = ldb_msg_find_attr_as_uint(res->msgs[i], "mappedId", 0);
		if (current_id > 0 && highest_id < current_id) {
			highest_id = current_id;
		}
	}

	talloc_free(mem_ctx);

	DEBUG(5, ("next_mapped_id: %d\n", (highest_id + 1)));

	return (highest_id + 1);
}
Example #15
0
static int mit_samba_get_pac_data(struct mit_samba_context *ctx,
				  hdb_entry_ex *client,
				  DATA_BLOB *data)
{
	TALLOC_CTX *tmp_ctx;
	DATA_BLOB *pac_blob;
	NTSTATUS nt_status;

	tmp_ctx = talloc_named(ctx, 0, "mit_samba_get_pac_data context");
	if (!tmp_ctx) {
		return ENOMEM;
	}

	nt_status = samba_kdc_get_pac_blob(tmp_ctx, client, &pac_blob);
	if (!NT_STATUS_IS_OK(nt_status)) {
		talloc_free(tmp_ctx);
		return EINVAL;
	}

	data->data = (uint8_t *)malloc(pac_blob->length);
	if (!data->data) {
		talloc_free(tmp_ctx);
		return ENOMEM;
	}
	memcpy(data->data, pac_blob->data, pac_blob->length);
	data->length = pac_blob->length;

	talloc_free(tmp_ctx);
	return 0;
}
Example #16
0
int mit_samba_generate_random_password(krb5_data *pwd)
{
	TALLOC_CTX *tmp_ctx;
	char *password;

	if (pwd == NULL) {
		return EINVAL;
	}
	pwd->length = 24;

	tmp_ctx = talloc_named(NULL,
			       0,
			       "mit_samba_create_principal_password context");
	if (tmp_ctx == NULL) {
		return ENOMEM;
	}

	password = generate_random_password(tmp_ctx, pwd->length, pwd->length);
	if (password == NULL) {
		talloc_free(tmp_ctx);
		return ENOMEM;
	}

	pwd->data = strdup(password);
	talloc_free(tmp_ctx);
	if (pwd->data == NULL) {
		return ENOMEM;
	}

	return 0;
}
Example #17
0
static void tc_mapi_copy_spropvalues_setup(void)
{
	mem_ctx = talloc_named(NULL, 0, "libmapi_property_suite");
	test_srow = talloc_zero(mem_ctx, struct SRow);

	_make_test_srow(mem_ctx);
}
Example #18
0
/**
   \details Test #1863 NspiQueryRows and try to build PR_ENTRYID for
   AD user which is not part of OpenChange.

   \param mt pointer to the top level mapitest structure

   \return true on success, otherwise false
 */
_PUBLIC_ bool mapitest_zentyal_1863(struct mapitest *mt)
{
	TALLOC_CTX			*mem_ctx;
	enum MAPISTATUS			retval;
	struct nspi_context		*nspi_ctx;
	struct PropertyTagArray_r	*MIds;
	struct PropertyRowSet_r		*RowSet;
	struct SPropTagArray		*SPropTagArray;
	struct PropertyValue_r		*lpProp;
	struct Restriction_r		Filter;

	mem_ctx = talloc_named(NULL, 0, "mapitest_zentyal_1863");
	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;

	/* Build the array of columns we want to retrieve */
	SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_DISPLAY_NAME,
					  PR_DISPLAY_TYPE);

	/* Build the restriction we want for NspiGetMatches on
	 * existing AD user but not OpenChange one
	 */
	lpProp = talloc_zero(mem_ctx, struct PropertyValue_r);
	lpProp->ulPropTag = PR_ACCOUNT;
	lpProp->dwAlignPad = 0;
	lpProp->value.lpszA = talloc_strdup(lpProp, mt->profile->username);

	Filter.rt = RES_PROPERTY;
	Filter.res.resProperty.relop = RES_PROPERTY;
	Filter.res.resProperty.ulPropTag = PR_ACCOUNT;
	Filter.res.resProperty.lpProp = lpProp;

	RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r);
	MIds = talloc_zero(mem_ctx, struct PropertyTagArray_r);
	retval = nspi_GetMatches(nspi_ctx, mem_ctx, SPropTagArray, &Filter, 5000, &RowSet, &MIds);
	MAPIFreeBuffer(lpProp);
	MAPIFreeBuffer(RowSet);
	MAPIFreeBuffer(SPropTagArray);
	mapitest_print_retval_clean(mt, "NspiGetMatches", retval);
	if (retval != MAPI_E_SUCCESS) {
		talloc_free(mem_ctx);
		return false;
	}

	/* Query the rows */
	SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_ENTRYID);
	RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r);
	retval = nspi_QueryRows(nspi_ctx, mem_ctx, SPropTagArray, MIds, 1, &RowSet);
	MAPIFreeBuffer(SPropTagArray);
	MAPIFreeBuffer(RowSet);
	mapitest_print_retval_clean(mt, "NspiQueryRows", retval);
	if (retval != MAPI_E_SUCCESS) {
		MAPIFreeBuffer(MIds);
		talloc_free(mem_ctx);
		return false;
	}

	talloc_free(mem_ctx);

	return true;
}
Example #19
0
/**
   \details Test #1645 NspiUpdateStat and try to sort the result
   with an, for now, unsupported sorting type SortTypePhoneticDisplayName

   \param mt pointer to the top level mapitest structure

   \return true on success, otherwise false
 */
_PUBLIC_ bool mapitest_zentyal_1645(struct mapitest *mt)
{
	TALLOC_CTX			*mem_ctx;
	struct nspi_context		*nspi_ctx;
	uint32_t        		plDelta = 1;
	enum MAPISTATUS	retval;

	/* Sanity checks */
	mem_ctx = talloc_named(NULL, 0, "mapitest_zentyal_1645");
	if (!mem_ctx) return false;

	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
	if (!nspi_ctx) return false;

	/* Update pStat with unsupported SortTypePhoneticDisplayName */
	nspi_ctx->pStat->ContainerID = 0;  // Global Access List
	nspi_ctx->pStat->CurrentRec = MID_END_OF_TABLE;
        nspi_ctx->pStat->Delta = -46;
        nspi_ctx->pStat->NumPos = 3;
        nspi_ctx->pStat->TotalRecs = 3;
	nspi_ctx->pStat->SortType = SortTypePhoneticDisplayName;

	retval = nspi_UpdateStat(nspi_ctx, mem_ctx, &plDelta);
	mapitest_print_retval_clean(mt, "NspiUpdateStat", retval);
	if (retval != MAPI_E_CALL_FAILED) {
		talloc_free(mem_ctx);
		return false;
	}

	talloc_free(mem_ctx);
	return true;
}
Example #20
0
/**
   \details Retrieve the total number of records in the global address
   list

   The Global Address List is the full list of email addresses (and other
   account-type things, such as "rooms" and distribution lists) accessible
   on the server. A user will usually have access to both a personal
   address book, and to the Global Address List. Public Address Book is
   another name for Global Address List.

   \param session pointer to the MAPI session context
   \param totalRecs pointers to the total number of records in the
   global address list returned

   \return MAPI_E_SUCCESS on success, otherwise MAPI error.

   \note Developers may also call GetLastError() to retrieve the last
   MAPI error code. Possible MAPI error codes are:
   -# MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
   -# MAPI_E_SESSION_LIMIT: No session has been opened on the provider
   -# MAPI_E_INVALID_PARAMETER: if a function parameter is invalid
   -# MAPI_E_CALL_FAILED: A network problem was encountered during the
     transaction
 */
_PUBLIC_ enum MAPISTATUS GetGALTableCount(struct mapi_session *session,
					  uint32_t *totalRecs)
{
	TALLOC_CTX		*mem_ctx;
	struct nspi_context	*nspi;
	enum MAPISTATUS		retval;
	struct PropertyRowSet_r	*rowset;

	/* Sanity Checks */
	OPENCHANGE_RETVAL_IF(!session, MAPI_E_SESSION_LIMIT, NULL);
	OPENCHANGE_RETVAL_IF(!session->nspi, MAPI_E_SESSION_LIMIT, NULL);
	OPENCHANGE_RETVAL_IF(!session->nspi->ctx, MAPI_E_SESSION_LIMIT, NULL);

	mem_ctx = talloc_named(session, 0, "GetGALTableCount");
	nspi = (struct nspi_context *) session->nspi->ctx;

	nspi->pStat->CurrentRec = 0;
	nspi->pStat->Delta = 0;
	nspi->pStat->NumPos = 0;
	nspi->pStat->TotalRecs = 0xffffffff;

	rowset = talloc_zero(mem_ctx, struct PropertyRowSet_r);
	retval = nspi_QueryRows(nspi, mem_ctx, NULL, NULL, 0, &rowset);

	*totalRecs = nspi->pStat->TotalRecs;
	
	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
	talloc_free(mem_ctx);
	
	return MAPI_E_SUCCESS;
}
Example #21
0
static int mit_samba_update_pac_data(struct mit_samba_context *ctx,
				     hdb_entry_ex *client,
				     DATA_BLOB *pac_data,
				     DATA_BLOB *logon_data)
{
	TALLOC_CTX *tmp_ctx;
	DATA_BLOB *logon_blob;
	krb5_error_code code;
	NTSTATUS nt_status;
	krb5_pac pac = NULL;
	int ret;

	/* The user account may be set not to want the PAC */
    	if (client && !samba_princ_needs_pac(client)) {
		return EINVAL;
	}

	tmp_ctx = talloc_named(ctx, 0, "mit_samba_update_pac_data context");
	if (!tmp_ctx) {
		return ENOMEM;
	}

	logon_blob = talloc_zero(tmp_ctx, DATA_BLOB);
	if (!logon_blob) {
		ret = ENOMEM;
		goto done;
	}

	code = krb5_pac_parse(ctx->context,
			      pac_data->data, pac_data->length, &pac);
	if (code) {
		ret = EINVAL;
		goto done;
	}

	nt_status = samba_kdc_update_pac_blob(tmp_ctx, ctx->context,
					      &pac, logon_blob);
	if (!NT_STATUS_IS_OK(nt_status)) {
		DEBUG(0, ("Building PAC failed: %s\n",
			  nt_errstr(nt_status)));
		ret = EINVAL;
		goto done;
	}

	logon_data->data = (uint8_t *)malloc(logon_blob->length);
	if (!logon_data->data) {
		ret = ENOMEM;
		goto done;
	}
	memcpy(logon_data->data, logon_blob->data, logon_blob->length);
	logon_data->length = logon_blob->length;

	ret = 0;

done:
	if (pac) krb5_pac_free(ctx->context, pac);
	talloc_free(tmp_ctx);
	return ret;
}
Example #22
0
/**
   \details Initiates a session between a client and the NSPI server.

   \param parent_ctx pointer to the memory context
   \param p pointer to the DCERPC pipe
   \param cred pointer to the user credentials
   \param codepage the code to set in the STAT structure
   \param language the language to set in the STAT structure
   \param method the method to set in the STAT structure

   \return Allocated pointer to a nspi_context structure on success,
   otherwise NULL
 */
_PUBLIC_ struct nspi_context *nspi_bind(TALLOC_CTX *parent_ctx, 
					struct dcerpc_pipe *p,
					struct cli_credentials *cred, 
					uint32_t codepage,
					uint32_t language, 
					uint32_t method)
{
	TALLOC_CTX		*mem_ctx;
	struct NspiBind		r;
	NTSTATUS		status;
	enum MAPISTATUS		retval;
	struct nspi_context	*ret;
	struct GUID		guid;

	/* Sanity checks */
	if (!p) return NULL;
	if (!cred) return NULL;

	ret = talloc(parent_ctx, struct nspi_context);
	ret->rpc_connection = p;
	ret->mem_ctx = parent_ctx;
	ret->cred = cred;
	ret->version = 0;

	/* Sanity Checks */
	if (!(ret->pStat = nspi_set_STAT((TALLOC_CTX *) ret, codepage, language, method))) {
		talloc_free(ret);
		return NULL;
	}

	mem_ctx = talloc_named(parent_ctx, 0, __FUNCTION__);

	r.in.dwFlags = 0;

	r.in.pStat = ret->pStat;
	r.in.pStat->ContainerID = 0x0;

	r.in.mapiuid = talloc(mem_ctx, struct GUID);
	memset(r.in.mapiuid, 0, sizeof(struct GUID));
	
	r.out.mapiuid = &guid;

	r.in.mapiuid = talloc(mem_ctx, struct GUID);
	memset(r.in.mapiuid, 0, sizeof(struct GUID));

	r.out.handle = &ret->handle;

	status = dcerpc_NspiBind_r(p->binding_handle, mem_ctx, &r);
	retval = r.out.result;
	if ((!NT_STATUS_IS_OK(status)) || (retval != MAPI_E_SUCCESS)) {
		talloc_free(ret);
		talloc_free(mem_ctx);
		return NULL;
	}
	
	talloc_free(mem_ctx);
	return ret;
}
Example #23
0
} END_TEST


// ^ unit tests ---------------------------------------------------------------

// v suite definition ---------------------------------------------------------

static void tc_mysql_util_setup(void)
{
	mem_ctx = talloc_named(NULL, 0, __FUNCTION__);
}
Example #24
0
/**
 * Retrieve server specific information
 */
static bool mapitest_get_server_info(struct mapitest *mt,
				     char *opt_profname,
				     const char *password,
				     bool opt_dumpdata,
				     const char *opt_debug)
{
	TALLOC_CTX		*mem_ctx;
	enum MAPISTATUS		retval;
	struct emsmdb_info	*info = NULL;
	struct mapi_session	*session = NULL;

	/* if the user explicitly asked for just the no-server tests 
	to be run, then we're done here */
	if (mt->no_server == true) return 0;

	mem_ctx = talloc_named(NULL, 0, "mapitest_get_server_info");

	/* if no profile was specified, get the default */
	if (!opt_profname) {
		retval = GetDefaultProfile(mt->mapi_ctx, &opt_profname);
		if (retval != MAPI_E_SUCCESS) {
			mapi_errstr("GetDefaultProfile", retval);
			talloc_free(mem_ctx);
			return false;
		}
	}
		

	/* debug options */
	SetMAPIDumpData(mt->mapi_ctx, opt_dumpdata);

	if (opt_debug) {
		SetMAPIDebugLevel(mt->mapi_ctx, atoi(opt_debug));
	}

	retval = MapiLogonEx(mt->mapi_ctx, &session, opt_profname, password);
	MAPIFreeBuffer(opt_profname);
	talloc_free(mem_ctx);
	if (retval != MAPI_E_SUCCESS) {
		mapi_errstr("MapiLogonEx", retval);
		return false;
	}
	mt->session = session;
	mt->profile = session->profile;

	info = emsmdb_get_info(session);
	memcpy(&mt->info, info, sizeof (struct emsmdb_info));

	/* extract org and org_unit from info.mailbox */
	mt->org = x500_get_dn_element(mt->mem_ctx, info->szDNPrefix, "/o=");
	mt->org_unit = x500_get_dn_element(mt->mem_ctx, info->szDNPrefix, "/ou=");
	
	return true;
}
Example #25
0
/**
   \details Test the NspiSeekEntries RPC operation (0x04)

   \param mt pointer on the top-level mapitest structure

   \return true on success, otherwise false
 */
_PUBLIC_ bool mapitest_nspi_SeekEntries(struct mapitest *mt)
{
	TALLOC_CTX		*mem_ctx;
	enum MAPISTATUS		retval;
	struct nspi_context	*nspi_ctx;
	struct PropertyValue_r	pTarget;
	struct SPropTagArray	*pPropTags;
	struct PropertyRowSet_r		*RowSet;
	struct emsmdb_context	*emsmdb;
	bool			ret = true;

	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_SeekEntries");
	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;

	emsmdb = (struct emsmdb_context *) mt->session->emsmdb->ctx;
	RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r);
	
	pTarget.ulPropTag = PR_DISPLAY_NAME;
	pTarget.dwAlignPad = 0x0;
	pTarget.value.lpszA = emsmdb->info.szDisplayName;

	pPropTags = set_SPropTagArray(mem_ctx, 0x1, PR_ACCOUNT);
	retval = nspi_SeekEntries(nspi_ctx, mem_ctx, SortTypeDisplayName, &pTarget, pPropTags, NULL, &RowSet);
	if (retval != MAPI_E_SUCCESS) {
		ret = false;
	}

	mapitest_print_retval_clean(mt, "NspiSeekEntries", retval);
	MAPIFreeBuffer(RowSet);
	MAPIFreeBuffer(pPropTags);

	RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r);

	pTarget.ulPropTag = PR_DISPLAY_NAME_UNICODE;
	pTarget.dwAlignPad = 0x0;
	pTarget.value.lpszA = emsmdb->info.szDisplayName;

	pPropTags = set_SPropTagArray(mem_ctx, 0x1, PR_ACCOUNT);
	retval = nspi_SeekEntries(nspi_ctx, mem_ctx, SortTypeDisplayName, &pTarget, pPropTags, NULL, &RowSet);
	if (retval != MAPI_E_SUCCESS) {
		ret = false;
	}

	mapitest_print_retval_clean(mt, "NspiSeekEntries", retval);
	MAPIFreeBuffer(RowSet);
	MAPIFreeBuffer(pPropTags);

	talloc_free(mem_ctx);

	return ret;
}
Example #26
0
/**
   \details Release an object on the server

   The function releases the object \a obj on the server.

   \param obj the object to release

   \return MAPI_E_SUCCESS on success, otherwise MAPI error.

   \note Developers may also call GetLastError() to retrieve the last
   MAPI error code. Possible MAPI error codes are:
   - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
   - MAPI_E_CALL_FAILED: A network problem was encountered during the
     transaction

   \sa GetLastError
*/
_PUBLIC_ enum MAPISTATUS Release(mapi_object_t *obj)
{
	struct mapi_request	*mapi_request;
	struct mapi_response	*mapi_response;
	struct EcDoRpc_MAPI_REQ *mapi_req;
	struct mapi_session	*session;
	NTSTATUS		status;
	TALLOC_CTX		*mem_ctx;
	uint32_t		size = 0;
	enum MAPISTATUS		retval;
	uint8_t 		logon_id = 0;

	mapi_response = 0;

	/* Sanity checks */
	session = mapi_object_get_session(obj);
	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);

	if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS)
		return retval;

	mem_ctx = talloc_named(session, 0, "Release");

	/* Fill the MAPI_REQ request */
	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
	mapi_req->opnum = op_MAPI_Release;
	mapi_req->logon_id = logon_id;
	mapi_req->handle_idx = 0;
	size += 5;

	/* Fill the mapi_request structure */
	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
	mapi_request->mapi_len = size + sizeof (uint32_t);
	mapi_request->length = (uint16_t)size;
	mapi_request->mapi_req = mapi_req;
	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
	mapi_request->handles[0] = mapi_object_get_handle(obj);

	status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response);
	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);

	if (mapi_response->mapi_repl) {
		OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
	}

	talloc_free(mapi_response);
	talloc_free(mem_ctx);

	errno = 0;
	return MAPI_E_SUCCESS;
}
Example #27
0
/**
   \details Returns values of one or more properties for an object
 
   The function takes a pointer on the object obj, a MAPITAGS array
   specified in mapitags, and the count of properties.  The function
   returns associated values within the SPropValue values pointer.

   The array of MAPI property tags can be filled with both known and
   named properties.

   \param obj the object to get properties on
   \param flags Flags for behaviour; can be bit-OR of MAPI_UNICODE and
      MAPI_PROPS_SKIP_NAMEDID_CHECK constants
   \param SPropTagArray an array of MAPI property tags
   \param lpProps the result of the query
   \param PropCount the count of property tags

   \return MAPI_E_SUCCESS on success, otherwise MAPI error.

   \note Developers may also call GetLastError() to retrieve the last
   MAPI error code. Possible MAPI error codes are:
   - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
   - MAPI_E_INVALID_PARAMETER: obj or SPropTagArray are null, or the
   session context could not be obtained
   - MAPI_E_CALL_FAILED: A network problem was encountered during the
     transaction

   \sa SetProps, GetPropList, GetPropsAll, DeleteProps, GetLastError
*/
_PUBLIC_ enum MAPISTATUS GetProps(mapi_object_t *obj,
				  uint32_t flags,
				  struct SPropTagArray *SPropTagArray,
				  struct SPropValue **lpProps, 
				  uint32_t *PropCount)
{
	struct mapi_context	*mapi_ctx;
	struct mapi_request	*mapi_request;
	struct mapi_response	*mapi_response;
	struct EcDoRpc_MAPI_REQ	*mapi_req;
	struct GetProps_req	request;
	struct mapi_session	*session;
	struct mapi_nameid	*nameid;
	struct SPropTagArray	properties;
	struct SPropTagArray	*SPropTagArray2 = NULL;
	NTSTATUS		status;
	enum MAPISTATUS		retval;
	enum MAPISTATUS		mapistatus;
	uint32_t		size;
	TALLOC_CTX		*mem_ctx;
	bool			named = false;
	uint8_t			logon_id;

	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL);

	session = mapi_object_get_session(obj);
	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);

	mapi_ctx = session->mapi_ctx;
	OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);

	if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS)
		return retval;

	mem_ctx = talloc_named(session, 0, "GetProps");

	/* Named property mapping */
	nameid = mapi_nameid_new(mem_ctx);
	if (!(flags & MAPI_PROPS_SKIP_NAMEDID_CHECK)) {
		retval = mapi_nameid_lookup_SPropTagArray(nameid, SPropTagArray);
		if (retval == MAPI_E_SUCCESS) {
			named = true;
			SPropTagArray2 = talloc_zero(mem_ctx, struct SPropTagArray);
			retval = GetIDsFromNames(obj, nameid->count, nameid->nameid, 0, &SPropTagArray2);
			OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);		
			mapi_nameid_map_SPropTagArray(nameid, SPropTagArray, SPropTagArray2);
			MAPIFreeBuffer(SPropTagArray2);
		}
Example #28
0
/**
  \details Get FMID by mapistore URI.

  \param ictx valid pointer to indexing context
  \param username samAccountName for current user
  \param uri mapistore URI or pattern to search for
  \param partia if true, uri is pattern to search for
  \param fmidp pointer to valid location to store found FMID
  \param soft_deletedp Pointer to bool var to return Soft Deleted state

  \return MAPISTORE_SUCCESS on success
	  MAPISTORE_ERR_NOT_FOUND if uri does not exists in DB
	  MAPISTORE_ERR_NOT_INITIALIZED if ictx pointer is invalid (NULL)
	  MAPISTORE_ERR_INVALID_PARAMETER in case other parameters are not valid
	  MAPISTORE_ERR_DATABASE_OPS in case of MySQL error
 */
static enum mapistore_error mysql_record_get_fmid(struct indexing_context *ictx,
						  const char *username,
						  const char *uri,
						  bool partial,
						  uint64_t *fmidp,
						  bool *soft_deletedp)
{
	enum MYSQLRESULT	ret;
	char			*sql, *uri_like;
	MYSQL_RES		*res;
	MYSQL_ROW		row;
	TALLOC_CTX		*mem_ctx;

	// Sanity checks
	MAPISTORE_RETVAL_IF(!ictx, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
	MAPISTORE_RETVAL_IF(!username, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
	MAPISTORE_RETVAL_IF(!uri, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
	MAPISTORE_RETVAL_IF(!fmidp, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
	MAPISTORE_RETVAL_IF(!soft_deletedp, MAPISTORE_ERR_INVALID_PARAMETER, NULL);

	mem_ctx = talloc_named(NULL, 0, "mysql_record_get_fmid");

	sql = talloc_asprintf(mem_ctx,
		"SELECT fmid, soft_deleted FROM "INDEXING_TABLE" "
		"WHERE username = '******'", _sql(mem_ctx, username));
	if (partial) {
		uri_like = talloc_strdup(mem_ctx, uri);
		string_replace(uri_like, '*', '%');
		sql = talloc_asprintf_append(sql, " AND url LIKE '%s'",
					     _sql(mem_ctx, uri_like));
	} else {
		sql = talloc_asprintf_append(sql, " AND url = '%s'",
					     _sql(mem_ctx, uri));
	}

	ret = select_without_fetch(MYSQL(ictx), sql, &res);
	MAPISTORE_RETVAL_IF(ret == MYSQL_NOT_FOUND, MAPISTORE_ERR_NOT_FOUND, mem_ctx);
	MAPISTORE_RETVAL_IF(ret != MYSQL_SUCCESS, MAPISTORE_ERR_DATABASE_OPS, mem_ctx);

	row = mysql_fetch_row(res);

	*fmidp = strtoull(row[0], NULL, 0);
	*soft_deletedp = strtoull(row[1], NULL, 0) == 1;

	mysql_free_result(res);
	talloc_free(mem_ctx);

	return MAPISTORE_SUCCESS;
}
Example #29
0
/**
   \details Returns the name of an NSPI server

   \param mapi_ctx pointer to the MAPI context
   \param session pointer to the MAPI session context
   \param server the Exchange server address (IP or FQDN)
   \param userDN optional user mailbox DN
   \param dsa pointer to a new dsa (return value), containing
      a valid allocated string on success, otherwise NULL

   \return MAPI_E_SUCCESS on success, otherwise a MAPI error and
   serverFQDN content set to NULL.

   \note The string returned can either be RfrGetNewDSA one on
   success, or a copy of the server's argument one on failure. If no
   server string is provided, NULL is returned.

   It is up to the developer to free the returned string when
   not needed anymore.
 */
_PUBLIC_ enum MAPISTATUS RfrGetNewDSA(struct mapi_context *mapi_ctx,
                                      struct mapi_session *session,
                                      const char *server,
                                      const char *userDN,
                                      char **dsa)
{
    NTSTATUS		status;
    TALLOC_CTX		*mem_ctx;
    struct mapi_profile	*profile;
    struct RfrGetNewDSA	r;
    struct dcerpc_pipe	*pipe;
    char			*binding;
    char			*ppszServer = NULL;

    /* Sanity Checks */
    if (!mapi_ctx) return MAPI_E_NOT_INITIALIZED;
    if (!mapi_ctx->session) return MAPI_E_NOT_INITIALIZED;

    mem_ctx = talloc_named(session, 0, "RfrGetNewDSA");
    profile = session->profile;

    binding = build_binding_string(mapi_ctx, mem_ctx, server, profile);
    status = provider_rpc_connection(mem_ctx, &pipe, binding, profile->credentials, &ndr_table_exchange_ds_rfr, mapi_ctx->lp_ctx);
    talloc_free(binding);

    if (!NT_STATUS_IS_OK(status)) {
        talloc_free(mem_ctx);
        return ecRpcFailed;
    }


    r.in.ulFlags = 0x0;
    r.in.pUserDN = userDN ? userDN : "";
    r.in.ppszUnused = NULL;
    r.in.ppszServer = (const char **) &ppszServer;

    status = dcerpc_RfrGetNewDSA_r(pipe->binding_handle, mem_ctx, &r);
    if ((!NT_STATUS_IS_OK(status) || !r.out.ppszServer || !*r.out.ppszServer) && server) {
        ppszServer = talloc_strdup((TALLOC_CTX *)session, server);
    } else {
        ppszServer = (char *)talloc_steal((TALLOC_CTX *)session, *r.out.ppszServer);
    }

    talloc_free(mem_ctx);

    *dsa = ppszServer;

    return MAPI_E_SUCCESS;
}
Example #30
0
/**
   \details Initialize OCPF context

   Initialize ocpf context and allocate memory for internal structures

   \return OCPF_SUCCESS on success, otherwise OCPF_ERROR

   \sa ocpf_release, ocpf_parse
 */
_PUBLIC_ int ocpf_init(void)
{
	TALLOC_CTX	*mem_ctx;
	
	OCPF_RETVAL_IF(ocpf, NULL, OCPF_INITIALIZED, NULL);

	mem_ctx = talloc_named(NULL, 0, "ocpf");
	ocpf = talloc_zero(mem_ctx, struct ocpf);
	ocpf->mem_ctx = mem_ctx;

	ocpf->context = talloc_zero(mem_ctx, struct ocpf_context);
	ocpf->free_id = talloc_zero(mem_ctx, struct ocpf_freeid);
	ocpf->last_id = 1;

	return OCPF_SUCCESS;
}