/* * Calculate the set of rights the user in 'auth_state' has in the ACL 'acl'. * 'acl' must be writable, but is restored to its original condition. */ EXPORTED int cyrus_acl_myrights(struct auth_state *auth_state, const char *origacl) { char *acl = xstrdupsafe(origacl); char *thisid, *rights, *nextid; long acl_positive = 0, acl_negative = 0; long *acl_ptr; for (thisid = acl; *thisid; thisid = nextid) { acl_ptr = &acl_positive; rights = strchr(thisid, '\t'); if (!rights) { break; } *rights++ = '\0'; nextid = strchr(rights, '\t'); if (!nextid) { rights[-1] = '\t'; break; } *nextid++ = '\0'; if (*thisid == '-') { acl_ptr = &acl_negative; thisid++; } if (auth_memberof(auth_state, thisid)) { *acl_ptr |= cyrus_acl_strtomask(rights); } } free(acl); return acl_positive & ~acl_negative; }
/* Called before a cyrus application starts (but after command line parameters * are read) */ EXPORTED int cyrus_init(const char *alt_config, const char *ident, unsigned flags, int config_need_data) { char *p; const char *val; const char *prefix; int umaskval = 0; int syslog_opts = LOG_PID; const char *facility; if(cyrus_init_run != NOT_RUNNING) { fatal("cyrus_init called twice!", EC_CONFIG); } else { cyrus_init_run = RUNNING; } cyrus_init_nodb = (flags & CYRUSINIT_NODB); #ifdef LOG_PERROR if ((flags & CYRUSINIT_PERROR)) syslog_opts |= LOG_PERROR; #endif initialize_imap_error_table(); initialize_mupd_error_table(); if(!ident) fatal("service name was not specified to cyrus_init", EC_CONFIG); config_ident = ident; /* xxx we lose here since we can't have the prefix until we load the * config file */ openlog(config_ident, syslog_opts, SYSLOG_FACILITY); /* Load configuration file. This will set config_dir when it finds it */ config_read(alt_config, config_need_data); prefix = config_getstring(IMAPOPT_SYSLOG_PREFIX); facility = config_getstring(IMAPOPT_SYSLOG_FACILITY); /* Reopen the log with the new prefix, if needed */ if (prefix || facility) { char *ident_buf; int facnum = facility ? get_facility(facility) : SYSLOG_FACILITY; if (prefix) ident_buf = strconcat(prefix, "/", ident, (char *)NULL); else ident_buf = xstrdup(ident); closelog(); openlog(ident_buf, syslog_opts, facnum); /* don't free the openlog() string! */ } /* allow debug logging */ if (!config_debug) setlogmask(~LOG_MASK(LOG_DEBUG)); /* Look up default partition */ config_defpartition = config_getstring(IMAPOPT_DEFAULTPARTITION); for (p = (char *)config_defpartition; p && *p; p++) { if (!Uisalnum(*p)) fatal("defaultpartition option contains non-alphanumeric character", EC_CONFIG); if (Uisupper(*p)) *p = tolower((unsigned char) *p); } /* Look up umask */ val = config_getstring(IMAPOPT_UMASK); while (*val) { if (*val >= '0' && *val <= '7') umaskval = umaskval*8 + *val - '0'; val++; } umask(umaskval); config_fulldirhash = config_getswitch(IMAPOPT_FULLDIRHASH); /* look up and canonify the implicit rights of mailbox owners */ cyrus_acl_strtomask(config_getstring(IMAPOPT_IMPLICIT_OWNER_RIGHTS), &config_implicitrights); /* XXX and if strtomask fails? */ config_metapartition_files = config_getbitfield(IMAPOPT_METAPARTITION_FILES); val = config_getstring(IMAPOPT_SUPPRESS_CAPABILITIES); if (val) suppressed_capabilities = strarray_split(val, NULL, 0); if (config_getswitch(IMAPOPT_SEARCH_SKIPDIACRIT)) charset_flags |= CHARSET_SKIPDIACRIT; switch (config_getenum(IMAPOPT_SEARCH_WHITESPACE)) { case IMAP_ENUM_SEARCH_WHITESPACE_MERGE: charset_flags |= CHARSET_MERGESPACE; break; case IMAP_ENUM_SEARCH_WHITESPACE_SKIP: charset_flags |= CHARSET_SKIPSPACE; break; default: break; } if (config_getswitch(IMAPOPT_SEARCH_SKIPHTML)) charset_flags |= CHARSET_SKIPHTML; if (config_getswitch(IMAPOPT_RFC2047_UTF8)) charset_flags |= CHARSET_MIME_UTF8; /* Set snippet conversion flags. */ charset_snippet_flags = CHARSET_SNIPPET; if (config_getenum(IMAPOPT_SEARCH_ENGINE) != IMAP_ENUM_SEARCH_ENGINE_XAPIAN) { /* All search engines other than Xapian require escaped HTML */ charset_snippet_flags |= CHARSET_ESCAPEHTML; } if (!cyrus_init_nodb) { /* lookup the database backends */ config_mboxlist_db = config_getstring(IMAPOPT_MBOXLIST_DB); config_quota_db = config_getstring(IMAPOPT_QUOTA_DB); config_subscription_db = config_getstring(IMAPOPT_SUBSCRIPTION_DB); config_annotation_db = config_getstring(IMAPOPT_ANNOTATION_DB); config_seenstate_db = config_getstring(IMAPOPT_SEENSTATE_DB); config_mboxkey_db = config_getstring(IMAPOPT_MBOXKEY_DB); config_duplicate_db = config_getstring(IMAPOPT_DUPLICATE_DB); config_tls_sessions_db = config_getstring(IMAPOPT_TLS_SESSIONS_DB); config_ptscache_db = config_getstring(IMAPOPT_PTSCACHE_DB); config_statuscache_db = config_getstring(IMAPOPT_STATUSCACHE_DB); config_userdeny_db = config_getstring(IMAPOPT_USERDENY_DB); config_zoneinfo_db = config_getstring(IMAPOPT_ZONEINFO_DB); config_conversations_db = config_getstring(IMAPOPT_CONVERSATIONS_DB); config_backup_db = config_getstring(IMAPOPT_BACKUP_DB); /* configure libcyrus as needed */ libcyrus_config_setstring(CYRUSOPT_CONFIG_DIR, config_dir); libcyrus_config_setswitch(CYRUSOPT_AUTH_UNIX_GROUP_ENABLE, config_getswitch(IMAPOPT_UNIX_GROUP_ENABLE)); libcyrus_config_setswitch(CYRUSOPT_USERNAME_TOLOWER, config_getswitch(IMAPOPT_USERNAME_TOLOWER)); libcyrus_config_setswitch(CYRUSOPT_SKIPLIST_UNSAFE, config_getswitch(IMAPOPT_SKIPLIST_UNSAFE)); libcyrus_config_setstring(CYRUSOPT_TEMP_PATH, config_getstring(IMAPOPT_TEMP_PATH)); libcyrus_config_setint(CYRUSOPT_PTS_CACHE_TIMEOUT, config_getint(IMAPOPT_PTSCACHE_TIMEOUT)); libcyrus_config_setswitch(CYRUSOPT_FULLDIRHASH, config_getswitch(IMAPOPT_FULLDIRHASH)); libcyrus_config_setstring(CYRUSOPT_PTSCACHE_DB, config_getstring(IMAPOPT_PTSCACHE_DB)); libcyrus_config_setstring(CYRUSOPT_PTSCACHE_DB_PATH, config_getstring(IMAPOPT_PTSCACHE_DB_PATH)); libcyrus_config_setstring(CYRUSOPT_PTLOADER_SOCK, config_getstring(IMAPOPT_PTLOADER_SOCK)); libcyrus_config_setswitch(CYRUSOPT_VIRTDOMAINS, config_getenum(IMAPOPT_VIRTDOMAINS)); libcyrus_config_setstring(CYRUSOPT_AUTH_MECH, config_getstring(IMAPOPT_AUTH_MECH)); libcyrus_config_setstring(CYRUSOPT_DELETERIGHT, config_getstring(IMAPOPT_DELETERIGHT)); libcyrus_config_setstring(CYRUSOPT_SQL_DATABASE, config_getstring(IMAPOPT_SQL_DATABASE)); libcyrus_config_setstring(CYRUSOPT_SQL_ENGINE, config_getstring(IMAPOPT_SQL_ENGINE)); libcyrus_config_setstring(CYRUSOPT_SQL_HOSTNAMES, config_getstring(IMAPOPT_SQL_HOSTNAMES)); libcyrus_config_setstring(CYRUSOPT_SQL_USER, config_getstring(IMAPOPT_SQL_USER)); libcyrus_config_setstring(CYRUSOPT_SQL_PASSWD, config_getstring(IMAPOPT_SQL_PASSWD)); libcyrus_config_setswitch(CYRUSOPT_SQL_USESSL, config_getswitch(IMAPOPT_SQL_USESSL)); libcyrus_config_setswitch(CYRUSOPT_SKIPLIST_ALWAYS_CHECKPOINT, config_getswitch(IMAPOPT_SKIPLIST_ALWAYS_CHECKPOINT)); /* Not until all configuration parameters are set! */ libcyrus_init(); } return 0; }
/* * Modify the ACL pointed to by 'acl' to make the rights granted to * 'identifier' the set specified in the mask 'access'. The pointer * pointed to by 'acl' must have been obtained from malloc(). */ EXPORTED int cyrus_acl_set(char **acl, const char *identifier, int mode, int access, cyrus_acl_canonproc_t *canonproc, void *canonrock) { const char *canonid; char *newidentifier = 0; char *newacl; char *thisid, *nextid; int oldaccess = 0; char *rights; /* Convert 'identifier' into canonical form */ canonid = auth_canonifyid(*identifier == '-' ? identifier+1 : identifier, 0); if (canonid) { if (*identifier == '-') { newidentifier = xmalloc(strlen(canonid)+2); newidentifier[0] = '-'; strcpy(newidentifier+1, canonid); identifier = newidentifier; } else { identifier = canonid; } } else if (access != 0L) { return -1; } else { /* trying to delete invalid/non-existent identifier */ } /* Find any existing entry for 'identifier' in 'acl' */ for (thisid = nextid = *acl; *thisid; thisid = nextid) { rights = strchr(thisid, '\t'); if (!rights) { /* ACK, nuke trailing garbage */ *thisid = '\0'; nextid = thisid; break; } *rights++ = '\0'; nextid = strchr(rights, '\t'); if (!nextid) { /* ACK, nuke trailing garbage */ *thisid = '\0'; nextid = thisid; break; } *nextid++ = '\0'; if (strcmp(identifier, thisid) == 0) { oldaccess = cyrus_acl_strtomask(rights); break; } rights[-1] = '\t'; nextid[-1] = '\t'; } switch (mode) { case ACL_MODE_SET: break; case ACL_MODE_ADD: access |= oldaccess; break; case ACL_MODE_REMOVE: access = oldaccess & ~access; break; } if (canonproc) { if (*identifier == '-') access = ~(canonproc(canonrock, identifier+1, ~access)); else access = canonproc(canonrock, identifier, access); } if (access == 0L) { /* Remove any existing entry for 'identifier'. Special case: When we try to delete an invalid/non-existent identifier, both 'thisid' and 'nextid' point to the end of *acl. */ newacl = xmalloc(strlen(*acl) + strlen(nextid) - strlen(thisid) + 1); /* Copy existing ACLs without the current identifier. Note: The buffer will not be zero terminated. */ strncpy(newacl, *acl, (thisid - *acl)); /* Append the remaining ACL string. Zero-terminates the string. */ strcpy(newacl + (thisid - *acl), nextid); free(*acl); *acl = newacl; } else { /* Replace any existing entry for 'identifier' */ newacl = xmalloc((thisid - *acl) + strlen(identifier) + 40 + strlen(nextid)); strncpy(newacl, *acl, (thisid - *acl)); strcpy(newacl + (thisid - *acl), identifier); strcat(newacl, "\t"); (void) cyrus_acl_masktostr(access, newacl + strlen(newacl)); strcat(newacl, "\t"); strcat(newacl, nextid); free(*acl); *acl = newacl; } if (newidentifier) free(newidentifier); return 0; }
/* Called before a cyrus application starts (but after command line parameters * are read) */ int cyrus_init(const char *alt_config, const char *ident, unsigned flags) { char *p; const char *val; const char *prefix; int umaskval = 0; if(cyrus_init_run != NOT_RUNNING) { fatal("cyrus_init called twice!", EC_CONFIG); } else { cyrus_init_run = RUNNING; } cyrus_init_nodb = (flags & CYRUSINIT_NODB); initialize_imap_error_table(); initialize_mupd_error_table(); if(!ident) fatal("service name was not specified to cyrus_init", EC_CONFIG); config_ident = ident; /* xxx we lose here since we can't have the prefix until we load the * config file */ openlog(config_ident, LOG_PID, SYSLOG_FACILITY); /* Load configuration file. This will set config_dir when it finds it */ config_read(alt_config); prefix = config_getstring(IMAPOPT_SYSLOG_PREFIX); /* Reopen the log with the new prefix, if needed */ if(prefix) { int size = strlen(prefix) + 1 + strlen(ident) + 1; char *ident_buf = xmalloc(size); strlcpy(ident_buf, prefix, size); strlcat(ident_buf, "/", size); strlcat(ident_buf, ident, size); closelog(); openlog(ident_buf, LOG_PID, SYSLOG_FACILITY); /* don't free the openlog() string! */ } /* Look up default partition */ config_defpartition = config_getstring(IMAPOPT_DEFAULTPARTITION); for (p = (char *)config_defpartition; p && *p; p++) { if (!Uisalnum(*p)) fatal("defaultpartition option contains non-alphanumeric character", EC_CONFIG); if (Uisupper(*p)) *p = tolower((unsigned char) *p); } /* Look up umask */ val = config_getstring(IMAPOPT_UMASK); while (*val) { if (*val >= '0' && *val <= '7') umaskval = umaskval*8 + *val - '0'; val++; } umask(umaskval); config_fulldirhash = config_getswitch(IMAPOPT_FULLDIRHASH); /* look up and canonify the implicit rights of mailbox owners */ config_implicitrights = cyrus_acl_strtomask(config_getstring(IMAPOPT_IMPLICIT_OWNER_RIGHTS)); config_metapartition_files = config_getbitfield(IMAPOPT_METAPARTITION_FILES); if (!cyrus_init_nodb) { /* lookup the database backends */ config_mboxlist_db = cyrusdb_fromname(config_getstring(IMAPOPT_MBOXLIST_DB)); config_quota_db = cyrusdb_fromname(config_getstring(IMAPOPT_QUOTA_DB)); config_subscription_db = cyrusdb_fromname(config_getstring(IMAPOPT_SUBSCRIPTION_DB)); config_annotation_db = cyrusdb_fromname(config_getstring(IMAPOPT_ANNOTATION_DB)); config_seenstate_db = cyrusdb_fromname(config_getstring(IMAPOPT_SEENSTATE_DB)); config_mboxkey_db = cyrusdb_fromname(config_getstring(IMAPOPT_MBOXKEY_DB)); config_duplicate_db = cyrusdb_fromname(config_getstring(IMAPOPT_DUPLICATE_DB)); config_tlscache_db = cyrusdb_fromname(config_getstring(IMAPOPT_TLSCACHE_DB)); config_ptscache_db = cyrusdb_fromname(config_getstring(IMAPOPT_PTSCACHE_DB)); config_statuscache_db = cyrusdb_fromname(config_getstring(IMAPOPT_STATUSCACHE_DB)); config_userdeny_db = cyrusdb_fromname(config_getstring(IMAPOPT_USERDENY_DB)); /* configure libcyrus as needed */ libcyrus_config_setstring(CYRUSOPT_CONFIG_DIR, config_dir); libcyrus_config_setswitch(CYRUSOPT_AUTH_UNIX_GROUP_ENABLE, config_getswitch(IMAPOPT_UNIX_GROUP_ENABLE)); libcyrus_config_setswitch(CYRUSOPT_USERNAME_TOLOWER, config_getswitch(IMAPOPT_USERNAME_TOLOWER)); libcyrus_config_setswitch(CYRUSOPT_SKIPLIST_UNSAFE, config_getswitch(IMAPOPT_SKIPLIST_UNSAFE)); libcyrus_config_setstring(CYRUSOPT_TEMP_PATH, config_getstring(IMAPOPT_TEMP_PATH)); libcyrus_config_setint(CYRUSOPT_PTS_CACHE_TIMEOUT, config_getint(IMAPOPT_PTSCACHE_TIMEOUT)); libcyrus_config_setswitch(CYRUSOPT_FULLDIRHASH, config_getswitch(IMAPOPT_FULLDIRHASH)); libcyrus_config_setstring(CYRUSOPT_PTSCACHE_DB, config_getstring(IMAPOPT_PTSCACHE_DB)); libcyrus_config_setstring(CYRUSOPT_PTSCACHE_DB_PATH, config_getstring(IMAPOPT_PTSCACHE_DB_PATH)); libcyrus_config_setstring(CYRUSOPT_PTLOADER_SOCK, config_getstring(IMAPOPT_PTLOADER_SOCK)); libcyrus_config_setswitch(CYRUSOPT_VIRTDOMAINS, config_getenum(IMAPOPT_VIRTDOMAINS)); libcyrus_config_setint(CYRUSOPT_BERKELEY_CACHESIZE, config_getint(IMAPOPT_BERKELEY_CACHESIZE)); libcyrus_config_setstring(CYRUSOPT_AUTH_MECH, config_getstring(IMAPOPT_AUTH_MECH)); libcyrus_config_setint(CYRUSOPT_BERKELEY_LOCKS_MAX, config_getint(IMAPOPT_BERKELEY_LOCKS_MAX)); libcyrus_config_setint(CYRUSOPT_BERKELEY_TXNS_MAX, config_getint(IMAPOPT_BERKELEY_TXNS_MAX)); libcyrus_config_setstring(CYRUSOPT_DELETERIGHT, config_getstring(IMAPOPT_DELETERIGHT)); libcyrus_config_setstring(CYRUSOPT_SQL_DATABASE, config_getstring(IMAPOPT_SQL_DATABASE)); libcyrus_config_setstring(CYRUSOPT_SQL_ENGINE, config_getstring(IMAPOPT_SQL_ENGINE)); libcyrus_config_setstring(CYRUSOPT_SQL_HOSTNAMES, config_getstring(IMAPOPT_SQL_HOSTNAMES)); libcyrus_config_setstring(CYRUSOPT_SQL_USER, config_getstring(IMAPOPT_SQL_USER)); libcyrus_config_setstring(CYRUSOPT_SQL_PASSWD, config_getstring(IMAPOPT_SQL_PASSWD)); libcyrus_config_setswitch(CYRUSOPT_SQL_USESSL, config_getswitch(IMAPOPT_SQL_USESSL)); /* Not until all configuration parameters are set! */ libcyrus_init(); } return 0; }