int proc_update_privileges(int uid, int gid) { #ifdef HAVE_SETGROUPS /* Drop supplementary groups. */ if (uid != getuid() || gid != getgid()) { if (setgroups(0, NULL) < 0) { log_server_warning("Failed to drop supplementary groups" " for uid '%d' (%s).\n", getuid(), strerror(errno)); } } #endif /* Watch uid/gid. */ if (gid != getgid()) { log_server_info("Changing group id to '%d'.\n", gid); if (setregid(gid, gid) < 0) { log_server_error("Failed to change gid to '%d'.\n", gid); } } if (uid != getuid()) { log_server_info("Changing user id to '%d'.\n", uid); if (setreuid(uid, uid) < 0) { log_server_error("Failed to change uid to '%d'.\n", uid); } } /* Check storage writeability. */ int ret = KNOT_EOK; char *lfile = strcdup(conf()->storage, "/knot.lock"); assert(lfile != NULL); FILE* fp = fopen(lfile, "w"); if (fp == NULL) { log_server_warning("Storage directory '%s' is not writeable.\n", conf()->storage); ret = KNOT_EACCES; } else { fclose(fp); unlink(lfile); } free(lfile); return ret; }
int proc_update_privileges(int uid, int gid) { #ifdef HAVE_SETGROUPS /* Drop supplementary groups. */ if ((uid_t)uid != getuid() || (gid_t)gid != getgid()) { if (setgroups(0, NULL) < 0) { log_server_warning("Failed to drop supplementary groups" " for uid '%d' (%s).\n", getuid(), strerror(errno)); } # ifdef HAVE_INITGROUPS struct passwd *pw; if ((pw = getpwuid(uid)) == NULL) { log_server_warning("Failed to get passwd entry" " for uid '%d' (%s).\n", uid, strerror(errno)); } else { if (initgroups(pw->pw_name, gid) < 0) { log_server_warning("Failed to set supplementary groups" " for uid '%d' (%s).\n", uid, strerror(errno)); } } # endif /* HAVE_INITGROUPS */ } #endif /* HAVE_SETGROUPS */ /* Watch uid/gid. */ if ((gid_t)gid != getgid()) { log_server_info("Changing group id to '%d'.\n", gid); if (setregid(gid, gid) < 0) { log_server_error("Failed to change gid to '%d'.\n", gid); } } if ((uid_t)uid != getuid()) { log_server_info("Changing user id to '%d'.\n", uid); if (setreuid(uid, uid) < 0) { log_server_error("Failed to change uid to '%d'.\n", uid); } } /* Check storage writeability. */ int ret = KNOT_EOK; const bool sorted = false; hattrie_iter_t *z_iter = hattrie_iter_begin(conf()->zones, sorted); if (z_iter == NULL) { return KNOT_ERROR; } for (; !hattrie_iter_finished(z_iter); hattrie_iter_next(z_iter)) { conf_zone_t *zone = (conf_zone_t *)*hattrie_iter_val(z_iter); char *lfile = strcdup(zone->storage, "/knot.lock"); assert(lfile != NULL); FILE* fp = fopen(lfile, "w"); if (fp == NULL) { log_server_warning("Storage directory '%s' is not " "writeable.\n", zone->storage); ret = KNOT_EACCES; } else { fclose(fp); unlink(lfile); } free(lfile); if (ret != KNOT_EOK) { break; } } hattrie_iter_free(z_iter); return ret; }
int notify_process_request(knot_nameserver_t *ns, knot_packet_t *notify, sockaddr_t *from, uint8_t *buffer, size_t *size) { /*! \todo Most of this function is identical to xfrin_transfer_needed() * - it will be fine to merge the code somehow. */ if (notify == NULL || ns == NULL || buffer == NULL || size == NULL || from == NULL) { dbg_notify("notify: invalid parameters for %s()\n", "notify_process_request"); return KNOT_EINVAL; } int ret = KNOT_EOK; dbg_notify("notify: parsing rest of the packet\n"); if (notify->parsed < notify->size) { if (knot_packet_parse_rest(notify, 0) != KNOT_EOK) { dbg_notify("notify: failed to parse NOTIFY query\n"); knot_ns_error_response_from_query(ns, notify, KNOT_RCODE_FORMERR, buffer, size); return KNOT_EOK; } } // check if it makes sense - if the QTYPE is SOA if (knot_packet_qtype(notify) != KNOT_RRTYPE_SOA) { // send back FORMERR knot_ns_error_response_from_query(ns, notify, KNOT_RCODE_FORMERR, buffer, size); return KNOT_EOK; } // create NOTIFY response dbg_notify("notify: creating response\n"); ret = notify_create_response(notify, buffer, size); if (ret != KNOT_EOK) { dbg_notify("notify: failed to create NOTIFY response\n"); knot_ns_error_response_from_query(ns, notify, KNOT_RCODE_SERVFAIL, buffer, size); return KNOT_EOK; } /* Process notification. */ ret = KNOT_ENOZONE; unsigned serial = 0; const knot_dname_t *qname = knot_packet_qname(notify); rcu_read_lock(); /* z */ const knot_zone_t *z = knot_zonedb_find_zone_for_name(ns->zone_db, qname); if (z != NULL) { ret = notify_check_and_schedule(ns, z, from); const knot_rrset_t *soa_rr = NULL; soa_rr = knot_packet_answer_rrset(notify, 0); if (soa_rr && knot_rrset_type(soa_rr) == KNOT_RRTYPE_SOA) { serial = knot_rrset_rdata_soa_serial(soa_rr); } } rcu_read_unlock(); int rcode = KNOT_RCODE_NOERROR; switch (ret) { case KNOT_ENOZONE: rcode = KNOT_RCODE_NOTAUTH; break; case KNOT_EACCES: rcode = KNOT_RCODE_REFUSED; break; default: break; } /* Format resulting log message. */ char *qstr = knot_dname_to_str(qname); char *fromstr = xfr_remote_str(from, NULL); if (rcode != KNOT_RCODE_NOERROR) { knot_ns_error_response_from_query(ns, notify, KNOT_RCODE_REFUSED, buffer, size); log_server_warning(NOTIFY_MSG "%s\n", qstr, fromstr, knot_strerror(ret)); ret = KNOT_EOK; /* Send response. */ } else { log_server_info(NOTIFY_MSG NOTIFY_XMSG "\n", qstr, fromstr, serial); } free(qstr); free(fromstr); return ret; }