add WITH_SENDFILE profiling data (from Pierre Belanger)
[Samba.git] / source / smbd / groupname.c
blob2c7440d75a74492852af5a6533dbec7f7c1aadf2
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 DOM_SID global_sam_sid;
28 /**************************************************************************
29 Groupname map functionality. The code loads a groupname map file and
30 (currently) loads it into a linked list. This is slow and memory
31 hungry, but can be changed into a more efficient storage format
32 if the demands on it become excessive.
33 ***************************************************************************/
35 typedef struct groupname_map {
36 ubi_slNode next;
38 char *windows_name;
39 DOM_SID windows_sid;
40 char *unix_name;
41 gid_t unix_gid;
42 } groupname_map_entry;
44 static ubi_slList groupname_map_list;
46 /**************************************************************************
47 Delete all the entries in the groupname map list.
48 ***************************************************************************/
50 static void delete_groupname_map_list(void)
52 groupname_map_entry *gmep;
54 while((gmep = (groupname_map_entry *)ubi_slRemHead( &groupname_map_list )) != NULL) {
55 SAFE_FREE(gmep->windows_name);
56 SAFE_FREE(gmep->unix_name);
57 SAFE_FREE(gmep);
61 /**************************************************************************
62 Load a groupname map file. Sets last accessed timestamp.
63 ***************************************************************************/
65 void load_groupname_map(void)
67 static time_t groupmap_file_last_modified = (time_t)0;
68 static BOOL initialized = False;
69 char *groupname_map_file = lp_groupname_map();
70 SMB_STRUCT_STAT st;
71 char **lines;
72 int i;
73 groupname_map_entry *new_ep;
75 if(!initialized) {
76 ubi_slInitList( &groupname_map_list );
77 initialized = True;
80 if (!*groupname_map_file)
81 return;
83 if(sys_stat(groupname_map_file, &st) != 0) {
84 DEBUG(0, ("load_groupname_map: Unable to stat file %s. Error was %s\n",
85 groupname_map_file, strerror(errno) ));
86 return;
90 * Check if file has changed.
92 if( st.st_mtime <= groupmap_file_last_modified)
93 return;
95 groupmap_file_last_modified = st.st_mtime;
98 * Load the file.
101 lines = file_lines_load(groupname_map_file,NULL,False);
102 if (!lines) {
103 DEBUG(0,("load_groupname_map: can't open groupname map %s. Error was %s\n",
104 groupname_map_file, strerror(errno)));
105 return;
107 file_lines_slashcont(lines);
110 * Throw away any previous list.
112 delete_groupname_map_list();
114 DEBUG(4,("load_groupname_map: Scanning groupname map %s\n",groupname_map_file));
116 for (i=0; lines[i]; i++) {
117 pstring unixname;
118 pstring windows_name;
119 gid_t gid;
120 DOM_SID tmp_sid;
121 char *s = lines[i];
123 DEBUG(10,("load_groupname_map: Read line |%s|\n", s));
125 if (!*s || strchr("#;",*s))
126 continue;
128 if(!next_token(&s,unixname, "\t\n\r=", sizeof(unixname)))
129 continue;
131 if(!next_token(&s,windows_name, "\t\n\r=", sizeof(windows_name)))
132 continue;
134 trim_string(unixname, " ", " ");
135 trim_string(windows_name, " ", " ");
137 if (!*windows_name)
138 continue;
140 if(!*unixname)
141 continue;
143 DEBUG(5,("load_groupname_map: unixname = %s, windowsname = %s.\n",
144 unixname, windows_name));
147 * Attempt to get the unix gid_t for this name.
150 if ((gid = nametogid(unixname)) == (gid_t)-1)
151 DEBUG(0,("load_groupname_map: nametogid for group %s failed.\
152 Error was %s.\n", unixname, strerror(errno) ));
153 continue;
157 * Now map to an NT SID.
160 if(!lookup_wellknown_sid_from_name(windows_name, &tmp_sid)) {
162 * It's not a well known name, convert the UNIX gid_t
163 * to a rid within this domain SID.
165 tmp_sid = global_sam_sid;
166 tmp_sid.sub_auths[tmp_sid.num_auths++] =
167 pdb_gid_to_group_rid(gid);
171 * Create the list entry and add it onto the list.
174 if((new_ep = (groupname_map_entry *)malloc( sizeof(groupname_map_entry) ))== NULL) {
175 DEBUG(0,("load_groupname_map: malloc fail for groupname_map_entry.\n"));
176 fclose(fp);
177 return;
180 new_ep->unix_gid = gid;
181 new_ep->windows_sid = tmp_sid;
182 new_ep->windows_name = strdup( windows_name );
183 new_ep->unix_name = strdup( unixname );
185 if(new_ep->windows_name == NULL || new_ep->unix_name == NULL) {
186 DEBUG(0,("load_groupname_map: malloc fail for names in groupname_map_entry.\n"));
187 fclose(fp);
188 SAFE_FREE(new_ep->windows_name);
189 SAFE_FREE(new_ep->unix_name);
190 SAFE_FREE(new_ep);
191 file_lines_free(lines);
192 return;
194 memset((char *)&new_ep->next, '\0', sizeof(new_ep->next) );
196 ubi_slAddHead( &groupname_map_list, (ubi_slNode *)new_ep);
199 DEBUG(10,("load_groupname_map: Added %ld entries to groupname map.\n",
200 ubi_slCount(&groupname_map_list)));
202 file_lines_free(lines);
205 /***********************************************************
206 Lookup a SID entry by gid_t.
207 ************************************************************/
209 void map_gid_to_sid( gid_t gid, DOM_SID *psid)
211 groupname_map_entry *gmep;
214 * Initialize and load if not already loaded.
216 load_groupname_map();
218 for( gmep = (groupname_map_entry *)ubi_slFirst( &groupname_map_list);
219 gmep; gmep = (groupname_map_entry *)ubi_slNext( gmep )) {
221 if( gmep->unix_gid == gid) {
222 *psid = gmep->windows_sid;
223 DEBUG(7,("map_gid_to_sid: Mapping unix group %s to windows group %s.\n",
224 gmep->unix_name, gmep->windows_name ));
225 return;
230 * If there's no map, convert the UNIX gid_t
231 * to a rid within this domain SID.
233 *psid = global_sam_sid;
234 psid->sub_auths[psid->num_auths++] = pdb_gid_to_group_rid(gid);
236 return;
238 #else /* USING_GROUPNAME_MAP */
239 void load_groupname_map(void) {;}
240 #endif /* USING_GROUPNAME_MAP */