Fixed typo.
[Samba.git] / source / smbd / groupname.c
blob4dadfaa9396e62a07a14849a85364c498b243f33
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Groupname handling
5 Copyright (C) Jeremy Allison 1998.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #ifdef USING_GROUPNAME_MAP
24 #include "includes.h"
25 extern int DEBUGLEVEL;
26 extern DOM_SID global_sam_sid;
29 /**************************************************************************
30 Groupname map functionality. The code loads a groupname map file and
31 (currently) loads it into a linked list. This is slow and memory
32 hungry, but can be changed into a more efficient storage format
33 if the demands on it become excessive.
34 ***************************************************************************/
36 typedef struct groupname_map {
37 ubi_slNode next;
39 char *windows_name;
40 DOM_SID windows_sid;
41 char *unix_name;
42 gid_t unix_gid;
43 } groupname_map_entry;
45 static ubi_slList groupname_map_list;
47 /**************************************************************************
48 Delete all the entries in the groupname map list.
49 ***************************************************************************/
51 static void delete_groupname_map_list(void)
53 groupname_map_entry *gmep;
55 while((gmep = (groupname_map_entry *)ubi_slRemHead( &groupname_map_list )) != NULL) {
56 if(gmep->windows_name)
57 free(gmep->windows_name);
58 if(gmep->unix_name)
59 free(gmep->unix_name);
60 free((char *)gmep);
64 /**************************************************************************
65 Load a groupname map file. Sets last accessed timestamp.
66 ***************************************************************************/
68 void load_groupname_map(void)
70 static time_t groupmap_file_last_modified = (time_t)0;
71 static BOOL initialized = False;
72 char *groupname_map_file = lp_groupname_map();
73 SMB_STRUCT_STAT st;
74 FILE *fp;
75 char *s;
76 pstring buf;
77 groupname_map_entry *new_ep;
79 if(!initialized) {
80 ubi_slInitList( &groupname_map_list );
81 initialized = True;
84 if (!*groupname_map_file)
85 return;
87 if(sys_stat(groupname_map_file, &st) != 0) {
88 DEBUG(0, ("load_groupname_map: Unable to stat file %s. Error was %s\n",
89 groupname_map_file, strerror(errno) ));
90 return;
94 * Check if file has changed.
96 if( st.st_mtime <= groupmap_file_last_modified)
97 return;
99 groupmap_file_last_modified = st.st_mtime;
102 * Load the file.
105 fp = sys_fopen(groupname_map_file,"r");
106 if (!fp) {
107 DEBUG(0,("load_groupname_map: can't open groupname map %s. Error was %s\n",
108 groupname_map_file, strerror(errno)));
109 return;
113 * Throw away any previous list.
115 delete_groupname_map_list();
117 DEBUG(4,("load_groupname_map: Scanning groupname map %s\n",groupname_map_file));
119 while((s=fgets_slash(buf,sizeof(buf),fp))!=NULL) {
120 pstring unixname;
121 pstring windows_name;
122 struct group *gptr;
123 DOM_SID tmp_sid;
125 DEBUG(10,("load_groupname_map: Read line |%s|\n", s));
127 if (!*s || strchr("#;",*s))
128 continue;
130 if(!next_token(&s,unixname, "\t\n\r=", sizeof(unixname)))
131 continue;
133 if(!next_token(&s,windows_name, "\t\n\r=", sizeof(windows_name)))
134 continue;
136 trim_string(unixname, " ", " ");
137 trim_string(windows_name, " ", " ");
139 if (!*windows_name)
140 continue;
142 if(!*unixname)
143 continue;
145 DEBUG(5,("load_groupname_map: unixname = %s, windowsname = %s.\n",
146 unixname, windows_name));
149 * Attempt to get the unix gid_t for this name.
152 if((gptr = (struct group *)getgrnam(unixname)) == NULL) {
153 DEBUG(0,("load_groupname_map: getgrnam for group %s failed.\
154 Error was %s.\n", unixname, strerror(errno) ));
155 continue;
159 * Now map to an NT SID.
162 if(!lookup_wellknown_sid_from_name(windows_name, &tmp_sid)) {
164 * It's not a well known name, convert the UNIX gid_t
165 * to a rid within this domain SID.
167 tmp_sid = global_sam_sid;
168 tmp_sid.sub_auths[tmp_sid.num_auths++] =
169 pdb_gid_to_group_rid((gid_t)gptr->gr_gid);
173 * Create the list entry and add it onto the list.
176 if((new_ep = (groupname_map_entry *)malloc( sizeof(groupname_map_entry) ))== NULL) {
177 DEBUG(0,("load_groupname_map: malloc fail for groupname_map_entry.\n"));
178 fclose(fp);
179 return;
182 new_ep->unix_gid = gptr->gr_gid;
183 new_ep->windows_sid = tmp_sid;
184 new_ep->windows_name = strdup( windows_name );
185 new_ep->unix_name = strdup( unixname );
187 if(new_ep->windows_name == NULL || new_ep->unix_name == NULL) {
188 DEBUG(0,("load_groupname_map: malloc fail for names in groupname_map_entry.\n"));
189 fclose(fp);
190 if(new_ep->windows_name != NULL)
191 free(new_ep->windows_name);
192 if(new_ep->unix_name != NULL)
193 free(new_ep->unix_name);
194 free((char *)new_ep);
195 return;
197 memset((char *)&new_ep->next, '\0', sizeof(new_ep->next) );
199 ubi_slAddHead( &groupname_map_list, (ubi_slNode *)new_ep);
202 DEBUG(10,("load_groupname_map: Added %ld entries to groupname map.\n",
203 ubi_slCount(&groupname_map_list)));
205 fclose(fp);
208 /***********************************************************
209 Lookup a SID entry by gid_t.
210 ************************************************************/
212 void map_gid_to_sid( gid_t gid, DOM_SID *psid)
214 groupname_map_entry *gmep;
217 * Initialize and load if not already loaded.
219 load_groupname_map();
221 for( gmep = (groupname_map_entry *)ubi_slFirst( &groupname_map_list);
222 gmep; gmep = (groupname_map_entry *)ubi_slNext( gmep )) {
224 if( gmep->unix_gid == gid) {
225 *psid = gmep->windows_sid;
226 DEBUG(7,("map_gid_to_sid: Mapping unix group %s to windows group %s.\n",
227 gmep->unix_name, gmep->windows_name ));
228 return;
233 * If there's no map, convert the UNIX gid_t
234 * to a rid within this domain SID.
236 *psid = global_sam_sid;
237 psid->sub_auths[psid->num_auths++] = pdb_gid_to_group_rid(gid);
239 return;
241 #else /* USING_GROUPNAME_MAP */
242 void load_groupname_map(void) {;}
243 #endif /* USING_GROUPNAME_MAP */