summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/replace.c64
-rw-r--r--source3/lib/system_smbd.c105
-rw-r--r--source3/lib/util_getent.c35
-rw-r--r--source3/lib/util_smbd.c65
4 files changed, 170 insertions, 99 deletions
diff --git a/source3/lib/replace.c b/source3/lib/replace.c
index e2664accfa..fd7b2cf7f0 100644
--- a/source3/lib/replace.c
+++ b/source3/lib/replace.c
@@ -430,67 +430,3 @@ char *rep_inet_ntoa(struct in_addr ip)
#endif /* HAVE_VSYSLOG */
-#ifndef HAVE_GETGROUPLIST
-/*
- This is a *much* faster way of getting the list of groups for a user
- without changing the current supplemenrary group list. The old
- method used getgrent() which could take 20 minutes on a really big
- network with hundeds of thousands of groups and users. The new method
- takes a couple of seconds.
-
- NOTE!! this function only works if it is called as root!
- */
- int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
-{
- gid_t *gids_saved;
- int ret, ngrp_saved;
-
- /* work out how many groups we need to save */
- ngrp_saved = getgroups(0, NULL);
- if (ngrp_saved == -1) {
- /* this shouldn't happen */
- return -1;
- }
-
- gids_saved = (gid_t *)malloc(sizeof(gid_t) * (ngrp_saved+1));
- if (!gids_saved) {
- errno = ENOMEM;
- return -1;
- }
-
- ngrp_saved = getgroups(ngrp_saved, gids_saved);
- if (ngrp_saved == -1) {
- free(gids_saved);
- /* very strange! */
- return -1;
- }
-
- if (initgroups(user, gid) != 0) {
- free(gids_saved);
- return -1;
- }
-
- /* this must be done to cope with systems that put the current egid in the
- return from getgroups() */
- save_re_gid();
- set_effective_gid(gid);
- setgid(gid);
-
- ret = getgroups(*grpcnt, groups);
- if (ret >= 0) {
- *grpcnt = ret;
- }
-
- restore_re_gid();
-
- if (setgroups(ngrp_saved, gids_saved) != 0) {
- /* yikes! */
- DEBUG(0,("ERROR: getgrouplist: failed to reset group list!\n"));
- free(gids_saved);
- return -1;
- }
-
- free(gids_saved);
- return ret;
-}
-#endif
diff --git a/source3/lib/system_smbd.c b/source3/lib/system_smbd.c
new file mode 100644
index 0000000000..28ceaf3939
--- /dev/null
+++ b/source3/lib/system_smbd.c
@@ -0,0 +1,105 @@
+/*
+ Unix SMB/CIFS implementation.
+ system call wrapper interface.
+ Copyright (C) Andrew Tridgell 2002
+ Copyright (C) Andrew Barteltt 2002
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ This file may assume linkage with smbd - for things like become_root()
+ etc.
+*/
+
+#include "includes.h"
+
+#ifndef HAVE_GETGROUPLIST
+/*
+ This is a *much* faster way of getting the list of groups for a user
+ without changing the current supplemenrary group list. The old
+ method used getgrent() which could take 20 minutes on a really big
+ network with hundeds of thousands of groups and users. The new method
+ takes a couple of seconds.
+
+ NOTE!! this function only works if it is called as root!
+ */
+static int getgrouplist_internals(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
+{
+ gid_t *gids_saved;
+ int ret, ngrp_saved;
+
+ /* work out how many groups we need to save */
+ ngrp_saved = getgroups(0, NULL);
+ if (ngrp_saved == -1) {
+ /* this shouldn't happen */
+ return -1;
+ }
+
+ gids_saved = (gid_t *)malloc(sizeof(gid_t) * (ngrp_saved+1));
+ if (!gids_saved) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ngrp_saved = getgroups(ngrp_saved, gids_saved);
+ if (ngrp_saved == -1) {
+ free(gids_saved);
+ /* very strange! */
+ return -1;
+ }
+
+ if (initgroups(user, gid) != 0) {
+ free(gids_saved);
+ return -1;
+ }
+
+ /* this must be done to cope with systems that put the current egid in the
+ return from getgroups() */
+ save_re_gid();
+ set_effective_gid(gid);
+ setgid(gid);
+
+ ret = getgroups(*grpcnt, groups);
+ if (ret >= 0) {
+ *grpcnt = ret;
+ }
+
+ restore_re_gid();
+
+ if (setgroups(ngrp_saved, gids_saved) != 0) {
+ /* yikes! */
+ DEBUG(0,("ERROR: getgrouplist: failed to reset group list!\n"));
+ smb_panic("getgrouplist: failed to reset group list!\n");
+ free(gids_saved);
+ return -1;
+ }
+
+ free(gids_saved);
+ return ret;
+}
+#endif
+
+int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
+{
+#ifdef HAVE_GETGROUPLIST
+ return getgrouplist(user, gid, groups, grpcnt);
+#else
+ int retval;
+ become_root();
+ retval = getgrouplist_internals(user, gid, groups, grpcnt);
+ unbecome_root();
+#endif
+}
diff --git a/source3/lib/util_getent.c b/source3/lib/util_getent.c
index 5d2fcd7652..6699ce3e92 100644
--- a/source3/lib/util_getent.c
+++ b/source3/lib/util_getent.c
@@ -299,38 +299,3 @@ void free_userlist(struct sys_userlist *list_head)
SAFE_FREE(old_head);
}
}
-
-
-/*
- return a full list of groups for a user
-
- returns the number of groups the user is a member of. The return will include the
- users primary group.
-
- remember to free the resulting gid_t array
-
- NOTE! you must be root to call this function on some systems
-*/
-int getgroups_user(const char *user, gid_t **groups)
-{
- struct passwd *pwd;
- int ngrp, max_grp;
-
- pwd = getpwnam(user);
- if (!pwd) return -1;
-
- max_grp = groups_max();
- (*groups) = (gid_t *)malloc(sizeof(gid_t) * max_grp);
- if (! *groups) {
- errno = ENOMEM;
- return -1;
- }
-
- ngrp = getgrouplist(user, pwd->pw_gid, *groups, &max_grp);
- if (ngrp <= 0) {
- free(*groups);
- return ngrp;
- }
-
- return ngrp;
-}
diff --git a/source3/lib/util_smbd.c b/source3/lib/util_smbd.c
new file mode 100644
index 0000000000..071f20b416
--- /dev/null
+++ b/source3/lib/util_smbd.c
@@ -0,0 +1,65 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions, used in smbd only
+ Copyright (C) Andrew Tridgell 2002
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/*
+ This function requires sys_getgrouplist - which is only
+ available in smbd due to it's use of become_root() in a
+ legacy systems hack.
+*/
+
+/*
+ return a full list of groups for a user
+
+ returns the number of groups the user is a member of. The return will include the
+ users primary group.
+
+ remember to free the resulting gid_t array
+
+ NOTE! uses become_root() to gain correct priviages on systems
+ that lack a native getgroups() call (uses initgroups and getgroups)
+*/
+int getgroups_user(const char *user, gid_t **groups)
+{
+ struct passwd *pwd;
+ int ngrp, max_grp;
+
+ pwd = getpwnam_alloc(user);
+ if (!pwd) return -1;
+
+ max_grp = groups_max();
+ (*groups) = (gid_t *)malloc(sizeof(gid_t) * max_grp);
+ if (! *groups) {
+ passwd_free(&pwd);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ngrp = sys_getgrouplist(user, pwd->pw_gid, *groups, &max_grp);
+ if (ngrp <= 0) {
+ passwd_free(&pwd);
+ free(*groups);
+ return ngrp;
+ }
+
+ passwd_free(&pwd);
+ return ngrp;
+}