summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2012-07-20 12:27:19 +0000
committerArthur de Jong <arthur@arthurdejong.org>2012-07-20 12:27:19 +0000
commitb28a4e39bcc4e48b08e615dcc51a8118a706326a (patch)
tree68ddb72eba9865026ac1171e907786e279eab0a2
parent08e0feea8b0330b16d2503929686479752843619 (diff)
on startup have the gid option default to the primary group of the specified user and load the user's supplementary groups
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-pam-ldapd@1723 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r--configure.ac2
-rw-r--r--nslcd/cfg.c19
-rw-r--r--nslcd/cfg.h2
-rw-r--r--nslcd/nslcd.c29
-rwxr-xr-xpynslcd/pynslcd.py19
5 files changed, 48 insertions, 23 deletions
diff --git a/configure.ac b/configure.ac
index be4516b..e330335 100644
--- a/configure.ac
+++ b/configure.ac
@@ -575,7 +575,7 @@ then
AC_SEARCH_LIBS(dlopen,dl)
# check for availability of functions
- AC_CHECK_FUNCS(setgroups)
+ AC_CHECK_FUNCS(initgroups setgroups)
AC_CHECK_FUNCS(getpeereid)
AC_CHECK_FUNCS(getpeerucred)
AC_CHECK_FUNCS(__nss_configure_lookup)
diff --git a/nslcd/cfg.c b/nslcd/cfg.c
index b98ad38..bc57c6b 100644
--- a/nslcd/cfg.c
+++ b/nslcd/cfg.c
@@ -87,6 +87,7 @@ static void cfg_defaults(struct ldap_config *cfg)
int i;
memset(cfg,0,sizeof(struct ldap_config));
cfg->ldc_threads=5;
+ cfg->ldc_uidname=NULL;
cfg->ldc_uid=NOUID;
cfg->ldc_gid=NOGID;
cfg->ldc_ignorecase=0;
@@ -441,7 +442,7 @@ static void get_eol(const char *filename,int lnr,
static void get_uid(const char *filename,int lnr,
const char *keyword,char **line,
- uid_t *var)
+ uid_t *var,gid_t *gid,char **str)
{
/* TODO: refactor to have less overhead */
char token[32];
@@ -452,12 +453,24 @@ static void get_uid(const char *filename,int lnr,
errno=0;
*var=strtouid(token,&tmp,10);
if ((*token!='\0')&&(*tmp=='\0')&&(errno==0)&&(strchr(token,'-')==NULL))
+ {
+ /* get the name and gid from the passwd database */
+ pwent=getpwuid(*var);
+ if ((gid!=NULL)&&(*gid!=NOGID))
+ *gid=pwent->pw_gid;
+ if (str!=NULL)
+ *str=strdup(pwent->pw_name);
return;
+ }
/* find by name */
pwent=getpwnam(token);
if (pwent!=NULL)
{
*var=pwent->pw_uid;
+ if ((gid!=NULL)&&(*gid!=NOGID))
+ *gid=pwent->pw_gid;
+ if (str!=NULL)
+ *str=strdup(token);
return;
}
/* log an error */
@@ -883,7 +896,7 @@ static void cfg_read(const char *filename,struct ldap_config *cfg)
}
else if (strcasecmp(keyword,"uid")==0)
{
- get_uid(filename,lnr,keyword,&line,&cfg->ldc_uid);
+ get_uid(filename,lnr,keyword,&line,&cfg->ldc_uid,&cfg->ldc_gid,&cfg->ldc_uidname);
get_eol(filename,lnr,keyword,&line);
}
else if (strcasecmp(keyword,"gid")==0)
@@ -1153,7 +1166,7 @@ static void cfg_read(const char *filename,struct ldap_config *cfg)
}
else if (strcasecmp(keyword,"nss_min_uid")==0)
{
- get_uid(filename,lnr,keyword,&line,&cfg->ldc_nss_min_uid);
+ get_uid(filename,lnr,keyword,&line,&cfg->ldc_nss_min_uid,NULL,NULL);
get_eol(filename,lnr,keyword,&line);
}
else if (strcasecmp(keyword,"validnames")==0)
diff --git a/nslcd/cfg.h b/nslcd/cfg.h
index 0c432ee..ebdd95a 100644
--- a/nslcd/cfg.h
+++ b/nslcd/cfg.h
@@ -85,6 +85,8 @@ struct ldap_config
{
/* the number of threads to start */
int ldc_threads;
+ /* the user name specified in the uid option */
+ char *ldc_uidname;
/* the user id nslcd should be run as */
uid_t ldc_uid;
/* the group id nslcd should be run as */
diff --git a/nslcd/nslcd.c b/nslcd/nslcd.c
index 773d6db..20515e3 100644
--- a/nslcd/nslcd.c
+++ b/nslcd/nslcd.c
@@ -42,9 +42,7 @@
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
-#ifdef HAVE_GRP_H
#include <grp.h>
-#endif /* HAVE_GRP_H */
#ifdef HAVE_NSS_H
#include <nss.h>
#endif /* HAVE_NSS_H */
@@ -741,15 +739,28 @@ int main(int argc,char *argv[])
}
/* create socket */
nslcd_serversocket=create_socket(NSLCD_SOCKET);
+ if ((nslcd_cfg->ldc_gid!=NOGID)&&(nslcd_cfg->ldc_uidname!=NULL))
+ {
+#ifdef HAVE_INITGROUPS
+ /* load supplementary groups */
+ if (initgroups(nslcd_cfg->ldc_uidname,nslcd_cfg->ldc_gid)<0)
+ log_log(LOG_WARNING,"cannot initgroups(\"%s\",%d) (ignored): %s",
+ nslcd_cfg->ldc_uidname,nslcd_cfg->ldc_gid,strerror(errno));
+ else
+ log_log(LOG_DEBUG,"initgroups(\"%s\",%d) done",
+ nslcd_cfg->ldc_uidname,nslcd_cfg->ldc_gid);
+#else /* not HAVE_INITGROUPS */
#ifdef HAVE_SETGROUPS
- /* drop all supplemental groups */
- if (setgroups(0,NULL)<0)
- log_log(LOG_WARNING,"cannot setgroups(0,NULL) (ignored): %s",strerror(errno));
- else
- log_log(LOG_DEBUG,"setgroups(0,NULL) done");
-#else /* HAVE_SETGROUPS */
- log_log(LOG_DEBUG,"setgroups() not available");
+ /* just drop all supplemental groups */
+ if (setgroups(0,NULL)<0)
+ log_log(LOG_WARNING,"cannot setgroups(0,NULL) (ignored): %s",strerror(errno));
+ else
+ log_log(LOG_DEBUG,"setgroups(0,NULL) done");
+#else /* not HAVE_SETGROUPS */
+ log_log(LOG_DEBUG,"neither initgroups() or setgroups() available");
#endif /* not HAVE_SETGROUPS */
+#endif /* not HAVE_INITGROUPS */
+ }
/* change to nslcd gid */
if (nslcd_cfg->ldc_gid!=NOGID)
{
diff --git a/pynslcd/pynslcd.py b/pynslcd/pynslcd.py
index 5add334..42dfb90 100755
--- a/pynslcd/pynslcd.py
+++ b/pynslcd/pynslcd.py
@@ -326,19 +326,18 @@ if __name__ == '__main__':
try:
# create socket
nslcd_serversocket = create_socket()
- # drop all supplemental groups
- try:
- os.setgroups(())
- except OSError, e:
- logging.warning('cannot setgroups(()) (ignored): %s', e)
- # change to nslcd gid
- if cfg.gid is not None:
- import grp
- os.setgid(grp.getgrnam(cfg.gid).gr_gid)
- # change to nslcd uid
+ # load supplementary groups
if cfg.uid is not None:
import pwd
+ import grp
u = pwd.getpwnam(cfg.uid)
+ if cfg.gid is None:
+ gid = u.pw_gid
+ else:
+ gid = grp.getgrnam(cfg.gid).gr_gid
+ # set supplementary groups, gid and uid
+ os.initgroups(u.pw_name, gid)
+ os.setgid(gid)
os.setuid(u.pw_uid)
os.environ['HOME'] = u.pw_dir
logging.info('accepting connections')