int CheckAccountAccess(ClientInfo *cp) { __pmHashNode *node; const char *userid; const char *groupid; userid = ((node = __pmHashSearch(PCP_ATTR_USERID, &cp->attrs)) ? (const char *)node->data : NULL); groupid = ((node = __pmHashSearch(PCP_ATTR_GROUPID, &cp->attrs)) ? (const char *)node->data : NULL); if (!userid || !groupid) if (__pmServerHasFeature(PM_SERVER_FEATURE_CREDS_REQD)) return PM_ERR_PERMISSION; return __pmAccAddAccount(userid, groupid, &cp->denyOps); }
int CheckAccountAccess(ClientInfo *cp) { __pmHashNode *node; const char *userid; const char *groupid; userid = ((node = __pmHashSearch(PCP_ATTR_USERID, &cp->attrs)) ? (const char *)node->data : NULL); groupid = ((node = __pmHashSearch(PCP_ATTR_GROUPID, &cp->attrs)) ? (const char *)node->data : NULL); #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_AUTH) fprintf(stderr, "CheckAccountAccess: client fd=%d userid=%s groupid=%s\n", cp->fd, userid, groupid); #endif if (!userid || !groupid) if (__pmServerHasFeature(PM_SERVER_FEATURE_CREDS_REQD)) return PM_ERR_PERMISSION; return __pmAccAddAccount(userid, groupid, &cp->denyOps); }
/* * Open request ports for client connections. * For each request port, open an inet and IPv6 (if supported) socket * for clients. Also open a local unix domain socket, if it has been * specified */ static int OpenRequestPorts(__pmFdSet *fdset, int backlog) { int i, fd, family, success = 0, maximum = -1; int with_ipv6 = strcmp(__pmGetAPIConfig("ipv6"), "true") == 0; for (i = 0; i < nReqPorts; i++) { ReqPortInfo *rp = &reqPorts[i]; int portsOpened = 0; /* * If the spec is NULL or "INADDR_ANY" or "INADDR_LOOPBACK", then * we open one socket for each address family (inet, IPv6). * Otherwise, the address family will be determined by * OpenRequestSocket. Reporting of all errors is left to * OpenRequestSocket to avoid doubling up. */ if (rp->address == NULL || strcmp(rp->address, "INADDR_ANY") == 0 || strcmp(rp->address, "INADDR_LOOPBACK") == 0) { family = AF_INET; if ((fd = OpenRequestSocket(rp->port, rp->address, &family, backlog, fdset, &maximum)) >= 0) { rp->fds[INET_FD] = fd; ++portsOpened; success = 1; } if (with_ipv6) { family = AF_INET6; if ((fd = OpenRequestSocket(rp->port, rp->address, &family, backlog, fdset, &maximum)) >= 0) { rp->fds[IPV6_FD] = fd; ++portsOpened; success = 1; } } else rp->fds[IPV6_FD] = -EPROTO; } else { family = AF_UNSPEC; if ((fd = OpenRequestSocket(rp->port, rp->address, &family, backlog, fdset, &maximum)) >= 0) { if (family == AF_INET) { rp->fds[INET_FD] = fd; ++portsOpened; success = 1; } else if (family == AF_INET6) { rp->fds[IPV6_FD] = fd; ++portsOpened; success = 1; } } } if (portsOpened > 0) { /* Advertise our presence on the network, if requested. */ if (serviceSpec != NULL && __pmServerHasFeature(PM_SERVER_FEATURE_DISCOVERY)) { rp->presence = __pmServerAdvertisePresence(serviceSpec, rp->port); } } } #ifndef IS_MINGW /* Open a local unix domain socket, if specified, and supported. */ if (localSocketPath != NULL) { #if defined(HAVE_STRUCT_SOCKADDR_UN) family = AF_UNIX; if ((localSocketFd = OpenRequestSocket(0, localSocketPath, &family, backlog, fdset, &maximum)) >= 0) { __pmServerSetFeature(PM_SERVER_FEATURE_UNIX_DOMAIN); success = 1; } #else __pmNotifyErr(LOG_ERR, "%s: unix domain sockets are not supported\n", pmProgname); #endif } #endif if (success) return maximum; __pmNotifyErr(LOG_ERR, "%s: can't open any request ports, exiting\n", pmProgname); return -1; }
static void CheckNewClient(__pmFdSet * fdset, int rfd, int family) { int s, sts, accepted = 1; __uint32_t challenge; ClientInfo *cp; if (__pmFD_ISSET(rfd, fdset)) { if ((cp = AcceptNewClient(rfd)) == NULL) return; /* Accept failed and no client added */ sts = __pmAccAddClient(cp->addr, &cp->denyOps); #if defined(HAVE_STRUCT_SOCKADDR_UN) if (sts >= 0 && family == AF_UNIX) { if ((sts = __pmServerSetLocalCreds(cp->fd, &cp->attrs)) < 0) { __pmNotifyErr(LOG_ERR, "ClientLoop: error extracting local credentials: %s", pmErrStr(sts)); } } #endif if (sts >= 0) { memset(&cp->pduInfo, 0, sizeof(cp->pduInfo)); cp->pduInfo.version = PDU_VERSION; cp->pduInfo.licensed = 1; if (__pmServerHasFeature(PM_SERVER_FEATURE_SECURE)) cp->pduInfo.features |= (PDU_FLAG_SECURE | PDU_FLAG_SECURE_ACK); if (__pmServerHasFeature(PM_SERVER_FEATURE_COMPRESS)) cp->pduInfo.features |= PDU_FLAG_COMPRESS; if (__pmServerHasFeature(PM_SERVER_FEATURE_AUTH)) /*optional*/ cp->pduInfo.features |= PDU_FLAG_AUTH; if (__pmServerHasFeature(PM_SERVER_FEATURE_CREDS_REQD)) /*required*/ cp->pduInfo.features |= PDU_FLAG_CREDS_REQD; if (__pmServerHasFeature(PM_SERVER_FEATURE_CONTAINERS)) cp->pduInfo.features |= PDU_FLAG_CONTAINER; challenge = *(__uint32_t *)(&cp->pduInfo); sts = 0; } else { challenge = 0; accepted = 0; } pmcd_trace(TR_XMIT_PDU, cp->fd, PDU_ERROR, sts); /* reset (no meaning, use fd table to version) */ cp->pduInfo.version = UNKNOWN_VERSION; s = __pmSendXtendError(cp->fd, FROM_ANON, sts, htonl(challenge)); if (s < 0) { __pmNotifyErr(LOG_ERR, "ClientLoop: error sending Conn ACK PDU to new client %s\n", pmErrStr(s)); if (sts >= 0) /* * prefer earlier failure status if any, else * use the one from __pmSendXtendError() */ sts = s; accepted = 0; } if (!accepted) CleanupClient(cp, sts); } }