summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorLuke Leighton <lkcl@samba.org>1998-11-17 16:19:04 +0000
committerLuke Leighton <lkcl@samba.org>1998-11-17 16:19:04 +0000
commit74d539f5573a3ed3ff1b96c54752a389da4c3e14 (patch)
treecc4cee5bc8c5ff3e7ebfef04c4ed3ff6a199df48 /source3/smbd
parentb7c4cd9fc6460c2138750237ee4525f929e93a76 (diff)
downloadsamba-74d539f5573a3ed3ff1b96c54752a389da4c3e14.tar.gz
samba-74d539f5573a3ed3ff1b96c54752a389da4c3e14.tar.bz2
samba-74d539f5573a3ed3ff1b96c54752a389da4c3e14.zip
- group database API. oops and oh dear, the threat has been carried out:
the pre-alpha "domain group" etc parameters have disappeared. - interactive debug detection - re-added mem_man (andrew's memory management, detects memory corruption) - american spellings of "initialise" replaced with english spelling of "initialise". - started on "lookup_name()" and "lookup_sid()" functions. proper ones. - moved lots of functions around. created some modules of commonly used code. e.g the password file locking code, which is used in groupfile.c and aliasfile.c and smbpass.c - moved RID_TYPE_MASK up another bit. this is really unfortunate, but there is no other "fast" way to identify users from groups from aliases. i do not believe that this code saves us anything (the multipliers) and puts us at a disadvantage (reduces the useable rid space). the designers of NT aren't silly: if they can get away with a user- interface-speed LsaLookupNames / LsaLookupSids, then so can we. i spoke with isaac at the cifs conference, the only time for example that they do a security context check is on file create. certainly not on individual file reads / writes, which would drastically hit their performance and ours, too. - renamed myworkgroup to global_sam_name, amongst other things, when used in the rpc code. there is also a global_member_name, as we are always responsible for a SAM database, the scope of which is limited by the role of the machine (e.g if a member of a workgroup, your SAM is for _local_ logins only, and its name is the name of your server. you even still have a SID. see LsaQueryInfoPolicy, levels 3 and 5). - updated functionality of groupname.c to be able to cope with names like DOMAIN\group and SERVER\alias. used this code to be able to do aliases as well as groups. this code may actually be better off being used in username mapping, too. - created a connect to serverlist function in clientgen.c and used it in password.c - initialisation in server.c depends on the role of the server. well, it does now. - rpctorture. smbtorture. EXERCISE EXTREME CAUTION. (This used to be commit 0d21e1e6090b933f396c764af535ca3388a562db)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/groupname.c729
-rw-r--r--source3/smbd/nttrans.c4
-rw-r--r--source3/smbd/password.c114
-rw-r--r--source3/smbd/reply.c4
-rw-r--r--source3/smbd/server.c51
-rw-r--r--source3/smbd/service.c2
6 files changed, 609 insertions, 295 deletions
diff --git a/source3/smbd/groupname.c b/source3/smbd/groupname.c
index 4afa9ece88..2b87cad330 100644
--- a/source3/smbd/groupname.c
+++ b/source3/smbd/groupname.c
@@ -19,12 +19,43 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifdef USING_GROUPNAME_MAP
+/*
+ * UNIX gid and Local or Domain SID resolution. This module resolves
+ * only those entries in the map files, it is *NOT* responsible for
+ * resolving UNIX groups not listed: that is an entirely different
+ * matter, altogether...
+ */
+
+/*
+ *
+ *
+
+ format of the file is:
+
+ unixname NT Group name
+ unixname Domain Admins (well-known Domain Group)
+ unixname DOMAIN_NAME\NT Group name
+ unixname OTHER_DOMAIN_NAME\NT Group name
+ unixname DOMAIN_NAME\Domain Admins (well-known Domain Group)
+ ....
+
+ if the DOMAIN_NAME\ component is left off, then your own domain is assumed.
+
+ *
+ *
+ */
+
#include "includes.h"
extern int DEBUGLEVEL;
-extern DOM_SID global_sam_sid;
+/* we can map either local aliases or domain groups */
+typedef enum
+{
+ GROUP_LOCAL,
+ GROUP_DOMAIN
+
+} GROUP_TYPE;
/**************************************************************************
Groupname map functionality. The code loads a groupname map file and
@@ -33,211 +64,543 @@ extern DOM_SID global_sam_sid;
if the demands on it become excessive.
***************************************************************************/
-typedef struct groupname_map {
- ubi_slNode next;
-
- char *windows_name;
- DOM_SID windows_sid;
+typedef struct group_name_info
+{
+ char *nt_name;
+ char *nt_domain;
char *unix_name;
- gid_t unix_gid;
-} groupname_map_entry;
+
+ DOM_SID sid;
+ gid_t unix_gid;
+
+} GROUP_NAME_INFO;
+
+typedef struct name_map
+{
+ ubi_slNode next;
+ GROUP_NAME_INFO grp;
+
+} name_map_entry;
static ubi_slList groupname_map_list;
+static ubi_slList aliasname_map_list;
+
+static void delete_name_entry(name_map_entry *gmep)
+{
+ if (gmep->grp.nt_name)
+ {
+ free(gmep->grp.nt_name);
+ }
+ if (gmep->grp.nt_domain)
+ {
+ free(gmep->grp.nt_domain);
+ }
+ if (gmep->grp.unix_name)
+ {
+ free(gmep->grp.unix_name);
+ }
+ free((char*)gmep);
+}
+
+/**************************************************************************
+ Delete all the entries in the name map list.
+***************************************************************************/
+
+static void delete_map_list(ubi_slList *map_list)
+{
+ name_map_entry *gmep;
+
+ while ((gmep = (name_map_entry *)ubi_slRemHead(map_list )) != NULL)
+ {
+ delete_name_entry(gmep);
+ }
+}
+
/**************************************************************************
- Delete all the entries in the groupname map list.
+ makes a group sid out of a domain sid and a _unix_ gid.
***************************************************************************/
+static BOOL make_mydomain_sid(GROUP_NAME_INFO *grp, GROUP_TYPE type)
+{
+ uint32 tmp_rid;
+ uint8 tmp_type;
+
+ DEBUG(10,("make_mydomain_sid\n"));
+
+ if (!map_domain_name_to_sid(&grp->sid, &(grp->nt_domain)))
+ {
+ DEBUG(0,("make_mydomain_sid: unknown domain %s\n",
+ grp->nt_domain));
+ return False;
+ }
+ else if (lookup_wk_group_rid(grp->nt_name, &tmp_rid, &tmp_type))
+ {
+ return sid_append_rid(&grp->sid, tmp_rid);
+ }
+ else
+ {
+ if (type == GROUP_DOMAIN)
+ {
+ tmp_rid = pwdb_gid_to_group_rid(grp->unix_gid);
+ }
+ else
+ {
+ tmp_rid = pwdb_gid_to_alias_rid(grp->unix_gid);
+ }
+ return sid_append_rid(&(grp->sid), tmp_rid);
+ }
+}
-static void delete_groupname_map_list(void)
+/**************************************************************************
+ makes a group sid out of an nt domain, nt group name or a unix group name.
+***************************************************************************/
+static BOOL unix_name_to_group_info(GROUP_NAME_INFO *grp, GROUP_TYPE type)
{
- groupname_map_entry *gmep;
+ extern fstring global_sam_name;
+ struct group *gptr = NULL;
+
+ /*
+ * Attempt to get the unix gid_t for this name.
+ */
+
+ DEBUG(5,("unix_name_to_group_info: unix_name:%s\n", grp->unix_name));
+
+ gptr = (struct group *)getgrnam(grp->unix_name);
+ if (gptr == NULL)
+ {
+ DEBUG(0,("unix_name_to_group_info: getgrnam for group %s\
+failed. Error was %s.\n", grp->unix_name, strerror(errno) ));
+ return False;
+ }
+
+ grp->unix_gid = (gid_t)gptr->gr_gid;
+
+ DEBUG(5,("unix_name_to_group_info: unix gid:%d\n", grp->unix_gid));
+
+ /*
+ * Now map the name to an NT SID+RID.
+ */
+
+ if (grp->nt_domain != NULL && !strequal(grp->nt_domain, global_sam_name))
+ {
+ /* Must add client-call lookup code here, to
+ * resolve remote domain's sid and the group's rid,
+ * in that domain.
+ *
+ * NOTE: it is _incorrect_ to put code here that assumes
+ * that we can call pwdb_gid_to_group_rid() or _alias_rid():
+ * it is a totally different domain for which we are *NOT*
+ * responsible.
+ * for foriegn domains for which we are *NOT* the PDC, all
+ * we can be responsible for is the unix * gid_t to which
+ * the foriegn SID+rid maps to, on this _local_ machine.
+ */
+
+ if (!map_domain_name_to_sid(&grp->sid, &(grp->nt_domain)))
+ {
+ DEBUG(0,("unix_name_to_group_info: no known sid for %s\n",
+ grp->nt_domain));
+ return False;
+ }
+
+ DEBUG(0,("unix_name_to_group_info: cannot resolve domain %s\n",
+ grp->nt_domain));
+
+ return False;
+ }
+ else
+ {
+ return make_mydomain_sid(grp, type);
+ }
+}
- while((gmep = (groupname_map_entry *)ubi_slRemHead( &groupname_map_list )) != NULL) {
- if(gmep->windows_name)
- free(gmep->windows_name);
- if(gmep->unix_name)
- free(gmep->unix_name);
- free((char *)gmep);
- }
+static BOOL make_name_entry(name_map_entry **new_ep,
+ char *nt_domain, char *nt_group, char *unix_group,
+ GROUP_TYPE type)
+{
+ /*
+ * Create the list entry and add it onto the list.
+ */
+
+ DEBUG(5,("make_name_entry:%s,%s,%s\n", nt_domain, nt_group, unix_group));
+
+ (*new_ep) = (name_map_entry *)malloc(sizeof(name_map_entry));
+ if ((*new_ep) == NULL)
+ {
+ DEBUG(0,("make_name_entry: malloc fail for name_map_entry.\n"));
+ return False;
+ }
+
+ ZERO_STRUCTP(*new_ep);
+
+ (*new_ep)->grp.nt_name = strdup(nt_group );
+ (*new_ep)->grp.nt_domain = strdup(nt_domain );
+ (*new_ep)->grp.unix_name = strdup(unix_group);
+
+ if ((*new_ep)->grp.nt_name == NULL ||
+ (*new_ep)->grp.unix_name == NULL)
+ {
+ DEBUG(0,("make_name_entry: malloc fail for names in name_map_entry.\n"));
+ delete_name_entry((*new_ep));
+ return False;
+ }
+
+ /*
+ * look up the group names, make the Group-SID and unix gid
+ */
+
+ if (!unix_name_to_group_info(&(*new_ep)->grp, type))
+ {
+ delete_name_entry((*new_ep));
+ return False;
+ }
+
+ return True;
}
/**************************************************************************
- Load a groupname map file. Sets last accessed timestamp.
+ Load a name map file. Sets last accessed timestamp.
***************************************************************************/
+static void load_name_map(GROUP_TYPE type)
+{
+ static time_t groupmap_file_last_modified = (time_t)0;
+ static time_t aliasmap_file_last_modified = (time_t)0;
+ static BOOL initialised_group = False;
+ static BOOL initialised_alias = False;
+ char *groupname_map_file = lp_groupname_map();
+ char *aliasname_map_file = lp_aliasname_map();
+
+ SMB_STRUCT_STAT st;
+ FILE *fp;
+ char *s;
+ pstring buf;
+ name_map_entry *new_ep;
+
+ time_t *file_last_modified;
+ int *initialised;
+ char *map_file;
+ ubi_slList *map_list;
+
+ if (type == GROUP_DOMAIN)
+ {
+ file_last_modified = &groupmap_file_last_modified;
+ initialised = &initialised_group;
+ map_file = groupname_map_file;
+ map_list = &groupname_map_list;
+ }
+ else
+ {
+ file_last_modified = &aliasmap_file_last_modified;
+ initialised = &initialised_alias;
+ map_file = aliasname_map_file;
+ map_list = &aliasname_map_list;
+ }
+
+ DEBUG(10,("load_name_map : %s\n", map_file));
+
+ if (!(*initialised))
+ {
+ ubi_slInitList(map_list);
+ (*initialised) = True;
+ }
+
+ if (!*map_file)
+ {
+ return;
+ }
+
+ if (sys_stat(map_file, &st) != 0)
+ {
+ DEBUG(0, ("load_name_map: Unable to stat file %s. Error was %s\n",
+ map_file, strerror(errno) ));
+ return;
+ }
+
+ /*
+ * Check if file has changed.
+ */
+ if (st.st_mtime <= (*file_last_modified))
+ {
+ return;
+ }
+
+ (*file_last_modified) = st.st_mtime;
+
+ /*
+ * Load the file.
+ */
+
+ fp = fopen(map_file,"r");
+ if (!fp)
+ {
+ DEBUG(0,("load_name_map: can't open name map %s. Error was %s\n",
+ map_file, strerror(errno)));
+ return;
+ }
+
+ /*
+ * Throw away any previous list.
+ */
+ delete_map_list(map_list);
+
+ DEBUG(4,("load_name_map: Scanning name map %s\n",map_file));
+
+ while ((s = fgets_slash(buf, sizeof(buf), fp)) != NULL)
+ {
+ pstring unixname;
+ pstring nt_name;
+ fstring nt_domain;
+ fstring nt_group;
+ char *p;
+
+ DEBUG(10,("Read line |%s|\n", s));
+
+ memset(nt_name, 0, sizeof(nt_name));
+
+ if (!*s || strchr("#;",*s))
+ continue;
+
+ if (!next_token(&s,unixname, "\t\n\r=", sizeof(unixname)))
+ continue;
+
+ if (!next_token(&s,nt_name, "\t\n\r=", sizeof(nt_name)))
+ continue;
+
+ trim_string(unixname, " ", " ");
+ trim_string(nt_name, " ", " ");
+
+ if (!*nt_name)
+ continue;
+
+ if (!*unixname)
+ continue;
+
+ DEBUG(5,("unixname = %s, ntname = %s.\n",
+ unixname, nt_name));
+
+ p = strchr(nt_name, '\\');
+
+ if (p == NULL)
+ {
+ memset(nt_domain, 0, sizeof(nt_domain));
+ fstrcpy(nt_group, nt_name);
+ }
+ else
+ {
+ *p = 0;
+ p++;
+ fstrcpy(nt_domain, nt_name);
+ fstrcpy(nt_group , p);
+ }
+
+ if (make_name_entry(&new_ep, nt_domain, nt_name, unixname, type))
+ {
+ ubi_slAddHead(map_list, (ubi_slNode *)new_ep);
+ }
+ }
+
+ DEBUG(10,("load_name_map: Added %ld entries to name map.\n",
+ ubi_slCount(map_list)));
+
+ fclose(fp);
+}
+
+/***********************************************************
+ Lookup a gid_t by SID
+************************************************************/
+static BOOL map_sid_to_gid(GROUP_TYPE type, ubi_slList *map_list,
+ DOM_SID *psid, gid_t *gid)
+{
+ name_map_entry *gmep;
+
+ /*
+ * Initialize and load if not already loaded.
+ */
+ load_name_map(type);
+
+ for (gmep = (name_map_entry *)ubi_slFirst(map_list);
+ gmep != NULL;
+ gmep = (name_map_entry *)ubi_slNext(gmep ))
+ {
+ if (sid_equal(&gmep->grp.sid, psid))
+ {
+ *gid = gmep->grp.unix_gid;
+ DEBUG(7,("map_sid_to_gid: Mapping unix group %s to nt group %s.\n",
+ gmep->grp.unix_name, gmep->grp.nt_name ));
+ return True;
+ }
+ }
+
+ return False;
+}
+
+/***********************************************************
+ Lookup a SID entry by nt name.
+************************************************************/
+static BOOL map_sid_to_ntname(GROUP_TYPE type, ubi_slList *map_list,
+ DOM_SID *psid, char *ntname, char *ntdomain)
+{
+ name_map_entry *gmep;
+
+ /*
+ * Initialize and load if not already loaded.
+ */
+ load_name_map(type);
+
+ for (gmep = (name_map_entry *)ubi_slFirst(&map_list);
+ gmep != NULL;
+ gmep = (name_map_entry *)ubi_slNext(gmep ))
+ {
+ if (sid_equal(&gmep->grp.sid, psid))
+ {
+ if (ntname != NULL)
+ {
+ fstrcpy(ntname, gmep->grp.nt_name);
+ }
+ if (ntdomain != NULL)
+ {
+ fstrcpy(ntname, gmep->grp.nt_domain);
+ }
+ DEBUG(7,("map_sid_to_ntname: Mapping unix group %s to nt group \%s\%s\n",
+ gmep->grp.unix_name,
+ gmep->grp.nt_domain, gmep->grp.nt_name ));
+ return True;
+ }
+ }
+
+ return False;
+}
-void load_groupname_map(void)
-{
- static time_t groupmap_file_last_modified = (time_t)0;
- static BOOL initialized = False;
- char *groupname_map_file = lp_groupname_map();
- SMB_STRUCT_STAT st;
- FILE *fp;
- char *s;
- pstring buf;
- groupname_map_entry *new_ep;
-
- if(!initialized) {
- ubi_slInitList( &groupname_map_list );
- initialized = True;
- }
-
- if (!*groupname_map_file)
- return;
-
- if(sys_stat(groupname_map_file, &st) != 0) {
- DEBUG(0, ("load_groupname_map: Unable to stat file %s. Error was %s\n",
- groupname_map_file, strerror(errno) ));
- return;
- }
-
- /*
- * Check if file has changed.
- */
- if( st.st_mtime <= groupmap_file_last_modified)
- return;
-
- groupmap_file_last_modified = st.st_mtime;
-
- /*
- * Load the file.
- */
-
- fp = fopen(groupname_map_file,"r");
- if (!fp) {
- DEBUG(0,("load_groupname_map: can't open groupname map %s. Error was %s\n",
- groupname_map_file, strerror(errno)));
- return;
- }
-
- /*
- * Throw away any previous list.
- */
- delete_groupname_map_list();
-
- DEBUG(4,("load_groupname_map: Scanning groupname map %s\n",groupname_map_file));
-
- while((s=fgets_slash(buf,sizeof(buf),fp))!=NULL) {
- pstring unixname;
- pstring windows_name;
- struct group *gptr;
- DOM_SID tmp_sid;
-
- DEBUG(10,("load_groupname_map: Read line |%s|\n", s));
-
- if (!*s || strchr("#;",*s))
- continue;
-
- if(!next_token(&s,unixname, "\t\n\r=", sizeof(unixname)))
- continue;
-
- if(!next_token(&s,windows_name, "\t\n\r=", sizeof(windows_name)))
- continue;
-
- trim_string(unixname, " ", " ");
- trim_string(windows_name, " ", " ");
-
- if (!*windows_name)
- continue;
-
- if(!*unixname)
- continue;
-
- DEBUG(5,("load_groupname_map: unixname = %s, windowsname = %s.\n",
- unixname, windows_name));
-
- /*
- * 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.\
-Error was %s.\n", unixname, strerror(errno) ));
- continue;
- }
-
- /*
- * Now map to an NT SID.
- */
-
- if(!lookup_wellknown_sid_from_name(windows_name, &tmp_sid)) {
- /*
- * It's not a well known name, convert the UNIX gid_t
- * to a rid within this domain SID.
- */
- tmp_sid = global_sam_sid;
- tmp_sid.sub_auths[tmp_sid.num_auths++] =
- pdb_gid_to_group_rid((gid_t)gptr->gr_gid);
- }
-
- /*
- * Create the list entry and add it onto the list.
- */
-
- if((new_ep = (groupname_map_entry *)malloc( sizeof(groupname_map_entry) ))== NULL) {
- DEBUG(0,("load_groupname_map: malloc fail for groupname_map_entry.\n"));
- fclose(fp);
- return;
- }
-
- new_ep->unix_gid = gptr->gr_gid;
- new_ep->windows_sid = tmp_sid;
- new_ep->windows_name = strdup( windows_name );
- new_ep->unix_name = strdup( unixname );
-
- if(new_ep->windows_name == NULL || new_ep->unix_name == NULL) {
- DEBUG(0,("load_groupname_map: malloc fail for names in groupname_map_entry.\n"));
- fclose(fp);
- if(new_ep->windows_name != NULL)
- free(new_ep->windows_name);
- if(new_ep->unix_name != NULL)
- free(new_ep->unix_name);
- free((char *)new_ep);
- return;
- }
- memset((char *)&new_ep->next, '\0', sizeof(new_ep->next) );
-
- ubi_slAddHead( &groupname_map_list, (ubi_slNode *)new_ep);
- }
-
- DEBUG(10,("load_groupname_map: Added %ld entries to groupname map.\n",
- ubi_slCount(&groupname_map_list)));
-
- fclose(fp);
+/***********************************************************
+ Lookup a SID entry by nt name.
+************************************************************/
+static BOOL map_ntname_to_sid(GROUP_TYPE type, ubi_slList *map_list,
+ char * ntname, DOM_SID *psid)
+{
+ name_map_entry *gmep;
+
+ /*
+ * Initialize and load if not already loaded.
+ */
+ load_name_map(type);
+
+ for (gmep = (name_map_entry *)ubi_slFirst(&map_list);
+ gmep != NULL;
+ gmep = (name_map_entry *)ubi_slNext(gmep ))
+ {
+ if (strequal(gmep->grp.nt_name, ntname))
+ {
+ *psid = gmep->grp.sid;
+ DEBUG(7,("map_ntname_to_sid: Mapping unix group %s to nt group %s.\n",
+ gmep->grp.unix_name, gmep->grp.nt_name ));
+ return True;
+ }
+ }
+
+ return False;
}
/***********************************************************
Lookup a SID entry by gid_t.
************************************************************/
+static BOOL map_gid_to_sid(GROUP_TYPE type, ubi_slList *map_list,
+ gid_t gid, DOM_SID *psid)
+{
+ name_map_entry *gmep;
+
+ /*
+ * Initialize and load if not already loaded.
+ */
+ load_name_map(type);
+
+ for (gmep = (name_map_entry *)ubi_slFirst(&map_list);
+ gmep != NULL;
+ gmep = (name_map_entry *)ubi_slNext(gmep ))
+ {
+ if (gmep->grp.unix_gid == gid)
+ {
+ *psid = gmep->grp.sid;
+ DEBUG(7,("map_gid_to_sid: Mapping unix group %s to nt group %s.\n",
+ gmep->grp.unix_name, gmep->grp.nt_name ));
+ return True;
+ }
+ }
+
+ return False;
+}
+
+/*
+ * Call these four functions to resolve unix group ids and either
+ * local group SIDs or domain group SIDs listed in the local group
+ * or domain group map files.
+ *
+ * Note that it is *NOT* the responsibility of these functions to
+ * resolve entries that are not in the map files.
+ *
+ * Any SID can be in the map files (i.e from any Domain).
+ */
-void map_gid_to_sid( gid_t gid, DOM_SID *psid)
+/***********************************************************
+ Lookup a Group entry by sid.
+************************************************************/
+BOOL map_group_sid_to_name(DOM_SID *psid, char *group_name, char *nt_domain)
+{
+ return map_sid_to_ntname(GROUP_DOMAIN, &groupname_map_list, psid, group_name, nt_domain);
+}
+
+/***********************************************************
+ Lookup an Alias SID entry by name.
+************************************************************/
+BOOL map_alias_sid_to_name(DOM_SID *psid, char *alias_name, char *nt_domain)
+{
+ return map_sid_to_ntname(GROUP_LOCAL, &aliasname_map_list, psid, alias_name, nt_domain);
+}
+
+/***********************************************************
+ Lookup a Group SID entry by name.
+************************************************************/
+BOOL map_group_name_to_sid(char *group_name, DOM_SID *psid)
{
- groupname_map_entry *gmep;
+ return map_ntname_to_sid(GROUP_DOMAIN, &groupname_map_list, group_name, psid);
+}
- /*
- * Initialize and load if not already loaded.
- */
- load_groupname_map();
+/***********************************************************
+ Lookup an Alias SID entry by name.
+************************************************************/
+BOOL map_alias_name_to_sid(char *alias_name, DOM_SID *psid)
+{
+ return map_ntname_to_sid(GROUP_LOCAL, &aliasname_map_list, alias_name, psid);
+}
- for( gmep = (groupname_map_entry *)ubi_slFirst( &groupname_map_list);
- gmep; gmep = (groupname_map_entry *)ubi_slNext( gmep )) {
+/***********************************************************
+ Lookup an Alias SID entry by gid_t.
+************************************************************/
+BOOL map_gid_to_alias_sid(gid_t gid, DOM_SID *psid)
+{
+ return map_gid_to_sid(GROUP_LOCAL, &aliasname_map_list, gid, psid);
+}
- if( gmep->unix_gid == gid) {
- *psid = gmep->windows_sid;
- DEBUG(7,("map_gid_to_sid: Mapping unix group %s to windows group %s.\n",
- gmep->unix_name, gmep->windows_name ));
- return;
- }
- }
+/***********************************************************
+ Lookup a Group SID entry by gid_t.
+************************************************************/
+BOOL map_gid_to_group_sid( gid_t gid, DOM_SID *psid)
+{
+ return map_gid_to_sid(GROUP_DOMAIN, &groupname_map_list, gid, psid);
+}
- /*
- * If there's no map, convert the UNIX gid_t
- * to a rid within this domain SID.
- */
- *psid = global_sam_sid;
- psid->sub_auths[psid->num_auths++] = pdb_gid_to_group_rid(gid);
+/***********************************************************
+ Lookup a Group gid_t by SID
+************************************************************/
+BOOL map_group_sid_to_gid( DOM_SID *psid, gid_t *gid)
+{
+ return map_sid_to_gid(GROUP_DOMAIN, &groupname_map_list, psid, gid);
+}
- return;
+/***********************************************************
+ Lookup an Alias gid_t by SID
+************************************************************/
+BOOL map_alias_sid_to_gid( DOM_SID *psid, gid_t *gid)
+{
+ return map_sid_to_gid(GROUP_LOCAL, &aliasname_map_list, psid, gid);
}
-#else /* USING_GROUPNAME_MAP */
- void load_groupname_map(void) {;}
-#endif /* USING_GROUPNAME_MAP */
+
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 8b4049cd96..e4f0d2e2ec 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -562,8 +562,8 @@ int reply_ntcreate_and_X(connection_struct *conn,
/* If it's an IPC, use the pipe handler. */
- if (IS_IPC(conn) && lp_nt_pipe_support()) {
-
+ if (IS_IPC(conn) && lp_nt_pipe_support() && lp_security() != SEC_SHARE)
+ {
int ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum);
if(ret != 0)
return ret;
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index fb5acf156f..0c8eb124ff 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -153,7 +153,7 @@ char *validated_username(uint16 vuid)
/****************************************************************************
Setup the groups a user belongs to.
****************************************************************************/
-int setup_groups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups)
+int get_unixgroups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups)
{
int i,ngroups;
gid_t grp = 0;
@@ -180,7 +180,7 @@ int setup_groups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_gro
if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL)
{
- DEBUG(0,("setup_groups malloc fail !\n"));
+ DEBUG(0,("get_unixgroups malloc fail !\n"));
return -1;
}
@@ -263,7 +263,7 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
/* Find all the groups this uid is in and store them.
Used by become_user() */
- setup_groups(unix_name,uid,gid,
+ get_unixgroups(unix_name,uid,gid,
&vuser->n_groups,
&vuser->groups);
@@ -1142,15 +1142,10 @@ BOOL domain_client_validate( char *user, char *domain,
unsigned char local_lm_response[24];
unsigned char local_nt_reponse[24];
unsigned char trust_passwd[16];
- fstring remote_machine;
- char *p;
- struct in_addr dest_ip;
NET_ID_INFO_CTR ctr;
NET_USER_INFO_3 info3;
struct cli_state cli;
uint32 smb_uid_low;
- BOOL connected_ok = False;
- struct nmb_name calling, called;
/*
* Check that the requested domain is not our own machine name.
@@ -1211,102 +1206,9 @@ BOOL domain_client_validate( char *user, char *domain,
* see if they were valid.
*/
- ZERO_STRUCT(cli);
-
- if(cli_initialise(&cli) == False) {
- DEBUG(0,("domain_client_validate: unable to initialize client connection.\n"));
- return False;
- }
-
- /*
- * Treat each name in the 'password server =' line as a potential
- * PDC/BDC. Contact each in turn and try and authenticate.
- */
-
- p = lp_passwordserver();
- while(p && next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) {
-
- standard_sub_basic(remote_machine);
- strupper(remote_machine);
-
- if(!resolve_name( remote_machine, &dest_ip, 0x20)) {
- DEBUG(1,("domain_client_validate: Can't resolve address for %s\n", remote_machine));
- continue;
- }
-
- if (ismyip(dest_ip)) {
- DEBUG(1,("domain_client_validate: Password server loop - not using password server %s\n",remote_machine));
- continue;
- }
-
- if (!cli_connect(&cli, remote_machine, &dest_ip)) {
- DEBUG(0,("domain_client_validate: unable to connect to SMB server on \
-machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
- continue;
- }
-
- make_nmb_name(&calling, global_myname , 0x0 , scope);
- make_nmb_name(&called , remote_machine, 0x20, scope);
-
- if (!cli_session_request(&cli, &calling, &called))
+ if (!cli_connect_serverlist(&cli, lp_passwordserver()))
{
- DEBUG(0,("domain_client_validate: machine %s rejected the session setup. \
-Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
- cli_shutdown(&cli);
- continue;
- }
-
- cli.protocol = PROTOCOL_NT1;
-
- if (!cli_negprot(&cli)) {
- DEBUG(0,("domain_client_validate: machine %s rejected the negotiate protocol. \
-Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
- cli_shutdown(&cli);
- continue;
- }
-
- if (cli.protocol != PROTOCOL_NT1) {
- DEBUG(0,("domain_client_validate: machine %s didn't negotiate NT protocol.\n",
- remote_machine));
- cli_shutdown(&cli);
- continue;
- }
-
- /*
- * Do an anonymous session setup.
- */
-
- if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
- DEBUG(0,("domain_client_validate: machine %s rejected the session setup. \
-Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
- cli_shutdown(&cli);
- continue;
- }
-
- if (!(cli.sec_mode & 1)) {
- DEBUG(1,("domain_client_validate: machine %s isn't in user level security mode\n",
- remote_machine));
- cli_shutdown(&cli);
- continue;
- }
-
- if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
- DEBUG(0,("domain_client_validate: machine %s rejected the tconX on the IPC$ share. \
-Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
- cli_shutdown(&cli);
- continue;
- }
-
- /*
- * We have an anonymous connection to IPC$.
- */
- connected_ok = True;
- break;
- }
-
- if (!connected_ok) {
DEBUG(0,("domain_client_validate: Domain password server not available.\n"));
- cli_shutdown(&cli);
return False;
}
@@ -1317,7 +1219,7 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
if(cli_nt_session_open(&cli, PIPE_NETLOGON) == False) {
DEBUG(0,("domain_client_validate: unable to open the domain client session to \
-machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
+machine %s. Error was : %s.\n", cli.desthost, cli_errstr(&cli)));
cli_nt_session_close(&cli);
cli_ulogoff(&cli);
cli_shutdown(&cli);
@@ -1326,7 +1228,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
if(cli_nt_setup_creds(&cli, trust_passwd) == False) {
DEBUG(0,("domain_client_validate: unable to setup the PDC credentials to machine \
-%s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
+%s. Error was : %s.\n", cli.desthost, cli_errstr(&cli)));
cli_nt_session_close(&cli);
cli_ulogoff(&cli);
cli_shutdown(&cli);
@@ -1341,7 +1243,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
((smb_ntpasslen != 0) ? smb_ntpasswd : NULL),
&ctr, &info3) == False) {
DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \
-%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli)));
+%s to Domain controller %s. Error was %s.\n", user, domain, cli.desthost, cli_errstr(&cli)));
cli_nt_session_close(&cli);
cli_ulogoff(&cli);
cli_shutdown(&cli);
@@ -1361,7 +1263,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
if(cli_nt_logoff(&cli, &ctr) == False) {
DEBUG(0,("domain_client_validate: unable to log off user %s in domain \
-%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli)));
+%s to Domain controller %s. Error was %s.\n", user, domain, cli.desthost, cli_errstr(&cli)));
cli_nt_session_close(&cli);
cli_ulogoff(&cli);
cli_shutdown(&cli);
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index ee0053aed0..78a09e46e7 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -1403,8 +1403,10 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
files_struct *fsp;
/* If it's an IPC, pass off the pipe handler. */
- if (IS_IPC(conn) && lp_nt_pipe_support())
+ if (IS_IPC(conn) && lp_nt_pipe_support() && lp_security() != SEC_SHARE)
+ {
return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
+ }
/* XXXX we need to handle passed times, sattr and flags */
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 68f722ff51..49816e5d47 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -25,6 +25,7 @@
pstring servicesf = CONFIGFILE;
extern pstring debugf;
extern fstring global_myworkgroup;
+extern fstring global_sam_name;
extern pstring global_myname;
int am_parent = 1;
@@ -428,6 +429,13 @@ void exit_server(char *reason)
locking_end();
DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
+#ifdef MEM_MAN
+ {
+ extern FILE *dbf;
+ smb_mem_write_verbose(dbf);
+ dbgflush();
+ }
+#endif
exit(0);
}
@@ -644,12 +652,42 @@ static void usage(char *pname)
codepage_initialise(lp_client_code_page());
fstrcpy(global_myworkgroup, lp_workgroup());
+ memset(global_sam_name, 0, sizeof(global_sam_name));
+
+ if (lp_domain_logons())
+ {
+ if (lp_security() == SEC_USER)
+ {
+ /* we are PDC (or BDC) for a Domain */
+ fstrcpy(global_sam_name, lp_workgroup());
+ }
+ else if (lp_security() == SEC_DOMAIN)
+ {
+ /* we are a "PDC", but FOR LOCAL SAM DATABASE ONLY */
+ fstrcpy(global_sam_name, global_myname);
+ }
+ else if (lp_security() == SEC_SHARE)
+ {
+ DEBUG(0,("ERROR: no Domain functionality in security = share\n"));
+ exit(1);
+ }
+ }
+
+ generate_wellknown_sids();
- if(!pdb_generate_sam_sid()) {
+ if (!generate_sam_sid())
+ {
DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n"));
exit(1);
}
+ if (lp_security() == SEC_DOMAIN && !get_member_domain_sid())
+ {
+ DEBUG(0,("ERROR: Samba cannot obtain PDC SID from PDC(s) %s.\n",
+ lp_passwordserver()));
+ exit(1);
+ }
+
CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
/* Setup the signals that allow the debug log level
@@ -696,7 +734,16 @@ static void usage(char *pname)
if (!locking_init(0))
exit(1);
- if(!initialize_password_db())
+ if(!initialise_passgrp_db())
+ exit(1);
+
+ if(!initialise_password_db())
+ exit(1);
+
+ if(!initialise_group_db())
+ exit(1);
+
+ if(!initialise_alias_db())
exit(1);
/* possibly reload the services file. */
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index ee195e12ec..cedac1c76f 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -387,7 +387,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
if (!IS_IPC(conn)) {
/* Find all the groups this uid is in and
store them. Used by become_user() */
- setup_groups(conn->user,conn->uid,conn->gid,
+ get_unixgroups(conn->user,conn->uid,conn->gid,
&conn->ngroups,&conn->groups);
/* check number of connections */