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 # 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) # port (required)
@ -46,6 +46,18 @@ mp3_dir /mnt/mp3
servername mt-daapd 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) # playlist (optional)
# #
@ -59,7 +71,7 @@ servername mt-daapd
# specified # specified
# #
playlist /etc/mt-daapd.playlist playlist /home/ron/mt-daapd.playlist
# #
# password (optional) # password (optional)
@ -69,3 +81,6 @@ playlist /etc/mt-daapd.playlist
# #
#password mp3 #password mp3

View File

@ -72,6 +72,7 @@ typedef struct tag_configelement {
} CONFIGELEMENT; } CONFIGELEMENT;
CONFIGELEMENT config_elements[] = { 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_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_INT,"port",(void*)&config.port,config_emit_int },
{ 1,1,0,CONFIG_TYPE_STRING,"admin_pw",(void*)&config.adminpassword,config_emit_string }, { 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.readpassword=NULL;
config.mp3dir=NULL; config.mp3dir=NULL;
config.playlist=NULL; config.playlist=NULL;
config.runas=NULL;
config.servername="mt-daapd " VERSION; config.servername="mt-daapd " VERSION;
while(fgets(buffer,MAX_LINE,fin)) { while(fgets(buffer,MAX_LINE,fin)) {

View File

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

View File

@ -27,6 +27,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <limits.h> #include <limits.h>
#include <pthread.h> #include <pthread.h>
#include <pwd.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -379,6 +380,7 @@ int main(int argc, char *argv[]) {
int parseonly=0; int parseonly=0;
int foreground=0; int foreground=0;
config.use_mdns=0; config.use_mdns=0;
struct passwd *pw=NULL;
#ifdef DEBUG #ifdef DEBUG
char *optval="d:c:mpf"; 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 /* read the configfile, if specified, otherwise
* try defaults */ * try defaults */
@ -430,7 +439,24 @@ int main(int argc, char *argv[]) {
if((config.use_mdns) && (!parseonly)) { if((config.use_mdns) && (!parseonly)) {
fprintf(stderr,"Starting rendezvous daemon\n"); 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"); DPRINTF(ERR_DEBUG,"Initializing database\n");
@ -488,17 +514,17 @@ int main(int argc, char *argv[]) {
sleep(10); sleep(10);
if(config.use_mdns) { if(config.use_mdns) {
fprintf(stderr,"Killing rendezvous daemon\n"); if(foreground) fprintf(stderr,"Killing rendezvous daemon\n");
kill(config.rend_pid,SIGINT); kill(config.rend_pid,SIGINT);
wait(&status); wait(&status);
} }
fprintf(stderr,"Stopping webserver\n"); if(foreground) fprintf(stderr,"Stopping webserver\n");
ws_stop(server); ws_stop(server);
config_close(); config_close();
fprintf(stderr,"Closing database\n"); if(foreground) fprintf(stderr,"Closing database\n");
db_deinit(); db_deinit();
#ifdef DEBUG #ifdef DEBUG
@ -506,7 +532,9 @@ int main(int argc, char *argv[]) {
err_leakcheck(); err_leakcheck();
#endif #endif
fprintf(stderr,"\nDone\n"); if(foreground) fprintf(stderr,"\nDone\n");
log_err(0,"Exiting");
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -21,9 +21,13 @@
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <pwd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <rendezvous/rendezvous.h> #include <rendezvous/rendezvous.h>
#include <salt/log.h> #include <salt/log.h>
#include "err.h" #include "err.h"
/* /*
@ -51,11 +55,30 @@ static sw_result rend_howl_reply(sw_rendezvous_publish_handler handler,
/* /*
* public interface * 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_rendezvous rendezvous;
sw_result result; sw_result result;
sw_rendezvous_publish_id daap_id; sw_rendezvous_publish_id daap_id;
sw_rendezvous_publish_id http_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) { if(sw_rendezvous_init(&rendezvous) != SW_OKAY) {
DPRINTF(ERR_WARN,"Error initializing rendezvous\n"); 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 * 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 <libc.h>
#include <arpa/nameser.h> #include <arpa/nameser.h>
#include <CoreFoundation/CoreFoundation.h> #include <CoreFoundation/CoreFoundation.h>
@ -79,16 +83,36 @@ static void rend_reply(DNSServiceRegistrationReplyErrorType errorCode, void *con
/* /*
* public interface * 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 daap_ref=NULL;
dns_service_discovery_ref http_ref=NULL; dns_service_discovery_ref http_ref=NULL;
unsigned short usPort=port; unsigned short usPort=port;
struct passwd *pw=NULL;
*pid=fork(); *pid=fork();
if(*pid) { if(*pid) {
return 0; 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 signal(SIGINT, rend_sigint); // SIGINT is what you get for a Ctrl-C

View File

@ -89,6 +89,9 @@
Change History (most recent first): Change History (most recent first):
$Log$ $Log$
Revision 1.8 2003/12/29 23:39:18 ron
add priv dropping
Revision 1.7 2003/12/29 20:41:08 ron Revision 1.7 2003/12/29 20:41:08 ron
Make sure all files have GPL notice Make sure all files have GPL notice
@ -132,6 +135,8 @@
#include <errno.h> // For errno, EINTR #include <errno.h> // For errno, EINTR
#include <signal.h> #include <signal.h>
#include <fcntl.h> #include <fcntl.h>
#include <pwd.h>
#include <sys/types.h>
#define __IN_ERR__ #define __IN_ERR__
#include "err.h" #include "err.h"
@ -543,9 +548,10 @@ static void DeregisterOurServices(void)
#pragma mark **** Main #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; mStatus status;
mDNSBool result; mDNSBool result;
struct passwd *pw=NULL;
status = mDNS_Init(&mDNSStorage, &PlatformStorage, status = mDNS_Init(&mDNSStorage, &PlatformStorage,
mDNS_Init_NoCache, mDNS_Init_ZeroCacheSize, mDNS_Init_NoCache, mDNS_Init_ZeroCacheSize,
@ -562,6 +568,24 @@ int rend_init(pid_t *pid,char *name, int port) {
return 0; 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"); DPRINTF(ERR_DEBUG,"Registering tcp service\n");
RegisterOneService(name,"_http._tcp",NULL,0,port); RegisterOneService(name,"_http._tcp",NULL,0,port);
RegisterOneService(name,"_daap._tcp",NULL,0,port); RegisterOneService(name,"_daap._tcp",NULL,0,port);

View File

@ -22,6 +22,6 @@
#ifndef _REND_H_ #ifndef _REND_H_
#define _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_ */ #endif /* _REND_H_ */