예제 #1
0
/**
   \details Initialize mapistore named properties MySQL backend

   \param mem_ctx pointer to the memory context
   \param lp_ctx pointer to the loadparm context
   \param nprops_ctx pointer on pointer to the namedprops context to
   return

   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
 */
enum mapistore_error mapistore_namedprops_mysql_init(TALLOC_CTX *mem_ctx,
						     struct loadparm_context *lp_ctx,
						     struct namedprops_context **nprops_ctx)
{
	enum mapistore_error		retval;
	struct namedprops_context	*nprops = NULL;
	struct namedprops_mysql_params	parms;
	MYSQL				*conn = NULL;

	/* Sanity checks */
	MAPISTORE_RETVAL_IF(!lp_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);
	MAPISTORE_RETVAL_IF(!nprops_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL);

	/* Retrieve smb.conf arguments */
	retval = mapistore_namedprops_mysql_parameters(lp_ctx, &parms);
	if (retval != MAPISTORE_SUCCESS) {
		DEBUG(0, ("[%s:%d] ERROR: parsing MySQL named properties "
			  "parametric option failed with %s\n",
			  __FUNCTION__, __LINE__, mapistore_errstr(retval)));
		MAPISTORE_RETVAL_ERR(retval, NULL);
	}

	/* Establish MySQL connection */
	if (parms.sock) {
		// FIXME
		DEBUG(0, ("Not implemented connect through unix socket to mysql"));
	} else {
		char *connection_string = connection_string_from_parameters(mem_ctx, &parms);
		MAPISTORE_RETVAL_IF(!connection_string, MAPISTORE_ERR_NOT_INITIALIZED, NULL);
		create_connection(connection_string, &conn);
	}
	MAPISTORE_RETVAL_IF(!conn, MAPISTORE_ERR_NOT_INITIALIZED, NULL);

	/* Initialize the database */
	if (!is_schema_created(conn) || is_database_empty(conn)) {
		retval = initialize_database(conn, parms.data);
		MAPISTORE_RETVAL_IF(retval != MAPISTORE_SUCCESS, retval, NULL);
	}

	/* Create context */
	nprops = talloc_zero(mem_ctx, struct namedprops_context);
	MAPISTORE_RETVAL_IF(!nprops, MAPISTORE_ERR_NO_MEMORY, NULL);

	nprops->backend_type = NAMEDPROPS_BACKEND_MYSQL;

	nprops->create_id = create_id;
	nprops->get_mapped_id = get_mapped_id;
	nprops->get_nameid = get_nameid;
	nprops->get_nameid_type = get_nameid_type;
	nprops->next_unused_id = next_unused_id;
	nprops->transaction_commit = transaction_commit;
	nprops->transaction_start = transaction_start;

	nprops->data = conn;
	talloc_set_destructor(nprops, mapistore_namedprops_mysql_destructor);

	*nprops_ctx = nprops;
	return MAPISTORE_SUCCESS;
}
예제 #2
0
/**
   \details EcDoRpc ModifyPermissions (0x40) Rop. This operation
   gets the GUID of a public folder's per-user information.

   \param mem_ctx pointer to the memory context
   \param emsmdbp_ctx pointer to the emsmdb provider context
   \param mapi_req pointer to the GetPerUserLongTermIds EcDoRpc_MAPI_REQ
   \param mapi_repl pointer to the GetPerUserLongTermIds EcDoRpc_MAPI_REPL
   \param handles pointer to the MAPI handles array
   \param size pointer to the mapi_response size to update

   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 */
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopModifyPermissions(TALLOC_CTX *mem_ctx,
						      struct emsmdbp_context *emsmdbp_ctx,
						      struct EcDoRpc_MAPI_REQ *mapi_req,
						      struct EcDoRpc_MAPI_REPL *mapi_repl,
						      uint32_t *handles, uint16_t *size)
{
	enum MAPISTATUS			retval;
	enum mapistore_error		mretval;
	struct mapi_handles		*folder;
	struct emsmdbp_object		*folder_object;
	void				*data = NULL;
	uint32_t			handle;
	struct ModifyPermissions_req	*request;


	OC_DEBUG(4, "exchange_emsmdb: [OXCSTOR] ModifyPermissions (0x40)\n");

	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);

	mapi_repl->opnum = mapi_req->opnum;
	mapi_repl->handle_idx = mapi_req->handle_idx;
	mapi_repl->error_code = MAPI_E_SUCCESS;

	/* Ensure handle references a folder object */
	handle = handles[mapi_req->handle_idx];
	retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &folder);
	if (retval) {
		mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
		OC_DEBUG(5, "  handle (%x) not found: %x\n", handle, mapi_req->handle_idx);
		goto end;
	}

	retval = mapi_handles_get_private_data(folder, &data);
	if (retval || !data) {
		mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
		OC_DEBUG(5, "  handle data not found, idx = %x\n", mapi_req->handle_idx);
		goto end;
	}

	folder_object = (struct emsmdbp_object *) data;
	if (folder_object->type != EMSMDBP_OBJECT_FOLDER) {
		mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
		OC_DEBUG(5, "  unhandled object type: %d\n", folder_object->type);
		goto end;
	}

	request = &mapi_req->u.mapi_ModifyPermissions;

	if (emsmdbp_is_mapistore(folder_object)) {
		mretval = mapistore_folder_modify_permissions(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(folder_object),
							      folder_object->backend_object, request->rowList.ModifyFlags,
							      request->rowList.ModifyCount, request->rowList.PermissionsData);
		if (mretval != MAPISTORE_SUCCESS) {
			OC_DEBUG(5, "mapistore_folder_modify_permissions: %s\n", mapistore_errstr(mretval));
			mapi_repl->error_code = mapistore_error_to_mapi(mretval);
		}
	}
	else {
		mapi_repl->error_code = MAPI_E_NOT_FOUND;
	}

end:
	*size += libmapiserver_RopModifyPermissions_size(mapi_repl);

	return MAPI_E_SUCCESS;
}
예제 #3
0
/**
   \details EcDoRpc DeleteFolder (0x1d) Rop. This operation deletes a
   folder on the remote server.

   \param mem_ctx pointer to the memory context
   \param emsmdbp_ctx pointer to the emsmdb provider context
   \param mapi_req pointer to the DeleteFolder EcDoRpc_MAPI_REQ
   structure
   \param mapi_repl pointer to the DeleteFolder EcDoRpc_MAPI_REPL
   structure
   \param handles pointer to the MAPI handles array
   \param size pointer to the mapi_response size to update
   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 */
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopDeleteFolder(TALLOC_CTX *mem_ctx,
						 struct emsmdbp_context *emsmdbp_ctx,
						 struct EcDoRpc_MAPI_REQ *mapi_req,
						 struct EcDoRpc_MAPI_REPL *mapi_repl,
						 uint32_t *handles, uint16_t *size)
{
	enum MAPISTATUS		retval;
	enum mapistore_error	ret;
	struct mapi_handles	*rec = NULL;
	uint32_t		handle;
	void			*handle_priv_data;
	struct emsmdbp_object	*handle_object = NULL;

	OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] DeleteFolder (0x1d)\n");

	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);

	/* Initialize default empty DeleteFolder reply */
	mapi_repl->opnum = mapi_req->opnum;
	mapi_repl->error_code = MAPI_E_SUCCESS;
	mapi_repl->handle_idx = mapi_req->handle_idx;

	/* TODO: factor this out to be convenience API */
	/* Convert the handle index into a handle, and then get the folder id */
	handle = handles[mapi_req->handle_idx];
	retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
	OPENCHANGE_RETVAL_IF(retval, retval, NULL);

	mapi_handles_get_private_data(rec, &handle_priv_data);
	handle_object = (struct emsmdbp_object *)handle_priv_data;
	if (!handle_object) {
		OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] DeleteFolder null object\n");
		mapi_repl->error_code = MAPI_E_NO_SUPPORT;
		return MAPI_E_SUCCESS;
	}

	if (handle_object->type != EMSMDBP_OBJECT_FOLDER) {
		OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] DeleteFolder wrong object type: 0x%x\n", handle_object->type);
		mapi_repl->error_code = MAPI_E_NO_SUPPORT;
		return MAPI_E_SUCCESS;
	}

	retval = MAPI_E_SUCCESS;
	ret = emsmdbp_folder_delete(emsmdbp_ctx, handle_object, mapi_req->u.mapi_DeleteFolder.FolderId, mapi_req->u.mapi_DeleteFolder.DeleteFolderFlags);
	if (ret == MAPISTORE_ERR_EXIST) {
		mapi_repl->u.mapi_DeleteFolder.PartialCompletion = true;
	} else if (ret != MAPISTORE_SUCCESS) {
		OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] DeleteFolder failed to delete fid 0x%.16"PRIx64" (%s)",
			 mapi_req->u.mapi_DeleteFolder.FolderId, mapistore_errstr(ret));
		if (ret == MAPISTORE_ERR_DENIED) {
			retval = MAPI_E_NO_ACCESS;
		} else {
			retval = MAPI_E_NOT_FOUND;
		}
	}
	mapi_repl->error_code = retval;

	*size += libmapiserver_RopDeleteFolder_size(mapi_repl);

	return MAPI_E_SUCCESS;
}
예제 #4
0
/**
   \details EcDoRpc RegisterNotification (0x29) Rop. This operation
   subscribes for specified notifications on the server and returns a
   handle of the subscription to the client.

   \param mem_ctx pointer to the memory context
   \param emsmdbp_ctx pointer to the emsmdb provider context
   \param mapi_req pointer to the RegisterNotification
   EcDoRpc_MAPI_REQ structure
   \param mapi_repl pointer to the RegisterNotification
   EcDoRpc_MAPI_REPL structure
   \param handles pointer to the MAPI handles array
   \param size pointer to the mapi_response size to update

   \return MAPI_E_SUCCESS on success, otherwise MAPI error
 */
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopRegisterNotification(TALLOC_CTX *mem_ctx,
							 struct emsmdbp_context *emsmdbp_ctx,
							 struct EcDoRpc_MAPI_REQ *mapi_req,
							 struct EcDoRpc_MAPI_REPL *mapi_repl,
							 uint32_t *handles, uint16_t *size)
{
	enum MAPISTATUS		retval;
	enum mapistore_error	mretval;
	struct emsmdbp_object	*parent_object;
	struct emsmdbp_object	*subscription_object;
	struct mapi_handles	*parent_rec = NULL;
	struct mapi_handles	*subscription_rec = NULL;
	uint32_t		handle;
        void                    *data;
	uint16_t		flags;
	uint64_t		fid = 0;
	uint64_t		mid = 0;

	OC_DEBUG(4, "exchange_emsmdb: [OXCNOTIF] RegisterNotification (0x29)\n");

	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);

	mapi_repl->opnum = mapi_req->opnum;
	mapi_repl->handle_idx = mapi_req->u.mapi_RegisterNotification.handle_idx;
	mapi_repl->error_code = MAPI_E_SUCCESS;

	handle = handles[mapi_req->handle_idx];
	retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent_rec);
	if (retval) {
		mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
		OC_DEBUG(5, "  handle (%x) not found: %x\n", handle, mapi_req->handle_idx);
		goto end;
	}

        retval = mapi_handles_get_private_data(parent_rec, &data);
	if (retval) {
		mapi_repl->error_code = retval;
		OC_DEBUG(5, "  handle data not found, idx = %x\n", mapi_req->handle_idx);
		goto end;
	}

	parent_object = (struct emsmdbp_object *) data;

	retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &subscription_rec);
	if (retval) {
		mapi_repl->error_code = retval;
		goto end;
	}
	/* Notification subscriptions */
	flags = mapi_req->u.mapi_RegisterNotification.NotificationFlags;
	if (mapi_req->u.mapi_RegisterNotification.WantWholeStore) {
		flags |= sub_WholeStore;
	} else {
		fid = mapi_req->u.mapi_RegisterNotification.FolderId.ID;
		mid = mapi_req->u.mapi_RegisterNotification.MessageId.ID;
	}

	mretval = mapistore_notification_subscription_add(emsmdbp_ctx->mstore_ctx,
							  emsmdbp_ctx->session_uuid,
							  subscription_rec->handle,
							  flags, fid, mid, 0, NULL);
	if (mretval != MAPISTORE_SUCCESS) {
		/* MS-OXCROPS section 2.2.14.1 does not describe a
		 * failure response buffer for RegisterNotification
		 * Rop */
		OC_DEBUG(0, "Failed to add subscription: %s", mapistore_errstr(mretval));
	}

	handles[mapi_repl->handle_idx] = subscription_rec->handle;

	/* Create emsmdbp subscription object */
	subscription_object = emsmdbp_object_subscription_init(subscription_rec, emsmdbp_ctx, parent_object);
	if (!subscription_object) {
		OC_DEBUG(0, "Unable to create subscription object");
	}
	mapi_handles_set_private_data(subscription_rec, subscription_object);
	subscription_object->object.subscription->handle = subscription_rec->handle;

end:
	*size += libmapiserver_RopRegisterNotification_size();

	return MAPI_E_SUCCESS;
}
예제 #5
0
int main(int argc, const char *argv[])
{
TALLOC_CTX			*mem_ctx;
int				retval;
struct mapistore_context		*mstore_ctx;
struct loadparm_context			*lp_ctx;
struct backend_context			*context;
struct backend_context_list *context_list;
poptContext			pc;
int				opt, i;
const char			*opt_debug = NULL;
uint32_t			context_id = 0;
void				*root_folder;

enum { OPT_DEBUG=1000 };

struct poptOption long_options[] = {
		POPT_AUTOHELP
		{ "debuglevel",	'd', POPT_ARG_STRING, NULL, OPT_DEBUG,	"set the debug level", NULL },
		{ NULL, 0, 0, NULL, 0, NULL, NULL }
	};

mem_ctx = talloc_named(NULL, 0, "mapistore_EL_test");
lp_ctx = loadparm_init_global(true);
setup_logging(NULL, DEBUG_STDOUT);
	
pc = poptGetContext("mapistore_test", argc, argv, long_options, 0);
while ((opt = poptGetNextOpt(pc)) != -1) 
  {
	switch (opt) 
	  {
		case OPT_DEBUG:
			opt_debug = poptGetOptArg(pc);
			break;
		}
	}

poptFreeContext(pc);

if (opt_debug) 
	lpcfg_set_cmdline(lp_ctx, "log level", opt_debug);
	
	
printf("Mapping path             : ");
retval = mapistore_set_mapping_path("/tmp");
if (retval != MAPISTORE_SUCCESS) 
  {
	printf("ERROR: %s\n", mapistore_errstr(retval));
	exit (1);
	}
printf("OK\n");

printf("Initialise mapistore\n");
mstore_ctx = mapistore_init(mem_ctx, lp_ctx, NULL);
if (!mstore_ctx) 
  {
	printf("ERROR: %s\n", mapistore_errstr(retval));
	exit (1);
	}

printf("Adding a context (INBOX)\n");
retval = mapistore_add_context(mstore_ctx, "Administrator", "EasyLinux://INBOX", -1, &context_id, &root_folder);
if (retval != MAPISTORE_SUCCESS) 
  {
	printf("ERROR: %s\n", mapistore_errstr(retval));
	exit (1);
	}
  //DEBUG(0,("    Root folder: %s",(char *)root_folder) );
/*

  DEBUG(0,("Delete context             : "));
	retval = mapistore_del_context(mstore_ctx, context_id);
	DEBUG(0,("OK\n"));
*/	
	DEBUG(0,("Release                     : "));
	retval = mapistore_release(mstore_ctx);
	if (retval != MAPISTORE_SUCCESS) {
		DEBUG(0, ("%s\n", mapistore_errstr(retval)));
		exit (1);
	}
	DEBUG(0,("OK\n"));

	return 0;
}
예제 #6
0
int main(int argc, const char *argv[])
{
	TALLOC_CTX				*mem_ctx;
	enum mapistore_error			retval;
	poptContext				pc;
	int					opt;
	struct loadparm_context			*lp_ctx;
	struct ocnotify_private			ocnotify;
	struct mapistore_notification_context	*ctx;
	const char				*opt_server = NULL;
	const char				*opt_newmail = NULL;
	bool					opt_list_server = false;
	bool					ret;
	int					verbosity = 0;
	char					*debuglevel = NULL;
	const char				*sep = NULL;
	uint32_t				i = 0;
	uint32_t				count = 0;
	const char				**hosts = NULL;

	enum { OPT_USERNAME=1000, OPT_BACKEND, OPT_DSTFOLDER, OPT_SEPARATOR, OPT_SERVER, OPT_SERVER_LIST, OPT_FLUSH, OPT_NEWMAIL, OPT_VERBOSE };

	struct poptOption long_options[] = {
		POPT_AUTOHELP
		{ "username", 'U', POPT_ARG_STRING, NULL, OPT_USERNAME, "set the username", NULL },
		{ "backend", 'b', POPT_ARG_STRING, NULL, OPT_BACKEND, "set the mapistore backend", NULL },
		{ "dstfolder", 0, POPT_ARG_STRING, NULL, OPT_DSTFOLDER, "set the destination folder", NULL },
		{ "sep", 0, POPT_ARG_STRING, NULL, OPT_SEPARATOR, "set the folder separator", NULL },
		{ "server", 'H', POPT_ARG_STRING, NULL, OPT_SERVER, "set the resolver address", NULL },
		{ "list", 0, POPT_ARG_NONE, NULL, OPT_SERVER_LIST, "list notification service instances", NULL },
		{ "flush", 0, POPT_ARG_NONE, NULL, OPT_FLUSH, "flush notification cache for the user", NULL },
		{ "newmail", 'n', POPT_ARG_STRING, NULL, OPT_NEWMAIL, "send newmail notification and specify .eml", NULL },
		{ "verbose", 'v', POPT_ARG_NONE, NULL, OPT_VERBOSE, "Add one or more -v to increase verbosity", NULL },
		{ NULL, 0, 0, NULL, 0, NULL, NULL }
	};

	mem_ctx = talloc_new(NULL);
	if (!mem_ctx) return 1;

	lp_ctx = loadparm_init_global(true);
	if (!lp_ctx) return 1;

	oc_log_init_stdout();

	memset(&ocnotify, 0, sizeof (struct ocnotify_private));

	pc = poptGetContext("ocnotify", argc, argv, long_options, 0);
	while ((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		case OPT_USERNAME:
			ocnotify.username = poptGetOptArg(pc);
			break;
		case OPT_BACKEND:
			ocnotify.backend = poptGetOptArg(pc);
			break;
		case OPT_DSTFOLDER:
			ocnotify.dstfolder = poptGetOptArg(pc);
			break;
		case OPT_SEPARATOR:
			sep = poptGetOptArg(pc);
			ocnotify.sep = sep[0];
			break;
		case OPT_SERVER:
			opt_server = poptGetOptArg(pc);
			break;
		case OPT_SERVER_LIST:
			opt_list_server = true;
			break;
		case OPT_FLUSH:
			ocnotify.flush = true;
			break;
		case OPT_NEWMAIL:
			opt_newmail = poptGetOptArg(pc);
			break;
		case OPT_VERBOSE:
			verbosity += 1;
			break;
		}
	}

	if (!ocnotify.username) {
		fprintf(stderr, "[ERR] username not specified\n");
		exit (1);
	}

	debuglevel = talloc_asprintf(mem_ctx, "%u", verbosity);
	ret = lpcfg_set_cmdline(lp_ctx, "log level", debuglevel);
	if (ret == false) {
		oc_log(OC_LOG_FATAL, "unable to set log level");
		exit (1);
	}
	talloc_free(debuglevel);

	if (opt_server) {
		ret = lpcfg_set_cmdline(lp_ctx, "mapistore:notification_cache", opt_server);
		if (ret == false) {
			oc_log(OC_LOG_FATAL, "unable to set mapistore:notification_cache");
			exit (1);
		}
	}

	retval = mapistore_notification_init(mem_ctx, lp_ctx, &ctx);
	if (retval != MAPISTORE_SUCCESS) {
		oc_log(OC_LOG_FATAL, "[ERR] unable to initialize mapistore notification");
		exit(1);
	}
	ocnotify.mstore_ctx.notification_ctx = ctx;

	/* Check if the user is registered */
	retval = mapistore_notification_resolver_exist(&ocnotify.mstore_ctx, ocnotify.username);
	if (retval) {
		oc_log(OC_LOG_ERROR, "[ERR] resolver session: '%s'", mapistore_errstr(retval));
		exit(1);
	}

	/* Retrieve server instances */
	retval = mapistore_notification_resolver_get(mem_ctx, &ocnotify.mstore_ctx, ocnotify.username,
						     &count, &hosts);
	if (retval) {
		oc_log(OC_LOG_ERROR, "[ERR] resolver record: '%s'", mapistore_errstr(retval));
		exit (1);
	}

	if (opt_list_server) {
		oc_log(0, "%d servers found for '%s'\n", count, ocnotify.username);
		for (i = 0; i < count; i++) {
			oc_log(0, "\t* %s\n", hosts[i]);
		}
	}

	/* Send mail notification */
	if (opt_newmail) {
		ocnotify_newmail(mem_ctx, ocnotify, count, hosts, opt_newmail);
	}

	/* Flush invalid data */
	if (ocnotify.flush) {
		for (i = 0; i < count; i++) {
			retval = mapistore_notification_resolver_delete(&ocnotify.mstore_ctx, ocnotify.username, hosts[i]);
		}
	}

	talloc_free(ctx);

	poptFreeContext(pc);
	talloc_free(mem_ctx);
	return 0;
}