summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h29
-rw-r--r--source3/lib/username.c130
-rw-r--r--source3/lib/util.c50
-rw-r--r--source3/libsmb/namequery.c2
-rw-r--r--source3/nsswitch/wb_client.c247
-rw-r--r--source3/smbd/groupname.c10
-rw-r--r--source3/smbd/service.c16
-rw-r--r--source3/smbd/uid.c226
8 files changed, 457 insertions, 253 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index b68209434f..e3d574de21 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -151,6 +151,7 @@ void mdfour(unsigned char *out, unsigned char *in, int n);
/*The following definitions come from lib/messages.c */
void ping_message(int msg_type, pid_t src, void *buf, size_t len);
+void debuglevel_message(int msg_type, pid_t src, void *buf, size_t len);
BOOL message_init(void);
BOOL message_send_pid(pid_t pid, int msg_type, void *buf, size_t len);
void message_dispatch(void);
@@ -317,6 +318,7 @@ char *ufc_crypt(char *key,char *salt);
char *get_user_home_dir(char *user);
BOOL map_username(char *user);
struct passwd *Get_Pwnam(char *user,BOOL allow_change);
+BOOL user_in_group_list(char *user,char *gname);
BOOL user_in_list(char *user,char *list);
struct passwd *smb_getpwnam(char *user, BOOL allow_change);
@@ -358,8 +360,8 @@ struct hostent *Get_Hostbyname(const char *name);
BOOL process_exists(pid_t pid);
char *uidtoname(uid_t uid);
char *gidtoname(gid_t gid);
-uid_t nametouid(const char *name);
-gid_t nametogid(const char *name);
+uid_t nametouid(char *name);
+gid_t nametogid(char *name);
void smb_panic(char *why);
char *readdirname(DIR *p);
BOOL is_in_path(char *name, name_compare_entry *namelist);
@@ -1299,12 +1301,16 @@ void expire_workgroups_and_servers(time_t t);
BOOL winbind_lookup_name(char *name, DOM_SID *sid, enum SID_NAME_USE *name_type);
BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type);
-BOOL lookup_name(char *name, DOM_SID *psid, enum SID_NAME_USE *name_type);
-BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type);
-DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid);
-DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid);
-BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype);
-BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype);
+BOOL winbind_sid_to_uid(uid_t *puid, DOM_SID *sid);
+BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid);
+BOOL winbind_sid_to_gid(gid_t *pgid, DOM_SID *sid);
+BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid);
+int winbind_initgroups(char *user, gid_t gid);
+int winbind_getgroups(char *user, int size, gid_t *list);
+BOOL winbind_uidtoname(fstring name, uid_t uid);
+BOOL winbind_gidtoname(fstring name, gid_t gid);
+BOOL winbind_nametouid(uid_t *puid, char *name);
+BOOL winbind_nametogid(gid_t *pgid, char *gname);
/*The following definitions come from nsswitch/wb_common.c */
@@ -3648,7 +3654,6 @@ user_struct *get_valid_user_struct(uint16 vuid);
void invalidate_vuid(uint16 vuid);
char *validated_username(uint16 vuid);
char *validated_domain(uint16 vuid);
-BOOL initialize_groups(char *user, uid_t uid, gid_t gid);
NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups);
uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
char *domain,BOOL guest);
@@ -3843,6 +3848,12 @@ BOOL become_authenticated_pipe_user(pipes_struct *p);
BOOL unbecome_authenticated_pipe_user(pipes_struct *p);
void become_root(void);
void unbecome_root(void);
+BOOL lookup_name(char *name, DOM_SID *psid, enum SID_NAME_USE *name_type);
+BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type);
+DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid);
+DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid);
+BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype);
+BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype);
#endif
/*The following definitions come from smbd/unix_acls.c */
diff --git a/source3/lib/username.c b/source3/lib/username.c
index ad44c0c544..32e9eb3188 100644
--- a/source3/lib/username.c
+++ b/source3/lib/username.c
@@ -260,29 +260,109 @@ static BOOL user_in_netgroup_list(char *user,char *ngname)
}
/****************************************************************************
- Check if a user is in a UNIX user list.
+ Check if a user is in a winbind group.
+****************************************************************************/
+
+static BOOL user_in_winbind_group_list(char *user,char *gname, BOOL *winbind_answered)
+{
+ int num_groups;
+ int i;
+ gid_t *groups = NULL;
+ gid_t gid;
+ DOM_SID g_sid;
+ enum SID_NAME_USE name_type;
+ BOOL ret = False;
+
+ *winbind_answered = False;
+
+ /*
+ * Get the gid's that this user belongs to.
+ */
+
+ if ((num_groups = winbind_getgroups(user, 0, NULL)) == -1)
+ return False;
+
+ if (num_groups == 0) {
+ *winbind_answered = True;
+ return False;
+ }
+
+ if ((groups = (gid_t *)malloc(sizeof(gid_t) * num_groups )) == NULL) {
+ DEBUG(0,("user_in_winbind_group_list: malloc fail.\n"));
+ goto err;
+ }
+
+ if ((num_groups = winbind_getgroups(user, num_groups, groups)) == -1) {
+ DEBUG(0,("user_in_winbind_group_list: second winbind_getgroups call \
+failed with error %s\n", strerror(errno) ));
+ goto err;
+ }
+
+ /*
+ * Now we have the gid list for this user - convert the gname
+ * to a gid_t via winbind and do the comparison.
+ */
+
+ if (!winbind_nametogid(gname, &gid)) {
+ DEBUG(0,("user_in_winbind_group_list: winbind_lookup_name for group %s failed.\n",
+ gname ));
+ goto err;
+ }
+
+ for (i = 0; i < num_groups; i++) {
+ if (gid == groups[i]) {
+ ret = True;
+ break;
+ }
+ }
+
+ *winbind_answered = True;
+ safe_free(groups);
+ return ret;
+
+ err:
+
+ *winbind_answered = False;
+ safe_free(groups);
+ return False;
+}
+
+/****************************************************************************
+ Check if a user is in a UNIX group.
****************************************************************************/
-static BOOL user_in_group_list(char *user,char *gname)
+static BOOL user_in_unix_group_list(char *user,char *gname)
{
struct group *gptr;
char **member;
struct passwd *pass = Get_Pwnam(user,False);
- if (pass) {
- gptr = getgrgid(pass->pw_gid);
- if (gptr && strequal(gptr->gr_name,gname))
- return True;
- }
-
- if ((gptr = (struct group *)getgrnam(gname)) == NULL)
- return False;
-
- member = gptr->gr_mem;
- while (member && *member) {
- if (strequal(*member,user)) {
- return(True);
- }
+ DEBUG(10,("user_in_unix_group_list: checking user %s in group %s\n", user, gname));
+
+ /*
+ * We need to check the users primary group as this
+ * group is implicit and often not listed in the group database.
+ */
+
+ if (pass) {
+ gptr = getgrgid(pass->pw_gid);
+ if (gptr && strequal(gptr->gr_name,gname)) {
+ DEBUG(10,("user_in_unix_group_list: group %s is primary group.\n", gname ));
+ return True;
+ }
+ }
+
+ if ((gptr = (struct group *)getgrnam(gname)) == NULL) {
+ DEBUG(10,("user_in_unix_group_list: no such group %s\n", gname ));
+ return False;
+ }
+
+ member = gptr->gr_mem;
+ while (member && *member) {
+ DEBUG(10,("user_in_unix_group_list: checking user %s against member %s\n", user, *member ));
+ if (strequal(*member,user)) {
+ return(True);
+ }
member++;
}
@@ -290,6 +370,21 @@ static BOOL user_in_group_list(char *user,char *gname)
}
/****************************************************************************
+ Check if a user is in a group list. Ask winbind first, then use UNIX.
+****************************************************************************/
+
+BOOL user_in_group_list(char *user,char *gname)
+{
+ BOOL winbind_answered = False;
+ BOOL ret = user_in_winbind_group_list(user, gname, &winbind_answered);
+
+ if (winbind_answered)
+ return ret;
+
+ return user_in_unix_group_list(user, gname);
+}
+
+/****************************************************************************
Check if a user is in a user list - can check combinations of UNIX
and netgroup lists.
****************************************************************************/
@@ -299,6 +394,8 @@ BOOL user_in_list(char *user,char *list)
pstring tok;
char *p=list;
+ DEBUG(10,("user_in_list: checking user %s in list %s\n", user, list));
+
while (next_token(&p,tok,LIST_SEP, sizeof(tok))) {
/*
* Check raw username.
@@ -447,4 +544,3 @@ struct passwd *smb_getpwnam(char *user, BOOL allow_change)
return NULL;
}
-
diff --git a/source3/lib/util.c b/source3/lib/util.c
index aced56bc2f..0aef60082f 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -1099,60 +1099,80 @@ BOOL process_exists(pid_t pid)
/*******************************************************************
-turn a uid into a user name
+ Convert a uid into a user name.
********************************************************************/
+
char *uidtoname(uid_t uid)
{
- static char name[40];
- struct passwd *pass = sys_getpwuid(uid);
- if (pass) return(pass->pw_name);
- slprintf(name, sizeof(name) - 1, "%d",(int)uid);
- return(name);
+ static fstring name;
+ struct passwd *pass;
+
+ if (winbind_uidtoname(name, uid))
+ return name;
+
+ pass = sys_getpwuid(uid);
+ if (pass) return(pass->pw_name);
+ slprintf(name, sizeof(name) - 1, "%d",(int)uid);
+ return(name);
}
/*******************************************************************
-turn a gid into a group name
+ Convert a gid into a group name.
********************************************************************/
char *gidtoname(gid_t gid)
{
- static char name[40];
- struct group *grp = getgrgid(gid);
+ static fstring name;
+ struct group *grp;
+
+ if (winbind_gidtoname(name, gid))
+ return name;
+
+ grp = getgrgid(gid);
if (grp) return(grp->gr_name);
slprintf(name,sizeof(name) - 1, "%d",(int)gid);
return(name);
}
/*******************************************************************
-turn a user name into a uid
+ Convert a user name into a uid. If winbindd is present uses this.
********************************************************************/
-uid_t nametouid(const char *name)
+
+uid_t nametouid(char *name)
{
struct passwd *pass;
char *p;
uid_t u;
- u = strtol(name, &p, 0);
+ u = (uid_t)strtol(name, &p, 0);
if (p != name) return u;
+ if (winbind_nametouid(&u, name))
+ return u;
+
pass = sys_getpwnam(name);
if (pass) return(pass->pw_uid);
return (uid_t)-1;
}
/*******************************************************************
-turn a group name into a gid
+ Convert a name to a gid_t if possible. Return -1 if not a group. If winbindd
+ is present does a shortcut lookup...
********************************************************************/
-gid_t nametogid(const char *name)
+
+gid_t nametogid(char *name)
{
struct group *grp;
char *p;
gid_t g;
- g = strtol(name, &p, 0);
+ g = (gid_t)strtol(name, &p, 0);
if (p != name) return g;
+ if (winbind_nametogid(&g, name))
+ return g;
+
grp = getgrnam(name);
if (grp) return(grp->gr_gid);
return (gid_t)-1;
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 41924d4631..52ff6287c4 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -891,7 +891,7 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd
dgram->header.packet_offset = 0;
make_nmb_name(&dgram->source_name,srcname,0);
- make_nmb_name(&dgram->dest_name,domain,0x1B);
+ make_nmb_name(&dgram->dest_name,domain,0x1C);
ptr = &dgram->data[0];
diff --git a/source3/nsswitch/wb_client.c b/source3/nsswitch/wb_client.c
index 436bbc7bcc..d2762674aa 100644
--- a/source3/nsswitch/wb_client.c
+++ b/source3/nsswitch/wb_client.c
@@ -58,27 +58,8 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_N
struct winbindd_request request;
struct winbindd_response response;
enum nss_status result;
- DOM_SID tmp_sid;
- uint32 rid;
fstring sid_str;
- if (!name_type)
- return False;
-
- /* Check if this is our own sid. This should perhaps be done by
- winbind? For the moment handle it here. */
-
- if (sid->num_auths == 5) {
- sid_copy(&tmp_sid, sid);
- sid_split_rid(&tmp_sid, &rid);
-
- if (sid_equal(&global_sam_sid, &tmp_sid)) {
-
- return map_domain_sid_to_name(&tmp_sid, dom_name) &&
- local_lookup_rid(rid, name, name_type);
- }
- }
-
/* Initialise request */
ZERO_STRUCT(request);
@@ -103,7 +84,7 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_N
/* Call winbindd to convert SID to uid */
-static BOOL winbind_sid_to_uid(uid_t *puid, DOM_SID *sid)
+BOOL winbind_sid_to_uid(uid_t *puid, DOM_SID *sid)
{
struct winbindd_request request;
struct winbindd_response response;
@@ -136,7 +117,7 @@ static BOOL winbind_sid_to_uid(uid_t *puid, DOM_SID *sid)
/* Call winbindd to convert uid to sid */
-static BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
+BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
{
struct winbindd_request request;
struct winbindd_response response;
@@ -169,7 +150,7 @@ static BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
/* Call winbindd to convert SID to gid */
-static BOOL winbind_sid_to_gid(gid_t *pgid, DOM_SID *sid)
+BOOL winbind_sid_to_gid(gid_t *pgid, DOM_SID *sid)
{
struct winbindd_request request;
struct winbindd_response response;
@@ -202,7 +183,7 @@ static BOOL winbind_sid_to_gid(gid_t *pgid, DOM_SID *sid)
/* Call winbindd to convert gid to sid */
-static BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid)
+BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid)
{
struct winbindd_request request;
struct winbindd_response response;
@@ -361,208 +342,82 @@ int winbind_getgroups(char *user, int size, gid_t *list)
return result;
}
-/*****************************************************************
- *THE CANONICAL* convert name to SID function.
- Tries winbind first - then uses local lookup.
-*****************************************************************/
+/**********************************************************************************
+ Utility function. Convert a uid_t to a name if possible.
+**********************************************************************************/
-BOOL lookup_name(char *name, DOM_SID *psid, enum SID_NAME_USE *name_type)
+BOOL winbind_uidtoname(fstring name, uid_t uid)
{
- extern pstring global_myname;
- fstring sid;
-
- if (!winbind_lookup_name(name, psid, name_type)) {
- BOOL ret;
-
- DEBUG(10,("lookup_name: winbind lookup for %s failed - trying local\n", name ));
-
- ret = local_lookup_name(global_myname, name, psid, name_type);
- if (ret)
- DEBUG(10,("lookup_name : (local) %s -> SID %s (type %u)\n",
- name, sid_to_string(sid,psid),
- (unsigned int)*name_type ));
- else
- DEBUG(10,("lookup name : (local) %s failed.\n",
- name ));
- return ret;
- }
-
- DEBUG(10,("lookup_name (winbindd): %s -> SID %s (type %u)\n",
- name, sid_to_string(sid,psid), (unsigned int)*name_type ));
- return True;
-}
-
-/*****************************************************************
- *THE CANONICAL* convert SID to name function.
- Tries winbind first - then uses local lookup.
-*****************************************************************/
+ DOM_SID sid;
+ fstring dom_name;
+ enum SID_NAME_USE name_type;
-BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type)
-{
- if (!winbind_lookup_sid(sid, dom_name, name, name_type)) {
- fstring sid_str;
- DOM_SID tmp_sid;
- uint32 rid;
+ if (!winbind_uid_to_sid(&sid, uid))
+ return False;
+ if (!winbind_lookup_sid(&sid, dom_name, name, &name_type))
+ return False;
- DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying local.\n", sid_to_string(sid_str, sid) ));
+ if (name_type != SID_NAME_USER)
+ return False;
- sid_copy(&tmp_sid, sid);
- sid_split_rid(&tmp_sid, &rid);
- return map_domain_sid_to_name(&tmp_sid, dom_name) &&
- lookup_known_rid(&tmp_sid, rid, name, name_type);
- }
return True;
}
-/*****************************************************************
- *THE CANONICAL* convert uid_t to SID function.
- Tries winbind first - then uses local lookup.
- Returns SID pointer.
-*****************************************************************/
+/**********************************************************************************
+ Utility function. Convert a gid_t to a name if possible.
+**********************************************************************************/
-DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid)
+BOOL winbind_gidtoname(fstring name, gid_t gid)
{
- fstring sid;
-
- if (!winbind_uid_to_sid(psid, uid)) {
- DEBUG(10,("uid_to_sid: winbind lookup for uid %u failed - trying local.\n", (unsigned int)uid ));
-
- return local_uid_to_sid(psid, uid);
- }
-
- DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
- (unsigned int)uid, sid_to_string(sid, psid) ));
-
- return psid;
-}
-
-/*****************************************************************
- *THE CANONICAL* convert gid_t to SID function.
- Tries winbind first - then uses local lookup.
- Returns SID pointer.
-*****************************************************************/
-
-DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid)
-{
- fstring sid;
-
- if (!winbind_gid_to_sid(psid, gid)) {
- DEBUG(10,("gid_to_sid: winbind lookup for gid %u failed - trying local.\n", (unsigned int)gid ));
-
- return local_gid_to_sid(psid, gid);
- }
-
- DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
- (unsigned int)gid, sid_to_string(sid,psid) ));
-
- return psid;
-}
-
-/*****************************************************************
- *THE CANONICAL* convert SID to uid function.
- Tries winbind first - then uses local lookup.
- Returns True if this name is a user sid and the conversion
- was done correctly, False if not.
-*****************************************************************/
-
-BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
-{
- fstring dom_name, name, sid_str;
+ DOM_SID sid;
+ fstring dom_name;
enum SID_NAME_USE name_type;
- *sidtype = SID_NAME_UNKNOWN;
-
- /*
- * First we must look up the name and decide if this is a user sid.
- */
-
- if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) {
- DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n",
- sid_to_string(sid_str, psid) ));
-
- return local_sid_to_uid(puid, psid, sidtype);
- }
-
- /*
- * Ensure this is a user sid.
- */
-
- if (name_type != SID_NAME_USER) {
- DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a uid (%u)\n",
- (unsigned int)name_type ));
+ if (!winbind_gid_to_sid(&sid, gid))
return False;
- }
-
- *sidtype = SID_NAME_USER;
-
- /*
- * Get the uid for this SID.
- */
-
- if (!winbind_sid_to_uid(puid, psid)) {
- DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed.\n",
- sid_to_string(sid_str, psid) ));
+ if (!winbind_lookup_sid(&sid, dom_name, name, &name_type))
return False;
- }
- DEBUG(10,("sid_to_uid: winbindd %s -> %u\n",
- sid_to_string(sid_str, psid),
- (unsigned int)*puid ));
+ if (name_type != SID_NAME_USER)
+ return False;
return True;
}
-/*****************************************************************
- *THE CANONICAL* convert SID to gid function.
- Tries winbind first - then uses local lookup.
- Returns True if this name is a user sid and the conversion
- was done correctly, False if not.
-*****************************************************************/
+/**********************************************************************************
+ Utility function. Convert a name to a uid_t if possible.
+**********************************************************************************/
-BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype)
+BOOL winbind_nametouid(uid_t *puid, char *name)
{
- fstring dom_name, name, sid_str;
+ DOM_SID sid;
enum SID_NAME_USE name_type;
- *sidtype = SID_NAME_UNKNOWN;
-
- /*
- * First we must look up the name and decide if this is a group sid.
- */
+ if (!winbind_lookup_name(name, &sid, &name_type)) {
+ return False;
+ }
- if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) {
- DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n",
- sid_to_string(sid_str, psid) ));
-
- return local_sid_to_gid(pgid, psid, sidtype);
- }
-
- /*
- * Ensure this is a group sid.
- */
+ if (name_type != SID_NAME_USER)
+ return False;
- if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) {
- DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a know group (%u)\n",
- (unsigned int)name_type ));
+ return winbind_sid_to_uid(puid, &sid);
+}
- return local_sid_to_gid(pgid, psid, sidtype);
- }
+/**********************************************************************************
+ Utility function. Convert a name to a gid_t if possible.
+**********************************************************************************/
- *sidtype = name_type;
+BOOL winbind_nametogid(gid_t *pgid, char *gname)
+{
+ DOM_SID g_sid;
+ enum SID_NAME_USE name_type;
- /*
- * Get the gid for this SID.
- */
+ if (!winbind_lookup_name(gname, &g_sid, &name_type)) {
+ return False;
+ }
- if (!winbind_sid_to_gid(pgid, psid)) {
- DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n",
- sid_to_string(sid_str, psid) ));
+ if (name_type != SID_NAME_DOM_GRP)
return False;
- }
-
- DEBUG(10,("gid_to_uid: winbindd %s -> %u\n",
- sid_to_string(sid_str, psid),
- (unsigned int)*pgid ));
- return True;
+ return winbind_sid_to_gid(pgid, &g_sid);
}
diff --git a/source3/smbd/groupname.c b/source3/smbd/groupname.c
index f0b11e1b36..d53fa56a44 100644
--- a/source3/smbd/groupname.c
+++ b/source3/smbd/groupname.c
@@ -119,7 +119,7 @@ void load_groupname_map(void)
for (i=0; lines[i]; i++) {
pstring unixname;
pstring windows_name;
- struct group *gptr;
+ gid_t gid;
DOM_SID tmp_sid;
char *s = lines[i];
@@ -150,8 +150,8 @@ void load_groupname_map(void)
* Attempt to get the unix gid_t for this name.
*/
- if((gptr = (struct group *)getgrnam(unixname)) == NULL) {
- DEBUG(0,("load_groupname_map: getgrnam for group %s failed.\
+ if ((gid = nametogid(unixname)) == (gid_t)-1)
+ DEBUG(0,("load_groupname_map: nametogid for group %s failed.\
Error was %s.\n", unixname, strerror(errno) ));
continue;
}
@@ -167,7 +167,7 @@ Error was %s.\n", unixname, strerror(errno) ));
*/
tmp_sid = global_sam_sid;
tmp_sid.sub_auths[tmp_sid.num_auths++] =
- pdb_gid_to_group_rid((gid_t)gptr->gr_gid);
+ pdb_gid_to_group_rid(gid);
}
/*
@@ -180,7 +180,7 @@ Error was %s.\n", unixname, strerror(errno) ));
return;
}
- new_ep->unix_gid = gptr->gr_gid;
+ new_ep->unix_gid = gid;
new_ep->windows_sid = tmp_sid;
new_ep->windows_name = strdup( windows_name );
new_ep->unix_name = strdup( unixname );
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 6d07562743..b86f3beadd 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -401,7 +401,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
*/
if (*lp_force_group(snum)) {
- struct group *gptr;
+ gid_t gid;
pstring gname;
pstring tmp_gname;
BOOL user_must_be_member = False;
@@ -416,9 +416,9 @@ connection_struct *make_connection(char *service,char *user,char *password, int
}
/* default service may be a group name */
pstring_sub(gname,"%S",service);
- gptr = (struct group *)getgrnam(gname);
+ gid = nametogid(gname);
- if (gptr) {
+ if (gid != (gid_t)-1) {
/*
* If the user has been forced and the forced group starts
* with a '+', then we only set the group to be the forced
@@ -426,16 +426,12 @@ connection_struct *make_connection(char *service,char *user,char *password, int
* Otherwise, the meaning of the '+' would be ignored.
*/
if (conn->force_user && user_must_be_member) {
- int i;
- for (i = 0; gptr->gr_mem[i] != NULL; i++) {
- if (strcmp(user,gptr->gr_mem[i]) == 0) {
- conn->gid = gptr->gr_gid;
+ if (user_in_group_list( user, gname )) {
+ conn->gid = gid;
DEBUG(3,("Forced group %s for member %s\n",gname,user));
- break;
- }
}
} else {
- conn->gid = gptr->gr_gid;
+ conn->gid = gid;
DEBUG(3,("Forced group %s\n",gname));
}
} else {
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index b28f056a30..fb83e724b8 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -257,4 +257,230 @@ void unbecome_root(void)
pop_sec_ctx();
}
+/*****************************************************************
+ *THE CANONICAL* convert name to SID function.
+ Tries winbind first - then uses local lookup.
+*****************************************************************/
+
+BOOL lookup_name(char *name, DOM_SID *psid, enum SID_NAME_USE *name_type)
+{
+ extern pstring global_myname;
+ fstring sid;
+
+ if (!winbind_lookup_name(name, psid, name_type)) {
+ BOOL ret;
+
+ DEBUG(10,("lookup_name: winbind lookup for %s failed - trying local\n", name ));
+
+ ret = local_lookup_name(global_myname, name, psid, name_type);
+ if (ret)
+ DEBUG(10,("lookup_name : (local) %s -> SID %s (type %u)\n",
+ name, sid_to_string(sid,psid),
+ (unsigned int)*name_type ));
+ else
+ DEBUG(10,("lookup name : (local) %s failed.\n",
+ name ));
+ return ret;
+ }
+
+ DEBUG(10,("lookup_name (winbindd): %s -> SID %s (type %u)\n",
+ name, sid_to_string(sid,psid), (unsigned int)*name_type ));
+ return True;
+}
+
+/*****************************************************************
+ *THE CANONICAL* convert SID to name function.
+ Tries winbind first - then uses local lookup.
+*****************************************************************/
+
+BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type)
+{
+ if (!name_type)
+ return False;
+
+ /* Check if this is our own sid. This should perhaps be done by
+ winbind? For the moment handle it here. */
+
+ if (sid->num_auths == 5) {
+ DOM_SID tmp_sid;
+ uint32 rid;
+
+ sid_copy(&tmp_sid, sid);
+ sid_split_rid(&tmp_sid, &rid);
+
+ if (sid_equal(&global_sam_sid, &tmp_sid)) {
+
+ return map_domain_sid_to_name(&tmp_sid, dom_name) &&
+ local_lookup_rid(rid, name, name_type);
+ }
+ }
+
+ if (!winbind_lookup_sid(sid, dom_name, name, name_type)) {
+ fstring sid_str;
+ DOM_SID tmp_sid;
+ uint32 rid;
+
+ DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying local.\n", sid_to_string(sid_str, sid) ));
+
+ sid_copy(&tmp_sid, sid);
+ sid_split_rid(&tmp_sid, &rid);
+ return map_domain_sid_to_name(&tmp_sid, dom_name) &&
+ lookup_known_rid(&tmp_sid, rid, name, name_type);
+ }
+ return True;
+}
+
+/*****************************************************************
+ *THE CANONICAL* convert uid_t to SID function.
+ Tries winbind first - then uses local lookup.
+ Returns SID pointer.
+*****************************************************************/
+
+DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid)
+{
+ fstring sid;
+
+ if (!winbind_uid_to_sid(psid, uid)) {
+ DEBUG(10,("uid_to_sid: winbind lookup for uid %u failed - trying local.\n", (unsigned int)uid ));
+
+ return local_uid_to_sid(psid, uid);
+ }
+
+ DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
+ (unsigned int)uid, sid_to_string(sid, psid) ));
+
+ return psid;
+}
+
+/*****************************************************************
+ *THE CANONICAL* convert gid_t to SID function.
+ Tries winbind first - then uses local lookup.
+ Returns SID pointer.
+*****************************************************************/
+
+DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid)
+{
+ fstring sid;
+
+ if (!winbind_gid_to_sid(psid, gid)) {
+ DEBUG(10,("gid_to_sid: winbind lookup for gid %u failed - trying local.\n", (unsigned int)gid ));
+
+ return local_gid_to_sid(psid, gid);
+ }
+
+ DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
+ (unsigned int)gid, sid_to_string(sid,psid) ));
+
+ return psid;
+}
+
+/*****************************************************************
+ *THE CANONICAL* convert SID to uid function.
+ Tries winbind first - then uses local lookup.
+ Returns True if this name is a user sid and the conversion
+ was done correctly, False if not.
+*****************************************************************/
+
+BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
+{
+ fstring dom_name, name, sid_str;
+ enum SID_NAME_USE name_type;
+
+ *sidtype = SID_NAME_UNKNOWN;
+
+ /*
+ * First we must look up the name and decide if this is a user sid.
+ */
+
+ if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) {
+ DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n",
+ sid_to_string(sid_str, psid) ));
+
+ return local_sid_to_uid(puid, psid, sidtype);
+ }
+
+ /*
+ * Ensure this is a user sid.
+ */
+
+ if (name_type != SID_NAME_USER) {
+ DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a uid (%u)\n",
+ (unsigned int)name_type ));
+ return False;
+ }
+
+ *sidtype = SID_NAME_USER;
+
+ /*
+ * Get the uid for this SID.
+ */
+
+ if (!winbind_sid_to_uid(puid, psid)) {
+ DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed.\n",
+ sid_to_string(sid_str, psid) ));
+ return False;
+ }
+
+ DEBUG(10,("sid_to_uid: winbindd %s -> %u\n",
+ sid_to_string(sid_str, psid),
+ (unsigned int)*puid ));
+
+ return True;
+}
+
+/*****************************************************************
+ *THE CANONICAL* convert SID to gid function.
+ Tries winbind first - then uses local lookup.
+ Returns True if this name is a user sid and the conversion
+ was done correctly, False if not.
+*****************************************************************/
+
+BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype)
+{
+ fstring dom_name, name, sid_str;
+ enum SID_NAME_USE name_type;
+
+ *sidtype = SID_NAME_UNKNOWN;
+
+ /*
+ * First we must look up the name and decide if this is a group sid.
+ */
+
+ if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) {
+ DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n",
+ sid_to_string(sid_str, psid) ));
+
+ return local_sid_to_gid(pgid, psid, sidtype);
+ }
+
+ /*
+ * Ensure this is a group sid.
+ */
+
+ if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) {
+ DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a know group (%u)\n",
+ (unsigned int)name_type ));
+
+ return local_sid_to_gid(pgid, psid, sidtype);
+ }
+
+ *sidtype = name_type;
+
+ /*
+ * Get the gid for this SID.
+ */
+
+ if (!winbind_sid_to_gid(pgid, psid)) {
+ DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n",
+ sid_to_string(sid_str, psid) ));
+ return False;
+ }
+
+ DEBUG(10,("gid_to_uid: winbindd %s -> %u\n",
+ sid_to_string(sid_str, psid),
+ (unsigned int)*pgid ));
+
+ return True;
+}
+
#undef OLD_NTDOMAIN