diff --git a/usr.sbin/sdpd/main.c b/usr.sbin/sdpd/main.c index fe42456c4ad4..8252e523c0f9 100644 --- a/usr.sbin/sdpd/main.c +++ b/usr.sbin/sdpd/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.1 2006/06/19 15:44:56 gdamore Exp $ */ +/* $NetBSD: main.c,v 1.2 2007/03/18 10:00:42 plunky Exp $ */ /* * main.c @@ -27,7 +27,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: main.c,v 1.1 2006/06/19 15:44:56 gdamore Exp $ + * $Id: main.c,v 1.2 2007/03/18 10:00:42 plunky Exp $ * $FreeBSD: src/usr.sbin/bluetooth/sdpd/main.c,v 1.1 2004/01/20 20:48:26 emax Exp $ */ @@ -35,7 +35,7 @@ __COPYRIGHT("@(#) Copyright (c) 2006 Itronix, Inc.\n" "@(#) Copyright (c) 2004 Maksim Yevmenkin \n" "All rights reserved.\n"); -__RCSID("$NetBSD: main.c,v 1.1 2006/06/19 15:44:56 gdamore Exp $"); +__RCSID("$NetBSD: main.c,v 1.2 2007/03/18 10:00:42 plunky Exp $"); #include #include @@ -75,10 +75,11 @@ main(int argc, char *argv[]) server_t server; char const *control = SDP_LOCAL_PATH; char const *user = "nobody", *group = "nobody"; + char const *sgroup = NULL; int32_t detach = 1, opt; struct sigaction sa; - while ((opt = getopt(argc, argv, "c:dg:hu:")) != -1) { + while ((opt = getopt(argc, argv, "c:dG:g:hu:")) != -1) { switch (opt) { case 'c': /* control */ control = optarg; @@ -88,6 +89,10 @@ main(int argc, char *argv[]) detach = 0; break; + case 'G': /* super group */ + sgroup = optarg; + break; + case 'g': /* group */ group = optarg; break; @@ -132,7 +137,7 @@ main(int argc, char *argv[]) } /* Initialize server */ - if (server_init(&server, control) < 0) + if (server_init(&server, control, sgroup) < 0) exit(1); if ((user != NULL || group != NULL) && drop_root(user, group) < 0) @@ -234,6 +239,7 @@ usage(void) "Where options are:\n" \ " -c specify control socket name (default %s)\n" \ " -d do not detach (run in foreground)\n" \ +" -G grp allow privileges to group\n" \ " -g grp specify group\n" \ " -h display usage and exit\n" \ " -u usr specify user\n", diff --git a/usr.sbin/sdpd/sdpd.8 b/usr.sbin/sdpd/sdpd.8 index 1bf9ce0334e6..f0e3a18313b6 100644 --- a/usr.sbin/sdpd/sdpd.8 +++ b/usr.sbin/sdpd/sdpd.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: sdpd.8,v 1.1 2006/06/19 15:44:56 gdamore Exp $ +.\" $NetBSD: sdpd.8,v 1.2 2007/03/18 10:00:42 plunky Exp $ .\" .\" Copyright (c) 2004 Maksim Yevmenkin .\" All rights reserved. @@ -24,7 +24,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: sdpd.8,v 1.1 2006/06/19 15:44:56 gdamore Exp $ +.\" $Id: sdpd.8,v 1.2 2007/03/18 10:00:42 plunky Exp $ .\" $FreeBSD: src/usr.sbin/bluetooth/sdpd/sdpd.8,v 1.5 2005/12/06 17:56:36 emax Exp $ .\" .Dd January 13, 2004 @@ -37,6 +37,7 @@ .Nm .Op Fl dh .Op Fl c Ar path +.Op Fl G Ar group .Op Fl g Ar group .Op Fl u Ar user .Sh DESCRIPTION @@ -77,6 +78,12 @@ Do not detach from the controlling terminal. Specify path to the control socket. The default path is .Pa /var/run/sdp . +.It Fl G Ar group +Grant permission to members of the +.Ar group +to modify the +.Nm +Service Database. .It Fl g Ar group Specifies the group the .Nm @@ -116,10 +123,11 @@ Requests to register, remove or change service can only be made via the control socket. The .Nm -daemon will check peer's credentials and will only accept the request if -the application has the same effective user ID as the -.Dq Li root -user ID. +daemon will check the peer's credentials and will only accept the request +when the peer is the superuser, of if the peer is a member of the group +specified with the +.Fl G +option. .Pp The .Nm diff --git a/usr.sbin/sdpd/server.c b/usr.sbin/sdpd/server.c index b7a664749d68..fba06a8f157c 100644 --- a/usr.sbin/sdpd/server.c +++ b/usr.sbin/sdpd/server.c @@ -1,4 +1,4 @@ -/* $NetBSD: server.c,v 1.2 2007/02/22 20:49:32 plunky Exp $ */ +/* $NetBSD: server.c,v 1.3 2007/03/18 10:00:42 plunky Exp $ */ /*- * Copyright (c) 2006 Itronix Inc. @@ -55,12 +55,12 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: server.c,v 1.2 2007/02/22 20:49:32 plunky Exp $ + * $Id: server.c,v 1.3 2007/03/18 10:00:42 plunky Exp $ * $FreeBSD: src/usr.sbin/bluetooth/sdpd/server.c,v 1.2 2005/12/06 17:56:36 emax Exp $ */ #include -__RCSID("$NetBSD: server.c,v 1.2 2007/02/22 20:49:32 plunky Exp $"); +__RCSID("$NetBSD: server.c,v 1.3 2007/03/18 10:00:42 plunky Exp $"); #include #include @@ -73,6 +73,7 @@ __RCSID("$NetBSD: server.c,v 1.2 2007/02/22 20:49:32 plunky Exp $"); #include #include #include +#include #include #include #include @@ -89,13 +90,14 @@ static int32_t server_process_request (server_p srv, int32_t fd); static int32_t server_send_error_response (server_p srv, int32_t fd, uint16_t error); static void server_close_fd (server_p srv, int32_t fd); +static int server_auth_check (server_p srv, struct sockcred *cred); /* * Initialize server */ int32_t -server_init(server_p srv, char const *control) +server_init(server_p srv, char const *control, char const *sgroup) { struct sockaddr_un un; struct sockaddr_bt l2; @@ -108,6 +110,7 @@ server_init(server_p srv, char const *control) assert(control != NULL); memset(srv, 0, sizeof(srv)); + srv->sgroup = sgroup; /* Open control socket */ if (unlink(control) < 0 && errno != ENOENT) { @@ -423,7 +426,6 @@ server_process_request(server_p srv, int32_t fd) struct iovec iov; int32_t len, error; struct cmsghdr *cmsg; - struct sockcred *cred; assert(srv->imtu > 0); assert(srv->req != NULL); @@ -463,10 +465,9 @@ server_process_request(server_p srv, int32_t fd) if ((cmsg = CMSG_FIRSTHDR(&msg)) != NULL && cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDS - && cmsg->cmsg_len >= CMSG_LEN(SOCKCREDSIZE(0)) - && (cred = (struct sockcred *)CMSG_DATA(cmsg)) != NULL - && (cred->sc_uid == 0 || cred->sc_euid == 0)) - srv->fdidx[fd].priv = 1; + && cmsg->cmsg_len >= CMSG_LEN(SOCKCREDSIZE(0))) + srv->fdidx[fd].priv = + server_auth_check(srv, (struct sockcred *)CMSG_DATA(cmsg)); if (len >= sizeof(*pdu) && (sizeof(*pdu) + (pdu->len = ntohs(pdu->len))) == len) { @@ -622,3 +623,36 @@ server_close_fd(server_p srv, int32_t fd) provider_unregister(provider); } } + +static int +server_auth_check(server_p srv, struct sockcred *cred) +{ + struct group *grp; + int n; + + if (cred == NULL) + return 0; + + if (cred->sc_uid == 0 || cred->sc_euid == 0) + return 1; + + if (srv->sgroup == NULL) + return 0; + + grp = getgrnam(srv->sgroup); + if (grp == NULL) { + log_err("No gid for group '%s'", srv->sgroup); + srv->sgroup = NULL; + return 0; + } + + if (cred->sc_gid == grp->gr_gid || cred->sc_egid == grp->gr_gid) + return 1; + + for (n = 0 ; n < cred->sc_ngroups ; n++) { + if (cred->sc_groups[n] == grp->gr_gid) + return 1; + } + + return 0; +} diff --git a/usr.sbin/sdpd/server.h b/usr.sbin/sdpd/server.h index 125d47b2c0fe..ebc39c4a8042 100644 --- a/usr.sbin/sdpd/server.h +++ b/usr.sbin/sdpd/server.h @@ -1,4 +1,4 @@ -/* $NetBSD: server.h,v 1.1 2006/06/19 15:44:56 gdamore Exp $ */ +/* $NetBSD: server.h,v 1.2 2007/03/18 10:00:43 plunky Exp $ */ /*- * Copyright (c) 2006 Itronix Inc. @@ -55,7 +55,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: server.h,v 1.1 2006/06/19 15:44:56 gdamore Exp $ + * $Id: server.h,v 1.2 2007/03/18 10:00:43 plunky Exp $ * $FreeBSD: src/usr.sbin/bluetooth/sdpd/server.h,v 1.2 2005/12/06 17:56:36 emax Exp $ */ @@ -95,6 +95,7 @@ struct server fd_set fdset; /* current descriptor set */ fd_idx_p fdidx; /* descriptor index */ struct sockaddr_bt req_sa; /* local address */ + const char *sgroup; /* privileged group */ }; typedef struct server server_t; @@ -104,7 +105,7 @@ typedef struct server * server_p; * External API */ -int32_t server_init(server_p srv, const char *control); +int32_t server_init(server_p srv, const char *control, char const *sgroup); void server_shutdown(server_p srv); int32_t server_do(server_p srv);