Add an option to permit members of a specific group to register services, in

order to lower the barrier for users of bluetooth devices which may need to
query services on the local host.
This commit is contained in:
plunky 2007-03-18 10:00:42 +00:00
parent ca549fcb8e
commit 5c5f46b32b
4 changed files with 72 additions and 23 deletions

View File

@ -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 <m_evmenkin@yahoo.com>\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 <sys/select.h>
#include <bluetooth.h>
@ -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",

View File

@ -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 <m_evmenkin@yahoo.com>
.\" 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

View File

@ -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 <sys/cdefs.h>
__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 <sys/param.h>
#include <sys/select.h>
@ -73,6 +73,7 @@ __RCSID("$NetBSD: server.c,v 1.2 2007/02/22 20:49:32 plunky Exp $");
#include <assert.h>
#include <bluetooth.h>
#include <errno.h>
#include <grp.h>
#include <pwd.h>
#include <sdp.h>
#include <stdio.h>
@ -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;
}

View File

@ -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);