Beispiel #1
0
/*
 * return user name of file owner
 * If the calendar name is the same as a user account name, the
 * calendar name is return; otherwise, the owner name is derived from
 * the owner of the calendar file
 */
static CSA_return_code
get_file_owner(char *calname, char **owner)
{
	struct stat info;
	struct passwd *pw;
	char buf[BUFSIZ];
	char *log;
	int res;

	if (calname == NULL || owner == NULL)
		return (CSA_E_FAILURE);

	*owner = NULL;

	if (_DtCmIsUserName(calname) == B_TRUE) {
		strcpy(buf, calname);
	} else {
		if ((log = _DtCmsGetLogFN(calname)) == NULL)
			return (CSA_E_INSUFFICIENT_MEMORY);

		res = stat(log, &info);
		free(log);

		if (res == 0) {

			if (pw = getpwuid(info.st_uid))
				strcpy(buf, pw->pw_name);
			else
				return (CSA_E_FAILURE);
		} else
			return(CSA_X_DT_E_BACKING_STORE_PROBLEM);
	}

	if (((*owner) = (char *)strdup(buf)) == NULL)
		return (CSA_E_INSUFFICIENT_MEMORY);
	else
		return (CSA_SUCCESS);
}
Beispiel #2
0
extern CSA_return_code
_DtCmsV5TransactLog(_DtCmsCalendar *cal, cms_entry *e, _DtCmsLogOps op)
{
	CSA_return_code	stat;
	char		*log;

	if ((log = _DtCmsGetLogFN(cal->calendar)) == NULL)
		 return (CSA_E_INSUFFICIENT_MEMORY);

	if (cal->hashed == B_FALSE ||
	    cal->num_entry_attrs < cal->entry_tbl->size) {
		if ((stat = _DtCmsAppendHTableByFN(log, cal->entry_tbl->size,
		    cal->entry_tbl->names, cal->types)) != CSA_SUCCESS) {
			free(log);
			return (stat);
		} else {
			cal->hashed = B_TRUE;
			cal->num_entry_attrs = cal->entry_tbl->size;
		}
	}
	stat = _DtCmsAppendEntryByFN(log, e, op);
	free(log);
	return(stat);
}
Beispiel #3
0
extern CSA_return_code
_DtCmsUpdateCalAttributesAndLog(
	_DtCmsCalendar	*cal,
	uint		numsrc,
	cms_attribute	*srcattrs,
	uint		access)
{
	CSA_return_code stat = CSA_SUCCESS;
	uint		i, oldnum = 0;
	cms_attribute	*oldattrs = NULL;
	char		*log;

	/* we didn't use _DtCmUpdateAttributes because we need
	 * to check access rights here
	 */

	/* copy original attributes for rollback if update fails */
	if (cal->attrs && (stat = _DtCm_copy_cms_attributes(cal->num_attrs,
	    cal->attrs, &oldnum, &oldattrs)) != CSA_SUCCESS)
		return (stat);

	for (i = 0; i < numsrc && stat == CSA_SUCCESS; i++) {
		if (srcattrs[i].name.name == NULL)
			continue;

		if (srcattrs[i].name.num <= 0)
			srcattrs[i].name.num = _DtCm_get_index_from_table(
						cal->cal_tbl,
						srcattrs[i].name.name);

		if (srcattrs[i].name.num < 0) {
			if (!_DTCMS_HAS_INSERT_CALENDAR_ATTR_ACCESS(access))
				stat = CSA_E_NO_AUTHORITY;
			else {
				if ((stat = _DtCmExtendNameTable(
				    srcattrs[i].name.name, 0, 0,
				    _DtCm_cal_name_tbl,
				    _DtCM_DEFINED_CAL_ATTR_SIZE,
				    _CSA_calendar_attribute_names,
				    &cal->cal_tbl, NULL)) == CSA_SUCCESS) {
					srcattrs[i].name.num =
						cal->cal_tbl->size;
					stat = _DtCmGrowAttrArray(
						&cal->num_attrs, &cal->attrs,
						&srcattrs[i]);
				}
			}

		} else if (!_DTCMS_HAS_CHANGE_CALENDAR_ATTR_ACCESS(access)) {

			stat = CSA_E_NO_AUTHORITY;
		} else {
			cms_attribute_value val;

			if (srcattrs[i].name.num == CSA_CAL_ATTR_ACCESS_LIST_I
			    && srcattrs[i].value == NULL) {
				val.type = CSA_VALUE_ACCESS_LIST;
				val.item.access_list_value = NULL;
				srcattrs[i].value = &val;
			}
			stat = _DtCmUpdateAttribute(&srcattrs[i],
				&cal->attrs[srcattrs[i].name.num]);
		}
	}

	if (stat == CSA_SUCCESS) {
		log = _DtCmsGetLogFN(cal->calendar);

		/* dump file */
		stat = _DtCmsAppendCalAttrsByFN(log, cal->num_attrs,
			cal->attrs);
		free(log);
	}

	if (stat == CSA_SUCCESS) {
		cal->modified = B_TRUE;

		_DtCm_free_cms_attributes(oldnum + 1, oldattrs);
		free(oldattrs);
	} else {
		_DtCm_free_cms_attributes(cal->num_attrs+1, cal->attrs);
		free(cal->attrs);
		cal->num_attrs = oldnum;
		cal->attrs = oldattrs;
	}

	return (stat);
}
Beispiel #4
0
/*
 * Load calendar data into memory from callog file.
 */
extern CSA_return_code
_DtCmsLoadCalendar(char *target, _DtCmsCalendar **infoptr)
{
	CSA_return_code	stat;
	char		*calname;
	char		*log;
	_DtCmsCalendar	*cal = NULL;

	if (target == NULL || infoptr == NULL)
		return (CSA_E_FAILURE);

	*infoptr = NULL;

	if ((calname = get_calname(target)) == NULL)
		return(CSA_E_INSUFFICIENT_MEMORY);

	if ((log = _DtCmsGetLogFN(calname)) == NULL)
	{
		free(calname);
		return(CSA_E_INSUFFICIENT_MEMORY);
	}

	if ((cal = (_DtCmsCalendar *)calloc(1, sizeof(_DtCmsCalendar)))
	    == NULL) {
		stat = CSA_E_INSUFFICIENT_MEMORY;
		goto ERROR;
	}

	if (!(cal->calendar = (char *)strdup(calname))) {
		stat = CSA_E_INSUFFICIENT_MEMORY;
		goto ERROR;
	}

	/* load data from file */
	if ((stat = start_log(cal, log)) != CSA_SUCCESS) {
		goto ERROR;
	}

	/*
	 * get file owner after the file is loaded since file
	 * ownership might be fixed in start_log()
	 */
	if (cal->fversion == _DtCMS_VERSION1) {
		if ((stat = get_file_owner(calname, &cal->owner))
		    != CSA_SUCCESS)
			goto ERROR;

		cal->alist = _DtCmsCalendarAccessList(cal);
	} else {
		if (cal->attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].value)
			cal->owner = strdup(cal->\
					attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].\
					value->item.calendar_user_value);
		else {
			stat = CSA_X_DT_E_BACKING_STORE_PROBLEM;
	    		fprintf(stderr, "%s: %s\n", pgname,
				"calendar owner attribute is missing from callog file");
			goto ERROR;
		}

		if (cal->attrs[CSA_CAL_ATTR_PRODUCT_IDENTIFIER_I].value == NULL)
		{
			if ((stat = _DtCm_set_string_attrval(
			    _DtCM_PRODUCT_IDENTIFIER, &cal->\
			    attrs[CSA_CAL_ATTR_PRODUCT_IDENTIFIER_I].value,
			    CSA_VALUE_STRING)) != CSA_SUCCESS) {
				goto ERROR;
			}
		}

		if (cal->attrs[CSA_CAL_ATTR_VERSION_I].value == NULL) {
			if ((stat = _DtCm_set_string_attrval(
			    _DtCM_SPEC_VERSION_SUPPORTED,
			    &cal->attrs[CSA_CAL_ATTR_VERSION_I].value,
			    CSA_VALUE_STRING)) != CSA_SUCCESS) {
				goto ERROR;
			}
		}

		cal->num_entry_attrs = cal->entry_tbl->size;
	}

	cal->getattrfuncs = _GetAttrFuncPtrs;

	/* link with other calendar structures */
	cal->next = calendar_list;
	calendar_list = cal;

	free(log);
	free(calname);

	*infoptr = cal;
	return (CSA_SUCCESS);
ERROR:
	free(calname);
	free(log);

	_DtCmsFreeCalendar(cal);
	return (stat);
}
Beispiel #5
0
static CSA_return_code
_DtCmsCreateCallog(char *user, cms_create_args *args, _DtCmsCalendar **newcal)
{
	CSA_return_code	stat;
	_DtCmsCalendar	*cal;
	int		i, index;
	char		datestr[80];
	char		*calname;
	char		*log;
	char		*username;
	cms_attribute_value val;
	cms_access_entry aentry;
	int		nidx = 0, oidx = 0;
	char		*name, *owner;

	/*
	 * if calendar name is a user name, make sure that
	 * it's the same as the sender.
	 */
	calname = _DtCmGetPrefix(args->cal, '@');
	username = _DtCmGetPrefix(user, '@');

	if (_DtCmIsUserName(calname) && strcmp(calname, username)) {
		free(calname);
		free(username);
		return (CSA_E_NO_AUTHORITY);
	}
	log = _DtCmsGetLogFN(calname);
	free(calname);
	free(username);

	/* create internal calendar data structure */
	if ((cal = _DtCmsMakeCalendar(user, args->cal)) == NULL) {
		free(log);
		return (CSA_E_INSUFFICIENT_MEMORY);
	}

	/* fill in information */
	_csa_tick_to_iso8601(time(0), datestr);

	if ((stat = _DtCm_set_string_attrval(datestr,
	    &cal->attrs[CSA_CAL_ATTR_DATE_CREATED_I].value,
	    CSA_VALUE_DATE_TIME)) != CSA_SUCCESS) {
		_DtCmsFreeCalendar(cal);
		free(log);
		return (stat);
	}

	/* initialize access list to be "WORLD", VIEW_PUBLIC */
	aentry.user = WORLD;
	aentry.rights = CSA_VIEW_PUBLIC_ENTRIES;
	aentry.next = NULL;
	val.item.access_list_value = &aentry;
	val.type = CSA_VALUE_ACCESS_LIST;

	if ((stat = _DtCmUpdateAccessListAttrVal(&val,
	    &cal->attrs[CSA_CAL_ATTR_ACCESS_LIST_I].value)) != CSA_SUCCESS) {
		_DtCmsFreeCalendar(cal);
		free(log);
		return (stat);
	}

	/* set product identifier */
	if ((stat = _DtCm_set_string_attrval(_DtCM_PRODUCT_IDENTIFIER,
	    &cal->attrs[CSA_CAL_ATTR_PRODUCT_IDENTIFIER_I].value,
	    CSA_VALUE_STRING)) != CSA_SUCCESS) {
		_DtCmsFreeCalendar(cal);
		free(log);
		return (stat);
	}

	/* set CSA version */
	if ((stat = _DtCm_set_string_attrval(_DtCM_SPEC_VERSION_SUPPORTED,
	    &cal->attrs[CSA_CAL_ATTR_VERSION_I].value, CSA_VALUE_STRING))
	    != CSA_SUCCESS) {
		_DtCmsFreeCalendar(cal);
		free(log);
		return (stat);
	}

	/* we dont use the values specified by client */
	for (i = 0; i < args->num_attrs; i++) {
		if (strcmp(args->attrs[i].name.name,
		    CSA_CAL_ATTR_CALENDAR_NAME) == 0) {
			nidx = i;
			name = args->attrs[i].name.name;
			args->attrs[i].name.name = NULL;
		} else if (strcmp(args->attrs[i].name.name,
		    CSA_CAL_ATTR_CALENDAR_OWNER) == 0) {
			oidx = i;
			owner = args->attrs[i].name.name;
			args->attrs[i].name.name = NULL;
		}
	}

	/* initialize calendar attribute with info provided by caller */
	if ((stat = _DtCmUpdateAttributes(args->num_attrs, args->attrs,
	    &cal->num_attrs, &cal->attrs, &cal->cal_tbl, B_TRUE,
	    NULL, B_FALSE)) != CSA_SUCCESS) {
		_DtCmsFreeCalendar(cal);
		free(log);
		return (stat);
	}

	if (nidx) args->attrs[nidx].name.name = name;
	if (oidx) args->attrs[oidx].name.name = owner;

	/* use passed in char set if client does not supply one */
	if (cal->attrs[CSA_CAL_ATTR_CHARACTER_SET_I].value == NULL &&
	     args->char_set && *args->char_set != NULL) {
		if ((stat = _DtCm_set_string_attrval(args->char_set,
		    &cal->attrs[CSA_CAL_ATTR_CHARACTER_SET_I].value,
		    CSA_VALUE_STRING)) != CSA_SUCCESS) {
			_DtCmsFreeCalendar(cal);
			free(log);
			return (stat);
		}
	}

	/* create file */
	if ((stat = _DtCmsCreateLogV2(user, log)) != CSA_SUCCESS) {
		_DtCmsFreeCalendar(cal);
		free(log);
		return (stat);
	}

	/* dump file */
	if ((stat = _DtCmsAppendCalAttrsByFN(log, cal->num_attrs, cal->attrs))
	    != CSA_SUCCESS) {
		free(log);
		unlink(log);
		_DtCmsFreeCalendar(cal);
		return (stat);
	}
	free(log);

	_DtCmsPutInCalList(cal);

	*newcal = cal;

	return (stat);
}
Beispiel #6
0
extern void
_DtCmsCollectOne(_DtCmsCalendar *cal)
{
	Rb_Status	status;
	CSA_return_code	 	stat;
	char *bak, *temp, *clog;

	if (cal == NULL)
		return;

	status	= rb_check_tree(APPT_TREE(cal));
	clog	= _DtCmsGetLogFN(cal->calendar);
	temp	= _DtCmsGetTmpFN(cal->calendar);
	bak	= _DtCmsGetBakFN(cal->calendar);

	if (status != rb_ok || clog==NULL || temp==NULL || bak==NULL) {
		fprintf(stderr, "%s: cannot acquire files to execute garbage collection.\n", pgname);
		fprintf(stderr, "possible causes: cannot find home directory.\n");
		fprintf(stderr, "\tNIS or your host server might be down.\n");
		fprintf(stderr, "damage: none\n\n");
		goto cleanup;
	}

	/* Make sure that the temp file does not exist before garbage collect */
	unlink (temp);
	if (cal->fversion == _DtCMS_VERSION1)
		stat = _DtCmsCreateLogV1(cal->owner, temp);
	else
		stat = _DtCmsCreateLogV2(cal->owner, temp);

	if (stat != CSA_SUCCESS) {
		if (stat == (CSA_X_DT_E_BACKING_STORE_PROBLEM))
			print_file_error(temp,
				"file error during garbage collection");
		else {
			fprintf(stderr, "%s: file error on %s during garbage collection\n",
				pgname, temp);
			fprintf(stderr, "Reason: getpwnam() failed. %s%s\n",
				"No passwd entry for owner of ",
				cal->calendar);

			fprintf(stderr, "damage: none\n\n");
		}
		goto cleanup;
	}

	if (cal->fversion == _DtCMS_VERSION1)
		stat = _DtCmsDumpDataV1(temp, cal);
	else
		stat = _DtCmsDumpDataV2(temp, cal);

	if (stat != CSA_SUCCESS) {
		print_file_error(temp,
			(stat == (CSA_X_DT_E_BACKING_STORE_PROBLEM) ?
			 "file error during garbage collection" :
			 "can't dump data structure to file during garbage collection"));
		goto cleanup;
	}

	/* mv -f .callog .calbak; mv -f temp .callog */
	if (rename (clog, bak) < 0) {
		perror ("rpc.cmsd: Can't backup callog to .calbak.\nreason:");
		goto cleanup;
	}

	if (rename (temp, clog) < 0) {
		perror("rpc.cmsd: Can't move .caltemp to callog.\nreason:");
		fprintf(stderr, "%s: you may recover %s from %s.\n", pgname,
			clog, bak);
	}

cleanup:
	if (bak != NULL) {
		free(bak);
		bak = NULL;
	}
	if (temp != NULL) {
		free(temp);
		temp = NULL;
	}
	if (clog != NULL) {
		free(clog);
		clog = NULL;
	}
}