must add one to the extra_data size to transfer the 0 string terminator.
[Samba/gebeck_regimport.git] / source3 / smbd / groupname.c
blob5147ae4b95ef76c6fda5f39b8ef4ff55e101ca3b
1 /*
2 Unix SMB/CIFS implementation.
3 Groupname handling
4 Copyright (C) Jeremy Allison 1998.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #ifdef USING_GROUPNAME_MAP
23 #include "includes.h"
25 /**************************************************************************
26 Groupname map functionality. The code loads a groupname map file and
27 (currently) loads it into a linked list. This is slow and memory
28 hungry, but can be changed into a more efficient storage format
29 if the demands on it become excessive.
30 ***************************************************************************/
32 typedef struct groupname_map {
33 ubi_slNode next;
35 char *windows_name;
36 DOM_SID windows_sid;
37 char *unix_name;
38 gid_t unix_gid;
39 } groupname_map_entry;
41 static ubi_slList groupname_map_list;
43 /**************************************************************************
44 Delete all the entries in the groupname map list.
45 ***************************************************************************/
47 static void delete_groupname_map_list(void)
49 groupname_map_entry *gmep;
51 while((gmep = (groupname_map_entry *)ubi_slRemHead( &groupname_map_list )) != NULL) {
52 SAFE_FREE(gmep->windows_name);
53 SAFE_FREE(gmep->unix_name);
54 SAFE_FREE(gmep);
58 /**************************************************************************
59 Load a groupname map file. Sets last accessed timestamp.
60 ***************************************************************************/
62 void load_groupname_map(void)
64 static time_t groupmap_file_last_modified = (time_t)0;
65 static BOOL initialized = False;
66 char *groupname_map_file = lp_groupname_map();
67 SMB_STRUCT_STAT st;
68 char **lines;
69 int i;
70 groupname_map_entry *new_ep;
72 if(!initialized) {
73 ubi_slInitList( &groupname_map_list );
74 initialized = True;
77 if (!*groupname_map_file)
78 return;
80 if(sys_stat(groupname_map_file, &st) != 0) {
81 DEBUG(0, ("load_groupname_map: Unable to stat file %s. Error was %s\n",
82 groupname_map_file, strerror(errno) ));
83 return;
87 * Check if file has changed.
89 if( st.st_mtime <= groupmap_file_last_modified)
90 return;
92 groupmap_file_last_modified = st.st_mtime;
95 * Load the file.
98 lines = file_lines_load(groupname_map_file,NULL,False);
99 if (!lines) {
100 DEBUG(0,("load_groupname_map: can't open groupname map %s. Error was %s\n",
101 groupname_map_file, strerror(errno)));
102 return;
104 file_lines_slashcont(lines);
107 * Throw away any previous list.
109 delete_groupname_map_list();
111 DEBUG(4,("load_groupname_map: Scanning groupname map %s\n",groupname_map_file));
113 for (i=0; lines[i]; i++) {
114 pstring unixname;
115 pstring windows_name;
116 gid_t gid;
117 DOM_SID tmp_sid;
118 char *s = lines[i];
120 DEBUG(10,("load_groupname_map: Read line |%s|\n", s));
122 if (!*s || strchr_m("#;",*s))
123 continue;
125 if(!next_token(&s,unixname, "\t\n\r=", sizeof(unixname)))
126 continue;
128 if(!next_token(&s,windows_name, "\t\n\r=", sizeof(windows_name)))
129 continue;
131 trim_string(unixname, " ", " ");
132 trim_string(windows_name, " ", " ");
134 if (!*windows_name)
135 continue;
137 if(!*unixname)
138 continue;
140 DEBUG(5,("load_groupname_map: unixname = %s, windowsname = %s.\n",
141 unixname, windows_name));
144 * Attempt to get the unix gid_t for this name.
147 if ((gid = nametogid(unixname)) == (gid_t)-1)
148 DEBUG(0,("load_groupname_map: nametogid for group %s failed.\
149 Error was %s.\n", unixname, strerror(errno) ));
150 continue;
154 * Now map to an NT SID.
157 if(!lookup_wellknown_sid_from_name(windows_name, &tmp_sid)) {
159 * It's not a well known name, convert the UNIX gid_t
160 * to a rid within this domain SID.
162 sid_copy(&tmp_sid,get_global_sam_sid());
163 tmp_sid.sub_auths[tmp_sid.num_auths++] =
164 pdb_gid_to_group_rid(gid);
168 * Create the list entry and add it onto the list.
171 if((new_ep = (groupname_map_entry *)malloc( sizeof(groupname_map_entry) ))== NULL) {
172 DEBUG(0,("load_groupname_map: malloc fail for groupname_map_entry.\n"));
173 fclose(fp);
174 return;
177 new_ep->unix_gid = gid;
178 new_ep->windows_sid = tmp_sid;
179 new_ep->windows_name = strdup( windows_name );
180 new_ep->unix_name = strdup( unixname );
182 if(new_ep->windows_name == NULL || new_ep->unix_name == NULL) {
183 DEBUG(0,("load_groupname_map: malloc fail for names in groupname_map_entry.\n"));
184 fclose(fp);
185 SAFE_FREE(new_ep->windows_name);
186 SAFE_FREE(new_ep->unix_name);
187 SAFE_FREE(new_ep);
188 file_lines_free(lines);
189 return;
191 memset((char *)&new_ep->next, '\0', sizeof(new_ep->next) );
193 ubi_slAddHead( &groupname_map_list, (ubi_slNode *)new_ep);
196 DEBUG(10,("load_groupname_map: Added %ld entries to groupname map.\n",
197 ubi_slCount(&groupname_map_list)));
199 file_lines_free(lines);
202 /***********************************************************
203 Lookup a SID entry by gid_t.
204 ************************************************************/
206 void map_gid_to_sid( gid_t gid, DOM_SID *psid)
208 groupname_map_entry *gmep;
211 * Initialize and load if not already loaded.
213 load_groupname_map();
215 for( gmep = (groupname_map_entry *)ubi_slFirst( &groupname_map_list);
216 gmep; gmep = (groupname_map_entry *)ubi_slNext( gmep )) {
218 if( gmep->unix_gid == gid) {
219 *psid = gmep->windows_sid;
220 DEBUG(7,("map_gid_to_sid: Mapping unix group %s to windows group %s.\n",
221 gmep->unix_name, gmep->windows_name ));
222 return;
227 * If there's no map, convert the UNIX gid_t
228 * to a rid within this domain SID.
230 sid_copy(psid,get_global_sam_sid());
231 psid->sub_auths[psid->num_auths++] = pdb_gid_to_group_rid(gid);
233 return;
235 #else /* USING_GROUPNAME_MAP */
236 void load_groupname_map(void) {;}
237 #endif /* USING_GROUPNAME_MAP */