add priv dropping

This commit is contained in:
Ron Pedde 2003-12-29 23:39:18 +00:00
parent 54a22bfee4
commit ad6a6b3d5e
8 changed files with 129 additions and 12 deletions

View File

@ -9,7 +9,7 @@
# Location of the admin web pages. This should be correct
#
web_root /usr/share/mt-daapd/admin-root
web_root /home/ron/working/mt-daapd/admin-root
#
# port (required)
@ -46,6 +46,18 @@ mp3_dir /mnt/mp3
servername mt-daapd
#
# runas (required)
#
# This is the user to drop privs to if running as
# root. If mt-daapd is not started as root, this
# configuration option is ignored. Notice that this
# must be specified whether the server is running
# as root or not.
#
runas nobody
#
# playlist (optional)
#
@ -59,7 +71,7 @@ servername mt-daapd
# specified
#
playlist /etc/mt-daapd.playlist
playlist /home/ron/mt-daapd.playlist
#
# password (optional)
@ -68,4 +80,7 @@ playlist /etc/mt-daapd.playlist
# i.e. the password that iTunes prompts for
#
#password mp3
#password mp3

View File

@ -72,6 +72,7 @@ typedef struct tag_configelement {
} CONFIGELEMENT;
CONFIGELEMENT config_elements[] = {
{ 1,1,0,CONFIG_TYPE_STRING,"runas",(void*)&config.runas,config_emit_string },
{ 1,1,0,CONFIG_TYPE_STRING,"web_root",(void*)&config.web_root,config_emit_string },
{ 1,1,0,CONFIG_TYPE_INT,"port",(void*)&config.port,config_emit_int },
{ 1,1,0,CONFIG_TYPE_STRING,"admin_pw",(void*)&config.adminpassword,config_emit_string },
@ -141,6 +142,7 @@ int config_read(char *file) {
config.readpassword=NULL;
config.mp3dir=NULL;
config.playlist=NULL;
config.runas=NULL;
config.servername="mt-daapd " VERSION;
while(fgets(buffer,MAX_LINE,fin)) {

View File

@ -41,6 +41,7 @@ typedef struct tag_config {
char *mp3dir;
char *servername;
char *playlist;
char *runas;
SONGENTRY songlist;
} CONFIG;

View File

@ -27,6 +27,7 @@
#include <fcntl.h>
#include <limits.h>
#include <pthread.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@ -379,6 +380,7 @@ int main(int argc, char *argv[]) {
int parseonly=0;
int foreground=0;
config.use_mdns=0;
struct passwd *pw=NULL;
#ifdef DEBUG
char *optval="d:c:mpf";
@ -420,6 +422,13 @@ int main(int argc, char *argv[]) {
}
}
#ifdef DEBUG
if(!foreground) {
fprintf(stderr,"WARNING: Debug mode: not detaching\n");
foreground=1;
}
#endif
/* read the configfile, if specified, otherwise
* try defaults */
@ -430,7 +439,24 @@ int main(int argc, char *argv[]) {
if((config.use_mdns) && (!parseonly)) {
fprintf(stderr,"Starting rendezvous daemon\n");
rend_init(&config.rend_pid,config.servername, config.port);
rend_init(&config.rend_pid,config.servername, config.port, config.runas);
}
/* drop privs */
if(getuid() == (uid_t)0) {
pw=getpwnam(config.runas);
if(pw) {
if(initgroups(config.runas,pw->pw_gid) != 0 ||
setgid(pw->pw_gid) != 0 ||
setuid(pw->pw_uid) != 0) {
fprintf(stderr,"Couldn't change to %s, gid=%d, uid=%d\n",
config.runas,pw->pw_gid, pw->pw_uid);
exit(EXIT_FAILURE);
}
} else {
fprintf(stderr,"Couldn't lookup user %s\n",config.runas);
exit(EXIT_FAILURE);
}
}
DPRINTF(ERR_DEBUG,"Initializing database\n");
@ -488,17 +514,17 @@ int main(int argc, char *argv[]) {
sleep(10);
if(config.use_mdns) {
fprintf(stderr,"Killing rendezvous daemon\n");
if(foreground) fprintf(stderr,"Killing rendezvous daemon\n");
kill(config.rend_pid,SIGINT);
wait(&status);
}
fprintf(stderr,"Stopping webserver\n");
if(foreground) fprintf(stderr,"Stopping webserver\n");
ws_stop(server);
config_close();
fprintf(stderr,"Closing database\n");
if(foreground) fprintf(stderr,"Closing database\n");
db_deinit();
#ifdef DEBUG
@ -506,7 +532,9 @@ int main(int argc, char *argv[]) {
err_leakcheck();
#endif
fprintf(stderr,"\nDone\n");
if(foreground) fprintf(stderr,"\nDone\n");
log_err(0,"Exiting");
return EXIT_SUCCESS;
}

View File

@ -21,9 +21,13 @@
#include <errno.h>
#include <stdio.h>
#include <pwd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <rendezvous/rendezvous.h>
#include <salt/log.h>
#include "err.h"
/*
@ -51,11 +55,30 @@ static sw_result rend_howl_reply(sw_rendezvous_publish_handler handler,
/*
* public interface
*/
int rend_init(pid_t *pid, char *name, int port) {
int rend_init(pid_t *pid, char *name, int port, char *user) {
sw_rendezvous rendezvous;
sw_result result;
sw_rendezvous_publish_id daap_id;
sw_rendezvous_publish_id http_id;
struct passwd *pw=NULL;
/* drop privs */
if(getuid() == (uid_t)0) {
pw=getpwnam(user);
if(pw) {
if(initgroups(user,pw->pw_gid) != 0 ||
setgid(pw->pw_gid) != 0 ||
setuid(pw->pw_uid) != 0) {
fprintf(stderr,"Couldn't change to %s, gid=%d, uid=%d\n",
user,pw->pw_gid, pw->pw_uid);
exit(EXIT_FAILURE);
}
} else {
fprintf(stderr,"Couldn't lookup user %s\n",user);
exit(EXIT_FAILURE);
}
}
if(sw_rendezvous_init(&rendezvous) != SW_OKAY) {
DPRINTF(ERR_WARN,"Error initializing rendezvous\n");

View File

@ -19,6 +19,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#include <libc.h>
#include <arpa/nameser.h>
#include <CoreFoundation/CoreFoundation.h>
@ -79,16 +83,36 @@ static void rend_reply(DNSServiceRegistrationReplyErrorType errorCode, void *con
/*
* public interface
*/
int rend_init(pid_t *pid, char *name, int port) {
int rend_init(pid_t *pid, char *name, int port, char *user) {
dns_service_discovery_ref daap_ref=NULL;
dns_service_discovery_ref http_ref=NULL;
unsigned short usPort=port;
struct passwd *pw=NULL;
*pid=fork();
if(*pid) {
return 0;
}
/* drop privs */
if(getuid() == (uid_t)0) {
pw=getpwnam(user);
if(pw) {
if(initgroups(user,pw->pw_gid) != 0 ||
setgid(pw->pw_gid) != 0 ||
setuid(pw->pw_uid) != 0) {
fprintf(stderr,"Couldn't change to %s, gid=%d, uid=%d\n",
user,pw->pw_gid, pw->pw_uid);
exit(EXIT_FAILURE);
}
} else {
fprintf(stderr,"Couldn't lookup user %s\n",user);
exit(EXIT_FAILURE);
}
}
signal(SIGINT, rend_sigint); // SIGINT is what you get for a Ctrl-C

View File

@ -89,6 +89,9 @@
Change History (most recent first):
$Log$
Revision 1.8 2003/12/29 23:39:18 ron
add priv dropping
Revision 1.7 2003/12/29 20:41:08 ron
Make sure all files have GPL notice
@ -132,6 +135,8 @@
#include <errno.h> // For errno, EINTR
#include <signal.h>
#include <fcntl.h>
#include <pwd.h>
#include <sys/types.h>
#define __IN_ERR__
#include "err.h"
@ -543,9 +548,10 @@ static void DeregisterOurServices(void)
#pragma mark **** Main
int rend_init(pid_t *pid,char *name, int port) {
int rend_init(pid_t *pid,char *name, int port, char user) {
mStatus status;
mDNSBool result;
struct passwd *pw=NULL;
status = mDNS_Init(&mDNSStorage, &PlatformStorage,
mDNS_Init_NoCache, mDNS_Init_ZeroCacheSize,
@ -562,6 +568,24 @@ int rend_init(pid_t *pid,char *name, int port) {
return 0;
}
/* drop privs */
if(getuid() == (uid_t)0) {
pw=getpwnam(user);
if(pw) {
if(initgroups(user,pw->pw_gid) != 0 ||
setgid(pw->pw_gid) != 0 ||
setuid(pw->pw_uid) != 0) {
fprintf(stderr,"Couldn't change to %s, gid=%d, uid=%d\n",
user,pw->pw_gid, pw->pw_uid);
exit(EXIT_FAILURE);
}
} else {
fprintf(stderr,"Couldn't lookup user %s\n",user);
exit(EXIT_FAILURE);
}
}
DPRINTF(ERR_DEBUG,"Registering tcp service\n");
RegisterOneService(name,"_http._tcp",NULL,0,port);
RegisterOneService(name,"_daap._tcp",NULL,0,port);

View File

@ -22,6 +22,6 @@
#ifndef _REND_H_
#define _REND_H_
int rend_init(pid_t *pid, char *name, int port);
int rend_init(pid_t *pid, char *name, int port, char *user);
#endif /* _REND_H_ */