1 /*----------------------------------------------------------------------------
2 --
3 --  Module:           xtmAccBase
4 --
5 --  Project:          XDiary
6 --  System:           xtm - X Desktop Calendar
7 --    Subsystem:      <>
8 --    Function block: <>
9 --
10 --  Description:
11 --    Base access control functions.
12 --
13 --  Filename:         xtmAccBase.c
14 --
15 --  Authors:          Roger Larsson, Ulrika Bornetun
16 --  Creation date:    1995-02-03
17 --
18 --
19 --  (C) Copyright Ulrika Bornetun, Roger Larsson (1995)
20 --      All rights reserved
21 --
22 --  Permission to use, copy, modify, and distribute this software and its
23 --  documentation for any purpose and without fee is hereby granted,
24 --  provided that the above copyright notice appear in all copies. Ulrika
25 --  Bornetun and Roger Larsson make no representations about the usability
26 --  of this software for any purpose. It is provided "as is" without express
27 --  or implied warranty.
28 ----------------------------------------------------------------------------*/
29 
30 /* SCCS module identifier. */
31 static char SCCSID[] = "@(#) Module: xtmAccBase.c, Version: 1.1, Date: 95/02/18 15:51:49";
32 
33 
34 /*----------------------------------------------------------------------------
35 --  Include files
36 ----------------------------------------------------------------------------*/
37 
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <ctype.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 
45 #include <X11/Intrinsic.h>
46 
47 #include "System.h"
48 #include "LstLinked.h"
49 #include "Message.h"
50 
51 #include "msgXdiary.h"
52 #include "xtmGlobal.h"
53 #include "xtmDbTools.h"
54 #include "xitError.h"
55 #include "xtmAccBase.h"
56 
57 
58 /*----------------------------------------------------------------------------
59 --  Macro definitions
60 ----------------------------------------------------------------------------*/
61 
62 /* Access control file. */
63 #define ACCESS_FILE      "dbAccess"
64 #define AFS_ACCESS_FILE  "dbAfsAccess"
65 
66 /* Keys to use in the access file. */
67 #define KEY_ACCESS_CONTROL  "Access"
68 
69 
70 /*----------------------------------------------------------------------------
71 --  Type declarations
72 ----------------------------------------------------------------------------*/
73 
74 
75 /*----------------------------------------------------------------------------
76 --  Global definitions
77 ----------------------------------------------------------------------------*/
78 
79 /* Name of module. */
80 static char  *module_name = "xtmAccessBase";
81 
82 
83 /*----------------------------------------------------------------------------
84 --  Function prototypes
85 ----------------------------------------------------------------------------*/
86 
87 
88 
89 /*----------------------------------------------------------------------------
90 --  Functions
91 ----------------------------------------------------------------------------*/
92 
93 XTM_AB_STATUS
xtmAbGetAccessInfo(char * directory,LST_DESC_TYPE * access_info)94   xtmAbGetAccessInfo( char           *directory,
95                       LST_DESC_TYPE  *access_info )
96 {
97 
98   /* Variables. */
99   char                buffer[ 200 ];
100   char                flags[ 20 ];
101   char                group[ 30 ];
102   char                key[ 50 ];
103   char                user[ 30 ];
104   char                *char_ref;
105   FILE                *file_ref;
106   LST_STATUS          lst_status;
107   XTM_AB_ACCESS_INFO  access;
108 
109 
110   /* Code. */
111 
112   /* Create an new access list. */
113   *access_info = LstLinkNew( sizeof( XTM_AB_ACCESS_INFO ), NULL );
114 
115 
116   /* Build the filename. */
117   sprintf( buffer, "%s/%s", directory, ACCESS_FILE );
118 
119   /* Open the access control file. */
120   file_ref = fopen( buffer, "r" );
121   if( file_ref == NULL )
122     return( XTM_AB_ERROR );
123 
124 
125   /* Start reading from the file, skip all blank lines and comments. */
126   do {
127 
128     char_ref = fgets( buffer, sizeof( buffer ), file_ref );
129     if( char_ref == NULL ) {
130       fclose( file_ref );
131       return( XTM_AB_OK );
132     }
133 
134     /* Skip leading blanks. */
135     while( isspace( *char_ref ) )
136       char_ref++;
137 
138 
139     /* What kind of line is it? */
140 
141     /* Blank line? */
142     if( *char_ref == '\0' ) {
143       ;
144 
145     /* Comment? */
146     } else if( *char_ref == '#' ) {
147       ;
148 
149     /* Access information? */
150     } else if( strncmp( char_ref, KEY_ACCESS_CONTROL,
151                strlen( KEY_ACCESS_CONTROL) ) == 0 ) {
152 
153       user[  0 ] ='\0';
154       group[ 0 ] ='\0';
155       flags[ 0 ] ='\0';
156 
157       sscanf( char_ref, "%[^:]: %[^ ] %[^ ] %[^ \n]",
158               key,
159               user, group, flags );
160 
161       /* Convert user name to uid. */
162       if( strcmp( user, "*" ) == 0 )
163         access.uid = -1;
164       else
165         access.uid = atoi( user );
166 
167       if( strcmp( group, "*" ) == 0 )
168         access.gid = -1;
169       else
170         access.gid = atoi( group );
171 
172 
173       /* Check the flags. */
174       access.flags = 0;
175 
176       if( strchr( flags, 'r' ) != NULL )
177         flagSet( access.flags, XTM_AB_FLAG_READ );
178 
179       if( strchr( flags, 'w' ) != NULL )
180         flagSet( access.flags, XTM_AB_FLAG_WRITE );
181 
182       if( strchr( flags, 'm' ) != NULL )
183         flagSet( access.flags, XTM_AB_FLAG_MSG );
184 
185       if( strchr( flags, 'p' ) != NULL )
186         flagSet( access.flags, XTM_AB_FLAG_PRIV );
187 
188       lst_status = LstLinkInsertLast( *access_info, &access );
189 
190     /* Unknown key. */
191     } else {
192       sprintf( buffer, "Unknown key %s", char_ref );
193 
194       fprintf( stderr, "XDiary, %s %s: %s\n",
195                module_name, "xtmAbGetAccessInfo", buffer );
196     } /* if */
197 
198   } while( True );
199 
200 
201 } /* xtmAbGetAccessInfo */
202 
203 
204 /*----------------------------------------------------------------------*/
205 
206 XTM_AB_STATUS
xtmAbGetAfsAccessInfo(char * directory,LST_DESC_TYPE * access_info)207   xtmAbGetAfsAccessInfo( char           *directory,
208                          LST_DESC_TYPE  *access_info )
209 {
210 
211   /* Variables. */
212   char                 buffer[ 600 ];
213   char                 flags[ 20 ];
214   char                 key[ 50 ];
215   char                 *char_ref;
216   FILE                 *file_ref;
217   LST_STATUS           lst_status;
218   XTM_AB_AFS_ACL_INFO  acl_id;
219 
220 
221   /* Code. */
222 
223   /* Create an new access list. */
224   *access_info = LstLinkNew( sizeof( XTM_AB_AFS_ACL_INFO ), NULL );
225 
226   /* Build the filename. */
227   sprintf( buffer, "%s/%s", directory, AFS_ACCESS_FILE );
228 
229   /* Open the access control file. */
230   file_ref = fopen( buffer, "r" );
231   if( file_ref == NULL )
232     return( XTM_AB_ERROR );
233 
234 
235   /* Start reading from the file, skip all blank lines and comments. */
236   do {
237 
238     char_ref = fgets( buffer, sizeof( buffer ), file_ref );
239     if( char_ref == NULL ) {
240       fclose( file_ref );
241       return( XTM_AB_OK );
242     }
243 
244     /* Skip leading blanks. */
245     while( isspace( *char_ref ) )
246       char_ref++;
247 
248 
249     /* What kind of line is it? */
250 
251     /* Blank line? */
252     if( *char_ref == '\0' ) {
253       ;
254 
255     /* Comment? */
256     } else if( *char_ref == '#' ) {
257       ;
258 
259     /* Access information? */
260     } else if( strncmp( char_ref, KEY_ACCESS_CONTROL,
261                strlen( KEY_ACCESS_CONTROL) ) == 0 ) {
262 
263       flags[ 0 ] ='\0';
264 
265       sscanf( char_ref, "%[^:]: %[^ ] %[^ ]\n]", key, acl_id.id, flags );
266 
267       /* Check the flags. */
268       acl_id.flags = 0;
269 
270       if( strchr( flags, 'r' ) != NULL )
271         flagSet( acl_id.flags, XTM_AB_FLAG_READ );
272 
273       if( strchr( flags, 'w' ) != NULL )
274         flagSet( acl_id.flags, XTM_AB_FLAG_WRITE );
275 
276       if( strchr( flags, 'm' ) != NULL )
277         flagSet( acl_id.flags, XTM_AB_FLAG_MSG );
278 
279       lst_status = LstLinkInsertLast( *access_info, &acl_id );
280 
281     /* Unknown key. */
282     } else {
283       sprintf( buffer, "Unknown key %s", char_ref );
284 
285       fprintf( stderr, "XDiary, %s %s: %s\n",
286                module_name, "xtmAbGetAfsAccessInfo", buffer );
287     } /* if */
288 
289   } while( True );
290 
291 
292 } /* xtmAbGetAfsAccessInfo */
293 
294 
295 /*----------------------------------------------------------------------*/
296 
297 XTM_AB_STATUS
xtmAbSaveAccessInfo(char * directory,LST_DESC_TYPE access_info)298   xtmAbSaveAccessInfo( char           *directory,
299                        LST_DESC_TYPE  access_info )
300 {
301 
302   /* Variables. */
303   char                buffer[ 200 ];
304   char                group[ 30 ];
305   char                user[ 30 ];
306   FILE                *file_ref;
307   LST_STATUS          lst_status;
308   XTM_AB_ACCESS_INFO  access;
309 
310 
311   /* Code. */
312 
313   /* Write the database locations. */
314   if( LstLinkElements( access_info ) == 0 )
315     return( XTM_AB_OK );
316 
317 
318   /* Build the filename. */
319   sprintf( buffer, "%s/%s", directory, ACCESS_FILE );
320 
321   /* Open the access control file. */
322   file_ref = fopen( buffer, "w" );
323   if( file_ref == NULL )
324     return( XTM_AB_ERROR );
325 
326 
327   /* Save all access entries. */
328   lst_status = LstLinkCurrentFirst( access_info );
329 
330   while( lst_status == LST_OK ) {
331     lst_status = LstLinkGetCurrent( access_info, &access );
332 
333     /* Take care of user and group id. */
334     if( access.uid == -1 )
335       sprintf( user, "*" );
336     else
337       sprintf( user, "%d", access.uid );
338 
339     if( access.gid == -1 )
340       sprintf( group, "*" );
341     else
342       sprintf( group, "%d", access.gid );
343 
344     fprintf( file_ref, "%s: %-20.20s %-20.20s ",
345              KEY_ACCESS_CONTROL,
346              user, group );
347 
348     /* Write the flags. */
349     if( flagIsSet( access.flags, XTM_AB_FLAG_READ ) )
350       fprintf( file_ref, "r" );
351 
352     if( flagIsSet( access.flags, XTM_AB_FLAG_WRITE ) )
353       fprintf( file_ref, "w" );
354 
355     if( flagIsSet( access.flags, XTM_AB_FLAG_MSG ) )
356       fprintf( file_ref, "m" );
357 
358     fprintf( file_ref, "\n" );
359 
360     /* Next entry. */
361     lst_status = LstLinkCurrentNext( access_info );
362 
363   } /* while */
364 
365   fclose( file_ref );
366 
367   return( XTM_AB_OK );
368 
369 } /* xtmAbSaveAccessInfo */
370 
371 
372 /*----------------------------------------------------------------------*/
373 
374 XTM_AB_STATUS
xtmAbSaveAfsAccessInfo(char * directory,LST_DESC_TYPE access_info)375   xtmAbSaveAfsAccessInfo( char           *directory,
376                           LST_DESC_TYPE  access_info )
377 {
378 
379   /* Variables. */
380   char                 buffer[ 600 ];
381   FILE                 *file_ref;
382   LST_STATUS           lst_status;
383   XTM_AB_AFS_ACL_INFO  acl_id;
384 
385 
386   /* Code. */
387 
388   /* Write the database locations. */
389   if( LstLinkElements( access_info ) == 0 )
390     return( XTM_AB_OK );
391 
392 
393   /* Build the filename. */
394   sprintf( buffer, "%s/%s", directory, AFS_ACCESS_FILE );
395 
396   /* Open the access control file. */
397   file_ref = fopen( buffer, "w" );
398   if( file_ref == NULL )
399     return( XTM_AB_ERROR );
400 
401 
402   /* Save all access entries. */
403   lst_status = LstLinkCurrentFirst( access_info );
404 
405   while( lst_status == LST_OK ) {
406     lst_status = LstLinkGetCurrent( access_info, &acl_id );
407 
408     fprintf( file_ref, "%s: %s ", KEY_ACCESS_CONTROL, acl_id.id );
409 
410     /* Write the flags. */
411     if( flagIsSet( acl_id.flags, XTM_AB_FLAG_READ ) )
412       fprintf( file_ref, "r" );
413 
414     if( flagIsSet( acl_id.flags, XTM_AB_FLAG_WRITE ) )
415       fprintf( file_ref, "w" );
416 
417     if( flagIsSet( acl_id.flags, XTM_AB_FLAG_MSG ) )
418       fprintf( file_ref, "m" );
419 
420     fprintf( file_ref, "\n" );
421 
422     /* Next entry. */
423     lst_status = LstLinkCurrentNext( access_info );
424 
425   } /* while */
426 
427   fclose( file_ref );
428 
429   return( XTM_AB_OK );
430 
431 } /* xtmAbSaveAfsAccessInfo */
432 
433 
434 /*----------------------------------------------------------------------*/
435 
436 XTM_AB_STATUS
xtmAbGetUserOperations(char * directory,int user_id,int group_id,UINT32 * operations)437   xtmAbGetUserOperations( char    *directory,
438                           int     user_id,
439                           int     group_id,
440                           UINT32  *operations )
441 {
442 
443   /* Variables. */
444   XTM_AB_ACCESS_INFO  access;
445   XTM_AB_STATUS       ac_status;
446   LST_DESC_TYPE       access_info;
447   LST_STATUS          lst_status;
448 
449 
450   /* Code. */
451 
452   *operations = 0;
453 
454   /* Fetch the access control list for this database. */
455   ac_status = xtmAbGetAccessInfo( directory, &access_info );
456   if( ac_status != XTM_AB_OK )
457     return( XTM_AB_OK );
458 
459   /* Check the access information. */
460   lst_status = LstLinkCurrentFirst( access_info );
461 
462   while( lst_status == LST_OK ) {
463     lst_status = LstLinkGetCurrent( access_info, &access );
464 
465     /* Do we have a match? */
466     if( (access.uid == -1       && access.gid == -1 ) ||
467         (access.uid == -1       && access.gid == group_id) ||
468         (access.uid == user_id  && access.gid == -1 ) ||
469         (access.uid == user_id  && access.gid == group_id) ) {
470 
471       /* Check the flags. */
472       if( flagIsSet( access.flags, XTM_AB_FLAG_READ ) ) {
473         flagSet( *operations, XTM_DB_FLAG_MODE_READ );
474       }
475 
476       if( flagIsSet( access.flags, XTM_AB_FLAG_WRITE ) ) {
477         flagSet( *operations, XTM_DB_FLAG_MODE_READ );
478         flagSet( *operations, XTM_DB_FLAG_MODE_WRITE );
479         flagSet( *operations, XTM_DB_FLAG_MODE_MSG );
480       }
481 
482       if( flagIsSet( access.flags, XTM_AB_FLAG_MSG ) ) {
483         flagSet( *operations, XTM_DB_FLAG_MODE_MSG );
484       }
485 
486       if( flagIsSet( access.flags, XTM_AB_FLAG_PRIV ) ) {
487         flagSet( *operations, XTM_DB_FLAG_MODE_READ );
488         flagSet( *operations, XTM_DB_FLAG_MODE_WRITE );
489         flagSet( *operations, XTM_DB_FLAG_MODE_MSG );
490         flagSet( *operations, XTM_DB_FLAG_MODE_PRIV );
491       }
492 
493       if( *operations != 0 )
494         flagSet( *operations, XTM_DB_FLAG_MODE_SETID );
495 
496       LstLinkClear( access_info );
497 
498       return( XTM_AB_OK );
499 
500     } /* if */
501 
502     /* Next entry. */
503     lst_status = LstLinkCurrentNext( access_info );
504 
505   } /* while */
506 
507   LstLinkClear( access_info );
508 
509 
510   return( XTM_AB_OK );
511 
512 } /* xtmAbGetUserOperations */
513