/* * 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); }
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); }
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); }
/* * 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); }
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); }
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; } }