bool master_threads2::run_alone(const char* addrs, const char* path /* = NULL */, unsigned int count /* = 1 */, int threads_count /* = 1 */) { // 每个进程只能有一个实例在运行 acl_assert(has_called == false); has_called = true; daemon_mode_ = false; acl_assert(addrs && *addrs); __count_limit = count; #ifdef WIN32 acl_init(); #endif std::vector<ACL_VSTREAM*> sstreams; ACL_EVENT* eventp = acl_event_new_select_thr(1, 0); set_event(eventp); // 设置基类的事件句柄 ACL_ARGV* tokens = acl_argv_split(addrs, ";,| \t"); ACL_ITER iter; acl_foreach(iter, tokens) { const char* addr = (const char*) iter.data; ACL_VSTREAM* sstream = acl_vstream_listen(addr, 128); if (sstream == NULL) { logger_error("listen %s error(%s)", addr, acl_last_serror()); acl_argv_free(tokens); close_sstreams(eventp, sstreams); acl_event_free(eventp); return false; } acl_event_enable_listen(eventp, sstream, 0, listen_callback, sstream); sstreams.push_back(sstream); } acl_argv_free(tokens); // 初始化配置参数 conf_.load(path); service_pre_jail(NULL); service_init(NULL); if (threads_count > 1) { __thread_pool = acl_thread_pool_create(threads_count, 120); acl_pthread_pool_atinit(__thread_pool, thread_begin, NULL); acl_pthread_pool_atfree(__thread_pool, thread_finish, NULL); } else thread_init(NULL); while (!__stop) acl_event_loop(eventp); if (__thread_pool) acl_pthread_pool_destroy(__thread_pool); else thread_exit(NULL); service_exit(NULL); // 必须在调用 acl_event_free 前调用 close_sstreams,因为在关闭 // 网络流对象时依然有对 ACL_EVENT 引擎的使用 close_sstreams(eventp, sstreams); acl_event_free(eventp); eventp = NULL; return true; }
static int CheckPosixLinuxACEs(EvalContext *ctx, Rlist *aces, AclMethod method, const char *file_path, acl_type_t acl_type, Attributes a, const Promise *pp, PromiseResult *result) { acl_t acl_existing; acl_t acl_new; acl_t acl_tmp; acl_entry_t ace_parsed; acl_entry_t ace_current; acl_permset_t perms; char *cf_ace; int retv; int has_mask; Rlist *rp; char *acl_type_str; acl_new = NULL; acl_existing = NULL; acl_tmp = NULL; has_mask = false; acl_type_str = acl_type == ACL_TYPE_ACCESS ? "Access" : "Default"; // read existing acl if ((acl_existing = acl_get_file(file_path, acl_type)) == NULL) { Log(LOG_LEVEL_VERBOSE, "No ACL for '%s' could be read. (acl_get_file: %s)", file_path, GetErrorStr()); return false; } // allocate memory for temp ace (it needs to reside in a temp acl) if ((acl_tmp = acl_init(1)) == NULL) { Log(LOG_LEVEL_ERR, "New ACL could not be allocated (acl_init: %s)", GetErrorStr()); acl_free((void *) acl_existing); return false; } if (acl_create_entry(&acl_tmp, &ace_parsed) != 0) { Log(LOG_LEVEL_ERR, "New ACL could not be allocated (acl_create_entry: %s)", GetErrorStr()); acl_free((void *) acl_existing); acl_free((void *) acl_tmp); return false; } // copy existing aces if we are appending if (method == ACL_METHOD_APPEND) { if ((acl_new = acl_dup(acl_existing)) == NULL) { Log(LOG_LEVEL_ERR, "Error copying existing ACL (acl_dup: %s)", GetErrorStr()); acl_free((void *) acl_existing); acl_free((void *) acl_tmp); return false; } } else // overwrite existing acl { if ((acl_new = acl_init(5)) == NULL) // TODO: Always OK with 5 here ? { Log(LOG_LEVEL_ERR, "New ACL could not be allocated (acl_init: %s)", GetErrorStr()); acl_free((void *) acl_existing); acl_free((void *) acl_tmp); return false; } } for (rp = aces; rp != NULL; rp = rp->next) { cf_ace = RlistScalarValue(rp); if (!ParseEntityPosixLinux(&cf_ace, ace_parsed, &has_mask)) { Log(LOG_LEVEL_ERR, "Error parsing entity in 'cf_ace'."); acl_free((void *) acl_existing); acl_free((void *) acl_tmp); acl_free((void *) acl_new); return false; } // check if an ACE with this entity-type and id already exist in the Posix Linux ACL ace_current = FindACE(acl_new, ace_parsed); // create new entry in ACL if it did not exist if (ace_current == NULL) { if (acl_create_entry(&acl_new, &ace_current) != 0) { Log(LOG_LEVEL_ERR, "Failed to allocate ace (acl_create_entry: %s)", GetErrorStr()); acl_free((void *) acl_existing); acl_free((void *) acl_tmp); acl_free((void *) acl_new); return false; } // copy parsed entity-type and id if (acl_copy_entry(ace_current, ace_parsed) != 0) { Log(LOG_LEVEL_ERR, "Error copying Linux entry in 'cf_ace' (acl_copy_entry: %s)", GetErrorStr()); acl_free((void *) acl_existing); acl_free((void *) acl_tmp); acl_free((void *) acl_new); return false; } // clear ace_current's permissions to avoid ace_parsed from last // loop iteration to be taken into account when applying mode below if ((acl_get_permset(ace_current, &perms) != 0)) { Log(LOG_LEVEL_ERR, "Error obtaining permset for 'ace_current' (acl_get_permset: %s)", GetErrorStr()); acl_free((void *) acl_existing); acl_free((void *) acl_tmp); acl_free((void *) acl_new); return false; } if (acl_clear_perms(perms) != 0) { Log(LOG_LEVEL_ERR, "Error clearing permset for 'ace_current'. (acl_clear_perms: %s)", GetErrorStr()); acl_free((void *) acl_existing); acl_free((void *) acl_tmp); acl_free((void *) acl_new); return false; } } // mode string should be prefixed with an entry seperator if (*cf_ace != ':') { Log(LOG_LEVEL_ERR, "No separator before mode-string in 'cf_ace'"); acl_free((void *) acl_existing); acl_free((void *) acl_tmp); acl_free((void *) acl_new); return false; } cf_ace += 1; if (acl_get_permset(ace_current, &perms) != 0) { Log(LOG_LEVEL_ERR, "Error obtaining permset for 'cf_ace'"); acl_free((void *) acl_existing); acl_free((void *) acl_tmp); acl_free((void *) acl_new); return false; } if (!ParseModePosixLinux(cf_ace, perms)) { Log(LOG_LEVEL_ERR, "Error parsing mode-string in 'cf_ace'"); acl_free((void *) acl_existing); acl_free((void *) acl_tmp); acl_free((void *) acl_new); return false; } // only allow permissions exist on posix acls, so we do // not check what follows next } // if no mask exists, calculate one (or both?): run acl_calc_mask and add one if (!has_mask) { if (acl_calc_mask(&acl_new) != 0) { Log(LOG_LEVEL_ERR, "Error calculating new acl mask"); acl_free((void *) acl_existing); acl_free((void *) acl_tmp); acl_free((void *) acl_new); return false; } } if ((retv = ACLEquals(acl_existing, acl_new)) == -1) { Log(LOG_LEVEL_ERR, "Error while comparing existing and new ACL, unable to repair."); acl_free((void *) acl_existing); acl_free((void *) acl_tmp); acl_free((void *) acl_new); return false; } if (retv == 1) // existing and new acl differ, update existing { switch (a.transaction.action) { case cfa_warn: cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_WARN, pp, a, "%s ACL on file '%s' needs to be updated", acl_type_str, file_path); *result = PromiseResultUpdate(*result, PROMISE_RESULT_WARN); break; case cfa_fix: if (!DONTDO) { if ((retv = acl_set_file(file_path, acl_type, acl_new)) != 0) { Log(LOG_LEVEL_ERR, "Error setting new %s ACL on file '%s' (acl_set_file: %s), are required ACEs present ?", acl_type_str, file_path, GetErrorStr()); acl_free((void *) acl_existing); acl_free((void *) acl_tmp); acl_free((void *) acl_new); return false; } } cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "%s ACL on '%s' successfully changed.", acl_type_str, file_path); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); break; default: ProgrammingError("CFEngine: internal error: illegal file action"); } } else { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "'%s' ACL on '%s' needs no modification.", acl_type_str, file_path); } acl_free((void *) acl_existing); acl_free((void *) acl_new); acl_free((void *) acl_tmp); return true; }
int slap_init( int mode, const char *name ) { int rc; assert( mode ); if ( slapMode != SLAP_UNDEFINED_MODE ) { /* Make sure we write something to stderr */ slap_debug |= LDAP_DEBUG_NONE; Debug( LDAP_DEBUG_ANY, "%s init: init called twice (old=%d, new=%d)\n", name, slapMode, mode ); return 1; } slapMode = mode; slap_op_init(); #ifdef SLAPD_MODULES if ( module_init() != 0 ) { slap_debug |= LDAP_DEBUG_NONE; Debug( LDAP_DEBUG_ANY, "%s: module_init failed\n", name, 0, 0 ); return 1; } #endif if ( slap_schema_init( ) != 0 ) { slap_debug |= LDAP_DEBUG_NONE; Debug( LDAP_DEBUG_ANY, "%s: slap_schema_init failed\n", name, 0, 0 ); return 1; } if ( filter_init() != 0 ) { slap_debug |= LDAP_DEBUG_NONE; Debug( LDAP_DEBUG_ANY, "%s: filter_init failed\n", name, 0, 0 ); return 1; } if ( entry_init() != 0 ) { slap_debug |= LDAP_DEBUG_NONE; Debug( LDAP_DEBUG_ANY, "%s: entry_init failed\n", name, 0, 0 ); return 1; } switch ( slapMode & SLAP_MODE ) { case SLAP_SERVER_MODE: root_dse_init(); /* FALLTHRU */ case SLAP_TOOL_MODE: Debug( LDAP_DEBUG_TRACE, "%s init: initiated %s.\n", name, (mode & SLAP_MODE) == SLAP_TOOL_MODE ? "tool" : "server", 0 ); slap_name = name; ldap_pvt_thread_pool_init_q( &connection_pool, connection_pool_max, 0, connection_pool_queues); slap_counters_init( &slap_counters ); ldap_pvt_thread_mutex_init( &slapd_rq.rq_mutex ); LDAP_STAILQ_INIT( &slapd_rq.task_list ); LDAP_STAILQ_INIT( &slapd_rq.run_list ); slap_passwd_init(); rc = slap_sasl_init(); if( rc == 0 ) { rc = backend_init( ); } if ( rc ) return rc; break; default: slap_debug |= LDAP_DEBUG_NONE; Debug( LDAP_DEBUG_ANY, "%s init: undefined mode (%d).\n", name, mode, 0 ); rc = 1; break; } if ( slap_controls_init( ) != 0 ) { slap_debug |= LDAP_DEBUG_NONE; Debug( LDAP_DEBUG_ANY, "%s: slap_controls_init failed\n", name, 0, 0 ); return 1; } if ( frontend_init() ) { slap_debug |= LDAP_DEBUG_NONE; Debug( LDAP_DEBUG_ANY, "%s: frontend_init failed\n", name, 0, 0 ); return 1; } if ( overlay_init() ) { slap_debug |= LDAP_DEBUG_NONE; Debug( LDAP_DEBUG_ANY, "%s: overlay_init failed\n", name, 0, 0 ); return 1; } if ( glue_sub_init() ) { slap_debug |= LDAP_DEBUG_NONE; Debug( LDAP_DEBUG_ANY, "%s: glue/subordinate init failed\n", name, 0, 0 ); return 1; } if ( acl_init() ) { slap_debug |= LDAP_DEBUG_NONE; Debug( LDAP_DEBUG_ANY, "%s: acl_init failed\n", name, 0, 0 ); return 1; } return rc; }
int CheckDefaultClearACL(char *file_path, Attributes a, Promise *pp) { acl_t acl_existing; acl_t acl_empty; acl_entry_t ace_dummy; int retv; int result = false; acl_existing = NULL; acl_empty = NULL; if ((acl_existing = acl_get_file(file_path, ACL_TYPE_DEFAULT)) == NULL) { CfOut(OUTPUT_LEVEL_ERROR, "acl_get_file", "Unable to read default acl for %s", file_path); return false; } retv = acl_get_entry(acl_existing, ACL_FIRST_ENTRY, &ace_dummy); switch (retv) { case -1: CfOut(OUTPUT_LEVEL_VERBOSE, "acl_get_entry", "Couldn't retrieve ACE for %s", file_path); result = false; break; case 0: // no entries, as desired cfPS(OUTPUT_LEVEL_INFORM, CF_NOP, "", pp, a, "-> Default ACL on \"%s\" needs no modification.", file_path); result = true; break; case 1: // entries exist, set empty ACL if ((acl_empty = acl_init(0)) == NULL) { CfOut(OUTPUT_LEVEL_ERROR, "", "Could not reinitialize ACL for %s", file_path); result = false; break; } switch (a.transaction.action) { case cfa_warn: cfPS(OUTPUT_LEVEL_ERROR, CF_WARN, "", pp, a, " !! Default ACL on \"%s\" needs to be cleared", file_path); break; case cfa_fix: if (!DONTDO) { if (acl_set_file(file_path, ACL_TYPE_DEFAULT, acl_empty) != 0) { CfOut(OUTPUT_LEVEL_ERROR, "", "Could not reset ACL for %s", file_path); result = false; break; } } cfPS(OUTPUT_LEVEL_INFORM, CF_CHG, "", pp, a, "-> Default ACL on \"%s\" successfully cleared", file_path); result = true; break; default: ProgrammingError("Cfengine: internal error: illegal file action\n"); result = false; } break; default: result = false; } acl_free(acl_empty); acl_free(acl_existing); return result; }
/* * return an ACL corresponding to the permissions * contained in struct stat */ static acl_t acl_from_stat(struct stat sb) { acl_t acl; acl_entry_t entry; acl_permset_t perms; /* create the ACL */ acl = acl_init(3); if (!acl) return NULL; /* First entry: ACL_USER_OBJ */ if (acl_create_entry(&acl, &entry) == -1) return NULL; if (acl_set_tag_type(entry, ACL_USER_OBJ) == -1) return NULL; if (acl_get_permset(entry, &perms) == -1) return NULL; if (acl_clear_perms(perms) == -1) return NULL; /* calculate user mode */ if (sb.st_mode & S_IRUSR) if (acl_add_perm(perms, ACL_READ) == -1) return NULL; if (sb.st_mode & S_IWUSR) if (acl_add_perm(perms, ACL_WRITE) == -1) return NULL; if (sb.st_mode & S_IXUSR) if (acl_add_perm(perms, ACL_EXECUTE) == -1) return NULL; if (acl_set_permset(entry, perms) == -1) return NULL; /* Second entry: ACL_GROUP_OBJ */ if (acl_create_entry(&acl, &entry) == -1) return NULL; if (acl_set_tag_type(entry, ACL_GROUP_OBJ) == -1) return NULL; if (acl_get_permset(entry, &perms) == -1) return NULL; if (acl_clear_perms(perms) == -1) return NULL; /* calculate group mode */ if (sb.st_mode & S_IRGRP) if (acl_add_perm(perms, ACL_READ) == -1) return NULL; if (sb.st_mode & S_IWGRP) if (acl_add_perm(perms, ACL_WRITE) == -1) return NULL; if (sb.st_mode & S_IXGRP) if (acl_add_perm(perms, ACL_EXECUTE) == -1) return NULL; if (acl_set_permset(entry, perms) == -1) return NULL; /* Third entry: ACL_OTHER */ if (acl_create_entry(&acl, &entry) == -1) return NULL; if (acl_set_tag_type(entry, ACL_OTHER) == -1) return NULL; if (acl_get_permset(entry, &perms) == -1) return NULL; if (acl_clear_perms(perms) == -1) return NULL; /* calculate other mode */ if (sb.st_mode & S_IROTH) if (acl_add_perm(perms, ACL_READ) == -1) return NULL; if (sb.st_mode & S_IWOTH) if (acl_add_perm(perms, ACL_WRITE) == -1) return NULL; if (sb.st_mode & S_IXOTH) if (acl_add_perm(perms, ACL_EXECUTE) == -1) return NULL; if (acl_set_permset(entry, perms) == -1) return NULL; return(acl); }
/* 初始化函数 */ void service_init(void *init_ctx) { acl_init(); http_service_init(init_ctx); }
int modify_file_acl(unsigned int optflags, const char *path, acl_t modifier, int position, int inheritance_level, int follow) { acl_t oacl = NULL; unsigned aindex = 0, flag_new_acl = 0; acl_entry_t newent = NULL; acl_entry_t entry = NULL; unsigned retval = 0; extern int chmod_fflag; /* XXX acl_get_file() returns a zero entry ACL if an ACL was previously * associated with the file, and has had its entries removed. * However, POSIX 1003.1e states that a zero entry ACL should be * returned if the caller asks for ACL_TYPE_DEFAULT, and no ACL is * associated with the path; it * does not specifically state that a request for ACL_TYPE_EXTENDED * should not return a zero entry ACL, however. */ /* Determine if we've been given a zero entry ACL, or create an ACL if * none exists. There are some issues to consider here: Should we create * a zero-entry ACL for a delete or check canonicity operation? */ if (path == NULL) chmod_usage(); if (optflags & ACL_CLEAR_FLAG) { filesec_t fsec = filesec_init(); if (fsec == NULL) { // err(1, "filesec_init() failed"); fprintf(stderr, "chmod: filesec_init() failed: %s\n", strerror(errno)); pthread_exit(NULL); } if (filesec_set_property(fsec, FILESEC_ACL, _FILESEC_REMOVE_ACL) != 0) { // err(1, "filesec_set_property() failed"); fprintf(stderr, "chmod: filesec_set_property() failed: %s\n", strerror(errno)); pthread_exit(NULL); } if (follow) { if (chmodx_np(path, fsec) != 0) { if (!chmod_fflag) { // warn("Failed to clear ACL on file %s", path); fprintf(stderr, "chmod: Failed to clear ACL on file %s: %s\n", path, strerror(errno)); } retval = 1; } } else { int fd = open(path, O_SYMLINK); if (fd != -1) { if (fchmodx_np(fd, fsec) != 0) { if (!chmod_fflag) { fprintf(stderr, "chmod: Failed to clear ACL on file %s: %s\n", path, strerror(errno)); // warn("Failed to clear ACL on file %s", path); } retval = 1; } close(fd); } else { if (!chmod_fflag) { // warn("Failed to open file %s", path); fprintf(stderr, "chmod: Failed to open file %s: %s\n", path, strerror(errno)); } retval = 1; } } filesec_free(fsec); return (retval); } if (optflags & ACL_FROM_STDIN) { oacl = acl_dup(modifier); } else { if (follow) { oacl = acl_get_file(path, ACL_TYPE_EXTENDED); } else { int fd = open(path, O_SYMLINK); if (fd != -1) { oacl = acl_get_fd_np(fd, ACL_TYPE_EXTENDED); close(fd); } } if ((oacl == NULL) || (acl_get_entry(oacl,ACL_FIRST_ENTRY, &newent) != 0)) { if ((oacl = acl_init(1)) == NULL) { // err(1, "acl_init() failed"); fprintf(stderr, "chmod: acl_init() failed: %s\n", strerror(errno)); pthread_exit(NULL); } flag_new_acl = 1; position = 0; } if ((0 == flag_new_acl) && (optflags & (ACL_REMOVE_INHERIT_FLAG | ACL_REMOVE_INHERITED_ENTRIES))) { acl_t facl = NULL; if ((facl = acl_init(1)) == NULL) { //err(1, "acl_init() failed"); fprintf(stderr, "chmod: acl_init() failed: %s\n", strerror(errno)); pthread_exit(NULL); } for (aindex = 0; acl_get_entry(oacl, (entry == NULL ? ACL_FIRST_ENTRY : ACL_NEXT_ENTRY), &entry) == 0; aindex++) { acl_flagset_t eflags; acl_entry_t fent = NULL; if (acl_get_flagset_np(entry, &eflags) != 0) { fprintf(stderr, "chmod: Unable to obtain flagset: %s\n", strerror(errno)); pthread_exit(NULL); // err(1, "Unable to obtain flagset"); } if (acl_get_flag_np(eflags, ACL_ENTRY_INHERITED)) { if (optflags & ACL_REMOVE_INHERIT_FLAG) { acl_delete_flag_np(eflags, ACL_ENTRY_INHERITED); acl_set_flagset_np(entry, eflags); acl_create_entry(&facl, &fent); acl_copy_entry(fent, entry); } } else { acl_create_entry(&facl, &fent); acl_copy_entry(fent, entry); } } if (oacl) acl_free(oacl); oacl = facl; } else if (optflags & ACL_TO_STDOUT) { ssize_t len; /* need to get printacl() from ls(1) */ char *text = acl_to_text(oacl, &len); puts(text); acl_free(text); } else if (optflags & ACL_CHECK_CANONICITY) { if (flag_new_acl) { // warnx("No ACL currently associated with file '%s'", path); fprintf(stderr, "chmod: No ACL currently associated with file '%s'\n", path); } retval = is_canonical(oacl); } else if ((optflags & ACL_SET_FLAG) && (position == -1) && (!is_canonical(oacl))) { // warnx("The specified file '%s' does not have an ACL in canonical order, please specify a position with +a# ", path); fprintf(stderr, "chmod: The specified file '%s' does not have an ACL in canonical order, please specify a position with +a# \n", path); retval = 1; } else if (((optflags & ACL_DELETE_FLAG) && (position != -1)) || (optflags & ACL_CHECK_CANONICITY)) { retval = modify_acl(&oacl, NULL, optflags, position, inheritance_level, flag_new_acl, path); } else if ((optflags & (ACL_REMOVE_INHERIT_FLAG|ACL_REMOVE_INHERITED_ENTRIES)) && flag_new_acl) { // warnx("No ACL currently associated with file '%s'", path); fprintf(stderr, "chmod: No ACL currently associated with file '%s'\n", path); retval = 1; } else { if (!modifier) { /* avoid bus error in acl_get_entry */ // errx(1, "Internal error: modifier should not be NULL"); fprintf(stderr, "Internal error: modifier should not be NULL\n"); pthread_exit(NULL); } for (aindex = 0; acl_get_entry(modifier, (entry == NULL ? ACL_FIRST_ENTRY : ACL_NEXT_ENTRY), &entry) == 0; aindex++) { retval += modify_acl(&oacl, entry, optflags, position, inheritance_level, flag_new_acl, path); } } } /* XXX Potential race here, since someone else could've modified or * read the ACL on this file (with the intention of modifying it) in * the interval from acl_get_file() to acl_set_file(); we can * minimize one aspect of this window by comparing the original acl * to a fresh one from acl_get_file() but we could consider a * "changeset" mechanism, common locking strategy, or kernel * supplied reservation mechanism to prevent this race. */ if (!(optflags & (ACL_TO_STDOUT|ACL_CHECK_CANONICITY))) { int status = -1; if (follow) { status = acl_set_file(path, ACL_TYPE_EXTENDED, oacl); } else { int fd = open(path, O_SYMLINK); if (fd != -1) { status = acl_set_fd_np(fd, oacl, ACL_TYPE_EXTENDED); close(fd); } } if (status != 0) { if (!chmod_fflag) fprintf(stderr, "chmod: Failed to set ACL on file '%s': %s\n", path, strerror(errno)); // warn("Failed to set ACL on file '%s'", path); retval = 1; } } if (oacl) acl_free(oacl); return retval; }
int acl_readonly_example(uuid_t *uuid) { int fd; acl_t acl; acl_entry_t ace; acl_permset_t perms; filesec_t fsec; /* initialize our ACL */ if (NULL == (acl = acl_init(32))) err(1, "acl_init()"); /* * create an ACE * * acl_create_entry_np() has a position capability via the * 'entry_index' argument (ACL_FIRST_ENTRY or ACL_LAST_ENTRY) */ if (0 != acl_create_entry(&acl, &ace)) err(1, "acl_create_entry()"); /* allow or deny */ if (0 != acl_set_tag_type(ace, ACL_EXTENDED_ALLOW)) err(1, "acl_set_tag_type()"); /* associate this with our uuid */ if (0 != acl_set_qualifier(ace, uuid)) err(1, "acl_set_qualifier()"); /* grant "read only" permissions */ if (0 != acl_get_permset(ace, &perms)) err(1, "acl_get_permset()"); if (0 != acl_clear_perms(perms)) err(1, "acl_clear_perms()"); if (0 != acl_add_perm(perms, ROPERMS)) err(1, "acl_add_perm()"); if (0 != acl_set_permset(ace, perms)) err(1, "acl_set_permset()"); /* create a file security object */ fsec = filesec_init(); /* add the ACL to the security descriptor */ filesec_set_property(fsec, FILESEC_ACL, &acl); acl_free(acl); /* turn off all other permissions on the file */ filesec_set_property(fsec, FILESEC_MODE, 0); /* create a file using our ACL */ fd = openx_np("foo", O_CREAT|O_EXCL|O_RDWR, fsec); /* clean up */ filesec_free(fsec); if (-1 != fd ) close(fd); return(fd); }
int fpm_unix_resolve_socket_premissions(struct fpm_worker_pool_s *wp) /* {{{ */ { struct fpm_worker_pool_config_s *c = wp->config; #ifdef HAVE_FPM_ACL int n; /* uninitialized */ wp->socket_acl = NULL; #endif wp->socket_uid = -1; wp->socket_gid = -1; wp->socket_mode = 0660; if (!c) { return 0; } if (c->listen_mode && *c->listen_mode) { wp->socket_mode = strtoul(c->listen_mode, 0, 8); } #ifdef HAVE_FPM_ACL /* count the users and groups configured */ n = 0; if (c->listen_acl_users && *c->listen_acl_users) { char *p; n++; for (p=strchr(c->listen_acl_users, ',') ; p ; p=strchr(p+1, ',')) { n++; } } if (c->listen_acl_groups && *c->listen_acl_groups) { char *p; n++; for (p=strchr(c->listen_acl_groups, ',') ; p ; p=strchr(p+1, ',')) { n++; } } /* if ACL configured */ if (n) { acl_t acl; acl_entry_t entry; acl_permset_t perm; char *tmp, *p, *end; acl = acl_init(n); if (!acl) { zlog(ZLOG_SYSERROR, "[pool %s] cannot allocate ACL", wp->config->name); return -1; } /* Create USER ACL */ if (c->listen_acl_users && *c->listen_acl_users) { struct passwd *pwd; tmp = estrdup(c->listen_acl_users); for (p=tmp ; p ; p=end) { if ((end = strchr(p, ','))) { *end++ = 0; } pwd = getpwnam(p); if (pwd) { zlog(ZLOG_DEBUG, "[pool %s] user '%s' have uid=%d", wp->config->name, p, pwd->pw_uid); } else { zlog(ZLOG_SYSERROR, "[pool %s] cannot get uid for user '%s'", wp->config->name, p); acl_free(acl); efree(tmp); return -1; } if (0 > acl_create_entry(&acl, &entry) || 0 > acl_set_tag_type(entry, ACL_USER) || 0 > acl_set_qualifier(entry, &pwd->pw_uid) || 0 > acl_get_permset(entry, &perm) || 0 > acl_clear_perms (perm) || 0 > acl_add_perm (perm, ACL_READ) || 0 > acl_add_perm (perm, ACL_WRITE)) { zlog(ZLOG_SYSERROR, "[pool %s] cannot create ACL for user '%s'", wp->config->name, p); acl_free(acl); efree(tmp); return -1; } } efree(tmp); } /* Create GROUP ACL */ if (c->listen_acl_groups && *c->listen_acl_groups) { struct group *grp; tmp = estrdup(c->listen_acl_groups); for (p=tmp ; p ; p=end) { if ((end = strchr(p, ','))) { *end++ = 0; } grp = getgrnam(p); if (grp) { zlog(ZLOG_DEBUG, "[pool %s] group '%s' have gid=%d", wp->config->name, p, grp->gr_gid); } else { zlog(ZLOG_SYSERROR, "[pool %s] cannot get gid for group '%s'", wp->config->name, p); acl_free(acl); efree(tmp); return -1; } if (0 > acl_create_entry(&acl, &entry) || 0 > acl_set_tag_type(entry, ACL_GROUP) || 0 > acl_set_qualifier(entry, &grp->gr_gid) || 0 > acl_get_permset(entry, &perm) || 0 > acl_clear_perms (perm) || 0 > acl_add_perm (perm, ACL_READ) || 0 > acl_add_perm (perm, ACL_WRITE)) { zlog(ZLOG_SYSERROR, "[pool %s] cannot create ACL for group '%s'", wp->config->name, p); acl_free(acl); efree(tmp); return -1; } } efree(tmp); } if (c->listen_owner && *c->listen_owner) { zlog(ZLOG_WARNING, "[pool %s] ACL set, listen.owner = '%s' is ignored", wp->config->name, c->listen_owner); } if (c->listen_group && *c->listen_group) { zlog(ZLOG_WARNING, "[pool %s] ACL set, listen.group = '%s' is ignored", wp->config->name, c->listen_group); } wp->socket_acl = acl; return 0; } /* When listen.users and listen.groups not configured, continue with standard right */ #endif if (c->listen_owner && *c->listen_owner) { struct passwd *pwd; pwd = getpwnam(c->listen_owner); if (!pwd) { zlog(ZLOG_SYSERROR, "[pool %s] cannot get uid for user '%s'", wp->config->name, c->listen_owner); return -1; } wp->socket_uid = pwd->pw_uid; wp->socket_gid = pwd->pw_gid; } if (c->listen_group && *c->listen_group) { struct group *grp; grp = getgrnam(c->listen_group); if (!grp) { zlog(ZLOG_SYSERROR, "[pool %s] cannot get gid for group '%s'", wp->config->name, c->listen_group); return -1; } wp->socket_gid = grp->gr_gid; } return 0; }
static acl_t _posix1e_acl_strip_np(const acl_t aclp, int recalculate_mask) { acl_t acl_new, acl_old; acl_entry_t entry, entry_new; acl_permset_t perm; acl_tag_t tag; int entry_id, have_mask_entry; assert(_acl_brand(aclp) == ACL_BRAND_POSIX); acl_old = acl_dup(aclp); if (acl_old == NULL) return (NULL); assert(_acl_brand(acl_old) == ACL_BRAND_POSIX); have_mask_entry = 0; acl_new = acl_init(ACL_MAX_ENTRIES); if (acl_new == NULL) { acl_free(acl_old); return (NULL); } tag = ACL_UNDEFINED_TAG; /* only save the default user/group/other entries */ entry_id = ACL_FIRST_ENTRY; while (acl_get_entry(acl_old, entry_id, &entry) == 1) { entry_id = ACL_NEXT_ENTRY; assert(_entry_brand(entry) == ACL_BRAND_POSIX); if (acl_get_tag_type(entry, &tag) == -1) goto fail; switch(tag) { case ACL_USER_OBJ: case ACL_GROUP_OBJ: case ACL_OTHER: if (acl_get_tag_type(entry, &tag) == -1) goto fail; if (acl_get_permset(entry, &perm) == -1) goto fail; if (acl_create_entry(&acl_new, &entry_new) == -1) return (NULL); if (acl_set_tag_type(entry_new, tag) == -1) return (NULL); if (acl_set_permset(entry_new, perm) == -1) return (NULL); if (acl_copy_entry(entry_new, entry) == -1) return (NULL); assert(_entry_brand(entry_new) == ACL_BRAND_POSIX); break; case ACL_MASK: have_mask_entry = 1; break; default: break; } fail: acl_free(acl_new); acl_free(acl_old); return (NULL); } assert(_acl_brand(acl_new) == ACL_BRAND_POSIX); if (have_mask_entry && recalculate_mask) { if (acl_calc_mask(&acl_new) == -1) return (NULL); } return (acl_new); }
static acl_t smb_acl_to_posix(const struct smb_acl_t *acl) { acl_t result; int i; result = acl_init(acl->count); if (result == NULL) { DEBUG(10, ("acl_init failed\n")); return NULL; } for (i=0; i<acl->count; i++) { const struct smb_acl_entry *entry = &acl->acl[i]; acl_entry_t e; acl_tag_t tag; if (acl_create_entry(&result, &e) != 0) { DEBUG(1, ("acl_create_entry failed: %s\n", strerror(errno))); goto fail; } switch (entry->a_type) { case SMB_ACL_USER: tag = ACL_USER; break; case SMB_ACL_USER_OBJ: tag = ACL_USER_OBJ; break; case SMB_ACL_GROUP: tag = ACL_GROUP; break; case SMB_ACL_GROUP_OBJ: tag = ACL_GROUP_OBJ; break; case SMB_ACL_OTHER: tag = ACL_OTHER; break; case SMB_ACL_MASK: tag = ACL_MASK; break; default: DEBUG(1, ("Unknown tag value %d\n", entry->a_type)); goto fail; } if (acl_set_tag_type(e, tag) != 0) { DEBUG(10, ("acl_set_tag_type(%d) failed: %s\n", tag, strerror(errno))); goto fail; } switch (entry->a_type) { case SMB_ACL_USER: if (acl_set_qualifier(e, &entry->uid) != 0) { DEBUG(1, ("acl_set_qualifiier failed: %s\n", strerror(errno))); goto fail; } break; case SMB_ACL_GROUP: if (acl_set_qualifier(e, &entry->gid) != 0) { DEBUG(1, ("acl_set_qualifiier failed: %s\n", strerror(errno))); goto fail; } break; default: /* Shut up, compiler! :-) */ break; } if (smb_acl_set_mode(e, entry->a_perm) != 0) { goto fail; } } if (acl_valid(result) != 0) { DEBUG(0, ("smb_acl_to_posix: ACL is invalid for set (%s)\n", strerror(errno))); goto fail; } return result; fail: if (result != NULL) { acl_free(result); } return NULL; }
acl_t acl_from_text(const char *buf_p) { int i, error = 0, need_tag, ug_tag; char *buf, *orig_buf; char *entry, *field, *sub; uuid_t *uu = NULL; struct passwd *tpass = NULL; struct group *tgrp = NULL; acl_entry_t acl_entry; acl_flagset_t flags = NULL; acl_permset_t perms = NULL; acl_tag_t tag; acl_t acl_ret; if (buf_p == NULL) { errno = EINVAL; return NULL; } if ((buf = strdup(buf_p)) == NULL) return NULL; if ((acl_ret = acl_init(1)) == NULL) return NULL; orig_buf = buf; /* global acl flags * format: !#acl <version> [<flags>] */ if ((entry = strsep(&buf, "\n")) != NULL && *entry) { /* field 1: !#acl */ field = strsep(&entry, " "); if (*field && strncmp(field, "!#acl", strlen("!#acl"))) { error = EINVAL; goto exit; } /* field 2: <version> * currently only accepts 1 */ field = strsep(&entry, " "); errno = 0; if (!*field || strtol(field, NULL, 0) != 1) { error = EINVAL; goto exit; } /* field 3: <flags> * optional */ if((field = strsep(&entry, " ")) != NULL && *field) { acl_get_flagset_np(acl_ret, &flags); while ((sub = strsep(&field, ",")) && *sub) { for (i = 0; acl_flags[i].name != NULL; ++i) { if (acl_flags[i].type & ACL_TYPE_ACL && !strcmp(acl_flags[i].name, sub)) { acl_add_flag_np(flags, acl_flags[i].flag); break; } } if (acl_flags[i].name == NULL) { /* couldn't find flag */ error = EINVAL; goto exit; } } } } else { error = EINVAL; goto exit; } /* parse each acl line * format: <user|group>: * [<uuid>]: * [<user|group>]: * [<uid|gid>]: * <allow|deny>[,<flags>] * [:<permissions>[,<permissions>]] * * only one of the user/group identifies is required * the first one found is used */ while ((entry = strsep(&buf, "\n")) && *entry) { need_tag = 1; ug_tag = -1; /* field 1: <user|group> */ field = strsep(&entry, ":"); if(uu) bzero(uu, sizeof(uuid_t)); else if((uu = calloc(1, sizeof(uuid_t))) == NULL) { error = errno; goto exit; } if(acl_create_entry(&acl_ret, &acl_entry)) { error = errno; goto exit; } if (-1 == acl_get_flagset_np(acl_entry, &flags) || -1 == acl_get_permset(acl_entry, &perms)) { error = errno; goto exit; } switch(*field) { case 'u': if(!strcmp(field, "user")) ug_tag = ID_TYPE_UID; break; case 'g': if(!strcmp(field, "group")) ug_tag = ID_TYPE_GID; break; default: error = EINVAL; goto exit; } /* field 2: <uuid> */ if ((field = strsep(&entry, ":")) != NULL && *field) { uuid_parse(field, *uu); need_tag = 0; } /* field 3: <username|groupname> */ if ((field = strsep(&entry, ":")) != NULL && *field && need_tag) { switch(ug_tag) { case ID_TYPE_UID: if((tpass = getpwnam(field)) != NULL) if (mbr_uid_to_uuid(tpass->pw_uid, *uu) != 0) { error = EINVAL; goto exit; } break; case ID_TYPE_GID: if ((tgrp = getgrnam(field)) != NULL) if (mbr_gid_to_uuid(tgrp->gr_gid, *uu) != 0) { error = EINVAL; goto exit; } break; default: error = EINVAL; goto exit; } need_tag = 0; } /* field 4: <uid|gid> */ if ((field = strsep(&entry, ":")) != NULL && *field && need_tag) { uid_t id; error = 0; if((id = strtol(field, NULL, 10)) == 0 && error) { error = EINVAL; goto exit; } switch(ug_tag) { case ID_TYPE_UID: if((tpass = getpwuid((uid_t)id)) != NULL) if (mbr_uid_to_uuid(tpass->pw_uid, *uu) != 0) { error = EINVAL; goto exit; } break; case ID_TYPE_GID: if ((tgrp = getgrgid((gid_t)id)) != NULL) if (mbr_gid_to_uuid(tgrp->gr_gid, *uu) != 0) { error = EINVAL; goto exit; } break; } need_tag = 0; } /* sanity check: nothing set as qualifier */ if (need_tag) { error = EINVAL; goto exit; } /* field 5: <flags> */ if((field = strsep(&entry, ":")) == NULL || !*field) { error = EINVAL; goto exit; } for (tag = 0; (sub = strsep(&field, ",")) && *sub;) { if (!tag) { if (!strcmp(sub, "allow")) tag = ACL_EXTENDED_ALLOW; else if (!strcmp(sub, "deny")) tag = ACL_EXTENDED_DENY; else { error = EINVAL; goto exit; } continue; } for (i = 0; acl_flags[i].name != NULL; ++i) { if (acl_flags[i].type & (ACL_TYPE_FILE | ACL_TYPE_DIR) && !strcmp(acl_flags[i].name, sub)) { acl_add_flag_np(flags, acl_flags[i].flag); break; } } if (acl_flags[i].name == NULL) { /* couldn't find perm */ error = EINVAL; goto exit; } } /* field 6: <perms> (can be empty) */ if((field = strsep(&entry, ":")) != NULL && *field) { while ((sub = strsep(&field, ",")) && *sub) { for (i = 0; acl_perms[i].name != NULL; i++) { if (acl_perms[i].type & (ACL_TYPE_FILE | ACL_TYPE_DIR) && !strcmp(acl_perms[i].name, sub)) { acl_add_perm(perms, acl_perms[i].perm); break; } } if (acl_perms[i].name == NULL) { /* couldn't find perm */ error = EINVAL; goto exit; } } } acl_set_tag_type(acl_entry, tag); acl_set_qualifier(acl_entry, *uu); } exit: if(uu) free(uu); free(orig_buf); if (error) { acl_free(acl_ret); acl_ret = NULL; errno = error; } return acl_ret; }
/* * acl_from_text -- Convert a string into an ACL. * Postpone most validity checking until the end and call acl_valid() to do * that. */ acl_t acl_from_text(const char *buf_p) { acl_t acl; char *mybuf_p, *line, *cur, *notcomment, *comment, *entry; int error; /* Local copy we can mess up. */ mybuf_p = strdup(buf_p); if (mybuf_p == NULL) return(NULL); acl = acl_init(3); /* XXX: WTF, 3? */ if (acl == NULL) { free(mybuf_p); return(NULL); } /* Outer loop: delimit at \n boundaries. */ cur = mybuf_p; while ((line = strsep(&cur, "\n"))) { /* Now split the line on the first # to strip out comments. */ comment = line; notcomment = strsep(&comment, "#"); /* Inner loop: delimit at ',' boundaries. */ while ((entry = strsep(¬comment, ","))) { /* Skip empty lines. */ if (strlen(string_skip_whitespace(entry)) == 0) continue; if (_acl_brand(acl) == ACL_BRAND_UNKNOWN) { if (_text_is_nfs4_entry(entry)) _acl_brand_as(acl, ACL_BRAND_NFS4); else _acl_brand_as(acl, ACL_BRAND_POSIX); } switch (_acl_brand(acl)) { case ACL_BRAND_NFS4: error = _nfs4_acl_entry_from_text(acl, entry); break; case ACL_BRAND_POSIX: error = _posix1e_acl_entry_from_text(acl, entry); break; default: error = EINVAL; break; } if (error) goto error_label; } } #if 0 /* XXX Should we only return ACLs valid according to acl_valid? */ /* Verify validity of the ACL we read in. */ if (acl_valid(acl) == -1) { errno = EINVAL; goto error_label; } #endif free(mybuf_p); return(acl); error_label: acl_free(acl); free(mybuf_p); return(NULL); }
int CheckDefaultClearACL(EvalContext *ctx, const char *file_path, Attributes a, const Promise *pp, PromiseResult *result) { acl_t acl_existing; acl_t acl_empty; acl_entry_t ace_dummy; int retv; int retval = false; acl_existing = NULL; acl_empty = NULL; if ((acl_existing = acl_get_file(file_path, ACL_TYPE_DEFAULT)) == NULL) { Log(LOG_LEVEL_ERR, "Unable to read default acl for '%s'. (acl_get_file: %s)", file_path, GetErrorStr()); return false; } retv = acl_get_entry(acl_existing, ACL_FIRST_ENTRY, &ace_dummy); switch (retv) { case -1: Log(LOG_LEVEL_VERBOSE, "Couldn't retrieve ACE for '%s'. (acl_get_entry: %s)", file_path, GetErrorStr()); retval = false; break; case 0: // no entries, as desired cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Default ACL on '%s' needs no modification.", file_path); retval = true; break; case 1: // entries exist, set empty ACL if ((acl_empty = acl_init(0)) == NULL) { Log(LOG_LEVEL_ERR, "Could not reinitialize ACL for '%s'. (acl_init: %s)", file_path, GetErrorStr()); retval = false; break; } switch (a.transaction.action) { case cfa_warn: cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_WARN, pp, a, "Default ACL on '%s' needs to be cleared", file_path); *result = PromiseResultUpdate(*result, PROMISE_RESULT_WARN); break; case cfa_fix: if (!DONTDO) { if (acl_set_file(file_path, ACL_TYPE_DEFAULT, acl_empty) != 0) { Log(LOG_LEVEL_ERR, "Could not reset ACL for %s", file_path); retval = false; break; } } cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Default ACL on '%s' successfully cleared", file_path); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); retval = true; break; default: ProgrammingError("CFEngine: internal error: illegal file action"); retval = false; } break; default: retval = false; } acl_free(acl_empty); acl_free(acl_existing); return retval; }
/* ------------------------------------------------------------------------- *\ * FUNCTION main (argc, argv) * * -------------------------- * * Goes over configured host-groups and fishes for hosts in /var/state/n2 * * for some summary information. Prints out the information either in a CSV * * format (default), in XML (with -x) or as tabulated human-readable data * * (with -f). An optional groupname argument will limit the scope of the * * search to a single host-group. * \* ------------------------------------------------------------------------- */ int main (int argc, char *argv[]) { DIR *dir; struct dirent *de; FILE *fsumm; char *name; unsigned int addr; hostgroup *grp; int first=1; netload_rec *rec; hstat *info; unsigned long long netin, netout; int numwarn, numalert, numcrit; int rtt, count; int asxml; int ascsv; int asjson=0; int op; int firstmember=0; int firstgroup=1; char outline[256]; char addrbuf[32]; const char *groupname = NULL; ipnode *firstnode = NULL; ipnode *currentnode = NULL; ipnode *newnode = NULL; int isacked; asxml = 0; ascsv = 1; while ((op = getopt (argc, argv, "xfjg:")) > 0) { switch (op) { case 'x': asjson=0; asxml=1; ascsv=0; break; case 'f': asjson=0; ascsv=0; asxml=0; break; case 'j': asxml=0; ascsv=0; asjson=1; break; case 'g': groupname=optarg; break; } } conf_init (); acl_init (); load_config ("/etc/n2/n2rxd.conf"); if (asxml) { printf ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); printf ("<nl.madscience.svc.n2.groups>\n"); } else if ((!ascsv)&&(!asjson)) { printf ("Host Status Load CPU RTT " "Loss Net In/ Out i/o\n"); // Kb/s " } else if (asjson) { printf ("{"); } fsumm = fopen ("/var/state/n2/current/summary", "r"); if (! fsumm) { fprintf (stderr, "%% Error loading summary file\n"); return 1; } newnode = (ipnode *) malloc (sizeof (ipnode)); while (fread (newnode, sizeof (hstat), 1, fsumm) > 0) { newnode->next = NULL; if (currentnode) { currentnode->next = newnode; currentnode = newnode; } else { currentnode = firstnode = newnode; } newnode = (ipnode *) malloc (sizeof (ipnode)); } fclose (fsumm); free (newnode); grp = GROUPS.groups; while (grp) { if ((! groupname) || (! strcmp (groupname, grp->name))) { netin = netout = 0; numwarn = numalert = numcrit = rtt = count = 0; if (ascsv) { if (ascsv) printf ("%s:", grp->name); } else if (asjson) { if (firstgroup) firstgroup=0; else printf (","); printf ("\"%s\":{\"description\":\"%s\",\"members\":{", grp->name, grp->description); firstmember=1; } else if (asxml) { printf (" <group name=\"%s\" description=\"%s\">\n", grp->name, grp->description); printf (" <members>\n"); } first = 1; currentnode = firstnode; while (currentnode) { addr = currentnode->st.addr; printip (addr, addrbuf); if (grp == hostgroup_acl_resolve (addr)) { isacked = 0; if (asxml) { printf (" <member ip=\"%s\"", addrbuf); } else if (asjson) { if (firstmember) firstmember=0; else printf (","); printf ("\"%s\":{", addrbuf); } else if (ascsv) { printf ("%s%s", first ? "" : " ", addrbuf); } first = 0; info = &(currentnode->st); if (info) { if (CHKOFLAG(info->oflags,OFLAG_ACKED)) { // hide the flag, but keep it tracked. info->oflags ^= 1<<OFLAG_ACKED; isacked = 1; } else isacked = 0; if (asxml || asjson) { // FIXME@ koert: potential stack overflow here if error flags are added // or get longer names char flags[512]; flags[0] = '\0'; if( CHKSTATUSFLAG(info->status,FLAG_RTT) ) strcat(flags,", rtt"); if( CHKSTATUSFLAG(info->status,FLAG_LOSS) ) strcat(flags,", loss"); if( CHKSTATUSFLAG(info->status,FLAG_LOAD) ) strcat(flags,", load"); if( CHKOFLAG(info->oflags,OFLAG_RAM) ) strcat(flags,", ram"); if( CHKOFLAG(info->oflags,OFLAG_SWAP) ) strcat(flags,", swap"); if( CHKOFLAG(info->oflags,OFLAG_NETIN) ) strcat(flags,", netin"); if( CHKOFLAG(info->oflags,OFLAG_NETOUT) ) strcat(flags,", netout"); if( CHKOFLAG(info->oflags,OFLAG_SVCDOWN) ) strcat(flags,", svcdown"); if( CHKOFLAG(info->oflags,OFLAG_DISKIO) ) strcat(flags,", diskio"); if( CHKOFLAG(info->oflags,OFLAG_DISKSPACE) ) strcat(flags,", diskspace"); if( CHKOFLAG(info->oflags,OFLAG_DECODINGERR) ) strcat(flags,", decodingerr"); if( CHKOFLAG(info->oflags,OFLAG_IOWAIT) ) strcat(flags,", iowait"); // if( CHKSTATUSFLAG(info->status,FLAG_OTHER) ) strcat(flags,", other"); if (asxml) { printf (" netin=\"%u\" netout=\"%u\" " "rtt=\"%.1f\" cpu=\"%.2f\" " "loadavg=\"%.2f\" status=\"%s\" " "diskio=\"%u\" flags=\"%s\" ", info->netin, info->netout, ((double) info->ping10) / 10.0, ((double) info->cpu) / 2.56, ((double) info->load1) / 100.0, isacked ? "ACKED" : STR_STATUS[info->status & 15], info->diskio, *flags ? flags+2 : flags ); } else { printf ("\"netin\":%u,", info->netin); printf ("\"netout\":%u,", info->netout); printf ("\"rtt\":%.1f,", ((double)info->ping10)/10.0); printf ("\"cpu\":%.2f,",((double) info->cpu)/2.56); printf ("\"loadavg\":%.2f,",((double)info->load1)/100.0); printf ("\"status\":\"%s\",",isacked?"ACKED":STR_STATUS[info->status&15]); printf ("\"diskio\":%u,",info->diskio); printf ("\"flags\":\"%s\"", *flags?flags+2:flags); } } else if (! ascsv) { sprintf (outline, "%-17s ", addrbuf); sprintf (outline+18, "%s ", isacked ? "ACKED" : STR_STATUS[info->status&15]); if (info->status == ST_DEAD) { sprintf (outline+24, " -.-- -.-- %% " "%6.1f %3i %% -/ -" " -", ((double)info->ping10) / 10.0, info->loss/100 ); } else sprintf (outline+24, " %6.2f %6.2f %% " "%6.1f %3i %% %7i/%7i %7i", ((double) info->load1) / 100.0, ((double) info->cpu) / 2.56, ((double) info->ping10) / 10.0, info->loss/100, info->netin, info->netout, info->diskio); printf ("%s\n", outline); } netin += info->netin; netout += info->netout; rtt += info->ping10; if (ascsv) { switch (RDSTATUS(info->status)) { case ST_WARNING: if (isacked) break; printf ("=WARNING"); ++numwarn; break; case ST_STALE: case ST_ALERT: case ST_DEAD: if (isacked) break; printf ("=ALERT"); ++numalert; break; case ST_CRITICAL: if (isacked) break; printf ("=CRITICAL"); ++numcrit; break; default: printf ("=OK"); break; } } pool_free (info); } else { free (rec); } if (asxml) printf ("/>\n"); if (asjson) printf ("}"); ++count; } currentnode = currentnode->next; } if (asjson) { printf ("},\"summary\":{"); printf ("\"netin\":%u,", netin); printf ("\"netout\":%u,",netout); printf ("\"rtt\":%.1f,",((double)rtt/(10.0*((double)count)))); printf ("\"counts.warning\":%i,", numwarn); printf ("\"counts.alert\":%i,", numalert); printf ("\"counts.critical\":%i", numcrit); printf ("}}"); } else if (! asxml) { if (! count) count=1; if (ascsv) { printf (":%i:%llu:%llu:%.1f:%i:%i:%i\n", count, netin, netout, ((double) rtt / (10.0 * ((double) count))), numwarn, numalert, numcrit); } } else if (! ascsv) { printf (" </members>\n"); printf (" <summary>\n"); printf (" <netin>%u</netin>\n", netin); printf (" <netout>%u</netout>\n", netout); printf (" <rtt>%.1f</rtt>\n", ((double) rtt / (10.0 * ((double) count)))); printf (" <counts.warning>%i</counts.warning>\n", numwarn); printf (" <counts.alert>%i</counts.alert>\n", numalert); printf (" <counts.critical>%i</counts.critical>\n", numcrit); printf (" </summary>\n"); printf (" </group>\n"); } } grp = grp->next; } if (asxml) { printf ("</nl.madscience.svc.n2.groups>\n"); } if (asjson) printf ("}\n"); exit(0); }
int do_set( const char *path_p, const struct stat *st, const seq_t seq) { acl_t old_acl = NULL, old_default_acl = NULL; acl_t acl = NULL, default_acl = NULL; acl_t *xacl, *old_xacl; acl_entry_t ent; cmd_t cmd; int which_entry; int errors = 0, error; char *acl_text; int acl_modified = 0, default_acl_modified = 0; int acl_mask_provided = 0, default_acl_mask_provided = 0; /* Execute the commands in seq (read ACLs on demand) */ error = seq_get_cmd(seq, SEQ_FIRST_CMD, &cmd); if (error == 0) return 0; while (error == 1) { if (cmd->c_type == ACL_TYPE_ACCESS) { xacl = &acl; old_xacl = &old_acl; acl_modified = 1; if (cmd->c_tag == ACL_MASK) acl_mask_provided = 1; } else { xacl = &default_acl; old_xacl = &old_default_acl; default_acl_modified = 1; if (cmd->c_tag == ACL_MASK) default_acl_mask_provided = 1; } RETRIEVE_ACL(cmd->c_type); /* Check for `X', and replace with `x' as appropriate. */ if (cmd->c_perm & CMD_PERM_COND_EXECUTE) { cmd->c_perm &= ~CMD_PERM_COND_EXECUTE; if (S_ISDIR(st->st_mode) || has_execute_perms(*xacl)) cmd->c_perm |= CMD_PERM_EXECUTE; } switch(cmd->c_cmd) { case CMD_ENTRY_REPLACE: ent = find_entry(*xacl, cmd->c_tag, cmd->c_id); if (!ent) { if (acl_create_entry(xacl, &ent) != 0) goto fail; acl_set_tag_type(ent, cmd->c_tag); if (cmd->c_id != ACL_UNDEFINED_ID) acl_set_qualifier(ent, &cmd->c_id); } set_perm(ent, cmd->c_perm, ~cmd->c_perm); break; case CMD_ENTRY_ADD: ent = find_entry(*xacl, cmd->c_tag, cmd->c_id); if (ent) set_perm(ent, cmd->c_perm, 0); break; case CMD_ENTRY_SUBTRACT: ent = find_entry(*xacl, cmd->c_tag, cmd->c_id); if (ent) set_perm(ent, 0, cmd->c_perm); break; case CMD_REMOVE_ENTRY: ent = find_entry(*xacl, cmd->c_tag, cmd->c_id); if (ent) acl_delete_entry(*xacl, ent); else /* ignore */; break; case CMD_REMOVE_EXTENDED_ACL: remove_extended_entries(acl); break; case CMD_REMOVE_ACL: acl_free(*xacl); *xacl = acl_init(5); if (!*xacl) goto fail; break; default: errno = EINVAL; goto fail; } error = seq_get_cmd(seq, SEQ_NEXT_CMD, &cmd); } if (error < 0) goto fail; /* Try to fill in missing entries */ if (default_acl && acl_entries(default_acl) != 0) { xacl = &acl; old_xacl = &old_acl; if (!find_entry(default_acl, ACL_USER_OBJ, ACL_UNDEFINED_ID)) { if (!acl) RETRIEVE_ACL(ACL_TYPE_ACCESS); clone_entry(acl, ACL_USER_OBJ, &default_acl, ACL_USER_OBJ); } if (!find_entry(default_acl, ACL_GROUP_OBJ, ACL_UNDEFINED_ID)) { if (!acl) RETRIEVE_ACL(ACL_TYPE_ACCESS); clone_entry(acl, ACL_GROUP_OBJ, &default_acl, ACL_GROUP_OBJ); } if (!find_entry(default_acl, ACL_OTHER, ACL_UNDEFINED_ID)) { if (!acl) RETRIEVE_ACL(ACL_TYPE_ACCESS); clone_entry(acl, ACL_OTHER, &default_acl, ACL_OTHER); } } /* update mask entries and check if ACLs are valid */ if (acl && acl_modified) { if (acl_equiv_mode(acl, NULL) != 0) { if (!acl_mask_provided && !find_entry(acl, ACL_MASK, ACL_UNDEFINED_ID)) clone_entry(acl, ACL_GROUP_OBJ, &acl, ACL_MASK); if (opt_recalculate != -1 && (!acl_mask_provided || opt_recalculate == 1)) acl_calc_mask(&acl); } error = acl_check(acl, &which_entry); if (error < 0) goto fail; if (error > 0) { acl_text = acl_to_any_text(acl, NULL, ',', 0); fprintf(stderr, gettext("%s: %s: Malformed access ACL " "`%s': %s at entry %d\n"), progname, path_p, acl_text, acl_error(error), which_entry+1); acl_free(acl_text); errors++; goto cleanup; } } if (default_acl && acl_entries(default_acl) != 0 && default_acl_modified) { if (acl_equiv_mode(default_acl, NULL) != 0) { if (!default_acl_mask_provided && !find_entry(default_acl,ACL_MASK,ACL_UNDEFINED_ID)) clone_entry(default_acl, ACL_GROUP_OBJ, &default_acl, ACL_MASK); if (opt_recalculate != -1 && (!default_acl_mask_provided || opt_recalculate == 1)) acl_calc_mask(&default_acl); } error = acl_check(default_acl, &which_entry); if (error < 0) goto fail; if (error > 0) { acl_text = acl_to_any_text(default_acl, NULL, ',', 0); fprintf(stderr, gettext("%s: %s: Malformed default ACL " "`%s': %s at entry %d\n"), progname, path_p, acl_text, acl_error(error), which_entry+1); acl_free(acl_text); errors++; goto cleanup; } } /* Only directores can have default ACLs */ if (default_acl && !S_ISDIR(st->st_mode) && opt_recursive) { /* In recursive mode, ignore default ACLs for files */ acl_free(default_acl); default_acl = NULL; } /* check which ACLs have changed */ if (acl && old_acl && acl_cmp(old_acl, acl) == 0) { acl_free(acl); acl = NULL; } if ((default_acl && old_default_acl && acl_cmp(old_default_acl, default_acl) == 0)) { acl_free(default_acl); default_acl = NULL; } /* update the file system */ if (opt_test) { print_test(stdout, path_p, st, acl, default_acl); goto cleanup; } if (acl) { if (acl_set_file(path_p, ACL_TYPE_ACCESS, acl) != 0) { if (errno == ENOSYS || errno == ENOTSUP) { int saved_errno = errno; mode_t mode; if (acl_equiv_mode(acl, &mode) != 0) { errno = saved_errno; goto fail; } else if (chmod(path_p, mode) != 0) goto fail; } else goto fail; } } if (default_acl) { if (S_ISDIR(st->st_mode)) { if (acl_entries(default_acl) == 0) { if (acl_delete_def_file(path_p) != 0 && errno != ENOSYS && errno != ENOTSUP) goto fail; } else { if (acl_set_file(path_p, ACL_TYPE_DEFAULT, default_acl) != 0) goto fail; } } else { if (acl_entries(default_acl) != 0) { fprintf(stderr, gettext( "%s: %s: Only directories " "can have default ACLs\n"), progname, path_p); errors++; goto cleanup; } } } error = 0; cleanup: if (acl) acl_free(acl); if (old_acl) acl_free(old_acl); if (default_acl) acl_free(default_acl); if (old_default_acl) acl_free(old_default_acl); return errors; fail: fprintf(stderr, "%s: %s: %s\n", progname, path_p, strerror(errno)); errors++; goto cleanup; }
void acl_cpp_init(void) { acl_init(); }
static int set_acl(struct archive *a, int fd, const char *name, struct archive_acl *abstract_acl, acl_type_t acl_type, int ae_requested_type, const char *tname) { acl_t acl; acl_entry_t acl_entry; acl_permset_t acl_permset; #ifdef ACL_TYPE_NFS4 acl_flagset_t acl_flagset; int r; #endif int ret; int ae_type, ae_permset, ae_tag, ae_id; uid_t ae_uid; gid_t ae_gid; const char *ae_name; int entries; int i; ret = ARCHIVE_OK; entries = archive_acl_reset(abstract_acl, ae_requested_type); if (entries == 0) return (ARCHIVE_OK); acl = acl_init(entries); while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type, &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) { acl_create_entry(&acl, &acl_entry); switch (ae_tag) { case ARCHIVE_ENTRY_ACL_USER: acl_set_tag_type(acl_entry, ACL_USER); ae_uid = archive_write_disk_uid(a, ae_name, ae_id); acl_set_qualifier(acl_entry, &ae_uid); break; case ARCHIVE_ENTRY_ACL_GROUP: acl_set_tag_type(acl_entry, ACL_GROUP); ae_gid = archive_write_disk_gid(a, ae_name, ae_id); acl_set_qualifier(acl_entry, &ae_gid); break; case ARCHIVE_ENTRY_ACL_USER_OBJ: acl_set_tag_type(acl_entry, ACL_USER_OBJ); break; case ARCHIVE_ENTRY_ACL_GROUP_OBJ: acl_set_tag_type(acl_entry, ACL_GROUP_OBJ); break; case ARCHIVE_ENTRY_ACL_MASK: acl_set_tag_type(acl_entry, ACL_MASK); break; case ARCHIVE_ENTRY_ACL_OTHER: acl_set_tag_type(acl_entry, ACL_OTHER); break; #ifdef ACL_TYPE_NFS4 case ARCHIVE_ENTRY_ACL_EVERYONE: acl_set_tag_type(acl_entry, ACL_EVERYONE); break; #endif default: /* XXX */ break; } #ifdef ACL_TYPE_NFS4 switch (ae_type) { case ARCHIVE_ENTRY_ACL_TYPE_ALLOW: acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW); break; case ARCHIVE_ENTRY_ACL_TYPE_DENY: acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_DENY); break; case ARCHIVE_ENTRY_ACL_TYPE_AUDIT: acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_AUDIT); break; case ARCHIVE_ENTRY_ACL_TYPE_ALARM: acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALARM); break; case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: // These don't translate directly into the system ACL. break; default: // XXX error handling here. break; } #endif acl_get_permset(acl_entry, &acl_permset); acl_clear_perms(acl_permset); for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) { if (ae_permset & acl_perm_map[i].archive_perm) acl_add_perm(acl_permset, acl_perm_map[i].platform_perm); } #ifdef ACL_TYPE_NFS4 // XXX acl_get_flagset_np on FreeBSD returns EINVAL for // non-NFSv4 ACLs r = acl_get_flagset_np(acl_entry, &acl_flagset); if (r == 0) { acl_clear_flags_np(acl_flagset); for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) { if (ae_permset & acl_inherit_map[i].archive_inherit) acl_add_flag_np(acl_flagset, acl_inherit_map[i].platform_inherit); } } #endif } /* Try restoring the ACL through 'fd' if we can. */ #if HAVE_ACL_SET_FD if (fd >= 0 && acl_type == ACL_TYPE_ACCESS && acl_set_fd(fd, acl) == 0) ret = ARCHIVE_OK; else #else #if HAVE_ACL_SET_FD_NP if (fd >= 0 && acl_set_fd_np(fd, acl, acl_type) == 0) ret = ARCHIVE_OK; else #endif #endif #if HAVE_ACL_SET_LINK_NP if (acl_set_link_np(name, acl_type, acl) != 0) { archive_set_error(a, errno, "Failed to set %s acl", tname); ret = ARCHIVE_WARN; } #else /* TODO: Skip this if 'name' is a symlink. */ if (acl_set_file(name, acl_type, acl) != 0) { archive_set_error(a, errno, "Failed to set %s acl", tname); ret = ARCHIVE_WARN; } #endif acl_free(acl); return (ret); }
int qset_acl (char const *name, int desc, mode_t mode) { #if USE_ACL # if HAVE_ACL_GET_FILE /* POSIX 1003.1e draft 17 (abandoned) specific version. */ /* Linux, FreeBSD, MacOS X, IRIX, Tru64 */ # if MODE_INSIDE_ACL /* Linux, FreeBSD, IRIX, Tru64 */ /* We must also have acl_from_text and acl_delete_def_file. (acl_delete_def_file could be emulated with acl_init followed by acl_set_file, but acl_set_file with an empty acl is unspecified.) */ # ifndef HAVE_ACL_FROM_TEXT # error Must have acl_from_text (see POSIX 1003.1e draft 17). # endif # ifndef HAVE_ACL_DELETE_DEF_FILE # error Must have acl_delete_def_file (see POSIX 1003.1e draft 17). # endif acl_t acl; int ret; if (HAVE_ACL_FROM_MODE) /* Linux */ { acl = acl_from_mode (mode); if (!acl) return -1; } else /* FreeBSD, IRIX, Tru64 */ { /* If we were to create the ACL using the functions acl_init(), acl_create_entry(), acl_set_tag_type(), acl_set_qualifier(), acl_get_permset(), acl_clear_perm[s](), acl_add_perm(), we would need to create a qualifier. I don't know how to do this. So create it using acl_from_text(). */ # if HAVE_ACL_FREE_TEXT /* Tru64 */ char acl_text[] = "u::---,g::---,o::---,"; # else /* FreeBSD, IRIX */ char acl_text[] = "u::---,g::---,o::---"; # endif if (mode & S_IRUSR) acl_text[ 3] = 'r'; if (mode & S_IWUSR) acl_text[ 4] = 'w'; if (mode & S_IXUSR) acl_text[ 5] = 'x'; if (mode & S_IRGRP) acl_text[10] = 'r'; if (mode & S_IWGRP) acl_text[11] = 'w'; if (mode & S_IXGRP) acl_text[12] = 'x'; if (mode & S_IROTH) acl_text[17] = 'r'; if (mode & S_IWOTH) acl_text[18] = 'w'; if (mode & S_IXOTH) acl_text[19] = 'x'; acl = acl_from_text (acl_text); if (!acl) return -1; } if (HAVE_ACL_SET_FD && desc != -1) ret = acl_set_fd (desc, acl); else ret = acl_set_file (name, ACL_TYPE_ACCESS, acl); if (ret != 0) { int saved_errno = errno; acl_free (acl); if (ACL_NOT_WELL_SUPPORTED (errno)) return chmod_or_fchmod (name, desc, mode); else { errno = saved_errno; return -1; } } else acl_free (acl); if (S_ISDIR (mode) && acl_delete_def_file (name)) return -1; if (mode & (S_ISUID | S_ISGID | S_ISVTX)) { /* We did not call chmod so far, so the special bits have not yet been set. */ return chmod_or_fchmod (name, desc, mode); } return 0; # else /* !MODE_INSIDE_ACL */ /* MacOS X */ # if !HAVE_ACL_TYPE_EXTENDED # error Must have ACL_TYPE_EXTENDED # endif /* On MacOS X, acl_get_file (name, ACL_TYPE_ACCESS) and acl_get_file (name, ACL_TYPE_DEFAULT) always return NULL / EINVAL. You have to use acl_get_file (name, ACL_TYPE_EXTENDED) or acl_get_fd (open (name, ...)) to retrieve an ACL. On the other hand, acl_set_file (name, ACL_TYPE_ACCESS, acl) and acl_set_file (name, ACL_TYPE_DEFAULT, acl) have the same effect as acl_set_file (name, ACL_TYPE_EXTENDED, acl): Each of these calls sets the file's ACL. */ acl_t acl; int ret; /* Remove the ACL if the file has ACLs. */ if (HAVE_ACL_GET_FD && desc != -1) acl = acl_get_fd (desc); else acl = acl_get_file (name, ACL_TYPE_EXTENDED); if (acl) { acl_free (acl); acl = acl_init (0); if (acl) { if (HAVE_ACL_SET_FD && desc != -1) ret = acl_set_fd (desc, acl); else ret = acl_set_file (name, ACL_TYPE_EXTENDED, acl); if (ret != 0) { int saved_errno = errno; acl_free (acl); if (ACL_NOT_WELL_SUPPORTED (saved_errno)) return chmod_or_fchmod (name, desc, mode); else { errno = saved_errno; return -1; } } acl_free (acl); } } /* Since !MODE_INSIDE_ACL, we have to call chmod explicitly. */ return chmod_or_fchmod (name, desc, mode); # endif # elif HAVE_ACL && defined GETACLCNT /* Solaris, Cygwin, not HP-UX */ # if defined ACL_NO_TRIVIAL /* Solaris 10 (newer version), which has additional API declared in <sys/acl.h> (acl_t) and implemented in libsec (acl_set, acl_trivial, acl_fromtext, ...). */ acl_t *aclp; char acl_text[] = "user::---,group::---,mask:---,other:---"; int ret; int saved_errno; if (mode & S_IRUSR) acl_text[ 6] = 'r'; if (mode & S_IWUSR) acl_text[ 7] = 'w'; if (mode & S_IXUSR) acl_text[ 8] = 'x'; if (mode & S_IRGRP) acl_text[17] = acl_text[26] = 'r'; if (mode & S_IWGRP) acl_text[18] = acl_text[27] = 'w'; if (mode & S_IXGRP) acl_text[19] = acl_text[28] = 'x'; if (mode & S_IROTH) acl_text[36] = 'r'; if (mode & S_IWOTH) acl_text[37] = 'w'; if (mode & S_IXOTH) acl_text[38] = 'x'; if (acl_fromtext (acl_text, &aclp) != 0) { errno = ENOMEM; return -1; } ret = (desc < 0 ? acl_set (name, aclp) : facl_set (desc, aclp)); saved_errno = errno; acl_free (aclp); if (ret < 0) { if (saved_errno == ENOSYS || saved_errno == EOPNOTSUPP) return chmod_or_fchmod (name, desc, mode); errno = saved_errno; return -1; } if (mode & (S_ISUID | S_ISGID | S_ISVTX)) { /* We did not call chmod so far, so the special bits have not yet been set. */ return chmod_or_fchmod (name, desc, mode); } return 0; # else /* Solaris, Cygwin, general case */ # ifdef ACE_GETACL /* Solaris also has a different variant of ACLs, used in ZFS and NFSv4 file systems (whereas the other ones are used in UFS file systems). */ /* The flags in the ace_t structure changed in a binary incompatible way when ACL_NO_TRIVIAL etc. were introduced in <sys/acl.h> version 1.15. How to distinguish the two conventions at runtime? We fetch the existing ACL. In the old convention, usually three ACEs have a_flags = ACE_OWNER / ACE_GROUP / ACE_OTHER, in the range 0x0100..0x0400. In the new convention, these values are not used. */ int convention; { int count; ace_t *entries; for (;;) { if (desc != -1) count = facl (desc, ACE_GETACLCNT, 0, NULL); else count = acl (name, ACE_GETACLCNT, 0, NULL); if (count <= 0) { convention = -1; break; } entries = (ace_t *) malloc (count * sizeof (ace_t)); if (entries == NULL) { errno = ENOMEM; return -1; } if ((desc != -1 ? facl (desc, ACE_GETACL, count, entries) : acl (name, ACE_GETACL, count, entries)) == count) { int i; convention = 0; for (i = 0; i < count; i++) if (entries[i].a_flags & (ACE_OWNER | ACE_GROUP | ACE_OTHER)) { convention = 1; break; } free (entries); break; } /* Huh? The number of ACL entries changed since the last call. Repeat. */ free (entries); } } if (convention >= 0) { ace_t entries[3]; int ret; if (convention) { /* Running on Solaris 10. */ entries[0].a_type = ALLOW; entries[0].a_flags = ACE_OWNER; entries[0].a_who = 0; /* irrelevant */ entries[0].a_access_mask = (mode >> 6) & 7; entries[1].a_type = ALLOW; entries[1].a_flags = ACE_GROUP; entries[1].a_who = 0; /* irrelevant */ entries[1].a_access_mask = (mode >> 3) & 7; entries[2].a_type = ALLOW; entries[2].a_flags = ACE_OTHER; entries[2].a_who = 0; entries[2].a_access_mask = mode & 7; } else {